Commit graph

169 commits

Author SHA1 Message Date
Bryan Helmkamp
4c4471e630 Refactor config resolution around ConfigLayer 2026-03-29 13:46:43 -04:00
Bryan Helmkamp
5d9d4f8b35 Add publish = false to all crates to prevent accidental crates.io publish
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:08:19 -04:00
Bryan Helmkamp
1c0dcf58b1 Rename fabro-api crate to fabro-server
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:04:06 -04:00
Bryan Helmkamp
01dd50752e Harden store dump path handling 2026-03-29 12:42:18 -04:00
Bryan Helmkamp
271e26f2c0 Add store dump CLI export command 2026-03-29 09:48:05 -04:00
Bryan Helmkamp
5d53ad6dbd Make metadata rebuild recovery robust 2026-03-29 09:35:13 -04:00
Bryan Helmkamp
87ab03898d Configure SlateDB flush_interval to 5ms for local storage
SlateDB defaults to 100ms flush_interval (tuned for S3 cost). For
local/in-memory object stores this adds unnecessary write latency.
Pass flush_interval through SlateStore::new() so callers control
the setting, and switch open_db() to use Db::builder().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:16:36 -04:00
Bryan Helmkamp
a6da73ecd1 Rebuild metadata branches from the run store 2026-03-29 09:10:50 -04:00
Bryan Helmkamp
9c66dcb6f0 Fix remaining CLI store migration gaps 2026-03-28 23:23:38 -04:00
Bryan Helmkamp
f6f5c25498 Wire workflows and CLI to fabro-store 2026-03-28 22:57:49 -04:00
Bryan Helmkamp
0db3856445 Consolidate integration tests under tests/it 2026-03-28 18:39:52 -04:00
Bryan Helmkamp
007fb54286 Fix unreachable_pub and unsafe_code warnings in test code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:22:27 -04:00
Bryan Helmkamp
533ebc3f87 Fix clippy type_complexity lints with OnNodeCallback type alias
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:11:40 -04:00
Bryan Helmkamp
71573ad9ec Add Printer enum and warn_user! macros for unified verbosity control
Introduces a uv-style Printer enum (Silent/Quiet/Default/Verbose) and
warn_user!/warn_user_once! macros in fabro-util, wires --quiet/--verbose
global flags into the CLI, and converts the `fabro init` deprecation
warning as a proof of concept.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:08:57 -04:00
Bryan Helmkamp
20f2a3b8bb Add detached engine process titles 2026-03-28 16:44:56 -04:00
Bryan Helmkamp
8b3ca5ef01 Centralize sandbox variant handling 2026-03-28 16:34:27 -04:00
Bryan Helmkamp
4cb56de9ec Remove legacy runtime IPC fallbacks 2026-03-28 15:26:32 -04:00
Bryan Helmkamp
4d22c7e549 Fix process_alive panic on u32 PID values exceeding i32::MAX
The cast_possible_wrap lint fix changed `pid as i32` to
`i32::try_from(pid).unwrap()`, but the unwrap panics when the PID
exceeds i32::MAX (e.g. u32::MAX used in tests). Return false instead
since such values are not valid Unix PIDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:17:26 -04:00
Bryan Helmkamp
2eb39d368c Rename *config* variables/params that hold *Settings types
Local variables and function parameters named with "config" but holding
*Settings types (FabroSettings, TlsSettings, ApiSettings, LlmSettings)
are renamed to use "settings" for consistency with the type system.
Module paths (cli_config::) and struct fields are unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:15:15 -04:00
Bryan Helmkamp
52d0478a47 Enable 7 additional pedantic clippy lints
Enables char_lit_as_u8, collapsible_else_if, collapsible_if,
map_unwrap_or, match_same_arms, used_underscore_binding, and
if_not_else. Fixes all violations: combines duplicate match arms,
renames underscore-prefixed bindings that are actually used, rewrites
if-not-else patterns, and applies map_or where appropriate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:57:48 -04:00
Bryan Helmkamp
ef70bc1596 Enable cast_possible_wrap clippy lint and fix violations
Replaces 14 unsigned-to-signed `as` casts with try_from().unwrap()
to panic on overflow instead of silently wrapping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:36:12 -04:00
Bryan Helmkamp
4901e0ec8f Enable additional pedantic clippy lints and fix violations
Enables cast_possible_truncation, cast_sign_loss, items_after_statements,
needless_pass_by_value, return_self_not_must_use, uninlined_format_args,
unreadable_literal, and unnested_or_patterns. Keeps doc_markdown disabled.

