import { randomUUID } from "node:crypto";import { existsSync, realpathSync } from "node:fs";import { dirname, join, resolve } from "node:path";// Make sibling binaries (if any are added later) discoverable on $PATH so// child processes spawned without an absolute path still find them.const execDir = dirname(process.execPath);if (process.env.PATH && !process.env.PATH.includes(execDir)) { process.env.PATH = `${execDir}:${process.env.PATH}`;} // Point the keychain plugin at the colocated @napi-rs/keyring binding.// bun --compile doesn't include .node files in bunfs, so the loader's// normal `require('@napi-rs/keyring-<plat>-<arch>')` walk fails inside the// binary. We can't use NAPI_RS_NATIVE_LIBRARY_PATH because @napi-rs/keyring// 1.2.0 has a bug where the env-var branch assigns to a local variable that// gets overwritten before the binding is returned. build.ts copies the// platform .node next to the executor; the keychain plugin reads this var// and loads the file directly via createRequire, bypassing the broken// loader.const keyringNodeOnDisk = join(execDir, "keyring.node");if ( typeof Bun !== "undefined" && !process.env.EXECUTOR_KEYRING_NATIVE_PATH && (await Bun.file(keyringNodeOnDisk).exists())) { process.env.EXECUTOR_KEYRING_NATIVE_PATH = keyringNodeOnDisk;} // Pre-load QuickJS WASM for compiled binaries — must run before server importsconst wasmOnDisk = join(execDir, "emscripten-module.wasm");if (typeof Bun !== "undefined" && (await Bun.file(wasmOnDisk).exists())) { const { setQuickJSModule } = await import("@executor-js/runtime-quickjs"); const { newQuickJSWASMModule } = await import("quickjs-emscripten"); type QuickJSSyncVariant = import("quickjs-emscripten").QuickJSSyncVariant; const wasmBinary = await Bun.file(wasmOnDisk).arrayBuffer(); const importFFI: QuickJSSyncVariant["importFFI"] = () => import("@jitl/quickjs-wasmfile-release-sync/ffi").then((m) => m.QuickJSFFI); const importModuleLoader: QuickJSSyncVariant["importModuleLoader"] = async () => { const { default: original } = await import("@jitl/quickjs-wasmfile-release-sync/emscripten-module"); return (moduleArg = {}) => original({ ...moduleArg, wasmBinary }); }; const variant: QuickJSSyncVariant = { type: "sync" as const, importFFI, importModuleLoader, }; const mod = await newQuickJSWASMModule(variant); setQuickJSModule(mod);} import { Argument as Args, Command, Flag as Options } from "effect/unstable/cli";import { BunRuntime, BunServices } from "@effect/platform-bun";import { HttpApiClient } from "effect/unstable/httpapi";import { FetchHttpClient } from "effect/unstable/http";import { FileSystem, Path as PlatformPath } from "effect";import * as Effect from "effect/Effect";import * as Option from "effect/Option";import * as Cause from "effect/Cause"; import { ExecutorApi } from "@executor-js/api";import { startServer, runMcpStdioServer, getExecutor } from "@executor-js/local";import { makeQuickJsExecutor } from "@executor-js/runtime-quickjs";import { fetchIntegrations } from "./integrations";import { buildDaemonSpawnSpec, chooseDaemonPort, canAutoStartLocalDaemonForHost, isDevCliEntrypoint, parseDaemonBaseUrl, spawnDetached, waitForReachable, waitForUnreachable,} from "./daemon";import { acquireDaemonStartLock, canonicalDaemonHost, currentDaemonScopeId, isPidAlive, readDaemonPointer, readDaemonRecord, releaseDaemonStartLock, removeDaemonPointer, removeDaemonRecord, terminatePid, writeDaemonPointer, writeDaemonRecord,} from "./daemon-state";import { buildResumeContentTemplate, buildToolPath, buildDescribeToolCode, filterToolPathChildren, buildInvokeToolCode, buildListSourcesCode, buildSearchToolsCode, extractExecutionId, extractPausedInteraction, extractExecutionResult, inspectToolPath, normalizeCliErrorText, parseJsonObjectInput, sanitizeCliOutputText, shellQuoteArg,} from "./tooling"; // Embedded web UI — baked into compiled binaries via `with { type: "file" }`import embeddedWebUI from "./embedded-web-ui.gen"; // ---------------------------------------------------------------------------// Constants// --------------------------------------------------------------------------- const { version: CLI_VERSION } = await import("../package.json");const DEFAULT_PORT = 4788;const DEFAULT_BASE_URL = `http://localhost:${DEFAULT_PORT}`;const DAEMON_BOOT_TIMEOUT_MS = 15_000;const DAEMON_BOOT_POLL_MS = 150;const DAEMON_STOP_TIMEOUT_MS = 10_000; // ---------------------------------------------------------------------------// Helpers// --------------------------------------------------------------------------- const waitForShutdownSignal = () => Effect.callback<void, never>((resume) => { const shutdown = () => resume(Effect.void); process.once("SIGINT", shutdown); process.once("SIGTERM", shutdown); return Effect.sync(() => { process.off("SIGINT", shutdown); process.off("SIGTERM", shutdown); }); }); // ---------------------------------------------------------------------------// Background server management// --------------------------------------------------------------------------- const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); interface DaemonScopeInfo { readonly id: string; readonly name: string; readonly dir: string;} const readDaemonScopeInfo = (baseUrl: string): Effect.Effect<DaemonScopeInfo | null> => Effect.tryPromise(() => fetch(`${baseUrl}/api/scope`, { signal: AbortSignal.timeout(2000) }), ).pipe( Effect.flatMap((res) => { if (!res.ok) return Effect.succeed(null); return Effect.tryPromise(() => res.json()).pipe( Effect.map((payload) => { if (!isRecord(payload)) return null; if ( typeof payload.id === "string" && typeof payload.name === "string" && typeof payload.dir === "string" ) { return { id: payload.id, name: payload.name, dir: payload.dir, }; } return null; }), Effect.catchCause(() => Effect.succeed(null)), ); }), Effect.catchCause(() => Effect.succeed(null)), ); const isServerReachable = (baseUrl: string): Effect.Effect<boolean> => readDaemonScopeInfo(baseUrl).pipe(Effect.map((scopeInfo) => scopeInfo !== null)); const normalizeDaemonScopeDir = (dir: string): string => { const resolved = resolve(dir); return existsSync(resolved) ? realpathSync.native(resolved) : resolved;}; const currentDaemonScopeDir = (): string => normalizeDaemonScopeDir(process.env.EXECUTOR_SCOPE_DIR ?? process.cwd()); const script = process.argv[1];const isDevMode = isDevCliEntrypoint(script);const cliPrefix = isDevMode ? `bun run ${script}` : "executor"; const toError = (cause: unknown): Error => cause instanceof Error ? cause : new Error(String(cause)); const parseDaemonUrl = (baseUrl: string) => Effect.try({ try: () => parseDaemonBaseUrl(baseUrl, DEFAULT_PORT), catch: (cause) => cause instanceof Error ? cause : new Error(`Invalid base URL: ${String(cause)}`), }); const daemonBaseUrl = (hostname: string, port: number): string => `http://${canonicalDaemonHost(hostname)}:${port}`; const installDefaultExecutorWebBaseUrl = (baseUrl: string): (() => void) => { if (process.env.EXECUTOR_WEB_BASE_URL !== undefined) { return () => {}; } process.env.EXECUTOR_WEB_BASE_URL = baseUrl; return () => { delete process.env.EXECUTOR_WEB_BASE_URL; };}; const cleanupPointer = (input: { hostname: string; scopeId: string; port: number }) => Effect.gen(function* () { yield* removeDaemonPointer({ hostname: input.hostname, scopeId: input.scopeId }).pipe( Effect.ignore, ); yield* removeDaemonRecord({ hostname: input.hostname, port: input.port }).pipe(Effect.ignore); }); const resolveDaemonTarget = (baseUrl: string) => Effect.gen(function* () { const parsed = yield* parseDaemonUrl(baseUrl); const host = canonicalDaemonHost(parsed.hostname); const scopeId = currentDaemonScopeId(); const pointer = yield* readDaemonPointer({ hostname: host, scopeId }); if (pointer) { const pointerUrl = daemonBaseUrl(pointer.hostname, pointer.port); if (isPidAlive(pointer.pid) && (yield* isServerReachable(pointerUrl))) { return { baseUrl: pointerUrl, hostname: pointer.hostname, port: pointer.port, scopeId, }; } yield* cleanupPointer({ hostname: pointer.hostname, scopeId, port: pointer.port }); } return { baseUrl: daemonBaseUrl(host, parsed.port), hostname: host, port: parsed.port, scopeId, }; }); // Serialize daemon startup behind a filesystem lock so concurrent CLI invocations don't// each spawn their own daemon. The post-lock pointer recheck catches the case where// another invocation finished bootstrapping while we were waiting for the lock.const spawnAndWaitForDaemon = (input: { host: string; scopeId: string; preferredPort: number; allowedHosts: ReadonlyArray<string>;}): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const lock = yield* acquireDaemonStartLock({ hostname: input.host, scopeId: input.scopeId }); try { const existing = yield* readDaemonPointer({ hostname: input.host, scopeId: input.scopeId }); if (existing && isPidAlive(existing.pid)) { const existingUrl = daemonBaseUrl(existing.hostname, existing.port); if (yield* isServerReachable(existingUrl)) { return existingUrl; } } const selectedPort = yield* chooseDaemonPort({ preferredPort: input.preferredPort, hostname: input.host, }); if (selectedPort !== input.preferredPort) { console.error( `Port ${input.preferredPort} is in use. Starting daemon on available port ${selectedPort} instead.`, ); } const spec = yield* Effect.try({ try: () => buildDaemonSpawnSpec({ port: selectedPort, hostname: input.host, isDevMode, scriptPath: script, executablePath: process.execPath, allowedHosts: input.allowedHosts, }), catch: (cause) => cause instanceof Error ? cause : new Error(`Failed to build daemon command: ${String(cause)}`), }); const startBaseUrl = daemonBaseUrl(input.host, selectedPort); console.error(`Starting daemon on ${input.host}:${selectedPort}...`); yield* spawnDetached({ command: spec.command, args: spec.args, env: process.env, }); const ready = yield* waitForReachable({ check: isServerReachable(startBaseUrl), timeoutMs: DAEMON_BOOT_TIMEOUT_MS, intervalMs: DAEMON_BOOT_POLL_MS, }); if (!ready) { return yield* Effect.fail( new Error( [ `Daemon did not become reachable at ${startBaseUrl} within ${DAEMON_BOOT_TIMEOUT_MS}ms.`, `Run in foreground to inspect logs: ${cliPrefix} daemon run --foreground --port ${selectedPort} --hostname ${input.host}`, ].join("\n"), ), ); } return startBaseUrl; } finally { yield* releaseDaemonStartLock(lock).pipe(Effect.ignore); } }); // Auto-start a local daemon on demand so commands like `executor call` work without the// user having to run `daemon run` first. Refuses non-local hosts because spawning a// daemon process on the user's behalf only makes sense when "the user's machine" is// also where the request will land.const ensureDaemon = ( baseUrl: string,): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const resolvedTarget = yield* resolveDaemonTarget(baseUrl); const reachableScope = yield* readDaemonScopeInfo(resolvedTarget.baseUrl); if (reachableScope && normalizeDaemonScopeDir(reachableScope.dir) === currentDaemonScopeDir()) { return resolvedTarget.baseUrl; } const parsed = yield* parseDaemonUrl(baseUrl); const host = canonicalDaemonHost(parsed.hostname); if (!canAutoStartLocalDaemonForHost(host)) { return yield* Effect.fail( new Error( [ `Executor daemon is not reachable at ${baseUrl}.`, "Auto-start is only supported for local hosts.", `Start it manually: ${cliPrefix} daemon run --port ${parsed.port} --hostname ${host}`, ].join("\n"), ), ); } return yield* spawnAndWaitForDaemon({ host, scopeId: resolvedTarget.scopeId, preferredPort: parsed.port, allowedHosts: [], }); }).pipe(Effect.mapError(toError)); const stopDaemon = ( baseUrl: string,): Effect.Effect<void, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const target = yield* resolveDaemonTarget(baseUrl); const host = canonicalDaemonHost(target.hostname); const scopeId = target.scopeId; const record = yield* readDaemonRecord({ hostname: host, port: target.port }); const reachable = yield* isServerReachable(target.baseUrl); if (!record) { if (reachable) { return yield* Effect.fail( new Error( [ `Executor is reachable at ${target.baseUrl} but no daemon record exists.`, "It may not be managed by this CLI process.", "Stop it from the terminal/session where it was started.", ].join("\n"), ), ); } console.log(`No daemon running at ${target.baseUrl}.`); return; } if (!isPidAlive(record.pid)) { yield* removeDaemonRecord({ hostname: host, port: target.port }); yield* removeDaemonPointer({ hostname: host, scopeId }).pipe(Effect.ignore); if (reachable) { return yield* Effect.fail( new Error( [ `Daemon record for ${target.baseUrl} points to dead pid ${record.pid}, but endpoint is still reachable.`, "Refusing to stop an unknown process without ownership metadata.", ].join("\n"), ), ); } console.log( `No daemon running at ${target.baseUrl} (removed stale record for pid ${record.pid}).`, ); return; } console.log(`Stopping daemon at ${target.baseUrl} (pid ${record.pid})...`); yield* terminatePid(record.pid); const stopped = yield* waitForUnreachable({ check: isServerReachable(target.baseUrl), timeoutMs: DAEMON_STOP_TIMEOUT_MS, intervalMs: DAEMON_BOOT_POLL_MS, }); if (!stopped) { return yield* Effect.fail( new Error( [ `Daemon at ${target.baseUrl} did not stop within ${DAEMON_STOP_TIMEOUT_MS}ms.`, "Try terminating the process manually.", ].join("\n"), ), ); } yield* removeDaemonRecord({ hostname: host, port: target.port }); yield* removeDaemonPointer({ hostname: host, scopeId }).pipe(Effect.ignore); console.log(`Daemon stopped at ${target.baseUrl}.`); }).pipe(Effect.mapError(toError)); type ExecuteCodeOutcome = | { readonly status: "completed"; readonly result: unknown; } | { readonly status: "paused"; readonly text: string; readonly executionId: string | undefined; readonly approvalUrl: string | undefined; readonly interaction: | { readonly kind: "url" | "form"; readonly message: string; readonly url?: string; readonly requestedSchema?: Record<string, unknown>; } | undefined; }; const buildResumeApprovalUrl = (baseUrl: string, executionId: string): string => { const url = new URL(`/resume/${encodeURIComponent(executionId)}`, baseUrl); return url.toString();}; const executeCode = (input: { baseUrl: string; code: string;}): Effect.Effect<ExecuteCodeOutcome, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const daemonUrl = yield* ensureDaemon(input.baseUrl); const client = yield* makeApiClient(daemonUrl); const response = yield* client.executions.execute({ payload: { code: input.code, }, }); if (response.status === "paused") { const executionId = extractExecutionId(response.structured); return { status: "paused" as const, text: response.text, executionId, approvalUrl: executionId ? buildResumeApprovalUrl(daemonUrl, executionId) : undefined, interaction: extractPausedInteraction(response.structured), }; } if (response.isError) { return yield* Effect.fail(new Error(response.text)); } return { status: "completed" as const, result: extractExecutionResult(response.structured), }; }).pipe(Effect.mapError(toError)); const printExecutionOutcome = (input: { baseUrl: string; outcome: ExecuteCodeOutcome }) => Effect.sync(() => {Lines 1–500 of 1654. Load more
import { randomUUID } from "node:crypto"; import { existsSync, realpathSync } from "node:fs"; import { dirname, join, resolve } from "node:path"; // Make sibling binaries (if any are added later) discoverable on $PATH so // child processes spawned without an absolute path still find them. const execDir = dirname(process.execPath); if (process.env.PATH && !process.env.PATH.includes(execDir)) { process.env.PATH = `${execDir}:${process.env.PATH}`; } // Point the keychain plugin at the colocated @napi-rs/keyring binding. // bun --compile doesn't include .node files in bunfs, so the loader's // normal `require('@napi-rs/keyring-<plat>-<arch>')` walk fails inside the // binary. We can't use NAPI_RS_NATIVE_LIBRARY_PATH because @napi-rs/keyring // 1.2.0 has a bug where the env-var branch assigns to a local variable that // gets overwritten before the binding is returned. build.ts copies the // platform .node next to the executor; the keychain plugin reads this var // and loads the file directly via createRequire, bypassing the broken // loader. const keyringNodeOnDisk = join(execDir, "keyring.node"); if ( typeof Bun !== "undefined" && !process.env.EXECUTOR_KEYRING_NATIVE_PATH && (await Bun.file(keyringNodeOnDisk).exists()) ) { process.env.EXECUTOR_KEYRING_NATIVE_PATH = keyringNodeOnDisk; } // Pre-load QuickJS WASM for compiled binaries — must run before server imports const wasmOnDisk = join(execDir, "emscripten-module.wasm"); if (typeof Bun !== "undefined" && (await Bun.file(wasmOnDisk).exists())) { const { setQuickJSModule } = await import("@executor-js/runtime-quickjs"); const { newQuickJSWASMModule } = await import("quickjs-emscripten"); type QuickJSSyncVariant = import("quickjs-emscripten").QuickJSSyncVariant; const wasmBinary = await Bun.file(wasmOnDisk).arrayBuffer(); const importFFI: QuickJSSyncVariant["importFFI"] = () => import("@jitl/quickjs-wasmfile-release-sync/ffi").then((m) => m.QuickJSFFI); const importModuleLoader: QuickJSSyncVariant["importModuleLoader"] = async () => { const { default: original } = await import("@jitl/quickjs-wasmfile-release-sync/emscripten-module"); return (moduleArg = {}) => original({ ...moduleArg, wasmBinary }); }; const variant: QuickJSSyncVariant = { type: "sync" as const, importFFI, importModuleLoader, }; const mod = await newQuickJSWASMModule(variant); setQuickJSModule(mod); } import { Argument as Args, Command, Flag as Options } from "effect/unstable/cli"; import { BunRuntime, BunServices } from "@effect/platform-bun"; import { HttpApiClient } from "effect/unstable/httpapi"; import { FetchHttpClient } from "effect/unstable/http"; import { FileSystem, Path as PlatformPath } from "effect"; import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as Cause from "effect/Cause"; import { ExecutorApi } from "@executor-js/api"; import { startServer, runMcpStdioServer, getExecutor } from "@executor-js/local"; import { makeQuickJsExecutor } from "@executor-js/runtime-quickjs"; import { fetchIntegrations } from "./integrations"; import { buildDaemonSpawnSpec, chooseDaemonPort, canAutoStartLocalDaemonForHost, isDevCliEntrypoint, parseDaemonBaseUrl, spawnDetached, waitForReachable, waitForUnreachable, } from "./daemon"; import { acquireDaemonStartLock, canonicalDaemonHost, currentDaemonScopeId, isPidAlive, readDaemonPointer, readDaemonRecord, releaseDaemonStartLock, removeDaemonPointer, removeDaemonRecord, terminatePid, writeDaemonPointer, writeDaemonRecord, } from "./daemon-state"; import { buildResumeContentTemplate, buildToolPath, buildDescribeToolCode, filterToolPathChildren, buildInvokeToolCode, buildListSourcesCode, buildSearchToolsCode, extractExecutionId, extractPausedInteraction, extractExecutionResult, inspectToolPath, normalizeCliErrorText, parseJsonObjectInput, sanitizeCliOutputText, shellQuoteArg, } from "./tooling"; // Embedded web UI — baked into compiled binaries via `with { type: "file" }` import embeddedWebUI from "./embedded-web-ui.gen"; // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const { version: CLI_VERSION } = await import("../package.json"); const DEFAULT_PORT = 4788; const DEFAULT_BASE_URL = `http://localhost:${DEFAULT_PORT}`; const DAEMON_BOOT_TIMEOUT_MS = 15_000; const DAEMON_BOOT_POLL_MS = 150; const DAEMON_STOP_TIMEOUT_MS = 10_000; // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- const waitForShutdownSignal = () => Effect.callback<void, never>((resume) => { const shutdown = () => resume(Effect.void); process.once("SIGINT", shutdown); process.once("SIGTERM", shutdown); return Effect.sync(() => { process.off("SIGINT", shutdown); process.off("SIGTERM", shutdown); }); }); // --------------------------------------------------------------------------- // Background server management // --------------------------------------------------------------------------- const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); interface DaemonScopeInfo { readonly id: string; readonly name: string; readonly dir: string; } const readDaemonScopeInfo = (baseUrl: string): Effect.Effect<DaemonScopeInfo | null> => Effect.tryPromise(() => fetch(`${baseUrl}/api/scope`, { signal: AbortSignal.timeout(2000) }), ).pipe( Effect.flatMap((res) => { if (!res.ok) return Effect.succeed(null); return Effect.tryPromise(() => res.json()).pipe( Effect.map((payload) => { if (!isRecord(payload)) return null; if ( typeof payload.id === "string" && typeof payload.name === "string" && typeof payload.dir === "string" ) { return { id: payload.id, name: payload.name, dir: payload.dir, }; } return null; }), Effect.catchCause(() => Effect.succeed(null)), ); }), Effect.catchCause(() => Effect.succeed(null)), ); const isServerReachable = (baseUrl: string): Effect.Effect<boolean> => readDaemonScopeInfo(baseUrl).pipe(Effect.map((scopeInfo) => scopeInfo !== null)); const normalizeDaemonScopeDir = (dir: string): string => { const resolved = resolve(dir); return existsSync(resolved) ? realpathSync.native(resolved) : resolved; }; const currentDaemonScopeDir = (): string => normalizeDaemonScopeDir(process.env.EXECUTOR_SCOPE_DIR ?? process.cwd()); const script = process.argv[1]; const isDevMode = isDevCliEntrypoint(script); const cliPrefix = isDevMode ? `bun run ${script}` : "executor"; const toError = (cause: unknown): Error => cause instanceof Error ? cause : new Error(String(cause)); const parseDaemonUrl = (baseUrl: string) => Effect.try({ try: () => parseDaemonBaseUrl(baseUrl, DEFAULT_PORT), catch: (cause) => cause instanceof Error ? cause : new Error(`Invalid base URL: ${String(cause)}`), }); const daemonBaseUrl = (hostname: string, port: number): string => `http://${canonicalDaemonHost(hostname)}:${port}`; const installDefaultExecutorWebBaseUrl = (baseUrl: string): (() => void) => { if (process.env.EXECUTOR_WEB_BASE_URL !== undefined) { return () => {}; } process.env.EXECUTOR_WEB_BASE_URL = baseUrl; return () => { delete process.env.EXECUTOR_WEB_BASE_URL; }; }; const cleanupPointer = (input: { hostname: string; scopeId: string; port: number }) => Effect.gen(function* () { yield* removeDaemonPointer({ hostname: input.hostname, scopeId: input.scopeId }).pipe( Effect.ignore, ); yield* removeDaemonRecord({ hostname: input.hostname, port: input.port }).pipe(Effect.ignore); }); const resolveDaemonTarget = (baseUrl: string) => Effect.gen(function* () { const parsed = yield* parseDaemonUrl(baseUrl); const host = canonicalDaemonHost(parsed.hostname); const scopeId = currentDaemonScopeId(); const pointer = yield* readDaemonPointer({ hostname: host, scopeId }); if (pointer) { const pointerUrl = daemonBaseUrl(pointer.hostname, pointer.port); if (isPidAlive(pointer.pid) && (yield* isServerReachable(pointerUrl))) { return { baseUrl: pointerUrl, hostname: pointer.hostname, port: pointer.port, scopeId, }; } yield* cleanupPointer({ hostname: pointer.hostname, scopeId, port: pointer.port }); } return { baseUrl: daemonBaseUrl(host, parsed.port), hostname: host, port: parsed.port, scopeId, }; }); // Serialize daemon startup behind a filesystem lock so concurrent CLI invocations don't // each spawn their own daemon. The post-lock pointer recheck catches the case where // another invocation finished bootstrapping while we were waiting for the lock. const spawnAndWaitForDaemon = (input: { host: string; scopeId: string; preferredPort: number; allowedHosts: ReadonlyArray<string>; }): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const lock = yield* acquireDaemonStartLock({ hostname: input.host, scopeId: input.scopeId }); try { const existing = yield* readDaemonPointer({ hostname: input.host, scopeId: input.scopeId }); if (existing && isPidAlive(existing.pid)) { const existingUrl = daemonBaseUrl(existing.hostname, existing.port); if (yield* isServerReachable(existingUrl)) { return existingUrl; } } const selectedPort = yield* chooseDaemonPort({ preferredPort: input.preferredPort, hostname: input.host, }); if (selectedPort !== input.preferredPort) { console.error( `Port ${input.preferredPort} is in use. Starting daemon on available port ${selectedPort} instead.`, ); } const spec = yield* Effect.try({ try: () => buildDaemonSpawnSpec({ port: selectedPort, hostname: input.host, isDevMode, scriptPath: script, executablePath: process.execPath, allowedHosts: input.allowedHosts, }), catch: (cause) => cause instanceof Error ? cause : new Error(`Failed to build daemon command: ${String(cause)}`), }); const startBaseUrl = daemonBaseUrl(input.host, selectedPort); console.error(`Starting daemon on ${input.host}:${selectedPort}...`); yield* spawnDetached({ command: spec.command, args: spec.args, env: process.env, }); const ready = yield* waitForReachable({ check: isServerReachable(startBaseUrl), timeoutMs: DAEMON_BOOT_TIMEOUT_MS, intervalMs: DAEMON_BOOT_POLL_MS, }); if (!ready) { return yield* Effect.fail( new Error( [ `Daemon did not become reachable at ${startBaseUrl} within ${DAEMON_BOOT_TIMEOUT_MS}ms.`, `Run in foreground to inspect logs: ${cliPrefix} daemon run --foreground --port ${selectedPort} --hostname ${input.host}`, ].join("\n"), ), ); } return startBaseUrl; } finally { yield* releaseDaemonStartLock(lock).pipe(Effect.ignore); } }); // Auto-start a local daemon on demand so commands like `executor call` work without the // user having to run `daemon run` first. Refuses non-local hosts because spawning a // daemon process on the user's behalf only makes sense when "the user's machine" is // also where the request will land. const ensureDaemon = ( baseUrl: string, ): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const resolvedTarget = yield* resolveDaemonTarget(baseUrl); const reachableScope = yield* readDaemonScopeInfo(resolvedTarget.baseUrl); if (reachableScope && normalizeDaemonScopeDir(reachableScope.dir) === currentDaemonScopeDir()) { return resolvedTarget.baseUrl; } const parsed = yield* parseDaemonUrl(baseUrl); const host = canonicalDaemonHost(parsed.hostname); if (!canAutoStartLocalDaemonForHost(host)) { return yield* Effect.fail( new Error( [ `Executor daemon is not reachable at ${baseUrl}.`, "Auto-start is only supported for local hosts.", `Start it manually: ${cliPrefix} daemon run --port ${parsed.port} --hostname ${host}`, ].join("\n"), ), ); } return yield* spawnAndWaitForDaemon({ host, scopeId: resolvedTarget.scopeId, preferredPort: parsed.port, allowedHosts: [], }); }).pipe(Effect.mapError(toError)); const stopDaemon = ( baseUrl: string, ): Effect.Effect<void, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const target = yield* resolveDaemonTarget(baseUrl); const host = canonicalDaemonHost(target.hostname); const scopeId = target.scopeId; const record = yield* readDaemonRecord({ hostname: host, port: target.port }); const reachable = yield* isServerReachable(target.baseUrl); if (!record) { if (reachable) { return yield* Effect.fail( new Error( [ `Executor is reachable at ${target.baseUrl} but no daemon record exists.`, "It may not be managed by this CLI process.", "Stop it from the terminal/session where it was started.", ].join("\n"), ), ); } console.log(`No daemon running at ${target.baseUrl}.`); return; } if (!isPidAlive(record.pid)) { yield* removeDaemonRecord({ hostname: host, port: target.port }); yield* removeDaemonPointer({ hostname: host, scopeId }).pipe(Effect.ignore); if (reachable) { return yield* Effect.fail( new Error( [ `Daemon record for ${target.baseUrl} points to dead pid ${record.pid}, but endpoint is still reachable.`, "Refusing to stop an unknown process without ownership metadata.", ].join("\n"), ), ); } console.log( `No daemon running at ${target.baseUrl} (removed stale record for pid ${record.pid}).`, ); return; } console.log(`Stopping daemon at ${target.baseUrl} (pid ${record.pid})...`); yield* terminatePid(record.pid); const stopped = yield* waitForUnreachable({ check: isServerReachable(target.baseUrl), timeoutMs: DAEMON_STOP_TIMEOUT_MS, intervalMs: DAEMON_BOOT_POLL_MS, }); if (!stopped) { return yield* Effect.fail( new Error( [ `Daemon at ${target.baseUrl} did not stop within ${DAEMON_STOP_TIMEOUT_MS}ms.`, "Try terminating the process manually.", ].join("\n"), ), ); } yield* removeDaemonRecord({ hostname: host, port: target.port }); yield* removeDaemonPointer({ hostname: host, scopeId }).pipe(Effect.ignore); console.log(`Daemon stopped at ${target.baseUrl}.`); }).pipe(Effect.mapError(toError)); type ExecuteCodeOutcome = | { readonly status: "completed"; readonly result: unknown; } | { readonly status: "paused"; readonly text: string; readonly executionId: string | undefined; readonly approvalUrl: string | undefined; readonly interaction: | { readonly kind: "url" | "form"; readonly message: string; readonly url?: string; readonly requestedSchema?: Record<string, unknown>; } | undefined; }; const buildResumeApprovalUrl = (baseUrl: string, executionId: string): string => { const url = new URL(`/resume/${encodeURIComponent(executionId)}`, baseUrl); return url.toString(); }; const executeCode = (input: { baseUrl: string; code: string; }): Effect.Effect<ExecuteCodeOutcome, Error, FileSystem.FileSystem | PlatformPath.Path> => Effect.gen(function* () { const daemonUrl = yield* ensureDaemon(input.baseUrl); const client = yield* makeApiClient(daemonUrl); const response = yield* client.executions.execute({ payload: { code: input.code, }, }); if (response.status === "paused") { const executionId = extractExecutionId(response.structured); return { status: "paused" as const, text: response.text, executionId, approvalUrl: executionId ? buildResumeApprovalUrl(daemonUrl, executionId) : undefined, interaction: extractPausedInteraction(response.structured), }; } if (response.isError) { return yield* Effect.fail(new Error(response.text)); } return { status: "completed" as const, result: extractExecutionResult(response.structured), }; }).pipe(Effect.mapError(toError)); const printExecutionOutcome = (input: { baseUrl: string; outcome: ExecuteCodeOutcome }) => Effect.sync(() => {