Commit graph

1680 commits

Author SHA1 Message Date
Bryan Helmkamp
8c5d8b8d06 Hide unconfigured LLM providers in arc doctor output
Only show providers where the API key is set, reducing noise for users
who only have one or two providers configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:04:31 -04:00
Bryan Helmkamp
293bae27a7 Add blank line before additional LLM providers prompt in arc install
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:02:34 -04:00
Bryan Helmkamp
92720aed52 Style arc install output with 2-step layout, dim progress, and green checkmarks
Redesign the install CLI output for a friendlier experience:
- Bold header with  emoji and dim description paragraph
- Collapse 4 steps into 2: "LLM Providers" and "GitHub App"
- Dim all intermediate progress lines (browser, waiting, wrote, etc.)
- Replace [ok] markers with green ✔ checkmarks
- Write .env incrementally after each step instead of once at end
- Include GitHub App slug in success line
- Add closing message with bold+cyan "arc init" call-to-action

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:58:02 -04:00
Bryan Helmkamp
332be07b0c Style OpenAI OAuth callback page with card layout
Match the styled card design used by the GitHub App manifest callback,
replacing the plain unstyled HTML on the /auth/callback page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:52:50 -04:00
Bryan Helmkamp
4a7c0e7c11 Integrate OpenAI OAuth into arc install via Codex detection
When the codex binary is found on PATH, arc install now offers browser-based
OpenAI OAuth login before the standard provider picker. Falls back to manual
API key entry if OAuth fails or user declines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:21:43 -04:00
Bryan Helmkamp
963f0e2c7c Check GitHub App installation during arc init
Catches missing GitHub App installations early by verifying the app
is installed for the repo's GitHub remote after scaffolding project
files. Shows install URL and optional interactive prompt if not
installed; never fails init on check errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:18:18 -04:00
Bryan Helmkamp
92f40e59fb Validate API keys immediately during arc install
Instead of deferring key validation to the optional `arc doctor` step,
each API key is now validated right after entry with a retry loop if
invalid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:12:08 -04:00
Bryan Helmkamp
2ddb8fdae3 Gate prompt_input behind server feature flag
The function is only called from a #[cfg(feature = "server")] block,
so it triggers a dead_code warning when compiled without the feature.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:07:09 -04:00
Bryan Helmkamp
17e384de24 Unify workflow resolution for validate and parse commands
Extract resolve_workflow() in project_config to handle bare name, .toml,
and .dot resolution in one place. Previously validate and parse treated
bare words as literal file paths while run resolved them via arc.toml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 17:05:47 -04:00
Bryan Helmkamp
943779c1e0 Polish arc init output with styled terminal formatting
Use green checkmarks, dim file paths, bold header, and cyan+bold
command to match qlty CLI conventions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:58:01 -04:00
Bryan Helmkamp
974f2d31e2 Simplify GitHub App setup prompt in install wizard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:47:06 -04:00
Bryan Helmkamp
2c6a06e43b Gate system dependency checks behind server feature flag
System deps (openssl, node, dot) are only needed in server mode.
Remove them from standalone arc doctor output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:06:52 -04:00
Bryan Helmkamp
5e06cd788e Guide users through LLM setup with single-choice first provider
Start with a single-choice prompt for the first LLM (Anthropic, OpenAI,
or Gemini), then optionally offer a multi-select for additional providers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:00:09 -04:00
Bryan Helmkamp
8fc03130ef Fix OAuth callback path to /auth/callback and add login example
The redirect_uri path must be /auth/callback (not /callback) to match
what OpenAI's auth server expects for this client ID. Also use localhost
instead of 127.0.0.1 to match the Codex CLI convention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 15:39:15 -04:00
Bryan Helmkamp
d26149bf33 Add arc-openai-oauth crate for OpenAI OAuth PKCE token acquisition
Standalone library implementing OpenAI's OAuth PKCE flow (browser + device)
for authenticating with ChatGPT subscriptions instead of API keys.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 15:31:16 -04:00
Bryan Helmkamp
4408a30adc Improve install flow ordering, doctor diagnostics, and callback page
- Swap LLM providers and GitHub App steps so LLM setup comes first
- List specific providers with connectivity issues in arc doctor warnings
- Style the GitHub App callback page with a centered card and checkmark

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 14:41:08 -04:00
Bryan Helmkamp
4ac4fc4ea9 Add GitHub App manifest setup to arc install
Adds a temporary local HTTP server in `arc install` that handles the
GitHub App manifest registration flow, enabling standalone users to
register a GitHub App without running the arc-web server.

Also gates server-only install steps (pre-flight checks, server.toml,
secrets/certs, start servers) behind #[cfg(feature = "server")] and
removes the `gh` CLI from system dependency checks. Reloads .env before
running arc doctor so it picks up freshly written credentials.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 14:36:13 -04:00
Bryan Helmkamp
cbe6282263 Flip arc doctor default to live mode with --dry-run opt-out
Live service probes now run by default instead of requiring --live.
Added --dry-run flag to skip probes when needed. Install command now
runs doctor with live probes to validate setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 14:17:59 -04:00
Bryan Helmkamp
aad4cb61c0 Skip mTLS tests on macOS (LibreSSL generates incompatible certs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:55:29 -04:00
Bryan Helmkamp
89655140f8 Show Arc Details in PR body even without retro
Extend conclusion.json with per-stage operational data (cost, duration,
retries) so the Arc Details section of PR descriptions no longer depends
on retro.json. The retro section remains optional and only appears when
the retro agent runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:49:17 -04:00
Bryan Helmkamp
4558774a34 Add [pull_request] support to project config (arc.toml)
Project-level arc.toml can now set [pull_request] with enabled/draft
fields, slotting between cli.toml defaults and workflow.toml overrides.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:34:26 -04:00
Bryan Helmkamp
2969c98057 Add CliConfig helper methods to reduce accessor boilerplate
Add app_id(), slug(), and git_author() methods to CliConfig to
replace repeated .git.as_ref().and_then(...) chains across 5 call
sites in main.rs and doctor.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:21:06 -04:00
Bryan Helmkamp
c32e74fbb4 Make standalone CLI read only cli.toml, never server.toml
Move GitHub App credentials (app_id, slug) and run defaults (llm,
sandbox, pull_request) into cli.toml so standalone commands (run, pr
create, llm) no longer require server.toml. The server.toml loading is
now limited to `arc serve` and server-mode doctor checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:12:30 -04:00
Bryan Helmkamp
20b446d1e5 Add comments and docs link to generated arc.toml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:02:59 -04:00
Bryan Helmkamp
8cec8d6546 Add arc init command to initialize a new arc project
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 13:00:36 -04:00
Bryan Helmkamp
44731e0926 Rename arc setup to arc install for clarity
The one-time environment setup command (LLMs, certs, GitHub) is now
`arc install`, freeing up naming space for a future `arc init` command
for per-project initialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 12:56:53 -04:00
Bryan Helmkamp
5f9c211031 Add arc diff command to view workflow run diffs
Surfaces existing final.patch and per-node diff.patch files via CLI.
Supports live diffs from in-progress runs by reconnecting to the sandbox.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 12:50:51 -04:00
Bryan Helmkamp
fb04333d45 Fix LLM provider resolution to use model catalog before default fallback
When no explicit provider is set on a request, resolve_provider now
consults the model catalog (e.g. gpt-5.4 → openai) before falling back
to the client's default provider. This fixes PR description generation
sending cross-provider model IDs to the wrong provider.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 12:47:24 -04:00
Bryan Helmkamp
4fe05e8a71 Add arc ssh command for SSH access to Daytona sandboxes
Standalone subcommand that creates SSH credentials for a run's Daytona
sandbox and connects directly (or prints the command with --print).
Also parameterizes create_ssh_access TTL instead of hardcoding 60 min.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 12:28:17 -04:00
Bryan Helmkamp
f27a5e187a Fix verbose mode breaking terminal rendering after many tool calls
In verbose mode, completed tool call bars accumulated in indicatif's
MultiProgress without limit. After ~80+ bars exceeded the terminal
height, indicatif's cursor repositioning broke and all rendering stopped.

Now in verbose mode, completed tool calls are printed as permanent output
via multi.println() and their bars are removed from MultiProgress. Only
running tool calls remain as live bars with spinner + elapsed time. This
keeps MultiProgress small regardless of how many tool calls execute.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 11:58:07 -04:00
Bryan Helmkamp
ec7fc8d5a2 Add arc preview command for Daytona sandbox preview URLs
Provides CLI access to preview URLs for ports exposed by Daytona sandboxes.
Supports standard (URL + token + curl), signed (self-contained URL), and
--open (browser launch) modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 11:55:47 -04:00
Bryan Helmkamp
1dcad0529a Split ~/.arc/logs/ into logs/ and runs/
Per-run data now lives in ~/.arc/runs/ while daily CLI log files
stay in ~/.arc/logs/. Renames: logs_root → run_dir (RunConfig field,
Handler trait param, all handlers), logs_dir → run_dir (CLI arg,
local variables), default_logs_base → default_runs_base (path fn).
Adds DB migration 002 to rename workflow_runs.logs_dir → run_dir.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 09:40:03 -04:00
Bryan Helmkamp
54ecae9586 Write per-run tracing logs to cli.log inside each run directory
Adds a switchable tracing layer that writes to ~/.arc/logs/{run-dir}/cli.log,
so all diagnostic info for a run is co-located with its other artifacts instead
of buried in the shared daily log file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 09:30:00 -04:00
Bryan Helmkamp
ae5bdd4446 Hide arc ps subcommand from help output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 09:22:19 -04:00
Bryan Helmkamp
53e218926f Print full ~/... paths for assets instead of sandbox-relative paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 09:14:24 -04:00
Bryan Helmkamp
5883b71efd Print captured asset paths after workflow run output
Display collected assets in an "=== Assets ===" section after the run
result, so users can see which files were captured without digging
through the logs directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 09:01:52 -04:00
Bryan Helmkamp
5515c11aad Add GitHub App check to arc doctor for all builds, validate private key
The GitHub App check was gated behind #[cfg(feature = "server")] so it
never ran in CLI-only builds. It also only checked whether env vars were
set, not whether the key could actually sign JWTs.

- Move GithubAppStatus and check_github_app out of the server feature gate
- Try sign_app_jwt to validate the private key, catching corrupt keys
- Show app_id and slug in doctor output
- Keep server-only fields (client_id, client_secret, webhook_secret)
  behind #[cfg(feature = "server")]

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 08:55:14 -04:00
Bryan Helmkamp
03ac5bc6ac Hide llm, exec, and parse commands from CLI help output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 08:25:49 -04:00
Bryan Helmkamp
ea73e40070 Gate server-only doctor checks behind #[cfg(feature = "server")]
Arc API, Arc Web, GitHub App, and cryptographic key checks are only
relevant when the server feature is enabled. Without this gate, `arc
doctor` showed misleading connectivity errors for services that cannot
even be started.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 08:23:48 -04:00
Bryan Helmkamp
3a7f5cdb6c Fix unused_assignments warning in run_from_branch
Return worktree_path from the match expression instead of mutating
a pre-initialized variable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 08:20:24 -04:00
Bryan Helmkamp
7a18faa712 Fall back to localhost for sandbox MCP transport on local sandboxes
When the sandbox does not support preview URLs (e.g., local sandbox),
fall back to http://localhost:{port} instead of erroring. This makes
the sandbox MCP transport work transparently on both local and remote
(Daytona) sandboxes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:14:37 -04:00
Bryan Helmkamp
08461fe603 Add MCP server support to workflow engine and Playwright demo workflow
Wire MCP server configs from workflow TOML into agent sessions so
MCP tools are available to agent stages during workflow runs.

Changes:
- run_config.rs: add mcp_servers HashMap to WorkflowRunConfig
- backend.rs: AgentApiBackend.with_mcp_servers() passes configs to SessionConfig
- run.rs: extract mcp_servers from RunConfig and pass to backend
- demo/mod.rs: add default mcp_servers field to struct literals

New workflow: arc/workflows/playwright-demo/
- Runs on Daytona with daytona-medium snapshot
- Configures Playwright MCP as a sandbox transport (port 3100)
- Agent browses Hacker News, takes screenshots at each step
- asset_globs captures screenshots/** into logs directory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:05:12 -04:00
Bryan Helmkamp
d426eebf1a Add sandbox MCP transport for running MCP servers inside Daytona sandboxes
Adds McpTransport::Sandbox variant that starts an MCP server inside the
sandbox, waits for it to listen, gets a Daytona preview URL, and rewrites
to HTTP transport for the MCP client connection.

Key changes:
- Sandbox trait: add get_preview_url(port) for authenticated port access
- DaytonaSandbox: implement get_preview_url via Daytona SDK preview links
- McpTransport::Sandbox: new variant with command, port, env fields
- Session: resolve_sandbox_mcp_servers() starts servers and rewrites to HTTP
- Integration test: end-to-end Playwright MCP in Daytona - navigates to
  example.com and verifies "Example Domain" in accessibility snapshot

Config example:
  [mcp_servers.playwright]
  type = "sandbox"
  command = ["npx", "@playwright/mcp@latest", "--port", "3100", "--headless"]
  port = 3100

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:09:04 -04:00
Bryan Helmkamp
2e1015241e Add DaytonaSandbox::computer_use() and browser screenshot integration test
Expose the Daytona SDK's ComputerUseService through DaytonaSandbox so
callers can start the virtual desktop, take screenshots, and interact
with mouse/keyboard programmatically.

The new integration test validates the full flow: start the desktop
environment, launch Chromium on DISPLAY=:0, and capture a screenshot
of example.com via the Computer Use API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:54:14 -04:00
Bryan Helmkamp
a0a43611b7 Gate arc-exe behind exedev feature flag
The Exe sandbox variant, its config field, and all arc_exe usage in
arc-workflows are now behind #[cfg(feature = "exedev")]. Default CLI
builds skip arc-exe and openssh entirely. arc-api enables exedev since
its demo module constructs full SandboxConfig structs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 00:08:09 -04:00
Bryan Helmkamp
e776fb9bb1 Disable server feature by default in arc-cli
CLI-only builds no longer pull in arc-api and its heavy server
dependencies (axum, tower, hyper, sqlx, arc-db, arc-types) unless
the server feature is explicitly enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 23:52:49 -04:00
Bryan Helmkamp
11414c15b2 Add arc-config crate and make arc-api optional via server feature flag
Centralizes config types (ServerConfig, CliConfig, expand_tilde) into a
new arc-config crate. Makes arc-api an optional dependency of arc-cli
behind a default-on "server" feature flag, so CLI-only builds skip heavy
server deps (axum, tower, hyper, sqlx, arc-db, arc-types).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 23:50:41 -04:00
Bryan Helmkamp
53d1943ee5 Fix deadlock and missed event in retro agent session
Drop session before awaiting event_writer_handle to close the
broadcast channel, preventing a deadlock where the spawned task
waits for senders to drop while session is still alive.

Move subscribe() before initialize() so the SessionStarted event
is captured in retro_session.jsonl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:54:27 -04:00
Bryan Helmkamp
b4045ffc3c Fix PR body rendering bugs found in PR #15 code review
Use 4-backtick fences for plan section to prevent LLM-generated
triple backticks from breaking the markdown. Fix singular/plural
grammar for stage, node, and edge counts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:53:05 -04:00
Bryan Helmkamp
1846846e72 Apply rustfmt formatting and add missing newlines at end of files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:42:37 -04:00