Skip to content

feat(git-status): configurable max repositories and git timeout; keep unreadable repos listed - #543

Merged
Ark0N merged 1 commit into
Ark0N:masterfrom
opticon454:feat/git-status-limits
Oct 9, 2026
Merged

Ark0N merged 1 commit into
Ark0N:masterfrom
opticon454:feat/git-status-limits

Conversation

@opticon454

@opticon454 opticon454 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

What

The Git status window's two hard limits become per-device settings (App Settings → Header & Panels → Bottom bar):

  • Git status: max repositories — how many repositories to list when the session's folder holds several projects instead of being one (1 to 50, default 12, as before).
  • Git status: git timeout — seconds one git command may run (5 to 120, default 30; it was a fixed 10 s).

Why

Reported on a folder of 26 repositories on a network share: the window said "Showing the first 11 repositories found under this folder." Twelve are read; git status in Archive-Configs took 10.0 s on that share, which is exactly the fixed timeout, so it errored and was dropped without a word. Hence 11 under a limit of 12, with no hint that one was skipped or why (Media took 7.8 s, close behind). Nothing is wrong with the repositories; the share is slow.

Changes

  • GitRunner takes an optional { timeoutMs } third argument (existing fakes that ignore it keep working). runGit uses it (default 30 s instead of the old constant), and the status, rev-parse, discovery and diff paths pass it through.
  • GitOverviewOptions.maxRepos / timeoutMs, clamped by resolveOverviewLimits (clampInt treats an empty or non-numeric value as "not given", not 0). The 30 s discovery cache is now keyed by the limit, so a list cut at 12 cannot answer a request for 30.
  • GET /api/sessions/:id/git-status and /git-diff accept maxRepos and timeout (seconds) query parameters, clamped server-side, so an odd value can never cost more than the module's own ceiling. The overview reports repoLimit. The diff route takes them too, so a repository listed because the limit was raised can still be opened.
  • A repository whose git status fails is kept in the list with status.state: 'error' and the reason (previously dropped). The window shows ⚠ could not read: git timed out, the indicator shows ? N and amber instead of ✓, and the tooltip says "N repositories could not be read".
  • The truncation line names the limit and the fix: "Showing the first 12 of more than 12 repositories under this folder. Raise “Git status: max repositories” in Settings → Bottom bar to see more."
  • Docs (api-reference, Settings Reference, Working With Files) and a changeset.

Tests

  • test/git-workspace-status.test.ts (+5): clampInt, resolveOverviewLimits defaults and both ends of the clamp, the limit and repoLimit with the cache not reused across limits, an unreadable repo kept with its reason, and the timeout reaching every git command.
  • test/routes/git-status-routes.test.ts (+1): the query parameters, clamped, with junk and empty values falling back to the defaults.
  • test/git-status.browser.test.ts (+1): the settings reach the request, clamp on save and never reach the strict PUT /api/settings; an unreadable repository and the truncation line render, and the indicator reads ? 1, not ✓.

… unreadable repos listed

Settings (per device): Git status: max repositories (1-50, default 12) and git timeout (5-120 s, default 30, was a fixed 10). Both go to /git-status and /git-diff as maxRepos / timeout query parameters, clamped server-side (an empty value means the default). A repository whose git status fails stays in the list with the reason instead of being dropped silently, shows as '? N' in the indicator, and the truncation line now names the limit and the setting. The discovery cache is keyed by the limit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
@Ark0N
Ark0N merged commit 1ee566e into Ark0N:master Oct 9, 2026
2 checks passed
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
A lone repository git could not read rendered as a clean, empty one. The
panel took its single-repository view whenever the overview held one row,
and the error row only exists in the list view, so it showed "Nothing
uncommitted / No remote configured" with an empty header while the
indicator said "? 1". The single-repository view now needs a readable
repository and an untruncated overview; anything else takes the list view
(headed "1 repository"), and the tooltip names the unreadable repository
instead of saying "no branch".

The same condition covers a limit of 1 in a folder of several projects,
now that max repositories can go down to 1: the one row shown keeps the
"Showing the first" notice instead of looking like the only repository.

A repeated timeout query parameter reaches the route as an array, and
calling trim() on it answered 500 with an internal message, before the
ownership check. The route now treats a non-string timeout as "default",
like an empty or absent one, and the route test pins it.

The browser test gains the lone-unreadable-repository case (error row,
no "Nothing uncommitted", "? 1", tooltip names the repository) and the
truncated single-row case. Both fail against the unfixed panel.

The git timeout input steps by 1, not 5: the save accepts any whole
number of seconds and step 5 flagged values like 7 as invalid.

Docs: api-reference says repoLimit is only present in the
folder-of-projects case, the Settings Reference and Working With Files
glyph lists mention "? N", and the module header says the repository
count is the caller's maxRepos.

The PR's own changeset is removed; its text goes into the single
combined release changeset.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
Thirteen contributor PRs, each re-checked against its GitHub head, merged
with its own merge commit and landing fixes, reviewed, and gated together
(524 test files, 10194 tests): #559, #552, #550, #556, #551, #546, #542,
#540, #555, #543, #541, #502, #432.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ark0N pushed a commit that referenced this pull request Oct 9, 2026
…oasts, tile and spreadsheet text

- Case picker: the "New or link a case…" and "Case settings…" rows that
  replaced the translated + and gear buttons get zh-CN entries reusing the
  buttons' wording, plus the list's "No cases match".
- App Settings, Bottom bar: the whole group translates as one (heading, the
  four Git status rows with #543's max repositories and git timeout, and
  their descriptions), so it never reads half English. The Git panel's two
  button names, which the new "Git status" key reaches, read naturally too.
- Toasts: the three "Could not open a new window for this ..." errors and
  the dictation-closed warning.
- Spreadsheet preview: "Spreadsheet preview failed (<status>)" gets a
  pattern. Worker refusals map their error code to one user sentence each in
  the renderer (the raw message goes to the console), feature ids read as
  words (pivot tables, external links), and the notice bar translates each
  item before the join; a number format's code passes through untouched.
  The worker and core are unchanged, so their pinned strings and the
  asset version hash stay as they were.
- Header Stats Style Tiles: the connection tile's value word reads in
  Chinese through scoped "Connection tile: <word>" keys, never bare-word
  keys ("retry" is also the orchestrator's Retry button, "LIVE" a resume
  list badge). The indicator cache now includes the UI language, so a
  language switch repaints it on the next update.
- Tile grid: the "Loading…" label was CSS content text the translator
  cannot reach; it is now content: attr(data-loading-label), written through
  the translator when the tile is built and each time it starts loading.

Tests pin every new string (zh differs, no English left, English unchanged)
and fail without these changes: the tile harvest sees the loading label and
the rename field, a CSS guard keeps words out of tile generated content, the
Bottom bar group, the case picker rows and toasts read from their source,
the connection tile across a language switch, and the spreadsheet error
codes, notice bar and status line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Ark0N

Ark0N commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Merged in 1.40.0, thanks @opticon454! Configurable limits, plus keeping a repository git cannot read on the list as ? N, is exactly what big folders and slow shares needed. Applied on the way in (e86c3d1): a lone unreadable repository now takes the list view with its error row instead of rendering as clean and empty, a repeated timeout query parameter no longer answers 500 before the ownership check, the timeout field steps by 1, and the docs mention ? N. The browser test gained both cases, and both fail against the unfixed panel.

@opticon454
opticon454 deleted the feat/git-status-limits branch October 18, 2026 10:44
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.

2 participants