Skip to content

feat: remote TUI support via aggregate API endpoints #130

@wesm

Description

@wesm

Problem

The TUI only works with local data. CLI commands (search, stats, list-senders, etc.) support remote servers via [remote] config, but the TUI always opens a local SQLite database directly.

For NAS/remote deployments, users can query their archive via CLI but cannot use the interactive TUI to explore it.

Root Cause

The TUI uses query.Engine which requires aggregate operations (Aggregate, SubAggregate, SearchFastWithStats) that the remote HTTP API doesn't expose. The remote store only implements MessageStore (list, get, search).

Proposed Solution

Add aggregate API endpoints to the server and implement a RemoteEngine that satisfies query.Engine over HTTP:

  1. New API endpoints:

    • GET /api/v1/aggregate — group-by aggregation (senders, domains, labels, time, etc.)
    • GET /api/v1/aggregate/sub — drill-down sub-aggregation with filters
    • GET /api/v1/stats/total — total stats with filter options
  2. New RemoteEngine in internal/remote/ that implements query.Engine by calling these endpoints.

  3. Update tui.go to check IsRemoteMode() and use RemoteEngine when remote config is present.

Interface Reference

The query.Engine interface (internal/query/engine.go):

type Engine interface {
    Aggregate(ctx, groupBy, opts) ([]AggregateRow, error)
    SubAggregate(ctx, filter, groupBy, opts) ([]AggregateRow, error)
    ListMessages(ctx, filter) ([]MessageSummary, error)
    GetMessage(ctx, id) (*MessageDetail, error)
    Search(ctx, query, limit, offset) ([]MessageSummary, error)
    SearchFastWithStats(ctx, query, queryStr, filter, statsGroupBy, limit, offset) (*SearchFastResult, error)
    GetTotalStats(ctx, opts) (*TotalStats, error)
    ListAccounts(ctx) ([]AccountInfo, error)
    Close() error
}

Current State

  • CLI remote support works via store_resolver.goremote.Store
  • TUI hardcodes store.Open() at cmd/msgvault/cmd/tui.go:55
  • The limitation is documented in the docs site

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions