Files
triggershell/src/cli/lib/network.ts
T
valknarandClaude Sonnet 5 c6337ea942 Run prettier across the repo, exclude the lockfile from it
Prettier had never been run in --check mode here before, so this had
drifted across most files (markdown tables, long option() chains,
line wrapping). Purely formatting, no logic changes - needed so a CI
format:check gate can actually pass. Adds .prettierignore for
pnpm-lock.yaml specifically: prettier's YAML formatter rewrites every
quoted key (single -> double quotes) producing an ~8700-line diff of
pure noise on a file pnpm itself owns the formatting of.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 13:55:25 +02:00

70 lines
1.9 KiB
TypeScript

import { spawn } from "node:child_process";
import net from "node:net";
export function isPortFree(host: string, port: number): Promise<boolean> {
return new Promise((resolve) => {
const socket = net.connect({ host, port, timeout: 500 });
socket.once("connect", () => {
socket.destroy();
resolve(false);
});
socket.once("timeout", () => {
socket.destroy();
resolve(true);
});
socket.once("error", () => {
resolve(true);
});
});
}
export async function waitUntilReady(
url: string,
timeoutMs: number,
intervalMs = 400,
): Promise<boolean> {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
try {
const response = await fetch(url, { signal: AbortSignal.timeout(1500) });
if (response.status === 200) return true;
} catch {
// not ready yet
}
await new Promise((resolve) => setTimeout(resolve, intervalMs));
}
return false;
}
/** Single-shot check (not a poll loop, unlike `waitUntilReady`) for whether a triggershell server
* is already listening at `url` - used to decide whether `run` can go through the REST/WS API. */
export async function isServerReachable(url: string): Promise<boolean> {
try {
const response = await fetch(`${url}/api/healthz`, {
signal: AbortSignal.timeout(1000),
});
return response.status === 200;
} catch {
return false;
}
}
export function openBrowser(url: string): void {
const command =
process.platform === "darwin"
? "open"
: process.platform === "win32"
? "start"
: "xdg-open";
const args = process.platform === "win32" ? ["", url] : [url];
try {
spawn(command, args, {
detached: true,
stdio: "ignore",
shell: process.platform === "win32",
}).unref();
} catch {
// best-effort - not fatal if no browser opener is available
}
}