{"version":3,"file":"index.cjs","names":["WorkflowRegistryService","WorkflowTerminalFacade","createWorkflowTerminalService","Hono","routes","streamSSE","WORKFLOW_SCREEN_EVENT","randomUUID","path","fs","Readable","WORKFLOW_API_BASE_PATH"],"sources":["../../../../src/services/workflowHubApi/index.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/package-api';\nimport {\n  WorkflowRegistryService,\n  WorkflowTerminalService as WorkflowTerminalFacade,\n  type WorkflowRunRecord,\n  type WorkflowStage,\n} from '@agimon-ai/workflow-mcp';\nimport { type Context, Hono } from 'hono';\nimport { streamSSE } from 'hono/streaming';\n\nimport { createWorkflowTerminalService } from '../../services/workflowTerminal';\nimport routes, { ARTIFACT_DOWNLOAD_PARAM, ARTIFACT_RAW_PARAM } from '../../types/apiRoutes';\nimport {\n  WORKFLOW_API_BASE_PATH,\n  WORKFLOW_SCREEN_EVENT,\n  type WorkflowArtifactContentResponse,\n  type WorkflowArtifactsResponse,\n  type WorkflowArtifactView,\n  type WorkflowControlResponse,\n  type WorkflowDeleteResponse,\n  type WorkflowScreenEvent,\n} from '../../types/webWorkflowTerminal';\n\n/** Stages a run can be recorded under, newest first: a live run is the common case. */\nconst STAGES: readonly WorkflowStage[] = ['running', 'error', 'completed'];\n/** Lines of screen the stream sends, which is a terminal's visible height plus room. */\nconst SCREEN_LINES = 48;\n/** How often the stream re-reads; the service coalesces, so this is an upper bound. */\nconst STREAM_TICK_MS = 500;\n/** How often a settled run is re-checked before the stream closes itself. */\nconst SETTLED_POLL_TICKS = 4;\n/** Bytes of one textual artifact returned as JSON; binary previews use a stream. */\nconst MAX_ARTIFACT_BYTES = 512 * 1024;\n/** Path segments a client supplies are names, never paths. */\nconst SAFE_SEGMENT = /^[\\w.@-]+$/;\nconst ARTIFACT_MIME_TYPES: Readonly<Record<string, string>> = {\n  '.aac': 'audio/aac',\n  '.bmp': 'image/bmp',\n  '.css': 'text/css',\n  '.csv': 'text/csv',\n  '.gif': 'image/gif',\n  '.htm': 'text/html',\n  '.html': 'text/html',\n  '.ico': 'image/x-icon',\n  '.jpeg': 'image/jpeg',\n  '.jpg': 'image/jpeg',\n  '.js': 'text/javascript',\n  '.json': 'application/json',\n  '.jsx': 'text/jsx',\n  '.m4a': 'audio/mp4',\n  '.markdown': 'text/markdown',\n  '.md': 'text/markdown',\n  '.mov': 'video/quicktime',\n  '.mp3': 'audio/mpeg',\n  '.mp4': 'video/mp4',\n  '.oga': 'audio/ogg',\n  '.ogg': 'audio/ogg',\n  '.ogv': 'video/ogg',\n  '.pdf': 'application/pdf',\n  '.png': 'image/png',\n  '.sh': 'text/x-shellscript',\n  '.svg': 'image/svg+xml',\n  '.toml': 'text/toml',\n  '.ts': 'text/typescript',\n  '.tsv': 'text/tab-separated-values',\n  '.tsx': 'text/tsx',\n  '.txt': 'text/plain',\n  '.wav': 'audio/wav',\n  '.webm': 'video/webm',\n  '.webp': 'image/webp',\n  '.xml': 'application/xml',\n  '.yaml': 'text/yaml',\n  '.yml': 'text/yaml',\n};\n\n/**\n * One request's JSON body as a plain record.\n *\n * A body that is absent, malformed, or not an object reads as empty rather\n * than failing the route: every field is checked by the route anyway, and a\n * 400 naming the missing field beats a parse error naming nothing.\n */\nasync function jsonBody(context: Context): Promise<Record<string, unknown>> {\n  const parsed: unknown = await context.req.json().catch(() => undefined);\n  return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n    ? (parsed as Record<string, unknown>)\n    : {};\n}\n\n/** Rejects anything that could climb out of the registry before a path is built. */\nfunction isSafeSegment(value: string): boolean {\n  return value !== '' && value !== '../adapters' && value !== '..' && SAFE_SEGMENT.test(value);\n}\n\n/** One run's identity for caches and leases, stable across stage moves. */\nfunction runIdentityOf(workspace: string, runKey: string): string {\n  return `${workspace}/${runKey}`;\n}\n\nexport interface WorkflowHubApiOptions {\n  registry?: WorkflowRegistryService;\n  terminal?: WorkflowTerminalFacade;\n  now?: () => number;\n}\n\n/**\n * This package's HTTP surface: one workflow run's terminal, and the files its\n * run directory holds.\n *\n * Mounted in the hub rather than in a session's server, because a run's\n * terminal belongs to its multiplexer rather than to the session that launched\n * it: any process can read a tmux pane, and the session's own server cannot\n * reach anything more. The routes therefore name a run, never a session.\n */\nexport function createWorkflowHubApi(options: WorkflowHubApiOptions = {}): Hono {\n  const registry = options.registry ?? new WorkflowRegistryService();\n  const facade = options.terminal ?? new WorkflowTerminalFacade();\n  const terminal = createWorkflowTerminalService<WorkflowRunRecord>({\n    terminal: facade,\n    now: options.now ?? (() => Date.now()),\n  });\n  const app = new Hono();\n\n  /** The record behind a request, whichever stage it now sits in. */\n  const runOf = async (workspace: string, runKey: string): Promise<WorkflowRunRecord | undefined> => {\n    if (!isSafeSegment(workspace) || !isSafeSegment(runKey)) return undefined;\n    for (const stage of STAGES) {\n      try {\n        return await registry.readRunByKey(workspace, stage, runKey);\n      } catch {\n        // Not in this stage. A run moves between them as it settles, so a miss\n        // here is ordinary; only a miss in every stage means no such run.\n      }\n    }\n    return undefined;\n  };\n\n  const missing = (workspace: string, runKey: string): { error: string } => ({\n    error: `No workflow run '${runKey}' in workspace '${workspace}'.`,\n  });\n\n  app.get(routes.screen.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const identity = runIdentityOf(workspace, runKey);\n\n    return streamSSE(context, async (stream) => {\n      let settledTicks = 0;\n      let running = true;\n      stream.onAbort(() => {\n        running = false;\n      });\n      while (running) {\n        const current = (await runOf(workspace, runKey)) ?? record;\n        const capabilities = terminal.capabilities(current);\n        const lines = capabilities.readable ? await terminal.screen(identity, current, SCREEN_LINES) : [];\n        // A settled run is read a few more times before the stream closes: the\n        // last thing a failing step printed is what the reader came for, and it\n        // lands after the record has already moved to its final stage.\n        const settled = current.stage !== 'running';\n        if (settled) settledTicks += 1;\n        const ended = settled && settledTicks >= SETTLED_POLL_TICKS;\n        const event: WorkflowScreenEvent = { lines, capabilities, ...(ended ? { ended: true } : {}) };\n        await stream.writeSSE({ event: WORKFLOW_SCREEN_EVENT, data: JSON.stringify(event) });\n        if (ended) break;\n        await stream.sleep(STREAM_TICK_MS);\n      }\n      terminal.forget(new Set());\n    });\n  });\n\n  app.post(routes.control.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const identity = runIdentityOf(workspace, runKey);\n    const body = await jsonBody(context);\n    const capabilities = terminal.capabilities(record);\n\n    if (body.release === true) {\n      if (typeof body.token === 'string') terminal.releaseControl(identity, body.token);\n      const released: WorkflowControlResponse = { held: false };\n      return context.json(released);\n    }\n    if (!capabilities.writable) {\n      const refused: WorkflowControlResponse = { held: false, reason: capabilities.reason };\n      return context.json(refused, 409);\n    }\n    const token = typeof body.token === 'string' && body.token !== '' ? body.token : randomUUID();\n    if (!terminal.takeControl(identity, token)) {\n      const taken: WorkflowControlResponse = { held: false, reason: 'Another reader holds the keyboard.' };\n      return context.json(taken, 409);\n    }\n    const held: WorkflowControlResponse = { held: true, token };\n    return context.json(held);\n  });\n\n  app.post(routes.keys.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const body = await jsonBody(context);\n    if (typeof body.token !== 'string' || typeof body.data !== 'string') {\n      return context.json({ error: 'A keystroke needs a control token and its data.' }, 400);\n    }\n    try {\n      await terminal.write(runIdentityOf(workspace, runKey), record, body.token, body.data);\n    } catch (error) {\n      return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n    }\n    return context.body(null, 204);\n  });\n\n  app.post(routes.resize.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const body = await jsonBody(context);\n    const { token, columns, rows } = body;\n    if (typeof token !== 'string' || typeof columns !== 'number' || typeof rows !== 'number') {\n      return context.json({ error: 'A resize needs a control token, columns and rows.' }, 400);\n    }\n    try {\n      const resized = await terminal.resize(runIdentityOf(workspace, runKey), record, token, columns, rows);\n      return context.json({ resized });\n    } catch (error) {\n      return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n    }\n  });\n\n  app.delete(routes.remove.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    if (record.stage === 'running') {\n      return context.json({ error: 'A running workflow must be stopped before it can be deleted.' }, 409);\n    }\n    try {\n      fs.rmSync(registry.runDirectoryFor(record), { recursive: true, force: true });\n    } catch (error) {\n      return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n    }\n    const response: WorkflowDeleteResponse = { deleted: true };\n    return context.json(response);\n  });\n\n  app.get(routes.artifacts.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const runDir = registry.runDirectoryFor(record);\n    const body: WorkflowArtifactsResponse = {\n      runDir,\n      description: record.runDirectory?.description ?? '',\n      artifacts: readArtifacts(runDir, record),\n    };\n    return context.json(body);\n  });\n\n  app.get(routes.artifact.path, async (context) => {\n    const workspace = context.req.param('workspace');\n    const runKey = context.req.param('runKey');\n    const record = await runOf(workspace, runKey);\n    if (record === undefined) return context.json(missing(workspace, runKey), 404);\n    const runDir = registry.runDirectoryFor(record);\n    const requested = context.req.param('name');\n    const resolved = resolveInside(runDir, requested);\n    if (resolved === undefined) return context.json({ error: `'${requested}' is not inside this run.` }, 400);\n    if (context.req.query(ARTIFACT_RAW_PARAM) === '1') {\n      const response = streamArtifact(\n        resolved,\n        requested,\n        context.req.header('range'),\n        context.req.query(ARTIFACT_DOWNLOAD_PARAM) === '1',\n      );\n      return response ?? context.json({ error: `'${requested}' has not been written.` }, 404);\n    }\n    const body = readArtifact(resolved, requested);\n    if (body === undefined) return context.json({ error: `'${requested}' has not been written.` }, 404);\n    return context.json(body);\n  });\n\n  return app;\n}\n\n/**\n * A path inside the run directory, or undefined when it points anywhere else.\n *\n * The client supplies this one verbatim, unlike the run key, so it is resolved\n * and then checked rather than trusted: without the check the route would read\n * any file the hub can reach.\n */\nfunction resolveInside(runDir: string, requested: string): string | undefined {\n  const resolved = path.resolve(runDir, requested);\n  const root = path.resolve(runDir);\n  if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) return undefined;\n  return resolved;\n}\n\n/** Size and modification time of one path, or undefined when it is not there. */\nfunction statOf(target: string): fs.Stats | undefined {\n  try {\n    return fs.statSync(target);\n  } catch {\n    return undefined; // Not written yet, which is an ordinary state for an artifact.\n  }\n}\n\nfunction stateOf(stats: fs.Stats | undefined): WorkflowArtifactView['state'] {\n  if (stats === undefined) return 'pending';\n  if (stats.isDirectory()) return 'written';\n  return stats.size === 0 ? 'empty' : 'written';\n}\n\nfunction viewOf(\n  runDir: string,\n  entry: Omit<WorkflowArtifactView, 'state' | 'size' | 'modifiedAt'>,\n): WorkflowArtifactView {\n  const stats = statOf(path.join(runDir, entry.path));\n  return {\n    ...entry,\n    state: stateOf(stats),\n    ...(stats === undefined ? {} : { size: stats.size, modifiedAt: stats.mtime.toISOString() }),\n  };\n}\n\n/**\n * What the run directory holds: the workflow's own declaration first, then the\n * files nobody declared.\n *\n * The declaration is the point of the folder, so it leads and keeps its order\n * even for entries no job has written yet. The rest follows rather than being\n * hidden: the engine's own context.md and progress log are often exactly what a\n * reader is looking for.\n */\nfunction readArtifacts(runDir: string, record: WorkflowRunRecord): WorkflowArtifactView[] {\n  const declared = (record.runDirectory?.entries ?? []).map((entry) =>\n    viewOf(runDir, {\n      path: entry.path,\n      kind: entry.kind,\n      description: entry.description,\n      producedBy: entry['produced-by'] ?? [],\n      declared: true,\n    }),\n  );\n  const claimed = new Set(declared.map((entry) => entry.path));\n  let names: fs.Dirent[];\n  try {\n    names = fs.readdirSync(runDir, { withFileTypes: true });\n  } catch {\n    return declared; // The directory is gone; the declaration is still worth showing.\n  }\n  const found = names\n    .filter((entry) => !claimed.has(entry.name))\n    .map((entry) =>\n      viewOf(runDir, {\n        path: entry.name,\n        kind: entry.isDirectory() ? 'directory' : 'file',\n        description: '',\n        producedBy: [],\n        declared: false,\n      }),\n    )\n    .sort((left, right) => left.path.localeCompare(right.path));\n  return [...declared, ...found];\n}\n\n/** Browser content type inferred from a filename without trusting client input. */\nfunction artifactMimeType(requested: string): string {\n  return ARTIFACT_MIME_TYPES[path.extname(requested).toLowerCase()] ?? 'application/octet-stream';\n}\n\nfunction isTextArtifact(mimeType: string): boolean {\n  return mimeType.startsWith('text/') || mimeType === 'application/json' || mimeType === 'application/xml';\n}\n\n/** One artifact's metadata and bounded text, or undefined when it is not readable. */\nfunction readArtifact(resolved: string, requested: string): WorkflowArtifactContentResponse | undefined {\n  const stats = statOf(resolved);\n  if (stats === undefined || stats.isDirectory()) return undefined;\n  const mimeType = artifactMimeType(requested);\n  let text: string | undefined;\n  if (isTextArtifact(mimeType)) {\n    try {\n      const handle = fs.openSync(resolved, 'r');\n      try {\n        const buffer = Buffer.alloc(Math.min(stats.size, MAX_ARTIFACT_BYTES));\n        fs.readSync(handle, buffer, 0, buffer.length, 0);\n        text = buffer.toString('utf8');\n      } finally {\n        fs.closeSync(handle);\n      }\n    } catch {\n      return undefined;\n    }\n  }\n  return {\n    path: requested,\n    size: stats.size,\n    modifiedAt: stats.mtime.toISOString(),\n    mimeType,\n    ...(text === undefined ? {} : { text }),\n    truncated: text !== undefined && stats.size > MAX_ARTIFACT_BYTES,\n  };\n}\n\n/** Streams media with byte-range support so browser audio, video, and PDF controls can seek. */\nfunction streamArtifact(\n  resolved: string,\n  requested: string,\n  rangeHeader: string | undefined,\n  download: boolean,\n): Response | undefined {\n  const stats = statOf(resolved);\n  if (stats === undefined || stats.isDirectory()) return undefined;\n  const mimeType = artifactMimeType(requested);\n  let start = 0;\n  let end = Math.max(0, stats.size - 1);\n  let partial = false;\n  const match = rangeHeader?.match(/^bytes=(\\d*)-(\\d*)$/);\n  if (match !== null && match !== undefined && stats.size > 0) {\n    const requestedStart = match[1] === '' ? undefined : Number(match[1]);\n    const requestedEnd = match[2] === '' ? undefined : Number(match[2]);\n    if (requestedStart === undefined && requestedEnd !== undefined) {\n      start = Math.max(0, stats.size - requestedEnd);\n    } else if (requestedStart !== undefined) {\n      start = requestedStart;\n      end = requestedEnd === undefined ? end : Math.min(requestedEnd, end);\n    }\n    if (start >= stats.size || start > end) {\n      return new Response(null, { status: 416, headers: { 'content-range': `bytes */${String(stats.size)}` } });\n    }\n    partial = true;\n  }\n  const filename = path.basename(requested).replace(/[\"\\\\\\r\\n]/g, '_');\n  const forceDownload = download || mimeType === 'text/html';\n  const headers = new Headers({\n    'accept-ranges': 'bytes',\n    'content-disposition': `${forceDownload ? 'attachment' : 'inline'}; filename=\"${filename}\"`,\n    'content-length': String(stats.size === 0 ? 0 : end - start + 1),\n    'content-type': mimeType,\n    'x-content-type-options': 'nosniff',\n  });\n  if (partial) headers.set('content-range', `bytes ${String(start)}-${String(end)}/${String(stats.size)}`);\n  if (stats.size === 0) return new Response(null, { status: 200, headers });\n  const body = Readable.toWeb(fs.createReadStream(resolved, { start, end }));\n  return new Response(body, { status: partial ? 206 : 200, headers });\n}\n\n/** The named export a host imports from this package's built hub entry. */\nexport const api: DoomApi = {\n  basePath: WORKFLOW_API_BASE_PATH,\n  start(_context: DoomApiContext): DoomApiHandler {\n    // Hub-scoped: the host hands no session, and these routes want none. A run\n    // is addressed by its registry identity, which is machine-wide.\n    const app = createWorkflowHubApi();\n    return {\n      fetch: (request) => app.fetch(request),\n      // Nothing outlives a request: a stream's loop ends when its own socket\n      // aborts, and the caches it touched are per run rather than per client.\n      close: () => undefined,\n    };\n  },\n};\n"],"mappings":"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"}