Debug Search CLI and UI Result Discrepancies · Entire

Search CLI vs UI Audit — Differences Found

1. Types requested: CLI only searches checkpoints, UI searches everything

CLI (search.go:255): Hardcodes types=checkpoints in the query string:

q.Set("types", "checkpoints")

UI (api.ts:10): Passes types from params, which defaults to all types (checkpoints, commits, sessions, repos, prs). The search page doesn't pass types at all in useGlobalSearchQuery, so the API defaults to [ "repos", "checkpoints", "commits", "prs", "sessions" ].

Impact: The CLI only ever gets checkpoint results. The UI gets checkpoints, commits, sessions, PRs, and repos — then filters client-side by type tabs. This means the same query will return different results and different totals.

2. Search mode: CLI uses hybrid (default), UI uses hybrid (default) — same

Both omit the mode parameter, so the server defaults to hybrid. This is consistent.

3. Limit: CLI requests 200, UI requests 100

CLI (search_cmd.go:156): Always overrides limit to MaxLimit = 200 before calling the API.

UI (search.tsx:138): Passes limit: 100.

Impact: CLI fetches up to 200 results, UI fetches up to 100. This can cause different result ordering because the server's tier pipeline and Cohere reranking operates on different sized result sets.

4. Missing parameters: CLI doesn't send mode or filter_type

UI (api.ts:17-18): Can send mode and filter_type params.

CLI (search.go): Never sends mode or filter_type. The Config struct has no fields for these.

Impact: The UI's type-tab filtering (filterType) happens server-side before pagination, so the UI gets correctly paginated type-filtered results. The CLI gets everything mixed together (checkpoints only due to issue #1, but still).

5. Response fields: CLI drops several fields from the response

CLI (search.go:30-65): The CheckpointResult struct is missing:

The CLI Meta struct (search.go:31-35) has matchType, score, and snippet but is missing:

The CLI Response struct (search.go:60-65) is missing:

Impact: The CLI can't display type counts, timing info, or use tier/ranking data for display. The missing commitSubject means the CLI shows raw commit messages where the UI shows parsed subjects.

6. Repo scoping: CLI auto-scopes to current repo, UI doesn't scope by default

CLI (search_cmd.go:99-101): Parses the git remote to get owner/repo and always sends it as the repo param (unless repo:* is used).

UI (search.tsx:101-105): Only sends repo if the user explicitly selects a repo filter.

Impact: CLI searches within the current repo only. UI searches across all accessible repos. This is probably the biggest source of result differences — the same query in the CLI is repo-scoped while the UI is org-wide.

7. Client-side type filtering: UI hides repos and PRs, CLI only gets checkpoints

UI (search.tsx:35): HIDDEN_SEARCH_RESULT_TYPES = new Set(["repo", "pr"]) — filters out repo and PR results from display, then further filters by the selected type tab.

CLI: Only requests checkpoints so this isn't relevant, but it means commits and sessions are never shown.


Summary of Root Causes for Result Differences

Issue CLI UI Impact
Repo scoping Always scoped to current repo All repos by default Biggest difference — CLI misses cross-repo results
Types filter types=checkpoints only All types (checkpoints, commits, sessions, prs, repos) CLI misses commits, sessions
Result limit 200 100 Different reranking due to different candidate pool sizes
Missing response fields No commitSubject, tier, counts, timing Full response Display differences, missing commit subjects

Recommended Fixes

  1. Remove types=checkpoints hardcoding — let the CLI request all types like the UI does, and filter client-side or add a --type flag
  2. Add a --all-repos or make repo scoping opt-in — or at minimum document that CLI is repo-scoped while UI is not
  3. Align the limit — use the same default (100) or make it configurable
  4. Update the CLI CheckpointResult struct to include commitSubject and update Meta/Response to match the full API response shape