- settings.test.ts: use browser.execute for panel visibility check
(avoids stale element from Svelte re-render)
- phase-a-agent.test.ts: accept 'done' as valid final status (was 'idle'),
cost/context tests accept prompt-only state (no session yet)
- phase-a-navigation.test.ts: wait for terminal-tabs after expanding,
add tab before checking active styling, re-open palette if closed
Port 9700 was occupied by BridgeCoach Docker container, causing the
Tauri debug binary to load the wrong frontend. Changed to 9710:
- vite.config.ts: server.port 9700 → 9710
- tauri.conf.json: devUrl localhost:9700 → localhost:9710
- wdio.conf.js: DEV_URL_PORT check updated
- Binary rebuilt with new port baked in
Debug binary has devUrl (localhost:9700) baked in via cfg(debug_assertions).
If another app (Docker, Nuxt, etc.) serves on that port, the Tauri WebView
loads the WRONG frontend. onPrepare now fails fast with a clear message
if port 9700 is occupied, preventing false test results against wrong app.
- onPrepare: run `npm run build` before `cargo tauri build --debug --no-bundle`
(--no-bundle skips beforeBuildCommand, leaving no dist/ for the WebView)
- SKIP_BUILD: still verify dist/index.html exists, build frontend if missing
- Without this fix, the Tauri binary falls back to devUrl and loads whatever
app is serving on that port (e.g., BridgeCoach on another project)
- onPrepare: kill stale tauri-driver on port 9750 before spawning
- onPrepare: verify debug binary exists (fail fast with clear message)
- before: app identity check — waits for known Agent Orchestrator elements
(status-bar, project-grid, settings-panel) or matching window title
- Prevents wrong-app connection when other Tauri/WebKit2GTK apps are running
- tauri-driver spawned with --port 9750 (was default 4444)
- Pre-check: fail fast if port already in use (clear error message)
- TCP readiness probe uses the dedicated port
- Follows project port convention (9000-9999 range)
- Move fixtures.ts, llm-judge.ts, results-db.ts to tests/e2e/infra/
- Deduplicate wdio.conf.js: use createTestFixture() instead of inline copy
- Replace __dirname paths with projectRoot-anchored paths
- Create test-mode-constants.ts (typed env var names, flag registry)
- Create scripts/preflight-check.sh (validates tauri-driver, display, Claude CLI)
- Create scripts/check-test-flags.sh (CI lint for AGOR_TEST flag drift)
- Rewrite tests/e2e/README.md with full documentation
- Update spec imports for moved infra files
- ThemeEditor.svelte: 26 color pickers (14 accents + 12 neutrals) with
native <input type="color"> and hex text input, live CSS preview
- custom-themes.ts: persistence layer (SQLite JSON blob), validation,
import/export as JSON files, clone from any built-in theme
- theme.svelte.ts: previewPalette/clearPreview for live editing,
setCustomTheme for persistence, initTheme loads custom themes on startup
- themes.ts: applyPaletteDirect + buildXtermThemeFromPalette + PALETTE_KEYS
- AppearanceSettings.svelte: custom themes list with edit/delete, "New
Custom Theme" button, ThemeEditor toggle
- All files under 300 lines (296 + 227 + 98)
- All 6 settings components: save handlers use handleError with user intent
- onMount loaders migrated from Promise.all to Promise.allSettled (partial recovery)
- loadError $state + inline warning banner on full load failure
- JSON parse catches use handleInfraError with explicit fallback comments
- Secret operations (reveal/store/delete) use handleError for user feedback
- extractErrorMessage(err: unknown) normalizes any error shape to string
- handleError/handleInfraError dual utilities (user-facing vs infra-only)
- error-classifier extended with ipc/database/filesystem types (9 total)
- Toast rate-limiting (max 3 per type per 30s) in notifications store
- Infrastructure bridges use documented console.warn (recursion prevention)
- 13 new tests for extractErrorMessage
SettingsPanel now renders actual components instead of placeholders:
AppearanceSettings, AgentSettings, SecuritySettings, ProjectSettings,
OrchestrationSettings, AdvancedSettings. Category switching via sidebar
with keyboard navigation and search deep-linking.
Settings redesign complete: 2959-line monolith replaced by 7 modular
components totaling ~1,700 lines. Monolith retained for backward
compatibility — will be removed once all edge cases are verified.