fix(windows): stabilize ci path and wsl checks

This commit is contained in:
iliya 2026-04-26 12:04:11 +03:00
parent 3f1c1acb4f
commit 2c3ee3e2e9
3 changed files with 16 additions and 6 deletions

View file

@ -115,11 +115,14 @@ export class TmuxWslService {
};
}
const distros = this.#parseWslDistros(distroListProbe.stdout);
const listedDistros = this.#parseWslDistros(distroListProbe.stdout);
const serviceDistros = listedDistros.filter((distro) => this.#isInternalWslDistro(distro));
const distros = listedDistros.filter((distro) => !this.#isInternalWslDistro(distro));
if (distros.length === 0) {
if (persistedPreferredDistro) {
await this.#preferenceStore.clearPreferredDistro();
}
const hasOnlyServiceDistros = serviceDistros.length > 0;
return {
preference: null,
status: {
@ -134,7 +137,9 @@ export class TmuxWslService {
tmuxBinaryPath: null,
statusDetail: rebootRequired
? 'WSL was installed, but Windows still needs a restart before a Linux distro can be configured.'
: 'WSL is available, but no Linux distribution is installed yet.',
: hasOnlyServiceDistros
? `WSL has only service distributions (${serviceDistros.join(', ')}). Install a Linux distribution such as Ubuntu for teammate runtime support.`
: 'WSL is available, but no Linux distribution is installed yet.',
},
};
}
@ -420,7 +425,6 @@ export class TmuxWslService {
.split(/\r?\n/)
.map((line) => line.replace(/\0/g, '').trim())
.map((line) => line.replace(/^\*\s*/, '').trim())
.filter((line) => !this.#isInternalWslDistro(line))
.filter(Boolean);
}

View file

@ -162,7 +162,8 @@ describe('TmuxWslService', () => {
expect(result.status.wslInstalled).toBe(true);
expect(result.status.distroName).toBeNull();
expect(result.status.statusDetail).toContain('no Linux distribution');
expect(result.status.statusDetail).toContain('only service distributions');
expect(result.status.statusDetail).toContain('docker-desktop');
});
it('switches preference source away from persisted after clearing a stale distro', async () => {

View file

@ -32,6 +32,11 @@ interface ResolveProjectPathOptions {
forceRefresh?: boolean;
}
function isAbsolutePathLike(value: string): boolean {
const slashPath = value.replace(/\\/g, '/');
return path.isAbsolute(value) || /^[a-zA-Z]:\//.test(slashPath) || slashPath.startsWith('//');
}
export class ProjectPathResolver {
private readonly projectsDir: string;
private readonly fsProvider: FileSystemProvider;
@ -66,7 +71,7 @@ export class ProjectPathResolver {
}
const cwdHint = opts.cwdHint?.trim();
if (cwdHint && path.isAbsolute(cwdHint)) {
if (cwdHint && isAbsolutePathLike(cwdHint)) {
this.projectPathCache.set(projectId, cwdHint);
return cwdHint;
}
@ -85,7 +90,7 @@ export class ProjectPathResolver {
for (const sessionPath of sessionPaths.slice(0, maxPathsToInspect)) {
try {
const cwd = await extractCwd(sessionPath, this.fsProvider);
if (cwd && path.isAbsolute(cwd)) {
if (cwd && isAbsolutePathLike(cwd)) {
this.projectPathCache.set(projectId, cwd);
return cwd;
}