Commit graph

84 commits

Author SHA1 Message Date
Bryan Helmkamp
84b2003a5a Add [web] config section and arc doctor command
Move auth config under [web.auth] in arc.toml to group web-specific
settings together. Add WebConfig with url field (default localhost:5173).
Add `arc doctor` command with checks for config, API, web, LLM providers,
Brave Search, sandbox, and GitHub App. Extract Provider::api_key_env_vars
and has_api_key to deduplicate validation logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 15:17:41 -05:00
Bryan Helmkamp
d5b98af6d1 Support base64-encoded PEM for ARC_JWT_PUBLIC_KEY and ARC_JWT_PRIVATE_KEY
Some deployment environments (e.g. container orchestrators) make it
easier to pass secrets as single-line base64 strings rather than
multi-line PEM. Both env vars now auto-detect the format: if the value
starts with "-----" it's treated as raw PEM, otherwise base64-decoded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 14:39:49 -05:00
Bryan Helmkamp
c8c1ec6916 Fix stale config after setup and extract shared config path
Add reloadAppConfig() so setup-callback refreshes the in-memory config
after writing TOML, fixing a bug where the login redirect would fail.
Export ARC_CONFIG_PATH to eliminate duplicated path construction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 01:11:46 -05:00
Bryan Helmkamp
ae41f1c2c3 Move GitHub App ID and Client ID from env vars to TOML config
Non-secret config (app_id, client_id) now lives in [git] section of
~/.arc/arc.toml. Secrets remain in .env. Setup callback writes
non-secrets to TOML and secrets to .env.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 01:05:48 -05:00
Bryan Helmkamp
c888ab8be5 Rename TaskConfig → WorkflowRunConfig, task → goal
Better reflects domain semantics: the config describes a workflow run,
and the free-text field is the run's goal, not a generic "task".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:44:24 -05:00
Bryan Helmkamp
d93785ae83 Simplify config loading: fix TOCTOU, eager init, remove dead code
- Rust: replace exists() check with direct read + NotFound handling
- TS: load config eagerly at module init instead of lazy per-request
- TS: remove unused resetAppConfigCache() export

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:24:39 -05:00
Bryan Helmkamp
1cebe29fad Move auth and API config from env vars to TOML (~/.arc/arc.toml)
Replace ARC_INSECURE_DISABLE_AUTHENTICATION and ARC_API_BASE_URL env vars
with [auth] and [api] sections in ~/.arc/arc.toml. Only secrets
(ARC_JWT_PUBLIC_KEY, ARC_JWT_PRIVATE_KEY) remain as env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 22:49:04 -05:00
Bryan Helmkamp
1fd9a8ebfe SQLite-backed sessions with GitHub email and app manifest fix
Replace cookie-based sessions with SQLite-backed storage using
better-sqlite3 and React Router's createSessionStorage. Sessions are
now stored in ~/.arc/arc-web.db with a session ID cookie, enabling
larger payloads and server-side revocation.

- Add db.server.ts (lazy singleton, WAL mode, web_sessions table)
- Add session-storage.server.ts (CRUD ops, probabilistic cleanup)
- Fetch primary verified email from /user/emails during OAuth
- Add emails:read to GitHub App manifest default_permissions
- Expand session data: userUrl, githubId, githubNodeId, email
- Default ARC_API_BASE_URL to localhost:3000
- Whitelist better-sqlite3 in trustedDependencies
- Externalize better-sqlite3 from Vite SSR bundling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:05:59 -05:00
Bryan Helmkamp
b0e65423ae Base64-encode GITHUB_APP_PRIVATE_KEY in .env
Write the private key as base64 to avoid multiline quoting issues.
Add getGitHubAppPrivateKey() that accepts both raw PEM and base64.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:21:53 -05:00
Bryan Helmkamp
f1bf37349d Extract AuthLayout component and polish auth UI
Shared layout for setup, login, and callback pages with consistent
styling. Add GitHub mark icon to action buttons. Document dev server
commands in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:19:15 -05:00
Bryan Helmkamp
4d362f320c Auto-restart after GitHub App setup instead of requiring manual restart
Set env vars on process.env at runtime after writing .env, then redirect
to /auth/login. Removes the success UI telling users to restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:03:18 -05:00
Bryan Helmkamp
743a4fc677 Add GitHub App manifest registration and OAuth login
Adds one-click GitHub App setup via the manifest flow, OAuth login
via Arctic, and cookie-based sessions so the app shell shows the
real authenticated user instead of a hardcoded placeholder.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:45:50 -05:00
Bryan Helmkamp
47f032e535 Add POST /runs/{id}/preview endpoint and Preview button on Run page
Adds a new API endpoint for generating sandbox preview URLs (stubbed to
return google.com in demo mode). The Run detail page now shows a Preview
button that POSTs to this endpoint and opens the returned URL in a new tab.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 12:16:01 -05:00
Bryan Helmkamp
79d97ebb5c Fix stale labels, grammar, and comments from sandbox rename
- Fix display label `image:` → `name:` for SnapshotPulling/SnapshotPulled
  in format_event_detail
