(input: {
port: number;
hostname: string;
allowedHosts: ReadonlyArray<string>;
})
| 1317 | // command is idempotent: re-running while a daemon is already up should report success |
| 1318 | // (matching the auto-start behaviour) rather than fail or spawn a duplicate. |
| 1319 | const runBackgroundDaemonStart = (input: { |
| 1320 | port: number; |
| 1321 | hostname: string; |
| 1322 | allowedHosts: ReadonlyArray<string>; |
| 1323 | }): Effect.Effect<void, Error, FileSystem.FileSystem | PlatformPath.Path> => |
| 1324 | Effect.gen(function* () { |
| 1325 | const host = canonicalDaemonHost(input.hostname); |
| 1326 | const requestedUrl = daemonBaseUrl(host, input.port); |
| 1327 | const target = yield* resolveDaemonTarget(requestedUrl); |
| 1328 | |
| 1329 | if (yield* isServerReachable(target.baseUrl)) { |
| 1330 | console.log(`Daemon already running at ${target.baseUrl}.`); |
| 1331 | return; |
| 1332 | } |
| 1333 | |
| 1334 | if (!canAutoStartLocalDaemonForHost(host)) { |
| 1335 | return yield* Effect.fail( |
| 1336 | new Error( |
| 1337 | [ |
| 1338 | `Cannot background a daemon for non-local host ${host}.`, |
| 1339 | `Use --foreground or bind to localhost / 127.0.0.1.`, |
| 1340 | ].join("\n"), |
| 1341 | ), |
| 1342 | ); |
| 1343 | } |
| 1344 | |
| 1345 | const startBaseUrl = yield* spawnAndWaitForDaemon({ |
| 1346 | host, |
| 1347 | scopeId: target.scopeId, |
| 1348 | preferredPort: input.port, |
| 1349 | allowedHosts: input.allowedHosts, |
| 1350 | }); |
| 1351 | |
| 1352 | console.log(`Daemon ready on ${startBaseUrl}`); |
| 1353 | }).pipe(Effect.mapError(toError)); |
| 1354 | |
| 1355 | // --------------------------------------------------------------------------- |
| 1356 | // Stdio MCP session: a pure stdio <-> HTTP bridge to the owning local daemon. |
no test coverage detected