@evalops/maestro 0.10.21 → 0.10.23
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/agent.d.ts +1 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +15 -4
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +68 -3
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/types.d.ts +3 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/transport.js +7 -1
- package/dist/agent/transport.js.map +1 -1
- package/dist/audit/logger.d.ts +1 -1
- package/dist/bootstrap/tools-setup.d.ts.map +1 -1
- package/dist/bootstrap/tools-setup.js +3 -2
- package/dist/bootstrap/tools-setup.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts.map +1 -1
- package/dist/cli/commands/a2a.js +141 -8
- package/dist/cli/commands/a2a.js.map +1 -1
- package/dist/cli/commands/codex.d.ts.map +1 -1
- package/dist/cli/commands/codex.js +4 -3
- package/dist/cli/commands/codex.js.map +1 -1
- package/dist/cli/commands/hosted-runner.d.ts +1 -0
- package/dist/cli/commands/hosted-runner.d.ts.map +1 -1
- package/dist/cli/commands/hosted-runner.js +31 -2
- package/dist/cli/commands/hosted-runner.js.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +2 -9
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli-tui/commands/a2a-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/a2a-handlers.js +55 -0
- package/dist/cli-tui/commands/a2a-handlers.js.map +1 -1
- package/dist/cli.js +3925 -2024
- package/dist/codex/compatibility.d.ts +17 -1
- package/dist/codex/compatibility.d.ts.map +1 -1
- package/dist/codex/compatibility.js +57 -1
- package/dist/codex/compatibility.js.map +1 -1
- package/dist/guardian/config.d.ts +8 -6
- package/dist/guardian/config.d.ts.map +1 -1
- package/dist/guardian/config.js +33 -7
- package/dist/guardian/config.js.map +1 -1
- package/dist/guardian/runner.d.ts.map +1 -1
- package/dist/guardian/runner.js +54 -9
- package/dist/guardian/runner.js.map +1 -1
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +2 -0
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/fathom-cua.d.ts +3 -0
- package/dist/mcp/fathom-cua.d.ts.map +1 -0
- package/dist/mcp/fathom-cua.js +158 -0
- package/dist/mcp/fathom-cua.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/artifacts.d.ts +58 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.d.ts.map +1 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.js +191 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.js.map +1 -0
- package/dist/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +10 -10
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts +1 -0
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/index.js +1 -0
- package/dist/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +1 -1
- package/dist/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +3 -3
- package/dist/node_modules/@evalops/contracts/package.json +1 -1
- package/dist/node_modules/@evalops/tui/package.json +1 -1
- package/dist/platform/a2a-cockpit.d.ts +90 -0
- package/dist/platform/a2a-cockpit.d.ts.map +1 -0
- package/dist/platform/a2a-cockpit.js +302 -0
- package/dist/platform/a2a-cockpit.js.map +1 -0
- package/dist/platform/a2a-fleet.d.ts +14 -0
- package/dist/platform/a2a-fleet.d.ts.map +1 -1
- package/dist/platform/a2a-fleet.js +66 -1
- package/dist/platform/a2a-fleet.js.map +1 -1
- package/dist/platform/a2a-ownership.d.ts +27 -0
- package/dist/platform/a2a-ownership.d.ts.map +1 -0
- package/dist/platform/a2a-ownership.js +149 -0
- package/dist/platform/a2a-ownership.js.map +1 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -1
- package/dist/platform/a2a-task-ledger.js +29 -5
- package/dist/platform/a2a-task-ledger.js.map +1 -1
- package/dist/server/agent-trajectory-replay-lab.d.ts +36 -0
- package/dist/server/agent-trajectory-replay-lab.d.ts.map +1 -0
- package/dist/server/agent-trajectory-replay-lab.js +48 -0
- package/dist/server/agent-trajectory-replay-lab.js.map +1 -0
- package/dist/server/any-agent-control-plane-proof.d.ts +42 -0
- package/dist/server/any-agent-control-plane-proof.d.ts.map +1 -0
- package/dist/server/any-agent-control-plane-proof.js +175 -0
- package/dist/server/any-agent-control-plane-proof.js.map +1 -0
- package/dist/server/app-context.d.ts +1 -0
- package/dist/server/app-context.d.ts.map +1 -1
- package/dist/server/app-context.js.map +1 -1
- package/dist/server/handlers/a2a-cockpit.d.ts +3 -0
- package/dist/server/handlers/a2a-cockpit.d.ts.map +1 -0
- package/dist/server/handlers/a2a-cockpit.js +71 -0
- package/dist/server/handlers/a2a-cockpit.js.map +1 -0
- package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
- package/dist/server/handlers/headless-sessions.js +17 -2
- package/dist/server/handlers/headless-sessions.js.map +1 -1
- package/dist/server/handlers/session-artifacts.d.ts.map +1 -1
- package/dist/server/handlers/session-artifacts.js +14 -58
- package/dist/server/handlers/session-artifacts.js.map +1 -1
- package/dist/server/handlers/session-replay-lab.d.ts +13 -0
- package/dist/server/handlers/session-replay-lab.d.ts.map +1 -0
- package/dist/server/handlers/session-replay-lab.js +80 -0
- package/dist/server/handlers/session-replay-lab.js.map +1 -0
- package/dist/server/handlers/stats.js +1 -1
- package/dist/server/handlers/stats.js.map +1 -1
- package/dist/server/handlers/status.d.ts +44 -3
- package/dist/server/handlers/status.d.ts.map +1 -1
- package/dist/server/handlers/status.js +227 -17
- package/dist/server/handlers/status.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts +17 -0
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +143 -3
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.d.ts +17 -0
- package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.js +352 -15
- package/dist/server/hosted-agent-runtime-progress.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +14 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/services/intelligent-router/index.d.ts +1 -1
- package/dist/services/intelligent-router/index.d.ts.map +1 -1
- package/dist/services/intelligent-router/index.js +1 -1
- package/dist/services/intelligent-router/index.js.map +1 -1
- package/dist/services/intelligent-router/normalize.d.ts +10 -2
- package/dist/services/intelligent-router/normalize.d.ts.map +1 -1
- package/dist/services/intelligent-router/normalize.js +20 -1
- package/dist/services/intelligent-router/normalize.js.map +1 -1
- package/dist/services/intelligent-router/service.d.ts.map +1 -1
- package/dist/services/intelligent-router/service.js +35 -0
- package/dist/services/intelligent-router/service.js.map +1 -1
- package/dist/services/intelligent-router/types.d.ts +13 -0
- package/dist/services/intelligent-router/types.d.ts.map +1 -1
- package/dist/services/intelligent-router/types.js +1 -0
- package/dist/services/intelligent-router/types.js.map +1 -1
- package/dist/telemetry/cli-command-aggregator.d.ts +1 -0
- package/dist/telemetry/cli-command-aggregator.d.ts.map +1 -1
- package/dist/telemetry/cli-command-aggregator.js +23 -0
- package/dist/telemetry/cli-command-aggregator.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +11 -5
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-event-catalog.d.ts +15 -1
- package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-catalog.js +30 -0
- package/dist/telemetry/maestro-event-catalog.js.map +1 -1
- package/dist/version.json +2 -2
- package/package.json +289 -283
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-artifacts.js","sourceRoot":"","sources":["../../../src/server/handlers/session-artifacts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { ComposerMessage } from \"@evalops/contracts\";\nimport { lookup as lookupMimeType } from \"mime-types\";\nimport { createLogger } from \"../../utils/logger.js\";\nimport {\n\tARTIFACT_ACCESS_HEADER,\n\ttype ArtifactAccessAction,\n\tgetArtifactAccessGrantFromRequest,\n\tgetArtifactAccessTokenFromRequest,\n\tissueArtifactAccessGrant,\n} from \"../artifact-access.js\";\nimport { subscribeArtifactUpdates } from \"../artifacts-live-reload.js\";\nimport {\n\tApiError,\n\tbuildContentDisposition,\n\tsendJson,\n} from \"../server-utils.js\";\nimport {\n\tcreateWebSessionManagerForRequest,\n\tresolveSessionScope,\n} from \"../session-scope.js\";\nimport { convertAppMessagesToComposer } from \"../session-serialization.js\";\n\nconst logger = createLogger(\"session-artifacts\");\nconst sessionIdPattern = /^[a-zA-Z0-9._-]+$/;\n\nfunction escapeScriptContent(code: string): string {\n\treturn code.replace(/<\\/script/gi, \"<\\\\/script\");\n}\n\nfunction injectLiveReload(html: string, eventsUrl: string): string {\n\treturn injectLiveReloadWithAuth(html, eventsUrl);\n}\n\nfunction injectLiveReloadWithAuth(\n\thtml: string,\n\teventsUrl: string,\n\taccessToken?: string | null,\n): string {\n\tconst authHeaders = accessToken\n\t\t? `{ ${JSON.stringify(ARTIFACT_ACCESS_HEADER)}: ${JSON.stringify(accessToken)} }`\n\t\t: \"undefined\";\n\tconst scriptBody = `\n\t(function() {\n\t try {\n\t const reload = () => location.reload();\n\t const connect = ${\n\t\t\t\taccessToken\n\t\t\t\t\t? `async () => {\n\t const response = await fetch(${JSON.stringify(eventsUrl)}, {\n\t headers: ${authHeaders},\n\t cache: \"no-store\",\n\t });\n\t if (!response.body) throw new Error(\"Missing response body\");\n\t const reader = response.body.getReader();\n\t const decoder = new TextDecoder();\n\t let buffer = \"\";\n\t while (true) {\n\t const { done, value } = await reader.read();\n\t if (done) break;\n\t buffer += decoder.decode(value, { stream: true });\n\t let boundary = buffer.indexOf(\"\\\\n\\\\n\");\n\t while (boundary !== -1) {\n\t const chunk = buffer.slice(0, boundary);\n\t buffer = buffer.slice(boundary + 2);\n\t const dataLine = chunk\n\t .split(\"\\\\n\")\n\t .find((line) => line.startsWith(\"data:\"));\n\t if (dataLine) {\n\t reload();\n\t return;\n\t }\n\t boundary = buffer.indexOf(\"\\\\n\\\\n\");\n\t }\n\t }\n\t }`\n\t\t\t\t\t: `() => {\n\t const es = new EventSource(${JSON.stringify(eventsUrl)});\n\t es.onmessage = (e) => {\n\t try {\n\t const data = JSON.parse(e.data);\n\t if (data && data.type === \"artifact_updated\") {\n\t reload();\n\t }\n\t } catch (err) { console.error(\"[Maestro] Failed to parse live reload event:\", err); }\n\t };\n\t }`\n\t\t\t};\n\t Promise.resolve(connect()).catch((err) => {\n\t console.error(\"[Maestro] Failed to setup live reload transport:\", err);\n\t });\n\t } catch (err) { console.error(\"[Maestro] Failed to setup live reload EventSource:\", err); }\n\t})();\n\t`.trim();\n\tconst script = `<script>\\n${escapeScriptContent(scriptBody)}\\n</script>`;\n\tconst injected = `\\n${script}\\n`;\n\tif (/<\\/body>/i.test(html)) {\n\t\treturn html.replace(/<\\/body>/i, `${injected}</body>`);\n\t}\n\treturn `${html}${injected}`;\n}\n\nfunction wrapHtmlDocument(htmlContent: string): string {\n\tconst trimmed = htmlContent.trim();\n\tconst looksLikeDocument =\n\t\t/^<!doctype/i.test(trimmed) || /<html[\\s>]/i.test(trimmed);\n\n\tif (looksLikeDocument) return trimmed;\n\n\treturn `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n </head>\n <body>\n${trimmed}\n </body>\n</html>`;\n}\n\nfunction injectArtifactsSnapshotRuntime(\n\thtmlContent: string,\n\tartifacts: Map<string, string>,\n): string {\n\tconst snapshot: Record<string, string> = {};\n\tfor (const [name, content] of artifacts) {\n\t\tsnapshot[name] = content;\n\t}\n\n\tconst runtime = `\n<script>\n(function() {\n try {\n window.artifacts = ${escapeScriptContent(JSON.stringify(snapshot))};\n } catch (err) {\n console.error(\"[Maestro] Failed to initialize artifacts snapshot:\", err);\n window.artifacts = {};\n }\n\n const isJson = (f) => (f || \"\").toLowerCase().endsWith(\".json\");\n\n window.listArtifacts = async () => Object.keys(window.artifacts || {});\n\n window.getArtifact = async (filename) => {\n const content = (window.artifacts || {})[filename];\n if (typeof content !== \"string\") throw new Error(\"Artifact not found: \" + filename);\n if (isJson(filename)) {\n try { return JSON.parse(content); } catch (e) { throw new Error(\"Failed to parse JSON: \" + e); }\n }\n return content;\n };\n})();\n</script>\n`.trim();\n\n\tconst html = wrapHtmlDocument(htmlContent);\n\tif (/<\\/body>/i.test(html)) {\n\t\treturn html.replace(/<\\/body>/i, `\\n${runtime}\\n</body>`);\n\t}\n\treturn `${html}\\n${runtime}`;\n}\n\ntype ArtifactsCommand =\n\t| \"create\"\n\t| \"update\"\n\t| \"rewrite\"\n\t| \"get\"\n\t| \"delete\"\n\t| \"logs\";\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction reconstructArtifactsFromMessages(\n\tmessages: ComposerMessage[],\n): Map<string, string> {\n\tconst byFilename = new Map<string, string>();\n\n\tfor (const msg of messages) {\n\t\tconst tools = msg.tools ?? [];\n\t\tfor (const tool of tools) {\n\t\t\tif (tool.name !== \"artifacts\") continue;\n\t\t\tif (tool.status !== \"completed\") continue;\n\t\t\tif (tool.result && typeof tool.result === \"object\") {\n\t\t\t\tconst maybeErr = tool.result as { isError?: boolean };\n\t\t\t\tif (maybeErr.isError) continue;\n\t\t\t}\n\n\t\t\tconst args = (\n\t\t\t\ttool.args && typeof tool.args === \"object\"\n\t\t\t\t\t? (tool.args as Record<string, unknown>)\n\t\t\t\t\t: {}\n\t\t\t) as Record<string, unknown>;\n\n\t\t\tconst command = asString(args.command) as ArtifactsCommand | undefined;\n\t\t\tconst filename = asString(args.filename)?.trim();\n\n\t\t\tif (!command || !filename) continue;\n\t\t\tif (command === \"get\" || command === \"logs\") continue;\n\n\t\t\tif (command === \"create\") {\n\t\t\t\tif (byFilename.has(filename)) continue;\n\t\t\t\tbyFilename.set(filename, asString(args.content) ?? \"\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (command === \"rewrite\") {\n\t\t\t\tif (!byFilename.has(filename)) continue;\n\t\t\t\tbyFilename.set(filename, asString(args.content) ?? \"\");\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (command === \"update\") {\n\t\t\t\tconst current = byFilename.get(filename);\n\t\t\t\tif (current === undefined) continue;\n\t\t\t\tconst oldStr = asString(args.old_str);\n\t\t\t\tconst newStr = asString(args.new_str);\n\t\t\t\tif (oldStr === undefined || newStr === undefined) continue;\n\t\t\t\tif (!current.includes(oldStr)) continue;\n\t\t\t\tbyFilename.set(filename, current.replace(oldStr, newStr));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (command === \"delete\") {\n\t\t\t\tbyFilename.delete(filename);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn byFilename;\n}\n\nasync function loadComposerMessages(\n\treq: IncomingMessage,\n\tsessionId: string,\n): Promise<ComposerMessage[]> {\n\tconst sessionManager = createWebSessionManagerForRequest(req, true);\n\tconst session = await sessionManager.loadSession(sessionId);\n\tif (!session) {\n\t\tthrow new ApiError(404, \"Session not found\");\n\t}\n\treturn convertAppMessagesToComposer(session.messages || []);\n}\n\nfunction validateFilename(filename: string): void {\n\t// Keep this strict: no path traversal, no folder hierarchies.\n\tif (\n\t\tfilename.includes(\"..\") ||\n\t\tfilename.includes(\"/\") ||\n\t\tfilename.includes(\"\\\\\")\n\t) {\n\t\tthrow new ApiError(400, \"Invalid filename\");\n\t}\n}\n\nfunction buildSessionArtifactFileUrl(\n\tsessionId: string,\n\tfilename: string,\n\toptions?: {\n\t\tdownload?: boolean;\n\t\traw?: boolean;\n\t\tstandalone?: boolean;\n\t},\n): string {\n\tconst path = `/api/sessions/${encodeURIComponent(sessionId)}/artifacts/${encodeURIComponent(filename)}`;\n\tconst url = new URL(path, \"http://localhost\");\n\tif (options?.download) url.searchParams.set(\"download\", \"1\");\n\tif (options?.raw) url.searchParams.set(\"raw\", \"1\");\n\tif (options?.standalone) url.searchParams.set(\"standalone\", \"1\");\n\treturn `${url.pathname}${url.search}`;\n}\n\nfunction buildSessionArtifactViewerUrl(\n\tsessionId: string,\n\tfilename: string,\n): string {\n\treturn `/api/sessions/${encodeURIComponent(sessionId)}/artifacts/${encodeURIComponent(filename)}/view`;\n}\n\nfunction buildSessionArtifactsEventsUrl(\n\tsessionId: string,\n\tfilename: string,\n): string {\n\tconst url = new URL(\n\t\t`/api/sessions/${encodeURIComponent(sessionId)}/artifacts/events`,\n\t\t\"http://localhost\",\n\t);\n\turl.searchParams.set(\"filename\", filename);\n\treturn `${url.pathname}${url.search}`;\n}\n\nfunction buildSessionArtifactsZipUrl(sessionId: string): string {\n\treturn `/api/sessions/${encodeURIComponent(sessionId)}/artifacts.zip`;\n}\n\nfunction resolveArtifactAccessContext(req: IncomingMessage): {\n\taccessToken: string | null;\n\tgrant: ReturnType<typeof getArtifactAccessGrantFromRequest>;\n} {\n\tconst grant = getArtifactAccessGrantFromRequest(req);\n\treturn {\n\t\taccessToken: grant ? getArtifactAccessTokenFromRequest(req) : null,\n\t\tgrant,\n\t};\n}\n\nfunction canUseArtifactAccess(\n\tgrant: ReturnType<typeof getArtifactAccessGrantFromRequest>,\n\taction: ArtifactAccessAction,\n): boolean {\n\treturn Boolean(grant?.actions.includes(action));\n}\n\nexport async function handleSessionArtifactsIndex(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tsendJson(\n\t\t\tres,\n\t\t\t200,\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tfilenames: Array.from(artifacts.keys()).sort((a, b) =>\n\t\t\t\t\ta.localeCompare(b),\n\t\t\t\t),\n\t\t\t},\n\t\t\tcors,\n\t\t\treq,\n\t\t);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactAccess(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst filename = url.searchParams.get(\"filename\")?.trim() || undefined;\n\t\tconst actions = Array.from(\n\t\t\tnew Set(\n\t\t\t\t(url.searchParams.get(\"actions\") || \"\")\n\t\t\t\t\t.split(\",\")\n\t\t\t\t\t.map((action) => action.trim())\n\t\t\t\t\t.filter(Boolean),\n\t\t\t),\n\t\t).filter((action): action is ArtifactAccessAction => {\n\t\t\treturn [\"view\", \"file\", \"events\", \"zip\"].includes(action);\n\t\t});\n\n\t\tif (actions.length === 0) {\n\t\t\tsendJson(\n\t\t\t\tres,\n\t\t\t\t400,\n\t\t\t\t{ error: \"At least one artifact access action is required\" },\n\t\t\t\tcors,\n\t\t\t\treq,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (filename) {\n\t\t\tvalidateFilename(filename);\n\t\t}\n\n\t\tif (!filename && actions.some((action) => action !== \"zip\")) {\n\t\t\tsendJson(\n\t\t\t\tres,\n\t\t\t\t400,\n\t\t\t\t{ error: \"filename is required for artifact file access\" },\n\t\t\t\tcors,\n\t\t\t\treq,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\n\t\tif (filename && !artifacts.has(filename)) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst access = issueArtifactAccessGrant({\n\t\t\tsessionId,\n\t\t\tscope: resolveSessionScope(req),\n\t\t\tfilename,\n\t\t\tactions,\n\t\t});\n\n\t\tsendJson(\n\t\t\tres,\n\t\t\t200,\n\t\t\t{\n\t\t\t\ttoken: access.token,\n\t\t\t\texpiresAt: access.expiresAtIso,\n\t\t\t\tactions: access.actions,\n\t\t\t\tsessionId,\n\t\t\t\t...(filename ? { filename } : {}),\n\t\t\t},\n\t\t\tcors,\n\t\t\treq,\n\t\t);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactFile(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string; filename: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\tconst filename = decodeURIComponent(params.filename || \"\");\n\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\t\tvalidateFilename(filename);\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tconst content = artifacts.get(filename);\n\t\tif (content === undefined) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst wantsDownload = url.searchParams.get(\"download\") === \"1\";\n\t\tconst wantsRaw = url.searchParams.get(\"raw\") === \"1\";\n\t\tconst wantsStandalone = url.searchParams.get(\"standalone\") === \"1\";\n\n\t\tconst mime = lookupMimeType(filename) || \"text/plain; charset=utf-8\";\n\t\tconst isHtml = String(mime).startsWith(\"text/html\");\n\t\tconst { accessToken, grant } = resolveArtifactAccessContext(req);\n\n\t\tconst eventsUrl = canUseArtifactAccess(grant, \"events\")\n\t\t\t? buildSessionArtifactsEventsUrl(sessionId, filename)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsEventsUrl(sessionId, filename);\n\n\t\tlet body =\n\t\t\tisHtml && !wantsRaw && eventsUrl\n\t\t\t\t? injectLiveReloadWithAuth(content, eventsUrl, accessToken)\n\t\t\t\t: content;\n\n\t\t// Standalone download: force attachment and embed artifacts snapshot + helpers.\n\t\tif (isHtml && wantsStandalone) {\n\t\t\tbody = injectArtifactsSnapshotRuntime(body, artifacts);\n\t\t}\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": String(mime),\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...(wantsDownload || wantsStandalone\n\t\t\t\t? {\n\t\t\t\t\t\t\"Content-Disposition\": buildContentDisposition(filename),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...cors,\n\t\t});\n\t\tres.end(body);\n\t} catch (err) {\n\t\tlogger.warn(\"Failed to serve artifact\", {\n\t\t\terr: err instanceof Error ? err.message : String(err),\n\t\t\tsessionId,\n\t\t\tfilename,\n\t\t});\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactViewer(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string; filename: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\tconst filename = decodeURIComponent(params.filename || \"\");\n\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\t\tvalidateFilename(filename);\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tconst content = artifacts.get(filename);\n\t\tif (content === undefined) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst mime = lookupMimeType(filename) || \"text/plain; charset=utf-8\";\n\t\tconst isHtml = String(mime).startsWith(\"text/html\");\n\t\tconst { accessToken, grant } = resolveArtifactAccessContext(req);\n\n\t\tconst title = `Maestro Artifact · ${filename}`;\n\t\tconst viewerUrl = buildSessionArtifactViewerUrl(sessionId, filename);\n\n\t\tconst eventsUrl = canUseArtifactAccess(grant, \"events\")\n\t\t\t? buildSessionArtifactsEventsUrl(sessionId, filename)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsEventsUrl(sessionId, filename);\n\t\tconst zipUrl = canUseArtifactAccess(grant, \"zip\")\n\t\t\t? buildSessionArtifactsZipUrl(sessionId)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsZipUrl(sessionId);\n\t\tconst rawDownloadUrl = canUseArtifactAccess(grant, \"file\")\n\t\t\t? buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\tdownload: true,\n\t\t\t\t\traw: true,\n\t\t\t\t})\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\traw: true,\n\t\t\t\t\t});\n\t\tconst standaloneDownloadUrl = isHtml\n\t\t\t? canUseArtifactAccess(grant, \"file\")\n\t\t\t\t? buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\tstandalone: true,\n\t\t\t\t\t})\n\t\t\t\t: accessToken\n\t\t\t\t\t? null\n\t\t\t\t\t: buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\t\tstandalone: true,\n\t\t\t\t\t\t})\n\t\t\t: null;\n\n\t\tconst zipAction = zipUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-zip\" class=\"hint-button\" type=\"button\">Download ZIP</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${zipUrl}\" target=\"_blank\" rel=\"noopener\">Download ZIP</a>`\n\t\t\t: \"\";\n\t\tconst rawDownloadAction = rawDownloadUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-raw\" class=\"hint-button\" type=\"button\">Download Raw</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${rawDownloadUrl}\" target=\"_blank\" rel=\"noopener\">Download Raw</a>`\n\t\t\t: \"\";\n\t\tconst standaloneDownloadAction = standaloneDownloadUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-standalone\" class=\"hint-button\" type=\"button\">Download Standalone</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${standaloneDownloadUrl}\" target=\"_blank\" rel=\"noopener\">Download Standalone</a>`\n\t\t\t: \"\";\n\t\tconst zipDownloadName = `${sessionId}-artifacts.zip`;\n\n\t\tconst srcdoc = isHtml\n\t\t\t? injectArtifactsSnapshotRuntime(content, artifacts)\n\t\t\t: wrapHtmlDocument(\n\t\t\t\t\t`<pre style=\"white-space:pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 13px; line-height: 1.4; padding: 16px; margin: 0;\">${content\n\t\t\t\t\t\t.replace(/&/g, \"&\")\n\t\t\t\t\t\t.replace(/</g, \"<\")\n\t\t\t\t\t\t.replace(/>/g, \">\")}</pre>`,\n\t\t\t\t);\n\n\t\tconst openExternalHandler = `\n<script>\nwindow.addEventListener(\"message\", (e) => {\n if (!e || !e.data) return;\n if (e.data.type !== \"open-external-url\") return;\n const url = e.data.url;\n if (typeof url !== \"string\") return;\n let parsed;\n try { parsed = new URL(url); } catch { return; }\n if (!parsed || (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\")) return;\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n});\n</script>\n`.trim();\n\n\t\tconst viewerHtml = `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${title.replace(/</g, \"<\").replace(/>/g, \">\")}</title>\n <style>\n html, body { height: 100%; margin: 0; background: #0b0c0f; color: #e6edf3; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; }\n .bar { display:flex; align-items:center; gap:12px; padding:10px 12px; border-bottom: 1px solid #1e2023; background: #08090a; position: sticky; top: 0; z-index: 1; }\n .title { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 12px; color: #9da3af; }\n .spacer { flex: 1; }\n a, button { font: inherit; }\n button { background: transparent; border: 1px solid #30363d; color: #c9d1d9; padding: 6px 10px; cursor: pointer; }\n button:hover { border-color: #58a6ff; color: #58a6ff; }\n iframe { width: 100%; height: calc(100% - 52px); border: 0; display:block; background: #fff; }\n .hint { font-size: 12px; color: #7d8590; }\n .hint-button { padding: 0; border: 0; color: #7d8590; font-size: 12px; }\n </style>\n </head>\n <body>\n <div class=\"bar\">\n <div class=\"title\">${title.replace(/</g, \"<\").replace(/>/g, \">\")}</div>\n <div class=\"spacer\"></div>\n ${zipAction}\n ${rawDownloadAction}\n ${standaloneDownloadAction}\n <button id=\"reload\">Reload</button>\n </div>\n ${openExternalHandler}\n <iframe id=\"frame\" sandbox=\"allow-scripts allow-modals allow-downloads\"></iframe>\n <script>\n const frame = document.getElementById(\"frame\");\n const reloadBtn = document.getElementById(\"reload\");\n const viewerUrl = ${JSON.stringify(viewerUrl)};\n const eventsUrl = ${JSON.stringify(eventsUrl)};\n const zipUrl = ${JSON.stringify(zipUrl)};\n const rawDownloadUrl = ${JSON.stringify(rawDownloadUrl)};\n const standaloneDownloadUrl = ${JSON.stringify(standaloneDownloadUrl)};\n const artifactAccessToken = ${JSON.stringify(accessToken)};\n const artifactAccessHeaders = artifactAccessToken\n ? { ${JSON.stringify(ARTIFACT_ACCESS_HEADER)}: artifactAccessToken }\n : undefined;\n\n const setDoc = (html) => {\n frame.srcdoc = html;\n };\n\n const parseDownloadFilename = (response, fallbackName) => {\n const contentDisposition = response.headers.get(\"content-disposition\") || \"\";\n const utf8Match = contentDisposition.match(/filename\\*=UTF-8''([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n const quotedMatch = contentDisposition.match(/filename=\"([^\"]+)\"/i);\n if (quotedMatch?.[1]) {\n return quotedMatch[1];\n }\n const bareMatch = contentDisposition.match(/filename=([^;]+)/i);\n return bareMatch?.[1]?.trim() || fallbackName || \"\";\n };\n\n const fetchViewerResource = async (url) => {\n const response = await fetch(url, {\n cache: \"no-store\",\n ...(artifactAccessHeaders ? { headers: artifactAccessHeaders } : {}),\n });\n if (!response.ok) {\n\t\t throw new Error(\"Request failed (\" + response.status + \")\");\n }\n return response;\n };\n\n const downloadViewerResource = async (url, fallbackName) => {\n const response = await fetchViewerResource(url);\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = objectUrl;\n const downloadName = parseDownloadFilename(response, fallbackName);\n if (downloadName) {\n link.download = downloadName;\n }\n link.rel = \"noopener\";\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n };\n\n const refreshViewer = async () => {\n if (!artifactAccessHeaders) {\n location.reload();\n return;\n }\n const response = await fetchViewerResource(viewerUrl);\n const nextHtml = await response.text();\n const nextUrl = URL.createObjectURL(\n new Blob([nextHtml], { type: \"text/html\" }),\n );\n setTimeout(() => URL.revokeObjectURL(nextUrl), 60_000);\n location.replace(nextUrl);\n };\n\n const triggerRefresh = () => {\n void refreshViewer().catch((err) => {\n console.error(\"[Maestro] Failed to refresh viewer:\", err);\n });\n };\n\n const bindDownloadButton = (id, url, fallbackName) => {\n const button = document.getElementById(id);\n if (!button || !url || !artifactAccessHeaders) {\n return;\n }\n button.addEventListener(\"click\", () => {\n void downloadViewerResource(url, fallbackName).catch((err) => {\n console.error(\"[Maestro] Failed to download artifact:\", err);\n });\n });\n };\n\n const srcdoc = ${JSON.stringify(srcdoc)};\n setDoc(srcdoc);\n\n\t\t\t\tbindDownloadButton(\"download-zip\", zipUrl, ${JSON.stringify(zipDownloadName)});\n bindDownloadButton(\"download-raw\", rawDownloadUrl, ${JSON.stringify(filename)});\n bindDownloadButton(\"download-standalone\", standaloneDownloadUrl, ${JSON.stringify(filename)});\n\n reloadBtn.addEventListener(\"click\", () => triggerRefresh());\n\n ${\n\t\t\t\teventsUrl\n\t\t\t\t\t? `try {\n\t\tconst reload = () => triggerRefresh();\n const connect = ${\n\t\t\t\t\taccessToken\n\t\t\t\t\t\t? `async () => {\n\t\t const response = await fetchViewerResource(eventsUrl);\n if (!response.body) throw new Error(\"Missing response body\");\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let boundary = buffer.indexOf(\"\\\\n\\\\n\");\n while (boundary !== -1) {\n const chunk = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n const dataLine = chunk\n .split(\"\\\\n\")\n .find((line) => line.startsWith(\"data:\"));\n if (dataLine) {\n reload();\n return;\n }\n boundary = buffer.indexOf(\"\\\\n\\\\n\");\n }\n }\n }`\n\t\t\t\t\t\t: `() => {\n const es = new EventSource(${JSON.stringify(eventsUrl)});\n es.onmessage = () => reload();\n }`\n\t\t\t\t};\n Promise.resolve(connect()).catch((err) => {\n console.error(\"[Maestro] Failed to setup viewer live reload transport:\", err);\n });\n } catch (err) { console.error(\"[Maestro] Failed to setup viewer EventSource:\", err); }`\n\t\t\t\t\t: \"\"\n\t\t\t}\n </script>\n </body>\n</html>`;\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"text/html; charset=utf-8\",\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...cors,\n\t\t});\n\t\tres.end(viewerHtml);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactsEvents(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst filenameFilter = url.searchParams.get(\"filename\");\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\tConnection: \"keep-alive\",\n\t\t\t...cors,\n\t\t});\n\n\t\tlet closed = false;\n\t\tconst canWrite = () =>\n\t\t\tres.writable !== false && !res.writableEnded && !res.destroyed;\n\t\tconst safeWrite = (payload: string) => {\n\t\t\tif (!canWrite()) return false;\n\t\t\ttry {\n\t\t\t\tres.write(payload);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\tlet heartbeat: ReturnType<typeof setInterval> | null = null;\n\t\tlet unsubscribe: () => void = () => {};\n\n\t\tconst cleanup = () => {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (heartbeat) {\n\t\t\t\tclearInterval(heartbeat);\n\t\t\t\theartbeat = null;\n\t\t\t}\n\t\t\tunsubscribe();\n\t\t\treq.off(\"close\", cleanup);\n\t\t\tres.off(\"close\", cleanup);\n\t\t};\n\n\t\tunsubscribe = subscribeArtifactUpdates(sessionId, (event) => {\n\t\t\tif (filenameFilter && event.filename !== filenameFilter) return;\n\t\t\tif (!safeWrite(`data: ${JSON.stringify(event)}\\n\\n`)) {\n\t\t\t\tcleanup();\n\t\t\t}\n\t\t});\n\n\t\theartbeat = setInterval(() => {\n\t\t\tif (!safeWrite(\": ping\\n\\n\")) {\n\t\t\t\tcleanup();\n\t\t\t}\n\t\t}, 15_000);\n\n\t\tif (heartbeat.unref) {\n\t\t\theartbeat.unref();\n\t\t}\n\n\t\tif (!safeWrite(\": ok\\n\\n\")) {\n\t\t\tcleanup();\n\t\t\treturn;\n\t\t}\n\n\t\treq.on(\"close\", cleanup);\n\t\tres.on(\"close\", cleanup);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactsZip(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\n\t\t// Lazy import to keep startup cost low.\n\t\tconst { strToU8, zipSync } = await import(\"fflate\");\n\n\t\tconst entries: Record<string, Uint8Array> = {};\n\t\tfor (const [filename, content] of artifacts) {\n\t\t\tentries[filename] = strToU8(content);\n\t\t}\n\n\t\tconst zipBytes = zipSync(entries, { level: 6 });\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"application/zip\",\n\t\t\t\"Content-Disposition\": buildContentDisposition(\n\t\t\t\t`artifacts-${sessionId}.zip`,\n\t\t\t),\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...cors,\n\t\t});\n\t\tres.end(Buffer.from(zipBytes));\n\t} catch (err) {\n\t\tlogger.warn(\"Failed to export artifacts zip\", {\n\t\t\terr: err instanceof Error ? err.message : String(err),\n\t\t\tsessionId,\n\t\t});\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-artifacts.js","sourceRoot":"","sources":["../../../src/server/handlers/session-artifacts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport {\n\ttype ComposerMessage,\n\tartifactContentsByFilename,\n\tisValidArtifactFilename,\n\treconstructArtifactsFromMessages as reconstructArtifactStateFromMessages,\n} from \"@evalops/contracts\";\nimport { lookup as lookupMimeType } from \"mime-types\";\nimport { createLogger } from \"../../utils/logger.js\";\nimport {\n\tARTIFACT_ACCESS_HEADER,\n\ttype ArtifactAccessAction,\n\tgetArtifactAccessGrantFromRequest,\n\tgetArtifactAccessTokenFromRequest,\n\tissueArtifactAccessGrant,\n} from \"../artifact-access.js\";\nimport { subscribeArtifactUpdates } from \"../artifacts-live-reload.js\";\nimport {\n\tApiError,\n\tbuildContentDisposition,\n\tsendJson,\n} from \"../server-utils.js\";\nimport {\n\tcreateWebSessionManagerForRequest,\n\tresolveSessionScope,\n} from \"../session-scope.js\";\nimport { convertAppMessagesToComposer } from \"../session-serialization.js\";\n\nconst logger = createLogger(\"session-artifacts\");\nconst sessionIdPattern = /^[a-zA-Z0-9._-]+$/;\n\nfunction escapeScriptContent(code: string): string {\n\treturn code.replace(/<\\/script/gi, \"<\\\\/script\");\n}\n\nfunction injectLiveReload(html: string, eventsUrl: string): string {\n\treturn injectLiveReloadWithAuth(html, eventsUrl);\n}\n\nfunction injectLiveReloadWithAuth(\n\thtml: string,\n\teventsUrl: string,\n\taccessToken?: string | null,\n): string {\n\tconst authHeaders = accessToken\n\t\t? `{ ${JSON.stringify(ARTIFACT_ACCESS_HEADER)}: ${JSON.stringify(accessToken)} }`\n\t\t: \"undefined\";\n\tconst scriptBody = `\n\t(function() {\n\t try {\n\t const reload = () => location.reload();\n\t const connect = ${\n\t\t\t\taccessToken\n\t\t\t\t\t? `async () => {\n\t const response = await fetch(${JSON.stringify(eventsUrl)}, {\n\t headers: ${authHeaders},\n\t cache: \"no-store\",\n\t });\n\t if (!response.body) throw new Error(\"Missing response body\");\n\t const reader = response.body.getReader();\n\t const decoder = new TextDecoder();\n\t let buffer = \"\";\n\t while (true) {\n\t const { done, value } = await reader.read();\n\t if (done) break;\n\t buffer += decoder.decode(value, { stream: true });\n\t let boundary = buffer.indexOf(\"\\\\n\\\\n\");\n\t while (boundary !== -1) {\n\t const chunk = buffer.slice(0, boundary);\n\t buffer = buffer.slice(boundary + 2);\n\t const dataLine = chunk\n\t .split(\"\\\\n\")\n\t .find((line) => line.startsWith(\"data:\"));\n\t if (dataLine) {\n\t reload();\n\t return;\n\t }\n\t boundary = buffer.indexOf(\"\\\\n\\\\n\");\n\t }\n\t }\n\t }`\n\t\t\t\t\t: `() => {\n\t const es = new EventSource(${JSON.stringify(eventsUrl)});\n\t es.onmessage = (e) => {\n\t try {\n\t const data = JSON.parse(e.data);\n\t if (data && data.type === \"artifact_updated\") {\n\t reload();\n\t }\n\t } catch (err) { console.error(\"[Maestro] Failed to parse live reload event:\", err); }\n\t };\n\t }`\n\t\t\t};\n\t Promise.resolve(connect()).catch((err) => {\n\t console.error(\"[Maestro] Failed to setup live reload transport:\", err);\n\t });\n\t } catch (err) { console.error(\"[Maestro] Failed to setup live reload EventSource:\", err); }\n\t})();\n\t`.trim();\n\tconst script = `<script>\\n${escapeScriptContent(scriptBody)}\\n</script>`;\n\tconst injected = `\\n${script}\\n`;\n\tif (/<\\/body>/i.test(html)) {\n\t\treturn html.replace(/<\\/body>/i, `${injected}</body>`);\n\t}\n\treturn `${html}${injected}`;\n}\n\nfunction wrapHtmlDocument(htmlContent: string): string {\n\tconst trimmed = htmlContent.trim();\n\tconst looksLikeDocument =\n\t\t/^<!doctype/i.test(trimmed) || /<html[\\s>]/i.test(trimmed);\n\n\tif (looksLikeDocument) return trimmed;\n\n\treturn `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n </head>\n <body>\n${trimmed}\n </body>\n</html>`;\n}\n\nfunction injectArtifactsSnapshotRuntime(\n\thtmlContent: string,\n\tartifacts: Map<string, string>,\n): string {\n\tconst snapshot: Record<string, string> = {};\n\tfor (const [name, content] of artifacts) {\n\t\tsnapshot[name] = content;\n\t}\n\n\tconst runtime = `\n<script>\n(function() {\n try {\n window.artifacts = ${escapeScriptContent(JSON.stringify(snapshot))};\n } catch (err) {\n console.error(\"[Maestro] Failed to initialize artifacts snapshot:\", err);\n window.artifacts = {};\n }\n\n const isJson = (f) => (f || \"\").toLowerCase().endsWith(\".json\");\n\n window.listArtifacts = async () => Object.keys(window.artifacts || {});\n\n window.getArtifact = async (filename) => {\n const content = (window.artifacts || {})[filename];\n if (typeof content !== \"string\") throw new Error(\"Artifact not found: \" + filename);\n if (isJson(filename)) {\n try { return JSON.parse(content); } catch (e) { throw new Error(\"Failed to parse JSON: \" + e); }\n }\n return content;\n };\n})();\n</script>\n`.trim();\n\n\tconst html = wrapHtmlDocument(htmlContent);\n\tif (/<\\/body>/i.test(html)) {\n\t\treturn html.replace(/<\\/body>/i, `\\n${runtime}\\n</body>`);\n\t}\n\treturn `${html}\\n${runtime}`;\n}\n\nfunction reconstructArtifactsFromMessages(\n\tmessages: ComposerMessage[],\n): Map<string, string> {\n\tconst diagnostics: string[] = [];\n\tconst state = reconstructArtifactStateFromMessages(messages, {\n\t\tonDiagnostic: (diagnostic) => {\n\t\t\tdiagnostics.push(diagnostic.code);\n\t\t},\n\t});\n\tif (diagnostics.length > 0) {\n\t\tlogger.warn(\"Skipped invalid persisted artifact commands\", {\n\t\t\tcount: diagnostics.length,\n\t\t\tcodes: diagnostics,\n\t\t});\n\t}\n\treturn artifactContentsByFilename(state);\n}\n\nasync function loadComposerMessages(\n\treq: IncomingMessage,\n\tsessionId: string,\n): Promise<ComposerMessage[]> {\n\tconst sessionManager = createWebSessionManagerForRequest(req, true);\n\tconst session = await sessionManager.loadSession(sessionId);\n\tif (!session) {\n\t\tthrow new ApiError(404, \"Session not found\");\n\t}\n\treturn convertAppMessagesToComposer(session.messages || []);\n}\n\nfunction validateFilename(filename: string): void {\n\t// Keep this strict: no path traversal, no folder hierarchies.\n\tif (!isValidArtifactFilename(filename.trim())) {\n\t\tthrow new ApiError(400, \"Invalid filename\");\n\t}\n}\n\nfunction buildSessionArtifactFileUrl(\n\tsessionId: string,\n\tfilename: string,\n\toptions?: {\n\t\tdownload?: boolean;\n\t\traw?: boolean;\n\t\tstandalone?: boolean;\n\t},\n): string {\n\tconst path = `/api/sessions/${encodeURIComponent(sessionId)}/artifacts/${encodeURIComponent(filename)}`;\n\tconst url = new URL(path, \"http://localhost\");\n\tif (options?.download) url.searchParams.set(\"download\", \"1\");\n\tif (options?.raw) url.searchParams.set(\"raw\", \"1\");\n\tif (options?.standalone) url.searchParams.set(\"standalone\", \"1\");\n\treturn `${url.pathname}${url.search}`;\n}\n\nfunction buildSessionArtifactViewerUrl(\n\tsessionId: string,\n\tfilename: string,\n): string {\n\treturn `/api/sessions/${encodeURIComponent(sessionId)}/artifacts/${encodeURIComponent(filename)}/view`;\n}\n\nfunction buildSessionArtifactsEventsUrl(\n\tsessionId: string,\n\tfilename: string,\n): string {\n\tconst url = new URL(\n\t\t`/api/sessions/${encodeURIComponent(sessionId)}/artifacts/events`,\n\t\t\"http://localhost\",\n\t);\n\turl.searchParams.set(\"filename\", filename);\n\treturn `${url.pathname}${url.search}`;\n}\n\nfunction buildSessionArtifactsZipUrl(sessionId: string): string {\n\treturn `/api/sessions/${encodeURIComponent(sessionId)}/artifacts.zip`;\n}\n\nfunction resolveArtifactAccessContext(req: IncomingMessage): {\n\taccessToken: string | null;\n\tgrant: ReturnType<typeof getArtifactAccessGrantFromRequest>;\n} {\n\tconst grant = getArtifactAccessGrantFromRequest(req);\n\treturn {\n\t\taccessToken: grant ? getArtifactAccessTokenFromRequest(req) : null,\n\t\tgrant,\n\t};\n}\n\nfunction canUseArtifactAccess(\n\tgrant: ReturnType<typeof getArtifactAccessGrantFromRequest>,\n\taction: ArtifactAccessAction,\n): boolean {\n\treturn Boolean(grant?.actions.includes(action));\n}\n\nexport async function handleSessionArtifactsIndex(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tsendJson(\n\t\t\tres,\n\t\t\t200,\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tfilenames: Array.from(artifacts.keys()).sort((a, b) =>\n\t\t\t\t\ta.localeCompare(b),\n\t\t\t\t),\n\t\t\t},\n\t\t\tcors,\n\t\t\treq,\n\t\t);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactAccess(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst filename = url.searchParams.get(\"filename\")?.trim() || undefined;\n\t\tconst actions = Array.from(\n\t\t\tnew Set(\n\t\t\t\t(url.searchParams.get(\"actions\") || \"\")\n\t\t\t\t\t.split(\",\")\n\t\t\t\t\t.map((action) => action.trim())\n\t\t\t\t\t.filter(Boolean),\n\t\t\t),\n\t\t).filter((action): action is ArtifactAccessAction => {\n\t\t\treturn [\"view\", \"file\", \"events\", \"zip\"].includes(action);\n\t\t});\n\n\t\tif (actions.length === 0) {\n\t\t\tsendJson(\n\t\t\t\tres,\n\t\t\t\t400,\n\t\t\t\t{ error: \"At least one artifact access action is required\" },\n\t\t\t\tcors,\n\t\t\t\treq,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (filename) {\n\t\t\tvalidateFilename(filename);\n\t\t}\n\n\t\tif (!filename && actions.some((action) => action !== \"zip\")) {\n\t\t\tsendJson(\n\t\t\t\tres,\n\t\t\t\t400,\n\t\t\t\t{ error: \"filename is required for artifact file access\" },\n\t\t\t\tcors,\n\t\t\t\treq,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\n\t\tif (filename && !artifacts.has(filename)) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst access = issueArtifactAccessGrant({\n\t\t\tsessionId,\n\t\t\tscope: resolveSessionScope(req),\n\t\t\tfilename,\n\t\t\tactions,\n\t\t});\n\n\t\tsendJson(\n\t\t\tres,\n\t\t\t200,\n\t\t\t{\n\t\t\t\ttoken: access.token,\n\t\t\t\texpiresAt: access.expiresAtIso,\n\t\t\t\tactions: access.actions,\n\t\t\t\tsessionId,\n\t\t\t\t...(filename ? { filename } : {}),\n\t\t\t},\n\t\t\tcors,\n\t\t\treq,\n\t\t);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactFile(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string; filename: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\tconst filename = decodeURIComponent(params.filename || \"\");\n\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\t\tvalidateFilename(filename);\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tconst content = artifacts.get(filename);\n\t\tif (content === undefined) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst wantsDownload = url.searchParams.get(\"download\") === \"1\";\n\t\tconst wantsRaw = url.searchParams.get(\"raw\") === \"1\";\n\t\tconst wantsStandalone = url.searchParams.get(\"standalone\") === \"1\";\n\n\t\tconst mime = lookupMimeType(filename) || \"text/plain; charset=utf-8\";\n\t\tconst isHtml = String(mime).startsWith(\"text/html\");\n\t\tconst { accessToken, grant } = resolveArtifactAccessContext(req);\n\n\t\tconst eventsUrl = canUseArtifactAccess(grant, \"events\")\n\t\t\t? buildSessionArtifactsEventsUrl(sessionId, filename)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsEventsUrl(sessionId, filename);\n\n\t\tlet body =\n\t\t\tisHtml && !wantsRaw && eventsUrl\n\t\t\t\t? injectLiveReloadWithAuth(content, eventsUrl, accessToken)\n\t\t\t\t: content;\n\n\t\t// Standalone download: force attachment and embed artifacts snapshot + helpers.\n\t\tif (isHtml && wantsStandalone) {\n\t\t\tbody = injectArtifactsSnapshotRuntime(body, artifacts);\n\t\t}\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": String(mime),\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...(wantsDownload || wantsStandalone\n\t\t\t\t? {\n\t\t\t\t\t\t\"Content-Disposition\": buildContentDisposition(filename),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...cors,\n\t\t});\n\t\tres.end(body);\n\t} catch (err) {\n\t\tlogger.warn(\"Failed to serve artifact\", {\n\t\t\terr: err instanceof Error ? err.message : String(err),\n\t\t\tsessionId,\n\t\t\tfilename,\n\t\t});\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactViewer(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string; filename: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\tconst filename = decodeURIComponent(params.filename || \"\");\n\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\t\tvalidateFilename(filename);\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\t\tconst content = artifacts.get(filename);\n\t\tif (content === undefined) {\n\t\t\tsendJson(res, 404, { error: \"Artifact not found\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst mime = lookupMimeType(filename) || \"text/plain; charset=utf-8\";\n\t\tconst isHtml = String(mime).startsWith(\"text/html\");\n\t\tconst { accessToken, grant } = resolveArtifactAccessContext(req);\n\n\t\tconst title = `Maestro Artifact · ${filename}`;\n\t\tconst viewerUrl = buildSessionArtifactViewerUrl(sessionId, filename);\n\n\t\tconst eventsUrl = canUseArtifactAccess(grant, \"events\")\n\t\t\t? buildSessionArtifactsEventsUrl(sessionId, filename)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsEventsUrl(sessionId, filename);\n\t\tconst zipUrl = canUseArtifactAccess(grant, \"zip\")\n\t\t\t? buildSessionArtifactsZipUrl(sessionId)\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactsZipUrl(sessionId);\n\t\tconst rawDownloadUrl = canUseArtifactAccess(grant, \"file\")\n\t\t\t? buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\tdownload: true,\n\t\t\t\t\traw: true,\n\t\t\t\t})\n\t\t\t: accessToken\n\t\t\t\t? null\n\t\t\t\t: buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\traw: true,\n\t\t\t\t\t});\n\t\tconst standaloneDownloadUrl = isHtml\n\t\t\t? canUseArtifactAccess(grant, \"file\")\n\t\t\t\t? buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\tstandalone: true,\n\t\t\t\t\t})\n\t\t\t\t: accessToken\n\t\t\t\t\t? null\n\t\t\t\t\t: buildSessionArtifactFileUrl(sessionId, filename, {\n\t\t\t\t\t\t\tdownload: true,\n\t\t\t\t\t\t\tstandalone: true,\n\t\t\t\t\t\t})\n\t\t\t: null;\n\n\t\tconst zipAction = zipUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-zip\" class=\"hint-button\" type=\"button\">Download ZIP</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${zipUrl}\" target=\"_blank\" rel=\"noopener\">Download ZIP</a>`\n\t\t\t: \"\";\n\t\tconst rawDownloadAction = rawDownloadUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-raw\" class=\"hint-button\" type=\"button\">Download Raw</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${rawDownloadUrl}\" target=\"_blank\" rel=\"noopener\">Download Raw</a>`\n\t\t\t: \"\";\n\t\tconst standaloneDownloadAction = standaloneDownloadUrl\n\t\t\t? accessToken\n\t\t\t\t? `<button id=\"download-standalone\" class=\"hint-button\" type=\"button\">Download Standalone</button>`\n\t\t\t\t: `<a class=\"hint\" href=\"${standaloneDownloadUrl}\" target=\"_blank\" rel=\"noopener\">Download Standalone</a>`\n\t\t\t: \"\";\n\t\tconst zipDownloadName = `${sessionId}-artifacts.zip`;\n\n\t\tconst srcdoc = isHtml\n\t\t\t? injectArtifactsSnapshotRuntime(content, artifacts)\n\t\t\t: wrapHtmlDocument(\n\t\t\t\t\t`<pre style=\"white-space:pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 13px; line-height: 1.4; padding: 16px; margin: 0;\">${content\n\t\t\t\t\t\t.replace(/&/g, \"&\")\n\t\t\t\t\t\t.replace(/</g, \"<\")\n\t\t\t\t\t\t.replace(/>/g, \">\")}</pre>`,\n\t\t\t\t);\n\n\t\tconst openExternalHandler = `\n<script>\nwindow.addEventListener(\"message\", (e) => {\n if (!e || !e.data) return;\n if (e.data.type !== \"open-external-url\") return;\n const url = e.data.url;\n if (typeof url !== \"string\") return;\n let parsed;\n try { parsed = new URL(url); } catch { return; }\n if (!parsed || (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\")) return;\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n});\n</script>\n`.trim();\n\n\t\tconst viewerHtml = `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${title.replace(/</g, \"<\").replace(/>/g, \">\")}</title>\n <style>\n html, body { height: 100%; margin: 0; background: #0b0c0f; color: #e6edf3; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; }\n .bar { display:flex; align-items:center; gap:12px; padding:10px 12px; border-bottom: 1px solid #1e2023; background: #08090a; position: sticky; top: 0; z-index: 1; }\n .title { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 12px; color: #9da3af; }\n .spacer { flex: 1; }\n a, button { font: inherit; }\n button { background: transparent; border: 1px solid #30363d; color: #c9d1d9; padding: 6px 10px; cursor: pointer; }\n button:hover { border-color: #58a6ff; color: #58a6ff; }\n iframe { width: 100%; height: calc(100% - 52px); border: 0; display:block; background: #fff; }\n .hint { font-size: 12px; color: #7d8590; }\n .hint-button { padding: 0; border: 0; color: #7d8590; font-size: 12px; }\n </style>\n </head>\n <body>\n <div class=\"bar\">\n <div class=\"title\">${title.replace(/</g, \"<\").replace(/>/g, \">\")}</div>\n <div class=\"spacer\"></div>\n ${zipAction}\n ${rawDownloadAction}\n ${standaloneDownloadAction}\n <button id=\"reload\">Reload</button>\n </div>\n ${openExternalHandler}\n <iframe id=\"frame\" sandbox=\"allow-scripts allow-modals allow-downloads\"></iframe>\n <script>\n const frame = document.getElementById(\"frame\");\n const reloadBtn = document.getElementById(\"reload\");\n const viewerUrl = ${JSON.stringify(viewerUrl)};\n const eventsUrl = ${JSON.stringify(eventsUrl)};\n const zipUrl = ${JSON.stringify(zipUrl)};\n const rawDownloadUrl = ${JSON.stringify(rawDownloadUrl)};\n const standaloneDownloadUrl = ${JSON.stringify(standaloneDownloadUrl)};\n const artifactAccessToken = ${JSON.stringify(accessToken)};\n const artifactAccessHeaders = artifactAccessToken\n ? { ${JSON.stringify(ARTIFACT_ACCESS_HEADER)}: artifactAccessToken }\n : undefined;\n\n const setDoc = (html) => {\n frame.srcdoc = html;\n };\n\n const parseDownloadFilename = (response, fallbackName) => {\n const contentDisposition = response.headers.get(\"content-disposition\") || \"\";\n const utf8Match = contentDisposition.match(/filename\\*=UTF-8''([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n const quotedMatch = contentDisposition.match(/filename=\"([^\"]+)\"/i);\n if (quotedMatch?.[1]) {\n return quotedMatch[1];\n }\n const bareMatch = contentDisposition.match(/filename=([^;]+)/i);\n return bareMatch?.[1]?.trim() || fallbackName || \"\";\n };\n\n const fetchViewerResource = async (url) => {\n const response = await fetch(url, {\n cache: \"no-store\",\n ...(artifactAccessHeaders ? { headers: artifactAccessHeaders } : {}),\n });\n if (!response.ok) {\n\t\t throw new Error(\"Request failed (\" + response.status + \")\");\n }\n return response;\n };\n\n const downloadViewerResource = async (url, fallbackName) => {\n const response = await fetchViewerResource(url);\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = objectUrl;\n const downloadName = parseDownloadFilename(response, fallbackName);\n if (downloadName) {\n link.download = downloadName;\n }\n link.rel = \"noopener\";\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n };\n\n const refreshViewer = async () => {\n if (!artifactAccessHeaders) {\n location.reload();\n return;\n }\n const response = await fetchViewerResource(viewerUrl);\n const nextHtml = await response.text();\n const nextUrl = URL.createObjectURL(\n new Blob([nextHtml], { type: \"text/html\" }),\n );\n setTimeout(() => URL.revokeObjectURL(nextUrl), 60_000);\n location.replace(nextUrl);\n };\n\n const triggerRefresh = () => {\n void refreshViewer().catch((err) => {\n console.error(\"[Maestro] Failed to refresh viewer:\", err);\n });\n };\n\n const bindDownloadButton = (id, url, fallbackName) => {\n const button = document.getElementById(id);\n if (!button || !url || !artifactAccessHeaders) {\n return;\n }\n button.addEventListener(\"click\", () => {\n void downloadViewerResource(url, fallbackName).catch((err) => {\n console.error(\"[Maestro] Failed to download artifact:\", err);\n });\n });\n };\n\n const srcdoc = ${JSON.stringify(srcdoc)};\n setDoc(srcdoc);\n\n\t\t\t\tbindDownloadButton(\"download-zip\", zipUrl, ${JSON.stringify(zipDownloadName)});\n bindDownloadButton(\"download-raw\", rawDownloadUrl, ${JSON.stringify(filename)});\n bindDownloadButton(\"download-standalone\", standaloneDownloadUrl, ${JSON.stringify(filename)});\n\n reloadBtn.addEventListener(\"click\", () => triggerRefresh());\n\n ${\n\t\t\t\teventsUrl\n\t\t\t\t\t? `try {\n\t\tconst reload = () => triggerRefresh();\n const connect = ${\n\t\t\t\t\taccessToken\n\t\t\t\t\t\t? `async () => {\n\t\t const response = await fetchViewerResource(eventsUrl);\n if (!response.body) throw new Error(\"Missing response body\");\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let boundary = buffer.indexOf(\"\\\\n\\\\n\");\n while (boundary !== -1) {\n const chunk = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n const dataLine = chunk\n .split(\"\\\\n\")\n .find((line) => line.startsWith(\"data:\"));\n if (dataLine) {\n reload();\n return;\n }\n boundary = buffer.indexOf(\"\\\\n\\\\n\");\n }\n }\n }`\n\t\t\t\t\t\t: `() => {\n const es = new EventSource(${JSON.stringify(eventsUrl)});\n es.onmessage = () => reload();\n }`\n\t\t\t\t};\n Promise.resolve(connect()).catch((err) => {\n console.error(\"[Maestro] Failed to setup viewer live reload transport:\", err);\n });\n } catch (err) { console.error(\"[Maestro] Failed to setup viewer EventSource:\", err); }`\n\t\t\t\t\t: \"\"\n\t\t\t}\n </script>\n </body>\n</html>`;\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"text/html; charset=utf-8\",\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...cors,\n\t\t});\n\t\tres.end(viewerHtml);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactsEvents(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\tconst filenameFilter = url.searchParams.get(\"filename\");\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\tConnection: \"keep-alive\",\n\t\t\t...cors,\n\t\t});\n\n\t\tlet closed = false;\n\t\tconst canWrite = () =>\n\t\t\tres.writable !== false && !res.writableEnded && !res.destroyed;\n\t\tconst safeWrite = (payload: string) => {\n\t\t\tif (!canWrite()) return false;\n\t\t\ttry {\n\t\t\t\tres.write(payload);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\tlet heartbeat: ReturnType<typeof setInterval> | null = null;\n\t\tlet unsubscribe: () => void = () => {};\n\n\t\tconst cleanup = () => {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (heartbeat) {\n\t\t\t\tclearInterval(heartbeat);\n\t\t\t\theartbeat = null;\n\t\t\t}\n\t\t\tunsubscribe();\n\t\t\treq.off(\"close\", cleanup);\n\t\t\tres.off(\"close\", cleanup);\n\t\t};\n\n\t\tunsubscribe = subscribeArtifactUpdates(sessionId, (event) => {\n\t\t\tif (filenameFilter && event.filename !== filenameFilter) return;\n\t\t\tif (!safeWrite(`data: ${JSON.stringify(event)}\\n\\n`)) {\n\t\t\t\tcleanup();\n\t\t\t}\n\t\t});\n\n\t\theartbeat = setInterval(() => {\n\t\t\tif (!safeWrite(\": ping\\n\\n\")) {\n\t\t\t\tcleanup();\n\t\t\t}\n\t\t}, 15_000);\n\n\t\tif (heartbeat.unref) {\n\t\t\theartbeat.unref();\n\t\t}\n\n\t\tif (!safeWrite(\": ok\\n\\n\")) {\n\t\t\tcleanup();\n\t\t\treturn;\n\t\t}\n\n\t\treq.on(\"close\", cleanup);\n\t\tres.on(\"close\", cleanup);\n\t} catch (err) {\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n\nexport async function handleSessionArtifactsZip(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: { id: string },\n\tcors: Record<string, string>,\n) {\n\tconst sessionId = params.id;\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tif (!sessionIdPattern.test(sessionId)) {\n\t\t\tsendJson(res, 400, { error: \"Invalid session id\" }, cors, req);\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = await loadComposerMessages(req, sessionId);\n\t\tconst artifacts = reconstructArtifactsFromMessages(messages);\n\n\t\t// Lazy import to keep startup cost low.\n\t\tconst { strToU8, zipSync } = await import(\"fflate\");\n\n\t\tconst entries: Record<string, Uint8Array> = {};\n\t\tfor (const [filename, content] of artifacts) {\n\t\t\tentries[filename] = strToU8(content);\n\t\t}\n\n\t\tconst zipBytes = zipSync(entries, { level: 6 });\n\n\t\tres.writeHead(200, {\n\t\t\t\"Content-Type\": \"application/zip\",\n\t\t\t\"Content-Disposition\": buildContentDisposition(\n\t\t\t\t`artifacts-${sessionId}.zip`,\n\t\t\t),\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t...cors,\n\t\t});\n\t\tres.end(Buffer.from(zipBytes));\n\t} catch (err) {\n\t\tlogger.warn(\"Failed to export artifacts zip\", {\n\t\t\terr: err instanceof Error ? err.message : String(err),\n\t\t\tsessionId,\n\t\t});\n\t\tconst error =\n\t\t\terr instanceof ApiError ? err : new ApiError(500, \"Internal error\");\n\t\tsendJson(res, error.statusCode, { error: error.message }, cors, req);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type AgentTrajectoryReplayLabReport } from "../agent-trajectory-replay-lab.js";
|
|
3
|
+
import type { HostedRunnerContext } from "../app-context.js";
|
|
4
|
+
interface SessionReplayLabParams {
|
|
5
|
+
id?: string;
|
|
6
|
+
}
|
|
7
|
+
interface SessionReplayLabOptions {
|
|
8
|
+
hostedRunner?: HostedRunnerContext;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildSessionReplayLabForRequest(req: IncomingMessage, params: SessionReplayLabParams, options?: SessionReplayLabOptions): Promise<AgentTrajectoryReplayLabReport>;
|
|
11
|
+
export declare function handleSessionReplayLab(req: IncomingMessage, res: ServerResponse, params: SessionReplayLabParams, cors: Record<string, string>, options?: SessionReplayLabOptions): Promise<void>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=session-replay-lab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-replay-lab.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/session-replay-lab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,EACN,KAAK,8BAA8B,EAEnC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAQ7D,UAAU,sBAAsB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,uBAAuB;IAChC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACnC;AA8CD,wBAAsB,+BAA+B,CACpD,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,CAAC,EAAE,uBAAuB,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CA4BzC;AAED,wBAAsB,sBAAsB,CAC3C,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,sBAAsB,EAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { tryListMaestroTimelineWithPlatform } from "../../platform/maestro-timeline-client.js";
|
|
2
|
+
import { buildAgentTrajectoryReplayLab, } from "../agent-trajectory-replay-lab.js";
|
|
3
|
+
import { getAuthSubject } from "../authz.js";
|
|
4
|
+
import { getPendingComposerRequests } from "../pending-request-payload.js";
|
|
5
|
+
import { ApiError, respondWithApiError, sendJson } from "../server-utils.js";
|
|
6
|
+
import { createWebSessionManagerForRequest } from "../session-scope.js";
|
|
7
|
+
import { buildComposerRunTimeline } from "../session-timeline.js";
|
|
8
|
+
import { sessionIdPattern, verifySessionOwnership } from "./sessions.js";
|
|
9
|
+
function requireSessionId(params) {
|
|
10
|
+
const sessionId = params.id?.trim();
|
|
11
|
+
if (!sessionId || !sessionIdPattern.test(sessionId)) {
|
|
12
|
+
throw new ApiError(400, "Invalid session id");
|
|
13
|
+
}
|
|
14
|
+
return sessionId;
|
|
15
|
+
}
|
|
16
|
+
function hostedRunnerMatchesSession(hostedRunner, sessionId) {
|
|
17
|
+
if (!hostedRunner?.enabled) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const activeSessionId = hostedRunner.activeMaestroSessionId ??
|
|
21
|
+
hostedRunner.configuredMaestroSessionId;
|
|
22
|
+
return activeSessionId === sessionId;
|
|
23
|
+
}
|
|
24
|
+
async function tryBuildPlatformTimeline(sessionId, pendingRequestCount, options) {
|
|
25
|
+
const hostedRunner = options?.hostedRunner;
|
|
26
|
+
if (!hostedRunnerMatchesSession(hostedRunner, sessionId)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const agentRunId = hostedRunner?.agentRunId;
|
|
30
|
+
const remoteRunnerSessionId = hostedRunner?.runnerSessionId;
|
|
31
|
+
if (!agentRunId && !remoteRunnerSessionId) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return await tryListMaestroTimelineWithPlatform({
|
|
35
|
+
sessionId,
|
|
36
|
+
agentRunId,
|
|
37
|
+
remoteRunnerSessionId,
|
|
38
|
+
workspaceId: hostedRunner?.workspaceId,
|
|
39
|
+
pendingRequestCount,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export async function buildSessionReplayLabForRequest(req, params, options) {
|
|
43
|
+
const sessionId = requireSessionId(params);
|
|
44
|
+
const sessionManager = createWebSessionManagerForRequest(req, true);
|
|
45
|
+
const session = await sessionManager.loadSession(sessionId);
|
|
46
|
+
if (!session) {
|
|
47
|
+
throw new ApiError(404, "Session not found");
|
|
48
|
+
}
|
|
49
|
+
const subject = getAuthSubject(req);
|
|
50
|
+
if (!verifySessionOwnership(session, subject)) {
|
|
51
|
+
throw new ApiError(403, "Access denied: session belongs to another user");
|
|
52
|
+
}
|
|
53
|
+
const entries = (await sessionManager.loadEntries(sessionId)) ?? [];
|
|
54
|
+
const pendingRequests = getPendingComposerRequests(session.id);
|
|
55
|
+
const timeline = (await tryBuildPlatformTimeline(session.id, pendingRequests.length, options)) ??
|
|
56
|
+
buildComposerRunTimeline({
|
|
57
|
+
sessionId: session.id,
|
|
58
|
+
entries,
|
|
59
|
+
messages: session.messages || [],
|
|
60
|
+
pendingRequests,
|
|
61
|
+
});
|
|
62
|
+
return buildAgentTrajectoryReplayLab(timeline);
|
|
63
|
+
}
|
|
64
|
+
export async function handleSessionReplayLab(req, res, params, cors, options) {
|
|
65
|
+
try {
|
|
66
|
+
if (req.method !== "GET") {
|
|
67
|
+
res.writeHead(405, cors);
|
|
68
|
+
res.end();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const responseBody = await buildSessionReplayLabForRequest(req, params, options);
|
|
72
|
+
sendJson(res, 200, responseBody, cors, req);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (!respondWithApiError(res, error, 500, cors, req)) {
|
|
76
|
+
sendJson(res, 500, { error: "Failed to load session replay lab" }, cors, req);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=session-replay-lab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-replay-lab.js","sourceRoot":"","sources":["../../../src/server/handlers/session-replay-lab.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { ComposerRunTimelineResponse } from \"@evalops/contracts\";\nimport { tryListMaestroTimelineWithPlatform } from \"../../platform/maestro-timeline-client.js\";\nimport {\n\ttype AgentTrajectoryReplayLabReport,\n\tbuildAgentTrajectoryReplayLab,\n} from \"../agent-trajectory-replay-lab.js\";\nimport type { HostedRunnerContext } from \"../app-context.js\";\nimport { getAuthSubject } from \"../authz.js\";\nimport { getPendingComposerRequests } from \"../pending-request-payload.js\";\nimport { ApiError, respondWithApiError, sendJson } from \"../server-utils.js\";\nimport { createWebSessionManagerForRequest } from \"../session-scope.js\";\nimport { buildComposerRunTimeline } from \"../session-timeline.js\";\nimport { sessionIdPattern, verifySessionOwnership } from \"./sessions.js\";\n\ninterface SessionReplayLabParams {\n\tid?: string;\n}\n\ninterface SessionReplayLabOptions {\n\thostedRunner?: HostedRunnerContext;\n}\n\nfunction requireSessionId(params: SessionReplayLabParams): string {\n\tconst sessionId = params.id?.trim();\n\tif (!sessionId || !sessionIdPattern.test(sessionId)) {\n\t\tthrow new ApiError(400, \"Invalid session id\");\n\t}\n\treturn sessionId;\n}\n\nfunction hostedRunnerMatchesSession(\n\thostedRunner: HostedRunnerContext | undefined,\n\tsessionId: string,\n): boolean {\n\tif (!hostedRunner?.enabled) {\n\t\treturn false;\n\t}\n\tconst activeSessionId =\n\t\thostedRunner.activeMaestroSessionId ??\n\t\thostedRunner.configuredMaestroSessionId;\n\treturn activeSessionId === sessionId;\n}\n\nasync function tryBuildPlatformTimeline(\n\tsessionId: string,\n\tpendingRequestCount: number,\n\toptions: SessionReplayLabOptions | undefined,\n): Promise<ComposerRunTimelineResponse | null> {\n\tconst hostedRunner = options?.hostedRunner;\n\tif (!hostedRunnerMatchesSession(hostedRunner, sessionId)) {\n\t\treturn null;\n\t}\n\tconst agentRunId = hostedRunner?.agentRunId;\n\tconst remoteRunnerSessionId = hostedRunner?.runnerSessionId;\n\tif (!agentRunId && !remoteRunnerSessionId) {\n\t\treturn null;\n\t}\n\treturn await tryListMaestroTimelineWithPlatform({\n\t\tsessionId,\n\t\tagentRunId,\n\t\tremoteRunnerSessionId,\n\t\tworkspaceId: hostedRunner?.workspaceId,\n\t\tpendingRequestCount,\n\t});\n}\n\nexport async function buildSessionReplayLabForRequest(\n\treq: IncomingMessage,\n\tparams: SessionReplayLabParams,\n\toptions?: SessionReplayLabOptions,\n): Promise<AgentTrajectoryReplayLabReport> {\n\tconst sessionId = requireSessionId(params);\n\tconst sessionManager = createWebSessionManagerForRequest(req, true);\n\tconst session = await sessionManager.loadSession(sessionId);\n\tif (!session) {\n\t\tthrow new ApiError(404, \"Session not found\");\n\t}\n\n\tconst subject = getAuthSubject(req);\n\tif (!verifySessionOwnership(session, subject)) {\n\t\tthrow new ApiError(403, \"Access denied: session belongs to another user\");\n\t}\n\n\tconst entries = (await sessionManager.loadEntries(sessionId)) ?? [];\n\tconst pendingRequests = getPendingComposerRequests(session.id);\n\tconst timeline =\n\t\t(await tryBuildPlatformTimeline(\n\t\t\tsession.id,\n\t\t\tpendingRequests.length,\n\t\t\toptions,\n\t\t)) ??\n\t\tbuildComposerRunTimeline({\n\t\t\tsessionId: session.id,\n\t\t\tentries,\n\t\t\tmessages: session.messages || [],\n\t\t\tpendingRequests,\n\t\t});\n\treturn buildAgentTrajectoryReplayLab(timeline);\n}\n\nexport async function handleSessionReplayLab(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tparams: SessionReplayLabParams,\n\tcors: Record<string, string>,\n\toptions?: SessionReplayLabOptions,\n): Promise<void> {\n\ttry {\n\t\tif (req.method !== \"GET\") {\n\t\t\tres.writeHead(405, cors);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\tconst responseBody = await buildSessionReplayLabForRequest(\n\t\t\treq,\n\t\t\tparams,\n\t\t\toptions,\n\t\t);\n\t\tsendJson(res, 200, responseBody, cors, req);\n\t} catch (error) {\n\t\tif (!respondWithApiError(res, error, 500, cors, req)) {\n\t\t\tsendJson(\n\t\t\t\tres,\n\t\t\t\t500,\n\t\t\t\t{ error: \"Failed to load session replay lab\" },\n\t\t\t\tcors,\n\t\t\t\treq,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/server/handlers/stats.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,GAAoB,EACpB,GAAmB,EACnB,WAAmC;IAEnC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,OAAO;IACR,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/server/handlers/stats.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,GAAoB,EACpB,GAAmB,EACnB,WAAmC;IAEnC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,OAAO;IACR,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,QAAQ,CACP,GAAG,EACH,GAAG,EACH;YACC,MAAM;YACN,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,EACD,WAAW,EACX,GAAG,CACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,QAAQ,CACP,GAAG,EACH,GAAG,EACH,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjE,WAAW,EACX,GAAG,CACH,CAAC;IACH,CAAC;AACF,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { sendJson } from \"../server-utils.js\";\nimport { getStatusSnapshot } from \"./status.js\";\nimport { getUsageSnapshot } from \"./usage.js\";\n\nexport async function handleStats(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n\tcorsHeaders: Record<string, string>,\n) {\n\tif (req.method !== \"GET\") {\n\t\tsendJson(res, 405, { error: \"Method not allowed\" }, corsHeaders);\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst status = await getStatusSnapshot();\n\t\tconst usage = getUsageSnapshot();\n\t\tsendJson(\n\t\t\tres,\n\t\t\t200,\n\t\t\t{\n\t\t\t\tstatus,\n\t\t\t\tusage,\n\t\t\t\tupdatedAt: Date.now(),\n\t\t\t},\n\t\t\tcorsHeaders,\n\t\t\treq,\n\t\t);\n\t} catch (error) {\n\t\tsendJson(\n\t\t\tres,\n\t\t\t500,\n\t\t\t{ error: error instanceof Error ? error.message : String(error) },\n\t\t\tcorsHeaders,\n\t\t\treq,\n\t\t);\n\t}\n}\n"]}
|
|
@@ -1,7 +1,47 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
export declare function resetStatusDatabaseHealthCacheForTests(): void;
|
|
3
|
+
export type RunHealthLevel = "healthy" | "degraded" | "unhealthy";
|
|
4
|
+
export interface RunHealthSlo {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
status: RunHealthLevel;
|
|
8
|
+
target: string;
|
|
9
|
+
observed: string;
|
|
10
|
+
detail?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface RunHealthSnapshot {
|
|
13
|
+
status: RunHealthLevel;
|
|
14
|
+
slos: RunHealthSlo[];
|
|
15
|
+
diagnostics: string[];
|
|
16
|
+
generatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RunHealthInput {
|
|
19
|
+
apiLatencyMs: number;
|
|
20
|
+
backgroundTasks: {
|
|
21
|
+
running?: number;
|
|
22
|
+
failed?: number;
|
|
23
|
+
restarting?: number;
|
|
24
|
+
} | null;
|
|
25
|
+
database: {
|
|
26
|
+
configured: boolean;
|
|
27
|
+
connected: boolean;
|
|
28
|
+
initialized?: boolean;
|
|
29
|
+
reachable?: boolean;
|
|
30
|
+
};
|
|
31
|
+
hooks: {
|
|
32
|
+
asyncInFlight: number;
|
|
33
|
+
concurrency: {
|
|
34
|
+
max: number;
|
|
35
|
+
active: number;
|
|
36
|
+
queued: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
generatedAt?: number;
|
|
40
|
+
}
|
|
41
|
+
export declare function buildRunHealthSnapshot(input: RunHealthInput): RunHealthSnapshot;
|
|
2
42
|
export declare function getStatusSnapshot(options?: {
|
|
3
43
|
staticCacheMaxAge?: number;
|
|
4
|
-
}): {
|
|
44
|
+
}): Promise<{
|
|
5
45
|
cwd: string;
|
|
6
46
|
git: {
|
|
7
47
|
branch: string;
|
|
@@ -36,10 +76,11 @@ export declare function getStatusSnapshot(options?: {
|
|
|
36
76
|
queued: number;
|
|
37
77
|
};
|
|
38
78
|
};
|
|
79
|
+
runHealth: RunHealthSnapshot;
|
|
39
80
|
lastUpdated: number;
|
|
40
81
|
lastLatencyMs: number;
|
|
41
|
-
}
|
|
82
|
+
}>;
|
|
42
83
|
export declare function handleStatus(req: IncomingMessage, res: ServerResponse, cors: Record<string, string>, options?: {
|
|
43
84
|
staticCacheMaxAge?: number;
|
|
44
|
-
}): void
|
|
85
|
+
}): Promise<void>;
|
|
45
86
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/status.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/status.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA4GjE,wBAAgB,sCAAsC,IAAI,IAAI,CAK7D;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAElE,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,QAAQ,EAAE;QACT,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,KAAK,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE;YACZ,GAAG,EAAE,MAAM,CAAC;YACZ,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;SACf,CAAC;KACF,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAqHD,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,cAAc,GACnB,iBAAiB,CAgBnB;AAED,wBAAsB,iBAAiB,CACtC,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;oBAhNhC,OAAO;mBACR,OAAO;;;;;;;;;;;;;;GAoRlB;AAED,wBAAsB,YAAY,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|