import { cpSync, existsSync, readdirSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";import path from "node:path";import { spawnSync } from "node:child_process";import { fileURLToPath } from "node:url"; const packageDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));const distDir = path.join(packageDir, "dist");const bundlePath = path.join(distDir, "standalone.mjs");const runtimePackages = [ "playwright-core", "chromium-bidi", "mitt", "devtools-protocol", "@silvia-odwyer/photon-node", "undici", // pty-service loads node-pty with a dynamic require at runtime, so the // bundler never sees it — it has to travel as real files. Without these the // packaged app's every terminal open failed with "Cannot find module // '@lydell/node-pty'" while the UI kept re-opening the dead terminal. "@lydell/node-pty",]; rmSync(distDir, { recursive: true, force: true });mkdirSync(distDir, { recursive: true }); const build = spawnSync( "bun", [ "build", "src/server.ts", "--target=node", "--external", "fsevents", "--external", "playwright-core", "--external", "@silvia-odwyer/photon-node", "--external", "undici", "--outfile=dist/standalone.mjs", ], { cwd: packageDir, stdio: "inherit" },); if (build.status !== 0) { throw new Error(`Agent runtime bundle failed with status ${build.status ?? "unknown"}`);} // The platform package carries the native prebuild; copy whichever ones the// build machine has installed (darwin-arm64 locally, linux-x64 in CI).const lydellDir = path.join(packageDir, "node_modules", "@lydell");if (existsSync(lydellDir)) { for (const entry of readdirSync(lydellDir)) { if (entry.startsWith("node-pty-")) runtimePackages.push(`@lydell/${entry}`); }} for (const packageName of runtimePackages) { const segments = packageName.split("/"); const source = path.join(packageDir, "node_modules", ...segments); const destination = path.join(distDir, "node_modules", ...segments); if (!existsSync(path.join(source, "package.json"))) { throw new Error(`Missing browser runtime package: ${packageName}`); } mkdirSync(path.dirname(destination), { recursive: true }); cpSync(source, destination, { recursive: true });} const bundle = readFileSync(bundlePath, "utf8");const sourceRoot = realpathSync(path.join(packageDir, "..", ".."));if (bundle.includes(sourceRoot)) { throw new Error(`Agent runtime bundle contains the build-machine root: ${sourceRoot}`);} console.log(`Packaged portable browser runtime: ${runtimePackages.join(", ")}`);
import { cpSync, existsSync,
readdirSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const packageDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
const distDir = path.join(packageDir, "dist");
const bundlePath = path.join(distDir, "standalone.mjs");
const runtimePackages = [
"playwright-core",
"chromium-bidi",
"mitt",
"devtools-protocol",
"@silvia-odwyer/photon-node",
"undici",
// pty-service loads node-pty with a dynamic require at runtime, so the
// bundler never sees it — it has to travel as real files. Without these the
// packaged app's every terminal open failed with "Cannot find module
// '@lydell/node-pty'" while the UI kept re-opening the dead terminal.
"@lydell/node-pty",
];
rmSync(distDir, { recursive: true, force: true });
mkdirSync(distDir, { recursive: true });
const build = spawnSync(
"bun",
[
"build",
"src/server.ts",
"--target=node",
"--external",
"fsevents",
"--external",
"playwright-core",
"--external",
"@silvia-odwyer/photon-node",
"--external",
"undici",
"--outfile=dist/standalone.mjs",
],
{ cwd: packageDir, stdio: "inherit" },
);
if (build.status !== 0) {
throw new Error(`Agent runtime bundle failed with status ${build.status ?? "unknown"}`);
}
// The platform package carries the native prebuild; copy whichever ones the
// build machine has installed (darwin-arm64 locally, linux-x64 in CI).
const lydellDir = path.join(packageDir, "node_modules", "@lydell");
if (existsSync(lydellDir)) {
for (const entry of readdirSync(lydellDir)) {
if (entry.startsWith("node-pty-")) runtimePackages.push(`@lydell/${entry}`);
}
}
for (const packageName of runtimePackages) {
const segments = packageName.split("/");
const source = path.join(packageDir, "node_modules", ...segments);
const destination = path.join(distDir, "node_modules", ...segments);
if (!existsSync(path.join(source, "package.json"))) {
throw new Error(`Missing browser runtime package: ${packageName}`);
}
mkdirSync(path.dirname(destination), { recursive: true });
cpSync(source, destination, { recursive: true });
}
const bundle = readFileSync(bundlePath, "utf8");
const sourceRoot = realpathSync(path.join(packageDir, "..", ".."));
if (bundle.includes(sourceRoot)) {
throw new Error(`Agent runtime bundle contains the build-machine root: ${sourceRoot}`);
}
console.log(`Packaged portable browser runtime: ${runtimePackages.join(", ")}`);