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.
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.
Public functions now take ctx: &GitHubContext<'_> instead of by-value
GitHubContext<'_>. Matches the surrounding &str / &GitHubCredentials
convention. The type stays Copy so internal call sites that pass `ctx`
through still work without explicit reborrows.
Touched: 8 fabro-github functions + matching _with_client variants,
plus call sites in fabro-server, fabro-workflow, fabro-sandbox, and
fabro-github's integration + unit tests. Pure mechanical change.
Verified: workspace fmt clean, clippy --all-targets -D warnings clean,
cargo nextest run --workspace 4581 passed, 182 skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two cleanups:
1. Threaded GitHubContext through the remaining fabro-github functions
that pair credentials with the API base URL: branch_exists,
resolve_clone_credentials, resolve_authenticated_url. Each loses its
trailing `base_url: &str` and replaces `creds: &GitHubCredentials`
with `ctx: GitHubContext<'_>`. is_app_public was skipped — it doesn't
take credentials. Updated production callers in fabro-sandbox/daytona
and fabro-workflow/sandbox_git, plus integration and unit tests.
2. Added OpenPullRequestRequest::from_run_state on the workflow struct.
Bundles the validated unpacked-from-RunState pieces into a draft PR
request with the server's defaults (`draft = true`, `auto_merge =
None`). Server's create_run_pull_request handler now calls the
constructor instead of inlining a 12-field struct literal — the
handler reads as a sequence of validations followed by one named
request build, not as plumbing.
Verified: workspace fmt clean, clippy --all-targets -D warnings clean,
cargo nextest run --workspace 4587 passed, 182 skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three cleanups in one pass:
1. Bundle GitHub creds + base URL into a GitHubContext<'_>:
Defined in fabro-github and threaded through create_pull_request,
enable_auto_merge, get_pull_request, merge_pull_request, and
close_pull_request (plus their _with_client variants). Each function
loses its trailing `base_url: &str` and replaces `creds:
&GitHubCredentials` with `ctx: GitHubContext<'_>`. Bundle propagates
into OpenPullRequestRequest as a single `github` field instead of
the prior split `creds` + `github_api_base_url`.
2. Delete dead CommandContext::storage_dir() and ::server_settings():
Origin added these for client-side PR commands that no longer exist
after the server-side migration. Field `server_settings` removed
from CommandContext (only the deleted method read it). Same field
pruned from ResolvedCommandSettings; one test that verified the
underlying loader behavior was rewired to read LoadedSettings
directly via load_resolved_settings_from_toml.
3. Audit *_error helpers in fabro-server: no remaining single-use
factories. The previous inlining pass left a tidy surface. No diff.
Verified: workspace fmt clean, clippy --all-targets -D warnings clean,
cargo nextest run --workspace 4587 passed, 182 skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Make gh_cli the default GitHub integration path across install, server,
workflow, and CLI surfaces while keeping app-based setup available when
explicitly selected.
Also defer GitHub reqwest client initialization until an HTTP request is
actually needed so missing-token and token-only paths do not trip workspace
test slow timeouts.
No production deployments exist, so there's no need for migration shims.
Remove all six backwards-compat type aliases (AgentError, SdkError,
CoreError, GraphvizError, StoreError, FabroError) and migrate ~880
callsites to use the canonical Error name directly within each crate,
or qualified imports (e.g., `use fabro_llm::Error as LlmError`) for
cross-crate references. Also fix a pre-existing absolute-path clippy
lint in fabro-server error.rs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns naming with the convention that "Config" is for file-level configuration
while "Options" and "Settings" describe runtime parameters. Also applies
rustfmt formatting fixes in web_auth.rs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add the stripped twin-github test server to the workspace, wire it through
fabro-test, and cover fabro-github's real HTTP auth and pull-request flows
with twin-backed integration tests. This also refactors the GitHub helper
entry points to take explicit base URLs so tests and callers share the same
request path.