Commit graph

353 commits

Author SHA1 Message Date
Bryan Helmkamp
dede93dceb
Merge remote-tracking branch 'origin/main' 2026-04-29 11:51:47 -04:00
Bryan Helmkamp
85c763d511
fix(cli): persist auth login target
When auth login succeeds and no CLI target is configured, write the resolved server target to settings.toml so later CLI commands can reuse it.
2026-04-29 08:02:50 -04:00
fabro-releases[bot]
46bbac92eb Bump version to 0.218.0-nightly.0 2026-04-29 09:55:40 +00:00
Bryan Helmkamp
8c3d3c340a
Merge remote-tracking branch 'origin/main' 2026-04-28 12:31:09 -07:00
Bryan Helmkamp
642e312cca
refactor: unify duplicate API types via with_replacement
Eliminate four parallel-type duplications between fabro-api generated
DTOs and fabro-types canonical types. The wire shape is owned by
OpenAPI; canonical types are reused via fabro-api/build.rs
with_replacement so the adapter functions and silent unwrap_or_default
defaults disappear.

- SecretType moves to fabro-types (was fabro-vault); deletes
  secret_type_from_api adapter.
- DiffLineStats renamed to DiffStats, moved to fabro-types, switched
  u64 -> i64 to match the OpenAPI integer; deletes line_stats_to_api.
- ManifestPreRunPushOutcome rewritten as a oneOf+discriminator
  PreRunPushOutcome over five variant schemas, deleting both
  pre_run_push_outcome_from_manifest and build_manifest_push_outcome.
- ManifestGit and PreRunGitContext unify as GitContext: dirty:
  DirtyStatus replaces clean: bool (preserving the Unknown state
  previously truncated on the wire), sha becomes Option<String>, and
  origin_url/branch fold into the unified context. RunSpec and
  RunCreatedProps flatten three fields (repo_origin_url, base_branch,
  pre_run_git) into a single git: Option<GitContext>.

Each replacement gets a fabro-api parity test (TypeId equality plus
JSON roundtrip) modeled on run_summary_round_trip.rs. TS client
regenerated.

Greenfield app, no production deployments — wire contract changed
directly without backwards-compat shims.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:29:37 -07:00
Bryan Helmkamp
be9d9284be
feat(dev): add bench-tests command for capturing per-test timing CSV
Runs the workspace test suite N times via `cargo nextest run --no-fail-fast`
and appends one row per testcase to a CSV (git_sha, run_index, started_at,
binary, package, classname, test_name, status, duration_ms). Group ≈ package
is derived from the JUnit testsuite name.

The lenient `[profile.bench]` (with junit.path) is synthesized at runtime to
target/bench-tests/nextest-tool.toml and passed via `--tool-config-file`, so
nothing needs to be added to .config/nextest.toml.

