Skip to content

sessions: a search hit carries no time, no siblings and no context #146

Description

@grimmerk

Symptom

A search result today is effectively a boolean: this session contains your word, somewhere, at some point. Three things follow from that, and each was hit in practice:

  1. You cannot tell when the match happened. Results sort by lastTimestamp — the session's last activity — so a session where the word was typed an hour ago sorts below one that merely got touched five minutes ago having mentioned it in June. The session you actually want ends up lower.
  2. A session with many hits shows one. match #N displays a single window. If the word appears twelve times, eleven of them are unreachable without opening the session.
  3. A hit has no surroundings. PR feat(sessions): shorten titles from the middle, window lines to the match #139 made the window follow the match instead of always showing the line's head, which fixed "the row does not show why it matched". It did not give you the sentence before or after — and for a question like "what did I decide about this", the answer is usually adjacent, not inside the matched line.

Proposal

Three pieces over one data change:

  • matchedAt — carry the matched message's timestamp through the search result, not just the fact of a match. Enables sorting by match time, and lets a row say when rather than only where.
  • All hits, not the first — keep the hit list per session so the row can step through them (3/12), rather than recomputing one window.
  • Context around a hit — the message before and after the matched one. This is the smallest useful version of the reader in Feature / TODO list — remaining: detail view, AI Assistant cleanup, remote control #66 and can ship without it.

Why these belong together

They are one pipeline change and three presentations of it. Search currently returns "does this session match"; all three want it to return which messages matched, when, and where in the file. Doing them separately means rewriting the same plumbing three times — the same argument that groups #140's parser work in #144's group A.

Related, deliberately separate: #141 answers which field matched. Same result object, different axis (field identity vs. position and time), and each is useful without the other.

Open questions

  1. Default sort. Should search results sort by match time, or keep session last-activity? Leaning: keep today's default and offer a toggle — changing the default makes "find what I was just working on" harder, which is the more common case.
  2. Vertical space. A menu-bar popup row already carries title, first/last prompt, branch, badges and possibly a match #N line. 3/12 plus context lines cannot all be always-on; probably progressive — the count inline, context only on an expanded row.

Cost note

Reading the extra data is not the expensive part: on the largest transcript in the corpus (62MB) a grep -oE sweep runs in 0.052s. The cost is in the result plumbing and the UI, not the scan.

Priority

Medium. Group D in #144, after the search-aiming work in group A — aiming the query reduces how often you need to navigate a noisy result at all.

🤖 On behalf of @grimmerk — generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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