{"version":3,"file":"service-descriptor.cjs","names":["Context","Layer","existsSync","path"],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { Context, Layer } from \"effect\";\nimport type { JsonObject, RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface AuthSlotShape {\n  source: string;\n  localPath?: string;\n  url?: string;\n}\n\n/**\n * True when a `plugins.<id>` entry is the runtime-config mirror of the\n * app-slot auth plugin (same backend target) — the `auth` service already\n * spawns that backend, so the mirror contributes only its `ui` surface.\n * The single implementation; consumed by the service descriptors, the DAG,\n * the infra planner, and the dev session.\n */\nexport function isAuthMirrorPluginEntry(\n  authEntry: AuthSlotShape | undefined,\n  pluginId: string,\n  pluginConfig: AuthSlotShape,\n): boolean {\n  if (pluginId !== \"auth\" || !authEntry) return false;\n  if (pluginConfig === authEntry) return true;\n  if (pluginConfig.localPath && pluginConfig.localPath === authEntry.localPath) return true;\n  if (\n    !pluginConfig.localPath &&\n    pluginConfig.source === \"remote\" &&\n    pluginConfig.url &&\n    pluginConfig.url === authEntry.url\n  ) {\n    return true;\n  }\n  return false;\n}\n\nexport interface ServiceDescriptor {\n  key: string;\n  source: SourceMode;\n  url: string;\n  remoteUrl?: string;\n  entry: string;\n  name: string;\n  localPath?: string;\n  port?: number;\n  readinessPath: string;\n  defaultPort: number;\n  integrity?: string;\n  proxy?: string;\n  variables?: JsonObject;\n  secrets?: string[];\n  ssr?: boolean;\n  command?: string;\n  args?: string[];\n  env?: Record<string, string>;\n  readyPatterns?: RegExp[];\n  errorPatterns?: RegExp[];\n  /** folder-form plugin UI port — the UI build is a child of this dev process (BOS_UI_PORT) */\n  uiPort?: number;\n}\n\nexport class ServiceDescriptorMap extends Context.Service<\n  ServiceDescriptorMap,\n  Map<string, ServiceDescriptor>\n>()(\"ServiceDescriptorMap\") {}\n\nexport class DevRuntimeConfig extends Context.Service<DevRuntimeConfig, RuntimeConfig>()(\n  \"DevRuntimeConfig\",\n) {}\n\nexport class DevGeneratedEnv extends Context.Service<DevGeneratedEnv, Record<string, string>>()(\n  \"DevGeneratedEnv\",\n) {}\n\nexport const DevGeneratedEnvLive = (env: Record<string, string>) =>\n  Layer.succeed(DevGeneratedEnv, env);\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [\n  /\\bERROR in\\b/,\n  /failed to compile/i,\n  /Module not found/i,\n  /Cannot find module/i,\n];\n\nconst SERVICE_CONFIGS = {\n  host: {\n    command: \"pnpm\",\n    args: [\"run\", \"dev\"],\n    // The host dev server runs on tsx (TS-capable node), so it can consume\n    // framework package sources directly — NODE_OPTIONS makes node's\n    // resolver pick the `development` export condition. The env var rides\n    // the spawn environment (ADR 0026 §2) and is inherited by the host's\n    // tsx children. rsbuild/rspack config loaders must NOT rely on it:\n    // their .mjs config evaluation resolves dist (freshness is the\n    // prerequisite train's job, ADR 0022).\n    env: { NODE_OPTIONS: \"--conditions=development\" },\n    readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n    errorPatterns: [/\\berror\\b(?!s)/i, /\\bfailed to\\b/i, /\\bbuild failed\\b/i, /exception/i],\n    defaultPort: 3000,\n    readinessPath: \"/health\",\n  },\n  auth: {\n    command: \"pnpm\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: PLUGIN_READY_PATTERNS,\n    errorPatterns: PLUGIN_ERROR_PATTERNS,\n    defaultPort: 3002,\n    readinessPath: \"/remoteEntry.js\",\n  },\n  ui: {\n    command: \"pnpm\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n    errorPatterns: [/\\berror\\b(?!s)/i, /\\bfailed to\\b/i, /\\bbuild failed\\b/i],\n    defaultPort: 3003,\n    readinessPath: \"/remoteEntry.js\",\n  },\n  api: {\n    command: \"pnpm\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: PLUGIN_READY_PATTERNS,\n    errorPatterns: PLUGIN_ERROR_PATTERNS,\n    defaultPort: 3001,\n    readinessPath: \"/remoteEntry.js\",\n  },\n} as const satisfies Record<\n  string,\n  Pick<\n    ServiceDescriptor,\n    \"command\" | \"args\" | \"env\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n  >\n>;\n\nexport function buildServiceDescriptorMap(\n  runtimeConfig: RuntimeConfig,\n  options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n  const map = new Map<string, ServiceDescriptor>();\n  const ssr = options?.ssr ?? false;\n\n  const hostIsRemote = runtimeConfig.host.source === \"remote\";\n  const hostProbeUrl = hostIsRemote\n    ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n    : runtimeConfig.host.url;\n  map.set(\"host\", {\n    key: \"host\",\n    source: runtimeConfig.host.source,\n    url: hostProbeUrl,\n    remoteUrl: runtimeConfig.host.remoteUrl,\n    entry: hostIsRemote\n      ? hostProbeUrl\n        ? `${hostProbeUrl}/mf-manifest.json`\n        : \"/mf-manifest.json\"\n      : runtimeConfig.host.entry,\n    name: runtimeConfig.host.name,\n    localPath: runtimeConfig.host.localPath,\n    port: runtimeConfig.host.port,\n    integrity: runtimeConfig.host.integrity,\n    secrets: runtimeConfig.host.secrets,\n    ...SERVICE_CONFIGS.host,\n  });\n\n  map.set(\"ui\", {\n    key: \"ui\",\n    source: runtimeConfig.ui.source,\n    url: runtimeConfig.ui.url,\n    remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n    entry: runtimeConfig.ui.entry,\n    name: runtimeConfig.ui.name,\n    localPath: runtimeConfig.ui.localPath,\n    port: runtimeConfig.ui.port,\n    integrity: runtimeConfig.ui.integrity,\n    ssr,\n    ...SERVICE_CONFIGS.ui,\n    env: { BOS_DEV_SERVER: \"1\" },\n    // BOS_NO_WATCH stacks (regression/CI) build once and serve the built dist\n    // via rsbuild preview — no watcher, no HMR.\n    args: process.env.BOS_NO_WATCH === \"1\" ? [\"run\", \"dev:built\"] : SERVICE_CONFIGS.ui.args,\n  });\n\n  map.set(\"api\", {\n    key: \"api\",\n    source: runtimeConfig.api.source,\n    url: runtimeConfig.api.url,\n    remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n    entry: runtimeConfig.api.entry,\n    name: runtimeConfig.api.name,\n    localPath: runtimeConfig.api.localPath,\n    port: runtimeConfig.api.port,\n    integrity: runtimeConfig.api.integrity,\n    proxy: runtimeConfig.api.proxy,\n    variables: runtimeConfig.api.variables,\n    secrets: runtimeConfig.api.secrets,\n    ...SERVICE_CONFIGS.api,\n  });\n\n  if (runtimeConfig.auth) {\n    map.set(\"auth\", {\n      key: \"auth\",\n      source: runtimeConfig.auth.source,\n      url: runtimeConfig.auth.url,\n      remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n      entry: runtimeConfig.auth.entry,\n      name: runtimeConfig.auth.name,\n      localPath: runtimeConfig.auth.localPath,\n      port: runtimeConfig.auth.port,\n      integrity: runtimeConfig.auth.integrity,\n      proxy: runtimeConfig.auth.proxy,\n      variables: runtimeConfig.auth.variables,\n      secrets: runtimeConfig.auth.secrets,\n      ...SERVICE_CONFIGS.auth,\n    });\n  }\n\n  if (runtimeConfig.plugins) {\n    let pluginBasePort = 3010;\n    for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n      const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginConfig);\n      const pluginKey = `plugin:${pluginId}`;\n      const resolvedPort = pluginConfig.port ?? pluginBasePort;\n      pluginBasePort = resolvedPort + 1;\n\n      // Folder-form ui source: the ui dir lives inside the plugin workspace\n      // (no own package.json) — `every-plugin dev` spawns its UI build as a\n      // child (BOS_UI_PORT), so no separate plugin-ui service is spawned.\n      const uiLocalPath = pluginConfig.ui?.localPath;\n      const isFolderFormUi = Boolean(\n        uiLocalPath &&\n          pluginConfig.ui?.source === \"local\" &&\n          existsSync(path.join(uiLocalPath, \"src\", \"routes\")) &&\n          !existsSync(path.join(uiLocalPath, \"package.json\")),\n      );\n      const folderUiPort = pluginConfig.ui?.port ?? pluginBasePort;\n      if (isFolderFormUi) pluginBasePort = folderUiPort + 1;\n\n      if (!isAuthMirror) {\n        map.set(pluginKey, {\n          key: pluginKey,\n          source: pluginConfig.source,\n          url: pluginConfig.url,\n          remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n          entry: pluginConfig.entry,\n          name: pluginConfig.name,\n          localPath: pluginConfig.localPath,\n          port: resolvedPort,\n          integrity: pluginConfig.integrity,\n          proxy: pluginConfig.proxy,\n          variables: pluginConfig.variables,\n          secrets: pluginConfig.secrets,\n          command: \"pnpm\",\n          args: [\"run\", \"dev\"],\n          env: isFolderFormUi ? { BOS_UI_PORT: String(folderUiPort) } : undefined,\n          uiPort: isFolderFormUi ? folderUiPort : undefined,\n          readyPatterns: PLUGIN_READY_PATTERNS,\n          errorPatterns: PLUGIN_ERROR_PATTERNS,\n          defaultPort: resolvedPort,\n          readinessPath: \"/remoteEntry.js\",\n        });\n      } else if (isFolderFormUi) {\n        // Folder-form ui for the auth mirror: the `auth` app slot owns the\n        // dev process (plugin:auth is not spawned), so BOS_UI_PORT rides on\n        // the auth descriptor. folderUiPort is the same port the runtime\n        // config wired into the mirror's ui.url (withLocalRuntimeUrl).\n        const authDescriptor = map.get(\"auth\");\n        if (authDescriptor) {\n          map.set(\"auth\", {\n            ...authDescriptor,\n            env: { BOS_UI_PORT: String(folderUiPort) },\n            uiPort: folderUiPort,\n          });\n        }\n      }\n\n      if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\" && !isFolderFormUi) {\n        const uiKey = `plugin-ui:${pluginId}`;\n        const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n        pluginBasePort = uiPort + 1;\n\n        map.set(uiKey, {\n          key: uiKey,\n          source: pluginConfig.ui.source,\n          url: pluginConfig.ui.url,\n          entry: pluginConfig.ui.entry,\n          name: pluginConfig.ui.name,\n          localPath: pluginConfig.ui.localPath,\n          port: uiPort,\n          integrity: pluginConfig.ui.integrity,\n          command: \"pnpm\",\n          args: [\"run\", \"dev\"],\n          readyPatterns: PLUGIN_READY_PATTERNS,\n          errorPatterns: PLUGIN_ERROR_PATTERNS,\n          defaultPort: uiPort,\n          readinessPath: \"/remoteEntry.js\",\n        });\n      }\n    }\n  }\n\n  return map;\n}\n\nexport interface AppOrchestrator {\n  packages: string[];\n  description: string;\n  env: Record<string, string>;\n  port?: number;\n  interactive?: boolean;\n  noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n  Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n  Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildServiceDescriptorMapFromPlan(\n  plan: {\n    runtimeConfig: RuntimeConfig;\n    resolvedPorts: { host?: number; api?: number; auth?: number; ui?: number; uiSsr?: number };\n  },\n  options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n  return buildServiceDescriptorMap(plan.runtimeConfig, options);\n}\n\ninterface ServiceDescriptorInfo {\n  key: string;\n  source: string;\n  proxy?: string;\n}\n\nexport function buildDescription(map: Map<string, ServiceDescriptorInfo>): string {\n  const descriptors = [...map.values()].filter((d) => !d.key.startsWith(\"plugin:\"));\n\n  const allLocal = descriptors.every((d) => d.source === \"local\");\n  const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n  if (allLocal && !hasProxy) return \"Full Local Development\";\n\n  const parts: string[] = [];\n  for (const d of descriptors) {\n    if (d.source === \"remote\") {\n      const label =\n        d.key === \"host\"\n          ? \"Remote Host\"\n          : d.key === \"ui\"\n            ? \"Remote UI\"\n            : d.key === \"api\"\n              ? hasProxy\n                ? undefined\n                : \"Remote API\"\n              : d.key === \"auth\"\n                ? \"Remote Auth\"\n                : undefined;\n      if (label) parts.push(label);\n    }\n  }\n  if (hasProxy) parts.push(\"Proxy API → Production\");\n  return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}