← Files fstackARCHIVED FILE
skills/engineer-mode/scripts/bootstrap.ts
2.1 KB · Oct 5, 2026 · 18:35 UTC
import { createHash } from "node:crypto";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
// This tooling is bun-only (import.meta.dir, Bun.spawnSync, bun.lock). Fail with a
// clear message instead of an opaque `import.meta.dir is undefined` crash under node.
if (typeof Bun === "undefined") {
console.error(
"pstack poteto-mode tooling requires bun (https://bun.sh). Install bun, then re-run."
);
process.exit(1);
}
const scriptsDirectory = import.meta.dir;
const nodeModulesDirectory = join(scriptsDirectory, "node_modules");
const commanderPackagePath = join(
nodeModulesDirectory,
"commander",
"package.json"
);
const installKeyPath = join(
nodeModulesDirectory,
".poteto-mode-tools-install-key"
);
function currentInstallKey(): string {
return createHash("sha256")
.update(readFileSync(join(scriptsDirectory, "package.json")))
.update("\0")
.update(readFileSync(join(scriptsDirectory, "bun.lock")))
.digest("hex");
}
export function ensureDependenciesInstalled(): void {
const installKey = currentInstallKey();
if (
existsSync(commanderPackagePath) &&
existsSync(installKeyPath) &&
readFileSync(installKeyPath, "utf8").trim() === installKey
) {
return;
}
const result = Bun.spawnSync(
[process.execPath, "install", "--frozen-lockfile"],
{ cwd: scriptsDirectory }
);
if (result.exitCode !== 0) {
process.stdout.write(result.stdout);
process.stderr.write(result.stderr);
throw new Error(
`bun install --frozen-lockfile exited with status ${result.exitCode}`
);
}
if (!existsSync(commanderPackagePath)) {
throw new Error(
"bun install --frozen-lockfile completed without installing commander"
);
}
writeFileSync(installKeyPath, `${installKey}\n`);
const restarted = Bun.spawnSync([process.execPath, ...process.argv.slice(1)], {
cwd: process.cwd(),
env: process.env,
stdin: "inherit",
stdout: "inherit",
stderr: "inherit",
});
process.exit(restarted.exitCode ?? 1);
}
SHA-256: ecf9bd5025212cf74c9b3b944da4bd01d8dad2c330fe814c5490a8a3259e4d5b