Clarify recap scope and range controls#1161
Conversation
Entire-Checkpoint: 96518e6260ce
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0b4335f. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR improves the recap UX by making the recap “scope” (repo selection) and “range” controls clearer in both the static recap rendering and the TUI, including displaying an explicit server-provided time window when available.
Changes:
- Add explicit “window …” rendering for server-provided
since/until, with configurable display timezone. - Improve repo scope display by listing repo names (with an overflow “+N more”) when multiple repos are included.
- Update the recap TUI to support direct range hotkeys (d/w/m/r) and move reload to uppercase
R, with corresponding tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/recap/static_server_test.go | Updates/extends static recap tests for window display and multi-repo scope rendering. |
| cmd/entire/cli/recap/render_static.go | Adds window rendering, repo-scope text selection, and repo name normalization/deduping. |
| cmd/entire/cli/recap/me_recap.go | Extends API response model to include repos list. |
| cmd/entire/cli/recap_tui.go | Adds direct range keybindings and changes reload to R; refactors range setting into setRange. |
| cmd/entire/cli/recap_tui_test.go | Adds coverage for direct range keys and R reload; updates footer expectations. |
Comments suppressed due to low confidence (1)
cmd/entire/cli/recap_tui.go:160
- The reload keybinding was changed to uppercase "R" (and lowercase "r" is now used for the 90d range), but the error screen still instructs users to "Press r to retry" (see View()). Pressing "r" will now change the range to 90d rather than retrying the current range. Update the error prompt and/or the handled key so the retry instruction matches actual behavior (e.g., use "R" for retry).
case "R":
m.requestID++
m.loading = true
m.loadErr = nil
return m, m.fetch(m.requestID)
Entire-Checkpoint: 8515a171f1ec
2110185 to
917e05c
Compare
Entire-Checkpoint: ad59fd9c3cc4
- Wrap the unavailable-transcripts note at the summary box width so large counts at minimum terminal width no longer tear the box border. Adds wrapPlainLine() and summaryContentWidth() helpers. - Log time-parse failures in renderWindow via slog so malformed since/until become diagnosable instead of silently dropped. - Guard visibleTranscriptStatus default arm with a debug log so a future ViewMode addition does not silently zero the diagnostics. - Preserve API-supplied repo order in recapRepoNames so the +N more overflow does not hide the user's primary repo when the server ranks by activity. - setRange now retries on same-key press when a load error is on screen, instead of silently dropping the keystroke. New tests cover ViewBoth Me+Team summing, nil-team safety in ViewTeam, zero/singular pluralization, invalid-timestamp window fallback, and same-range-key retry. The wrap test now uses counts that actually exceed minWidth and asserts the note content is present alongside the existing width check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small follow-ups from review of this PR: 1. Switch render_static.go's debug sites from slog.Default() to the project's logging.Debug helper. The default slog handler routes to stderr (or wherever main configures it); operators triaging "why is the recap window missing?" or "why isn't the transcript note showing?" look in .entire/logs/, which is what logging.Debug writes to. Three sites converted (unknown view mode, since parse, until parse) — passing context.Background() at the call site keeps RenderOptions stable; threading a real ctx is a follow-up if the signature ever changes for unrelated reasons. 2. Document the same-range-retry preserve-resp contract on setRange. The new-range branch nils m.resp; the same-range retry branch intentionally does not, mirroring the 'R' reload behavior — the user is asking for the same data so anything already on screen stays visible under the loading state. Added an assertion to TestRecapTUIModel_SameRangeKeyRetriesAfterError so future refactors can't accidentally nil-out m.resp without the test catching the flicker regression. 3. Document the Repo / Repos precedence contract on MeRecapResponse. recapRepoNames already encodes "Repo wins when set", but reading the struct in isolation a reader can't tell whether Repos is the superset or alternative. The struct-level comment now states the contract and also notes Repos's "most-active-first" ordering that the +N more overflow relies on. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
repoScopeText joins up to three repo names with ", " and the renderer emitted the full context line (agents · repos … · active days) as a single un-wrapped muted line. Three long names like "org/very-long-monorepo-name" easily push the line past the box's inner content width at width 60, tearing the right border. The transcript-note path already handled this correctly via wrapPlainLine + summaryContentWidth; the context line did not. Route the joined context through the same wrap helper. wrapPlainLine breaks on whitespace only, so a single ultra-long repo name still overflows its line — but renderBox truncates overflow lines, the same fallback the transcript note already relies on. No information lost in the common case; preserves the server-ranked repo order so the +N more overflow still hides the least-active repos rather than the user's primary one. Wrap-over-truncate chosen deliberately: truncating long names would obscure which repo is which, and the existing recapRepoNames comment explicitly relies on order conveying activity ranking. Regression test TestRenderStaticRecap_WrapsContextLineWithLongRepoNames at width 60 with three long repo names asserts (1) all three names render, (2) the active-days segment renders, (3) no box line exceeds width 60. Verified to fail against the previous single-line render. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

https://entire.io/gh/entireio/cli/trails/335
Summary
since/untiltimestamps rendered in the local timezone.dday,wweek,mmonth,r90d; keeptas a backward-compatible range cycle and move manual reload toR.Why
Users could see different recap numbers in different terminal windows because the CLI silently scoped to the current repo. The summary only said
1 repo, which made the scoped repo invisible. The range labels also did not explain the exact local-time boundaries behind day/week/month/90d.The API can now report when checkpoint transcript payloads are failed, pending, or empty. Showing that count explains why checkpoint totals can be higher than mapped session totals without promoting missing transcript data into an
Unknownagent row.Testing
mise run checkENTIRE_API_BASE_URL=https://partial.to go run ./cmd/entire recap --static --week --color neverENTIRE_API_BASE_URL=https://partial.to go run ./cmd/entire recap --week --color neverSmoke
72306b36-3ec2-49e2-82a9-c2d0910da6d6, the recap agent list showsCodex,Claude Code, andOpenCode;Unknownis not rendered.144 unavailable transcriptswith the failed/pending/empty breakdown.