1import * as Effect from "effect/Effect";
2import { Command } from "effect/cli";
3
4import { main as runServiceLauncher } from "../serviceLauncher.ts";
5
6/**
7 * Hosts the service launcher inside the CLI executable. The service manager
8 * runs `t3 __service-launcher` and the launcher spawns the server from the
9 * same executable, so the machine needs no Node to run either.
10 *
11 * The launcher owns SIGTERM handling and the process lifetime: it must finish
12 * stopping its child before the process exits, so it runs detached from the
13 * CLI's fiber rather than under `runMain`, whose signal handler would
14 * interrupt the fiber and exit while the child is still being terminated.
15 */
16export const serviceLauncherCommand = Command.make("__service-launcher").pipe(
17 Command.unlisted,
18 Command.withHandler(() =>
19 Effect.sync(() => {
20 runServiceLauncher().catch((cause: unknown) => {
21 const error = cause instanceof Error ? cause : new Error(String(cause));
22 process.stderr.write(`[service-launcher] ${error.message}\n`);
23 process.exitCode = 1;
24 });
25 }),
26 ),
27);