Hibryda
0f7024ec8f
fix(electrobun): copy pty-client locally, fix import path for Bun bundler
2026-03-20 03:23:52 +01:00
Hibryda
4676fc2c94
feat(electrobun): wire PTY daemon into terminal tabs via Electrobun RPC
...
- Bun process connects to agor-ptyd via PtyClient (5 retries, exponential backoff)
- RPC bridge: 5 request handlers (create/write/resize/unsubscribe/close)
- Daemon output forwarded to WebView as pty.output messages (base64 passthrough)
- Terminal.svelte: real PTY sessions via RPC instead of echo mode
- Shared RPC schema at src/shared/pty-rpc-schema.ts
- Fixed pty-client.ts protocol: base64 string for data (was number array)
- TerminalTabs passes sessionId to Terminal component
2026-03-20 03:20:13 +01:00
Hibryda
f3456bd09d
feat(agor-pty): complete PTY daemon — auth, sessions, output fanout
2026-03-20 03:10:49 +01:00
Hibryda
4b5583430d
feat: agor-pty crate — standalone PTY multiplexer daemon (Phase 1 WIP)
...
New crate at agor-pty/ (standalone, not in workspace — portable to Tauri/Electrobun):
- Rust daemon (agor-ptyd) with Unix socket IPC, JSON-framed protocol
- PTY session lifecycle: create, resize, write, close, output fanout
- 256-bit token auth, multi-client support, session persistence
- TypeScript IPC client at clients/ts/pty-client.ts (Bun + Node.js)
- Protocol: 9 client messages, 7 daemon messages
- Based on tribunal ruling (78% confidence, 4 rounds, 55 objections)
WIP: Rust implementation in progress (protocol.rs + auth.rs done)
2026-03-20 03:04:36 +01:00
Hibryda
e8132b7dc6
fix(electrobun): rewrite terminal collapse — blur fix, tab bar as bottom divider
2026-03-20 02:41:07 +01:00
Hibryda
9edece0dc7
fix(electrobun): terminal collapse — tab bar as divider, messages fill freed space
2026-03-20 02:36:11 +01:00
Hibryda
3d1cd0028f
fix(electrobun): tab bar at bottom, collapse slides down naturally
2026-03-20 02:29:49 +01:00
Hibryda
cb4fe5bd4a
fix(electrobun): collapse animation + z-index fix, gitignore .tribunal/
2026-03-20 02:25:50 +01:00
Hibryda
bdd4477aec
fix(electrobun): terminal collapse animation + tab bar z-index above canvas
2026-03-20 02:14:10 +01:00
Hibryda
4ae558af17
feat(electrobun): fixes + 7 new features (terminal input, file browser, memory, toasts)
...
Fixes:
- Terminal accepts keyboard input (echo mode with prompt)
- Terminal drawer collapses properly (display:none preserves xterm state)
Features:
- 6 project tabs: Model | Docs | Context | Files | SSH | Memory
- FileBrowser.svelte: recursive tree with expand/collapse + file preview
- MemoryTab.svelte: memory cards with trust badges (human/agent/auto)
- Subagent tree in AgentPane (demo: search-agent, test-runner)
- Drag resize handle between agent pane and terminal
- Theme dropdown in Settings (4 Catppuccin flavors)
- ToastContainer.svelte: auto-dismiss notifications
2026-03-20 02:07:18 +01:00
Hibryda
b11a856b72
feat(electrobun): full UI — terminal tabs, agent pane, settings, palette
...
Extracted into 6 components:
- ProjectCard.svelte: header with badges, tab bar, content area
- AgentPane.svelte: collapsible tool calls, status strip, prompt input
- TerminalTabs.svelte: add/close shell tabs, active highlighting
- SettingsDrawer.svelte: theme, fonts, providers
- CommandPalette.svelte: Ctrl+K search overlay
- Terminal.svelte: xterm.js with Canvas + Image addons
Status bar: running/idle/stalled counts, attention queue, session
duration, notification bell, Ctrl+K hint. All ARIA labeled.
2026-03-20 01:55:24 +01:00
Hibryda
931bc1b94c
test(electrobun): 6-terminal stress test to verify Canvas context limit
2026-03-20 01:42:59 +01:00
Hibryda
f97ea95373
feat(electrobun): add xterm.js terminal with image addon (Sixel/iTerm2)
...
- Terminal.svelte component with @xterm/xterm + Canvas + Fit + Image addons
- Catppuccin Mocha terminal theme matching main app
- Sixel, iTerm2 inline image protocol support via xterm-addon-image
- ResizeObserver for responsive terminal sizing
- Demo cargo test output in terminal section below agent messages
2026-03-20 01:40:24 +01:00
Hibryda
b79fbf688e
perf(electrobun): JS blink replaces CSS animation, 1.13% CPU (was 6.5%)
...
JS setInterval(500ms) toggles .blink-off class instead of CSS @keyframes.
WebKitGTK handles discrete class toggle efficiently (single repaint per toggle).
0.7% idle + 0.43% blink overhead = 1.13% total.
Comparison:
- CSS @keyframes: 6.5% (continuous compositor animation)
- JS class toggle: 1.13% (2 repaints/sec)
- No animation: 0.7% (baseline)
- Tauri (CSS): ~0% (browser compositor optimized)
- GPUI (custom Element): 2.17%
2026-03-20 01:35:33 +01:00
Hibryda
6b4a2494b3
perf: disable CSS pulse animation, measure 0.7% idle baseline (Electrobun)
2026-03-20 01:30:52 +01:00
Hibryda
cfc135ffaf
feat: Electrobun Svelte+WGPU prototype (Dawn GPU confirmed on Linux)
...
- Svelte 5 frontend with Catppuccin Mocha theme, 2 project cards
- Electrobun v1.16.0 with bundleWGPU: true (Dawn on Linux x64)
- WebKitGTK webview + WGPU surface coexistence confirmed
- CPU: 6.5% idle (CSS animation + WebKitGTK overhead)
- Port 9760 for dev server (project convention)
2026-03-20 01:25:41 +01:00
Hibryda
1f20fc460e
feat: add Electrobun WGPU prototype (Dawn GPU on Linux confirmed)
2026-03-20 01:18:19 +01:00
Hibryda
14a3dbd096
fix(ui-gpui): layout flex-1 + min-width for side-by-side grid
2026-03-20 00:45:54 +01:00
Hibryda
c61262c604
perf(ui-gpui): eliminate ProjectBox Entity, plain struct + direct render (2.17%)
...
ProjectBoxData replaces Entity<ProjectBox>. Workspace is the only view
entity in the dispatch tree. Timer notifies Workspace via cx.spawn.
12 optimization iterations: 90% → 2.17% CPU for a pulsing dot.
2026-03-20 00:40:35 +01:00
Hibryda
3bbaefa9a2
perf(ui-gpui): ProjectBoxFullElement wraps entire card, 2.1% CPU
...
Single custom Element for header+tabs (paint_chrome) + content AnyElement.
Only 1 div remains (content wrapper). Down from 90% → 2.1% over 11 iterations.
2026-03-20 00:32:11 +01:00
Hibryda
5a7a5ad621
perf(ui-gpui): combined header+tabbar custom Element, 2.63% CPU
...
Header + tab bar in single custom Element (10 GPU primitives).
ProjectBox::render() now only 2 divs (root + content).
Down from 90% → 2.63% through 10 optimization iterations.
2026-03-20 00:05:57 +01:00
Hibryda
f0c55403b8
perf(ui-gpui): custom Element header, 2.73% CPU (down from 90%)
...
ProjectBoxHeaderElement: 5 paint_quad + 2 text runs, zero Taffy nodes.
Flattened hierarchy + SharedBlink + cached children + focus-gated blink.
GPUI architectural floor: cx.notify() always walks ancestors.
2026-03-19 23:55:39 +01:00
Hibryda
54e68df295
docs: deep dive into GPUI dirty propagation, SharedBlink, hierarchy flattening results
2026-03-19 23:47:39 +01:00
Hibryda
6f0f276400
perf(ui-gpui): flatten hierarchy + SharedBlink (Arc<AtomicBool>)
...
- Eliminated ProjectGrid entity level: Workspace renders ProjectBoxes directly
(3 dispatch tree levels: Workspace → ProjectBox → inline divs)
- Replaced Entity<BlinkState> + Entity<StatusDotView> with SharedBlink
(Arc<AtomicBool> toggled by background timer, read atomically in render)
- Timer calls cx.notify() directly on ProjectBox (no intermediate entities)
- CPU: 2.93% (unchanged from 3.07% — confirms cost is ProjectBox::render()
overhead, not hierarchy depth or entity count)
- Each blink frame: ~15ms total (render + layout + prepaint + paint + GPU submit)
- Zed comparison: ~5ms per blink frame (EditorElement is custom Element, not div tree)
2026-03-19 23:45:05 +01:00
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