Commit graph

1012 commits

Author SHA1 Message Date
Bryan Helmkamp
2dadd49605 Revert "Fix verbose mode breaking terminal rendering after many tool calls"
This reverts commit f27a5e187a.
2026-03-10 23:19:27 -04:00
Bryan Helmkamp
f8bd618f97 Fix heading: "AI research and labs" -> "AI researchers and labs"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 23:13:22 -04:00
Bryan Helmkamp
aaf51756de Add AI research labs acknowledgement and reorder sections
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 23:13:02 -04:00
Bryan Helmkamp
efc3615852 Add acknowledgements page crediting StrongDM's Attractor as inspiration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 23:12:16 -04:00
Bryan Helmkamp
9245a9987b Fix Daytona sandbox clone failing on unpushed worktree branch
When `arc run` uses a Daytona sandbox, `initialize()` re-detects the
branch from cwd — but by that point the worktree has switched HEAD to
`arc/run/{run_id}`, which was never pushed, causing the clone to fail
with HTTP 400. Pass the already-known base branch (e.g. `main`) from
the caller instead of re-detecting it inside the sandbox.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 23:11:42 -04:00
Bryan Helmkamp
ecb585d2a4 Clean up devcontainer bridge: inline trivial wrappers, fix initializeCommand bugs
- Remove `devcontainer_env()` and `resolve_devcontainer()` trivial wrappers,
  inline at call sites
- Fix initializeCommand Args quoting: use shlex::try_quote instead of naive join
- Fix initializeCommand silently dropping Parallel commands: now executes them
- Convert three repetitive lifecycle calls to a data-driven loop
- Use crate::millis_u64() in setup command loop for consistency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 23:06:33 -04:00
Bryan Helmkamp
e8067740f7 Wire arc-devcontainer into sandbox creation flow
When `devcontainer = true` in TOML sandbox config, Arc now resolves
devcontainer.json from the repo, uses its Dockerfile for the Daytona
snapshot, runs lifecycle hooks (on_create, post_create, post_start)
in the sandbox, and merges devcontainer env vars under TOML env.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:54:59 -04:00
Bryan Helmkamp
e248fc5651 Migrate 29 CLI tests from assert_cmd/insta to declarative trycmd
Model list tests (6): exact stdout snapshots in .trycmd files, replacing
insta .snap files. Error validation tests (5): TOML with stderr-to-stdout
checking specific error messages. Doctor tests (3): TOML with env.inherit
= false for env_clear(). Validate tests (7): TOML with fs.cwd/sandbox for
file path access. Dry-run tests (6): TOML with fs.cwd/sandbox. Exec help
and no-prompt tests (2): TOML with env config.

Remaining in cli.rs: negative-assertion tests, file-system side-effect
test, tmpdir+env test, and 11 ignored API-key-dependent tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:42:24 -04:00
Bryan Helmkamp
bf807686f6 Fix "Git clean: false" for remote sandboxes by checking clean + pushed
Remote sandboxes clone from origin, so "clean" should mean no uncommitted
changes AND the local branch is pushed. Replaces the hardcoded `false` with
a new `ensure_clean_and_pushed` that reuses `ensure_clean` + `branch_needs_push`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:35:08 -04:00
Bryan Helmkamp
11c17bffab Add CLI telemetry event tracking with command sanitization and git hashing
Activate the dormant Segment-based telemetry infrastructure by wiring
lifecycle events in main.rs. Each CLI invocation now emits a "Command Run"
or "Command Error" event with sanitized args, duration, hashed repo
identifier, and CI detection.

- Add sanitize.rs: redacts sensitive CLI args (paths, values) while
  keeping flags, booleans, and numeric patterns
- Add git.rs: MD5-hashes normalized origin remote URL so HTTPS/SSH
  variants produce the same identifier
- Extend command_name to include nested subcommands (e.g. "pr create",
  "llm prompt", "system prune", "model list")
- Restructure main/main_inner to capture timing and return command name
  alongside result for telemetry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:32:54 -04:00
