everything-dev 1.7.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/api.cjs +1 -1
  2. package/dist/api.mjs +1 -1
  3. package/dist/app.cjs +82 -51
  4. package/dist/app.cjs.map +1 -1
  5. package/dist/app.mjs +82 -51
  6. package/dist/app.mjs.map +1 -1
  7. package/dist/cli/upgrade.cjs.map +1 -1
  8. package/dist/cli/upgrade.mjs.map +1 -1
  9. package/dist/components/dev-view.cjs +6 -3
  10. package/dist/components/dev-view.cjs.map +1 -1
  11. package/dist/components/dev-view.mjs +6 -3
  12. package/dist/components/dev-view.mjs.map +1 -1
  13. package/dist/components/streaming-view.cjs +5 -2
  14. package/dist/components/streaming-view.cjs.map +1 -1
  15. package/dist/components/streaming-view.mjs +5 -2
  16. package/dist/components/streaming-view.mjs.map +1 -1
  17. package/dist/config.cjs +28 -5
  18. package/dist/config.cjs.map +1 -1
  19. package/dist/config.d.cts.map +1 -1
  20. package/dist/config.d.mts.map +1 -1
  21. package/dist/config.mjs +28 -5
  22. package/dist/config.mjs.map +1 -1
  23. package/dist/contract.cjs +1 -0
  24. package/dist/contract.cjs.map +1 -1
  25. package/dist/contract.d.cts +14 -6
  26. package/dist/contract.d.cts.map +1 -1
  27. package/dist/contract.d.mts +14 -6
  28. package/dist/contract.d.mts.map +1 -1
  29. package/dist/contract.mjs +1 -0
  30. package/dist/contract.mjs.map +1 -1
  31. package/dist/dev-logs.cjs +6 -2
  32. package/dist/dev-logs.cjs.map +1 -1
  33. package/dist/dev-logs.mjs +7 -2
  34. package/dist/dev-logs.mjs.map +1 -1
  35. package/dist/dev-session.cjs +27 -23
  36. package/dist/dev-session.cjs.map +1 -1
  37. package/dist/dev-session.mjs +27 -24
  38. package/dist/dev-session.mjs.map +1 -1
  39. package/dist/federation.server.cjs +1 -1
  40. package/dist/federation.server.mjs +1 -1
  41. package/dist/host.cjs +4 -3
  42. package/dist/host.cjs.map +1 -1
  43. package/dist/host.d.cts.map +1 -1
  44. package/dist/host.d.mts.map +1 -1
  45. package/dist/host.mjs +4 -3
  46. package/dist/host.mjs.map +1 -1
  47. package/dist/integrity.cjs +68 -2
  48. package/dist/integrity.cjs.map +1 -1
  49. package/dist/integrity.d.cts +14 -1
  50. package/dist/integrity.d.cts.map +1 -1
  51. package/dist/integrity.d.mts +14 -1
  52. package/dist/integrity.d.mts.map +1 -1
  53. package/dist/integrity.mjs +66 -3
  54. package/dist/integrity.mjs.map +1 -1
  55. package/dist/mf.cjs +32 -0
  56. package/dist/mf.cjs.map +1 -1
  57. package/dist/mf.d.cts +3 -1
  58. package/dist/mf.d.cts.map +1 -1
  59. package/dist/mf.d.mts +3 -1
  60. package/dist/mf.d.mts.map +1 -1
  61. package/dist/mf.mjs +32 -1
  62. package/dist/mf.mjs.map +1 -1
  63. package/dist/orchestrator.cjs +167 -317
  64. package/dist/orchestrator.cjs.map +1 -1
  65. package/dist/orchestrator.d.cts +24 -21
  66. package/dist/orchestrator.d.cts.map +1 -1
  67. package/dist/orchestrator.d.mts +24 -21
  68. package/dist/orchestrator.d.mts.map +1 -1
  69. package/dist/orchestrator.mjs +168 -316
  70. package/dist/orchestrator.mjs.map +1 -1
  71. package/dist/plugin.cjs +38 -107
  72. package/dist/plugin.cjs.map +1 -1
  73. package/dist/plugin.d.cts +19 -5
  74. package/dist/plugin.d.cts.map +1 -1
  75. package/dist/plugin.d.mts +19 -5
  76. package/dist/plugin.d.mts.map +1 -1
  77. package/dist/plugin.mjs +39 -108
  78. package/dist/plugin.mjs.map +1 -1
  79. package/dist/service-descriptor.cjs +188 -0
  80. package/dist/service-descriptor.cjs.map +1 -0
  81. package/dist/service-descriptor.d.cts +107 -0
  82. package/dist/service-descriptor.d.cts.map +1 -0
  83. package/dist/service-descriptor.d.mts +107 -0
  84. package/dist/service-descriptor.d.mts.map +1 -0
  85. package/dist/service-descriptor.mjs +182 -0
  86. package/dist/service-descriptor.mjs.map +1 -0
  87. package/dist/types.cjs +8 -1
  88. package/dist/types.cjs.map +1 -1
  89. package/dist/types.d.cts +18 -3
  90. package/dist/types.d.cts.map +1 -1
  91. package/dist/types.d.mts +18 -3
  92. package/dist/types.d.mts.map +1 -1
  93. package/dist/types.mjs +8 -1
  94. package/dist/types.mjs.map +1 -1
  95. package/dist/ui/index.cjs +1 -0
  96. package/dist/ui/index.d.cts +2 -2
  97. package/dist/ui/index.d.mts +2 -2
  98. package/dist/ui/index.mjs +2 -2
  99. package/dist/ui/runtime.cjs +4 -0
  100. package/dist/ui/runtime.cjs.map +1 -1
  101. package/dist/ui/runtime.d.cts +2 -1
  102. package/dist/ui/runtime.d.cts.map +1 -1
  103. package/dist/ui/runtime.d.mts +2 -1
  104. package/dist/ui/runtime.d.mts.map +1 -1
  105. package/dist/ui/runtime.mjs +4 -1
  106. package/dist/ui/runtime.mjs.map +1 -1
  107. package/package.json +12 -4
  108. package/skills/dev-workflow/SKILL.md +105 -0
  109. package/skills/publish-sync/SKILL.md +130 -0
  110. package/src/app.ts +98 -204
  111. package/src/cli/upgrade.ts +20 -4
  112. package/src/components/dev-view.tsx +8 -3
  113. package/src/components/streaming-view.ts +7 -2
  114. package/src/config.ts +40 -8
  115. package/src/contract.ts +1 -0
  116. package/src/dev-logs.ts +8 -1
  117. package/src/dev-session.ts +56 -79
  118. package/src/host.ts +4 -3
  119. package/src/integrity.ts +96 -10
  120. package/src/mf.ts +42 -0
  121. package/src/orchestrator.ts +232 -411
  122. package/src/plugin.ts +48 -136
  123. package/src/service-descriptor.ts +258 -0
  124. package/src/types.ts +8 -1
  125. package/src/ui/runtime.ts +5 -0
  126. package/dist/process-registry.cjs +0 -120
  127. package/dist/process-registry.cjs.map +0 -1
  128. package/dist/process-registry.d.cts +0 -25
  129. package/dist/process-registry.d.cts.map +0 -1
  130. package/dist/process-registry.d.mts +0 -25
  131. package/dist/process-registry.d.mts.map +0 -1
  132. package/dist/process-registry.mjs +0 -119
  133. package/dist/process-registry.mjs.map +0 -1
  134. package/src/process-registry.ts +0 -154
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.mjs","names":[],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { createConnection } from \"node:net\";\nimport { Deferred, Effect, Fiber, Ref } from \"effect\";\nimport { getHostDevelopmentPort, getProjectRoot, parsePort } from \"./config\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport type { ProcessRegistry } from \"./process-registry\";\nimport type { BosConfig, RuntimeConfig } from \"./types\";\n\nexport interface DevProcess {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n env?: Record<string, string>;\n port: number;\n readyPatterns: RegExp[];\n errorPatterns: RegExp[];\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, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\ninterface ProcessConfigBase {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n readyPatterns: RegExp[];\n errorPatterns: RegExp[];\n}\n\nconst processConfigBases: Record<string, ProcessConfigBase> = {\n \"host-build\": {\n name: \"host-build\",\n command: \"bun\",\n args: [\"run\", \"build\"],\n cwd: \"host\",\n readyPatterns: [/built in/i, /compiled.*successfully/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n },\n host: {\n name: \"host\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"host\",\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n },\n ui: {\n name: \"ui\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"ui\",\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n },\n \"ui-ssr\": {\n name: \"ui-ssr\",\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n cwd: \"ui\",\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n },\n api: {\n name: \"api\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"api\",\n readyPatterns: [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i],\n errorPatterns: [/error/i, /failed/i],\n },\n};\n\nexport function getProcessConfig(\n pkg: string,\n env?: Record<string, string>,\n portOverride?: number,\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n): DevProcess | null {\n if (pkg === \"auth\") {\n const authConfig = runtimeConfig?.auth;\n if (!authConfig?.localPath || authConfig.source !== \"local\") return null;\n\n const port =\n portOverride ?? authConfig.port ?? (authConfig.url ? parsePort(authConfig.url) : 3020);\n\n return {\n name: \"auth\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: authConfig.localPath,\n port,\n readyPatterns: [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i],\n errorPatterns: [/error/i, /failed/i],\n env,\n };\n }\n\n if (pkg.startsWith(\"plugin:\")) {\n const pluginId = pkg.slice(\"plugin:\".length);\n const pluginConfig = runtimeConfig?.plugins?.[pluginId] ?? null;\n const localPath = pluginConfig?.localPath;\n\n if (!localPath || pluginConfig?.source !== \"local\") return null;\n\n const port =\n portOverride ?? pluginConfig?.port ?? (pluginConfig?.url ? parsePort(pluginConfig.url) : 0);\n\n return {\n name: pkg,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: localPath,\n port,\n readyPatterns: [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i],\n errorPatterns: [/error/i, /failed/i],\n env,\n };\n }\n\n const base = processConfigBases[pkg];\n if (!base) return null;\n\n let port: number;\n if (pkg === \"host\") {\n port =\n portOverride ??\n (runtimeConfig?.hostUrl\n ? parsePort(runtimeConfig.hostUrl)\n : bosConfig\n ? getHostDevelopmentPort(bosConfig.app.host.development)\n : 3000);\n } else if (pkg === \"ui\") {\n port =\n runtimeConfig?.ui.port ?? (runtimeConfig?.ui.url ? parsePort(runtimeConfig.ui.url) : 3002);\n } else if (pkg === \"ui-ssr\") {\n const uiPort = runtimeConfig?.ui.ssrUrl\n ? parsePort(runtimeConfig.ui.ssrUrl)\n : runtimeConfig?.ui.port\n ? runtimeConfig.ui.port + 1\n : 3003;\n port = uiPort;\n } else if (pkg === \"api\") {\n port =\n runtimeConfig?.api.port ?? (runtimeConfig?.api.url ? parsePort(runtimeConfig.api.url) : 3014);\n } else {\n port = 0;\n }\n\n const cwd =\n pkg === \"ui\"\n ? (runtimeConfig?.ui.localPath ?? base.cwd)\n : pkg === \"api\"\n ? (runtimeConfig?.api.localPath ?? base.cwd)\n : base.cwd;\n\n return { ...base, cwd, port, env };\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = async (url: string, timeoutMs = 400): Promise<boolean> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n};\n\nconst probeTcpOpen = async (port: number, timeoutMs = 250): Promise<boolean> => {\n return new Promise((resolve) => {\n const socket = createConnection({ host: \"127.0.0.1\", port });\n const timer = setTimeout(() => {\n socket.destroy();\n resolve(false);\n }, timeoutMs);\n socket.once(\"connect\", () => {\n clearTimeout(timer);\n socket.destroy();\n resolve(true);\n });\n socket.once(\"error\", () => {\n clearTimeout(timer);\n resolve(false);\n });\n });\n};\n\nconst detectStatus = (\n line: string,\n config: DevProcess,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n for (const pattern of config.errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of config.readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\nconst killProcessTree = (pid: number) =>\n Effect.gen(function* () {\n const killSignal = (signal: NodeJS.Signals) =>\n Effect.try({\n try: () => {\n process.kill(-pid, signal);\n },\n catch: () => null,\n }).pipe(Effect.ignore);\n\n const killDirect = (signal: NodeJS.Signals) =>\n Effect.try({\n try: () => {\n process.kill(pid, signal);\n },\n catch: () => null,\n }).pipe(Effect.ignore);\n\n const isRunning = () =>\n Effect.try({\n try: () => {\n process.kill(pid, 0);\n return true;\n },\n catch: () => false,\n });\n\n yield* killSignal(\"SIGTERM\");\n yield* killDirect(\"SIGTERM\");\n\n yield* Effect.sleep(\"200 millis\");\n\n const stillRunning = yield* isRunning();\n if (stillRunning) {\n yield* killSignal(\"SIGKILL\");\n yield* killDirect(\"SIGKILL\");\n yield* Effect.sleep(\"100 millis\");\n }\n });\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\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[]): string => {\n return args\n .map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg)))\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);\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 const spawnRemoteHost = (\n config: DevProcess,\n callbacks: ProcessCallbacks,\n runtimeConfig: RuntimeConfig,\n) =>\n Effect.gen(function* () {\n const remoteUrl = config.env?.HOST_REMOTE_URL;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"HOST_REMOTE_URL not provided for remote host\"));\n }\n\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n }\n\n callbacks.onStatus(config.name, \"starting\");\n callbacks.onLog(config.name, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(config.name, callbacks);\n callbacks.onLog(config.name, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const res = await fetch(manifestUrl);\n if (!res.ok) return remoteEntryUrl;\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 return manifestUrl;\n }\n } catch {}\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(config.name, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(config.name, \"Starting server...\");\n const serverHandle = hostModule.runServer({ config: runtimeConfig });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(config.name, \"ready\");\n\n return {\n name: config.name,\n pid: process.pid,\n kill: Effect.gen(function* () {\n callbacks.onLog(config.name, \"Shutting down remote host...\");\n restoreConsole();\n yield* Effect.tryPromise({\n try: () => serverHandle.shutdown(),\n catch: () => {},\n }).pipe(Effect.ignore);\n }),\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const spawnDevProcess = (\n config: DevProcess,\n callbacks: ProcessCallbacks,\n runtimeConfig?: RuntimeConfig,\n registry?: ProcessRegistry,\n) =>\n Effect.gen(function* () {\n let configDir: string;\n try {\n configDir = getProjectRoot();\n } catch {\n configDir = process.cwd();\n }\n const fullCwd = config.cwd.startsWith(\"/\") ? config.cwd : `${configDir}/${config.cwd}`;\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(config.name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n ...config.env,\n FORCE_COLOR: \"1\",\n ...(config.port > 0 ? { PORT: String(config.port) } : {}),\n };\n\n if (runtimeConfig && config.name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const proc = Bun.spawn({\n cmd: [config.command, ...config.args],\n cwd: fullCwd,\n env: envVars,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\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(config.name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n if (config.port > 0) {\n const readinessPath =\n config.name === \"host\" ? \"/health\" : config.name === \"ui-ssr\" ? \"/\" : \"/remoteEntry.js\";\n const url = `http://127.0.0.1:${config.port}${readinessPath}`;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + 90_000;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = url\n ? yield* Effect.tryPromise({\n try: () => probeHttpOk(url),\n catch: () => false,\n })\n : yield* Effect.tryPromise({\n try: () => probeTcpOpen(config.port),\n catch: () => false,\n });\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(\"200 millis\");\n }\n }),\n );\n }\n\n if (registry && proc.pid) {\n yield* registry.track({\n pid: proc.pid,\n name: config.name,\n port: config.port,\n startedAt: Date.now(),\n command: [config.command, ...config.args].join(\" \"),\n });\n }\n\n yield* Effect.forkScoped(\n Effect.promise(() => proc.exited).pipe(\n Effect.andThen((code) =>\n Effect.gen(function* () {\n if (registry && proc.pid) {\n yield* registry.untrack(proc.pid).pipe(Effect.ignore);\n }\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\") return;\n callbacks.onLog(config.name, `Process exited before ready (exit code: ${code})`, true);\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(config.name, \"error\");\n yield* Deferred.fail(\n readyDeferred,\n new Error(`Process exited before ready: ${config.name}`),\n ).pipe(Effect.ignore);\n }),\n ),\n ),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n callbacks.onLog(config.name, line, isStderr);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\") return;\n\n const detected = detectStatus(line, config);\n if (detected) {\n yield* Ref.set(statusRef, detected.status);\n callbacks.onStatus(config.name, detected.status);\n if (detected.status === \"ready\" || detected.status === \"error\") {\n if (detected.status === \"ready\") {\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n } else {\n yield* Deferred.fail(readyDeferred, new Error(`Process failed: ${config.name}`)).pipe(\n Effect.ignore,\n );\n }\n }\n }\n });\n\n const decoder = new TextDecoder();\n\n const stdoutFiber = yield* Effect.forkScoped(\n Effect.async<void>((resume) => {\n if (!proc.stdout) {\n resume(Effect.void);\n return;\n }\n const reader = proc.stdout.getReader();\n let buffer = \"\";\n let active = true;\n\n const pump = (): Promise<void> =>\n reader.read().then(({ done, value }) => {\n if (!active) return;\n if (done) {\n if (buffer) Effect.runSync(handleLine(buffer, false));\n return;\n }\n buffer += decoder\n .decode(value, { stream: true })\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n Effect.runSync(handleLine(line, false));\n }\n return pump();\n });\n\n pump().then(() => {\n if (active) resume(Effect.void);\n });\n\n return Effect.sync(() => {\n active = false;\n reader.cancel();\n });\n }),\n );\n\n const stderrFiber = yield* Effect.forkScoped(\n Effect.async<void>((resume) => {\n if (!proc.stderr) {\n resume(Effect.void);\n return;\n }\n const reader = proc.stderr.getReader();\n let buffer = \"\";\n let active = true;\n\n const pump = (): Promise<void> =>\n reader.read().then(({ done, value }) => {\n if (!active) return;\n if (done) {\n if (buffer) Effect.runSync(handleLine(buffer, true));\n return;\n }\n buffer += decoder\n .decode(value, { stream: true })\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n Effect.runSync(handleLine(line, true));\n }\n return pump();\n });\n\n pump().then(() => {\n if (active) resume(Effect.void);\n });\n\n return Effect.sync(() => {\n active = false;\n reader.cancel();\n });\n }),\n );\n\n const handle: ProcessHandle = {\n name: config.name,\n pid: proc.pid,\n kill: proc.pid\n ? killProcessTree(proc.pid)\n : Effect.gen(function* () {\n proc.kill(\"SIGTERM\");\n yield* Effect.sleep(\"100 millis\");\n try {\n proc.kill(\"SIGKILL\");\n } catch {}\n }),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.gen(function* () {\n yield* Fiber.joinAll([stdoutFiber, stderrFiber]);\n return yield* Effect.promise(() => proc.exited);\n }),\n };\n\n return handle;\n });\n\nexport const makeDevProcess = (\n pkg: string,\n env: Record<string, string> | undefined,\n callbacks: ProcessCallbacks,\n portOverride?: number,\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n registry?: ProcessRegistry,\n) =>\n Effect.gen(function* () {\n const config = getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig);\n if (!config) {\n return yield* Effect.fail(new Error(`Unknown package: ${pkg}`));\n }\n\n if (pkg === \"host\" && runtimeConfig) {\n if (env?.HOST_SOURCE === \"remote\") {\n return yield* spawnRemoteHost(config, callbacks, runtimeConfig);\n }\n return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);\n }\n\n return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);\n });\n"],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.mjs","names":[],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { createConnection } from \"node:net\";\nimport { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n DevRuntimeConfig,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\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, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<ExitCode, unknown>;\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}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n Effect.tryPromise({\n try: async () => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n },\n catch: () => false,\n });\n\nconst probeTcpOpen = (port: number, timeoutMs = 250) =>\n Effect.async<boolean>((resume) => {\n const socket = createConnection({ host: \"127.0.0.1\", port });\n const timer = setTimeout(() => {\n socket.destroy();\n resume(Effect.succeed(false));\n }, timeoutMs);\n socket.once(\"connect\", () => {\n clearTimeout(timer);\n socket.destroy();\n resume(Effect.succeed(true));\n });\n socket.once(\"error\", () => {\n clearTimeout(timer);\n resume(Effect.succeed(false));\n });\n });\n\nconst 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 errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\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}\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[]): string => {\n return args\n .map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg)))\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);\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\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* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\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 mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const res = await fetch(manifestUrl);\n if (!res.ok) return remoteEntryUrl;\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 return manifestUrl;\n }\n } catch {}\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(descriptor.key, \"Starting server...\");\n const serverHandle = hostModule.runServer({ config: runtimeConfig });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(descriptor.key, \"ready\");\n\n return {\n name: descriptor.key,\n pid: process.pid,\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.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\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* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n }\n\n const fullCwd = descriptor.localPath;\n const command = descriptor.command ?? \"bun\";\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, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n FORCE_COLOR: \"1\",\n ...(port > 0 ? { PORT: String(port) } : {}),\n };\n\n if (name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const cmd = Command.make(command, ...args).pipe(\n Command.workingDirectory(fullCwd),\n Command.env(envVars),\n );\n\n const proc = yield* Command.start(cmd);\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 if (port > 0) {\n const readinessPath = descriptor.readinessPath;\n const url = `http://127.0.0.1:${port}${readinessPath}`;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + 90_000;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = yield* probeHttpOk(url);\n if (ok) {\n yield* markReady;\n return;\n }\n const tcpOk = yield* probeTcpOpen(port);\n if (tcpOk) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(\"200 millis\");\n }\n }),\n );\n }\n\n const pid = Number(proc.pid);\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const exitCode = yield* proc.exitCode;\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\") return;\n callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(name, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Process exited before ready: ${name}`)).pipe(\n Effect.ignore,\n );\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 !/^\\$/.test(cleanLine);\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 yield* Ref.set(statusRef, detected.status);\n callbacks.onStatus(name, detected.status);\n if (detected.status === \"ready\" || detected.status === \"error\") {\n if (detected.status === \"ready\") {\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n } else {\n yield* Deferred.fail(readyDeferred, new Error(`Process failed: ${name}`)).pipe(\n Effect.ignore,\n );\n }\n }\n }\n });\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, false))(\n Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n ),\n );\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, true))(\n Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n ),\n );\n\n return {\n name,\n pid,\n kill: Effect.gen(function* () {\n const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n if (Option.isNone(result)) {\n const pid = Number(proc.pid);\n yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n yield* Effect.sleep(\"250 millis\");\n }\n }).pipe(Effect.ignore),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: proc.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, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n const markReady = Effect.gen(function* () {\n yield* Ref.set(statusRef, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined);\n callbacks.onStatus(pkg, \"ready\", \"loaded\");\n });\n\n const markError = Effect.gen(function* () {\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`));\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 deadline = Date.now() + 60_000;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n\n const ok = yield* probeHttpOk(probeUrl, 400);\n\n if (ok) {\n yield* markReady;\n return;\n }\n\n const fallbackOk = yield* probeHttpOk(entryUrl, 400);\n\n if (fallbackOk) {\n yield* markReady;\n return;\n }\n\n yield* Effect.sleep(\"500 millis\");\n }\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(readyDeferred, new Error(\"Killed\")).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);\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 };\n });\n}\n"],"mappings":"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"}
package/dist/plugin.cjs CHANGED
@@ -11,8 +11,9 @@ const require_prompts = require('./cli/prompts.cjs');
11
11
  const require_status = require('./cli/status.cjs');
