Hibryda
ddec12db3f
perf(ui-gpui): simplify ProjectBox render, confirm 3% is hierarchy depth cost
...
Each blink = ~15ms CPU (1-2 ticks/500ms). Cost is Entity dispatch tree
walk through 4 levels (Workspace→ProjectGrid→ProjectBox→StatusDotView),
not div count. Zed achieves ~5ms with 3 levels. To match: flatten hierarchy.
2026-03-19 23:31:28 +01:00
Hibryda
5d69f6b28f
perf(ui-gpui): focus-gated blink + comprehensive rendering analysis
...
Focus-gated blink: only first (focused) project blinks.
Root cause: 14 header divs × 2 boxes × 2/sec = 2.8% CPU.
Cached children (AgentPane, TerminalView) confirmed at 0%.
Path to <1%: custom Element for ProjectBox (major refactor).
2026-03-19 23:26:20 +01:00
Hibryda
f797a676f4
perf(ui-gpui): isolate StatusDotView entity, document 3% CPU floor
...
Root cause analysis:
- 0% baseline: calloop 60Hz polling has zero measurable CPU cost
- 3% is entirely from ProjectBox::render() rebuilding ~30 header divs
× 2 boxes × 2/sec = 120 div constructions/sec
- AgentPane + TerminalView cached (into_cached_flex) = 0% contribution
- mark_view_dirty() walks ancestors unconditionally in GPUI 0.2.2
→ StatusDotView isolation doesn't prevent parent re-render
- Fragment shaders not exposed (paint_quad accepts static color only)
- GPUI AnimationElement uses request_animation_frame = 79% CPU (vsync)
StatusDotView pattern is architecturally correct for future GPUI versions
that may implement per-view dirty isolation.
2026-03-19 23:09:56 +01:00
Hibryda
727c7d2e06
perf(ui-gpui): revert AnimationElement (79% CPU), document shader limitation
...
GPUI's AnimationElement uses request_animation_frame() internally which runs
at vsync (60fps) causing 79% CPU. Fragment shaders not exposed through GPUI's
Scene API (paint_quad only accepts static color, no time uniform).
Reverted to BlinkState timer pattern (3% CPU, 2 renders/sec).
This is the same approach Zed uses for cursor blink.
Tested approaches and results:
- AnimationElement + pulsating_between: 79% CPU (vsync loop)
- BlinkState + timer(500ms) + cx.notify(): 3% CPU (correct)
- Custom Element + paint_quad: no shader access
- CSS animation (Blitz): 30% CPU (full repaint loop)
2026-03-19 23:03:04 +01:00
Hibryda
640e2bd494
fix(ui-gpui): re-enable start_blinking (was disabled for testing)
2026-03-19 22:50:16 +01:00
Hibryda
3859317477
perf(ui-gpui): add render counters, remove redundant cx.observe, reduce repaints
...
- BlinkState.start_from_context<V>() uses Context<V> spawn (not App)
which correctly registers the async task in the window's executor
- ProjectGrid NOT cached (blocks child dirty propagation)
- AgentPane + TerminalView cached with into_cached_flex()
- Render diagnostic: ProjectBox renders 2x/sec (blink), both boxes
re-render because shared parent, but inner cached views are free
- CPU: ~3% with pulsing dot visible
2026-03-19 22:48:29 +01:00
Hibryda
1f26e5b272
perf(ui-gpui): diagnostic counters confirm 2 renders/sec at window level (GPUI limit)
...
- Sidebar and StatusBar uncached (natural size collapsed with StyleRefinement::default)
- ProjectGrid cached with flex-1 style (into_cached_flex)
- AgentPane + TerminalView cached within ProjectBox
- BlinkState::start() fixed with &mut *cx deref coercion
- CPU: ~3% with full layout visible (down from 6.8% uncached)
- Remaining: ProjectBox re-renders full tree on blink (reads BlinkState)
- Next: isolate dot into StatusDotView entity to prevent ProjectBox re-render
2026-03-19 22:45:21 +01:00
Hibryda
a25e024d54
docs: add GPUI breakthrough (4.5% → 0.83% CPU) with shared-entity pattern
2026-03-19 22:36:13 +01:00
Hibryda
73cfdf6752
perf(ui-gpui): cache SharedStrings, remove diagnostics, zero alloc per render frame
...
- BlinkState as shared Entity (not child) → cx.notify() only dirties ProjectBox,
NOT ancestors (Workspace, ProjectGrid). Siblings serve from GPU cache.
- .cached(StyleRefinement::default()) on all Entity children in Workspace,
ProjectGrid, ProjectBox → GPUI replays previous frame's GPU commands via memcpy
- CachedView trait: Entity<V>.into_cached_view() → AnyView::from().cached()
- Result: 4.5% CPU → 0.83% CPU (25 ticks / 30s) for pulsing dot animation
2026-03-19 22:35:41 +01:00
Hibryda
ad45a8d88d
docs: comprehensive GPUI findings (API, animation patterns, gotchas, benchmarks)
2026-03-19 09:43:17 +01:00
Hibryda
5dbf5bd43c
perf(ui-gpui): cache SharedStrings, remove diagnostics, zero alloc per render frame
2026-03-19 09:38:00 +01:00
Hibryda
b557aeb833
perf(ui-gpui): diagnostic counters confirm 2 renders/sec at window level (GPUI limit)
2026-03-19 09:33:34 +01:00
Hibryda
7ab5d97352
perf(ui-gpui): add render counters, remove redundant cx.observe, reduce repaints
2026-03-19 09:27:08 +01:00
Hibryda
8dd3d82d31
fix(ui-gpui): re-enable start_blinking (was disabled for testing)
2026-03-19 09:21:21 +01:00
Hibryda
ba74e19ff2
feat(ui-gpui): Zed-style BlinkManager pattern for pulsing dot (epoch guard, 500ms timer)
2026-03-19 09:20:04 +01:00
Hibryda
84324f9ae3
chore: add daemon package-lock, gitignore test-results
2026-03-19 08:20:52 +01:00
Hibryda
3383334821
feat(ui-gpui): custom Element with direct paint_quad() for zero-overhead pulse
2026-03-19 08:16:44 +01:00
Hibryda
713b53ba0c
perf(ui-gpui): throttle pulse to 5fps via spawn+timer instead of request_animation_frame
2026-03-19 08:11:22 +01:00
Hibryda
c4d0707514
fix(ui-gpui): set first project to Running status so pulse animation triggers
2026-03-19 08:08:53 +01:00
Hibryda
18cfe7979c
fix(ui-gpui): color interpolation instead of alpha (GPUI ignores alpha on bg)
2026-03-19 08:03:24 +01:00
Hibryda
573105eae6
feat(ui-gpui): render-driven pulse via request_animation_frame() (GPUI native)
2026-03-19 07:59:32 +01:00
Hibryda
57e0e3a087
feat(ui-gpui): add pulsing dot via GPUI async runtime (entity-scoped repaint)
2026-03-19 07:51:25 +01:00
Hibryda
3e6307ffd0
perf(ui-dioxus): 6-step color fade without CSS transition engine (~0% CPU)
2026-03-19 07:28:38 +01:00
Hibryda
8b5a4daf72
feat(ui-dioxus): smooth pulse via background-color transition (bounded, not infinite)
2026-03-19 07:24:00 +01:00
Hibryda
a1e2a66cd6
feat(ui-dioxus): smooth 8-step opacity pulse via CSS class cycling
2026-03-19 07:14:43 +01:00
Hibryda
2f03cf0ef0
fix(ui-dioxus): class-toggle animation instead of inline opacity (Blitz compatible)
2026-03-19 07:11:01 +01:00
Hibryda
67ab77ebf4
feat(ui-dioxus): use dioxus-motion for Blitz-compatible pulse animation
2026-03-19 07:04:23 +01:00
Hibryda
c9f8679744
fix(ui-dioxus): use schedule_update() for cross-thread Blitz animation
2026-03-19 06:50:26 +01:00
Hibryda
7cea86361a
fix(ui-dioxus): use atomic+thread for Blitz animation (Signal not Send)
2026-03-19 06:45:52 +01:00
Hibryda
b0547d5c05
feat(ui-dioxus): add signal-based PulsingDot animation (Blitz-friendly)
2026-03-19 06:39:47 +01:00
Hibryda
6f9607d1ba
fix(ui-dioxus): remove CSS animations causing 30% CPU in Blitz renderer
2026-03-19 06:31:48 +01:00
Hibryda
d5172275e2
feat(ui-dioxus): switch to Blitz/wgpu native renderer (no WebView)
2026-03-19 06:12:11 +01:00
Hibryda
f3d2ca78ba
feat: add Dioxus and GPUI UI prototypes for framework comparison
...
Dioxus (ui-dioxus/): 2,169 lines, WebView mode (same wry as Tauri),
Catppuccin theme, 12 components, agor-core integration, compiles clean.
Evolution path — keeps xterm.js, gradual migration from Tauri.
GPUI (ui-gpui/): 2,490 lines, GPU-accelerated rendering, alacritty_terminal
for native terminal, 17 files, Catppuccin palette, demo data.
Revolution path — pure Rust UI, 120fps target, no WebView.
Both are standalone (not in workspace), share agor-core backend.
Created for side-by-side comparison to inform framework decision.
2026-03-19 06:05:58 +01:00
Hibryda
90c7315336
docs: add v3.2 features and architecture decisions to TODO
...
- Profile export/import with format evaluation
- Keyboard shortcuts settings (levels, compose, conflicts)
- Per-project settings cascade (global → group → project)
- Custom AI-augmented editors (image, video, audio, 3D)
- Tauri vs WGPU alternative evaluation
- Frontend-backend tight binding investigation
- More realistic E2E fixtures (multi-provider, multi-group)
2026-03-18 05:56:26 +01:00
Hibryda
60614a75f5
fix(e2e): daemon runner parses per-spec PASSED/FAILED from WDIO output
...
Previously marked all specs as failed when any single spec failed.
Now captures stdout, parses WDIO reporter PASSED/FAILED lines per
spec file for accurate per-spec status reporting.
2026-03-18 05:36:56 +01:00
Hibryda
d7dd7722ab
feat(e2e): add test daemon CLI with ANSI dashboard and Agent SDK bridge
...
- index.ts: CLI entry point (--full, --spec, --watch, --agent flags)
- runner.ts: programmatic WDIO launcher with result streaming
- dashboard.ts: ANSI terminal UI (pass/fail/skip/running icons, summary)
- agent-bridge.ts: NDJSON stdin/stdout for Agent SDK queries
(status, rerun, failures, reset-cache)
- Standalone package at tests/e2e/daemon/
2026-03-18 05:17:17 +01:00
Hibryda
46f51d7941
feat(e2e): add smart test caching and error toast catching
...
- results-db.ts: TestPassCache with consecutivePasses counter,
recordTestResult(), shouldSkip(threshold=3), resetCache()
- wdio.conf.js: afterTest hook catches unexpected .toast.error/.load-error
elements, records results to smart cache. FULL_RESCAN=1 bypasses caching
2026-03-18 05:16:49 +01:00
Hibryda
0803dc3844
docs: update TODO and CHANGELOG for session work
...
- TODO: mark completed (SPKI persistence, theme editor, pro components,
error handling, marketplace, E2E expansion), add new items (E2E failures,
daemon integration)
- CHANGELOG: add ThemeEditor, marketplace, 6 commercial modules, AppError
enum, E2E daemon, security fixes (5 critical + 14 high)
2026-03-18 05:16:37 +01:00
Hibryda
a94158e894
fix(e2e): fix remaining selector and state issues (3 files)
...
- 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
2026-03-18 04:56:06 +01:00
Hibryda
1b838eb9fc
fix(e2e): update selectors for redesigned UI (9 spec files)
...
- BTerminal → Agent Orchestrator (title, describe blocks, LLM context)
- Settings: .sidebar-panel → .settings-panel .settings-content,
.dropdown-trigger → .dropdown-btn, .dropdown-option → .dropdown-item
- Settings open: [data-testid=settings-btn] + .panel-close
- Font controls: .size-control → .stepper, .size-btn → stepper button
- Terminal: data-testid selectors for toggle/tab-add
- Agent pane: .cost-bar → .status-strip/.done-bar, context meter conditional
- Project header: .cwd → .info-cwd
- Health: .health-dot → .status-dot
- Multi-project: proper this.skip() when single-project fixture
2026-03-18 04:45:22 +01:00
Hibryda
6459877c89
fix: change dev port from 9700 to 9710 (avoid BridgeCoach conflict)
...
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
2026-03-18 04:20:49 +01:00
Hibryda
10de2a3c8b
fix(e2e): detect devUrl port conflict before launching tests
...
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.
2026-03-18 04:11:31 +01:00
Hibryda
c73a2e1caf
fix(e2e): build frontend before tests (prevents wrong-app loading)
...
- 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)
2026-03-18 04:06:28 +01:00
Hibryda
1f21a9fb46
fix(e2e): kill stale processes, verify app identity before tests
...
- 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
2026-03-18 04:01:46 +01:00
Hibryda
ae321ad108
fix(e2e): use dedicated port 9750 for tauri-driver (avoid conflicts)
...
- 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)
2026-03-18 03:58:21 +01:00
Hibryda
91a3b56dba
test(e2e): split + expand phase-b into grid + LLM specs
...
- phase-b-grid.test.ts (227 lines): multi-project grid, tab switching,
status bar, accent colors, project icons, scroll, tab bar completeness
- phase-b-llm.test.ts (211 lines): LLM-judged agent response, code gen,
context tab, tool calls, cost display, session persistence
- Original phase-b.test.ts (377 lines) deleted
- New exhaustive tests added for grid layout and agent interaction
2026-03-18 03:47:16 +01:00
Hibryda
718133f9f6
test(e2e): split + expand agent-scenarios into Phase A (22 → 47 tests)
...
- phase-a-structure.test.ts (156 lines, 14 tests): structural integrity,
settings panel, sidebar gear, accent colors, project name/icon, grid layout
- phase-a-agent.test.ts (210 lines, 14 tests): agent pane, prompts,
provider badge, cost display, context meter, status transitions
- phase-a-navigation.test.ts (297 lines, 19 tests): terminal tabs,
command palette, focus switching, palette categories, shortcut hints
- Original agent-scenarios.test.ts (429 lines) deleted
- 25 new exhaustive tests added
2026-03-18 03:46:40 +01:00
Hibryda
56971c3f27
test(e2e): add Phase D/E/F specs covering new architecture (54 tests)
...
Phase D — Settings & Error Handling:
- D1: Settings panel 6-category tabs, search, active highlighting
- D2: Appearance settings (themes, fonts, cursor, scrollback)
- D3: Theme Editor (color pickers, groups, save/cancel)
- D4: Toast notifications, notification center bell/dropdown
- D5: Error states (no loadError warnings, status bar)
Phase E — Agents & Health:
- E1: ProjectBox tab bar (7+ tabs, PERSISTED-LAZY switching)
- E2: Agent session UI (prompt input, context meter, cost)
- E3: Provider configuration (panels, capabilities, toggles)
- E4: Status bar fleet state (counts, cost, attention queue)
- E5: Project health indicators (status dot, CWD, pressure, burn rate)
- E6: Metrics tab (fleet aggregates, health cards, Live/History)
- E7: Conflict detection (no false badges on fresh launch)
- E8: Audit log (manager-only tab, toolbar, entries)
Phase F — Search & LLM Quality:
- F1: Search overlay (Ctrl+Shift+F, input, empty state, close)
- F2: Context tab & anchors (visualization, budget scale)
- F3: SSH tab (connection list, add button)
- F4-F7: LLM-judged quality (settings completeness, theme editor,
error messages, overall UI consistency)
2026-03-18 03:20:37 +01:00
Hibryda
6f247da514
refactor(e2e): complete agor.test.ts split (799 lines → 5 files)
...
- smoke.test.ts (47) — stateless smoke checks
- workspace.test.ts (79) — workspace & projects
- settings.test.ts (247) — settings panel + interaction
- features.test.ts (220) — command palette + keyboard shortcuts
- terminal-theme.test.ts (292) — terminal tabs + theme switching
- Reset-to-home-state hooks in all stateful before() blocks
- Original agor.test.ts deleted, wdio.conf.js specs updated
- All 50+ original tests preserved
2026-03-18 03:11:10 +01:00
Hibryda
f08c4b18cf
refactor(e2e): split spec files under 300-line limit
...
- phase-c.test.ts (626 lines) → phase-c-ui.test.ts (279), phase-c-tabs.test.ts
(272), phase-c-llm.test.ts (76) — all 11 scenarios preserved
- agor.test.ts (799 lines) → smoke.test.ts (47), workspace.test.ts (79),
settings.test.ts (247), features.test.ts (488) — split in progress
- Reset-to-home-state hooks added to stateful before() blocks
- wdio.conf.js specs array updated for all new filenames
2026-03-18 03:09:29 +01:00