Intended use: collect samples on the current checkout, switch SHAs, collect
again, then diff/aggregate externally to hunt slowdowns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 09:18:00 -07:00
fabro-releases[bot]
2880133af2 Bump version to 0.217.0-nightly.0 2026-04-28 10:00:53 +00:00
Bryan Helmkamp
69d4ac5b9b
Merge remote-tracking branch 'origin/main'
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Build (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
2026-04-27 15:27:05 -07:00
Bryan Helmkamp
2460ffc37a
feat(install): add sandbox provider step to web install wizard
Operators choose Docker (default, zero-config) or Daytona (validated
via Daytona SDK) during browser install. Selection is captured in
settings.toml under [run.sandbox] -- explicitly even for Docker, so the
choice is locked in. Daytona keys land in the vault as DAYTONA_API_KEY
(Environment secret). Step always runs after object_store and before
the LLM step.

Server adds POST /install/sandbox/test (validates Daytona key via
client.list) and PUT /install/sandbox; both reuse the install-token
auth and InstallSecret redaction patterns established by object-store.
A resolve_install_sandbox_state helper preserves a saved Daytona key
when the operator revisits the step without re-entering it. The
in-memory api_key is dropped from PendingInstall after finish, matching
the manual_credentials cleanup for S3 access keys.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:59:17 -07:00
fabro-releases[bot]
5563369492 Bump version to 0.216.0-nightly.1 2026-04-27 18:50:35 +00:00
Bryan Helmkamp
bac0d4a601
Merge remote-tracking branch 'origin/main' 2026-04-27 10:41:52 -07:00
Bryan Helmkamp
50847ebc6f
fix(sandbox): preserve error chains
Introduce typed sandbox errors and carry source causes through workflow events, persisted failure summaries, and API/CLI string boundaries so Docker client failures keep the actionable underlying cause.
2026-04-27 10:41:39 -07:00
fabro-releases[bot]
b7c3ce89ff Bump version to 0.216.0-nightly.0 2026-04-27 16:23:30 +00:00
Bryan Helmkamp
3a8e1a0517
refactor(sandbox): make Docker clone-based by default
Switch Docker sandboxes from host bind mounts to per-run clone-based containers with structured run metadata, reconnect validation, archive-based file transfer, and Docker resource defaults.

Extend run config/API surfaces so Docker image and clone settings flow through manifests, server preflight, workflow startup, and generated clients.

Update docs and tests for the new default Docker provider path.
2026-04-26 18:21:02 -04:00
Bryan Helmkamp
d07596ca80
feat(server): support stdout log destination
Add configurable server log destinations with an environment override so containers can stream foreground server logs to stdout while local installs keep file logging by default. Validate configured log filters at load time and reject stdout logging for daemon mode.
2026-04-26 14:52:15 -04:00
fabro-releases[bot]
98dd4595ed Bump version to 0.215.0-nightly.0 2026-04-26 09:33:44 +00:00
fabro-releases[bot]
9951f6dcfd Bump version to 0.214.0-nightly.2 2026-04-25 23:25:21 +00:00
Bryan Helmkamp
c28b040c6f
fix(install): reject wildcard public URLs
Normalize bind-address wildcards before presenting install URLs, reject wildcard public origins at CLI and server install boundaries, and surface recovery guidance in the installer and doctor output.
2026-04-25 18:58:00 -04:00
Bryan Helmkamp
3d92a1a46b
Merge pull request #172 from fabro-sh/dependabot-fix/rustls-webpki-0.103.13
chore(deps): bump rustls-webpki to 0.103.13 (GHSA-82j2-j2ch-gfr8)
2026-04-25 10:24:14 -04:00
fabro-releases[bot]
859d7a3aa7 Bump version to 0.214.0-nightly.1 2026-04-25 14:07:53 +00:00
Bryan Helmkamp
fa7a496dcf
chore(deps): bump rustls-webpki to 0.103.13
Patches GHSA-82j2-j2ch-gfr8: a malformed CRL BIT STRING can panic
bit_string_flags() in rustls-webpki via BorrowedCertRevocationList::from_der().
Reachable when applications opt into CRL checking and load CRL bytes from an
attacker-influenced source.

Resolves Dependabot alert #25.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:01:40 -04:00
fabro-releases[bot]
7ea8698dbf Bump version to 0.214.0-nightly.0 2026-04-25 09:30:44 +00:00
Bryan Helmkamp
11be286fa1
refactor(dev): simplify generated docs tooling
Share the real CLI parser with reference generation, reuse option metadata flattening, and centralize dev command execution helpers.
2026-04-24 18:41:00 -04:00
Bryan Helmkamp
5e28ec0f82
Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.github/workflows/nightly.yml
#	bin/dev/release.sh
2026-04-24 17:04:55 -04:00
Bryan Helmkamp
12ea5341bb
feat(dev): generate options reference
Add a settings reference generator backed by OptionsMetadata on the sparse config layer structs. The generated user-configuration page is fenced and checked in CI alongside the CLI reference.
2026-04-24 16:49:16 -04:00
fabro-releases[bot]
dfb1f308e8 Bump version to 0.213.0-nightly.2 2026-04-24 20:38:42 +00:00
Bryan Helmkamp
0f3c28db87
feat(dev): generate CLI reference
Add a cargo dev generator for the CLI reference and gate the generated docs in CI. The generator reads the fabro clap command tree through a narrow public reference surface so CLI docs drift is caught without exposing runtime command internals.
2026-04-24 16:35:06 -04:00
Bryan Helmkamp
fc7382ce79
feat(options): add options metadata derive 2026-04-24 16:13:32 -04:00
Bryan Helmkamp
a03c689a44
feat(dev): port release automation 2026-04-24 16:00:25 -04:00
Bryan Helmkamp
99257846d1
feat(dev): enforce CLI boundary with cargo dev 2026-04-24 15:50:01 -04:00
Bryan Helmkamp
99d2adb216
feat(dev): add fabro-dev scaffold
Introduce the internal fabro-dev CLI shell and cargo dev alias so follow-up units can port development scripts behind typed clap subcommands.
2026-04-24 15:43:30 -04:00
Bryan Helmkamp
7e64bf8b69
feat(cli): render fatal errors with miette
Wrap root CLI errors at the main boundary so fatal diagnostics use miette's styled renderer while preserving existing telemetry, exit codes, and auth help hints.
2026-04-24 15:35:57 -04:00
fabro-releases[bot]
6dfb3e1a50 Bump version to 0.213.0-nightly.1 2026-04-24 19:18:35 +00:00
Bryan Helmkamp
56de394e01
refactor(redact): extract redaction into dedicated crate
Move secret redaction and DisplaySafeUrl into fabro-redact so credential handling has a narrow ownership boundary. Update direct consumers and docs to depend on fabro_redact instead of fabro_util::redact.
2026-04-24 15:02:23 -04:00
Bryan Helmkamp
828a8c4429
refactor(redact): make credentialed URL logging safe
Add DisplaySafeUrl under fabro-util::redact so URL Display and Debug output redact credentials by default. Migrate token-bearing GitHub, OAuth, server, LLM, sandbox, and workflow paths to use the wrapper at logging/error boundaries while keeping raw URLs explicit for wire and shell transit.
2026-04-24 13:39:34 -04:00
Bryan Helmkamp
80de5ca616 refactor(static): centralize env var names
Add fabro-static::EnvVars as the shared registry for fixed environment variable names and migrate env reads, clap env bindings, and subprocess/test allowlists to use it.

Add clippy bans for raw std::env lookup APIs so future dynamic env facades must be documented explicitly.
2026-04-24 12:29:51 -04:00
Bryan Helmkamp
baa20ca375
Merge remote-tracking branch 'origin/main' 2026-04-24 11:23:34 -04:00
Bryan Helmkamp
0a297b26bf
refactor(pr): simplify server-side PR plumbing
Reuse the existing merge strategy type across CLI/API/GitHub paths, consolidate repeated PR command setup, and serialize server-side PR creation per run to avoid duplicate external work.
2026-04-24 11:17:01 -04:00
Bryan Helmkamp
d6eb18f037
Merge remote-tracking branch 'origin/main' into fix/auto-pr-resolved-client 2026-04-24 09:33:28 -04:00
Bryan Helmkamp
f19c0e2e91
test(fabro-llm): remove trybuild compile-fail test 2026-04-24 09:30:55 -04:00
Bryan Helmkamp
d822af3d32
Merge remote-tracking branch 'origin/main' 2026-04-24 09:29:21 -04:00
fabro-releases[bot]
825dff6142 Bump version to 0.213.0-nightly.0 2026-04-24 09:45:14 +00:00
Bryan Helmkamp
4e9dd6fb52
Merge origin/main (preserving RunServices architecture)
Reconciles 61 origin commits (settings/config architectural reshape:
sparse layers → dense snapshots via builders, WorkflowSettings rename,
RunLayer/CliLayer moves, workflow builders, drop of public load wrappers)
with our LLM credential + RunServices refactor.

Our architecture preserved where it conflicted with origin's:

- RunServices / EngineServices stay (services.rs does not exist on
  origin, which inlined the fields onto Initialized). Origin's new
  Initialized fields (inputs, run_store, emitter, sandbox, registry,
  env, dry_run, llm_client, provider) are absorbed through RunServices
  and EngineServices instead of being inlined.
- llm_source: Arc<dyn CredentialSource> stays on AppState and
  RunServices. Origin had a parallel ProviderCredentials struct in
  fabro-server; our CredentialSource trait is more general and
  complies with docs-internal/llm-client-resolution.md. Point-of-use
  Client::from_source(...) rebuild preserves OAuth refresh.
- CommandContext.llm_source() uses self.storage_dir (origin's direct
  field) instead of self.machine_settings (our side's field, removed
  by origin).
- standalone_llm_source in fabro-agent drops the dead Result wrap and
  uses fabro_config::user::default_storage_dir (origin's entrypoint)
  instead of the removed load_settings_user/resolve_storage_root.

Absorbed from origin wholesale:

- SettingsLayer → WorkflowSettings rename everywhere
- Dense run settings: RunOptions.settings is WorkflowSettings, inputs
  read via settings.run.inputs directly (not Option<RunLayer>)
- AppState.manifest_run_defaults / manifest_run_settings
- fabro_config re-exports of CliLayer/RunLayer/CliOutputLayer/etc.
- Lifecycle terminal-event changes, finalize dedup, list_events
  consolidation — already brought in on the previous merge, kept

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:10:01 -04:00
Bryan Helmkamp
600720423c
Merge remote-tracking branch 'origin/main'
Merge origin's fabro-config types boundary refactor (dense settings
migration: WorkflowSettings/UserSettings/ServerSettings moved to
fabro-types; SettingsLayer made pub(crate) inside fabro-config) into
local PR-refactor branch.

Conflict resolution intent:

- lib/crates/fabro-cli/src/commands/pr/{create,mod}.rs — kept HEAD's
  server-side PR command implementations; origin still carried the
  pre-refactor client-side helpers (build_github_credentials,
  load_pr_record, branch_exists pre-check) that local commits had
  already migrated to the server.
- lib/crates/fabro-cli/src/user_config.rs — took origin's resolution
  (load_resolved_settings_from_toml + storage_dir_from_document tests),
  which implements the same dead-storage_dir-wrapper cleanup local had
  done via local_server::storage_dir.
- lib/crates/fabro-server/src/server.rs — kept HEAD's PullRequestRecord
  import alongside origin's added ServerSettings; rewrote test helpers
  github_token_settings + create_github_token_app_state to use origin's
  ServerSettingsBuilder + AppStateConfig dense-settings shape (replaces
  HEAD's parse_settings_layer + Arc<RwLock<SettingsLayer>>); switched
  RunSpec.settings fixture from SettingsLayer::default() to
  WorkflowSettings::default() per origin's RunSpec retype.
- Suppressed dead_code on CommandContext::storage_dir() and
  ::server_settings() (added by origin for use by client-side PR
  commands that no longer exist after local's server-side migration);
  gated load_resolved_settings_from_toml on cfg(test).

Verified post-merge: workspace fmt clean, clippy --all-targets
-D warnings clean, cargo nextest run --workspace 4587 passed,
182 skipped.
2026-04-24 00:01:09 -04:00
Bryan Helmkamp
7d63e2c298
refactor(github): replace stringly-typed PR errors with typed enum
Introduce PullRequestApiError with a structured NotFound variant and an
Other(String) catch-all for non-classified failures. Update
get_pull_request, merge_pull_request, and close_pull_request to return
the new type so callers can branch on shape rather than substring.

Server PR handlers now match Err(PullRequestApiError::NotFound { .. })
to map a missing GitHub PR to the existing github_pull_request_not_found
ApiError, removing three err.contains("not found") substring checks.

The Display impl for NotFound preserves the prior message format
("Pull request #N not found in owner/repo") so logging and the
catch-all BAD_GATEWAY response keep their human-readable text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 22:31:23 -04:00
Bryan Helmkamp
b9911fc6e7
Merge origin/main
Reconciles origin's "emit terminal event from FINALIZE" refactor
(41c47dbe1, e8a89ac39, 904c8842f) with the local RunServices refactor.

finalize() now performs origin's single list_events walk for stage
durations + artifact count, origin's compute_final_patch, deduped
stages/billing via billing_from_checkpoint, and origin's terminal event
emission — but reads run_store/sandbox/emitter from the shared
RunServices instead of individual Retroed fields. services.emitter.notice
replaces origin's local emit_run_notice helper.

test_support's execute_and_emit_terminal (added by origin) now accesses
run_store/emitter via executed.engine.run.* since Executed bundles
EngineServices. execute/tests.rs drops the terminal-event status
assertion origin deleted — status is no longer set at EXECUTE end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:46:24 -04:00
Bryan Helmkamp
f46803b367
refactor(api): unify PR detail types via with_replacement
Move PullRequestDetail, PullRequestGithubDetail, PullRequestUser,
PullRequestRef, and MergeMethod into fabro-types. Register them as
fabro-api with_replacement targets so the OpenAPI client and the server
share one canonical type per concept.

PullRequestDetail composes a stored PullRequestRecord with a flattened
PullRequestGithubDetail mirroring GitHub's REST payload, removing the
hand-rolled pull_request_detail_json builder in the server. Change the
PullRequestRef wire field from `ref_name` to `ref` so the same Rust
type round-trips through both GitHub and our API without aliases.

The server now uses fabro_api::types::{Create,Merge,Close}* directly,
deleting the hand-defined request/response shadows and the
`body.method.parse::<...>()` call (the typed MergeMethod enum drives
deserialization). Drops fabro-cli's `i64::try_from(record.number)`
panic path and the AutoMergeMethod enum (replaced by MergeMethod).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:41:11 -04:00
Bryan Helmkamp
099dd881a8
merge origin/main into local main
Integrates origin's worker-JWT-auth work (commits 8a6f83bb0..c847a828d)
with the config-boundary refactor that landed locally. Conflicts
resolved:

- commands/dump.rs: take origin's removal of the 500-line in-process
  test block (replaced by real-server integration coverage).
- commands/run/runner.rs: keep local's dense WorkflowSettings import,
  drop dead SettingsLayer import, pull in origin's ActorRef.
- manifest_builder.rs: adopt origin's lifted working_directory
  resolution (fixes #159 - manifest git detection in nested repos),
  but via local's resolve_working_directory_from_run API that takes
  the dense RunNamespace. Update the regression test's
  ManifestBuildInput literal to local's run_overrides/cli_overrides
  field shape.
- server.rs: keep origin's jwt_auth_mode/jwt_auth_state/
  test_user_subject/issue_test_user_jwt/issue_test_worker_token/
  create_run_with_bearer/bearer_request test helpers, adapt
  jwt_auth_state to local's create_test_app_state_with_session_key
  signature (ServerSettings + RunLayer), keep local's dense
  canonical_origin_settings that returns ServerSettings via
  server_settings_from_toml. Rewrite
  build_app_state_requires_session_secret_for_worker_tokens against
  the dense AppStateConfig (resolved_settings +
  resolved_runtime_settings_for_tests).

Post-merge verification: workspace builds clean, cargo +nightly
fmt --check all clean, cargo +nightly clippy --workspace
--all-targets -- -D warnings clean, cargo nextest run --workspace
4560 tests passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:13:28 -04:00
Bryan Helmkamp
d380c8f496
drop vestigial fabro-macros dep and DurationLayer aliases
After Unit 3.1 of the config boundary refactor, fabro-types no longer has
any #[derive(Combine)] sites — the fabro-macros dep is unused. Likewise
`Duration as DurationLayer` was an artifact from when layer and vocabulary
types lived side-by-side; the resolved Duration type has no Layer form now,
so the alias was misleading.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 20:06:19 -04:00
Bryan Helmkamp
ba2eea3148
fix(llm): close remaining source resolution gaps 2026-04-23 19:40:57 -04:00