Commit graph

133 commits

Author SHA1 Message Date
Bryan Helmkamp
21aff5431c Update docs, frontend, marketing, and skills for .fabro extension
Update 47 MDX doc pages, OpenAPI spec, SVG diagram, language
grammar, frontend demo data, marketing page, skills, and README
to use .fabro extension. Add "fabro" to fileTypes in language
grammars. Document stack.child_workflow alongside stack.child_dotfile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 22:38:25 -04:00
Bryan Helmkamp
4dd76b259e rename Arc to Fabro in README, marketing site, and events strategy doc
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:57:13 -04:00
Bryan Helmkamp
28884ae093 rename Arc to Fabro in all Rust crates, symbols, env vars, and supporting files
- Rename 20 crate directories lib/crates/arc-* → fabro-*
- Update all Cargo.toml: crate names, dep paths, feature flags, bin name
- Rename arc_server module → fabro_server in fabro-llm
- ArcError → FabroError across 30+ files
- ARC_VERSION/ARC_GIT_SHA/ARC_BUILD_DATE → FABRO_* constants
- All use/qualified paths: arc_agent:: → fabro_agent::, etc. (~1500 occurrences)
- Env vars ARC_* → FABRO_* in string literals and shell scripts
- String literals: X-Arc-Demo, arc-bot, arc@local, arc-web, arc-mcp, etc.
- Path strings: .arc/ → .fabro/, arc.toml → fabro.toml, refs/arc/ → refs/fabro/
- arc-api.yaml → fabro-api.yaml (OpenAPI spec)
- skills/arc-create-workflow → fabro-create-workflow
- trycmd fixtures: $ arc → $ fabro
- Inline snapshots (insta) updated
- CI, Docker, install.sh, scripts, CLAUDE.md, AGENTS.md
- TypeScript app: env vars, headers, JWT issuer
- Docs: page slugs, git refs, config paths, sandbox names, repo URLs
- Repo references: brynary/arc → fabro-sh/fabro

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:25:58 -04:00
Bryan Helmkamp
3ce976a006 docs: update license references from AGPL to MIT
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:14:37 -04:00
Bryan Helmkamp
3a6ec9b9ef Rename Arc to Fabro in TypeScript/JavaScript
Rename directories (arc-web → fabro-web, arc-api-client → fabro-api-client),
update package names, import paths, TS-only identifiers (theme key, session
cookie, demo cookie, OAuth state, db filename, mock data), and supporting
files (Dockerfile, docker-compose, entrypoint, CI workflow, CLAUDE.md).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:13:18 -04:00
Bryan Helmkamp
01c0fe2e82 cleanup 2026-03-12 10:55:11 -04:00
Bryan Helmkamp
f6554ca689 Add web UI screenshots to docs, update branding to Fabro, simplify Quick Start
- Add 10 screenshots of the Fabro web UI to docs pages (workflows, runs,
  retros, observability, steering)
