fix: audit fallout — tunnel port, orphaned dev processes, scrollback clear
Auditing for repeats of the `pnpm dev --tunnel` bugs turned up the same mistakes elsewhere. Remote tunnels assumed 4040. ProjectEngine's Cloudflare quick tunnel hardcoded http://localhost:4040, so a dashboard on an explicit --port, a PORT override, or runDashboard's EADDRINUSE rebind published a PUBLIC tunnel to whatever else held 4040. The dashboard now records its bound port (setLocalDashboardPort, from both runDashboard and headless serve) and the tunnel reads it, keeping 4040 only as the pre-report default. register-discovery-routes already derived its port from req.socket.localPort and is untouched. Stopping the dev wrapper orphaned everything it started. It installed no signal handlers, so teardown only ran from the child's close handler: signalling the wrapper left the dev server AND its cloudflared alive — observed twice, four surviving processes each time, including a public trycloudflare URL still serving a dev server believed to be down. Ctrl-C hid it by signalling the whole process group. SessionTerminal appended scrollback instead of clearing first, though the server sends it as a separate frame precisely so the client can clear. Latent today because every reattach builds a fresh xterm; a duplicated-history bug the moment an in-place reconnect appears. And BackupManager's centralDbPath is gone: written, never read, and a leftover of the removed SQLite backup — the same class of stale artifact that onboarding was using as evidence about a Postgres install. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -100,6 +100,7 @@ import {
|
||||
createFusionAuthStorage,
|
||||
createFusionModelRegistry,
|
||||
refreshFusionModelRegistry,
|
||||
setLocalDashboardPort,
|
||||
} from "@fusion/engine";
|
||||
import { setHostTaskStore, clearHostTaskStores } from "../extension.js";
|
||||
import { DefaultPackageManager, SettingsManager, discoverAndLoadExtensions, createExtensionRuntime } from "@earendil-works/pi-coding-agent";
|
||||
@@ -2964,6 +2965,14 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
|
||||
logSink.warn(`Port ${selectedPort} in use, using ${actualPort} instead`, "dashboard");
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:RemoteAccess 2026-08-19-04:00:
|
||||
Publish the bound port to the engine so remote tunnels target THIS dashboard. Before this they
|
||||
pointed at a hardcoded localhost:4040, so a dashboard on any other port (explicit --port, PORT,
|
||||
or the EADDRINUSE rebind just above) tunnelled whatever else owned 4040.
|
||||
*/
|
||||
setLocalDashboardPort(actualPort);
|
||||
|
||||
/*
|
||||
FNXC:DevTunnel 2026-08-19-02:05: report the REAL port to the dev supervisor (no-op without an
|
||||
IPC channel, i.e. every non-`pnpm dev` launch). See DEV_SERVER_LISTENING_MESSAGE.
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
createFusionAuthStorage,
|
||||
createFusionModelRegistry,
|
||||
refreshFusionModelRegistry,
|
||||
setLocalDashboardPort,
|
||||
} from "@fusion/engine";
|
||||
import { setHostTaskStore, clearHostTaskStores } from "../extension.js";
|
||||
import { resolveServeDaemonToken } from "./serve-daemon-token.js";
|
||||
@@ -1105,6 +1106,9 @@ export async function runServe(
|
||||
});
|
||||
|
||||
const actualPort = (server.address() as AddressInfo).port;
|
||||
// FNXC:RemoteAccess 2026-08-19-04:00: headless serve must publish its bound port too, or a remote
|
||||
// tunnel started from it targets a hardcoded 4040. See local-dashboard-port.
|
||||
setLocalDashboardPort(actualPort);
|
||||
logPhase(`startup phase time-to-listen: ${Date.now() - serveStartedAt}ms`);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user