* perf(backend): cap cumulative diff bytes and file count during large rebases
* perf(web): coalesce cumulative-diff refetches and skip redundant status compares
* feat(web): warn when the changes panel hides files from a capped diff
* fix(backend): enforce cumulative diff total byte budget strictly
* fix(web): keep coalesced refetch timer shared across envKey subscribers
* fix(web): drop unsound git-status SHA fast-path that staled live diffs
* fix(web): cancel coalesced timer on mid-flight drain to avoid duplicate refetch
* refactor(web): move changes-panel banner and helper to a sibling file
* docs(backend): clarify cumulative diff truncated-files-count semantics
* fix(web): tighten useSelectedFileKey mode param to the all|file union
* fix(backend): force fresh git status on session subscribe
Every new WS subscriber to a session now triggers a fresh `git status
--porcelain` in agentctl instead of replaying the cached snapshot.
This makes the cache an optimization for already-subscribed observers
only — a fresh observer revalidates ground truth on every connect, so
a stale cache (e.g. left over when the poll loop missed a HEAD change
in paused mode or dropped a tick) self-heals on the next subscribe.
- `?fresh=true` on `/api/v1/git/status/multi` propagates through to
`WorkspaceTracker.GetGitStatus(ctx, true)`.
- New `GetGitStatusMultiFresh` client method; `tryGetLiveGitStatus`
(the session-subscribe hydration path) uses it.
- Regression test reproduces the bug: dirty file → cache primed →
commit without refresh → cached read still shows the file as
modified; fresh=true returns the clean truth.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: address PR review feedback
- Reframe regression-test precondition comment so it reads as scenario
setup (Claude review).
- Document GetGitStatusMultiFresh's read-only-vs-cache contract in its
godoc so a future reader doesn't try to write the result back into
the tracker's currentStatus (Claude review).
- Trim multi-line block comment in helpers.go to a single line per the
backend AGENTS.md convention (Claude review).
- Parallelize handleGitStatusMulti's per-repo fan-out via sync.WaitGroup
to keep the fresh-path wall-clock close to the slowest single repo
regardless of repo count, so multi-repo workspaces don't blow past
the 2s subscribe-path timeout (Greptile review). Pre-sized result
slice means each goroutine writes its own slot — no shared-slice
contention. collectStatusForRepo now takes context.Context directly
instead of *gin.Context.
- Add a third assertion in the regression test that locks in the
documented cache-unchanged contract — after fresh=true, a subsequent
GetGitStatus(ctx, false) call must still return the stale cached
value, so any future change that silently writes through fresh would
fail the test (Greptile review).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: address round 2 review feedback
- Trim the parallelization rationale in handleGitStatusMulti to a
single line per AGENTS.md convention (Claude review).
- Drop unused GetGitStatusMulti client method (cached variant) and its
internal getGitStatusMulti helper — only GetGitStatusMultiFresh has
a caller after this PR, and AGENTS.md says to delete unused code
outright (Claude review).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>