@agimon-ai/po-core 0.0.0-alpha.83 → 0.0.0-alpha.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -198,7 +198,9 @@ function createTunnelLauncher(options) {
198
198
  if (stopped) return;
199
199
  const outcome = await single(supervisedInput);
200
200
  if (stopped) {
201
- if (outcome.ok) await outcome.stop().catch(() => void 0);
201
+ if (outcome.ok) await outcome.stop().catch((error) => {
202
+ notice(`Could not stop recovered tunnel: ${String(error)}`);
203
+ });
202
204
  return;
203
205
  }
204
206
  if (!outcome.ok) {
@@ -239,8 +241,12 @@ function createTunnelLauncher(options) {
239
241
  recoveryAbort.abort();
240
242
  const recovering = recoveryPromise;
241
243
  stopPromise = (async () => {
242
- await activeStop?.().catch(() => void 0);
243
- await recovering?.catch(() => void 0);
244
+ await activeStop?.().catch((error) => {
245
+ notice(`Could not stop tunnel: ${String(error)}`);
246
+ });
247
+ await recovering?.catch((error) => {
248
+ notice(`Tunnel recovery cleanup failed: ${String(error)}`);
249
+ });
244
250
  await node_fs_promises.default.rm(node_path.default.join(options.stateDir, PID_FILE), { force: true });
245
251
  await node_fs_promises.default.rm(node_path.default.join(options.stateDir, TOKEN_FILE), { force: true });
246
252
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["path","fs","readFileSync","spawn","describeTunnelFailure","tunnelArgs","PAIRING_PAGE_ROUTE","extractTunnelUrl","mentionsRegisteredConnection"],"sources":["../../../../src/services/tunnelProcess/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync, rmSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { PAIRING_PAGE_ROUTE } from '../../constants/remote';\nimport {\n type TunnelConfig,\n type TunnelLauncher,\n type TunnelStartInput,\n type TunnelStartResult,\n} from '../../types/remote';\nimport { PAIRING_PAGE_MARKER } from '../pairingPage';\nimport { describeTunnelFailure, extractTunnelUrl, mentionsRegisteredConnection, tunnelArgs } from '../tunnelOutput';\n\n/** Explicit binary path, ahead of a PATH scan. */\nexport const CLOUDFLARED_ENV = 'PO_CLOUDFLARED';\n// Give new quick-host DNS and negative caches time to settle, within a bounded startup.\nconst START_TIMEOUT_MS = 120_000;\nconst TERMINATE_GRACE_MS = 2000;\nconst SELF_TEST_ATTEMPTS = 240;\nconst SELF_TEST_RETRY_MS = 500;\nconst NAMED_RESTART_ATTEMPTS = 3;\nconst NAMED_RESTART_BASE_DELAY_MS = 500;\nconst NAMED_RESTART_MAX_DELAY_MS = 4000;\nconst NAMED_RESTART_STABLE_MS = 60_000;\n/** Lines of process output kept for a failure report. */\nconst LOG_TAIL = 20;\nconst UNAUTHORIZED = 401;\n/** Cloudflare has the DNS route but no connector has registered yet. */\nconst EDGE_TUNNEL_UNAVAILABLE = 530;\nconst OK = 200;\nconst PID_FILE = 'tunnel.pid';\nconst TOKEN_FILE = 'tunnel.token';\nconst FILE_MODE = 0o600;\n/** A pid file older than this is stale beyond usefulness and the pid has likely been recycled. */\nconst PID_FILE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface ProbeResult {\n status: number;\n body: string;\n}\n\nexport interface TunnelProcessOptions {\n /** Explicit binary, ahead of the env var and the PATH scan. */\n cloudflaredPath?: string;\n stateDir: string;\n onNotice?: (message: string) => void;\n /** Test seam: stands in for node:child_process.spawn. */\n spawnProcess?: typeof spawn;\n /** Test seam: reaches the tunnel from outside, so the self-test needs no network. */\n probe?: (url: string, signal: AbortSignal) => Promise<ProbeResult>;\n /** Test seam: production waits briefly for a new public hostname to propagate. */\n selfTestRetryMs?: number;\n /** Test seam: production bounds the complete startup, including its self-test. */\n startTimeoutMs?: number;\n /** Test seam: production backs named-tunnel restarts off from 500 ms. */\n restartBaseDelayMs?: number;\n /** Test seam: production resets the rapid-crash budget after one stable minute. */\n restartStableMs?: number;\n /** Called after a quick tunnel exits, or after named-tunnel recovery is exhausted. */\n onExit?: (message: string) => void;\n}\n\n/**\n * Finds cloudflared without a shell.\n *\n * A manual scan rather than `which`: spawning a shell to locate a binary is a\n * quoting hazard for no benefit, and this also works the same on every platform.\n */\nexport async function findCloudflared(env: NodeJS.ProcessEnv = process.env): Promise<string | undefined> {\n const names = process.platform === 'win32' ? ['cloudflared.exe', 'cloudflared'] : ['cloudflared'];\n for (const directory of (env.PATH ?? '').split(path.delimiter)) {\n if (directory === '') continue;\n for (const name of names) {\n const candidate = path.join(directory, name);\n try {\n await fs.access(candidate, fs.constants.X_OK);\n return candidate;\n } catch {\n // Not here, or not executable; keep looking.\n }\n }\n }\n return undefined;\n}\n\nasync function defaultProbe(url: string, signal: AbortSignal): Promise<ProbeResult> {\n const response = await fetch(url, { redirect: 'manual', signal });\n return { status: response.status, body: await response.text() };\n}\n\n/**\n * Kills a tunnel left behind by a hub that could not clean up after itself.\n *\n * A SIGKILLed hub never runs its exit handler, and the child is not detached so\n * it is reparented rather than killed. It then holds the tunnel open against a\n * dead port. This is the sweep on the next start.\n *\n * The residual risk is pid reuse after a reboot. The age window narrows it and\n * on Linux the command line is checked; macOS has no equally cheap check, so\n * there the window stands.\n */\ninterface TunnelPidRecord {\n pid?: unknown;\n ownerPid?: unknown;\n startedAt?: unknown;\n}\n\nfunction validPid(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;\n}\n\n/** Only ESRCH proves the owner is gone; permission and platform errors fail safe. */\nfunction ownerMayBeAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n// sync: exported createRemoteRuntime must reap stale public tunnels before its synchronous startup returns.\nexport function reapStaleTunnel(stateDir: string, onNotice: (message: string) => void): void {\n const pidPath = path.join(stateDir, PID_FILE);\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let raw: string;\n try {\n raw = readFileSync(pidPath, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') rmSync(tokenPath, { force: true });\n return; // No pid file is the normal case; other read failures are unsafe to guess through.\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return; // A malformed record cannot prove that its owner is gone.\n }\n if (typeof parsed !== 'object' || parsed === null) return;\n const record = parsed as TunnelPidRecord;\n if (Object.hasOwn(record, 'ownerPid')) {\n if (!validPid(record.ownerPid) || ownerMayBeAlive(record.ownerPid)) return;\n }\n\n rmSync(tokenPath, { force: true });\n rmSync(pidPath, { force: true });\n const pid = validPid(record.pid) ? record.pid : undefined;\n const startedAt = typeof record.startedAt === 'number' ? record.startedAt : 0;\n if (pid === undefined || Date.now() - startedAt > PID_FILE_MAX_AGE_MS) return;\n if (process.platform === 'linux') {\n try {\n if (!readFileSync(`/proc/${String(pid)}/cmdline`, 'utf8').includes('cloudflared')) return;\n } catch {\n return; // The process is gone.\n }\n }\n try {\n process.kill(pid, 'SIGTERM');\n onNotice(`stopped a tunnel left running by a previous hub (pid ${String(pid)})`);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') onNotice(`Could not stop stale tunnel: ${String(error)}`);\n }\n}\n\nfunction tailOf(lines: readonly string[]): string {\n return lines.slice(-LOG_TAIL).join('').trim();\n}\n\n/** Copies a named tunnel token to a private runtime file understood by cloudflared. */\nasync function writeTokenFile(config: TunnelConfig, stateDir: string): Promise<string | undefined> {\n if (config.kind !== 'named' || config.tokenFile === undefined) return undefined;\n let token: string;\n let sourcePath: string;\n try {\n sourcePath = await fs.realpath(config.tokenFile);\n token = (await fs.readFile(sourcePath, 'utf8')).trim();\n } catch {\n return undefined;\n }\n if (token === '') return undefined;\n await fs.mkdir(stateDir, { recursive: true, mode: 0o700 });\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let existingTarget: string | undefined;\n try {\n existingTarget = await fs.realpath(tokenPath);\n } catch (error) {\n // Missing is the normal state before launch; other failures must not hide an alias.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n if (sourcePath === path.resolve(tokenPath) || sourcePath === existingTarget) {\n throw new Error('The configured tunnel token file cannot also be Po runtime token storage.');\n }\n await fs.rm(tokenPath, { force: true });\n await fs.writeFile(tokenPath, token, { mode: FILE_MODE });\n await fs.chmod(tokenPath, FILE_MODE);\n return tokenPath;\n}\n\nexport function createTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const restartBaseDelayMs = options.restartBaseDelayMs ?? NAMED_RESTART_BASE_DELAY_MS;\n const restartStableMs = options.restartStableMs ?? NAMED_RESTART_STABLE_MS;\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n let stopped = false;\n let activeStop: (() => Promise<void>) | undefined;\n let stopPromise: Promise<void> | undefined;\n let recoveryPromise: Promise<void> | undefined;\n let pendingExit: string | undefined;\n let restartCount = 0;\n let lastReadyAt = 0;\n const recoveryAbort = new AbortController();\n const signal =\n input.signal === undefined ? recoveryAbort.signal : AbortSignal.any([input.signal, recoveryAbort.signal]);\n const supervisedInput: TunnelStartInput = { ...input, signal };\n\n function queueUnexpectedExit(message: string): void {\n if (stopped) return;\n if (input.config.kind === 'quick') {\n options.onExit?.(message);\n return;\n }\n if (recoveryPromise !== undefined) {\n pendingExit = message;\n return;\n }\n beginRecovery(message);\n }\n\n const single = createSingleTunnelLauncher({ ...options, onExit: queueUnexpectedExit });\n\n async function waitForRestart(attempt: number): Promise<void> {\n if (recoveryAbort.signal.aborted) return;\n const delayMs = Math.min(restartBaseDelayMs * 2 ** (attempt - 1), NAMED_RESTART_MAX_DELAY_MS);\n await new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const done = (): void => {\n clearTimeout(timer);\n recoveryAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n timer = setTimeout(done, delayMs);\n recoveryAbort.signal.addEventListener('abort', done, { once: true });\n if (recoveryAbort.signal.aborted) done();\n });\n }\n\n async function recover(initialMessage: string): Promise<void> {\n if (Date.now() - lastReadyAt >= restartStableMs) restartCount = 0;\n let lastFailure = initialMessage;\n while (!stopped && restartCount < NAMED_RESTART_ATTEMPTS) {\n restartCount += 1;\n notice(\n `cloudflared stopped; restarting named tunnel (attempt ${String(restartCount)} of ${String(NAMED_RESTART_ATTEMPTS)})`,\n );\n await waitForRestart(restartCount);\n if (stopped) return;\n\n const outcome = await single(supervisedInput);\n if (stopped) {\n if (outcome.ok) await outcome.stop().catch(() => undefined);\n return;\n }\n if (!outcome.ok) {\n lastFailure = outcome.message;\n continue;\n }\n activeStop = outcome.stop;\n lastReadyAt = Date.now();\n notice(`named tunnel recovered at ${outcome.publicOrigin}`);\n return;\n }\n\n if (!stopped) {\n options.onExit?.(\n `${initialMessage}\\nNamed tunnel recovery failed after ${String(NAMED_RESTART_ATTEMPTS)} attempts. Last failure: ${lastFailure}`,\n );\n }\n }\n\n function beginRecovery(message: string): void {\n recoveryPromise = recover(message)\n .catch((error: unknown) => {\n if (!stopped) {\n const cause = error instanceof Error ? error.message : String(error);\n options.onExit?.(`${message}\\nNamed tunnel recovery failed: ${cause}`);\n }\n })\n .finally(() => {\n recoveryPromise = undefined;\n const queued = pendingExit;\n pendingExit = undefined;\n if (queued !== undefined && !stopped) beginRecovery(queued);\n });\n }\n\n const initial = await single(supervisedInput);\n if (!initial.ok) {\n stopped = true;\n recoveryAbort.abort();\n return initial;\n }\n activeStop = initial.stop;\n lastReadyAt = Date.now();\n\n const stop = async (): Promise<void> => {\n if (stopPromise !== undefined) return await stopPromise;\n stopped = true;\n recoveryAbort.abort();\n const recovering = recoveryPromise;\n stopPromise = (async () => {\n await activeStop?.().catch(() => undefined);\n await recovering?.catch(() => undefined);\n await fs.rm(path.join(options.stateDir, PID_FILE), { force: true });\n await fs.rm(path.join(options.stateDir, TOKEN_FILE), { force: true });\n })();\n return await stopPromise;\n };\n\n return { ok: true, publicOrigin: initial.publicOrigin, stop };\n };\n}\n\n/** Starts one cloudflared child; the exported launcher supervises successive named-tunnel children. */\nfunction createSingleTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const spawnProcess = options.spawnProcess ?? spawn;\n const probe = options.probe ?? defaultProbe;\n const selfTestRetryMs = options.selfTestRetryMs ?? SELF_TEST_RETRY_MS;\n const startTimeoutMs = options.startTimeoutMs ?? START_TIMEOUT_MS;\n const pidPath = path.join(options.stateDir, PID_FILE);\n const runtimeTokenPath = path.join(options.stateDir, TOKEN_FILE);\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n if (input.signal?.aborted === true) {\n return { ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' };\n }\n const binary = options.cloudflaredPath ?? process.env[CLOUDFLARED_ENV] ?? (await findCloudflared());\n if (binary === undefined || binary === '') {\n return { ok: false, failure: 'not_installed', message: describeTunnelFailure('not_installed') };\n }\n\n let tokenPath: string | undefined;\n try {\n tokenPath = await writeTokenFile(input.config, options.stateDir);\n } catch (error) {\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n const args = tunnelArgs(input.config, input.port, tokenPath);\n let child: ChildProcess;\n try {\n // Never detached and never unref'd. A detached child becomes a process\n // group leader that survives the terminal's SIGINT, which is exactly the\n // orphaned public tunnel this must avoid. Contrast serverSpawner.ts,\n // which detaches on purpose because sessions outlive the hub.\n child = spawnProcess(binary, args, { detached: false, stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (error) {\n await fs.rm(runtimeTokenPath, { force: true });\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n\n const lines: string[] = [];\n let stopped = false;\n let settle: ((result: TunnelStartResult) => void) | undefined;\n let selfTestStarted = false;\n const selfTestAbort = new AbortController();\n\n const killTree = (): void => {\n try {\n child.kill('SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not stop tunnel: ${String(error)}`);\n }\n };\n const onProcessExit = (): void => {\n // sync: Node does not await filesystem cleanup in the process exit handler.\n // This is the net under process.exit(), an uncaught exception, and an\n // unhandled rejection, none of which reach the graceful close path.\n rmSync(runtimeTokenPath, { force: true });\n try {\n if (child.pid !== undefined) process.kill(child.pid, 'SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH')\n notice(`Could not kill tunnel at exit: ${String(error)}`);\n }\n };\n process.once('exit', onProcessExit);\n\n const stop = async (): Promise<void> => {\n if (stopped) return;\n stopped = true;\n if (child.exitCode !== null || child.signalCode !== null) {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n return;\n }\n await new Promise<void>((resolve) => {\n const escalate = setTimeout(() => {\n try {\n child.kill('SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not kill tunnel: ${String(error)}`);\n }\n }, TERMINATE_GRACE_MS);\n child.once('exit', () => {\n clearTimeout(escalate);\n resolve();\n });\n killTree();\n });\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n };\n\n // Register child listeners below without yielding, so early exits cannot be missed.\n // Cleanup waits for this ordered write before removing the record.\n const pidWrite = fs\n .mkdir(options.stateDir, { recursive: true, mode: 0o700 })\n .then(() =>\n fs.writeFile(\n pidPath,\n JSON.stringify({ pid: child.pid, ownerPid: process.pid, startedAt: Date.now(), command: binary }),\n { mode: FILE_MODE },\n ),\n )\n .catch((error: unknown) => {\n // The reaper is a safety net; report unavailable recovery without blocking startup.\n notice(`Could not write tunnel process record: ${String(error)}`);\n });\n\n const configuredOrigin = input.config.kind === 'named' ? `https://${input.config.hostname}` : undefined;\n let seenUrl = configuredOrigin;\n let seenConnection = false;\n\n const waitToRetry = async (): Promise<void> => {\n if (selfTestRetryMs <= 0) return;\n await new Promise<void>((resolve) => {\n const done = (): void => {\n clearTimeout(timer);\n selfTestAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, selfTestRetryMs);\n selfTestAbort.signal.addEventListener('abort', done, { once: true });\n });\n };\n\n /** Proves end to end that pairing is reachable and that everything else is not. */\n const runSelfTest = async (origin: string): Promise<TunnelStartResult> => {\n let pairResponse: ProbeResult | undefined;\n let healthResponse: ProbeResult | undefined;\n let cause = 'fetch failed';\n for (let attempt = 0; attempt < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted; attempt += 1) {\n try {\n pairResponse = await probe(`${origin}${PAIRING_PAGE_ROUTE}`, selfTestAbort.signal);\n healthResponse = await probe(`${origin}/api/health`, selfTestAbort.signal);\n if (pairResponse.status !== EDGE_TUNNEL_UNAVAILABLE && healthResponse.status !== EDGE_TUNNEL_UNAVAILABLE)\n break;\n cause = `Cloudflare edge answered ${String(healthResponse.status)} before the connector registered`;\n } catch (error) {\n cause = error instanceof Error ? error.message : String(error);\n }\n if (attempt + 1 < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted) await waitToRetry();\n }\n if (pairResponse === undefined || healthResponse === undefined) {\n return { ok: false, failure: 'self_test_failed', message: `The tunnel did not answer: ${cause}` };\n }\n if (healthResponse.status !== UNAUTHORIZED) {\n // The agent would be on the public internet unauthenticated. This is\n // the one failure worth an automatic abort rather than a warning.\n const message = `${describeTunnelFailure('self_test_failed')} /api/health answered ${String(healthResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n if (pairResponse.status !== OK || !pairResponse.body.includes(PAIRING_PAGE_MARKER)) {\n const message = `The pairing page answered ${String(pairResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n notice(`tunnel ready at ${origin}`);\n return { ok: true, publicOrigin: origin, stop };\n };\n\n const consider = (chunk: string): void => {\n lines.push(chunk);\n if (settle === undefined || selfTestStarted) return;\n seenUrl ??= extractTunnelUrl(chunk);\n seenConnection ||= mentionsRegisteredConnection(chunk);\n if (seenUrl === undefined || !seenConnection) return;\n selfTestStarted = true;\n input.acceptOrigin?.(seenUrl);\n void runSelfTest(seenUrl).then((result) => settle?.(result));\n };\n\n child.stdout?.on('data', (data: Buffer) => consider(data.toString()));\n child.stderr?.on('data', (data: Buffer) => consider(data.toString()));\n\n return await new Promise<TunnelStartResult>((resolve) => {\n let deadline: ReturnType<typeof setTimeout>;\n const finish = (result: TunnelStartResult, stopProcess = !result.ok): void => {\n if (settle === undefined) return;\n settle = undefined;\n clearTimeout(deadline);\n input.signal?.removeEventListener('abort', cancel);\n selfTestAbort.abort();\n if (stopProcess) {\n void stop().then(() => resolve(result));\n } else {\n resolve(result);\n }\n };\n const cancel = (): void => {\n finish({ ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' });\n };\n settle = (result) => finish(result);\n deadline = setTimeout(() => {\n finish({\n ok: false,\n failure: 'timeout',\n message: `${describeTunnelFailure('timeout')}\\n${tailOf(lines)}`,\n });\n }, startTimeoutMs);\n input.signal?.addEventListener('abort', cancel, { once: true });\n\n child.once('error', (error) => {\n finish({\n ok: false,\n failure: 'spawn_failed',\n message: `${describeTunnelFailure('spawn_failed')} ${error.message}`,\n });\n });\n\n child.once('exit', async (code) => {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(runtimeTokenPath, { force: true }).catch((error: unknown) => {\n notice(`Tunnel token cleanup failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n const message = `${describeTunnelFailure('exited')} (code ${String(code)})\\n${tailOf(lines)}`;\n if (settle !== undefined) {\n finish({ ok: false, failure: 'exited', message }, false);\n return;\n }\n // It came up and then died: network loss, an edge rejection, or a\n // self-update. The supervisor either replaces a named connector or tells\n // the host to fail closed rather than leave an unreachable cockpit enabled.\n if (!stopped) options.onExit?.(message);\n });\n\n // A named tunnel already knows its hostname, but it still waits for\n // cloudflared to register an edge connection before probing the public URL.\n if (input.signal?.aborted === true) cancel();\n });\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["path","fs","readFileSync","spawn","describeTunnelFailure","tunnelArgs","PAIRING_PAGE_ROUTE","extractTunnelUrl","mentionsRegisteredConnection"],"sources":["../../../../src/services/tunnelProcess/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync, rmSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { PAIRING_PAGE_ROUTE } from '../../constants/remote';\nimport {\n type TunnelConfig,\n type TunnelLauncher,\n type TunnelStartInput,\n type TunnelStartResult,\n} from '../../types/remote';\nimport { PAIRING_PAGE_MARKER } from '../pairingPage';\nimport { describeTunnelFailure, extractTunnelUrl, mentionsRegisteredConnection, tunnelArgs } from '../tunnelOutput';\n\n/** Explicit binary path, ahead of a PATH scan. */\nexport const CLOUDFLARED_ENV = 'PO_CLOUDFLARED';\n// Give new quick-host DNS and negative caches time to settle, within a bounded startup.\nconst START_TIMEOUT_MS = 120_000;\nconst TERMINATE_GRACE_MS = 2000;\nconst SELF_TEST_ATTEMPTS = 240;\nconst SELF_TEST_RETRY_MS = 500;\nconst NAMED_RESTART_ATTEMPTS = 3;\nconst NAMED_RESTART_BASE_DELAY_MS = 500;\nconst NAMED_RESTART_MAX_DELAY_MS = 4000;\nconst NAMED_RESTART_STABLE_MS = 60_000;\n/** Lines of process output kept for a failure report. */\nconst LOG_TAIL = 20;\nconst UNAUTHORIZED = 401;\n/** Cloudflare has the DNS route but no connector has registered yet. */\nconst EDGE_TUNNEL_UNAVAILABLE = 530;\nconst OK = 200;\nconst PID_FILE = 'tunnel.pid';\nconst TOKEN_FILE = 'tunnel.token';\nconst FILE_MODE = 0o600;\n/** A pid file older than this is stale beyond usefulness and the pid has likely been recycled. */\nconst PID_FILE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface ProbeResult {\n status: number;\n body: string;\n}\n\nexport interface TunnelProcessOptions {\n /** Explicit binary, ahead of the env var and the PATH scan. */\n cloudflaredPath?: string;\n stateDir: string;\n onNotice?: (message: string) => void;\n /** Test seam: stands in for node:child_process.spawn. */\n spawnProcess?: typeof spawn;\n /** Test seam: reaches the tunnel from outside, so the self-test needs no network. */\n probe?: (url: string, signal: AbortSignal) => Promise<ProbeResult>;\n /** Test seam: production waits briefly for a new public hostname to propagate. */\n selfTestRetryMs?: number;\n /** Test seam: production bounds the complete startup, including its self-test. */\n startTimeoutMs?: number;\n /** Test seam: production backs named-tunnel restarts off from 500 ms. */\n restartBaseDelayMs?: number;\n /** Test seam: production resets the rapid-crash budget after one stable minute. */\n restartStableMs?: number;\n /** Called after a quick tunnel exits, or after named-tunnel recovery is exhausted. */\n onExit?: (message: string) => void;\n}\n\n/**\n * Finds cloudflared without a shell.\n *\n * A manual scan rather than `which`: spawning a shell to locate a binary is a\n * quoting hazard for no benefit, and this also works the same on every platform.\n */\nexport async function findCloudflared(env: NodeJS.ProcessEnv = process.env): Promise<string | undefined> {\n const names = process.platform === 'win32' ? ['cloudflared.exe', 'cloudflared'] : ['cloudflared'];\n for (const directory of (env.PATH ?? '').split(path.delimiter)) {\n if (directory === '') continue;\n for (const name of names) {\n const candidate = path.join(directory, name);\n try {\n await fs.access(candidate, fs.constants.X_OK);\n return candidate;\n } catch {\n // Not here, or not executable; keep looking.\n }\n }\n }\n return undefined;\n}\n\nasync function defaultProbe(url: string, signal: AbortSignal): Promise<ProbeResult> {\n const response = await fetch(url, { redirect: 'manual', signal });\n return { status: response.status, body: await response.text() };\n}\n\n/**\n * Kills a tunnel left behind by a hub that could not clean up after itself.\n *\n * A SIGKILLed hub never runs its exit handler, and the child is not detached so\n * it is reparented rather than killed. It then holds the tunnel open against a\n * dead port. This is the sweep on the next start.\n *\n * The residual risk is pid reuse after a reboot. The age window narrows it and\n * on Linux the command line is checked; macOS has no equally cheap check, so\n * there the window stands.\n */\ninterface TunnelPidRecord {\n pid?: unknown;\n ownerPid?: unknown;\n startedAt?: unknown;\n}\n\nfunction validPid(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;\n}\n\n/** Only ESRCH proves the owner is gone; permission and platform errors fail safe. */\nfunction ownerMayBeAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n// sync: exported createRemoteRuntime must reap stale public tunnels before its synchronous startup returns.\nexport function reapStaleTunnel(stateDir: string, onNotice: (message: string) => void): void {\n const pidPath = path.join(stateDir, PID_FILE);\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let raw: string;\n try {\n raw = readFileSync(pidPath, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') rmSync(tokenPath, { force: true });\n return; // No pid file is the normal case; other read failures are unsafe to guess through.\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return; // A malformed record cannot prove that its owner is gone.\n }\n if (typeof parsed !== 'object' || parsed === null) return;\n const record = parsed as TunnelPidRecord;\n if (Object.hasOwn(record, 'ownerPid')) {\n if (!validPid(record.ownerPid) || ownerMayBeAlive(record.ownerPid)) return;\n }\n\n rmSync(tokenPath, { force: true });\n rmSync(pidPath, { force: true });\n const pid = validPid(record.pid) ? record.pid : undefined;\n const startedAt = typeof record.startedAt === 'number' ? record.startedAt : 0;\n if (pid === undefined || Date.now() - startedAt > PID_FILE_MAX_AGE_MS) return;\n if (process.platform === 'linux') {\n try {\n if (!readFileSync(`/proc/${String(pid)}/cmdline`, 'utf8').includes('cloudflared')) return;\n } catch {\n return; // The process is gone.\n }\n }\n try {\n process.kill(pid, 'SIGTERM');\n onNotice(`stopped a tunnel left running by a previous hub (pid ${String(pid)})`);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') onNotice(`Could not stop stale tunnel: ${String(error)}`);\n }\n}\n\nfunction tailOf(lines: readonly string[]): string {\n return lines.slice(-LOG_TAIL).join('').trim();\n}\n\n/** Copies a named tunnel token to a private runtime file understood by cloudflared. */\nasync function writeTokenFile(config: TunnelConfig, stateDir: string): Promise<string | undefined> {\n if (config.kind !== 'named' || config.tokenFile === undefined) return undefined;\n let token: string;\n let sourcePath: string;\n try {\n sourcePath = await fs.realpath(config.tokenFile);\n token = (await fs.readFile(sourcePath, 'utf8')).trim();\n } catch {\n return undefined;\n }\n if (token === '') return undefined;\n await fs.mkdir(stateDir, { recursive: true, mode: 0o700 });\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let existingTarget: string | undefined;\n try {\n existingTarget = await fs.realpath(tokenPath);\n } catch (error) {\n // Missing is the normal state before launch; other failures must not hide an alias.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n if (sourcePath === path.resolve(tokenPath) || sourcePath === existingTarget) {\n throw new Error('The configured tunnel token file cannot also be Po runtime token storage.');\n }\n await fs.rm(tokenPath, { force: true });\n await fs.writeFile(tokenPath, token, { mode: FILE_MODE });\n await fs.chmod(tokenPath, FILE_MODE);\n return tokenPath;\n}\n\nexport function createTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const restartBaseDelayMs = options.restartBaseDelayMs ?? NAMED_RESTART_BASE_DELAY_MS;\n const restartStableMs = options.restartStableMs ?? NAMED_RESTART_STABLE_MS;\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n let stopped = false;\n let activeStop: (() => Promise<void>) | undefined;\n let stopPromise: Promise<void> | undefined;\n let recoveryPromise: Promise<void> | undefined;\n let pendingExit: string | undefined;\n let restartCount = 0;\n let lastReadyAt = 0;\n const recoveryAbort = new AbortController();\n const signal =\n input.signal === undefined ? recoveryAbort.signal : AbortSignal.any([input.signal, recoveryAbort.signal]);\n const supervisedInput: TunnelStartInput = { ...input, signal };\n\n function queueUnexpectedExit(message: string): void {\n if (stopped) return;\n if (input.config.kind === 'quick') {\n options.onExit?.(message);\n return;\n }\n if (recoveryPromise !== undefined) {\n pendingExit = message;\n return;\n }\n beginRecovery(message);\n }\n\n const single = createSingleTunnelLauncher({ ...options, onExit: queueUnexpectedExit });\n\n async function waitForRestart(attempt: number): Promise<void> {\n if (recoveryAbort.signal.aborted) return;\n const delayMs = Math.min(restartBaseDelayMs * 2 ** (attempt - 1), NAMED_RESTART_MAX_DELAY_MS);\n await new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const done = (): void => {\n clearTimeout(timer);\n recoveryAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n timer = setTimeout(done, delayMs);\n recoveryAbort.signal.addEventListener('abort', done, { once: true });\n if (recoveryAbort.signal.aborted) done();\n });\n }\n\n async function recover(initialMessage: string): Promise<void> {\n if (Date.now() - lastReadyAt >= restartStableMs) restartCount = 0;\n let lastFailure = initialMessage;\n while (!stopped && restartCount < NAMED_RESTART_ATTEMPTS) {\n restartCount += 1;\n notice(\n `cloudflared stopped; restarting named tunnel (attempt ${String(restartCount)} of ${String(NAMED_RESTART_ATTEMPTS)})`,\n );\n await waitForRestart(restartCount);\n if (stopped) return;\n\n const outcome = await single(supervisedInput);\n if (stopped) {\n if (outcome.ok) {\n await outcome.stop().catch((error: unknown) => {\n notice(`Could not stop recovered tunnel: ${String(error)}`);\n });\n }\n return;\n }\n if (!outcome.ok) {\n lastFailure = outcome.message;\n continue;\n }\n activeStop = outcome.stop;\n lastReadyAt = Date.now();\n notice(`named tunnel recovered at ${outcome.publicOrigin}`);\n return;\n }\n\n if (!stopped) {\n options.onExit?.(\n `${initialMessage}\\nNamed tunnel recovery failed after ${String(NAMED_RESTART_ATTEMPTS)} attempts. Last failure: ${lastFailure}`,\n );\n }\n }\n\n function beginRecovery(message: string): void {\n recoveryPromise = recover(message)\n .catch((error: unknown) => {\n if (!stopped) {\n const cause = error instanceof Error ? error.message : String(error);\n options.onExit?.(`${message}\\nNamed tunnel recovery failed: ${cause}`);\n }\n })\n .finally(() => {\n recoveryPromise = undefined;\n const queued = pendingExit;\n pendingExit = undefined;\n if (queued !== undefined && !stopped) beginRecovery(queued);\n });\n }\n\n const initial = await single(supervisedInput);\n if (!initial.ok) {\n stopped = true;\n recoveryAbort.abort();\n return initial;\n }\n activeStop = initial.stop;\n lastReadyAt = Date.now();\n\n const stop = async (): Promise<void> => {\n if (stopPromise !== undefined) return await stopPromise;\n stopped = true;\n recoveryAbort.abort();\n const recovering = recoveryPromise;\n stopPromise = (async () => {\n await activeStop?.().catch((error: unknown) => {\n notice(`Could not stop tunnel: ${String(error)}`);\n });\n await recovering?.catch((error: unknown) => {\n notice(`Tunnel recovery cleanup failed: ${String(error)}`);\n });\n await fs.rm(path.join(options.stateDir, PID_FILE), { force: true });\n await fs.rm(path.join(options.stateDir, TOKEN_FILE), { force: true });\n })();\n return await stopPromise;\n };\n\n return { ok: true, publicOrigin: initial.publicOrigin, stop };\n };\n}\n\n/** Starts one cloudflared child; the exported launcher supervises successive named-tunnel children. */\nfunction createSingleTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const spawnProcess = options.spawnProcess ?? spawn;\n const probe = options.probe ?? defaultProbe;\n const selfTestRetryMs = options.selfTestRetryMs ?? SELF_TEST_RETRY_MS;\n const startTimeoutMs = options.startTimeoutMs ?? START_TIMEOUT_MS;\n const pidPath = path.join(options.stateDir, PID_FILE);\n const runtimeTokenPath = path.join(options.stateDir, TOKEN_FILE);\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n if (input.signal?.aborted === true) {\n return { ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' };\n }\n const binary = options.cloudflaredPath ?? process.env[CLOUDFLARED_ENV] ?? (await findCloudflared());\n if (binary === undefined || binary === '') {\n return { ok: false, failure: 'not_installed', message: describeTunnelFailure('not_installed') };\n }\n\n let tokenPath: string | undefined;\n try {\n tokenPath = await writeTokenFile(input.config, options.stateDir);\n } catch (error) {\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n const args = tunnelArgs(input.config, input.port, tokenPath);\n let child: ChildProcess;\n try {\n // Never detached and never unref'd. A detached child becomes a process\n // group leader that survives the terminal's SIGINT, which is exactly the\n // orphaned public tunnel this must avoid. Contrast serverSpawner.ts,\n // which detaches on purpose because sessions outlive the hub.\n child = spawnProcess(binary, args, { detached: false, stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (error) {\n await fs.rm(runtimeTokenPath, { force: true });\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n\n const lines: string[] = [];\n let stopped = false;\n let settle: ((result: TunnelStartResult) => void) | undefined;\n let selfTestStarted = false;\n const selfTestAbort = new AbortController();\n\n const killTree = (): void => {\n try {\n child.kill('SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not stop tunnel: ${String(error)}`);\n }\n };\n const onProcessExit = (): void => {\n // sync: Node does not await filesystem cleanup in the process exit handler.\n // This is the net under process.exit(), an uncaught exception, and an\n // unhandled rejection, none of which reach the graceful close path.\n rmSync(runtimeTokenPath, { force: true });\n try {\n if (child.pid !== undefined) process.kill(child.pid, 'SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH')\n notice(`Could not kill tunnel at exit: ${String(error)}`);\n }\n };\n process.once('exit', onProcessExit);\n\n const stop = async (): Promise<void> => {\n if (stopped) return;\n stopped = true;\n if (child.exitCode !== null || child.signalCode !== null) {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n return;\n }\n await new Promise<void>((resolve) => {\n const escalate = setTimeout(() => {\n try {\n child.kill('SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not kill tunnel: ${String(error)}`);\n }\n }, TERMINATE_GRACE_MS);\n child.once('exit', () => {\n clearTimeout(escalate);\n resolve();\n });\n killTree();\n });\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n };\n\n // Register child listeners below without yielding, so early exits cannot be missed.\n // Cleanup waits for this ordered write before removing the record.\n const pidWrite = fs\n .mkdir(options.stateDir, { recursive: true, mode: 0o700 })\n .then(() =>\n fs.writeFile(\n pidPath,\n JSON.stringify({ pid: child.pid, ownerPid: process.pid, startedAt: Date.now(), command: binary }),\n { mode: FILE_MODE },\n ),\n )\n .catch((error: unknown) => {\n // The reaper is a safety net; report unavailable recovery without blocking startup.\n notice(`Could not write tunnel process record: ${String(error)}`);\n });\n\n const configuredOrigin = input.config.kind === 'named' ? `https://${input.config.hostname}` : undefined;\n let seenUrl = configuredOrigin;\n let seenConnection = false;\n\n const waitToRetry = async (): Promise<void> => {\n if (selfTestRetryMs <= 0) return;\n await new Promise<void>((resolve) => {\n const done = (): void => {\n clearTimeout(timer);\n selfTestAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, selfTestRetryMs);\n selfTestAbort.signal.addEventListener('abort', done, { once: true });\n });\n };\n\n /** Proves end to end that pairing is reachable and that everything else is not. */\n const runSelfTest = async (origin: string): Promise<TunnelStartResult> => {\n let pairResponse: ProbeResult | undefined;\n let healthResponse: ProbeResult | undefined;\n let cause = 'fetch failed';\n for (let attempt = 0; attempt < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted; attempt += 1) {\n try {\n pairResponse = await probe(`${origin}${PAIRING_PAGE_ROUTE}`, selfTestAbort.signal);\n healthResponse = await probe(`${origin}/api/health`, selfTestAbort.signal);\n if (pairResponse.status !== EDGE_TUNNEL_UNAVAILABLE && healthResponse.status !== EDGE_TUNNEL_UNAVAILABLE)\n break;\n cause = `Cloudflare edge answered ${String(healthResponse.status)} before the connector registered`;\n } catch (error) {\n cause = error instanceof Error ? error.message : String(error);\n }\n if (attempt + 1 < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted) await waitToRetry();\n }\n if (pairResponse === undefined || healthResponse === undefined) {\n return { ok: false, failure: 'self_test_failed', message: `The tunnel did not answer: ${cause}` };\n }\n if (healthResponse.status !== UNAUTHORIZED) {\n // The agent would be on the public internet unauthenticated. This is\n // the one failure worth an automatic abort rather than a warning.\n const message = `${describeTunnelFailure('self_test_failed')} /api/health answered ${String(healthResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n if (pairResponse.status !== OK || !pairResponse.body.includes(PAIRING_PAGE_MARKER)) {\n const message = `The pairing page answered ${String(pairResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n notice(`tunnel ready at ${origin}`);\n return { ok: true, publicOrigin: origin, stop };\n };\n\n const consider = (chunk: string): void => {\n lines.push(chunk);\n if (settle === undefined || selfTestStarted) return;\n seenUrl ??= extractTunnelUrl(chunk);\n seenConnection ||= mentionsRegisteredConnection(chunk);\n if (seenUrl === undefined || !seenConnection) return;\n selfTestStarted = true;\n input.acceptOrigin?.(seenUrl);\n void runSelfTest(seenUrl).then((result) => settle?.(result));\n };\n\n child.stdout?.on('data', (data: Buffer) => consider(data.toString()));\n child.stderr?.on('data', (data: Buffer) => consider(data.toString()));\n\n return await new Promise<TunnelStartResult>((resolve) => {\n let deadline: ReturnType<typeof setTimeout>;\n const finish = (result: TunnelStartResult, stopProcess = !result.ok): void => {\n if (settle === undefined) return;\n settle = undefined;\n clearTimeout(deadline);\n input.signal?.removeEventListener('abort', cancel);\n selfTestAbort.abort();\n if (stopProcess) {\n void stop().then(() => resolve(result));\n } else {\n resolve(result);\n }\n };\n const cancel = (): void => {\n finish({ ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' });\n };\n settle = (result) => finish(result);\n deadline = setTimeout(() => {\n finish({\n ok: false,\n failure: 'timeout',\n message: `${describeTunnelFailure('timeout')}\\n${tailOf(lines)}`,\n });\n }, startTimeoutMs);\n input.signal?.addEventListener('abort', cancel, { once: true });\n\n child.once('error', (error) => {\n finish({\n ok: false,\n failure: 'spawn_failed',\n message: `${describeTunnelFailure('spawn_failed')} ${error.message}`,\n });\n });\n\n child.once('exit', async (code) => {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(runtimeTokenPath, { force: true }).catch((error: unknown) => {\n notice(`Tunnel token cleanup failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n const message = `${describeTunnelFailure('exited')} (code ${String(code)})\\n${tailOf(lines)}`;\n if (settle !== undefined) {\n finish({ ok: false, failure: 'exited', message }, false);\n return;\n }\n // It came up and then died: network loss, an edge rejection, or a\n // self-update. The supervisor either replaces a named connector or tells\n // the host to fail closed rather than leave an unreachable cockpit enabled.\n if (!stopped) options.onExit?.(message);\n });\n\n // A named tunnel already knows its hostname, but it still waits for\n // cloudflared to register an edge connection before probing the public URL.\n if (input.signal?.aborted === true) cancel();\n });\n };\n}\n"],"mappings":"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"}
@@ -195,7 +195,9 @@ function createTunnelLauncher(options) {
195
195
  if (stopped) return;
196
196
  const outcome = await single(supervisedInput);
197
197
  if (stopped) {
198
- if (outcome.ok) await outcome.stop().catch(() => void 0);
198
+ if (outcome.ok) await outcome.stop().catch((error) => {
199
+ notice(`Could not stop recovered tunnel: ${String(error)}`);
200
+ });
199
201
  return;
200
202
  }
201
203
  if (!outcome.ok) {
@@ -236,8 +238,12 @@ function createTunnelLauncher(options) {
236
238
  recoveryAbort.abort();
237
239
  const recovering = recoveryPromise;
238
240
  stopPromise = (async () => {
239
- await activeStop?.().catch(() => void 0);
240
- await recovering?.catch(() => void 0);
241
+ await activeStop?.().catch((error) => {
242
+ notice(`Could not stop tunnel: ${String(error)}`);
243
+ });
244
+ await recovering?.catch((error) => {
245
+ notice(`Tunnel recovery cleanup failed: ${String(error)}`);
246
+ });
241
247
  await fs.rm(path.join(options.stateDir, PID_FILE), { force: true });
242
248
  await fs.rm(path.join(options.stateDir, TOKEN_FILE), { force: true });
243
249
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/tunnelProcess/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync, rmSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { PAIRING_PAGE_ROUTE } from '../../constants/remote';\nimport {\n type TunnelConfig,\n type TunnelLauncher,\n type TunnelStartInput,\n type TunnelStartResult,\n} from '../../types/remote';\nimport { PAIRING_PAGE_MARKER } from '../pairingPage';\nimport { describeTunnelFailure, extractTunnelUrl, mentionsRegisteredConnection, tunnelArgs } from '../tunnelOutput';\n\n/** Explicit binary path, ahead of a PATH scan. */\nexport const CLOUDFLARED_ENV = 'PO_CLOUDFLARED';\n// Give new quick-host DNS and negative caches time to settle, within a bounded startup.\nconst START_TIMEOUT_MS = 120_000;\nconst TERMINATE_GRACE_MS = 2000;\nconst SELF_TEST_ATTEMPTS = 240;\nconst SELF_TEST_RETRY_MS = 500;\nconst NAMED_RESTART_ATTEMPTS = 3;\nconst NAMED_RESTART_BASE_DELAY_MS = 500;\nconst NAMED_RESTART_MAX_DELAY_MS = 4000;\nconst NAMED_RESTART_STABLE_MS = 60_000;\n/** Lines of process output kept for a failure report. */\nconst LOG_TAIL = 20;\nconst UNAUTHORIZED = 401;\n/** Cloudflare has the DNS route but no connector has registered yet. */\nconst EDGE_TUNNEL_UNAVAILABLE = 530;\nconst OK = 200;\nconst PID_FILE = 'tunnel.pid';\nconst TOKEN_FILE = 'tunnel.token';\nconst FILE_MODE = 0o600;\n/** A pid file older than this is stale beyond usefulness and the pid has likely been recycled. */\nconst PID_FILE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface ProbeResult {\n status: number;\n body: string;\n}\n\nexport interface TunnelProcessOptions {\n /** Explicit binary, ahead of the env var and the PATH scan. */\n cloudflaredPath?: string;\n stateDir: string;\n onNotice?: (message: string) => void;\n /** Test seam: stands in for node:child_process.spawn. */\n spawnProcess?: typeof spawn;\n /** Test seam: reaches the tunnel from outside, so the self-test needs no network. */\n probe?: (url: string, signal: AbortSignal) => Promise<ProbeResult>;\n /** Test seam: production waits briefly for a new public hostname to propagate. */\n selfTestRetryMs?: number;\n /** Test seam: production bounds the complete startup, including its self-test. */\n startTimeoutMs?: number;\n /** Test seam: production backs named-tunnel restarts off from 500 ms. */\n restartBaseDelayMs?: number;\n /** Test seam: production resets the rapid-crash budget after one stable minute. */\n restartStableMs?: number;\n /** Called after a quick tunnel exits, or after named-tunnel recovery is exhausted. */\n onExit?: (message: string) => void;\n}\n\n/**\n * Finds cloudflared without a shell.\n *\n * A manual scan rather than `which`: spawning a shell to locate a binary is a\n * quoting hazard for no benefit, and this also works the same on every platform.\n */\nexport async function findCloudflared(env: NodeJS.ProcessEnv = process.env): Promise<string | undefined> {\n const names = process.platform === 'win32' ? ['cloudflared.exe', 'cloudflared'] : ['cloudflared'];\n for (const directory of (env.PATH ?? '').split(path.delimiter)) {\n if (directory === '') continue;\n for (const name of names) {\n const candidate = path.join(directory, name);\n try {\n await fs.access(candidate, fs.constants.X_OK);\n return candidate;\n } catch {\n // Not here, or not executable; keep looking.\n }\n }\n }\n return undefined;\n}\n\nasync function defaultProbe(url: string, signal: AbortSignal): Promise<ProbeResult> {\n const response = await fetch(url, { redirect: 'manual', signal });\n return { status: response.status, body: await response.text() };\n}\n\n/**\n * Kills a tunnel left behind by a hub that could not clean up after itself.\n *\n * A SIGKILLed hub never runs its exit handler, and the child is not detached so\n * it is reparented rather than killed. It then holds the tunnel open against a\n * dead port. This is the sweep on the next start.\n *\n * The residual risk is pid reuse after a reboot. The age window narrows it and\n * on Linux the command line is checked; macOS has no equally cheap check, so\n * there the window stands.\n */\ninterface TunnelPidRecord {\n pid?: unknown;\n ownerPid?: unknown;\n startedAt?: unknown;\n}\n\nfunction validPid(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;\n}\n\n/** Only ESRCH proves the owner is gone; permission and platform errors fail safe. */\nfunction ownerMayBeAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n// sync: exported createRemoteRuntime must reap stale public tunnels before its synchronous startup returns.\nexport function reapStaleTunnel(stateDir: string, onNotice: (message: string) => void): void {\n const pidPath = path.join(stateDir, PID_FILE);\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let raw: string;\n try {\n raw = readFileSync(pidPath, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') rmSync(tokenPath, { force: true });\n return; // No pid file is the normal case; other read failures are unsafe to guess through.\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return; // A malformed record cannot prove that its owner is gone.\n }\n if (typeof parsed !== 'object' || parsed === null) return;\n const record = parsed as TunnelPidRecord;\n if (Object.hasOwn(record, 'ownerPid')) {\n if (!validPid(record.ownerPid) || ownerMayBeAlive(record.ownerPid)) return;\n }\n\n rmSync(tokenPath, { force: true });\n rmSync(pidPath, { force: true });\n const pid = validPid(record.pid) ? record.pid : undefined;\n const startedAt = typeof record.startedAt === 'number' ? record.startedAt : 0;\n if (pid === undefined || Date.now() - startedAt > PID_FILE_MAX_AGE_MS) return;\n if (process.platform === 'linux') {\n try {\n if (!readFileSync(`/proc/${String(pid)}/cmdline`, 'utf8').includes('cloudflared')) return;\n } catch {\n return; // The process is gone.\n }\n }\n try {\n process.kill(pid, 'SIGTERM');\n onNotice(`stopped a tunnel left running by a previous hub (pid ${String(pid)})`);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') onNotice(`Could not stop stale tunnel: ${String(error)}`);\n }\n}\n\nfunction tailOf(lines: readonly string[]): string {\n return lines.slice(-LOG_TAIL).join('').trim();\n}\n\n/** Copies a named tunnel token to a private runtime file understood by cloudflared. */\nasync function writeTokenFile(config: TunnelConfig, stateDir: string): Promise<string | undefined> {\n if (config.kind !== 'named' || config.tokenFile === undefined) return undefined;\n let token: string;\n let sourcePath: string;\n try {\n sourcePath = await fs.realpath(config.tokenFile);\n token = (await fs.readFile(sourcePath, 'utf8')).trim();\n } catch {\n return undefined;\n }\n if (token === '') return undefined;\n await fs.mkdir(stateDir, { recursive: true, mode: 0o700 });\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let existingTarget: string | undefined;\n try {\n existingTarget = await fs.realpath(tokenPath);\n } catch (error) {\n // Missing is the normal state before launch; other failures must not hide an alias.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n if (sourcePath === path.resolve(tokenPath) || sourcePath === existingTarget) {\n throw new Error('The configured tunnel token file cannot also be Po runtime token storage.');\n }\n await fs.rm(tokenPath, { force: true });\n await fs.writeFile(tokenPath, token, { mode: FILE_MODE });\n await fs.chmod(tokenPath, FILE_MODE);\n return tokenPath;\n}\n\nexport function createTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const restartBaseDelayMs = options.restartBaseDelayMs ?? NAMED_RESTART_BASE_DELAY_MS;\n const restartStableMs = options.restartStableMs ?? NAMED_RESTART_STABLE_MS;\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n let stopped = false;\n let activeStop: (() => Promise<void>) | undefined;\n let stopPromise: Promise<void> | undefined;\n let recoveryPromise: Promise<void> | undefined;\n let pendingExit: string | undefined;\n let restartCount = 0;\n let lastReadyAt = 0;\n const recoveryAbort = new AbortController();\n const signal =\n input.signal === undefined ? recoveryAbort.signal : AbortSignal.any([input.signal, recoveryAbort.signal]);\n const supervisedInput: TunnelStartInput = { ...input, signal };\n\n function queueUnexpectedExit(message: string): void {\n if (stopped) return;\n if (input.config.kind === 'quick') {\n options.onExit?.(message);\n return;\n }\n if (recoveryPromise !== undefined) {\n pendingExit = message;\n return;\n }\n beginRecovery(message);\n }\n\n const single = createSingleTunnelLauncher({ ...options, onExit: queueUnexpectedExit });\n\n async function waitForRestart(attempt: number): Promise<void> {\n if (recoveryAbort.signal.aborted) return;\n const delayMs = Math.min(restartBaseDelayMs * 2 ** (attempt - 1), NAMED_RESTART_MAX_DELAY_MS);\n await new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const done = (): void => {\n clearTimeout(timer);\n recoveryAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n timer = setTimeout(done, delayMs);\n recoveryAbort.signal.addEventListener('abort', done, { once: true });\n if (recoveryAbort.signal.aborted) done();\n });\n }\n\n async function recover(initialMessage: string): Promise<void> {\n if (Date.now() - lastReadyAt >= restartStableMs) restartCount = 0;\n let lastFailure = initialMessage;\n while (!stopped && restartCount < NAMED_RESTART_ATTEMPTS) {\n restartCount += 1;\n notice(\n `cloudflared stopped; restarting named tunnel (attempt ${String(restartCount)} of ${String(NAMED_RESTART_ATTEMPTS)})`,\n );\n await waitForRestart(restartCount);\n if (stopped) return;\n\n const outcome = await single(supervisedInput);\n if (stopped) {\n if (outcome.ok) await outcome.stop().catch(() => undefined);\n return;\n }\n if (!outcome.ok) {\n lastFailure = outcome.message;\n continue;\n }\n activeStop = outcome.stop;\n lastReadyAt = Date.now();\n notice(`named tunnel recovered at ${outcome.publicOrigin}`);\n return;\n }\n\n if (!stopped) {\n options.onExit?.(\n `${initialMessage}\\nNamed tunnel recovery failed after ${String(NAMED_RESTART_ATTEMPTS)} attempts. Last failure: ${lastFailure}`,\n );\n }\n }\n\n function beginRecovery(message: string): void {\n recoveryPromise = recover(message)\n .catch((error: unknown) => {\n if (!stopped) {\n const cause = error instanceof Error ? error.message : String(error);\n options.onExit?.(`${message}\\nNamed tunnel recovery failed: ${cause}`);\n }\n })\n .finally(() => {\n recoveryPromise = undefined;\n const queued = pendingExit;\n pendingExit = undefined;\n if (queued !== undefined && !stopped) beginRecovery(queued);\n });\n }\n\n const initial = await single(supervisedInput);\n if (!initial.ok) {\n stopped = true;\n recoveryAbort.abort();\n return initial;\n }\n activeStop = initial.stop;\n lastReadyAt = Date.now();\n\n const stop = async (): Promise<void> => {\n if (stopPromise !== undefined) return await stopPromise;\n stopped = true;\n recoveryAbort.abort();\n const recovering = recoveryPromise;\n stopPromise = (async () => {\n await activeStop?.().catch(() => undefined);\n await recovering?.catch(() => undefined);\n await fs.rm(path.join(options.stateDir, PID_FILE), { force: true });\n await fs.rm(path.join(options.stateDir, TOKEN_FILE), { force: true });\n })();\n return await stopPromise;\n };\n\n return { ok: true, publicOrigin: initial.publicOrigin, stop };\n };\n}\n\n/** Starts one cloudflared child; the exported launcher supervises successive named-tunnel children. */\nfunction createSingleTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const spawnProcess = options.spawnProcess ?? spawn;\n const probe = options.probe ?? defaultProbe;\n const selfTestRetryMs = options.selfTestRetryMs ?? SELF_TEST_RETRY_MS;\n const startTimeoutMs = options.startTimeoutMs ?? START_TIMEOUT_MS;\n const pidPath = path.join(options.stateDir, PID_FILE);\n const runtimeTokenPath = path.join(options.stateDir, TOKEN_FILE);\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n if (input.signal?.aborted === true) {\n return { ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' };\n }\n const binary = options.cloudflaredPath ?? process.env[CLOUDFLARED_ENV] ?? (await findCloudflared());\n if (binary === undefined || binary === '') {\n return { ok: false, failure: 'not_installed', message: describeTunnelFailure('not_installed') };\n }\n\n let tokenPath: string | undefined;\n try {\n tokenPath = await writeTokenFile(input.config, options.stateDir);\n } catch (error) {\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n const args = tunnelArgs(input.config, input.port, tokenPath);\n let child: ChildProcess;\n try {\n // Never detached and never unref'd. A detached child becomes a process\n // group leader that survives the terminal's SIGINT, which is exactly the\n // orphaned public tunnel this must avoid. Contrast serverSpawner.ts,\n // which detaches on purpose because sessions outlive the hub.\n child = spawnProcess(binary, args, { detached: false, stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (error) {\n await fs.rm(runtimeTokenPath, { force: true });\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n\n const lines: string[] = [];\n let stopped = false;\n let settle: ((result: TunnelStartResult) => void) | undefined;\n let selfTestStarted = false;\n const selfTestAbort = new AbortController();\n\n const killTree = (): void => {\n try {\n child.kill('SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not stop tunnel: ${String(error)}`);\n }\n };\n const onProcessExit = (): void => {\n // sync: Node does not await filesystem cleanup in the process exit handler.\n // This is the net under process.exit(), an uncaught exception, and an\n // unhandled rejection, none of which reach the graceful close path.\n rmSync(runtimeTokenPath, { force: true });\n try {\n if (child.pid !== undefined) process.kill(child.pid, 'SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH')\n notice(`Could not kill tunnel at exit: ${String(error)}`);\n }\n };\n process.once('exit', onProcessExit);\n\n const stop = async (): Promise<void> => {\n if (stopped) return;\n stopped = true;\n if (child.exitCode !== null || child.signalCode !== null) {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n return;\n }\n await new Promise<void>((resolve) => {\n const escalate = setTimeout(() => {\n try {\n child.kill('SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not kill tunnel: ${String(error)}`);\n }\n }, TERMINATE_GRACE_MS);\n child.once('exit', () => {\n clearTimeout(escalate);\n resolve();\n });\n killTree();\n });\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n };\n\n // Register child listeners below without yielding, so early exits cannot be missed.\n // Cleanup waits for this ordered write before removing the record.\n const pidWrite = fs\n .mkdir(options.stateDir, { recursive: true, mode: 0o700 })\n .then(() =>\n fs.writeFile(\n pidPath,\n JSON.stringify({ pid: child.pid, ownerPid: process.pid, startedAt: Date.now(), command: binary }),\n { mode: FILE_MODE },\n ),\n )\n .catch((error: unknown) => {\n // The reaper is a safety net; report unavailable recovery without blocking startup.\n notice(`Could not write tunnel process record: ${String(error)}`);\n });\n\n const configuredOrigin = input.config.kind === 'named' ? `https://${input.config.hostname}` : undefined;\n let seenUrl = configuredOrigin;\n let seenConnection = false;\n\n const waitToRetry = async (): Promise<void> => {\n if (selfTestRetryMs <= 0) return;\n await new Promise<void>((resolve) => {\n const done = (): void => {\n clearTimeout(timer);\n selfTestAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, selfTestRetryMs);\n selfTestAbort.signal.addEventListener('abort', done, { once: true });\n });\n };\n\n /** Proves end to end that pairing is reachable and that everything else is not. */\n const runSelfTest = async (origin: string): Promise<TunnelStartResult> => {\n let pairResponse: ProbeResult | undefined;\n let healthResponse: ProbeResult | undefined;\n let cause = 'fetch failed';\n for (let attempt = 0; attempt < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted; attempt += 1) {\n try {\n pairResponse = await probe(`${origin}${PAIRING_PAGE_ROUTE}`, selfTestAbort.signal);\n healthResponse = await probe(`${origin}/api/health`, selfTestAbort.signal);\n if (pairResponse.status !== EDGE_TUNNEL_UNAVAILABLE && healthResponse.status !== EDGE_TUNNEL_UNAVAILABLE)\n break;\n cause = `Cloudflare edge answered ${String(healthResponse.status)} before the connector registered`;\n } catch (error) {\n cause = error instanceof Error ? error.message : String(error);\n }\n if (attempt + 1 < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted) await waitToRetry();\n }\n if (pairResponse === undefined || healthResponse === undefined) {\n return { ok: false, failure: 'self_test_failed', message: `The tunnel did not answer: ${cause}` };\n }\n if (healthResponse.status !== UNAUTHORIZED) {\n // The agent would be on the public internet unauthenticated. This is\n // the one failure worth an automatic abort rather than a warning.\n const message = `${describeTunnelFailure('self_test_failed')} /api/health answered ${String(healthResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n if (pairResponse.status !== OK || !pairResponse.body.includes(PAIRING_PAGE_MARKER)) {\n const message = `The pairing page answered ${String(pairResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n notice(`tunnel ready at ${origin}`);\n return { ok: true, publicOrigin: origin, stop };\n };\n\n const consider = (chunk: string): void => {\n lines.push(chunk);\n if (settle === undefined || selfTestStarted) return;\n seenUrl ??= extractTunnelUrl(chunk);\n seenConnection ||= mentionsRegisteredConnection(chunk);\n if (seenUrl === undefined || !seenConnection) return;\n selfTestStarted = true;\n input.acceptOrigin?.(seenUrl);\n void runSelfTest(seenUrl).then((result) => settle?.(result));\n };\n\n child.stdout?.on('data', (data: Buffer) => consider(data.toString()));\n child.stderr?.on('data', (data: Buffer) => consider(data.toString()));\n\n return await new Promise<TunnelStartResult>((resolve) => {\n let deadline: ReturnType<typeof setTimeout>;\n const finish = (result: TunnelStartResult, stopProcess = !result.ok): void => {\n if (settle === undefined) return;\n settle = undefined;\n clearTimeout(deadline);\n input.signal?.removeEventListener('abort', cancel);\n selfTestAbort.abort();\n if (stopProcess) {\n void stop().then(() => resolve(result));\n } else {\n resolve(result);\n }\n };\n const cancel = (): void => {\n finish({ ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' });\n };\n settle = (result) => finish(result);\n deadline = setTimeout(() => {\n finish({\n ok: false,\n failure: 'timeout',\n message: `${describeTunnelFailure('timeout')}\\n${tailOf(lines)}`,\n });\n }, startTimeoutMs);\n input.signal?.addEventListener('abort', cancel, { once: true });\n\n child.once('error', (error) => {\n finish({\n ok: false,\n failure: 'spawn_failed',\n message: `${describeTunnelFailure('spawn_failed')} ${error.message}`,\n });\n });\n\n child.once('exit', async (code) => {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(runtimeTokenPath, { force: true }).catch((error: unknown) => {\n notice(`Tunnel token cleanup failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n const message = `${describeTunnelFailure('exited')} (code ${String(code)})\\n${tailOf(lines)}`;\n if (settle !== undefined) {\n finish({ ok: false, failure: 'exited', message }, false);\n return;\n }\n // It came up and then died: network loss, an edge rejection, or a\n // self-update. The supervisor either replaces a named connector or tells\n // the host to fail closed rather than leave an unreachable cockpit enabled.\n if (!stopped) options.onExit?.(message);\n });\n\n // A named tunnel already knows its hostname, but it still waits for\n // cloudflared to register an edge connection before probing the public URL.\n if (input.signal?.aborted === true) cancel();\n });\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/tunnelProcess/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync, rmSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { PAIRING_PAGE_ROUTE } from '../../constants/remote';\nimport {\n type TunnelConfig,\n type TunnelLauncher,\n type TunnelStartInput,\n type TunnelStartResult,\n} from '../../types/remote';\nimport { PAIRING_PAGE_MARKER } from '../pairingPage';\nimport { describeTunnelFailure, extractTunnelUrl, mentionsRegisteredConnection, tunnelArgs } from '../tunnelOutput';\n\n/** Explicit binary path, ahead of a PATH scan. */\nexport const CLOUDFLARED_ENV = 'PO_CLOUDFLARED';\n// Give new quick-host DNS and negative caches time to settle, within a bounded startup.\nconst START_TIMEOUT_MS = 120_000;\nconst TERMINATE_GRACE_MS = 2000;\nconst SELF_TEST_ATTEMPTS = 240;\nconst SELF_TEST_RETRY_MS = 500;\nconst NAMED_RESTART_ATTEMPTS = 3;\nconst NAMED_RESTART_BASE_DELAY_MS = 500;\nconst NAMED_RESTART_MAX_DELAY_MS = 4000;\nconst NAMED_RESTART_STABLE_MS = 60_000;\n/** Lines of process output kept for a failure report. */\nconst LOG_TAIL = 20;\nconst UNAUTHORIZED = 401;\n/** Cloudflare has the DNS route but no connector has registered yet. */\nconst EDGE_TUNNEL_UNAVAILABLE = 530;\nconst OK = 200;\nconst PID_FILE = 'tunnel.pid';\nconst TOKEN_FILE = 'tunnel.token';\nconst FILE_MODE = 0o600;\n/** A pid file older than this is stale beyond usefulness and the pid has likely been recycled. */\nconst PID_FILE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport interface ProbeResult {\n status: number;\n body: string;\n}\n\nexport interface TunnelProcessOptions {\n /** Explicit binary, ahead of the env var and the PATH scan. */\n cloudflaredPath?: string;\n stateDir: string;\n onNotice?: (message: string) => void;\n /** Test seam: stands in for node:child_process.spawn. */\n spawnProcess?: typeof spawn;\n /** Test seam: reaches the tunnel from outside, so the self-test needs no network. */\n probe?: (url: string, signal: AbortSignal) => Promise<ProbeResult>;\n /** Test seam: production waits briefly for a new public hostname to propagate. */\n selfTestRetryMs?: number;\n /** Test seam: production bounds the complete startup, including its self-test. */\n startTimeoutMs?: number;\n /** Test seam: production backs named-tunnel restarts off from 500 ms. */\n restartBaseDelayMs?: number;\n /** Test seam: production resets the rapid-crash budget after one stable minute. */\n restartStableMs?: number;\n /** Called after a quick tunnel exits, or after named-tunnel recovery is exhausted. */\n onExit?: (message: string) => void;\n}\n\n/**\n * Finds cloudflared without a shell.\n *\n * A manual scan rather than `which`: spawning a shell to locate a binary is a\n * quoting hazard for no benefit, and this also works the same on every platform.\n */\nexport async function findCloudflared(env: NodeJS.ProcessEnv = process.env): Promise<string | undefined> {\n const names = process.platform === 'win32' ? ['cloudflared.exe', 'cloudflared'] : ['cloudflared'];\n for (const directory of (env.PATH ?? '').split(path.delimiter)) {\n if (directory === '') continue;\n for (const name of names) {\n const candidate = path.join(directory, name);\n try {\n await fs.access(candidate, fs.constants.X_OK);\n return candidate;\n } catch {\n // Not here, or not executable; keep looking.\n }\n }\n }\n return undefined;\n}\n\nasync function defaultProbe(url: string, signal: AbortSignal): Promise<ProbeResult> {\n const response = await fetch(url, { redirect: 'manual', signal });\n return { status: response.status, body: await response.text() };\n}\n\n/**\n * Kills a tunnel left behind by a hub that could not clean up after itself.\n *\n * A SIGKILLed hub never runs its exit handler, and the child is not detached so\n * it is reparented rather than killed. It then holds the tunnel open against a\n * dead port. This is the sweep on the next start.\n *\n * The residual risk is pid reuse after a reboot. The age window narrows it and\n * on Linux the command line is checked; macOS has no equally cheap check, so\n * there the window stands.\n */\ninterface TunnelPidRecord {\n pid?: unknown;\n ownerPid?: unknown;\n startedAt?: unknown;\n}\n\nfunction validPid(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;\n}\n\n/** Only ESRCH proves the owner is gone; permission and platform errors fail safe. */\nfunction ownerMayBeAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code !== 'ESRCH';\n }\n}\n\n// sync: exported createRemoteRuntime must reap stale public tunnels before its synchronous startup returns.\nexport function reapStaleTunnel(stateDir: string, onNotice: (message: string) => void): void {\n const pidPath = path.join(stateDir, PID_FILE);\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let raw: string;\n try {\n raw = readFileSync(pidPath, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') rmSync(tokenPath, { force: true });\n return; // No pid file is the normal case; other read failures are unsafe to guess through.\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return; // A malformed record cannot prove that its owner is gone.\n }\n if (typeof parsed !== 'object' || parsed === null) return;\n const record = parsed as TunnelPidRecord;\n if (Object.hasOwn(record, 'ownerPid')) {\n if (!validPid(record.ownerPid) || ownerMayBeAlive(record.ownerPid)) return;\n }\n\n rmSync(tokenPath, { force: true });\n rmSync(pidPath, { force: true });\n const pid = validPid(record.pid) ? record.pid : undefined;\n const startedAt = typeof record.startedAt === 'number' ? record.startedAt : 0;\n if (pid === undefined || Date.now() - startedAt > PID_FILE_MAX_AGE_MS) return;\n if (process.platform === 'linux') {\n try {\n if (!readFileSync(`/proc/${String(pid)}/cmdline`, 'utf8').includes('cloudflared')) return;\n } catch {\n return; // The process is gone.\n }\n }\n try {\n process.kill(pid, 'SIGTERM');\n onNotice(`stopped a tunnel left running by a previous hub (pid ${String(pid)})`);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') onNotice(`Could not stop stale tunnel: ${String(error)}`);\n }\n}\n\nfunction tailOf(lines: readonly string[]): string {\n return lines.slice(-LOG_TAIL).join('').trim();\n}\n\n/** Copies a named tunnel token to a private runtime file understood by cloudflared. */\nasync function writeTokenFile(config: TunnelConfig, stateDir: string): Promise<string | undefined> {\n if (config.kind !== 'named' || config.tokenFile === undefined) return undefined;\n let token: string;\n let sourcePath: string;\n try {\n sourcePath = await fs.realpath(config.tokenFile);\n token = (await fs.readFile(sourcePath, 'utf8')).trim();\n } catch {\n return undefined;\n }\n if (token === '') return undefined;\n await fs.mkdir(stateDir, { recursive: true, mode: 0o700 });\n const tokenPath = path.join(stateDir, TOKEN_FILE);\n let existingTarget: string | undefined;\n try {\n existingTarget = await fs.realpath(tokenPath);\n } catch (error) {\n // Missing is the normal state before launch; other failures must not hide an alias.\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n if (sourcePath === path.resolve(tokenPath) || sourcePath === existingTarget) {\n throw new Error('The configured tunnel token file cannot also be Po runtime token storage.');\n }\n await fs.rm(tokenPath, { force: true });\n await fs.writeFile(tokenPath, token, { mode: FILE_MODE });\n await fs.chmod(tokenPath, FILE_MODE);\n return tokenPath;\n}\n\nexport function createTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const restartBaseDelayMs = options.restartBaseDelayMs ?? NAMED_RESTART_BASE_DELAY_MS;\n const restartStableMs = options.restartStableMs ?? NAMED_RESTART_STABLE_MS;\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n let stopped = false;\n let activeStop: (() => Promise<void>) | undefined;\n let stopPromise: Promise<void> | undefined;\n let recoveryPromise: Promise<void> | undefined;\n let pendingExit: string | undefined;\n let restartCount = 0;\n let lastReadyAt = 0;\n const recoveryAbort = new AbortController();\n const signal =\n input.signal === undefined ? recoveryAbort.signal : AbortSignal.any([input.signal, recoveryAbort.signal]);\n const supervisedInput: TunnelStartInput = { ...input, signal };\n\n function queueUnexpectedExit(message: string): void {\n if (stopped) return;\n if (input.config.kind === 'quick') {\n options.onExit?.(message);\n return;\n }\n if (recoveryPromise !== undefined) {\n pendingExit = message;\n return;\n }\n beginRecovery(message);\n }\n\n const single = createSingleTunnelLauncher({ ...options, onExit: queueUnexpectedExit });\n\n async function waitForRestart(attempt: number): Promise<void> {\n if (recoveryAbort.signal.aborted) return;\n const delayMs = Math.min(restartBaseDelayMs * 2 ** (attempt - 1), NAMED_RESTART_MAX_DELAY_MS);\n await new Promise<void>((resolve) => {\n let timer: ReturnType<typeof setTimeout>;\n const done = (): void => {\n clearTimeout(timer);\n recoveryAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n timer = setTimeout(done, delayMs);\n recoveryAbort.signal.addEventListener('abort', done, { once: true });\n if (recoveryAbort.signal.aborted) done();\n });\n }\n\n async function recover(initialMessage: string): Promise<void> {\n if (Date.now() - lastReadyAt >= restartStableMs) restartCount = 0;\n let lastFailure = initialMessage;\n while (!stopped && restartCount < NAMED_RESTART_ATTEMPTS) {\n restartCount += 1;\n notice(\n `cloudflared stopped; restarting named tunnel (attempt ${String(restartCount)} of ${String(NAMED_RESTART_ATTEMPTS)})`,\n );\n await waitForRestart(restartCount);\n if (stopped) return;\n\n const outcome = await single(supervisedInput);\n if (stopped) {\n if (outcome.ok) {\n await outcome.stop().catch((error: unknown) => {\n notice(`Could not stop recovered tunnel: ${String(error)}`);\n });\n }\n return;\n }\n if (!outcome.ok) {\n lastFailure = outcome.message;\n continue;\n }\n activeStop = outcome.stop;\n lastReadyAt = Date.now();\n notice(`named tunnel recovered at ${outcome.publicOrigin}`);\n return;\n }\n\n if (!stopped) {\n options.onExit?.(\n `${initialMessage}\\nNamed tunnel recovery failed after ${String(NAMED_RESTART_ATTEMPTS)} attempts. Last failure: ${lastFailure}`,\n );\n }\n }\n\n function beginRecovery(message: string): void {\n recoveryPromise = recover(message)\n .catch((error: unknown) => {\n if (!stopped) {\n const cause = error instanceof Error ? error.message : String(error);\n options.onExit?.(`${message}\\nNamed tunnel recovery failed: ${cause}`);\n }\n })\n .finally(() => {\n recoveryPromise = undefined;\n const queued = pendingExit;\n pendingExit = undefined;\n if (queued !== undefined && !stopped) beginRecovery(queued);\n });\n }\n\n const initial = await single(supervisedInput);\n if (!initial.ok) {\n stopped = true;\n recoveryAbort.abort();\n return initial;\n }\n activeStop = initial.stop;\n lastReadyAt = Date.now();\n\n const stop = async (): Promise<void> => {\n if (stopPromise !== undefined) return await stopPromise;\n stopped = true;\n recoveryAbort.abort();\n const recovering = recoveryPromise;\n stopPromise = (async () => {\n await activeStop?.().catch((error: unknown) => {\n notice(`Could not stop tunnel: ${String(error)}`);\n });\n await recovering?.catch((error: unknown) => {\n notice(`Tunnel recovery cleanup failed: ${String(error)}`);\n });\n await fs.rm(path.join(options.stateDir, PID_FILE), { force: true });\n await fs.rm(path.join(options.stateDir, TOKEN_FILE), { force: true });\n })();\n return await stopPromise;\n };\n\n return { ok: true, publicOrigin: initial.publicOrigin, stop };\n };\n}\n\n/** Starts one cloudflared child; the exported launcher supervises successive named-tunnel children. */\nfunction createSingleTunnelLauncher(options: TunnelProcessOptions): TunnelLauncher {\n const notice = options.onNotice ?? ((): void => {});\n const spawnProcess = options.spawnProcess ?? spawn;\n const probe = options.probe ?? defaultProbe;\n const selfTestRetryMs = options.selfTestRetryMs ?? SELF_TEST_RETRY_MS;\n const startTimeoutMs = options.startTimeoutMs ?? START_TIMEOUT_MS;\n const pidPath = path.join(options.stateDir, PID_FILE);\n const runtimeTokenPath = path.join(options.stateDir, TOKEN_FILE);\n\n return async function launch(input: TunnelStartInput): Promise<TunnelStartResult> {\n if (input.signal?.aborted === true) {\n return { ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' };\n }\n const binary = options.cloudflaredPath ?? process.env[CLOUDFLARED_ENV] ?? (await findCloudflared());\n if (binary === undefined || binary === '') {\n return { ok: false, failure: 'not_installed', message: describeTunnelFailure('not_installed') };\n }\n\n let tokenPath: string | undefined;\n try {\n tokenPath = await writeTokenFile(input.config, options.stateDir);\n } catch (error) {\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n const args = tunnelArgs(input.config, input.port, tokenPath);\n let child: ChildProcess;\n try {\n // Never detached and never unref'd. A detached child becomes a process\n // group leader that survives the terminal's SIGINT, which is exactly the\n // orphaned public tunnel this must avoid. Contrast serverSpawner.ts,\n // which detaches on purpose because sessions outlive the hub.\n child = spawnProcess(binary, args, { detached: false, stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (error) {\n await fs.rm(runtimeTokenPath, { force: true });\n const cause = error instanceof Error ? error.message : String(error);\n return { ok: false, failure: 'spawn_failed', message: `${describeTunnelFailure('spawn_failed')} ${cause}` };\n }\n\n const lines: string[] = [];\n let stopped = false;\n let settle: ((result: TunnelStartResult) => void) | undefined;\n let selfTestStarted = false;\n const selfTestAbort = new AbortController();\n\n const killTree = (): void => {\n try {\n child.kill('SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not stop tunnel: ${String(error)}`);\n }\n };\n const onProcessExit = (): void => {\n // sync: Node does not await filesystem cleanup in the process exit handler.\n // This is the net under process.exit(), an uncaught exception, and an\n // unhandled rejection, none of which reach the graceful close path.\n rmSync(runtimeTokenPath, { force: true });\n try {\n if (child.pid !== undefined) process.kill(child.pid, 'SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH')\n notice(`Could not kill tunnel at exit: ${String(error)}`);\n }\n };\n process.once('exit', onProcessExit);\n\n const stop = async (): Promise<void> => {\n if (stopped) return;\n stopped = true;\n if (child.exitCode !== null || child.signalCode !== null) {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n return;\n }\n await new Promise<void>((resolve) => {\n const escalate = setTimeout(() => {\n try {\n child.kill('SIGKILL');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ESRCH') notice(`Could not kill tunnel: ${String(error)}`);\n }\n }, TERMINATE_GRACE_MS);\n child.once('exit', () => {\n clearTimeout(escalate);\n resolve();\n });\n killTree();\n });\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(pidPath, { force: true });\n await fs.rm(runtimeTokenPath, { force: true });\n };\n\n // Register child listeners below without yielding, so early exits cannot be missed.\n // Cleanup waits for this ordered write before removing the record.\n const pidWrite = fs\n .mkdir(options.stateDir, { recursive: true, mode: 0o700 })\n .then(() =>\n fs.writeFile(\n pidPath,\n JSON.stringify({ pid: child.pid, ownerPid: process.pid, startedAt: Date.now(), command: binary }),\n { mode: FILE_MODE },\n ),\n )\n .catch((error: unknown) => {\n // The reaper is a safety net; report unavailable recovery without blocking startup.\n notice(`Could not write tunnel process record: ${String(error)}`);\n });\n\n const configuredOrigin = input.config.kind === 'named' ? `https://${input.config.hostname}` : undefined;\n let seenUrl = configuredOrigin;\n let seenConnection = false;\n\n const waitToRetry = async (): Promise<void> => {\n if (selfTestRetryMs <= 0) return;\n await new Promise<void>((resolve) => {\n const done = (): void => {\n clearTimeout(timer);\n selfTestAbort.signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, selfTestRetryMs);\n selfTestAbort.signal.addEventListener('abort', done, { once: true });\n });\n };\n\n /** Proves end to end that pairing is reachable and that everything else is not. */\n const runSelfTest = async (origin: string): Promise<TunnelStartResult> => {\n let pairResponse: ProbeResult | undefined;\n let healthResponse: ProbeResult | undefined;\n let cause = 'fetch failed';\n for (let attempt = 0; attempt < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted; attempt += 1) {\n try {\n pairResponse = await probe(`${origin}${PAIRING_PAGE_ROUTE}`, selfTestAbort.signal);\n healthResponse = await probe(`${origin}/api/health`, selfTestAbort.signal);\n if (pairResponse.status !== EDGE_TUNNEL_UNAVAILABLE && healthResponse.status !== EDGE_TUNNEL_UNAVAILABLE)\n break;\n cause = `Cloudflare edge answered ${String(healthResponse.status)} before the connector registered`;\n } catch (error) {\n cause = error instanceof Error ? error.message : String(error);\n }\n if (attempt + 1 < SELF_TEST_ATTEMPTS && !selfTestAbort.signal.aborted) await waitToRetry();\n }\n if (pairResponse === undefined || healthResponse === undefined) {\n return { ok: false, failure: 'self_test_failed', message: `The tunnel did not answer: ${cause}` };\n }\n if (healthResponse.status !== UNAUTHORIZED) {\n // The agent would be on the public internet unauthenticated. This is\n // the one failure worth an automatic abort rather than a warning.\n const message = `${describeTunnelFailure('self_test_failed')} /api/health answered ${String(healthResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n if (pairResponse.status !== OK || !pairResponse.body.includes(PAIRING_PAGE_MARKER)) {\n const message = `The pairing page answered ${String(pairResponse.status)} through the tunnel.`;\n notice(message);\n return { ok: false, failure: 'self_test_failed', message };\n }\n notice(`tunnel ready at ${origin}`);\n return { ok: true, publicOrigin: origin, stop };\n };\n\n const consider = (chunk: string): void => {\n lines.push(chunk);\n if (settle === undefined || selfTestStarted) return;\n seenUrl ??= extractTunnelUrl(chunk);\n seenConnection ||= mentionsRegisteredConnection(chunk);\n if (seenUrl === undefined || !seenConnection) return;\n selfTestStarted = true;\n input.acceptOrigin?.(seenUrl);\n void runSelfTest(seenUrl).then((result) => settle?.(result));\n };\n\n child.stdout?.on('data', (data: Buffer) => consider(data.toString()));\n child.stderr?.on('data', (data: Buffer) => consider(data.toString()));\n\n return await new Promise<TunnelStartResult>((resolve) => {\n let deadline: ReturnType<typeof setTimeout>;\n const finish = (result: TunnelStartResult, stopProcess = !result.ok): void => {\n if (settle === undefined) return;\n settle = undefined;\n clearTimeout(deadline);\n input.signal?.removeEventListener('abort', cancel);\n selfTestAbort.abort();\n if (stopProcess) {\n void stop().then(() => resolve(result));\n } else {\n resolve(result);\n }\n };\n const cancel = (): void => {\n finish({ ok: false, failure: 'exited', message: 'Tunnel startup was cancelled.' });\n };\n settle = (result) => finish(result);\n deadline = setTimeout(() => {\n finish({\n ok: false,\n failure: 'timeout',\n message: `${describeTunnelFailure('timeout')}\\n${tailOf(lines)}`,\n });\n }, startTimeoutMs);\n input.signal?.addEventListener('abort', cancel, { once: true });\n\n child.once('error', (error) => {\n finish({\n ok: false,\n failure: 'spawn_failed',\n message: `${describeTunnelFailure('spawn_failed')} ${error.message}`,\n });\n });\n\n child.once('exit', async (code) => {\n process.off('exit', onProcessExit);\n await pidWrite;\n await fs.rm(runtimeTokenPath, { force: true }).catch((error: unknown) => {\n notice(`Tunnel token cleanup failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n const message = `${describeTunnelFailure('exited')} (code ${String(code)})\\n${tailOf(lines)}`;\n if (settle !== undefined) {\n finish({ ok: false, failure: 'exited', message }, false);\n return;\n }\n // It came up and then died: network loss, an edge rejection, or a\n // self-update. The supervisor either replaces a named connector or tells\n // the host to fail closed rather than leave an unreachable cockpit enabled.\n if (!stopped) options.onExit?.(message);\n });\n\n // A named tunnel already knows its hostname, but it still waits for\n // cloudflared to register an edge connection before probing the public URL.\n if (input.signal?.aborted === true) cancel();\n });\n };\n}\n"],"mappings":"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"}
@@ -509,6 +509,8 @@ export interface DashboardTileData {
509
509
  title: string;
510
510
  icon?: ActivityGroupContribution['icon'];
511
511
  size?: DashboardTileSize;
512
+ /** Web column preference; native keeps the fill's reading order. */
513
+ column?: 'main' | 'side';
512
514
  open?: {
513
515
  kind: 'page' | 'settings';
514
516
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"webPlugin.d.mts","names":[],"sources":["../../../../src/web/types/webPlugin.ts"],"mappings":"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"}
1
+ {"version":3,"file":"webPlugin.d.mts","names":[],"sources":["../../../../src/web/types/webPlugin.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-core",
3
- "version": "0.0.0-alpha.83",
3
+ "version": "0.0.0-alpha.85",
4
4
  "description": "Po runtime systems and reusable core services.",
5
5
  "keywords": [
6
6
  "ai",
@@ -569,8 +569,8 @@
569
569
  "registry": "https://registry.npmjs.org/"
570
570
  },
571
571
  "dependencies": {
572
- "@agimon-ai/po-logsink": "0.0.1-alpha.65",
573
- "@agimon-ai/po-web-security": "0.0.0-alpha.83",
572
+ "@agimon-ai/po-logsink": "0.0.1-alpha.67",
573
+ "@agimon-ai/po-web-security": "0.0.0-alpha.85",
574
574
  "@deepseek-ai/cordis": "4.0.5",
575
575
  "@earendil-works/chord": "1.4.0",
576
576
  "@earendil-works/pi-agent-core": "1.4.0",
@@ -594,7 +594,7 @@
594
594
  "yaml": "2.9.1"
595
595
  },
596
596
  "devDependencies": {
597
- "@agimon-ai/vibe-lint-plugin-po-core": "0.0.0-alpha.83",
597
+ "@agimon-ai/vibe-lint-plugin-po-core": "0.0.0-alpha.85",
598
598
  "@apidevtools/swagger-parser": "^13.1.0",
599
599
  "@asyncapi/parser": "^3.6.4",
600
600
  "@earendil-works/pi-ai": "1.4.0",