Commit graph

2151 commits

Author SHA1 Message Date
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
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
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
Bryan Helmkamp
c7a9f1e30b refactor(auth): deduplicate session secret, remove dead code, tighten test helpers
- Extract generate_session_secret and validate_session_secret to
  fabro_util::session_secret, removing duplicate implementations in
  install.rs (with private hex module) and start.rs
- Remove dead run_auth_method_for_config/run_auth_method_for_method
  from jwt_auth.rs (zero callers)
- Replace test read_dev_token helper with dev_token::read_dev_token_file
  which validates the fabro_dev_ prefix rather than just non-empty
- Extract build_unix_socket_probe_client to deduplicate probe client
  construction in try_connect/connect_unix_socket_api_client_bundle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:18:01 -04:00
Bryan Helmkamp
47de0914f3 fix(auth): harden setup registration and oauth state
Require dev-token operator auth for setup registration and move the
GitHub OAuth state cookie onto the protected SESSION_SECRET-backed
cookie path.
2026-04-13 12:07:02 -04:00
Bryan Helmkamp
015fe94c29 Merge remote-tracking branch 'origin/main' 2026-04-13 11:36:29 -04:00
Bryan Helmkamp
6e80d8b8f2 Fix OpenAI Codex OAuth device auth
Align the OpenAI device-auth flow with the live Codex endpoints and
allow API-backed OpenAI resolution to fall back to the stored
openai_codex credential. This makes provider login work against the
current OpenAI response shape and lets doctor/workflows use the saved
credential without OPENAI_API_KEY in the environment.
2026-04-13 11:29:01 -04:00
Bryan Helmkamp
ce10169a49 refactor(auth): simplify server auth model
Replace the old strategy matrix with server.auth.methods, browser session
cookies, and raw dev-token bearer auth. Remove mTLS auth leftovers, auto-
provision local session secrets, and update tests and docs to the new auth
surface.
2026-04-13 11:25:30 -04:00
Bryan Helmkamp
56de288f59 Stabilize CLI test isolation and snapshots 2026-04-13 10:36:33 -04:00
Bryan Helmkamp
e980008a52 Finish vault-backed workflow auth and installer QA fixes
Pass the shared storage dir into worker runs so vault-backed credentials
load during real workflow execution, including server-spawned workers.

