`thiserror`-derived `Display` does not walk `#[source]`, so `format!("{err}")`
and `format!("{err:#}")` on a typed error silently produce only the
top-level message — the same format string changes meaning when migrating
from `anyhow::Result` to a typed `Result`. Point at
`fabro_util::error::collect_chain` as the canonical helper and broaden
the test guidance to cover typed errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Include completed stages without LLM usage in run billing responses so command-only runs still show runtime rows. Keep token and model aggregates scoped to billed LLM usage, and render placeholder values in the web billing table.
Keep sandbox exec failures structured until event emission so git push, checkpoint, notice, and retro failures can expose redacted output tails without expanding their terse error strings.
Also add log rendering that appends sanitized tail content for exec-backed errors while preserving the existing safe Display behavior.
Emit snapshot slow-path events only when Docker or Daytona actually performs image or snapshot work, replace retired completion markers with snapshot.ready, and render the lifecycle in attach/log output.
So that CLI and other API consumers can surface a clickable link to the
run's web UI page instead of guessing route shapes or probing settings.
The server populates `web_url` from `server.web.enabled` and
`server.web.url`, returns it on `RunStatusResponse` (create plus all
lifecycle transitions), and persists it on the `run.created` event so
attach replays the same link without re-deriving it.
CLI: prints `Web UI: <url>` as a run-header info line, driven off the
replayed event so fresh runs and `attach` share one code path. Absent
when the UI is disabled.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The smoke and implement-plan workflows ran cargo clippy without a
toolchain prefix, so on the Daytona snapshot they fell through to the
baked-in stable toolchain. clippy.toml now uses allow-unwrap-types
(added in clippy 1.95), which the stable in fabro-v7 doesn't recognize.
Pin every fmt and clippy invocation to nightly-2026-04-14 so they match
.github/workflows/rust.yml. Also update the public repl-handoff example
to keep the documented template consistent.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use HTTP health checks with short deadlines for managed server readiness and add finite control-plane request timeouts for CLI/server clients. Keep stream bodies uncapped so SSE attach flows can remain long-lived.
Keep fabro_workflow::event as the public facade while moving event conversion, names, redaction, sink, emitter, stored-field helpers, and StageScope into focused modules. Co-locate the existing event tests with the moved code and update the events strategy docs for the new module layout.
provider_used, script_invocation, and script_timing become object | null;
parallel_results becomes Array<object> | null. The Rust StageState type is
unaffected because fabro-api/build.rs replaces it with fabro_types::StageState.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reframe the deployment docs around the actual product story: Fabro
runs as a server, and the only deployment question is where that
server runs (laptop vs self-hosted Docker). Drop the Render, Fly.io,
and DigitalOcean guides and their config files; keep Railway as the
managed shortcut.
- New: administration/deployment.mdx (overview, two-mode framing)
- New: administration/self-host-docker.mdx (compose-first how-to)
- Move: administration/deploy-server.mdx -> reference/server-operations.mdx
(it was operational reference, not deploy guidance)
- Delete: deploy-render.mdx, deploy-fly-io.mdx, deploy-digital-ocean.mdx
- Delete: render.yaml, fly.toml, railway.toml, Dockerfile.deploy
- docker-compose.yaml: load .env if present so users can drive the
stack from a single env file end-to-end
- Update internal links and the docs-test that pinned the old path
Add bounded redacted exec output tails to failure events while keeping tracing log-safe. Centralize tail projection on ExecResult and thread diagnostics through metadata, setup, devcontainer, and CLI install failures.
Move RunDump into fabro-dump so CLI export and retro uploads share the same hydrated run layout. Drop the legacy artifact file-ref parser, add best-effort run.log retrieval for retro, and update retro prompts/docs to use events.jsonl and checkpoints.
Represent command termination explicitly across sandbox results, events,
run projections, API types, and the run stage UI. This removes the fake
-1 exit code path for timeout/cancel and lets consumers tell cancelled
commands apart from timed-out commands.
Persist command stdout/stderr through scratch logs and finalized CAS refs, expose byte-offset tailing through the API, and render separate streaming panels in the web run view.
Resolve command output blob refs for execution-time consumers such as edge routing and retros, and make Docker streaming timeout/cancel drain output before returning.
Add configured to the model API contract and server responses so clients can see whether provider credential material exists before testing. Use that signal in bulk model tests to skip unconfigured providers before printing progress and treat post-list skips as race failures.
Move favicon, logo, logotype, and PNG icons from /public/ root to
/public/images/ so the HTTP log middleware can drop them by path
prefix. Extends the existing /assets/ skip in http_log_middleware to
cover /images/ as well, removing favicon/logo entries from the server
log without filtering by extension (which would risk muting future
extension-suffixed API routes).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stage the two 2026-04-30 plan documents: command output streaming with
CAS log storage, and the duplicate-type unification rollup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reflect Docker as the default sandbox provider, add `skip_clone` for
clone-based providers, document the `[run.sandbox.docker]` config
table, and update tutorial command lines from `files-internal/...` to
`docs/internal/...`. Bump the docs skill watermark to the latest synced
commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename `files-internal/prompts/simplify.md` to `prompts/simplify.md`
adjacent to the .fabro files that reference it, and update the
plan-implement and simplify demos plus the plan-implement test fixture
to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add typed metadata snapshot events around init, checkpoint, and finalize archive writes so run logs expose durable metadata timing and failures. Include snapshot accounting, CLI rendering with compatibility-notice suppression, and event documentation.
Return degraded run files with the same FileDiff[] shape as live responses, using nullable contents and per-file unified patches so the web sidebar and deep links work consistently.
Generate a fresh UUIDv4 per request, attach it to response headers,
JSON error bodies, and HTTP response logs so client-visible failures can be
matched to server logs without trusting inbound request id headers.
Expose the configured server.web.url in system info so the empty runs quick start can show a runnable fabro auth login command instead of a placeholder.
Mintlify parses pages as MDX and rejects HTML-style `<!-- ... -->`
comments, which broke the docs deployment on cli.mdx with a parse
error. Switch the generator fences (and the matching markers in the
two reference pages and the dev test fixtures) to `{/* ... */}` so
Mintlify can parse them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop async from validate::run after the preflight refactor removed all
awaits, replace absolute paths and a one-liner helper in
manifest_validation, swap a redundant to_path_buf for clone in a test,
and regenerate cli.mdx so docs check stays green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a validation-only API response and route while keeping fabro validate local so it does not start or contact the server for structural workflow checks.