desktop: tri-platform window chrome, packaging and draft-release CI
This commit is contained in:
@@ -6,7 +6,9 @@
|
||||
* outside that the docs require us to copy: public/ and .next/static/.
|
||||
* This script finishes the job and sanity-checks the result — including
|
||||
* the exclusion that keeps the repo's real data/ OUT of the bundle
|
||||
* (see next.config.ts outputFileTracingExcludes).
|
||||
* (see next.config.ts outputFileTracingExcludes). It also removes two
|
||||
* exact build-only paths the tracer sweeps in: old installers and the
|
||||
* development Electron runtime. Broad trace exclusions break externals.
|
||||
*/
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
@@ -58,6 +60,22 @@ for (const secret of ["auth.json", ".env", ".env.local"]) {
|
||||
}
|
||||
}
|
||||
|
||||
// 2c) Payload curation (2026-10-11): the trace sweep can copy repo-root
|
||||
// dist/ (previous installers, recursively) and the development Electron
|
||||
// runtime (the demo helper's dev-only require). Neither belongs in the
|
||||
// server: packaged helpers use process.execPath, the app's own binary.
|
||||
// Remove ONLY these standalone-root paths AFTER tracing — excluding a
|
||||
// generic dist/** earlier broke pi-ai / pi-agent-core's runtime dist/.
|
||||
// Never touch ROOT/dist or ROOT/node_modules/electron (the running app
|
||||
// and the build runtime); native canvas/resvg packages stay untouched.
|
||||
for (const extra of ["dist", path.join("node_modules", "electron")]) {
|
||||
const target = path.join(STANDALONE, extra);
|
||||
if (exists(target)) {
|
||||
fs.rmSync(target, { recursive: true, force: true });
|
||||
console.log(`[build-server] removed build-only payload: ${extra}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Sanity: the runtime-read prompt assets must be present (the teacher
|
||||
// agent reads them from disk at request time).
|
||||
for (const asset of [
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
* in seconds, not after a full packaging pass.
|
||||
*
|
||||
* What it does: spawns .next/standalone/server.js exactly the way the
|
||||
* Electron shell does (electron/main.cjs) — 127.0.0.1 on a kernel-assigned
|
||||
* Electron shell does (electron/main.cjs) — with --electron it uses
|
||||
* Electron's bundled Node via ELECTRON_RUN_AS_NODE, otherwise host Node —
|
||||
* 127.0.0.1 on a kernel-assigned
|
||||
* free port, NODE_ENV=production, a THROWAWAY LH_DATA_DIR and an EMPTY
|
||||
* LH_AUTH_FILE under os.tmpdir() (no real keys or data ever touch it) —
|
||||
* polls GET / until 200, then probes the GET-only API surface (graph /
|
||||
@@ -23,6 +25,7 @@
|
||||
* way, same day).
|
||||
*/
|
||||
import { spawn } from "node:child_process";
|
||||
import { createRequire } from "node:module";
|
||||
import * as fs from "node:fs";
|
||||
import * as http from "node:http";
|
||||
import * as net from "node:net";
|
||||
@@ -32,6 +35,8 @@ import * as path from "node:path";
|
||||
const ROOT = path.resolve(import.meta.dirname, "..");
|
||||
const STANDALONE = path.join(ROOT, ".next", "standalone");
|
||||
const SERVER = path.join(STANDALONE, "server.js");
|
||||
const ELECTRON_MODE = process.argv.includes("--electron");
|
||||
const RUNTIME = ELECTRON_MODE ? createRequire(import.meta.url)("electron") : process.execPath;
|
||||
|
||||
const POLL_MS = 500;
|
||||
const BOOT_TIMEOUT_MS = 30_000;
|
||||
@@ -95,10 +100,12 @@ async function main() {
|
||||
for (const line of tail.slice(-40)) if (line.trim()) console.error(` ${line}`);
|
||||
};
|
||||
|
||||
const child = spawn(process.execPath, [SERVER], {
|
||||
console.log(`[smoke-server] runtime: ${ELECTRON_MODE ? "Electron bundled Node" : "host Node"}`);
|
||||
const child = spawn(RUNTIME, [SERVER], {
|
||||
cwd: STANDALONE,
|
||||
env: {
|
||||
...process.env,
|
||||
...(ELECTRON_MODE ? { ELECTRON_RUN_AS_NODE: "1" } : {}),
|
||||
NODE_ENV: "production",
|
||||
PORT: String(port),
|
||||
HOSTNAME: "127.0.0.1",
|
||||
|
||||
Reference in New Issue
Block a user