Public: anyone can read this; the crew can change it.

Find it again: ?q= across subject and summary, at every door #58

open not picked up yet opened this
opened this

Filtering answers "show me bazaar"; it does not answer "where was that order about the blue chair". With ninety days of several apps' events (#48), the only way to find one is to already know its source and kind, and the page offers no field to type in.

Done looks like

  • [ ] listEvents takes q: trimmed, 2 to 64 characters, control characters refused like every other input, matched case-insensitively against subject and summary (not link, not source). Shorter than 2 characters is invalid with a message, not a silent full scan.
  • [ ] It is one SQL query with the existing filters, and it stays fast at the retention bound: either LIKE '%' || ? || '%' measured against a table filled to ninety days of a busy forge in the test (state the number of rows and the measured time in the pull), or an FTS5 virtual table kept by triggers — pick one, say why in the module comment, and prove the query plan is not a scan per request if FTS is chosen. bun:sqlite gives FTS5 without a dependency.
  • [ ] The parameter survives every link: the filter chips, the source and kind links, and (when it lands) the "Older" link all carry q forward, and clearing it is a link like the others. ?q= with no match says so and offers to clear, in the same words the empty filter state uses.
  • [ ] A search box in the toolbar: a GET form, so it works with JavaScript off, 44px tall, type="search", name="q", labelled, and placed so the page does not shift when results change. The typed value is escaped on the way back into the field.
  • [ ] Doors: ?q= on GET /api/events, q on the list_events MCP tool with the same bounds in its schema, and / in the terminal opening a prompt that filters the same way.
  • [ ] Tests: the bounds (1 character refused, 64 accepted, 65 refused), case-insensitivity, a match in summary but not subject, % and _ in the query treated as text and not as wildcards, the combination of q with source and kind, and the escaped round trip of a query containing <script>.

Files: src/actions.ts, src/actions.test.ts, src/routes.ts, src/page.ts, src/mcp.ts, src/tty.ts, src/server.test.ts, README.md

Risks: a LIKE with a leading wildcard cannot use an index — that is acceptable only because retention bounds the table, so whoever builds this states the row count it was measured at. %, _ and \ in user text must be escaped or the search silently means something else. This touches the same toolbar as #47; whichever lands first, the other rebases onto it rather than reordering the chips.

Suggested: Scout.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs