You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds agentsview tui, a full-screen Bubble Tea interface backed by the existing daemon HTTP API and SSE stream rather than direct archive access. It covers session browsing and transcripts, dashboards, usage, activity, trends, insights, pins, trash, recent edits, settings, mutations, exports and publishing, persistent filters, localized labels, and terminal-safe rendering. Shared report services also expand the MCP surface for analytics, activity, trends, pins, insights, and recent edits.
Startup serves the client before the initial archive sync completes. Report panels stream independently, session details load concurrently, and transcript and filter-editor work stays bounded by the viewport and render caches. Concurrent sync is normal active status, empty trends remain an input state, and sidebar filters open an explicit keyboard editor with cursor and paste handling.
The implementation deliberately reuses daemon and service contracts instead of adding a second SQLite path. Fixed keybindings and colon commands remain the terminal-specific tradeoff; sidebar text filters are free-form rather than metadata pickers. The main review surfaces are internal/tui, cmd/agentsview/tui.go, the shared report and message-window changes, and docs/tui.md.
Changes need revisions: four medium-severity issues remain; no critical or high findings were reported.
Medium
internal/service/reports.go:57, internal/tui/client.go:289 — Custom activity ranges use incompatible date/filter contracts across HTTP, TUI, and direct/PG transports. Use an activity-specific builder with RFC3339 bounds and consistent filtering semantics.
internal/tui/client.go:614, internal/tui/model.go:1007 — Imports buffer entire archives in memory, while long-running mutations have a fixed ten-minute timeout. Stream multipart uploads and use cancellation without a fixed deadline.
internal/tui/view.go:141, internal/tui/model.go:1114 — At widths 80–119, navigation is hidden but remains focusable, causing blind navigation. Show it when focused or remove it from the focus cycle and expose a visible route selector.
internal/tui/view.go:804 — Fallback session IDs reach the terminal without sanitization, allowing control sequences. Sanitize them with terminaltext.Sanitize.
Seven medium-severity issues remain, including terminal escape injection, broken authentication/session workflows, and reporting and navigation regressions.
Medium
Terminal escape injection bypasses sanitization — internal/tui/view.go:366, internal/tui/view.go:820
Glamour decodes HTML entities after sanitization, allowing encoded control sequences such as OSC 52 to become active terminal commands. The session-ID title fallback is also unsanitized. Sanitize after entity decoding while preserving only trusted renderer styling, sanitize the fallback ID, and test direct and entity-encoded OSC payloads.
Authentication token is not propagated to the session backend — internal/tui/client.go:551
Enabling require_auth updates c.token, but c.sessions retains its original token, causing session, search, transcript, and usage requests to return 401 until restart. Update or recreate the backend when the token changes and synchronize concurrent token access.
open-session always sends an invalid request — internal/tui/client.go:589
The command posts an empty body despite the server requiring a valid opener_id, so it fails with opener "" not found. Resolve an opener through /api/v1/openers, accept one as an argument, or open the session directory locally.
Direct activity reports cannot use custom ranges consistently — internal/service/reports.go:66 ResolveQuery requires RFC3339 bounds, while reportDBFilter requires the same values to be date-only. The reused filter also excludes one-shot sessions by default, unlike the HTTP activity endpoint. Build an independent activity filter and align its visibility semantics with the HTTP endpoint.
Long transcript content is inaccessible — internal/tui/view.go:231
Rendering always begins at line zero without intra-message scrolling, permanently truncating long messages and tool output and potentially hiding the selected message. Track a rendered-line viewport offset and keep the selection visible.
Report-list scrolling uses item indexes as line offsets — internal/tui/model.go:811
Multi-line insights, pins, and recent edits cause the selected item to move off-screen while navigation continues invisibly. Calculate actual rendered-line offsets or use a virtualized viewport.
Archive imports buffer entire files in memory — internal/tui/client.go:615
Large ChatGPT or Claude exports can exhaust memory before upload begins. Stream multipart encoding through an io.Pipe and propagate encoder errors asynchronously.
I've tested this out locally on my large agentsview corpus. As it stands the performance of this TUI is not of a sufficient bar to be included in agentsview.
Review found five medium-severity functional issues; no concrete security vulnerabilities were identified.
Medium
internal/tui/client.go:763 — :open-session always fails: The command sends an empty body, but the endpoint requires a valid opener_id, and no registered opener has an empty ID. Load /api/v1/openers and allow opener selection, or provide a documented server-side default.
internal/tui/client.go:723 — Authentication token is not propagated: Enabling authentication updates only Client.token; the service.SessionService in Client.sessions retains the old token, causing subsequent session, transcript, search, and usage calls to fail. Recreate or update the session backend whenever the token changes, including during startup when adopting a locally returned settings token.
internal/tui/client.go:263 — Custom activity dates use the wrong format: The TUI sends date-only From and To values to an endpoint requiring RFC3339 instants, so the documented custom-range workflow returns HTTP 400. Convert calendar dates to timezone-aware RFC3339 bounds with an exclusive end boundary.
internal/service/reports.go:57 — Activity reporting differs by transport: The direct implementation validates RFC3339 custom bounds through a date-only filter and applies filters differently from the HTTP endpoint. Identical MCP calls can therefore fail or return different results under PostgreSQL and daemon transports. Introduce activity-specific range mapping and align supported filter semantics across the service, MCP schema, and HTTP endpoint.
internal/tui/model.go:869 — Selection can scroll outside the viewport: Report pages use item indexes as line anchors even though some items render multiple lines. Track rendered line offsets or separate selection and detail rendering before applying windowLines.
Verdict: 6 medium-severity issues require attention before merging.
Medium
Stale :find results can load the wrong transcript window — internal/tui/model.go:104-108, 279-293, 1130-1136
Results are keyed only by page generation; changing sessions increments a separate generation, allowing previous-session results to apply to the newly selected session. Validate the searched session ID and session-load generation.
Timezone inconsistency in TUI session filtering — internal/tui/model.go:160-172
The initial session ListFilter omits the configured timezone, causing date filtering to default to UTC while reports use the configured timezone. Set Timezone: opts.Timezone.
Activity-report filters are silently ignored over HTTP — internal/service/reports.go:117-124, internal/server/huma_routes_activity.go:34-48, 311-317
Filters including model, min_user_messages, include_one_shot, and include_automated are sent by the client but not accepted or applied by the endpoint, producing inconsistent direct and HTTP results. Align the endpoint and client behavior.
Custom activity ranges use incompatible date formats — internal/tui/client.go:269-285, internal/tui/model.go:551-564, internal/mcp/tools.go:714-716
The API requires RFC3339 timestamps, while TUI and MCP documentation reuse from/to as YYYY-MM-DD dates. Add RFC3339-specific fields and validation or convert date-only ranges to explicit boundaries.
Configured SSH remotes may not resolve correctly — internal/tui/client.go:730-737 :sync-remote sends only the host, so remotes with non-default users or ports are not matched and may fall back to default credentials. Send a stable remote ID or include user and port.
Session-derived fallback IDs can inject terminal control sequences — internal/tui/view.go:329-345, 846-854
The fallback session ID is rendered without sanitization, potentially allowing terminal spoofing or state modification through malicious daemon data. Sanitize it and audit all daemon-provided metadata at the rendering boundary.
Verdict: Multiple medium-severity correctness issues remain in the TUI and activity-report paths.
Medium
internal/tui/client.go:763-764 — open-session sends an empty request body even though the server requires a valid opener_id, causing the command to always fail.
internal/tui/client.go:263-285 — Custom activity ranges pass YYYY-MM-DD values directly, but the API expects RFC3339 timestamps.
internal/service/reports.go:66-82 — Direct ActivityReport calls inherit ExcludeOneShot, excluding one-shot sessions by default unlike the HTTP activity route.
internal/tui/model.go:279-293,1130-1136 — Pending find results are validated only by page generation, allowing results from a previous session to apply to the newly selected transcript.
internal/tui/model.go:1105-1119 — Repeated transcript-page requests before completion reuse the same ordinal and can append duplicate pages.
Verdict: Five medium-severity issues require attention; no critical or high-severity findings were identified.
Medium
internal/tui/client.go:204,753-758 — Enabling authentication updates c.token, but the delegated c.sessions backend retains the original token. The triggered reload uses stale credentials and receives 401 responses. Refresh or recreate the backend when the token changes, with synchronized access.
internal/mcp/tools.go:714-786, internal/service/reports.go:57-70,177-193 — Activity custom ranges have inconsistent contracts: MCP documents from/to as YYYY-MM-DD, while activity.ResolveQuery requires RFC3339. Without preset:"custom" the range is ignored; with it, documented values are rejected. Define, validate, and normalize the fields consistently.
internal/service/reports.go:117-124; internal/server/huma_routes_activity.go:34-49,310-316 — Shared filters such as model, min_user_messages, and include_one_shot are serialized by the HTTP report backend but are not accepted or applied by the activity endpoint. Add support or stop advertising unsupported filters.
internal/service/reports.go:66-77,193 — Direct activity reports default to ExcludeOneShot: true, while the HTTP activity endpoint includes one-shot sessions. PostgreSQL-backed and daemon-backed results therefore differ. Align the default one-shot visibility semantics.
internal/tui/model.go:1235-1239,1285-1292 — Referenced-session and search-match transcript windows use Around without a Limit, producing a zero page size. Consequently, pressing n cannot load additional transcript rows. Track a positive page size or derive continuation state for around-window loads.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
agentsview tui, a full-screen Bubble Tea interface backed by the existing daemon HTTP API and SSE stream rather than direct archive access. It covers session browsing and transcripts, dashboards, usage, activity, trends, insights, pins, trash, recent edits, settings, mutations, exports and publishing, persistent filters, localized labels, and terminal-safe rendering. Shared report services also expand the MCP surface for analytics, activity, trends, pins, insights, and recent edits.Startup serves the client before the initial archive sync completes. Report panels stream independently, session details load concurrently, and transcript and filter-editor work stays bounded by the viewport and render caches. Concurrent sync is normal active status, empty trends remain an input state, and sidebar filters open an explicit keyboard editor with cursor and paste handling.
The implementation deliberately reuses daemon and service contracts instead of adding a second SQLite path. Fixed keybindings and colon commands remain the terminal-specific tradeoff; sidebar text filters are free-form rather than metadata pickers. The main review surfaces are
internal/tui,cmd/agentsview/tui.go, the shared report and message-window changes, anddocs/tui.md.