Extract telemetry from fabro-util into a dedicated fabro-telemetry crate.
Replace the synchronous Telemetry struct with a global background buffer
that flushes periodically via blocking HTTP (mid-run) and detached
subprocess (final flush at exit). The new API is init_cli()/track!()/shutdown().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reference SEGMENT_BASE_URL (var) and SEGMENT_WRITE_KEY (secret) so
they are compiled into release binaries via option_env!().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Store only the base URL (e.g. https://api.segment.io) so that
different endpoints (/v1/batch, /v1/track, etc.) can reuse it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow overriding the Segment API endpoint via the SEGMENT_API_URL
environment variable at build time, defaulting to the standard
https://api.segment.io/v1/batch endpoint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The DaytonaConfig struct had a skip_clone field that was missing from
both the OpenAPI spec and the conformance test initializer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
doctor and provider_auth used cheapest_model (gpt-5-mini) for connectivity
probes, but gpt-5-mini is rejected by the ChatGPT/Codex backend. Adds
probe_model_for_provider() which returns gpt-5.4-mini for OpenAI and falls
back to the default model for other providers.
Fixes#96
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gpt-5-mini is not supported on the ChatGPT/Codex backend, causing all
16 OpenAI parity tests to fail when using browser-auth credentials.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce an Env trait in fabro-util so tests can inject a HashMap-backed
TestEnv instead of mutating process-global environment variables, which
is unsafe since Rust 1.66+ and causes flakiness in concurrent tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two Daytona integration tests used std::env::set_current_dir to a temp
directory so detect_repo_info() would fail and skip cloning. Since cwd
is process-global, this poisoned concurrent tests. Replace with an
explicit skip_clone config flag that skips repo detection and cloning
during sandbox initialization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This function had zero callers after sync_status was introduced in
ad84f9f9. Remove it along with its four tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace fully-qualified fabro_workflows::GitSyncStatus paths with a
use import, and consolidate the near-duplicate dirty-worktree warning arms
into a single block that varies only the environment name.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The git sync check and auto-push logic was gated on should_create_worktree,
which was always false for remote sandboxes. This meant Daytona/Exe/SSH runs
silently proceeded without verifying commits were pushed or warning about
uncommitted changes. Replace the git_clean boolean and should_create_worktree
boolean with two enums (GitSyncStatus: Synced/Unsynced/Dirty and
WorkdirStrategy: LocalDirectory/LocalWorktree/Cloud) so every combination
is handled explicitly via match arms. Also display the base commit SHA for
cloud runs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MDX treats {…} as JSX expressions. Bare curly braces in headings
and bold text caused acorn parse failures during Mintlify deploy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Some providers return summaries of example.com without the exact phrases
"Example Domain" or "example.com", so accept related terms like
"documentation" or "iana" alongside "example".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zai provider tests are unreliable (editing, web_fetch, web_search
failures). Gate them behind cfg(feature = "quarantine") like Inception
tests so they don't block the default test suite.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add `--` separator before `bash -c` in sprite exec args so the CLI
stops parsing flags and doesn't interpret `-c` as its own flag.
Also add E2E live test commands to CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The assertion was checking for the old repo name brynary/arc instead of
fabro-sh/fabro.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Docker and Daytona asset collection tests were failing because
asset_globs was empty, causing the engine to skip collection entirely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Codex endpoint commit (459a9c22) added `store: false` unconditionally
to all OpenAI Responses API requests. This broke multi-turn conversations
because OpenAI doesn't persist items when store is false, so referencing
previous reasoning/message IDs on subsequent turns returns a 404. The fix
makes store conditional: true for regular OpenAI (the API default), false
only for the Codex endpoint which requires it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sets up apps/remotion with a 5-second 1080p intro video featuring the
Fabro symbol, logotype, and tagline animated over the brand navy background.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fabro-api doesn't use `SandboxProvider::Exe` but was unconditionally
enabling `exedev` on fabro-workflows. Cargo feature unification made
the `Exe` variant exist while fabro-cli's cfg-gated match arms were
inactive, causing non-exhaustive pattern errors in workspace builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
- Disable git2 default features (`ssh`, `https`) which pulled in
`openssl-sys` and `libssh2-sys`
- These transports are unused — all git2 usage in the codebase is local
repo operations (commits, blobs, revwalks)
- The CLI binary no longer dynamically links against `libssl.3.dylib` /
`libcrypto.3.dylib`
Fixes#92
## Verification
- `otool -L target/debug/fabro | grep ssl` returns nothing (no OpenSSL
linkage)
- `cargo tree -i openssl-sys` returns nothing (fully removed from dep
tree)
- All 179 workspace tests pass
## Test plan
- [ ] Build release binary and verify with `otool -L` (macOS) or `ldd`
(Linux) that no OpenSSL refs remain
- [ ] Run on a machine without OpenSSL v3 installed — should launch
without `dyld` error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract git_repo_root() helper in init.rs (was duplicated between
run_init and run_deinit)
- Fix TOCTOU in run_deinit: remove .exists() check, handle NotFound
from remove_file directly
- Change dotenv::remove_env_key() to return Option<String> so callers
don't need to separately parse the file to check key existence
- Remove merge_env wrapper in install.rs, call shared function directly
- Remove duplicate merge_env tests from install.rs (already in dotenv.rs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides get/list/rm/set subcommands to manage secrets without manually
editing the .env file. Extracts shared dotenv utilities into
fabro-config::dotenv and refactors install.rs to use them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allows skill installation during project setup via `fabro repo init --skill`,
which installs the fabro-create-workflow skill to .claude/skills/. The flag is
hidden from help output since `fabro skill install` is being deprecated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removes fabro.toml and the fabro/ directory from the git repo root.
Fails with a clear error when the project is not initialized.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SandboxProvider::Exe variant is gated behind #[cfg(feature = "exedev")],
so the remaining variants are exhaustively matched without the wildcard.
Removing the dead arms fixes clippy's unreachable-patterns warning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move `fabro init` under `fabro repo init` subcommand group.
The old `fabro init` still works but is hidden from help and
prints a deprecation warning before executing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add coverage for validate, model list, workflow list, doctor, exec,
ps, inspect, logs, rm, system df, asset list, asset cp, and cp.
Uses HOME isolation for run lifecycle tests and synthetic assets
for asset/cp testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Promote fabro pr, fabro init, fabro diff, fabro preview, fabro graph,
user-level workflows, and GPT-5.4 Mini from accordion items to hero
sections. Reframe lifecycle hooks with positive language.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add March 17 changelog entry (OpenAI Codex backend, fabro docs/discord
commands, gpt-5.4-mini). Update March 16 entry with OAuth error fix.
Add gpt-5.4-mini to model catalog docs and fabro docs/discord to CLI
reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidate six duplicated helper functions (tilde_path, color_if,
split_run_path, validate_daytona_provider, format_duration_ms,
format_size) into commands/shared.rs. Also hoist Utc::now() out of a
per-run loop in list_command and avoid an unnecessary Vec<char>
allocation in truncate_goal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>