Commit graph

60 commits

Author SHA1 Message Date
Bryan Helmkamp
aae1efab98 Add arc cp command for copying files to/from run sandboxes
Introduces sandbox reconnection via persisted SandboxRecord, adds
upload_file_from_local to the Sandbox trait, and migrates arc-sprites
shell quoting to shlex::try_quote.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:03:10 -04:00
Bryan Helmkamp
ac0314de2c Support [pull_request] config in cli.toml
Allow setting pull_request.enabled in ~/.arc/cli.toml so auto-PR
works when running `arc run` with a .dot file (no run.toml needed).
Cascade precedence: run.toml > cli.toml > server.toml > defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 01:35:31 -04:00
Bryan Helmkamp
105bdc04de Add e2e tests for arc exec against live LLM
Five new CLI-level tests covering file creation, shell execution,
read-only permission enforcement, JSON output format, and read+edit
multi-step tool use. All gated with #[ignore = "requires API key"].

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:26:52 -04:00
Bryan Helmkamp
7f264e44c1 arc exec server mode via /completions proxy (#4)
* arc(01KK6WHKW0XB829BBCXH5N5G03): implement (success)

Arc-Run: 01KK6WHKW0XB829BBCXH5N5G03
Arc-Completed: 2
Arc-Checkpoint: b394706ae5111891bed4c3c20290464410a8ff23

* arc(01KK6WHKW0XB829BBCXH5N5G03): simplify (success)

Arc-Run: 01KK6WHKW0XB829BBCXH5N5G03
Arc-Completed: 3
Arc-Checkpoint: fa9fabbe6016dd6bb795a4a1711792320aa4e1b2

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:36:33 -04:00
Bryan Helmkamp
7f6f356bae TOML Config Format for MCP Servers (#2)
* arc(01KK6WHD2MEDZ0JVYTHEK9HFNF): implement (success)

Arc-Run: 01KK6WHD2MEDZ0JVYTHEK9HFNF
Arc-Completed: 2
Arc-Checkpoint: 25f71de745f9001a09e566706d62a6ac2ea6f827

* arc(01KK6WHD2MEDZ0JVYTHEK9HFNF): simplify (success)

Arc-Run: 01KK6WHD2MEDZ0JVYTHEK9HFNF
Arc-Completed: 3
Arc-Checkpoint: fed4325308110df4799171944ddb5170de59044c

* Fix Rust formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:26:46 -04:00
Bryan Helmkamp
d002aa0b51 Rename arc run start → arc run (#5)
* arc(01KK7524KNGTPS4090QMF87FJN): implement (success)

Arc-Run: 01KK7524KNGTPS4090QMF87FJN
Arc-Completed: 2
Arc-Checkpoint: 1ff03c704805dfe8e7c37b37f97bd06dfa0e5dc5

* Fix: restore trailing newlines stripped by previous commit

* arc(01KK7524KNGTPS4090QMF87FJN): simplify (success)

Arc-Run: 01KK7524KNGTPS4090QMF87FJN
Arc-Completed: 3
Arc-Checkpoint: 21771adfd26283a1d1e6b8a123a83a0c4277db48

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Arc Assistant <assistant@arc.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:14:50 -04:00
Bryan Helmkamp
18aaa75ae7 Support verbose = true in cli.toml to default verbose output on
Adds a top-level `verbose` bool to CliConfig so `arc run start` and
`arc doctor` pick it up without requiring `-v` every invocation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:01:05 -04:00
Bryan Helmkamp
3dce68d664 cargo fmt 2026-03-08 09:51:10 -04:00
Bryan Helmkamp
15a8eed5dc Reuse server_config::LogConfig in CLI instead of duplicate struct
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 00:37:46 -05:00
Bryan Helmkamp
a1fb96c08a Add [log] config section to server.toml and cli.toml
Allow persistent log level configuration without environment variables.
Precedence: ARC_LOG env > --debug flag > config [log] level > "info".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 00:33:51 -05:00
Bryan Helmkamp
006f198014 Rename stale agent variable to exec in cli_config tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:42:15 -05:00
Bryan Helmkamp
1825b61b0e Rename arc agent CLI subcommand to arc exec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:38:03 -05:00
Bryan Helmkamp
f0c97a2739 Add server-mode support for arc llm chat via session endpoints
Implement the server-side session handlers (create, retrieve, send message,
stream events, list) with in-memory storage and LLM generation, wire them
into the router replacing not_implemented stubs, add run_chat_via_server
CLI function with SSE streaming, and add mode dispatch so `arc llm chat
--mode server` delegates to the API server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:34:15 -05:00
Bryan Helmkamp
21f94f48de Add POST /completions endpoint with Anthropic-style SSE streaming
Adds a completions API endpoint that supports both streaming (SSE) and
non-streaming (JSON) modes, with structured output via JSON Schema.
Wires up the CLI `arc llm prompt` command to use the server when
`--mode server` is specified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:06:58 -05:00
Bryan Helmkamp
f36ec7aab4 Replace git_author_name/email parameter pairs with GitAuthor struct
Consolidates the two separate String parameters (git_author_name,
git_author_email) threaded through ~10 function signatures into a
single GitAuthor struct with Default providing "arc"/"arc@local".
Also quotes git config values in parallel.rs shell commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:06:57 -05:00
Bryan Helmkamp
99ee007572 Add configurable git author identity for checkpoint commits
Users can now configure the git author name/email used for checkpoint
commits via [git.author] in server.toml (default) and cli.toml (override).
Defaults to "arc" / "arc@local" preserving current behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:06:57 -05:00
Bryan Helmkamp
95d95e81b1 Rename arc models CLI subcommand to arc model
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 12:47:07 -05:00
Bryan Helmkamp
7836eb4eaa Separate serve logs from CLI logs
`arc serve` writes to `serve-YYYY-MM-DD.log` and all other commands
write to `cli-YYYY-MM-DD.log` so the two are easy to tail independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:31:12 -05:00
Bryan Helmkamp
73d2d7918c Add --mode standalone|server CLI support for arc models list
Commands can now delegate to a running Arc API server instead of
executing in-process. Adds ExecutionMode, ServerDefaults, and
ClientTlsConfig to cli.toml parsing with CLI flag > config > default
precedence. The models list command fetches from GET /models when in
server mode, with mTLS client certificate auth when [server.tls] is
configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:03:55 -05:00
Bryan Helmkamp
c1630b5a21 Restructure ModelInfo into nested shape with new fields
Replaces flat ModelInfo fields with nested sub-structs (ModelLimits,
ModelFeatures, ModelCosts) and adds family, training, and
cache_input_cost_per_mtok fields to enrich the model catalog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:44:25 -05:00
Bryan Helmkamp
72b6e86f3d Clean up GitHub App credentials: share reqwest client, accept raw PEM, avoid clone
- Share a single reqwest::Client across GitHub API calls in resolve_clone_credentials
  to reuse the TLS connection pool
- Accept raw PEM (not just base64-encoded) in build_github_app_credentials, matching
  the existing decode_pem_env/decode_pem_value convention
- Move github_app into DaytonaSandbox::new() instead of cloning

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 22:45:19 -05:00
Bryan Helmkamp
cf50625824 Switch Daytona git cloning from gh CLI to GitHub App Installation Access Tokens
Replace `gh auth token` with GitHub App IATs scoped to `contents: read` for
Daytona sandbox git cloning. Public repos are auto-detected and cloned without
credentials. Private repos get short-lived, repo-scoped tokens. Clear error
messages for each failure mode (app not installed, suspended, no repo access,
auth failure). Falls back gracefully when no GitHub App is configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 22:31:40 -05:00
Bryan Helmkamp
9d1bd1d091 Add GPT-5.4 and GPT-5.4 Pro to model catalog
Add both models with aliases (gpt54, gpt54-pro). Neither replaces
gpt-5.2 as the OpenAI default. Update fallback chain test since
GPT-5.4 ($2.50) is now closer to Opus ($15) than GPT-5.2 ($1.75).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 22:12:21 -05:00
Bryan Helmkamp
57dd00a1a5 Add arc parse FILE.dot subcommand to print raw AST as JSON
Parses a DOT file and outputs its AST as pretty-printed JSON, useful for
debugging and tooling. Adds Serialize/Deserialize to all AST types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:16:04 -05:00
Bryan Helmkamp
40b707b077 Use typed enums in cli.toml config and simplify defaults
- Deserialize permissions/output_format as typed enums instead of strings
  so invalid values in cli.toml fail at parse time
- Use Option::or/or_else combinators instead of if-is_none pattern
- Load cli.toml only for agent/llm commands, not all CLI invocations
- Standalone arc-agent binary calls apply_cli_defaults for single source
  of hardcoded defaults
- Remove redundant #[serde(default)] on Option fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:37:43 -05:00
Bryan Helmkamp
7580be75ea Add ~/.arc/cli.toml config for persistent CLI defaults
Users who always use the same provider/model/permissions no longer need
to pass flags every time. Precedence: CLI flag > cli.toml > hardcoded default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:31:31 -05:00
Bryan Helmkamp
ba90d1e90e Add --config CLI arg to override server config path
load_server_config() now accepts an optional explicit path. When
provided, it reads from that path (erroring if missing) instead of
the default ~/.arc/server.toml. The --config flag is wired through
ServeArgs and the hot-reload polling loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:36:32 -05:00
Bryan Helmkamp
289451e78a Extract CheckReport into arc-util and use it for preflight output
Move CheckReport, CheckResult, CheckDetail, and CheckStatus types from
arc-cli doctor into arc-util so they can be reused. Refactor the workflow
run_preflight to render a styled check report instead of ad-hoc key=value
output and separate stderr errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:52:58 -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
dc3867a3c4 Fix cargo fmt formatting across workspace
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:36:44 -05:00
Bryan Helmkamp
fe9f6f6882 Remove 3 redundant doctor CLI integration tests
These tests only assert that section headings appear in stdout, which is
fully covered by unit tests in src/doctor.rs (check_llm_*, check_api_*,
check_web_*, and render tests). Removing them saves ~2.4s of parallel
nextest wall time from cold binary loads.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:18:18 -05:00
Bryan Helmkamp
79a6a5e973 Simplify setup.rs: extract openssl helpers, remove unwraps, flatten state
- Extract run_openssl/run_openssl_with_stdin to deduplicate 8 command
  invocations into 2 reusable helpers
- Replace all .unwrap() in production code with .context() for proper
  error messages (stdin handles, path UTF-8 conversions)
- Collect API keys directly into env_pairs, removing redundant
  intermediate api_keys Vec

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:28:34 -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
d373ffd10f Clean up doctor types: ProbeOutcome enum, typed status structs, Ord
- Replace found/success/version bools with ProbeOutcome enum to
  eliminate impossible state (found=false, success=true)
- Remove DepProbeResult; check_system_deps takes DepSpec + ProbeOutcome
  directly, eliminating redundant field copying and the clone
- Use typed Vec<ApiAuthStrategy> and AuthProvider in ApiStatus/WebStatus
  instead of converting enums to strings at construction time
- Derive Ord on CheckStatus, replace manual severity-max with .max()
- Extract dep_issue helper to deduplicate required/optional formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:55:34 -05:00
Bryan Helmkamp
78a8f93bc5 Replace version tuples with semver::Version in doctor
Use the semver crate's Version type instead of manual (u32, u32, u32)
tuples for version comparison and display, eliminating the custom
format_version helper in favor of Version's built-in Display and Ord.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:47:08 -05:00
Bryan Helmkamp
9243c94ded Replace fragile string filter with structural error tracking
The remediation list was derived by filtering details for strings not
containing ": valid", which could silently exclude real errors. Replace
with CryptoCheckState that accumulates errors structurally as they
occur, and unify all validation paths through record/record_unit/
push_error methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:25:27 -05:00
Bryan Helmkamp
d688a6c095 Simplify crypto validation in arc doctor after code review
- Extract record_validation() helper to deduplicate Ok/Err → detail handling
- Make expand_tilde public in tls.rs and reuse it in doctor instead of
  duplicating the tilde expansion logic
- Make now_epoch injectable in CryptoInput for deterministic tests
- Change tls_files to Option<Result<...>> to distinguish "not configured"
  from "files unreadable"
- Use struct update syntax in tests to reduce boilerplate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:21:34 -05:00
Bryan Helmkamp
dc7b0af2bc Add cryptographic key validation to arc doctor
Validates mTLS certs (PEM parsing, expiry), JWT public/private keys
(Ed25519 PEM with base64 support), and session secret (hex, 256-bit
minimum) when the corresponding auth strategies are configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 20:35:36 -05:00
Bryan Helmkamp
2afd63ba5a Simplify system dependency checks after code review
- Consolidate 4 duplicate parser functions into one `parse_version(re, output)`
- Use `LazyLock<Regex>` statics (matching codebase patterns in arc-util, arc-workflows)
- Replace 5-element tuple with named `DepSpec` struct
- Replace `raw_output: Option<String>` with `found: bool` (content was never used)
- Remove unnecessary `pub` from internal types and functions
- Parse stdout/stderr separately instead of concatenating
- Consolidate 10 parser tests into 6 via shared `parse_version`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:52:37 -05:00
Bryan Helmkamp
510d8b6df6 Add system dependency checks to arc doctor
Checks openssl, node, gh, and dot for presence, version, and command
success. Reports errors for missing/broken required tools and warnings
for optional ones. Also fixes pre-existing build break from
ApiAuthenticationStrategy -> ApiAuthStrategy rename.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:49:20 -05:00
Bryan Helmkamp
07a765f5a2 Simplify doctor --live: share HTTP client, concurrent LLM probes, extract helper
- Extract apply_live_result() helper to deduplicate connectivity-result
  handling across check_api, check_web, and check_brave_search
- Merge probe_api/probe_web into single probe_url function
- Share one reqwest::Client across all HTTP probes
- Run LLM probes concurrently via futures::future::join_all instead of
  sequential loop (saves wall-clock time with multiple providers)
- Compute daytona_configured once before the live/offline branch
- Move live flag from DoctorReport struct field to render() parameter

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 16:19:39 -05:00
Bryan Helmkamp
c2ea8b3084 Replace DIY terminal color with console crate
Styles fields change from &'static str (raw ANSI escape codes) to
console::Style, removing unsafe Send/Sync impls and manual reset
handling. The console crate handles TTY detection and NO_COLOR natively.

Also adds live connectivity probes to arc doctor (--live flag).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 16:02:10 -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
e3fa99eba1 Add run defaults to server config for workflow run inheritance
Rename AppConfig → ServerConfig with flattened RunDefaults so users can
set default llm, sandbox, setup, directory and vars in ~/.arc/arc.toml.
Precedence: CLI flags > workflow TOML > server config defaults > DOT
graph attrs > hardcoded defaults. Vars merge (defaults first, task
config overwrites collisions).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 01:26:41 -05:00
Bryan Helmkamp
c560c608e2 Rename progress.jsonl fields for clarity
Add node_id to Stage* enum variants so both the programmatic ID and
display label are available. Add rename_fields() post-processing in
flatten_event() to give flattened JSONL fields self-describing names:

- timestamp → ts (save space)
- name → node_label (Stage*), workflow_name, snapshot_name
- index → stage_index, branch_index, command_index
- stage → node_id (Agent.*, Interview*, Prompt)
- branch → node_id (ParallelBranch*)
- node → node_id (StallWatchdogTimeout)
- from_node/to_node → from_node_id/to_node_id
- start_node → start_node_id
- provider → sandbox_provider (Sandbox.*)
- text → prompt_text (Prompt)
- Insert node_label defaulting to node_id where only an id exists

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:11:33 -05:00
Bryan Helmkamp
62b54c8f4d Flatten progress.jsonl event format to top-level fields
Event data was nested inside a tagged enum (`"event": {"StageStarted": {fields}}`).
Now `event` is a string name and fields merge into the top-level object
(`"event": "StageStarted", "name": "plan", ...`).

Nested events use dot notation:
- Agent wrapper: "Agent.ToolCallStarted" with stage at top level
- Sandbox wrapper: "Sandbox.Initializing" with fields at top level
- SubAgentEvent: "Agent.SubAgentEvent.ToolCallStarted" flattened one level

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 18:25:27 -05:00
Bryan Helmkamp
9e74e6f913 Add --debug global CLI flag to switch log level from INFO to DEBUG
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 12:13:59 -05:00
Bryan Helmkamp
095dd5ff3c Add arc llm chat subcommand for interactive multi-turn conversations
Adds a new `chat` subcommand under `arc llm` that reads user input in a
loop, maintains conversation history, streams LLM responses, and supports
`--model` and `--system` options. Includes an e2e test verifying multi-turn
context and system prompt behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:54:47 -05:00
Bryan Helmkamp
6dd422186e Rename progress.ndjson to progress.jsonl
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 11:46:31 -05:00
Bryan Helmkamp
46af8e6887 Rename Pipeline to Workflow in CLI help text and test assertions
Update command descriptions and test event name strings to use
workflow/run terminology instead of pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 00:07:35 -05:00