Also finish the QA follow-ups around scripted install behavior, list
credential metadata in secret listings, and give the slow OpenAPI
conformance test a narrow nextest timeout override.
2026-04-13 10:25:38 -04:00
Bryan Helmkamp
f3aa30d782 Complete provider credential auth and scripted install 2026-04-13 09:15:45 -04:00
Bryan Helmkamp
9b83453454 fix(auth): restore local tcp and web dev-token flows 2026-04-13 08:54:22 -04:00
Bryan Helmkamp
6036e5cdab refactor(auth): deduplicate dev-token helpers and remove dead parameter
Extract atomic_write_private in dev_token.rs, export read_dev_token_file
for reuse in server_client.rs, extract build_authed_unix_socket_client
to unify try_connect/connect, and remove always-true announce param.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 08:07:26 -04:00
Bryan Helmkamp
2bf88cfe7f fix(auth): restore local dev-token client coverage
Propagate the local dev token through worker subprocesses, share the
same authenticated local-server helper across CLI integration tests,
and clean up the async token wait path so fmt, clippy, and full tests
pass again after the dev-token auth rollout.
2026-04-13 07:33:35 -04:00
Bryan Helmkamp
a6775a051c feat(auth): add dev-token local server auth
Replace local no-auth startup with a shared dev-token flow for CLI-managed
servers. This provisions and validates dev tokens, preserves dev-token
provenance through browser sessions, and teaches local CLI and web clients how
to authenticate against local Unix and TCP servers.
2026-04-13 07:04:47 -04:00
Bryan Helmkamp
43d73cb4a1 Clean up provider auth helper duplication
Share provider display names and OAuth expiry helpers across auth, CLI,
and server code, and simplify the small match arms and helper plumbing
that full-workspace clippy surfaced during final verification.
2026-04-13 07:02:03 -04:00
Bryan Helmkamp
36490a6014 Move vault secrets under vaults/default/ directory
Prepares for future multi-vault support by nesting the secrets file
at storage_root/vaults/default/secrets.json instead of storage_root/secrets.json.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:40:31 -04:00
Bryan Helmkamp
a1d8b738d8 Add typed provider credential auth flow 2026-04-12 22:10:11 -04:00
Bryan Helmkamp
7d01c4e42b Merge branch 'dense-default-fabro-settings' 2026-04-12 19:06:41 -04:00
Bryan Helmkamp
53b5ec6376 Merge branch 'main' of github.com:fabro-sh/fabro 2026-04-12 19:06:39 -04:00
Bryan Helmkamp
c60d859c08 Default settings output to dense resolved view
Make `fabro settings` render dense resolved settings by default for local
inspection, add a resolved view to the server settings endpoint with an
explicit compatibility marker, and update tests plus generated API clients
to lock the new behavior.
2026-04-12 19:06:07 -04:00
Bryan Helmkamp
51d764f6e3 Pin GHA action, Docker base images, and mintlify version
Addresses supply chain hardening items from #160:
- Pin taiki-e/install-action to commit SHA
- Pin rust:1-bookworm and oven/bun:1 to image digests
- Pin mintlify to 4.2.507

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:52:53 -04:00
Bryan Helmkamp
7f9f4e964e docs: update CLI reference and GitHub integration for recent changes
Add fabro uninstall, pr create --force, secret list metadata, and
install owner selection to CLI reference. Add GitHub App owner
selection step to integration setup flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:07:28 -04:00
Bryan Helmkamp
85e068ffa9 docs(changelog): add entries for Apr 7–12
Cover embedded web UI, settings v2, events schema v2, typed secrets,
fabro uninstall, unified templates, GitHub App owner selection, worker
lifecycle hardening, object-backed artifacts, and other changes since
Apr 6.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:07:19 -04:00
Bryan Helmkamp
ecbae9b732 Materialize builtin settings defaults
Embed defaults.toml as a base settings layer and apply it when
materializing effective settings and resolving typed settings.

This also fixes partial CLI table merging so builtin fields survive
higher-precedence overrides, and updates the affected CLI tests and
snapshots.
2026-04-12 16:54:01 -04:00
Bryan Helmkamp
a0c4b3b7db Check for storage dir in fabro doctor (#153)
Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:43:30 -04:00
Bryan Helmkamp
730d252949 Add --force option for fabro pr create (#155)
Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:56:01 -04:00
Bryan Helmkamp
48edaa009d Add Homebrew tap auto-update to release workflow
Adds installer/fabro.rb.template and an update-homebrew job that
generates the formula from release artifacts and pushes it to
fabro-sh/homebrew-tap on each tagged release.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:38:58 -04:00
Bryan Helmkamp
ba67ad9cea Stop waiting for headless Chrome to exit 2026-04-12 15:12:36 -04:00
Bryan Helmkamp
e828ce35a5 Disable debug UI auto-refresh for screenshot test 2026-04-12 15:06:04 -04:00
Bryan Helmkamp
385f7ab7a2 Increase debug UI Chrome test timeout in CI 2026-04-12 14:59:23 -04:00
Bryan Helmkamp
7771dc1e41 Fix headless Chrome debug UI CI test 2026-04-12 14:54:28 -04:00
Bryan Helmkamp
b5d0297f1d Increase timeout for headless Chrome debug UI test 2026-04-12 14:48:27 -04:00
Bryan Helmkamp
ad1d947248 Stabilize worker shutdown process group test 2026-04-12 14:36:44 -04:00
Bryan Helmkamp
48f461207d Stabilize TCP host-only bind fallback test 2026-04-12 14:32:10 -04:00
Bryan Helmkamp
eef19dc7c0 Fix fabro-server mTLS integration test API 2026-04-12 14:26:28 -04:00