+22
-20
@@ -12,3 +12,2 @@ // `gorilator serve` — the foreground process the OS service supervises. Runs the | ||
| import { clientDist, envFile, serverDir } from "../lib/paths.js"; | ||
| import { which } from "../lib/proc.js"; | ||
| export function serve(opts) { | ||
@@ -38,9 +37,21 @@ // Prefer the saved install record unless --dir was given explicitly. | ||
| env.GORILATOR_UPDATE_LOG = join(appDir, ".gorilator-update.log"); | ||
| // Developer mode (toggled in `gorilator setup → Developer`): instead of serving | ||
| // the production build, run the project's live dev server (Vite HMR + tsx) so | ||
| // the in-game Dev Mode editor + hot reload are available. Mock Nostr login is | ||
| // explicitly suppressed (VITE_NO_MOCK_NOSTR) so a reachable dev server can't be | ||
| // used to impersonate any npub. | ||
| // Developer mode (toggled in `gorilator setup → Developer`) serves the SAME | ||
| // single-port build as production — ONE process answers the game page, the | ||
| // WebSocket, monitor, and API on one port, behind ONE Cloudflare tunnel | ||
| // (permanent or temporary) — but with NODE_ENV=development so the server runs | ||
| // its development code paths. The port manager and tunnel behave identically to | ||
| // production; the only difference is the environment. | ||
| // | ||
| // The live Vite HMR + in-game Dev Mode editor is a LOCAL workflow (two ports on | ||
| // localhost): run `gorilator start` inside a checkout, or `pnpm dev`. A public, | ||
| // tunneled host stays single-port — running Vite there is heavier and would | ||
| // need a second tunnel. Mock Nostr login is suppressed (VITE_NO_MOCK_NOSTR) so a | ||
| // reachable server can't be used to impersonate any npub. | ||
| const devMode = env.GORILATOR_DEV === "1"; | ||
| const child = devMode ? spawnDevServer(appDir, env) : spawnProdServer(appDir, env); | ||
| if (devMode) { | ||
| env.NODE_ENV = "development"; | ||
| env.VITE_NO_MOCK_NOSTR = "1"; | ||
| log.info("Developer mode: serving the dev build (NODE_ENV=development) on one port."); | ||
| } | ||
| const child = spawnProdServer(appDir, env); | ||
| const forward = (sig) => { | ||
@@ -67,4 +78,6 @@ if (child.pid) { | ||
| } | ||
| /** Production: same node that runs the CLI runs the built server via tsx — no | ||
| * reliance on the service PATH; tsx resolves from packages/server/node_modules. */ | ||
| /** Run the built server via tsx — the same node that runs the CLI, so there's no | ||
| * reliance on the service PATH (tsx resolves from packages/server/node_modules). | ||
| * The server serves the built client via CLIENT_DIST, so one process answers the | ||
| * game page AND the WebSocket on one port (production AND developer mode). */ | ||
| function spawnProdServer(appDir, env) { | ||
@@ -77,12 +90,1 @@ return spawn(process.execPath, ["--import", "tsx", "src/index.ts"], { | ||
| } | ||
| /** Developer mode: run the project's live dev server (`pnpm dev` → Vite HMR + | ||
| * tsx watch) from the repo root, with dev features on but mock login off. */ | ||
| function spawnDevServer(appDir, baseEnv) { | ||
| const env = { ...baseEnv }; | ||
| env.NODE_ENV = "development"; | ||
| env.VITE_NO_MOCK_NOSTR = "1"; // never expose ?mocknostr on a managed dev server | ||
| delete env.CLIENT_DIST; // Vite serves the client in dev, not the built bundle | ||
| log.info("Developer mode: starting the live dev server (Vite + tsx)…"); | ||
| const pnpm = which("pnpm") ?? "pnpm"; | ||
| return spawn(pnpm, ["dev"], { cwd: appDir, env, stdio: "inherit" }); | ||
| } |
+12
-19
@@ -5,3 +5,3 @@ // `gorilator setup` — interactive configuration for the native deploy. The | ||
| import { existsSync, readFileSync, writeFileSync } from "node:fs"; | ||
| import { buildClient, pnpmInstall } from "../lib/build.js"; | ||
| import { buildClient } from "../lib/build.js"; | ||
| import { logsCmd } from "./service.js"; | ||
@@ -126,4 +126,5 @@ import { installId, loadConfig, updateConfig } from "../lib/config.js"; | ||
| /** Developer tools. Currently a single toggle: when ON, `gorilator serve` runs | ||
| * the live dev server (Vite HMR + tsx, in-game Dev Mode editor) instead of the | ||
| * production build — see commands/serve.ts. Mock Nostr login stays disabled. */ | ||
| * the daemon with NODE_ENV=development — same single-port build + tunnel as | ||
| * production, just the development environment (see commands/serve.ts). Mock | ||
| * Nostr login stays disabled. */ | ||
| async function developerMenu(opts) { | ||
@@ -134,3 +135,3 @@ for (;;) { | ||
| const choice = await selectMenu(`Developer\n Dev mode is ${on ? "ON" : "off"}\n`, [ | ||
| { label: on ? "Turn dev mode OFF" : "Turn dev mode ON", hint: on ? "back to production build" : "live dev server (Vite + tsx)" }, | ||
| { label: on ? "Turn dev mode OFF" : "Turn dev mode ON", hint: on ? "back to production env" : "dev env (single port, NODE_ENV=development)" }, | ||
| { label: "Back" }, | ||
@@ -144,21 +145,13 @@ ]); | ||
| } | ||
| /** Switch the system install between the production build and the development | ||
| * environment (live dev server). Exported so the Main Menu can offer it too. */ | ||
| /** Switch the system install between the production and development environments. | ||
| * Both serve the built client on one port behind one tunnel — dev mode only sets | ||
| * NODE_ENV=development. Exported so the Main Menu can offer it too. */ | ||
| export function toggleDevMode(opts, on) { | ||
| const ctx = requireInstall(opts); | ||
| if (on && !confirm("Run this server in DEVELOPMENT mode (Vite HMR + tsx, in-game Dev Mode editor)? Heavier to run; not for a public production host.")) { | ||
| if (on && !confirm("Run this server in DEVELOPMENT mode (NODE_ENV=development)? Same single port + tunnel as production.")) { | ||
| return; | ||
| } | ||
| if (on) { | ||
| // The dev server runs `pnpm dev` (Vite), whose build-only deps a prebuilt | ||
| // (slim) install skips. Ensure the full dependency set is present first. | ||
| log.info("Ensuring developer dependencies are installed (Vite + build tools)…"); | ||
| try { | ||
| pnpmInstall(ctx.appDir); | ||
| } | ||
| catch (e) { | ||
| log.warn(`Could not install dev dependencies: ${e.message}`); | ||
| } | ||
| } | ||
| writeEnvPatch(ctx, { GORILATOR_DEV: on ? "1" : "" }, on ? "Dev mode ON — the daemon will run the live dev server." : "Dev mode off — back to the production build."); | ||
| writeEnvPatch(ctx, { GORILATOR_DEV: on ? "1" : "" }, on | ||
| ? "Dev mode ON — the daemon runs in the development environment (single port)." | ||
| : "Dev mode off — back to the production environment."); | ||
| restartDaemon(); | ||
@@ -165,0 +158,0 @@ pause(); |
+2
-2
| { | ||
| "name": "gorilator", | ||
| "version": "1.8.0", | ||
| "version": "1.8.1", | ||
| "description": "One command to install, run, and supervise the Gorilator RPG game server natively (no Docker) as a systemd/launchd service, with an optional Cloudflare Tunnel setup.", | ||
@@ -17,3 +17,3 @@ "type": "module", | ||
| "scripts": { | ||
| "build": "tsc -p tsconfig.json", | ||
| "build": "tsc -p tsconfig.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"", | ||
| "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput", | ||
@@ -20,0 +20,0 @@ "start": "tsx src/index.ts", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
273540
-0.04%6547
-0.08%