fix: apply the review items for #714 at merge

- 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>
This commit is contained in:
Codeman maintainer committed 2026-10-27 01:58:14 +01:00
1 parent 3411d7f35a
commit 6539bc6c82
12 files changed
+299 -68

No files matched your search

+7 -7
View File
@@ -615,9 +615,9 @@ export class Session extends EventEmitter {
private _keepWarmEnabled: boolean | undefined;
/** Last status the keep-warm service published for this session; ephemeral. */
private _keepWarm: KeepWarmStatus | null = null;
/** Git fetch on an interval for this case; undefined = follow the app-wide default. Persisted. */
/** Git fetch on an interval for this session; undefined = follow the app-wide default. Persisted. */
private _gitFetchEnabled: boolean | undefined;
/** Seconds between this case's fetch runs; undefined = follow the app-wide default. Persisted. */
/** Seconds between this session's fetch runs; undefined = follow the app-wide default. Persisted. */
private _gitFetchIntervalSeconds: number | undefined;
/** Last status the fetch scheduler published for this session; ephemeral. */
private _gitFetch: GitFetchStatus | null = null;
@@ -933,9 +933,9 @@ export class Session extends EventEmitter {
lastRealPromptAt?: number;
/** Restored prompt-cache keep-warm choice (see `keepWarmEnabled`). */
keepWarmEnabled?: boolean;
/** Restored Git fetch override for this case (see `gitFetchEnabled`). */
/** Restored Git fetch override for this session (see `gitFetchEnabled`). */
gitFetchEnabled?: boolean;
/** Restored Git fetch interval for this case (see `gitFetchIntervalSeconds`). */
/** Restored Git fetch interval for this session (see `gitFetchIntervalSeconds`). */
gitFetchIntervalSeconds?: number;
/** Restored conversation chain, oldest first (see `claudeSessionChain`). */
claudeSessionChain?: string[];
@@ -1594,18 +1594,18 @@ export class Session extends EventEmitter {
return changed;
}
/** Git fetch override for this case; undefined means the app-wide setting applies. */
/** Git fetch override for this session; undefined means the app-wide setting applies. */
get gitFetchEnabled(): boolean | undefined {
return this._gitFetchEnabled;
}
/** Interval override for this case; undefined means the app-wide setting applies. */
/** Interval override for this session; undefined means the app-wide setting applies. */
get gitFetchIntervalSeconds(): number | undefined {
return this._gitFetchIntervalSeconds;
}
/**
* Set the case's override. The Session Options rows save on their own, so a caller passes what it has
* Set the session's override. The Session Options rows save on their own, so a caller passes what it has
* and leaves the other half as it was; `undefined` on either means the app-wide setting applies again.
*/
setGitFetchSettings(enabled: boolean | undefined, intervalSeconds: number | undefined): void {