Return just the SSH command string instead of the full SshAccessDto,
and hardcode the 60-minute expiration internally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show smoothness rating, outcome, friction/open item counts, and file
path after retro completes instead of just the file path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Creates SSH access after sandbox init and displays the connection
command in the progress output, aligned under the sandbox detail line.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Handle ParallelBranchStarted/Completed events as nested entries under
the fork stage, using the same indented spinner styling as tool calls.
Branch bars persist after the stage completes so they remain visible
in the final output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use insert_after instead of add so the detail bar renders directly
below the sandbox bar, not at the bottom of the multi-progress.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show sandbox name, CPU, and memory on a second indented detail line
beneath the "Sandbox: provider" line. Hyperlink the provider name to
its dashboard URL using OSC 8 terminal escape sequences (TTY only).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
apply_defaults() previously did whole-struct replacement for llm, setup,
and sandbox sections. If run.toml specified only [llm] model, the entire
server.toml [llm] block (including provider) was lost. Now each field
merges individually: task values win per-field, with map-merge for labels
(like vars) and whole-struct semantics for snapshot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a shared floor_char_boundary() utility that rounds byte indices down
to the nearest char boundary, preventing panics on multi-byte UTF-8
characters like emoji. Applied to all 9 unsafe slice sites across
arc-agent and arc-workflows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display the LLM model ID (dim, bracketed) next to stage names as soon as
the first AssistantMessage arrives, and show the script command (dim,
truncated to 60 chars) for parallelogram/script stages from stage start.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reads the checkpoint to find the last stage with a response and
prints it under an "=== Output ===" header so users can see what
the workflow produced without digging into log files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Show tool args in dim parenthetical: read_file(CLAUDE.md)
- Shorten CWD-relative paths in tool call display
- Show elapsed time on completed tool calls
- Emit StageStarted/StageCompleted for terminal (exit) nodes
- Add --no-retro flag to skip retro generation
- Add demo/02-tool-use.dot, renumber existing demos 03-07
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Shorten paths with ~ instead of full home directory
- Show retro duration right-aligned like stage lines
- Add "Running retro..." indicator before retro agent runs
- Dim the Cost/Tokens summary line
- Add blank line after Goal before progress section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap cost and duration order so cost appears first and duration
stays consistently on the far right edge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Insert a separator bar through indicatif before hiding progress bars
for interactive prompts, ensuring a visual gap between the spinner
and the dialoguer prompt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Increase indent from 2 to 4 spaces for progress UI lines
- Add blank line separators after Sandbox/Setup and before Retro output
- Dim Sandbox/Setup and workflow metadata lines
- Rename "Parsed workflow:" to "Workflow:"
- Remove redundant inform() calls for run/stage start/complete
- Remove Notes: and Logs: lines from end-of-run summary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cache ProgressStyle and glyph strings with OnceLock (avoid repeated
template parsing and allocations on every event)
- Fix unsafe byte-based string slicing in tool_display_name (use chars)
- Parse status via StageStatus enum instead of raw string comparison
- Remove unused started_at and logs_bar fields
- Extract shared finish_stage method from duplicate completed/failed logic
- Simplify match arms to if-let where only TTY branch has work
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Cover format_cost, format_tokens_human, compute_stage_cost, all
format_event_summary variants, validate_command, context_diff, and
parse_label_filters with fast unit tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
Shrink timeouts and handler durations by ~5-10x. The tests verify
the same relative timing behavior (keepalive interval < stall timeout,
hung handler outlasts timeout) with smaller absolute values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add magenta, underline, bold_green, and bold_red styles to Styles struct.
Fix color semantics: server address uses cyan (info, not success), status
lines use bold_green/bold_red, preflight verdict uses bold variants, and
file paths are underlined instead of dim.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Replace raw stdin.lock().lines() in run_chat with dialoguer::Input
using spawn_blocking for TTY, with a stdin fallback for non-TTY.
Apply ColorfulTheme::default() to all dialoguer widgets in both
arc-llm and arc-workflows ConsoleInterviewer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Extract parse_sandbox_provider, resolve_sandbox_provider, and
resolve_daytona_config helpers to eliminate 4 near-identical sandbox
parsing chains. Compute sandbox_provider once with proper error handling
instead of twice (preview silently swallowed errors). Fix bug where
run_preflight did not fall back to run_defaults for daytona config.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Better reflects domain semantics: the config describes a workflow run,
and the free-text field is the run's goal, not a generic "task".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove RunMode enum (only Preflight was checked; DryRun/Normal unused)
— use args.preflight directly
- Switch default_model_for_provider() to take Provider enum instead of
Option<&str> for exhaustive matching; adds missing Inception default
- Extract sandbox init/cleanup into creation + single check pattern,
eliminating 3x copy-paste of identical init/cleanup boilerplate
- Replace setup_commands Vec clone with direct count (only .len() used)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verifies sandbox boot (local/docker/daytona), LLM provider availability,
and model/provider resolution chain, then prints a structured report.
Extracts model/provider resolution into reusable helpers
(default_model_for_provider, resolve_model_provider) with tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parallel branches now include the node visit count (pass1, pass2, etc.)
in their ref names, preventing silent overwrite when a parallel node is
re-executed via retry or loop_restart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename node visit suffix from `-attempt_{V}` to `-visit_{V}` and move
asset collection under `artifacts/assets/` alongside artifact values in
`artifacts/values/`. Retry directories use `retry_{N}` instead of the
ambiguous `attempt_{N}`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automatically discovers and collects well-known output files (test reports,
screenshots, trace files) from each node's execution into its log directory.
Works across all three sandbox types (local, Docker, Daytona) via a new
`download_file_to_local` trait method that handles binary files correctly.
- New `asset_snapshot` module with pure functions for find command generation,
output parsing, candidate matching, and budget enforcement
- `Sandbox::download_file_to_local` implemented for Local (fs::copy),
Docker (host bind-mount resolution), and Daytona (SDK download)
- `AssetsCaptured` event variant with DEBUG-level tracing
- Engine integration: baseline snapshot before handler, collection after
(both success and error paths), non-fatal on errors
- E2e tests for local sandbox (2 tests), Docker (#[ignore]), Daytona (#[ignore])
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Instead of flattening the inner event's fields into the top level
(which causes collisions when SubAgentEvent wraps SubAgentEvent —
losing inner agent_id, depth, and nested event body), keep the inner
event as a `nested_event` JSON value. The dot-notation event name
still reflects the inner type for easy filtering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WorkflowRunStarted and GitCheckpoint have a `run_id` field that
collides with the envelope's top-level `run_id`. Filter out
`timestamp`, `run_id`, and `event` from event fields to avoid
duplicate keys in the JSONL output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
The `-vv` (full detail) mode was not useful in practice. This collapses
the two-tier `-v`/`-vv` into a single `--verbose` boolean and removes
the now-dead `format_event_detail` function and its tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adopt cleaner terminology: Sandbox (resource providing disk + execution),
SandboxProvider (Local/Docker/Daytona), SandboxEvent (lifecycle events),
and Snapshot (pre-built environment images). Flatten DaytonaSandboxConfig
into DaytonaConfig, rename CLI flag to --sandbox, and update TOML config
sections from [execution] to [sandbox].
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>