macOS recursive fs.watch fires multiple events per logical save and emits
spurious "bubble" events for sibling directories. With the previous slow
~10s tailwind step those re-fires were absorbed between rebuilds; with
~60ms rebuilds the watcher entered a continuous-rebuild loop instead.
- Coalesce events with a 75ms debounce window so one save fires one
rebuild even when the editor produces several FS events.
- Filter to source-relevant extensions (ts/tsx/css/html/images/fonts);
ignore .DS_Store, .tsbuildinfo, swap files, and the extensionless
bubble events (e.g. "rename images") that were the dominant source
of the loop.
- Optional FABRO_BUILD_DEBUG=1 logs which path queued or skipped each
rebuild for future diagnosis.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In --watch-web dev mode the server silently fell back to the embedded SPA
snapshot whenever the disk dist/ was missing or partial, so edits to the
web app appeared not to take effect with no error anywhere. This change
makes the dev loop visible and quick:
- static_files plumbs a dev_disk_only flag from RouterOptions.watch_web
into the fallback handler. When set, embedded fallback is skipped and
a miss returns 503 with a "build in progress" auto-refresh page.
- The web build script writes each rebuild into apps/fabro-web/.dist-builds/<id>/
and atomically replaces the dist symlink via rename(2), so requests
never observe a partially-populated dist tree.
- Tailwind is invoked through node_modules/.bin/tailwindcss directly
instead of bunx, removing a per-rebuild bun add @latest --force round-
trip and dropping rebuild time from ~10s to ~250ms.
- load_asset no longer falls through to the workspace dist/ when an
explicit asset_root is provided, restoring test isolation when a
real dev build is sitting next door.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Always route non-empty Files Changed views through Pierre's Virtualizer and worker pool, with full-height layout propagation and stable per-file cache keys. Copy Pierre worker assets during the web build so the static worker URL resolves in production.
Implement the web-first install experience across the server, CLI, API spec,
web app, and packaged SPA assets.
This also removes test-side process env mutation by pushing env-dependent
decision points behind explicit helpers and test wiring.
Keep project config and checked-in workflows under .fabro so they stay out of
normal repo listings. Update config discovery, CLI project commands, fixtures,
docs, and checked-in workflow paths to use .fabro/project.toml and
.fabro/workflows/*.
Replace the unsupported Bun.watch call in the SPA build script with
node:fs.watch so `bun run dev` keeps running in local development.
Add a regression test that verifies watch mode stays alive until
interrupted.
Replace the old React Router SSR setup with a static SPA build served by
fabro-server, move setup and GitHub auth handling into Rust, and update the
default local web URL and stale Arc-era references to match the Fabro name.