From b8e5d5ea37cc64ffa05352c3fb3130ca59471935 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:18:00 +0200 Subject: Flagged marker for history entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Last of the "should build soon" items from the Burp/ZAP/Caido gap research - Burp's row highlighting and Caido's Findings both serve the same real workflow: mark something interesting mid-engagement, revisit later. Scoped to a boolean flag (★) rather than full free-text notes/comments, which would need their own text-input overlay for comparatively modest extra value over a simple marker - tracked as a real follow-up in PLAN.md, not dropped silently. internal/store: history gains a flagged column (migrated in for existing databases the same way source was) plus Store.SetFlagged and Summary/Entry.Flagged. Search's structured-filter layer (added last commit for status:/source:) gains flagged:true/false alongside them - extractStructured already existed for exactly this kind of "pull it out before it reaches FTS5" filter. internal/ipc gains a "set_flagged" request. cmd/mitmux: 'f' toggles the flag on the selected history row (applied optimistically to local state, persisted async - a drift between local and server state on failure is an acceptable trade-off for a marker this low-stakes), shown as a ★ column in the list and in the detail view's title. store_test.go covers the flagged: parsing (true/false spellings, and a "looks like it but isn't" case - flagged:maybe - falling through as literal search text, matching the existing pattern for status:). Verified live: toggling 'f' shows the star immediately, flagged:true correctly filtered to just that entry, and a direct SQLite check confirmed the flag actually persisted to the database (flagged=1), not just reflected in local UI state. --- internal/store/store_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'internal/store/store_test.go') diff --git a/internal/store/store_test.go b/internal/store/store_test.go index 7999ac3..7fa985a 100644 --- a/internal/store/store_test.go +++ b/internal/store/store_test.go @@ -3,6 +3,8 @@ package store import "testing" func TestExtractStructured(t *testing.T) { + boolPtr := func(b bool) *bool { return &b } + tests := []struct { name string query string @@ -10,12 +12,30 @@ func TestExtractStructured(t *testing.T) { statusSQL string statusArgs []any source string + flagged *bool }{ { name: "plain text only", query: "admin login", remaining: "admin login", }, + { + name: "flagged true", + query: "flagged:true", + remaining: "", + flagged: boolPtr(true), + }, + { + name: "flagged false", + query: "flagged:no", + remaining: "", + flagged: boolPtr(false), + }, + { + name: "not a real flagged token falls through as text", + query: "flagged:maybe", + remaining: "flagged:maybe", + }, { name: "exact status", query: "status:404", @@ -90,6 +110,13 @@ func TestExtractStructured(t *testing.T) { if pred.source != tt.source { t.Errorf("source = %q, want %q", pred.source, tt.source) } + switch { + case pred.flagged == nil && tt.flagged == nil: + case pred.flagged == nil || tt.flagged == nil: + t.Errorf("flagged = %v, want %v", pred.flagged, tt.flagged) + case *pred.flagged != *tt.flagged: + t.Errorf("flagged = %v, want %v", *pred.flagged, *tt.flagged) + } }) } } -- cgit v1.2.3