- Fix grammar: "an Sandbox" → "a Sandbox" in README and parallel.rs
- Fix typo: "sandboxs" → "sandboxes" in parallel.rs
- Update remaining "execution environment" comments to "sandbox"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:43:34 -05:00
Bryan Helmkamp
e938d3395a Throw Response from apiJson so API 404s render as 404 pages
apiJson was throwing a plain Error on non-ok responses, which React
Router always treated as a 500. Now throws a Response with the actual
status code so API 404s surface as proper 404 error pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:05:34 -05:00
Bryan Helmkamp
fcba787cd5 Add styled 404 and 500 error pages matching Arc design system
Replace the unstyled error boundary with themed pages: teal gradient
number for 404, coral for 500, centered on the atmospheric background
with action buttons and a collapsible stack trace in dev mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:04:04 -05:00
Bryan Helmkamp
49364b0843 Add demo API server and wire React app to fetch from API
Expand the OpenAPI spec from 11 to 39 endpoints covering Runs, Workflows,
Verifications, Retros, Sessions, Insights, Settings, and Projects with ~45
schemas. Add `--demo` flag to `arc serve` that serves static demo data for
all endpoints (auth disabled, read-only). Non-demo mode returns 501 for new
endpoints while existing run handlers continue working.

Regenerate the TypeScript API client and add `apiJson` helper. Wire all 19
React route files with server-side loaders that fetch from the API and map
snake_case responses to camelCase UI types. Mock data kept as fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 09:39:53 -05:00
Bryan Helmkamp
331dad98ec Rename Pipeline to Workflow in frontend
- routes/pipelines.tsx → routes/runs.tsx, component Pipelines → Runs
- Update route config to point to runs.tsx
- Retro.pipeline_name → workflow_name in data and all display components
- Table header "Pipeline" → "Workflow" in retros list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 00:09:15 -05:00
Bryan Helmkamp
1aca8231bc Add Terminal dropdown button to run detail page
Adds a sandboxId field to RunItem and a Terminal dropdown on the run
detail page with "Web Terminal" (links to Daytona proxy) and
"Connect with SSH" options. Uses existing Headless UI Menu pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:01:15 -05:00
Bryan Helmkamp
726ab184dc Add cursor: pointer to all click targets site-wide
Add a global CSS base rule for interactive elements (buttons, links,
selects, summary, ARIA roles) and add cursor-pointer to clickable
table rows. Remove now-redundant per-element cursor-pointer classes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:36:21 -05:00
Bryan Helmkamp
ae72cd059d Add verification control detail page with clickable catalog rows
Adds /verifications/:slug route with detail page showing control
description, stat cards, evaluation history, recent runs, checks/examples,
and sibling navigation. Makes verification catalog rows fully clickable.
Fixes dark mode hydration mismatch with suppressHydrationWarning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:25:00 -05:00
Bryan Helmkamp
4a0fc63d5a Add generated Axios API client package (@qltysh/arc-api-client)
Replace openapi-typescript types-only output with a full TypeScript Axios
client generated by openapi-generator-cli. The generated code is committed
so IDE support works without running codegen. arc-web consumes the client
via bun workspaces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:03:38 -05:00
Bryan Helmkamp
1334a952af Add spec-first OpenAPI for arc-api with generated types
- Create openapi/arc-api.yaml as source of truth for all API endpoints
- Add arc-types crate with build.rs using typify to generate Rust structs
  from the spec's component schemas
