All route views now mount once and hide via CSS (.view-hidden) instead of
unmounting. Tenant pages wrapped in .page-scroll divs for scrollability.
Only LoginView stays in RouterView (no state to preserve).
TestsView updated to use active ref in provideToolbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Views mounted via v-if+CSS-hide never unmount, so onMounted/onUnmounted only fire
once. When a RouterView (Tests) unmounts it clears _config, and the always-mounted
view never restores it. Fix: provideToolbar accepts optional active ref and uses
watch() instead of lifecycle hooks for those views.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vue Router can mount the incoming component before unmounting the outgoing one.
Without a version guard, the old component's onUnmounted would null out the config
that the new component just set — causing toolbar groups to disappear on back-nav.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Themes are a global preference — always shown when logged in.
Connection, quad-view, and panels remain view-specific via provideToolbar.
Fixes blank toolbar when navigating to views that don't call provideToolbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AppToolbar is a sibling of RouterView, not a descendant — provide/inject
only flows down the tree. Module-level reactive ref works across boundaries:
views write on mount/unmount, toolbar reads reactively.
Each view declares its toolbar groups and connection via provideToolbar().
AppToolbar injects and renders only what the active view needs.
- AgentsView: quad-view + themes + panels + chat connection
- TestsView: themes + test SSE connection (replaces raw EventSource)
- ViewerView: themes only
- Home/Login: no provide → toolbar hidden
useConnection() manages any SSE endpoint: connect, reconnect, state.
Tenant feature gating follows naturally — routes that don't exist
contribute no toolbar config.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four groups: connection, quad view, themes, panel config.
Each group shares one background pill. Bigger icons (w-6 h-6),
36px hit area with minimal padding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove media query resize listener and responsive auto-expand/collapse logic.
Start collapsed by default, persist user choice in sessionStorage (cleared on
browser close). No width-based rules — same behavior on desktop and mobile.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When test results include stats from --repeat mode, display inline
stat pills instead of raw duration. Adds TestStats interface.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DisplayPane/KonsolePane: use storeToRefs for computed refs (fixes
displayArtifacts/konsoleArtifacts not reacting to store changes)
- useTakeover: remove eval confirm dialog (blocks automated testing)
- useTakeover: structured screenshot() returning pane states, artifact
list and message count instead of raw body text
- main.ts: expose pinia on window.__pinia in DEV mode for test injection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AppToolbar: rename togglePanel→toggleDropdown to avoid collision with
debug panel toggle from usePanels
- ChatPane: computed()→toRef() for props passed to composables (consistent)
- ChatPane: add console.warn on session history fetch failure
- DebugColumn: skip object spread when no new panels resolved (perf)
- AgentsView: remove unused wsSwitchAgent, annotate disabled picker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each tenant config now includes oidcClientId. Auth composable reads
client ID from tenant config instead of hardcoded fallback. Dev tenant
uses restricted Zitadel project (role-check enabled, developer grant).
Added NODE_ENV=production to env files to fix --mode dev builds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build-time tenant config via VITE_TENANT env var (--mode loop42/dev).
Content pages moved to tenants/{name}/pages/ with dynamic imports and
loop42 fallback. Feature-gated routing (viewer/devTools per tenant).
Dockerfile parameterized with TENANT build arg. Deployed to separate
K8s namespaces: loop42.de → ns/loop42, loop42.dev → ns/dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Slim sidebar (Home, nyx, Impressum, Datenschutz, Sign-in/User), global
AppToolbar for system features, /agents→/nyx rename, agent auto-select,
OIDC user name extraction from id_token, theme-consistent content pages,
removed DevView and old system panel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- agents.ts: fallback agent list when server sends none, auto-select default
- useAgentSocket.ts: set connectionState=SYNCED + channelState=READY on
assay ready signal, unlocks chat input
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ws.ts: auth via query params (token + session), store session_id
from assay session_info, mark connected on ready signal
- useAgentSocket.ts: handlers for session_info, controls, artifacts, cleared
- auth.ts: auto-set dev service token for instant login
- Dockerfile + nginx.conf for K3s deployment
- .env.production: wss://assay.loop42.de/ws
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>