@w6w/ui 0.1.1 → 0.2.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/CHANGELOG.md +20 -0
- package/README.md +7 -5
- package/dist/AppPicker.d.ts +1 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs +11 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs.map +1 -0
- package/dist/{ConfirmModal-CD-P8mhN.js → ConfirmModal-Wx3i8F1n.js} +1588 -1564
- package/dist/ConfirmModal-Wx3i8F1n.js.map +1 -0
- package/dist/ConnectionHeader.d.ts +19 -0
- package/dist/EditConnectionModal.d.ts +21 -0
- package/dist/app-pages.d.ts +3 -0
- package/dist/components/AuthFieldsForm.d.ts +8 -1
- package/dist/components/CallableList.d.ts +57 -0
- package/dist/components/ConnectionList.d.ts +44 -0
- package/dist/components/ListItem.d.ts +16 -6
- package/dist/components/ReliabilityChart.d.ts +10 -0
- package/dist/components/ReliabilityList.d.ts +47 -0
- package/dist/connection-app-meta.d.ts +32 -0
- package/dist/flow.cjs +1 -1
- package/dist/flow.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.mjs +1700 -891
- package/dist/index.mjs.map +1 -1
- package/dist/provider.d.ts +19 -0
- package/dist/reliability-board-layout.d.ts +121 -0
- package/dist/types.d.ts +8 -0
- package/package.json +2 -2
- package/src/styles/_callable-list.scss +60 -0
- package/src/styles/_connections.scss +100 -0
- package/src/styles/_lists.scss +4 -0
- package/src/styles/_reliability.scss +339 -0
- package/src/styles.css +592 -0
- package/src/styles.scss +3 -0
- package/dist/ConfirmModal-8avl9Nv8.cjs +0 -11
- package/dist/ConfirmModal-8avl9Nv8.cjs.map +0 -1
- package/dist/ConfirmModal-CD-P8mhN.js.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/createW6WApi.ts","../src/components/ApiCallsPanel.tsx","../src/components/ListItem.tsx","../src/ActionTestForm.tsx","../src/YamlEditor.tsx","../src/components/CopyableText.tsx","../src/components/HealthStatusPill.tsx","../src/components/UptimeStrip.tsx","../src/components/server-resources-format.ts","../src/components/ServerResources.tsx","../src/components/history-scale.ts","../src/components/HistoryTimeline.tsx","../src/components/InfoTip.tsx","../src/components/EditButton.tsx","../src/components/DeleteButton.tsx","../src/components/RepoSyncIndicator.tsx","../src/components/StepStatusPill.tsx","../src/components/execution-format.ts","../src/components/ExecutionList.tsx","../src/components/ExecutionLogPanel.tsx","../src/components/ExecutionFilters.tsx","../src/components/ExecutionStats.tsx","../src/components/ExecutionDetail.tsx"],"sourcesContent":["/**\n * Default fetch-based W6WApi client. Convenience for partners without their\n * own HTTP client — studio wires react-query around its own implementation\n * and doesn't use this. Every method calls the w6w server directly and\n * throws `ApiError` on non-OK responses so callers can surface the message.\n */\nimport type { StepMeta, StepTest, TestRunSummary, W6WApi } from \"./provider.tsx\";\nimport type {\n ActionDef,\n ApiCallRecord,\n AppSummary,\n AuthDef,\n ConnectionSummary,\n FunctionDetail,\n FunctionSummary,\n SavedTest,\n WorkflowDetail,\n WorkflowSummary,\n} from \"./types.ts\";\n\nexport interface CreateW6WApiOptions {\n /** Absolute URL or path prefix — e.g. `\"https://w6w.example.com\"` or `\"/api\"`. */\n baseUrl: string;\n /**\n * Bearer token to send. Accepts a string (static) or a supplier function so\n * a JWT that rotates on refresh is fetched fresh on every request. The\n * supplier may be sync or return a `Promise` — either way it is awaited\n * once per request. It receives an optional `{ forceRefresh? }` ctx arg\n * (unused by this client today, but part of the shape so a caller's\n * supplier can share one implementation with `@w6w/sdk`'s `TokenProvider`).\n */\n token?:\n | string\n | ((ctx?: { forceRefresh?: boolean }) =>\n | string\n | null\n | undefined\n | Promise<string | null | undefined>);\n /** Optional fetch replacement — handy for tests. Defaults to `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\nexport class ApiError extends Error {\n status: number;\n code: string;\n /**\n * The parsed error response body, when the server sent one. Carries the\n * fields that ride alongside an error — e.g. an invoke's `logs` and\n * `apiCalls` — which the message alone would drop.\n */\n body?: unknown;\n\n constructor(status: number, code: string, message: string, body?: unknown) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.body = body;\n }\n}\n\n/** Build a fetch-based W6WApi client bound to a base URL + token supplier. */\nexport function createW6WApi(opts: CreateW6WApiOptions): W6WApi {\n const baseUrl = opts.baseUrl.replace(/\\/$/, \"\");\n const doFetch = opts.fetch ?? globalThis.fetch;\n const getToken = async () => (typeof opts.token === \"function\" ? await opts.token() : opts.token);\n\n // The shared fetch core: auth header, JSON parse, and the one error-shaping\n // idiom every member uses. Exposes the response's own status code (`req<T>`\n // below discards it) — `runWorkflow` is the one caller that needs it, to\n // derive `terminal` from `200` vs the server's own `202` wait-timeout arm.\n async function rawReq(\n path: string,\n init?: RequestInit,\n ): Promise<{ status: number; data: unknown }> {\n const headers = new Headers(init?.headers);\n const token = await getToken();\n if (token) headers.set(\"authorization\", `Bearer ${token}`);\n if (init?.body && !headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n\n let res: Response;\n try {\n res = await doFetch(`${baseUrl}${path}`, { ...init, headers });\n } catch (e) {\n // A failed fetch throws a bare `TypeError: Failed to fetch` — wrap it with\n // the target so callers can tell the server is down vs. a real API error.\n throw new ApiError(\n 0,\n \"network_error\",\n `Could not reach the w6w server (${init?.method ?? \"GET\"} ${baseUrl}${path}). ` +\n `It may be down or unreachable. (${(e as Error).message})`,\n );\n }\n const text = await res.text();\n let data: unknown = null;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n if (!res.ok) {\n throw new ApiError(\n res.status,\n \"bad_response\",\n `Server returned a non-JSON ${res.status} response: ${text.slice(0, 200)}`,\n );\n }\n }\n }\n if (!res.ok) {\n const err = ((data as { error?: { code?: string; message?: string } } | null)?.error ??\n {}) as { code?: string; message?: string };\n throw new ApiError(res.status, err.code ?? \"error\", err.message ?? res.statusText, data);\n }\n return { status: res.status, data };\n }\n\n async function req<T>(path: string, init?: RequestInit): Promise<T> {\n const { data } = await rawReq(path, init);\n return data as T;\n }\n\n return {\n // A bare GET only returns the server's default page (50) — every consumer\n // of this client treats the result as the complete catalog, so page\n // through it here. Capped at 20 pages as a runaway backstop.\n listApps: async () => {\n const apps: AppSummary[] = [];\n let cursor: string | undefined;\n for (let page = 0; page < 20; page++) {\n const qs = new URLSearchParams({ limit: \"200\" });\n if (cursor) qs.set(\"cursor\", cursor);\n const r = await req<{ apps: AppSummary[]; nextCursor?: string }>(`/apps?${qs}`);\n apps.push(...r.apps);\n if (!r.nextCursor) break;\n cursor = r.nextCursor;\n }\n return apps;\n },\n\n // Bounded lookup: dedupe; `[]` sends nothing; chunks of <= 100 (the server's\n // `MAX_IDS_PER_QUERY`), each `GET /apps?ids=a,b` with no limit/cursor.\n listAppsByIds: async (ids) => {\n const unique = Array.from(new Set(ids));\n const apps: AppSummary[] = [];\n for (let i = 0; i < unique.length; i += 100) {\n const chunk = unique.slice(i, i + 100);\n const qs = chunk.map(encodeURIComponent).join(\",\");\n const r = await req<{ apps: AppSummary[] }>(`/apps?ids=${qs}`);\n apps.push(...r.apps);\n }\n return apps;\n },\n\n getAppAuth: async (id: string) => {\n const r = await req<{ auths: AuthDef[] }>(`/apps/${encodeURIComponent(id)}/auths`);\n return r.auths ?? [];\n },\n\n createConnection: (appId, body) =>\n req<{ connection: ConnectionSummary }>(`/apps/${encodeURIComponent(appId)}/connections`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((r) => r.connection),\n\n startAppOAuthFlow: (appId, authKey, body) =>\n req<{ authorizationUrl: string }>(\n `/apps/${encodeURIComponent(appId)}/oauth-config/${encodeURIComponent(authKey)}/authorize-url`,\n { method: \"POST\", body: JSON.stringify(body) },\n ),\n\n getAppActions: (appId) =>\n req<{ actions: ActionDef[] }>(`/apps/${encodeURIComponent(appId)}`).then(\n (r) => r.actions ?? [],\n ),\n\n listConnectionsForApp: (appId) =>\n req<{ connections: ConnectionSummary[] }>(\n `/apps/${encodeURIComponent(appId)}/connections`,\n ).then((r) => r.connections ?? []),\n\n listConnections: () =>\n req<{ connections: ConnectionSummary[] }>(\"/connections\").then((r) => r.connections ?? []),\n\n invokeAction: (appId, actionKey, params, opts = {}) =>\n req<{\n value: unknown;\n logs?: string[];\n apiCalls?: ApiCallRecord[];\n meta?: StepMeta;\n }>(\n `/apps/${encodeURIComponent(appId)}/actions/${encodeURIComponent(actionKey)}/invoke`,\n // This body is built KEY BY KEY, not by spreading `opts` — so every new\n // option has to be named here or it is silently dropped before the wire\n // (the caller compiles, the UI looks right, the field never leaves the\n // page). `project` scopes document-expression resolution to the\n // workflow's selected project; `state` is the start state upstream step\n // outputs are seeded from, so `{{ steps.<id>.output.<f> }}` resolves.\n // Undefined keys are dropped by JSON.stringify, so an absent project or\n // state leaves the request byte-identical to one that never had them.\n {\n method: \"POST\",\n body: JSON.stringify({\n params,\n connectionId: opts.connectionId,\n project: opts.project,\n state: opts.state,\n }),\n },\n ),\n\n listSavedTests: (connectionId) =>\n req<{ savedTests: SavedTest[] }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests`,\n ).then((r) => r.savedTests ?? []),\n\n createSavedTest: (connectionId, body) =>\n req<{ savedTest: SavedTest }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then((r) => r.savedTest),\n\n updateSavedTest: (connectionId, id, patch) =>\n req<{ savedTest: SavedTest }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests/${encodeURIComponent(id)}`,\n { method: \"PATCH\", body: JSON.stringify(patch) },\n ).then((r) => r.savedTest),\n\n deleteSavedTest: (connectionId, id) =>\n req<void>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests/${encodeURIComponent(id)}`,\n { method: \"DELETE\" },\n ).then(() => undefined),\n\n recordTestRun: (connId, body) =>\n req<{ run: unknown }>(`/connections/${encodeURIComponent(connId)}/test-runs`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then(() => undefined),\n\n listTestRuns: (connectionId) =>\n req<{ runs: TestRunSummary[] }>(\n `/connections/${encodeURIComponent(connectionId)}/test-runs`,\n ).then((r) => r.runs ?? []),\n\n saveStepTest: (workflowId, stepId, body) =>\n req<{ stepTest: StepTest }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/tests`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then((r) => r.stepTest),\n\n listStepTests: (workflowId, stepId) =>\n req<{ stepTests: StepTest[] }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/tests`,\n ).then((r) => r.stepTests ?? []),\n\n recordStepTestRun: (workflowId, stepId, body) =>\n req<{ run: unknown }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/test-runs`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then(() => undefined),\n\n listFunctions: () =>\n req<{ functions: FunctionSummary[] }>(\"/functions\").then((r) => r.functions ?? []),\n\n getFunction: (id) =>\n req<{ function: Omit<FunctionDetail, \"valid\">; valid: boolean }>(\n `/functions/${encodeURIComponent(id)}`,\n ).then((r) => ({ ...r.function, valid: r.valid })),\n\n // The real synchronous route (`/functions/:id/invoke`) — deliberately NOT\n // `POST /run`, which would give the test stage a different code path than\n // the `@w6w/call` node it's standing in for. Returns the raw output,\n // pinned against the committed `studio/src/repos/functions.ts` signature.\n invokeFunction: (id, inputs) =>\n req<{ output?: unknown }>(`/functions/${encodeURIComponent(id)}/invoke`, {\n method: \"POST\",\n body: JSON.stringify({ inputs }),\n }).then((r) => r.output),\n\n listWorkflows: () =>\n req<{ workflows: WorkflowSummary[] }>(\"/workflows\").then((r) => r.workflows ?? []),\n\n getWorkflow: (id) =>\n req<{ workflow: WorkflowDetail }>(`/workflows/${encodeURIComponent(id)}`).then(\n (r) => r.workflow,\n ),\n\n // `rawReq`, not `req<T>` — the ONE caller that needs the response's own\n // status code: `200` (the run reached a terminal state inside the wait\n // window) vs `202` (the server's own wait-timeout, still running). Both\n // are 2xx successes; `rawReq` already throws on a non-2xx.\n runWorkflow: (id, opts = {}) =>\n rawReq(`/workflows/${encodeURIComponent(id)}/run?wait=true`, {\n method: \"POST\",\n body: JSON.stringify({ variables: opts.variables, input: opts.input }),\n }).then(({ status, data }) => {\n const body = (data ?? {}) as {\n runId: string;\n status: string;\n output?: unknown;\n error?: unknown;\n };\n return { ...body, terminal: status === 200 };\n }),\n };\n}\n","import type { ReactNode } from \"react\";\nimport type { ApiCallRecord } from \"../types.ts\";\n\nexport interface ApiCallsPanelProps {\n /** The captured outbound calls to render, in the order they were made. */\n calls: ApiCallRecord[];\n /**\n * Open every call's `<details>` on first render. Default `false` — the wire\n * log is ground truth you reach for, not something to read on every run. A\n * host that already landed the user on ONE specific call (e.g. a drill-down\n * that scoped the list to it) passes `true` so the user isn't made to click\n * twice through their own target.\n */\n defaultOpen?: boolean;\n /**\n * React `key` for each call. Defaults to method + url + array index, which is\n * stable within a single run because captured calls carry no id of their own.\n * A host rendering PERSISTED rows (which do have an id) across a paginated\n * list must pass its own — index keys collide between pages and React then\n * reuses the wrong `<details>` open-state.\n */\n keyOf?: (call: ApiCallRecord, index: number) => string;\n /**\n * Section header. Defaults to `API call(s) (N)`. Pass `false` to suppress it\n * entirely when the host already owns the heading — same idiom as\n * `ActionTestForm`'s `embedded` prop, which suppresses its own pop-out chrome\n * because the host provides it. Any other node replaces the default text.\n */\n title?: ReactNode | false;\n}\n\n/** Pretty-print a captured body when it is JSON; otherwise show it verbatim. */\nfunction formatBody(body: string | null | undefined): string {\n if (!body) return \"\";\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n}\n\n/** Captured calls have no id of their own; index is stable within a run. */\nfunction defaultKeyOf(call: ApiCallRecord, index: number): string {\n return `${call.method}-${call.url ?? call.host}-${index}`;\n}\n\n/**\n * The wire log for a run: each outbound HTTP call the action made, with the\n * request we sent and the response we got back. Collapsed by default — it is the\n * ground truth you open when the result looks wrong (e.g. a template variable\n * that came through unrendered), not something to read on every run.\n *\n * Purely presentational: it renders exactly what it is given, with no fetching,\n * no context, and no derivation of state from the calls. Credential redaction\n * happens server-side at capture time (request AND response headers); nothing\n * here re-inspects or re-redacts them.\n */\nexport function ApiCallsPanel({ calls, defaultOpen, keyOf, title }: ApiCallsPanelProps) {\n if (calls.length === 0) return null;\n const key = keyOf ?? defaultKeyOf;\n return (\n <div className=\"w6w-stack\" style={{ gap: 4 }}>\n {title !== false && (\n <strong className=\"w6w-small\">\n {title ?? (\n <>\n API {calls.length === 1 ? \"call\" : \"calls\"} ({calls.length})\n </>\n )}\n </strong>\n )}\n {calls.map((call, i) => (\n <details\n key={key(call, i)}\n open={defaultOpen}\n className=\"w6w-result\"\n style={{ padding: 8 }}\n >\n <summary style={{ cursor: \"pointer\" }}>\n <span className=\"w6w-small\">\n {call.method} {call.url ?? call.host} →{\" \"}\n <strong>{call.error ? \"failed\" : call.status}</strong>\n {call.durationMs !== undefined && (\n <span className=\"w6w-muted\"> · {call.durationMs}ms</span>\n )}\n </span>\n </summary>\n <div className=\"w6w-stack\" style={{ gap: 6, marginTop: 8 }}>\n {call.error && <div className=\"w6w-error w6w-small\">{call.error}</div>}\n <div className=\"w6w-muted w6w-small\">Request headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.requestHeaders ?? {}, null, 2)}</pre>\n {call.requestBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Request body</div>\n <pre className=\"w6w-result\">{formatBody(call.requestBody)}</pre>\n </>\n )}\n <div className=\"w6w-muted w6w-small\">Response headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.responseHeaders ?? {}, null, 2)}</pre>\n {call.responseBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Response body</div>\n <pre className=\"w6w-result\">{formatBody(call.responseBody)}</pre>\n </>\n )}\n {call.truncated && (\n <div className=\"w6w-muted w6w-small\">\n A captured body exceeded the size cap and was truncated.\n </div>\n )}\n </div>\n </details>\n ))}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface ListItemProps {\n /** Primary label — prominent, single-line with ellipsis overflow. */\n title: ReactNode;\n /** Secondary label under the title — muted, small, truncates. */\n subtitle?: ReactNode;\n /** Leading slot (e.g. an `<AppIcon />` or status glyph). */\n icon?: ReactNode;\n /** Trailing slot pushed to the right (e.g. a badge or chevron). */\n trailing?: ReactNode;\n /** Highlights the row as selected/current. Reflected as `aria-pressed` when clickable. */\n active?: boolean;\n /** When provided, the row renders as a focusable, keyboard-activatable button. */\n onClick?: () => void;\n /** Accessible label for the clickable row (falls back to the `title` DOM text). */\n ariaLabel?: string;\n}\n\n/**\n * A clean, reusable list row: leading icon · title over subtitle · trailing slot.\n *\n * Mirrors the look/behaviour of the saved-test button rows it replaces. When\n * `onClick` is given it renders a `<button type=\"button\">` (focusable, Enter/Space\n * activatable) with `aria-pressed={active}`; otherwise a plain, non-interactive row.\n */\nexport function ListItem({\n title,\n subtitle,\n icon,\n trailing,\n active = false,\n onClick,\n ariaLabel,\n}: ListItemProps) {\n const body = (\n <>\n {icon != null && <span className=\"w6w-list-item-icon\">{icon}</span>}\n <span className=\"w6w-list-item-body\">\n <span className=\"w6w-list-item-title\">{title}</span>\n {subtitle != null && <span className=\"w6w-list-item-subtitle\">{subtitle}</span>}\n </span>\n {trailing != null && <span className=\"w6w-list-item-trailing\">{trailing}</span>}\n </>\n );\n\n const className = `w6w-list-item${active ? \" active\" : \"\"}`;\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n className={className}\n aria-pressed={active}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {body}\n </button>\n );\n }\n\n return (\n <div className={className} aria-label={ariaLabel}>\n {body}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { JsonEditor } from \"./JsonEditor.tsx\";\nimport { ParamsForm } from \"./ParamsForm.tsx\";\nimport { ApiCallsPanel } from \"./components/ApiCallsPanel.tsx\";\nimport { Combobox } from \"./components/Combobox.tsx\";\nimport { ConfirmModal } from \"./components/ConfirmModal.tsx\";\nimport { ListItem } from \"./components/ListItem.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type { RequestOverrides, TestRunSummary } from \"./provider.tsx\";\nimport type { ActionDef, ApiCallRecord, SavedTest, ThemeMode } from \"./types.ts\";\n\nexport interface ActionTestFormProps {\n /** App the action belongs to. */\n appId: string;\n /** The app's actions — the caller already has them from the app detail. */\n actions: ActionDef[];\n /** Fixed connection to run against; its credential is resolved server-side. */\n connectionId?: string;\n /**\n * Pre-selected action (controlled). When provided the built-in action\n * `<select>` is hidden — the caller is already driving the selection.\n */\n action?: ActionDef | null;\n /** Theme hint, accepted for parity with other ui-lib components. */\n theme?: ThemeMode;\n /**\n * Studio-integration seam: when provided (and its reference changes) the\n * current action's params are seeded from a shallow copy of this object, so a\n * host page can \"open\" a saved test pre-filled. The stored object is never\n * mutated; a subsequent user edit is free to diverge. Optional — existing\n * consumers keep compiling.\n */\n seedValues?: Record<string, unknown> | null;\n /**\n * Studio-integration seam: fired after a successful saved-test create/delete\n * so the host page can invalidate its own `[\"saved-tests\", connId]` query.\n * The modal rail still refreshes its own list independently. Optional.\n */\n onSavedTestsChanged?: () => void;\n /**\n * Studio-integration seam (URL-driven host): the id of the saved test being\n * edited, from a studio deep link (`…/test/:testId`). When it changes to a\n * non-null id it is adopted as the current `editingTestId` — so the bottom Save\n * PATCHes that row and the Delete button shows; when null the tester is a\n * fresh/unsaved test. Optional — existing consumers keep compiling.\n */\n seedTestId?: string | null;\n /**\n * Studio-integration seam: fired whenever the current `values` diverge from\n * (or return to) the seeded baseline. This is the unsaved-changes signal the\n * studio host gates modal-close on (its ConfirmModal prompt). Optional.\n */\n onDirtyChange?: (dirty: boolean) => void;\n /**\n * Studio-integration seam: fired after a successful save (POST create or PATCH\n * update) with the resulting `SavedTest`, so the host can sync the URL\n * (`…/test/:id`) and clear its own dirty state. Optional.\n */\n onTestSaved?: (test: SavedTest) => void;\n /**\n * Studio-integration seam: fired after a successful delete of the saved test\n * currently being edited, with the deleted id, so the host can navigate away\n * from a now-dead `…/test/:id` URL. Optional — existing consumers keep compiling.\n */\n onDeleted?: (testId: string) => void;\n /**\n * Host-embedded mode. When `true` the caller already renders this widget inside\n * its own modal (studio's `ConnectionTesterModal`), so the widget suppresses its\n * OWN `<Modal>` + pop-out (⤢) toggle and instead fills the host container as a\n * full-height flex column: the params + saved-tests region scrolls and the\n * action bar is pinned to the bottom. Default `false` — non-embedded (inline /\n * own pop-out) usages are unchanged.\n */\n embedded?: boolean;\n}\n\n/**\n * Minimal relative-time label (\"just now\", \"5m ago\", \"3h ago\", \"2d ago\", or a\n * date for anything older) from an ISO timestamp. Kept inline — no formatter is\n * imported here — and only used for the saved-tests rail subtitle.\n */\nfunction relativeTime(iso: string): string {\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return \"\";\n const secs = Math.max(0, Math.round((Date.now() - then) / 1000));\n if (secs < 45) return \"just now\";\n const mins = Math.round(secs / 60);\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.round(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.round(hours / 24);\n if (days < 7) return `${days}d ago`;\n return new Date(then).toLocaleDateString();\n}\n\n/** Pull default values out of declared params so the form starts populated. */\nfunction defaultParamsFor(action: ActionDef | null | undefined): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const p of action?.params ?? []) {\n if (p.key && p.default !== undefined) out[p.key] = p.default;\n }\n return out;\n}\n\n/** A rendered action error: a plain-language headline, an optional fix hint, and the raw provider detail. */\ninterface InvokeError {\n headline: string;\n hint?: string;\n detail?: string;\n}\n\n/**\n * Pull the provider's own human-readable message out of a raw error string. App\n * actions often throw like `SendGrid list index returned 403: {\"errors\":[{\"message\":\"…\"}]}`\n * — parse the trailing JSON and surface just the human message, keeping the\n * `\"<App> … returned <status>\"` prefix.\n */\nfunction extractProviderMessage(msg: string): string {\n const brace = msg.indexOf(\"{\");\n if (brace >= 0) {\n try {\n const j = JSON.parse(msg.slice(brace)) as {\n errors?: { message?: string }[];\n error?: { message?: string } | string;\n message?: string;\n };\n const m =\n j?.errors?.[0]?.message ??\n (typeof j?.error === \"object\" ? j.error?.message : j?.error) ??\n j?.message;\n if (typeof m === \"string\" && m.trim()) {\n const prefix = msg.slice(0, brace).replace(/[:\\s]+$/, \"\");\n return prefix ? `${prefix}: ${m.trim()}` : m.trim();\n }\n } catch {\n // Not JSON — fall through and return the message as-is.\n }\n }\n return msg;\n}\n\n/**\n * A failed-invoke error shape, matched by field rather than class identity —\n * ui's own `ApiError` and `@w6w/sdk`'s are two different classes across the\n * package boundary, and `status`+`code` is what both actually carry.\n * Considered mirroring `packages/wrappers/cli/src/exit.ts:60-63`'s `name ===\n * \"ApiError\"` fallback; not adopted — that solves module DUPLICATION of one\n * class, while ui's problem is cross-package IDENTITY, which `status`+`code`\n * already settles.\n */\nfunction isInvokeApiError(\n e: unknown,\n): e is { status: number; code: string; message?: string; body?: unknown; raw?: unknown } {\n return (\n typeof e === \"object\" &&\n e !== null &&\n typeof (e as { status: unknown }).status === \"number\" &&\n typeof (e as { code: unknown }).code === \"string\"\n );\n}\n\n/**\n * Turn a thrown invoke error into a user-facing message. A permission/credential\n * failure at the underlying provider (HTTP 401/403, or the message mentions\n * scopes/forbidden/unauthorized) is stated plainly with what to fix, so the user\n * isn't left staring at a raw upstream JSON blob.\n */\nfunction describeInvokeError(e: unknown): InvokeError {\n if (!isInvokeApiError(e)) {\n return { headline: (e as Error)?.message ?? \"The action failed to run.\" };\n }\n const detail = extractProviderMessage(e.message ?? \"\");\n const haystack = `${e.status} ${e.code} ${e.message ?? \"\"}`.toLowerCase();\n const isPermission =\n e.status === 401 ||\n e.status === 403 ||\n /\\b(401|403)\\b|forbidden|unauthorized|not authorized|permission|scope|access denied|invalid api key|invalid credential/.test(\n haystack,\n );\n if (isPermission) {\n return {\n headline:\n \"Permission denied by the provider — this is a credential/scope problem, not a w6w error.\",\n hint:\n \"The connection's API key is missing the permissions this action needs. Fix it at the \" +\n \"provider — e.g. SendGrid → Settings → API Keys → give the key the required scopes (or Full \" +\n \"Access), or create a new key — then update this connection's credential and try again.\",\n detail,\n };\n }\n return { headline: \"The action returned an error.\", detail };\n}\n\n/**\n * The captured outbound calls the server attached to a failed invoke — ui's\n * own `ApiError` carries them on `body`, `@w6w/sdk`'s on `raw`; read `body ??\n * raw` so either shape's calls surface.\n */\nfunction apiCallsOf(e: unknown): ApiCallRecord[] {\n const source = isInvokeApiError(e)\n ? ((e.body ?? e.raw) as { apiCalls?: ApiCallRecord[] } | null)\n : null;\n return source?.apiCalls ?? [];\n}\n\n/**\n * One Overrides sub-editor's local state (`body`/`query`/`headers`): raw text\n * (the widget's source of truth), the last value that parsed as a plain JSON\n * object, and whether the CURRENT text is invalid. Empty/whitespace text is\n * always valid and means \"not set\" — never blocks Run — matching the\n * requirement that clearing a field returns to \"no override\", not an error.\n *\n * Deliberately re-parses on every keystroke here rather than wiring\n * `JsonEditor`'s own `onValidChange`/`onValidityChange`: that pair reports an\n * emptied field as `{valid: false, error: \"Empty\"}`, which would wrongly keep\n * Run refusing the moment a touched field is cleared back out.\n */\nfunction useOverrideJsonField() {\n const [text, setText] = useState(\"\");\n const [value, setValue] = useState<Record<string, unknown> | undefined>(undefined);\n const [invalid, setInvalid] = useState(false);\n const onChange = (next: string) => {\n setText(next);\n const trimmed = next.trim();\n if (trimmed === \"\") {\n setInvalid(false);\n return;\n }\n try {\n const parsed = JSON.parse(trimmed);\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setValue(parsed as Record<string, unknown>);\n setInvalid(false);\n } else {\n setInvalid(true);\n }\n } catch {\n setInvalid(true);\n }\n };\n return { text, value, invalid, onChange } as const;\n}\n\n/**\n * Schema-driven form to test/run a single action against a connection. Renders\n * the action's declared params through {@link ParamsForm} (the same primitive\n * the step builder uses) instead of a raw JSON textarea, invokes the action via\n * `useW6WApi().invokeAction`, and shows the returned value or error.\n *\n * The selected action is either controlled by the caller (`action` prop) or\n * chosen from a built-in `<select>` over `actions`. Param values reset whenever\n * the selected action changes.\n */\nexport function ActionTestForm({\n appId,\n actions,\n connectionId,\n action,\n seedValues,\n onSavedTestsChanged,\n seedTestId,\n onDirtyChange,\n onTestSaved,\n onDeleted,\n embedded = false,\n}: ActionTestFormProps) {\n const api = useW6WApi();\n\n // Actions sorted for the built-in picker (only used when uncontrolled).\n const sortedActions = useMemo(() => {\n const list = [...actions];\n list.sort((a, b) => (a.title || a.key).localeCompare(b.title || b.key));\n return list;\n }, [actions]);\n\n // Internal selection, used only when the caller doesn't control `action`.\n const [pickedKey, setPickedKey] = useState<string>(action?.key ?? \"\");\n const selectedAction: ActionDef | null =\n action ?? actions.find((a) => a.key === pickedKey) ?? null;\n\n const [running, setRunning] = useState(false);\n const [error, setError] = useState<InvokeError | null>(null);\n const [result, setResult] = useState<unknown>(undefined);\n // The outbound HTTP calls the last run made (redacted request + response).\n // Populated on success AND failure — a wrong payload is usually only visible\n // on the wire, not in the value.\n const [apiCalls, setApiCalls] = useState<ApiCallRecord[]>([]);\n\n // Overrides region (T2.1.1): a RequestOverrides envelope submitted as a\n // fourth field alongside params — architecturally NOT a Param (it never\n // enters `resolveParams`), so it is a SIBLING region to `paramsRegion`\n // rather than a slot inside `ParamsForm`'s \"Additional parameters\"\n // disclosure. See `.claude/docs/overrides.md`.\n const ovBody = useOverrideJsonField();\n const ovQuery = useOverrideJsonField();\n const ovHeaders = useOverrideJsonField();\n const [ovTarget, setOvTarget] = useState<\"\" | \"first\" | \"first-write\" | \"all\">(\"\");\n const [ovMatch, setOvMatch] = useState(\"\");\n // Any sub-editor currently holding invalid JSON blocks the run outright —\n // never send a half-parsed envelope.\n const overridesInvalid = ovBody.invalid || ovQuery.invalid || ovHeaders.invalid;\n // Built fresh from current state on every call — an untouched (or cleared)\n // control leaves every field empty, so this returns `undefined` and the run\n // sends no `overrides` key at all: byte-identical to a request from before\n // this control existed.\n const currentOverrides = (): RequestOverrides | undefined => {\n const out: RequestOverrides = {};\n if (ovBody.text.trim() !== \"\" && ovBody.value !== undefined) out.body = ovBody.value;\n if (ovQuery.text.trim() !== \"\" && ovQuery.value !== undefined) {\n out.query = ovQuery.value as Record<string, string | number | boolean | null>;\n }\n if (ovHeaders.text.trim() !== \"\" && ovHeaders.value !== undefined) {\n out.headers = ovHeaders.value as Record<string, string>;\n }\n if (ovTarget) out.target = ovTarget;\n if (ovMatch.trim() !== \"\") out.match = ovMatch.trim();\n return Object.keys(out).length > 0 ? out : undefined;\n };\n\n // Params view: the schema-driven form, or the whole `values` object as raw JSON.\n const [viewMode, setViewMode] = useState<\"form\" | \"json\">(\"form\");\n const [jsonText, setJsonText] = useState(\"\");\n const [jsonInvalid, setJsonInvalid] = useState(false);\n\n // Pop-out: when open, the params region moves into a larger `Modal` canvas.\n // It is the SAME region bound to the SAME `values`/`setValues`, just relocated,\n // so edits stay in sync with the inline view.\n const [modalOpen, setModalOpen] = useState(false);\n\n // Param values, re-seeded from defaults whenever the selected action changes.\n // On a FRESH MOUNT with `seedValues` present (e.g. a deep-linked saved test),\n // seed from a shallow copy of it rather than defaults — otherwise the seed guard\n // below never fires on first render (`lastSeed` inits to the same ref) and the\n // seeded values are dropped.\n const selectedKey = selectedAction?.key ?? null;\n const initialValues = seedValues ? { ...seedValues } : defaultParamsFor(selectedAction);\n const [valuesByAction, setValuesByAction] = useState<{\n key: string | null;\n values: Record<string, unknown>;\n }>(() => ({\n key: selectedKey,\n values: initialValues,\n }));\n\n // The id of the saved test currently being edited, or `null` for an unsaved\n // test. Drives the PATCH-vs-POST decision in `submitSaveTest`: a set id updates\n // that row in place, `null` creates a new named row. Seeded from `seedTestId`\n // so a studio deep link (`…/test/:testId`) mounts already in edit mode.\n const [editingTestId, setEditingTestId] = useState<string | null>(seedTestId ?? null);\n\n // Dirty baseline: the values as last seeded/loaded/saved. `values` is compared\n // against this to derive the host-facing `dirty` signal (`onDirtyChange`). Reset\n // wherever a fresh set of values is adopted (action change, seed, load, save).\n const [baseline, setBaseline] = useState<Record<string, unknown>>(initialValues);\n\n if (valuesByAction.key !== selectedKey) {\n // Selection changed (controlled or via the picker, without a remount) — reset the\n // form values AND clear any stale result/error carried over from the previously\n // selected action (a 403 from `list-get` must not linger while `mail-send` shows).\n // Editing id: a genuine action-switch starts a fresh unsaved test (→ null), BUT a\n // deep-link whose action arrives AFTER mount is NOT an action-switch — the selected\n // action IS the seeded test's action. A truthy `seedTestId` therefore wins here, so\n // the late null→key transition keeps `editingTestId === seedTestId` (Save PATCHes,\n // Delete shows) instead of clobbering it to null and POSTing a duplicate row.\n const fresh = defaultParamsFor(selectedAction);\n setValuesByAction({ key: selectedKey, values: fresh });\n setBaseline(fresh);\n setEditingTestId(seedTestId ?? null);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n }\n\n // Studio seam: adopt a deep-linked saved-test id. When `seedTestId` changes to a\n // non-null id, make it the current editing id (bottom Save PATCHes, Delete\n // shows); a change to null returns the tester to a fresh/unsaved test.\n const [lastSeedTestId, setLastSeedTestId] = useState<string | null | undefined>(seedTestId);\n if (seedTestId !== lastSeedTestId) {\n setLastSeedTestId(seedTestId);\n setEditingTestId(seedTestId ?? null);\n }\n\n // Studio seam: when a new `seedValues` reference arrives (e.g. \"open a saved\n // test\"), seed the current action's params from a SHALLOW COPY of it. Applied\n // as a render-phase guard like the action-change reseed above; the passed\n // object is never mutated and later edits are free to diverge.\n const [lastSeed, setLastSeed] = useState<Record<string, unknown> | null | undefined>(seedValues);\n if (seedValues !== lastSeed) {\n // Content-aware, not reference-keyed: a `[\"saved-tests\"]` invalidation (fired by\n // onTestSaved/onSavedTestsChanged after a Save) hands back a fresh OBJECT with the\n // SAME content — that must NOT reseed the draft or clear the on-screen Run\n // result/error. Reseed only when the incoming values differ STRUCTURALLY from the\n // last applied seed. `lastSeed` advances to the new ref regardless, so we don't\n // re-compare the same pair every render.\n const structurallyChanged =\n JSON.stringify(seedValues ?? null) !== JSON.stringify(lastSeed ?? null);\n setLastSeed(seedValues);\n if (seedValues && structurallyChanged) {\n const seeded = { ...seedValues };\n setValuesByAction({ key: selectedKey, values: seeded });\n setBaseline(seeded);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n }\n }\n\n const values = valuesByAction.values;\n const setValues = (next: Record<string, unknown>) =>\n setValuesByAction({ key: selectedKey, values: next });\n\n // Host-facing dirty signal: do the current values diverge from the seeded\n // baseline? Compared by structural JSON so a load→edit→revert cycle clears it.\n const dirty = useMemo(\n () => JSON.stringify(values) !== JSON.stringify(baseline),\n [values, baseline],\n );\n // biome-ignore lint/correctness/useExhaustiveDependencies: fire only when `dirty` flips, not on every `onDirtyChange` identity change.\n useEffect(() => {\n onDirtyChange?.(dirty);\n }, [dirty]);\n\n // Entering the JSON view seeds the editor from the current values; edits that\n // parse to a plain object round-trip straight back into `values`.\n const enterJsonView = () => {\n setJsonText(JSON.stringify(values, null, 2));\n setJsonInvalid(false);\n setViewMode(\"json\");\n };\n\n // The single invoke path — used by \"Run action\" and by re-running a saved test.\n const runWith = async (params: Record<string, unknown>) => {\n if (!selectedAction) return;\n // An invalid Overrides sub-editor refuses the run outright — the Run\n // button is also disabled for this, but guard here too so a saved-test\n // re-run (which bypasses the button) can't slip a half-parsed envelope\n // through either.\n if (overridesInvalid) return;\n const actionKey = selectedAction.key;\n setRunning(true);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n let outcome: { ok: boolean; summary: string; result?: unknown };\n const overrides = currentOverrides();\n try {\n const r = await api.invokeAction(appId, actionKey, params, {\n connectionId,\n ...(overrides ? { overrides } : {}),\n });\n setResult(r.value);\n setApiCalls(r.apiCalls ?? []);\n outcome = { ok: true, summary: \"OK\", result: r.value };\n } catch (e) {\n const err = describeInvokeError(e);\n setError(err);\n // The server returns the captured calls on the error body too — the\n // request that failed is the thing worth looking at.\n setApiCalls(apiCallsOf(e));\n outcome = { ok: false, summary: err.headline };\n } finally {\n setRunning(false);\n }\n // Log every run (success or failure) against the connection, and update the\n // saved test's last-run when this run came from an editing session. Best\n // effort — a logging failure must not mask the run's own result.\n if (connectionId) {\n try {\n await api.recordTestRun(connectionId, {\n savedTestId: editingTestId ?? null,\n actionKey,\n ok: outcome.ok,\n summary: outcome.summary.slice(0, 200),\n result: outcome.result,\n });\n refreshSavedTests();\n refreshRunHistory();\n onSavedTestsChanged?.();\n } catch {\n // Ignore — the run itself already surfaced via result/error.\n }\n }\n };\n const run = () => runWith(values);\n\n // Saved tests for this connection. `nonce` re-triggers the fetch after a\n // create/delete so the rail reflects the change without a full remount.\n const [savedTests, setSavedTests] = useState<SavedTest[] | null>(null);\n const [savedTestsError, setSavedTestsError] = useState<string | null>(null);\n const [savedTestsNonce, setSavedTestsNonce] = useState(0);\n // Name-a-saved-test dialog (in-app Modal — never the browser's prompt()).\n const [nameModalOpen, setNameModalOpen] = useState(false);\n const [pendingName, setPendingName] = useState(\"\");\n // Delete-confirm dialog (in-app ConfirmModal — never the browser's confirm()).\n const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);\n const refreshSavedTests = () => setSavedTestsNonce((n) => n + 1);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `savedTestsNonce` is a deliberate re-fetch trigger, not read inside the effect.\n useEffect(() => {\n if (!connectionId) {\n setSavedTests(null);\n return;\n }\n let canceled = false;\n setSavedTestsError(null);\n api\n .listSavedTests(connectionId)\n .then((list) => !canceled && setSavedTests(list))\n .catch((e) => !canceled && setSavedTestsError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, connectionId, savedTestsNonce]);\n\n // Only this action's saved tests belong on the rail.\n const railTests = selectedKey\n ? (savedTests ?? []).filter((t) => t.actionKey === selectedKey)\n : [];\n\n // Connection run history from the unified `run_log` ledger (F-1). Complements\n // the per-saved-test `lastRun*` badge with the full recent-run list. Fetched\n // via the OPTIONAL `api.listTestRuns` — a consumer that doesn't implement it\n // (studio, until T2.2.2) simply shows no history. `runHistoryNonce` re-triggers\n // the fetch after a run is recorded so the list stays current.\n const [runHistory, setRunHistory] = useState<TestRunSummary[] | null>(null);\n const [runHistoryNonce, setRunHistoryNonce] = useState(0);\n const refreshRunHistory = () => setRunHistoryNonce((n) => n + 1);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `runHistoryNonce` is a deliberate re-fetch trigger, not read inside the effect.\n useEffect(() => {\n const load = api.listTestRuns;\n if (!connectionId || !load) {\n setRunHistory(null);\n return;\n }\n let canceled = false;\n load(connectionId)\n .then((list) => !canceled && setRunHistory(list))\n // Best-effort: a history load failure must never break the tester.\n .catch(() => !canceled && setRunHistory(null));\n return () => {\n canceled = true;\n };\n }, [api, connectionId, runHistoryNonce]);\n\n // History rows for the current action (mirrors the saved-tests rail filter),\n // most-recent first — the server orders newest-first but we don't rely on it.\n const railRunHistory = selectedKey\n ? (runHistory ?? [])\n .filter((r) => r.actionKey === selectedKey)\n .slice()\n .sort((a, b) => Date.parse(b.occurredAt) - Date.parse(a.occurredAt))\n : [];\n\n // Open the in-app name dialog to save the current params as a NEW named test.\n const openSaveModal = () => {\n if (!connectionId || !selectedAction) return;\n setPendingName(\"\");\n setSavedTestsError(null);\n setNameModalOpen(true);\n };\n // Bottom Save affordance. When a saved test is loaded for editing\n // (`editingTestId` set) the save is a silent PATCH — no throwaway name dialog\n // (FU-1). With no editing id, open the name dialog to create a new named row.\n const handleSaveClick = () => {\n if (!connectionId || !selectedAction) return;\n if (editingTestId) {\n void submitSaveTest();\n } else {\n openSaveModal();\n }\n };\n // Persist the current params. When a saved test is loaded for editing\n // (`editingTestId` set), PATCH that row in place — updating only `values` keeps\n // its name and sidesteps the 409 duplicate-name guard a re-POST would trip.\n // With no editing id, create a new named row from the dialog and remember its\n // id so the next save updates in place rather than spawning a second row.\n const submitSaveTest = async () => {\n if (!connectionId || !selectedAction) return;\n try {\n let saved: SavedTest;\n if (editingTestId) {\n saved = await api.updateSavedTest(connectionId, editingTestId, { values });\n } else {\n const name = pendingName.trim();\n if (!name) return;\n saved = await api.createSavedTest(connectionId, {\n actionKey: selectedAction.key,\n name,\n values,\n });\n setEditingTestId(saved.id);\n }\n // The just-saved values are the new clean baseline (dirty → false).\n setBaseline({ ...values });\n setNameModalOpen(false);\n setPendingName(\"\");\n refreshSavedTests();\n onSavedTestsChanged?.();\n onTestSaved?.(saved);\n } catch (e) {\n setSavedTestsError((e as Error).message);\n }\n };\n\n // Load a saved test's values into the form (shallow copy — never mutate the\n // stored row). Clicking a saved test's name loads it for editing: values +\n // editing id are adopted and the load becomes the new clean baseline.\n const loadSavedTest = (t: SavedTest) => {\n const loaded = { ...t.values };\n setValuesByAction({ key: selectedKey, values: loaded });\n setBaseline(loaded);\n // Remember which row is being edited so a subsequent save PATCHes it in place.\n setEditingTestId(t.id);\n setViewMode(\"form\");\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n };\n // Delete the saved test currently being edited (Delete only shows with an\n // editing id set). Clears the editing id so the form drops to unsaved state.\n const deleteCurrentTest = async () => {\n if (!connectionId || !editingTestId) return;\n const deletedId = editingTestId;\n try {\n await api.deleteSavedTest(connectionId, deletedId);\n setEditingTestId(null);\n refreshSavedTests();\n onSavedTestsChanged?.();\n // Host hook: let the URL-driven host (studio's ConnectionTesterModal) navigate\n // away from the now-dead `…/test/:deletedId` deep link.\n onDeleted?.(deletedId);\n } catch (e) {\n setSavedTestsError((e as Error).message);\n }\n };\n\n // The params region: the form↔JSON toggle plus the ParamsForm/JsonEditor block.\n // Rendered in exactly one place at a time — inline when the pop-out is closed,\n // inside the `Modal` when it's open — so there's a single instance bound to the\n // single `values`/`setValues` state (no copy-on-open, edits stay in sync).\n const paramsRegion = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1-5)\" }}>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Parameters</span>\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1)\" }}>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${viewMode === \"form\" ? \" active\" : \"\"}`}\n aria-pressed={viewMode === \"form\"}\n onClick={() => setViewMode(\"form\")}\n >\n Form\n </button>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${viewMode === \"json\" ? \" active\" : \"\"}`}\n aria-pressed={viewMode === \"json\"}\n onClick={enterJsonView}\n >\n JSON\n </button>\n {/* Pop-out toggle — suppressed in embedded mode: the host already\n provides full-screen modal chrome, so a modal-in-modal ⤢ is redundant. */}\n {!embedded && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-sm w6w-btn-ghost\"\n aria-pressed={modalOpen}\n title={\n modalOpen ? \"Collapse the params editor\" : \"Open the params editor in a larger view\"\n }\n aria-label={\n modalOpen ? \"Collapse the params editor\" : \"Open the params editor in a larger view\"\n }\n onClick={() => setModalOpen((v) => !v)}\n >\n {modalOpen ? \"⤡\" : \"⤢\"}\n </button>\n )}\n </div>\n </div>\n\n {viewMode === \"form\" ? (\n <ParamsForm params={selectedAction?.params ?? []} values={values} onChange={setValues} />\n ) : (\n <>\n <JsonEditor\n value={jsonText}\n onChange={setJsonText}\n minHeight={modalOpen ? \"50vh\" : \"200px\"}\n aria-label=\"Params JSON\"\n onValidChange={(parsed) => {\n // Only a JSON object maps onto the params `values` record; ignore a\n // bare array/scalar so `values` stays a plain key→value object.\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setValues(parsed as Record<string, unknown>);\n }\n }}\n onValidityChange={({ valid }) => setJsonInvalid(!valid)}\n />\n {jsonInvalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </>\n )}\n </div>\n );\n\n // The Overrides region: a sibling to `paramsRegion`, never nested inside it\n // (and never inside `ParamsForm`'s own \"Additional parameters\" disclosure —\n // `overrides` is not a Param). Collapsed by default via `<details>`, reusing\n // the same `.w6w-section` disclosure `SectionField` renders for a\n // `section: \"collapsible\"` param, since this is the identical visual shape\n // (titled, collapsed-by-default disclosure) applied to a hand-built control\n // instead of a schema-driven one.\n const overridesRegion = (\n <details className=\"w6w-section\" data-testid=\"overrides-region\">\n <summary className=\"w6w-section-summary\">\n <span className=\"w6w-section-title\">Overrides</span>\n <span className=\"w6w-section-subtitle\">\n Reach a vendor field this action's own params don't declare\n </span>\n </summary>\n <div className=\"w6w-stack w6w-section-body\" style={{ gap: \"var(--w6w-sp-2)\" }}>\n <div className=\"w6w-field\">\n <span>Body</span>\n <JsonEditor\n value={ovBody.text}\n onChange={ovBody.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides body (JSON)\"\n />\n {ovBody.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <div className=\"w6w-field\">\n <span>Query</span>\n <JsonEditor\n value={ovQuery.text}\n onChange={ovQuery.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides query (JSON)\"\n />\n {ovQuery.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <div className=\"w6w-field\">\n <span>Headers</span>\n <JsonEditor\n value={ovHeaders.text}\n onChange={ovHeaders.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides headers (JSON)\"\n />\n {ovHeaders.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <label className=\"w6w-field\">\n <span>Target</span>\n <select\n aria-label=\"Overrides target\"\n value={ovTarget}\n onChange={(e) => setOvTarget(e.target.value as typeof ovTarget)}\n >\n <option value=\"\">— default (first) —</option>\n <option value=\"first\">first</option>\n <option value=\"first-write\">first-write</option>\n <option value=\"all\">all</option>\n </select>\n </label>\n <label className=\"w6w-field\">\n <span>Match</span>\n <input\n type=\"text\"\n aria-label=\"Overrides match\"\n value={ovMatch}\n placeholder=\"Restrict to requests whose URL contains…\"\n onChange={(e) => setOvMatch(e.target.value)}\n />\n </label>\n <span className=\"w6w-hint\">\n Merged onto the outbound request at the wire, never into the params above — name a field\n the way the vendor's own API documents it.\n </span>\n </div>\n </details>\n );\n\n // The saved-tests rail — the right pane of the pop-out. Only meaningful when a\n // connection is fixed; hidden entirely otherwise (guarded on `connectionId`).\n const savedTestsRail = connectionId ? (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1-5)\" }}>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Saved tests</span>\n </div>\n {savedTestsError && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n {savedTestsError}\n </span>\n )}\n {railTests.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">No saved tests for this action yet.</p>\n ) : (\n <ul\n className=\"w6w-stack\"\n style={{ listStyle: \"none\", margin: 0, padding: 0, gap: \"var(--w6w-sp-1-5)\" }}\n >\n {railTests.map((t) => (\n <li key={t.id}>\n {/* Clicking a saved test loads it for editing — no per-row\n Load/Run/Delete buttons; those actions live at the modal bottom.\n Subtitle shows the last run (✓/✗ + relative time), falling back\n to the last-saved time when the test has never been run. */}\n <ListItem\n title={t.name}\n subtitle={\n t.lastRunAt ? (\n <span>\n <span\n style={{ color: t.lastRunOk ? \"var(--w6w-success)\" : \"var(--w6w-danger)\" }}\n >\n {t.lastRunOk ? \"✓\" : \"✗\"}\n </span>{\" \"}\n {t.lastRunSummary ? `${t.lastRunSummary} · ` : \"\"}\n {relativeTime(t.lastRunAt)}\n </span>\n ) : (\n `saved ${relativeTime(t.updatedAt)}`\n )\n }\n active={t.id === editingTestId}\n onClick={() => loadSavedTest(t)}\n />\n </li>\n ))}\n </ul>\n )}\n\n {/* Run history (F-1): the connection's recent tester runs for this action,\n from the unified `run_log` ledger. Read-only rows (no onClick) — this is\n a log, not a loadable input like the saved tests above. Only rendered\n when the api exposes `listTestRuns` (optional member) and there is\n history to show, so a consumer without it degrades to no section. */}\n {api.listTestRuns && railRunHistory.length > 0 && (\n <>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Recent runs</span>\n </div>\n <ul\n className=\"w6w-stack\"\n style={{ listStyle: \"none\", margin: 0, padding: 0, gap: \"var(--w6w-sp-1-5)\" }}\n >\n {railRunHistory.map((r) => (\n <li key={r.id}>\n <ListItem\n title={\n <span>\n <span style={{ color: r.ok ? \"var(--w6w-success)\" : \"var(--w6w-danger)\" }}>\n {r.ok ? \"✓\" : \"✗\"}\n </span>{\" \"}\n {r.actionKey}\n </span>\n }\n subtitle={\n <span>\n {r.summary ? `${r.summary} · ` : \"\"}\n {relativeTime(r.occurredAt)}\n </span>\n }\n />\n </li>\n ))}\n </ul>\n </>\n )}\n </div>\n ) : null;\n\n // Nullable: `editingTestId` can be seeded from a studio deep link before\n // `savedTests` itself has finished fetching, so this may not resolve yet.\n const deletingTestName = savedTests?.find((t) => t.id === editingTestId)?.name;\n\n return (\n <div className={`w6w-stack${embedded ? \" w6w-tester-embedded-root\" : \"\"}`}>\n {/* Action picker — only when the caller isn't controlling the selection. */}\n {!action &&\n (actions.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">This app exposes no actions.</p>\n ) : (\n // biome-ignore lint/a11y/noLabelWithoutControl: Combobox renders its own <select>/<input> INSIDE this label, so the field text labels the control at runtime; the rule cannot see through the component boundary.\n <label className=\"w6w-field\">\n <span>Action{selectedKey ? \"\" : \" *\"}</span>\n <Combobox\n value={pickedKey}\n placeholder=\"— pick an action —\"\n onChange={setPickedKey}\n options={sortedActions.map((a) => ({\n value: a.key,\n label: `${a.title ?? a.key} (${a.key})`,\n }))}\n />\n </label>\n ))}\n\n {selectedAction ? (\n <>\n <div>\n <strong>\n {selectedAction.title ?? selectedAction.key}{\" \"}\n <code className=\"w6w-muted\">{selectedAction.key}</code>\n </strong>\n {selectedAction.description && (\n <p className=\"w6w-muted w6w-small\" style={{ margin: \"var(--w6w-sp-0-5) 0 0\" }}>\n {selectedAction.description}\n </p>\n )}\n </div>\n\n {(() => {\n // The scrollable tester content: params editor + error + result. Shared\n // by every layout (inline body, pop-out modal, embedded footer layout)\n // so it stays a single instance bound to the single `values` state.\n const paramsAndResult = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-3)\" }}>\n {paramsRegion}\n {overridesRegion}\n {error && (\n <div className=\"w6w-result w6w-error\">\n <strong>{error.headline}</strong>\n {error.hint && (\n <div style={{ marginTop: \"var(--w6w-sp-1-5)\" }}>{error.hint}</div>\n )}\n {error.detail && (\n <div\n className=\"w6w-muted w6w-small\"\n style={{\n marginTop: \"var(--w6w-sp-1-5)\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {error.detail}\n </div>\n )}\n </div>\n )}\n {result !== undefined && (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1)\" }}>\n <strong className=\"w6w-small\">Result</strong>\n <pre className=\"w6w-result\">{JSON.stringify(result, null, 2)}</pre>\n </div>\n )}\n <ApiCallsPanel calls={apiCalls} />\n </div>\n );\n // Bottom-anchored actions: Run / Save always; Delete only when an\n // editing id is set (an already-saved test is loaded). In embedded mode\n // this becomes a bottom-pinned, bordered footer outside the scroll region.\n const actionBar = (\n <div\n className={`w6w-tester-actions${\n embedded || modalOpen ? \" w6w-tester-actions-footer\" : \"\"\n }`}\n style={{ display: \"flex\", gap: \"var(--w6w-sp-2)\" }}\n >\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={running || overridesInvalid}\n onClick={run}\n >\n {running ? \"Running…\" : \"Run action\"}\n </button>\n {connectionId && (\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={handleSaveClick}>\n Save test\n </button>\n )}\n {connectionId && editingTestId && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n style={{ marginLeft: \"auto\", color: \"var(--w6w-danger)\" }}\n onClick={() => setConfirmDeleteOpen(true)}\n >\n Delete\n </button>\n )}\n </div>\n );\n // The tester body: params + result + actions, stacked. Rendered inline\n // when the pop-out modal is closed, and inside the pop-out modal (left\n // pane, saved-tests rail on the right) when open.\n const body = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-3)\" }}>\n {paramsAndResult}\n {actionBar}\n </div>\n );\n // Host-embedded: the host owns the modal chrome, so fill it as a\n // full-height flex column — params + saved-tests rail scroll, the action\n // bar is pinned to the bottom as a non-scrolling footer.\n if (embedded) {\n return (\n <div className=\"w6w-tester-embedded\">\n <div className=\"w6w-tester-embedded-scroll\">\n {savedTestsRail ? (\n <div className=\"w6w-tester-embedded-cols\">\n <div className=\"w6w-tester-embedded-main\">{paramsAndResult}</div>\n <div className=\"w6w-tester-embedded-rail\">{savedTestsRail}</div>\n </div>\n ) : (\n paramsAndResult\n )}\n </div>\n {actionBar}\n </div>\n );\n }\n return modalOpen ? (\n <Modal\n title={`Edit params — ${selectedAction.title ?? selectedAction.key}`}\n onClose={() => setModalOpen(false)}\n size=\"full\"\n >\n {/* The pop-out's own internal scroll boundary (T1.4.1 round 2): with\n `-full`'s `overflow: hidden` live, the dialog itself no longer\n scrolls, so params + result (+ the saved-tests rail) get a\n dedicated scroll region here and the action bar stays a pinned\n footer below it — mirrors `.w6w-tester-embedded-scroll`'s\n mechanism (see styles.css), just for this own-pop-out layout\n instead of the host-embedded one. */}\n <div className=\"w6w-tester-popout\">\n <div className=\"w6w-tester-popout-scroll\">\n {savedTestsRail ? (\n <div\n style={{\n display: \"flex\",\n gap: \"var(--w6w-sp-4)\",\n alignItems: \"flex-start\",\n }}\n >\n <div style={{ flex: 1, minWidth: 0 }}>{paramsAndResult}</div>\n <div style={{ width: 260, flexShrink: 0 }}>{savedTestsRail}</div>\n </div>\n ) : (\n paramsAndResult\n )}\n </div>\n {actionBar}\n </div>\n </Modal>\n ) : (\n body\n );\n })()}\n\n {nameModalOpen && (\n <Modal title=\"Save test\" onClose={() => setNameModalOpen(false)}>\n <form\n className=\"w6w-stack\"\n style={{ gap: \"var(--w6w-sp-3)\" }}\n onSubmit={(e) => {\n e.preventDefault();\n void submitSaveTest();\n }}\n >\n <label className=\"w6w-field\">\n <span>Name this saved test</span>\n <input\n type=\"text\"\n value={pendingName}\n placeholder=\"e.g. valid sender\"\n onChange={(e) => setPendingName(e.target.value)}\n />\n </label>\n {savedTestsError && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n {savedTestsError}\n </span>\n )}\n <div\n style={{ display: \"flex\", gap: \"var(--w6w-sp-2)\", justifyContent: \"flex-end\" }}\n >\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setNameModalOpen(false)}\n >\n Cancel\n </button>\n <button type=\"submit\" className=\"w6w-btn\" disabled={!pendingName.trim()}>\n Save\n </button>\n </div>\n </form>\n </Modal>\n )}\n\n {confirmDeleteOpen && (\n <ConfirmModal\n title=\"Delete saved test\"\n message={\n deletingTestName\n ? `Delete \"${deletingTestName}\"? This cannot be undone.`\n : \"Delete this saved test? This cannot be undone.\"\n }\n confirmLabel=\"Delete\"\n onConfirm={() => {\n setConfirmDeleteOpen(false);\n void deleteCurrentTest();\n }}\n onClose={() => setConfirmDeleteOpen(false)}\n />\n )}\n </>\n ) : (\n !action && <p className=\"w6w-muted w6w-small\">Pick an action above to test it.</p>\n )}\n </div>\n );\n}\n","import { yaml } from \"@codemirror/lang-yaml\";\nimport { EditorView } from \"@codemirror/view\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { useMemo } from \"react\";\nimport { CheckGlyph, CopyGlyph } from \"./components/Copyable.tsx\";\nimport { useCopyToClipboard } from \"./components/use-copy.ts\";\nimport { useEffectiveTheme } from \"./theme.ts\";\nimport type { ThemeMode } from \"./types.ts\";\n\nexport interface YamlEditorProps {\n value: string;\n onChange: (value: string) => void;\n\n /** Placeholder text shown when value is empty. */\n placeholder?: string;\n /** Minimum editor height. Defaults to \"240px\". */\n minHeight?: string;\n /** Maximum editor height before scrolling. Defaults to no cap. */\n maxHeight?: string;\n /**\n * Explicit editor height. Pass `\"100%\"` to fill a flex parent (the whole-config\n * \"code\" view). Omit to let the editor grow with its content between\n * `minHeight` and `maxHeight` — an inline YAML/group field wants this.\n */\n height?: string;\n\n /** Read-only mode — useful for previewing a stored definition. */\n readOnly?: boolean;\n\n /**\n * Explicit theme. If omitted, the editor auto-detects `data-theme` on\n * `<html>` and falls back to `prefers-color-scheme` — same behavior as\n * `<AppIcon>`. Uses CodeMirror's built-in one-dark for dark mode.\n */\n theme?: ThemeMode;\n\n /** Accessible label for the editor. */\n \"aria-label\"?: string;\n\n /**\n * Render an in-box copy-to-clipboard button, a direct child of this\n * component's own `.w6w-yaml-editor` wrapper (sibling to the CodeMirror\n * mount — no extra DOM node). Copies the current `value` verbatim.\n *\n * Off by default: the other mounts of this component must render byte-\n * identically to before this prop existed.\n */\n copyable?: boolean;\n}\n\n/**\n * YAML editor built on CodeMirror 6. Syntax highlighting, folding, gutter,\n * and line numbers. Themed with the `--w6w-*` custom properties so it\n * inherits from the consumer's palette.\n *\n * ```tsx\n * <YamlEditor value={text} onChange={setText} minHeight=\"320px\" />\n * ```\n */\nexport function YamlEditor(props: YamlEditorProps) {\n const theme = useEffectiveTheme(props.theme);\n // Only mounted when `copyable` is on, but the hook itself must run\n // unconditionally (Rules of Hooks) — it is inert (no button, no listener)\n // until `copy()` is actually invoked from the button below.\n const { copied, copy } = useCopyToClipboard(props.value);\n const extensions = useMemo(\n () => [\n yaml(),\n EditorView.theme({\n \"&\": {\n fontSize: \"13px\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n backgroundColor: \"var(--w6w-panel-2)\",\n color: \"var(--w6w-text)\",\n border: \"1px solid var(--w6w-border)\",\n borderRadius: \"8px\",\n },\n \"&.cm-focused\": { outline: \"2px solid var(--w6w-accent)\" },\n \".cm-gutters\": {\n backgroundColor: \"var(--w6w-panel)\",\n color: \"var(--w6w-muted)\",\n border: \"none\",\n borderRight: \"1px solid var(--w6w-border)\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n }),\n ],\n [],\n );\n\n function handleChange(next: string) {\n props.onChange(next);\n }\n\n return (\n <div className=\"w6w-yaml-editor\" aria-label={props[\"aria-label\"] ?? \"YAML editor\"}>\n <CodeMirror\n value={props.value}\n onChange={handleChange}\n extensions={extensions}\n placeholder={props.placeholder}\n readOnly={props.readOnly}\n // `readOnly` alone only blocks CodeMirror's own transactions\n // (`EditorState.readOnly`) — it leaves the content DOM\n // `contenteditable=\"true\"`, so a screen reader / a11y test still sees\n // it as an editable field. `editable` is the separate switch that\n // actually sets `contenteditable` (`EditorView.editable`); tying it to\n // `readOnly` here makes the prop mean what its name says.\n editable={!props.readOnly}\n theme={theme}\n height={props.height}\n minHeight={props.minHeight ?? \"240px\"}\n maxHeight={props.maxHeight}\n basicSetup={{\n lineNumbers: true,\n foldGutter: true,\n highlightActiveLine: !props.readOnly,\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n }}\n />\n {props.copyable && (\n <>\n <button\n type=\"button\"\n className={`w6w-icon-btn w6w-copyable-btn${copied ? \" is-copied\" : \"\"}`}\n aria-label=\"Copy\"\n onClick={() => void copy()}\n >\n {copied ? <CheckGlyph /> : <CopyGlyph />}\n </button>\n {/* Same live-region convention as `Copyable.tsx:141-147`: the\n button's accessible name stays constant, so this announces the\n result. */}\n <span className=\"w6w-copyable-status\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </span>\n </>\n )}\n </div>\n );\n}\n","import { Copyable } from \"./Copyable.tsx\";\n\n/** The single truncation marker every crop arm uses — matches\n * `studio/src/lib/page-title.ts:53-56`'s convention (one `…`, U+2026, never\n * three periods). */\nconst MARKER = \"…\";\n\n/**\n * Truncate `value` on a character budget, keeping `chars` VALUE characters and\n * adding {@link MARKER} on top (the marker is extra, not counted against\n * `chars`) — mirrors `page-title.ts`'s `clamp()` in STYLE (a single budget,\n * slice + marker, pure) but NOT its arithmetic: `clamp` slices at\n * `MAX - 1` so its marker counts inside the budget, which is the wrong shape\n * here (see `CopyableText.test.ts`'s fixture table).\n *\n * `chars` omitted, less than 1, or covering the whole value: returned as-is,\n * no marker.\n */\nexport function cropText(\n value: string,\n chars?: number,\n crop: \"start\" | \"end\" | \"middle\" = \"end\",\n): string {\n if (chars === undefined || chars < 1 || chars >= value.length) return value;\n\n if (crop === \"start\") {\n return `${MARKER}${value.slice(value.length - chars)}`;\n }\n if (crop === \"end\") {\n return `${value.slice(0, chars)}${MARKER}`;\n }\n\n // middle\n const head = Math.ceil(chars / 2);\n const tail = chars - head;\n return `${value.slice(0, head)}${MARKER}${value.slice(value.length - tail)}`;\n}\n\nexport interface CopyableTextProps {\n /** The full string. Always what gets written to the clipboard, regardless\n * of how much of it the cropped display shows. */\n value: string;\n /** How many VALUE characters to show. Omitted, `< 1`, or `>= value.length`\n * ⇒ shown in full. */\n chars?: number;\n /** Where the marker goes. Default `\"end\"`. */\n crop?: \"start\" | \"end\" | \"middle\";\n /** Accessible name of the copy button. Default \"Copy\" (per `Copyable`). */\n label?: string;\n className?: string;\n /** Forwarded to `Copyable`. See its own doc for the revert-delay caveat. */\n copiedMs?: number;\n}\n\n/**\n * A chrome-less, croppable copy-to-clipboard text — for a value too long to\n * show in full inline (an id, a token, a URL fragment) that still needs to be\n * copyable exactly.\n *\n * Composes `Copyable` rather than widening it (`Copyable`'s box chrome has 9\n * existing call sites depending on it) — `readOnly` + the\n * `.w6w-copyable--bare` modifier (`_copyable.scss`) strip the box, and the\n * FULL `value` is what `Copyable` receives, so a click always copies the\n * whole string even when the display is cropped. No `navigator.clipboard`\n * call lives in this file — that stays `Copyable`'s alone.\n */\nexport function CopyableText(props: CopyableTextProps) {\n const { value, chars, crop = \"end\", label, className, copiedMs } = props;\n const cropped = cropText(value, chars, crop);\n const classes = [\"w6w-copyable--bare\", className].filter(Boolean).join(\" \");\n\n return (\n <Copyable value={value} readOnly label={label} className={classes} copiedMs={copiedMs}>\n <span>{cropped}</span>\n </Copyable>\n );\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * The four health states a probe can report — a thin LOCAL copy of the RFC's\n * `HealthReport.state` union. `@w6w/ui` deliberately keeps a small literal type\n * here rather than depend on `@w6w/types`, so the display component stays a\n * pure-presentation leaf with no transport/spec coupling.\n */\nexport type HealthPillState = \"ok\" | \"degraded\" | \"down\" | \"unknown\";\n\nexport interface HealthStatusPillProps {\n /** Which health state to render — drives the colour + default label. */\n state: HealthPillState;\n /** Override the visible text (defaults to a humanised form of `state`). */\n label?: ReactNode;\n /** Accessible label for the pill (falls back to the visible text). */\n ariaLabel?: string;\n}\n\nconst DEFAULT_LABELS: Record<HealthPillState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\n/**\n * A small, theme-aware status pill for a single health state.\n *\n * Renders a coloured dot + label using the `--w6w-health-*` tokens, so a host\n * can restyle every state by overriding those custom properties (see\n * `styles.css`). Colour is never the only signal — the text label carries the\n * same meaning for accessibility.\n */\nexport function HealthStatusPill({ state, label, ariaLabel }: HealthStatusPillProps) {\n const text = label ?? DEFAULT_LABELS[state];\n\n return (\n <span className={`w6w-health-pill w6w-health-pill-${state}`} aria-label={ariaLabel}>\n <span className=\"w6w-health-pill-dot\" aria-hidden=\"true\" />\n <span className=\"w6w-health-pill-label\">{text}</span>\n </span>\n );\n}\n","/**\n * The four states a single day of the strip can be in — a thin LOCAL copy of the\n * RFC's `HealthReport.state` union, exactly as `HealthStatusPill` keeps one. The\n * duplication is deliberate: it keeps `@w6w/ui` a pure-presentation leaf with no\n * transport/spec coupling, so nothing here has to move when the spec package does.\n *\n * There is no fifth state. A day on which the account made no calls at all is\n * `unknown`, never `ok` — an unverified day must never be presented as a healthy\n * one (`rfcs/healthcheck.md`: `unknown` ranks above `ok` for that reason).\n */\nexport type UptimeCellState = \"ok\" | \"degraded\" | \"down\" | \"unknown\";\n\n/** One cell: the day it stands for, and the state already decided for it. */\nexport interface UptimeDay {\n /** The day this cell represents, e.g. `2026-07-27`. Shown verbatim in the tooltip. */\n day: string;\n /** The state for that day. The strip renders it; it never decides it. */\n state: UptimeCellState;\n /** Tooltip override. Defaults to `<day> — <state label>`. */\n label?: string;\n}\n\nexport interface UptimeStripProps {\n /**\n * The days to render, oldest first, one cell each. The component makes no\n * assumption about how many there are — a caller showing a 30-day window\n * passes 30, and a younger account can pass fewer.\n */\n days: UptimeDay[];\n /**\n * Accessible label for the strip as a whole (it is exposed as one image, not\n * as N unlabelled boxes). Defaults to `<n>-day status`.\n */\n ariaLabel?: string;\n}\n\nconst STATE_LABELS: Record<UptimeCellState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\n/**\n * A fixed-height strip of one cell per day, for \"how has this service behaved\n * lately\" at a glance.\n *\n * Purely presentational — it is handed an array of ALREADY-DECIDED states and\n * renders exactly those. No rules, no roll-up and no judgement about what counts\n * as broken live in this package; whatever decided the states owns that.\n *\n * Colour is never the only signal (same rule as `HealthStatusPill`, which pairs\n * its dot with a text label). Thirty cells cannot carry thirty labels, so the\n * strip signals twice in two other ways:\n * - every cell carries a `title` with its day and state, and\n * - the FILL HEIGHT encodes severity, so the row survives greyscale and\n * colour-blind viewing: `ok` is a short baseline bar, `degraded` a taller\n * one, `down` fills the cell, and `unknown` is a hatched outline with no\n * solid fill at all (nothing was measured — it is not a good day and not a\n * bad one).\n *\n * Colour itself comes from the shared `--w6w-health-*` tokens through the single\n * `--w6w-health-color` indirection the health pill uses, so a host that\n * overrides a token restyles the pill and the strip together.\n */\nexport function UptimeStrip({ days, ariaLabel }: UptimeStripProps) {\n if (days.length === 0) return null;\n\n return (\n <div\n className=\"w6w-uptime-strip\"\n role=\"img\"\n aria-label={ariaLabel ?? `${days.length}-day status`}\n >\n {days.map((entry, i) => (\n <span\n // Days are expected to be unique, but the index keeps the key stable\n // even if a caller repeats one — same guard as `ApiCallsPanel`.\n key={`${entry.day}-${i}`}\n className={`w6w-uptime-cell w6w-uptime-cell-${entry.state}`}\n title={entry.label ?? `${entry.day} — ${STATE_LABELS[entry.state]}`}\n />\n ))}\n </div>\n );\n}\n","/**\n * Pure formatting + geometry helpers for the server-resources family, kept in\n * their own module so they carry no React and can be unit-tested on their own.\n *\n * `ServerResourceSample` is a thin LOCAL copy of the sampler's wire sample\n * (`plan.md` §Pinned wire) — the same deliberate duplication `UptimeStrip.tsx`\n * keeps of the health union, and for the same reason: it keeps `@w6w/ui` a\n * pure-presentation leaf with no transport/spec coupling, so nothing here has\n * to move when the server's payload grows a field.\n *\n * Every helper is TOTAL: an unknown number is never rendered as `0`, it is\n * rendered as an em dash. A node whose CPU reading is missing must not read as\n * an idle node.\n */\n\n/** One sample of the host's resource usage, exactly as the server sends it. */\nexport interface ServerResourceSample {\n /** ISO-8601 instant the sample was taken. */\n ts: string;\n cpus: number | null;\n cpuLimit: number | null;\n load1: number | null;\n load5: number | null;\n load15: number | null;\n memoryTotal: number | null;\n memoryAvailable: number | null;\n memoryLimit: number | null;\n processRss: number | null;\n processHeapUsed: number | null;\n processHeapTotal: number | null;\n}\n\n/** What an unknown value renders as. Never `0`, never an empty cell. */\nconst UNKNOWN = \"—\";\n\n/** Binary magnitude suffixes, index-aligned with the 1024ᵏ divisor. */\nconst BYTE_UNITS = [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\"] as const;\n\n/**\n * A byte count as a short human string: exact bytes below 1 KiB (`1023 B`),\n * one decimal place per binary magnitude from KiB up (`1.5 KiB`, `15.6 GiB`).\n * `null` (nothing measured) is `—`.\n */\nexport function formatBytes(n: number | null): string {\n if (n === null || !Number.isFinite(n)) return UNKNOWN;\n if (n < 1024) return `${Math.round(n)} B`;\n\n let value = n;\n let unit = 0;\n while (value >= 1024 && unit < BYTE_UNITS.length - 1) {\n value /= 1024;\n unit += 1;\n }\n return `${value.toFixed(1)} ${BYTE_UNITS[unit]}`;\n}\n\n/**\n * A 0…1-ish fraction as a whole-percent string (`0.123` → `12%`). Not clamped:\n * a load above the CPU count is real and reads `135%`. `null` is `—`.\n */\nexport function formatPercent(f: number | null): string {\n if (f === null || !Number.isFinite(f)) return UNKNOWN;\n return `${Math.round(f * 100)}%`;\n}\n\n/**\n * `load1` against the effective CPU budget — the container's `cpuLimit` when\n * the server set one, otherwise the host CPU count. `null` when either operand\n * is unknown or the divisor is ≤ 0 (a zero-CPU budget is not \"0% busy\", it is\n * \"not measurable\").\n */\nexport function cpuLoadFraction(s: ServerResourceSample | undefined): number | null {\n if (s === undefined) return null;\n if (s.load1 === null) return null;\n const divisor = s.cpuLimit ?? s.cpus;\n if (divisor === null || divisor <= 0) return null;\n return s.load1 / divisor;\n}\n\n/**\n * Used memory as a fraction of total: `(memoryTotal − memoryAvailable) /\n * memoryTotal`. `null` when either operand is unknown or the total is ≤ 0.\n */\nexport function memoryUsedFraction(s: ServerResourceSample | undefined): number | null {\n if (s === undefined) return null;\n const { memoryTotal, memoryAvailable } = s;\n if (memoryTotal === null || memoryAvailable === null) return null;\n if (memoryTotal <= 0) return null;\n return (memoryTotal - memoryAvailable) / memoryTotal;\n}\n\n/** `v` pinned into `[lo, hi]`. */\nfunction clamp(v: number, lo: number, hi: number): number {\n if (v < lo) return lo;\n return v > hi ? hi : v;\n}\n\n/**\n * The `points` attribute of a sparkline polyline, hand-drawn — this package\n * has no chart dependency on purpose (D-5), and a polyline over ~60 samples\n * does not justify one.\n *\n * The x axis is positional (`i / (n − 1) · width`), so a gap in the series\n * still advances the line; `y` is inverted (SVG grows downward) and scaled\n * against `max`. Nulls are SKIPPED, not plotted as zero, and a series of fewer\n * than two values has no line at all (`\"\"` — a single point is not a shape).\n * `max ≤ 0` flattens the line along the baseline rather than dividing by it.\n *\n * Every coordinate is rounded to two decimals so the attribute stays short and\n * a snapshot of it stays readable.\n */\nexport function sparklinePoints(\n values: readonly (number | null)[],\n width: number,\n height: number,\n max: number,\n): string {\n const n = values.length;\n if (n < 2) return \"\";\n\n const points: string[] = [];\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (v === null) continue;\n const x = (i / (n - 1)) * width;\n const y = max <= 0 ? height : height - (clamp(v, 0, max) / max) * height;\n points.push(`${Number(x.toFixed(2))},${Number(y.toFixed(2))}`);\n }\n return points.join(\" \");\n}\n","/**\n * The server-resources display family — four PURE PRESENTATIONAL variants over\n * the same array of samples: a large card, a small card, a left-rail strip and\n * a header badge.\n *\n * There is no data layer here, on purpose (plan.md §Pinned decisions: \"no\n * transport in ui\"): every variant is handed `samples` and renders the LAST\n * one, plus a sparkline drawn from the whole array. Nothing in this file reads\n * a network, a context or a host API — the caller owns the stream and the\n * operator gate.\n *\n * The sparkline is hand-rolled inline SVG rather than a chart dependency: a\n * polyline over ~60 points is a dozen lines of arithmetic (see\n * `sparklinePoints`), and `@w6w/ui` carrying recharts or d3 for it would be\n * unjustified weight for every consumer (D-5).\n *\n * An unknown value is never rendered as `0` — it is the em dash `formatBytes` /\n * `formatPercent` return for `null`. An unreported CPU reading must not read as\n * an idle node. The same applies to `samples: []`: every variant still renders\n * (all dashes, no line), so a caller never has to branch before mounting.\n */\nimport {\n type ServerResourceSample,\n cpuLoadFraction,\n formatBytes,\n formatPercent,\n memoryUsedFraction,\n sparklinePoints,\n} from \"./server-resources-format.ts\";\n\nexport interface ServerResourcesProps {\n /**\n * The samples to render, oldest first. The LAST entry is the current reading;\n * the whole array is the sparkline's series. May be empty — then every value\n * reads `—` and no line is drawn.\n */\n samples: readonly ServerResourceSample[];\n}\n\nexport interface ServerResourcesCardProps extends ServerResourcesProps {\n /** Heading text. Defaults to `Server resources`. */\n title?: string;\n /** The sampler's cadence, in ms. When given, the card shows `Sampled every Ns`. */\n intervalMs?: number;\n}\n\nexport interface ServerResourcesRailProps extends ServerResourcesProps {\n /**\n * When given, the rail shows one button that asks the caller to open the full\n * view. The rail never opens anything itself — mounting is the caller's job.\n */\n onExpand?: () => void;\n}\n\n/** What an unknown value renders as — the same dash the format helpers return. */\nconst UNKNOWN = \"—\";\n\n/** Sparkline geometry. The viewBox is 100 × 24 units, scaled by CSS. */\nconst SPARK_WIDTH = 100;\nconst SPARK_HEIGHT = 24;\n\n/** The sparkline. Deliberately NOT the shared `Icon` (`../components/Icon.tsx`):\n * nothing here is a fixed glyph — `points` is computed from the data, the\n * viewBox is this chart's own 100 × 24 units (scaled by CSS) rather than a\n * 24 × 24 icon box, and the stroke is the accent token, not `currentColor`. */\nfunction Sparkline({\n values,\n max,\n className,\n}: {\n values: readonly (number | null)[];\n max: number;\n className: string;\n}) {\n const points = sparklinePoints(values, SPARK_WIDTH, SPARK_HEIGHT, max);\n if (points === \"\") return null;\n\n return (\n <svg\n className={className}\n viewBox={`0 0 ${SPARK_WIDTH} ${SPARK_HEIGHT}`}\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <polyline\n points={points}\n fill=\"none\"\n stroke=\"var(--w6w-accent)\"\n strokeWidth={2}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n );\n}\n\n/**\n * A fraction as a two-decimal string (`0.5` → `0.50`), or `—` when unknown.\n * The fixed precision is what keeps the three load averages visually aligned.\n */\nfunction formatLoad(n: number | null): string {\n return n === null ? UNKNOWN : n.toFixed(2);\n}\n\n/**\n * The largest value a series of fractions is drawn against — at least 1, so a\n * quiet host draws a flat-ish line near the baseline instead of amplifying\n * its own noise to a full-height sawtooth.\n */\nfunction fractionMax(values: readonly (number | null)[]): number {\n let max = 1;\n for (const v of values) if (v !== null && v > max) max = v;\n return max;\n}\n\n/** A labelled reading plus the sparkline of its series. */\nfunction MetricRow({\n label,\n value,\n values,\n max,\n}: {\n label: string;\n value: string;\n values: readonly (number | null)[];\n max: number;\n}) {\n return (\n <li className=\"w6w-server-resources__row\">\n <span className=\"w6w-server-resources__label\">{label}</span>\n <span className=\"w6w-server-resources__value\">{value}</span>\n <Sparkline className=\"w6w-server-resources__spark\" values={values} max={max} />\n </li>\n );\n}\n\n/** The one-sample readings every variant shows, computed once per render. */\nfunction readings(samples: readonly ServerResourceSample[]) {\n const last = samples[samples.length - 1];\n const cpuValues = samples.map((s) => cpuLoadFraction(s));\n const memoryValues = samples.map((s) => memoryUsedFraction(s));\n const rssValues = samples.map((s) => s.processRss);\n return { last, cpuValues, memoryValues, rssValues };\n}\n\n/**\n * The large variant: three readings (CPU, memory, process RSS), each with its\n * own sparkline, plus the load averages and — when the caller knows it — the\n * sampling cadence. This is the Console/Modal body.\n */\nexport function ServerResourcesCard({\n samples,\n title = \"Server resources\",\n intervalMs,\n}: ServerResourcesCardProps) {\n const { last, cpuValues, memoryValues, rssValues } = readings(samples);\n\n return (\n <section className=\"w6w-server-resources w6w-server-resources--card\" aria-label={title}>\n <h3 className=\"w6w-server-resources__title\">{title}</h3>\n <ul className=\"w6w-server-resources__rows\">\n <MetricRow\n label=\"CPU\"\n value={formatPercent(cpuLoadFraction(last))}\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n <MetricRow\n label=\"Memory\"\n value={formatPercent(memoryUsedFraction(last))}\n values={memoryValues}\n max={1}\n />\n <MetricRow\n label=\"Process\"\n value={formatBytes(last?.processRss ?? null)}\n values={rssValues}\n max={fractionMax(rssValues)}\n />\n </ul>\n <p className=\"w6w-server-resources__meta\">\n {`Load ${formatLoad(last?.load1 ?? null)} / ${formatLoad(last?.load5 ?? null)} / ${formatLoad(\n last?.load15 ?? null,\n )}`}\n </p>\n {intervalMs !== undefined && (\n <p className=\"w6w-server-resources__meta\">{`Sampled every ${intervalMs / 1000}s`}</p>\n )}\n </section>\n );\n}\n\n/**\n * The small variant: CPU and memory only, one sparkline (CPU). For a compact\n * surface that has room for a headline and a shape, but not for a third\n * reading or the load breakdown.\n */\nexport function ServerResourcesCardSmall({ samples, title = \"Server\" }: ServerResourcesCardProps) {\n const { last, cpuValues } = readings(samples);\n\n return (\n <section className=\"w6w-server-resources w6w-server-resources--small\" aria-label={title}>\n <h3 className=\"w6w-server-resources__title\">{title}</h3>\n <ul className=\"w6w-server-resources__rows\">\n <MetricRow\n label=\"CPU\"\n value={formatPercent(cpuLoadFraction(last))}\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n <li className=\"w6w-server-resources__row\">\n <span className=\"w6w-server-resources__label\">Memory</span>\n <span className=\"w6w-server-resources__value\">\n {formatPercent(memoryUsedFraction(last))}\n </span>\n </li>\n </ul>\n </section>\n );\n}\n\n/**\n * The left-rail variant: a stacked CPU and MEM reading, each with a sparkline,\n * sized to fit a ~200 px column. When the caller passes `onExpand` it also\n * shows the single \"show me the rest\" button; without one it is read-only\n * decoration and renders no interactive element at all.\n */\nexport function ServerResourcesRail({ samples, onExpand }: ServerResourcesRailProps) {\n const { last, cpuValues, memoryValues } = readings(samples);\n\n return (\n <aside className=\"w6w-server-resources w6w-server-resources--rail\">\n <div className=\"w6w-server-resources__rail-row\">\n <span className=\"w6w-server-resources__label\">CPU</span>\n <span className=\"w6w-server-resources__value\">{formatPercent(cpuLoadFraction(last))}</span>\n <Sparkline\n className=\"w6w-server-resources__spark\"\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n </div>\n <div className=\"w6w-server-resources__rail-row\">\n <span className=\"w6w-server-resources__label\">MEM</span>\n <span className=\"w6w-server-resources__value\">\n {formatPercent(memoryUsedFraction(last))}\n </span>\n <Sparkline className=\"w6w-server-resources__spark\" values={memoryValues} max={1} />\n </div>\n {onExpand !== undefined && (\n <button\n type=\"button\"\n className=\"w6w-server-resources__expand\"\n aria-label=\"Show server resources\"\n onClick={onExpand}\n >\n Details\n </button>\n )}\n </aside>\n );\n}\n\n/**\n * The header badge: one line, `CPU <pct> · MEM <pct>`, no sparkline (a badge is\n * a fixed-height strip of text, and a line there would be unreadable). The\n * whole string is a single text node so assistive tech reads it as one phrase.\n */\nexport function ServerResourcesBadge({ samples }: ServerResourcesProps) {\n const last = samples[samples.length - 1];\n const cpu = formatPercent(cpuLoadFraction(last));\n const mem = formatPercent(memoryUsedFraction(last));\n\n return (\n <span className=\"w6w-server-resources w6w-server-resources--badge\">\n {`CPU ${cpu} · MEM ${mem}`}\n </span>\n );\n}\n","/**\n * Pure geometry for `HistoryTimeline`'s vendor lane — positioning a vendor\n * incident bar on the SAME percentage scale the execution lane's day cells\n * use, so the two series can never drift apart (`HistoryTimeline.tsx`'s\n * alignment invariant). Deliberately split out of the component: a function\n * that reads a clock itself makes that invariant unobservable to a gate, so\n * `nowMs` is always a parameter here, never `Date.now()`.\n *\n * No JSX, no React import — this file is imported directly by its own test\n * (`__tests__/HistoryTimeline.test.ts`) with no transpile step.\n */\nimport type { HistoryWindow, VendorIncidentBar } from \"./HistoryTimeline.tsx\";\n\n/**\n * Minimum visible width for a bar, as a percentage of the window's span. A\n * point-in-time entry (no `startedAt`) has zero duration and would otherwise\n * be invisible; a very short span is floored to the same width so it never\n * shrinks below it either.\n */\nexport const MIN_BAR_WIDTH_PCT = 1;\n\nexport interface BarPlacement {\n /** Left edge, as a percentage of the window's span, clamped to `[0, 100]`. */\n leftPct: number;\n /** Width, as a percentage of the window's span. Never below `MIN_BAR_WIDTH_PCT`. */\n widthPct: number;\n /** `true` if the bar's start was clamped to the window's left edge. */\n clippedStart: boolean;\n /** `true` if the bar's end was clamped to the window's right edge. */\n clippedEnd: boolean;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Places one vendor incident bar on the window's `[from T00:00:00Z, to+1 day\n * T00:00:00Z)` span.\n *\n * - A bar's start is `startedAt ?? updatedAt`; with neither present there is\n * nothing to place, so this returns `null` (B5).\n * - Its end is `resolvedAt ?? (startedAt !== undefined ? nowMs : start)` — an\n * open incident (has `startedAt`, no `resolvedAt`) therefore runs to\n * `nowMs`, and a feed-only entry with no `startedAt` is a point in time,\n * not a span (B3).\n * - A bar wholly outside the window (ends before it starts, or starts at or\n * after it ends) returns `null` (B4). One overlapping an edge is clamped\n * into the window, with `clippedStart`/`clippedEnd` set accordingly.\n */\nexport function placeIncidentBar(\n window: HistoryWindow,\n bar: VendorIncidentBar,\n nowMs: number,\n): BarPlacement | null {\n const start = bar.startedAt ?? bar.updatedAt;\n if (start === undefined) return null;\n\n const startMs = Date.parse(start);\n const endMs =\n bar.resolvedAt !== undefined\n ? Date.parse(bar.resolvedAt)\n : bar.startedAt !== undefined\n ? nowMs\n : startMs;\n\n const windowStartMs = Date.parse(`${window.from}T00:00:00.000Z`);\n const windowEndMs = Date.parse(`${window.to}T00:00:00.000Z`) + DAY_MS;\n const spanMs = windowEndMs - windowStartMs;\n\n if (endMs < windowStartMs || startMs >= windowEndMs) return null;\n\n const clippedStart = startMs < windowStartMs;\n const clippedEnd = endMs > windowEndMs;\n\n // The clamp to [0, 100] (B2) happens HERE, on the raw timestamps, and is\n // the ONLY place either bound is clamped — `leftPct`/`widthPct` below are\n // plain arithmetic on the clamped values, so there is no second, redundant\n // clamp for a mutation to skip past undetected.\n const clampedStartMs = Math.max(startMs, windowStartMs);\n const clampedEndMs = Math.min(endMs, windowEndMs);\n\n const leftPct = ((clampedStartMs - windowStartMs) / spanMs) * 100;\n const rawWidthPct = ((clampedEndMs - clampedStartMs) / spanMs) * 100;\n const widthPct = Math.max(rawWidthPct, MIN_BAR_WIDTH_PCT);\n\n return { leftPct, widthPct, clippedStart, clippedEnd };\n}\n","import type { UptimeCellState, UptimeDay } from \"./UptimeStrip.tsx\";\nimport { placeIncidentBar } from \"./history-scale.ts\";\n\n/** The calendar window both lanes are plotted against. Both bounds inclusive. */\nexport interface HistoryWindow {\n /** Inclusive first calendar day, `YYYY-MM-DD`. */\n from: string;\n /** Inclusive last calendar day, `YYYY-MM-DD`. */\n to: string;\n}\n\n/** One entry in the vendor's incident feed. */\nexport interface VendorIncidentBar {\n id?: string;\n title: string;\n state: UptimeCellState;\n /** ISO instant. Absent = a point-in-time update, not a span. */\n startedAt?: string;\n updatedAt?: string;\n /** ISO instant. Absent WITH `startedAt` present = still open. */\n resolvedAt?: string;\n components?: string[];\n link?: string;\n}\n\nexport interface HistoryTimelineProps {\n window: HistoryWindow;\n /** Execution lane, oldest first, one entry per calendar day. */\n days: UptimeDay[];\n /** Vendor lane. `undefined` = this vendor publishes no incident history at all. */\n incidents?: VendorIncidentBar[];\n /** Overrides the vendor lane's empty text. */\n vendorEmptyLabel?: string;\n /** Clock injection for tests and for an open incident's right edge. Defaults to `Date.now()`. */\n nowMs?: number;\n ariaLabel?: string;\n}\n\nconst STATE_LABELS: Record<UptimeCellState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\nconst NO_FEED_LABEL = \"This vendor publishes no incident history.\";\nconst QUIET_LABEL = \"No incidents in this window.\";\n\nfunction barTitle(bar: VendorIncidentBar): string {\n const start = bar.startedAt ?? bar.updatedAt;\n const parts = [bar.title];\n if (bar.components !== undefined && bar.components.length > 0) {\n parts.push(`(${bar.components.join(\", \")})`);\n }\n if (start !== undefined) {\n parts.push(\n bar.resolvedAt !== undefined ? `${start} – ${bar.resolvedAt}` : `${start} – ongoing`,\n );\n }\n return parts.join(\" \");\n}\n\n/**\n * Two time series — our per-day execution history and the vendor's incident\n * history — plotted on one shared x-axis, so \"our calls failed *during* that\n * vendor incident\" is a visible alignment rather than a claim.\n *\n * Purely presentational, same discipline as `UptimeStrip`: `days` is already\n * one already-decided state per calendar day (no sort, no reverse, no gap\n * fill), and `incidents` is already the vendor's own feed. This component\n * places them; it makes no judgement about what counts as an incident.\n *\n * `incidents === undefined` (\"this vendor publishes no incident history\") and\n * `incidents === []` (\"nothing happened in this window\") are different facts\n * and render different empty-row text — Stripe is the first, a quiet Slack\n * window is the second. Either way the axis and the execution lane render in\n * full, at full width: a vendor with no feed never shrinks the half of the\n * chart that does have data.\n *\n * Severity is encoded twice, same rule as `UptimeStrip` and `HealthStatusPill`:\n * a per-state class AND a geometry difference (fill height on a day cell,\n * clip markers on a bar), never colour alone. Every cell and every bar\n * carries a `title`.\n */\nexport function HistoryTimeline({\n window: win,\n days,\n incidents,\n vendorEmptyLabel,\n nowMs = Date.now(),\n ariaLabel,\n}: HistoryTimelineProps) {\n const n = days.length;\n const cellWidthPct = n > 0 ? 100 / n : 0;\n\n const emptyLabel =\n incidents === undefined\n ? (vendorEmptyLabel ?? NO_FEED_LABEL)\n : incidents.length === 0\n ? (vendorEmptyLabel ?? QUIET_LABEL)\n : null;\n\n return (\n <div className=\"w6w-history-timeline\" role=\"img\" aria-label={ariaLabel ?? `${n}-day history`}>\n <div className=\"w6w-history-plot\">\n <div className=\"w6w-history-lane w6w-history-lane-execution\">\n {days.map((entry, i) => (\n <span\n // Days are expected to be unique, but the index keeps the key\n // stable even if a caller repeats one — same guard `UptimeStrip` uses.\n key={`${entry.day}-${i}`}\n className={`w6w-history-cell w6w-history-cell-${entry.state}`}\n style={{ left: `${i * cellWidthPct}%`, width: `${cellWidthPct}%` }}\n title={entry.label ?? `${entry.day} — ${STATE_LABELS[entry.state]}`}\n />\n ))}\n </div>\n <div className=\"w6w-history-lane w6w-history-lane-vendor\">\n {emptyLabel !== null ? (\n <span className=\"w6w-history-empty\" title={emptyLabel}>\n {emptyLabel}\n </span>\n ) : (\n incidents?.map((bar, i) => {\n const placement = placeIncidentBar(win, bar, nowMs);\n if (placement === null) return null;\n const clipClass = [\n placement.clippedStart ? \"w6w-history-bar-clip-start\" : \"\",\n placement.clippedEnd ? \"w6w-history-bar-clip-end\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n return (\n <span\n key={bar.id ?? `${bar.title}-${i}`}\n className={`w6w-history-bar w6w-history-bar-${bar.state}${clipClass ? ` ${clipClass}` : \"\"}`}\n style={{ left: `${placement.leftPct}%`, width: `${placement.widthPct}%` }}\n title={barTitle(bar)}\n />\n );\n })\n )}\n </div>\n <div className=\"w6w-history-axis\">\n <span className=\"w6w-history-tick w6w-history-tick-start\" style={{ left: \"0%\" }}>\n {win.from}\n </span>\n <span className=\"w6w-history-tick w6w-history-tick-end\" style={{ left: \"100%\" }}>\n {win.to}\n </span>\n </div>\n </div>\n </div>\n );\n}\n","import { type ReactNode, useId, useState } from \"react\";\nimport { IconButton } from \"./IconButton.tsx\";\n\nexport interface InfoTipProps {\n /** Accessible name AND tooltip of the toggle button (e.g. \"About client secrets\"). */\n label: string;\n /** The explanation, rendered only while expanded. */\n children: ReactNode;\n className?: string;\n}\n\n/**\n * A small \"i\" button that reveals a muted explanation block on click — for\n * copy that would otherwise clutter a modal. Collapsed by default; the button\n * carries `aria-expanded` and `aria-controls` pointing at the block, and the\n * block is not rendered at all while collapsed.\n */\nexport function InfoTip({ label, children, className }: InfoTipProps) {\n const [open, setOpen] = useState(false);\n const id = useId();\n return (\n <span className={[\"w6w-info-tip\", className ?? \"\"].filter(Boolean).join(\" \")}>\n <IconButton\n label={label}\n icon=\"info\"\n aria-expanded={open}\n aria-controls={id}\n onClick={() => setOpen((o) => !o)}\n />\n {open && (\n <span id={id} className=\"w6w-info-tip-body w6w-muted w6w-small\">\n {children}\n </span>\n )}\n </span>\n );\n}\n","import { IconButton } from \"./IconButton.tsx\";\n\nexport interface EditButtonProps {\n label: string;\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/** An `IconButton` bundling the canonical pencil glyph — `icons.tsx`'s `edit`,\n * the two-path Feather pencil — with no `danger` styling. */\nexport function EditButton(props: EditButtonProps) {\n const { label, onClick, disabled, className, ...rest } = props;\n return (\n <IconButton\n label={label}\n onClick={onClick}\n disabled={disabled}\n className={className}\n icon=\"edit\"\n data-testid={rest[\"data-testid\"]}\n />\n );\n}\n","import { IconButton } from \"./IconButton.tsx\";\n\nexport interface DeleteButtonProps {\n label: string;\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * An `IconButton` bundling the canonical trash glyph — `icons.tsx`'s `delete`,\n * the fuller 4-shape Feather `trash-2` — always `danger`-styled.\n *\n * Presentational only (HITL-1, binding): takes a plain `onClick`, never an\n * `onConfirm`, and never imports any confirm-dialog component — the call\n * site owns whether and which one gates the click.\n */\nexport function DeleteButton(props: DeleteButtonProps) {\n const { label, onClick, disabled, className, ...rest } = props;\n return (\n <IconButton\n label={label}\n onClick={onClick}\n disabled={disabled}\n className={className}\n danger\n icon=\"delete\"\n data-testid={rest[\"data-testid\"]}\n />\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { Icon } from \"./Icon.tsx\";\n\nexport interface RepoSyncIndicatorProps {\n /** Branch name, e.g. \"main\". */\n branch: string;\n /** Already-shortened commit sha (the consumer formats it — D-6). `null` renders no sha. */\n shortSha: string | null;\n /** Already-formatted last-sync text, e.g. \"3/9/2026, 12:16:29 PM\" or \"Never synced\".\n * `null` renders no time row. */\n lastSyncLabel: string | null;\n /** Fired when the flyout's \"Sync now\" item is activated. The consumer owns the mutation. */\n onSyncNow: () => void;\n /** True while the consumer's sync is in flight. */\n syncing?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * A compact header control showing a repo glyph, a branch name and a short\n * commit sha, with an inline flyout menu carrying the sync detail and a\n * \"Sync now\" action the consumer wires.\n *\n * `@w6w/ui` never fetches and holds no studio policy\n * (`studio/src/ui/ExpressionScope.tsx:40-41`, extended by D-6) — this\n * component takes already-formatted strings and a callback.\n *\n * The open/close + outside-click + Escape state machine mirrors\n * `studio/src/components/Layout.tsx:222-328`'s `ProjectMenu()` (D-3: no\n * shared Menu/Popover/Dropdown primitive — there is exactly one consumer).\n */\nexport function RepoSyncIndicator(props: RepoSyncIndicatorProps) {\n const { branch, shortSha, lastSyncLabel, onSyncNow, syncing, className, ...rest } = props;\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n return (\n <div\n className={`w6w-repo-sync${className ? ` ${className}` : \"\"}`}\n ref={ref}\n data-testid={rest[\"data-testid\"]}\n >\n <button\n type=\"button\"\n className=\"w6w-repo-sync-trigger\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-busy={syncing}\n onClick={() => setOpen((v) => !v)}\n >\n <span className=\"w6w-repo-sync-icon\">\n {/* The connection provider's mark — `icons.tsx`'s `github` (`RepoBinding.provider`\n is always `\"github\"` today), 16px, the set's default. */}\n <Icon name=\"github\" />\n {/* The in-flight badge over the mark while `syncing`: `icons.tsx`'s `sync`\n (Feather `refresh-cw`), shrunk to 10×10 for this corner use and spun by\n `.w6w-repo-sync-spin`, which `Icon` merges with `w6w-icon`. */}\n {syncing && <Icon name=\"sync\" size={10} className=\"w6w-repo-sync-spin\" />}\n </span>\n <span className=\"w6w-repo-sync-branch\">{branch}</span>\n {shortSha != null && <code className=\"w6w-repo-sync-sha\">{shortSha}</code>}\n </button>\n {open && (\n <div className=\"w6w-repo-sync-menu\" role=\"menu\">\n <div className=\"w6w-repo-sync-detail\">\n <span>{branch}</span>\n {shortSha != null && <code>{shortSha}</code>}\n {lastSyncLabel != null && <span>{lastSyncLabel}</span>}\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"w6w-repo-sync-item\"\n data-testid=\"repo-sync-now\"\n disabled={syncing}\n onClick={onSyncNow}\n >\n {syncing ? \"Syncing…\" : \"Sync now\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * The five states a workflow step's execution can be in — a thin LOCAL copy\n * of the workflow spec's `StepStatus` union\n * (`packages/w6w-workflow/packages/types/mod.ts`). `@w6w/ui` deliberately\n * keeps a small literal type here rather than depend on `@w6w/workflow-types`,\n * so this stays a pure-presentation leaf with no transport/spec coupling —\n * the same precedent `HealthStatusPill`'s `HealthPillState` establishes.\n */\nexport type StepStatus = \"pending\" | \"running\" | \"succeeded\" | \"failed\" | \"skipped\";\n\n/**\n * The five states a whole EXECUTION (an invocation, an endpoint call, a\n * workflow run) can be in — the run-level sibling of `StepStatus`, and again a\n * thin LOCAL literal rather than an import of any spec/wire type. The two\n * unions differ exactly where runs and steps differ: a run can be `queued`\n * before it starts and `canceled` after it started, while a step inside a run\n * can be `pending` or `skipped` (a run is never either). They are deliberately\n * NOT merged into one five/six-member union — `ExecutionList` and the step\n * panel must each accept only their own vocabulary.\n */\nexport type ExecutionStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"canceled\";\n\nexport interface StepStatusPillProps {\n /**\n * Which state to render — drives the colour + default label. Accepts both\n * vocabularies: a workflow step's `StepStatus` and a whole run's\n * `ExecutionStatus` (the pill is only a coloured label, so it does not care\n * which of the two a host is describing).\n */\n state: StepStatus | ExecutionStatus;\n /** Override the visible text (defaults to a humanised form of `state`). */\n label?: ReactNode;\n /** Accessible label for the pill (falls back to the visible text). */\n ariaLabel?: string;\n}\n\nconst DEFAULT_LABELS: Record<StepStatus | ExecutionStatus, string> = {\n pending: \"Pending\",\n running: \"Running\",\n succeeded: \"Succeeded\",\n failed: \"Failed\",\n skipped: \"Skipped\",\n queued: \"Queued\",\n canceled: \"Canceled\",\n};\n\n/**\n * A small, theme-aware status pill for one workflow step's execution state.\n *\n * Mirrors `HealthStatusPill` shape for shape: a state union, a\n * `DEFAULT_LABELS` record, a coloured dot + text label using one\n * `--w6w-step-color` custom property per modifier class, and the\n * `w6w-step-pill w6w-step-pill-${state}` className convention. Colour is\n * never the only signal — the text label carries the same meaning for\n * accessibility. Five states rather than `HealthStatusPill`'s four, so this\n * is a mirror of that shape, not a shared implementation.\n *\n * Renders BOTH vocabularies through the one prop: `StepStatus` (a step inside\n * a run) and `ExecutionStatus` (a whole run). The union is widened at the\n * PROP only — `StepStatus` itself is unchanged, so the step panel's own type\n * cannot silently grow run-only states.\n */\nexport function StepStatusPill({ state, label, ariaLabel }: StepStatusPillProps) {\n const text = label ?? DEFAULT_LABELS[state];\n\n return (\n <span className={`w6w-step-pill w6w-step-pill-${state}`} aria-label={ariaLabel}>\n <span className=\"w6w-step-pill-dot\" aria-hidden=\"true\" />\n <span className=\"w6w-step-pill-label\">{text}</span>\n </span>\n );\n}\n","/**\n * Pure duration/time formatters for the execution-history family, kept in\n * their own module so they carry no React and can be unit-tested on their own\n * — the same split `server-resources-format.ts` establishes.\n *\n * Both are TOTAL: a duration that was never measured (a still-running or\n * queued run) is rendered as an em dash, never as `0 ms` — \"unknown\" must not\n * read as \"instant\".\n */\n\n/** What an unmeasured/unknown value renders as. Never `0`. */\nconst UNKNOWN = \"—\";\n\nconst MS_PER_SECOND = 1000;\nconst MS_PER_MINUTE = 60_000;\n\n/**\n * A run duration as a short human string: whole milliseconds below a second\n * (`999 ms`), one decimal place in seconds below a minute (`1.5 s`), and\n * `2m 5s` from a minute up. `null`/`undefined` (nothing measured), `NaN` and\n * negatives are all `—`.\n */\nexport function formatDurationMs(ms: number | null | undefined): string {\n if (ms == null || !Number.isFinite(ms) || ms < 0) return UNKNOWN;\n if (ms < MS_PER_SECOND) return `${Math.round(ms)} ms`;\n if (ms < MS_PER_MINUTE) return `${(ms / MS_PER_SECOND).toFixed(1)} s`;\n return `${Math.floor(ms / MS_PER_MINUTE)}m ${Math.round((ms % MS_PER_MINUTE) / MS_PER_SECOND)}s`;\n}\n\n/**\n * An ISO-8601 instant as a short, locale-formatted date+time (`Sep 22, 2026,\n * 10:00 AM` under the default locale). The locale is the HOST's\n * (`undefined`), so the string follows the viewer's own settings rather than\n * baking one in. A string `Date` cannot parse is returned UNCHANGED — an\n * unrenderable timestamp is shown as the wire value, never as \"Invalid Date\".\n */\nexport function formatExecutionTime(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return date.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n","import type { ReactNode } from \"react\";\nimport { ListItem } from \"./ListItem.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport { formatDurationMs, formatExecutionTime } from \"./execution-format.ts\";\n\n/** What kind of callable a run belongs to. A thin LOCAL literal — the same\n * deliberate duplication `StepStatusPill`'s unions keep. */\nexport type ExecutionKind = \"function\" | \"endpoint\" | \"workflow\";\n\n/** One past execution's display row — an already-mapped slice of the host's\n * history payload. The HOST maps its own record into this shape (the same\n * \"host owns the data, the list is presentational\" split `ExecutionLogPanel`\n * establishes): this component never fetches, paginates or reaches for an SDK. */\nexport interface ExecutionListItem {\n /** Stable id for this row — what `onSelect` reports and `selectedId` matches. */\n id: string;\n kind: ExecutionKind;\n /** The callable's name/key this run belongs to. */\n callableName: string;\n status: ExecutionStatus;\n /** ISO-8601 instant the run started. */\n startedAt: string;\n /** Wall-clock duration once the run has finished; `null` while it is still\n * queued/running (rendered as `—`). */\n durationMs: number | null;\n}\n\nexport interface ExecutionListProps {\n /** The page of past executions, rendered in exactly this order — never re-sorted. */\n items: ExecutionListItem[];\n /** The row to highlight as current. `null`/omitted ⇒ no row is active. */\n selectedId?: string | null;\n /** Supplied ⇒ rows are clickable and report their id here. Omitted ⇒ every\n * row is a plain, non-interactive row. */\n onSelect?: (id: string) => void;\n /**\n * `true` ⇒ each row's title is the callable's name and its subtitle carries\n * the kind + start time (the project-wide history view). `false` ⇒ the title\n * is the start time and the subtitle is the run id (the per-callable view,\n * where the callable is already known). Defaults to `false`.\n */\n showCallable?: boolean;\n /** `true` ⇒ the loading branch while there is nothing to show yet. */\n loading?: boolean;\n /** Shown instead of the list when `items` is empty. */\n emptyLabel?: ReactNode;\n /** Whether a previous page exists — drives the pager's `Previous` state. */\n hasPrev?: boolean;\n /** Whether a next page exists — drives the pager's `Next` state. */\n hasNext?: boolean;\n /** Supplied ⇒ the pager renders and `Previous` calls this. */\n onPrev?: () => void;\n /** Supplied ⇒ the pager renders and `Next` calls this. */\n onNext?: () => void;\n}\n\n/** Row subtitle's kind prefix, in the `showCallable` view. */\nconst KIND_LABEL: Record<ExecutionKind, string> = {\n function: \"Function\",\n endpoint: \"Endpoint\",\n workflow: \"Workflow\",\n};\n\n/**\n * A paged list of past executions: one row per run, click-to-select, with a\n * prev/next pager.\n *\n * A pure display leaf — no fetching, no polling, no sorting, no local\n * selection state. It renders `items` in the order given, reports a click, and\n * reports a page request; the host owns which page is loaded and which row is\n * selected.\n */\nexport function ExecutionList({\n items,\n selectedId = null,\n onSelect,\n showCallable = false,\n loading = false,\n emptyLabel,\n hasPrev,\n hasNext,\n onPrev,\n onNext,\n}: ExecutionListProps) {\n // Rendered in EVERY branch below, deliberately: a host that reports it can\n // go back to a previous page must still offer that control from an empty\n // page (the state reached by paging past the last run) and while a page is\n // loading.\n const pager =\n onPrev || onNext ? (\n <div className=\"w6w-execution-list-pager\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-list-prev\"\n disabled={!hasPrev}\n onClick={onPrev}\n >\n Previous\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-list-next\"\n disabled={!hasNext}\n onClick={onNext}\n >\n Next\n </button>\n </div>\n ) : null;\n\n let body: ReactNode;\n if (loading && items.length === 0) {\n body = <p data-testid=\"execution-list-loading\">Loading…</p>;\n } else if (items.length === 0) {\n body = <p data-testid=\"execution-list-empty\">{emptyLabel ?? \"No executions yet.\"}</p>;\n } else {\n body = (\n <ul className=\"w6w-execution-list-rows\">\n {items.map((item) => (\n <li key={item.id} data-testid=\"execution-row\" data-execution-id={item.id}>\n <ListItem\n icon={<StepStatusPill state={item.status} />}\n title={showCallable ? item.callableName : formatExecutionTime(item.startedAt)}\n subtitle={\n showCallable\n ? `${KIND_LABEL[item.kind]} · ${formatExecutionTime(item.startedAt)}`\n : item.id\n }\n trailing={formatDurationMs(item.durationMs)}\n active={item.id === selectedId}\n onClick={onSelect ? () => onSelect(item.id) : undefined}\n />\n </li>\n ))}\n </ul>\n );\n }\n\n return (\n <div className=\"w6w-execution-list\" data-testid=\"execution-list\">\n {body}\n {pager}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { CodeBlock } from \"../CodeBlock.tsx\";\nimport type { StepMeta } from \"../provider.tsx\";\nimport { IconButton } from \"./IconButton.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport type { StepStatus } from \"./StepStatusPill.tsx\";\n\n/**\n * A step's or run's failure, already normalised by the HOST from the workflow\n * spec's `StepError` (`code`/`message`/`phase`/`retryable`). The panel never\n * parses an `unknown` error itself — same \"host owns the data\" split as the\n * rest of this file. Rendered in `TriggerFillForm`'s error visual: a\n * `.w6w-result.w6w-error` box, an optional `<code>` badge line, then the message.\n */\nexport interface ExecutionLogError {\n /** `StepError.code`. Optional: the host may normalise an error that carries no code. */\n code?: string;\n /** The human-readable reason. Never empty when the host supplies it. */\n message: string;\n /** `StepError.phase`, when known. Carried for the host; not rendered. */\n phase?: string;\n /** `StepError.retryable`, when known. Carried for the host; not rendered. */\n retryable?: boolean;\n}\n\n/**\n * One entry of `RunState.stepErrors` — a step failure the run recorded and\n * moved past (`onError: \"continue-record\"`, or a failure an error edge\n * handled), so the run itself may still have succeeded.\n */\nexport interface ExecutionLogRecordedError {\n /** The step the error belongs to. */\n stepId: string;\n /** Human-readable step name. Falls back to `stepId` when rendered. */\n label?: string;\n error: ExecutionLogError;\n}\n\n/**\n * One step's display row — an already-mapped, already-resolved slice of a\n * `RunState`/`StepExecution` (workflow spec). The HOST maps its own run\n * state into this shape (same \"host owns the data, the panel is\n * presentational\" split `readOnly` already establishes elsewhere in this\n * package) — this component never fetches, polls, or reaches for an SDK.\n */\nexport interface ExecutionLogStep {\n /** Stable id for this row — typically the step id from the workflow definition. */\n id: string;\n /** Human-readable step name. Falls back to `id` when omitted. */\n label?: string;\n status: StepStatus;\n /** ISO-8601 timestamp the step started, once it has. */\n startedAt?: string;\n /** ISO-8601 timestamp the step finished, once it has. */\n finishedAt?: string;\n /** The resolved input sent to the step's action, once it is known. */\n input?: unknown;\n /** The step's output, once it has one. */\n output?: unknown;\n /**\n * What ran (`StepExecution.meta`): app, version, action and connection id. Shown as a\n * Metadata block after Output. Absent or `null` ⇒ no block at all (R-12: no filler).\n */\n meta?: StepMeta | null;\n /**\n * Why the step failed (`StepExecution.error`, \"present on failed\"). Rendered\n * below the row's box and outside its lazy `<details>` body, so the reason\n * reads without expanding the row.\n */\n error?: ExecutionLogError;\n}\n\nexport interface ExecutionLogPanelProps {\n /** The run's steps, rendered in exactly this order — never re-sorted. */\n steps: ExecutionLogStep[];\n /** Shown instead of the list when `steps` is empty. */\n emptyLabel?: ReactNode;\n /**\n * Supplied ⇒ the panel grows a header row carrying a dismiss control that\n * calls this and nothing else (T1.1.1). Omitted ⇒ no header row at all, no\n * extra DOM node. The panel still owns no run state — it only reports the\n * click; the host decides what dismissing means.\n */\n onDismiss?: () => void;\n /**\n * The run's own failure (`RunState.error`). Rendered below the dismiss head\n * and above the steps — in the empty branch too, since a run that failed\n * before any step ran has nothing else to say why.\n */\n runError?: ExecutionLogError;\n /**\n * Step failures the run recorded and moved past (`RunState.stepErrors`),\n * one error block each, in the order given, after `runError`.\n */\n stepErrors?: ExecutionLogRecordedError[];\n}\n\n/**\n * Read-only log of a workflow run's steps, in the order given: each row is\n * the step's status pill, its timing, and its resolved input/output.\n *\n * A pure display leaf — no data fetching, no polling, no layout media\n * queries (the host docks the panel; see `_scale.scss`'s breakpoint\n * docstring). Fills whatever box its host gives it.\n */\nexport function ExecutionLogPanel({\n steps,\n emptyLabel,\n onDismiss,\n runError,\n stepErrors,\n}: ExecutionLogPanelProps) {\n // Rendered by BOTH branches below, deliberately: the reported repro (T-1) is\n // a canvas whose log panel shows \"No steps have run yet.\" — a header mounted\n // only above the `<ol>` would be invisible in exactly that state, and that is\n // the state the dismiss control exists to get the user out of.\n const head = onDismiss ? (\n <div className=\"w6w-execution-log-head\">\n <IconButton label=\"Dismiss run log\" data-testid=\"execution-log-dismiss\" onClick={onDismiss}>\n ×\n </IconButton>\n </div>\n ) : null;\n\n // Same both-branches rule as `head`: a run that failed before its first step\n // is exactly the empty branch. Nothing to report ⇒ no wrapper node at all.\n const recorded = stepErrors ?? [];\n const errors =\n runError || recorded.length > 0 ? (\n <div className=\"w6w-execution-log-errors w6w-stack\">\n {runError && <ExecutionLogErrorBlock error={runError} />}\n {recorded.map((entry, index) => (\n <ExecutionLogErrorBlock\n // `stepId` alone may repeat (a step retried into the record twice).\n key={`${entry.stepId}:${index}`}\n label={entry.label ?? entry.stepId}\n error={entry.error}\n />\n ))}\n </div>\n ) : null;\n\n if (steps.length === 0) {\n return (\n <>\n {head}\n {errors}\n <div className=\"w6w-execution-log-empty\">\n <p className=\"w6w-muted w6w-small\">{emptyLabel ?? \"No steps have run yet.\"}</p>\n </div>\n </>\n );\n }\n\n return (\n <>\n {head}\n {errors}\n <ol className=\"w6w-execution-log\">\n {steps.map((step) => (\n <ExecutionLogRow key={step.id} step={step} />\n ))}\n </ol>\n </>\n );\n}\n\n/**\n * Collapsed-by-default disclosure per step (REVIEW.md R-1) — reuses\n * `.w6w-section`'s bordered `<details>` idiom (`ApiCallsPanel.tsx`,\n * `ParamsForm.tsx`'s `section: \"collapsible\"`), not a bespoke card. The\n * `<summary>` is the one-line scan line (pill + label + timing, unchanged\n * content from the old always-visible row header); Input/Output move inside\n * the details body, and are only mounted into the DOM once opened — a\n * closed run of N steps costs N compact rows, not N×2 rendered JSON blocks.\n *\n * A step with neither `input` nor `output` has nothing to disclose: it\n * renders a plain, non-interactive row (still `.w6w-section`-styled for\n * visual consistency with its siblings) rather than an empty `<details>` a\n * user opens only to find \"Not available.\" twice (A3). An `error` alone is\n * not something to disclose either: it renders on every row as a sibling\n * AFTER the row's box — outside the lazily mounted `<details>` body (so it\n * reads while collapsed and never mounts twice once opened) and outside the\n * `<summary>` (whose phrasing-content model and click-to-toggle make it the\n * wrong home for a selectable block of text).\n */\nfunction ExecutionLogRow({ step }: { step: ExecutionLogStep }) {\n const [open, setOpen] = useState(false);\n const header = (\n <div className=\"w6w-execution-log-row-header\">\n <StepStatusPill state={step.status} />\n <span className=\"w6w-execution-log-row-label\">{step.label ?? step.id}</span>\n <StepTiming startedAt={step.startedAt} finishedAt={step.finishedAt} />\n </div>\n );\n\n const error = step.error ? <ExecutionLogErrorBlock error={step.error} /> : null;\n\n if (step.input === undefined && step.output === undefined && !step.meta) {\n return (\n <li className=\"w6w-execution-log-row\">\n <div className=\"w6w-section\">{header}</div>\n {error}\n </li>\n );\n }\n\n return (\n <li className=\"w6w-execution-log-row\">\n <details className=\"w6w-section\" open={open} onToggle={(e) => setOpen(e.currentTarget.open)}>\n <summary className=\"w6w-section-summary\">{header}</summary>\n {open && (\n <div className=\"w6w-execution-log-row-body w6w-section-body w6w-stack\">\n <ExecutionLogJson title=\"Input\" value={step.input} />\n <ExecutionLogJson title=\"Output\" value={step.output} />\n {step.meta && (\n <div className=\"w6w-execution-log-json w6w-stack\">\n <strong className=\"w6w-small\">Metadata</strong>\n <CodeBlock code={JSON.stringify(step.meta, null, 2)} language=\"json\" />\n </div>\n )}\n </div>\n )}\n </details>\n {error}\n </li>\n );\n}\n\n/**\n * `TriggerFillForm`'s StepError visual, reused rather than re-invented: the\n * `.w6w-result.w6w-error` box, an optional muted `<code>` line, then the\n * message. `label` (recorded step errors only) names the step on a line above.\n * The code line's spacing lives in `_execution-log.scss` as tokens instead of\n * `TriggerFillForm`'s inline style — same values (`0.75` opacity, a 4px gap).\n */\nfunction ExecutionLogErrorBlock({ error, label }: { error: ExecutionLogError; label?: string }) {\n return (\n <div className=\"w6w-result w6w-error\">\n {label !== undefined && <strong className=\"w6w-execution-log-error-label\">{label}</strong>}\n {error.code && (\n <div className=\"w6w-small w6w-execution-log-error-code\">\n <code>{error.code}</code>\n </div>\n )}\n {error.message}\n </div>\n );\n}\n\n/**\n * \"started / finished, or elapsed\" (A2): both timestamps render verbatim\n * plus the computed elapsed duration between them; only `startedAt` renders\n * as \"Started <ts>\"; neither renders as a plain dash. Never a live-ticking\n * clock — a `setInterval` would make this component a timer owner rather\n * than a pure function of its props.\n */\nfunction StepTiming({ startedAt, finishedAt }: { startedAt?: string; finishedAt?: string }) {\n if (startedAt && finishedAt) {\n const elapsed = formatElapsed(startedAt, finishedAt);\n return (\n <span className=\"w6w-execution-log-timing\">\n {startedAt} → {finishedAt}\n {elapsed && <span> ({elapsed})</span>}\n </span>\n );\n }\n if (startedAt) {\n return <span className=\"w6w-execution-log-timing\">Started {startedAt}</span>;\n }\n return <span className=\"w6w-execution-log-timing\">—</span>;\n}\n\nfunction formatElapsed(startedAt: string, finishedAt: string): string | null {\n const startMs = Date.parse(startedAt);\n const endMs = Date.parse(finishedAt);\n if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs) return null;\n const ms = endMs - startMs;\n if (ms < 1000) return `${ms}ms`;\n const totalSeconds = ms / 1000;\n if (totalSeconds < 60) return `${totalSeconds.toFixed(1)}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = Math.round(totalSeconds % 60);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Input/output as read-only, syntax-highlighted JSON — `CodeBlock`, not\n * `JsonEditor`: per `CodeBlock.tsx`'s own doc comment, `JsonEditor` mounts a\n * CodeMirror instance to *edit* text, \"heavy and semantically wrong for a\n * snippet nobody types into\" — exactly this row's read-only value, rendered\n * potentially many times over a whole run. `ResolvedParams.tsx` doesn't fit\n * either: it renders a *schema* (`ActionParam[]`) against resolved values,\n * and this panel has no param schema, only the already-resolved input/output\n * values themselves (see the file header's \"host maps `RunState`\" note).\n * Never a plain `<pre>` dump: `CodeBlock` is this library's own read-only\n * structured-code idiom (highlighting, copy affordance, `--w6w-code-*`\n * tokens), the thing `<pre>` is not.\n */\nfunction ExecutionLogJson({ title, value }: { title: string; value: unknown }) {\n return (\n <div className=\"w6w-execution-log-json w6w-stack\">\n <strong className=\"w6w-small\">{title}</strong>\n {value === undefined ? (\n <p className=\"w6w-muted w6w-small\">Not available.</p>\n ) : (\n <CodeBlock code={JSON.stringify(value, null, 2)} language=\"json\" />\n )}\n </div>\n );\n}\n","import type { ExecutionKind } from \"./ExecutionList.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\n\n/**\n * The filter/search state of the history view — one plain object, owned by the\n * HOST. This component is fully controlled: it holds no state of its own, it\n * only renders `value` and reports the next one. Same \"host owns the data, the\n * control is presentational\" split `ExecutionList` establishes, and the same\n * reason: the host owns where the filters live (URL search params today, a\n * query cache tomorrow) and this leaf must not disagree with it.\n */\nexport interface ExecutionFilterValue {\n /** `\"\"` = \"no status filter\" (the `Any status` option), never `null`. */\n status: ExecutionStatus | \"\";\n /** `\"\"` = \"no kind filter\" (the `Any type` option). Only reachable when the\n * host renders the kind select (`showKind`). */\n kind: ExecutionKind | \"\";\n /** Inclusive lower bound on the run's start, as `YYYY-MM-DD` — exactly what\n * `input[type=date]` reports and accepts. `\"\"` = unbounded. */\n from: string;\n /** Inclusive upper bound on the run's start, same format. `\"\"` = unbounded. */\n to: string;\n /** Free-text query. D3: the server matches execution id + callable name/key,\n * never payload JSON. */\n q: string;\n}\n\nexport interface ExecutionFiltersProps {\n /** The current filter state — rendered verbatim, never re-derived. */\n value: ExecutionFilterValue;\n /** Called ONCE per user interaction with the ONE field that changed:\n * `{ ...value, <that field>: next }`. No debounce, no batching — the host\n * decides when a request is worth making (it may debounce `q` itself). */\n onChange: (next: ExecutionFilterValue) => void;\n /** `true` ⇒ the kind select renders between the status select and the date\n * bounds. Defaults to `false`: the per-callable history view already knows\n * the kind, so a kind filter there would be a control of one option. */\n showKind?: boolean;\n /** Placeholder for the search box. Defaults to `\"Search by id or name\"` —\n * the same two fields D3 pins the server-side search to. */\n searchPlaceholder?: string;\n /** `true` ⇒ every control (the clear button included) renders disabled — the\n * state a host uses while a request is already in flight. */\n disabled?: boolean;\n}\n\n/** The \"nothing filtered\" state — what Clear reports, and what a host starts\n * from. Kept module-local: it is one object literal, and a host that needs its\n * own initial value should own it (it must be encoded into a URL anyway). */\nconst EMPTY: ExecutionFilterValue = { status: \"\", kind: \"\", from: \"\", to: \"\", q: \"\" };\n\n/** `\"\"` first (the \"any\" option), then one entry per run state, capitalised. */\nconst STATUS_OPTIONS: Array<{ value: ExecutionStatus | \"\"; label: string }> = [\n { value: \"\", label: \"Any status\" },\n { value: \"queued\", label: \"Queued\" },\n { value: \"running\", label: \"Running\" },\n { value: \"succeeded\", label: \"Succeeded\" },\n { value: \"failed\", label: \"Failed\" },\n { value: \"canceled\", label: \"Canceled\" },\n];\n\nconst KIND_OPTIONS: Array<{ value: ExecutionKind | \"\"; label: string }> = [\n { value: \"\", label: \"Any type\" },\n { value: \"function\", label: \"Function\" },\n { value: \"endpoint\", label: \"Endpoint\" },\n { value: \"workflow\", label: \"Workflow\" },\n];\n\n/**\n * The history view's filter/search bar: free text, status, (optionally) kind,\n * and a start-date window, plus a Clear control that appears only once there is\n * something to clear.\n *\n * A pure controlled leaf. Every change reports exactly one field's new value,\n * spread over the value it was given — a control that rebuilt the whole object\n * would silently drop a sibling filter the moment the two are edited close\n * together, and the host is the only party that knows the authoritative value.\n *\n * Each control carries its own `aria-label`: the visible layout is one dense\n * row of heterogeneous controls (a search box, three or four dropdowns, two\n * date pickers) with no room for a label per control, so the accessible name is\n * what tells them apart.\n */\nexport function ExecutionFilters({\n value,\n onChange,\n showKind = false,\n searchPlaceholder = \"Search by id or name\",\n disabled = false,\n}: ExecutionFiltersProps) {\n const clearable =\n value.status !== \"\" ||\n value.kind !== \"\" ||\n value.from !== \"\" ||\n value.to !== \"\" ||\n value.q !== \"\";\n\n return (\n <div className=\"w6w-execution-filters\" data-testid=\"execution-filters\">\n <input\n type=\"search\"\n className=\"w6w-execution-filters-search\"\n data-testid=\"execution-filter-q\"\n aria-label=\"Search executions\"\n placeholder={searchPlaceholder}\n value={value.q}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, q: e.target.value })}\n />\n <select\n className=\"w6w-execution-filters-select\"\n data-testid=\"execution-filter-status\"\n aria-label=\"Status\"\n value={value.status}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, status: e.target.value as ExecutionStatus | \"\" })}\n >\n {STATUS_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n {showKind && (\n <select\n className=\"w6w-execution-filters-select\"\n data-testid=\"execution-filter-kind\"\n aria-label=\"Type\"\n value={value.kind}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, kind: e.target.value as ExecutionKind | \"\" })}\n >\n {KIND_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n <input\n type=\"date\"\n className=\"w6w-execution-filters-date\"\n data-testid=\"execution-filter-from\"\n aria-label=\"From date\"\n value={value.from}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n />\n <input\n type=\"date\"\n className=\"w6w-execution-filters-date\"\n data-testid=\"execution-filter-to\"\n aria-label=\"To date\"\n value={value.to}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n />\n {clearable && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-execution-filters-clear\"\n data-testid=\"execution-filter-clear\"\n disabled={disabled}\n onClick={() => onChange({ ...EMPTY })}\n >\n Clear\n </button>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { formatDurationMs } from \"./execution-format.ts\";\n\n/**\n * The aggregate numbers of a history view — the same rows the list shows,\n * rolled up (D1: stats are computed over the same visibility the list uses, so\n * the two can never disagree about who may see what).\n *\n * `succeeded`/`canceled` are carried even though the strip renders no card for\n * them today: the host's payload has them, the breakdown is what a host needs\n * for a chart or a chip row, and a host re-deriving them from the list would be\n * computing the same total a second time.\n */\nexport interface ExecutionStatsValue {\n /** Every run in the current filter — the denominator of `successRate`. */\n total: number;\n succeeded: number;\n failed: number;\n canceled: number;\n /** Runs that are queued or running right now. `> 0` is what makes the\n * `In flight` card exist at all. */\n inFlight: number;\n /** `0…1`, or `null` when the host has no rate to report (no runs at all —\n * a rate over zero runs is not 0%). */\n successRate: number | null;\n /** Mean wall-clock duration of the FINISHED runs, or `null` when none has\n * finished. */\n avgDurationMs: number | null;\n}\n\nexport interface ExecutionStatsProps {\n /** The aggregate, or `null` while nothing has loaded yet — rendered as `—`\n * per card rather than as a spinner, so the strip never changes height. */\n stats: ExecutionStatsValue | null;\n /** Caption above the cards, e.g. the window they cover (\"Last 7 days\").\n * Omitted ⇒ no node at all. */\n label?: ReactNode;\n}\n\n/** What an absent/unknown number renders as — never `0`, which would read as a\n * measured result. Same em dash `execution-format.ts` uses for the same\n * reason. */\nconst UNKNOWN = \"—\";\n\ninterface Card {\n testid: string;\n label: string;\n value: string;\n}\n\n/**\n * A headline strip of run aggregates: one big value over a muted label per\n * card.\n *\n * Promotes studio `DashboardPage.tsx`'s page-local `StatCard` into `ui`, with\n * two differences that come from this being a shared component rather than one\n * page's private helper: the values are pre-formatted here (a rate as `67%`, a\n * duration through `formatDurationMs`) so every consumer renders the same\n * string, and each card carries `data-stat-value` so a host can assert on the\n * value without re-parsing its own formatting.\n */\nexport function ExecutionStats({ stats, label }: ExecutionStatsProps) {\n const cards: Card[] = [\n {\n testid: \"execution-stat-total\",\n label: \"Executions\",\n value: stats ? String(stats.total) : UNKNOWN,\n },\n {\n testid: \"execution-stat-success-rate\",\n label: \"Success rate\",\n value: formatSuccessRate(stats?.successRate),\n },\n {\n testid: \"execution-stat-failed\",\n label: \"Failed\",\n value: stats ? String(stats.failed) : UNKNOWN,\n },\n {\n testid: \"execution-stat-avg-duration\",\n label: \"Avg duration\",\n value: stats ? formatDurationMs(stats.avgDurationMs) : UNKNOWN,\n },\n ];\n\n // The one CONDITIONAL card: a zero in-flight count is the steady state, and a\n // permanent \"In flight 0\" would draw the eye to the least interesting number\n // in the strip. A missing `stats` counts as zero, so the strip keeps four\n // cards while loading instead of five-then-four.\n if (stats && stats.inFlight > 0) {\n cards.push({\n testid: \"execution-stat-in-flight\",\n label: \"In flight\",\n value: String(stats.inFlight),\n });\n }\n\n return (\n <section className=\"w6w-execution-stats\" data-testid=\"execution-stats\">\n {label != null && <p className=\"w6w-execution-stats-label\">{label}</p>}\n <div className=\"w6w-execution-stats-cards\">\n {cards.map((card) => (\n <div key={card.testid} className=\"w6w-execution-stat\" data-testid={card.testid}>\n <span className=\"w6w-execution-stat-value\" data-stat-value={card.value}>\n {card.value}\n </span>\n <span className=\"w6w-execution-stat-label\">{card.label}</span>\n </div>\n ))}\n </div>\n </section>\n );\n}\n\n/**\n * A `0…1` rate as a whole-percent string (`0.666…` → `\"67%\"`, rounded rather\n * than floored so `2/3` does not read as `66%`).\n *\n * `null` (nothing to report) and a non-finite rate (a host dividing by zero\n * somewhere upstream) are both `—` — the same totality `formatDurationMs`\n * keeps, so no input can render `NaN%`.\n */\nfunction formatSuccessRate(rate: number | null | undefined): string {\n if (rate == null || !Number.isFinite(rate)) return UNKNOWN;\n return `${Math.round(rate * 100)}%`;\n}\n","import type { ReactNode } from \"react\";\nimport { CodeBlock } from \"../CodeBlock.tsx\";\nimport type { ExecutionKind } from \"./ExecutionList.tsx\";\nimport { ExecutionLogPanel } from \"./ExecutionLogPanel.tsx\";\nimport type { ExecutionLogStep } from \"./ExecutionLogPanel.tsx\";\nimport { IconButton } from \"./IconButton.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\nimport { formatDurationMs, formatExecutionTime } from \"./execution-format.ts\";\n\n/**\n * One past execution in full — an already-mapped slice of the host's history\n * payload, the detail-level sibling of `ExecutionListItem`. The HOST maps its\n * own record into this shape; this component never fetches, polls or reaches\n * for an SDK.\n *\n * D2: there is no log-line field anywhere in this shape, on purpose — \"logs\"\n * for an execution ARE its status, timing, input, output and error, and for a\n * workflow that is the per-step `steps` list below.\n */\nexport interface ExecutionDetailValue {\n id: string;\n kind: ExecutionKind;\n callableName: string;\n status: ExecutionStatus;\n /** ISO-8601 instant the run started. */\n startedAt: string;\n /** ISO-8601 instant the run finished, or `null` while it is still\n * queued/running (rendered as `—`). */\n finishedAt: string | null;\n /** Wall-clock duration once the run has finished, or `null` while it has not\n * (rendered as `—`). */\n durationMs: number | null;\n /** The run's own input, once it is known. `undefined` = \"not available\" (no\n * section); `null` = \"available, and it is null\" (section renders `null`). */\n input?: unknown;\n output?: unknown;\n /** The failure's payload for a failed run. `null`/`undefined` = no error\n * section at all — the reverse gate to `input`/`output`, because an error\n * that is `null` is the absence of an error. */\n error?: unknown;\n /** A workflow run's steps. `undefined` = not a step-bearing run (no section);\n * `[]` = it ran and no step did (the panel's own empty state). */\n steps?: ExecutionLogStep[];\n}\n\nexport interface ExecutionDetailProps {\n /** The execution to show, or `null` when there is nothing to show yet. */\n execution: ExecutionDetailValue | null;\n /** `true` while the fetch for a `null` `execution` is still in flight —\n * renders the loading branch. Once an `execution` is present it is rendered\n * as-is: a host re-fetching (polling a running run) keeps showing the last\n * known state rather than flashing back to \"Loading…\". */\n loading?: boolean;\n /** A failure to surface, e.g. the fetch for this execution failed. Rendered\n * as an alert in EVERY branch — it is about the view, not about the run. */\n errorMessage?: ReactNode;\n /** Supplied ⇒ a dismiss control renders and calls this. Omitted ⇒ no\n * control. */\n onClose?: () => void;\n /** Supplied ⇒ the \"Open in visual editor\" button renders and calls this.\n * Omitted ⇒ no button (a function/endpoint run has no visual editor to open). */\n onOpenInEditor?: () => void;\n}\n\nconst KIND_LABEL: Record<ExecutionKind, string> = {\n function: \"Function\",\n endpoint: \"Endpoint\",\n workflow: \"Workflow\",\n};\n\n/** A value the section is showing that JSON cannot serialise (`undefined`,\n * a function, a symbol) renders as `null` rather than an empty block. */\nfunction toJson(value: unknown): string {\n return JSON.stringify(value, null, 2) ?? \"null\";\n}\n\n/**\n * Everything known about one past execution: which callable it was and how it\n * went, its timing, its own input/output/error, and — for a workflow run — the\n * per-step list.\n *\n * The per-step list sits directly under the timing, above the run's own\n * payloads: for a workflow it is the substance of the view (D2), and burying it\n * under three JSON blocks would make the run read as a function call with\n * appendices.\n *\n * A pure display leaf — no fetching, no polling, no live-ticking timer.\n */\nexport function ExecutionDetail({\n execution,\n loading = false,\n errorMessage,\n onClose,\n onOpenInEditor,\n}: ExecutionDetailProps) {\n return (\n <section className=\"w6w-execution-detail w6w-stack\" data-testid=\"execution-detail\">\n {errorMessage != null && (\n <p\n role=\"alert\"\n className=\"w6w-execution-detail-error-message\"\n data-testid=\"execution-detail-error-message\"\n >\n {errorMessage}\n </p>\n )}\n {execution ? (\n <Body execution={execution} onClose={onClose} onOpenInEditor={onOpenInEditor} />\n ) : loading ? (\n <p className=\"w6w-muted\" data-testid=\"execution-detail-loading\">\n Loading…\n </p>\n ) : (\n <p className=\"w6w-muted\" data-testid=\"execution-detail-empty\">\n No execution selected.\n </p>\n )}\n </section>\n );\n}\n\nfunction Body({\n execution,\n onClose,\n onOpenInEditor,\n}: {\n execution: ExecutionDetailValue;\n onClose?: () => void;\n onOpenInEditor?: () => void;\n}) {\n return (\n <>\n <div className=\"w6w-execution-detail-head\">\n <div className=\"w6w-execution-detail-title\">\n <h3 className=\"w6w-execution-detail-name\">{execution.callableName}</h3>\n <div className=\"w6w-execution-detail-meta\">\n <StepStatusPill state={execution.status} />\n <span className=\"w6w-execution-detail-kind w6w-muted w6w-small\">\n {KIND_LABEL[execution.kind]}\n </span>\n </div>\n </div>\n {(onOpenInEditor || onClose) && (\n <div className=\"w6w-execution-detail-actions\">\n {onOpenInEditor && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-detail-open-editor\"\n onClick={onOpenInEditor}\n >\n Open in visual editor\n </button>\n )}\n {onClose && (\n <IconButton label=\"Close\" data-testid=\"execution-detail-close\" onClick={onClose}>\n ×\n </IconButton>\n )}\n </div>\n )}\n </div>\n\n <p className=\"w6w-execution-detail-id-line\">\n <code className=\"w6w-execution-detail-id\" data-testid=\"execution-detail-id\">\n {execution.id}\n </code>\n </p>\n\n <dl className=\"w6w-execution-detail-timing\">\n <TimingItem label=\"Started\" value={formatExecutionTime(execution.startedAt)} />\n <TimingItem\n label=\"Finished\"\n value={execution.finishedAt ? formatExecutionTime(execution.finishedAt) : \"—\"}\n />\n <TimingItem label=\"Duration\" value={formatDurationMs(execution.durationMs)} />\n </dl>\n\n {execution.steps !== undefined && (\n <section\n className=\"w6w-execution-detail-section w6w-stack\"\n data-testid=\"execution-detail-steps\"\n >\n <strong className=\"w6w-small\">Steps</strong>\n <ExecutionLogPanel steps={execution.steps} emptyLabel=\"No steps ran.\" />\n </section>\n )}\n\n {execution.input !== undefined && (\n <JsonSection title=\"Input\" testid=\"execution-detail-input\" value={execution.input} />\n )}\n {execution.output !== undefined && (\n <JsonSection title=\"Output\" testid=\"execution-detail-output\" value={execution.output} />\n )}\n {execution.error != null && (\n <JsonSection title=\"Error\" testid=\"execution-detail-error\" value={execution.error} />\n )}\n </>\n );\n}\n\nfunction TimingItem({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"w6w-execution-detail-timing-item\">\n <dt>{label}</dt>\n <dd>{value}</dd>\n </div>\n );\n}\n\n/**\n * One payload as read-only, syntax-highlighted JSON — `CodeBlock`, the same\n * idiom `ExecutionLogPanel` renders a step's input/output through (see its own\n * doc comment for why `CodeBlock` and not `JsonEditor`/`<pre>`).\n */\nfunction JsonSection({ title, testid, value }: { title: string; testid: string; value: unknown }) {\n return (\n <section className=\"w6w-execution-detail-section w6w-stack\" data-testid={testid}>\n <strong className=\"w6w-small\">{title}</strong>\n <CodeBlock code={toJson(value)} language=\"json\" />\n </section>\n );\n}\n"],"names":["ApiError","status","code","message","body","__publicField","createW6WApi","opts","baseUrl","doFetch","getToken","rawReq","path","init","headers","token","res","e","text","data","err","req","apps","cursor","page","qs","r","ids","unique","i","id","appId","authKey","actionKey","params","connectionId","patch","connId","workflowId","stepId","inputs","formatBody","defaultKeyOf","call","index","ApiCallsPanel","calls","defaultOpen","keyOf","title","key","jsxs","jsx","Fragment","ListItem","subtitle","icon","trailing","active","onClick","ariaLabel","className","relativeTime","iso","then","secs","mins","hours","days","defaultParamsFor","action","out","p","extractProviderMessage","msg","brace","j","m","_b","_a","_c","prefix","isInvokeApiError","describeInvokeError","detail","haystack","apiCallsOf","source","useOverrideJsonField","setText","useState","value","setValue","invalid","setInvalid","next","trimmed","parsed","ActionTestForm","actions","seedValues","onSavedTestsChanged","seedTestId","onDirtyChange","onTestSaved","onDeleted","embedded","api","useW6WApi","sortedActions","useMemo","list","a","b","pickedKey","setPickedKey","selectedAction","running","setRunning","error","setError","result","setResult","apiCalls","setApiCalls","ovBody","ovQuery","ovHeaders","ovTarget","setOvTarget","ovMatch","setOvMatch","overridesInvalid","currentOverrides","viewMode","setViewMode","jsonText","setJsonText","jsonInvalid","setJsonInvalid","modalOpen","setModalOpen","selectedKey","initialValues","valuesByAction","setValuesByAction","editingTestId","setEditingTestId","baseline","setBaseline","fresh","lastSeedTestId","setLastSeedTestId","lastSeed","setLastSeed","structurallyChanged","seeded","values","setValues","dirty","useEffect","enterJsonView","runWith","outcome","overrides","refreshSavedTests","refreshRunHistory","run","savedTests","setSavedTests","savedTestsError","setSavedTestsError","savedTestsNonce","setSavedTestsNonce","nameModalOpen","setNameModalOpen","pendingName","setPendingName","confirmDeleteOpen","setConfirmDeleteOpen","n","canceled","railTests","t","runHistory","setRunHistory","runHistoryNonce","setRunHistoryNonce","load","railRunHistory","openSaveModal","handleSaveClick","submitSaveTest","saved","name","loadSavedTest","loaded","deleteCurrentTest","deletedId","paramsRegion","v","ParamsForm","JsonEditor","valid","overridesRegion","savedTestsRail","deletingTestName","Combobox","paramsAndResult","actionBar","Modal","ConfirmModal","YamlEditor","props","theme","useEffectiveTheme","copied","copy","useCopyToClipboard","extensions","yaml","EditorView","handleChange","CodeMirror","CheckGlyph","CopyGlyph","MARKER","cropText","chars","crop","head","tail","CopyableText","label","copiedMs","cropped","classes","Copyable","DEFAULT_LABELS","HealthStatusPill","state","STATE_LABELS","UptimeStrip","entry","UNKNOWN","BYTE_UNITS","formatBytes","unit","formatPercent","f","cpuLoadFraction","s","divisor","memoryUsedFraction","memoryTotal","memoryAvailable","clamp","lo","hi","sparklinePoints","width","height","max","points","x","y","SPARK_WIDTH","SPARK_HEIGHT","Sparkline","formatLoad","fractionMax","MetricRow","readings","samples","last","cpuValues","memoryValues","rssValues","ServerResourcesCard","intervalMs","ServerResourcesCardSmall","ServerResourcesRail","onExpand","ServerResourcesBadge","cpu","mem","MIN_BAR_WIDTH_PCT","DAY_MS","placeIncidentBar","window","bar","nowMs","start","startMs","endMs","windowStartMs","windowEndMs","spanMs","clippedStart","clippedEnd","clampedStartMs","clampedEndMs","leftPct","rawWidthPct","widthPct","NO_FEED_LABEL","QUIET_LABEL","barTitle","parts","HistoryTimeline","win","incidents","vendorEmptyLabel","cellWidthPct","emptyLabel","placement","clipClass","InfoTip","children","open","setOpen","useId","IconButton","o","EditButton","disabled","rest","DeleteButton","RepoSyncIndicator","branch","shortSha","lastSyncLabel","onSyncNow","syncing","ref","useRef","onDown","onKey","Icon","StepStatusPill","MS_PER_SECOND","MS_PER_MINUTE","formatDurationMs","ms","formatExecutionTime","date","KIND_LABEL","ExecutionList","items","selectedId","onSelect","showCallable","loading","hasPrev","hasNext","onPrev","onNext","pager","item","ExecutionLogPanel","steps","onDismiss","runError","stepErrors","recorded","errors","ExecutionLogErrorBlock","step","ExecutionLogRow","header","StepTiming","ExecutionLogJson","CodeBlock","startedAt","finishedAt","elapsed","formatElapsed","totalSeconds","minutes","seconds","EMPTY","STATUS_OPTIONS","KIND_OPTIONS","ExecutionFilters","onChange","showKind","searchPlaceholder","clearable","option","ExecutionStats","stats","cards","formatSuccessRate","card","rate","toJson","ExecutionDetail","execution","errorMessage","onClose","onOpenInEditor","Body","TimingItem","JsonSection","testid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/createW6WApi.ts","../src/components/ApiCallsPanel.tsx","../src/components/ListItem.tsx","../src/ActionTestForm.tsx","../src/YamlEditor.tsx","../src/components/CopyableText.tsx","../src/components/HealthStatusPill.tsx","../src/components/UptimeStrip.tsx","../src/components/server-resources-format.ts","../src/components/ServerResources.tsx","../src/components/history-scale.ts","../src/components/HistoryTimeline.tsx","../src/components/InfoTip.tsx","../src/components/EditButton.tsx","../src/components/DeleteButton.tsx","../src/components/RepoSyncIndicator.tsx","../src/components/StepStatusPill.tsx","../src/components/execution-format.ts","../src/components/ExecutionList.tsx","../src/components/ExecutionLogPanel.tsx","../src/components/ExecutionFilters.tsx","../src/components/ExecutionStats.tsx","../src/components/ExecutionDetail.tsx","../src/reliability-board-layout.ts","../src/components/ReliabilityChart.tsx","../src/components/ReliabilityList.tsx","../src/components/CallableList.tsx","../src/connection-app-meta.ts","../src/components/ConnectionList.tsx","../src/EditConnectionModal.tsx","../src/ConnectionHeader.tsx"],"sourcesContent":["/**\n * Default fetch-based W6WApi client. Convenience for partners without their\n * own HTTP client — studio wires react-query around its own implementation\n * and doesn't use this. Every method calls the w6w server directly and\n * throws `ApiError` on non-OK responses so callers can surface the message.\n */\nimport type { StepMeta, StepTest, TestRunSummary, W6WApi } from \"./provider.tsx\";\nimport type {\n ActionDef,\n ApiCallRecord,\n AppSummary,\n AuthDef,\n ConnectionSummary,\n FunctionDetail,\n FunctionSummary,\n SavedTest,\n WorkflowDetail,\n WorkflowSummary,\n} from \"./types.ts\";\n\nexport interface CreateW6WApiOptions {\n /** Absolute URL or path prefix — e.g. `\"https://w6w.example.com\"` or `\"/api\"`. */\n baseUrl: string;\n /**\n * Bearer token to send. Accepts a string (static) or a supplier function so\n * a JWT that rotates on refresh is fetched fresh on every request. The\n * supplier may be sync or return a `Promise` — either way it is awaited\n * once per request. It receives an optional `{ forceRefresh? }` ctx arg\n * (unused by this client today, but part of the shape so a caller's\n * supplier can share one implementation with `@w6w/sdk`'s `TokenProvider`).\n */\n token?:\n | string\n | ((ctx?: { forceRefresh?: boolean }) =>\n | string\n | null\n | undefined\n | Promise<string | null | undefined>);\n /** Optional fetch replacement — handy for tests. Defaults to `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\nexport class ApiError extends Error {\n status: number;\n code: string;\n /**\n * The parsed error response body, when the server sent one. Carries the\n * fields that ride alongside an error — e.g. an invoke's `logs` and\n * `apiCalls` — which the message alone would drop.\n */\n body?: unknown;\n\n constructor(status: number, code: string, message: string, body?: unknown) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.body = body;\n }\n}\n\n/** Build a fetch-based W6WApi client bound to a base URL + token supplier. */\nexport function createW6WApi(opts: CreateW6WApiOptions): W6WApi {\n const baseUrl = opts.baseUrl.replace(/\\/$/, \"\");\n const doFetch = opts.fetch ?? globalThis.fetch;\n const getToken = async () => (typeof opts.token === \"function\" ? await opts.token() : opts.token);\n\n // The shared fetch core: auth header, JSON parse, and the one error-shaping\n // idiom every member uses. Exposes the response's own status code (`req<T>`\n // below discards it) — `runWorkflow` is the one caller that needs it, to\n // derive `terminal` from `200` vs the server's own `202` wait-timeout arm.\n async function rawReq(\n path: string,\n init?: RequestInit,\n ): Promise<{ status: number; data: unknown }> {\n const headers = new Headers(init?.headers);\n const token = await getToken();\n if (token) headers.set(\"authorization\", `Bearer ${token}`);\n if (init?.body && !headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n\n let res: Response;\n try {\n res = await doFetch(`${baseUrl}${path}`, { ...init, headers });\n } catch (e) {\n // A failed fetch throws a bare `TypeError: Failed to fetch` — wrap it with\n // the target so callers can tell the server is down vs. a real API error.\n throw new ApiError(\n 0,\n \"network_error\",\n `Could not reach the w6w server (${init?.method ?? \"GET\"} ${baseUrl}${path}). ` +\n `It may be down or unreachable. (${(e as Error).message})`,\n );\n }\n const text = await res.text();\n let data: unknown = null;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n if (!res.ok) {\n throw new ApiError(\n res.status,\n \"bad_response\",\n `Server returned a non-JSON ${res.status} response: ${text.slice(0, 200)}`,\n );\n }\n }\n }\n if (!res.ok) {\n const err = ((data as { error?: { code?: string; message?: string } } | null)?.error ??\n {}) as { code?: string; message?: string };\n throw new ApiError(res.status, err.code ?? \"error\", err.message ?? res.statusText, data);\n }\n return { status: res.status, data };\n }\n\n async function req<T>(path: string, init?: RequestInit): Promise<T> {\n const { data } = await rawReq(path, init);\n return data as T;\n }\n\n return {\n // A bare GET only returns the server's default page (50) — every consumer\n // of this client treats the result as the complete catalog, so walk one\n // server snapshot by `nextCursor` (opaque; the cursor encodes the\n // snapshot, so `snapshot`/`offset` are never sent). No page cap: the walk\n // ends when the cursor is absent or fails to advance. If the snapshot\n // expired mid-walk (410 `snapshot_expired` / 404 `unknown_snapshot`, alike\n // to a token holder), drop what was gathered and restart once.\n listApps: async () => {\n const walk = async (): Promise<AppSummary[]> => {\n const apps: AppSummary[] = [];\n let cursor: string | undefined;\n for (;;) {\n const qs = new URLSearchParams({ limit: \"200\" });\n if (cursor) qs.set(\"cursor\", cursor);\n const r = await req<{ apps: AppSummary[]; nextCursor?: string }>(`/apps?${qs}`);\n apps.push(...r.apps);\n if (!r.nextCursor || r.nextCursor === cursor) return apps;\n cursor = r.nextCursor;\n }\n };\n try {\n return await walk();\n } catch (e) {\n if (\n e instanceof ApiError &&\n (e.code === \"snapshot_expired\" || e.code === \"unknown_snapshot\")\n ) {\n return await walk();\n }\n throw e;\n }\n },\n\n // Bounded lookup: dedupe; `[]` sends nothing; chunks of <= 100 (the server's\n // `MAX_IDS_PER_QUERY`), each `GET /apps?ids=a,b` with no limit/cursor.\n listAppsByIds: async (ids) => {\n const unique = Array.from(new Set(ids));\n const apps: AppSummary[] = [];\n for (let i = 0; i < unique.length; i += 100) {\n const chunk = unique.slice(i, i + 100);\n const qs = chunk.map(encodeURIComponent).join(\",\");\n const r = await req<{ apps: AppSummary[] }>(`/apps?ids=${qs}`);\n apps.push(...r.apps);\n }\n return apps;\n },\n\n getAppAuth: async (id: string) => {\n const r = await req<{ auths: AuthDef[] }>(`/apps/${encodeURIComponent(id)}/auths`);\n return r.auths ?? [];\n },\n\n createConnection: (appId, body) =>\n req<{ connection: ConnectionSummary }>(`/apps/${encodeURIComponent(appId)}/connections`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((r) => r.connection),\n\n updateConnection: (id, body) =>\n req<{ connection: ConnectionSummary }>(`/connections/${encodeURIComponent(id)}`, {\n method: \"PATCH\",\n body: JSON.stringify(body),\n }).then((r) => r.connection),\n\n startAppOAuthFlow: (appId, authKey, body) =>\n req<{ authorizationUrl: string }>(\n `/apps/${encodeURIComponent(appId)}/oauth-config/${encodeURIComponent(authKey)}/authorize-url`,\n { method: \"POST\", body: JSON.stringify(body) },\n ),\n\n getAppActions: (appId) =>\n req<{ actions: ActionDef[] }>(`/apps/${encodeURIComponent(appId)}`).then(\n (r) => r.actions ?? [],\n ),\n\n listConnectionsForApp: (appId) =>\n req<{ connections: ConnectionSummary[] }>(\n `/apps/${encodeURIComponent(appId)}/connections`,\n ).then((r) => r.connections ?? []),\n\n listConnections: () =>\n req<{ connections: ConnectionSummary[] }>(\"/connections\").then((r) => r.connections ?? []),\n\n invokeAction: (appId, actionKey, params, opts = {}) =>\n req<{\n value: unknown;\n logs?: string[];\n apiCalls?: ApiCallRecord[];\n meta?: StepMeta;\n }>(\n `/apps/${encodeURIComponent(appId)}/actions/${encodeURIComponent(actionKey)}/invoke`,\n // This body is built KEY BY KEY, not by spreading `opts` — so every new\n // option has to be named here or it is silently dropped before the wire\n // (the caller compiles, the UI looks right, the field never leaves the\n // page). `project` scopes document-expression resolution to the\n // workflow's selected project; `state` is the start state upstream step\n // outputs are seeded from, so `{{ steps.<id>.output.<f> }}` resolves.\n // Undefined keys are dropped by JSON.stringify, so an absent project or\n // state leaves the request byte-identical to one that never had them.\n {\n method: \"POST\",\n body: JSON.stringify({\n params,\n connectionId: opts.connectionId,\n project: opts.project,\n state: opts.state,\n }),\n },\n ),\n\n listSavedTests: (connectionId) =>\n req<{ savedTests: SavedTest[] }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests`,\n ).then((r) => r.savedTests ?? []),\n\n createSavedTest: (connectionId, body) =>\n req<{ savedTest: SavedTest }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then((r) => r.savedTest),\n\n updateSavedTest: (connectionId, id, patch) =>\n req<{ savedTest: SavedTest }>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests/${encodeURIComponent(id)}`,\n { method: \"PATCH\", body: JSON.stringify(patch) },\n ).then((r) => r.savedTest),\n\n deleteSavedTest: (connectionId, id) =>\n req<void>(\n `/connections/${encodeURIComponent(connectionId)}/saved-tests/${encodeURIComponent(id)}`,\n { method: \"DELETE\" },\n ).then(() => undefined),\n\n recordTestRun: (connId, body) =>\n req<{ run: unknown }>(`/connections/${encodeURIComponent(connId)}/test-runs`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then(() => undefined),\n\n listTestRuns: (connectionId) =>\n req<{ runs: TestRunSummary[] }>(\n `/connections/${encodeURIComponent(connectionId)}/test-runs`,\n ).then((r) => r.runs ?? []),\n\n saveStepTest: (workflowId, stepId, body) =>\n req<{ stepTest: StepTest }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/tests`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then((r) => r.stepTest),\n\n listStepTests: (workflowId, stepId) =>\n req<{ stepTests: StepTest[] }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/tests`,\n ).then((r) => r.stepTests ?? []),\n\n recordStepTestRun: (workflowId, stepId, body) =>\n req<{ run: unknown }>(\n `/workflows/${encodeURIComponent(workflowId)}/steps/${encodeURIComponent(stepId)}/test-runs`,\n { method: \"POST\", body: JSON.stringify(body) },\n ).then(() => undefined),\n\n listFunctions: () =>\n req<{ functions: FunctionSummary[] }>(\"/functions\").then((r) => r.functions ?? []),\n\n getFunction: (id) =>\n req<{ function: Omit<FunctionDetail, \"valid\">; valid: boolean }>(\n `/functions/${encodeURIComponent(id)}`,\n ).then((r) => ({ ...r.function, valid: r.valid })),\n\n // The real synchronous route (`/functions/:id/invoke`) — deliberately NOT\n // `POST /run`, which would give the test stage a different code path than\n // the `@w6w/call` node it's standing in for. Returns the raw output,\n // pinned against the committed `studio/src/repos/functions.ts` signature.\n invokeFunction: (id, inputs) =>\n req<{ output?: unknown }>(`/functions/${encodeURIComponent(id)}/invoke`, {\n method: \"POST\",\n body: JSON.stringify({ inputs }),\n }).then((r) => r.output),\n\n listWorkflows: () =>\n req<{ workflows: WorkflowSummary[] }>(\"/workflows\").then((r) => r.workflows ?? []),\n\n getWorkflow: (id) =>\n req<{ workflow: WorkflowDetail }>(`/workflows/${encodeURIComponent(id)}`).then(\n (r) => r.workflow,\n ),\n\n // `rawReq`, not `req<T>` — the ONE caller that needs the response's own\n // status code: `200` (the run reached a terminal state inside the wait\n // window) vs `202` (the server's own wait-timeout, still running). Both\n // are 2xx successes; `rawReq` already throws on a non-2xx.\n runWorkflow: (id, opts = {}) =>\n rawReq(`/workflows/${encodeURIComponent(id)}/run?wait=true`, {\n method: \"POST\",\n body: JSON.stringify({ variables: opts.variables, input: opts.input }),\n }).then(({ status, data }) => {\n const body = (data ?? {}) as {\n runId: string;\n status: string;\n output?: unknown;\n error?: unknown;\n };\n return { ...body, terminal: status === 200 };\n }),\n };\n}\n","import type { ReactNode } from \"react\";\nimport type { ApiCallRecord } from \"../types.ts\";\n\nexport interface ApiCallsPanelProps {\n /** The captured outbound calls to render, in the order they were made. */\n calls: ApiCallRecord[];\n /**\n * Open every call's `<details>` on first render. Default `false` — the wire\n * log is ground truth you reach for, not something to read on every run. A\n * host that already landed the user on ONE specific call (e.g. a drill-down\n * that scoped the list to it) passes `true` so the user isn't made to click\n * twice through their own target.\n */\n defaultOpen?: boolean;\n /**\n * React `key` for each call. Defaults to method + url + array index, which is\n * stable within a single run because captured calls carry no id of their own.\n * A host rendering PERSISTED rows (which do have an id) across a paginated\n * list must pass its own — index keys collide between pages and React then\n * reuses the wrong `<details>` open-state.\n */\n keyOf?: (call: ApiCallRecord, index: number) => string;\n /**\n * Section header. Defaults to `API call(s) (N)`. Pass `false` to suppress it\n * entirely when the host already owns the heading — same idiom as\n * `ActionTestForm`'s `embedded` prop, which suppresses its own pop-out chrome\n * because the host provides it. Any other node replaces the default text.\n */\n title?: ReactNode | false;\n}\n\n/** Pretty-print a captured body when it is JSON; otherwise show it verbatim. */\nfunction formatBody(body: string | null | undefined): string {\n if (!body) return \"\";\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n}\n\n/** Captured calls have no id of their own; index is stable within a run. */\nfunction defaultKeyOf(call: ApiCallRecord, index: number): string {\n return `${call.method}-${call.url ?? call.host}-${index}`;\n}\n\n/**\n * The wire log for a run: each outbound HTTP call the action made, with the\n * request we sent and the response we got back. Collapsed by default — it is the\n * ground truth you open when the result looks wrong (e.g. a template variable\n * that came through unrendered), not something to read on every run.\n *\n * Purely presentational: it renders exactly what it is given, with no fetching,\n * no context, and no derivation of state from the calls. Credential redaction\n * happens server-side at capture time (request AND response headers); nothing\n * here re-inspects or re-redacts them.\n */\nexport function ApiCallsPanel({ calls, defaultOpen, keyOf, title }: ApiCallsPanelProps) {\n if (calls.length === 0) return null;\n const key = keyOf ?? defaultKeyOf;\n return (\n <div className=\"w6w-stack\" style={{ gap: 4 }}>\n {title !== false && (\n <strong className=\"w6w-small\">\n {title ?? (\n <>\n API {calls.length === 1 ? \"call\" : \"calls\"} ({calls.length})\n </>\n )}\n </strong>\n )}\n {calls.map((call, i) => (\n <details\n key={key(call, i)}\n open={defaultOpen}\n className=\"w6w-result\"\n style={{ padding: 8 }}\n >\n <summary style={{ cursor: \"pointer\" }}>\n <span className=\"w6w-small\">\n {call.method} {call.url ?? call.host} →{\" \"}\n <strong>{call.error ? \"failed\" : call.status}</strong>\n {call.durationMs !== undefined && (\n <span className=\"w6w-muted\"> · {call.durationMs}ms</span>\n )}\n </span>\n </summary>\n <div className=\"w6w-stack\" style={{ gap: 6, marginTop: 8 }}>\n {call.error && <div className=\"w6w-error w6w-small\">{call.error}</div>}\n <div className=\"w6w-muted w6w-small\">Request headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.requestHeaders ?? {}, null, 2)}</pre>\n {call.requestBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Request body</div>\n <pre className=\"w6w-result\">{formatBody(call.requestBody)}</pre>\n </>\n )}\n <div className=\"w6w-muted w6w-small\">Response headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.responseHeaders ?? {}, null, 2)}</pre>\n {call.responseBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Response body</div>\n <pre className=\"w6w-result\">{formatBody(call.responseBody)}</pre>\n </>\n )}\n {call.truncated && (\n <div className=\"w6w-muted w6w-small\">\n A captured body exceeded the size cap and was truncated.\n </div>\n )}\n </div>\n </details>\n ))}\n </div>\n );\n}\n","import type { MouseEvent, ReactNode } from \"react\";\n\nexport interface ListItemProps {\n /** Primary label — prominent, single-line with ellipsis overflow. */\n title: ReactNode;\n /** Secondary label under the title — muted, small, truncates. */\n subtitle?: ReactNode;\n /** Leading slot (e.g. an `<AppIcon />` or status glyph). */\n icon?: ReactNode;\n /**\n * Trailing slot pushed to the right (e.g. a badge or chevron). With `href` it sits INSIDE the\n * anchor, so it must stay non-interactive (no buttons or links).\n */\n trailing?: ReactNode;\n /** Highlights the row as selected/current. Reflected as `aria-pressed` when clickable. */\n active?: boolean;\n /**\n * When provided, the row renders as a focusable, keyboard-activatable button — or, with `href`,\n * still fires on a click of the anchor. Receives the click event; ListItem never calls\n * `preventDefault`, so the host decides whether the browser navigates.\n */\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n /** When provided, the row renders as a real `<a href>` (middle-click, copy link, new tab). */\n href?: string;\n /** Accessible label for the clickable row (falls back to the `title` DOM text). */\n ariaLabel?: string;\n}\n\n/**\n * A clean, reusable list row: leading icon · title over subtitle · trailing slot.\n *\n * Mirrors the look/behaviour of the saved-test button rows it replaces. When\n * `onClick` is given it renders a `<button type=\"button\">` (focusable, Enter/Space\n * activatable) with `aria-pressed={active}`; with `href` an `<a href>` (the click still reaches\n * `onClick`); otherwise a plain, non-interactive row.\n */\nexport function ListItem({\n title,\n subtitle,\n icon,\n trailing,\n active = false,\n onClick,\n href,\n ariaLabel,\n}: ListItemProps) {\n const body = (\n <>\n {icon != null && <span className=\"w6w-list-item-icon\">{icon}</span>}\n <span className=\"w6w-list-item-body\">\n <span className=\"w6w-list-item-title\">{title}</span>\n {subtitle != null && <span className=\"w6w-list-item-subtitle\">{subtitle}</span>}\n </span>\n {trailing != null && <span className=\"w6w-list-item-trailing\">{trailing}</span>}\n </>\n );\n\n const className = `w6w-list-item${active ? \" active\" : \"\"}`;\n\n if (href !== undefined) {\n return (\n <a\n className={className}\n href={href}\n aria-current={active ? \"true\" : undefined}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {body}\n </a>\n );\n }\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n className={className}\n aria-pressed={active}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {body}\n </button>\n );\n }\n\n return (\n <div className={className} aria-label={ariaLabel}>\n {body}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { JsonEditor } from \"./JsonEditor.tsx\";\nimport { ParamsForm } from \"./ParamsForm.tsx\";\nimport { ApiCallsPanel } from \"./components/ApiCallsPanel.tsx\";\nimport { Combobox } from \"./components/Combobox.tsx\";\nimport { ConfirmModal } from \"./components/ConfirmModal.tsx\";\nimport { ListItem } from \"./components/ListItem.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type { RequestOverrides, TestRunSummary } from \"./provider.tsx\";\nimport type { ActionDef, ApiCallRecord, SavedTest, ThemeMode } from \"./types.ts\";\n\nexport interface ActionTestFormProps {\n /** App the action belongs to. */\n appId: string;\n /** The app's actions — the caller already has them from the app detail. */\n actions: ActionDef[];\n /** Fixed connection to run against; its credential is resolved server-side. */\n connectionId?: string;\n /**\n * Pre-selected action (controlled). When provided the built-in action\n * `<select>` is hidden — the caller is already driving the selection.\n */\n action?: ActionDef | null;\n /** Theme hint, accepted for parity with other ui-lib components. */\n theme?: ThemeMode;\n /**\n * Studio-integration seam: when provided (and its reference changes) the\n * current action's params are seeded from a shallow copy of this object, so a\n * host page can \"open\" a saved test pre-filled. The stored object is never\n * mutated; a subsequent user edit is free to diverge. Optional — existing\n * consumers keep compiling.\n */\n seedValues?: Record<string, unknown> | null;\n /**\n * Studio-integration seam: fired after a successful saved-test create/delete\n * so the host page can invalidate its own `[\"saved-tests\", connId]` query.\n * The modal rail still refreshes its own list independently. Optional.\n */\n onSavedTestsChanged?: () => void;\n /**\n * Studio-integration seam (URL-driven host): the id of the saved test being\n * edited, from a studio deep link (`…/test/:testId`). When it changes to a\n * non-null id it is adopted as the current `editingTestId` — so the bottom Save\n * PATCHes that row and the Delete button shows; when null the tester is a\n * fresh/unsaved test. Optional — existing consumers keep compiling.\n */\n seedTestId?: string | null;\n /**\n * Studio-integration seam: fired whenever the current `values` diverge from\n * (or return to) the seeded baseline. This is the unsaved-changes signal the\n * studio host gates modal-close on (its ConfirmModal prompt). Optional.\n */\n onDirtyChange?: (dirty: boolean) => void;\n /**\n * Studio-integration seam: fired after a successful save (POST create or PATCH\n * update) with the resulting `SavedTest`, so the host can sync the URL\n * (`…/test/:id`) and clear its own dirty state. Optional.\n */\n onTestSaved?: (test: SavedTest) => void;\n /**\n * Studio-integration seam: fired after a successful delete of the saved test\n * currently being edited, with the deleted id, so the host can navigate away\n * from a now-dead `…/test/:id` URL. Optional — existing consumers keep compiling.\n */\n onDeleted?: (testId: string) => void;\n /**\n * Host-embedded mode. When `true` the caller already renders this widget inside\n * its own modal (studio's `ConnectionTesterModal`), so the widget suppresses its\n * OWN `<Modal>` + pop-out (⤢) toggle and instead fills the host container as a\n * full-height flex column: the params + saved-tests region scrolls and the\n * action bar is pinned to the bottom. Default `false` — non-embedded (inline /\n * own pop-out) usages are unchanged.\n */\n embedded?: boolean;\n}\n\n/**\n * Minimal relative-time label (\"just now\", \"5m ago\", \"3h ago\", \"2d ago\", or a\n * date for anything older) from an ISO timestamp. Kept inline — no formatter is\n * imported here — and only used for the saved-tests rail subtitle.\n */\nfunction relativeTime(iso: string): string {\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return \"\";\n const secs = Math.max(0, Math.round((Date.now() - then) / 1000));\n if (secs < 45) return \"just now\";\n const mins = Math.round(secs / 60);\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.round(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.round(hours / 24);\n if (days < 7) return `${days}d ago`;\n return new Date(then).toLocaleDateString();\n}\n\n/** Pull default values out of declared params so the form starts populated. */\nfunction defaultParamsFor(action: ActionDef | null | undefined): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const p of action?.params ?? []) {\n if (p.key && p.default !== undefined) out[p.key] = p.default;\n }\n return out;\n}\n\n/** A rendered action error: a plain-language headline, an optional fix hint, and the raw provider detail. */\ninterface InvokeError {\n headline: string;\n hint?: string;\n detail?: string;\n}\n\n/**\n * Pull the provider's own human-readable message out of a raw error string. App\n * actions often throw like `SendGrid list index returned 403: {\"errors\":[{\"message\":\"…\"}]}`\n * — parse the trailing JSON and surface just the human message, keeping the\n * `\"<App> … returned <status>\"` prefix.\n */\nfunction extractProviderMessage(msg: string): string {\n const brace = msg.indexOf(\"{\");\n if (brace >= 0) {\n try {\n const j = JSON.parse(msg.slice(brace)) as {\n errors?: { message?: string }[];\n error?: { message?: string } | string;\n message?: string;\n };\n const m =\n j?.errors?.[0]?.message ??\n (typeof j?.error === \"object\" ? j.error?.message : j?.error) ??\n j?.message;\n if (typeof m === \"string\" && m.trim()) {\n const prefix = msg.slice(0, brace).replace(/[:\\s]+$/, \"\");\n return prefix ? `${prefix}: ${m.trim()}` : m.trim();\n }\n } catch {\n // Not JSON — fall through and return the message as-is.\n }\n }\n return msg;\n}\n\n/**\n * A failed-invoke error shape, matched by field rather than class identity —\n * ui's own `ApiError` and `@w6w/sdk`'s are two different classes across the\n * package boundary, and `status`+`code` is what both actually carry.\n * Considered mirroring `packages/wrappers/cli/src/exit.ts:60-63`'s `name ===\n * \"ApiError\"` fallback; not adopted — that solves module DUPLICATION of one\n * class, while ui's problem is cross-package IDENTITY, which `status`+`code`\n * already settles.\n */\nfunction isInvokeApiError(\n e: unknown,\n): e is { status: number; code: string; message?: string; body?: unknown; raw?: unknown } {\n return (\n typeof e === \"object\" &&\n e !== null &&\n typeof (e as { status: unknown }).status === \"number\" &&\n typeof (e as { code: unknown }).code === \"string\"\n );\n}\n\n/**\n * Turn a thrown invoke error into a user-facing message. A permission/credential\n * failure at the underlying provider (HTTP 401/403, or the message mentions\n * scopes/forbidden/unauthorized) is stated plainly with what to fix, so the user\n * isn't left staring at a raw upstream JSON blob.\n */\nfunction describeInvokeError(e: unknown): InvokeError {\n if (!isInvokeApiError(e)) {\n return { headline: (e as Error)?.message ?? \"The action failed to run.\" };\n }\n const detail = extractProviderMessage(e.message ?? \"\");\n const haystack = `${e.status} ${e.code} ${e.message ?? \"\"}`.toLowerCase();\n const isPermission =\n e.status === 401 ||\n e.status === 403 ||\n /\\b(401|403)\\b|forbidden|unauthorized|not authorized|permission|scope|access denied|invalid api key|invalid credential/.test(\n haystack,\n );\n if (isPermission) {\n return {\n headline:\n \"Permission denied by the provider — this is a credential/scope problem, not a w6w error.\",\n hint:\n \"The connection's API key is missing the permissions this action needs. Fix it at the \" +\n \"provider — e.g. SendGrid → Settings → API Keys → give the key the required scopes (or Full \" +\n \"Access), or create a new key — then update this connection's credential and try again.\",\n detail,\n };\n }\n return { headline: \"The action returned an error.\", detail };\n}\n\n/**\n * The captured outbound calls the server attached to a failed invoke — ui's\n * own `ApiError` carries them on `body`, `@w6w/sdk`'s on `raw`; read `body ??\n * raw` so either shape's calls surface.\n */\nfunction apiCallsOf(e: unknown): ApiCallRecord[] {\n const source = isInvokeApiError(e)\n ? ((e.body ?? e.raw) as { apiCalls?: ApiCallRecord[] } | null)\n : null;\n return source?.apiCalls ?? [];\n}\n\n/**\n * One Overrides sub-editor's local state (`body`/`query`/`headers`): raw text\n * (the widget's source of truth), the last value that parsed as a plain JSON\n * object, and whether the CURRENT text is invalid. Empty/whitespace text is\n * always valid and means \"not set\" — never blocks Run — matching the\n * requirement that clearing a field returns to \"no override\", not an error.\n *\n * Deliberately re-parses on every keystroke here rather than wiring\n * `JsonEditor`'s own `onValidChange`/`onValidityChange`: that pair reports an\n * emptied field as `{valid: false, error: \"Empty\"}`, which would wrongly keep\n * Run refusing the moment a touched field is cleared back out.\n */\nfunction useOverrideJsonField() {\n const [text, setText] = useState(\"\");\n const [value, setValue] = useState<Record<string, unknown> | undefined>(undefined);\n const [invalid, setInvalid] = useState(false);\n const onChange = (next: string) => {\n setText(next);\n const trimmed = next.trim();\n if (trimmed === \"\") {\n setInvalid(false);\n return;\n }\n try {\n const parsed = JSON.parse(trimmed);\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setValue(parsed as Record<string, unknown>);\n setInvalid(false);\n } else {\n setInvalid(true);\n }\n } catch {\n setInvalid(true);\n }\n };\n return { text, value, invalid, onChange } as const;\n}\n\n/**\n * Schema-driven form to test/run a single action against a connection. Renders\n * the action's declared params through {@link ParamsForm} (the same primitive\n * the step builder uses) instead of a raw JSON textarea, invokes the action via\n * `useW6WApi().invokeAction`, and shows the returned value or error.\n *\n * The selected action is either controlled by the caller (`action` prop) or\n * chosen from a built-in `<select>` over `actions`. Param values reset whenever\n * the selected action changes.\n */\nexport function ActionTestForm({\n appId,\n actions,\n connectionId,\n action,\n seedValues,\n onSavedTestsChanged,\n seedTestId,\n onDirtyChange,\n onTestSaved,\n onDeleted,\n embedded = false,\n}: ActionTestFormProps) {\n const api = useW6WApi();\n\n // Actions sorted for the built-in picker (only used when uncontrolled).\n const sortedActions = useMemo(() => {\n const list = [...actions];\n list.sort((a, b) => (a.title || a.key).localeCompare(b.title || b.key));\n return list;\n }, [actions]);\n\n // Internal selection, used only when the caller doesn't control `action`.\n const [pickedKey, setPickedKey] = useState<string>(action?.key ?? \"\");\n const selectedAction: ActionDef | null =\n action ?? actions.find((a) => a.key === pickedKey) ?? null;\n\n const [running, setRunning] = useState(false);\n const [error, setError] = useState<InvokeError | null>(null);\n const [result, setResult] = useState<unknown>(undefined);\n // The outbound HTTP calls the last run made (redacted request + response).\n // Populated on success AND failure — a wrong payload is usually only visible\n // on the wire, not in the value.\n const [apiCalls, setApiCalls] = useState<ApiCallRecord[]>([]);\n\n // Overrides region (T2.1.1): a RequestOverrides envelope submitted as a\n // fourth field alongside params — architecturally NOT a Param (it never\n // enters `resolveParams`), so it is a SIBLING region to `paramsRegion`\n // rather than a slot inside `ParamsForm`'s \"Additional parameters\"\n // disclosure. See `.claude/docs/overrides.md`.\n const ovBody = useOverrideJsonField();\n const ovQuery = useOverrideJsonField();\n const ovHeaders = useOverrideJsonField();\n const [ovTarget, setOvTarget] = useState<\"\" | \"first\" | \"first-write\" | \"all\">(\"\");\n const [ovMatch, setOvMatch] = useState(\"\");\n // Any sub-editor currently holding invalid JSON blocks the run outright —\n // never send a half-parsed envelope.\n const overridesInvalid = ovBody.invalid || ovQuery.invalid || ovHeaders.invalid;\n // Built fresh from current state on every call — an untouched (or cleared)\n // control leaves every field empty, so this returns `undefined` and the run\n // sends no `overrides` key at all: byte-identical to a request from before\n // this control existed.\n const currentOverrides = (): RequestOverrides | undefined => {\n const out: RequestOverrides = {};\n if (ovBody.text.trim() !== \"\" && ovBody.value !== undefined) out.body = ovBody.value;\n if (ovQuery.text.trim() !== \"\" && ovQuery.value !== undefined) {\n out.query = ovQuery.value as Record<string, string | number | boolean | null>;\n }\n if (ovHeaders.text.trim() !== \"\" && ovHeaders.value !== undefined) {\n out.headers = ovHeaders.value as Record<string, string>;\n }\n if (ovTarget) out.target = ovTarget;\n if (ovMatch.trim() !== \"\") out.match = ovMatch.trim();\n return Object.keys(out).length > 0 ? out : undefined;\n };\n\n // Params view: the schema-driven form, or the whole `values` object as raw JSON.\n const [viewMode, setViewMode] = useState<\"form\" | \"json\">(\"form\");\n const [jsonText, setJsonText] = useState(\"\");\n const [jsonInvalid, setJsonInvalid] = useState(false);\n\n // Pop-out: when open, the params region moves into a larger `Modal` canvas.\n // It is the SAME region bound to the SAME `values`/`setValues`, just relocated,\n // so edits stay in sync with the inline view.\n const [modalOpen, setModalOpen] = useState(false);\n\n // Param values, re-seeded from defaults whenever the selected action changes.\n // On a FRESH MOUNT with `seedValues` present (e.g. a deep-linked saved test),\n // seed from a shallow copy of it rather than defaults — otherwise the seed guard\n // below never fires on first render (`lastSeed` inits to the same ref) and the\n // seeded values are dropped.\n const selectedKey = selectedAction?.key ?? null;\n const initialValues = seedValues ? { ...seedValues } : defaultParamsFor(selectedAction);\n const [valuesByAction, setValuesByAction] = useState<{\n key: string | null;\n values: Record<string, unknown>;\n }>(() => ({\n key: selectedKey,\n values: initialValues,\n }));\n\n // The id of the saved test currently being edited, or `null` for an unsaved\n // test. Drives the PATCH-vs-POST decision in `submitSaveTest`: a set id updates\n // that row in place, `null` creates a new named row. Seeded from `seedTestId`\n // so a studio deep link (`…/test/:testId`) mounts already in edit mode.\n const [editingTestId, setEditingTestId] = useState<string | null>(seedTestId ?? null);\n\n // Dirty baseline: the values as last seeded/loaded/saved. `values` is compared\n // against this to derive the host-facing `dirty` signal (`onDirtyChange`). Reset\n // wherever a fresh set of values is adopted (action change, seed, load, save).\n const [baseline, setBaseline] = useState<Record<string, unknown>>(initialValues);\n\n if (valuesByAction.key !== selectedKey) {\n // Selection changed (controlled or via the picker, without a remount) — reset the\n // form values AND clear any stale result/error carried over from the previously\n // selected action (a 403 from `list-get` must not linger while `mail-send` shows).\n // Editing id: a genuine action-switch starts a fresh unsaved test (→ null), BUT a\n // deep-link whose action arrives AFTER mount is NOT an action-switch — the selected\n // action IS the seeded test's action. A truthy `seedTestId` therefore wins here, so\n // the late null→key transition keeps `editingTestId === seedTestId` (Save PATCHes,\n // Delete shows) instead of clobbering it to null and POSTing a duplicate row.\n const fresh = defaultParamsFor(selectedAction);\n setValuesByAction({ key: selectedKey, values: fresh });\n setBaseline(fresh);\n setEditingTestId(seedTestId ?? null);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n }\n\n // Studio seam: adopt a deep-linked saved-test id. When `seedTestId` changes to a\n // non-null id, make it the current editing id (bottom Save PATCHes, Delete\n // shows); a change to null returns the tester to a fresh/unsaved test.\n const [lastSeedTestId, setLastSeedTestId] = useState<string | null | undefined>(seedTestId);\n if (seedTestId !== lastSeedTestId) {\n setLastSeedTestId(seedTestId);\n setEditingTestId(seedTestId ?? null);\n }\n\n // Studio seam: when a new `seedValues` reference arrives (e.g. \"open a saved\n // test\"), seed the current action's params from a SHALLOW COPY of it. Applied\n // as a render-phase guard like the action-change reseed above; the passed\n // object is never mutated and later edits are free to diverge.\n const [lastSeed, setLastSeed] = useState<Record<string, unknown> | null | undefined>(seedValues);\n if (seedValues !== lastSeed) {\n // Content-aware, not reference-keyed: a `[\"saved-tests\"]` invalidation (fired by\n // onTestSaved/onSavedTestsChanged after a Save) hands back a fresh OBJECT with the\n // SAME content — that must NOT reseed the draft or clear the on-screen Run\n // result/error. Reseed only when the incoming values differ STRUCTURALLY from the\n // last applied seed. `lastSeed` advances to the new ref regardless, so we don't\n // re-compare the same pair every render.\n const structurallyChanged =\n JSON.stringify(seedValues ?? null) !== JSON.stringify(lastSeed ?? null);\n setLastSeed(seedValues);\n if (seedValues && structurallyChanged) {\n const seeded = { ...seedValues };\n setValuesByAction({ key: selectedKey, values: seeded });\n setBaseline(seeded);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n }\n }\n\n const values = valuesByAction.values;\n const setValues = (next: Record<string, unknown>) =>\n setValuesByAction({ key: selectedKey, values: next });\n\n // Host-facing dirty signal: do the current values diverge from the seeded\n // baseline? Compared by structural JSON so a load→edit→revert cycle clears it.\n const dirty = useMemo(\n () => JSON.stringify(values) !== JSON.stringify(baseline),\n [values, baseline],\n );\n // biome-ignore lint/correctness/useExhaustiveDependencies: fire only when `dirty` flips, not on every `onDirtyChange` identity change.\n useEffect(() => {\n onDirtyChange?.(dirty);\n }, [dirty]);\n\n // Entering the JSON view seeds the editor from the current values; edits that\n // parse to a plain object round-trip straight back into `values`.\n const enterJsonView = () => {\n setJsonText(JSON.stringify(values, null, 2));\n setJsonInvalid(false);\n setViewMode(\"json\");\n };\n\n // The single invoke path — used by \"Run action\" and by re-running a saved test.\n const runWith = async (params: Record<string, unknown>) => {\n if (!selectedAction) return;\n // An invalid Overrides sub-editor refuses the run outright — the Run\n // button is also disabled for this, but guard here too so a saved-test\n // re-run (which bypasses the button) can't slip a half-parsed envelope\n // through either.\n if (overridesInvalid) return;\n const actionKey = selectedAction.key;\n setRunning(true);\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n let outcome: { ok: boolean; summary: string; result?: unknown };\n const overrides = currentOverrides();\n try {\n const r = await api.invokeAction(appId, actionKey, params, {\n connectionId,\n ...(overrides ? { overrides } : {}),\n });\n setResult(r.value);\n setApiCalls(r.apiCalls ?? []);\n outcome = { ok: true, summary: \"OK\", result: r.value };\n } catch (e) {\n const err = describeInvokeError(e);\n setError(err);\n // The server returns the captured calls on the error body too — the\n // request that failed is the thing worth looking at.\n setApiCalls(apiCallsOf(e));\n outcome = { ok: false, summary: err.headline };\n } finally {\n setRunning(false);\n }\n // Log every run (success or failure) against the connection, and update the\n // saved test's last-run when this run came from an editing session. Best\n // effort — a logging failure must not mask the run's own result.\n if (connectionId) {\n try {\n await api.recordTestRun(connectionId, {\n savedTestId: editingTestId ?? null,\n actionKey,\n ok: outcome.ok,\n summary: outcome.summary.slice(0, 200),\n result: outcome.result,\n });\n refreshSavedTests();\n refreshRunHistory();\n onSavedTestsChanged?.();\n } catch {\n // Ignore — the run itself already surfaced via result/error.\n }\n }\n };\n const run = () => runWith(values);\n\n // Saved tests for this connection. `nonce` re-triggers the fetch after a\n // create/delete so the rail reflects the change without a full remount.\n const [savedTests, setSavedTests] = useState<SavedTest[] | null>(null);\n const [savedTestsError, setSavedTestsError] = useState<string | null>(null);\n const [savedTestsNonce, setSavedTestsNonce] = useState(0);\n // Name-a-saved-test dialog (in-app Modal — never the browser's prompt()).\n const [nameModalOpen, setNameModalOpen] = useState(false);\n const [pendingName, setPendingName] = useState(\"\");\n // Delete-confirm dialog (in-app ConfirmModal — never the browser's confirm()).\n const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);\n const refreshSavedTests = () => setSavedTestsNonce((n) => n + 1);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `savedTestsNonce` is a deliberate re-fetch trigger, not read inside the effect.\n useEffect(() => {\n if (!connectionId) {\n setSavedTests(null);\n return;\n }\n let canceled = false;\n setSavedTestsError(null);\n api\n .listSavedTests(connectionId)\n .then((list) => !canceled && setSavedTests(list))\n .catch((e) => !canceled && setSavedTestsError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, connectionId, savedTestsNonce]);\n\n // Only this action's saved tests belong on the rail.\n const railTests = selectedKey\n ? (savedTests ?? []).filter((t) => t.actionKey === selectedKey)\n : [];\n\n // Connection run history from the unified `run_log` ledger (F-1). Complements\n // the per-saved-test `lastRun*` badge with the full recent-run list. Fetched\n // via the OPTIONAL `api.listTestRuns` — a consumer that doesn't implement it\n // (studio, until T2.2.2) simply shows no history. `runHistoryNonce` re-triggers\n // the fetch after a run is recorded so the list stays current.\n const [runHistory, setRunHistory] = useState<TestRunSummary[] | null>(null);\n const [runHistoryNonce, setRunHistoryNonce] = useState(0);\n const refreshRunHistory = () => setRunHistoryNonce((n) => n + 1);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `runHistoryNonce` is a deliberate re-fetch trigger, not read inside the effect.\n useEffect(() => {\n const load = api.listTestRuns;\n if (!connectionId || !load) {\n setRunHistory(null);\n return;\n }\n let canceled = false;\n load(connectionId)\n .then((list) => !canceled && setRunHistory(list))\n // Best-effort: a history load failure must never break the tester.\n .catch(() => !canceled && setRunHistory(null));\n return () => {\n canceled = true;\n };\n }, [api, connectionId, runHistoryNonce]);\n\n // History rows for the current action (mirrors the saved-tests rail filter),\n // most-recent first — the server orders newest-first but we don't rely on it.\n const railRunHistory = selectedKey\n ? (runHistory ?? [])\n .filter((r) => r.actionKey === selectedKey)\n .slice()\n .sort((a, b) => Date.parse(b.occurredAt) - Date.parse(a.occurredAt))\n : [];\n\n // Open the in-app name dialog to save the current params as a NEW named test.\n const openSaveModal = () => {\n if (!connectionId || !selectedAction) return;\n setPendingName(\"\");\n setSavedTestsError(null);\n setNameModalOpen(true);\n };\n // Bottom Save affordance. When a saved test is loaded for editing\n // (`editingTestId` set) the save is a silent PATCH — no throwaway name dialog\n // (FU-1). With no editing id, open the name dialog to create a new named row.\n const handleSaveClick = () => {\n if (!connectionId || !selectedAction) return;\n if (editingTestId) {\n void submitSaveTest();\n } else {\n openSaveModal();\n }\n };\n // Persist the current params. When a saved test is loaded for editing\n // (`editingTestId` set), PATCH that row in place — updating only `values` keeps\n // its name and sidesteps the 409 duplicate-name guard a re-POST would trip.\n // With no editing id, create a new named row from the dialog and remember its\n // id so the next save updates in place rather than spawning a second row.\n const submitSaveTest = async () => {\n if (!connectionId || !selectedAction) return;\n try {\n let saved: SavedTest;\n if (editingTestId) {\n saved = await api.updateSavedTest(connectionId, editingTestId, { values });\n } else {\n const name = pendingName.trim();\n if (!name) return;\n saved = await api.createSavedTest(connectionId, {\n actionKey: selectedAction.key,\n name,\n values,\n });\n setEditingTestId(saved.id);\n }\n // The just-saved values are the new clean baseline (dirty → false).\n setBaseline({ ...values });\n setNameModalOpen(false);\n setPendingName(\"\");\n refreshSavedTests();\n onSavedTestsChanged?.();\n onTestSaved?.(saved);\n } catch (e) {\n setSavedTestsError((e as Error).message);\n }\n };\n\n // Load a saved test's values into the form (shallow copy — never mutate the\n // stored row). Clicking a saved test's name loads it for editing: values +\n // editing id are adopted and the load becomes the new clean baseline.\n const loadSavedTest = (t: SavedTest) => {\n const loaded = { ...t.values };\n setValuesByAction({ key: selectedKey, values: loaded });\n setBaseline(loaded);\n // Remember which row is being edited so a subsequent save PATCHes it in place.\n setEditingTestId(t.id);\n setViewMode(\"form\");\n setError(null);\n setResult(undefined);\n setApiCalls([]);\n };\n // Delete the saved test currently being edited (Delete only shows with an\n // editing id set). Clears the editing id so the form drops to unsaved state.\n const deleteCurrentTest = async () => {\n if (!connectionId || !editingTestId) return;\n const deletedId = editingTestId;\n try {\n await api.deleteSavedTest(connectionId, deletedId);\n setEditingTestId(null);\n refreshSavedTests();\n onSavedTestsChanged?.();\n // Host hook: let the URL-driven host (studio's ConnectionTesterModal) navigate\n // away from the now-dead `…/test/:deletedId` deep link.\n onDeleted?.(deletedId);\n } catch (e) {\n setSavedTestsError((e as Error).message);\n }\n };\n\n // The params region: the form↔JSON toggle plus the ParamsForm/JsonEditor block.\n // Rendered in exactly one place at a time — inline when the pop-out is closed,\n // inside the `Modal` when it's open — so there's a single instance bound to the\n // single `values`/`setValues` state (no copy-on-open, edits stay in sync).\n const paramsRegion = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1-5)\" }}>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Parameters</span>\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1)\" }}>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${viewMode === \"form\" ? \" active\" : \"\"}`}\n aria-pressed={viewMode === \"form\"}\n onClick={() => setViewMode(\"form\")}\n >\n Form\n </button>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${viewMode === \"json\" ? \" active\" : \"\"}`}\n aria-pressed={viewMode === \"json\"}\n onClick={enterJsonView}\n >\n JSON\n </button>\n {/* Pop-out toggle — suppressed in embedded mode: the host already\n provides full-screen modal chrome, so a modal-in-modal ⤢ is redundant. */}\n {!embedded && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-sm w6w-btn-ghost\"\n aria-pressed={modalOpen}\n title={\n modalOpen ? \"Collapse the params editor\" : \"Open the params editor in a larger view\"\n }\n aria-label={\n modalOpen ? \"Collapse the params editor\" : \"Open the params editor in a larger view\"\n }\n onClick={() => setModalOpen((v) => !v)}\n >\n {modalOpen ? \"⤡\" : \"⤢\"}\n </button>\n )}\n </div>\n </div>\n\n {viewMode === \"form\" ? (\n <ParamsForm params={selectedAction?.params ?? []} values={values} onChange={setValues} />\n ) : (\n <>\n <JsonEditor\n value={jsonText}\n onChange={setJsonText}\n minHeight={modalOpen ? \"50vh\" : \"200px\"}\n aria-label=\"Params JSON\"\n onValidChange={(parsed) => {\n // Only a JSON object maps onto the params `values` record; ignore a\n // bare array/scalar so `values` stays a plain key→value object.\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setValues(parsed as Record<string, unknown>);\n }\n }}\n onValidityChange={({ valid }) => setJsonInvalid(!valid)}\n />\n {jsonInvalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </>\n )}\n </div>\n );\n\n // The Overrides region: a sibling to `paramsRegion`, never nested inside it\n // (and never inside `ParamsForm`'s own \"Additional parameters\" disclosure —\n // `overrides` is not a Param). Collapsed by default via `<details>`, reusing\n // the same `.w6w-section` disclosure `SectionField` renders for a\n // `section: \"collapsible\"` param, since this is the identical visual shape\n // (titled, collapsed-by-default disclosure) applied to a hand-built control\n // instead of a schema-driven one.\n const overridesRegion = (\n <details className=\"w6w-section\" data-testid=\"overrides-region\">\n <summary className=\"w6w-section-summary\">\n <span className=\"w6w-section-title\">Overrides</span>\n <span className=\"w6w-section-subtitle\">\n Reach a vendor field this action's own params don't declare\n </span>\n </summary>\n <div className=\"w6w-stack w6w-section-body\" style={{ gap: \"var(--w6w-sp-2)\" }}>\n <div className=\"w6w-field\">\n <span>Body</span>\n <JsonEditor\n value={ovBody.text}\n onChange={ovBody.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides body (JSON)\"\n />\n {ovBody.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <div className=\"w6w-field\">\n <span>Query</span>\n <JsonEditor\n value={ovQuery.text}\n onChange={ovQuery.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides query (JSON)\"\n />\n {ovQuery.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <div className=\"w6w-field\">\n <span>Headers</span>\n <JsonEditor\n value={ovHeaders.text}\n onChange={ovHeaders.onChange}\n minHeight=\"80px\"\n aria-label=\"Overrides headers (JSON)\"\n />\n {ovHeaders.invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </div>\n <label className=\"w6w-field\">\n <span>Target</span>\n <select\n aria-label=\"Overrides target\"\n value={ovTarget}\n onChange={(e) => setOvTarget(e.target.value as typeof ovTarget)}\n >\n <option value=\"\">— default (first) —</option>\n <option value=\"first\">first</option>\n <option value=\"first-write\">first-write</option>\n <option value=\"all\">all</option>\n </select>\n </label>\n <label className=\"w6w-field\">\n <span>Match</span>\n <input\n type=\"text\"\n aria-label=\"Overrides match\"\n value={ovMatch}\n placeholder=\"Restrict to requests whose URL contains…\"\n onChange={(e) => setOvMatch(e.target.value)}\n />\n </label>\n <span className=\"w6w-hint\">\n Merged onto the outbound request at the wire, never into the params above — name a field\n the way the vendor's own API documents it.\n </span>\n </div>\n </details>\n );\n\n // The saved-tests rail — the right pane of the pop-out. Only meaningful when a\n // connection is fixed; hidden entirely otherwise (guarded on `connectionId`).\n const savedTestsRail = connectionId ? (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1-5)\" }}>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Saved tests</span>\n </div>\n {savedTestsError && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n {savedTestsError}\n </span>\n )}\n {railTests.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">No saved tests for this action yet.</p>\n ) : (\n <ul\n className=\"w6w-stack\"\n style={{ listStyle: \"none\", margin: 0, padding: 0, gap: \"var(--w6w-sp-1-5)\" }}\n >\n {railTests.map((t) => (\n <li key={t.id}>\n {/* Clicking a saved test loads it for editing — no per-row\n Load/Run/Delete buttons; those actions live at the modal bottom.\n Subtitle shows the last run (✓/✗ + relative time), falling back\n to the last-saved time when the test has never been run. */}\n <ListItem\n title={t.name}\n subtitle={\n t.lastRunAt ? (\n <span>\n <span\n style={{ color: t.lastRunOk ? \"var(--w6w-success)\" : \"var(--w6w-danger)\" }}\n >\n {t.lastRunOk ? \"✓\" : \"✗\"}\n </span>{\" \"}\n {t.lastRunSummary ? `${t.lastRunSummary} · ` : \"\"}\n {relativeTime(t.lastRunAt)}\n </span>\n ) : (\n `saved ${relativeTime(t.updatedAt)}`\n )\n }\n active={t.id === editingTestId}\n onClick={() => loadSavedTest(t)}\n />\n </li>\n ))}\n </ul>\n )}\n\n {/* Run history (F-1): the connection's recent tester runs for this action,\n from the unified `run_log` ledger. Read-only rows (no onClick) — this is\n a log, not a loadable input like the saved tests above. Only rendered\n when the api exposes `listTestRuns` (optional member) and there is\n history to show, so a consumer without it degrades to no section. */}\n {api.listTestRuns && railRunHistory.length > 0 && (\n <>\n <div\n className=\"w6w-field-labelrow\"\n style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}\n >\n <span className=\"w6w-muted w6w-small\">Recent runs</span>\n </div>\n <ul\n className=\"w6w-stack\"\n style={{ listStyle: \"none\", margin: 0, padding: 0, gap: \"var(--w6w-sp-1-5)\" }}\n >\n {railRunHistory.map((r) => (\n <li key={r.id}>\n <ListItem\n title={\n <span>\n <span style={{ color: r.ok ? \"var(--w6w-success)\" : \"var(--w6w-danger)\" }}>\n {r.ok ? \"✓\" : \"✗\"}\n </span>{\" \"}\n {r.actionKey}\n </span>\n }\n subtitle={\n <span>\n {r.summary ? `${r.summary} · ` : \"\"}\n {relativeTime(r.occurredAt)}\n </span>\n }\n />\n </li>\n ))}\n </ul>\n </>\n )}\n </div>\n ) : null;\n\n // Nullable: `editingTestId` can be seeded from a studio deep link before\n // `savedTests` itself has finished fetching, so this may not resolve yet.\n const deletingTestName = savedTests?.find((t) => t.id === editingTestId)?.name;\n\n return (\n <div className={`w6w-stack${embedded ? \" w6w-tester-embedded-root\" : \"\"}`}>\n {/* Action picker — only when the caller isn't controlling the selection. */}\n {!action &&\n (actions.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">This app exposes no actions.</p>\n ) : (\n // biome-ignore lint/a11y/noLabelWithoutControl: Combobox renders its own <select>/<input> INSIDE this label, so the field text labels the control at runtime; the rule cannot see through the component boundary.\n <label className=\"w6w-field\">\n <span>Action{selectedKey ? \"\" : \" *\"}</span>\n <Combobox\n value={pickedKey}\n placeholder=\"— pick an action —\"\n onChange={setPickedKey}\n options={sortedActions.map((a) => ({\n value: a.key,\n label: `${a.title ?? a.key} (${a.key})`,\n }))}\n />\n </label>\n ))}\n\n {selectedAction ? (\n <>\n <div>\n <strong>\n {selectedAction.title ?? selectedAction.key}{\" \"}\n <code className=\"w6w-muted\">{selectedAction.key}</code>\n </strong>\n {selectedAction.description && (\n <p className=\"w6w-muted w6w-small\" style={{ margin: \"var(--w6w-sp-0-5) 0 0\" }}>\n {selectedAction.description}\n </p>\n )}\n </div>\n\n {(() => {\n // The scrollable tester content: params editor + error + result. Shared\n // by every layout (inline body, pop-out modal, embedded footer layout)\n // so it stays a single instance bound to the single `values` state.\n const paramsAndResult = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-3)\" }}>\n {paramsRegion}\n {overridesRegion}\n {error && (\n <div className=\"w6w-result w6w-error\">\n <strong>{error.headline}</strong>\n {error.hint && (\n <div style={{ marginTop: \"var(--w6w-sp-1-5)\" }}>{error.hint}</div>\n )}\n {error.detail && (\n <div\n className=\"w6w-muted w6w-small\"\n style={{\n marginTop: \"var(--w6w-sp-1-5)\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {error.detail}\n </div>\n )}\n </div>\n )}\n {result !== undefined && (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-1)\" }}>\n <strong className=\"w6w-small\">Result</strong>\n <pre className=\"w6w-result\">{JSON.stringify(result, null, 2)}</pre>\n </div>\n )}\n <ApiCallsPanel calls={apiCalls} />\n </div>\n );\n // Bottom-anchored actions: Run / Save always; Delete only when an\n // editing id is set (an already-saved test is loaded). In embedded mode\n // this becomes a bottom-pinned, bordered footer outside the scroll region.\n const actionBar = (\n <div\n className={`w6w-tester-actions${\n embedded || modalOpen ? \" w6w-tester-actions-footer\" : \"\"\n }`}\n style={{ display: \"flex\", gap: \"var(--w6w-sp-2)\" }}\n >\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={running || overridesInvalid}\n onClick={run}\n >\n {running ? \"Running…\" : \"Run action\"}\n </button>\n {connectionId && (\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={handleSaveClick}>\n Save test\n </button>\n )}\n {connectionId && editingTestId && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n style={{ marginLeft: \"auto\", color: \"var(--w6w-danger)\" }}\n onClick={() => setConfirmDeleteOpen(true)}\n >\n Delete\n </button>\n )}\n </div>\n );\n // The tester body: params + result + actions, stacked. Rendered inline\n // when the pop-out modal is closed, and inside the pop-out modal (left\n // pane, saved-tests rail on the right) when open.\n const body = (\n <div className=\"w6w-stack\" style={{ gap: \"var(--w6w-sp-3)\" }}>\n {paramsAndResult}\n {actionBar}\n </div>\n );\n // Host-embedded: the host owns the modal chrome, so fill it as a\n // full-height flex column — params + saved-tests rail scroll, the action\n // bar is pinned to the bottom as a non-scrolling footer.\n if (embedded) {\n return (\n <div className=\"w6w-tester-embedded\">\n <div className=\"w6w-tester-embedded-scroll\">\n {savedTestsRail ? (\n <div className=\"w6w-tester-embedded-cols\">\n <div className=\"w6w-tester-embedded-main\">{paramsAndResult}</div>\n <div className=\"w6w-tester-embedded-rail\">{savedTestsRail}</div>\n </div>\n ) : (\n paramsAndResult\n )}\n </div>\n {actionBar}\n </div>\n );\n }\n return modalOpen ? (\n <Modal\n title={`Edit params — ${selectedAction.title ?? selectedAction.key}`}\n onClose={() => setModalOpen(false)}\n size=\"full\"\n >\n {/* The pop-out's own internal scroll boundary (T1.4.1 round 2): with\n `-full`'s `overflow: hidden` live, the dialog itself no longer\n scrolls, so params + result (+ the saved-tests rail) get a\n dedicated scroll region here and the action bar stays a pinned\n footer below it — mirrors `.w6w-tester-embedded-scroll`'s\n mechanism (see styles.css), just for this own-pop-out layout\n instead of the host-embedded one. */}\n <div className=\"w6w-tester-popout\">\n <div className=\"w6w-tester-popout-scroll\">\n {savedTestsRail ? (\n <div\n style={{\n display: \"flex\",\n gap: \"var(--w6w-sp-4)\",\n alignItems: \"flex-start\",\n }}\n >\n <div style={{ flex: 1, minWidth: 0 }}>{paramsAndResult}</div>\n <div style={{ width: 260, flexShrink: 0 }}>{savedTestsRail}</div>\n </div>\n ) : (\n paramsAndResult\n )}\n </div>\n {actionBar}\n </div>\n </Modal>\n ) : (\n body\n );\n })()}\n\n {nameModalOpen && (\n <Modal title=\"Save test\" onClose={() => setNameModalOpen(false)}>\n <form\n className=\"w6w-stack\"\n style={{ gap: \"var(--w6w-sp-3)\" }}\n onSubmit={(e) => {\n e.preventDefault();\n void submitSaveTest();\n }}\n >\n <label className=\"w6w-field\">\n <span>Name this saved test</span>\n <input\n type=\"text\"\n value={pendingName}\n placeholder=\"e.g. valid sender\"\n onChange={(e) => setPendingName(e.target.value)}\n />\n </label>\n {savedTestsError && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n {savedTestsError}\n </span>\n )}\n <div\n style={{ display: \"flex\", gap: \"var(--w6w-sp-2)\", justifyContent: \"flex-end\" }}\n >\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setNameModalOpen(false)}\n >\n Cancel\n </button>\n <button type=\"submit\" className=\"w6w-btn\" disabled={!pendingName.trim()}>\n Save\n </button>\n </div>\n </form>\n </Modal>\n )}\n\n {confirmDeleteOpen && (\n <ConfirmModal\n title=\"Delete saved test\"\n message={\n deletingTestName\n ? `Delete \"${deletingTestName}\"? This cannot be undone.`\n : \"Delete this saved test? This cannot be undone.\"\n }\n confirmLabel=\"Delete\"\n onConfirm={() => {\n setConfirmDeleteOpen(false);\n void deleteCurrentTest();\n }}\n onClose={() => setConfirmDeleteOpen(false)}\n />\n )}\n </>\n ) : (\n !action && <p className=\"w6w-muted w6w-small\">Pick an action above to test it.</p>\n )}\n </div>\n );\n}\n","import { yaml } from \"@codemirror/lang-yaml\";\nimport { EditorView } from \"@codemirror/view\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { useMemo } from \"react\";\nimport { CheckGlyph, CopyGlyph } from \"./components/Copyable.tsx\";\nimport { useCopyToClipboard } from \"./components/use-copy.ts\";\nimport { useEffectiveTheme } from \"./theme.ts\";\nimport type { ThemeMode } from \"./types.ts\";\n\nexport interface YamlEditorProps {\n value: string;\n onChange: (value: string) => void;\n\n /** Placeholder text shown when value is empty. */\n placeholder?: string;\n /** Minimum editor height. Defaults to \"240px\". */\n minHeight?: string;\n /** Maximum editor height before scrolling. Defaults to no cap. */\n maxHeight?: string;\n /**\n * Explicit editor height. Pass `\"100%\"` to fill a flex parent (the whole-config\n * \"code\" view). Omit to let the editor grow with its content between\n * `minHeight` and `maxHeight` — an inline YAML/group field wants this.\n */\n height?: string;\n\n /** Read-only mode — useful for previewing a stored definition. */\n readOnly?: boolean;\n\n /**\n * Explicit theme. If omitted, the editor auto-detects `data-theme` on\n * `<html>` and falls back to `prefers-color-scheme` — same behavior as\n * `<AppIcon>`. Uses CodeMirror's built-in one-dark for dark mode.\n */\n theme?: ThemeMode;\n\n /** Accessible label for the editor. */\n \"aria-label\"?: string;\n\n /**\n * Render an in-box copy-to-clipboard button, a direct child of this\n * component's own `.w6w-yaml-editor` wrapper (sibling to the CodeMirror\n * mount — no extra DOM node). Copies the current `value` verbatim.\n *\n * Off by default: the other mounts of this component must render byte-\n * identically to before this prop existed.\n */\n copyable?: boolean;\n}\n\n/**\n * YAML editor built on CodeMirror 6. Syntax highlighting, folding, gutter,\n * and line numbers. Themed with the `--w6w-*` custom properties so it\n * inherits from the consumer's palette.\n *\n * ```tsx\n * <YamlEditor value={text} onChange={setText} minHeight=\"320px\" />\n * ```\n */\nexport function YamlEditor(props: YamlEditorProps) {\n const theme = useEffectiveTheme(props.theme);\n // Only mounted when `copyable` is on, but the hook itself must run\n // unconditionally (Rules of Hooks) — it is inert (no button, no listener)\n // until `copy()` is actually invoked from the button below.\n const { copied, copy } = useCopyToClipboard(props.value);\n const extensions = useMemo(\n () => [\n yaml(),\n EditorView.theme({\n \"&\": {\n fontSize: \"13px\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n backgroundColor: \"var(--w6w-panel-2)\",\n color: \"var(--w6w-text)\",\n border: \"1px solid var(--w6w-border)\",\n borderRadius: \"8px\",\n },\n \"&.cm-focused\": { outline: \"2px solid var(--w6w-accent)\" },\n \".cm-gutters\": {\n backgroundColor: \"var(--w6w-panel)\",\n color: \"var(--w6w-muted)\",\n border: \"none\",\n borderRight: \"1px solid var(--w6w-border)\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n }),\n ],\n [],\n );\n\n function handleChange(next: string) {\n props.onChange(next);\n }\n\n return (\n <div className=\"w6w-yaml-editor\" aria-label={props[\"aria-label\"] ?? \"YAML editor\"}>\n <CodeMirror\n value={props.value}\n onChange={handleChange}\n extensions={extensions}\n placeholder={props.placeholder}\n readOnly={props.readOnly}\n // `readOnly` alone only blocks CodeMirror's own transactions\n // (`EditorState.readOnly`) — it leaves the content DOM\n // `contenteditable=\"true\"`, so a screen reader / a11y test still sees\n // it as an editable field. `editable` is the separate switch that\n // actually sets `contenteditable` (`EditorView.editable`); tying it to\n // `readOnly` here makes the prop mean what its name says.\n editable={!props.readOnly}\n theme={theme}\n height={props.height}\n minHeight={props.minHeight ?? \"240px\"}\n maxHeight={props.maxHeight}\n basicSetup={{\n lineNumbers: true,\n foldGutter: true,\n highlightActiveLine: !props.readOnly,\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n }}\n />\n {props.copyable && (\n <>\n <button\n type=\"button\"\n className={`w6w-icon-btn w6w-copyable-btn${copied ? \" is-copied\" : \"\"}`}\n aria-label=\"Copy\"\n onClick={() => void copy()}\n >\n {copied ? <CheckGlyph /> : <CopyGlyph />}\n </button>\n {/* Same live-region convention as `Copyable.tsx:141-147`: the\n button's accessible name stays constant, so this announces the\n result. */}\n <span className=\"w6w-copyable-status\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </span>\n </>\n )}\n </div>\n );\n}\n","import { Copyable } from \"./Copyable.tsx\";\n\n/** The single truncation marker every crop arm uses — matches\n * `studio/src/lib/page-title.ts:53-56`'s convention (one `…`, U+2026, never\n * three periods). */\nconst MARKER = \"…\";\n\n/**\n * Truncate `value` on a character budget, keeping `chars` VALUE characters and\n * adding {@link MARKER} on top (the marker is extra, not counted against\n * `chars`) — mirrors `page-title.ts`'s `clamp()` in STYLE (a single budget,\n * slice + marker, pure) but NOT its arithmetic: `clamp` slices at\n * `MAX - 1` so its marker counts inside the budget, which is the wrong shape\n * here (see `CopyableText.test.ts`'s fixture table).\n *\n * `chars` omitted, less than 1, or covering the whole value: returned as-is,\n * no marker.\n */\nexport function cropText(\n value: string,\n chars?: number,\n crop: \"start\" | \"end\" | \"middle\" = \"end\",\n): string {\n if (chars === undefined || chars < 1 || chars >= value.length) return value;\n\n if (crop === \"start\") {\n return `${MARKER}${value.slice(value.length - chars)}`;\n }\n if (crop === \"end\") {\n return `${value.slice(0, chars)}${MARKER}`;\n }\n\n // middle\n const head = Math.ceil(chars / 2);\n const tail = chars - head;\n return `${value.slice(0, head)}${MARKER}${value.slice(value.length - tail)}`;\n}\n\nexport interface CopyableTextProps {\n /** The full string. Always what gets written to the clipboard, regardless\n * of how much of it the cropped display shows. */\n value: string;\n /** How many VALUE characters to show. Omitted, `< 1`, or `>= value.length`\n * ⇒ shown in full. */\n chars?: number;\n /** Where the marker goes. Default `\"end\"`. */\n crop?: \"start\" | \"end\" | \"middle\";\n /** Accessible name of the copy button. Default \"Copy\" (per `Copyable`). */\n label?: string;\n className?: string;\n /** Forwarded to `Copyable`. See its own doc for the revert-delay caveat. */\n copiedMs?: number;\n}\n\n/**\n * A chrome-less, croppable copy-to-clipboard text — for a value too long to\n * show in full inline (an id, a token, a URL fragment) that still needs to be\n * copyable exactly.\n *\n * Composes `Copyable` rather than widening it (`Copyable`'s box chrome has 9\n * existing call sites depending on it) — `readOnly` + the\n * `.w6w-copyable--bare` modifier (`_copyable.scss`) strip the box, and the\n * FULL `value` is what `Copyable` receives, so a click always copies the\n * whole string even when the display is cropped. No `navigator.clipboard`\n * call lives in this file — that stays `Copyable`'s alone.\n */\nexport function CopyableText(props: CopyableTextProps) {\n const { value, chars, crop = \"end\", label, className, copiedMs } = props;\n const cropped = cropText(value, chars, crop);\n const classes = [\"w6w-copyable--bare\", className].filter(Boolean).join(\" \");\n\n return (\n <Copyable value={value} readOnly label={label} className={classes} copiedMs={copiedMs}>\n <span>{cropped}</span>\n </Copyable>\n );\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * The four health states a probe can report — a thin LOCAL copy of the RFC's\n * `HealthReport.state` union. `@w6w/ui` deliberately keeps a small literal type\n * here rather than depend on `@w6w/types`, so the display component stays a\n * pure-presentation leaf with no transport/spec coupling.\n */\nexport type HealthPillState = \"ok\" | \"degraded\" | \"down\" | \"unknown\";\n\nexport interface HealthStatusPillProps {\n /** Which health state to render — drives the colour + default label. */\n state: HealthPillState;\n /** Override the visible text (defaults to a humanised form of `state`). */\n label?: ReactNode;\n /** Accessible label for the pill (falls back to the visible text). */\n ariaLabel?: string;\n}\n\nconst DEFAULT_LABELS: Record<HealthPillState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\n/**\n * A small, theme-aware status pill for a single health state.\n *\n * Renders a coloured dot + label using the `--w6w-health-*` tokens, so a host\n * can restyle every state by overriding those custom properties (see\n * `styles.css`). Colour is never the only signal — the text label carries the\n * same meaning for accessibility.\n */\nexport function HealthStatusPill({ state, label, ariaLabel }: HealthStatusPillProps) {\n const text = label ?? DEFAULT_LABELS[state];\n\n return (\n <span className={`w6w-health-pill w6w-health-pill-${state}`} aria-label={ariaLabel}>\n <span className=\"w6w-health-pill-dot\" aria-hidden=\"true\" />\n <span className=\"w6w-health-pill-label\">{text}</span>\n </span>\n );\n}\n","/**\n * The four states a single day of the strip can be in — a thin LOCAL copy of the\n * RFC's `HealthReport.state` union, exactly as `HealthStatusPill` keeps one. The\n * duplication is deliberate: it keeps `@w6w/ui` a pure-presentation leaf with no\n * transport/spec coupling, so nothing here has to move when the spec package does.\n *\n * There is no fifth state. A day on which the account made no calls at all is\n * `unknown`, never `ok` — an unverified day must never be presented as a healthy\n * one (`rfcs/healthcheck.md`: `unknown` ranks above `ok` for that reason).\n */\nexport type UptimeCellState = \"ok\" | \"degraded\" | \"down\" | \"unknown\";\n\n/** One cell: the day it stands for, and the state already decided for it. */\nexport interface UptimeDay {\n /** The day this cell represents, e.g. `2026-07-27`. Shown verbatim in the tooltip. */\n day: string;\n /** The state for that day. The strip renders it; it never decides it. */\n state: UptimeCellState;\n /** Tooltip override. Defaults to `<day> — <state label>`. */\n label?: string;\n}\n\nexport interface UptimeStripProps {\n /**\n * The days to render, oldest first, one cell each. The component makes no\n * assumption about how many there are — a caller showing a 30-day window\n * passes 30, and a younger account can pass fewer.\n */\n days: UptimeDay[];\n /**\n * Accessible label for the strip as a whole (it is exposed as one image, not\n * as N unlabelled boxes). Defaults to `<n>-day status`.\n */\n ariaLabel?: string;\n}\n\nconst STATE_LABELS: Record<UptimeCellState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\n/**\n * A fixed-height strip of one cell per day, for \"how has this service behaved\n * lately\" at a glance.\n *\n * Purely presentational — it is handed an array of ALREADY-DECIDED states and\n * renders exactly those. No rules, no roll-up and no judgement about what counts\n * as broken live in this package; whatever decided the states owns that.\n *\n * Colour is never the only signal (same rule as `HealthStatusPill`, which pairs\n * its dot with a text label). Thirty cells cannot carry thirty labels, so the\n * strip signals twice in two other ways:\n * - every cell carries a `title` with its day and state, and\n * - the FILL HEIGHT encodes severity, so the row survives greyscale and\n * colour-blind viewing: `ok` is a short baseline bar, `degraded` a taller\n * one, `down` fills the cell, and `unknown` is a hatched outline with no\n * solid fill at all (nothing was measured — it is not a good day and not a\n * bad one).\n *\n * Colour itself comes from the shared `--w6w-health-*` tokens through the single\n * `--w6w-health-color` indirection the health pill uses, so a host that\n * overrides a token restyles the pill and the strip together.\n */\nexport function UptimeStrip({ days, ariaLabel }: UptimeStripProps) {\n if (days.length === 0) return null;\n\n return (\n <div\n className=\"w6w-uptime-strip\"\n role=\"img\"\n aria-label={ariaLabel ?? `${days.length}-day status`}\n >\n {days.map((entry, i) => (\n <span\n // Days are expected to be unique, but the index keeps the key stable\n // even if a caller repeats one — same guard as `ApiCallsPanel`.\n key={`${entry.day}-${i}`}\n className={`w6w-uptime-cell w6w-uptime-cell-${entry.state}`}\n title={entry.label ?? `${entry.day} — ${STATE_LABELS[entry.state]}`}\n />\n ))}\n </div>\n );\n}\n","/**\n * Pure formatting + geometry helpers for the server-resources family, kept in\n * their own module so they carry no React and can be unit-tested on their own.\n *\n * `ServerResourceSample` is a thin LOCAL copy of the sampler's wire sample\n * (`plan.md` §Pinned wire) — the same deliberate duplication `UptimeStrip.tsx`\n * keeps of the health union, and for the same reason: it keeps `@w6w/ui` a\n * pure-presentation leaf with no transport/spec coupling, so nothing here has\n * to move when the server's payload grows a field.\n *\n * Every helper is TOTAL: an unknown number is never rendered as `0`, it is\n * rendered as an em dash. A node whose CPU reading is missing must not read as\n * an idle node.\n */\n\n/** One sample of the host's resource usage, exactly as the server sends it. */\nexport interface ServerResourceSample {\n /** ISO-8601 instant the sample was taken. */\n ts: string;\n cpus: number | null;\n cpuLimit: number | null;\n load1: number | null;\n load5: number | null;\n load15: number | null;\n memoryTotal: number | null;\n memoryAvailable: number | null;\n memoryLimit: number | null;\n processRss: number | null;\n processHeapUsed: number | null;\n processHeapTotal: number | null;\n}\n\n/** What an unknown value renders as. Never `0`, never an empty cell. */\nconst UNKNOWN = \"—\";\n\n/** Binary magnitude suffixes, index-aligned with the 1024ᵏ divisor. */\nconst BYTE_UNITS = [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\"] as const;\n\n/**\n * A byte count as a short human string: exact bytes below 1 KiB (`1023 B`),\n * one decimal place per binary magnitude from KiB up (`1.5 KiB`, `15.6 GiB`).\n * `null` (nothing measured) is `—`.\n */\nexport function formatBytes(n: number | null): string {\n if (n === null || !Number.isFinite(n)) return UNKNOWN;\n if (n < 1024) return `${Math.round(n)} B`;\n\n let value = n;\n let unit = 0;\n while (value >= 1024 && unit < BYTE_UNITS.length - 1) {\n value /= 1024;\n unit += 1;\n }\n return `${value.toFixed(1)} ${BYTE_UNITS[unit]}`;\n}\n\n/**\n * A 0…1-ish fraction as a whole-percent string (`0.123` → `12%`). Not clamped:\n * a load above the CPU count is real and reads `135%`. `null` is `—`.\n */\nexport function formatPercent(f: number | null): string {\n if (f === null || !Number.isFinite(f)) return UNKNOWN;\n return `${Math.round(f * 100)}%`;\n}\n\n/**\n * `load1` against the effective CPU budget — the container's `cpuLimit` when\n * the server set one, otherwise the host CPU count. `null` when either operand\n * is unknown or the divisor is ≤ 0 (a zero-CPU budget is not \"0% busy\", it is\n * \"not measurable\").\n */\nexport function cpuLoadFraction(s: ServerResourceSample | undefined): number | null {\n if (s === undefined) return null;\n if (s.load1 === null) return null;\n const divisor = s.cpuLimit ?? s.cpus;\n if (divisor === null || divisor <= 0) return null;\n return s.load1 / divisor;\n}\n\n/**\n * Used memory as a fraction of total: `(memoryTotal − memoryAvailable) /\n * memoryTotal`. `null` when either operand is unknown or the total is ≤ 0.\n */\nexport function memoryUsedFraction(s: ServerResourceSample | undefined): number | null {\n if (s === undefined) return null;\n const { memoryTotal, memoryAvailable } = s;\n if (memoryTotal === null || memoryAvailable === null) return null;\n if (memoryTotal <= 0) return null;\n return (memoryTotal - memoryAvailable) / memoryTotal;\n}\n\n/** `v` pinned into `[lo, hi]`. */\nfunction clamp(v: number, lo: number, hi: number): number {\n if (v < lo) return lo;\n return v > hi ? hi : v;\n}\n\n/**\n * The `points` attribute of a sparkline polyline, hand-drawn — this package\n * has no chart dependency on purpose (D-5), and a polyline over ~60 samples\n * does not justify one.\n *\n * The x axis is positional (`i / (n − 1) · width`), so a gap in the series\n * still advances the line; `y` is inverted (SVG grows downward) and scaled\n * against `max`. Nulls are SKIPPED, not plotted as zero, and a series of fewer\n * than two values has no line at all (`\"\"` — a single point is not a shape).\n * `max ≤ 0` flattens the line along the baseline rather than dividing by it.\n *\n * Every coordinate is rounded to two decimals so the attribute stays short and\n * a snapshot of it stays readable.\n */\nexport function sparklinePoints(\n values: readonly (number | null)[],\n width: number,\n height: number,\n max: number,\n): string {\n const n = values.length;\n if (n < 2) return \"\";\n\n const points: string[] = [];\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (v === null) continue;\n const x = (i / (n - 1)) * width;\n const y = max <= 0 ? height : height - (clamp(v, 0, max) / max) * height;\n points.push(`${Number(x.toFixed(2))},${Number(y.toFixed(2))}`);\n }\n return points.join(\" \");\n}\n","/**\n * The server-resources display family — four PURE PRESENTATIONAL variants over\n * the same array of samples: a large card, a small card, a left-rail strip and\n * a header badge.\n *\n * There is no data layer here, on purpose (plan.md §Pinned decisions: \"no\n * transport in ui\"): every variant is handed `samples` and renders the LAST\n * one, plus a sparkline drawn from the whole array. Nothing in this file reads\n * a network, a context or a host API — the caller owns the stream and the\n * operator gate.\n *\n * The sparkline is hand-rolled inline SVG rather than a chart dependency: a\n * polyline over ~60 points is a dozen lines of arithmetic (see\n * `sparklinePoints`), and `@w6w/ui` carrying recharts or d3 for it would be\n * unjustified weight for every consumer (D-5).\n *\n * An unknown value is never rendered as `0` — it is the em dash `formatBytes` /\n * `formatPercent` return for `null`. An unreported CPU reading must not read as\n * an idle node. The same applies to `samples: []`: every variant still renders\n * (all dashes, no line), so a caller never has to branch before mounting.\n */\nimport {\n type ServerResourceSample,\n cpuLoadFraction,\n formatBytes,\n formatPercent,\n memoryUsedFraction,\n sparklinePoints,\n} from \"./server-resources-format.ts\";\n\nexport interface ServerResourcesProps {\n /**\n * The samples to render, oldest first. The LAST entry is the current reading;\n * the whole array is the sparkline's series. May be empty — then every value\n * reads `—` and no line is drawn.\n */\n samples: readonly ServerResourceSample[];\n}\n\nexport interface ServerResourcesCardProps extends ServerResourcesProps {\n /** Heading text. Defaults to `Server resources`. */\n title?: string;\n /** The sampler's cadence, in ms. When given, the card shows `Sampled every Ns`. */\n intervalMs?: number;\n}\n\nexport interface ServerResourcesRailProps extends ServerResourcesProps {\n /**\n * When given, the rail shows one button that asks the caller to open the full\n * view. The rail never opens anything itself — mounting is the caller's job.\n */\n onExpand?: () => void;\n}\n\n/** What an unknown value renders as — the same dash the format helpers return. */\nconst UNKNOWN = \"—\";\n\n/** Sparkline geometry. The viewBox is 100 × 24 units, scaled by CSS. */\nconst SPARK_WIDTH = 100;\nconst SPARK_HEIGHT = 24;\n\n/** The sparkline. Deliberately NOT the shared `Icon` (`../components/Icon.tsx`):\n * nothing here is a fixed glyph — `points` is computed from the data, the\n * viewBox is this chart's own 100 × 24 units (scaled by CSS) rather than a\n * 24 × 24 icon box, and the stroke is the accent token, not `currentColor`. */\nfunction Sparkline({\n values,\n max,\n className,\n}: {\n values: readonly (number | null)[];\n max: number;\n className: string;\n}) {\n const points = sparklinePoints(values, SPARK_WIDTH, SPARK_HEIGHT, max);\n if (points === \"\") return null;\n\n return (\n <svg\n className={className}\n viewBox={`0 0 ${SPARK_WIDTH} ${SPARK_HEIGHT}`}\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <polyline\n points={points}\n fill=\"none\"\n stroke=\"var(--w6w-accent)\"\n strokeWidth={2}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n );\n}\n\n/**\n * A fraction as a two-decimal string (`0.5` → `0.50`), or `—` when unknown.\n * The fixed precision is what keeps the three load averages visually aligned.\n */\nfunction formatLoad(n: number | null): string {\n return n === null ? UNKNOWN : n.toFixed(2);\n}\n\n/**\n * The largest value a series of fractions is drawn against — at least 1, so a\n * quiet host draws a flat-ish line near the baseline instead of amplifying\n * its own noise to a full-height sawtooth.\n */\nfunction fractionMax(values: readonly (number | null)[]): number {\n let max = 1;\n for (const v of values) if (v !== null && v > max) max = v;\n return max;\n}\n\n/** A labelled reading plus the sparkline of its series. */\nfunction MetricRow({\n label,\n value,\n values,\n max,\n}: {\n label: string;\n value: string;\n values: readonly (number | null)[];\n max: number;\n}) {\n return (\n <li className=\"w6w-server-resources__row\">\n <span className=\"w6w-server-resources__label\">{label}</span>\n <span className=\"w6w-server-resources__value\">{value}</span>\n <Sparkline className=\"w6w-server-resources__spark\" values={values} max={max} />\n </li>\n );\n}\n\n/** The one-sample readings every variant shows, computed once per render. */\nfunction readings(samples: readonly ServerResourceSample[]) {\n const last = samples[samples.length - 1];\n const cpuValues = samples.map((s) => cpuLoadFraction(s));\n const memoryValues = samples.map((s) => memoryUsedFraction(s));\n const rssValues = samples.map((s) => s.processRss);\n return { last, cpuValues, memoryValues, rssValues };\n}\n\n/**\n * The large variant: three readings (CPU, memory, process RSS), each with its\n * own sparkline, plus the load averages and — when the caller knows it — the\n * sampling cadence. This is the Console/Modal body.\n */\nexport function ServerResourcesCard({\n samples,\n title = \"Server resources\",\n intervalMs,\n}: ServerResourcesCardProps) {\n const { last, cpuValues, memoryValues, rssValues } = readings(samples);\n\n return (\n <section className=\"w6w-server-resources w6w-server-resources--card\" aria-label={title}>\n <h3 className=\"w6w-server-resources__title\">{title}</h3>\n <ul className=\"w6w-server-resources__rows\">\n <MetricRow\n label=\"CPU\"\n value={formatPercent(cpuLoadFraction(last))}\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n <MetricRow\n label=\"Memory\"\n value={formatPercent(memoryUsedFraction(last))}\n values={memoryValues}\n max={1}\n />\n <MetricRow\n label=\"Process\"\n value={formatBytes(last?.processRss ?? null)}\n values={rssValues}\n max={fractionMax(rssValues)}\n />\n </ul>\n <p className=\"w6w-server-resources__meta\">\n {`Load ${formatLoad(last?.load1 ?? null)} / ${formatLoad(last?.load5 ?? null)} / ${formatLoad(\n last?.load15 ?? null,\n )}`}\n </p>\n {intervalMs !== undefined && (\n <p className=\"w6w-server-resources__meta\">{`Sampled every ${intervalMs / 1000}s`}</p>\n )}\n </section>\n );\n}\n\n/**\n * The small variant: CPU and memory only, one sparkline (CPU). For a compact\n * surface that has room for a headline and a shape, but not for a third\n * reading or the load breakdown.\n */\nexport function ServerResourcesCardSmall({ samples, title = \"Server\" }: ServerResourcesCardProps) {\n const { last, cpuValues } = readings(samples);\n\n return (\n <section className=\"w6w-server-resources w6w-server-resources--small\" aria-label={title}>\n <h3 className=\"w6w-server-resources__title\">{title}</h3>\n <ul className=\"w6w-server-resources__rows\">\n <MetricRow\n label=\"CPU\"\n value={formatPercent(cpuLoadFraction(last))}\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n <li className=\"w6w-server-resources__row\">\n <span className=\"w6w-server-resources__label\">Memory</span>\n <span className=\"w6w-server-resources__value\">\n {formatPercent(memoryUsedFraction(last))}\n </span>\n </li>\n </ul>\n </section>\n );\n}\n\n/**\n * The left-rail variant: a stacked CPU and MEM reading, each with a sparkline,\n * sized to fit a ~200 px column. When the caller passes `onExpand` it also\n * shows the single \"show me the rest\" button; without one it is read-only\n * decoration and renders no interactive element at all.\n */\nexport function ServerResourcesRail({ samples, onExpand }: ServerResourcesRailProps) {\n const { last, cpuValues, memoryValues } = readings(samples);\n\n return (\n <aside className=\"w6w-server-resources w6w-server-resources--rail\">\n <div className=\"w6w-server-resources__rail-row\">\n <span className=\"w6w-server-resources__label\">CPU</span>\n <span className=\"w6w-server-resources__value\">{formatPercent(cpuLoadFraction(last))}</span>\n <Sparkline\n className=\"w6w-server-resources__spark\"\n values={cpuValues}\n max={fractionMax(cpuValues)}\n />\n </div>\n <div className=\"w6w-server-resources__rail-row\">\n <span className=\"w6w-server-resources__label\">MEM</span>\n <span className=\"w6w-server-resources__value\">\n {formatPercent(memoryUsedFraction(last))}\n </span>\n <Sparkline className=\"w6w-server-resources__spark\" values={memoryValues} max={1} />\n </div>\n {onExpand !== undefined && (\n <button\n type=\"button\"\n className=\"w6w-server-resources__expand\"\n aria-label=\"Show server resources\"\n onClick={onExpand}\n >\n Details\n </button>\n )}\n </aside>\n );\n}\n\n/**\n * The header badge: one line, `CPU <pct> · MEM <pct>`, no sparkline (a badge is\n * a fixed-height strip of text, and a line there would be unreadable). The\n * whole string is a single text node so assistive tech reads it as one phrase.\n */\nexport function ServerResourcesBadge({ samples }: ServerResourcesProps) {\n const last = samples[samples.length - 1];\n const cpu = formatPercent(cpuLoadFraction(last));\n const mem = formatPercent(memoryUsedFraction(last));\n\n return (\n <span className=\"w6w-server-resources w6w-server-resources--badge\">\n {`CPU ${cpu} · MEM ${mem}`}\n </span>\n );\n}\n","/**\n * Pure geometry for `HistoryTimeline`'s vendor lane — positioning a vendor\n * incident bar on the SAME percentage scale the execution lane's day cells\n * use, so the two series can never drift apart (`HistoryTimeline.tsx`'s\n * alignment invariant). Deliberately split out of the component: a function\n * that reads a clock itself makes that invariant unobservable to a gate, so\n * `nowMs` is always a parameter here, never `Date.now()`.\n *\n * No JSX, no React import — this file is imported directly by its own test\n * (`__tests__/HistoryTimeline.test.ts`) with no transpile step.\n */\nimport type { HistoryWindow, VendorIncidentBar } from \"./HistoryTimeline.tsx\";\n\n/**\n * Minimum visible width for a bar, as a percentage of the window's span. A\n * point-in-time entry (no `startedAt`) has zero duration and would otherwise\n * be invisible; a very short span is floored to the same width so it never\n * shrinks below it either.\n */\nexport const MIN_BAR_WIDTH_PCT = 1;\n\nexport interface BarPlacement {\n /** Left edge, as a percentage of the window's span, clamped to `[0, 100]`. */\n leftPct: number;\n /** Width, as a percentage of the window's span. Never below `MIN_BAR_WIDTH_PCT`. */\n widthPct: number;\n /** `true` if the bar's start was clamped to the window's left edge. */\n clippedStart: boolean;\n /** `true` if the bar's end was clamped to the window's right edge. */\n clippedEnd: boolean;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Places one vendor incident bar on the window's `[from T00:00:00Z, to+1 day\n * T00:00:00Z)` span.\n *\n * - A bar's start is `startedAt ?? updatedAt`; with neither present there is\n * nothing to place, so this returns `null` (B5).\n * - Its end is `resolvedAt ?? (startedAt !== undefined ? nowMs : start)` — an\n * open incident (has `startedAt`, no `resolvedAt`) therefore runs to\n * `nowMs`, and a feed-only entry with no `startedAt` is a point in time,\n * not a span (B3).\n * - A bar wholly outside the window (ends before it starts, or starts at or\n * after it ends) returns `null` (B4). One overlapping an edge is clamped\n * into the window, with `clippedStart`/`clippedEnd` set accordingly.\n */\nexport function placeIncidentBar(\n window: HistoryWindow,\n bar: VendorIncidentBar,\n nowMs: number,\n): BarPlacement | null {\n const start = bar.startedAt ?? bar.updatedAt;\n if (start === undefined) return null;\n\n const startMs = Date.parse(start);\n const endMs =\n bar.resolvedAt !== undefined\n ? Date.parse(bar.resolvedAt)\n : bar.startedAt !== undefined\n ? nowMs\n : startMs;\n\n const windowStartMs = Date.parse(`${window.from}T00:00:00.000Z`);\n const windowEndMs = Date.parse(`${window.to}T00:00:00.000Z`) + DAY_MS;\n const spanMs = windowEndMs - windowStartMs;\n\n if (endMs < windowStartMs || startMs >= windowEndMs) return null;\n\n const clippedStart = startMs < windowStartMs;\n const clippedEnd = endMs > windowEndMs;\n\n // The clamp to [0, 100] (B2) happens HERE, on the raw timestamps, and is\n // the ONLY place either bound is clamped — `leftPct`/`widthPct` below are\n // plain arithmetic on the clamped values, so there is no second, redundant\n // clamp for a mutation to skip past undetected.\n const clampedStartMs = Math.max(startMs, windowStartMs);\n const clampedEndMs = Math.min(endMs, windowEndMs);\n\n const leftPct = ((clampedStartMs - windowStartMs) / spanMs) * 100;\n const rawWidthPct = ((clampedEndMs - clampedStartMs) / spanMs) * 100;\n const widthPct = Math.max(rawWidthPct, MIN_BAR_WIDTH_PCT);\n\n return { leftPct, widthPct, clippedStart, clippedEnd };\n}\n","import type { UptimeCellState, UptimeDay } from \"./UptimeStrip.tsx\";\nimport { placeIncidentBar } from \"./history-scale.ts\";\n\n/** The calendar window both lanes are plotted against. Both bounds inclusive. */\nexport interface HistoryWindow {\n /** Inclusive first calendar day, `YYYY-MM-DD`. */\n from: string;\n /** Inclusive last calendar day, `YYYY-MM-DD`. */\n to: string;\n}\n\n/** One entry in the vendor's incident feed. */\nexport interface VendorIncidentBar {\n id?: string;\n title: string;\n state: UptimeCellState;\n /** ISO instant. Absent = a point-in-time update, not a span. */\n startedAt?: string;\n updatedAt?: string;\n /** ISO instant. Absent WITH `startedAt` present = still open. */\n resolvedAt?: string;\n components?: string[];\n link?: string;\n}\n\nexport interface HistoryTimelineProps {\n window: HistoryWindow;\n /** Execution lane, oldest first, one entry per calendar day. */\n days: UptimeDay[];\n /** Vendor lane. `undefined` = this vendor publishes no incident history at all. */\n incidents?: VendorIncidentBar[];\n /** Overrides the vendor lane's empty text. */\n vendorEmptyLabel?: string;\n /** Clock injection for tests and for an open incident's right edge. Defaults to `Date.now()`. */\n nowMs?: number;\n ariaLabel?: string;\n}\n\nconst STATE_LABELS: Record<UptimeCellState, string> = {\n ok: \"Operational\",\n degraded: \"Degraded\",\n down: \"Down\",\n unknown: \"Unknown\",\n};\n\nconst NO_FEED_LABEL = \"This vendor publishes no incident history.\";\nconst QUIET_LABEL = \"No incidents in this window.\";\n\nfunction barTitle(bar: VendorIncidentBar): string {\n const start = bar.startedAt ?? bar.updatedAt;\n const parts = [bar.title];\n if (bar.components !== undefined && bar.components.length > 0) {\n parts.push(`(${bar.components.join(\", \")})`);\n }\n if (start !== undefined) {\n parts.push(\n bar.resolvedAt !== undefined ? `${start} – ${bar.resolvedAt}` : `${start} – ongoing`,\n );\n }\n return parts.join(\" \");\n}\n\n/**\n * Two time series — our per-day execution history and the vendor's incident\n * history — plotted on one shared x-axis, so \"our calls failed *during* that\n * vendor incident\" is a visible alignment rather than a claim.\n *\n * Purely presentational, same discipline as `UptimeStrip`: `days` is already\n * one already-decided state per calendar day (no sort, no reverse, no gap\n * fill), and `incidents` is already the vendor's own feed. This component\n * places them; it makes no judgement about what counts as an incident.\n *\n * `incidents === undefined` (\"this vendor publishes no incident history\") and\n * `incidents === []` (\"nothing happened in this window\") are different facts\n * and render different empty-row text — Stripe is the first, a quiet Slack\n * window is the second. Either way the axis and the execution lane render in\n * full, at full width: a vendor with no feed never shrinks the half of the\n * chart that does have data.\n *\n * Severity is encoded twice, same rule as `UptimeStrip` and `HealthStatusPill`:\n * a per-state class AND a geometry difference (fill height on a day cell,\n * clip markers on a bar), never colour alone. Every cell and every bar\n * carries a `title`.\n */\nexport function HistoryTimeline({\n window: win,\n days,\n incidents,\n vendorEmptyLabel,\n nowMs = Date.now(),\n ariaLabel,\n}: HistoryTimelineProps) {\n const n = days.length;\n const cellWidthPct = n > 0 ? 100 / n : 0;\n\n const emptyLabel =\n incidents === undefined\n ? (vendorEmptyLabel ?? NO_FEED_LABEL)\n : incidents.length === 0\n ? (vendorEmptyLabel ?? QUIET_LABEL)\n : null;\n\n return (\n <div className=\"w6w-history-timeline\" role=\"img\" aria-label={ariaLabel ?? `${n}-day history`}>\n <div className=\"w6w-history-plot\">\n <div className=\"w6w-history-lane w6w-history-lane-execution\">\n {days.map((entry, i) => (\n <span\n // Days are expected to be unique, but the index keeps the key\n // stable even if a caller repeats one — same guard `UptimeStrip` uses.\n key={`${entry.day}-${i}`}\n className={`w6w-history-cell w6w-history-cell-${entry.state}`}\n style={{ left: `${i * cellWidthPct}%`, width: `${cellWidthPct}%` }}\n title={entry.label ?? `${entry.day} — ${STATE_LABELS[entry.state]}`}\n />\n ))}\n </div>\n <div className=\"w6w-history-lane w6w-history-lane-vendor\">\n {emptyLabel !== null ? (\n <span className=\"w6w-history-empty\" title={emptyLabel}>\n {emptyLabel}\n </span>\n ) : (\n incidents?.map((bar, i) => {\n const placement = placeIncidentBar(win, bar, nowMs);\n if (placement === null) return null;\n const clipClass = [\n placement.clippedStart ? \"w6w-history-bar-clip-start\" : \"\",\n placement.clippedEnd ? \"w6w-history-bar-clip-end\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n return (\n <span\n key={bar.id ?? `${bar.title}-${i}`}\n className={`w6w-history-bar w6w-history-bar-${bar.state}${clipClass ? ` ${clipClass}` : \"\"}`}\n style={{ left: `${placement.leftPct}%`, width: `${placement.widthPct}%` }}\n title={barTitle(bar)}\n />\n );\n })\n )}\n </div>\n <div className=\"w6w-history-axis\">\n <span className=\"w6w-history-tick w6w-history-tick-start\" style={{ left: \"0%\" }}>\n {win.from}\n </span>\n <span className=\"w6w-history-tick w6w-history-tick-end\" style={{ left: \"100%\" }}>\n {win.to}\n </span>\n </div>\n </div>\n </div>\n );\n}\n","import { type ReactNode, useId, useState } from \"react\";\nimport { IconButton } from \"./IconButton.tsx\";\n\nexport interface InfoTipProps {\n /** Accessible name AND tooltip of the toggle button (e.g. \"About client secrets\"). */\n label: string;\n /** The explanation, rendered only while expanded. */\n children: ReactNode;\n className?: string;\n}\n\n/**\n * A small \"i\" button that reveals a muted explanation block on click — for\n * copy that would otherwise clutter a modal. Collapsed by default; the button\n * carries `aria-expanded` and `aria-controls` pointing at the block, and the\n * block is not rendered at all while collapsed.\n */\nexport function InfoTip({ label, children, className }: InfoTipProps) {\n const [open, setOpen] = useState(false);\n const id = useId();\n return (\n <span className={[\"w6w-info-tip\", className ?? \"\"].filter(Boolean).join(\" \")}>\n <IconButton\n label={label}\n icon=\"info\"\n aria-expanded={open}\n aria-controls={id}\n onClick={() => setOpen((o) => !o)}\n />\n {open && (\n <span id={id} className=\"w6w-info-tip-body w6w-muted w6w-small\">\n {children}\n </span>\n )}\n </span>\n );\n}\n","import { IconButton } from \"./IconButton.tsx\";\n\nexport interface EditButtonProps {\n label: string;\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/** An `IconButton` bundling the canonical pencil glyph — `icons.tsx`'s `edit`,\n * the two-path Feather pencil — with no `danger` styling. */\nexport function EditButton(props: EditButtonProps) {\n const { label, onClick, disabled, className, ...rest } = props;\n return (\n <IconButton\n label={label}\n onClick={onClick}\n disabled={disabled}\n className={className}\n icon=\"edit\"\n data-testid={rest[\"data-testid\"]}\n />\n );\n}\n","import { IconButton } from \"./IconButton.tsx\";\n\nexport interface DeleteButtonProps {\n label: string;\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * An `IconButton` bundling the canonical trash glyph — `icons.tsx`'s `delete`,\n * the fuller 4-shape Feather `trash-2` — always `danger`-styled.\n *\n * Presentational only (HITL-1, binding): takes a plain `onClick`, never an\n * `onConfirm`, and never imports any confirm-dialog component — the call\n * site owns whether and which one gates the click.\n */\nexport function DeleteButton(props: DeleteButtonProps) {\n const { label, onClick, disabled, className, ...rest } = props;\n return (\n <IconButton\n label={label}\n onClick={onClick}\n disabled={disabled}\n className={className}\n danger\n icon=\"delete\"\n data-testid={rest[\"data-testid\"]}\n />\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { Icon } from \"./Icon.tsx\";\n\nexport interface RepoSyncIndicatorProps {\n /** Branch name, e.g. \"main\". */\n branch: string;\n /** Already-shortened commit sha (the consumer formats it — D-6). `null` renders no sha. */\n shortSha: string | null;\n /** Already-formatted last-sync text, e.g. \"3/9/2026, 12:16:29 PM\" or \"Never synced\".\n * `null` renders no time row. */\n lastSyncLabel: string | null;\n /** Fired when the flyout's \"Sync now\" item is activated. The consumer owns the mutation. */\n onSyncNow: () => void;\n /** True while the consumer's sync is in flight. */\n syncing?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * A compact header control showing a repo glyph, a branch name and a short\n * commit sha, with an inline flyout menu carrying the sync detail and a\n * \"Sync now\" action the consumer wires.\n *\n * `@w6w/ui` never fetches and holds no studio policy\n * (`studio/src/ui/ExpressionScope.tsx:40-41`, extended by D-6) — this\n * component takes already-formatted strings and a callback.\n *\n * The open/close + outside-click + Escape state machine mirrors\n * `studio/src/components/Layout.tsx:222-328`'s `ProjectMenu()` (D-3: no\n * shared Menu/Popover/Dropdown primitive — there is exactly one consumer).\n */\nexport function RepoSyncIndicator(props: RepoSyncIndicatorProps) {\n const { branch, shortSha, lastSyncLabel, onSyncNow, syncing, className, ...rest } = props;\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n return (\n <div\n className={`w6w-repo-sync${className ? ` ${className}` : \"\"}`}\n ref={ref}\n data-testid={rest[\"data-testid\"]}\n >\n <button\n type=\"button\"\n className=\"w6w-repo-sync-trigger\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-busy={syncing}\n onClick={() => setOpen((v) => !v)}\n >\n <span className=\"w6w-repo-sync-icon\">\n {/* The connection provider's mark — `icons.tsx`'s `github` (`RepoBinding.provider`\n is always `\"github\"` today), 16px, the set's default. */}\n <Icon name=\"github\" />\n {/* The in-flight badge over the mark while `syncing`: `icons.tsx`'s `sync`\n (Feather `refresh-cw`), shrunk to 10×10 for this corner use and spun by\n `.w6w-repo-sync-spin`, which `Icon` merges with `w6w-icon`. */}\n {syncing && <Icon name=\"sync\" size={10} className=\"w6w-repo-sync-spin\" />}\n </span>\n <span className=\"w6w-repo-sync-branch\">{branch}</span>\n {shortSha != null && <code className=\"w6w-repo-sync-sha\">{shortSha}</code>}\n </button>\n {open && (\n <div className=\"w6w-repo-sync-menu\" role=\"menu\">\n <div className=\"w6w-repo-sync-detail\">\n <span>{branch}</span>\n {shortSha != null && <code>{shortSha}</code>}\n {lastSyncLabel != null && <span>{lastSyncLabel}</span>}\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"w6w-repo-sync-item\"\n data-testid=\"repo-sync-now\"\n disabled={syncing}\n onClick={onSyncNow}\n >\n {syncing ? \"Syncing…\" : \"Sync now\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * The five states a workflow step's execution can be in — a thin LOCAL copy\n * of the workflow spec's `StepStatus` union\n * (`packages/w6w-workflow/packages/types/mod.ts`). `@w6w/ui` deliberately\n * keeps a small literal type here rather than depend on `@w6w/workflow-types`,\n * so this stays a pure-presentation leaf with no transport/spec coupling —\n * the same precedent `HealthStatusPill`'s `HealthPillState` establishes.\n */\nexport type StepStatus = \"pending\" | \"running\" | \"succeeded\" | \"failed\" | \"skipped\";\n\n/**\n * The five states a whole EXECUTION (an invocation, an endpoint call, a\n * workflow run) can be in — the run-level sibling of `StepStatus`, and again a\n * thin LOCAL literal rather than an import of any spec/wire type. The two\n * unions differ exactly where runs and steps differ: a run can be `queued`\n * before it starts and `canceled` after it started, while a step inside a run\n * can be `pending` or `skipped` (a run is never either). They are deliberately\n * NOT merged into one five/six-member union — `ExecutionList` and the step\n * panel must each accept only their own vocabulary.\n */\nexport type ExecutionStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"canceled\";\n\nexport interface StepStatusPillProps {\n /**\n * Which state to render — drives the colour + default label. Accepts both\n * vocabularies: a workflow step's `StepStatus` and a whole run's\n * `ExecutionStatus` (the pill is only a coloured label, so it does not care\n * which of the two a host is describing).\n */\n state: StepStatus | ExecutionStatus;\n /** Override the visible text (defaults to a humanised form of `state`). */\n label?: ReactNode;\n /** Accessible label for the pill (falls back to the visible text). */\n ariaLabel?: string;\n}\n\nconst DEFAULT_LABELS: Record<StepStatus | ExecutionStatus, string> = {\n pending: \"Pending\",\n running: \"Running\",\n succeeded: \"Succeeded\",\n failed: \"Failed\",\n skipped: \"Skipped\",\n queued: \"Queued\",\n canceled: \"Canceled\",\n};\n\n/**\n * A small, theme-aware status pill for one workflow step's execution state.\n *\n * Mirrors `HealthStatusPill` shape for shape: a state union, a\n * `DEFAULT_LABELS` record, a coloured dot + text label using one\n * `--w6w-step-color` custom property per modifier class, and the\n * `w6w-step-pill w6w-step-pill-${state}` className convention. Colour is\n * never the only signal — the text label carries the same meaning for\n * accessibility. Five states rather than `HealthStatusPill`'s four, so this\n * is a mirror of that shape, not a shared implementation.\n *\n * Renders BOTH vocabularies through the one prop: `StepStatus` (a step inside\n * a run) and `ExecutionStatus` (a whole run). The union is widened at the\n * PROP only — `StepStatus` itself is unchanged, so the step panel's own type\n * cannot silently grow run-only states.\n */\nexport function StepStatusPill({ state, label, ariaLabel }: StepStatusPillProps) {\n const text = label ?? DEFAULT_LABELS[state];\n\n return (\n <span className={`w6w-step-pill w6w-step-pill-${state}`} aria-label={ariaLabel}>\n <span className=\"w6w-step-pill-dot\" aria-hidden=\"true\" />\n <span className=\"w6w-step-pill-label\">{text}</span>\n </span>\n );\n}\n","/**\n * Pure duration/time formatters for the execution-history family, kept in\n * their own module so they carry no React and can be unit-tested on their own\n * — the same split `server-resources-format.ts` establishes.\n *\n * Both are TOTAL: a duration that was never measured (a still-running or\n * queued run) is rendered as an em dash, never as `0 ms` — \"unknown\" must not\n * read as \"instant\".\n */\n\n/** What an unmeasured/unknown value renders as. Never `0`. */\nconst UNKNOWN = \"—\";\n\nconst MS_PER_SECOND = 1000;\nconst MS_PER_MINUTE = 60_000;\n\n/**\n * A run duration as a short human string: whole milliseconds below a second\n * (`999 ms`), one decimal place in seconds below a minute (`1.5 s`), and\n * `2m 5s` from a minute up. `null`/`undefined` (nothing measured), `NaN` and\n * negatives are all `—`.\n */\nexport function formatDurationMs(ms: number | null | undefined): string {\n if (ms == null || !Number.isFinite(ms) || ms < 0) return UNKNOWN;\n if (ms < MS_PER_SECOND) return `${Math.round(ms)} ms`;\n if (ms < MS_PER_MINUTE) return `${(ms / MS_PER_SECOND).toFixed(1)} s`;\n return `${Math.floor(ms / MS_PER_MINUTE)}m ${Math.round((ms % MS_PER_MINUTE) / MS_PER_SECOND)}s`;\n}\n\n/**\n * An ISO-8601 instant as a short, locale-formatted date+time (`Sep 22, 2026,\n * 10:00 AM` under the default locale). The locale is the HOST's\n * (`undefined`), so the string follows the viewer's own settings rather than\n * baking one in. A string `Date` cannot parse is returned UNCHANGED — an\n * unrenderable timestamp is shown as the wire value, never as \"Invalid Date\".\n */\nexport function formatExecutionTime(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return date.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n","import type { ReactNode } from \"react\";\nimport { ListItem } from \"./ListItem.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport { formatDurationMs, formatExecutionTime } from \"./execution-format.ts\";\n\n/** What kind of callable a run belongs to. A thin LOCAL literal — the same\n * deliberate duplication `StepStatusPill`'s unions keep. */\nexport type ExecutionKind = \"function\" | \"endpoint\" | \"workflow\";\n\n/** One past execution's display row — an already-mapped slice of the host's\n * history payload. The HOST maps its own record into this shape (the same\n * \"host owns the data, the list is presentational\" split `ExecutionLogPanel`\n * establishes): this component never fetches, paginates or reaches for an SDK. */\nexport interface ExecutionListItem {\n /** Stable id for this row — what `onSelect` reports and `selectedId` matches. */\n id: string;\n kind: ExecutionKind;\n /** The callable's name/key this run belongs to. */\n callableName: string;\n status: ExecutionStatus;\n /** ISO-8601 instant the run started. */\n startedAt: string;\n /** Wall-clock duration once the run has finished; `null` while it is still\n * queued/running (rendered as `—`). */\n durationMs: number | null;\n}\n\nexport interface ExecutionListProps {\n /** The page of past executions, rendered in exactly this order — never re-sorted. */\n items: ExecutionListItem[];\n /** The row to highlight as current. `null`/omitted ⇒ no row is active. */\n selectedId?: string | null;\n /** Supplied ⇒ rows are clickable and report their id here. Omitted ⇒ every\n * row is a plain, non-interactive row. */\n onSelect?: (id: string) => void;\n /**\n * `true` ⇒ each row's title is the callable's name and its subtitle carries\n * the kind + start time (the project-wide history view). `false` ⇒ the title\n * is the start time and the subtitle is the run id (the per-callable view,\n * where the callable is already known). Defaults to `false`.\n */\n showCallable?: boolean;\n /** `true` ⇒ the loading branch while there is nothing to show yet. */\n loading?: boolean;\n /** Shown instead of the list when `items` is empty. */\n emptyLabel?: ReactNode;\n /** Whether a previous page exists — drives the pager's `Previous` state. */\n hasPrev?: boolean;\n /** Whether a next page exists — drives the pager's `Next` state. */\n hasNext?: boolean;\n /** Supplied ⇒ the pager renders and `Previous` calls this. */\n onPrev?: () => void;\n /** Supplied ⇒ the pager renders and `Next` calls this. */\n onNext?: () => void;\n}\n\n/** Row subtitle's kind prefix, in the `showCallable` view. */\nconst KIND_LABEL: Record<ExecutionKind, string> = {\n function: \"Function\",\n endpoint: \"Endpoint\",\n workflow: \"Workflow\",\n};\n\n/**\n * A paged list of past executions: one row per run, click-to-select, with a\n * prev/next pager.\n *\n * A pure display leaf — no fetching, no polling, no sorting, no local\n * selection state. It renders `items` in the order given, reports a click, and\n * reports a page request; the host owns which page is loaded and which row is\n * selected.\n */\nexport function ExecutionList({\n items,\n selectedId = null,\n onSelect,\n showCallable = false,\n loading = false,\n emptyLabel,\n hasPrev,\n hasNext,\n onPrev,\n onNext,\n}: ExecutionListProps) {\n // Rendered in EVERY branch below, deliberately: a host that reports it can\n // go back to a previous page must still offer that control from an empty\n // page (the state reached by paging past the last run) and while a page is\n // loading.\n const pager =\n onPrev || onNext ? (\n <div className=\"w6w-execution-list-pager\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-list-prev\"\n disabled={!hasPrev}\n onClick={onPrev}\n >\n Previous\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-list-next\"\n disabled={!hasNext}\n onClick={onNext}\n >\n Next\n </button>\n </div>\n ) : null;\n\n let body: ReactNode;\n if (loading && items.length === 0) {\n body = <p data-testid=\"execution-list-loading\">Loading…</p>;\n } else if (items.length === 0) {\n body = <p data-testid=\"execution-list-empty\">{emptyLabel ?? \"No executions yet.\"}</p>;\n } else {\n body = (\n <ul className=\"w6w-execution-list-rows\">\n {items.map((item) => (\n <li key={item.id} data-testid=\"execution-row\" data-execution-id={item.id}>\n <ListItem\n icon={<StepStatusPill state={item.status} />}\n title={showCallable ? item.callableName : formatExecutionTime(item.startedAt)}\n subtitle={\n showCallable\n ? `${KIND_LABEL[item.kind]} · ${formatExecutionTime(item.startedAt)}`\n : item.id\n }\n trailing={formatDurationMs(item.durationMs)}\n active={item.id === selectedId}\n onClick={onSelect ? () => onSelect(item.id) : undefined}\n />\n </li>\n ))}\n </ul>\n );\n }\n\n return (\n <div className=\"w6w-execution-list\" data-testid=\"execution-list\">\n {body}\n {pager}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { CodeBlock } from \"../CodeBlock.tsx\";\nimport type { StepMeta } from \"../provider.tsx\";\nimport { IconButton } from \"./IconButton.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport type { StepStatus } from \"./StepStatusPill.tsx\";\n\n/**\n * A step's or run's failure, already normalised by the HOST from the workflow\n * spec's `StepError` (`code`/`message`/`phase`/`retryable`). The panel never\n * parses an `unknown` error itself — same \"host owns the data\" split as the\n * rest of this file. Rendered in `TriggerFillForm`'s error visual: a\n * `.w6w-result.w6w-error` box, an optional `<code>` badge line, then the message.\n */\nexport interface ExecutionLogError {\n /** `StepError.code`. Optional: the host may normalise an error that carries no code. */\n code?: string;\n /** The human-readable reason. Never empty when the host supplies it. */\n message: string;\n /** `StepError.phase`, when known. Carried for the host; not rendered. */\n phase?: string;\n /** `StepError.retryable`, when known. Carried for the host; not rendered. */\n retryable?: boolean;\n}\n\n/**\n * One entry of `RunState.stepErrors` — a step failure the run recorded and\n * moved past (`onError: \"continue-record\"`, or a failure an error edge\n * handled), so the run itself may still have succeeded.\n */\nexport interface ExecutionLogRecordedError {\n /** The step the error belongs to. */\n stepId: string;\n /** Human-readable step name. Falls back to `stepId` when rendered. */\n label?: string;\n error: ExecutionLogError;\n}\n\n/**\n * One step's display row — an already-mapped, already-resolved slice of a\n * `RunState`/`StepExecution` (workflow spec). The HOST maps its own run\n * state into this shape (same \"host owns the data, the panel is\n * presentational\" split `readOnly` already establishes elsewhere in this\n * package) — this component never fetches, polls, or reaches for an SDK.\n */\nexport interface ExecutionLogStep {\n /** Stable id for this row — typically the step id from the workflow definition. */\n id: string;\n /** Human-readable step name. Falls back to `id` when omitted. */\n label?: string;\n status: StepStatus;\n /** ISO-8601 timestamp the step started, once it has. */\n startedAt?: string;\n /** ISO-8601 timestamp the step finished, once it has. */\n finishedAt?: string;\n /** The resolved input sent to the step's action, once it is known. */\n input?: unknown;\n /** The step's output, once it has one. */\n output?: unknown;\n /**\n * What ran (`StepExecution.meta`): app, version, action and connection id. Shown as a\n * Metadata block after Output. Absent or `null` ⇒ no block at all (R-12: no filler).\n */\n meta?: StepMeta | null;\n /**\n * Why the step failed (`StepExecution.error`, \"present on failed\"). Rendered\n * below the row's box and outside its lazy `<details>` body, so the reason\n * reads without expanding the row.\n */\n error?: ExecutionLogError;\n}\n\nexport interface ExecutionLogPanelProps {\n /** The run's steps, rendered in exactly this order — never re-sorted. */\n steps: ExecutionLogStep[];\n /** Shown instead of the list when `steps` is empty. */\n emptyLabel?: ReactNode;\n /**\n * Supplied ⇒ the panel grows a header row carrying a dismiss control that\n * calls this and nothing else (T1.1.1). Omitted ⇒ no header row at all, no\n * extra DOM node. The panel still owns no run state — it only reports the\n * click; the host decides what dismissing means.\n */\n onDismiss?: () => void;\n /**\n * The run's own failure (`RunState.error`). Rendered below the dismiss head\n * and above the steps — in the empty branch too, since a run that failed\n * before any step ran has nothing else to say why.\n */\n runError?: ExecutionLogError;\n /**\n * Step failures the run recorded and moved past (`RunState.stepErrors`),\n * one error block each, in the order given, after `runError`.\n */\n stepErrors?: ExecutionLogRecordedError[];\n}\n\n/**\n * Read-only log of a workflow run's steps, in the order given: each row is\n * the step's status pill, its timing, and its resolved input/output.\n *\n * A pure display leaf — no data fetching, no polling, no layout media\n * queries (the host docks the panel; see `_scale.scss`'s breakpoint\n * docstring). Fills whatever box its host gives it.\n */\nexport function ExecutionLogPanel({\n steps,\n emptyLabel,\n onDismiss,\n runError,\n stepErrors,\n}: ExecutionLogPanelProps) {\n // Rendered by BOTH branches below, deliberately: the reported repro (T-1) is\n // a canvas whose log panel shows \"No steps have run yet.\" — a header mounted\n // only above the `<ol>` would be invisible in exactly that state, and that is\n // the state the dismiss control exists to get the user out of.\n const head = onDismiss ? (\n <div className=\"w6w-execution-log-head\">\n <IconButton label=\"Dismiss run log\" data-testid=\"execution-log-dismiss\" onClick={onDismiss}>\n ×\n </IconButton>\n </div>\n ) : null;\n\n // Same both-branches rule as `head`: a run that failed before its first step\n // is exactly the empty branch. Nothing to report ⇒ no wrapper node at all.\n const recorded = stepErrors ?? [];\n const errors =\n runError || recorded.length > 0 ? (\n <div className=\"w6w-execution-log-errors w6w-stack\">\n {runError && <ExecutionLogErrorBlock error={runError} />}\n {recorded.map((entry, index) => (\n <ExecutionLogErrorBlock\n // `stepId` alone may repeat (a step retried into the record twice).\n key={`${entry.stepId}:${index}`}\n label={entry.label ?? entry.stepId}\n error={entry.error}\n />\n ))}\n </div>\n ) : null;\n\n if (steps.length === 0) {\n return (\n <>\n {head}\n {errors}\n <div className=\"w6w-execution-log-empty\">\n <p className=\"w6w-muted w6w-small\">{emptyLabel ?? \"No steps have run yet.\"}</p>\n </div>\n </>\n );\n }\n\n return (\n <>\n {head}\n {errors}\n <ol className=\"w6w-execution-log\">\n {steps.map((step) => (\n <ExecutionLogRow key={step.id} step={step} />\n ))}\n </ol>\n </>\n );\n}\n\n/**\n * Collapsed-by-default disclosure per step (REVIEW.md R-1) — reuses\n * `.w6w-section`'s bordered `<details>` idiom (`ApiCallsPanel.tsx`,\n * `ParamsForm.tsx`'s `section: \"collapsible\"`), not a bespoke card. The\n * `<summary>` is the one-line scan line (pill + label + timing, unchanged\n * content from the old always-visible row header); Input/Output move inside\n * the details body, and are only mounted into the DOM once opened — a\n * closed run of N steps costs N compact rows, not N×2 rendered JSON blocks.\n *\n * A step with neither `input` nor `output` has nothing to disclose: it\n * renders a plain, non-interactive row (still `.w6w-section`-styled for\n * visual consistency with its siblings) rather than an empty `<details>` a\n * user opens only to find \"Not available.\" twice (A3). An `error` alone is\n * not something to disclose either: it renders on every row as a sibling\n * AFTER the row's box — outside the lazily mounted `<details>` body (so it\n * reads while collapsed and never mounts twice once opened) and outside the\n * `<summary>` (whose phrasing-content model and click-to-toggle make it the\n * wrong home for a selectable block of text).\n */\nfunction ExecutionLogRow({ step }: { step: ExecutionLogStep }) {\n const [open, setOpen] = useState(false);\n const header = (\n <div className=\"w6w-execution-log-row-header\">\n <StepStatusPill state={step.status} />\n <span className=\"w6w-execution-log-row-label\">{step.label ?? step.id}</span>\n <StepTiming startedAt={step.startedAt} finishedAt={step.finishedAt} />\n </div>\n );\n\n const error = step.error ? <ExecutionLogErrorBlock error={step.error} /> : null;\n\n if (step.input === undefined && step.output === undefined && !step.meta) {\n return (\n <li className=\"w6w-execution-log-row\">\n <div className=\"w6w-section\">{header}</div>\n {error}\n </li>\n );\n }\n\n return (\n <li className=\"w6w-execution-log-row\">\n <details className=\"w6w-section\" open={open} onToggle={(e) => setOpen(e.currentTarget.open)}>\n <summary className=\"w6w-section-summary\">{header}</summary>\n {open && (\n <div className=\"w6w-execution-log-row-body w6w-section-body w6w-stack\">\n <ExecutionLogJson title=\"Input\" value={step.input} />\n <ExecutionLogJson title=\"Output\" value={step.output} />\n {step.meta && (\n <div className=\"w6w-execution-log-json w6w-stack\">\n <strong className=\"w6w-small\">Metadata</strong>\n <CodeBlock code={JSON.stringify(step.meta, null, 2)} language=\"json\" />\n </div>\n )}\n </div>\n )}\n </details>\n {error}\n </li>\n );\n}\n\n/**\n * `TriggerFillForm`'s StepError visual, reused rather than re-invented: the\n * `.w6w-result.w6w-error` box, an optional muted `<code>` line, then the\n * message. `label` (recorded step errors only) names the step on a line above.\n * The code line's spacing lives in `_execution-log.scss` as tokens instead of\n * `TriggerFillForm`'s inline style — same values (`0.75` opacity, a 4px gap).\n */\nfunction ExecutionLogErrorBlock({ error, label }: { error: ExecutionLogError; label?: string }) {\n return (\n <div className=\"w6w-result w6w-error\">\n {label !== undefined && <strong className=\"w6w-execution-log-error-label\">{label}</strong>}\n {error.code && (\n <div className=\"w6w-small w6w-execution-log-error-code\">\n <code>{error.code}</code>\n </div>\n )}\n {error.message}\n </div>\n );\n}\n\n/**\n * \"started / finished, or elapsed\" (A2): both timestamps render verbatim\n * plus the computed elapsed duration between them; only `startedAt` renders\n * as \"Started <ts>\"; neither renders as a plain dash. Never a live-ticking\n * clock — a `setInterval` would make this component a timer owner rather\n * than a pure function of its props.\n */\nfunction StepTiming({ startedAt, finishedAt }: { startedAt?: string; finishedAt?: string }) {\n if (startedAt && finishedAt) {\n const elapsed = formatElapsed(startedAt, finishedAt);\n return (\n <span className=\"w6w-execution-log-timing\">\n {startedAt} → {finishedAt}\n {elapsed && <span> ({elapsed})</span>}\n </span>\n );\n }\n if (startedAt) {\n return <span className=\"w6w-execution-log-timing\">Started {startedAt}</span>;\n }\n return <span className=\"w6w-execution-log-timing\">—</span>;\n}\n\nfunction formatElapsed(startedAt: string, finishedAt: string): string | null {\n const startMs = Date.parse(startedAt);\n const endMs = Date.parse(finishedAt);\n if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs) return null;\n const ms = endMs - startMs;\n if (ms < 1000) return `${ms}ms`;\n const totalSeconds = ms / 1000;\n if (totalSeconds < 60) return `${totalSeconds.toFixed(1)}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = Math.round(totalSeconds % 60);\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * Input/output as read-only, syntax-highlighted JSON — `CodeBlock`, not\n * `JsonEditor`: per `CodeBlock.tsx`'s own doc comment, `JsonEditor` mounts a\n * CodeMirror instance to *edit* text, \"heavy and semantically wrong for a\n * snippet nobody types into\" — exactly this row's read-only value, rendered\n * potentially many times over a whole run. `ResolvedParams.tsx` doesn't fit\n * either: it renders a *schema* (`ActionParam[]`) against resolved values,\n * and this panel has no param schema, only the already-resolved input/output\n * values themselves (see the file header's \"host maps `RunState`\" note).\n * Never a plain `<pre>` dump: `CodeBlock` is this library's own read-only\n * structured-code idiom (highlighting, copy affordance, `--w6w-code-*`\n * tokens), the thing `<pre>` is not.\n */\nfunction ExecutionLogJson({ title, value }: { title: string; value: unknown }) {\n return (\n <div className=\"w6w-execution-log-json w6w-stack\">\n <strong className=\"w6w-small\">{title}</strong>\n {value === undefined ? (\n <p className=\"w6w-muted w6w-small\">Not available.</p>\n ) : (\n <CodeBlock code={JSON.stringify(value, null, 2)} language=\"json\" />\n )}\n </div>\n );\n}\n","import type { ExecutionKind } from \"./ExecutionList.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\n\n/**\n * The filter/search state of the history view — one plain object, owned by the\n * HOST. This component is fully controlled: it holds no state of its own, it\n * only renders `value` and reports the next one. Same \"host owns the data, the\n * control is presentational\" split `ExecutionList` establishes, and the same\n * reason: the host owns where the filters live (URL search params today, a\n * query cache tomorrow) and this leaf must not disagree with it.\n */\nexport interface ExecutionFilterValue {\n /** `\"\"` = \"no status filter\" (the `Any status` option), never `null`. */\n status: ExecutionStatus | \"\";\n /** `\"\"` = \"no kind filter\" (the `Any type` option). Only reachable when the\n * host renders the kind select (`showKind`). */\n kind: ExecutionKind | \"\";\n /** Inclusive lower bound on the run's start, as `YYYY-MM-DD` — exactly what\n * `input[type=date]` reports and accepts. `\"\"` = unbounded. */\n from: string;\n /** Inclusive upper bound on the run's start, same format. `\"\"` = unbounded. */\n to: string;\n /** Free-text query. D3: the server matches execution id + callable name/key,\n * never payload JSON. */\n q: string;\n}\n\nexport interface ExecutionFiltersProps {\n /** The current filter state — rendered verbatim, never re-derived. */\n value: ExecutionFilterValue;\n /** Called ONCE per user interaction with the ONE field that changed:\n * `{ ...value, <that field>: next }`. No debounce, no batching — the host\n * decides when a request is worth making (it may debounce `q` itself). */\n onChange: (next: ExecutionFilterValue) => void;\n /** `true` ⇒ the kind select renders between the status select and the date\n * bounds. Defaults to `false`: the per-callable history view already knows\n * the kind, so a kind filter there would be a control of one option. */\n showKind?: boolean;\n /** Placeholder for the search box. Defaults to `\"Search by id or name\"` —\n * the same two fields D3 pins the server-side search to. */\n searchPlaceholder?: string;\n /** `true` ⇒ every control (the clear button included) renders disabled — the\n * state a host uses while a request is already in flight. */\n disabled?: boolean;\n}\n\n/** The \"nothing filtered\" state — what Clear reports, and what a host starts\n * from. Kept module-local: it is one object literal, and a host that needs its\n * own initial value should own it (it must be encoded into a URL anyway). */\nconst EMPTY: ExecutionFilterValue = { status: \"\", kind: \"\", from: \"\", to: \"\", q: \"\" };\n\n/** `\"\"` first (the \"any\" option), then one entry per run state, capitalised. */\nconst STATUS_OPTIONS: Array<{ value: ExecutionStatus | \"\"; label: string }> = [\n { value: \"\", label: \"Any status\" },\n { value: \"queued\", label: \"Queued\" },\n { value: \"running\", label: \"Running\" },\n { value: \"succeeded\", label: \"Succeeded\" },\n { value: \"failed\", label: \"Failed\" },\n { value: \"canceled\", label: \"Canceled\" },\n];\n\nconst KIND_OPTIONS: Array<{ value: ExecutionKind | \"\"; label: string }> = [\n { value: \"\", label: \"Any type\" },\n { value: \"function\", label: \"Function\" },\n { value: \"endpoint\", label: \"Endpoint\" },\n { value: \"workflow\", label: \"Workflow\" },\n];\n\n/**\n * The history view's filter/search bar: free text, status, (optionally) kind,\n * and a start-date window, plus a Clear control that appears only once there is\n * something to clear.\n *\n * A pure controlled leaf. Every change reports exactly one field's new value,\n * spread over the value it was given — a control that rebuilt the whole object\n * would silently drop a sibling filter the moment the two are edited close\n * together, and the host is the only party that knows the authoritative value.\n *\n * Each control carries its own `aria-label`: the visible layout is one dense\n * row of heterogeneous controls (a search box, three or four dropdowns, two\n * date pickers) with no room for a label per control, so the accessible name is\n * what tells them apart.\n */\nexport function ExecutionFilters({\n value,\n onChange,\n showKind = false,\n searchPlaceholder = \"Search by id or name\",\n disabled = false,\n}: ExecutionFiltersProps) {\n const clearable =\n value.status !== \"\" ||\n value.kind !== \"\" ||\n value.from !== \"\" ||\n value.to !== \"\" ||\n value.q !== \"\";\n\n return (\n <div className=\"w6w-execution-filters\" data-testid=\"execution-filters\">\n <input\n type=\"search\"\n className=\"w6w-execution-filters-search\"\n data-testid=\"execution-filter-q\"\n aria-label=\"Search executions\"\n placeholder={searchPlaceholder}\n value={value.q}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, q: e.target.value })}\n />\n <select\n className=\"w6w-execution-filters-select\"\n data-testid=\"execution-filter-status\"\n aria-label=\"Status\"\n value={value.status}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, status: e.target.value as ExecutionStatus | \"\" })}\n >\n {STATUS_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n {showKind && (\n <select\n className=\"w6w-execution-filters-select\"\n data-testid=\"execution-filter-kind\"\n aria-label=\"Type\"\n value={value.kind}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, kind: e.target.value as ExecutionKind | \"\" })}\n >\n {KIND_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n <input\n type=\"date\"\n className=\"w6w-execution-filters-date\"\n data-testid=\"execution-filter-from\"\n aria-label=\"From date\"\n value={value.from}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n />\n <input\n type=\"date\"\n className=\"w6w-execution-filters-date\"\n data-testid=\"execution-filter-to\"\n aria-label=\"To date\"\n value={value.to}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n />\n {clearable && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-execution-filters-clear\"\n data-testid=\"execution-filter-clear\"\n disabled={disabled}\n onClick={() => onChange({ ...EMPTY })}\n >\n Clear\n </button>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { formatDurationMs } from \"./execution-format.ts\";\n\n/**\n * The aggregate numbers of a history view — the same rows the list shows,\n * rolled up (D1: stats are computed over the same visibility the list uses, so\n * the two can never disagree about who may see what).\n *\n * `succeeded`/`canceled` are carried even though the strip renders no card for\n * them today: the host's payload has them, the breakdown is what a host needs\n * for a chart or a chip row, and a host re-deriving them from the list would be\n * computing the same total a second time.\n */\nexport interface ExecutionStatsValue {\n /** Every run in the current filter — the denominator of `successRate`. */\n total: number;\n succeeded: number;\n failed: number;\n canceled: number;\n /** Runs that are queued or running right now. `> 0` is what makes the\n * `In flight` card exist at all. */\n inFlight: number;\n /** `0…1`, or `null` when the host has no rate to report (no runs at all —\n * a rate over zero runs is not 0%). */\n successRate: number | null;\n /** Mean wall-clock duration of the FINISHED runs, or `null` when none has\n * finished. */\n avgDurationMs: number | null;\n}\n\nexport interface ExecutionStatsProps {\n /** The aggregate, or `null` while nothing has loaded yet — rendered as `—`\n * per card rather than as a spinner, so the strip never changes height. */\n stats: ExecutionStatsValue | null;\n /** Caption above the cards, e.g. the window they cover (\"Last 7 days\").\n * Omitted ⇒ no node at all. */\n label?: ReactNode;\n}\n\n/** What an absent/unknown number renders as — never `0`, which would read as a\n * measured result. Same em dash `execution-format.ts` uses for the same\n * reason. */\nconst UNKNOWN = \"—\";\n\ninterface Card {\n testid: string;\n label: string;\n value: string;\n}\n\n/**\n * A headline strip of run aggregates: one big value over a muted label per\n * card.\n *\n * Promotes studio `DashboardPage.tsx`'s page-local `StatCard` into `ui`, with\n * two differences that come from this being a shared component rather than one\n * page's private helper: the values are pre-formatted here (a rate as `67%`, a\n * duration through `formatDurationMs`) so every consumer renders the same\n * string, and each card carries `data-stat-value` so a host can assert on the\n * value without re-parsing its own formatting.\n */\nexport function ExecutionStats({ stats, label }: ExecutionStatsProps) {\n const cards: Card[] = [\n {\n testid: \"execution-stat-total\",\n label: \"Executions\",\n value: stats ? String(stats.total) : UNKNOWN,\n },\n {\n testid: \"execution-stat-success-rate\",\n label: \"Success rate\",\n value: formatSuccessRate(stats?.successRate),\n },\n {\n testid: \"execution-stat-failed\",\n label: \"Failed\",\n value: stats ? String(stats.failed) : UNKNOWN,\n },\n {\n testid: \"execution-stat-avg-duration\",\n label: \"Avg duration\",\n value: stats ? formatDurationMs(stats.avgDurationMs) : UNKNOWN,\n },\n ];\n\n // The one CONDITIONAL card: a zero in-flight count is the steady state, and a\n // permanent \"In flight 0\" would draw the eye to the least interesting number\n // in the strip. A missing `stats` counts as zero, so the strip keeps four\n // cards while loading instead of five-then-four.\n if (stats && stats.inFlight > 0) {\n cards.push({\n testid: \"execution-stat-in-flight\",\n label: \"In flight\",\n value: String(stats.inFlight),\n });\n }\n\n return (\n <section className=\"w6w-execution-stats\" data-testid=\"execution-stats\">\n {label != null && <p className=\"w6w-execution-stats-label\">{label}</p>}\n <div className=\"w6w-execution-stats-cards\">\n {cards.map((card) => (\n <div key={card.testid} className=\"w6w-execution-stat\" data-testid={card.testid}>\n <span className=\"w6w-execution-stat-value\" data-stat-value={card.value}>\n {card.value}\n </span>\n <span className=\"w6w-execution-stat-label\">{card.label}</span>\n </div>\n ))}\n </div>\n </section>\n );\n}\n\n/**\n * A `0…1` rate as a whole-percent string (`0.666…` → `\"67%\"`, rounded rather\n * than floored so `2/3` does not read as `66%`).\n *\n * `null` (nothing to report) and a non-finite rate (a host dividing by zero\n * somewhere upstream) are both `—` — the same totality `formatDurationMs`\n * keeps, so no input can render `NaN%`.\n */\nfunction formatSuccessRate(rate: number | null | undefined): string {\n if (rate == null || !Number.isFinite(rate)) return UNKNOWN;\n return `${Math.round(rate * 100)}%`;\n}\n","import type { ReactNode } from \"react\";\nimport { CodeBlock } from \"../CodeBlock.tsx\";\nimport type { ExecutionKind } from \"./ExecutionList.tsx\";\nimport { ExecutionLogPanel } from \"./ExecutionLogPanel.tsx\";\nimport type { ExecutionLogStep } from \"./ExecutionLogPanel.tsx\";\nimport { IconButton } from \"./IconButton.tsx\";\nimport { StepStatusPill } from \"./StepStatusPill.tsx\";\nimport type { ExecutionStatus } from \"./StepStatusPill.tsx\";\nimport { formatDurationMs, formatExecutionTime } from \"./execution-format.ts\";\n\n/**\n * One past execution in full — an already-mapped slice of the host's history\n * payload, the detail-level sibling of `ExecutionListItem`. The HOST maps its\n * own record into this shape; this component never fetches, polls or reaches\n * for an SDK.\n *\n * D2: there is no log-line field anywhere in this shape, on purpose — \"logs\"\n * for an execution ARE its status, timing, input, output and error, and for a\n * workflow that is the per-step `steps` list below.\n */\nexport interface ExecutionDetailValue {\n id: string;\n kind: ExecutionKind;\n callableName: string;\n status: ExecutionStatus;\n /** ISO-8601 instant the run started. */\n startedAt: string;\n /** ISO-8601 instant the run finished, or `null` while it is still\n * queued/running (rendered as `—`). */\n finishedAt: string | null;\n /** Wall-clock duration once the run has finished, or `null` while it has not\n * (rendered as `—`). */\n durationMs: number | null;\n /** The run's own input, once it is known. `undefined` = \"not available\" (no\n * section); `null` = \"available, and it is null\" (section renders `null`). */\n input?: unknown;\n output?: unknown;\n /** The failure's payload for a failed run. `null`/`undefined` = no error\n * section at all — the reverse gate to `input`/`output`, because an error\n * that is `null` is the absence of an error. */\n error?: unknown;\n /** A workflow run's steps. `undefined` = not a step-bearing run (no section);\n * `[]` = it ran and no step did (the panel's own empty state). */\n steps?: ExecutionLogStep[];\n}\n\nexport interface ExecutionDetailProps {\n /** The execution to show, or `null` when there is nothing to show yet. */\n execution: ExecutionDetailValue | null;\n /** `true` while the fetch for a `null` `execution` is still in flight —\n * renders the loading branch. Once an `execution` is present it is rendered\n * as-is: a host re-fetching (polling a running run) keeps showing the last\n * known state rather than flashing back to \"Loading…\". */\n loading?: boolean;\n /** A failure to surface, e.g. the fetch for this execution failed. Rendered\n * as an alert in EVERY branch — it is about the view, not about the run. */\n errorMessage?: ReactNode;\n /** Supplied ⇒ a dismiss control renders and calls this. Omitted ⇒ no\n * control. */\n onClose?: () => void;\n /** Supplied ⇒ the \"Open in visual editor\" button renders and calls this.\n * Omitted ⇒ no button (a function/endpoint run has no visual editor to open). */\n onOpenInEditor?: () => void;\n}\n\nconst KIND_LABEL: Record<ExecutionKind, string> = {\n function: \"Function\",\n endpoint: \"Endpoint\",\n workflow: \"Workflow\",\n};\n\n/** A value the section is showing that JSON cannot serialise (`undefined`,\n * a function, a symbol) renders as `null` rather than an empty block. */\nfunction toJson(value: unknown): string {\n return JSON.stringify(value, null, 2) ?? \"null\";\n}\n\n/**\n * Everything known about one past execution: which callable it was and how it\n * went, its timing, its own input/output/error, and — for a workflow run — the\n * per-step list.\n *\n * The per-step list sits directly under the timing, above the run's own\n * payloads: for a workflow it is the substance of the view (D2), and burying it\n * under three JSON blocks would make the run read as a function call with\n * appendices.\n *\n * A pure display leaf — no fetching, no polling, no live-ticking timer.\n */\nexport function ExecutionDetail({\n execution,\n loading = false,\n errorMessage,\n onClose,\n onOpenInEditor,\n}: ExecutionDetailProps) {\n return (\n <section className=\"w6w-execution-detail w6w-stack\" data-testid=\"execution-detail\">\n {errorMessage != null && (\n <p\n role=\"alert\"\n className=\"w6w-execution-detail-error-message\"\n data-testid=\"execution-detail-error-message\"\n >\n {errorMessage}\n </p>\n )}\n {execution ? (\n <Body execution={execution} onClose={onClose} onOpenInEditor={onOpenInEditor} />\n ) : loading ? (\n <p className=\"w6w-muted\" data-testid=\"execution-detail-loading\">\n Loading…\n </p>\n ) : (\n <p className=\"w6w-muted\" data-testid=\"execution-detail-empty\">\n No execution selected.\n </p>\n )}\n </section>\n );\n}\n\nfunction Body({\n execution,\n onClose,\n onOpenInEditor,\n}: {\n execution: ExecutionDetailValue;\n onClose?: () => void;\n onOpenInEditor?: () => void;\n}) {\n return (\n <>\n <div className=\"w6w-execution-detail-head\">\n <div className=\"w6w-execution-detail-title\">\n <h3 className=\"w6w-execution-detail-name\">{execution.callableName}</h3>\n <div className=\"w6w-execution-detail-meta\">\n <StepStatusPill state={execution.status} />\n <span className=\"w6w-execution-detail-kind w6w-muted w6w-small\">\n {KIND_LABEL[execution.kind]}\n </span>\n </div>\n </div>\n {(onOpenInEditor || onClose) && (\n <div className=\"w6w-execution-detail-actions\">\n {onOpenInEditor && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"execution-detail-open-editor\"\n onClick={onOpenInEditor}\n >\n Open in visual editor\n </button>\n )}\n {onClose && (\n <IconButton label=\"Close\" data-testid=\"execution-detail-close\" onClick={onClose}>\n ×\n </IconButton>\n )}\n </div>\n )}\n </div>\n\n <p className=\"w6w-execution-detail-id-line\">\n <code className=\"w6w-execution-detail-id\" data-testid=\"execution-detail-id\">\n {execution.id}\n </code>\n </p>\n\n <dl className=\"w6w-execution-detail-timing\">\n <TimingItem label=\"Started\" value={formatExecutionTime(execution.startedAt)} />\n <TimingItem\n label=\"Finished\"\n value={execution.finishedAt ? formatExecutionTime(execution.finishedAt) : \"—\"}\n />\n <TimingItem label=\"Duration\" value={formatDurationMs(execution.durationMs)} />\n </dl>\n\n {execution.steps !== undefined && (\n <section\n className=\"w6w-execution-detail-section w6w-stack\"\n data-testid=\"execution-detail-steps\"\n >\n <strong className=\"w6w-small\">Steps</strong>\n <ExecutionLogPanel steps={execution.steps} emptyLabel=\"No steps ran.\" />\n </section>\n )}\n\n {execution.input !== undefined && (\n <JsonSection title=\"Input\" testid=\"execution-detail-input\" value={execution.input} />\n )}\n {execution.output !== undefined && (\n <JsonSection title=\"Output\" testid=\"execution-detail-output\" value={execution.output} />\n )}\n {execution.error != null && (\n <JsonSection title=\"Error\" testid=\"execution-detail-error\" value={execution.error} />\n )}\n </>\n );\n}\n\nfunction TimingItem({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"w6w-execution-detail-timing-item\">\n <dt>{label}</dt>\n <dd>{value}</dd>\n </div>\n );\n}\n\n/**\n * One payload as read-only, syntax-highlighted JSON — `CodeBlock`, the same\n * idiom `ExecutionLogPanel` renders a step's input/output through (see its own\n * doc comment for why `CodeBlock` and not `JsonEditor`/`<pre>`).\n */\nfunction JsonSection({ title, testid, value }: { title: string; testid: string; value: unknown }) {\n return (\n <section className=\"w6w-execution-detail-section w6w-stack\" data-testid={testid}>\n <strong className=\"w6w-small\">{title}</strong>\n <CodeBlock code={toJson(value)} language=\"json\" />\n </section>\n );\n}\n","/**\n * How the reliability board arranges itself — the decisions that are arithmetic\n * rather than markup, kept pure (no React, no DOM) so they test without a DOM\n * and so `@w6w/embed` can import them beside the components.\n *\n * **None of these decide a STATE.** Every state read below arrived already\n * decided by the server; nothing here compares a ratio, applies a threshold to\n * call data, or invents a fifth word. What these decide is where a row is PUT,\n * which is presentation.\n */\n\n/** The four words the server uses for a health verdict. */\nexport type ReliabilityViewState = \"ok\" | \"degraded\" | \"down\" | \"unknown\";\n\n/**\n * The row shape the reliability components render — owned by `@w6w/ui` so it\n * imports nothing from the SDK. The SDK's `ReliabilityService` assigns to it\n * structurally; the generic functions below keep the caller's richer row type.\n */\nexport interface ReliabilityServiceView {\n appId: string;\n displayName: string;\n /** Inline icon fields — the board never asks a catalog for them. */\n iconSrc?: string;\n iconSrcDark?: string;\n brandColor?: string;\n /** \"Did YOUR calls succeed\". */\n state: ReliabilityViewState;\n calls: number;\n errors: { e4xx: number; e429: number; eAuth: number; e5xx: number };\n p95Ms: number | null;\n ongoingOutageId: string | null;\n /** One entry per calendar day, oldest first, exactly as the server sent it. */\n uptime: readonly { day: string; state: ReliabilityViewState }[];\n /** \"What does the vendor say about itself\"; `null` when no public check exists. */\n vendorStatus: { state: ReliabilityViewState; message: string | null } | null;\n /** The server's tier for the row — read, never re-derived. */\n attention: \"now\" | \"recent\" | \"none\";\n}\n\n/** One point of the performance scatter — a service with both a call volume and a measured p95. */\nexport interface PerformancePoint {\n appId: string;\n displayName: string;\n calls: number;\n p95Ms: number;\n state: ReliabilityViewState;\n /** Total errors across all four kinds — drives the point's size, not its position. */\n errorCount: number;\n}\n\n/**\n * Every service with at least one timed call, as a (calls, p95) point — what\n * the performance chart plots. Excludes `p95Ms: null`: there is no Y position\n * for a service with nothing timed.\n */\nexport function performancePoints(services: readonly ReliabilityServiceView[]): PerformancePoint[] {\n const points: PerformancePoint[] = [];\n for (const s of services) {\n if (s.p95Ms === null) continue;\n points.push({\n appId: s.appId,\n displayName: s.displayName,\n calls: s.calls,\n p95Ms: s.p95Ms,\n state: s.state,\n errorCount: s.errors.e4xx + s.errors.e429 + s.errors.eAuth + s.errors.e5xx,\n });\n }\n return points;\n}\n\n/**\n * Does this service want the reader's attention? READS the tier the server\n * sent (`attention`), never re-derives it from `state` or `vendorStatus`: the\n * server's `boardRank` is the one implementation, and a second copy here would\n * drift. `now` and `recent` both count; they differ in tense only.\n */\nexport function needsAttention(service: Pick<ReliabilityServiceView, \"attention\">): boolean {\n return service.attention === \"now\" || service.attention === \"recent\";\n}\n\n/** The board in its three groups, each keeping the server's own ordering. */\nexport interface BoardPartition<T extends ReliabilityServiceView = ReliabilityServiceView> {\n /** Broken right now, on either signal. */\n now: T[];\n /** Clear now, but this window holds a failed stretch or an open advisory. */\n recent: T[];\n /** Everything else, in the server's recency order. */\n clear: T[];\n}\n\n/**\n * Group the board without reordering within any group. Bucketing is not\n * sorting: each group comes out in the order it arrived. An unrecognised\n * `attention` value falls to `clear` rather than throwing — a client can be\n * older than the server that answered it.\n */\nexport function partitionBoard<T extends ReliabilityServiceView>(\n services: readonly T[],\n): BoardPartition<T> {\n const groups: BoardPartition<T> = { now: [], recent: [], clear: [] };\n for (const s of services) {\n if (s.attention === \"now\") groups.now.push(s);\n else if (s.attention === \"recent\") groups.recent.push(s);\n else groups.clear.push(s);\n }\n return groups;\n}\n\n/**\n * The uptime strip's cells for one service — the server's own array, in the\n * order it arrived (oldest first). A passthrough on purpose: no sort, no\n * reverse, no gap filling. The strip has no date axis, so a reversed array is\n * visually plausible and would silently move an outage to the wrong end.\n */\nexport function uptimeDays(service: Pick<ReliabilityServiceView, \"uptime\">): {\n day: string;\n state: ReliabilityViewState;\n}[] {\n return service.uptime.map((entry) => ({ day: entry.day, state: entry.state }));\n}\n\n/** Compact mode shows at most this many needs-attention cards, `now` filling first. */\nexport const ATTENTION_DISPLAY_CAP = 3;\n/** Compact mode shows this many table rows unless the caller passes `limit`. */\nexport const RECENT_DISPLAY_CAP = 5;\n\n/** What the board shows and what a display cap hid. */\nexport interface BoardDisplay<T extends ReliabilityServiceView = ReliabilityServiceView> {\n /** TRUE total of attention rows (the whole input, not the capped slice). */\n attentionCount: number;\n shownNow: T[];\n shownRecent: T[];\n hiddenAttentionCount: number;\n /** Table rows in the server's order, every attention tier included. */\n shownTable: T[];\n hiddenTableCount: number;\n}\n\n/**\n * Apply the display caps to the complete board. Compact: ≤ 3 attention cards\n * (`now` first, `recent` tops up) and `limit ?? 5` table rows; otherwise\n * uncapped. Hidden counts are computed from the full input, so they are real.\n */\nexport function displayBoard<T extends ReliabilityServiceView>(\n services: readonly T[],\n opts: { compact?: boolean; limit?: number } = {},\n): BoardDisplay<T> {\n const compact = opts.compact ?? false;\n const { now, recent } = partitionBoard(services);\n const attentionCount = now.length + recent.length;\n const shownNow = compact ? now.slice(0, ATTENTION_DISPLAY_CAP) : now;\n const shownRecent = compact\n ? recent.slice(0, Math.max(0, ATTENTION_DISPLAY_CAP - shownNow.length))\n : recent;\n const shownTable = compact ? services.slice(0, opts.limit ?? RECENT_DISPLAY_CAP) : [...services];\n return {\n attentionCount,\n shownNow,\n shownRecent,\n hiddenAttentionCount: attentionCount - shownNow.length - shownRecent.length,\n shownTable,\n hiddenTableCount: services.length - shownTable.length,\n };\n}\n","import type { ReactElement, MouseEvent as ReactMouseEvent } from \"react\";\nimport { type ReliabilityServiceView, performancePoints } from \"../reliability-board-layout.ts\";\n\n/**\n * The performance chart — call volume × p95 latency, one point per API. One\n * axis never tells the whole story: a slow service nobody calls much matters\n * less than a slow service taking most of the traffic, so this is a real 2-axis\n * scatter, not a bar-per-app list.\n *\n * Ring colour carries exec status via the `--w6w-health-*` tokens (same as the\n * table's pills) and dot size carries the error count. Rows arrive with every\n * field they need; the chart makes no request.\n *\n * Navigation is the host's: with `getHref` each point is a real SVG `<a href>`;\n * a click calls `onOpen(appId, event)` and is never `preventDefault`ed here.\n * Neither given ⇒ points are not links.\n *\n * A fixed `viewBox` with a matching CSS `aspect-ratio` keeps points circular.\n * The y-axis runs INVERTED — 0ms at the top, the max at the bottom — so \"up\"\n * reads as \"better\" the same way \"right\" (more calls) does: the top-right\n * corner is fast AND heavily used.\n */\nconst WIDTH = 640;\nconst HEIGHT = 340;\nconst PAD = { top: 16, right: 24, bottom: 40, left: 56 };\n\nfunction niceMax(value: number): number {\n if (value <= 0) return 1;\n const magnitude = 10 ** Math.floor(Math.log10(value));\n const steps = [1, 2, 5, 10];\n for (const step of steps) {\n if (value <= step * magnitude) return step * magnitude;\n }\n return 10 * magnitude;\n}\n\nfunction ticks(max: number, count = 5): number[] {\n return Array.from({ length: count + 1 }, (_, i) => Math.round((max * i) / count));\n}\n\nexport interface ReliabilityChartProps<T extends ReliabilityServiceView = ReliabilityServiceView> {\n services: readonly T[];\n /** Real `<a href>` on each point when given. */\n getHref?: (appId: string) => string;\n /** Called on a point click; the host decides whether to `preventDefault`. */\n onOpen?: (appId: string, event: ReactMouseEvent<Element>) => void;\n}\n\nexport function ReliabilityChart<T extends ReliabilityServiceView>({\n services,\n getHref,\n onOpen,\n}: ReliabilityChartProps<T>): ReactElement {\n const points = performancePoints(services);\n\n if (points.length === 0) {\n return <p className=\"w6w-muted w6w-small\">No timed calls in this window yet.</p>;\n }\n\n const maxCalls = niceMax(Math.max(...points.map((p) => p.calls)));\n const maxP95 = niceMax(Math.max(...points.map((p) => p.p95Ms)));\n const maxErrors = Math.max(1, ...points.map((p) => p.errorCount));\n\n const plotW = WIDTH - PAD.left - PAD.right;\n const plotH = HEIGHT - PAD.top - PAD.bottom;\n const x = (calls: number) => PAD.left + (calls / maxCalls) * plotW;\n // Inverted on purpose — lower p95 (faster) sits HIGHER on the plot.\n const y = (p95: number) => PAD.top + (p95 / maxP95) * plotH;\n // 16px..30px icon diameter, scaled by error share.\n const iconSize = (errors: number) => 16 + (errors / maxErrors) * 14;\n\n const xTicks = ticks(maxCalls);\n const yTicks = ticks(maxP95);\n const yAxisTitleX = 18;\n const yAxisTitleY = PAD.top + plotH / 2;\n\n return (\n <div className=\"w6w-rel-scatter\">\n <svg\n viewBox={`0 0 ${WIDTH} ${HEIGHT}`}\n style={{ aspectRatio: `${WIDTH} / ${HEIGHT}` }}\n role=\"img\"\n aria-label=\"API performance: calls versus p95 latency, one point per API\"\n >\n <rect\n x={PAD.left}\n y={PAD.top}\n width={plotW}\n height={plotH}\n className=\"w6w-rel-scatter-plot-bg\"\n />\n\n {yTicks.map((t) => (\n <g key={`y-${t}`}>\n <line\n x1={PAD.left}\n x2={WIDTH - PAD.right}\n y1={y(t)}\n y2={y(t)}\n className=\"w6w-rel-scatter-grid\"\n />\n <text x={PAD.left - 8} y={y(t)} className=\"w6w-rel-scatter-axis-label\" textAnchor=\"end\">\n {t}\n </text>\n </g>\n ))}\n {xTicks.map((t) => (\n <text\n key={`x-${t}`}\n x={x(t)}\n y={HEIGHT - PAD.bottom + 18}\n className=\"w6w-rel-scatter-axis-label\"\n textAnchor=\"middle\"\n >\n {t}\n </text>\n ))}\n\n {/* Anchored on its own pivot so the rotation never leaves the viewBox. */}\n <text\n x={yAxisTitleX}\n y={yAxisTitleY}\n className=\"w6w-rel-scatter-axis-title\"\n textAnchor=\"middle\"\n transform={`rotate(-90, ${yAxisTitleX}, ${yAxisTitleY})`}\n >\n p95 (ms)\n </text>\n <text\n x={PAD.left + plotW / 2}\n y={HEIGHT - 4}\n className=\"w6w-rel-scatter-axis-title\"\n textAnchor=\"middle\"\n >\n calls in this window\n </text>\n\n {points.map((p) => {\n const size = iconSize(p.errorCount);\n const cx = x(p.calls);\n const cy = y(p.p95Ms);\n const dots = (\n <>\n <circle\n cx={cx}\n cy={cy}\n r={size / 2 + 2.5}\n className={`w6w-rel-scatter-ring w6w-rel-scatter-ring-${p.state}`}\n >\n <title>\n {p.displayName} — {p.calls} calls, {p.p95Ms} ms p95, {p.errorCount} errors\n </title>\n </circle>\n <circle\n cx={cx}\n cy={cy}\n r={size / 2}\n className={`w6w-rel-scatter-point w6w-rel-scatter-point-${p.state}`}\n />\n </>\n );\n if (getHref) {\n return (\n <a\n key={p.appId}\n href={getHref(p.appId)}\n className=\"w6w-rel-scatter-point-link\"\n onClick={onOpen ? (e) => onOpen(p.appId, e) : undefined}\n >\n {dots}\n </a>\n );\n }\n if (onOpen) {\n return (\n <g\n key={p.appId}\n // biome-ignore lint/a11y/useSemanticElements: an SVG group cannot be a <button>\n role=\"button\"\n tabIndex={0}\n className=\"w6w-rel-scatter-point-link\"\n onClick={(e) => onOpen(p.appId, e)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (e.currentTarget as unknown as HTMLElement).dispatchEvent(\n new MouseEvent(\"click\", { bubbles: true }),\n );\n }\n }}\n >\n {dots}\n </g>\n );\n }\n return <g key={p.appId}>{dots}</g>;\n })}\n </svg>\n <p className=\"w6w-muted w6w-small w6w-rel-scatter-note\">\n Up is faster, right is more calls — top-right is the best outcome. Icon size is the error\n count in this window; ring colour is exec status.\n </p>\n </div>\n );\n}\n","import type { MouseEvent, ReactElement, ReactNode } from \"react\";\nimport {\n type ReliabilityServiceView,\n displayBoard,\n uptimeDays,\n} from \"../reliability-board-layout.ts\";\nimport { AppIcon } from \"./AppIcon.tsx\";\nimport { HealthStatusPill } from \"./HealthStatusPill.tsx\";\nimport { ReliabilityChart } from \"./ReliabilityChart.tsx\";\nimport { UptimeStrip } from \"./UptimeStrip.tsx\";\n\n/**\n * The reliability board's presentation: needs-attention cards, the\n * performance chart and the services table, drawn from rows passed in.\n * Router-free and request-free (no provider needed) — icons come from the\n * rows' own `iconSrc`/`iconSrcDark`/`brandColor`. Loading, error and\n * no-project states belong to whatever fetches the rows.\n *\n * Navigation, at every site (issue card, service cell, chart point): with\n * `getHref` a real anchor; a click calls `onOpen(appId, event)` and is never\n * `preventDefault`ed here; only `onOpen` ⇒ a button; neither ⇒ not a link.\n */\n\ntype Open = (appId: string, event: MouseEvent<Element>) => void;\n\nexport interface ReliabilityListWindow {\n from: string;\n to: string;\n days: number;\n}\n\nexport interface ReliabilityListProps<T extends ReliabilityServiceView = ReliabilityServiceView> {\n services: readonly T[];\n /** The window the rows cover; labels the heading. */\n window?: ReliabilityListWindow;\n /** Table column label (\"Last N days\"); defaults to `window?.days ?? 30`. */\n days?: number;\n /** Trim the display: ≤3 attention cards, `limit ?? 5` table rows, chart off. */\n compact?: boolean;\n /** Defaults to `!compact`. */\n showChart?: boolean;\n /** Compact table row cap (default 5). */\n limit?: number;\n getHref?: (appId: string) => string;\n onOpen?: Open;\n /** \"Show all services →\" / \"view all →\" render only when one of these is given. */\n showAllHref?: string;\n onShowAll?: (event: MouseEvent<Element>) => void;\n slots?: {\n /** Replaces the \"Service reliability\" title text. */\n header?: ReactNode;\n /** Rendered at the end of the heading row. */\n actions?: ReactNode;\n /** Replaces the \"No services yet\" message. */\n empty?: ReactNode;\n };\n}\n\n/** Short date for the window line (\"Jun 28 – Jul 27\"). */\nfunction formatDay(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return d.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" });\n}\n\n/** The one anchor/button/plain wrapper every navigation site shares. */\nfunction Target({\n appId,\n className,\n title,\n getHref,\n onOpen,\n children,\n}: {\n appId: string;\n className: string;\n title?: string;\n getHref?: (appId: string) => string;\n onOpen?: Open;\n children: ReactNode;\n}) {\n if (getHref) {\n return (\n <a\n className={className}\n href={getHref(appId)}\n title={title}\n onClick={onOpen ? (e) => onOpen(appId, e) : undefined}\n >\n {children}\n </a>\n );\n }\n if (onOpen) {\n return (\n <button type=\"button\" className={className} title={title} onClick={(e) => onOpen(appId, e)}>\n {children}\n </button>\n );\n }\n return (\n <div className={className} title={title}>\n {children}\n </div>\n );\n}\n\n/** \"Did YOUR calls succeed\" — shared by the table cell and the issue card. */\nfunction ExecStatusSignal({ service }: { service: ReliabilityServiceView }) {\n return (\n <span className=\"w6w-rel-signal\">\n <HealthStatusPill state={service.state} />\n {service.ongoingOutageId && <span className=\"w6w-rel-tag\">outage open</span>}\n {service.calls === 0 && <span className=\"w6w-muted w6w-small\">no calls</span>}\n </span>\n );\n}\n\n/**\n * The API's own status, from the app's declared public health check. Kept a\n * SEPARATE signal from `ExecStatusSignal`: they answer different questions and\n * routinely disagree usefully. `null` ⇒ \"not published\", not an `unknown` pill.\n */\nfunction ApiStatusSignal({ vendor }: { vendor: ReliabilityServiceView[\"vendorStatus\"] }) {\n if (!vendor) return <span className=\"w6w-muted w6w-small\">not published</span>;\n // `unknown` is about US, not the API: we asked and could not tell.\n const unreadable = vendor.state === \"unknown\";\n return (\n <span className=\"w6w-rel-signal\" title={vendor.message ?? undefined}>\n <HealthStatusPill state={vendor.state} label={unreadable ? \"Unavailable\" : undefined} />\n {!unreadable && vendor.message && (\n <span className=\"w6w-rel-vendor-msg w6w-small\">{vendor.message}</span>\n )}\n </span>\n );\n}\n\ninterface NavProps {\n getHref?: (appId: string) => string;\n onOpen?: Open;\n}\n\nfunction IssueCard({ service, getHref, onOpen }: { service: ReliabilityServiceView } & NavProps) {\n return (\n <Target\n appId={service.appId}\n className=\"w6w-rel-issue-card\"\n title={`${service.displayName} — open service detail`}\n getHref={getHref}\n onOpen={onOpen}\n >\n <span className=\"w6w-rel-issue-head\">\n <AppIcon\n src={service.iconSrc}\n srcDark={service.iconSrcDark}\n brandColor={service.brandColor}\n name={service.displayName}\n size={24}\n />\n <span className=\"w6w-rel-issue-head-text\">\n <strong>{service.displayName}</strong>\n {service.attention === \"recent\" && (\n <span className=\"w6w-muted w6w-small\">trouble earlier in this window</span>\n )}\n </span>\n </span>\n <span className=\"w6w-rel-issue-signals\">\n <span className=\"w6w-rel-issue-signal\">\n <span className=\"w6w-muted w6w-small\">w6w exec</span>\n <ExecStatusSignal service={service} />\n </span>\n <span className=\"w6w-rel-issue-signal\">\n <span className=\"w6w-muted w6w-small\">API status</span>\n <ApiStatusSignal vendor={service.vendorStatus} />\n </span>\n </span>\n </Target>\n );\n}\n\nfunction ServiceTableRow({\n service,\n getHref,\n onOpen,\n}: { service: ReliabilityServiceView } & NavProps) {\n const noCalls = service.calls === 0;\n return (\n <tr\n className={`w6w-rel-tr${service.attention !== \"none\" ? \" w6w-rel-attention\" : \"\"}`}\n data-attention={service.attention === \"none\" ? undefined : service.attention}\n >\n <td className=\"w6w-rel-td-service\">\n <Target appId={service.appId} className=\"w6w-rel-open\" getHref={getHref} onOpen={onOpen}>\n <AppIcon\n src={service.iconSrc}\n srcDark={service.iconSrcDark}\n brandColor={service.brandColor}\n name={service.displayName}\n size={28}\n />\n <span className=\"w6w-rel-td-service-text\">\n <strong>{service.displayName}</strong>\n <code className=\"w6w-muted w6w-small\">{service.appId}</code>\n </span>\n </Target>\n </td>\n\n <td className=\"w6w-rel-td-status\">\n <span className=\"w6w-rel-status-row\">\n <span className=\"w6w-rel-status-label w6w-muted w6w-small\">Ops</span>\n <ExecStatusSignal service={service} />\n </span>\n <span className=\"w6w-rel-status-row\">\n <span className=\"w6w-rel-status-label w6w-muted w6w-small\">API</span>\n <ApiStatusSignal vendor={service.vendorStatus} />\n </span>\n </td>\n\n <td className=\"w6w-rel-td-uptime\">\n {noCalls ? (\n // A zero-call window is one identical hatched strip — the note says it better.\n <span className=\"w6w-rel-idle-note\">No calls in this window</span>\n ) : (\n <>\n {/* Oldest day first, exactly as the server sent it. */}\n <UptimeStrip\n days={uptimeDays(service)}\n ariaLabel={`${service.displayName}, ${service.uptime.length}-day status, oldest day first`}\n />\n <span className=\"w6w-muted w6w-small\">{service.calls} calls</span>\n </>\n )}\n </td>\n\n <td className=\"w6w-rel-td-p95\">{service.p95Ms === null ? \"—\" : `${service.p95Ms} ms`}</td>\n </tr>\n );\n}\n\nexport function ReliabilityList<T extends ReliabilityServiceView>({\n services,\n window: win,\n days,\n compact = false,\n showChart,\n limit,\n getHref,\n onOpen,\n showAllHref,\n onShowAll,\n slots,\n}: ReliabilityListProps<T>): ReactElement {\n const windowDays = days ?? win?.days ?? 30;\n // Reads `state` ONLY, on purpose: the card's copy says every service \"came\n // back ok\", a statement about YOUR CALLS that stays true while a vendor\n // reports an incident you have not hit. The grouping below reads `attention`.\n const allClear = services.length > 0 && services.every((s) => s.calls > 0 && s.state === \"ok\");\n const {\n attentionCount,\n shownNow,\n shownRecent,\n hiddenAttentionCount,\n shownTable,\n hiddenTableCount,\n } = displayBoard(services, { compact, limit });\n const shouldShowChart = showChart ?? !compact;\n const canShowAll = showAllHref !== undefined || onShowAll !== undefined;\n const showAllLink = (text: string): ReactNode => {\n const className = text.startsWith(\"Show\") ? \"w6w-muted w6w-small\" : undefined;\n if (showAllHref !== undefined) {\n return (\n <a href={showAllHref} className={className} onClick={onShowAll}>\n {text}\n </a>\n );\n }\n if (onShowAll) {\n return (\n <button\n type=\"button\"\n className={`w6w-rel-show-all${className ? ` ${className}` : \"\"}`}\n onClick={onShowAll}\n >\n {text}\n </button>\n );\n }\n return null;\n };\n\n return (\n <section className=\"w6w-rel-section\">\n <h3 className=\"w6w-rel-heading\">\n <span>\n {slots?.header ?? \"Service reliability\"}{\" \"}\n {win && (\n <span className=\"w6w-muted w6w-small\">\n {formatDay(win.from)} – {formatDay(win.to)} · {win.days} days\n </span>\n )}\n </span>\n {compact && showAllLink(\"Show all services →\")}\n {slots?.actions}\n </h3>\n\n <div className={compact ? \"w6w-rel-card\" : undefined}>\n <p className=\"w6w-muted w6w-small w6w-rel-intro\">\n Connected services across your account. Performance for the selected project.\n </p>\n\n {allClear && (\n <div className={compact ? \"w6w-rel-allclear\" : \"w6w-rel-card w6w-rel-allclear\"}>\n <h4>All clear</h4>\n <p>\n Every service you called in the last {windowDays} days came back{\" \"}\n <HealthStatusPill state=\"ok\" /> — no degraded stretches, no outages.\n </p>\n </div>\n )}\n\n {services.length === 0 &&\n (slots?.empty ?? (\n <div className={compact ? undefined : \"w6w-rel-card\"}>\n <p className=\"w6w-muted\">\n No services yet — connect an integration or use a service in this project.\n </p>\n </div>\n ))}\n\n {services.length > 0 && (\n <>\n {attentionCount > 0 && (\n <div className=\"w6w-rel-group\">\n <h4 className=\"w6w-rel-group-head\">\n Needs attention{\" \"}\n <span className=\"w6w-muted w6w-small\">\n {shownNow.length + shownRecent.length} of {attentionCount}\n </span>\n </h4>\n <div className=\"w6w-rel-issues\">\n {[...shownNow, ...shownRecent].map((s) => (\n <IssueCard key={s.appId} service={s} getHref={getHref} onOpen={onOpen} />\n ))}\n </div>\n {hiddenAttentionCount > 0 && (\n <p className=\"w6w-muted w6w-small w6w-rel-more-note\">\n {hiddenAttentionCount} more {hiddenAttentionCount === 1 ? \"needs\" : \"need\"}{\" \"}\n attention{canShowAll && <> — {showAllLink(\"view all →\")}</>}\n </p>\n )}\n </div>\n )}\n\n {shouldShowChart && (\n <div className=\"w6w-rel-group\">\n <h4 className=\"w6w-rel-group-head\">Performance across your APIs</h4>\n <ReliabilityChart services={services} getHref={getHref} onOpen={onOpen} />\n </div>\n )}\n\n {shownTable.length > 0 && (\n <div className=\"w6w-rel-group\">\n <h4 className=\"w6w-rel-group-head\">\n {compact ? \"Services\" : \"All services\"}{\" \"}\n <span className=\"w6w-muted w6w-small\">\n {compact ? `${shownTable.length} of ${services.length}` : services.length}\n </span>\n </h4>\n <div className=\"w6w-rel-table-wrap\">\n <table className=\"w6w-rel-table\">\n <thead>\n <tr>\n <th>Service</th>\n <th>Status</th>\n <th>Last {windowDays} days</th>\n <th>Latency</th>\n </tr>\n </thead>\n <tbody>\n {shownTable.map((s) => (\n <ServiceTableRow\n key={s.appId}\n service={s}\n getHref={getHref}\n onOpen={onOpen}\n />\n ))}\n </tbody>\n </table>\n </div>\n {hiddenTableCount > 0 && (\n <p className=\"w6w-muted w6w-small w6w-rel-more-note\">\n {hiddenTableCount} more{canShowAll && <> — {showAllLink(\"view all →\")}</>}\n </p>\n )}\n </div>\n )}\n </>\n )}\n </div>\n </section>\n );\n}\n","import { type MouseEvent, type ReactNode, useState } from \"react\";\nimport { ListItem } from \"./ListItem.tsx\";\n\n/** One row of a {@link CallableList}. The host decides `archived`; the list never learns a kind. */\nexport interface CallableListRow {\n id: string;\n title: ReactNode;\n description?: ReactNode;\n archived: boolean;\n /** Extra badges, rendered before the archived badge in the trailing slot. */\n badges?: ReactNode;\n /** Trailing content; sits inside the row's anchor when `getHref` is set, so keep it non-interactive. */\n trailing?: ReactNode;\n}\n\nexport interface CallableListProps {\n rows: readonly CallableListRow[];\n title: ReactNode;\n description?: ReactNode;\n /** Shown when `rows` is empty (total, not the visible subset) and not `loading`. */\n emptyCopy?: ReactNode;\n /** Label of the New button. Defaults to \"New\". */\n newLabel?: string;\n /** Tooltip (`title` attribute) on each openable row. */\n openRowTitle?: string;\n testIds?: { showArchived?: string; importOpen?: string; archivedBadge?: string };\n loading?: boolean;\n error?: string | null;\n /** The New button renders only when this is set. */\n onCreate?: () => void;\n /** New button is disabled and reads \"Creating…\" while true. */\n creating?: boolean;\n /** The Import button renders only when this is set. */\n onImport?: () => void;\n /** Row click. The event is passed through untouched; the host may `preventDefault`. */\n onOpen?: (id: string, event: MouseEvent<Element>) => void;\n /** When set, each row is a real `<a href>`. */\n getHref?: (id: string) => string;\n /** Controlled \"Show archived\". Omit for an uncontrolled toggle that starts off. */\n showArchived?: boolean;\n onShowArchivedChange?: (next: boolean) => void;\n slots?: {\n /** Replaces the default title/description block (the Show-archived toggle stays). */\n header?: ReactNode;\n /** Rendered before Import/New. */\n actions?: ReactNode;\n /** Replaces `emptyCopy`. */\n empty?: ReactNode;\n };\n}\n\n/**\n * A presentational list of callables (Functions, Endpoints, Workflows): rows in, callbacks out.\n * Owns only the archived filter and its toggle; it knows no router, query, modal or kind.\n * Rows render through {@link ListItem}: a button with `onOpen`, an anchor with `getHref`.\n */\nexport function CallableList({\n rows,\n title,\n description,\n emptyCopy,\n newLabel = \"New\",\n openRowTitle,\n testIds,\n loading,\n error,\n onCreate,\n creating,\n onImport,\n onOpen,\n getHref,\n showArchived: showArchivedProp,\n onShowArchivedChange,\n slots,\n}: CallableListProps) {\n const [showArchivedState, setShowArchivedState] = useState(false);\n const controlled = showArchivedProp !== undefined;\n const showArchived = controlled ? showArchivedProp : showArchivedState;\n const visible = showArchived ? rows : rows.filter((r) => !r.archived);\n const interactive = onOpen !== undefined || getHref !== undefined;\n\n return (\n <section className=\"w6w-callable-list\">\n <div className=\"w6w-callable-list-head\">\n <div className=\"w6w-callable-list-heading\">\n {slots?.header ?? (\n <>\n <h2 className=\"w6w-callable-list-title\">{title}</h2>\n {description != null && (\n <p className=\"w6w-muted w6w-small w6w-callable-list-description\">{description}</p>\n )}\n </>\n )}\n <label className=\"w6w-muted w6w-small w6w-callable-list-toggle\">\n <input\n type=\"checkbox\"\n checked={showArchived}\n data-testid={testIds?.showArchived}\n onChange={(e) => {\n if (!controlled) setShowArchivedState(e.target.checked);\n onShowArchivedChange?.(e.target.checked);\n }}\n />\n Show archived\n </label>\n </div>\n <div className=\"w6w-callable-list-actions\">\n {slots?.actions}\n {onImport && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid={testIds?.importOpen}\n onClick={onImport}\n >\n Import\n </button>\n )}\n {onCreate && (\n <button type=\"button\" className=\"w6w-btn\" disabled={creating} onClick={onCreate}>\n {creating ? \"Creating…\" : newLabel}\n </button>\n )}\n </div>\n </div>\n\n {error && <div className=\"w6w-error\">{error}</div>}\n\n <div className=\"w6w-callable-list-body\">\n {loading && <p className=\"w6w-muted\">Loading…</p>}\n {rows.length === 0 && !loading && (\n <div className=\"w6w-muted\">{slots?.empty ?? emptyCopy}</div>\n )}\n <ul className=\"w6w-callable-list-rows\">\n {visible.map((row) => (\n <li key={row.id} title={interactive ? openRowTitle : undefined}>\n <ListItem\n title={row.title}\n subtitle={row.description}\n href={getHref?.(row.id)}\n onClick={onOpen ? (event) => onOpen(row.id, event) : undefined}\n trailing={\n row.archived || row.badges != null || row.trailing != null ? (\n <span className=\"w6w-callable-list-trail\">\n {row.badges}\n {row.archived && (\n <span\n className=\"w6w-callable-list-badge\"\n data-testid={testIds?.archivedBadge}\n >\n archived\n </span>\n )}\n {row.trailing}\n </span>\n ) : undefined\n }\n />\n </li>\n ))}\n </ul>\n </div>\n </section>\n );\n}\n","/**\n * Which app meta (name/icon/brand) a connection renders with. PURE and free of\n * runtime imports so `node --test` can load it.\n *\n * The server inlines `app` on each connection summary. Three states:\n * - an object -> render from it; no lookup.\n * - `null` -> the server found no app row; render the `appId` fallback and\n * never look it up (a lookup would only miss again).\n * - `undefined`-> an older server that does not inline it; use the by-id record\n * the apps provider resolved.\n */\n\n/** The display fields every renderer of a connection's app reads. */\nexport interface InlineAppMeta {\n displayName?: string;\n iconSvg?: string;\n iconSvgDark?: string;\n brandColor?: string;\n brandColorDark?: string;\n}\n\ninterface ConnectionLike {\n appId: string;\n app?: InlineAppMeta | null;\n}\n\n/** The meta to render a connection with, or `undefined` for the `appId` fallback. */\nexport function resolveConnectionAppMeta<A extends InlineAppMeta>(\n connection: ConnectionLike,\n byId: ReadonlyMap<string, A>,\n): InlineAppMeta | undefined {\n if (connection.app) return connection.app;\n if (connection.app === null) return undefined;\n return byId.get(connection.appId);\n}\n\n/**\n * The app ids to look up by id: the unique `appId`s, first-seen order, of the\n * connections whose `app` is `undefined`. Rows with an object or `null` are\n * excluded.\n */\nexport function connectionAppIdsToLookUp(connections: readonly ConnectionLike[]): string[] {\n const seen = new Set<string>();\n for (const c of connections) {\n if (c.app === undefined) seen.add(c.appId);\n }\n return [...seen];\n}\n","import type { MouseEvent, ReactNode } from \"react\";\nimport { type InlineAppMeta, resolveConnectionAppMeta } from \"../connection-app-meta.ts\";\nimport type { ConnectionSummary } from \"../types.ts\";\nimport { AppIcon } from \"./AppIcon.tsx\";\nimport { DeleteButton } from \"./DeleteButton.tsx\";\nimport { EditButton } from \"./EditButton.tsx\";\nimport { ListItem } from \"./ListItem.tsx\";\n\nexport interface ConnectionListProps {\n connections: readonly ConnectionSummary[];\n /**\n * App meta by id, used for rows whose own inline `app` is `undefined` (an older server).\n * Rows with an inline `app` object, or `null`, never consult it.\n */\n appsById?: ReadonlyMap<string, InlineAppMeta>;\n loading?: boolean;\n error?: string | null;\n /** Row click. The event is passed through untouched; the host may `preventDefault`. */\n onOpen?: (id: string, event: MouseEvent<Element>) => void;\n /** When set, each openable row is a real `<a href>`. */\n getHref?: (id: string) => string;\n /**\n * Renders an Edit button per row. Pass it only when the host's adapter has `updateConnection`\n * (otherwise the modal it opens has nothing to save with).\n */\n onEdit?: (connection: ConnectionSummary) => void;\n /** Renders a Delete button per row. Confirmation and the delete call are the host's. */\n onDelete?: (connection: ConnectionSummary) => void;\n /** Disables every Delete button while a delete is in flight. */\n busy?: boolean;\n slots?: {\n /** Heading block above the rows. */\n header?: ReactNode;\n /** Trailing action(s) next to the header (e.g. an \"Add\" button). */\n actions?: ReactNode;\n /** Shown when there are no connections and the list is not `loading`. */\n empty?: ReactNode;\n };\n}\n\n/**\n * A presentational list of connections: rows in, callbacks out; it needs no provider. Each row is\n * a {@link ListItem} (app icon, name, auth key, state, an `invalid` tag after a failed test) with\n * Edit and Delete buttons as SIBLINGS of its link, never inside it.\n *\n * A `builtIn` row (the server's synthetic \"no credential\" entry) is a plain non-interactive item:\n * no link, no `onOpen`, no Edit, no Delete, because the server 404s get/test/delete on its id.\n * Detection is `row.builtIn === true`, never an id prefix.\n */\nexport function ConnectionList({\n connections,\n appsById,\n loading,\n error,\n onOpen,\n getHref,\n onEdit,\n onDelete,\n busy,\n slots,\n}: ConnectionListProps) {\n const byId = appsById ?? new Map<string, InlineAppMeta>();\n return (\n <section className=\"w6w-connection-list\">\n {(slots?.header != null || slots?.actions != null) && (\n <div className=\"w6w-connection-list-head\">\n <div className=\"w6w-connection-list-heading\">{slots?.header}</div>\n <div className=\"w6w-connection-list-actions\">{slots?.actions}</div>\n </div>\n )}\n {error && <div className=\"w6w-error\">{error}</div>}\n {loading && <p className=\"w6w-muted\">Loading…</p>}\n {connections.length === 0 && !loading && (\n <div className=\"w6w-muted\">{slots?.empty ?? \"No connections yet.\"}</div>\n )}\n <ul className=\"w6w-connection-rows\">\n {connections.map((c) => {\n const app = resolveConnectionAppMeta(c, byId);\n const name = c.displayName || c.id;\n const builtIn = c.builtIn === true;\n return (\n <li key={c.id} className=\"w6w-connection-row\">\n <div className=\"w6w-connection-row-main\">\n <ListItem\n href={builtIn ? undefined : getHref?.(c.id)}\n onClick={builtIn || !onOpen ? undefined : (event) => onOpen(c.id, event)}\n icon={\n <AppIcon\n src={app?.iconSvg}\n srcDark={app?.iconSvgDark}\n brandColor={app?.brandColor}\n name={app?.displayName ?? c.appId}\n />\n }\n title={\n <>\n <strong className=\"w6w-connection-name\" title={name}>\n {name}\n </strong>{\" \"}\n <span className=\"w6w-muted\">{app?.displayName ?? c.appId}</span>\n </>\n }\n subtitle={\n <>\n auth <code>{c.authKey}</code> ·{\" \"}\n <span\n className={`w6w-connection-tag${c.state === \"connected\" ? \"\" : \" w6w-connection-tag-warn\"}`}\n >\n {c.state}\n </span>\n {c.lastTestOk === false && (\n <span\n className=\"w6w-connection-tag w6w-connection-tag-danger\"\n title=\"Last test failed — update or re-test.\"\n >\n invalid\n </span>\n )}\n </>\n }\n />\n </div>\n {!builtIn && (onEdit || onDelete) && (\n <div className=\"w6w-connection-row-actions\">\n {onEdit && (\n <EditButton\n label=\"Edit\"\n onClick={() => onEdit(c)}\n data-testid={`connection-edit-${c.id}`}\n />\n )}\n {onDelete && (\n <DeleteButton\n label=\"Delete\"\n onClick={() => onDelete(c)}\n disabled={busy}\n data-testid={`connection-delete-${c.id}`}\n />\n )}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </section>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { AuthFieldsForm } from \"./components/AuthFieldsForm.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type { AuthDef, AuthField, ConnectionSummary, ThemeMode } from \"./types.ts\";\nimport { useEnterSubmit } from \"./use-enter-submit.ts\";\n\nexport interface EditConnectionModalProps {\n /** The row being edited. `builtIn` rows have nothing to edit: the modal shows a notice only. */\n connection: Pick<ConnectionSummary, \"id\" | \"appId\" | \"authKey\" | \"displayName\" | \"builtIn\">;\n onClose: () => void;\n /** Fired with the server's updated row. The typed credential is cleared before this runs. */\n onSaved: (updated: ConnectionSummary) => void;\n /** Reserved for icon variants, like the other modals. */\n theme?: ThemeMode;\n}\n\n/**\n * Edit an existing connection: rename it and/or replace some of its credential fields. Runs on\n * the {@link useW6WApi} adapter alone. The server never returns the stored secret, so credential\n * fields start empty and blank means \"keep what is stored\" — only the fields the user filled are\n * sent, and the server merges them over the stored credential. OAuth connections can be renamed\n * here; re-authorizing is not part of this modal.\n *\n * Needs `api.updateConnection`. Without it (or for a `builtIn` row) there is no Save button, a\n * one-line notice shows instead, and nothing is called. Hosts should not offer Edit in that case.\n */\nexport function EditConnectionModal({ connection, onClose, onSaved }: EditConnectionModalProps) {\n const api = useW6WApi();\n const update = api.updateConnection;\n const builtIn = connection.builtIn === true;\n const editable = !builtIn && typeof update === \"function\";\n\n const [displayName, setDisplayName] = useState(connection.displayName ?? \"\");\n const [credential, setCredential] = useState<Record<string, unknown>>({});\n const [auths, setAuths] = useState<AuthDef[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [pending, setPending] = useState(false);\n\n // The app's declared auth methods drive which credential fields to show.\n useEffect(() => {\n if (!editable) return;\n let canceled = false;\n setAuths(null);\n api\n .getAppAuth(connection.appId)\n .then((a) => !canceled && setAuths(a))\n .catch((e) => !canceled && setError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, editable, connection.appId]);\n\n const authDef = auths?.find((a) => a.key === connection.authKey);\n const isOAuth = authDef?.type === \"oauth2\";\n const fields: AuthField[] = isOAuth ? [] : (authDef?.fields ?? []);\n\n /** `null` = nothing to update. Only a changed name and non-blank credential fields are sent. */\n function buildBody(): { displayName?: string; credential?: Record<string, unknown> } | null {\n const filled: Record<string, unknown> = {};\n for (const f of fields) {\n const v = credential[f.key];\n if (v !== undefined && v !== \"\") filled[f.key] = v;\n }\n const body: { displayName?: string; credential?: Record<string, unknown> } = {};\n if (displayName !== (connection.displayName ?? \"\")) body.displayName = displayName;\n if (Object.keys(filled).length > 0) body.credential = filled;\n return body.displayName === undefined && body.credential === undefined ? null : body;\n }\n\n async function save() {\n if (!editable || !update || pending) return;\n setError(null);\n const body = buildBody();\n if (!body) {\n setError(\"Nothing to update — change the name or a credential field.\");\n return;\n }\n setPending(true);\n try {\n const updated = await update.call(api, connection.id, body);\n // Drop every typed secret before handing control back to the host.\n setCredential({});\n onSaved(updated);\n } catch (e) {\n // The rejection's message only — never the values the user typed.\n setError((e as Error).message);\n } finally {\n setPending(false);\n }\n }\n\n const enterSubmit = useEnterSubmit(save, { enabled: editable && !pending });\n\n return (\n <Modal title=\"Edit connection\" onClose={onClose}>\n <div className=\"w6w-stepconfig\">\n <div className=\"w6w-modal-body\">\n <div className=\"w6w-stack\">\n {builtIn && (\n <p className=\"w6w-muted w6w-small\">\n This connection is built in — it has no stored credential to edit.\n </p>\n )}\n {!builtIn && !editable && (\n <p className=\"w6w-muted w6w-small\">Editing connections is not available here.</p>\n )}\n {editable && (\n <>\n <label className=\"w6w-field\">\n <span>Display name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n placeholder=\"Connection name\"\n maxLength={80}\n name=\"w6w-connection-label\"\n autoComplete=\"off\"\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n {...enterSubmit}\n />\n </label>\n\n {auths === null && !error && (\n <p className=\"w6w-muted w6w-small\">Loading auth fields…</p>\n )}\n\n {isOAuth && (\n <p className=\"w6w-muted w6w-small\">\n This is an OAuth connection. You can rename it here; its credential is renewed\n by re-authorizing it.\n </p>\n )}\n\n {fields.length > 0 && (\n <>\n <p className=\"w6w-muted w6w-small\">\n Leave a field blank to keep it unchanged. Filled fields replace the stored\n credential.\n </p>\n <AuthFieldsForm\n mode=\"edit\"\n fields={fields}\n values={credential}\n onChange={setCredential}\n enterSubmitProps={enterSubmit}\n />\n </>\n )}\n </>\n )}\n\n {error && <div className=\"w6w-result w6w-error\">{error}</div>}\n </div>\n </div>\n <div className=\"w6w-modal-actions\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n {editable && (\n <button type=\"button\" className=\"w6w-btn\" disabled={pending} onClick={save}>\n {pending ? \"Saving…\" : \"Save\"}\n </button>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { AppIcon } from \"./components/AppIcon.tsx\";\nimport { CopyableText } from \"./components/CopyableText.tsx\";\nimport type { ConnectionSummary } from \"./types.ts\";\n\nexport interface ConnectionHeaderProps {\n conn: ConnectionSummary;\n /** The connection's app display meta (inline `app`, or the by-id record). */\n app:\n | { displayName?: string; iconSvg?: string; iconSvgDark?: string; brandColor?: string }\n | undefined;\n /** Actions slot, right-aligned (e.g. a Test or Edit button, or a back link). */\n children?: ReactNode;\n}\n\n/**\n * Connection identity strip: app icon, display name, copyable id, app id, auth key and state tag\n * (plus `invalid` after a failed test). Presentational; the actions live in `children`.\n */\nexport function ConnectionHeader({ conn, app, children }: ConnectionHeaderProps) {\n return (\n <div className=\"w6w-connection-header\" data-testid=\"connection-header\">\n <AppIcon\n src={app?.iconSvg}\n srcDark={app?.iconSvgDark}\n brandColor={app?.brandColor}\n name={app?.displayName ?? conn.appId}\n size={56}\n />\n <div className=\"w6w-connection-header-main\">\n <h2 className=\"w6w-connection-header-title\">{conn.displayName || conn.id}</h2>\n <p className=\"w6w-muted w6w-small w6w-connection-header-meta\">\n <CopyableText value={conn.id} className=\"w6w-connection-id-copy\" /> · App{\" \"}\n <code>{conn.appId}</code> · Auth <code>{conn.authKey}</code> ·{\" \"}\n <span\n className={`w6w-connection-tag${conn.state === \"connected\" ? \"\" : \" w6w-connection-tag-warn\"}`}\n >\n {conn.state}\n </span>\n {conn.lastTestOk === false && (\n <span\n className=\"w6w-connection-tag w6w-connection-tag-danger\"\n title=\"Last test failed — update or re-test.\"\n >\n invalid\n </span>\n )}\n </p>\n </div>\n {children && <div className=\"w6w-connection-header-actions\">{children}</div>}\n </div>\n );\n}\n"],"names":["ApiError","status","code","message","body","__publicField","createW6WApi","opts","baseUrl","doFetch","getToken","rawReq","path","init","headers","token","res","e","text","data","err","req","walk","apps","cursor","qs","r","ids","unique","i","id","appId","authKey","actionKey","params","connectionId","patch","connId","workflowId","stepId","inputs","formatBody","defaultKeyOf","call","index","ApiCallsPanel","calls","defaultOpen","keyOf","title","key","jsxs","jsx","Fragment","ListItem","subtitle","icon","trailing","active","onClick","href","ariaLabel","className","relativeTime","iso","then","secs","mins","hours","days","defaultParamsFor","action","out","p","extractProviderMessage","msg","brace","j","m","_b","_a","_c","prefix","isInvokeApiError","describeInvokeError","detail","haystack","apiCallsOf","source","useOverrideJsonField","setText","useState","value","setValue","invalid","setInvalid","next","trimmed","parsed","ActionTestForm","actions","seedValues","onSavedTestsChanged","seedTestId","onDirtyChange","onTestSaved","onDeleted","embedded","api","useW6WApi","sortedActions","useMemo","list","a","b","pickedKey","setPickedKey","selectedAction","running","setRunning","error","setError","result","setResult","apiCalls","setApiCalls","ovBody","ovQuery","ovHeaders","ovTarget","setOvTarget","ovMatch","setOvMatch","overridesInvalid","currentOverrides","viewMode","setViewMode","jsonText","setJsonText","jsonInvalid","setJsonInvalid","modalOpen","setModalOpen","selectedKey","initialValues","valuesByAction","setValuesByAction","editingTestId","setEditingTestId","baseline","setBaseline","fresh","lastSeedTestId","setLastSeedTestId","lastSeed","setLastSeed","structurallyChanged","seeded","values","setValues","dirty","useEffect","enterJsonView","runWith","outcome","overrides","refreshSavedTests","refreshRunHistory","run","savedTests","setSavedTests","savedTestsError","setSavedTestsError","savedTestsNonce","setSavedTestsNonce","nameModalOpen","setNameModalOpen","pendingName","setPendingName","confirmDeleteOpen","setConfirmDeleteOpen","n","canceled","railTests","t","runHistory","setRunHistory","runHistoryNonce","setRunHistoryNonce","load","railRunHistory","openSaveModal","handleSaveClick","submitSaveTest","saved","name","loadSavedTest","loaded","deleteCurrentTest","deletedId","paramsRegion","v","ParamsForm","JsonEditor","valid","overridesRegion","savedTestsRail","deletingTestName","Combobox","paramsAndResult","actionBar","Modal","ConfirmModal","YamlEditor","props","theme","useEffectiveTheme","copied","copy","useCopyToClipboard","extensions","yaml","EditorView","handleChange","CodeMirror","CheckGlyph","CopyGlyph","MARKER","cropText","chars","crop","head","tail","CopyableText","label","copiedMs","cropped","classes","Copyable","DEFAULT_LABELS","HealthStatusPill","state","STATE_LABELS","UptimeStrip","entry","UNKNOWN","BYTE_UNITS","formatBytes","unit","formatPercent","f","cpuLoadFraction","s","divisor","memoryUsedFraction","memoryTotal","memoryAvailable","clamp","lo","hi","sparklinePoints","width","height","max","points","x","y","SPARK_WIDTH","SPARK_HEIGHT","Sparkline","formatLoad","fractionMax","MetricRow","readings","samples","last","cpuValues","memoryValues","rssValues","ServerResourcesCard","intervalMs","ServerResourcesCardSmall","ServerResourcesRail","onExpand","ServerResourcesBadge","cpu","mem","MIN_BAR_WIDTH_PCT","DAY_MS","placeIncidentBar","window","bar","nowMs","start","startMs","endMs","windowStartMs","windowEndMs","spanMs","clippedStart","clippedEnd","clampedStartMs","clampedEndMs","leftPct","rawWidthPct","widthPct","NO_FEED_LABEL","QUIET_LABEL","barTitle","parts","HistoryTimeline","win","incidents","vendorEmptyLabel","cellWidthPct","emptyLabel","placement","clipClass","InfoTip","children","open","setOpen","useId","IconButton","o","EditButton","disabled","rest","DeleteButton","RepoSyncIndicator","branch","shortSha","lastSyncLabel","onSyncNow","syncing","ref","useRef","onDown","onKey","Icon","StepStatusPill","MS_PER_SECOND","MS_PER_MINUTE","formatDurationMs","ms","formatExecutionTime","date","KIND_LABEL","ExecutionList","items","selectedId","onSelect","showCallable","loading","hasPrev","hasNext","onPrev","onNext","pager","item","ExecutionLogPanel","steps","onDismiss","runError","stepErrors","recorded","errors","ExecutionLogErrorBlock","step","ExecutionLogRow","header","StepTiming","ExecutionLogJson","CodeBlock","startedAt","finishedAt","elapsed","formatElapsed","totalSeconds","minutes","seconds","EMPTY","STATUS_OPTIONS","KIND_OPTIONS","ExecutionFilters","onChange","showKind","searchPlaceholder","clearable","option","ExecutionStats","stats","cards","formatSuccessRate","card","rate","toJson","ExecutionDetail","execution","errorMessage","onClose","onOpenInEditor","Body","TimingItem","JsonSection","testid","performancePoints","services","needsAttention","service","partitionBoard","groups","uptimeDays","ATTENTION_DISPLAY_CAP","RECENT_DISPLAY_CAP","displayBoard","compact","now","recent","attentionCount","shownNow","shownRecent","shownTable","WIDTH","HEIGHT","PAD","niceMax","magnitude","ticks","count","_","ReliabilityChart","getHref","onOpen","maxCalls","maxP95","maxErrors","plotW","plotH","p95","iconSize","xTicks","yTicks","yAxisTitleX","yAxisTitleY","size","cx","cy","dots","formatDay","d","Target","ExecStatusSignal","ApiStatusSignal","vendor","unreadable","IssueCard","AppIcon","ServiceTableRow","noCalls","ReliabilityList","showChart","limit","showAllHref","onShowAll","slots","windowDays","allClear","hiddenAttentionCount","hiddenTableCount","shouldShowChart","canShowAll","showAllLink","CallableList","rows","description","emptyCopy","newLabel","openRowTitle","testIds","onCreate","creating","onImport","showArchivedProp","onShowArchivedChange","showArchivedState","setShowArchivedState","controlled","showArchived","visible","interactive","row","event","resolveConnectionAppMeta","connection","byId","connectionAppIdsToLookUp","connections","seen","c","ConnectionList","appsById","onEdit","onDelete","busy","app","builtIn","EditConnectionModal","onSaved","update","editable","displayName","setDisplayName","credential","setCredential","auths","setAuths","pending","setPending","authDef","isOAuth","fields","buildBody","filled","save","updated","enterSubmit","useEnterSubmit","AuthFieldsForm","ConnectionHeader","conn"],"mappings":"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"}
|