- Refactor server.rs to use generated types instead of hand-written ones
- Add route coverage conformance test validating router matches spec
- Add openapi-typescript to arc-web for TypeScript type generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:43:49 -05:00
Bryan Helmkamp
b15a526b0a Add darker logotype variant for light mode
The existing gradient logo (#c4dede-#495669) was designed for dark
backgrounds. Adds logotype-light.svg with the same paths but a
deeper gradient (#2a6b6b-#1c2a3a) for better contrast on white,
and swaps the src based on the current theme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:37:15 -05:00
Bryan Helmkamp
e515368838 Link ARC logo to /start instead of /workflows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:33:02 -05:00
Bryan Helmkamp
3b8a0c3af2 Fix light mode colors for diff views and charts
The .light CSS variable overrides were defined before the :root dark
defaults, so equal-specificity source-order caused the dark values to
always win. Move .light overrides after each :root block so they
correctly take effect.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:12:13 -05:00
Bryan Helmkamp
2ed164d190 Add light mode support with theme toggle
Introduce semantic CSS custom properties (page, panel, fg, line, overlay,
etc.) that swap values via .light/.dark class on <html>. An inline script
reads localStorage / prefers-color-scheme before first paint to prevent
flash-of-wrong-theme.

- ThemeProvider + useTheme hook in app/lib/theme.tsx
- Sun/Moon toggle in desktop nav and mobile menu
- .light overrides for all semantic tokens, accent colors (WCAG AA on
  white), atmosphere gradient, @pierre/diffs surfaces, and chart variables
- Migrated ~30 files from hardcoded color classes to semantic tokens
- GraphViz diagrams use getGraphTheme() for light/dark hex maps
- Chart gridlines and axis labels use CSS custom properties
- Workflow card colors reference CSS vars for automatic theme switching
- Pierre diffs switch between pierre-dark and pierre-light themes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:06:45 -05:00
Bryan Helmkamp
f53cc746dc Add split/unified and background toggles to diff headers
Inject per-file toggle controls into the Pierre diff header bar via
renderHeaderMetadata. Each file gets independent split/unified and
background on/off state using the Pierre icon style.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:43:57 -05:00
Bryan Helmkamp
375a833733 Add Steer button and inline comment forms to diff view
Hover any line in a diff hunk to see a "Steer" button on the right side.
Clicking opens an inline comment form; submitted comments persist as
read-only annotations. Uses onLineEnter/onLineLeave with absolute overlay
positioning to place the button at the row's right edge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:16:27 -05:00
Bryan Helmkamp
706413ec65 Add verifications catalog page and per-run verifications tab
Verifications catalog (/verifications) shows all verification criteria
organized by category with search, mode filter, and grouped/list toggle.
Each criterion has a unique icon, type badge, mode badge, and evaluation
sparkline. List view adds F1 accuracy, pass@1, and category columns.

Per-run verifications tab (/runs/:id/verifications) shows the same
criteria with pass/fail status for a specific run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:31:47 -05:00
Bryan Helmkamp
73b00f047b Add per-run retrospectives with LLM-powered retro agent
After each pipeline run, auto-derive stats from the checkpoint (stages,
retries, cost, files touched) then run an Opus agent session that
explores progress.ndjson to produce qualitative analysis: smoothness
rating, intent, outcome, learnings, friction points, and open items.

Backend:
- retro.rs: data model, save/load, derive_retro(), extract_stage_durations()
- retro_agent.rs: post-pipeline agent session with submit_retro tool
- cli/run.rs: hook retro generation after final.json, before engine_result?
- server.rs: GET /pipelines/{id}/retro endpoint, auto-derive on completion

Frontend:
- data/retros.ts: TS types + mock data + smoothness color config
- routes/retros.tsx: list page with smoothness badges
- routes/run-retro.tsx: detail view (stats, intent, stages, learnings)
- routes.ts + run-detail.tsx: wire up retro route and tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:46:02 -05:00
Bryan Helmkamp
6d2f362cd2 Add toolbar to files changed page with checkpoint picker and diff stats
Adds a toolbar above the diffs with a checkpoint dropdown (defaulting
to "All changes"), a GitHub-style +/- diff stat indicator with colored
blocks, and a settings cog button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 15:42:55 -05:00
Bryan Helmkamp
ae8faad1b2 Fix cross-browser SVG animation for running graph node
Replace CSS @keyframes animation with native SVG <animate> elements
for the pulsing glow on running nodes. CSS animations on SVG
presentation attributes (fill, stroke) are unreliable across browsers.
SVG SMIL animations work consistently in Chrome, Safari, and Firefox.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 15:11:57 -05:00
Bryan Helmkamp
e05abeaacf Render run graph as interactive SVG with animated running node
Replace DOT source code view with rendered SVG visualization using
viz.js. Running stages pulse with a teal glow animation, completed
stages are tinted green, and the graph supports pan/zoom/direction
controls matching the workflow diagram page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 15:06:01 -05:00
Bryan Helmkamp
162318a230 Improve retros and usage UI: search, filters, layout tweaks
- Add search bar and smoothness dropdown filter to retros list
- Replace Cost column with Frictions count on retros list
- Make retro table rows fully clickable
- Move Retro tab before Usage tab in run detail
- Move Stage Breakdown below Open Items on retro page
- Add per-model breakdown table to usage page with 3 models

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 15:02:12 -05:00
Bryan Helmkamp
d95ad80029 Add /insights/new page for creating queries via LLM or templates
Convert insights route to a parent layout with sidebar and two children:
- index route (insights-editor) with the existing SQL editor
- /insights/new with LLM input, template cards, and SQL link

Also fix wide layout detection in app-shell to check all matched routes
instead of only the last match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:49:58 -05:00
Bryan Helmkamp
810e8b4227 Add Insights page with SQL workbench UI
SQL query editor with line numbers, saved queries sidebar, history,
SQL AI dialog, chart/table results toggle, and query stats bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:38:25 -05:00
Bryan Helmkamp
a338f8a064 Add expandable check status rows and pending question text to Run cards
Replace simple CI dot indicators with rich check status data model
(CheckRun[] with per-check name, status, duration). Cards in Verify
and Merge columns show a full-width expandable status row with summary
icon and text. Clicking reveals individual check results. Pending
column cards now display the human-in-the-loop question above the
Answer Question button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:53:56 -05:00
Bryan Helmkamp
7f921fb82a Add drag-and-drop sortable Run cards on Runs page
Uses @dnd-kit to make cards reorderable within their column (board view)
and group (list view). Prevents accidental navigation on drag release.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:16:31 -05:00
Bryan Helmkamp
3912cab183 Improve settings page with sidebar nav, section icons, and accent colors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:16:24 -05:00
Bryan Helmkamp
6d22a6c622 Rename arc-attractor crate to arc-workflows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:05:43 -05:00
Bryan Helmkamp
4f9891427f Add hover copy button and date to session messages
Show a clipboard icon on hover below user prompts (with date)
and at the end of assistant sequences (not before tool calls).
Icon-only button, no label text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:01:56 -05:00
Bryan Helmkamp
d2234fed8f Add model label and prompt input to session pages
Show model name (e.g. Opus 4.6) right-aligned in the session
header bar. Add a pinned text input with send button at the
bottom of each session for continuing the conversation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:29:25 -05:00
Bryan Helmkamp
b5d8ad1494 Add columns/list toggle on Runs page and Settings page mockup
Runs: add a view toggle (columns vs list) with collapsible
status-grouped sections in list view.

Settings: populate with grouped panels (General, Git & VCS,
Compute, Notifications, Security) containing key/value fields
with text inputs, selects, and toggles. Hide redundant header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:24:22 -05:00
Bryan Helmkamp
9b1bab7561 Add Arc logo icon next to heading on /start page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:13:25 -05:00
Bryan Helmkamp
e054a853dd Replace fixed starter cards with expandable category menus on /start
Three category pills (Build, Review, Fix) expand into overlay panels
with prompt options, similar to Claude.ai's starter prompt pattern.
Panel renders over the pills directly below the textarea.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:11:34 -05:00
Bryan Helmkamp
2eebb00ab1 Add Start page, session chat UI, and filtering across arc-web
- /start page with AI prompt textarea, project/branch pickers, and starter workflow cards
- /sessions/:id page with chat conversation UI (user/assistant/tool turns with progressive disclosure)
- Session sidebar with grouped history (Today, Yesterday, Previous 7 days)
- Start nav tab with sparkles icon added to app shell
- Scheduled workflows with schedule badges and pause buttons on /workflows
- Trigger filter dropdown (All/Scheduled/Manual) on /workflows
- Search bar and repository filter dropdown on /runs kanban board

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:07:19 -05:00
Bryan Helmkamp
6d869aa8da Add asymmetric JWT service-to-service auth between arc-web and arc-attractor
Ed25519 asymmetric JWT: arc-web signs with private key, arc-attractor verifies
with public key. Adds AuthenticatedService axum extractor to all routes, jose
dependency for TypeScript signing, and key generation script.

Startup behavior: ARC_JWT_PUBLIC_KEY set → enforce JWT auth; not set +
ARC_INSECURE_DISABLE_AUTHENTICATION=true → allow unauthenticated; neither →
refuse to start with clear error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:05:49 -05:00
Bryan Helmkamp
d37d2c8f49 Add run configuration and graph sub-pages under /runs/:id
Sidebar "Run Configuration" and "Workflow Graph" links now navigate to
/runs/:id/configuration and /runs/:id/graph instead of away to the
workflow detail page. Extracts CollapsibleFile into a shared component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-28 17:17:19 -05:00
Bryan Helmkamp
ea89a62768 Link Arc logo to /workflows page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-28 17:12:52 -05:00