Skip to content

feat(ui): filter timeline calls#22

Merged
Neal006 merged 3 commits into
Neal006:mainfrom
kernelpanic888:feat/timeline-filter
Jul 7, 2026
Merged

feat(ui): filter timeline calls#22
Neal006 merged 3 commits into
Neal006:mainfrom
kernelpanic888:feat/timeline-filter

Conversation

@kernelpanic888

Copy link
Copy Markdown
Contributor

What & why

Adds the timeline filtering requested in #10:

  • search calls by tool or method name
  • toggle an errors-only view
  • show no matching calls when filters hide every row

I also added a small typed JSON helper in the UI API client so the current TypeScript gate treats response.json() results as the expected response types.

Closes #10.

Checklist

  • npm run check passes (same gate as CI)
  • Tests ride with the code change
  • Commit messages follow conventional commits (feat(scope): ...)
  • Nothing on the traffic path can throw — failures degrade to a plain pipe

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements client-side filtering controls for the UI timeline so users can narrow large call lists by tool/method substring and optionally show only errors, with an empty-state message when filters produce no rows.

Changes:

  • Added reusable timeline filtering helpers (filterTimelineCalls) and corresponding unit tests.
  • Updated the timeline UI to include a search box, an “errors only” toggle, and a “no matching calls” empty state.
  • Introduced a small typed readJson<T> helper for the UI API client to improve TypeScript inference around response.json().

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
ui/src/timeline-filter.ts Adds filtering helpers used by the timeline UI.
ui/src/style.css Styles new timeline filter controls and empty-state row.
ui/src/app.tsx Wires filtering UI into the timeline table and renders empty state.
ui/src/api.ts Adds typed JSON helper for fetch responses.
tests/timeline-filter.test.ts Adds Vitest coverage for timeline filtering behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ui/src/timeline-filter.ts Outdated
import type { Call } from "./api.js";

export function callLabel(call: Call): string {
return call.toolName ?? call.method;
Comment thread ui/src/timeline-filter.ts Outdated
if (!normalizedQuery) {
return true;
}
return callLabel(call).toLowerCase().includes(normalizedQuery);
Comment on lines +23 to +26
it("matches tool or method names case-insensitively", () => {
expect(filterTimelineCalls(calls, "GITHUB", false).map((entry) => entry.id)).toEqual(["1"]);
expect(filterTimelineCalls(calls, "resources", false).map((entry) => entry.id)).toEqual(["2"]);
});
@Neal006

Neal006 commented Jul 7, 2026

Copy link
Copy Markdown
Owner

The hasText guard resolves all three review points cleanly, and your new tests — tools/call matching tool rows, plus the empty-toolName fallback, lock the behavior in. The filter logic reads correctly.

One gap remains before this merges: you fixed the label logic inside the helper but left the two places that actually render it, so filtering and display now disagree. app.tsx:136 (the timeline cell) and app.tsx:185 (the CallDetail heading) still call c.toolName ?? c.method directly.
Since toolNameOf in src/store.ts:199 passes an empty params.name through as "", a tools/call with a blank name now matches your filter but still renders an empty label.

You already export callLabel for exactly this case, so import it and route both sites through callLabel(c). That closes the display edge case and removes the duplicated ?? logic in one move.

One nit you can ignore: !filteredCalls.length shows "no matching calls" even for a genuinely empty session, not just a filtered-out one.

@Neal006
Neal006 merged commit 195a897 into Neal006:main Jul 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI: search / filter in the timeline

3 participants