feat: Windows .bat launcher for codewhale (v2, rebased + review fixes) (#1861)

* fix: Windows .bat launcher with correct JS escaping and codewhale rebrand

* fix: complete Windows bat release asset handling

---------

Co-authored-by: cy2311 <cy2311@users.noreply.github.com>
Co-authored-by: Hunter B <hmbown@gmail.com>
This commit is contained in:
CY
2026-05-31 15:59:32 +08:00
committed by GitHub
parent ad7e127ef2
commit add5654c30
3 changed files with 37 additions and 3 deletions
+3 -3
View File
@@ -14,7 +14,7 @@ const ASSET_MATRIX = {
arm64: ["codewhale-macos-arm64", "codewhale-tui-macos-arm64"],
},
win32: {
x64: ["codewhale-windows-x64.exe", "codewhale-tui-windows-x64.exe"],
x64: ["codewhale-windows-x64.exe", "codewhale-tui-windows-x64.exe", "codewhale.bat"],
},
};
@@ -112,8 +112,8 @@ function releaseBinaryDirectory() {
function allAssetNames() {
const names = [];
for (const platformAssets of Object.values(ASSET_MATRIX)) {
for (const pair of Object.values(platformAssets)) {
names.push(pair[0], pair[1]);
for (const assets of Object.values(platformAssets)) {
names.push(...assets);
}
}
return Array.from(new Set(names));
+9
View File
@@ -65,3 +65,12 @@ test("known platforms are unaffected by alias map", () => {
});
}
});
test("allAssetNames includes every matrix entry", () => {
const { allAssetNames, allReleaseAssetNames } = require(ARTIFACTS_PATH);
const assetNames = allAssetNames();
assert.ok(assetNames.includes("codewhale-windows-x64.exe"));
assert.ok(assetNames.includes("codewhale-tui-windows-x64.exe"));
assert.ok(assetNames.includes("codewhale.bat"));
assert.ok(allReleaseAssetNames().includes("codewhale.bat"));
});
@@ -10,6 +10,9 @@ const {
detectBinaryNames,
} = require("../../npm/codewhale/scripts/artifacts");
const WINDOWS_LAUNCHER = "codewhale.bat";
const WINDOWS_CLI_ASSET = "codewhale-windows-x64.exe";
async function sha256(filePath) {
const content = await fs.readFile(filePath);
return crypto.createHash("sha256").update(content).digest("hex");
@@ -41,6 +44,9 @@ async function main() {
if (prepareAllAssets) {
for (const assetName of allAssetNames()) {
if (assetName === WINDOWS_LAUNCHER) {
continue;
}
if (assets.some((asset) => asset.target === assetName)) {
continue;
}
@@ -62,6 +68,25 @@ async function main() {
manifestLines.push(`${await sha256(outputPath)} ${asset.target}`);
}
if (assets.some((asset) => asset.target === WINDOWS_CLI_ASSET)) {
const batContent = [
"@echo off",
"where wt >nul 2>nul",
"set NO_ANIMATIONS=1",
'if "%ERRORLEVEL%"=="0" (',
' wt --title CodeWhale cmd /k "%~dp0codewhale-windows-x64.exe"',
") else (",
' "%~dp0codewhale-windows-x64.exe"',
")",
"",
].join("\r\n");
const batPath = path.join(outputDir, WINDOWS_LAUNCHER);
await fs.writeFile(batPath, batContent, "utf8");
const batHash = await sha256(batPath);
manifestLines.push(`${batHash} ${WINDOWS_LAUNCHER}`);
console.log(`Generated ${batPath}`);
}
manifestLines.sort();
const manifestPath = path.join(outputDir, CHECKSUM_MANIFEST);
await fs.writeFile(manifestPath, `${manifestLines.join("\n")}\n`, "utf8");