Commit graph

1345 commits

Author SHA1 Message Date
Fabro
bf010059cd fabro(01KM392JR46K2XB8VGJ3WKH4E2): work (success)
Fabro-Run: 01KM392JR46K2XB8VGJ3WKH4E2
Fabro-Completed: 2

⚒️ Generated with [Fabro](https://fabro.sh)
2026-03-19 14:47:59 +00:00
Bryan Helmkamp
d81fd8d656 Remove OpenSSL runtime dependency from CLI binary (#94)
## 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>
2026-03-19 08:48:40 -04:00
Bryan Helmkamp
e477c19646 Simplify recent CLI additions: dedup, fix TOCTOU, remove wrappers
- 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>
2026-03-18 18:09:08 -04:00
Bryan Helmkamp
8584f59e25 Update changelog and docs for secret management and repo commands
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:08:37 -04:00
Bryan Helmkamp
88b2bf31a6 Add fabro secret CLI subcommands for managing ~/.fabro/.env
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>
2026-03-18 18:02:38 -04:00
Bryan Helmkamp
bd8ebcf521 Add hidden --skill flag to fabro repo init
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>
2026-03-18 17:54:30 -04:00
Bryan Helmkamp
fe4896378d Add fabro repo deinit command to reverse project initialization
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>
2026-03-18 17:51:45 -04:00
Bryan Helmkamp
db89fe9e7d Use bunx for vercel deploy command in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:49:45 -04:00
Bryan Helmkamp
0ba54ffdea Remove unreachable wildcard arms in sandbox provider matches
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>
2026-03-18 17:43:39 -04:00
Bryan Helmkamp
b9f5b9a83b Add Triggers and Scheduled Workflows to roadmap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:43:05 -04:00
Bryan Helmkamp
0c79c368b2 Rename init to repo init with backwards-compat shim
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>
2026-03-18 17:41:49 -04:00
Bryan Helmkamp
285df54d0d Add issue-based contribution policy to README and CONTRIBUTING
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:41:34 -04:00
Bryan Helmkamp
e5ec057b79 Expand scenario tests to cover more CLI subcommands
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>
2026-03-18 16:05:13 -04:00
Bryan Helmkamp
d5277b9c85 Promote CLI commands to changelog heroes and improve framing
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>
2026-03-18 11:01:13 -04:00
Bryan Helmkamp
1d9f491314 Reframe Mar 17 changelog hero around OpenAI OAuth user value
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 09:59:26 -04:00
Bryan Helmkamp
f5e385c9a1 Update changelog and docs for Mar 16-17 changes
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>
2026-03-18 09:51:42 -04:00
Bryan Helmkamp
8ef79bb445 Deduplicate CLI command helpers into shared module
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>
2026-03-18 09:45:25 -04:00
Bryan Helmkamp
706f563847 Align hero CTA with bottom CTA on marketing homepage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 09:32:00 -04:00
Bryan Helmkamp
69a41c7029 Move workflow CLI ownership into fabro-cli 2026-03-18 09:31:11 -04:00
Bryan Helmkamp
d0b2ff2efc Fix docs footer social links
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:03:50 -04:00
Bryan Helmkamp
bea165192a Update model list snapshots for gpt-5.4-mini
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 15:50:10 -04:00
Bryan Helmkamp
ea789ba994 Deduplicate config loading and run-config merging
- Extract generic load_config_file<T>(path, filename) helper, reducing
  load_cli_config and load_server_config to one-liners.

- Rewrite WorkflowRunConfig::apply_defaults to delegate to
  RunDefaults::merge_overlay, eliminating ~90 lines of duplicate
  deep-merge logic. Both methods now share the same code path.

- Fix bug where RunDefaults::merge_overlay silently dropped the ssh
  sandbox config from overlays (the ssh field was never merged).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:33:04 -04:00
Bryan Helmkamp
6ebbad800d Move config type tests into fabro-config
Tests for types defined in fabro-config (HookEvent, HookDefinition,
HookConfig, McpServerConfig, McpTransport, etc.) now live alongside
their definitions rather than in the downstream re-exporting crates.

Tests for types that remain in fabro-hooks (HookContext, HookDecision,
PromptHookResponse) stay in fabro-hooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:21:16 -04:00
Bryan Helmkamp
98e8a9b7f6 Fix fabro-config dependency inversion
Move config/data types from upstream crates (fabro-agent, fabro-mcp,
fabro-workflows, fabro-hooks) down into fabro-config so it becomes a
leaf crate depending only on fabro-util + external crates.

New modules in fabro-config:
- mcp.rs: McpServerConfig, McpTransport, McpServerEntry
- sandbox.rs: DaytonaConfig, ExeConfig, SshConfig, SandboxConfig, etc.
- hook.rs: HookEvent, HookDefinition, HookConfig, HookType, TlsMode
- run.rs: RunDefaults, WorkflowRunConfig, LlmConfig, SetupConfig, etc.
- project.rs: ProjectConfig, workflow discovery/resolution functions

Source crates re-export from fabro-config for backward compatibility.
Also removes stale strsim dep and moves toml to dev-deps in
fabro-workflows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:17:55 -04:00
Bryan Helmkamp
9e079ed2c5 Clean up fabro-hooks extraction
Extract set_hook_node() helper to deduplicate the 5 call sites that
populate node fields on HookContext. The helper lives in fabro-workflows
(which has the fabro-graphviz dependency) rather than fabro-hooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 14:12:26 -04:00
Bryan Helmkamp
6c3607440f Extract fabro-hooks crate from fabro-workflows
Move the self-contained hooks module (~2900 LOC) into its own crate to
clarify the dependency graph and make the hook system independently
reusable. The set_node convenience method is inlined at its two call
sites in parallel.rs since it depends on fabro-graphviz types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 14:08:02 -04:00
Bryan Helmkamp
1430fb1f8e Clean up fabro-interview extraction
- Use already-imported names in run_from_branch instead of fully-qualified
  fabro_interview::* paths
- Use std::io::Error::other() for serde error conversion (matches codebase
  convention, more concise)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:56:51 -04:00
Bryan Helmkamp
075812478b Extract fabro-interview crate from fabro-workflows
The interviewer module (trait + 7 implementations for human-in-the-loop
interactions) had zero dependencies on fabro-workflows internals, making
it a clean extraction. Consumers (fabro-api, fabro-slack) now depend on
fabro-interview directly instead of reaching through fabro-workflows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:53:36 -04:00
Bryan Helmkamp
4daa906ee9 Add GPT-5.4 Mini to model catalog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:53:08 -04:00
Bryan Helmkamp
3d981ea25d Clean up fabro-validate extraction
- Add From<ValidationError> for FabroError to eliminate duplicated
  .map_err(|e| FabroError::Validation(e.0)) at call sites
- Use top-level `use` imports for stylesheet types in rules.rs
  instead of verbose fully-qualified paths
- Remove duplicate parse_condition tests from fabro-workflows
  (already covered by fabro-graphviz)
- Use //! inner doc comments in context/keys.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:42:54 -04:00
Bryan Helmkamp
addbf0563e Extract fabro-validate crate from fabro-workflows
Move validation/lint framework and all 24 rules into a dedicated
fabro-validate crate. As prerequisites, move Fidelity, stylesheet
parser/types, and condition parser into fabro-graphviz (where the
Graph types they operate on already live) so fabro-validate can
depend on fabro-graphviz directly without a circular dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:33:34 -04:00
Bryan Helmkamp
25d7c036b3 Extract fabro-daytona crate from fabro-workflows
Move DaytonaSandbox into its own crate, matching the pattern used by
fabro-exe, fabro-sprites, and fabro-ssh. The new crate internalizes
daytona_sdk::Client creation so callers never touch daytona-sdk directly:

- new() is now async and creates the client internally
- reconnect(name) replaces from_existing() + manual client/get boilerplate
- daytona-sdk and daytona-api-client removed as fabro-workflows dependencies

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:10:09 -04:00
Bryan Helmkamp
a8b8108087 Extract fabro-retro crate from fabro-workflows
Move retro.rs and retro_agent.rs into a new fabro-retro crate to reduce
the size of fabro-workflows and clarify domain boundaries.

Key design changes:
- Add CompletedStage struct as a flat DTO that decouples retro derivation
  from Checkpoint/Outcome types in the workflow engine
- derive_retro now takes Vec<CompletedStage> (owned) instead of &Checkpoint
- run_retro_agent takes an event_callback closure instead of EventEmitter,
  pushing event filtering to the caller
- Shared build_completed_stages() in fabro-workflows::lib converts
  Checkpoint → Vec<CompletedStage> for both run.rs and server.rs callers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:48:40 -04:00
Bryan Helmkamp
e8b3fe96a0 Normalize fabro_graphviz imports to use shorter re-exported paths
Replace fabro_graphviz::graph::types:: with fabro_graphviz::graph::
everywhere, since graph/mod.rs re-exports types::*. Also simplify
the From<GraphvizError> impl.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:26:23 -04:00
Bryan Helmkamp
b2bfbd341d Extract fabro-graphviz crate from fabro-workflows
Move the self-contained graph/ and parser/ modules into a new
fabro-graphviz crate so the Graphviz DOT parser can be used without
pulling in the full workflow engine.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:20:55 -04:00
Bryan Helmkamp
945d51ffd4 Switch release script to date-based versioning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:35:48 -04:00
Bryan Helmkamp
98f2097263 Bump version to 0.174.0 2026-03-17 10:35:38 -04:00
Bryan Helmkamp
aa7552c18a Add SVG workflow diagram for REPL Handoff example
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:32:48 -04:00
Bryan Helmkamp
bd315233d1 Remove debug markers from dot-highlight script
Verified script executes and highlights code blocks in production.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:23:48 -04:00
Bryan Helmkamp
d59bbde786 Add debug marker and delay to dot-highlight script
Add data attribute to confirm script execution, and delay
initialization to avoid React hydration clobbering changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:16:00 -04:00
Bryan Helmkamp
cd50af6d95 Add client-side DOT syntax highlighting for docs
Mintlify's custom TextMate grammar support doesn't work in production
builds (see mintlify/discussions#3401). Work around this with a lightweight
JS script that applies regex-based highlighting to code blocks containing
digraph definitions, matching Shiki's inline style format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:07:25 -04:00
Bryan Helmkamp
6717ceb006 Add fabro language for syntax highlighting in docs
Register a separate Shiki grammar so ```fabro code blocks get
DOT syntax highlighting alongside the existing ```dot blocks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:43:14 -04:00
Bryan Helmkamp
87484a989f Update README: discussions for feature requests, add fabro install/init to Quick Start
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:01:18 -04:00
Bryan Helmkamp
13befea8fa Check in .vercel project link for marketing site
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:39:01 -04:00
Bryan Helmkamp
134c7f5043 Bump version to 0.8.0 2026-03-17 08:33:12 -04:00
Bryan Helmkamp
7f7328b311 Update marketing roadmap: add new items, rename retros, remove Slack
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:31:05 -04:00
Bryan Helmkamp
9b6650ee48 Remove empty stub doc pages and fix broken links
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:25:05 -04:00
Bryan Helmkamp
1570466ef3 Use fabro.sh/discord redirect instead of direct Discord invite URL
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:22:12 -04:00
Bryan Helmkamp
d339aeae58 Add fabro discord subcommand to open Discord invite in browser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:18:02 -04:00
Bryan Helmkamp
aca96d14b0 Add fabro docs subcommand to open docs website in browser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:16:46 -04:00