mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
90 lines
2.9 KiB
JavaScript
90 lines
2.9 KiB
JavaScript
#!/usr/bin/env node
|
|
"use strict";
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const { getUnsupportedNodeVersionMessage, isNodeVersionSupported } = require("./node-version");
|
|
|
|
if (!isNodeVersionSupported(process.versions.node)) {
|
|
console.error(getUnsupportedNodeVersionMessage(process.versions.node));
|
|
process.exit(1);
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const { spawn } = require("child_process");
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const path = require("path");
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const fs = require("fs");
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const { parseLaunchOptions } = require("./pi-web-options");
|
|
|
|
const pkgDir = path.join(__dirname, "..");
|
|
const nextDir = path.join(pkgDir, ".next");
|
|
|
|
// Resolve next's CLI entry directly to avoid relying on .bin symlinks (which
|
|
// may not exist when installed via npx).
|
|
let nextBin;
|
|
try {
|
|
nextBin = require.resolve("next/dist/bin/next", { paths: [pkgDir] });
|
|
} catch {
|
|
// Fallback: locate next package root and derive the bin path manually.
|
|
try {
|
|
const nextPkg = require.resolve("next/package.json", { paths: [pkgDir] });
|
|
nextBin = path.join(path.dirname(nextPkg), "dist", "bin", "next");
|
|
} catch {
|
|
nextBin = path.join(pkgDir, "node_modules", "next", "dist", "bin", "next");
|
|
}
|
|
}
|
|
|
|
const { port, hostname, openBrowser } = parseLaunchOptions();
|
|
const loopbackHostnames = new Set(["127.0.0.1", "localhost", "::1", "[::1]"]);
|
|
|
|
if (!fs.existsSync(nextDir)) {
|
|
console.error("Build artifacts not found. Please report this issue.");
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!loopbackHostnames.has(hostname)) {
|
|
console.warn(
|
|
`Warning: pi-web is listening on ${hostname} without authentication. Only use this on a trusted network.`,
|
|
);
|
|
}
|
|
|
|
const nextArgs = ["start", "-p", port];
|
|
nextArgs.push("-H", hostname);
|
|
|
|
// Always run next's JS entry with node directly — avoids .bin symlink issues
|
|
// and path-with-spaces problems on Windows when shell: true is used.
|
|
const child = spawn(process.execPath, [nextBin, ...nextArgs], {
|
|
cwd: pkgDir,
|
|
stdio: ["inherit", "pipe", "inherit"],
|
|
env: { ...process.env, PI_WEB_HOSTNAME: hostname },
|
|
});
|
|
|
|
let browserOpened = false;
|
|
const url = `http://${hostname}:${port}`;
|
|
|
|
child.stdout.on("data", (chunk) => {
|
|
const text = chunk.toString();
|
|
process.stdout.write(text);
|
|
if (openBrowser && !browserOpened && text.includes("Ready")) {
|
|
browserOpened = true;
|
|
const isWindows = process.platform === "win32";
|
|
const isMac = process.platform === "darwin";
|
|
const openCmd = isWindows ? "start" : isMac ? "open" : "xdg-open";
|
|
const opener = spawn(openCmd, [url], {
|
|
shell: isWindows,
|
|
stdio: "ignore",
|
|
detached: true,
|
|
});
|
|
|
|
opener.on("error", (error) => {
|
|
console.warn(`Could not open browser automatically: ${error.message}`);
|
|
});
|
|
|
|
opener.unref();
|
|
}
|
|
});
|
|
|
|
child.on("exit", (code) => process.exit(code ?? 0));
|