Repository navigation
Description
What's wrong
Every git command goes through GitCli.Run (ProjectDirector/GitCli.cs:91-107). It calls RunCommand.Execute("git", arguments, handler) with default options. Nothing sets GIT_TERMINAL_PROMPT=0, nothing makes ssh non-interactive (BatchMode), stdin isn't closed, and there's no timeout.
git's HTTPS credential prompt (Username for 'https://github.com':) reads from /dev/tty directly, wherever stdin and stdout point. ssh does the same when it asks to confirm a host key or for a key passphrase. If ProjectDirector is started from a terminal (dotnet run, as CLAUDE.md documents), the child git process inherits that controlling terminal. It then blocks on a prompt the user probably can't see, because the app window is in front. The background task never finishes. Its result reaches the log only after git exits (QueueGitLog, ProjectDirector.cs:264-271), so the log shows nothing.
Effects:
- Clone:
MakeClone(ProjectDirector.cs:831-832) clones the OctokitCloneUrl, which is HTTPS.CloneTrackerkeeps the path in flight until the action returns (CloneTracker.cs:63-82). The Clone button is drawn only when!Clones.IsInFlight(repo.LocalPath)(ProjectDirector.cs:737-739). A clone stuck on a prompt therefore hides the button for the rest of the session, and nothing is logged. - Fetch / pull / push (
ProjectDirector.cs:458-468,520-529,654-660): these tasks never complete.- Today, auto-fetch starts another stuck process for the same repository every 60 s.
- With the bounded
FetchSchedulerin open PR Bound background fetches and run at most one per repository [patch] #518, each stuck fetch holds one of the four slots for good. Four stuck repositories stop all background fetching for the session.
Failure scenario
- On Linux or macOS, have no
credential.helperconfigured, or an expired cached token. - Run
dotnet run --project ProjectDirectorfrom a terminal. - Add an owner with a token so its private repositories are listed, then click Clone on a private repository.
The terminal shows Username for 'https://github.com':. The Clone button disappears and the log panel stays empty until someone answers the prompt or kills git. The same happens with an SSH remote whose host isn't in known_hosts, or with a key that has a passphrase and no agent.
Suggested fix
Pass a CommandOptions from GitCli.Run. ktsu.RunCommand, which is already referenced, supports EnvironmentVariables and StandardInput. Set:
GIT_TERMINAL_PROMPT=0. Missing HTTPS credentials then fail fast withterminal prompts disabled, and that message reaches the log.GIT_SSH_COMMAND=ssh -o BatchMode=yes, but only when the user hasn't setGIT_SSH_COMMANDorcore.sshCommandthemselves.StandardInput = StandardInputMode.Closed.
GUI credential helpers such as Git Credential Manager keep working, because they don't use the terminal.
Optionally, give clone, fetch, pull and push a generous cancellation timeout, so a stalled transfer is reported rather than held forever.
Acceptance criteria
- Cloning or fetching a private HTTPS repository with no credential helper, from a terminal-launched app, ends within seconds.
- The log shows the failure, including git's
terminal prompts disabledmessage. - The Clone button reappears afterwards.
- A
GitCliTestscase runs a network git command that would otherwise prompt, and asserts that it returns rather than blocks.
Related
- Auto-fetch starts a git fetch for every cloned repository at the same moment every minute, with no concurrency limit and no in-flight check #448 mentions a credential-helper prompt only as one reason a fetch can be slow. PR Bound background fetches and run at most one per repository [patch] #518 bounds concurrency but doesn't make git non-interactive.
- "Scan > Dev Dir" and "Scan > GitHub Owners" freeze the window: git subprocesses and GitHub API calls run on the render thread #461 (git running on the render thread) is a separate problem.
Activity
matt-edmondson commentedon Oct 31, 2026
Triage
GitCli.Runoptions.ProjectDirector/GitCli.cs(Run), which affects clone, fetch, pull and push inProjectDirector.csandCloneTracker.csGenerated by Claude Code