Files
Bilawal Sidhu b6da93b8ac release: v0.1.0 — one-click install, keyless boot, in-app Provider Settings (#142)
The first formal release.

- One-click install via Pinokio; keyless boot lands on a live Esri World
  Imagery satellite globe with keyless terrain, with automatic OSM fallback
  and graceful degradation when terrain is unavailable.
- Provider Settings (the POWER UP panel): add, replace, or remove API keys
  inside the app; credential files made owner-only before any secret is
  written; external keys shown read-only; the panel refuses shared or proxied
  servers.
- Keyless capability responses for the optional HUD summary and place search.
- Aircraft-identity voice answers cover operator, type, and route, and say so
  plainly when enrichment is unavailable.
- README rewritten keyless-first; concise 0.1.0 changelog section; CI
  workflow included.

Gates: 2,672 unit tests pass / 0 fail, build clean, tracking regression
108/108, map-source tray QA pass, setup doctor ready.
2026-08-31 17:49:45 -05:00

68 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
import { realpathSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { applyPinokioEnvironment } from './pinokio-environment.mjs';
import { isDirectInvocation } from './pinokio-install.mjs';
import { validatePinokioSharing } from './pinokio-preflight.mjs';
const MODULE_PATH = fileURLToPath(import.meta.url);
const ROOT = realpathSync(path.resolve(path.dirname(MODULE_PATH), '..'));
function launchPort(value) {
const port = Number.parseInt(value, 10);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new Error('Pinokio did not supply a valid local port.');
}
return port;
}
export async function loadViteFromCanonicalRoot(
root = ROOT,
loadVite = () => import('vite'),
) {
process.chdir(realpathSync(path.resolve(root)));
return loadVite();
}
async function start() {
applyPinokioEnvironment();
validatePinokioSharing();
const port = launchPort(process.env.PORT);
// Provider Settings routes credential writes to pinokio/ENVIRONMENT (never
// .env) when the app runs under this launcher. The marker is set here — after
// applyPinokioEnvironment, before Vite snapshots process.env — so the
// dev-server endpoint knows which store this launch owns.
process.env.GEV_LAUNCHER = 'pinokio';
console.log('[Pinokio] Local-only launch.');
// Import Vite only after app-scoped blank fields have replaced any merged
// Pinokio-global values. Vite snapshots process.env during configuration.
const { createServer } = await loadViteFromCanonicalRoot();
const server = await createServer({
root: ROOT,
server: {
host: '127.0.0.1',
port,
strictPort: true,
},
});
await server.listen();
server.printUrls();
console.log(`[Pinokio] Ready at http://127.0.0.1:${port}/`);
for (const signal of ['SIGINT', 'SIGTERM']) {
process.once(signal, async () => {
await server.close();
process.exit(0);
});
}
}
if (isDirectInvocation(process.argv[1], MODULE_PATH)) {
start().catch((error) => {
console.error(`[Pinokio] Start refused: ${error.message}`);
process.exitCode = 1;
});
}