Commit graph

22 commits

Author SHA1 Message Date
Bryan Helmkamp
4aa5aae691 Fix duplicate .env vars on re-setup, capture GitHub App slug
Replace append-based .env writing with mergeEnv() that upserts keys,
preventing duplicates when setup runs multiple times. Capture the GitHub
App slug from the manifest API response and persist it in TOML config
so we can construct installation URLs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 19:28:00 -05:00
Bryan Helmkamp
2b802835db Extract shared relativeTime helper from timeAgo and timeUntil
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 13:42:49 -05:00
Bryan Helmkamp
4976358260 Replace fake relative time strings with ISO 8601 timestamps in API
The API was returning human-readable strings like "2h ago" and "in 4 hours"
instead of real timestamps. The frontend now formats these for display using
timeAgo() and a new timeUntil() helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 13:35:36 -05:00
Bryan Helmkamp
3a2e91a123 Fix react-doctor warnings: remove dead code, fix keys and accessibility (92→99)
Delete unused files (run-logs.tsx, welcome/), remove unused mock data
and functions from data modules, un-export internal types, replace array
index keys with stable identifiers, fix label/htmlFor association, add
role+onKeyDown to click-intercepting div, and convert anchor to button
in settings sidebar nav.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:40:20 -05:00
Bryan Helmkamp
e569770c36 Enrich Sessions API: add ToolUse fields, timestamps, descriptions, and flatten list endpoint
- Add id, is_error, duration_ms to ToolUse; rename args to input
- Add created_at/updated_at timestamps to session schemas; replace time/date display strings
- Add descriptions and examples to all Sessions API fields and endpoints
- Flatten List Sessions response from grouped SessionGroup[] to SessionListItem[]
- Move date grouping (Today/Yesterday/etc.) to React client via groupSessionsByDate()
- Symlink docs/api-reference/arc-api.yaml to canonical openapi/arc-api.yaml
- Update React ToolRow components with duration display and error styling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 08:01:55 -05:00
Bryan Helmkamp
3fe77b6d5f Add session_sandboxes feature flag to gate project/branch pickers
Add a FeatureFlags config section with a session_sandboxes boolean
(default false) to both the Rust server config and web app config.
Gate the project/branch picker UI behind this flag. Set it to false
in the Docker demo config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:34:32 -05:00
Bryan Helmkamp
699c519c97 Update web UI sessions to use created_at timestamps
Adapt session detail and sidebar to the new schema: use created_at/
updated_at instead of repo/time, display relative timestamps via a new
timeAgo() helper, and remove repo badges from the UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:34:25 -05:00
Bryan Helmkamp
b601df47e5 Per-request demo mode with UI toggle
Replace the server-level `--demo` flag with per-request demo dispatch.
The Rust API builds both a demo and real router; incoming requests with
the `X-Arc-Demo: 1` header hit the demo router (auth disabled, static
data), all others hit the real router with normal auth.

The React web app gets a beaker icon toggle in the top nav bar (next to
the theme toggle) that sets an `arc-demo` cookie. Loaders read the
cookie to decide whether to send the `X-Arc-Demo: 1` header to the API.
The `ARC_DEMO=1` env var still works as a default when no cookie is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:30:23 -05:00
Bryan Helmkamp
129b8b98c4 Add Docker Compose demo setup for local development
Multi-stage Dockerfile builds Rust API binary and bundles the web app
and docs into a single image. docker-compose.demo.yaml orchestrates
the three services (api, web, docs) with a shared entrypoint router.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:32:48 -05:00
Bryan Helmkamp
d283ece683 Fix demo mode: install rustls CryptoProvider, skip TLS, add ARC_DEMO env var
- Install ring CryptoProvider at CLI startup to prevent rustls panic
- Skip TLS in demo mode so the server uses plain HTTP
- Add ARC_DEMO=1 env var to web app config to bypass GitHub OAuth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:51:57 -05:00
Bryan Helmkamp
fb47745cc2 Add Tailscale authentication provider
Read Tailscale-User-Login/Name/Profile-Pic headers when web.auth.provider
is "tailscale", checking login against required allowed_usernames list.
Rename githubLogin → login across session/callback/shell for provider
neutrality. Update app-shell loader and auth-login page to handle the
new provider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:46:55 -05:00
Bryan Helmkamp
be72df55c8 Add arc setup interactive setup wizard
Automates first-time setup: generates server.toml, Ed25519 JWT keypair,
mTLS CA+server certificates, session secret, and .env file with proper
permissions. Includes pre-flight system dependency checks shared with
doctor, LLM provider API key collection, and optional doctor verification.

Also renames config file from arc.toml to server.toml across the codebase,
and loads ~/.arc/.env before CWD .env for centralized secret management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:24:09 -05:00
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
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
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
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
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
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