Bryan Helmkamp
b864c1fa94 Add trycmd --help tests for each visible CLI subcommand
Covers run, validate, cp, preview, ssh, model, doctor, init, install,
pr, and system. Each test verifies --help exits 0 and produces output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:10:28 -04:00
Bryan Helmkamp
1b4c6cb903 Detect unsupported COPY/ADD in devcontainer base Dockerfiles
Daytona's Rust SDK doesn't support uploading build context files, so
COPY/ADD instructions referencing local files fail at build time with
confusing errors. Detect this early in resolve() and return a clear
UnsupportedCopyAdd error. Multi-stage COPY --from= and ADD http(s)://
are still allowed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 22:09:30 -04:00
Bryan Helmkamp
7e2e61a4a7 Convert field-by-field and contains() tests to insta inline snapshots
Replace verbose assertion chains with insta snapshots across 4 crates:
- arc-devcontainer: 3 generate_layer tests (contains → assert_snapshot)
- arc-llm catalog: 7 model info tests (field-by-field → assert_debug_snapshot)
- arc-llm types: 2 usage serialization tests (contains → assert_snapshot)
- arc-util telemetry: 3 track serialization tests (per-key → assert_snapshot)

Snapshots now cover all fields (aliases, family, training, cache costs, etc.)
that were previously unasserted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 21:24:27 -04:00
Bryan Helmkamp
b5e57419a7 Convert check_report.rs render tests to insta inline snapshots
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 21:15:53 -04:00
Bryan Helmkamp
bd96b94acf Introduce insta snapshot testing for arc-devcontainer and arc-cli
Replace assert_eq!/contains() chains with insta::assert_snapshot! in
dockerfile unit tests (11 inline snapshots) and CLI model/help tests
(7 file-based snapshots), making test output easier to read and update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 21:09:15 -04:00
Bryan Helmkamp
490dc2e5eb Fix __send_analytics to delete event file on deserialization failure
The file was only deleted after successful deserialization + send.
Wrap the read/deserialize/send in an async block so remove_file
runs regardless of where the error occurs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 20:50:44 -04:00
Bryan Helmkamp
2735e1fc9b Bump version to 0.2.0 2026-03-10 20:37:47 -04:00
Bryan Helmkamp
992a920f72 Send telemetry via detached subprocess to survive CLI exit
Replace tokio::spawn fire-and-forget with a detached subprocess pattern:
send() serializes Track to ~/.arc/tmp/, spawns `arc __send_analytics <path>`
with ARC_TELEMETRY=off, and the child sends to Segment then cleans up the file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 20:18:35 -04:00
Bryan Helmkamp
8909eafbf3 Simplify PR commands: rename fields, use constant, parallelize list
- Rename PullRequestDetail fields from user_wrapper/head_wrapper/
  base_wrapper to user/head/base (serde renames no longer needed)
