Skip to main content

Web UI features

The speca-web frontend mirrors the speca-cli TUI from issue #3 in the browser. This page collects every shipped feature in one place, with CLI-spec section references so you can map web ↔ TUI.

Dashboard​

/runs lists past audit runs. Start a new run, filter, re-run failed phases — all from the dashboard.

Dashboard default

Authentication​

Paste-code OAuth (CLI spec §4.5.1)​

Login screen with paste-code OAuth

The login screen's Continue with claude.ai (paste-code) button spawns claude auth login server-side, extracts the auth URL from its stdout, and opens it in a new browser tab. Paste the verification code back into the SPA form; the server feeds it to the subprocess's stdin and updates ~/.claude/.credentials.json.

The legacy "open a separate console" path is kept as a fallback inside a <details> disclosure.

API key​

Users without a subscription can paste an ANTHROPIC_API_KEY directly. It lands in ~/.claude/credentials.json (note: separate from the CLI's .credentials.json).

Run detail​

Run detail with phase rows and budget gauge

Phase-row keybindings (CLI spec §10.3)​

With a phase row focused:

KeyAction
Enter / SpaceExpand
lExpand + scroll the log pane into view
fForce re-run that phase only
sSkip (supervisor side not yet wired; handler is in place)

Budget gauge + cap-bump modal (CLI spec §5.3.3)​

The budget gauge colours by spent / cap (yellow at 80%, red at 100%). Click it to open the cap-bump modal and raise / clear max_budget_usd:

Budget cap-bump modal

Persisted via POST /api/runs/<id>/budget_cap.

Findings​

List — filter chips + DSL + Markdown export​

Findings list

Severity / verdict / phase chips filter server-side; the DSL input overlays an AND filter client-side. Export Markdown generates a severity-bucketed one-file report.

Filter DSL (CLI spec §5.4.1)​

severity:HIGH|CRITICAL verdict:CONFIRMED_VULNERABILITY prop:PROP-6a4* path:src/**/*.sol token1 token2
  • severity: / verdict: — OR-list
  • prop: / repo: — glob (* / ?)
  • path: — **-aware path glob
  • Free tokens — AND-substring across property_id / file / proof_trace / evidence_snippet / reviewer_notes

?glob= URL parameter (CLI spec §3.5 speca browse [glob])​

/runs/<id>/findings?glob=contracts/**/*.sol

Expands internally to ?q=path:<glob> so it AND-combines with any existing DSL filter.

Markdown export (CLI spec §3.1)​

The Export Markdown button generates a severity-bucketed Markdown report. Embedded backticks are wrapped in dynamic fences; CRLF is normalised to LF.

Code highlighting (CLI spec §5.4.4 [c])​

Finding detail with code highlight

Prism highlights evidence_snippet. Solidity / TS / JS / Python / Rust / Go / Java / C / C++ grammars ship; unknown languages fall through to plain text. Solarized theme has its own Prism palette.

Chat panel​

Chat panel

Multi-runtime switching (CLI spec issue #3)​

Five backends:

  • claude (default) — Anthropic Claude
  • codex — OpenAI Codex (codex exec --json)
  • gemini — Google Gemini (gemini -p --output-format stream-json)
  • ollama — Ollama (HTTP /api/chat, cloud or self-hosted)
  • copilot — GitHub Copilot (@github/copilot agentic CLI, copilot -p --output-format json)

Switchable in real time from Settings (see Multi-runtime backends):

Runtime selector

Ask Claude about this finding (CLI spec §3.1.6)​

The button on the finding detail opens the chat panel pre-filled with the finding's context (severity / verdict / file::line / evidence_snippet / …).

Context cap (CLI spec §8.5)​

The prefilled context block is truncated to 50 KB (TextEncoder byte-accurate, multi-byte safe). Over-cap context gets a trailing …(context truncated to 50 KB budget…) marker.

Approval gate (three layers)​

Side-effect tools that the chat can fire (launch_pipeline / stop_pipeline) are guarded three ways:

  1. SDK tools= argument is the read-only allowlist
  2. Stream-side re-check on each tool_use (out-of-allowlist names emit tool_not_allowed and terminate)
  3. Front-end <ToolCard> type guard

UX / settings​

Themes (CLI spec §10.5)​

light / dark / system / solarized. Solarized uses Ethan Schoonover's canonical palette layered on the Nyx tokens. Prism syntax highlighting tracks the theme:

DefaultSolarized
dashboard defaultdashboard solarized

Toggle from the header L D A S buttons:

Theme toggle 4 buttons

i18n​

Full EN / JA via i18next. Toggle from the header.

Diagnostics (/diagnostics)​

The speca doctor equivalent. Probes Node / uv / git / claude / gh / VSCode CLI versions, auth state, and MCP server connectivity.

Error handling​

7-case error modal (CLI spec §10.4)​

Backend launch errors (clone_failed, invalid_target_repo, ref_not_found, worktree_failed, anthropic_unreachable, run_not_found, still_running, invalid_phases, invalid_workspace_input) render in ErrorModal with i18n title / body / suggested action. Retry / Close, plus a "Show technical details" disclosure for the raw envelope.

Init config persistence (CLI spec §3.1 speca init)​

Creating a new run writes outputs/<run_id>/TARGET_INFO.json and BUG_BOUNTY_SCOPE.json from the wizard inputs immediately. Phases 0a / 0c overwrite them later, but the initial stub matches speca init and is inspectable by external tooling.

Keyboard shortcuts (full list, CLI spec §10.3)​

Keyboard shortcuts help modal

KeyScopeAction
?globalHelp modal
EscglobalClose any open modal / chat
cglobalToggle chat
g rglobal/runs
g sglobal/settings
g dglobal/diagnostics
/findingsFocus filter
j / kfindingsNext / previous row
Enter / Spacephase rowExpand
lphase rowExpand + scroll log
fphase rowForce re-run

All shortcuts are IME-safe (suppressed during composition).

Mobile​

≤720px: header wraps, runs table scrolls horizontally, findings list stacks vertically.

Architecture summary​

Browser
│ WebSocket + REST
▼
FastAPI (web/server/)
│ subprocess
▼
scripts/run_phase.py ─── ClaudeRunner / APIRunner / CodexAPIRunner ...
│
▼
Each LLM API

See UI_DESIGN.md for the slice diagrams + full API surface.