The GET / route has no auth middleware, so user_id was always
empty. Add UserIDFromCookie helper that opportunistically reads
the sb_token cookie and extracts user_id without requiring auth.
Now user preference correctly overrides the global default.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
resolveDefaultSurface was using ListEnabledByType("surface") which
missed extension packages with type "full". Switch to List() and
filter by source != core/builtin + type surface/full.
Also make welcome surface smarter: detect when extensions exist
but no default is set vs truly empty install, show appropriate
messaging and CTA (Set Default Surface vs Go to Packages).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create welcome surface: topbar + getting-started card shown when
no extension surfaces are installed. Admins see a link to Packages,
non-admins see a message to contact their administrator.
- Update resolveDefaultSurface priority chain:
user preference → global config → first extension → /welcome
- Register welcome as a core surface with authenticated auth
- Final fallback is now /welcome instead of /admin, breaking the
infinite back-button loop
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove "chat" from surface disable guard (only admin needs it)
- Remove "chat" from IsSurfaceEnabled always-on check
- Remove unused fmt.Sprintf references in team stores
- Update stale comments referencing personas and chat surfaces
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>