Move durable run access and execution control onto the server-backed client,
canonicalize run APIs under /api/v1/runs, and switch CLI integration tests
to a shared test daemon/storage model with shared-state-safe assertions.
Define the new run-store contract in the OpenAPI spec, regenerate the
Rust and TypeScript clients, and implement the matching store and
server support for run state, event access, blobs, and stage artifacts.
Align the HTTP API with the CLI's existing `fabro create` / `fabro start`
separation. POST /api/v1/runs now creates a run in `submitted` status
without queuing it. A new POST /api/v1/runs/{id}/start transitions to
`queued` and notifies the scheduler. Also removes the unused
/api/v1/runs/{id}/context endpoint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update the run directory, context, and output docs to describe
large offloaded values as file-backed artifacts while preserving the
existing cache path examples.
Replace typify-only type generation with progenitor, which generates both
Rust types (in a `types` module) and a reqwest-based HTTP client from the
OpenAPI spec. Also upgrades reqwest 0.12→0.13 and rmcp 0.15→1.3 to align
dependency versions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move storage_dir() from FabroSettingsExt trait in fabro-config into an
inherent method on Settings in fabro-types. Remove the re-export from
fabro-config so callers import directly from fabro_types. Drop the
redundant Fabro prefix since the type already lives in the fabro_types
crate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the old React Router SSR setup with a static SPA build served by
fabro-server, move setup and GitHub auth handling into Rust, and update the
default local web URL and stale Arc-era references to match the Fabro name.
Users should use `fabro repo init` instead. The deprecation shim has
been in place long enough; remove it and update all docs references.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uses clap_complete to generate tab-completion scripts for zsh, fish,
elvish, and PowerShell. Bash generation is caught gracefully since
clap_complete panics with #[command(flatten)] subcommands.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure the flat `serve` command into a nested `server start`
subcommand, following the existing namespace pattern (system prune,
repo init, etc.).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop the Sprites (Fly.io microVM) sandbox provider entirely. Three
providers remain: Local, Docker, and Daytona.
- Delete lib/crates/fabro-sandbox/src/sprites/ module
- Remove sprites feature flag and dep comments from Cargo.toml
- Remove sprites module declaration from lib.rs
- Update resolve_path cfg guard to daytona-only
- Delete docs/integrations/sprites.mdx and remove nav entry
- Remove Sprites rows from provider tables in docs
- Clean up SDK reference and changelog mentions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These commands all operate on a run's sandbox environment. Grouping them
under `fabro sandbox` makes the mental model clear and avoids confusion
with `fabro asset cp`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the batch AssetsCaptured event with per-file AssetCaptured events
that include content hashes and MIME type. The asset collection manifest
now stores a captured_assets array with full metadata instead of bare
path strings, enabling downstream integrity verification and content
type awareness.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Better reflects that this crate contains auto-generated types scoped
to the API layer. Pure rename with no behavior change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the per-run `--run-dir` CLI flag with `--storage-dir` which sets
the base storage directory (default ~/.fabro). Runs are now created under
`<storage-dir>/runs/` automatically. This unifies the server's `data_dir`
config with the CLI by renaming `FabroConfig.data_dir` to `storage_dir`
and adding a `storage_dir()` convenience method.
Key changes:
- FabroConfig: `data_dir` → `storage_dir` (serde alias preserves compat)
- CLI: `--run-dir` → `--storage-dir` on `fabro run`
- `__detached`: now takes `--storage-dir` + `--run-id` instead of `--run-dir`
- All ~20 CLI commands derive runs base from config instead of hardcoded default
- Added parameterized `runs_base(storage_dir)` and `make_run_dir()` helpers
- Updated OpenAPI spec, docs, and all tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Preflight validation is conceptually distinct from running a workflow —
it deserves its own top-level command rather than being a flag on `run`.
- Add `PreflightArgs` struct and `Commands::Preflight` variant
- Create `commands/preflight.rs` with dedicated `execute()` function
- Remove `--preflight` flag from `RunArgs`
- Refactor `load_workflow_source_input` to take individual params
instead of `&RunArgs`
- Refactor `resolve_cli_goal` to take `Option<&str>` / `Option<&Path>`
- Refactor `run_preflight` to take `cli_model`/`cli_provider` instead
of `&RunArgs`, make `pub(crate)`
- Update docs and skills references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resume now follows the same subprocess pattern as run: look up run
directory by ID prefix, validate checkpoint exists, clean stale
artifacts, reset status to Submitted, spawn _run_engine --resume, and
attach. This eliminates ~1600 lines of duplicated env/sandbox setup
from resume.rs.
Key changes:
- operations::start() and operations::resume() take run_dir instead
of Persisted, loading state from disk internally
- run_engine() builds RunOptions from RunRecord on disk, so callers
no longer extract record fields manually
- StartOptions flattened (no more nested InitOptions)
- FabroError::Precondition variant for start/resume guard checks
- _run_engine accepts --resume flag to dispatch to resume path
- operations::restore removed (no longer needed)
- Resume CLI stripped to just <RUN_ID> + --detach
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 5: Rename debug artifacts from run.toml/graph.fabro to
workflow.toml/workflow.fabro. Change write_run_config_snapshot to
byte-for-byte copy of the original TOML instead of re-serialization.
Phase 6: Add run_from_record() that builds execution state directly
from a RunRecord, bypassing prepare_workflow(). Refactor run_command
into run_command + run_command_impl to share execution logic. Simplify
run_engine_entrypoint to call run_from_record() instead of
reconstructing RunArgs and re-parsing the workflow.
Step 7k: Write RunRecord in the API server's execute_run() for
observability, enabling fabro ps/inspect for API-initiated runs.
Fix stale manifest.json reference in docs/agents/outputs.mdx.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce two new persistence types aligned to the CREATE/START lifecycle:
- RunRecord (run.json): written at CREATE with merged FabroConfig, fully
transformed Graph, and run metadata
- StartRecord (start.json): written at START with start_time, run_branch,
and base_sha
All readers (run_lookup, inspect, diff, pr, attach, detached_support,
start, run_fork, pull_request, run_rewind, resume) now read from the
new types first. Legacy manifest.json + spec.json are still written
for backward compatibility (removal in follow-up).
Also adds dry_run, auto_approve, no_retro fields to FabroConfig, derives
Default on LlmConfig and Graph, and updates docs + tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Context::append_log / logs_snapshot was a write-only audit trail that
was never surfaced — not in events, CLI output, or tracing. Errors like
"checkpoint save failed" were silently swallowed.
Replace all append_log call sites with RunNotice events (which are
automatically traced and visible in progress.jsonl / CLI). Remove the
logs field from both Context types, the Checkpoint struct, the OpenAPI
spec, and the TS client. Old checkpoints containing a logs field are
silently ignored during deserialization.
Also make git_diff return Result<String, String> with structured error
info (exit code + stderr) instead of Option<String>.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update references to WorkflowRunConfig, ServerConfig, apply_defaults,
and deny_unknown_fields in comments and docs to reflect the FabroConfig
unification.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Preserve original error chains (reqwest, serde_json, etc.) in SdkError
via Arc<dyn Error>-backed #[source] fields on Network, RequestTimeout,
Stream, and Configuration variants. This makes production debugging of
network/TLS/DNS issues easier since error reporters can now walk the
full chain. Serde-compatible via #[serde(skip)] — message string still
carries the text for serialized forms.
Also add a `type` field to ToolCall (defaulting to "function") so
non-function tool types from providers won't be silently mishandled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove ErrorPolicy enum (continue/fail_fast/ignore) and the k_of_n/quorum
join policies from the parallel handler, leaving only wait_all and
first_success. This deletes ~180 lines of conditional logic including
FailFast early termination, the ParallelEarlyTermination event, and all
related tests and documentation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove any-edge fallback from select_edge() in deterministic mode; random
mode retains it as an enhancement over the base spec
- Restrict preferred_label and suggested_next_ids matching to unconditional
edges only (already applied in prior work, tests added here)
- Rename default_max_retry → default_max_retries across codebase (code, docs,
fixtures, skills) and change default from 3 to 0
- Update transitions.mdx to document edge selection cascade accurately
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce a reusable Warning { kind, message, details } variant in
AgentEvent so non-fatal warnings (context window usage, deprecation,
etc.) share a single event shape. The context_window warning preserves
all original fields inside the JSON details object.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>