Two initialization-page defects made failures look like progress:
- A cache read exception while rendering a model/recipe page forced
is_initializing=True, showing an endless spinner; worse, the polling
fallback then reported the idle scanner as "complete", reloading the
page straight back into the same exception. Page handlers now pass
init_error to the initialization template, which renders the error
state (with retry) server-side, and initialization.js stays on it
instead of starting WebSocket/polling.
- The WebSocket path reloaded once the page's own scanner finished,
while the polling fallback waited for every scanner. The polling
fallback now mirrors the per-page semantics: /api/lm/init-status
accepts ?page=<pageType> (aggregate behavior preserved without it),
and ModelScanner records _init_error so a failed initial scan is
reported as "error" instead of masquerading as "complete". Polling
stops on error instead of reloading into the failure.
Fresh installs no longer start a full library scan (with per-file SHA256
and sidecar writes) automatically at startup. Instead a welcome page
lists the configured model roots, estimates the scan cost from a quick
hash-free walk, and lets the user pick the sidecar storage layout and
UI language before confirming. Deferring shows an empty library; the
existing refresh button starts the scan later. Upgrading installs are
detected via a non-empty persisted cache snapshot (row-count check, so
the empty file created by scanner construction no longer masquerades
as an existing library) and keep the old behavior.
Bundled fixes surfaced by the new flow:
- broadcast an init-progress error when the startup scan fails instead
of silently landing on an empty library; the initialization page now
shows the error with a retry button
- skip the onboarding language modal/tutorial while the welcome or
initialization page is up (its spotlight targets don't exist there,
so the tour was silently auto-completed and never shown)
- promotional banners wait until onboarding is completed or skipped;
alert banners (startup messages, cache health) are unaffected
- honor the hidden attribute in first-run/initialization CSS so the
no-roots hint and error boxes don't render as empty frames
- Created zh-CN.json and zh-TW.json for Simplified and Traditional Chinese translations respectively.
- Added comprehensive test suite in test_i18n.py to validate JSON structure, server-side i18n functionality, and translation completeness across multiple languages.
- Implement WebSocket route for initialization progress updates
- Create initialization component with progress bar and stages
- Add styles for initialization UI
- Update base template to include initialization component
- Enhance model scanner to broadcast progress during initialization