@agent-native/core 0.12.14 → 0.12.16
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.
- package/dist/agent/engine/index.d.ts +1 -0
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -0
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +56 -42
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/cli/workspace-dev.js +26 -5
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +33 -6
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +7 -2
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +2 -0
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +13 -12
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionEditor.js +23 -10
- package/dist/client/extensions/ExtensionEditor.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +15 -10
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.js +12 -6
- package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +8 -9
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/extensions/delete-extension.d.ts +12 -0
- package/dist/client/extensions/delete-extension.d.ts.map +1 -0
- package/dist/client/extensions/delete-extension.js +49 -0
- package/dist/client/extensions/delete-extension.js.map +1 -0
- package/dist/client/sharing/ShareButton.js +6 -1
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareButton.spec.d.ts +2 -0
- package/dist/client/sharing/ShareButton.spec.d.ts.map +1 -0
- package/dist/client/sharing/ShareButton.spec.js +90 -0
- package/dist/client/sharing/ShareButton.spec.js.map +1 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -2
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +19 -2
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +3 -0
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +41 -5
- package/dist/extensions/routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +11 -7
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/templates/default/AGENTS.md +7 -1
- package/dist/templates/default/DEVELOPING.md +12 -0
- package/dist/templates/default/app/hooks/use-navigation-state.ts +81 -0
- package/dist/templates/default/app/root.tsx +11 -5
- package/dist/templates/workspace-root/AGENTS.md +13 -0
- package/dist/templates/workspace-root/README.md +6 -0
- package/docs/content/multi-app-workspace.md +2 -0
- package/package.json +1 -1
- package/src/templates/default/AGENTS.md +7 -1
- package/src/templates/default/DEVELOPING.md +12 -0
- package/src/templates/default/app/hooks/use-navigation-state.ts +81 -0
- package/src/templates/default/app/root.tsx +11 -5
- package/src/templates/workspace-root/AGENTS.md +13 -0
- package/src/templates/workspace-root/README.md +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-dev.js","sourceRoot":"","sources":["../../src/cli/workspace-dev.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env tsx\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport http from \"node:http\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport type { Duplex } from \"node:stream\";\nimport * as Sentry from \"@sentry/node\";\nimport { extractOAuthStateAppId } from \"../shared/oauth-state.js\";\n\ninterface WorkspaceApp {\n id: string;\n name: string;\n dir: string;\n port: number;\n process?: ChildProcess;\n restartTimer?: NodeJS.Timeout;\n restartAttempts?: number;\n /**\n * Set true once we've successfully connected to the upstream. After that we\n * skip the readiness probe on every request — the child server stays\n * listening for the rest of the dev session.\n */\n ready?: boolean;\n}\n\nconst root = process.cwd();\nconst appsDir = path.join(root, \"apps\");\nfs.mkdirSync(path.join(root, \"data\"), { recursive: true });\nconst gatewayHost = process.env.WORKSPACE_HOST || \"127.0.0.1\";\nconst requestedPort = Number(\n process.env.WORKSPACE_PORT || process.env.PORT || 8080,\n);\nconst appPortStart = Number(process.env.WORKSPACE_APP_PORT_START || 8100);\nconst forceVite = process.env.WORKSPACE_VITE_FORCE === \"1\";\nlet gatewayUrl = `http://${gatewayHost}:${requestedPort}`;\n\nfunction readJson(file: string): any {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction discoverApps(): WorkspaceApp[] {\n if (!fs.existsSync(appsDir)) return [];\n // existsSync → readdirSync is a TOCTOU race — appsDir can vanish between\n // the two calls (e.g. user running `git checkout` on the workspace mid-dev).\n // Treat ENOENT as \"no apps right now\" and let the next 2s sync recover.\n // Other errors get surfaced to Sentry so we learn about new failure modes.\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(appsDir, { withFileTypes: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n console.warn(\n `[workspace] Could not read ${appsDir} (${code ?? \"unknown\"}): ` +\n `${(err as Error).message}`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-discover-readdir\" },\n level: \"warning\",\n });\n }\n return [];\n }\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => {\n const dir = path.join(appsDir, entry.name);\n const pkg = readJson(path.join(dir, \"package.json\"));\n if (!pkg) return null;\n return {\n id: entry.name,\n name: pkg.displayName || pkg.name || entry.name,\n dir,\n port: appPortStart,\n } satisfies WorkspaceApp;\n })\n .filter((app): app is WorkspaceApp => !!app)\n .sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.id.localeCompare(b.id);\n })\n .map((app, index) => ({ ...app, port: appPortStart + index }));\n}\n\nconst apps = discoverApps();\nif (apps.length === 0) {\n console.error(\"[workspace] No apps found under ./apps\");\n process.exit(1);\n}\n\nconst appById = new Map(apps.map((app) => [app.id, app]));\nconst defaultApp =\n process.env.WORKSPACE_DEFAULT_APP &&\n appById.has(process.env.WORKSPACE_DEFAULT_APP)\n ? process.env.WORKSPACE_DEFAULT_APP\n : appById.has(\"dispatch\")\n ? \"dispatch\"\n : apps[0].id;\n\nfunction isChildDevServerUrlLine(line: string): boolean {\n return /^\\s*➜\\s+(?:Local|Network):\\s+https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\]):\\d+(?:\\/\\S*)?\\s*$/i.test(\n line,\n );\n}\n\nfunction pipeAppOutput(\n prefix: string,\n chunk: unknown,\n write: (value: string) => void,\n): void {\n const lines = String(chunk)\n .split(/\\r?\\n/)\n .filter(Boolean)\n .filter((line) => !isChildDevServerUrlLine(line));\n if (lines.length === 0) return;\n write(lines.map((line) => `${prefix} ${line}`).join(\"\\n\") + \"\\n\");\n}\n\nfunction syncApps(): void {\n const discovered = discoverApps();\n for (const app of discovered) {\n const existing = appById.get(app.id);\n if (existing) {\n existing.name = app.name;\n existing.dir = app.dir;\n continue;\n }\n const usedPorts = new Set(apps.map((existing) => existing.port));\n let port = appPortStart;\n while (usedPorts.has(port)) port++;\n const next = { ...app, port };\n apps.push(next);\n apps.sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.id.localeCompare(b.id);\n });\n appById.set(next.id, next);\n console.log(`[workspace] Detected new app: /${next.id}`);\n startApp(next);\n }\n}\n\nlet syncTimer: NodeJS.Timeout | undefined;\nfunction scheduleSync(): void {\n if (syncTimer) clearTimeout(syncTimer);\n syncTimer = setTimeout(syncApps, 400);\n}\n\nfunction firstPathSegment(url: string | undefined): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url, \"http://workspace.local\");\n const [segment] = parsed.pathname.split(\"/\").filter(Boolean);\n return segment || null;\n } catch {\n return null;\n }\n}\n\nfunction appForRequest(req: http.IncomingMessage): WorkspaceApp | null {\n const params = new URL(req.url || \"/\", \"http://workspace.local\").searchParams;\n const explicit = params.get(\"_app\");\n if (explicit && appById.has(explicit)) return appById.get(explicit) ?? null;\n\n const direct = firstPathSegment(req.url);\n if (direct && appById.has(direct)) return appById.get(direct) ?? null;\n\n const fromState = extractOAuthStateAppId(params.get(\"state\"));\n if (fromState && appById.has(fromState)) {\n return appById.get(fromState) ?? null;\n }\n\n const referer = req.headers.referer;\n const fromReferer =\n typeof referer === \"string\" ? firstPathSegment(referer) : null;\n return fromReferer && appById.has(fromReferer)\n ? (appById.get(fromReferer) ?? null)\n : null;\n}\n\nfunction startApp(app: WorkspaceApp): void {\n if (app.process && !app.process.killed) return;\n if (app.restartTimer) {\n clearTimeout(app.restartTimer);\n app.restartTimer = undefined;\n }\n\n const basePath = `/${app.id}`;\n const workspaceAppsJson = JSON.stringify(\n apps.map((workspaceApp) => ({\n id: workspaceApp.id,\n name: workspaceApp.name,\n path: `/${workspaceApp.id}`,\n })),\n );\n const child = spawn(\n \"pnpm\",\n [\n \"--dir\",\n app.dir,\n \"exec\",\n \"vite\",\n \"--host\",\n \"127.0.0.1\",\n \"--port\",\n String(app.port),\n \"--strictPort\",\n ...(forceVite ? [\"--force\"] : []),\n ],\n {\n cwd: root,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n APP_NAME: app.id,\n AGENT_NATIVE_WORKSPACE: \"1\",\n AGENT_NATIVE_WORKSPACE_APPS_JSON: workspaceAppsJson,\n APP_BASE_PATH: basePath,\n VITE_AGENT_NATIVE_WORKSPACE: \"1\",\n VITE_APP_BASE_PATH: basePath,\n PORT: String(app.port),\n WORKSPACE_GATEWAY_URL: gatewayUrl,\n },\n },\n );\n app.process = child;\n\n const prefix = `[${app.id}]`;\n const stableTimer = setTimeout(() => {\n app.restartAttempts = 0;\n }, 5_000);\n stableTimer.unref();\n\n child.stdout?.on(\"data\", (chunk) => {\n pipeAppOutput(prefix, chunk, (value) => process.stdout.write(value));\n });\n child.stderr?.on(\"data\", (chunk) => {\n pipeAppOutput(prefix, chunk, (value) => process.stderr.write(value));\n });\n child.on(\"exit\", (code) => {\n clearTimeout(stableTimer);\n app.process = undefined;\n app.ready = false;\n if (code === 0 || shuttingDown) return;\n app.restartAttempts = (app.restartAttempts ?? 0) + 1;\n const delay = appRestartDelay(app.restartAttempts);\n console.error(\n `${prefix} exited with code ${code}; retrying in ${Math.round(\n delay / 1000,\n )}s`,\n );\n app.restartTimer = setTimeout(() => {\n app.restartTimer = undefined;\n startApp(app);\n }, delay);\n app.restartTimer.unref();\n });\n}\n\nfunction renderIndex(): string {\n return `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Agent-Native Workspace</title>\n <style>\n body { font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; margin: 0; padding: 32px; background: #fafafa; color: #171717; }\n main { max-width: 760px; margin: 0 auto; }\n a { color: inherit; text-decoration: none; }\n .grid { display: grid; gap: 12px; margin-top: 20px; }\n .card { display: flex; justify-content: space-between; border: 1px solid #d4d4d4; border-radius: 8px; padding: 14px 16px; background: white; }\n .muted { color: #737373; }\n </style>\n </head>\n <body>\n <main>\n <h1>Agent-Native Workspace</h1>\n <p class=\"muted\">Open an app below. Dispatch is the workspace control plane.</p>\n <div class=\"grid\">\n ${apps\n .map(\n (app) =>\n `<a class=\"card\" href=\"/${app.id}\"><strong>${app.name}</strong><span class=\"muted\">/${app.id}</span></a>`,\n )\n .join(\"\")}\n </div>\n </main>\n </body>\n</html>`;\n}\n\n// On `pnpm dev` the gateway answers requests immediately, but each app's vite\n// server takes a beat to bind its port. Without retry, the user sees an\n// \"App is not ready yet: ECONNREFUSED\" banner on the first page load and has\n// to refresh manually. We do a quick pre-flight TCP connect with retry so\n// startup is invisible for the common case (small/no body, slow boot).\nconst PROXY_READY_TIMEOUT_MS = Number(\n process.env.WORKSPACE_PROXY_READY_TIMEOUT_MS ?? 30_000,\n);\nconst PROXY_READY_RETRY_DELAY_MS = 250;\nconst APP_RESTART_MAX_DELAY_MS = 10_000;\n\nfunction appRestartDelay(attempts: number): number {\n return Math.min(\n 1_000 * 2 ** Math.max(0, attempts - 1),\n APP_RESTART_MAX_DELAY_MS,\n );\n}\n\nfunction probePort(port: number, timeoutMs = 1_000): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = new net.Socket();\n let settled = false;\n const finish = (ok: boolean) => {\n if (settled) return;\n settled = true;\n socket.destroy();\n resolve(ok);\n };\n socket.setTimeout(timeoutMs);\n socket.once(\"connect\", () => finish(true));\n socket.once(\"error\", () => finish(false));\n socket.once(\"timeout\", () => finish(false));\n socket.connect(port, \"127.0.0.1\");\n });\n}\n\nasync function waitForPort(port: number, deadline: number): Promise<boolean> {\n while (Date.now() < deadline) {\n if (await probePort(port)) return true;\n await new Promise((r) => setTimeout(r, PROXY_READY_RETRY_DELAY_MS));\n }\n return false;\n}\n\nfunction proxyHttp(\n app: WorkspaceApp,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n const dispatch = () => {\n const headers = { ...req.headers, host: `127.0.0.1:${app.port}` };\n const proxyReq = http.request(\n {\n hostname: \"127.0.0.1\",\n port: app.port,\n method: req.method,\n path: req.url,\n headers,\n },\n (proxyRes) => {\n app.ready = true;\n res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);\n proxyRes.pipe(res);\n },\n );\n\n proxyReq.on(\"error\", (err) => {\n if (res.headersSent) {\n res.end();\n return;\n }\n res.writeHead(502, { \"content-type\": \"text/plain\" });\n res.end(`App \"${app.id}\" is not ready yet: ${err.message}`);\n });\n\n req.pipe(proxyReq);\n };\n\n // Fast path: the upstream has accepted at least one request before, so it's\n // listening. Skip the probe so steady-state requests stay zero-latency.\n if (app.ready) {\n dispatch();\n return;\n }\n\n // Cold path: hold the request open while the child server boots. Node\n // keeps the request body in paused mode until a consumer attaches via\n // pipe(), so awaiting waitForPort() doesn't lose data.\n void waitForPort(app.port, Date.now() + PROXY_READY_TIMEOUT_MS).then(\n (ready) => {\n if (!ready) {\n if (!res.headersSent) {\n res.writeHead(502, { \"content-type\": \"text/plain\" });\n res.end(\n `App \"${app.id}\" is not ready yet: connect ECONNREFUSED 127.0.0.1:${app.port}`,\n );\n } else {\n res.end();\n }\n return;\n }\n app.ready = true;\n dispatch();\n },\n );\n}\n\nfunction proxyUpgrade(\n app: WorkspaceApp,\n req: http.IncomingMessage,\n socket: Duplex,\n head: Buffer,\n): void {\n const target = net.connect(app.port, \"127.0.0.1\", () => {\n const headers = Object.entries({\n ...req.headers,\n host: `127.0.0.1:${app.port}`,\n })\n .flatMap(([key, value]) =>\n Array.isArray(value)\n ? value.map((item) => `${key}: ${item}`)\n : [`${key}: ${value ?? \"\"}`],\n )\n .join(\"\\r\\n\");\n target.write(\n `${req.method} ${req.url} HTTP/${req.httpVersion}\\r\\n${headers}\\r\\n\\r\\n`,\n );\n if (head.length) target.write(head);\n socket.pipe(target).pipe(socket);\n });\n\n target.on(\"error\", () => socket.destroy());\n}\n\nlet shuttingDown = false;\nlet workspaceStarted = false;\n\nfunction handleWatcherError(err: NodeJS.ErrnoException): void {\n // ENOSPC: system inotify watcher limit hit (Linux). Userland-fixable;\n // capture as a warning so we still see frequency in Sentry but don't get\n // paged. Print actionable guidance and continue without watching — the\n // 2s polling interval below keeps app discovery working.\n if (err.code === \"ENOSPC\") {\n console.warn(\n `[workspace] Recursive file watcher hit the system limit (ENOSPC). ` +\n `New apps will still be detected via polling every ~2s. ` +\n `On Linux you can raise the limit with ` +\n `\\`sudo sysctl fs.inotify.max_user_watches=524288\\` ` +\n `(persist via /etc/sysctl.d/*.conf). On macOS/Windows this usually ` +\n `means too many other watchers are running.`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-watch-enospc\" },\n level: \"warning\",\n });\n return;\n }\n // ENOENT: a watched directory disappeared (or a transient subdir under\n // appsDir vanished mid-enumeration). Benign — the polling fallback and\n // future scheduleSync calls will re-establish state. Don't capture.\n if (err.code === \"ENOENT\") {\n console.debug(\n `[workspace] Recursive file watcher saw a directory disappear ` +\n `(ENOENT: ${err.path ?? \"unknown\"}). Polling fallback will recover.`,\n );\n return;\n }\n // Unknown failure mode — keep the dev experience alive (polling still\n // runs) but surface to Sentry as a warning so we learn about new cases.\n console.warn(\n `[workspace] Recursive file watcher failed (${err.code ?? \"unknown\"}): ${err.message}. ` +\n `Falling back to polling.`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-watch-unknown\" },\n level: \"warning\",\n });\n}\n\nfunction startWorkspaceProcesses(): void {\n if (workspaceStarted) return;\n workspaceStarted = true;\n for (const app of apps) startApp(app);\n try {\n const watcher = fs.watch(appsDir, { recursive: true }, scheduleSync);\n // Async errors (e.g. ENOENT when a subdir vanishes mid-watch) surface on\n // the watcher rather than the original call site. Without an `error`\n // listener, Node would treat them as uncaught and crash the dev process.\n watcher.on(\"error\", (err) => {\n handleWatcherError(err as NodeJS.ErrnoException);\n });\n } catch (err) {\n handleWatcherError(err as NodeJS.ErrnoException);\n }\n setInterval(syncApps, 2_000).unref();\n}\n\nfunction openBrowser(url: string): void {\n if (process.env.WORKSPACE_NO_OPEN === \"1\") return;\n const command =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"cmd\"\n : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n const child = spawn(command, args, {\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n}\n\nconst server = http.createServer((req, res) => {\n if (req.url === \"/\" || req.url === \"/index.html\") {\n res.writeHead(302, { location: `/${defaultApp}` });\n res.end();\n return;\n }\n\n if (req.url === \"/_workspace/apps\") {\n res.writeHead(200, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify(\n apps.map((app) => ({\n id: app.id,\n name: app.name,\n path: `/${app.id}`,\n port: app.port,\n })),\n ),\n );\n return;\n }\n\n const app = appForRequest(req);\n if (!app) {\n res.writeHead(404, { \"content-type\": \"text/html\" });\n res.end(renderIndex());\n return;\n }\n proxyHttp(app, req, res);\n});\n\nserver.on(\"upgrade\", (req, socket, head) => {\n const app = appForRequest(req);\n if (!app) {\n socket.destroy();\n return;\n }\n proxyUpgrade(app, req, socket, head);\n});\n\nfunction listen(port: number, attempts = 20): void {\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\" && attempts > 0) {\n listen(port + 1, attempts - 1);\n return;\n }\n console.error(`[workspace] Could not start gateway: ${err.message}`);\n process.exit(1);\n });\n server.listen(port, gatewayHost, () => {\n const address = server.address();\n const actualPort =\n typeof address === \"object\" && address ? address.port : port;\n gatewayUrl = `http://${gatewayHost}:${actualPort}`;\n console.log(\n `[workspace] Default: http://${gatewayHost}:${actualPort}/${defaultApp}`,\n );\n console.log(`[workspace] Gateway: http://${gatewayHost}:${actualPort}`);\n for (const app of apps) {\n console.log(`[workspace] ${app.id}: /${app.id} -> 127.0.0.1:${app.port}`);\n }\n startWorkspaceProcesses();\n openBrowser(`http://${gatewayHost}:${actualPort}/${defaultApp}`);\n });\n}\n\nfunction shutdown(): void {\n if (shuttingDown) return;\n shuttingDown = true;\n server.close();\n for (const app of apps) {\n app.process?.kill(\"SIGTERM\");\n }\n setTimeout(() => process.exit(0), 300).unref();\n}\n\nprocess.on(\"SIGINT\", shutdown);\nprocess.on(\"SIGTERM\", shutdown);\n\nlisten(requestedPort);\n"]}
|
|
1
|
+
{"version":3,"file":"workspace-dev.js","sourceRoot":"","sources":["../../src/cli/workspace-dev.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAkBlE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACxC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,WAAW,CAAC;AAC9D,MAAM,aAAa,GAAG,MAAM,CAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CACvD,CAAC;AACF,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,IAAI,CAAC,CAAC;AAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AAC3D,IAAI,UAAU,GAAG,UAAU,WAAW,IAAI,aAAa,EAAE,CAAC;AAE1D,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,yEAAyE;IACzE,6EAA6E;IAC7E,wEAAwE;IACxE,2EAA2E;IAC3E,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CACV,8BAA8B,OAAO,KAAK,IAAI,IAAI,SAAS,KAAK;gBAC9D,GAAI,GAAa,CAAC,OAAO,EAAE,CAC9B,CAAC;YACF,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE;gBAC3B,IAAI,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE;gBACzC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YAC/C,GAAG;YACH,IAAI,EAAE,YAAY;SACI,CAAC;IAC3B,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,GAAG,EAAuB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;SAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,YAAY,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;AAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1D,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,qBAAqB;IACjC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC5C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB;IACnC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACvB,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAEnB,SAAS,uBAAuB,CAAC,IAAY;IAC3C,OAAO,+FAA+F,CAAC,IAAI,CACzG,IAAI,CACL,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,MAAc,EACd,KAAc,EACd,KAA8B;IAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;SACxB,KAAK,CAAC,OAAO,CAAC;SACd,MAAM,CAAC,OAAO,CAAC;SACf,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACzB,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;YACvB,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,IAAI,IAAI,GAAG,YAAY,CAAC;QACxB,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACjB,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU;gBAAE,OAAO,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU;gBAAE,OAAO,CAAC,CAAC;YAClC,OAAO,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;AACH,CAAC;AAED,IAAI,SAAqC,CAAC;AAC1C,SAAS,YAAY;IACnB,IAAI,SAAS;QAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACvC,SAAS,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAuB;IAC/C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,OAAO,IAAI,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAyB;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,wBAAwB,CAAC,CAAC,YAAY,CAAC;IAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;IAE5E,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAEtE,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,IAAI,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;IACpC,MAAM,WAAW,GACf,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,OAAO,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAC5C,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;QACpC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,GAAiB;IACjC,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO;IAC/C,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC/B,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;IAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CACtC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC1B,EAAE,EAAE,YAAY,CAAC,EAAE;QACnB,IAAI,EAAE,YAAY,CAAC,IAAI;QACvB,IAAI,EAAE,IAAI,YAAY,CAAC,EAAE,EAAE;KAC5B,CAAC,CAAC,CACJ,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CACjB,MAAM,EACN;QACE,OAAO;QACP,GAAG,CAAC,GAAG;QACP,MAAM;QACN,MAAM;QACN,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAChB,cAAc;QACd,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAClC,EACD;QACE,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,QAAQ,EAAE,GAAG,CAAC,EAAE;YAChB,sBAAsB,EAAE,GAAG;YAC3B,gCAAgC,EAAE,iBAAiB;YACnD,aAAa,EAAE,QAAQ;YACvB,2BAA2B,EAAE,GAAG;YAChC,kBAAkB,EAAE,QAAQ;YAC5B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACtB,qBAAqB,EAAE,UAAU;SAClC;KACF,CACF,CAAC;IACF,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC;IAC7B,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;QAClC,GAAG,CAAC,eAAe,GAAG,CAAC,CAAC;IAC1B,CAAC,EAAE,KAAK,CAAC,CAAC;IACV,WAAW,CAAC,KAAK,EAAE,CAAC;IAEpB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACjC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACjC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,YAAY,CAAC,WAAW,CAAC,CAAC;QAC1B,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;QACxB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,IAAI,KAAK,CAAC,IAAI,YAAY;YAAE,OAAO;QACvC,GAAG,CAAC,eAAe,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CACX,GAAG,MAAM,qBAAqB,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAC3D,KAAK,GAAG,IAAI,CACb,GAAG,CACL,CAAC;QACF,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YACjC,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC;YAC7B,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC,EAAE,KAAK,CAAC,CAAC;QACV,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW;IAClB,OAAO;;;;;;;;;;;;;;;;;;;;UAoBC,IAAI;SACH,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,0BAA0B,GAAG,CAAC,EAAE,aAAa,GAAG,CAAC,IAAI,iCAAiC,GAAG,CAAC,EAAE,aAAa,CAC5G;SACA,IAAI,CAAC,EAAE,CAAC;;;;QAIX,CAAC;AACT,CAAC;AAED,8EAA8E;AAC9E,wEAAwE;AACxE,6EAA6E;AAC7E,0EAA0E;AAC1E,uEAAuE;AACvE,MAAM,sBAAsB,GAAG,MAAM,CACnC,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,MAAM,CACvD,CAAC;AACF,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAExC,SAAS,eAAe,CAAC,QAAgB;IACvC,OAAO,IAAI,CAAC,GAAG,CACb,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,EACtC,wBAAwB,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,SAAS,GAAG,KAAK;IAChD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,EAAW,EAAE,EAAE;YAC7B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CACvB,KAA6C;IAE7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,cAAc,CAAC,GAAyB;IAC/C,OAAO,CACL,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAClD,CAAE,GAAG,CAAC,MAAkC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CACvE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,GAAyB;IAC9C,OAAO,CACL,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACjD,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;QAClC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,GAAyB,EACzB,UAAkB;IAElB,OAAO;QACL,GAAG,GAAG,CAAC,OAAO;QACd,kBAAkB,EAAE,aAAa,CAAC,GAAG,CAAC;QACtC,mBAAmB,EAAE,cAAc,CAAC,GAAG,CAAC;QACxC,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,QAAgB;IACvD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,MAAM,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAChB,GAAiB,EACjB,GAAyB,EACzB,GAAwB;IAExB,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAC3B;YACE,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,GAAG;YACb,OAAO;SACR,EACD,CAAC,QAAQ,EAAE,EAAE;YACX,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;YACjB,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,CACF,CAAC;QAEF,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3B,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;gBACpB,GAAG,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,uBAAuB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,4EAA4E;IAC5E,wEAAwE;IACxE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,sEAAsE;IACtE,sEAAsE;IACtE,uDAAuD;IACvD,KAAK,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,sBAAsB,CAAC,CAAC,IAAI,CAClE,CAAC,KAAK,EAAE,EAAE;QACR,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;gBACrD,GAAG,CAAC,GAAG,CACL,QAAQ,GAAG,CAAC,EAAE,sDAAsD,GAAG,CAAC,IAAI,EAAE,CAC/E,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;YACD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;QACjB,QAAQ,EAAE,CAAC;IACb,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,GAAiB,EACjB,GAAyB,EACzB,MAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;aACvE,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CACxB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;YACxC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,KAAK,IAAI,EAAE,EAAE,CAAC,CAC/B;aACA,IAAI,CAAC,MAAM,CAAC,CAAC;QAChB,MAAM,CAAC,KAAK,CACV,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,WAAW,OAAO,OAAO,UAAU,CACzE,CAAC;QACF,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B,SAAS,kBAAkB,CAAC,GAA0B;IACpD,sEAAsE;IACtE,yEAAyE;IACzE,uEAAuE;IACvE,yDAAyD;IACzD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CACV,oEAAoE;YAClE,yDAAyD;YACzD,wCAAwC;YACxC,qDAAqD;YACrD,oEAAoE;YACpE,4CAA4C,CAC/C,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE;YAC3B,IAAI,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE;YACrC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,uEAAuE;IACvE,uEAAuE;IACvE,oEAAoE;IACpE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CACX,+DAA+D;YAC7D,YAAY,GAAG,CAAC,IAAI,IAAI,SAAS,mCAAmC,CACvE,CAAC;QACF,OAAO;IACT,CAAC;IACD,sEAAsE;IACtE,wEAAwE;IACxE,OAAO,CAAC,IAAI,CACV,8CAA8C,GAAG,CAAC,IAAI,IAAI,SAAS,MAAM,GAAG,CAAC,OAAO,IAAI;QACtF,0BAA0B,CAC7B,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE;QAC3B,IAAI,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE;QACtC,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,uBAAuB;IAC9B,IAAI,gBAAgB;QAAE,OAAO;IAC7B,gBAAgB,GAAG,IAAI,CAAC;IACxB,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,YAAY,CAAC,CAAC;QACrE,yEAAyE;QACzE,qEAAqE;QACrE,yEAAyE;QACzE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1B,kBAAkB,CAAC,GAA4B,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,kBAAkB,CAAC,GAA4B,CAAC,CAAC;IACnD,CAAC;IACD,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG;QAAE,OAAO;IAClD,MAAM,OAAO,GACX,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,UAAU,CAAC;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;QACjC,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5C,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;QACjD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,UAAU,EAAE,EAAE,CAAC,CAAC;QACnD,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,GAAG,KAAK,kBAAkB,EAAE,CAAC;QACnC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CACZ,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACjB,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC,CAAC,CACJ,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;QACpD,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IACzC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,SAAS,MAAM,CAAC,IAAY,EAAE,QAAQ,GAAG,EAAE;IACzC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;QAClD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,wCAAwC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;QACpC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,UAAU,GACd,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/D,UAAU,GAAG,UAAU,WAAW,IAAI,UAAU,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,+BAA+B,WAAW,IAAI,UAAU,IAAI,UAAU,EAAE,CACzE,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,+BAA+B,WAAW,IAAI,UAAU,EAAE,CAAC,CAAC;QACxE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,uBAAuB,EAAE,CAAC;QAC1B,WAAW,CAAC,UAAU,WAAW,IAAI,UAAU,IAAI,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ;IACf,IAAI,YAAY;QAAE,OAAO;IACzB,YAAY,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IACD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhC,MAAM,CAAC,aAAa,CAAC,CAAC","sourcesContent":["#!/usr/bin/env tsx\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport http from \"node:http\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport type { Duplex } from \"node:stream\";\nimport * as Sentry from \"@sentry/node\";\nimport { extractOAuthStateAppId } from \"../shared/oauth-state.js\";\n\ninterface WorkspaceApp {\n id: string;\n name: string;\n dir: string;\n port: number;\n process?: ChildProcess;\n restartTimer?: NodeJS.Timeout;\n restartAttempts?: number;\n /**\n * Set true once we've successfully connected to the upstream. After that we\n * skip the readiness probe on every request — the child server stays\n * listening for the rest of the dev session.\n */\n ready?: boolean;\n}\n\nconst root = process.cwd();\nconst appsDir = path.join(root, \"apps\");\nfs.mkdirSync(path.join(root, \"data\"), { recursive: true });\nconst gatewayHost = process.env.WORKSPACE_HOST || \"127.0.0.1\";\nconst requestedPort = Number(\n process.env.WORKSPACE_PORT || process.env.PORT || 8080,\n);\nconst appPortStart = Number(process.env.WORKSPACE_APP_PORT_START || 8100);\nconst forceVite = process.env.WORKSPACE_VITE_FORCE === \"1\";\nlet gatewayUrl = `http://${gatewayHost}:${requestedPort}`;\n\nfunction readJson(file: string): any {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction discoverApps(): WorkspaceApp[] {\n if (!fs.existsSync(appsDir)) return [];\n // existsSync → readdirSync is a TOCTOU race — appsDir can vanish between\n // the two calls (e.g. user running `git checkout` on the workspace mid-dev).\n // Treat ENOENT as \"no apps right now\" and let the next 2s sync recover.\n // Other errors get surfaced to Sentry so we learn about new failure modes.\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(appsDir, { withFileTypes: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n console.warn(\n `[workspace] Could not read ${appsDir} (${code ?? \"unknown\"}): ` +\n `${(err as Error).message}`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-discover-readdir\" },\n level: \"warning\",\n });\n }\n return [];\n }\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => {\n const dir = path.join(appsDir, entry.name);\n const pkg = readJson(path.join(dir, \"package.json\"));\n if (!pkg) return null;\n return {\n id: entry.name,\n name: pkg.displayName || pkg.name || entry.name,\n dir,\n port: appPortStart,\n } satisfies WorkspaceApp;\n })\n .filter((app): app is WorkspaceApp => !!app)\n .sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.id.localeCompare(b.id);\n })\n .map((app, index) => ({ ...app, port: appPortStart + index }));\n}\n\nconst apps = discoverApps();\nif (apps.length === 0) {\n console.error(\"[workspace] No apps found under ./apps\");\n process.exit(1);\n}\n\nconst appById = new Map(apps.map((app) => [app.id, app]));\nconst defaultApp =\n process.env.WORKSPACE_DEFAULT_APP &&\n appById.has(process.env.WORKSPACE_DEFAULT_APP)\n ? process.env.WORKSPACE_DEFAULT_APP\n : appById.has(\"dispatch\")\n ? \"dispatch\"\n : apps[0].id;\n\nfunction isChildDevServerUrlLine(line: string): boolean {\n return /^\\s*➜\\s+(?:Local|Network):\\s+https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\]):\\d+(?:\\/\\S*)?\\s*$/i.test(\n line,\n );\n}\n\nfunction pipeAppOutput(\n prefix: string,\n chunk: unknown,\n write: (value: string) => void,\n): void {\n const lines = String(chunk)\n .split(/\\r?\\n/)\n .filter(Boolean)\n .filter((line) => !isChildDevServerUrlLine(line));\n if (lines.length === 0) return;\n write(lines.map((line) => `${prefix} ${line}`).join(\"\\n\") + \"\\n\");\n}\n\nfunction syncApps(): void {\n const discovered = discoverApps();\n for (const app of discovered) {\n const existing = appById.get(app.id);\n if (existing) {\n existing.name = app.name;\n existing.dir = app.dir;\n continue;\n }\n const usedPorts = new Set(apps.map((existing) => existing.port));\n let port = appPortStart;\n while (usedPorts.has(port)) port++;\n const next = { ...app, port };\n apps.push(next);\n apps.sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.id.localeCompare(b.id);\n });\n appById.set(next.id, next);\n console.log(`[workspace] Detected new app: /${next.id}`);\n startApp(next);\n }\n}\n\nlet syncTimer: NodeJS.Timeout | undefined;\nfunction scheduleSync(): void {\n if (syncTimer) clearTimeout(syncTimer);\n syncTimer = setTimeout(syncApps, 400);\n}\n\nfunction firstPathSegment(url: string | undefined): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url, \"http://workspace.local\");\n const [segment] = parsed.pathname.split(\"/\").filter(Boolean);\n return segment || null;\n } catch {\n return null;\n }\n}\n\nfunction appForRequest(req: http.IncomingMessage): WorkspaceApp | null {\n const params = new URL(req.url || \"/\", \"http://workspace.local\").searchParams;\n const explicit = params.get(\"_app\");\n if (explicit && appById.has(explicit)) return appById.get(explicit) ?? null;\n\n const direct = firstPathSegment(req.url);\n if (direct && appById.has(direct)) return appById.get(direct) ?? null;\n\n const fromState = extractOAuthStateAppId(params.get(\"state\"));\n if (fromState && appById.has(fromState)) {\n return appById.get(fromState) ?? null;\n }\n\n const referer = req.headers.referer;\n const fromReferer =\n typeof referer === \"string\" ? firstPathSegment(referer) : null;\n return fromReferer && appById.has(fromReferer)\n ? (appById.get(fromReferer) ?? null)\n : null;\n}\n\nfunction startApp(app: WorkspaceApp): void {\n if (app.process && !app.process.killed) return;\n if (app.restartTimer) {\n clearTimeout(app.restartTimer);\n app.restartTimer = undefined;\n }\n\n const basePath = `/${app.id}`;\n const workspaceAppsJson = JSON.stringify(\n apps.map((workspaceApp) => ({\n id: workspaceApp.id,\n name: workspaceApp.name,\n path: `/${workspaceApp.id}`,\n })),\n );\n const child = spawn(\n \"pnpm\",\n [\n \"--dir\",\n app.dir,\n \"exec\",\n \"vite\",\n \"--host\",\n \"127.0.0.1\",\n \"--port\",\n String(app.port),\n \"--strictPort\",\n ...(forceVite ? [\"--force\"] : []),\n ],\n {\n cwd: root,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n APP_NAME: app.id,\n AGENT_NATIVE_WORKSPACE: \"1\",\n AGENT_NATIVE_WORKSPACE_APPS_JSON: workspaceAppsJson,\n APP_BASE_PATH: basePath,\n VITE_AGENT_NATIVE_WORKSPACE: \"1\",\n VITE_APP_BASE_PATH: basePath,\n PORT: String(app.port),\n WORKSPACE_GATEWAY_URL: gatewayUrl,\n },\n },\n );\n app.process = child;\n\n const prefix = `[${app.id}]`;\n const stableTimer = setTimeout(() => {\n app.restartAttempts = 0;\n }, 5_000);\n stableTimer.unref();\n\n child.stdout?.on(\"data\", (chunk) => {\n pipeAppOutput(prefix, chunk, (value) => process.stdout.write(value));\n });\n child.stderr?.on(\"data\", (chunk) => {\n pipeAppOutput(prefix, chunk, (value) => process.stderr.write(value));\n });\n child.on(\"exit\", (code) => {\n clearTimeout(stableTimer);\n app.process = undefined;\n app.ready = false;\n if (code === 0 || shuttingDown) return;\n app.restartAttempts = (app.restartAttempts ?? 0) + 1;\n const delay = appRestartDelay(app.restartAttempts);\n console.error(\n `${prefix} exited with code ${code}; retrying in ${Math.round(\n delay / 1000,\n )}s`,\n );\n app.restartTimer = setTimeout(() => {\n app.restartTimer = undefined;\n startApp(app);\n }, delay);\n app.restartTimer.unref();\n });\n}\n\nfunction renderIndex(): string {\n return `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Agent-Native Workspace</title>\n <style>\n body { font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; margin: 0; padding: 32px; background: #fafafa; color: #171717; }\n main { max-width: 760px; margin: 0 auto; }\n a { color: inherit; text-decoration: none; }\n .grid { display: grid; gap: 12px; margin-top: 20px; }\n .card { display: flex; justify-content: space-between; border: 1px solid #d4d4d4; border-radius: 8px; padding: 14px 16px; background: white; }\n .muted { color: #737373; }\n </style>\n </head>\n <body>\n <main>\n <h1>Agent-Native Workspace</h1>\n <p class=\"muted\">Open an app below. Dispatch is the workspace control plane.</p>\n <div class=\"grid\">\n ${apps\n .map(\n (app) =>\n `<a class=\"card\" href=\"/${app.id}\"><strong>${app.name}</strong><span class=\"muted\">/${app.id}</span></a>`,\n )\n .join(\"\")}\n </div>\n </main>\n </body>\n</html>`;\n}\n\n// On `pnpm dev` the gateway answers requests immediately, but each app's vite\n// server takes a beat to bind its port. Without retry, the user sees an\n// \"App is not ready yet: ECONNREFUSED\" banner on the first page load and has\n// to refresh manually. We do a quick pre-flight TCP connect with retry so\n// startup is invisible for the common case (small/no body, slow boot).\nconst PROXY_READY_TIMEOUT_MS = Number(\n process.env.WORKSPACE_PROXY_READY_TIMEOUT_MS ?? 30_000,\n);\nconst PROXY_READY_RETRY_DELAY_MS = 250;\nconst APP_RESTART_MAX_DELAY_MS = 10_000;\n\nfunction appRestartDelay(attempts: number): number {\n return Math.min(\n 1_000 * 2 ** Math.max(0, attempts - 1),\n APP_RESTART_MAX_DELAY_MS,\n );\n}\n\nfunction probePort(port: number, timeoutMs = 1_000): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = new net.Socket();\n let settled = false;\n const finish = (ok: boolean) => {\n if (settled) return;\n settled = true;\n socket.destroy();\n resolve(ok);\n };\n socket.setTimeout(timeoutMs);\n socket.once(\"connect\", () => finish(true));\n socket.once(\"error\", () => finish(false));\n socket.once(\"timeout\", () => finish(false));\n socket.connect(port, \"127.0.0.1\");\n });\n}\n\nfunction firstHeaderValue(\n value: string | string[] | number | undefined,\n): string | undefined {\n if (Array.isArray(value)) return value[0];\n if (value === undefined) return undefined;\n return String(value);\n}\n\nfunction forwardedProto(req: http.IncomingMessage): string {\n return (\n firstHeaderValue(req.headers[\"x-forwarded-proto\"]) ||\n ((req.socket as { encrypted?: boolean }).encrypted ? \"https\" : \"http\")\n );\n}\n\nfunction forwardedHost(req: http.IncomingMessage): string {\n return (\n firstHeaderValue(req.headers[\"x-forwarded-host\"]) ||\n firstHeaderValue(req.headers.host) ||\n new URL(gatewayUrl).host\n );\n}\n\nfunction proxyHeaders(\n req: http.IncomingMessage,\n targetHost: string,\n): http.OutgoingHttpHeaders {\n return {\n ...req.headers,\n \"x-forwarded-host\": forwardedHost(req),\n \"x-forwarded-proto\": forwardedProto(req),\n host: targetHost,\n };\n}\n\nasync function waitForPort(port: number, deadline: number): Promise<boolean> {\n while (Date.now() < deadline) {\n if (await probePort(port)) return true;\n await new Promise((r) => setTimeout(r, PROXY_READY_RETRY_DELAY_MS));\n }\n return false;\n}\n\nfunction proxyHttp(\n app: WorkspaceApp,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n const dispatch = () => {\n const headers = proxyHeaders(req, `127.0.0.1:${app.port}`);\n const proxyReq = http.request(\n {\n hostname: \"127.0.0.1\",\n port: app.port,\n method: req.method,\n path: req.url,\n headers,\n },\n (proxyRes) => {\n app.ready = true;\n res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);\n proxyRes.pipe(res);\n },\n );\n\n proxyReq.on(\"error\", (err) => {\n if (res.headersSent) {\n res.end();\n return;\n }\n res.writeHead(502, { \"content-type\": \"text/plain\" });\n res.end(`App \"${app.id}\" is not ready yet: ${err.message}`);\n });\n\n req.pipe(proxyReq);\n };\n\n // Fast path: the upstream has accepted at least one request before, so it's\n // listening. Skip the probe so steady-state requests stay zero-latency.\n if (app.ready) {\n dispatch();\n return;\n }\n\n // Cold path: hold the request open while the child server boots. Node\n // keeps the request body in paused mode until a consumer attaches via\n // pipe(), so awaiting waitForPort() doesn't lose data.\n void waitForPort(app.port, Date.now() + PROXY_READY_TIMEOUT_MS).then(\n (ready) => {\n if (!ready) {\n if (!res.headersSent) {\n res.writeHead(502, { \"content-type\": \"text/plain\" });\n res.end(\n `App \"${app.id}\" is not ready yet: connect ECONNREFUSED 127.0.0.1:${app.port}`,\n );\n } else {\n res.end();\n }\n return;\n }\n app.ready = true;\n dispatch();\n },\n );\n}\n\nfunction proxyUpgrade(\n app: WorkspaceApp,\n req: http.IncomingMessage,\n socket: Duplex,\n head: Buffer,\n): void {\n const target = net.connect(app.port, \"127.0.0.1\", () => {\n const headers = Object.entries(proxyHeaders(req, `127.0.0.1:${app.port}`))\n .flatMap(([key, value]) =>\n Array.isArray(value)\n ? value.map((item) => `${key}: ${item}`)\n : [`${key}: ${value ?? \"\"}`],\n )\n .join(\"\\r\\n\");\n target.write(\n `${req.method} ${req.url} HTTP/${req.httpVersion}\\r\\n${headers}\\r\\n\\r\\n`,\n );\n if (head.length) target.write(head);\n socket.pipe(target).pipe(socket);\n });\n\n target.on(\"error\", () => socket.destroy());\n}\n\nlet shuttingDown = false;\nlet workspaceStarted = false;\n\nfunction handleWatcherError(err: NodeJS.ErrnoException): void {\n // ENOSPC: system inotify watcher limit hit (Linux). Userland-fixable;\n // capture as a warning so we still see frequency in Sentry but don't get\n // paged. Print actionable guidance and continue without watching — the\n // 2s polling interval below keeps app discovery working.\n if (err.code === \"ENOSPC\") {\n console.warn(\n `[workspace] Recursive file watcher hit the system limit (ENOSPC). ` +\n `New apps will still be detected via polling every ~2s. ` +\n `On Linux you can raise the limit with ` +\n `\\`sudo sysctl fs.inotify.max_user_watches=524288\\` ` +\n `(persist via /etc/sysctl.d/*.conf). On macOS/Windows this usually ` +\n `means too many other watchers are running.`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-watch-enospc\" },\n level: \"warning\",\n });\n return;\n }\n // ENOENT: a watched directory disappeared (or a transient subdir under\n // appsDir vanished mid-enumeration). Benign — the polling fallback and\n // future scheduleSync calls will re-establish state. Don't capture.\n if (err.code === \"ENOENT\") {\n console.debug(\n `[workspace] Recursive file watcher saw a directory disappear ` +\n `(ENOENT: ${err.path ?? \"unknown\"}). Polling fallback will recover.`,\n );\n return;\n }\n // Unknown failure mode — keep the dev experience alive (polling still\n // runs) but surface to Sentry as a warning so we learn about new cases.\n console.warn(\n `[workspace] Recursive file watcher failed (${err.code ?? \"unknown\"}): ${err.message}. ` +\n `Falling back to polling.`,\n );\n Sentry.captureException(err, {\n tags: { handled: \"dev-watch-unknown\" },\n level: \"warning\",\n });\n}\n\nfunction startWorkspaceProcesses(): void {\n if (workspaceStarted) return;\n workspaceStarted = true;\n for (const app of apps) startApp(app);\n try {\n const watcher = fs.watch(appsDir, { recursive: true }, scheduleSync);\n // Async errors (e.g. ENOENT when a subdir vanishes mid-watch) surface on\n // the watcher rather than the original call site. Without an `error`\n // listener, Node would treat them as uncaught and crash the dev process.\n watcher.on(\"error\", (err) => {\n handleWatcherError(err as NodeJS.ErrnoException);\n });\n } catch (err) {\n handleWatcherError(err as NodeJS.ErrnoException);\n }\n setInterval(syncApps, 2_000).unref();\n}\n\nfunction openBrowser(url: string): void {\n if (process.env.WORKSPACE_NO_OPEN === \"1\") return;\n const command =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"cmd\"\n : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n const child = spawn(command, args, {\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n}\n\nconst server = http.createServer((req, res) => {\n if (req.url === \"/\" || req.url === \"/index.html\") {\n res.writeHead(302, { location: `/${defaultApp}` });\n res.end();\n return;\n }\n\n if (req.url === \"/_workspace/apps\") {\n res.writeHead(200, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify(\n apps.map((app) => ({\n id: app.id,\n name: app.name,\n path: `/${app.id}`,\n port: app.port,\n })),\n ),\n );\n return;\n }\n\n const app = appForRequest(req);\n if (!app) {\n res.writeHead(404, { \"content-type\": \"text/html\" });\n res.end(renderIndex());\n return;\n }\n proxyHttp(app, req, res);\n});\n\nserver.on(\"upgrade\", (req, socket, head) => {\n const app = appForRequest(req);\n if (!app) {\n socket.destroy();\n return;\n }\n proxyUpgrade(app, req, socket, head);\n});\n\nfunction listen(port: number, attempts = 20): void {\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\" && attempts > 0) {\n listen(port + 1, attempts - 1);\n return;\n }\n console.error(`[workspace] Could not start gateway: ${err.message}`);\n process.exit(1);\n });\n server.listen(port, gatewayHost, () => {\n const address = server.address();\n const actualPort =\n typeof address === \"object\" && address ? address.port : port;\n gatewayUrl = `http://${gatewayHost}:${actualPort}`;\n console.log(\n `[workspace] Default: http://${gatewayHost}:${actualPort}/${defaultApp}`,\n );\n console.log(`[workspace] Gateway: http://${gatewayHost}:${actualPort}`);\n for (const app of apps) {\n console.log(`[workspace] ${app.id}: /${app.id} -> 127.0.0.1:${app.port}`);\n }\n startWorkspaceProcesses();\n openBrowser(`http://${gatewayHost}:${actualPort}/${defaultApp}`);\n });\n}\n\nfunction shutdown(): void {\n if (shuttingDown) return;\n shuttingDown = true;\n server.close();\n for (const app of apps) {\n app.process?.kill(\"SIGTERM\");\n }\n setTimeout(() => process.exit(0), 300).unref();\n}\n\nprocess.on(\"SIGINT\", shutdown);\nprocess.on(\"SIGTERM\", shutdown);\n\nlisten(requestedPort);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AA6Bf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -807,7 +807,15 @@ function AssistantMessage() {
|
|
|
807
807
|
"");
|
|
808
808
|
})(), messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }) }))] }))] }));
|
|
809
809
|
}
|
|
810
|
-
|
|
810
|
+
function ActivitySteps({ steps }) {
|
|
811
|
+
if (steps.length === 0)
|
|
812
|
+
return null;
|
|
813
|
+
const visibleSteps = steps.slice(-4);
|
|
814
|
+
return (_jsx("div", { className: "max-w-[85%] rounded-md border border-border/60 bg-muted/30 px-2.5 py-2 text-xs text-muted-foreground", "aria-live": "polite", children: _jsx("div", { className: "space-y-1", children: visibleSteps.map((step, index) => {
|
|
815
|
+
const isCurrent = index === visibleSteps.length - 1;
|
|
816
|
+
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [isCurrent ? (_jsx(IconLoader2, { className: "h-3 w-3 shrink-0 animate-spin" })) : (_jsx(IconCheck, { className: "h-3 w-3 shrink-0 text-emerald-500" })), _jsx("span", { className: "truncate", children: step.label })] }, step.id));
|
|
817
|
+
}) }) }));
|
|
818
|
+
}
|
|
811
819
|
function ThinkingIndicator({ label = "Thinking" } = {}) {
|
|
812
820
|
const [dots, setDots] = useState(0);
|
|
813
821
|
useEffect(() => {
|
|
@@ -1106,6 +1114,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1106
1114
|
const wasRunningRef = useRef(false);
|
|
1107
1115
|
const lastBroadcastRunningRef = useRef(isRunning);
|
|
1108
1116
|
const tiptapRef = useRef(null);
|
|
1117
|
+
const [activitySteps, setActivitySteps] = useState([]);
|
|
1109
1118
|
useEffect(() => {
|
|
1110
1119
|
if (lastBroadcastRunningRef.current === isRunning)
|
|
1111
1120
|
return;
|
|
@@ -1623,15 +1632,32 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1623
1632
|
if (tabId && detail?.tabId && detail.tabId !== tabId)
|
|
1624
1633
|
return;
|
|
1625
1634
|
if (typeof detail?.label === "string" && detail.label.trim()) {
|
|
1626
|
-
|
|
1635
|
+
const label = detail.label.trim();
|
|
1636
|
+
const tool = detail.tool?.trim() || undefined;
|
|
1637
|
+
setActivityLabel(label);
|
|
1638
|
+
setActivitySteps((prev) => {
|
|
1639
|
+
const last = prev[prev.length - 1];
|
|
1640
|
+
if (last?.label === label && last.tool === tool)
|
|
1641
|
+
return prev;
|
|
1642
|
+
return [
|
|
1643
|
+
...prev,
|
|
1644
|
+
{
|
|
1645
|
+
id: `${Date.now()}-${prev.length}`,
|
|
1646
|
+
label,
|
|
1647
|
+
...(tool ? { tool } : {}),
|
|
1648
|
+
},
|
|
1649
|
+
].slice(-6);
|
|
1650
|
+
});
|
|
1627
1651
|
}
|
|
1628
1652
|
};
|
|
1629
1653
|
window.addEventListener("agent-chat:activity", handler);
|
|
1630
1654
|
return () => window.removeEventListener("agent-chat:activity", handler);
|
|
1631
1655
|
}, [tabId]);
|
|
1632
1656
|
useEffect(() => {
|
|
1633
|
-
if (!showRunningInUI)
|
|
1657
|
+
if (!showRunningInUI) {
|
|
1634
1658
|
setActivityLabel(null);
|
|
1659
|
+
setActivitySteps([]);
|
|
1660
|
+
}
|
|
1635
1661
|
}, [showRunningInUI]);
|
|
1636
1662
|
// Auto-dequeue: when agent finishes running, send the next queued message
|
|
1637
1663
|
useEffect(() => {
|
|
@@ -1699,6 +1725,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1699
1725
|
setRunErrorInfo(null);
|
|
1700
1726
|
setDismissedRunErrorKey(null);
|
|
1701
1727
|
setActivityLabel(null);
|
|
1728
|
+
setActivitySteps([]);
|
|
1702
1729
|
userStoppedRunRef.current = null;
|
|
1703
1730
|
// Selection context attached via Cmd+I is one-shot — clear it as soon
|
|
1704
1731
|
// as the user actually sends a message so it can't be re-used.
|
|
@@ -1915,9 +1942,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1915
1942
|
}
|
|
1916
1943
|
setRunErrorInfo(null);
|
|
1917
1944
|
} })), (isReconnecting || reconnectFrozen) &&
|
|
1918
|
-
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && (_jsx(ThinkingIndicator, { label: isReconnecting
|
|
1919
|
-
|
|
1920
|
-
|
|
1945
|
+
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && (_jsxs(_Fragment, { children: [_jsx(ActivitySteps, { steps: activitySteps }), _jsx(ThinkingIndicator, { label: isReconnecting
|
|
1946
|
+
? "Reconnecting"
|
|
1947
|
+
: (activityLabel ?? "Thinking") })] })), queuedMessages.map((msg) => {
|
|
1921
1948
|
const displayText = msg.text
|
|
1922
1949
|
.replace(/<context>[\s\S]*?<\/context>\n?/g, "")
|
|
1923
1950
|
.trim();
|