- Session update no longer resets "How often" while typing: updateGitFetchStatus
(session-ui.js) leaves a control alone while it is document.activeElement, and
autoSaveGitFetch writes the clamped interval back itself (Enter saves with the
field still focused).
- Partial override shows the app values: enabled = session ?? app switch,
interval = session ?? app interval ?? 300 (session-ui.js updateGitFetchStatus).
- runFetch (git-fetch.ts) arms the spawn with what the core.sshCommand read left
of timeoutMs, and answers ETIMEDOUT without spawning when nothing is left, so a
git that never answers costs one timeout, not two.
- fetchEnvFor keeps a GIT_SSH from the server's environment (repoSshCommand ||
base.GIT_SSH), fileoverview and CLAUDE.md line updated to say so.
- i18n.js: the zh-CN "Git fetch on an interval" description scopes the only
writing git command to the Git window.
- styles.css: the disabled/busy rules are scoped to .git-status-actions
.btn-icon-sm (moved beside .git-status-actions), and the busy pulse stops
under prefers-reduced-motion.
- Comments that called the override per case now say per session: session.ts
(field, restore and getter docs, setGitFetchSettings), git-fetch-scheduler.ts:2,
server-timing.ts:78, server.ts (cleanup and restore), app.js _onSessionUpdated,
session-ui.js (openSessionOptions and updateGitFetchStatus).
- Tests: test/git-fetch-session-options-ui.test.ts (new, JSDOM: typing survives
an SSE update, the Enter write-back, both partial cases); test/git-fetch.test.ts
(GIT_SSH kept; one bound for the read and the fetch, stub git on PATH).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>