Run Graphviz through an internal fabro subprocess so renderer failures no
longer share process fate with the server. Keep expected DOT parse failures
on the 400 path via an explicit stdout protocol, and treat child crashes or
protocol violations as 500s.
Three issues prevented the vendored Graphviz C source from working on
Linux:
1. Missing _GNU_SOURCE: with -std=c11, strdup is not declared on
glibc. The compiler assumes it returns int, truncating the 64-bit
return value on aarch64 and causing a SIGSEGV in gvplugin_install.
2. Circular static library dependency: common/emit.c references
gvevent symbols from gvc, but gvc depends on common. The Linux
single-pass linker cannot resolve this cycle. Fixed by merging all
archives into one combined archive using GNU ar's MRI script mode.
3. HAVE_MEMRCHR: with _GNU_SOURCE, glibc declares memrchr, which
conflicts with Graphviz's own static definition. Fixed by defining
HAVE_MEMRCHR on Linux to use the glibc declaration instead.
Also fixes: clippy borrow_as_ptr warning, disallowed_methods in
build.rs, and resolves a pre-existing merge conflict in serve.rs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add prerelease-aware release automation and keep default install and upgrade
paths pinned to the latest stable tag unless an explicit prerelease version is
requested.
Import fabro_util::path and use path::contract_tilde instead of
fully-qualified fabro_util::path::contract_tilde calls.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Doctor warnings for Sandbox and Brave Search now display the exact
command needed to configure the secret. Backtick-delimited text in
remediation strings renders in bold cyan, matching the conventional
CLI command styling used elsewhere.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reorder output so file-write confirmations appear immediately after
secret generation, move "To start Fabro" call-to-action to the end,
collapse duplicate blank line, shorten home-dir paths with ~, and
style the `fabro server start` command with bold cyan.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sandbox shows "recommended, not configured" and Brave Search is
renamed to "Web Search (Brave)" with "optional, not configured".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the server startup path that inferred dry-run from provider
availability and let run.execution.mode inherit normally from
settings.
Model tests now return skip for unconfigured providers at request
time, completions use the real error path, and the CLI/docs/tests are
updated for the removed server --dry-run flag.
Resolve CLI settings once from user config plus process-local overrides
and pass the resolved view through command dispatch and CommandContext.
This keeps config-driven cli.output, cli.updates, and cli.logging
behavior working while preserving commands that only reject explicit
--json overrides. It also removes the implicit auto-approve coupling
from JSON run output.
Update stale fabro-cli secret and workflow list tests to match the
intentional cli_table-rendered output introduced by the list-output
standardization refactor.
Migrate secret list, artifact list, pr list, workflow list, and run
output artifacts from manual format-string tables to cli_table with
bold headers, no borders/separators, and color support — matching the
convention used by model list, runs list, and system df. Also improve
secret list timestamps to show relative ages (e.g. "8h ago").
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Now that Graphviz is vendored, remove the DepSpec/probe_system_deps/
check_system_deps infrastructure from doctor.rs (empty since the
vendoring), the no-op pre-flight check from install.rs, and the
stale hardcoded "dot" check from demo diagnostics.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the Command::new("dot") shell-out in render_dot() with a direct
FFI call to the vendored Graphviz library. Drop PNG support (SVG only).
Remove GraphFormat enum, dot_is_available() helpers, dot-related
diagnostics/doctor checks, and the graphviz install prompt. Update
OpenAPI spec to remove png format and 502 responses. Update CLI help
text, snapshot tests, and documentation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vendor the Graphviz C source code into a new fabro-graphviz-sys crate,
compiled via the cc crate. This eliminates the system dependency on the
dot binary. Pre-generated parser files (grammar.c, scan.c, htmlparse.c)
and table files (colortbl.h, entities.h) are committed alongside the
vendored source. A global Mutex serializes FFI calls to work around
Graphviz's non-thread-safe internal state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The test framework now replaces home directory paths with [HOME_DIR],
but this snapshot still used the old [HOME] placeholder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use short imports instead of absolute paths in test assertions
(fabro-config merge.rs, resolve/mod.rs)
- Remove needless raw string hashes where string body has no quotes
(fabro-config, fabro-workflow, fabro-server)
- Use struct initializer instead of field reassignment on Default
(fabro-types resolved.rs)
- Allow disallowed_methods for Command::new in test that exercises
a real login command (fabro-auth resolve.rs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds explicit instructions for removing unused RenderWorkflowGraphFormat
and GraphFormat imports from server.rs. Clarifies the render_graph_from_manifest
handler changes with specific line references. Details graph.rs changes for
the format field, JSON output, and debug log. Documents the decision to
retain the --format CLI flag with a single svg value for forward compat.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add missing fabro-cli/tests/it/cmd/graph.rs snapshot updates (help text
references "SVG or PNG" and "[possible values: svg, png]")
- Add missing documentation updates (cli.mdx, overview.mdx, troubleshooting.mdx,
changelog) that reference Graphviz as a system dependency
- Add missing args.rs doc comment update ("SVG or PNG" -> "SVG") and Display impl
- Fix unused CStr import in lib.rs code sample
- Remove redundant #![allow(unsafe_code)] -- Cargo.toml override suffices
- Clarify util/ directory contents are speculative, include all initially
- Specify exact imports to remove from render.rs (Command, Write, bail)
- Specify exact doctor.rs tests affected and how to fix spec() helper
- Add graph.rs test snapshot to execution order step 9
- Add documentation update step 12 to execution order
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The plan was missing fabro-cli/tests/it/cmd/json_global.rs which has its
own dot_is_available() guard and clippy attribute that need updating.
Also improved specificity of diagnostics.rs, doctor.rs, and install.rs
change descriptions with exact line numbers and rationale.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add get_graph_returns_svg test to the BAD_GATEWAY guard removal list
(was only mentioning render_graph_from_manifest_returns_svg)
- Fix build.rs defines section: config.h is the single source of truth,
build.rs should use -include config.h instead of duplicating -D flags
- Change render_graph_bytes error from 502 BAD_GATEWAY to 400 BAD_REQUEST
since vendored Graphviz means failures are bad input, not missing service
- Clarify thread safety risk: Graphviz has global state beyond gvContext,
document Mutex fallback strategy if concurrent test reveals races
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detailed implementation plan for replacing the shell-out to `dot` with
a vendored Graphviz C library compiled via the `cc` crate. Covers crate
structure, build.rs approach, pre-generated parser files, FFI wrapper,
caller updates, OpenAPI spec changes, and testing strategy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The fabro-http crate's proxy policy mechanism was not being used in
tests. http_api.rs used #[cfg(test)] to call .no_proxy(), but cfg(test)
only applies within the crate being tested — downstream crates like
fabro-workflow and fabro-cli hit the production path with system proxy
discovery, adding ~900ms per reqwest client per process.
- Set FABRO_HTTP_PROXY_POLICY=disabled in .cargo/config.toml so all
test HTTP clients skip proxy discovery automatically
- Remove dead #[cfg(test)] branch in http_api.rs; it now relies on the
env var like every other fabro-http consumer
- Remove kind(test) from nextest overrides so timeout budgets apply to
unit tests too, not just integration tests
- Remove unused SessionCookie import in web_auth.rs
Eliminates all 11 flaky nextest timeouts under parallel load.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflicts in install.rs: apply gh_cli→token rename from local
to new non-interactive App support and pending_github_settings pattern
from origin/main.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test_secret_store_path() placed secrets directly in /tmp/, meaning all
tests shared /tmp/server.env. Under parallel nextest, tests that needed
SESSION_SECRET would race on this file, and tests that didn't provide one
(auth_login_github_redirects_to_github) would accidentally inherit it
from another test.
Fix: each test now gets its own temp directory via a ULID-keyed subdirectory.
Also fix the github redirect test to explicitly provide its session key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the install-time OpenSSL Ed25519 shell-out with Rust-native key
material generation, drop the stale OpenSSL doctor requirement, and make
GitHub App setup persist valid auth settings and secrets together.
This also fixes the live non-interactive app install path by enabling
GitHub auth, populating allowed usernames, and avoiding half-written
settings when later persistence fails.
The gh_cli strategy was named after its bootstrap mechanism, not what it
actually is at runtime: a stored token. This rename makes the abstraction
honest and decouples runtime behavior from the gh CLI.
- Rename GithubIntegrationStrategy::GhCli to Token (serialized as "token")
- Rename vault/env secret from GITHUB_CLI_TOKEN to GITHUB_TOKEN
- Accept GH_TOKEN as a fallback in both CLI and server
- CLI no longer shells out to `gh auth token` at runtime; reads from
vault/env like the server already did
- fabro install still bootstraps from `gh auth token` as a one-time op
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make fabro install the only supported GitHub App setup path. This removes
HTTP endpoints and browser routes that mutated local server config, rewrites
/setup as an operator instructions page, and aligns the installer manifest
with the live GitHub OAuth callback and setup URLs.
Clippy's absolute_paths lint requires importing the module rather than
using fully-qualified paths in production code.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Conflicts resolved:
- install.rs: kept simplified auth (port 32276, no TLS, no username
in merge_server_settings), adapted to origin's input_source API by
removing username from ServerConfigSelection::Write
- serve.rs: kept ProviderCredentials import from origin, dropped
ClientAuth (removed with mTLS)
- server.rs: kept both imports (ServerAuthMethod + Provider)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>