12
12
  const require_sync = require('./cli/sync.cjs');
13
13
  const require_upgrade = require('./cli/upgrade.cjs');
14
- const require_dev_session = require('./dev-session.cjs');
15
14
  const require_integrity = require('./integrity.cjs');
15
+ const require_service_descriptor = require('./service-descriptor.cjs');
16
+ const require_dev_session = require('./dev-session.cjs');
16
17
  const require_near_cli = require('./near-cli.cjs');
17
18
  const require_shared = require('./shared.cjs');
18
19
  const require_run = require('./utils/run.cjs');
@@ -38,12 +39,6 @@ function ensureEnvFile(configDir) {
38
39
  }).join("\n"));
39
40
  console.log(`[CLI] Created .env from .env.example with generated BETTER_AUTH_SECRET`);
40
41
  }
41
- const DEFAULT_DEV_CONFIG = {
42
- host: "local",
43
- ui: "local",
44
- api: "local",
45
- ssr: false
46
- };
47
42
  const buildCommands = {
48
43
  host: {
49
44
  cmd: "bun",
@@ -63,24 +58,6 @@ function parseSourceMode(value, defaultValue) {
63
58
  if (value === "local" || value === "remote") return value;
64
59
  return defaultValue;
65
60
  }
66
- function buildAppConfig(options) {
67
- return {
68
- host: parseSourceMode(options.host, DEFAULT_DEV_CONFIG.host),
69
- ui: parseSourceMode(options.ui, DEFAULT_DEV_CONFIG.ui),
70
- api: parseSourceMode(options.api, DEFAULT_DEV_CONFIG.api),
71
- proxy: options.proxy,
72
- ssr: options.ssr ?? DEFAULT_DEV_CONFIG.ssr
73
- };
74
- }
75
- function buildDescription(config) {
76
- if (config.host === "local" && config.ui === "local" && config.api === "local" && !config.proxy) return "Full Local Development";
77
- const parts = [];
78
- parts.push(config.host === "remote" ? "Remote Host" : "Local Host");
79
- if (config.ui === "remote") parts.push("Remote UI");
80
- if (config.proxy) parts.push("Proxy API → Production");
81
- else if (config.api === "remote") parts.push("Remote API");
82
- return parts.join(" + ");
83
- }
84
61
  function buildConfigResult(bosConfig) {
85
62
  const packages = bosConfig ? Object.keys(bosConfig.app) : [];
86
63
  return {
@@ -103,19 +80,6 @@ function resolveWorkspaceTarget(key, bosConfig, runtimeConfig, configDir) {
103
80
  };
104
81
  return null;
105
82
  }
106
- function determineProcesses(config, localPackages, runtimeConfig) {
107
- const processes = [];
108
- if (config.ssr && config.ui === "local") processes.push("ui-ssr");
109
- if (config.ui === "local") processes.push("ui");
110
- if (localPackages.includes("auth") && runtimeConfig?.auth?.source === "local") processes.push("auth");
111
- if (config.api === "local" && !config.proxy) processes.push("api");
112
- for (const pkg of localPackages) if (pkg.startsWith("plugin:")) {
113
- const pluginId = pkg.slice(7);
114
- if (runtimeConfig?.plugins?.[pluginId]?.source === "local") processes.push(pkg);
115
- }
116
- processes.push("host");
117
- return processes;
118
- }
119
83
  function isValidProxyUrl(url) {
120
84
  try {
121
85
  const parsed = new URL(url);
@@ -187,30 +151,6 @@ function extractPublishedUrl(output) {
187
151
  if (!match || match.length === 0) return null;
188
152
  return match[match.length - 1] ?? null;
189
153
  }
190
- async function buildEnvVars(config, bosConfig) {
191
- const env = {
192
- HOST_SOURCE: config.host,
193
- UI_SOURCE: config.ui,
194
- API_SOURCE: config.api
195
- };
196
- if (config.host === "remote") {
197
- const remoteUrl = bosConfig?.app.host.production;
198
- if (remoteUrl) env.HOST_REMOTE_URL = remoteUrl;
199
- }
200
- if (config.ui === "remote") {
201
- const remoteUrl = bosConfig?.app.ui.production;
202
- if (remoteUrl) env.UI_REMOTE_URL = remoteUrl;
203
- }
204
- if (config.api === "remote") {
205
- const remoteUrl = bosConfig?.app.api.production;
206
- if (remoteUrl) env.API_REMOTE_URL = remoteUrl;
207
- }
208
- if (config.proxy && bosConfig) {
209
- const proxyUrl = resolveProxyUrl(bosConfig);
210
- if (proxyUrl) env.API_PROXY = proxyUrl;
211
- }
212
- return env;
213
- }
214
154
  async function buildEveryPluginQuietly(cwd) {
215
155
  const packageDir = `${cwd}/packages/every-plugin`;
216
156
  if (!await Bun.file(`${packageDir}/package.json`).exists()) return;
@@ -562,19 +502,18 @@ var plugin_default = (0, every_plugin.createPlugin)({
562
502
  dev: builder.dev.handler(async ({ input }) => {
563
503
  ensureEnvFile(deps.configDir);
564
504
  const localPackages = require_app.detectLocalPackages(deps.bosConfig ?? void 0, deps.runtimeConfig ?? void 0);
565
- const appConfig = buildAppConfig({
566
- host: localPackages.includes("host") ? input.host : "remote",
567
- ui: localPackages.includes("ui") ? input.ui : "remote",
568
- api: localPackages.includes("api") ? input.api : "remote",
569
- proxy: input.proxy,
570
- ssr: input.ssr
571
- });
505
+ const hostSource = localPackages.includes("host") ? parseSourceMode(input.host, "local") : "remote";
506
+ const uiSource = localPackages.includes("ui") ? parseSourceMode(input.ui, "local") : "remote";
507
+ const apiSource = localPackages.includes("api") ? parseSourceMode(input.api, "local") : "remote";
508
+ const authSource = localPackages.includes("auth") ? parseSourceMode(input.auth, "local") : "remote";
509
+ const ssr = input.ssr ?? false;
510
+ const proxy = input.proxy ?? false;
572
511
  if ((await require_shared.syncAndGenerateSharedUi({
573
512
  configDir: deps.configDir,
574
- hostMode: appConfig.host,
513
+ hostMode: hostSource,
575
514
  bosConfig: deps.bosConfig ?? void 0
576
515
  })).catalogChanged) await require_run.run("bun", ["install"], { cwd: deps.configDir });
577
- if (appConfig.api === "local" && !appConfig.proxy || localPackages.some((pkg) => pkg.startsWith("plugin:"))) await buildEveryPluginQuietly(deps.configDir);
516
+ if (apiSource === "local" && !proxy || localPackages.some((pkg) => pkg.startsWith("plugin:"))) await buildEveryPluginQuietly(deps.configDir);
578
517
  await buildEverythingDevQuietly(deps.configDir);
579
518
  const refreshed = await require_config.loadConfig({ cwd: deps.configDir });
580
519
  deps.bosConfig = refreshed?.config ?? deps.bosConfig;
@@ -584,47 +523,50 @@ var plugin_default = (0, every_plugin.createPlugin)({
584
523
  description: "No bos.config.json found",
585
524
  processes: []
586
525
  };
587
- if (appConfig.proxy && !resolveProxyUrl(deps.bosConfig)) return {
526
+ if (proxy && !resolveProxyUrl(deps.bosConfig)) return {
588
527
  status: "error",
589
528
  description: "No valid proxy URL configured in bos.config.json",
590
529
  processes: []
591
530
  };
592
- const refreshedLocalPackages = require_app.detectLocalPackages(deps.bosConfig ?? void 0, deps.runtimeConfig ?? void 0);
593
- const processes = determineProcesses(appConfig, refreshedLocalPackages, deps.runtimeConfig);
594
- const env = await buildEnvVars(appConfig, deps.bosConfig);
595
531
  const hostPort = input.port ?? require_config.getHostDevelopmentPort(deps.bosConfig.app.host.development);
596
532
  const runtimeConfig = await require_app.prepareDevelopmentRuntimeConfig(require_app.buildRuntimeConfig(deps.bosConfig, {
597
- uiSource: appConfig.ui,
598
- apiSource: appConfig.api,
599
- authSource: refreshedLocalPackages.includes("auth") ? "local" : "remote",
600
- hostUrl: `http://localhost:${hostPort}`,
601
- proxy: env.API_PROXY,
533
+ uiSource,
534
+ apiSource,
535
+ authSource,
536
+ hostSource,
602
537
  env: "development",
603
538
  plugins: deps.runtimeConfig?.plugins
604
539
  }), {
605
540
  hostPort,
606
- ssr: appConfig.ssr
541
+ ssr
542
+ });
543
+ const services = require_service_descriptor.buildServiceDescriptorMap(runtimeConfig, {
544
+ ssr,
545
+ proxy
607
546
  });
547
+ const packages = [...services.keys()];
548
+ const displayEnv = {};
549
+ if (services.get("api")?.proxy) {
550
+ const proxyUrl = resolveProxyUrl(deps.bosConfig);
551
+ if (proxyUrl) displayEnv.API_PROXY = proxyUrl;
552
+ }
608
553
  await require_api_contract.syncApiContractBridge({
609
554
  configDir: deps.configDir,
610
555
  runtimeConfig,
611
556
  apiBaseUrl: runtimeConfig.api.url
612
557
  });
613
558
  const orchestrator = {
614
- packages: processes,
615
- env,
616
- description: buildDescription(appConfig),
617
- appConfig,
618
- bosConfig: deps.bosConfig,
619
- runtimeConfig,
620
- port: require_config.parsePort(runtimeConfig.hostUrl),
559
+ packages,
560
+ env: displayEnv,
561
+ description: require_service_descriptor.buildDescription(services),
562
+ port: runtimeConfig.host.port,
621
563
  interactive: input.interactive
622
564
  };
623
- require_dev_session.startApp(orchestrator);
565
+ require_dev_session.devApp(orchestrator, services, runtimeConfig);
624
566
  return {
625
567
  status: "started",
626
568
  description: orchestrator.description,
627
- processes
569
+ processes: packages
628
570
  };
629
571
  }),
630
572
  start: builder.start.handler(async ({ input }) => {
@@ -643,43 +585,32 @@ var plugin_default = (0, every_plugin.createPlugin)({
643
585
  url: ""
644
586
  };
645
587
  const port = input.port ?? require_config.getHostDevelopmentPort(config.app.host.development);
646
- const appConfig = {
647
- host: "remote",
648
- ui: "remote",
649
- api: "remote"
650
- };
651
- const env = await buildEnvVars(appConfig, config);
652
588
  const isStaging = input.env === "staging";
653
- const runtimePlugins = remoteConfig ? await require_config.buildRuntimePluginsForConfig(config, deps.configDir, "production") : deps.runtimeConfig?.plugins;
654
589
  const runtimeConfig = require_app.buildRuntimeConfig(config, {
655
590
  uiSource: "remote",
656
591
  apiSource: "remote",
657
592
  authSource: "remote",
658
- hostUrl: `http://localhost:${port}`,
593
+ hostSource: "remote",
659
594
  env: "production",
660
- plugins: runtimePlugins
595
+ plugins: remoteConfig ? await require_config.buildRuntimePluginsForConfig(config, deps.configDir, "production") : deps.runtimeConfig?.plugins
661
596
  });
597
+ const services = require_service_descriptor.buildServiceDescriptorMap(runtimeConfig);
662
598
  await require_api_contract.syncApiContractBridge({
663
599
  configDir: deps.configDir,
664
600
  runtimeConfig,
665
601
  apiBaseUrl: runtimeConfig.api.url
666
602
  });
667
- const stagingEnvVars = isStaging ? { GATEWAY_DOMAIN: config.staging?.domain ?? config.domain ?? "" } : {};
668
603
  require_dev_session.startApp({
669
604
  packages: ["host"],
670
605
  env: {
671
606
  NODE_ENV: "production",
672
- ...env,
673
- ...stagingEnvVars
607
+ ...isStaging ? { GATEWAY_DOMAIN: config.staging?.domain ?? config.domain ?? "" } : {}
674
608
  },
675
609
  description: `${isStaging ? "Staging" : "Production"} Mode (${config.account})`,
676
- appConfig,
677
- bosConfig: config,
678
- runtimeConfig,
679
610
  port,
680
611
  interactive: input.interactive,
681
612
  noLogs: true
682
- });
613
+ }, services, runtimeConfig);
683
614
  return {
684
615
  status: "running",
685
616
  url: `http://localhost:${port}`
@@ -701,7 +632,7 @@ var plugin_default = (0, every_plugin.createPlugin)({
701
632
  uiSource: deps.bosConfig.app.ui?.development ? "local" : "remote",
702
633
  apiSource: deps.bosConfig.app.api?.development ? "local" : "remote",
703
634
  authSource: deps.bosConfig.app.auth?.development ? "local" : "remote",
704
- hostUrl: require_config.resolveDevelopmentHostUrl(deps.bosConfig.app.host.development),
635
+ hostSource: deps.bosConfig.app.host?.development ? "local" : "remote",
705
636
  env: "development",
706
637
  plugins: deps.runtimeConfig?.plugins
707
638
  });