- Update arc-web logos from Arc to Fabro (logotype.svg, logotype-light.svg)
- Hide Start and Settings nav items in arc-web for cleaner screenshots
- Mount arc-web public/ as Docker volume for logo hot-swapping
- Combine "Run agents 24/7" and "Scale infinitely" use cases
- Replace clone-and-build Quick Start with curl installer from README
- Add internal docs for updating web screenshots

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:08:51 -04:00
Bryan Helmkamp
17efbe5168 Rebrand arc-web app from Arc to Fabro
Replace logo/favicon SVGs with Fabro brick icon wordmark.
Update all page titles, alt text, auth UI copy, and GitHub App name prefix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-11 22:10:51 -04:00
Bryan Helmkamp
c2b40b4cfc Move packages/ to lib/packages/ and update all references
Updated: package.json workspaces, tsconfig path alias, CI workflow
paths, Dockerfile COPY, AGENTS.md, and doc references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:13:56 -04:00
Bryan Helmkamp
5a720ddb26 Rename /runs/{id}/compare to /runs/{id}/files with pagination
Replace the RunCompare envelope (checkpoints + files + stats) with a
standard PaginatedRunFileList response containing FileDiff items,
matching the existing pagination pattern used by other endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:37:30 -04:00
Bryan Helmkamp
add14c63ee Remove List Projects and List Branches API endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:06:58 -05:00
Bryan Helmkamp
30f4fa5c3c Redesign marketing homepage with distinctive typography and visual depth
Swap Inter for Sora (headlines) + DM Sans (body) to eliminate generic AI-slop
aesthetics. Add animated gradient text, floating glow orbs, dot-grid background
texture, scroll-reveal animations, hover glow cards, and a trace visualization
for the observability section. Replace flat border-t dividers with gradient
lines and vary section visual treatments for better rhythm.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 13:15:52 -05:00
Bryan Helmkamp
2eae4224e1 Add marketing homepage with Tailwind CSS and brand colors
Sets up Tailwind v4 via @tailwindcss/vite, adds the full brand palette
(teal, navy, ice, mint, amber, coral) as custom theme tokens, and builds
a complete homepage with hero, feature grid, code examples, verification
section, multi-model section, observability, "Why Arc", and CTAs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:03:27 -05:00
Bryan Helmkamp
31ebd12c17 Add Astro marketing website with React integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:03:33 -05:00
Bryan Helmkamp
72c1e0759f Rename verification API: categories → criteria, separate controls endpoints
Restructure the verification API from a flat `/verifications` namespace to
`/verification/criteria` and `/verification/controls` as distinct resources.
Singularize the run sub-resource path to `/runs/{id}/verification`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:49:18 -05:00
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
a58bebff8b Fix 9 OpenAPI review items for run internals, workflows, and configuration
- Define typed RunCheckpoint schema replacing untyped object on checkpoint endpoint
- Rename WorkflowDetail.title to name for consistency with WorkflowListItem
- Make RunConfiguration.goal optional (only version and graph required)
- Add optional requestBody (StartWorkflowRunRequest) to startWorkflowRun
- Remove dead tools field from SystemStageTurn and AssistantStageTurn
- Add cancelled to StageStatus enum
- Document HookDefinition field-to-type mapping
- Add oneOf type to DaytonaConfiguration.network (string enum or allow_list object)
- Document stages pagination cardinality (bounded by graph size, typically <20)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 15:31:54 -05:00
Bryan Helmkamp
72c0c8e257 Fix 10 OpenAPI review items for HITL, run outputs, and verifications
Addresses agreed items from the openapi-hitl-and-run-outputs review:
rename retrieveRunDiff operationId, add 409s to steer/preview, bound
expires_in_secs, add selected_option_keys for multi-select end-to-end,
document skip/na semantics, add slug and require type on
RunVerificationControl, require file on CodeLocation, and remove the
checkpoint "all" sentinel in favor of omitting the parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 15:13:06 -05:00
Bryan Helmkamp
ec598c4abb Fix 8 OpenAPI review items for verifications and insights
- Add pagination params to /verifications endpoint
- Rename operationIds: listVerificationCategories, retrieveVerificationControl
- Merge VerificationStatus and EvaluationResult into unified VerificationResult enum
- Rename ControlDetail.description to rationale to avoid ambiguity
- Add 400 error response to POST /insights/execute
- Add GET /insights/queries/{id} endpoint with 404 handling
- Type ExecuteQueryResponse.rows items with oneOf instead of empty schema
- Make SavedQuery.updated_at required, default to created_at for unmodified queries

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 14:56:07 -05:00
Bryan Helmkamp
ae3a9e7505 Extract shared mapRunListItem and columnNames, fix O(n²) grouping
Consolidates the duplicated RunListItem-to-RunItem mapping from runs.tsx,
workflow-runs.tsx, and run-detail.tsx into a single mapRunListItem function
in data/runs.ts. Also unifies the status-to-label mapping into a shared
columnNames record and fixes the O(n²) find-by-id loop in the runs loader.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 14:10:34 -05:00
Bryan Helmkamp
c61aafcde6 Return structured JSON for run config and server config
Replace raw TOML / UI-oriented SettingGroup responses with structured
JSON that mirrors the Rust config types (WorkflowRunConfig, ServerConfig).

- Add Serialize derives to all config types in arc-workflows and arc-api
- Add manual Serialize impl for DaytonaNetwork enum
- Update OpenAPI spec: /runs/{id}/configuration returns RunConfiguration,
  /settings returns ServerConfiguration, WorkflowDetail.config is now
  RunConfiguration object instead of TOML string
- Remove SettingGroup/SettingField/SettingFieldType schemas
- Update demo handlers to construct and serialize real config structs
- Regenerate TypeScript client
- Simplify settings page to JSON display, update run-configuration and
  workflow-definition pages to show JSON

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 14:04:57 -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
daf5f5e24d Update TypeScript client and frontend for nested API schemas
Regenerate TypeScript Axios client from updated OpenAPI spec. Update all
frontend route loaders to access nested field paths: repository.name,
workflow.slug, pull_request?.number, timings?.elapsed_secs,
sandbox?.id, model.id, run.id, run.title, usage.input_tokens, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 13:11:36 -05:00
Bryan Helmkamp
8aa7abf7f4 Deduplicate utilities, remove TOCTOU checks, and strengthen types
- Extract millis_u64 and save_json/load_json to shared crate root, replacing
  identical copies in engine, parallel, human, conclusion, manifest,
  checkpoint, and retro modules
- Remove exists() pre-checks before Manifest::load and Conclusion::load
  in CLI runs scanner (TOCTOU anti-pattern)
- Merge duplicate cancel_run match arms for Queued/Starting/Running
- Change Conclusion.status from String to StageStatus enum
- Extract RunFilterArgs shared struct from RunsListArgs/RunsPruneArgs
- Replace hand-rolled formatDuration with formatDurationMs wrapper over
  existing formatDurationSecs
