fix(git): normalize discovered nested repository paths on the client

The server joins discovered repository paths with the platform separator
while every other git directory key in the UI is normalized, so on Windows a
discovered repository never matched its own selection or the root prefix the
picker strips. Parse the route's response at the boundary and normalize each
path. Note in the store docs that worktree bootstrap and session machinery
stay keyed on the project root while a nested repository is selected.
This commit is contained in:
Bohdan Triapitsyn
2026-08-30 10:23:26 +03:00
parent f6ffb0a1fe
commit 93fdfa50d5
2 changed files with 11 additions and 7 deletions
+10 -7
View File
@@ -35,6 +35,7 @@ import type {
RevertCommitResponse,
ResetToCommitResponse,
} from './api/types';
import { normalizePath } from './pathNormalization';
import { runtimeFetch } from './runtime-fetch';
import { getRuntimeUrlResolver } from './runtime-url';
import { getRuntimeKey } from './runtime-switch';
@@ -146,16 +147,18 @@ export async function listGitDirectories(root: string): Promise<string[]> {
if (!response.ok) {
throw new Error(`Failed to list git directories: ${response.statusText}`);
}
const data = await response.json();
if (!data || !Array.isArray(data.repositories)) {
// SAFETY: the route is ours (`GET /api/fs/git-dirs`) and answers this exact
// shape on every 2xx; a malformed body fails the array check below.
const data = await response.json() as { repositories?: Array<{ path?: string | null }> };
if (!Array.isArray(data?.repositories)) {
throw new Error('Unexpected git directories response');
}
// The server joins paths with the platform separator; every other git
// directory key in the UI is normalized, so match that here or a Windows
// repository never equals its own selection or root prefix.
return data.repositories
.map((entry: unknown) => {
const path = entry && typeof entry === 'object' && 'path' in entry ? (entry as { path?: unknown }).path : undefined;
return typeof path === 'string' && path.trim() ? path.trim() : null;
})
.filter((path: string | null): path is string => path !== null);
.map((entry) => normalizePath(entry?.path ?? null))
.filter((path): path is string => path !== null);
}
export async function getGitStatus(directory: string, options?: { mode?: 'light' }): Promise<GitStatus> {