summaryrefslogtreecommitdiff
path: root/internal/tui
AgeCommit message (Collapse)Author
2026-05-12refactor renderActiveContent to stay under 50-line limitPaul Buetow
Extract renderActiveContentViz (treemap/icicle/bubble dispatch) and renderActiveContentTable (table-with-sort dispatch) from the original 56-line renderActiveContent, reducing it to 15 lines of code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12refactor: split handleGlobalKeyPress into focused helpers under 50 linesPaul Buetow
Extract handleHelpOverlayKeyPress, handleQuitKeyPress, routeQuitAsEsc, and handleDashboardShortcutKeys from the 89-line handleGlobalKeyPress to comply with the project's 50-line function limit. All existing behaviour is preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12refactor flamegraph model.go: split Update and frameIndexAt below 50-line limitPaul Buetow
Extract handleSearchInput and handleKeyNavigation from Update (111 lines → 33), then split handleKeyNavigation into handleModeKey and handleMovementKey. Extract frameCoordToTargetRow and findFrameAtRow from frameIndexAt (66 lines → 32). All new helpers are ≤ 29 lines; behavior is preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11speed up flame graph TUI under heavy event loadPaul Buetow
Move the per-tick snapshot refresh off the Bubble Tea update goroutine, add a frame ancestry index so navigation and filter helpers run in O(subtree) instead of O(frames), skip refresh and animation while the user is actively pressing keys, and memoize View() output. Keystrokes (pause, filter, navigate) now land within one frame even when the live trie ingests thousands of events per tick. - new SnapshotTree() on LiveTrie bypasses JSON marshal+unmarshal - RefreshFromLiveTrieCmd runs SnapshotTree + layout + ancestry on a background goroutine, coalesced via refreshInFlight, and returns a flameSnapshotReadyMsg the Update loop applies cheaply - driveWindow gate (250 ms after last key press) skips refresh dispatch and snaps frames directly to target without animation while the user is driving - View() caches its rendered string keyed on the inputs that affect output; cache is bypassed during animation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09show auto-reset countdown and document the cyclePaul Buetow
Renders the next-tick countdown ("12s/30s") in the dashboard chrome so users can see when aggregates will clear, and adds a dedicated H-help line spelling out the cycle keys (off → 10s → 30s → 1m → 2m → 5m). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09refine auto-reset timer cycle and pause on blurPaul Buetow
Two follow-up refinements to the auto-reset timer added in 8da473a. - Hotkey cycle now goes off -> 10s -> 30s -> 60s -> 2m -> 5m -> off, giving the user finer control between 60s and 5m and a quicker starting cadence. - The timer now pauses while the TUI is blurred. SetFocused returns a tea.Cmd that re-arms a fresh tick on focus regain, and bumps the generation counter on every focus change so any tick scheduled before blur is dropped on arrival. autoResetTickCmd and handleAutoResetTick also gate on m.focused as defense in depth. - Dashboard chrome shows 'auto-reset: 30s (paused)' while the timer is enabled but blurred, distinguishing it from the disabled 'off' state. Tests cover the full preset cycle (including custom-value passthrough) and the pause-on-blur lifecycle: stale ticks ignored, current-gen ticks ignored while blurred, focus regain re-arms and fires the reset, no-op focus calls don't churn the generation counter, and the chrome label flips to '(paused)' as expected. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09add auto-reset timer for dashboard aggregatesPaul Buetow
Live flamegraph trie and stats engine grow unboundedly during long traces. Add a periodic auto-reset (same effect as the 'r' key) so they stay bounded. - New CLI flag -resetTimer=30s (default 30s, 0 disables). - Hotkey I cycles the cadence: off -> 15s -> 30s -> 60s -> 5m -> off. Custom intervals (e.g. -resetTimer=47s) advance to the first preset greater than the current value, then wrap to off. - autoResetTickMsg carries a generation counter so changing the cadence drops in-flight ticks scheduled under the previous interval. - Dashboard chrome shows 'auto-reset: 30s' or 'auto-reset: off'.
2026-05-08reconnect flamegraph live trie after in-place filter swapPaul Buetow
PrepareForTraceRestart was designed for the full-restart path, where the dashboard's live-trie reference is rebound when TracingStartedMsg fires. The in-place filter swap skips that message, leaving the flamegraph tab stuck on 'Flame: waiting for data...' until the next real trace restart. Re-bind via SetLiveTrie immediately after PrepareForTraceRestart in both applyGlobalFilter and undoGlobalFilter.
2026-05-08swap global filter in place to skip BPF reattachPaul Buetow
Changing the global filter used to call stopTrace + beginTraceCmd, which detached and re-attached every tracepoint and re-loaded the BPF object. On heavily loaded I/O systems that took several seconds and showed an 'Attaching tracepoints...' overlay each time. The probe set never depends on the global filter (ShouldIAttachTracepoint only reads CLI regex flags), so the restart was gratuitous. Now the eventloop holds its filter behind atomic.Pointer with SetFilter / Filter accessors, and the trace starter registers el.SetFilter via the runtime bindings as a SetLiveFilterSetter callback. applyGlobalFilter and undoGlobalFilter call runtime.applyLiveFilter first; only if no trace is running do they fall back to the full restart path.
2026-05-08add duration metric, tolerate missing tracepoints, ship el8 buildPaul Buetow
- Bubbles, treemap, icicle, and the live flamegraph 'b' cycle now include syscall duration (sum) as a third metric alongside events and bytes. Statsengine snapshots expose TotalLatencyNs to support this. - AttachAll takes an optional warn callback. Production passes one so older kernels that lack newer tracepoints log a warning and keep going instead of aborting startup. - Dockerfile.el8 + scripts/build-with-docker-el8.sh + mage buildDockerEl8 produce ior.el8, a static binary built against Rocky Linux 8 glibc for RHEL/Rocky/Alma 8 hosts. - README.md documents installing mage and the new el8 target.
2026-03-18cleanupPaul Buetow
2026-03-18refactor: extract keyboardState, filterState, processState sub-structs from ↵Paul Buetow
tui.Model (task 429) tui.Model had 33 fields mixing keyboard tracking, filter chain, process selection, and UI presentation concerns (SRP violation). Extract three focused sub-structs: - keyboardState (kb): enhancements, lastEvent{ID,At,WasPress}, suppress{ID,Until} — 7 fields managed by keys_normalize.go - filterState (filter): global filter, history slice, label stack — 3 fields for the trace filter chain - processState (proc): pid, tid, pickerReturn — 3 fields for PID/TID selection and picker navigation Model drops from 33 to 23 top-level fields. All field accesses in tui.go, keys_normalize.go, and tui_test.go are updated accordingly. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-18refactor: split TraceRuntimeBindings into RuntimePublisher and RuntimeState ↵Paul Buetow
(task 427/ISP) TraceRuntimeBindings mixed 4 setter methods (injecting data into TUI) with 4 getter methods (reading persistent TUI-owned state), violating ISP. Split into two focused interfaces: - RuntimePublisher: SetDashboardSnapshotSource, SetEventStreamSource, SetLiveTrie, SetProbeManager — the write/inject side - RuntimeState: StreamBuffer, Recorder, StreamSequencer, FilterEpoch — the read/persistent-state side TraceRuntimeBindings now embeds both, preserving all existing call sites. RuntimePublisherFromContext() added so callers that only inject data do not see the getter surface. Three such callers are narrowed: setupBPFModule, tuiTestFlamesStarter, tuiTestLiveFlamesStarter. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-18refactor: pass flags.Config explicitly, remove flags.Get() from library code ↵Paul Buetow
(task 429) flags.Get() (global mutable singleton) was called inside library packages, coupling them to global state and making tests fragile (DIP violation). - internal.Run() now takes an explicit flags.Config; main.go calls flags.Get() once at the CLI boundary and passes it in. - tui.Run(), RunWithTraceStarter(), RunTestFlamesWithTraceStarter() removed; callers already used the WithConfig variants directly. - tui.NewModel() preserved for test ergonomics but now uses flags.NewFlags() (pure defaults) instead of flags.Get() (global state). - Tests updated to use NewModelWithConfig() with explicit config structs instead of flags.Set*() + NewModel(), eliminating all test-level global-state mutation. flags.Get() is now called only in cmd/ior/main.go, the correct boundary. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-13test: expand parquet recording coveragePaul Buetow
2026-03-13feat: add tui parquet recording controlsPaul Buetow
2026-03-12feat: persist parquet recording across TUI restartsPaul Buetow
2026-03-12refactor: extract shared syscall stream row modelPaul Buetow
2026-03-10dashboard: centralize nil snapshot fallback (task 385)Paul Buetow
2026-03-10dashboard: unify viewport chrome calculation (task 388)Paul Buetow
2026-03-10dashboard: unify offset reanchoring helper (task 394)Paul Buetow
2026-03-10tui: split key normalization and help rendering (task 424)Paul Buetow
2026-03-10tui: hide stream buffer behind source interface (task 428)Paul Buetow
2026-03-10Prefer EDITOR for stream export openerPaul Buetow
2026-03-10tui/flamegraph: tighten arrow escape parsing (task 423)Paul Buetow
2026-03-10tui/flamegraph: centralize animation tick scheduling (task 422)Paul Buetow
2026-03-10tui: simplify default key map construction (task 425)Paul Buetow
2026-03-10globalfilter: share compare-op symbol helper (task 374)Paul Buetow
2026-03-09tui: add reverse sorting for dashboard tables (task 364)Paul Buetow
2026-03-09tui: export filtered stream rows from global CSV action (task 364)Paul Buetow
2026-03-09tui: add sortable processes dashboard table (task 365)Paul Buetow
2026-03-09tui: add sortable files dashboard table modes (task 364)Paul Buetow
2026-03-09tui: add sortable syscalls dashboard table (task 363)Paul Buetow
2026-03-09tui: harden paused flame renderingPaul Buetow
2026-03-09tui: fix flamegraph click re-rootingPaul Buetow
2026-03-09tui: use full width for zoomed flame barsPaul Buetow
2026-03-09tui: remove flame selected underlinePaul Buetow
2026-03-08tui: reserve p for pid pickerPaul Buetow
2026-03-08tui: unify table navigation and renderingPaul Buetow
2026-03-08tui: add process-tab enter filter pushPaul Buetow
2026-03-08tui: restore global filter stack and anchored matchesPaul Buetow
2026-03-08task 378: test aggregate filter restart behaviorPaul Buetow
2026-03-08task 375: show active global filter in dashboard helpPaul Buetow
2026-03-08task 374: remove stream-local filter stackPaul Buetow
2026-03-08task 373: preserve stream history across filter restartPaul Buetow
2026-03-08task 372: restart tracing when filters changePaul Buetow
2026-03-08task 371: wire global filter modal into top-level TUIPaul Buetow
2026-03-08task 370: extract reusable trace filter modalPaul Buetow
2026-03-08task 367: carry full trace filters through TUI contextPaul Buetow
2026-03-08task 366: extract shared global filter typesPaul Buetow