Improve TUI search, deletion, and export workflows - #723
Conversation
roborev: Combined Review (
|
247e03c to
c8f1c6f
Compare
roborev: Combined Review (
|
c8f1c6f to
4fa0b70
Compare
roborev: Combined Review (
|
4fa0b70 to
9af74a9
Compare
roborev: Combined Review (
|
3026d35 to
3aa9b3c
Compare
roborev: Combined Review (
|
Add session search history, all-match deletion staging, and configurable attachment exports. Correct export-eml guidance and document Gmail deletion reconciliation.
3aa9b3c to
5c791a3
Compare
roborev: Combined Review (
|
|
reviewing |
Bulk deletion could outlive the TUI request, drift while paging a live archive, and record stale selection details in its manifest. Invalid partial search input could also interrupt typing, and semantic queries were incorrectly parsed as structured searches. Resolve each all-match set in one backend query, preserve its exact filter provenance, and cancel work when the user leaves it. Keep structured validation inline and pass semantic text through unchanged. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
I pushed a follow-up in Here is what changed:
The generated API client was updated for the daemon path. The full tagged Go test suite, |
roborev: Combined Review (
|
An empty aggregate bucket previously became an unconstrained deletion filter. This could stage unrelated Gmail messages instead of the selected empty bucket. Daemon-backed semantic search could also reject natural-language text that looked like an invalid operator. A query-level message type could conflict with the active TUI view and widen the results. Keep empty-bucket predicates through deletion resolution. Send semantic text in a parser-safe form, and intersect message-type constraints before the request. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
Fixed the three follow-up review findings:
I added regression tests for each case. The full test suite, |
roborev: Combined Review (
|
Semantic search needs free text to rank messages. A query with only a matching message type became empty after the client moved that filter into the HTTP parameter, so the daemon returned a missing-query error. Reject filter-only semantic input before it replaces the current results. Keep the same guard in the daemon adapter so non-TUI callers cannot send an empty search request. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
Reviewed both follow-up findings:
I added focused coverage for the semantic case. The full test suite, |
roborev: Combined Review (
|
A search box can contain whitespace or an operator with no value even though the parser finds no search criteria. Bulk deletion treated that raw input as an active search, so a remote daemon received an empty query with a search mode and rejected the request. Treat successfully parsed empty input the same as no search. Preserve malformed query errors, and keep the deletion manifest aligned with the filter-only scope that selected the messages. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
Fixed this follow-up issue. Whitespace and empty operators such as I added focused tests for both the TUI staging record and the exact daemon request. The full test suite, |
roborev: Combined Review (
|
Bulk deletion could resolve a smaller set than the messages shown when a search and a sender, recipient, or domain view filter were both active. Inline search results could also arrive after the input changed or became invalid and replace the current list. Use the same filter composition for displayed and staged matches. Invalidate older search and message-list requests as soon as the inline input or search mode makes them obsolete. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
Fixed both remaining review findings in 7383f92.
I added regression coverage for fast and deep deletion searches, empty-bucket filters, changed input, and invalid input. |
roborev: Combined Review (
|
Aggregate deletion could stage messages hidden by the active search or attachment filter. Remote TUI staging also dropped the complete match criteria before saving through a daemon. Use the displayed aggregate scope for resolution and carry the provenance JSON across the daemon request so staged batches remain accurate and auditable. Generated with Codex Co-authored-by: Codex <noreply@openai.com>
|
Fixed the two latest review findings in
I added a real SQLite regression test for the grouped-row scope and an HTTP round-trip test for the saved filter details. The full test suite, vet, lint, and generated-client consistency check pass. |
roborev: Combined Review (
|
What changed
duses the selection/current row andDresolves every message-list filter or search match in the background before confirmation.[data].export_dirand routed TUI attachment ZIPs, downloads, and opened files through it.export-emlusage and default-filename guidance.Why
Search-heavy cleanup should not require retyping queries or selecting one loaded page at a time. Attachment exports should also have one predictable destination, while the CLI and sync docs should describe the behavior users actually get.
The all-match deletion path keeps source boundaries intact, rejects bounded semantic results, paginates fast and deep searches, stays responsive during resolution, and always presents the final count before a batch is staged.
Closes #40
Closes #41
Closes #44
Closes #72
Closes #88
Usage
dfor the current selection orDfor every filter/search match.export_dirunder[data]to choose where TUI attachment exports land. Relative paths resolve from the config directory; the default is<data_dir>/exports.msgvault export-eml <message-id> [source-message-id], optionally with-o -for stdout.