- Make GITHUB_API_BASE_URL public, replace hardcoded strings in pr.rs
- Replace opaque 5-tuple with PrRow struct in pr_list_from
- Parallelize GitHub API calls in pr_list using futures::join_all

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:54:38 -04:00
Bryan Helmkamp
9d966d3a08 Add arc pr list/view/merge/close subcommands
Add PR lifecycle commands that operate on workflow runs via their
pull_request.json records. Each loads the PR record from a run directory
and calls the GitHub API: list scans all runs and fetches live state,
view shows details, merge supports squash/merge/rebase, close sets
state to closed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:38:11 -04:00
Bryan Helmkamp
7ad187a78f Add signoff resource to verification system
Signoffs are stamps of approval for (control, repository, commit SHA)
tuples, enabling external tools and humans to mark a control as
pass/fail/pending for a specific commit. Adds OpenAPI spec, demo
handlers with 5 fixtures, route registration, and regenerated TS client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:32:33 -04:00
Bryan Helmkamp
0d9b300aaf Remove --no-dotenv flag, always load ~/.arc/.env, never load ./.env
The local .env loading was unnecessary since arc install writes all
config to ~/.arc/.env. Simplifies dotenv behavior to unconditionally
load from the home directory only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:26:43 -04:00
Bryan Helmkamp
fc77a2fb24 Gate --mode and --server-url CLI args behind server feature
When compiled without the server feature, these args are useless since
there is no server to delegate to. Wraps the CLI fields, parser,
resolve_mode, build_server_client, and related tests in cfg(feature =
"server"), with standalone-only fallback paths in each command handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:16:59 -04:00
Bryan Helmkamp
f9d114c521 Rename doctor "Sandbox" to "Cloud sandbox" and remove Docker checks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:05:47 -04:00
Bryan Helmkamp
8994250db9 Reorder arc doctor sections: Config, LLM, GitHub App, Sandbox, Brave Search
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:02:45 -04:00
Bryan Helmkamp
bb1de07c13 Clean up git checkpoint code: fix race condition, add shell quoting, deduplicate push helpers
- Fix /tmp/arc-commit-msg race: use unique path per run_id+node_id for concurrent local runs
- Add shell_quote for author.name/email interpolated into shell commands
- Unify git_push_meta_host and git_push_run_host into a single git_push_host helper
- Remove unused git_head_sha_remote function
- Extract repeated !sandbox.is_remote() && git_checkpoint_enabled into local_git_checkpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 19:00:34 -04:00
Bryan Helmkamp
71b4329669 Eliminate GitCheckpointMode enum, unify local and remote git operations
All git checkpoint, diff, push, worktree, and merge operations now go
through sandbox.exec_command() instead of maintaining parallel Host
(spawn_blocking) and Remote code paths. The enum is replaced by
git_checkpoint_enabled + host_repo_path on RunConfig, and
sandbox.is_remote() is used where behavior still differs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:46:46 -04:00
Bryan Helmkamp
982327da6c Add release script to bump version, tag, and push
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:36:54 -04:00
Bryan Helmkamp
5501ba6fe7 Fix install.sh prompt not showing when piped via stdin
Check for /dev/tty instead of stdin being a terminal, so the Y/n
prompt works with `cat install.sh | bash`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:31:34 -04:00
Bryan Helmkamp
d5bd2c6046 Install to ~/.arc/bin instead of /usr/local/bin and auto-configure PATH
- Use %b instead of %s in printf helpers to fix unescaped color codes
- Default install dir to ~/.arc/bin (no sudo needed)
- Auto-append PATH export to shell config (zsh, bash, fish)
- Skip PATH setup with dim message if arc is already on $PATH
- Add tildify helper for friendlier path display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:30:37 -04:00
Bryan Helmkamp
d5defaf2bd Improve install.sh output and prompt to run setup wizard
Redirect all UI output to stderr so piped installs work cleanly.
Add Fabro header, color enhancements, and checkmark/cross indicators.
Prompt interactive users to run `arc install` immediately after download.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:19:18 -04:00
Bryan Helmkamp
5b71f42994 Add install one-liner near top of README for quick access
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:18:13 -04:00
Bryan Helmkamp
6725cf38b3 Improve arc run --preflight output with Repository section, merged LLM check, and truncation
Split preflight into Repository (setup commands, git clean) and Workflow
(nodes, edges, goal, model, provider) sections. Merge LLM providers and
Provider checks into a single LLM check. Add terminal-width-aware
truncation for long detail lines. Render "Git clean: false" in red.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:17:16 -04:00
Bryan Helmkamp
2c9985100e Simplify README quick start and consolidate sections
- Replace platform-specific install instructions with curl | bash one-liner
- Combine quick start steps into a single code block with comments
- Remove Agents and CLI Reference doc links
- Move Contributing into Help or Feedback section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:17:04 -04:00
Bryan Helmkamp
3d5fe4d5bf Rebrand arc install header to Fabro with ⚒️ emoji
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:10:09 -04:00
Bryan Helmkamp
04ae811aff Add api.responses.write scope to OpenAI OAuth flow
The browser login flow only requested identity scopes, so the resulting
access token lacked permission to call the Responses API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 18:07:33 -04:00
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
38bc5c70b7 Add install.sh for automated Arc CLI installation
Uses gh CLI to download the latest release, detect platform
(macOS ARM with Rosetta detection, Linux x86_64), and install
the binary to /usr/local/bin (or ARC_INSTALL_DIR).

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