2025-06-20 16:10:07 +01:00
|
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
2025-06-27 18:14:25 +01:00
|
|
|
|
const { execSync, spawn } = require("child_process");
|
2025-06-20 21:05:30 +01:00
|
|
|
|
const path = require("path");
|
|
|
|
|
|
const fs = require("fs");
|
2025-06-20 16:10:07 +01:00
|
|
|
|
|
2025-09-22 17:14:03 +01:00
|
|
|
|
// Resolve effective arch for our published 64-bit binaries only.
|
|
|
|
|
|
// Any ARM → arm64; anything else → x64. On macOS, handle Rosetta.
|
|
|
|
|
|
function getEffectiveArch() {
|
2025-07-01 00:32:18 +01:00
|
|
|
|
const platform = process.platform;
|
|
|
|
|
|
const nodeArch = process.arch;
|
2025-06-20 21:05:30 +01:00
|
|
|
|
|
2025-09-22 17:14:03 +01:00
|
|
|
|
if (platform === "darwin") {
|
|
|
|
|
|
// If Node itself is arm64, we’re natively on Apple silicon
|
|
|
|
|
|
if (nodeArch === "arm64") return "arm64";
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise check for Rosetta translation
|
|
|
|
|
|
try {
|
|
|
|
|
|
const translated = execSync("sysctl -in sysctl.proc_translated", {
|
|
|
|
|
|
encoding: "utf8",
|
|
|
|
|
|
}).trim();
|
|
|
|
|
|
if (translated === "1") return "arm64";
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// sysctl key not present → assume true Intel
|
|
|
|
|
|
}
|
|
|
|
|
|
return "x64";
|
2025-06-27 18:14:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-22 17:14:03 +01:00
|
|
|
|
// Non-macOS: coerce to broad families we support
|
|
|
|
|
|
if (/arm/i.test(nodeArch)) return "arm64";
|
2025-06-27 16:18:35 +01:00
|
|
|
|
|
2025-09-22 17:14:03 +01:00
|
|
|
|
// On Windows with 32-bit Node (ia32), detect OS arch via env
|
|
|
|
|
|
if (platform === "win32") {
|
|
|
|
|
|
const pa = process.env.PROCESSOR_ARCHITECTURE || "";
|
|
|
|
|
|
const paw = process.env.PROCESSOR_ARCHITEW6432 || "";
|
|
|
|
|
|
if (/arm/i.test(pa) || /arm/i.test(paw)) return "arm64";
|
2025-06-27 18:14:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
return "x64";
|
|
|
|
|
|
}
|
2025-06-27 18:14:25 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
const platform = process.platform;
|
2025-09-22 17:14:03 +01:00
|
|
|
|
const arch = getEffectiveArch();
|
2025-06-27 16:18:35 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
// Map to our build target names
|
|
|
|
|
|
function getPlatformDir() {
|
|
|
|
|
|
if (platform === "linux" && arch === "x64") return "linux-x64";
|
|
|
|
|
|
if (platform === "linux" && arch === "arm64") return "linux-arm64";
|
|
|
|
|
|
if (platform === "win32" && arch === "x64") return "windows-x64";
|
|
|
|
|
|
if (platform === "win32" && arch === "arm64") return "windows-arm64";
|
|
|
|
|
|
if (platform === "darwin" && arch === "x64") return "macos-x64";
|
|
|
|
|
|
if (platform === "darwin" && arch === "arm64") return "macos-arm64";
|
|
|
|
|
|
|
|
|
|
|
|
console.error(`❌ Unsupported platform: ${platform}-${arch}`);
|
|
|
|
|
|
console.error("Supported platforms:");
|
|
|
|
|
|
console.error(" - Linux x64");
|
|
|
|
|
|
console.error(" - Linux ARM64");
|
|
|
|
|
|
console.error(" - Windows x64");
|
|
|
|
|
|
console.error(" - Windows ARM64");
|
|
|
|
|
|
console.error(" - macOS x64 (Intel)");
|
|
|
|
|
|
console.error(" - macOS ARM64 (Apple Silicon)");
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
2025-06-27 18:14:25 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
function getBinaryName(base) {
|
|
|
|
|
|
return platform === "win32" ? `${base}.exe` : base;
|
|
|
|
|
|
}
|
2025-06-27 18:14:25 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
const platformDir = getPlatformDir();
|
|
|
|
|
|
const extractDir = path.join(__dirname, "..", "dist", platformDir);
|
|
|
|
|
|
const isMcpMode = process.argv.includes("--mcp");
|
2025-06-20 21:05:30 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
// ensure output dir
|
|
|
|
|
|
fs.mkdirSync(extractDir, { recursive: true });
|
2025-06-27 18:14:25 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
function extractAndRun(baseName, launch) {
|
|
|
|
|
|
const binName = getBinaryName(baseName);
|
|
|
|
|
|
const binPath = path.join(extractDir, binName);
|
2025-06-27 18:14:25 +01:00
|
|
|
|
const zipName = `${baseName}.zip`;
|
|
|
|
|
|
const zipPath = path.join(extractDir, zipName);
|
2025-06-27 16:18:35 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
// clean old binary
|
|
|
|
|
|
if (fs.existsSync(binPath)) fs.unlinkSync(binPath);
|
2025-06-27 18:14:25 +01:00
|
|
|
|
if (!fs.existsSync(zipPath)) {
|
|
|
|
|
|
console.error(`❌ ${zipName} not found at: ${zipPath}`);
|
|
|
|
|
|
console.error(`Current platform: ${platform}-${arch} (${platformDir})`);
|
2025-06-27 16:18:35 +01:00
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
// extract
|
|
|
|
|
|
const unzipCmd =
|
|
|
|
|
|
platform === "win32"
|
|
|
|
|
|
? `powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${extractDir}' -Force"`
|
|
|
|
|
|
: `unzip -qq -o "${zipPath}" -d "${extractDir}"`;
|
|
|
|
|
|
execSync(unzipCmd, { stdio: "inherit" });
|
|
|
|
|
|
|
|
|
|
|
|
// perms & launch
|
|
|
|
|
|
if (platform !== "win32") {
|
|
|
|
|
|
try {
|
|
|
|
|
|
fs.chmodSync(binPath, 0o755);
|
2025-07-07 10:39:12 +01:00
|
|
|
|
} catch { }
|
2025-06-27 18:14:25 +01:00
|
|
|
|
}
|
2025-07-01 00:32:18 +01:00
|
|
|
|
return launch(binPath);
|
|
|
|
|
|
}
|
2025-06-27 16:18:35 +01:00
|
|
|
|
|
2025-07-01 00:32:18 +01:00
|
|
|
|
if (isMcpMode) {
|
|
|
|
|
|
extractAndRun("vibe-kanban-mcp", (bin) => {
|
2025-08-14 15:35:59 +01:00
|
|
|
|
const proc = spawn(bin, [], { stdio: "inherit" });
|
2025-07-01 00:32:18 +01:00
|
|
|
|
proc.on("exit", (c) => process.exit(c || 0));
|
|
|
|
|
|
proc.on("error", (e) => {
|
|
|
|
|
|
console.error("❌ MCP server error:", e.message);
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
});
|
|
|
|
|
|
process.on("SIGINT", () => {
|
|
|
|
|
|
console.error("\n🛑 Shutting down MCP server...");
|
|
|
|
|
|
proc.kill("SIGINT");
|
|
|
|
|
|
});
|
|
|
|
|
|
process.on("SIGTERM", () => proc.kill("SIGTERM"));
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.log(`📦 Extracting vibe-kanban...`);
|
|
|
|
|
|
extractAndRun("vibe-kanban", (bin) => {
|
|
|
|
|
|
console.log(`🚀 Launching vibe-kanban...`);
|
|
|
|
|
|
if (platform === "win32") {
|
|
|
|
|
|
execSync(`"${bin}"`, { stdio: "inherit" });
|
|
|
|
|
|
} else {
|
|
|
|
|
|
execSync(`"${bin}"`, { stdio: "inherit" });
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-06-20 16:10:07 +01:00
|
|
|
|
}
|