Add the new destination key to [server.logging], list FABRO_LOG_DESTINATION
in the env vars table, and note that containers stream to stdout. Update
docs-internal/logging-strategy.md to describe the destination setting.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CLI-side ServerLogDestination enum duplicated the domain
LogDestination from fabro-types and only existed to bundle a PathBuf.
Replace InternalLogSink::Server { destination: ServerLogDestination }
with { log_path: Option<PathBuf> }, drop the server_log_destination
adapter, and let prepare_foreground_server_log derive the log path
from runtime_directory internally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Keep browser-facing web and auth flows on server.web.url so OAuth state cookies and redirect_uri use the same authority, while preserving API, webhook, health, and CLI token routes without cross-host redirects.
Inline the one-line `validate_canonical_url` wrapper at its single
caller, collapse `check_config`'s repeated `is_empty()` branches into
one if/else, and remove an unreachable default in
`wildcard_public_url_details` (the function returns early when
`bad_urls` is empty, so `bad_urls[0]` always exists).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
The strategy doc lived alone under files-internal/ while every sibling
strategy doc (logging, events, server-secrets) lived under docs-internal/.
Move it next to the others and update plan/spec references.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keeps the repo root tidy. The staged Linux musl binaries used by
the Dockerfile and the release pipeline now live at
tmp/docker-context/<arch>/fabro instead of docker-context/<arch>/fabro.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SESSION_SECRET is the sole auth root; the JWT keypair env vars are no
longer part of the runtime auth model.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Render the OAuth callback state-validation error through the same
dark-themed browser shell used by the CLI auth flow instead of the bare
"<p>{body}</p>" fallback. Extract the shell into a shared
auth/browser_shell module so both flows reuse one definition.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Drop the border, rounding, and background from the FileTree wrapper
(and its empty state) so the tree sits directly on the sidebar
container.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the raw JSON dump with three panels (Server, Access & Capacity,
Integrations & Artifacts), each rendering a small set of curated rows.
Each row uses an aligned two-column layout — title and help on the
left, a typed value renderer on the right (toggle dot, mono path,
URL link, badge, tabular-nums count, listen/object-store summaries).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keep the changed-files tree selection aligned to valid file paths, avoid mobile and initial-reset overhead, and lazy-load the tree bundle. Refresh the embedded SPA assets to match.
Adds a GitHub-style left sidebar to /runs/:id/files using @pierre/trees.
Lists only the modified files, shows git status per row, and wires
selection into the existing #file=<path> deep-link flow so clicking a
row scrolls and focuses the matching diff. Uses the @pierre/theme
pierre-dark Shiki theme for visual parity with @pierre/diffs.
Configured read-only (no drag-and-drop, no rename), flattens empty
directory chains, defaults to standard icons and default density, and
filters via hide-non-matches search. Hidden below the md breakpoint to
match where the diff style is forced to unified.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`useFreshness` now appends the GitHub-style 7-char prefix of `meta.to_sha`
to the captured/fetched timestamp, e.g. `Captured 2m ago · a1b2c3d`.
The OpenAPI pattern guarantees at least 7 hex chars when present;
degraded responses with no captured commit gracefully omit the SHA.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds four tests for the degraded-fallback line-stats path:
- aggregates_across_multiple_files: sums +/- across multiple file
sections.
- ignores_hunk_headers_and_no_newline_marker: pins that `@@` and
`\ No newline at end of file` lines never count.
- zero_for_empty_patch: boundary on empty input.
- after_strip_denylisted_ignores_sensitive_section: integration with
`strip_denylisted_sections` — the `# sensitive file omitted: <path>`
placeholder it leaves behind contributes 0 to the totals.
The existing tests already covered basic counting, header exclusion,
and symlink/submodule mode-line skipping.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Track numstat by path so sensitive, binary, symlink, and submodule entries do not inflate aggregate line counts, and clean generated client whitespace churn from the API update.
Replace React Router loader/action state paths with SWR query and mutation hooks.
Add targeted run and board EventSource managers that invalidate SWR keys, and refresh embedded SPA assets.
Adds `meta.stats: DiffStats` (required) to `PaginatedRunFileList` so the
Files Changed toolbar can render `+387 −104` next to the file count.
Server: refactors `list_binary_paths` into `list_diff_numstat`, which
returns the binary-path set plus aggregate `+/-` totals from a single
`git diff --numstat` invocation. The degraded patch-only response
populates the same field by counting `+`/`-` line prefixes in the
filtered patch (excluding `+++`/`---` file headers).
UI: `Toolbar` accepts `additions` / `deletions` and renders them as
mono-tabular `+387 −104` to the right of the file count. The block is
elided when the diff has 0 changes (e.g. binary-only or empty runs) so
the empty case stays clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the panel-style toolbar with a single-row header showing
"<N> files changed" on the left and Captured-time + Split/Stacked
toggle + icon Refresh on the right. Heights of left and right groups
match. The Unified label is renamed to Stacked to match diffs.com
terminology; the underlying DiffStyle value is unchanged so the
@pierre/diffs option and the localStorage key continue to roundtrip.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Consolidate workspace_root, PlannedCommand, shell_arg, markdown_cell, and
replace_generated_region into commands/mod.rs; unify fabro_dev/output_text/
write_file/read_file into tests/it/main.rs. Drop the abandoned check-boundary
subcommand.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.