Commit graph

103 commits

Author SHA1 Message Date
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
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
832c48ce5b Improve fatal error display with colored output and workflow suggestions
Show colored "error:" prefix with cause chain for all CLI errors. When a
workflow name isn't found in a project with arc.toml, list available
workflows and suggest the closest match using Levenshtein distance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 19:29:01 -04:00
arc-1e68f1[bot]
6cdb91e5fa arc system df (#11)
* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): toolchain (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 2
Arc-Checkpoint: cf6f964b878309dc8d79a9aeea0fa9c7bd4cff8f

* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): preflight_compile (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 3
Arc-Checkpoint: ff8dba601f46c90b5b37d78804e77c42bbc4e712

* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): preflight_lint (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 4
Arc-Checkpoint: 0d6b2bd079847ef5be18f8e3100ed76fc846ded3

* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): implement (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 5
Arc-Checkpoint: 4bd461b413389877d773ef248ecdd798bce43471

* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): simplify (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 6
Arc-Checkpoint: c8ad93c70cc29c0dd5680a75c22292ca7bac874c

* arc(01KK9YGJ6EBM3XKQBZC23GQ88F): verify (success)

Arc-Run: 01KK9YGJ6EBM3XKQBZC23GQ88F
Arc-Completed: 7
Arc-Checkpoint: efb5421ea6bd57a350ba3606b1ab20e98142d68f

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Bryan Helmkamp <bryan@brynary.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 15:15:27 -04:00
Bryan Helmkamp
3d21b0cd40 Extract arc-github crate; ExeSandbox owns credentials directly
Move GitHub App authentication (types, JWT signing, token creation,
credential resolution) into a new leaf crate `arc-github`. ExeSandbox
now owns `github_app` directly and resolves clone credentials on-demand,
eliminating the GitCredentialSandbox decorator and its wrapping code in
cli/run.rs. GitCloneParams simplified to a single clean `url` field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:24:10 -04:00
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
6e1b99734e Shell-quote all script-assembled arguments with shlex::try_quote
Replace ad-hoc replace('\'', "'\\''") escaping and unquoted interpolation
with a shell_quote() helper backed by shlex::try_quote to prevent command
injection via branch names, clone URLs, image names, env vars, file paths,
and grep patterns. Covers both arc-exe (SSH transport) and arc-workflows
(Daytona sandbox).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:52:22 -04:00
Bryan Helmkamp
e24d20b439 Update daytona-sdk-rust to 06033ca and apply clippy/fmt fixes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:13:43 -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
8ee27278dd Add conformance test to detect ServerConfig ↔ OpenAPI spec drift
Recursively compares serialized ServerConfig keys against the
OpenAPI ServerConfiguration schema properties. Also fixes 7 fields
that were missing from the spec: log, checkpoint, git.slug,
git.author, git.webhooks, sandbox.exe, sandbox.env.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:44:59 -04:00
Bryan Helmkamp
d838fda004 Add GitHub webhook listener via Tailscale funnel
Adds a webhook subsystem that receives GitHub App webhooks when configured
in server.toml with [git.webhooks] strategy = "tailscale_funnel". On startup,
it binds a local HTTP listener on a random port, exposes it via `tailscale funnel`,
and patches the GitHub App webhook URL. Incoming webhooks are verified with
HMAC-SHA256 before processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:37:56 -04:00
Bryan Helmkamp
916e95764c Bump daytona-sdk-rust to 03b7c06 (revert envs field)
The toolbox API does not support envs in /process/execute, so the
SDK now matches the Go SDK: accepts env in options but does not send
it. Arc uses export prepending as the workaround.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:25:35 -05:00
Bryan Helmkamp
8dffe80527 Bump daytona-sdk-rust and remove exec_command env workaround
The upstream SDK now passes env vars through ExecuteRequest.envs,
so we no longer need to prepend export statements to commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:12:50 -05:00
Bryan Helmkamp
f4b530c691 Split anonymous ID into server (UUID-on-disk) and CLI (MAC-based hash) strategies
Server is long-lived on a fixed host, so a persisted UUID at ~/.arc/.id is
appropriate. CLI runs ephemerally, so an MD5 of the MAC address avoids file
I/O and is stable per-machine. CLI falls back to ~/.arc/.id if it exists
for migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:00:44 -05:00
Bryan Helmkamp
2b8d6a40a1 Add Segment-based telemetry module to arc-util
Adds a telemetry library for product analytics with Segment integration.
Includes Track/User wire types, persistent anonymous ID (~/.arc/anonymous_id),
OS/arch/locale context, fire-and-forget sender via tokio::spawn, and
ARC_TELEMETRY env var control (off/errors/all). No CLI or server integration yet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:47:03 -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
c3ec637f09 Add arc-sprites crate for Sprites (Fly.io) VM sandbox
Implements the Sandbox trait backed by the `sprite` CLI binary.
Includes 29 unit tests with mock runner and an e2e integration test
against the live Sprites service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:06:58 -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
5df7e178ac Add SandboxProvider::Exe for exe.dev VM sandboxes
New `arc-exe` crate that runs agent tool operations inside ephemeral
exe.dev VMs via SSH. Uses two SSH connections: a management plane
(`ssh exe.dev`) for VM lifecycle and a data plane (`ssh vmname.exe.xyz`)
for command execution and file I/O.

Includes SshRunner trait with MockSshRunner for unit tests and
OpensshRunner for real SSH, with raw_mode for the exe.dev management
plane's custom command handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:18:00 -05:00
Bryan Helmkamp
4d9b0828c1 Fix ensure_cli for Daytona: rootless Node.js install, better errors
- Replace apt-get/NodeSource install (requires root) with direct Node.js
  binary download to ~/.local (works as non-root daytona user)
- Run node install + npm install in single shell so PATH persists
- Add ~/.local/bin to PATH in env file and version check
- Fall back to stdout for error details when stderr is empty (Daytona
  always returns empty stderr)
- Add e2e assertion that cli_stdout.log is written during poll
- Verified on Daytona with haiku: ensure_cli installs in 2s, full
  workflow succeeds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 02:01:47 -05:00
Bryan Helmkamp
92dc29eb6f Sessions API review fixes: add updated_at to create response, UUID session IDs, remove misleading SSE schemas
- Add updated_at to CreateSessionResponse for consistency with SessionListItem/SessionDetail
- Add format: uuid to session ID fields and parameter across the OpenAPI spec
- Remove SessionEvent discriminated union and SessionEvent* wrapper schemas that conflated
  SSE transport-level event names with JSON data payload fields
- Update demo data to use proper UUIDs instead of string IDs
- Add uuid dependency to arc-types crate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:51:50 -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
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
e5354c3028 Simplify arc-slack: use thiserror, remove dead params, extract helpers
- Use thiserror for SlackApiError and ConnectionError (project convention)
- Remove misleading PartialEq/Eq on DispatchAction; use matches!() in tests
- Remove unused _slack_client and _default_channel params from event loop
- Extract check_ok() helper to deduplicate 3 ok-check sites in client.rs
- Make bot_token private on SlackClient; add http() accessor
- Make SlackClient Clone; eliminate duplicate instance in e2e example
- Reuse reqwest::Client in open_socket_url instead of creating a new one
- Filter empty env vars in resolve_credentials; remove redundant is_enabled

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 09:24:22 -05:00
Bryan Helmkamp
fb76c0ec3e Add arc-slack crate: Slack Socket Mode integration for interviewer
Implements a complete Slack integration for the interviewer system using
Socket Mode (WebSocket-based, no public URL required). Supports all five
question types: YesNo, Confirmation, MultipleChoice, MultiSelect, and
Freeform (via thread replies with @mention).

Modules: config, client, blocks, interaction, socket, dispatch,
connection, threads. 72 unit tests + e2e example.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 09:16:22 -05:00
Bryan Helmkamp
97594b3ab0 Add HTTP hook executor with env var interpolation
HTTP hooks (type = "http") now actually execute instead of failing with
"no command specified". The executor POSTs the hook context as JSON,
parses HookDecision from the response, and fails open on errors.

Header values support $VAR/${VAR} interpolation gated by an
allowed_env_vars whitelist on the hook definition. Renames
CommandHookExecutor to HookExecutorImpl since it now handles both
command and HTTP hook types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:59:38 -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
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
28b5d485c1 Render Markdown output in terminal using termimad
LLM responses were printing raw Markdown (bold markers, table pipes,
heading hashes). Use termimad to render with proper ANSI formatting
when color is enabled, falling back to plain text when NO_COLOR is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:25:36 -05:00
Bryan Helmkamp
bde59168c9 Fix sandbox cleanup race and improve warning formatting
Sandbox cleanup was spawned fire-and-forget in a scopeguard, causing DNS
resolution to be cancelled when the tokio runtime shut down before the
HTTP request completed. Now cleanup is awaited explicitly before
returning, with the scopeguard kept only as a safety net for panics.

Also: add blank line before the warning and color-code it yellow to
match other warnings. Update daytona-sdk to include full error source
chain in error messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 08:29:05 -05:00
Bryan Helmkamp
a1adbe89ca Fix Dependabot security alerts: update aws-lc-sys, jsonwebtoken, git2
- aws-lc-sys 0.37.1 → 0.38.0 (3 high: PKCS7 bypass, AES-CCM timing)
- jsonwebtoken 9 → 10.3.0 (medium: type confusion auth bypass)
- git2 0.19 → 0.20.4 (low: undefined behavior in Buf deref)
- Fix pre-existing clippy warning in arc-devcontainer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:42:23 -05:00
Bryan Helmkamp
c374ceb391 Add indicatif-based progress UI for arc run start (non-verbose)
Replace plain dimmed text output with cargo/BuildKit-style progress bars
using indicatif MultiProgress. Shows spinners during active stages and
tool calls, right-aligned timers, green/red glyphs for completion status,
and stage costs. Falls back to simple eprintln for non-TTY. Verbose mode
is unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:58:43 -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
7660cea15c Restore abbreviated token formatting (1.2k, 3.4m) instead of HumanCount
HumanCount's comma-separated output (1,234) is less scannable for token
counts. Restore k/m suffix formatting with added millions support. Remove
indicatif dependency from arc-agent since it no longer uses it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:11:47 -05:00
Bryan Helmkamp
66d3f62131 Use indicatif formatters for human-readable durations, tokens, and bytes
Replace hand-rolled format_duration_human, format_tokens_human, and
format_token_count with indicatif's HumanDuration, HumanCount, and
HumanBytes. Token counts now display as comma-separated (e.g. "1,234")
instead of abbreviated (e.g. "1.2k"), and byte counts show units
(e.g. "1.50 KiB").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:09:18 -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
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
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
e0b8da08f2 Add mTLS authentication to arc-api
Support mutual TLS as an authentication strategy alongside JWT.
The server accepts both auth methods on the same port — mTLS if a
client cert is presented, JWT via Bearer header otherwise.

Config changes:
- Replace `authentication_strategy` (singular) with
  `authentication_strategies` (list of "jwt" and/or "mtls")
- Add `[api.tls]` section for cert, key, and CA paths

New files: tls.rs (rustls ServerConfig builder)
Modified: server_config.rs, jwt_auth.rs, serve.rs, lib.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:36:22 -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
2737e6164e Add colored output to models list and test, fix clippy warnings
Add ANSI color to `arc models` and `arc models test` output when stdout
is a TTY: bold model IDs, dim provider/aliases, cyan speed, green/red
test results. Add `Styles::detect_stdout()` to arc-util.

Also fix pre-existing clippy warnings: derive Default instead of manual
impls for enums in server_config, remove unused FailureDetail imports
in arc-workflows error tests, inline print literal in test_models header.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 14:49:02 -05:00
Bryan Helmkamp
d5b98af6d1 Support base64-encoded PEM for ARC_JWT_PUBLIC_KEY and ARC_JWT_PRIVATE_KEY
Some deployment environments (e.g. container orchestrators) make it
easier to pass secrets as single-line base64 strings rather than
multi-line PEM. Both env vars now auto-detect the format: if the value
starts with "-----" it's treated as raw PEM, otherwise base64-decoded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 14:39:49 -05:00
Bryan Helmkamp
9748d2e3fe Update Cargo.lock for reqwest dependency in arc-devcontainer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:48:30 -05:00
Bryan Helmkamp
5e337b4cb3 Add arc-devcontainer crate for parsing and resolving devcontainer.json
Standalone crate that reads devcontainer.json (with JSONC support), fetches
OCI Features via oras, and produces a resolved config containing a generated
Dockerfile, lifecycle hooks, environment variables, and forwarded ports.

Supports image, Dockerfile, and Docker Compose modes with devcontainer
variable substitution. No coupling to arc-workflows or DaytonaSandbox.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 22:38:12 -05:00
Bryan Helmkamp
1334a952af Add spec-first OpenAPI for arc-api with generated types
- Create openapi/arc-api.yaml as source of truth for all API endpoints
- Add arc-types crate with build.rs using typify to generate Rust structs
  from the spec's component schemas
- Refactor server.rs to use generated types instead of hand-written ones
- Add route coverage conformance test validating router matches spec
- Add openapi-typescript to arc-web for TypeScript type generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:43:49 -05:00
Bryan Helmkamp
d7d2294b7c Add structured tracing across 7 crates per logging audit plan
Implements all 47 gaps and fixes all 7 violations identified in
docs/agent/logging-audit-plan.md:

- arc-llm: Add tracing dep + 18 log statements (requests, responses,
  retries, timeouts, tool execution)
- arc-api: Add tracing dep + 6 log statements (server lifecycle,
  pipeline start/complete/fail), replace eprintln with warn
- arc-mcp: Fix 3 violations (string interpolation, secret leakage),
  add 7 log statements (client creation, handshake, tool calls)
- arc-workflows: Fix 3 eprintln violations, add 9 log statements
  (git checkpoints, Daytona sandbox, worktrees, node visit limit)
- arc-git-storage: Add tracing dep + 9 log statements (branch ops,
  snapshot write/delete/rename)
- arc-db: Add 3 log statements (connection, migrations)
- arc-agent: Add 4 debug statements (session init, compaction)
- arc-cli: Add 1 debug statement (command dispatch)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:43:19 -05:00
Bryan Helmkamp
ec70be1e0d Add trace() method to event enums for structured file logging
Every emitted event now produces a structured tracing log line so
developers can debug after the fact via ~/.arc/logs/. Each event
variant gets an appropriate log level (info/debug/warn/error) with
structured fields. Streaming noise variants (TextDelta,
ToolCallOutputDelta) are no-ops, and wrapper variants (Agent,
ExecutionEnv on PipelineEvent) delegate to the inner event's trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:15:43 -05:00
Bryan Helmkamp
716400ac06 Add file-based tracing infrastructure with ARC_LOG control
Tracing events (e.g. 13 calls in arc-mcp) were silently dropped because
no subscriber was configured. This adds a file-based tracing subscriber
that logs to ~/.arc/logs/YYYY-MM-DD.log with INFO as the default level,
controllable via the ARC_LOG env var.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:18:12 -05:00