- Extract duplicated ToolRow/ToolBlock components to shared tool-use.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 12:59:22 -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
681791db3f Improve Sessions API schema: discriminated turns, date-time formats, consistent naming
- Refactor SessionTurn into discriminated union (UserTurn, AssistantTurn, ToolTurn)
  using oneOf + discriminator so invalid states are unrepresentable
- Add format: date-time to all timestamp fields for proper codegen types
- Rename CreateSessionRequest.prompt to .content for consistency with SendMessageRequest
- Change sendSessionMessage from 200 to 202 (async processing via SSE)
- Extract inline response to SendMessageResponse schema
- Add updated_at to SessionListItem for sort-by-activity support
- Extract SessionId parameter to components/parameters (DRY)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 08:33:51 -05:00
Bryan Helmkamp
a4f119ad79 Keep submit button right-aligned on start page when session_sandboxes is off
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 08:17:06 -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
872107e4d6 Fix Docker demo build and verifications API response parsing
- Switch mintlify install from bun to npm with katex version patch
- Add arm64 platform and pull_policy: never to docker-compose.demo.yaml
- Unwrap data envelope in verifications loader response
- Add name-gen script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 12:03:42 -05:00
Bryan Helmkamp
f8d96cb7ae Fix server-side error message leaking to browser in production
error.message was displayed to users in all environments, while
stack traces were correctly gated behind import.meta.env.DEV.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 10:25:07 -05:00
Bryan Helmkamp
41ed815a19 Fix apiStages.map crash by using PaginatedRunStageList type
Three routes (run-overview, run-configuration, run-graph) were typing
the stages API response as RunStage[] but the endpoint returns a
paginated wrapper { data, meta }. Destructure .data to get the array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 10:24:23 -05:00
Bryan Helmkamp
b57e30efad Rename run-files-changed.tsx to run-compare.tsx to match route
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:57:52 -05:00
Bryan Helmkamp
26f08a904e Rename GET /runs/{id}/files to GET /runs/{id}/compare
Rename the endpoint, schema (RunFiles -> RunCompare), operation ID,
handlers, and frontend route across the full stack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:53:45 -05:00
Bryan Helmkamp
14322f40c2 Wrap non-paginated list endpoints in paginated response shape
Wrap 4 list endpoints that returned bare arrays in the standard
paginated `{ data, meta: { has_more } }` shape so adding real
pagination later is additive rather than a breaking change.

Endpoints: GET /runs/{id}/questions, /runs/{id}/stages,
/runs/{id}/verifications, and /verifications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:41:32 -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
af12b0b697 Add offset-based pagination to 9 list endpoints
Apply the same page[limit]/page[offset] pagination pattern from
GET /runs to: workflows, workflow runs, retros, sessions, projects,
branches, saved queries, query history, and stage turns.

Each endpoint now returns { data, meta: { has_more } } instead of
a bare array. Includes OpenAPI spec updates, demo handler changes,
regenerated TS client, updated frontend consumers, and a new
pagination conformance test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:56:32 -05:00
Bryan Helmkamp
1d0e45ffdf Add offset-based pagination to GET /runs
Introduce page[limit]/page[offset] query params and { data, meta: { hasMore } }
response wrapper for the /runs endpoint, establishing the pagination pattern
for all future list endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:32:57 -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
c574fb7416 Fix Tailscale auth security issues in arc-web
- redirect-home: only check GitHub app config when provider is "github"
- app-shell: hide sign-out button when provider is "tailscale"
- auth-logout: skip session destroy and redirect to /start for Tailscale

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:18:58 -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
71f7af267a Add URL context to API fetch errors for easier debugging
When the API server is unreachable, the raw "fetch failed" error gives
no indication of what URL was being requested. Wrapping the error
includes the target URL in the message while chaining the original
cause.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:41:35 -05:00
Bryan Helmkamp
64a6b0278a Bypass GitHub OAuth when auth provider is insecure_disabled
The app-shell and redirect-home loaders unconditionally required GitHub
OAuth, which broke demo mode. Now they check the auth provider config
and use a hardcoded demo user when auth is disabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 20:36:30 -05:00
Bryan Helmkamp
518b6ab9ac Fix JWT sub claim to use GitHub profile URL instead of API URL
The sub claim was set to https://api.github.com/user/{id} (numeric ID),
but the API-side username extractor splits on '/' expecting a login name.
Use https://github.com/{login} so the extracted segment matches the
allowed_usernames config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 16:41:33 -05:00
Bryan Helmkamp
859da7d035 Add user identity (sub claim) to JWT for arc-web → arc-api auth
The JWT now includes a `sub` claim containing the authenticated user's
GitHub profile URL (e.g. https://github.com/brynary), enabling the
backend to identify which user is making each request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 15:38:03 -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