feat: Add winget support for uv and go installation on Windows
This commit is contained in:
parent
9e6b45faab
commit
308251c69c
@ -12,6 +12,7 @@ import {
|
||||
hasBinary,
|
||||
loadWorkspaceSkillEntries,
|
||||
resolveSkillsInstallPreferences,
|
||||
resolveRuntimePlatform,
|
||||
type SkillEntry,
|
||||
type SkillInstallSpec,
|
||||
type SkillsInstallPreferences,
|
||||
@ -276,6 +277,28 @@ async function installDownloadSpec(params: {
|
||||
};
|
||||
}
|
||||
|
||||
async function installWithWinget(
|
||||
packageId: string,
|
||||
timeoutMs: number,
|
||||
): Promise<{ code: number | null; stdout: string; stderr: string }> {
|
||||
if (!hasBinary("winget")) {
|
||||
return { code: null, stdout: "", stderr: "winget not found" };
|
||||
}
|
||||
return await runCommandWithTimeout(
|
||||
[
|
||||
"winget",
|
||||
"install",
|
||||
"--id",
|
||||
packageId,
|
||||
"-e",
|
||||
"--silent",
|
||||
"--accept-source-agreements",
|
||||
"--accept-package-agreements",
|
||||
],
|
||||
{ timeoutMs },
|
||||
);
|
||||
}
|
||||
|
||||
async function resolveBrewBinDir(timeoutMs: number, brewExe?: string): Promise<string | undefined> {
|
||||
const exe = brewExe ?? (hasBinary("brew") ? "brew" : resolveBrewExecutable());
|
||||
if (!exe) return undefined;
|
||||
@ -366,10 +389,21 @@ export async function installSkill(params: SkillInstallRequest): Promise<SkillIn
|
||||
code: brewResult.code,
|
||||
};
|
||||
}
|
||||
} else if (resolveRuntimePlatform() === "windows" && hasBinary("winget")) {
|
||||
const result = await installWithWinget("astral-sh.uv", timeoutMs);
|
||||
if (result.code !== 0) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Failed to install uv (winget)",
|
||||
stdout: result.stdout.trim(),
|
||||
stderr: result.stderr.trim(),
|
||||
code: result.code,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
ok: false,
|
||||
message: "uv not installed (install via brew)",
|
||||
message: "uv not installed (install via brew or winget)",
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
code: null,
|
||||
@ -404,10 +438,21 @@ export async function installSkill(params: SkillInstallRequest): Promise<SkillIn
|
||||
code: brewResult.code,
|
||||
};
|
||||
}
|
||||
} else if (resolveRuntimePlatform() === "windows" && hasBinary("winget")) {
|
||||
const result = await installWithWinget("GoLang.Go", timeoutMs);
|
||||
if (result.code !== 0) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Failed to install go (winget)",
|
||||
stdout: result.stdout.trim(),
|
||||
stderr: result.stderr.trim(),
|
||||
code: result.code,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
ok: false,
|
||||
message: "go not installed (install via brew)",
|
||||
message: "go not installed (install via brew or winget)",
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
code: null,
|
||||
|
||||
@ -74,13 +74,17 @@ export function isBundledSkillAllowed(entry: SkillEntry, allowlist?: string[]):
|
||||
export function hasBinary(bin: string): boolean {
|
||||
const pathEnv = process.env.PATH ?? "";
|
||||
const parts = pathEnv.split(path.delimiter).filter(Boolean);
|
||||
const extensions = process.platform === "win32" ? [".exe", ".cmd", ".bat", ""] : [""];
|
||||
|
||||
for (const part of parts) {
|
||||
const candidate = path.join(part, bin);
|
||||
try {
|
||||
fs.accessSync(candidate, fs.constants.X_OK);
|
||||
return true;
|
||||
} catch {
|
||||
// keep scanning
|
||||
for (const ext of extensions) {
|
||||
const candidate = path.join(part, bin + ext);
|
||||
try {
|
||||
fs.accessSync(candidate, fs.constants.X_OK);
|
||||
return true;
|
||||
} catch {
|
||||
// keep scanning
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user