Commit graph

2184 commits

Author SHA1 Message Date
Bryan Helmkamp
286eee7efa fix(graphviz): isolate rendering in a subprocess
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.
2026-04-14 18:15:23 -04:00
Bryan Helmkamp
d6ed6b3cda fix(ci): fix vendored Graphviz build on Linux
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>
2026-04-14 15:56:07 -04:00
Bryan Helmkamp
bf5da76678 Merge remote-tracking branch 'origin/main' 2026-04-14 15:45:01 -04:00
Bryan Helmkamp
ce26f66846 feat(release): support prerelease builds
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.
2026-04-14 15:43:00 -04:00
Bryan Helmkamp
09dc823e15 Fix clippy absolute_paths warnings in install command
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>
2026-04-14 15:37:06 -04:00
Bryan Helmkamp
be748a880d Show fabro secret set command in doctor remediation output
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>
2026-04-14 15:22:25 -04:00
Bryan Helmkamp
e366e4e761 Remove "Generating secrets and auth material..." status line
Secret generation is fast enough that the progress message is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:16:49 -04:00
Bryan Helmkamp
2ba84be748 Improve install command output ordering and path display
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>
2026-04-14 15:16:21 -04:00
Bryan Helmkamp
4f521b96a6 Run doctor in non-verbose mode after install
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:15:00 -04:00
Bryan Helmkamp
635b11b39a Use ~ for home directory paths in doctor output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:11:58 -04:00
Bryan Helmkamp
bda0d2e1f2 Improve doctor check labels for Sandbox and Brave Search
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>
2026-04-14 15:10:41 -04:00
Bryan Helmkamp
26f5c8f4a0 Format install command imports 2026-04-14 13:12:56 -04:00
Bryan Helmkamp
74dfb9f652 Restructure local object store layout 2026-04-14 13:08:07 -04:00
Bryan Helmkamp
2047e490d8 Merge remote-tracking branch 'origin/main' 2026-04-14 12:30:40 -04:00
Bryan Helmkamp
05c7fedd31 refactor(server): remove implicit dry-run fallback
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.
2026-04-14 12:28:55 -04:00
Bryan Helmkamp
99ce9a66c4 refactor(cli): route global args through settings layer
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.
2026-04-14 12:27:59 -04:00
Bryan Helmkamp
e2897fc910 refactor(store): rename SlateDB prefix from "db" to "slatedb"
Makes the on-disk storage subdirectory self-descriptive.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 11:54:25 -04:00
Bryan Helmkamp
c7461c31dc fix(doctor): omit absent legacy env check 2026-04-14 11:54:25 -04:00
Bryan Helmkamp
e199dea33a test(cli): refresh list output expectations
Update stale fabro-cli secret and workflow list tests to match the
intentional cli_table-rendered output introduced by the list-output
standardization refactor.
2026-04-14 11:30:34 -04:00
Bryan Helmkamp
b486d3125e Merge remote-tracking branch 'origin/main' 2026-04-14 08:12:06 -04:00
Bryan Helmkamp
5a7a42ede5 refactor(cli): standardize list command output with cli_table
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>
2026-04-14 08:11:22 -04:00
Bryan Helmkamp
5acfa46ddd fix(lint): use if-let instead of single-arm match in server start
Fixes clippy::single_match_else warning that was blocking CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:54:21 -04:00
Bryan Helmkamp
148f6c84c2 chore: add vendored Graphviz license to docs-internal/licenses
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:36:04 -04:00
Bryan Helmkamp
3389f1d551 chore: remove dead system dependency check infrastructure
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>
2026-04-14 07:30:32 -04:00
Bryan Helmkamp
829f2ae1d2 Merge remote-tracking branch 'origin/main' 2026-04-13 23:54:13 -04:00
Bryan Helmkamp
d22be78575 fix(server): honor server.listen when bind is omitted 2026-04-13 23:54:08 -04:00
Bryan Helmkamp
b3ae342a55 Merge branch 'vendor-graphviz-sys' 2026-04-13 23:42:45 -04:00
Bryan Helmkamp
ee5cd96f52 fix(tests): disable proxy discovery in install test 2026-04-13 23:34:59 -04:00
Bryan Helmkamp
15cf4d8640 refactor: wire vendored Graphviz into fabro-graphviz, remove dot dependency
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>
2026-04-13 22:46:29 -04:00
Bryan Helmkamp
ad775f2cb0 chore: refresh fabro spa assets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:36:03 -04:00
Bryan Helmkamp
0d4e4a3cbb feat: add fabro-graphviz-sys crate with vendored Graphviz 14.1.5
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>
2026-04-13 22:34:50 -04:00
Bryan Helmkamp
3674b112cb chore: regenerate TypeScript API client from OpenAPI spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:32:35 -04:00
Bryan Helmkamp
4cff947b87 fix(test): update snapshot placeholder [HOME] -> [HOME_DIR]
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>
2026-04-13 22:30:38 -04:00
Bryan Helmkamp
54a11e1426 fix(lint): resolve clippy warnings for Rust 1.94 on CI
- 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>
2026-04-13 22:26:36 -04:00
Bryan Helmkamp
c8f09307d0 docs: update changelog and docs for auth, install, and settings changes
Add Apr 13 changelog entry (scripted install, dev-token local auth,
GITHUB_TOKEN rename). Regenerate Apr 12 entry with provider credential
auth and resolved settings. Update CLI reference for --non-interactive
install and device code auth. Fix vault path, deploy-server --bind flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:24:29 -04:00
Bryan Helmkamp
f9a8891d74 fix(plan): add missing import removals, clarify graph.rs and server.rs changes
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>
2026-04-13 22:21:32 -04:00
Bryan Helmkamp
fb5f712da4 fix(plan): add missing files, improve precision of doctor/render/CLI changes
- 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>
2026-04-13 22:21:32 -04:00
Bryan Helmkamp
1ab3369bde fix(plan): add missing json_global.rs test file, improve precision of doctor/install/diagnostics steps
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>
2026-04-13 22:21:32 -04:00
Bryan Helmkamp
9c45e13285 fix(plan): add missing test guard removal, fix duplicate defines, clarify thread safety
- 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>
2026-04-13 22:21:32 -04:00
Bryan Helmkamp
aa5e3f600d plan: vendor Graphviz C source via fabro-graphviz-sys FFI crate
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>
2026-04-13 22:21:32 -04:00
Bryan Helmkamp
e5b7bb1909 fix(tests): disable macOS proxy discovery via FABRO_HTTP_PROXY_POLICY
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>
2026-04-13 22:14:51 -04:00
Bryan Helmkamp
01b1fd13bd Merge origin/main into local main
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>
2026-04-13 21:38:54 -04:00
Bryan Helmkamp
6db2408f2c fix(tests): isolate test secret store paths to prevent shared /tmp/server.env
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>
2026-04-13 21:26:02 -04:00
Bryan Helmkamp
67819457ad fix(install): harden GitHub app bootstrap
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.
2026-04-13 21:20:10 -04:00
Bryan Helmkamp
f91923892c refactor(github): rename gh_cli strategy to token, GITHUB_CLI_TOKEN to GITHUB_TOKEN
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>
2026-04-13 20:46:11 -04:00
Bryan Helmkamp
72c7147d73 chore(lint): fix fabro-cli clippy warnings 2026-04-13 19:45:26 -04:00
Bryan Helmkamp
f04e59f83f feat(install): support non-interactive github app setup 2026-04-13 19:42:03 -04:00
Bryan Helmkamp
f4bae6e9bc refactor(setup): remove browser-based GitHub app bootstrap
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.
2026-04-13 18:25:29 -04:00
Bryan Helmkamp
3692f0a6fa fix: use module imports instead of absolute paths for session_secret
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>
2026-04-13 15:55:49 -04:00
Bryan Helmkamp
a7e9dbe8b9 Merge origin/main into local main
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>
2026-04-13 12:28:08 -04:00