{"version":3,"file":"orchestrator.cjs","names":["Data","Schema","Effect","stripAnsi","DevRuntimeConfig","fetchRaw","registerRemote","loadRemoteModule","readInImagePlatformManifest","Deferred","Ref","DevGeneratedEnv","ShellEnv","spawn","Schedule","Readable","Stream","Option","ServiceDescriptorMap"],"sources":["../../../src/services/dev/orchestrator.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { Readable } from \"node:stream\";\nimport { Data, Deferred, Effect, Option, Ref, Schedule, Schema, Stream } from \"effect\";\nimport { ShellEnv } from \"../../env/project-env\";\nimport type { RuntimeConfig } from \"../../types\";\nimport { fetchRaw } from \"../../utils/http-client\";\nimport { loadRemoteModule, registerRemote } from \"../federation/service\";\nimport { readInImagePlatformManifest } from \"../platform/manifest\";\nimport { stripAnsi } from \"./logs\";\nimport {\n  DevGeneratedEnv,\n  DevRuntimeConfig,\n  type ServiceDescriptor,\n  ServiceDescriptorMap,\n} from \"./service-descriptor\";\n\nlet forceExitInFlight = false;\n\nexport const markForceExitInFlight = () => {\n  forceExitInFlight = true;\n};\n\nprocess.on(\"unhandledRejection\", (reason) => {\n  console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n  console.error(\"[Orchestrator] Uncaught exception:\", err);\n  if (forceExitInFlight) process.exit(1);\n});\n\nexport interface ProcessCallbacks {\n  onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n  onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n  name: string;\n  pid: number | undefined;\n  kill: Effect.Effect<void>;\n  waitForReady: Effect.Effect<void, OrchestratorError>;\n  waitForExit: Effect.Effect<number, OrchestratorError>;\n}\n\nexport class OrchestratorError extends Data.TaggedError(\"OrchestratorError\")<{\n  readonly operation: string;\n  readonly detail: string;\n  readonly cause?: unknown;\n}> {\n  override get message() {\n    return `${this.operation}: ${this.detail}`;\n  }\n}\n\nconst omitUndefined = (value: unknown): unknown => {\n  if (Array.isArray(value)) {\n    return value.map((item) => (item === undefined ? null : omitUndefined(item)));\n  }\n  if (value !== null && typeof value === \"object\") {\n    return Object.fromEntries(\n      Object.entries(value)\n        .filter(([, item]) => item !== undefined)\n        .map(([key, item]) => [key, omitUndefined(item)]),\n    );\n  }\n  return value;\n};\n\nexport const encodeRuntimeConfig = (runtimeConfig: unknown) =>\n  Schema.encodeUnknownEffect(Schema.fromJsonString(Schema.Json))(omitUndefined(runtimeConfig)).pipe(\n    Effect.mapError(\n      (cause) =>\n        new OrchestratorError({\n          operation: \"serialize runtime config\",\n          detail: cause.message,\n          cause,\n        }),\n    ),\n  );\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n  name: string;\n  status: ProcessStatus;\n  port: number;\n  message?: string;\n  source?: \"local\" | \"remote\";\n  uiPort?: number;\n}\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n  Effect.tryPromise({\n    try: async () => {\n      try {\n        const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });\n        return res.ok;\n      } catch {\n        return false;\n      }\n    },\n    catch: () => false,\n  });\n\nconst LOCAL_PROBE_DEADLINE_MS = 90_000;\n\n/** Remote-host boot budgets: every stage of the CDN-only boot is deadline-\n * bounded so a hung connection or a wedged module load fails loud with the\n * URL and stage — long before the smoke's 240s probe deadline turns the\n * silence into a mystery. */\nconst MANIFEST_FETCH_DEADLINE = \"10 seconds\";\nconst LOAD_REMOTE_DEADLINE = \"60 seconds\";\nconst SERVER_READY_DEADLINE = \"120 seconds\";\nconst REMOTE_HOST_BOOT_DEADLINE = \"180 seconds\";\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst cleanExitSignals: Record<string, true> = { SIGTERM: true, SIGINT: true };\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\n\nexport const detectStatus = (\n  line: string,\n  descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n  const cleanLine = stripAnsi(line);\n  const errorPatterns = descriptor.errorPatterns ?? [];\n  const readyPatterns = descriptor.readyPatterns ?? [];\n  for (const pattern of readyPatterns) {\n    if (pattern.test(cleanLine)) {\n      return { status: \"ready\", isError: false };\n    }\n  }\n  for (const pattern of errorPatterns) {\n    if (pattern.test(cleanLine)) {\n      return { status: \"error\", isError: true };\n    }\n  }\n  return null;\n};\n\ninterface ServerHandle {\n  ready: Promise<void>;\n  shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n  config: RuntimeConfig;\n  port?: number;\n  env?: Record<string, string>;\n  /** The serving build's identity (#537) — the host remote answers\n   * /.well-known/version with it. */\n  platform?: {\n    frameworkVersion: string;\n    everyPluginVersion?: string;\n    gitSha?: string;\n    image?: { ref: string; tags: string[] };\n  };\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n  const originalLog = console.log;\n  const originalError = console.error;\n  const originalWarn = console.warn;\n  const originalInfo = console.info;\n\n  const formatArgs = (args: unknown[], isError = false): string => {\n    return args\n      .map((arg) => {\n        if (arg instanceof Error) {\n          const parts = [`${arg.name}: ${arg.message}`];\n          if (arg.cause instanceof Error)\n            parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n          else if (arg.cause) {\n            const cause = arg.cause;\n            parts.push(\n              `(cause: ${cause instanceof Error ? cause.message : typeof cause === \"string\" ? cause : (JSON.stringify(cause) ?? \"[Unserializable cause]\")})`,\n            );\n          }\n          if (isError && arg.stack) parts.push(arg.stack);\n          return parts.join(\"\\n\");\n        }\n        if (arg === null) return \"null\";\n        if (typeof arg === \"string\") return arg;\n        if (typeof arg === \"number\" || typeof arg === \"bigint\" || typeof arg === \"boolean\")\n          return `${arg}`;\n        if (typeof arg === \"symbol\") return arg.description ?? \"\";\n        if (typeof arg === \"undefined\") return \"undefined\";\n        return JSON.stringify(arg, null, 2) ?? \"[Unserializable value]\";\n      })\n      .join(\" \");\n  };\n\n  console.log = (...args: unknown[]) => {\n    callbacks.onLog(name, formatArgs(args), false);\n  };\n  console.error = (...args: unknown[]) => {\n    callbacks.onLog(name, formatArgs(args, true), true);\n  };\n  console.warn = (...args: unknown[]) => {\n    callbacks.onLog(name, formatArgs(args), false);\n  };\n  console.info = (...args: unknown[]) => {\n    callbacks.onLog(name, formatArgs(args), false);\n  };\n\n  return () => {\n    console.log = originalLog;\n    console.error = originalError;\n    console.warn = originalWarn;\n    console.info = originalInfo;\n  };\n};\n\nexport class HostRemoteUrlMissing extends Data.TaggedError(\"HostRemoteUrlMissing\")<\n  Record<never, never>\n> {\n  override get message() {\n    return \"remoteUrl not provided on host descriptor\";\n  }\n}\n\nexport class HostModuleInvalid extends Data.TaggedError(\"HostModuleInvalid\")<Record<never, never>> {\n  override get message() {\n    return \"Host module does not export runServer function\";\n  }\n}\n\nexport class LocalPathMissing extends Data.TaggedError(\"LocalPathMissing\")<{ key: string }> {\n  override get message() {\n    return `No localPath for local service: ${this.key}`;\n  }\n}\n\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n  Effect.gen(function* () {\n    const runtimeConfig = yield* DevRuntimeConfig;\n    const remoteUrl = descriptor.remoteUrl;\n    if (!remoteUrl) {\n      return yield* new HostRemoteUrlMissing();\n    }\n\n    callbacks.onStatus(descriptor.key, \"starting\");\n    callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n    const restoreConsole = patchConsole(descriptor.key, callbacks);\n    callbacks.onLog(descriptor.key, \"Loading Module Federation runtime...\");\n\n    const baseUrl = remoteUrl\n      .replace(/\\/remoteEntry\\.js$/, \"\")\n      .replace(/\\/mf-manifest\\.json$/, \"\")\n      .replace(/\\/$/, \"\");\n    const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n    // The manifest IS the entry contract (ADR 0020 amendment: hashed\n    // entrypoints, fixed-name `remoteEntry.js` retired — it 404s on the CDN).\n    // A failed manifest fetch must fail loud with the URL and status: the old\n    // silent fallback to remoteEntry.js turned any transient hiccup (a CDN\n    // 403 challenge, a timeout) into a guaranteed loadRemote failure with no\n    // named cause.\n    const entryUrl = yield* Effect.tryPromise({\n      try: async () => {\n        let res: Response;\n        try {\n          res = await fetchRaw(manifestUrl, undefined, MANIFEST_FETCH_DEADLINE);\n        } catch (e) {\n          throw new OrchestratorError({\n            operation: \"fetch host manifest\",\n            detail: `${manifestUrl} — ${e instanceof Error ? e.message : String(e)}`,\n            cause: e,\n          });\n        }\n        if (!res.ok) {\n          throw new OrchestratorError({\n            operation: \"fetch host manifest\",\n            detail: `${manifestUrl} — HTTP ${res.status}${res.statusText ? ` ${res.statusText}` : \"\"}`,\n          });\n        }\n        const json = (await res.json()) as Record<string, unknown>;\n        if (\n          !json ||\n          typeof json !== \"object\" ||\n          !(\"metaData\" in json) ||\n          !(\"exposes\" in json) ||\n          !(\"shared\" in json)\n        ) {\n          throw new OrchestratorError({\n            operation: \"fetch host manifest\",\n            detail: `${manifestUrl} — not a Module Federation manifest (missing metaData/exposes/shared)`,\n          });\n        }\n        return manifestUrl;\n      },\n      catch: (cause) =>\n        cause instanceof OrchestratorError\n          ? cause\n          : new OrchestratorError({\n              operation: \"fetch host manifest\",\n              detail: `${manifestUrl} — ${String(cause)}`,\n            }),\n    });\n\n    yield* Effect.promise(() => registerRemote({ name: \"host\", entry: entryUrl }));\n    callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n    const hostModule = yield* Effect.tryPromise({\n      try: () =>\n        loadRemoteModule<{\n          runServer: (input: ServerInput) => ServerHandle;\n        }>(\"host/Server\"),\n      catch: (cause) =>\n        new OrchestratorError({\n          operation: \"load host module\",\n          detail: cause instanceof Error ? cause.message : String(cause),\n          cause,\n        }),\n    }).pipe(\n      Effect.timeoutOrElse({\n        duration: LOAD_REMOTE_DEADLINE,\n        orElse: () =>\n          Effect.fail(\n            new OrchestratorError({\n              operation: \"load host module\",\n              detail: `timed out after ${LOAD_REMOTE_DEADLINE} — the module (or its shared dependencies) did not finish loading from ${entryUrl}`,\n            }),\n          ),\n      }),\n    );\n\n    if (!hostModule?.runServer) {\n      return yield* new HostModuleInvalid();\n    }\n\n    callbacks.onLog(descriptor.key, \"Starting server...\");\n    const hostPort = runtimeConfig.host?.port;\n    const hostEnv: Record<string, string> | undefined = hostPort\n      ? { PORT: String(hostPort) }\n      : undefined;\n    // The serving build's identity (#537): the host remote cannot read the\n    // in-image platform manifest itself (its import.meta.url is a CDN URL),\n    // so the booting process resolves it once and injects it.\n    const manifest = readInImagePlatformManifest();\n    const platform = manifest\n      ? {\n          frameworkVersion: manifest.frameworkVersion,\n          everyPluginVersion: manifest.everyPluginVersion,\n          gitSha: manifest.gitSha,\n          image: manifest.image,\n        }\n      : undefined;\n    const serverHandle = hostModule.runServer({\n      config: runtimeConfig,\n      port: hostPort,\n      env: hostEnv,\n      platform,\n    });\n    yield* Effect.tryPromise({\n      try: () => serverHandle.ready,\n      catch: (cause) =>\n        new OrchestratorError({\n          operation: \"start server\",\n          detail: cause instanceof Error ? cause.message : String(cause),\n          cause,\n        }),\n    }).pipe(\n      Effect.timeoutOrElse({\n        duration: SERVER_READY_DEADLINE,\n        // A half-started server must not leak its port on the deadline path —\n        // the success path hands shutdown to the process handle instead.\n        orElse: () =>\n          Effect.gen(function* () {\n            yield* Effect.exit(Effect.promise(() => serverHandle.shutdown()));\n            return yield* new OrchestratorError({\n              operation: \"start server\",\n              detail: `server did not become ready within ${SERVER_READY_DEADLINE}`,\n            });\n          }),\n      }),\n    );\n\n    callbacks.onStatus(descriptor.key, \"ready\");\n\n    return {\n      name: descriptor.key,\n      pid: undefined,\n      kill: Effect.gen(function* () {\n        callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n        restoreConsole();\n        yield* Effect.tryPromise({\n          try: () => serverHandle.shutdown(),\n          catch: () => {},\n        }).pipe(Effect.ignore);\n      }),\n      waitForReady: Effect.void,\n      waitForExit: Effect.never,\n    } satisfies ProcessHandle;\n  });\n\n/**\n * Spawn env precedence, three tiers: values explicitly exported by the\n * caller (shell / CI / regression harness — captured by the bootstrap\n * program into the `ShellEnv` service before any `.env` loading) outrank the\n * generated infra env, which outranks `.env`-file values inherited through\n * `processEnv`. The service's resolved port is always authoritative.\n */\nexport function composeSpawnEnv(\n  processEnv: Record<string, string>,\n  generatedEnv: Record<string, string>,\n  port: number,\n  shellEnv: Record<string, string> = {},\n): Record<string, string> {\n  return {\n    ...processEnv,\n    ...mergeGeneratedOverFileEnv(generatedEnv, processEnv, shellEnv),\n    FORCE_COLOR: \"1\",\n    ...(port > 0 ? { PORT: String(port) } : {}),\n  };\n}\n\n/**\n * Overlay the generated infra env (ports drift, so stale `.env` values must\n * lose) while keeping every explicitly exported key from `shellEnv` intact.\n * Keys absent from both are untouched.\n *\n * Exception (ADR 0012 / plan 038): the origin keys BASE_URL and CORS_ORIGIN\n * are always generated-owned — a wrapper that sourced a stale `.env` must not\n * win over the resolved host port, in the child env or on disk.\n */\nconst GENERATED_OWNED_KEYS = new Set([\"BASE_URL\", \"CORS_ORIGIN\"]);\n\nexport function mergeGeneratedOverFileEnv(\n  generatedEnv: Record<string, string>,\n  processEnv: Record<string, string>,\n  shellEnv: Record<string, string> = {},\n): Record<string, string> {\n  const result: Record<string, string> = { ...processEnv };\n  for (const [key, value] of Object.entries(generatedEnv)) {\n    if (!GENERATED_OWNED_KEYS.has(key) && key in shellEnv) {\n      result[key] = shellEnv[key]!;\n    } else {\n      result[key] = value;\n    }\n  }\n  return result;\n}\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n  Effect.gen(function* () {\n    const runtimeConfig = yield* DevRuntimeConfig;\n\n    if (!descriptor.localPath) {\n      return yield* new LocalPathMissing({ key: descriptor.key });\n    }\n\n    const fullCwd = descriptor.localPath;\n    const command = descriptor.command ?? \"pnpm\";\n    const args = descriptor.args ?? [\"run\", \"dev\"];\n    const port = descriptor.port ?? descriptor.defaultPort;\n    const name = descriptor.key;\n\n    const readyDeferred = yield* Deferred.make<void, OrchestratorError>();\n    const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n    callbacks.onStatus(name, \"starting\");\n\n    const generatedEnv = yield* DevGeneratedEnv;\n    const shellTier = yield* ShellEnv;\n    // The descriptor's env joins the generated tier — folding it in before\n    // composeSpawnEnv keeps the documented precedence (shell > generated >\n    // .env-file); assigning after would let it outrank the shell tier (and\n    // the generated-owned keys) silently.\n    const envVars = composeSpawnEnv(\n      process.env as Record<string, string>,\n      { ...generatedEnv, ...descriptor.env },\n      port,\n      shellTier,\n    );\n\n    envVars.BOS_RUNTIME_CONFIG = yield* encodeRuntimeConfig(runtimeConfig);\n\n    const cmd = spawn(command, args, {\n      cwd: fullCwd,\n      env: envVars,\n      stdio: [\"ignore\", \"pipe\", \"pipe\"],\n      detached: true,\n    });\n\n    let lastExit: { code: number | null; signal: NodeJS.Signals | null } | null = null;\n    const exitCode = Effect.callback<number, OrchestratorError>((resume) => {\n      const onExit = (code: number | null, signal: NodeJS.Signals | null) => {\n        lastExit = { code, signal };\n        resume(Effect.succeed(code ?? (signal ? 1 : 0)));\n      };\n      const onError = (err: Error) => {\n        callbacks.onLog(name, `Spawn failed: ${err.message}`, true);\n        callbacks.onStatus(name, \"error\", `spawn failed: ${err.message}`);\n        resume(\n          Effect.fail(\n            new OrchestratorError({\n              operation: \"spawn process\",\n              detail: err.message,\n              cause: err,\n            }),\n          ),\n        );\n      };\n      cmd.once(\"exit\", onExit);\n      cmd.once(\"error\", onError);\n      return Effect.sync(() => {\n        cmd.off(\"exit\", onExit);\n        cmd.off(\"error\", onError);\n      });\n    });\n\n    const describeExit = (exitCodeValue: number): string => {\n      if (lastExit?.code === null && lastExit.signal) return `signal: ${lastExit.signal}`;\n      return `exit code: ${exitCodeValue}`;\n    };\n    const isCleanSignalExit = (): boolean =>\n      lastExit?.code === null && lastExit.signal != null && lastExit.signal in cleanExitSignals;\n\n    const markReady = Effect.gen(function* () {\n      const currentStatus = yield* Ref.get(statusRef);\n      if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n      yield* Ref.set(statusRef, \"ready\");\n      callbacks.onStatus(name, \"ready\");\n      yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n    });\n\n    const markError = (message: string) =>\n      Effect.gen(function* () {\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n        yield* Ref.set(statusRef, \"error\");\n        callbacks.onStatus(name, \"error\");\n        yield* Deferred.fail(\n          readyDeferred,\n          new OrchestratorError({ operation: \"wait for process readiness\", detail: message }),\n        ).pipe(Effect.ignore);\n      });\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const readinessPath = descriptor.readinessPath;\n        const url = `http://127.0.0.1:${port}${readinessPath}`;\n        const readinessCheck = Effect.gen(function* () {\n          const status = yield* Ref.get(statusRef);\n          if (status === \"ready\" || status === \"error\") return true;\n          if (port <= 0) return false;\n          const ok = yield* probeHttpOk(url);\n          if (ok) yield* markReady;\n          return ok;\n        });\n        const ready = yield* Effect.repeat(readinessCheck, {\n          schedule: Schedule.spaced(`${port > 0 ? LOCAL_PROBE_INTERVAL_MS : 500} millis`),\n          until: (done) => done,\n        }).pipe(\n          Effect.timeout(`${LOCAL_PROBE_DEADLINE_MS} millis`),\n          Effect.catchTag(\"TimeoutError\", () => Effect.succeed(false)),\n        );\n        if (ready) return;\n\n        const status = yield* Ref.get(statusRef);\n        if (status !== \"ready\" && status !== \"error\") {\n          callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n          yield* markError(`Probe deadline exceeded: ${name}`);\n        }\n      }),\n    );\n\n    const pid = cmd.pid ?? undefined;\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const exitCodeValue = yield* exitCode;\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\" || currentStatus === \"error\") {\n          // Post-ready exits must stay visible — a silently dead child (OOM\n          // kill included) used to leave the stack answering with nothing.\n          // A SIGTERM/SIGINT-signalled exit is the polite-quit path, not a\n          // crash, so it logs as a plain shutdown line.\n          if (currentStatus === \"ready\") {\n            const detail = describeExit(exitCodeValue);\n            callbacks.onLog(name, `Process exited after ready (${detail})`, !isCleanSignalExit());\n            if (!isCleanSignalExit()) {\n              callbacks.onStatus(name, \"error\", `exited after ready (${detail})`);\n            }\n            yield* markError(`Process exited after ready: ${name}`);\n          }\n          return;\n        }\n        callbacks.onLog(\n          name,\n          `Process exited before ready (${describeExit(exitCodeValue)})`,\n          !isCleanSignalExit(),\n        );\n        yield* markError(`Process exited before ready: ${name}`);\n      }),\n    );\n\n    const handleLine = (line: string, isStderr: boolean) =>\n      Effect.gen(function* () {\n        if (!line.trim()) return;\n\n        const cleanLine = stripAnsi(line);\n        const looksLikeError =\n          isStderr &&\n          /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n          !cleanLine.startsWith(\"$\");\n        callbacks.onLog(name, line, looksLikeError);\n\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\") return;\n\n        const detected = detectStatus(line, descriptor);\n        if (detected) {\n          if (detected.status === \"ready\") {\n            yield* markReady;\n          } else if (currentStatus !== \"error\") {\n            yield* markError(`Process failed: ${name}`);\n          }\n        }\n      });\n\n    const stdoutStream = cmd.stdout\n      ? (Readable.toWeb(cmd.stdout) as unknown as ReadableStream<Uint8Array>)\n      : null;\n    const stderrStream = cmd.stderr\n      ? (Readable.toWeb(cmd.stderr) as unknown as ReadableStream<Uint8Array>)\n      : null;\n\n    if (stdoutStream) {\n      yield* Effect.forkScoped(\n        Stream.runForEach((line: string) => handleLine(line, false))(\n          Stream.splitLines(\n            Stream.decodeText(\n              Stream.fromReadableStream({\n                evaluate: () => stdoutStream,\n                onError: (cause) =>\n                  new OrchestratorError({\n                    operation: \"read process stdout\",\n                    detail: String(cause),\n                    cause,\n                  }),\n              }),\n            ),\n          ),\n        ),\n      );\n    }\n\n    if (stderrStream) {\n      yield* Effect.forkScoped(\n        Stream.runForEach((line: string) => handleLine(line, true))(\n          Stream.splitLines(\n            Stream.decodeText(\n              Stream.fromReadableStream({\n                evaluate: () => stderrStream,\n                onError: (cause) =>\n                  new OrchestratorError({\n                    operation: \"read process stderr\",\n                    detail: String(cause),\n                    cause,\n                  }),\n              }),\n            ),\n          ),\n        ),\n      );\n    }\n\n    return {\n      name,\n      pid,\n      kill: Effect.gen(function* () {\n        const groupPid = pid;\n        const groupSignal = (signal: NodeJS.Signals) =>\n          Effect.try(() => {\n            if (groupPid !== undefined) process.kill(-groupPid, signal);\n          }).pipe(Effect.ignore);\n        yield* groupSignal(\"SIGTERM\");\n        const exited = yield* exitCode.pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n        if (Option.isNone(exited)) {\n          yield* groupSignal(\"SIGKILL\");\n          yield* Effect.sleep(\"250 millis\");\n        }\n      }).pipe(Effect.ignore),\n      waitForReady: Deferred.await(readyDeferred),\n      waitForExit: exitCode,\n    } satisfies ProcessHandle;\n  });\n\nconst spawnRemoteProbe = (\n  pkg: string,\n  descriptor: ServiceDescriptor,\n  callbacks: ProcessCallbacks,\n) =>\n  Effect.gen(function* () {\n    callbacks.onStatus(pkg, \"starting\");\n    const readyDeferred = yield* Deferred.make<void, OrchestratorError>();\n    const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n    const markReady = Effect.gen(function* () {\n      const currentStatus = yield* Ref.get(statusRef);\n      if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n      yield* Ref.set(statusRef, \"ready\");\n      yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n      callbacks.onStatus(pkg, \"ready\", \"loaded\");\n    });\n\n    const markError = Effect.gen(function* () {\n      const currentStatus = yield* Ref.get(statusRef);\n      if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n      yield* Ref.set(statusRef, \"error\");\n      yield* Deferred.fail(\n        readyDeferred,\n        new OrchestratorError({\n          operation: \"probe remote process\",\n          detail: `Remote ${pkg} unreachable`,\n        }),\n      ).pipe(Effect.ignore);\n      callbacks.onStatus(pkg, \"error\", \"unreachable\");\n    });\n\n    const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n    const manifestUrl = `${baseUrl}/mf-manifest.json`;\n    const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n    const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const readinessCheck = Effect.gen(function* () {\n          const status = yield* Ref.get(statusRef);\n          if (status === \"ready\" || status === \"error\") return true;\n\n          const ok = yield* probeHttpOk(probeUrl, REMOTE_PROBE_TIMEOUT_MS);\n          if (ok) {\n            yield* markReady;\n            return true;\n          }\n\n          const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n          if (fallbackOk) {\n            yield* markReady;\n            return true;\n          }\n          return false;\n        });\n        const ready = yield* Effect.repeat(readinessCheck, {\n          schedule: Schedule.min([\n            Schedule.exponential(`${REMOTE_PROBE_BACKOFF_INITIAL_MS} millis`, 1.5),\n            Schedule.spaced(`${REMOTE_PROBE_BACKOFF_MAX_MS} millis`),\n          ]),\n          until: (done) => done,\n        }).pipe(\n          Effect.timeout(`${REMOTE_PROBE_DEADLINE_MS} millis`),\n          Effect.catchTag(\"TimeoutError\", () => Effect.succeed(false)),\n        );\n        if (ready) return;\n\n        const status = yield* Ref.get(statusRef);\n        if (status !== \"ready\") {\n          yield* markError;\n        }\n      }),\n    );\n\n    return {\n      name: pkg,\n      pid: undefined,\n      kill: Effect.gen(function* () {\n        yield* Ref.set(statusRef, \"error\");\n        yield* Deferred.fail(\n          readyDeferred,\n          new OrchestratorError({ operation: \"stop remote process\", detail: \"Killed\" }),\n        ).pipe(Effect.ignore);\n      }),\n      waitForReady: Deferred.await(readyDeferred),\n      waitForExit: Effect.never,\n    } satisfies ProcessHandle;\n  });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n  Effect.gen(function* () {\n    const services = yield* ServiceDescriptorMap;\n    const descriptor = services.get(pkg);\n\n    if (!descriptor) {\n      callbacks.onStatus(pkg, \"ready\", \"Remote\");\n      return {\n        name: pkg,\n        pid: undefined,\n        kill: Effect.void,\n        waitForReady: Effect.void,\n        waitForExit: Effect.never,\n      } satisfies ProcessHandle;\n    }\n\n    if (pkg === \"host\" && descriptor.source === \"remote\") {\n      return yield* spawnRemoteHost(descriptor, callbacks).pipe(\n        // Overall boot budget: with per-stage deadlines inside, this is the\n        // backstop for anything the stage deadlines don't cover (a config\n        // fetch, a slow MF internal) — the boot either comes up named-and-\n        // ready or fails named-and-loud.\n        Effect.timeoutOrElse({\n          duration: REMOTE_HOST_BOOT_DEADLINE,\n          orElse: () =>\n            Effect.fail(\n              new OrchestratorError({\n                operation: \"boot remote host\",\n                detail: `remote host boot exceeded the ${REMOTE_HOST_BOOT_DEADLINE} overall deadline`,\n              }),\n            ),\n        }),\n      );\n    }\n\n    if (descriptor.source === \"remote\" || !descriptor.localPath) {\n      return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n    }\n\n    const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n    return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n  });\n\nexport function getProcessStates(\n  packages: string[],\n  services: Map<string, ServiceDescriptor>,\n  portOverride?: number,\n): ProcessState[] {\n  return packages.map((pkg) => {\n    const descriptor = services.get(pkg);\n    return {\n      name: pkg,\n      status: \"pending\" as const,\n      port:\n        portOverride && pkg === \"host\"\n          ? portOverride\n          : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n      source: descriptor?.source,\n      uiPort: descriptor?.uiPort,\n    };\n  });\n}\n"],"mappings":"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"}