Replaces unsafe `as` casts with try_from().unwrap() throughout, using
#[allow] only for f64-to-integer casts which have no try_from equivalent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:31:11 -04:00
Bryan Helmkamp
13eca22f5a Enable clippy pedantic lints and restriction lints workspace-wide
Adopts uv's clippy lint configuration: pedantic group at warn priority,
with noisy lints allowed, plus restriction lints for print/dbg/exit/use_self.
Fixes all violations across the workspace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:37:57 -04:00
Bryan Helmkamp
bd97e76fe5 Apply rustfmt 2024 style edition across workspace
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 12:56:30 -04:00
Bryan Helmkamp
e6d865e29f Enforce no-inline-qualified-paths via clippy absolute_paths lint
Add clippy.toml with absolute-paths-max-segments = 2 (allowing std/core/alloc)
and enable the absolute_paths = "warn" lint workspace-wide. Fix all ~300
violations across the codebase: replace 3+-segment inline paths with use
statements so call sites read as operations::create() rather than
fabro_workflows::operations::create(). The demo module gets an allow
attribute since it constructs many API types by design.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 12:42:02 -04:00
Bryan Helmkamp
9e5d77bb0b Enforce no-wildcard-imports via clippy workspace lint
Configure clippy `wildcard_imports = "warn"` at the workspace level and
opt all 28 crates in via `[lints] workspace = true`. Fix the three
production glob imports that triggered warnings: fabro-sandbox
read_guard, fabro-cli main, and fabro-api demo module (allowed via
attribute since it constructs many API types by design). Document the
import style convention in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:14:34 -04:00
Bryan Helmkamp
ae37d0316e Clean up runtime path docs and test comment 2026-03-28 01:20:06 -04:00
Bryan Helmkamp
cc381f2bf5 Create RuntimeState for run runtime and cache paths 2026-03-28 01:14:14 -04:00
Bryan Helmkamp
1944af5e54 Create fabro-types and rewire shared types 2026-03-27 21:15:03 -04:00
Bryan Helmkamp
75b5aa35b9 Refactor workflow operations and config resolution 2026-03-27 17:58:05 -04:00
Bryan Helmkamp
f8cc95e97d Tighten workflows request context and launcher cleanup 2026-03-27 17:04:45 -04:00
Bryan Helmkamp
3c3cefb452 Thin CLI run commands and move execution into workflows operations 2026-03-27 16:27:55 -04:00
Bryan Helmkamp
022e0cc54f Clean up resolved settings interfaces 2026-03-27 15:32:06 -04:00
Bryan Helmkamp
6a155cea2d Fold fabro-beastie into fabro-cli as internal sleep_inhibitor module
fabro-beastie had no consumers other than fabro-cli behind a feature
flag. Absorbing it as an internal module reduces workspace crate count
without changing any behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:08:55 -04:00
Bryan Helmkamp
3da5b248e7 Fix workflow-relative config resolution 2026-03-27 15:02:27 -04:00
Bryan Helmkamp
b1642a93ef Refactor config layering into combine plus settings 2026-03-27 14:52:11 -04:00
Bryan Helmkamp
ace13ac848 Rename --run-dir to --storage-dir, unify with data_dir
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>
2026-03-27 13:20:01 -04:00
Bryan Helmkamp
cc52be7016 Add goal_file and labels to FabroConfig
Allow workflow authors to set default goal files and labels in
workflow.toml/fabro.toml, reducing repetitive CLI flags. CLI flags
override config values; labels are deep-merged with CLI winning on
key collision.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 12:42:20 -04:00
Bryan Helmkamp
b1cab600a8 Add fabro config show command 2026-03-27 12:22:32 -04:00
Bryan Helmkamp
f2d90d97ba Merge detached_support.rs into detached.rs
The _support suffix was a naming smell — guards, failure persistence,
and progress helpers are all detached-run infrastructure and belong
alongside the detached run entry point.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:55:39 -04:00
Bryan Helmkamp
8de4aab7b3 Extract --preflight into fabro preflight subcommand
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>
2026-03-27 10:52:41 -04:00
Bryan Helmkamp
76554c3439 Extract runs list and rm commands into dedicated files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:42:39 -04:00
Bryan Helmkamp
4a6aba6e10 Move fabro-cli cp under run commands 2026-03-27 10:32:30 -04:00
Bryan Helmkamp
ad96519858 Refactor fabro-cli run command layout 2026-03-27 10:26:59 -04:00
Bryan Helmkamp
97655f2b2e refactor(fabro-cli): slim down main 2026-03-27 09:57:26 -04:00
Bryan Helmkamp
3792b2ea1f fix: detect early init failures in attach and roll back partial worktree state
Two pre-existing issues fixed:

1. attach: while waiting for progress.jsonl, check for terminal
   status.json and engine child death. A detached run that dies during
   early init (before any event fires) now surfaces the real failure
   instead of timing out after 10s.

2. worktree: when `git worktree add` fails after branch creation,
   roll back the branch with `git branch -D` to avoid leaking partial
   git state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:28:08 -04:00
Bryan Helmkamp
8e51d9c29b Fix verification regressions after runtime init refactor 2026-03-26 22:48:47 -04:00
Bryan Helmkamp
bb791e98b0 Refactor workflow runtime initialization 2026-03-26 22:18:07 -04:00
Bryan Helmkamp
571ac0e1f3 Guard resume against completed runs 2026-03-26 13:53:12 -04:00
Bryan Helmkamp
7c906fc570 fix(resume): reject succeeded runs and check PID before checkpoint parse
1. Succeeded runs now rejected — a completed run keeps checkpoint.json
   around, so resume would happily restart and overwrite start.json and
   conclusion.json. Now checks status.json and bails on Succeeded.

2. PID liveness check moved before checkpoint validation. The engine
   writes checkpoint.json with a plain fs::write, so a concurrent
   resume could see a half-written file and report "corrupt" for a
   run that is simply still alive. Order is now: PID → status →
   checkpoint parse → cleanup → spawn.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:19:41 -04:00