@workerdeck/server 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.mts +6 -4
- package/build/index.mjs +15 -12
- package/build/index.mjs.map +1 -1
- package/package.json +13 -13
package/build/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["resolvePath","#records","#ttlMs","#byCwd","#resolve","#maxFileBytes","#maxSessionBytes","#bySession","#verdicts","#warned","#opts","#options","#bridge","#sessions","#options","#chains","#emit","#send","#deliver","#options","#configs","#rememberDormant","#persistLive","#track","#forget","#park","#closed","#detachTimers","#owners","#settled","#queue","#storeOps","#resume","#clearTimer","#remembered","#timers","#forgetDormant","#resuming","#rebuild","#bySession","#declared","#declaredByName","#stored","#opts","#profiles","#options","#sessions","profiles"],"sources":["../src/lib/http.ts","../src/lib/profile-env.ts","../src/lib/parse-route.ts","../src/routes/executions.ts","../src/services/host-files.ts","../src/services/host-file-search.ts","../src/routes/host-files.ts","../src/routes/create-vet.ts","../src/routes/jobs.ts","../src/routes/profiles.ts","../src/routes/sdk-sessions.ts","../src/services/session-store.ts","../src/routes/attachments.ts","../src/routes/mcp.ts","../src/routes/produced-files.ts","../src/services/project-info.ts","../src/routes/project-icon.ts","../src/routes/tool-results.ts","../src/routes/sessions.ts","../src/routes/ws.ts","../src/services/attachments.ts","../src/lib/scope.ts","../src/services/auth.ts","../src/services/availability.ts","../src/services/bridge.ts","../src/services/notifications.ts","../src/services/parking.ts","../src/services/produced-files.ts","../src/services/profiles.ts","../src/services/profile-usage.ts","../src/services/registry.ts","../src/services/session-factory.ts","../src/server.ts","../src/lib/sandboxed-profile.ts","../src/lib/provider-runner.ts","../src/services/profile-store.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nconst CONTENT_TYPES: Record<string, string> = {\n json: 'application/json; charset=utf-8',\n md: 'text/markdown; charset=utf-8',\n html: 'text/html; charset=utf-8',\n csv: 'text/csv; charset=utf-8',\n xml: 'application/xml; charset=utf-8',\n svg: 'image/svg+xml; charset=utf-8',\n}\n\n// Headers for serving user-controlled bytes (attachments, produced files, sandbox VFS reads):\n// force download and forbid MIME sniffing so a crafted HTML/SVG payload can never execute in the\n// gateway's origin. Every byte-serving route must use this.\nexport function untrustedDownloadHeaders(filename: string, contentType: string, byteLength: number): Record<string, string | number> {\n return {\n 'content-type': contentType,\n 'content-length': byteLength,\n 'content-disposition': `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`,\n 'x-content-type-options': 'nosniff',\n }\n}\n\nexport function json(res: ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body)\n res.writeHead(status, {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n })\n res.end(payload)\n}\n\nexport async function readJsonBody(req: IncomingMessage, maxBytes: number): Promise<Record<string, unknown>> {\n const body = await readRawBody(req, maxBytes)\n if (body.length === 0) {\n return {}\n }\n return JSON.parse(body.toString('utf8')) as Record<string, unknown>\n}\n\nexport async function readRawBody(req: IncomingMessage, maxBytes: number): Promise<Buffer> {\n const chunks: Buffer[] = []\n let size = 0\n for await (const chunk of req) {\n size += (chunk as Buffer).length\n if (size > maxBytes) {\n throw new Error('request body too large')\n }\n chunks.push(chunk as Buffer)\n }\n return Buffer.concat(chunks)\n}\n\nexport function hashBytes(bytes: Buffer): string {\n return createHash('sha256').update(bytes).digest('hex')\n}\n\n// Decoding never fails in Node — invalid bytes become U+FFFD — so a round trip is the only honest test.\nexport function asUtf8(bytes: Buffer): string | null {\n const text = bytes.toString('utf8')\n return Buffer.from(text, 'utf8').equals(bytes) ? text : null\n}\n\nexport function contentTypeFor(filename: string): string {\n const ext = filename.includes('.') ? filename.split('.').pop()!.toLowerCase() : ''\n return CONTENT_TYPES[ext] ?? 'text/plain; charset=utf-8'\n}\n","import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join, resolve as resolvePath, sep } from 'node:path'\nimport type { ProfileConfigSnapshot, ProfileEngine, ProfileInfo } from '@workerdeck/protocol'\n\nexport function isProviderProfile(profile: ProfileInfo): boolean {\n return profile.engine === 'provider'\n}\n\nexport function engineOf(profile: ProfileInfo | undefined): ProfileEngine {\n return profile?.engine ?? 'claude'\n}\n\nexport function cliConfigDir(env: Record<string, string | undefined>): string {\n return env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude')\n}\n\nexport function detectDefaultProfiles(): ProfileInfo[] {\n const dir = cliConfigDir(process.env)\n return existsSync(dir) ? [{ name: 'default', configDir: dir }] : []\n}\n\nexport function canonicalDir(path: string): string {\n try {\n return realpathSync(path)\n } catch {\n return resolvePath(path)\n }\n}\n\n// Skipping the pin is load-bearing: CLAUDE_CONFIG_DIR set at all moves the CLI off the macOS Keychain.\nexport function claudeSessionEnv(profile: ProfileInfo, base: Record<string, string | undefined>): Record<string, string | undefined> {\n return canonicalDir(profile.configDir!) === canonicalDir(cliConfigDir(base)) ? base : { ...base, CLAUDE_CONFIG_DIR: profile.configDir! }\n}\n\nexport function cwdAllowed(cwd: string, roots: string[] | undefined): boolean {\n if (!roots || roots.length === 0) {\n return true\n }\n const resolved = resolvePath(cwd)\n return roots.some((root) => {\n const r = resolvePath(root)\n return resolved === r || resolved.startsWith(r + sep)\n })\n}\n\n// Env var VALUES are never read into this snapshot — names only.\nexport function readProfileConfig(profile: ProfileInfo): ProfileConfigSnapshot {\n const dir = profile.configDir\n if (!dir) {\n return { hasUserMemory: false, skills: [], agents: [], commands: [] }\n }\n const listDirs = (path: string): string[] => {\n try {\n return readdirSync(path, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort()\n } catch {\n return []\n }\n }\n const listMd = (path: string): string[] => {\n try {\n return readdirSync(path)\n .filter((file) => file.endsWith('.md'))\n .map((file) => file.slice(0, -3))\n .sort()\n } catch {\n return []\n }\n }\n const snapshot: ProfileConfigSnapshot = {\n hasUserMemory: existsSync(join(dir, 'CLAUDE.md')),\n skills: listDirs(join(dir, 'skills')),\n agents: listMd(join(dir, 'agents')),\n commands: listMd(join(dir, 'commands')),\n }\n try {\n const raw = JSON.parse(readFileSync(join(dir, 'settings.json'), 'utf8')) as Record<string, unknown>\n const permissions = (raw.permissions ?? {}) as Record<string, unknown>\n const count = (rules: unknown): number => (Array.isArray(rules) ? rules.length : 0)\n snapshot.settings = {\n model: typeof raw.model === 'string' ? raw.model : undefined,\n defaultPermissionMode: typeof permissions.defaultMode === 'string' ? permissions.defaultMode : undefined,\n permissionRules: {\n allow: count(permissions.allow),\n ask: count(permissions.ask),\n deny: count(permissions.deny),\n },\n envKeys: raw.env && typeof raw.env === 'object' ? Object.keys(raw.env).sort() : undefined,\n hooks: raw.hooks && typeof raw.hooks === 'object' ? Object.keys(raw.hooks).sort() : undefined,\n }\n } catch {}\n return snapshot\n}\n","export type SessionRoute = {\n id?: string\n ws?: boolean\n permissionId?: string\n files?: boolean\n filePath?: string\n attachments?: boolean\n attachmentId?: string\n mcp?: boolean\n mcpServer?: string\n produced?: boolean\n producedFileId?: string\n resultSeq?: number\n projectIcon?: boolean\n}\n\nexport function parseSessionRoute(basePath: string, url: string): SessionRoute | null {\n const pathname = new URL(url, 'http://internal').pathname\n if (!pathname.startsWith(basePath + '/sessions')) {\n return null\n }\n const rest = pathname.slice((basePath + '/sessions').length)\n if (rest === '' || rest === '/') {\n return {}\n }\n const parts = rest.replace(/^\\//, '').split('/')\n if (parts.length === 1) {\n return { id: decodeURIComponent(parts[0]!) }\n }\n if (parts.length === 2 && parts[1] === 'ws') {\n return { id: decodeURIComponent(parts[0]!), ws: true }\n }\n if (parts.length === 3 && parts[1] === 'permissions') {\n return { id: decodeURIComponent(parts[0]!), permissionId: decodeURIComponent(parts[2]!) }\n }\n if (parts.length <= 3 && parts[1] === 'attachments') {\n return {\n id: decodeURIComponent(parts[0]!),\n attachments: true,\n attachmentId: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length <= 3 && parts[1] === 'produced') {\n return {\n id: decodeURIComponent(parts[0]!),\n produced: true,\n producedFileId: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length === 3 && parts[1] === 'project' && parts[2] === 'icon') {\n return { id: decodeURIComponent(parts[0]!), projectIcon: true }\n }\n if (parts.length === 4 && parts[1] === 'events' && parts[3] === 'result') {\n const seq = Number(parts[2])\n if (!Number.isInteger(seq) || seq < 0) {\n return null\n }\n return { id: decodeURIComponent(parts[0]!), resultSeq: seq }\n }\n if (parts.length <= 3 && parts[1] === 'mcp') {\n // MCP server names are opaque and may contain ':' (plugin:gtm:gtm) — one segment, decoded whole.\n return {\n id: decodeURIComponent(parts[0]!),\n mcp: true,\n mcpServer: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length >= 2 && parts[1] === 'files') {\n const filePath = parts.slice(2).map(decodeURIComponent).join('/')\n return {\n id: decodeURIComponent(parts[0]!),\n files: true,\n filePath: filePath === '' ? undefined : '/' + filePath,\n }\n }\n return null\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ToolExecutionResult } from '@workerdeck/core'\nimport type { SubmitExecutionResultRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleExecutionResult(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, basePath, parking, registry } = ctx\n const rest = pathname.slice((basePath + '/executions/').length).split('/')\n if (rest.length !== 2 || rest[1] !== 'result' || !rest[0]) {\n json(res, 404, { error: 'not found' })\n return\n }\n if (req.method !== 'POST') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const executionId = decodeURIComponent(rest[0])\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as SubmitExecutionResultRequest\n let result: ToolExecutionResult\n if (body?.status === 'ok') {\n if (!body.output || typeof body.output !== 'object') {\n json(res, 400, { error: \"output is required for status 'ok'\" })\n return\n }\n result = { status: 'ok', output: body.output.value, logs: body.logs }\n } else if (body?.status === 'failed') {\n if (typeof body.reason !== 'string' || typeof body.error !== 'string') {\n json(res, 400, { error: \"reason and error are required for status 'failed'\" })\n return\n }\n result = { status: 'failed', reason: body.reason, error: body.error, logs: body.logs }\n } else {\n json(res, 400, { error: \"status must be 'ok' or 'failed'\" })\n return\n }\n if (auth.allowedProfiles || auth.scope || ctx.options.authorizeSession) {\n const owner = parking.sessionFor(executionId)\n const info = owner === undefined ? undefined : (registry.get(owner)?.info() ?? (await parking.get(owner))?.info)\n const profile = info?.profile\n // Indistinguishable from an unknown id on purpose: whether an execution exists elsewhere is not this caller's business.\n // A vanished session (`info === undefined`) refuses too — nobody passed canSee, and submitResult would disclose the owner id.\n const refused =\n owner === undefined ||\n info === undefined ||\n (auth.allowedProfiles !== undefined && profile !== undefined && !auth.allowedProfiles.includes(profile)) ||\n !authSvc.canSee(auth, info)\n if (refused) {\n json(res, 404, { error: 'execution not found' })\n return\n }\n }\n const applied = await parking.submitResult(executionId, result)\n if (!applied) {\n json(res, 404, { error: 'execution not found (unknown id, or its session has ended)' })\n return\n }\n json(res, 200, applied)\n}\n","import type { Dirent } from 'node:fs'\nimport { closeSync, constants, fstatSync, ftruncateSync, lstatSync, openSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, relative, sep } from 'node:path'\n\n// win32 lacks O_NOFOLLOW/O_NONBLOCK (undefined at runtime despite the typing): there they contribute 0 and the fstat gates stand alone.\nconst O_NOFOLLOW: number = constants.O_NOFOLLOW ?? 0\nconst O_NONBLOCK: number = constants.O_NONBLOCK ?? 0\n\nexport type HostFileRoot = {\n readonly configured: string\n readonly canonical: string\n}\n\nexport type HostFileRoots = { readonly roots: readonly HostFileRoot[] }\n\nexport function createHostFileRoots(roots: string[]): HostFileRoots {\n return {\n roots: roots.map((configured) => {\n if (invalidRequest(configured)) {\n throw new Error(`createHostFileRoots: root must be an absolute path: ${JSON.stringify(configured)}`)\n }\n let canonical: string\n try {\n canonical = realpathSync(configured)\n } catch {\n throw new Error(`createHostFileRoots: root does not exist: ${configured}`)\n }\n if (!lstatSync(canonical).isDirectory()) {\n throw new Error(`createHostFileRoots: root is not a directory: ${configured}`)\n }\n return { configured, canonical }\n }),\n }\n}\n\nexport type ResolveOutcome =\n | { ok: true; path: string; root: string; kind: 'file' | 'dir' }\n | { ok: false; status: 403 | 404; error: string }\n\ntype Refusal = { ok: false; status: 403 | 404; error: string }\n\nfunction refuse(status: 403 | 404, error: string): Refusal {\n return { ok: false, status, error }\n}\n\nfunction notFound(): Refusal {\n return refuse(404, 'not found')\n}\n\n// NUL is rejected before any fs call: Node throws a TypeError on one, and that must surface as a refusal rather than a 500.\nfunction invalidRequest(requested: string): boolean {\n return requested.length === 0 || requested.includes('\\0') || !isAbsolute(requested)\n}\n\n// A bare prefix check gets the boundary wrong (`/x/app` would swallow `/x/application`); both sides must be realpath output.\nexport function contained(rootCanonical: string, candidate: string): boolean {\n const rel = relative(rootCanonical, candidate)\n return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel))\n}\n\nfunction rootContaining(roots: HostFileRoots, canonical: string): HostFileRoot | undefined {\n return roots.roots.find((root) => contained(root.canonical, canonical))\n}\n\nexport function resolveExisting(roots: HostFileRoots, requested: string): ResolveOutcome {\n if (invalidRequest(requested)) {\n return refuse(403, 'invalid path')\n }\n let canonical: string\n try {\n canonical = realpathSync(requested)\n } catch {\n return notFound()\n }\n const root = rootContaining(roots, canonical)\n if (!root) {\n return notFound()\n }\n let target\n try {\n // realpath output cannot name a symlink, so lstat === stat modulo a race — and a swap inside the window then classifies as neither.\n target = lstatSync(canonical)\n } catch {\n return notFound()\n }\n if (target.isFile()) {\n return { ok: true, path: canonical, root: root.canonical, kind: 'file' }\n }\n if (target.isDirectory()) {\n return { ok: true, path: canonical, root: root.canonical, kind: 'dir' }\n }\n return refuse(403, 'not a regular file or directory')\n}\n\n// Only the final component may be new: a missing target canonicalizes its parent, so a dangling symlink sitting there is refused, not created through.\nexport function resolveForWrite(roots: HostFileRoots, requested: string): ResolveOutcome {\n if (invalidRequest(requested)) {\n return refuse(403, 'invalid path')\n }\n try {\n const canonical = realpathSync(requested)\n const root = rootContaining(roots, canonical)\n if (!root) {\n return notFound()\n }\n const target = lstatSync(canonical)\n if (target.isDirectory()) {\n return refuse(403, 'is a directory')\n }\n if (!target.isFile()) {\n return refuse(403, 'not a regular file')\n }\n return { ok: true, path: canonical, root: root.canonical, kind: 'file' }\n } catch {}\n const base = basename(requested)\n if (base === '' || base === '.' || base === '..') {\n return refuse(403, 'invalid path')\n }\n let parent: string\n try {\n parent = realpathSync(dirname(requested))\n } catch {\n return notFound()\n }\n const root = rootContaining(roots, parent)\n if (!root) {\n return notFound()\n }\n try {\n if (!lstatSync(parent).isDirectory()) {\n return notFound()\n }\n } catch {\n return notFound()\n }\n const path = join(parent, base)\n // Redundant by construction (basename() cannot smuggle a separator) — kept because this is the line an escape would have to cross.\n if (!contained(root.canonical, path)) {\n return notFound()\n }\n try {\n lstatSync(path)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { ok: true, path, root: root.canonical, kind: 'file' }\n }\n return notFound()\n }\n return notFound()\n}\n\nexport type HostEntryKind = 'file' | 'dir' | 'symlink' | 'other'\n\nexport function entryKind(entry: Dirent): HostEntryKind {\n if (entry.isSymbolicLink()) {\n return 'symlink'\n }\n if (entry.isFile()) {\n return 'file'\n }\n if (entry.isDirectory()) {\n return 'dir'\n }\n return 'other'\n}\n\nexport type ReadOutcome = { ok: true; data: Buffer } | Refusal\n\nexport function readContained(path: string): ReadOutcome {\n let fd: number\n try {\n fd = openSync(path, constants.O_RDONLY | O_NOFOLLOW | O_NONBLOCK)\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT' ? notFound() : refuse(403, 'refused')\n }\n try {\n if (!fstatSync(fd).isFile()) {\n return refuse(403, 'not a regular file')\n }\n return { ok: true, data: readFileSync(fd) }\n } catch {\n return refuse(403, 'refused')\n } finally {\n closeSync(fd)\n }\n}\n\nexport type WriteOutcome = { ok: true } | Refusal\n\nexport function writeContained(path: string, data: string | Uint8Array): WriteOutcome {\n let fd: number\n try {\n fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | O_NOFOLLOW | O_NONBLOCK, 0o644)\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT' ? notFound() : refuse(403, 'refused')\n }\n try {\n if (!fstatSync(fd).isFile()) {\n return refuse(403, 'not a regular file')\n }\n ftruncateSync(fd)\n writeFileSync(fd, data)\n return { ok: true }\n } catch {\n return refuse(403, 'refused')\n } finally {\n closeSync(fd)\n }\n}\n","import { readdirSync } from 'node:fs'\nimport { join, relative } from 'node:path'\nimport { entryKind } from './host-files.ts'\n\nexport const DEFAULT_IGNORED_DIRS = [\n '.git',\n '.hg',\n '.svn',\n 'node_modules',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.turbo',\n '.cache',\n 'dist',\n 'build',\n 'out',\n 'target',\n '.venv',\n 'venv',\n '__pycache__',\n '.pytest_cache',\n '.gradle',\n 'Pods',\n 'DerivedData',\n // Swift Package Manager: its object files carry the source names, so `@` answers `Transcript.o` before `Transcript.swift` without this.\n '.build',\n]\n\nexport type FoundFile = {\n path: string\n relative: string\n}\n\nexport type SearchResult = {\n matches: FoundFile[]\n truncated: boolean\n}\n\nexport type SearchOptions = {\n query?: string\n limit?: number\n ignore?: readonly string[]\n maxScanned?: number\n}\n\nexport function searchFiles(base: string, options: SearchOptions = {}): SearchResult {\n const limit = options.limit ?? 50\n const maxScanned = options.maxScanned ?? 20_000\n const ignore = new Set(options.ignore ?? DEFAULT_IGNORED_DIRS)\n const needle = (options.query ?? '').toLowerCase()\n\n const found: { file: FoundFile; score: number; depth: number }[] = []\n const queue: { dir: string; depth: number }[] = [{ dir: base, depth: 0 }]\n let scanned = 0\n let exhausted = true\n\n while (queue.length > 0) {\n const { dir, depth } = queue.shift()!\n let entries\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n continue\n }\n for (const entry of entries) {\n if (++scanned > maxScanned) {\n exhausted = false\n queue.length = 0\n break\n }\n const kind = entryKind(entry)\n if (kind === 'dir') {\n if (!ignore.has(entry.name)) {\n queue.push({ dir: join(dir, entry.name), depth: depth + 1 })\n }\n continue\n }\n if (kind !== 'file') {\n continue\n }\n const path = join(dir, entry.name)\n const rel = relative(base, path)\n const score = scoreMatch(rel, entry.name, needle)\n if (score !== null) {\n found.push({ file: { path, relative: rel }, score, depth })\n }\n }\n }\n\n found.sort(\n (a, b) =>\n b.score - a.score ||\n a.depth - b.depth ||\n a.file.relative.length - b.file.relative.length ||\n a.file.relative.localeCompare(b.file.relative),\n )\n return {\n matches: found.slice(0, limit).map((f) => f.file),\n truncated: !exhausted || found.length > limit,\n }\n}\n\nfunction scoreMatch(relativePath: string, name: string, needle: string): number | null {\n if (needle === '') {\n return 0\n }\n const inName = subsequenceScore(name.toLowerCase(), needle)\n if (inName !== null) {\n return inName + 1000\n }\n return subsequenceScore(relativePath.toLowerCase(), needle)\n}\n\nfunction subsequenceScore(haystack: string, needle: string): number | null {\n let score = 0\n let from = 0\n let previous = -2\n for (const char of needle) {\n const at = haystack.indexOf(char, from)\n if (at === -1) {\n return null\n }\n if (at === previous + 1) {\n score += 8\n }\n if (at === 0) {\n score += 4\n }\n from = at + 1\n previous = at\n }\n // Shorter haystacks matched the same needle more tightly.\n return score - haystack.length / 100\n}\n","import { lstatSync, readdirSync, type Dirent } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { WriteHostFileRequest } from '@workerdeck/protocol'\nimport { asUtf8, hashBytes, json, readJsonBody } from '../lib/http.ts'\nimport { searchFiles } from '../services/host-file-search.ts'\nimport { entryKind, readContained, resolveExisting, resolveForWrite, writeContained } from '../services/host-files.ts'\nimport type { ServerContext } from '../context.ts'\n\nfunction kindRank(type: string): number {\n return type === 'dir' ? 0 : 1\n}\n\nexport async function handleHostFiles(ctx: ServerContext, req: IncomingMessage, res: ServerResponse, pathname: string): Promise<void> {\n const { basePath, hostFiles, hostFilesWritable, maxHostFileBytes, maxHostDirEntries } = ctx\n if (!hostFiles) {\n json(res, 404, { error: 'host file access is not configured on this server' })\n return\n }\n const route = pathname.slice((basePath + '/fs/').length)\n const url = new URL(req.url ?? '/', 'http://internal')\n const requested = url.searchParams.get('path')\n\n if (route === 'roots') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n // The canonical spelling, not the operator's: a client round-tripping a root it was given must land on the same tree.\n json(res, 200, {\n roots: hostFiles.roots.map(({ canonical }) => ({\n path: canonical,\n name: basename(canonical) || canonical,\n })),\n canWrite: hostFilesWritable,\n })\n return\n }\n\n if (route === 'find') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!requested) {\n json(res, 400, { error: 'path is required' })\n return\n }\n const resolved = resolveExisting(hostFiles, requested)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n if (resolved.kind !== 'dir') {\n json(res, 400, { error: 'not a directory' })\n return\n }\n // Clamped, not validated: this runs per keystroke from a phone.\n const asked = Number(url.searchParams.get('limit') ?? '')\n const limit = Number.isFinite(asked) && asked > 0 ? Math.min(asked, 200) : 50\n const result = searchFiles(resolved.path, {\n query: url.searchParams.get('q') ?? '',\n limit,\n ignore: ctx.options.hostFiles?.ignore,\n })\n json(res, 200, { base: resolved.path, ...result })\n return\n }\n\n if (route === 'list' || route === 'read') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!requested) {\n json(res, 400, { error: 'path is required' })\n return\n }\n const resolved = resolveExisting(hostFiles, requested)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n if (route === 'list') {\n if (resolved.kind !== 'dir') {\n json(res, 400, { error: 'not a directory' })\n return\n }\n let names: Dirent[]\n try {\n names = readdirSync(resolved.path, { withFileTypes: true })\n } catch {\n json(res, 403, { error: 'directory is not readable' })\n return\n }\n const truncated = names.length > maxHostDirEntries\n const entries = names.slice(0, maxHostDirEntries).map((entry) => {\n const path = join(resolved.path, entry.name)\n const type = entryKind(entry)\n // Never stat *through* a link: a directory holding a link to a fifo would become unlistable.\n let bytes: number | undefined\n let modifiedAt: number | undefined\n if (type === 'file') {\n try {\n const s = lstatSync(path)\n bytes = s.size\n modifiedAt = s.mtimeMs\n } catch {}\n }\n return { name: entry.name, path, type, bytes, modifiedAt }\n })\n entries.sort((a, b) => kindRank(a.type) - kindRank(b.type) || a.name.localeCompare(b.name))\n json(res, 200, { path: resolved.path, entries, ...(truncated ? { truncated } : {}) })\n return\n }\n\n if (resolved.kind !== 'file') {\n json(res, 400, { error: 'not a regular file' })\n return\n }\n // Advisory pre-check only — the authoritative cap is on the bytes actually read, since the file can grow before the open.\n let modifiedAt = 0\n try {\n const stats = lstatSync(resolved.path)\n if (stats.size > maxHostFileBytes) {\n json(res, 413, { error: `file is larger than ${maxHostFileBytes} bytes` })\n return\n }\n modifiedAt = stats.mtimeMs\n } catch {\n json(res, 404, { error: 'not found' })\n return\n }\n const read = readContained(resolved.path)\n if (!read.ok) {\n json(res, read.status, { error: read.error })\n return\n }\n if (read.data.length > maxHostFileBytes) {\n json(res, 413, { error: `file is larger than ${maxHostFileBytes} bytes` })\n return\n }\n const text = asUtf8(read.data)\n json(res, 200, {\n path: resolved.path,\n content: text ?? read.data.toString('base64'),\n encoding: text === null ? 'base64' : 'utf8',\n bytes: read.data.length,\n hash: hashBytes(read.data),\n modifiedAt,\n })\n return\n }\n\n if (route === 'write') {\n if (req.method !== 'PUT') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!hostFilesWritable) {\n json(res, 403, { error: 'host file writes are not enabled on this server' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as WriteHostFileRequest\n if (!body.path || typeof body.path !== 'string') {\n json(res, 400, { error: 'path is required' })\n return\n }\n if (typeof body.content !== 'string') {\n json(res, 400, { error: 'content is required' })\n return\n }\n if (body.encoding !== undefined && body.encoding !== 'utf8' && body.encoding !== 'base64') {\n json(res, 400, { error: \"encoding must be 'utf8' or 'base64'\" })\n return\n }\n const resolved = resolveForWrite(hostFiles, body.path)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n const next = Buffer.from(body.content, body.encoding ?? 'utf8')\n if (next.length > maxHostFileBytes) {\n json(res, 413, { error: `content is larger than ${maxHostFileBytes} bytes` })\n return\n }\n // Existence is decided by the read, not a stat: only ENOENT is 404, so anything else refuses rather than being clobbered as a create.\n const current = readContained(resolved.path)\n if (!current.ok && current.status !== 404) {\n json(res, current.status, { error: current.error })\n return\n }\n const existing = current.ok ? current.data : null\n if (existing && !body.expectedHash) {\n json(res, 409, { error: 'file exists — pass expectedHash to overwrite it' })\n return\n }\n if (existing && hashBytes(existing) !== body.expectedHash) {\n json(res, 409, { error: 'file changed on disk since it was read' })\n return\n }\n if (!existing && body.expectedHash) {\n json(res, 409, { error: 'file no longer exists' })\n return\n }\n const written = writeContained(resolved.path, next)\n if (!written.ok) {\n json(res, written.status, { error: written.error })\n return\n }\n let writtenAt = 0\n try {\n writtenAt = lstatSync(resolved.path).mtimeMs\n } catch {}\n json(res, 200, {\n path: resolved.path,\n bytes: next.length,\n hash: hashBytes(next),\n modifiedAt: writtenAt,\n })\n return\n }\n\n json(res, 404, { error: 'not found' })\n}\n","import type { CreateSessionRequest } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\nimport type { AuthContext } from '../services/auth.ts'\n\n/**\n * The one create-validation ladder, run by both create doors — `POST /sessions` and the\n * `session` block of `POST /jobs`. The scope design claims the two are indistinguishable, so\n * the order and the refusals have to come from a single place rather than two copies that can\n * drift. Mutates `req`: strips inert fields and pins the resolved profile name.\n */\nexport function vetCreateRequest(\n ctx: ServerContext,\n req: CreateSessionRequest,\n auth: AuthContext,\n): { status: number; error: string } | null {\n const { availability, factory } = ctx\n const refusedScope = factory.applyScope(req, auth)\n if (refusedScope) {\n return refusedScope\n }\n const refused = factory.applyBypassPolicy(req)\n if (refused) {\n return { status: 403, error: refused }\n }\n const resolved = factory.resolveProfile(req.profile, auth.allowedProfiles)\n if (!resolved.ok) {\n return { status: resolved.status, error: resolved.error }\n }\n const unavailable = availability.checkAvailable(resolved.profile)\n if (unavailable) {\n return unavailable\n }\n const refusedCwd = factory.checkCwd(req, resolved.profile)\n if (refusedCwd) {\n return refusedCwd\n }\n const badRequest = factory.checkPermissionMode(req.permissionMode, resolved.profile) ?? factory.checkEngineGrants(req, resolved.profile)\n if (badRequest) {\n return { status: 400, error: badRequest }\n }\n factory.stripInertFields(req, resolved.profile)\n req.profile = resolved.profile?.name\n return null\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { CreateJobRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport { vetCreateRequest } from './create-vet.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleJobs(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, basePath, queue } = ctx\n if (!queue) {\n json(res, 404, { error: 'job queue not configured' })\n return\n }\n if (pathname === basePath + '/queue') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!authSvc.isOperator(auth)) {\n json(res, 404, { error: 'not found' })\n return\n }\n json(res, 200, { stats: await queue.stats() })\n return\n }\n const rest = pathname.slice((basePath + '/jobs').length).replace(/^\\//, '')\n if (rest === '') {\n if (req.method === 'GET') {\n const jobs = await queue.list()\n json(res, 200, { jobs: jobs.filter((job) => authSvc.canSeeJob(auth, job)) })\n return\n }\n if (req.method === 'POST') {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as CreateJobRequest\n if (!body.session || typeof body.session !== 'object') {\n json(res, 400, { error: 'session is required' })\n return\n }\n if (!body.session.prompt || typeof body.session.prompt !== 'string') {\n json(res, 400, { error: 'session.prompt is required' })\n return\n }\n const refusal = vetCreateRequest(ctx, body.session, auth)\n if (refusal) {\n json(res, refusal.status, { error: refusal.error })\n return\n }\n try {\n json(res, 201, { job: await queue.submit(body) })\n } catch (error) {\n json(res, 400, { error: error instanceof Error ? error.message : 'invalid job' })\n }\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const id = decodeURIComponent(rest)\n if (id.includes('/')) {\n json(res, 404, { error: 'not found' })\n return\n }\n if (req.method === 'GET') {\n const job = await queue.get(id)\n if (job && authSvc.canSeeJob(auth, job)) {\n json(res, 200, { job })\n } else {\n json(res, 404, { error: 'job not found' })\n }\n return\n }\n if (req.method === 'DELETE') {\n // Checked before the cancel: a refused caller must not be able to kill a run and then be told it does not exist.\n const existing = await queue.get(id)\n if (!existing || !authSvc.canSeeJob(auth, existing)) {\n json(res, 404, { error: 'job not found' })\n return\n }\n const job = await queue.cancel(id)\n if (job) {\n json(res, 200, { job })\n } else {\n json(res, 404, { error: 'job not found' })\n }\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ProfileInfo, UpdateProfileRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport { readProfileConfig } from '../lib/profile-env.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleProfiles(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, availability, basePath, profiles } = ctx\n const saveManaged = async (incoming: ProfileInfo): Promise<void> => {\n const saved = await profiles.saveManaged(incoming)\n if (!saved.ok) {\n json(res, saved.status, { error: saved.error })\n } else {\n json(res, 200, { profile: saved.profile })\n }\n }\n const rest = pathname.slice((basePath + '/profiles').length).replace(/^\\//, '')\n if (rest === '') {\n if (req.method === 'GET') {\n const visible = auth.allowedProfiles ? profiles.all().filter((p) => auth.allowedProfiles!.includes(p.name)) : profiles.all()\n availability.refresh(visible)\n json(res, 200, {\n profiles: visible.map((p) => profiles.forResponse(p)),\n canManage: profiles.manageGuard(auth) === null,\n })\n return\n }\n if (req.method === 'POST') {\n const refused = profiles.manageGuard(auth)\n if (refused) {\n json(res, refused.status, { error: refused.error })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as ProfileInfo\n if (!body.name || typeof body.name !== 'string') {\n json(res, 400, { error: 'name is required' })\n return\n }\n if (profiles.get(body.name)) {\n json(res, 409, { error: `profile already exists: ${body.name}` })\n return\n }\n await saveManaged(body)\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const name = decodeURIComponent(rest)\n const profile = name.includes('/') ? undefined : profiles.get(name)\n if (!profile) {\n json(res, 404, { error: 'profile not found' })\n return\n }\n if (auth.allowedProfiles && !auth.allowedProfiles.includes(profile.name)) {\n json(res, 403, { error: `profile not allowed: ${profile.name}` })\n return\n }\n if (req.method === 'GET') {\n json(res, 200, {\n profile: profiles.forResponse(profile),\n config: authSvc.isOperator(auth) ? readProfileConfig(profile) : undefined,\n })\n return\n }\n if (req.method === 'PATCH' || req.method === 'DELETE') {\n const refused = profiles.manageGuard(auth) ?? profiles.declaredGuard(profile)\n if (refused) {\n json(res, refused.status, { error: refused.error })\n return\n }\n if (req.method === 'DELETE') {\n await ctx.options.profileStore!.delete(profile.name)\n await profiles.refreshStored()\n res.writeHead(204).end()\n return\n }\n const patch = (await readJsonBody(req, ctx.maxBodyBytes)) as UpdateProfileRequest\n await saveManaged({ ...profile, ...patch, name: profile.name })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ProfileInfo, SdkSessionSummary } from '@workerdeck/protocol'\nimport { json } from '../lib/http.ts'\nimport { cwdAllowed, engineOf } from '../lib/profile-env.ts'\nimport type { SdkSessionLister } from '../options.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\n// A summary with no `cwd` cannot be shown to be inside the roots, so it is dropped.\nfunction withinRoots(sessions: SdkSessionSummary[], roots: string[], limit?: number, offset = 0): SdkSessionSummary[] {\n const allowed = sessions.filter((s) => s.cwd !== undefined && cwdAllowed(s.cwd, roots)).sort((a, b) => b.lastModified - a.lastModified)\n return limit === undefined ? allowed.slice(offset) : allowed.slice(offset, offset + limit)\n}\n\nexport async function handleSdkSessions(ctx: ServerContext, req: IncomingMessage, res: ServerResponse, auth: AuthContext): Promise<void> {\n const { adapterFor, factory, profiles } = ctx\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const url = new URL(req.url ?? '/', 'http://internal')\n const dir = url.searchParams.get('dir') ?? undefined\n const roots = ctx.options.allowedCwdRoots\n const limit = Number(url.searchParams.get('limit') ?? '') || undefined\n const offset = Number(url.searchParams.get('offset') ?? '') || undefined\n const requested = url.searchParams.get('profile') ?? undefined\n let profile: ProfileInfo | undefined\n if (requested !== undefined) {\n const resolved = factory.resolveProfile(requested, auth.allowedProfiles)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n profile = resolved.profile\n } else {\n // Implicit only when unambiguous AND permitted: a caller scoped away from the one profile falls back to the legacy listing.\n const all = profiles.all()\n if (all.length === 1 && (!auth.allowedProfiles || auth.allowedProfiles.includes(all[0]!.name))) {\n profile = all[0]\n }\n }\n const adapter = adapterFor(profile?.engine)\n if (!adapter.capabilities.listSessions) {\n json(res, 400, {\n error: `profile '${profile?.name ?? 'default'}' runs the ${engineOf(profile)} engine, which has no browsable session store`,\n })\n return\n }\n const lister: SdkSessionLister =\n engineOf(profile) === 'claude' && ctx.listSdkSessions\n ? ctx.listSdkSessions\n : (params) => {\n if (!adapter.listSessions) {\n throw new Error(`the ${engineOf(profile)} engine does not implement session listing`)\n }\n return adapter.listSessions({\n ...params,\n profile,\n env: profile ? factory.sessionEnvFor(profile) : process.env,\n })\n }\n try {\n if (roots && roots.length > 0) {\n if (dir) {\n if (!cwdAllowed(dir, roots)) {\n json(res, 403, { error: 'dir is outside the allowed roots' })\n return\n }\n } else {\n // A bare listing spans every project on the host, so it filters after listing — which is why the paging is applied here too.\n json(res, 200, { sdkSessions: withinRoots(await lister({}), roots, limit, offset) })\n return\n }\n }\n json(res, 200, { sdkSessions: await lister({ dir, limit, offset }) })\n } catch (error) {\n json(res, 500, { error: error instanceof Error ? error.message : 'failed to list sessions' })\n }\n}\n","import { mkdir, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { ParkedExecution, RunnerSnapshot, SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type ParkedSessionRecord = {\n kind?: 'parked' | 'live'\n id: string\n info: SessionInfo\n profile?: string\n config: SessionRunnerConfig\n snapshot: RunnerSnapshot\n executions: ParkedExecution[]\n parkedAt: number\n}\n\nexport function isLiveRecord(record: StoredSessionRecord): boolean {\n return record.kind === 'live'\n}\n\nexport type DormantSessionRecord = {\n kind: 'dormant'\n id: string\n info: SessionInfo\n profile?: string\n config: SessionRunnerConfig\n sdkSessionId: string\n savedAt: number\n}\n\nexport type StoredSessionRecord = ParkedSessionRecord | DormantSessionRecord\n\nexport function isDormant(record: StoredSessionRecord): record is DormantSessionRecord {\n return record.kind === 'dormant'\n}\n\nexport interface SessionStore {\n save(record: StoredSessionRecord): Promise<void>\n get(id: string): Promise<StoredSessionRecord | null>\n list(): Promise<StoredSessionRecord[]>\n delete(id: string): Promise<boolean>\n}\n\nexport class MemorySessionStore implements SessionStore {\n #records = new Map<string, StoredSessionRecord>()\n\n save(record: StoredSessionRecord): Promise<void> {\n this.#records.set(record.id, record)\n return Promise.resolve()\n }\n\n get(id: string): Promise<StoredSessionRecord | null> {\n return Promise.resolve(this.#records.get(id) ?? null)\n }\n\n list(): Promise<StoredSessionRecord[]> {\n return Promise.resolve([...this.#records.values()])\n }\n\n delete(id: string): Promise<boolean> {\n return Promise.resolve(this.#records.delete(id))\n }\n}\n\nconst EPHEMERAL_CONFIG_KEYS = ['queryFn', 'historyFn', 'extraOptions', 'env'] as const\n\nexport function toDurableRecord<T extends StoredSessionRecord>(record: T): T {\n const config: SessionRunnerConfig = { ...record.config }\n for (const key of EPHEMERAL_CONFIG_KEYS) {\n delete config[key]\n }\n return { ...record, config }\n}\n\nconst FORMAT_VERSION = 1\n\nexport type FileSessionStoreOptions = {\n dir?: string\n onError?: (error: unknown, context: { path: string; op: 'save' | 'read' | 'delete' }) => void\n}\n\nexport function createFileSessionStore(options: FileSessionStoreOptions = {}): SessionStore {\n const dir = options.dir ?? join(process.cwd(), '.workerdeck', 'parked')\n // Encoded, not interpolated: an id is a runner-assigned string, and a '/' in one would otherwise write outside `dir`.\n const fileFor = (id: string): string => join(dir, `${encodeURIComponent(id)}.json`)\n\n const read = async (path: string): Promise<StoredSessionRecord | null> => {\n let raw: string\n try {\n raw = await readFile(path, 'utf8')\n } catch (error) {\n // Only absence is \"nothing parked\": reporting an EACCES as one is how a restart guard ends up saying the coast is clear.\n if (isMissing(error)) {\n return null\n }\n options.onError?.(error, { path, op: 'read' })\n return null\n }\n try {\n return parseRecord(JSON.parse(raw))\n } catch (error) {\n options.onError?.(error, { path, op: 'read' })\n return null\n }\n }\n\n return {\n save: async (record) => {\n const path = fileFor(record.id)\n let payload: string\n try {\n payload = JSON.stringify({ version: FORMAT_VERSION, record: toDurableRecord(record) })\n } catch (error) {\n options.onError?.(error, { path, op: 'save' })\n throw new Error(\n `parked session '${record.id}' is not JSON-serializable — a host-injected value ` +\n `reached its config or snapshot: ${String(error)}`,\n { cause: error },\n )\n }\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 })\n const temp = `${path}.${process.pid}.tmp`\n await writeFile(temp, payload, { mode: 0o600 })\n await rename(temp, path)\n } catch (error) {\n options.onError?.(error, { path, op: 'save' })\n throw error\n }\n },\n\n get: (id) => read(fileFor(id)),\n\n list: async () => {\n let names: string[]\n try {\n names = await readdir(dir)\n } catch (error) {\n if (isMissing(error)) {\n return []\n }\n options.onError?.(error, { path: dir, op: 'read' })\n throw error\n }\n const records = await Promise.all(\n names\n .filter((name) => name.endsWith('.json'))\n .map(async (name) => {\n const record = await read(join(dir, name))\n if (!record) {\n return null\n }\n // A record only answers `get`/`delete` under the name its id encodes to; one that arrived some other way would be unreachable.\n if (`${encodeURIComponent(record.id)}.json` === name) {\n return record\n }\n options.onError?.(new Error(`parked record '${record.id}' is stored as '${name}' and cannot be read back by id`), {\n path: join(dir, name),\n op: 'read',\n })\n return null\n }),\n )\n return records.filter((record): record is StoredSessionRecord => record !== null)\n },\n\n delete: async (id) => {\n const path = fileFor(id)\n try {\n await rm(path)\n return true\n } catch (error) {\n if (isMissing(error)) {\n return false\n }\n options.onError?.(error, { path, op: 'delete' })\n return false\n }\n },\n }\n}\n\nfunction isMissing(error: unknown): boolean {\n return (error as NodeJS.ErrnoException).code === 'ENOENT'\n}\n\nfunction parseRecord(value: unknown): StoredSessionRecord | null {\n if (!value || typeof value !== 'object') {\n return null\n }\n const envelope = value as { version?: unknown; record?: unknown }\n if (envelope.version !== FORMAT_VERSION) {\n return null\n }\n const record = envelope.record as Partial<StoredSessionRecord> | null\n if (!record || typeof record !== 'object') {\n return null\n }\n if (typeof record.id !== 'string') {\n return null\n }\n if (!record.info || !record.config) {\n return null\n }\n if (record.kind === 'dormant') {\n const dormant = record as Partial<DormantSessionRecord>\n if (typeof dormant.sdkSessionId !== 'string' || typeof dormant.savedAt !== 'number') {\n return null\n }\n return dormant as DormantSessionRecord\n }\n const parked = record as Partial<ParkedSessionRecord>\n if (typeof parked.parkedAt !== 'number' || !parked.snapshot) {\n return null\n }\n if (!Array.isArray(parked.executions)) {\n return null\n }\n return parked as ParkedSessionRecord\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { attachmentKind } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES, type SessionInfo } from '@workerdeck/protocol'\nimport { json, readRawBody, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleAttachments(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n sessionId: string,\n session: SessionInfo,\n attachmentId?: string,\n): Promise<void> {\n const { attachmentStore } = ctx\n if (req.method === 'POST' && attachmentId === undefined) {\n const url = new URL(req.url ?? '/', 'http://internal')\n const mediaType = req.headers['content-type']\n if (!mediaType) {\n json(res, 400, { error: 'content-type header is required' })\n return\n }\n const accepted = (session.capabilities ?? ENGINE_CAPABILITIES[session.engine ?? 'claude']).attachments\n const kind = attachmentKind(mediaType)\n if (kind && !accepted.includes(kind === 'document' ? 'pdf' : kind)) {\n json(res, 415, {\n error: `the ${session.engine ?? 'claude'} engine does not accept ${kind} attachments`,\n })\n return\n }\n let body: Buffer\n try {\n body = await readRawBody(req, attachmentStore.maxFileBytes)\n } catch {\n json(res, 413, { error: 'attachment is larger than the limit' })\n return\n }\n const result = attachmentStore.put(sessionId, url.searchParams.get('name') ?? 'attachment', mediaType, body)\n if (!result.ok) {\n const status = result.error.code === 'unsupported_type' ? 415 : result.error.code === 'empty' ? 400 : 413\n json(res, status, { error: result.error.message })\n return\n }\n json(res, 201, { attachment: result.attachment })\n return\n }\n if (req.method === 'GET' && attachmentId !== undefined) {\n const found = attachmentStore.get(sessionId, attachmentId)\n if (!found) {\n json(res, 404, { error: 'attachment not found' })\n return\n }\n const bytes = Buffer.from(found.data, 'base64')\n res.writeHead(200, untrustedDownloadHeaders(found.name, found.mediaType, bytes.length))\n res.end(bytes)\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { Runner } from '@workerdeck/core'\nimport type { McpServerActionRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleMcp(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n runner: Runner,\n serverName?: string,\n): Promise<void> {\n const listServers = async (): Promise<boolean> => {\n const servers = await runner.mcpServers?.()\n if (!servers) {\n json(res, 501, { error: 'this session does not report MCP servers' })\n return false\n }\n json(res, 200, { servers })\n return true\n }\n if (req.method === 'GET' && serverName === undefined) {\n await listServers()\n return\n }\n if (req.method === 'POST' && serverName !== undefined) {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as McpServerActionRequest\n if (body?.action !== 'reconnect' && body?.action !== 'enable' && body?.action !== 'disable') {\n json(res, 400, { error: \"action must be 'reconnect', 'enable' or 'disable'\" })\n return\n }\n const canAct =\n body.action === 'reconnect' ? typeof runner.reconnectMcpServer === 'function' : typeof runner.setMcpServerEnabled === 'function'\n if (!canAct) {\n json(res, 501, {\n error: `this session's engine cannot ${body.action} an MCP server`,\n })\n return\n }\n try {\n if (body.action === 'reconnect') {\n await runner.reconnectMcpServer?.(serverName)\n } else {\n await runner.setMcpServerEnabled?.(serverName, body.action === 'enable')\n }\n } catch (error) {\n json(res, 400, { error: error instanceof Error ? error.message : 'MCP action failed' })\n return\n }\n await listServers()\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import { createReadStream, statSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { contentTypeFor, json, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleProducedFiles(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n sessionId: string,\n fileId?: string,\n): Promise<void> {\n const { producedFiles } = ctx\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (fileId === undefined) {\n json(res, 200, {\n files: producedFiles.list(sessionId).map(({ fileId: id, path, mediaType, bytes }) => ({\n fileId: id,\n path,\n ...(mediaType ? { mediaType } : {}),\n ...(bytes !== undefined ? { bytes } : {}),\n })),\n })\n return\n }\n const found = producedFiles.get(sessionId, fileId)\n if (!found) {\n json(res, 404, { error: 'no such produced file' })\n return\n }\n // statSync follows symlinks deliberately: a link the engine created is part of what it produced, and there is no root to realpath against.\n let stat\n try {\n stat = statSync(found.path)\n } catch {\n json(res, 404, { error: 'produced file is no longer on disk' })\n return\n }\n if (!stat.isFile()) {\n json(res, 404, { error: 'produced file is not a regular file' })\n return\n }\n const filename = basename(found.path) || 'file'\n res.writeHead(200, untrustedDownloadHeaders(filename, found.mediaType ?? contentTypeFor(filename), stat.size))\n await new Promise<void>((done) => {\n const stream = createReadStream(found.path)\n stream.on('error', () => {\n res.destroy()\n done()\n })\n stream.on('close', () => done())\n stream.pipe(res)\n })\n}\n","import { createHash } from 'node:crypto'\nimport { lstatSync, realpathSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, resolve } from 'node:path'\nimport type { ProjectIcon, ProjectInfo, SessionInfo } from '@workerdeck/protocol'\nimport { contained, readContained } from './host-files.ts'\n\nconst PROJECT_FILE = '.workerdeck.json'\nconst MAX_PROJECT_FILE_BYTES = 64 * 1024\nexport const MAX_PROJECT_ICON_BYTES = 512 * 1024\nconst MAX_NAME_CHARS = 80\nconst GLYPH_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/\n\nconst DEFAULT_TTL_MS = 30_000\nconst SWEEP_ABOVE = 256\n\ntype IconMediaType = 'image/png' | 'image/svg+xml'\n\nexport type ResolvedProjectIcon = { path: string; mediaType: IconMediaType; hash: string }\n\ntype Resolution = {\n project?: ProjectInfo\n icon?: ResolvedProjectIcon\n expiresAt: number\n}\n\nexport class ProjectInfoService {\n readonly #ttlMs: number\n readonly #byCwd = new Map<string, Resolution>()\n\n constructor(options: { ttlMs?: number } = {}) {\n this.#ttlMs = options.ttlMs ?? DEFAULT_TTL_MS\n }\n\n withProject(info: SessionInfo): SessionInfo {\n if (!info.cwd) {\n return info\n }\n const project = this.#resolve(info.cwd).project\n return project ? { ...info, project } : info\n }\n\n iconFor(cwd: string): ResolvedProjectIcon | undefined {\n if (!cwd) {\n return undefined\n }\n return this.#resolve(cwd).icon\n }\n\n #resolve(cwd: string): Resolution {\n const now = Date.now()\n const held = this.#byCwd.get(cwd)\n if (held && held.expiresAt > now) {\n return held\n }\n if (this.#byCwd.size > SWEEP_ABOVE) {\n for (const [key, entry] of this.#byCwd) {\n if (entry.expiresAt <= now) {\n this.#byCwd.delete(key)\n }\n }\n }\n const fresh = { ...discover(cwd), expiresAt: now + this.#ttlMs }\n this.#byCwd.set(cwd, fresh)\n return fresh\n }\n}\n\nfunction discover(cwd: string): Omit<Resolution, 'expiresAt'> {\n if (!isAbsolute(cwd) || cwd.includes('\\0')) {\n return {}\n }\n let dir: string\n try {\n dir = realpathSync(cwd)\n } catch {\n return {}\n }\n for (;;) {\n const found = tryLoad(join(dir, PROJECT_FILE), dir)\n if (found) {\n return found\n }\n const parent = dirname(dir)\n if (parent === dir) {\n return {}\n }\n dir = parent\n }\n}\n\nfunction tryLoad(file: string, root: string): Omit<Resolution, 'expiresAt'> | undefined {\n let stat\n try {\n stat = lstatSync(file)\n } catch {\n return undefined\n }\n // A symlinked project file is skipped, not followed — the agent writes this tree.\n if (!stat.isFile() || stat.size > MAX_PROJECT_FILE_BYTES) {\n return undefined\n }\n const read = readContained(file)\n if (!read.ok) {\n return undefined\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(read.data.toString('utf8'))\n } catch {\n return undefined\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return undefined\n }\n const raw = parsed as { name?: unknown; icon?: unknown }\n const name = typeof raw.name === 'string' && raw.name.trim() ? raw.name.trim().slice(0, MAX_NAME_CHARS) : basename(root)\n const icon = classifyIcon(raw.icon, root)\n return {\n project: { name, root, ...(icon ? { icon: icon.wire } : {}) },\n ...(icon?.resolved ? { icon: icon.resolved } : {}),\n }\n}\n\nfunction classifyIcon(value: unknown, root: string): { wire: ProjectIcon; resolved?: ResolvedProjectIcon } | undefined {\n if (typeof value !== 'string') {\n return undefined\n }\n const declared = value.trim()\n if (!declared || declared.includes('\\0') || declared.length > 512) {\n return undefined\n }\n const lower = declared.toLowerCase()\n const mediaType: IconMediaType | undefined = lower.endsWith('.png') ? 'image/png' : lower.endsWith('.svg') ? 'image/svg+xml' : undefined\n if (!mediaType) {\n if (!GLYPH_RE.test(declared) || declared.length > 64) {\n return undefined\n }\n return { wire: { type: 'glyph', name: declared } }\n }\n if (isAbsolute(declared) || declared.includes('\\\\')) {\n return undefined\n }\n let canonical: string\n try {\n canonical = realpathSync(resolve(root, declared))\n } catch {\n return undefined\n }\n if (!contained(root, canonical)) {\n return undefined\n }\n let stat\n try {\n stat = lstatSync(canonical)\n } catch {\n return undefined\n }\n if (!stat.isFile() || stat.size === 0 || stat.size > MAX_PROJECT_ICON_BYTES) {\n return undefined\n }\n const read = readContained(canonical)\n if (!read.ok || read.data.length > MAX_PROJECT_ICON_BYTES) {\n return undefined\n }\n const hash = createHash('sha256').update(read.data).digest('hex')\n return {\n wire: { type: 'image', mediaType, hash },\n resolved: { path: canonical, mediaType, hash },\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { json } from '../lib/http.ts'\nimport { readContained } from '../services/host-files.ts'\nimport { MAX_PROJECT_ICON_BYTES, type ProjectInfoService } from '../services/project-info.ts'\n\nexport function handleProjectIcon(projects: ProjectInfoService, req: IncomingMessage, res: ServerResponse, cwd: string): void {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const icon = projects.iconFor(cwd)\n if (!icon) {\n json(res, 404, { error: 'no project icon' })\n return\n }\n const etag = `\"${icon.hash}\"`\n if (req.headers['if-none-match'] === etag) {\n res.writeHead(304, { etag })\n res.end()\n return\n }\n const read = readContained(icon.path)\n if (!read.ok || read.data.length > MAX_PROJECT_ICON_BYTES) {\n json(res, 404, { error: 'no project icon' })\n return\n }\n res.writeHead(200, {\n 'content-type': icon.mediaType,\n 'content-length': read.data.length,\n etag,\n 'cache-control': 'private, max-age=300',\n 'content-disposition': 'attachment; filename=\"project-icon\"',\n 'x-content-type-options': 'nosniff',\n })\n res.end(read.data)\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { imagePartRef, type SessionEvent, type ToolResultBlock } from '@workerdeck/protocol'\nimport { json } from '../lib/http.ts'\n\nexport type EventLookup = ((seq: number) => SessionEvent | undefined) | undefined\n\nexport function handleToolResult(req: IncomingMessage, res: ServerResponse, lookup: EventLookup, seq: number): void {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const url = new URL(req.url ?? '/', 'http://internal')\n const toolUseId = url.searchParams.get('toolUseId')\n if (!toolUseId) {\n json(res, 400, { error: 'toolUseId is required' })\n return\n }\n if (!lookup) {\n json(res, 501, { error: 'engine does not serve stored events' })\n return\n }\n const event = lookup(seq)\n if (!event || event.type !== 'user_message' || !Array.isArray(event.message.content)) {\n json(res, 404, { error: 'no such event' })\n return\n }\n const block = event.message.content.find(\n (candidate): candidate is ToolResultBlock =>\n candidate.type === 'tool_result' && (candidate as ToolResultBlock).tool_use_id === toolUseId,\n )\n if (!block) {\n json(res, 404, { error: 'no such tool result in that event' })\n return\n }\n\n const partParam = url.searchParams.get('part')\n if (partParam !== null) {\n const index = Number(partParam)\n const parts = block.content\n const part = Number.isInteger(index) && Array.isArray(parts) ? parts[index] : undefined\n const ref = part ? imagePartRef(part, index) : undefined\n if (!ref) {\n json(res, 404, { error: 'no such image part in that tool result' })\n return\n }\n const source = (part as { source?: { data?: string } }).source\n const bytes = Buffer.from(source?.data ?? '', 'base64')\n res.writeHead(200, { 'content-type': ref.media_type, 'content-length': String(bytes.length) })\n res.end(bytes)\n return\n }\n\n const content =\n url.searchParams.get('imageRefs') === '1' && Array.isArray(block.content)\n ? block.content.map((part, index) => imagePartRef(part, index) ?? part)\n : (block.content ?? '')\n json(res, 200, { seq, toolUseId, content, isError: block.is_error === true })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { CreateSessionRequest, ResolvePermissionRequest, UpdateSessionRequest } from '@workerdeck/protocol'\nimport { contentTypeFor, json, readJsonBody, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { SessionRoute } from '../lib/parse-route.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport { isDormant } from '../services/session-store.ts'\nimport type { ServerContext } from '../context.ts'\nimport { vetCreateRequest } from './create-vet.ts'\nimport { handleAttachments } from './attachments.ts'\nimport { handleMcp } from './mcp.ts'\nimport { handleProducedFiles } from './produced-files.ts'\nimport { handleProjectIcon } from './project-icon.ts'\nimport { handleToolResult } from './tool-results.ts'\n\nexport async function handleSessions(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n route: SessionRoute,\n auth: AuthContext,\n): Promise<void> {\n const { attachmentStore, auth: authSvc, bridge, factory, parking, producedFiles, projects, registry } = ctx\n\n if (!route.id) {\n if (req.method === 'GET') {\n const sessions = [...registry.list(), ...(await parking.listInfo())]\n json(res, 200, {\n sessions: sessions.filter((session) => authSvc.canSee(auth, session)).map((session) => projects.withProject(session)),\n })\n return\n }\n if (req.method === 'POST') {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as CreateSessionRequest\n const refusal = vetCreateRequest(ctx, body, auth)\n if (refusal) {\n json(res, refusal.status, { error: refusal.error })\n return\n }\n const runner = await factory.createRunner(factory.buildRunnerConfig(body))\n factory.watchAuthSource(runner)\n json(res, 201, { session: projects.withProject(runner.info()) })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n\n const runner = registry.get(route.id)\n const parked = runner ? null : await parking.get(route.id)\n if (!runner && !parked) {\n json(res, 404, { error: 'session not found' })\n return\n }\n if (!authSvc.canSee(auth, runner?.info() ?? parked!.info)) {\n json(res, 404, { error: 'session not found' })\n return\n }\n if (route.attachments) {\n await handleAttachments(ctx, req, res, route.id, runner?.info() ?? parked!.info, route.attachmentId)\n return\n }\n if (route.mcp) {\n if (!runner) {\n json(res, 409, { error: 'session is parked (wake it before asking about MCP)' })\n return\n }\n await handleMcp(ctx, req, res, runner, route.mcpServer)\n return\n }\n if (route.files) {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const snapshotFiles = parked && !isDormant(parked) ? parked.snapshot.vfs : undefined\n const vfs =\n runner?.vfs ??\n (snapshotFiles && {\n list: () => Object.keys(snapshotFiles).sort(),\n read: (path: string) => snapshotFiles[path]!,\n })\n if (!vfs) {\n json(res, 404, { error: 'session has no file store' })\n return\n }\n if (route.filePath === undefined) {\n const files = vfs.list().map((path) => ({ path, bytes: vfs.read(path)?.length ?? 0 }))\n json(res, 200, { files })\n return\n }\n const content = vfs.read(route.filePath)\n if (content === undefined) {\n json(res, 404, { error: `no such file: ${route.filePath}` })\n return\n }\n const filename = route.filePath.split('/').pop() || 'file'\n res.writeHead(200, untrustedDownloadHeaders(filename, contentTypeFor(filename), Buffer.byteLength(content)))\n res.end(content)\n return\n }\n if (route.produced) {\n await handleProducedFiles(ctx, req, res, route.id, route.producedFileId)\n return\n }\n if (route.projectIcon) {\n handleProjectIcon(projects, req, res, (runner?.info() ?? parked!.info).cwd)\n return\n }\n if (route.resultSeq !== undefined) {\n const snapshot = parked && !isDormant(parked) ? parked.snapshot.events : undefined\n handleToolResult(\n req,\n res,\n runner?.eventAt?.bind(runner) ?? (snapshot && ((seq: number) => snapshot.find((event) => event.seq === seq))),\n route.resultSeq,\n )\n return\n }\n if (route.permissionId) {\n if (req.method !== 'POST') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as ResolvePermissionRequest\n if (body?.behavior !== 'allow' && body?.behavior !== 'deny') {\n json(res, 400, { error: \"behavior must be 'allow' or 'deny'\" })\n return\n }\n if (!runner) {\n json(res, 409, { error: 'session is parked (it has no pending permission requests)' })\n return\n }\n if (!runner.resolvePermission(route.permissionId, body)) {\n json(res, 404, { error: 'permission request not found (already resolved or expired)' })\n return\n }\n json(res, 200, { resolved: true })\n return\n }\n if (req.method === 'GET') {\n json(res, 200, { session: projects.withProject(runner?.info() ?? parked!.info) })\n return\n }\n if (req.method === 'PATCH') {\n if (!runner) {\n json(res, 409, { error: 'session is parked (wake it before renaming)' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as UpdateSessionRequest\n if (body?.title !== undefined) {\n if (body.title !== null && typeof body.title !== 'string') {\n json(res, 400, { error: 'title must be a string or null' })\n return\n }\n const title = typeof body.title === 'string' ? body.title.trim() : ''\n runner.setTitle(title || undefined)\n parking.touch(runner)\n }\n json(res, 200, { session: projects.withProject(runner.info()) })\n return\n }\n if (req.method === 'DELETE') {\n registry.remove(route.id)\n bridge.remove(route.id)\n await parking.discard(route.id)\n attachmentStore.drop(route.id)\n producedFiles.drop(route.id)\n json(res, 200, {\n session: projects.withProject(runner?.info() ?? { ...parked!.info, status: 'closed' as const }),\n })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { WebSocket } from 'ws'\nimport type { Runner } from '@workerdeck/core'\nimport { PROTOCOL_VERSION, type ClientFrame, type ServerFrame } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\n\nexport function attachClient(ctx: ServerContext, ws: WebSocket, runner: Runner, req: IncomingMessage): void {\n const { bridge, parking } = ctx\n const url = new URL(req.url ?? '/', 'http://internal')\n const afterSeq = Number(url.searchParams.get('afterSeq') ?? '0') || 0\n const truncateResults = url.searchParams.get('truncateResults') === '1'\n const imageRefs = url.searchParams.get('imageRefs') === '1'\n\n const send = (frame: ServerFrame): void => {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(frame))\n }\n }\n\n send({\n type: 'attached',\n protocolVersion: PROTOCOL_VERSION,\n session: ctx.projects.withProject(runner.info()),\n replayingFrom: afterSeq,\n })\n const unsubscribe = runner.subscribe((event) => send({ type: 'event', event }), afterSeq, {\n coalesceReplay: true,\n truncateResults,\n imageRefs,\n })\n const detachBridge = bridge.attach(runner.id, send)\n\n ws.on('message', (data: Buffer) => {\n let frame: ClientFrame\n try {\n frame = JSON.parse(data.toString('utf8')) as ClientFrame\n } catch {\n send({ type: 'protocol_error', message: 'invalid JSON frame' })\n return\n }\n handleCommand(ctx, frame, runner).catch((error: unknown) => {\n send({\n type: 'protocol_error',\n message: error instanceof Error ? error.message : 'command failed',\n })\n })\n })\n ws.on('close', () => {\n unsubscribe()\n detachBridge()\n parking.onDetach(runner.id)\n })\n}\n\nasync function handleCommand(ctx: ServerContext, frame: ClientFrame, runner: Runner): Promise<void> {\n const { attachmentStore, bridge } = ctx\n switch (frame.type) {\n case 'user_message': {\n if (!frame.attachmentIds?.length) {\n runner.sendMessage(frame.text)\n return\n }\n const resolved = attachmentStore.resolve(runner.id, frame.attachmentIds)\n if (!resolved.ok) {\n throw new Error(`unknown attachment(s): ${resolved.missing.join(', ')}`)\n }\n runner.sendMessage(frame.text, resolved.attachments)\n return\n }\n case 'permission_decision': {\n if (frame.behavior === 'allow') {\n runner.resolvePermission(frame.requestId, {\n behavior: 'allow',\n updatedInput: frame.updatedInput,\n })\n } else {\n runner.resolvePermission(frame.requestId, {\n behavior: 'deny',\n message: frame.message,\n interrupt: frame.interrupt,\n })\n }\n return\n }\n case 'interrupt': {\n await runner.interrupt()\n return\n }\n case 'clear_context': {\n if (!runner.clearContext) {\n throw new Error(`the ${runner.info().engine ?? 'claude'} engine cannot clear a conversation`)\n }\n await runner.clearContext()\n return\n }\n case 'set_permission_mode': {\n if (frame.mode === 'bypassPermissions' && ctx.options.disableBypassPermissions) {\n throw new Error('bypassPermissions is disabled on this server (disableBypassPermissions)')\n }\n await runner.setPermissionMode(frame.mode)\n return\n }\n case 'set_model': {\n await runner.setModel(frame.model)\n return\n }\n case 'tool_call_result': {\n bridge.resolve(runner.id, frame.executionId, { output: frame.output, logs: frame.logs })\n return\n }\n case 'tool_call_error': {\n bridge.resolve(runner.id, frame.executionId, {\n reason: frame.reason,\n error: frame.error,\n logs: frame.logs,\n })\n return\n }\n case 'close': {\n runner.close('client')\n return\n }\n default: {\n throw new Error(`unknown command: ${(frame as { type?: string }).type}`)\n }\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { attachmentKind, normalizeMediaType, type AttachmentInput } from '@workerdeck/core'\nimport type { MessageAttachment } from '@workerdeck/protocol'\n\nexport type AttachmentStoreOptions = {\n maxFileBytes?: number\n maxSessionBytes?: number\n}\n\nexport type AttachmentRejection =\n | { code: 'too_large'; message: string }\n | { code: 'session_full'; message: string }\n | { code: 'unsupported_type'; message: string }\n | { code: 'empty'; message: string }\n\nexport type PutResult = { ok: true; attachment: MessageAttachment } | { ok: false; error: AttachmentRejection }\n\nconst DEFAULT_MAX_FILE_BYTES = 10 * 1024 * 1024\nconst DEFAULT_MAX_SESSION_BYTES = 64 * 1024 * 1024\n\nexport class AttachmentStore {\n #bySession = new Map<string, Map<string, AttachmentInput>>()\n #maxFileBytes: number\n #maxSessionBytes: number\n\n constructor(options: AttachmentStoreOptions = {}) {\n this.#maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES\n this.#maxSessionBytes = options.maxSessionBytes ?? DEFAULT_MAX_SESSION_BYTES\n }\n\n get maxFileBytes(): number {\n return this.#maxFileBytes\n }\n\n put(sessionId: string, name: string, mediaType: string, body: Buffer): PutResult {\n if (body.length === 0) {\n return { ok: false, error: { code: 'empty', message: 'attachment is empty' } }\n }\n if (body.length > this.#maxFileBytes) {\n return {\n ok: false,\n error: {\n code: 'too_large',\n message: `attachment is larger than the ${this.#maxFileBytes}-byte limit`,\n },\n }\n }\n const type = normalizeMediaType(mediaType)\n if (!attachmentKind(type)) {\n return {\n ok: false,\n error: { code: 'unsupported_type', message: `unsupported media type: ${type}` },\n }\n }\n const held = this.#bySession.get(sessionId) ?? new Map<string, AttachmentInput>()\n const heldBytes = [...held.values()].reduce((sum, a) => sum + a.bytes, 0)\n if (heldBytes + body.length > this.#maxSessionBytes) {\n return {\n ok: false,\n error: {\n code: 'session_full',\n message: `session is already holding ${heldBytes} bytes of attachments (limit ${this.#maxSessionBytes})`,\n },\n }\n }\n const attachment: AttachmentInput = {\n id: randomUUID(),\n name: safeName(name),\n mediaType: type,\n bytes: body.length,\n data: body.toString('base64'),\n }\n held.set(attachment.id, attachment)\n this.#bySession.set(sessionId, held)\n return { ok: true, attachment: ref(attachment) }\n }\n\n get(sessionId: string, id: string): AttachmentInput | undefined {\n return this.#bySession.get(sessionId)?.get(id)\n }\n\n resolve(sessionId: string, ids: readonly string[]): { ok: true; attachments: AttachmentInput[] } | { ok: false; missing: string[] } {\n const held = this.#bySession.get(sessionId)\n const attachments: AttachmentInput[] = []\n const missing: string[] = []\n for (const id of ids) {\n const found = held?.get(id)\n if (found) {\n attachments.push(found)\n } else {\n missing.push(id)\n }\n }\n return missing.length ? { ok: false, missing } : { ok: true, attachments }\n }\n\n drop(sessionId: string): void {\n this.#bySession.delete(sessionId)\n }\n}\n\nfunction ref(attachment: AttachmentInput): MessageAttachment {\n return {\n id: attachment.id,\n name: attachment.name,\n mediaType: attachment.mediaType,\n bytes: attachment.bytes,\n }\n}\n\nfunction safeName(name: string): string {\n const leaf = name.split(/[/\\\\]/).pop() ?? ''\n // oxlint-disable-next-line no-control-regex\n const cleaned = leaf.replace(/[\\u0000-\\u001f\\u007f\"<>]/g, '').trim()\n if (cleaned === '' || cleaned === '.' || cleaned === '..') {\n return 'attachment'\n }\n return cleaned.length > 120 ? cleaned.slice(0, 120) : cleaned\n}\n","const MAX_SCOPE_KEYS = 16\nconst MAX_SCOPE_LEN = 200\n\nexport function readScope(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return undefined\n }\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.some(([, v]) => typeof v !== 'string')) {\n return undefined\n }\n return Object.fromEntries(entries) as Record<string, string>\n}\n\nexport function checkScope(value: unknown): string | null {\n if (value === undefined) {\n return null\n }\n const scope = readScope(value)\n if (!scope) {\n return 'scope must be an object of string values'\n }\n const entries = Object.entries(scope)\n if (entries.length > MAX_SCOPE_KEYS) {\n return `scope may carry at most ${MAX_SCOPE_KEYS} keys`\n }\n for (const [key, val] of entries) {\n if (key.length === 0) {\n return 'scope keys must not be empty'\n }\n if (key.length > MAX_SCOPE_LEN || val.length > MAX_SCOPE_LEN) {\n return `scope keys and values must be at most ${MAX_SCOPE_LEN} characters`\n }\n }\n return null\n}\n\nexport function sameScope(a: Record<string, string> | undefined, b: Record<string, string> | undefined): boolean {\n const left = Object.entries(a ?? {}).sort(([x], [y]) => (x < y ? -1 : 1))\n const right = Object.entries(b ?? {}).sort(([x], [y]) => (x < y ? -1 : 1))\n return left.length === right.length && left.every(([key, value], i) => right[i]![0] === key && right[i]![1] === value)\n}\n\nexport function scopeMatches(principal: Record<string, string> | undefined, session: Record<string, string> | undefined): boolean {\n if (!principal) {\n return true\n }\n return Object.entries(principal).every(([key, value]) => session?.[key] === value)\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { JobInfo, SessionInfo } from '@workerdeck/protocol'\nimport { readScope, scopeMatches } from '../lib/scope.ts'\nimport type { LateBoundRefs, WorkerServerOptions } from '../options.ts'\n\nexport type AuthContext = {\n ok: boolean\n allowedProfiles?: string[]\n canManageProfiles?: boolean\n principal?: unknown\n scope?: Record<string, string>\n operator?: boolean\n}\n\nexport type AuthService = ReturnType<typeof createAuthService>\n\nexport function createAuthService(deps: {\n options: Pick<WorkerServerOptions, 'authenticate' | 'authorizeSession'>\n refs: Pick<LateBoundRefs, 'registry'>\n}) {\n const { options, refs } = deps\n\n const authenticate = async (req: IncomingMessage): Promise<AuthContext> => {\n if (!options.authenticate) {\n return { ok: true }\n }\n const principal = await options.authenticate(req)\n if (principal === null || principal === undefined || principal === false) {\n return { ok: false }\n }\n const allowed = (principal as { allowedProfiles?: unknown }).allowedProfiles\n const scope = readScope((principal as { scope?: unknown }).scope)\n return {\n ok: true,\n principal,\n scope: scope && Object.keys(scope).length > 0 ? scope : undefined,\n operator:\n typeof (principal as { operator?: unknown }).operator === 'boolean' ? (principal as { operator: boolean }).operator : undefined,\n allowedProfiles: Array.isArray(allowed) && allowed.every((p) => typeof p === 'string') ? (allowed as string[]) : undefined,\n canManageProfiles: (principal as { canManageProfiles?: unknown }).canManageProfiles === true,\n }\n }\n\n const canSee = (auth: AuthContext, session: SessionInfo): boolean => {\n if (!options.authorizeSession) {\n return scopeMatches(auth.scope, session.scope)\n }\n try {\n return options.authorizeSession(auth.principal, session) === true\n } catch {\n return false\n }\n }\n\n const canSeeJob = (auth: AuthContext, job: JobInfo): boolean => {\n const live = job.sessionId ? refs.registry!.get(job.sessionId)?.info() : undefined\n if (live) {\n return canSee(auth, live)\n }\n if (!options.authorizeSession) {\n return scopeMatches(auth.scope, job.scope)\n }\n return canSee(auth, {\n id: job.sessionId ?? job.id,\n status: job.status === 'running' ? 'running' : job.status === 'parked' ? 'parked' : job.status === 'queued' ? 'starting' : 'closed',\n cwd: job.cwd,\n profile: job.profile,\n createdAt: job.createdAt,\n lastSeq: 0,\n pendingPermissionCount: 0,\n scope: job.scope,\n })\n }\n\n const isOperator = (auth: AuthContext): boolean => auth.operator ?? (auth.scope === undefined && !options.authorizeSession)\n\n return { authenticate, canSee, canSeeJob, isOperator }\n}\n","import { checkClaudeAuth } from '@workerdeck/core'\nimport type { ClaudeAuthProbe, EngineAdapter, EngineAvailability } from '@workerdeck/core'\nimport type { ProfileEngine, ProfileInfo } from '@workerdeck/protocol'\nimport { engineOf } from '../lib/profile-env.ts'\nimport type { Refusal } from './profiles.ts'\n\nconst AVAILABILITY_TTL_MS = 60_000\n\nexport type AvailabilityTrackerOptions = {\n checkCredentials?: boolean | { probe?: ClaudeAuthProbe; timeoutMs?: number }\n requireAvailableProfile?: boolean\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n sessionEnvFor: (profile: ProfileInfo) => Record<string, string | undefined>\n}\n\nexport class AvailabilityTracker {\n readonly #verdicts = new Map<string, { verdict: EngineAvailability; at: number }>()\n readonly #warned = new Set<string>()\n readonly #opts: AvailabilityTrackerOptions\n\n constructor(opts: AvailabilityTrackerOptions) {\n this.#opts = opts\n }\n\n get(name: string): EngineAvailability | undefined {\n return this.#verdicts.get(name)?.verdict\n }\n\n probe(profile: ProfileInfo): void {\n const { checkCredentials, adapterFor, sessionEnvFor } = this.#opts\n if (!checkCredentials) {\n return\n }\n const conf = checkCredentials === true ? {} : checkCredentials\n // Mark in-flight immediately so concurrent GET /profiles don't re-spawn.\n this.#verdicts.set(profile.name, {\n verdict: this.#verdicts.get(profile.name)?.verdict ?? { available: 'unknown' },\n at: Date.now(),\n })\n const adapter = adapterFor(profile.engine)\n const claudeProbe: ClaudeAuthProbe | undefined =\n engineOf(profile) !== 'claude'\n ? undefined\n : (conf.probe ?? (conf.timeoutMs !== undefined ? (env) => checkClaudeAuth(env, { timeoutMs: conf.timeoutMs }) : undefined))\n const run: Promise<EngineAvailability> = claudeProbe\n ? claudeProbe(sessionEnvFor(profile)).then((status): EngineAvailability =>\n status === 'logged_in'\n ? { available: true }\n : status === 'logged_out'\n ? { available: false, reason: 'no usable Claude credentials for this profile' }\n : { available: 'unknown' },\n )\n : adapter.checkAvailability(profile, sessionEnvFor(profile))\n void run\n .then((verdict) => {\n this.#verdicts.set(profile.name, { verdict, at: Date.now() })\n if (verdict.available === false && !this.#warned.has(profile.name)) {\n this.#warned.add(profile.name)\n console.warn(\n `[workerdeck] Profile '${profile.name}' is unavailable: ${verdict.reason} ` + '(`checkCredentials: false` disables this check)',\n )\n }\n if (verdict.available === true) {\n this.#warned.delete(profile.name)\n }\n })\n .catch(() => {})\n }\n\n checkAvailable(profile: ProfileInfo | undefined): Refusal | null {\n if (!this.#opts.requireAvailableProfile || !profile) {\n return null\n }\n const verdict = this.get(profile.name)\n if (!verdict || verdict.available !== false) {\n return null\n }\n return {\n status: 503,\n error: `profile '${profile.name}' is unavailable: ${verdict.reason ?? 'no usable credentials'}`,\n }\n }\n\n preflight(profiles: ProfileInfo[]): void {\n for (const profile of profiles) {\n this.probe(profile)\n }\n }\n\n refresh(profiles: ProfileInfo[]): void {\n if (!this.#opts.checkCredentials) {\n return\n }\n const now = Date.now()\n for (const profile of profiles) {\n const cached = this.#verdicts.get(profile.name)\n if (!cached || now - cached.at > AVAILABILITY_TTL_MS) {\n this.probe(profile)\n }\n }\n }\n}\n","import { BrowserBridgeExecutor, type BridgeAnswer, type ToolExecutionResult } from '@workerdeck/core'\nimport type { ServerFrame, ToolCallRequestFrame } from '@workerdeck/protocol'\n\ntype SessionBridge = {\n sockets: Array<(frame: ServerFrame) => void>\n executor: BrowserBridgeExecutor\n}\n\nexport type BridgeHubOptions = {\n timeoutMs?: number\n onResult?: (sessionId: string, executionId: string, result: ToolExecutionResult) => void\n}\n\nexport class BridgeHub {\n #sessions = new Map<string, SessionBridge>()\n #options: BridgeHubOptions\n\n constructor(options: BridgeHubOptions = {}) {\n this.#options = options\n }\n\n executorFor(sessionId: string): BrowserBridgeExecutor {\n return this.#bridge(sessionId).executor\n }\n\n attachedCount(sessionId: string): number {\n return this.#sessions.get(sessionId)?.sockets.length ?? 0\n }\n\n attach(sessionId: string, send: (frame: ServerFrame) => void): () => void {\n const bridge = this.#bridge(sessionId)\n bridge.sockets.push(send)\n return () => {\n const index = bridge.sockets.indexOf(send)\n if (index >= 0) {\n bridge.sockets.splice(index, 1)\n }\n }\n }\n\n resolve(sessionId: string, executionId: string, answer: BridgeAnswer): boolean {\n return this.#sessions.get(sessionId)?.executor.resolve(executionId, answer) ?? false\n }\n\n remove(sessionId: string): void {\n const bridge = this.#sessions.get(sessionId)\n if (!bridge) {\n return\n }\n bridge.executor.registry.cancelAll('session_closed', 'the session was closed')\n this.#sessions.delete(sessionId)\n }\n\n #bridge(sessionId: string): SessionBridge {\n const existing = this.#sessions.get(sessionId)\n if (existing) {\n return existing\n }\n const bridge: SessionBridge = {\n sockets: [],\n executor: new BrowserBridgeExecutor({\n timeoutMs: this.#options.timeoutMs,\n send: (frame: ToolCallRequestFrame) => {\n const target = bridge.sockets[0]\n if (!target) {\n return false\n }\n target(frame)\n return true\n },\n cancel: (executionId, reason) => {\n for (const send of bridge.sockets) {\n send({ type: 'tool_call_canceled', executionId, reason })\n }\n },\n onResult: (executionId, result) => {\n this.#options.onResult?.(sessionId, executionId, result)\n },\n }),\n }\n this.#sessions.set(sessionId, bridge)\n return bridge\n }\n}\n","import type { SessionInfo, SessionNotification, SessionWebhookConfig } from '@workerdeck/protocol'\nimport type { Runner } from '@workerdeck/core'\n\nexport type SessionNotificationOptions = {\n webhook?: SessionWebhookConfig\n onNotification?: (notification: SessionNotification) => void\n attempts?: number\n retryDelayMs?: number\n decorateInfo?: (info: SessionInfo) => SessionInfo\n}\n\nexport class SessionNotifier {\n readonly #options: SessionNotificationOptions\n readonly #chains = new Map<string, Promise<void>>()\n\n constructor(options: SessionNotificationOptions) {\n this.#options = options\n }\n\n get idle(): boolean {\n return !this.#options.webhook && !this.#options.onNotification\n }\n\n watch(runner: Runner, afterSeq = runner.info().lastSeq): void {\n if (this.idle) {\n return\n }\n runner.subscribe((event) => {\n switch (event.type) {\n case 'permission_requested': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'permission_requested',\n preview: event.request.title ?? event.request.toolName,\n request: event.request,\n })\n return\n }\n case 'turn_result': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'turn_completed',\n preview: event.isError ? event.errors?.join('\\n') : event.result,\n result: {\n isError: event.isError,\n durationMs: event.durationMs,\n numTurns: event.numTurns,\n totalCostUsd: event.totalCostUsd,\n },\n })\n return\n }\n case 'session_error': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'session_error',\n preview: event.message,\n })\n return\n }\n case 'session_closed': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'session_closed',\n reason: event.reason,\n })\n return\n }\n default: {\n return\n }\n }\n }, afterSeq)\n }\n\n #emit(runner: Runner, seq: number, ts: number, body: Omit<SessionNotification, 'sessionId' | 'session' | 'seq' | 'ts'>): void {\n queueMicrotask(() => this.#send(runner, seq, ts, body))\n }\n\n #send(runner: Runner, seq: number, ts: number, body: Omit<SessionNotification, 'sessionId' | 'session' | 'seq' | 'ts'>): void {\n const webhook = this.#options.webhook\n const wanted = !webhook?.events || webhook.events.includes(body.type)\n if (!webhook && !this.#options.onNotification) {\n return\n }\n\n const notification: SessionNotification = {\n ...body,\n sessionId: runner.id,\n session: (this.#options.decorateInfo ?? ((info) => info))(runner.info()),\n seq,\n ts,\n }\n\n try {\n this.#options.onNotification?.(notification)\n } catch {}\n\n if (!webhook || !wanted) {\n return\n }\n const previous = this.#chains.get(runner.id) ?? Promise.resolve()\n const next = previous.then(() => this.#deliver(webhook, notification))\n this.#chains.set(runner.id, next)\n void next.then(() => {\n if (this.#chains.get(runner.id) === next) {\n this.#chains.delete(runner.id)\n }\n })\n }\n\n async #deliver(webhook: SessionWebhookConfig, notification: SessionNotification): Promise<void> {\n const attempts = this.#options.attempts ?? 3\n const baseDelay = this.#options.retryDelayMs ?? 500\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n const res = await fetch(webhook.url, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...webhook.headers },\n body: JSON.stringify(notification),\n })\n if (res.ok) {\n return\n }\n } catch {}\n if (attempt < attempts - 1) {\n await new Promise((resolve) => setTimeout(resolve, baseDelay * 2 ** attempt))\n }\n }\n }\n}\n","import type { ParkedExecution, Runner, SessionRunnerConfig, ToolExecutionResult } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES, type SessionInfo } from '@workerdeck/protocol'\nimport type { SessionRegistry } from './registry.ts'\nimport {\n isDormant,\n isLiveRecord,\n type DormantSessionRecord,\n type ParkedSessionRecord,\n type SessionStore,\n type StoredSessionRecord,\n} from './session-store.ts'\n\n// The context handed to parking's onError: which session, and which lifecycle step failed.\nexport type ParkErrorContext = { sessionId: string; phase: 'park' | 'remember' | 'resume' }\n\nexport type SessionParkOptions = {\n registry: SessionRegistry\n store: SessionStore\n rebuild: (record: StoredSessionRecord) => Promise<Runner>\n attachedCount: (sessionId: string) => number\n parkDelayMs?: number\n persistLive?: boolean\n expiredGraceMs?: number\n onParking?: (sessionId: string, executionId: string) => boolean\n onResumed?: (sessionId: string, runner: Runner) => void\n onError?: (error: unknown, context: ParkErrorContext) => void\n}\n\nexport class SessionParkManager {\n #options: SessionParkOptions\n #owners = new Map<string, string>()\n #settled = new Map<string, string>()\n #timers = new Map<string, ReturnType<typeof setTimeout>>()\n #resuming = new Map<string, Promise<Runner | undefined>>()\n #detachTimers = new Map<string, ReturnType<typeof setTimeout>>()\n #configs = new Map<string, SessionRunnerConfig>()\n #remembered = new Set<string>()\n #storeOps = new Map<string, Promise<void>>()\n #closed = false\n\n constructor(options: SessionParkOptions) {\n this.#options = options\n }\n\n remember(sessionId: string, config: SessionRunnerConfig): void {\n this.#configs.set(sessionId, config)\n }\n\n touch(runner: Runner): void {\n void this.#rememberDormant(runner)\n void this.#persistLive(runner)\n }\n\n async hydrate(): Promise<void> {\n const floor = Date.now() + (this.#options.expiredGraceMs ?? 60_000)\n for (const record of await this.#options.store.list()) {\n if (isDormant(record)) {\n continue\n }\n for (const execution of record.executions) {\n this.#track(record.id, execution, floor)\n }\n }\n }\n\n watch(runner: Runner, afterSeq = 0): () => void {\n return runner.subscribe((event) => {\n switch (event.type) {\n case 'execution_dispatched': {\n if (!event.deferred) {\n return\n }\n this.#track(runner.id, {\n executionId: event.executionId,\n toolName: event.toolName,\n expiresAt: event.expiresAt,\n })\n return\n }\n case 'execution_result':\n case 'execution_failed': {\n this.#forget(event.executionId)\n // One call of a multi-call park settling leaves the session parked on the rest, and no new status_changed will say so.\n if (runner.info().status === 'parked') {\n void this.#park(runner)\n }\n return\n }\n case 'status_changed': {\n if (event.status === 'parked') {\n void this.#park(runner)\n } else {\n void this.#rememberDormant(runner)\n }\n return\n }\n case 'turn_result': {\n void this.#persistLive(runner)\n return\n }\n case 'permission_mode_changed':\n case 'model_changed': {\n void this.#persistLive(runner)\n return\n }\n case 'system_init': {\n void this.#rememberDormant(runner)\n return\n }\n case 'conversation_reset': {\n void this.#rememberDormant(runner)\n void this.#persistLive(runner)\n return\n }\n case 'session_closed': {\n if (this.#closed) {\n return\n }\n void this.discard(runner.id)\n return\n }\n default: {\n return\n }\n }\n }, afterSeq)\n }\n\n onDetach(sessionId: string): void {\n if (this.#closed) {\n return\n }\n const runner = this.#options.registry.get(sessionId)\n if (!runner || runner.info().status !== 'parked') {\n return\n }\n clearTimeout(this.#detachTimers.get(sessionId))\n const timer = setTimeout(() => {\n this.#detachTimers.delete(sessionId)\n void this.#park(runner)\n }, this.#options.parkDelayMs ?? 2000)\n timer.unref?.()\n this.#detachTimers.set(sessionId, timer)\n }\n\n sessionFor(executionId: string): string | undefined {\n return this.#owners.get(executionId) ?? this.#settled.get(executionId)\n }\n\n get(id: string): Promise<StoredSessionRecord | null> {\n return this.#queue(id, () => this.#options.store.get(id))\n }\n\n async listInfo(): Promise<SessionInfo[]> {\n await Promise.all(this.#storeOps.values())\n const records = await this.#options.store.list()\n return records.filter((record) => this.#options.registry.get(record.id) === undefined).map((record) => record.info)\n }\n\n async ensureLive(id: string): Promise<Runner | undefined> {\n const live = this.#options.registry.get(id)\n if (live) {\n return live\n }\n return this.#resume(id)\n }\n\n async submitResult(executionId: string, result: ToolExecutionResult): Promise<{ applied: boolean; sessionId: string } | undefined> {\n const sessionId = this.#owners.get(executionId)\n if (sessionId === undefined) {\n const settled = this.#settled.get(executionId)\n return settled === undefined ? undefined : { applied: false, sessionId: settled }\n }\n const runner = await this.ensureLive(sessionId)\n if (!runner) {\n this.#forget(executionId)\n return undefined\n }\n // Clear the watchdog first: settling re-enters the agent loop, and a timeout firing behind it would fail a call that no longer exists.\n this.#clearTimer(executionId)\n const applied = runner.settleExecution?.(executionId, result) ?? false\n if (applied) {\n this.#forget(executionId)\n }\n return { applied, sessionId }\n }\n\n async discard(sessionId: string): Promise<void> {\n clearTimeout(this.#detachTimers.get(sessionId))\n this.#detachTimers.delete(sessionId)\n this.#configs.delete(sessionId)\n this.#remembered.delete(sessionId)\n for (const [executionId, owner] of this.#owners) {\n if (owner === sessionId) {\n this.#forget(executionId)\n }\n }\n for (const [executionId, owner] of this.#settled) {\n if (owner === sessionId) {\n this.#settled.delete(executionId)\n }\n }\n await this.#queue(sessionId, () => this.#options.store.delete(sessionId))\n }\n\n close(): void {\n this.#closed = true\n for (const timer of this.#timers.values()) {\n clearTimeout(timer)\n }\n for (const timer of this.#detachTimers.values()) {\n clearTimeout(timer)\n }\n this.#timers.clear()\n this.#detachTimers.clear()\n }\n\n async #rememberDormant(runner: Runner): Promise<void> {\n if (this.#closed) {\n return\n }\n const info = runner.info()\n const capabilities = info.capabilities ?? ENGINE_CAPABILITIES[info.engine ?? 'claude']\n if (!capabilities.resume) {\n return\n }\n const config = this.#configs.get(runner.id)\n if (!config) {\n return\n }\n if (this.#options.registry.get(runner.id) !== runner) {\n return\n }\n const sdkSessionId = info.sdkSessionId\n if (sdkSessionId === undefined) {\n // Checked last, behind the ownership guard: before the engine has ever named a session there is no record to remove.\n if (this.#remembered.has(runner.id)) {\n await this.#forgetDormant(runner.id)\n }\n return\n }\n const record: DormantSessionRecord = {\n kind: 'dormant',\n id: runner.id,\n info: { ...info, status: 'idle' },\n profile: info.profile,\n config: { ...config, meta: info.meta },\n sdkSessionId,\n savedAt: Date.now(),\n }\n try {\n // Marked before the write: a queued save already means a record may exist, and a reset arriving mid-write must not skip the forget.\n this.#remembered.add(runner.id)\n await this.#queue(runner.id, () => this.#options.store.save(record))\n } catch (error) {\n this.#options.onError?.(error, { sessionId: runner.id, phase: 'remember' })\n }\n }\n\n async #forgetDormant(sessionId: string): Promise<void> {\n this.#remembered.delete(sessionId)\n try {\n await this.#queue(sessionId, () => this.#options.store.delete(sessionId))\n } catch (error) {\n this.#options.onError?.(error, { sessionId, phase: 'remember' })\n }\n }\n\n async #persistLive(runner: Runner): Promise<void> {\n if (this.#closed || !this.#options.persistLive || !runner.snapshot) {\n return\n }\n const config = this.#configs.get(runner.id)\n if (!config) {\n return\n }\n if (this.#options.registry.get(runner.id) !== runner) {\n return\n }\n try {\n await this.#queue(runner.id, async () => {\n // Re-checked inside the queue: a park's record must not be overwritten by the live copy queued behind it.\n if (this.#closed || this.#options.registry.get(runner.id) !== runner) {\n return\n }\n const snapshot = runner.snapshot?.()\n if (!snapshot) {\n return\n }\n const info = runner.info()\n const record: ParkedSessionRecord = {\n kind: 'live',\n id: runner.id,\n info: { ...info, status: 'idle' },\n profile: info.profile,\n config: { ...config, meta: info.meta },\n snapshot,\n executions: snapshot.parked,\n parkedAt: Date.now(),\n }\n await this.#options.store.save(record)\n })\n } catch (error) {\n this.#options.onError?.(error, { sessionId: runner.id, phase: 'remember' })\n }\n }\n\n async #park(runner: Runner): Promise<void> {\n if (this.#closed || !runner.park) {\n return\n }\n const id = runner.id\n if (this.#options.registry.get(id) !== runner) {\n return\n }\n if (runner.info().status !== 'parked') {\n return\n }\n if (this.#options.attachedCount(id) > 0) {\n return\n }\n const executions = [...this.#owners].filter(([, owner]) => owner === id).map(([e]) => e)\n if (executions.length === 0) {\n return\n }\n const config = this.#configs.get(id)\n if (!config) {\n return\n }\n if (this.#options.onParking && !this.#options.onParking(id, executions[0]!)) {\n return\n }\n const snapshot = runner.park()\n if (!snapshot) {\n return\n }\n const info = { ...runner.info(), status: 'parked' as const }\n this.#options.registry.evict(id)\n const record: ParkedSessionRecord = {\n kind: 'parked',\n id,\n info,\n profile: info.profile,\n config,\n snapshot,\n executions: snapshot.parked,\n parkedAt: Date.now(),\n }\n for (const execution of snapshot.parked) {\n this.#track(id, execution)\n }\n try {\n await this.#queue(id, () => this.#options.store.save(record))\n } catch (error) {\n this.#options.onError?.(error, { sessionId: id, phase: 'park' })\n }\n }\n\n async #resume(id: string): Promise<Runner | undefined> {\n const inFlight = this.#resuming.get(id)\n if (inFlight) {\n return inFlight\n }\n const attempt = this.#rebuild(id)\n this.#resuming.set(id, attempt)\n try {\n return await attempt\n } finally {\n this.#resuming.delete(id)\n }\n }\n\n async #rebuild(id: string): Promise<Runner | undefined> {\n const record = await this.#queue(id, () => this.#options.store.get(id))\n if (!record) {\n return undefined\n }\n let runner: Runner\n try {\n runner = await this.#options.rebuild(record)\n } catch (error) {\n this.#options.onError?.(error, { sessionId: id, phase: 'resume' })\n throw error\n }\n if (runner.id !== id) {\n runner.close('error')\n const error = new Error(\n `rebuilt session has id '${runner.id}', expected '${id}' — the engine factory must ` +\n 'forward EngineRunnerContext.restore (or, without a snapshot, the session id) ' +\n 'to the runner config',\n )\n this.#options.onError?.(error, { sessionId: id, phase: 'resume' })\n throw error\n }\n this.#options.registry.register(runner)\n this.remember(id, record.config)\n // A park must not re-arm watchdogs from its own replayed events; a dormant session starts a fresh log, so it has no prior seq to skip.\n this.watch(runner, isDormant(record) ? 0 : record.snapshot.seq)\n this.#options.onResumed?.(id, runner)\n if (!isDormant(record) && !isLiveRecord(record)) {\n await this.#queue(id, () => this.#options.store.delete(id))\n }\n void runner.start()\n return runner\n }\n\n #queue<T>(sessionId: string, op: () => Promise<T>): Promise<T> {\n const previous = this.#storeOps.get(sessionId) ?? Promise.resolve()\n const result = previous.then(op)\n const settled = result.then(\n () => {},\n () => {},\n )\n this.#storeOps.set(sessionId, settled)\n void settled.then(() => {\n if (this.#storeOps.get(sessionId) === settled) {\n this.#storeOps.delete(sessionId)\n }\n })\n return result\n }\n\n #track(sessionId: string, execution: ParkedExecution, notBefore = 0): void {\n this.#owners.set(execution.executionId, sessionId)\n if (execution.expiresAt === undefined || this.#timers.has(execution.executionId)) {\n return\n }\n const expiresAt = Math.max(execution.expiresAt, notBefore)\n const timer = setTimeout(\n () => {\n this.#timers.delete(execution.executionId)\n void this.submitResult(execution.executionId, {\n status: 'failed',\n reason: 'timeout',\n error: `deferred execution '${execution.toolName}' produced no result before its deadline`,\n }).catch((error: unknown) => {\n this.#options.onError?.(error, { sessionId, phase: 'resume' })\n })\n },\n Math.max(0, expiresAt - Date.now()),\n )\n timer.unref?.()\n this.#timers.set(execution.executionId, timer)\n }\n\n #forget(executionId: string): void {\n this.#clearTimer(executionId)\n const owner = this.#owners.get(executionId)\n if (owner !== undefined) {\n this.#settled.set(executionId, owner)\n }\n this.#owners.delete(executionId)\n }\n\n #clearTimer(executionId: string): void {\n const timer = this.#timers.get(executionId)\n if (timer === undefined) {\n return\n }\n clearTimeout(timer)\n this.#timers.delete(executionId)\n }\n}\n","import type { Runner } from '@workerdeck/core'\n\nexport type ProducedFile = {\n fileId: string\n path: string\n mediaType?: string\n bytes?: number\n sessionId: string\n}\n\nexport class ProducedFileStore {\n #bySession = new Map<string, Map<string, ProducedFile>>()\n\n watch(runner: Runner): void {\n runner.subscribe((event) => {\n if (event.type !== 'file_produced') {\n return\n }\n const held = this.#bySession.get(runner.id) ?? new Map<string, ProducedFile>()\n held.set(event.fileId, {\n fileId: event.fileId,\n path: event.path,\n ...(event.mediaType ? { mediaType: event.mediaType } : {}),\n ...(event.bytes !== undefined ? { bytes: event.bytes } : {}),\n sessionId: runner.id,\n })\n this.#bySession.set(runner.id, held)\n }, 0)\n }\n\n get(sessionId: string, fileId: string): ProducedFile | undefined {\n return this.#bySession.get(sessionId)?.get(fileId)\n }\n\n list(sessionId: string): ProducedFile[] {\n return [...(this.#bySession.get(sessionId)?.values() ?? [])]\n }\n\n drop(sessionId: string): void {\n this.#bySession.delete(sessionId)\n }\n}\n","import { existsSync } from 'node:fs'\nimport { supportsPermissionMode, type ProfileEngine, type ProfileInfo } from '@workerdeck/protocol'\nimport type { EngineAdapter, EngineAvailability } from '@workerdeck/core'\nimport { cwdAllowed, engineOf, isProviderProfile } from '../lib/profile-env.ts'\nimport type { ProfileStore } from './profile-store.ts'\n\nexport type Refusal = { status: number; error: string }\n\nexport type ProfileServiceOptions = {\n declared: ProfileInfo[]\n store?: ProfileStore\n allowedConfigDirRoots?: string[]\n disableBypassPermissions?: boolean\n hasEngineRunnerFactory: boolean\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n decorate: {\n defaultModel: (name: string) => string | undefined\n availability: (name: string) => EngineAvailability | undefined\n usage: (name: string) => ProfileInfo['usage'] | undefined\n }\n}\n\nexport class ProfileService {\n readonly #declared: ProfileInfo[]\n readonly #declaredByName: Map<string, ProfileInfo>\n readonly #stored = new Map<string, ProfileInfo>()\n readonly #opts: ProfileServiceOptions\n\n constructor(opts: ProfileServiceOptions) {\n this.#opts = opts\n this.#declared = opts.declared\n this.#declaredByName = new Map(opts.declared.map((p) => [p.name, p]))\n if (this.#declaredByName.size !== opts.declared.length) {\n throw new Error('createWorkerServer: duplicate profile names in `profiles`')\n }\n }\n\n validate(p: ProfileInfo): string | null {\n const { adapterFor, disableBypassPermissions, hasEngineRunnerFactory } = this.#opts\n if (isProviderProfile(p)) {\n if (!p.provider?.id) {\n return `provider profile '${p.name}' is missing provider.id`\n }\n if (!hasEngineRunnerFactory) {\n return `profile '${p.name}' uses engine 'provider' but no ` + '`createEngineRunner` was provided to build one'\n }\n } else if (p.engine === 'codex') {\n if (p.codexHome && !existsSync(p.codexHome)) {\n return `profile '${p.name}' codexHome does not exist: ${p.codexHome}`\n }\n if (p.session?.instructions) {\n return (\n `profile '${p.name}' declares session.instructions, which the codex engine cannot ` +\n 'deliver — put instructions in the target repo’s AGENTS.md instead'\n )\n }\n } else if (!p.configDir || !existsSync(p.configDir)) {\n return `profile '${p.name}' configDir does not exist: ${p.configDir}`\n }\n if (disableBypassPermissions && p.defaults?.permissionMode === 'bypassPermissions') {\n return `profile '${p.name}' defaults to bypassPermissions but disableBypassPermissions is set`\n }\n const fallbackMode = p.defaults?.permissionMode\n if (fallbackMode && !supportsPermissionMode(p.engine, fallbackMode)) {\n return (\n `profile '${p.name}' defaults to permission mode '${fallbackMode}', which engine ` +\n `'${engineOf(p)}' does not support (supported: ` +\n `${adapterFor(engineOf(p)).capabilities.permissionModes.join(', ')})`\n )\n }\n return null\n }\n\n async refreshStored(): Promise<void> {\n if (!this.#opts.store) {\n return\n }\n this.#stored.clear()\n for (const p of await this.#opts.store.list()) {\n this.#stored.set(p.name, p)\n }\n }\n\n withManagedFlag(p: ProfileInfo): ProfileInfo {\n return this.#declaredByName.has(p.name) ? p : { ...p, managed: true }\n }\n\n forResponse(p: ProfileInfo): ProfileInfo {\n const { adapterFor, decorate } = this.#opts\n const adapter = adapterFor(p.engine)\n const base: ProfileInfo = {\n ...this.withManagedFlag(p),\n capabilities: adapter.capabilities,\n }\n if (adapter.catalog.models.length > 0) {\n base.models = adapter.catalog.models\n }\n const defaultModel = decorate.defaultModel(p.name)\n if (defaultModel) {\n base.defaultModel = defaultModel\n }\n const probed = decorate.availability(p.name)\n if (probed && probed.available !== 'unknown') {\n base.available = probed.available\n if (probed.available === false) {\n base.unavailableReason = probed.reason\n }\n }\n const usage = decorate.usage(p.name)\n if (usage) {\n base.usage = usage\n }\n return base\n }\n\n all(): ProfileInfo[] {\n return [...this.#declared, ...[...this.#stored.values()].filter((p) => !this.#declaredByName.has(p.name))]\n }\n\n get(name: string): ProfileInfo | undefined {\n return this.#declaredByName.get(name) ?? this.#stored.get(name)\n }\n\n manageGuard(auth: { canManageProfiles?: boolean }): Refusal | null {\n if (!this.#opts.store) {\n return { status: 404, error: 'profile management is not enabled on this server' }\n }\n if (!auth.canManageProfiles) {\n return { status: 403, error: 'not allowed to manage profiles' }\n }\n return null\n }\n\n declaredGuard(profile: ProfileInfo): Refusal | null {\n return this.#declaredByName.has(profile.name)\n ? {\n status: 403,\n error:\n `profile '${profile.name}' is declared in server options and cannot be changed ` +\n 'over the API — edit the `profiles` option instead',\n }\n : null\n }\n\n configDirGuard(profile: ProfileInfo): Refusal | null {\n if (isProviderProfile(profile)) {\n return null\n }\n const roots = this.#opts.allowedConfigDirRoots\n if (!roots || roots.length === 0) {\n return {\n status: 403,\n error: 'managed Claude profiles are disabled: set `allowedConfigDirRoots` to the ' + 'directories they may point at',\n }\n }\n return profile.configDir && cwdAllowed(profile.configDir, roots)\n ? null\n : { status: 403, error: 'configDir is outside the allowed roots' }\n }\n\n async saveManaged(incoming: ProfileInfo): Promise<{ ok: true; profile: ProfileInfo } | ({ ok: false } & Refusal)> {\n const { managed: _clientClaim, ...profile } = incoming\n const refused = this.configDirGuard(profile)\n if (refused) {\n return { ok: false, ...refused }\n }\n const invalid = this.validate(profile)\n if (invalid) {\n return { ok: false, status: 400, error: invalid }\n }\n await this.#opts.store!.save(profile)\n await this.refreshStored()\n return { ok: true, profile: this.withManagedFlag(profile) }\n }\n}\n","import type { Runner } from '@workerdeck/core'\nimport type { ProfileUsage, ProfileUsageWindow, RateLimitInfo } from '@workerdeck/protocol'\n\ntype HeldWindow = { info: RateLimitInfo; updatedAt: number }\n\nexport class ProfileUsageTracker {\n #profiles = new Map<string, Map<string, HeldWindow>>()\n\n watch(runner: Runner): void {\n const profile = runner.info().profile\n if (!profile) {\n return\n }\n runner.subscribe((event) => {\n if (event.type !== 'rate_limit') {\n return\n }\n const type = event.info.rateLimitType\n if (!type) {\n return\n }\n let windows = this.#profiles.get(profile)\n if (!windows) {\n this.#profiles.set(profile, (windows = new Map()))\n }\n const held = windows.get(type)\n if (held && held.updatedAt > event.ts) {\n return\n }\n windows.set(type, { info: event.info, updatedAt: event.ts })\n })\n }\n\n usage(profile: string, now = Date.now()): ProfileUsage | undefined {\n const windows = this.#profiles.get(profile)\n if (!windows || windows.size === 0) {\n return undefined\n }\n const out: ProfileUsage = {}\n for (const [type, held] of windows) {\n out[type] = serveWindow(held, now)\n }\n return out\n }\n}\n\n// `resetsAt` is epoch seconds (protocol contract); `now` is epoch ms.\nfunction serveWindow(held: HeldWindow, now: number): ProfileUsageWindow {\n const resetsAt = held.info.resetsAt\n if (resetsAt !== undefined && resetsAt * 1000 <= now) {\n return {\n info: {\n // The dropped `resetsAt`/`isUsingOverage` describe the window that rolled, not this one.\n status: 'allowed',\n rateLimitType: held.info.rateLimitType,\n utilization: 0,\n },\n updatedAt: held.updatedAt,\n inferredReset: true,\n }\n }\n return { info: held.info, updatedAt: held.updatedAt }\n}\n","import { SessionRunner, type Runner, type SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type SessionRegistryOptions = {\n onRegister?: (runner: Runner) => void\n}\n\nexport class SessionRegistry {\n #sessions = new Map<string, Runner>()\n #options: SessionRegistryOptions\n\n constructor(options: SessionRegistryOptions = {}) {\n this.#options = options\n }\n\n create(config: SessionRunnerConfig): Runner {\n return this.adopt(new SessionRunner(config))\n }\n\n prepare(config: SessionRunnerConfig): Runner {\n return this.register(new SessionRunner(config))\n }\n\n adopt(runner: Runner): Runner {\n this.register(runner)\n void runner.start()\n return runner\n }\n\n register(runner: Runner): Runner {\n const existing = this.#sessions.get(runner.id)\n this.#sessions.set(runner.id, runner)\n if (existing !== runner) {\n this.#options.onRegister?.(runner)\n }\n return runner\n }\n\n get(id: string): Runner | undefined {\n return this.#sessions.get(id)\n }\n\n list(): SessionInfo[] {\n return [...this.#sessions.values()].map((r) => r.info())\n }\n\n remove(id: string): boolean {\n const runner = this.#sessions.get(id)\n if (!runner) {\n return false\n }\n runner.close('server')\n return this.#sessions.delete(id)\n }\n\n evict(id: string): boolean {\n return this.#sessions.delete(id)\n }\n\n closeAll(): void {\n for (const runner of this.#sessions.values()) {\n runner.close('server')\n }\n }\n}\n","import {\n supportsPermissionMode,\n type CreateSessionRequest,\n type PermissionMode,\n type ProfileEngine,\n type ProfileInfo,\n} from '@workerdeck/protocol'\nimport type { EngineAdapter, Runner, RunnerSnapshot, SessionRunnerConfig } from '@workerdeck/core'\nimport { checkScope, sameScope } from '../lib/scope.ts'\nimport { claudeSessionEnv, cwdAllowed, engineOf, isProviderProfile } from '../lib/profile-env.ts'\nimport type { EngineRunnerContext, LateBoundRefs } from '../options.ts'\nimport type { ProfileService } from './profiles.ts'\n\nexport type SessionFactoryDeps = {\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n profiles: ProfileService\n hostBuildRunnerConfig: (req: CreateSessionRequest) => SessionRunnerConfig\n createEngineRunner?: (context: EngineRunnerContext) => Runner | Promise<Runner>\n allowedCwdRoots?: string[]\n disableBypassPermissions?: boolean\n requireApiKey?: boolean\n refs: LateBoundRefs\n}\n\nexport type SessionFactory = ReturnType<typeof createSessionFactory>\n\nexport function createSessionFactory(deps: SessionFactoryDeps) {\n const { adapterFor, profiles, refs } = deps\n\n const subscriptionNoticeShown = new Set<string>()\n\n const applyBypassPolicy = (req: CreateSessionRequest): string | null => {\n if (!deps.disableBypassPermissions) {\n return null\n }\n if (req.permissionMode === 'bypassPermissions') {\n return 'bypassPermissions is disabled on this server (disableBypassPermissions)'\n }\n delete req.allowDangerouslySkipPermissions\n return null\n }\n\n const checkPermissionMode = (mode: PermissionMode | undefined, profile: ProfileInfo | undefined): string | null => {\n if (mode === undefined || supportsPermissionMode(profile?.engine, mode)) {\n return null\n }\n return (\n `permission mode '${mode}' is not supported by profile '${profile!.name}' ` +\n `(engine '${engineOf(profile)}') — supported: ` +\n adapterFor(profile?.engine).capabilities.permissionModes.join(', ')\n )\n }\n\n const checkEngineGrants = (req: CreateSessionRequest, profile: ProfileInfo | undefined): string | null => {\n const engine = engineOf(profile)\n const caps = adapterFor(profile?.engine).capabilities\n const name = profile?.name ?? 'default'\n if (!caps.sessionMcpServers && req.mcpServers && Object.keys(req.mcpServers).length > 0) {\n return (\n `profile '${name}' runs the ${engine} engine, whose MCP servers are declared ` +\n 'outside the session request — a request cannot add its own'\n )\n }\n if (!caps.budgets && (req.maxTurns !== undefined || req.maxBudgetUsd !== undefined)) {\n return `the ${engine} engine does not honor maxTurns/maxBudgetUsd`\n }\n if (!caps.settingSources && req.settingSources !== undefined) {\n return `the ${engine} engine does not load settingSources`\n }\n if (!caps.resume && req.resume !== undefined) {\n return `the ${engine} engine cannot resume a session`\n }\n if (req.forkSession && engine !== 'claude') {\n return `the ${engine} engine cannot fork a resumed session`\n }\n if (req.reasoningEffort !== undefined && (!caps.reasoningEfforts || caps.reasoningEfforts.length === 0)) {\n return `the ${engine} engine does not take a reasoningEffort`\n }\n if (!profile || !isProviderProfile(profile)) {\n return null\n }\n const granted = profile.session?.capabilities\n if (!req.capabilities || !granted) {\n return null\n }\n const ungranted = req.capabilities.filter((c) => !granted.includes(c))\n if (ungranted.length === 0) {\n return null\n }\n return (\n `profile '${profile.name}' does not grant: ${ungranted.join(', ')} ` +\n `(granted: ${granted.join(', ') || 'none'}) — a request may narrow capabilities, not widen them`\n )\n }\n\n const stripInertFields = (req: CreateSessionRequest, profile: ProfileInfo | undefined): void => {\n if (!adapterFor(profile?.engine).capabilities.interactiveApprovals) {\n delete req.questionBehavior\n }\n }\n\n const applyScope = (req: CreateSessionRequest, auth: { scope?: Record<string, string> }): { status: number; error: string } | null => {\n const invalid = checkScope(req.scope)\n if (invalid) {\n return { status: 400, error: invalid }\n }\n if (!auth.scope) {\n return null\n }\n const merged: Record<string, string> = { ...req.scope }\n for (const [key, value] of Object.entries(auth.scope)) {\n const claimed = merged[key]\n if (claimed !== undefined && claimed !== value) {\n return { status: 403, error: `scope '${key}' does not match the caller's` }\n }\n merged[key] = value\n }\n const tooBig = checkScope(merged)\n if (tooBig) {\n return { status: 400, error: tooBig }\n }\n req.scope = merged\n return null\n }\n\n const checkCwd = (req: CreateSessionRequest, profile: ProfileInfo | undefined): { status: number; error: string } | null => {\n if (req.cwd !== undefined && typeof req.cwd !== 'string') {\n return { status: 400, error: 'cwd must be a string' }\n }\n if (!req.cwd) {\n // Absent = true, so an engine record predating the field keeps the old always-required behaviour.\n return adapterFor(profile?.engine).capabilities.hostCwd === false ? null : { status: 400, error: 'cwd is required' }\n }\n return cwdAllowed(req.cwd, deps.allowedCwdRoots) ? null : { status: 403, error: 'cwd is outside the allowed roots' }\n }\n\n const withScope = (config: SessionRunnerConfig, scope: Record<string, string> | undefined): SessionRunnerConfig =>\n scope === undefined ? config : { ...config, scope }\n\n const buildRunnerConfig = (req: CreateSessionRequest): SessionRunnerConfig => {\n const profile = req.profile !== undefined ? profiles.get(req.profile) : undefined\n if (!profile) {\n return withScope(deps.hostBuildRunnerConfig(req), req.scope)\n }\n const config = withScope(\n deps.hostBuildRunnerConfig({\n ...req,\n model: req.model ?? profile.defaults?.model ?? profile.provider?.model,\n permissionMode: req.permissionMode ?? profile.defaults?.permissionMode,\n }),\n req.scope,\n )\n if (engineOf(profile) !== 'claude') {\n return config\n }\n const base = config.env ?? process.env\n const env = claudeSessionEnv(profile, base)\n // A skipped pin returns `base` itself — leaving the config alone keeps an unset `env` unset, so the SDK spawns on process.env.\n return env === base ? config : { ...config, env }\n }\n\n const sessionEnvFor = (profile: ProfileInfo): Record<string, string | undefined> => {\n try {\n return buildRunnerConfig({ cwd: process.cwd(), profile: profile.name }).env ?? process.env\n } catch {\n return engineOf(profile) === 'claude' ? claudeSessionEnv(profile, process.env) : process.env\n }\n }\n\n const buildRunner = async (config: SessionRunnerConfig, restore?: RunnerSnapshot, id?: string): Promise<Runner> => {\n const name = config.profile\n const profile = name !== undefined ? profiles.get(name) : undefined\n if (name !== undefined && !profile) {\n throw new Error(`unknown profile: ${name}`)\n }\n const runner =\n profile && isProviderProfile(profile)\n ? // Non-null: startup refuses a provider profile when no factory was wired.\n await deps.createEngineRunner!({ config, profile, bridge: refs.bridge!, restore, id })\n : // The in-repo adapters refuse `restore` themselves — neither binary can rebuild a parked session.\n await adapterFor(profile?.engine).createRunner({ config, profile, restore, id })\n const reported = runner.info().scope\n if (!sameScope(reported, config.scope)) {\n throw new Error(\n `runner for session ${runner.id} reports scope ${JSON.stringify(reported)}, ` +\n `expected ${JSON.stringify(config.scope)} — echo config.scope from info()`,\n )\n }\n return runner\n }\n\n const createRunner = async (config: SessionRunnerConfig): Promise<Runner> => {\n const runner = refs.registry!.register(await buildRunner(config))\n // Watchers first, then start: a session must not emit anything before the things that persist and account for it are listening.\n refs.parking!.remember(runner.id, config)\n refs.parking!.watch(runner)\n void runner.start()\n return runner\n }\n\n const resolveProfile = (\n name: unknown,\n allowedProfiles: string[] | undefined,\n ): { ok: true; profile?: ProfileInfo } | { ok: false; status: number; error: string } => {\n if (name !== undefined && typeof name !== 'string') {\n return { ok: false, status: 400, error: 'profile must be a string' }\n }\n const all = profiles.all()\n if (all.length === 0) {\n return name !== undefined ? { ok: false, status: 400, error: 'no profiles are configured on this server' } : { ok: true }\n }\n const effective = name ?? (all.length === 1 ? all[0]!.name : undefined)\n if (effective === undefined) {\n const available = all.map((p) => p.name).join(', ')\n return { ok: false, status: 400, error: `profile is required (available: ${available})` }\n }\n const profile = profiles.get(effective)\n if (!profile) {\n return { ok: false, status: 400, error: `unknown profile: ${effective}` }\n }\n if (allowedProfiles && !allowedProfiles.includes(profile.name)) {\n return { ok: false, status: 403, error: `profile not allowed: ${profile.name}` }\n }\n return { ok: true, profile }\n }\n\n const watchAuthSource = (runner: Runner): void => {\n let seen = false\n runner.subscribe((event) => {\n if (seen || event.type !== 'system_init') {\n return\n }\n seen = true\n if (event.apiKeySource !== 'oauth') {\n return\n }\n if (deps.requireApiKey) {\n runner.fail(\n 'This server requires API-key auth (requireApiKey), but the session initialized ' +\n \"with claude.ai subscription credentials (apiKeySource 'oauth'). Set \" +\n 'ANTHROPIC_API_KEY (or Bedrock/Vertex auth) in the server environment.',\n )\n } else {\n const profileName = runner.info().profile ?? ''\n if (subscriptionNoticeShown.has(profileName)) {\n return\n }\n subscriptionNoticeShown.add(profileName)\n const scope = profileName ? `Sessions under profile '${profileName}'` : 'Sessions'\n console.warn(\n `[workerdeck] ${scope} are using claude.ai subscription credentials ` +\n \"(apiKeySource 'oauth'), not an API key. That is only appropriate for personal, \" +\n 'single-user use of your own account. Unattended/scheduled or multi-user use ' +\n \"requires an API key under Anthropic's terms — set ANTHROPIC_API_KEY in the \" +\n 'server environment, or set requireApiKey: true to fail closed.',\n )\n }\n })\n }\n\n return {\n applyBypassPolicy,\n checkPermissionMode,\n checkEngineGrants,\n stripInertFields,\n applyScope,\n checkCwd,\n buildRunnerConfig,\n sessionEnvFor,\n buildRunner,\n createRunner,\n resolveProfile,\n watchAuthSource,\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { Duplex } from 'node:stream'\nimport { WebSocketServer, type WebSocket } from 'ws'\nimport { getEngineAdapter } from '@workerdeck/core'\nimport type { EngineAdapter } from '@workerdeck/core'\nimport { JobQueue } from '@workerdeck/queue'\nimport {\n PROTOCOL_VERSION,\n sessionState,\n type CreateSessionRequest,\n type JobEvent,\n type ProfileEngine,\n type QueueServerFrame,\n} from '@workerdeck/protocol'\nimport type { SessionRunnerConfig } from '@workerdeck/core'\nimport type { ServerContext } from './context.ts'\nimport { json } from './lib/http.ts'\nimport { detectDefaultProfiles } from './lib/profile-env.ts'\nimport { parseSessionRoute } from './lib/parse-route.ts'\nimport type { DrainReport, LateBoundRefs, WorkerServer, WorkerServerOptions } from './options.ts'\nimport { handleExecutionResult } from './routes/executions.ts'\nimport { handleHostFiles } from './routes/host-files.ts'\nimport { handleJobs } from './routes/jobs.ts'\nimport { handleProfiles } from './routes/profiles.ts'\nimport { handleSdkSessions } from './routes/sdk-sessions.ts'\nimport { handleSessions } from './routes/sessions.ts'\nimport { attachClient } from './routes/ws.ts'\nimport { AttachmentStore } from './services/attachments.ts'\nimport { createAuthService } from './services/auth.ts'\nimport { AvailabilityTracker } from './services/availability.ts'\nimport { BridgeHub } from './services/bridge.ts'\nimport { createHostFileRoots } from './services/host-files.ts'\nimport { SessionNotifier } from './services/notifications.ts'\nimport { SessionParkManager } from './services/parking.ts'\nimport { ProducedFileStore } from './services/produced-files.ts'\nimport { ProfileService } from './services/profiles.ts'\nimport { ProfileUsageTracker } from './services/profile-usage.ts'\nimport { ProjectInfoService } from './services/project-info.ts'\nimport { SessionRegistry } from './services/registry.ts'\nimport { createSessionFactory } from './services/session-factory.ts'\nimport { isDormant, MemorySessionStore } from './services/session-store.ts'\n\nexport type {\n Authenticator,\n EngineRunnerContext,\n QueueServerOptions,\n SdkSessionLister,\n WorkerServer,\n WorkerServerOptions,\n} from './options.ts'\n\n/** How long a client gets to acknowledge the shutdown close frame before its socket is torn down. */\nconst SOCKET_CLOSE_GRACE_MS = 250\n\n/**\n * Split live sessions into \"will finish by itself\" and \"needs a person\".\n *\n * `sessionState` is the vocabulary the dashboard, the session list and `workerdeck guard` already sort by, and it\n * draws exactly the line a drain needs: `working` covers starting/running and running subagents, while `attention`\n * covers a pending approval. Re-spelling that set here is how the two definitions would drift apart.\n */\nfunction surveyDrain(registry: SessionRegistry): DrainReport {\n const working: string[] = []\n const awaitingHuman: string[] = []\n for (const info of registry.list()) {\n const state = sessionState(info)\n if (state === 'working') {\n working.push(info.id)\n } else if (state === 'attention') {\n awaitingHuman.push(info.id)\n }\n }\n return { working, awaitingHuman, timedOut: false }\n}\n\nfunction sameDrain(a: DrainReport, b: DrainReport): boolean {\n return a.working.join() === b.working.join() && a.awaitingHuman.join() === b.awaitingHuman.join()\n}\n\nexport function createWorkerServer(options: WorkerServerOptions = {}): WorkerServer {\n if (!options.authenticate && !options.allowUnauthenticated) {\n throw new Error('createWorkerServer: provide `authenticate` or explicitly set `allowUnauthenticated: true`')\n }\n const basePath = options.basePath ?? '/v1'\n const fallback = options.fallback\n const corsOrigins = options.cors?.origins.length ? new Set(options.cors.origins) : undefined\n const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024\n const adapterFor = (engine: ProfileEngine | undefined): EngineAdapter => options.engines?.[engine ?? 'claude'] ?? getEngineAdapter(engine)\n\n const profileDefaultModels = new Map<string, string>()\n const profileUsage = new ProfileUsageTracker()\n const profiles = new ProfileService({\n declared: options.profiles ?? detectDefaultProfiles(),\n store: options.profileStore,\n allowedConfigDirRoots: options.allowedConfigDirRoots,\n disableBypassPermissions: options.disableBypassPermissions,\n hasEngineRunnerFactory: options.createEngineRunner !== undefined,\n adapterFor,\n decorate: {\n defaultModel: (name) => profileDefaultModels.get(name),\n availability: (name) => availability.get(name),\n usage: (name) => profileUsage.usage(name),\n },\n })\n for (const p of options.profiles ?? []) {\n const invalid = profiles.validate(p)\n if (invalid) {\n throw new Error(`createWorkerServer: ${invalid}`)\n }\n }\n\n const refs: LateBoundRefs = {}\n const factory = createSessionFactory({\n adapterFor,\n profiles,\n hostBuildRunnerConfig: options.buildRunnerConfig ?? ((req: CreateSessionRequest): SessionRunnerConfig => req),\n createEngineRunner: options.createEngineRunner,\n allowedCwdRoots: options.allowedCwdRoots,\n disableBypassPermissions: options.disableBypassPermissions,\n requireApiKey: options.requireApiKey,\n refs,\n })\n\n const availability = new AvailabilityTracker({\n checkCredentials: options.checkCredentials,\n requireAvailableProfile: options.requireAvailableProfile,\n adapterFor,\n sessionEnvFor: factory.sessionEnvFor,\n })\n\n const projects = new ProjectInfoService()\n const notifier = new SessionNotifier({\n ...options.notifications,\n decorateInfo: (info) => projects.withProject(info),\n })\n const producedFiles = new ProducedFileStore()\n const registry = new SessionRegistry({\n onRegister: (runner) => {\n notifier.watch(runner)\n producedFiles.watch(runner)\n profileUsage.watch(runner)\n const profile = runner.info().profile\n if (!profile) {\n return\n }\n runner.subscribe((event) => {\n if (event.type !== 'capabilities' || !event.defaultModel) {\n return\n }\n profileDefaultModels.set(profile, event.defaultModel)\n })\n },\n })\n const attachmentStore = new AttachmentStore(options.attachments)\n const bridge = new BridgeHub({\n ...options.bridge,\n onResult: (sessionId, executionId, result) => {\n registry.get(sessionId)?.settleExecution?.(executionId, result)\n options.bridge?.onResult?.(sessionId, executionId, result)\n },\n })\n const parking = new SessionParkManager({\n registry,\n store: options.parking?.store ?? new MemorySessionStore(),\n parkDelayMs: options.parking?.parkDelayMs,\n expiredGraceMs: options.parking?.expiredGraceMs,\n persistLive: options.parking?.persistLive,\n onError: options.parking?.onError,\n rebuild: (record) =>\n isDormant(record)\n ? factory.buildRunner(\n factory.buildRunnerConfig({\n ...record.config,\n prompt: undefined,\n meta: record.info.title ? { ...record.config.meta, title: record.info.title } : record.config.meta,\n resume: record.sdkSessionId,\n }),\n undefined,\n record.id,\n )\n : factory.buildRunner(record.config, record.snapshot),\n attachedCount: (sessionId) => bridge.attachedCount(sessionId),\n onParking: (sessionId, executionId) => queue?.onSessionParking(sessionId, executionId) ?? true,\n onResumed: (sessionId, runner) => queue?.onSessionResumed(sessionId, runner),\n })\n refs.registry = registry\n refs.parking = parking\n refs.bridge = bridge\n\n const auth = createAuthService({ options, refs })\n\n const wss = new WebSocketServer({ noServer: true })\n let closing: Promise<void> | undefined\n let draining = false\n\n const queueSockets = new Set<WebSocket>()\n const sendQueueFrame = (ws: WebSocket, frame: QueueServerFrame): void => {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(frame))\n }\n }\n const broadcastJobEvent = (event: JobEvent): void => {\n if (queueSockets.size === 0) {\n return\n }\n for (const ws of queueSockets) {\n sendQueueFrame(ws, { type: 'job_event', event })\n }\n if (event.type !== 'job_progress') {\n void queue\n ?.stats()\n .then((stats) => {\n for (const ws of queueSockets) {\n sendQueueFrame(ws, { type: 'queue_stats', stats })\n }\n })\n .catch(() => {})\n }\n }\n\n const queue = options.queue\n ? new JobQueue({\n ...options.queue,\n onEvent: (event) => {\n try {\n options.queue?.onEvent?.(event)\n } finally {\n broadcastJobEvent(event)\n }\n },\n createRunner: async (config) => {\n const runner = await factory.createRunner(config)\n factory.watchAuthSource(runner)\n return runner\n },\n buildRunnerConfig: factory.buildRunnerConfig,\n discardSession: (sessionId) => parking.discard(sessionId),\n })\n : undefined\n\n const hostFileRootPaths = options.hostFiles?.roots ?? options.allowedCwdRoots\n const hostFiles = hostFileRootPaths?.length ? createHostFileRoots(hostFileRootPaths) : null\n\n const ctx: ServerContext = {\n options,\n basePath,\n maxBodyBytes,\n adapterFor,\n listSdkSessions: options.listSdkSessions,\n profiles,\n availability,\n auth,\n factory,\n registry,\n parking,\n bridge,\n projects,\n queue,\n attachmentStore,\n producedFiles,\n hostFiles,\n hostFilesWritable: options.hostFiles?.write === true,\n maxHostFileBytes: options.hostFiles?.maxFileBytes ?? 1024 * 1024,\n maxHostDirEntries: options.hostFiles?.maxEntries ?? 5000,\n }\n\n const handleRequest = async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const pathname = new URL(req.url ?? '/', 'http://internal').pathname\n\n const origin = req.headers.origin\n const originAllowed = typeof origin === 'string' && corsOrigins !== undefined && corsOrigins.has(origin)\n if (originAllowed) {\n res.setHeader('access-control-allow-origin', origin)\n res.setHeader('vary', 'origin')\n }\n if (req.method === 'OPTIONS' && req.headers['access-control-request-method'] !== undefined) {\n if (!originAllowed) {\n res.writeHead(403)\n res.end()\n return\n }\n res.setHeader('access-control-allow-methods', 'GET, HEAD, POST, PATCH, PUT, DELETE')\n res.setHeader('access-control-allow-headers', 'authorization, content-type, x-workerdeck-key')\n res.setHeader('access-control-max-age', '600')\n // Chrome's Private Network Access: a public page reaching a private address (a tailnet, a LAN) preflights for this explicitly.\n if (req.headers['access-control-request-private-network'] === 'true') {\n res.setHeader('access-control-allow-private-network', 'true')\n }\n res.writeHead(204)\n res.end()\n return\n }\n\n if (fallback && pathname !== basePath && !pathname.startsWith(basePath + '/')) {\n await fallback(req, res)\n return\n }\n if (pathname === basePath + '/jobs' || pathname.startsWith(basePath + '/jobs/') || pathname === basePath + '/queue') {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleJobs(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname === basePath + '/profiles' || pathname.startsWith(basePath + '/profiles/')) {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleProfiles(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname.startsWith(basePath + '/executions/')) {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleExecutionResult(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname === basePath + '/sdk-sessions') {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n if (!auth.isOperator(authCtx)) {\n json(res, 404, { error: 'not found' })\n return\n }\n await handleSdkSessions(ctx, req, res, authCtx)\n return\n }\n if (pathname.startsWith(basePath + '/fs/')) {\n // Authenticated before the 404-when-unconfigured answer: an unauthenticated caller must not learn whether a filesystem is exposed.\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n if (!auth.isOperator(authCtx)) {\n json(res, 404, { error: 'not found' })\n return\n }\n await handleHostFiles(ctx, req, res, pathname)\n return\n }\n const route = parseSessionRoute(basePath, req.url ?? '/')\n if (!route || route.ws) {\n json(res, 404, { error: 'not found' })\n return\n }\n // Starting a turn we have already promised to stop waiting for would make the drain unable to converge.\n // Existing sessions stay fully controllable — including approvals, which is how an operator unblocks one.\n if (draining && req.method === 'POST' && route.id === undefined) {\n json(res, 503, { error: 'server is shutting down' })\n return\n }\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleSessions(ctx, req, res, route, authCtx)\n }\n\n const server = createServer((req, res) => {\n handleRequest(req, res).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : 'internal error'\n if (!res.headersSent) {\n json(res, error instanceof SyntaxError ? 400 : 500, { error: message })\n } else {\n res.end()\n }\n })\n })\n\n server.on('upgrade', (req: IncomingMessage, socket: Duplex, head: Buffer) => {\n void (async () => {\n const pathname = new URL(req.url ?? '/', 'http://internal').pathname\n if (pathname === basePath + '/queue/ws') {\n if (!queue) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const queueAuth = await auth.authenticate(req)\n if (!queueAuth.ok) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n if (!auth.isOperator(queueAuth)) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n wss.handleUpgrade(req, socket, head, (ws) => {\n queueSockets.add(ws)\n ws.on('close', () => queueSockets.delete(ws))\n void queue\n .stats()\n .then((stats) => sendQueueFrame(ws, { type: 'queue_attached', protocolVersion: PROTOCOL_VERSION, stats }))\n .catch(() => {})\n })\n return\n }\n const route = parseSessionRoute(basePath, req.url ?? '/')\n if (!route?.ws || !route.id) {\n socket.destroy()\n return\n }\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const known = registry.get(route.id)?.info() ?? (await parking.get(route.id))?.info\n if (known && !auth.canSee(authCtx, known)) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const runner = await parking.ensureLive(route.id).catch(() => undefined)\n if (!runner || !auth.canSee(authCtx, runner.info())) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n wss.handleUpgrade(req, socket, head, (ws) => {\n attachClient(ctx, ws, runner, req)\n })\n })().catch(() => socket.destroy())\n })\n\n return {\n server,\n registry,\n queue,\n bridge,\n parking,\n listen: async (port, host) => {\n await profiles.refreshStored()\n await parking.hydrate()\n return new Promise((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n availability.preflight(profiles.all())\n const address = server.address()\n resolve({ port: typeof address === 'object' && address ? address.port : port })\n })\n })\n },\n drain: async (drainOptions = {}) => {\n const { timeoutMs = 30_000, pollMs = 250, onProgress } = drainOptions\n draining = true\n const deadline = Date.now() + timeoutMs\n let report = surveyDrain(registry)\n onProgress?.(report)\n while (report.working.length > 0 && Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, pollMs))\n const next = surveyDrain(registry)\n // Only speak when something actually changed: a shutdown that reports on its own progress should be\n // readable, not a per-tick redraw of the same two lines.\n if (!sameDrain(next, report)) {\n onProgress?.(next)\n }\n report = next\n }\n report = { ...surveyDrain(registry), timedOut: false }\n report.timedOut = report.working.length > 0\n onProgress?.(report)\n return report\n },\n close: () => {\n // Idempotent by contract, not by luck: a second SIGINT re-enters here, and `http.Server.close()` on an\n // already-closed server only fires its callback because we ignore the ERR_SERVER_NOT_RUNNING it passes.\n // Returning the first promise makes the second call a no-op we can reason about.\n closing ??= new Promise((resolve) => {\n queue?.close()\n // Ordering is load-bearing: parking's `#closed` guard must be set before the registry closes runners with\n // reason 'server', or shutdown discards every dormant record. See docs/GOTCHAS.md.\n parking.close()\n registry.closeAll()\n // `wss` is `noServer`, so `wss.close()` neither closes nor terminates clients — it waits for `clients` to\n // empty — and `server.closeAllConnections()` does not reach upgraded sockets. Any attached session socket\n // therefore keeps `server.close()`'s callback from ever firing. Send close frames, then force what lingers.\n for (const ws of wss.clients) {\n ws.close(1001, 'server shutting down')\n }\n queueSockets.clear()\n const force = setTimeout(() => {\n for (const ws of wss.clients) {\n ws.terminate()\n }\n }, SOCKET_CLOSE_GRACE_MS)\n force.unref()\n wss.close()\n server.close(() => {\n clearTimeout(force)\n resolve()\n })\n server.closeAllConnections()\n })\n return closing\n },\n }\n}\n","import type { ProfileInfo, ProviderConfig, SessionCapability } from '@workerdeck/protocol'\n\nexport function sandboxedProviderProfile(\n name: string,\n provider: ProviderConfig,\n options: {\n description?: string\n instructions?: string\n defaults?: ProfileInfo['defaults']\n capabilities?: SessionCapability[]\n mcpServers?: string[]\n } = {},\n): ProfileInfo {\n return {\n name,\n engine: 'provider',\n provider,\n description: options.description ?? 'Sandboxed: no host filesystem, no shell, no egress',\n defaults: options.defaults,\n session: {\n capabilities: options.capabilities ?? [],\n mcpServers: options.mcpServers ?? [],\n instructions: options.instructions,\n },\n }\n}\n","import {\n createEngineSession,\n type EngineSessionOptions,\n type HostToolDefinition,\n type LanguageModel,\n type McpConnection,\n type Runner,\n type ToolExecutionCall,\n type ToolExecutor,\n type ToolSet,\n} from '@workerdeck/core'\nimport type { EngineRunnerContext } from '../options.ts'\n\nexport type ProviderRunnerOptions = {\n model: LanguageModel | ((modelId: string | undefined) => LanguageModel)\n executor: ToolExecutor | 'browser' | ((call: ToolExecutionCall) => ToolExecutor | 'browser')\n capabilities?: EngineSessionOptions['capabilities']\n tools?: Record<string, HostToolDefinition>\n mcp?: McpConnection\n mcpTools?: ToolSet\n instructions?: string\n executionLimits?: { timeoutMs?: number; memoryLimitBytes?: number }\n seedVfs?: Record<string, string>\n shouldApprove?: (call: { toolName: string; input: unknown }) => boolean\n approvalTimeoutMs?: number\n // Runs on park as well as close: parking releases the same per-session resources.\n onClose?: () => void | Promise<void>\n}\n\nexport async function createProviderRunner(ctx: EngineRunnerContext, options: ProviderRunnerOptions): Promise<Runner> {\n const { config, profile, bridge, restore, id } = ctx\n const resolveModel = (modelId: string | undefined): LanguageModel =>\n typeof options.model === 'function' ? options.model(modelId) : options.model\n const resolveBridged = (): ToolExecutor => ({\n dispatch: (call) => bridge.executorFor(call.sessionId).dispatch(call),\n })\n const resolveExecutor = (raw: ToolExecutor | 'browser'): ToolExecutor => (raw === 'browser' ? resolveBridged() : raw)\n\n const isPerCall = typeof options.executor === 'function'\n const selectExecutor: EngineSessionOptions['selectExecutor'] = isPerCall\n ? (call: ToolExecutionCall) => resolveExecutor((options.executor as (call: ToolExecutionCall) => ToolExecutor | 'browser')(call))\n : () => resolveExecutor(options.executor as ToolExecutor | 'browser')\n const backend: EngineSessionOptions['backend'] = isPerCall\n ? (call: ToolExecutionCall) => {\n const raw = (options.executor as (call: ToolExecutionCall) => ToolExecutor | 'browser')(call)\n return raw === 'browser' ? 'browser' : 'server'\n }\n : options.executor === 'browser'\n ? 'browser'\n : 'server'\n\n return createEngineSession({\n config: {\n ...config,\n languageModel: resolveModel(config.model),\n restore,\n onClose: options.onClose,\n },\n id,\n profile,\n resolveModel: (_profile, c) => resolveModel(c.model),\n selectExecutor,\n backend,\n capabilities: options.capabilities,\n tools: options.tools,\n mcp: options.mcp,\n mcpTools: options.mcpTools,\n instructions: options.instructions,\n executionLimits: options.executionLimits,\n shouldApprove: options.shouldApprove,\n approvalTimeoutMs: options.approvalTimeoutMs,\n seedVfs: options.seedVfs,\n })\n}\n","import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport type { ProfileInfo } from '@workerdeck/protocol'\n\nexport type ProfileStore = {\n list(): ProfileInfo[] | Promise<ProfileInfo[]>\n save(profile: ProfileInfo): void | Promise<void>\n delete(name: string): void | Promise<void>\n}\n\nexport function createMemoryProfileStore(seed: ProfileInfo[] = []): ProfileStore {\n const profiles = new Map(seed.map((p) => [p.name, p]))\n return {\n list: () => [...profiles.values()],\n save: (profile) => void profiles.set(profile.name, profile),\n delete: (name) => void profiles.delete(name),\n }\n}\n\nexport function createFileProfileStore(path = join(process.cwd(), '.workerdeck', 'profiles.json')): ProfileStore {\n const read = (): Map<string, ProfileInfo> => {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown\n if (!Array.isArray(parsed)) {\n return new Map()\n }\n const profiles = parsed as ProfileInfo[]\n return new Map(profiles.filter((p) => p && typeof p.name === 'string').map((p) => [p.name, p]))\n } catch {\n return new Map()\n }\n }\n const write = (profiles: Map<string, ProfileInfo>): void => {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.tmp`\n writeFileSync(temp, JSON.stringify([...profiles.values()], null, 2))\n renameSync(temp, path)\n }\n return {\n list: () => [...read().values()],\n save: (profile) => {\n const profiles = read()\n profiles.set(profile.name, profile)\n write(profiles)\n },\n delete: (name) => {\n const profiles = read()\n if (profiles.delete(name)) {\n write(profiles)\n }\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["resolvePath","profiles"],"sources":["../src/lib/http.ts","../src/lib/profile-env.ts","../src/lib/parse-route.ts","../src/routes/executions.ts","../src/services/host-files.ts","../src/services/host-file-search.ts","../src/routes/host-files.ts","../src/routes/create-vet.ts","../src/routes/jobs.ts","../src/routes/profiles.ts","../src/routes/sdk-sessions.ts","../src/services/session-store.ts","../src/routes/attachments.ts","../src/routes/mcp.ts","../src/routes/produced-files.ts","../src/services/project-info.ts","../src/routes/project-icon.ts","../src/routes/tool-results.ts","../src/routes/sessions.ts","../src/routes/ws.ts","../src/services/attachments.ts","../src/lib/scope.ts","../src/services/auth.ts","../src/services/availability.ts","../src/services/bridge.ts","../src/services/notifications.ts","../src/services/parking.ts","../src/services/produced-files.ts","../src/services/profiles.ts","../src/services/profile-usage.ts","../src/services/registry.ts","../src/services/session-factory.ts","../src/server.ts","../src/lib/sandboxed-profile.ts","../src/lib/provider-runner.ts","../src/services/profile-store.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nconst CONTENT_TYPES: Record<string, string> = {\n json: 'application/json; charset=utf-8',\n md: 'text/markdown; charset=utf-8',\n html: 'text/html; charset=utf-8',\n csv: 'text/csv; charset=utf-8',\n xml: 'application/xml; charset=utf-8',\n svg: 'image/svg+xml; charset=utf-8',\n}\n\n// Headers for serving user-controlled bytes (attachments, produced files, sandbox VFS reads):\n// force download and forbid MIME sniffing so a crafted HTML/SVG payload can never execute in the\n// gateway's origin. Every byte-serving route must use this.\nexport function untrustedDownloadHeaders(filename: string, contentType: string, byteLength: number): Record<string, string | number> {\n return {\n 'content-type': contentType,\n 'content-length': byteLength,\n 'content-disposition': `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`,\n 'x-content-type-options': 'nosniff',\n }\n}\n\nexport function json(res: ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body)\n res.writeHead(status, {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(payload),\n })\n res.end(payload)\n}\n\nexport async function readJsonBody(req: IncomingMessage, maxBytes: number): Promise<Record<string, unknown>> {\n const body = await readRawBody(req, maxBytes)\n if (body.length === 0) {\n return {}\n }\n return JSON.parse(body.toString('utf8')) as Record<string, unknown>\n}\n\nexport async function readRawBody(req: IncomingMessage, maxBytes: number): Promise<Buffer> {\n const chunks: Buffer[] = []\n let size = 0\n for await (const chunk of req) {\n size += (chunk as Buffer).length\n if (size > maxBytes) {\n throw new Error('request body too large')\n }\n chunks.push(chunk as Buffer)\n }\n return Buffer.concat(chunks)\n}\n\nexport function hashBytes(bytes: Buffer): string {\n return createHash('sha256').update(bytes).digest('hex')\n}\n\n// Decoding never fails in Node — invalid bytes become U+FFFD — so a round trip is the only honest test.\nexport function asUtf8(bytes: Buffer): string | null {\n const text = bytes.toString('utf8')\n return Buffer.from(text, 'utf8').equals(bytes) ? text : null\n}\n\nexport function contentTypeFor(filename: string): string {\n const ext = filename.includes('.') ? filename.split('.').pop()!.toLowerCase() : ''\n return CONTENT_TYPES[ext] ?? 'text/plain; charset=utf-8'\n}\n","import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join, resolve as resolvePath, sep } from 'node:path'\nimport type { ProfileConfigSnapshot, ProfileEngine, ProfileInfo } from '@workerdeck/protocol'\n\nexport function isProviderProfile(profile: ProfileInfo): boolean {\n return profile.engine === 'provider'\n}\n\nexport function engineOf(profile: ProfileInfo | undefined): ProfileEngine {\n return profile?.engine ?? 'claude'\n}\n\nexport function cliConfigDir(env: Record<string, string | undefined>): string {\n return env.CLAUDE_CONFIG_DIR ?? join(homedir(), '.claude')\n}\n\nexport function detectDefaultProfiles(): ProfileInfo[] {\n const dir = cliConfigDir(process.env)\n return existsSync(dir) ? [{ name: 'default', configDir: dir }] : []\n}\n\nexport function canonicalDir(path: string): string {\n try {\n return realpathSync(path)\n } catch {\n return resolvePath(path)\n }\n}\n\n// Skipping the pin is load-bearing: CLAUDE_CONFIG_DIR set at all moves the CLI off the macOS Keychain.\nexport function claudeSessionEnv(profile: ProfileInfo, base: Record<string, string | undefined>): Record<string, string | undefined> {\n return canonicalDir(profile.configDir!) === canonicalDir(cliConfigDir(base)) ? base : { ...base, CLAUDE_CONFIG_DIR: profile.configDir! }\n}\n\nexport function cwdAllowed(cwd: string, roots: string[] | undefined): boolean {\n if (!roots || roots.length === 0) {\n return true\n }\n const resolved = resolvePath(cwd)\n return roots.some((root) => {\n const r = resolvePath(root)\n return resolved === r || resolved.startsWith(r + sep)\n })\n}\n\n// Env var VALUES are never read into this snapshot — names only.\nexport function readProfileConfig(profile: ProfileInfo): ProfileConfigSnapshot {\n const dir = profile.configDir\n if (!dir) {\n return { hasUserMemory: false, skills: [], agents: [], commands: [] }\n }\n const listDirs = (path: string): string[] => {\n try {\n return readdirSync(path, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort()\n } catch {\n return []\n }\n }\n const listMd = (path: string): string[] => {\n try {\n return readdirSync(path)\n .filter((file) => file.endsWith('.md'))\n .map((file) => file.slice(0, -3))\n .sort()\n } catch {\n return []\n }\n }\n const snapshot: ProfileConfigSnapshot = {\n hasUserMemory: existsSync(join(dir, 'CLAUDE.md')),\n skills: listDirs(join(dir, 'skills')),\n agents: listMd(join(dir, 'agents')),\n commands: listMd(join(dir, 'commands')),\n }\n try {\n const raw = JSON.parse(readFileSync(join(dir, 'settings.json'), 'utf8')) as Record<string, unknown>\n const permissions = (raw.permissions ?? {}) as Record<string, unknown>\n const count = (rules: unknown): number => (Array.isArray(rules) ? rules.length : 0)\n snapshot.settings = {\n model: typeof raw.model === 'string' ? raw.model : undefined,\n defaultPermissionMode: typeof permissions.defaultMode === 'string' ? permissions.defaultMode : undefined,\n permissionRules: {\n allow: count(permissions.allow),\n ask: count(permissions.ask),\n deny: count(permissions.deny),\n },\n envKeys: raw.env && typeof raw.env === 'object' ? Object.keys(raw.env).sort() : undefined,\n hooks: raw.hooks && typeof raw.hooks === 'object' ? Object.keys(raw.hooks).sort() : undefined,\n }\n } catch {}\n return snapshot\n}\n","export type SessionRoute = {\n id?: string\n ws?: boolean\n permissionId?: string\n files?: boolean\n filePath?: string\n attachments?: boolean\n attachmentId?: string\n mcp?: boolean\n mcpServer?: string\n produced?: boolean\n producedFileId?: string\n resultSeq?: number\n projectIcon?: boolean\n}\n\nexport function parseSessionRoute(basePath: string, url: string): SessionRoute | null {\n const pathname = new URL(url, 'http://internal').pathname\n if (!pathname.startsWith(basePath + '/sessions')) {\n return null\n }\n const rest = pathname.slice((basePath + '/sessions').length)\n if (rest === '' || rest === '/') {\n return {}\n }\n const parts = rest.replace(/^\\//, '').split('/')\n if (parts.length === 1) {\n return { id: decodeURIComponent(parts[0]!) }\n }\n if (parts.length === 2 && parts[1] === 'ws') {\n return { id: decodeURIComponent(parts[0]!), ws: true }\n }\n if (parts.length === 3 && parts[1] === 'permissions') {\n return { id: decodeURIComponent(parts[0]!), permissionId: decodeURIComponent(parts[2]!) }\n }\n if (parts.length <= 3 && parts[1] === 'attachments') {\n return {\n id: decodeURIComponent(parts[0]!),\n attachments: true,\n attachmentId: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length <= 3 && parts[1] === 'produced') {\n return {\n id: decodeURIComponent(parts[0]!),\n produced: true,\n producedFileId: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length === 3 && parts[1] === 'project' && parts[2] === 'icon') {\n return { id: decodeURIComponent(parts[0]!), projectIcon: true }\n }\n if (parts.length === 4 && parts[1] === 'events' && parts[3] === 'result') {\n const seq = Number(parts[2])\n if (!Number.isInteger(seq) || seq < 0) {\n return null\n }\n return { id: decodeURIComponent(parts[0]!), resultSeq: seq }\n }\n if (parts.length <= 3 && parts[1] === 'mcp') {\n // MCP server names are opaque and may contain ':' (plugin:gtm:gtm) — one segment, decoded whole.\n return {\n id: decodeURIComponent(parts[0]!),\n mcp: true,\n mcpServer: parts[2] === undefined ? undefined : decodeURIComponent(parts[2]),\n }\n }\n if (parts.length >= 2 && parts[1] === 'files') {\n const filePath = parts.slice(2).map(decodeURIComponent).join('/')\n return {\n id: decodeURIComponent(parts[0]!),\n files: true,\n filePath: filePath === '' ? undefined : '/' + filePath,\n }\n }\n return null\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ToolExecutionResult } from '@workerdeck/core'\nimport type { SubmitExecutionResultRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleExecutionResult(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, basePath, parking, registry } = ctx\n const rest = pathname.slice((basePath + '/executions/').length).split('/')\n if (rest.length !== 2 || rest[1] !== 'result' || !rest[0]) {\n json(res, 404, { error: 'not found' })\n return\n }\n if (req.method !== 'POST') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const executionId = decodeURIComponent(rest[0])\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as SubmitExecutionResultRequest\n let result: ToolExecutionResult\n if (body?.status === 'ok') {\n if (!body.output || typeof body.output !== 'object') {\n json(res, 400, { error: \"output is required for status 'ok'\" })\n return\n }\n result = { status: 'ok', output: body.output.value, logs: body.logs }\n } else if (body?.status === 'failed') {\n if (typeof body.reason !== 'string' || typeof body.error !== 'string') {\n json(res, 400, { error: \"reason and error are required for status 'failed'\" })\n return\n }\n result = { status: 'failed', reason: body.reason, error: body.error, logs: body.logs }\n } else {\n json(res, 400, { error: \"status must be 'ok' or 'failed'\" })\n return\n }\n if (auth.allowedProfiles || auth.scope || ctx.options.authorizeSession) {\n const owner = parking.sessionFor(executionId)\n const info = owner === undefined ? undefined : (registry.get(owner)?.info() ?? (await parking.get(owner))?.info)\n const profile = info?.profile\n // Indistinguishable from an unknown id on purpose: whether an execution exists elsewhere is not this caller's business.\n // A vanished session (`info === undefined`) refuses too — nobody passed canSee, and submitResult would disclose the owner id.\n const refused =\n owner === undefined ||\n info === undefined ||\n (auth.allowedProfiles !== undefined && profile !== undefined && !auth.allowedProfiles.includes(profile)) ||\n !authSvc.canSee(auth, info)\n if (refused) {\n json(res, 404, { error: 'execution not found' })\n return\n }\n }\n const applied = await parking.submitResult(executionId, result)\n if (!applied) {\n json(res, 404, { error: 'execution not found (unknown id, or its session has ended)' })\n return\n }\n json(res, 200, applied)\n}\n","import type { Dirent } from 'node:fs'\nimport { closeSync, constants, fstatSync, ftruncateSync, lstatSync, openSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, relative, sep } from 'node:path'\n\n// win32 lacks O_NOFOLLOW/O_NONBLOCK (undefined at runtime despite the typing): there they contribute 0 and the fstat gates stand alone.\nconst O_NOFOLLOW: number = constants.O_NOFOLLOW ?? 0\nconst O_NONBLOCK: number = constants.O_NONBLOCK ?? 0\n\nexport type HostFileRoot = {\n readonly configured: string\n readonly canonical: string\n}\n\nexport type HostFileRoots = { readonly roots: readonly HostFileRoot[] }\n\nexport function createHostFileRoots(roots: string[]): HostFileRoots {\n return {\n roots: roots.map((configured) => {\n if (invalidRequest(configured)) {\n throw new Error(`createHostFileRoots: root must be an absolute path: ${JSON.stringify(configured)}`)\n }\n let canonical: string\n try {\n canonical = realpathSync(configured)\n } catch {\n throw new Error(`createHostFileRoots: root does not exist: ${configured}`)\n }\n if (!lstatSync(canonical).isDirectory()) {\n throw new Error(`createHostFileRoots: root is not a directory: ${configured}`)\n }\n return { configured, canonical }\n }),\n }\n}\n\nexport type ResolveOutcome =\n | { ok: true; path: string; root: string; kind: 'file' | 'dir' }\n | { ok: false; status: 403 | 404; error: string }\n\ntype Refusal = { ok: false; status: 403 | 404; error: string }\n\nfunction refuse(status: 403 | 404, error: string): Refusal {\n return { ok: false, status, error }\n}\n\nfunction notFound(): Refusal {\n return refuse(404, 'not found')\n}\n\n// NUL is rejected before any fs call: Node throws a TypeError on one, and that must surface as a refusal rather than a 500.\nfunction invalidRequest(requested: string): boolean {\n return requested.length === 0 || requested.includes('\\0') || !isAbsolute(requested)\n}\n\n// A bare prefix check gets the boundary wrong (`/x/app` would swallow `/x/application`); both sides must be realpath output.\nexport function contained(rootCanonical: string, candidate: string): boolean {\n const rel = relative(rootCanonical, candidate)\n return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel))\n}\n\nfunction rootContaining(roots: HostFileRoots, canonical: string): HostFileRoot | undefined {\n return roots.roots.find((root) => contained(root.canonical, canonical))\n}\n\nexport function resolveExisting(roots: HostFileRoots, requested: string): ResolveOutcome {\n if (invalidRequest(requested)) {\n return refuse(403, 'invalid path')\n }\n let canonical: string\n try {\n canonical = realpathSync(requested)\n } catch {\n return notFound()\n }\n const root = rootContaining(roots, canonical)\n if (!root) {\n return notFound()\n }\n let target\n try {\n // realpath output cannot name a symlink, so lstat === stat modulo a race — and a swap inside the window then classifies as neither.\n target = lstatSync(canonical)\n } catch {\n return notFound()\n }\n if (target.isFile()) {\n return { ok: true, path: canonical, root: root.canonical, kind: 'file' }\n }\n if (target.isDirectory()) {\n return { ok: true, path: canonical, root: root.canonical, kind: 'dir' }\n }\n return refuse(403, 'not a regular file or directory')\n}\n\n// Only the final component may be new: a missing target canonicalizes its parent, so a dangling symlink sitting there is refused, not created through.\nexport function resolveForWrite(roots: HostFileRoots, requested: string): ResolveOutcome {\n if (invalidRequest(requested)) {\n return refuse(403, 'invalid path')\n }\n try {\n const canonical = realpathSync(requested)\n const root = rootContaining(roots, canonical)\n if (!root) {\n return notFound()\n }\n const target = lstatSync(canonical)\n if (target.isDirectory()) {\n return refuse(403, 'is a directory')\n }\n if (!target.isFile()) {\n return refuse(403, 'not a regular file')\n }\n return { ok: true, path: canonical, root: root.canonical, kind: 'file' }\n } catch {}\n const base = basename(requested)\n if (base === '' || base === '.' || base === '..') {\n return refuse(403, 'invalid path')\n }\n let parent: string\n try {\n parent = realpathSync(dirname(requested))\n } catch {\n return notFound()\n }\n const root = rootContaining(roots, parent)\n if (!root) {\n return notFound()\n }\n try {\n if (!lstatSync(parent).isDirectory()) {\n return notFound()\n }\n } catch {\n return notFound()\n }\n const path = join(parent, base)\n // Redundant by construction (basename() cannot smuggle a separator) — kept because this is the line an escape would have to cross.\n if (!contained(root.canonical, path)) {\n return notFound()\n }\n try {\n lstatSync(path)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { ok: true, path, root: root.canonical, kind: 'file' }\n }\n return notFound()\n }\n return notFound()\n}\n\nexport type HostEntryKind = 'file' | 'dir' | 'symlink' | 'other'\n\nexport function entryKind(entry: Dirent): HostEntryKind {\n if (entry.isSymbolicLink()) {\n return 'symlink'\n }\n if (entry.isFile()) {\n return 'file'\n }\n if (entry.isDirectory()) {\n return 'dir'\n }\n return 'other'\n}\n\nexport type ReadOutcome = { ok: true; data: Buffer } | Refusal\n\nexport function readContained(path: string): ReadOutcome {\n let fd: number\n try {\n fd = openSync(path, constants.O_RDONLY | O_NOFOLLOW | O_NONBLOCK)\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT' ? notFound() : refuse(403, 'refused')\n }\n try {\n if (!fstatSync(fd).isFile()) {\n return refuse(403, 'not a regular file')\n }\n return { ok: true, data: readFileSync(fd) }\n } catch {\n return refuse(403, 'refused')\n } finally {\n closeSync(fd)\n }\n}\n\nexport type WriteOutcome = { ok: true } | Refusal\n\nexport function writeContained(path: string, data: string | Uint8Array): WriteOutcome {\n let fd: number\n try {\n fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | O_NOFOLLOW | O_NONBLOCK, 0o644)\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'ENOENT' ? notFound() : refuse(403, 'refused')\n }\n try {\n if (!fstatSync(fd).isFile()) {\n return refuse(403, 'not a regular file')\n }\n ftruncateSync(fd)\n writeFileSync(fd, data)\n return { ok: true }\n } catch {\n return refuse(403, 'refused')\n } finally {\n closeSync(fd)\n }\n}\n","import { readdirSync } from 'node:fs'\nimport { join, relative } from 'node:path'\nimport { entryKind } from './host-files.ts'\n\nexport const DEFAULT_IGNORED_DIRS = [\n '.git',\n '.hg',\n '.svn',\n 'node_modules',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.turbo',\n '.cache',\n 'dist',\n 'build',\n 'out',\n 'target',\n '.venv',\n 'venv',\n '__pycache__',\n '.pytest_cache',\n '.gradle',\n 'Pods',\n 'DerivedData',\n // Swift Package Manager: its object files carry the source names, so `@` answers `Transcript.o` before `Transcript.swift` without this.\n '.build',\n]\n\nexport type FoundFile = {\n path: string\n relative: string\n}\n\nexport type SearchResult = {\n matches: FoundFile[]\n truncated: boolean\n}\n\nexport type SearchOptions = {\n query?: string\n limit?: number\n ignore?: readonly string[]\n maxScanned?: number\n}\n\nexport function searchFiles(base: string, options: SearchOptions = {}): SearchResult {\n const limit = options.limit ?? 50\n const maxScanned = options.maxScanned ?? 20_000\n const ignore = new Set(options.ignore ?? DEFAULT_IGNORED_DIRS)\n const needle = (options.query ?? '').toLowerCase()\n\n const found: { file: FoundFile; score: number; depth: number }[] = []\n const queue: { dir: string; depth: number }[] = [{ dir: base, depth: 0 }]\n let scanned = 0\n let exhausted = true\n\n while (queue.length > 0) {\n const { dir, depth } = queue.shift()!\n let entries\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n continue\n }\n for (const entry of entries) {\n if (++scanned > maxScanned) {\n exhausted = false\n queue.length = 0\n break\n }\n const kind = entryKind(entry)\n if (kind === 'dir') {\n if (!ignore.has(entry.name)) {\n queue.push({ dir: join(dir, entry.name), depth: depth + 1 })\n }\n continue\n }\n if (kind !== 'file') {\n continue\n }\n const path = join(dir, entry.name)\n const rel = relative(base, path)\n const score = scoreMatch(rel, entry.name, needle)\n if (score !== null) {\n found.push({ file: { path, relative: rel }, score, depth })\n }\n }\n }\n\n found.sort(\n (a, b) =>\n b.score - a.score ||\n a.depth - b.depth ||\n a.file.relative.length - b.file.relative.length ||\n a.file.relative.localeCompare(b.file.relative),\n )\n return {\n matches: found.slice(0, limit).map((f) => f.file),\n truncated: !exhausted || found.length > limit,\n }\n}\n\nfunction scoreMatch(relativePath: string, name: string, needle: string): number | null {\n if (needle === '') {\n return 0\n }\n const inName = subsequenceScore(name.toLowerCase(), needle)\n if (inName !== null) {\n return inName + 1000\n }\n return subsequenceScore(relativePath.toLowerCase(), needle)\n}\n\nfunction subsequenceScore(haystack: string, needle: string): number | null {\n let score = 0\n let from = 0\n let previous = -2\n for (const char of needle) {\n const at = haystack.indexOf(char, from)\n if (at === -1) {\n return null\n }\n if (at === previous + 1) {\n score += 8\n }\n if (at === 0) {\n score += 4\n }\n from = at + 1\n previous = at\n }\n // Shorter haystacks matched the same needle more tightly.\n return score - haystack.length / 100\n}\n","import { lstatSync, readdirSync, type Dirent } from 'node:fs'\nimport { basename, join } from 'node:path'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { WriteHostFileRequest } from '@workerdeck/protocol'\nimport { asUtf8, hashBytes, json, readJsonBody } from '../lib/http.ts'\nimport { searchFiles } from '../services/host-file-search.ts'\nimport { entryKind, readContained, resolveExisting, resolveForWrite, writeContained } from '../services/host-files.ts'\nimport type { ServerContext } from '../context.ts'\n\nfunction kindRank(type: string): number {\n return type === 'dir' ? 0 : 1\n}\n\nexport async function handleHostFiles(ctx: ServerContext, req: IncomingMessage, res: ServerResponse, pathname: string): Promise<void> {\n const { basePath, hostFiles, hostFilesWritable, maxHostFileBytes, maxHostDirEntries } = ctx\n if (!hostFiles) {\n json(res, 404, { error: 'host file access is not configured on this server' })\n return\n }\n const route = pathname.slice((basePath + '/fs/').length)\n const url = new URL(req.url ?? '/', 'http://internal')\n const requested = url.searchParams.get('path')\n\n if (route === 'roots') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n // The canonical spelling, not the operator's: a client round-tripping a root it was given must land on the same tree.\n json(res, 200, {\n roots: hostFiles.roots.map(({ canonical }) => ({\n path: canonical,\n name: basename(canonical) || canonical,\n })),\n canWrite: hostFilesWritable,\n })\n return\n }\n\n if (route === 'find') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!requested) {\n json(res, 400, { error: 'path is required' })\n return\n }\n const resolved = resolveExisting(hostFiles, requested)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n if (resolved.kind !== 'dir') {\n json(res, 400, { error: 'not a directory' })\n return\n }\n // Clamped, not validated: this runs per keystroke from a phone.\n const asked = Number(url.searchParams.get('limit') ?? '')\n const limit = Number.isFinite(asked) && asked > 0 ? Math.min(asked, 200) : 50\n const result = searchFiles(resolved.path, {\n query: url.searchParams.get('q') ?? '',\n limit,\n ignore: ctx.options.hostFiles?.ignore,\n })\n json(res, 200, { base: resolved.path, ...result })\n return\n }\n\n if (route === 'list' || route === 'read') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!requested) {\n json(res, 400, { error: 'path is required' })\n return\n }\n const resolved = resolveExisting(hostFiles, requested)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n if (route === 'list') {\n if (resolved.kind !== 'dir') {\n json(res, 400, { error: 'not a directory' })\n return\n }\n let names: Dirent[]\n try {\n names = readdirSync(resolved.path, { withFileTypes: true })\n } catch {\n json(res, 403, { error: 'directory is not readable' })\n return\n }\n const truncated = names.length > maxHostDirEntries\n const entries = names.slice(0, maxHostDirEntries).map((entry) => {\n const path = join(resolved.path, entry.name)\n const type = entryKind(entry)\n // Never stat *through* a link: a directory holding a link to a fifo would become unlistable.\n let bytes: number | undefined\n let modifiedAt: number | undefined\n if (type === 'file') {\n try {\n const s = lstatSync(path)\n bytes = s.size\n modifiedAt = s.mtimeMs\n } catch {}\n }\n return { name: entry.name, path, type, bytes, modifiedAt }\n })\n entries.sort((a, b) => kindRank(a.type) - kindRank(b.type) || a.name.localeCompare(b.name))\n json(res, 200, { path: resolved.path, entries, ...(truncated ? { truncated } : {}) })\n return\n }\n\n if (resolved.kind !== 'file') {\n json(res, 400, { error: 'not a regular file' })\n return\n }\n // Advisory pre-check only — the authoritative cap is on the bytes actually read, since the file can grow before the open.\n let modifiedAt = 0\n try {\n const stats = lstatSync(resolved.path)\n if (stats.size > maxHostFileBytes) {\n json(res, 413, { error: `file is larger than ${maxHostFileBytes} bytes` })\n return\n }\n modifiedAt = stats.mtimeMs\n } catch {\n json(res, 404, { error: 'not found' })\n return\n }\n const read = readContained(resolved.path)\n if (!read.ok) {\n json(res, read.status, { error: read.error })\n return\n }\n if (read.data.length > maxHostFileBytes) {\n json(res, 413, { error: `file is larger than ${maxHostFileBytes} bytes` })\n return\n }\n const text = asUtf8(read.data)\n json(res, 200, {\n path: resolved.path,\n content: text ?? read.data.toString('base64'),\n encoding: text === null ? 'base64' : 'utf8',\n bytes: read.data.length,\n hash: hashBytes(read.data),\n modifiedAt,\n })\n return\n }\n\n if (route === 'write') {\n if (req.method !== 'PUT') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!hostFilesWritable) {\n json(res, 403, { error: 'host file writes are not enabled on this server' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as WriteHostFileRequest\n if (!body.path || typeof body.path !== 'string') {\n json(res, 400, { error: 'path is required' })\n return\n }\n if (typeof body.content !== 'string') {\n json(res, 400, { error: 'content is required' })\n return\n }\n if (body.encoding !== undefined && body.encoding !== 'utf8' && body.encoding !== 'base64') {\n json(res, 400, { error: \"encoding must be 'utf8' or 'base64'\" })\n return\n }\n const resolved = resolveForWrite(hostFiles, body.path)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n const next = Buffer.from(body.content, body.encoding ?? 'utf8')\n if (next.length > maxHostFileBytes) {\n json(res, 413, { error: `content is larger than ${maxHostFileBytes} bytes` })\n return\n }\n // Existence is decided by the read, not a stat: only ENOENT is 404, so anything else refuses rather than being clobbered as a create.\n const current = readContained(resolved.path)\n if (!current.ok && current.status !== 404) {\n json(res, current.status, { error: current.error })\n return\n }\n const existing = current.ok ? current.data : null\n if (existing && !body.expectedHash) {\n json(res, 409, { error: 'file exists — pass expectedHash to overwrite it' })\n return\n }\n if (existing && hashBytes(existing) !== body.expectedHash) {\n json(res, 409, { error: 'file changed on disk since it was read' })\n return\n }\n if (!existing && body.expectedHash) {\n json(res, 409, { error: 'file no longer exists' })\n return\n }\n const written = writeContained(resolved.path, next)\n if (!written.ok) {\n json(res, written.status, { error: written.error })\n return\n }\n let writtenAt = 0\n try {\n writtenAt = lstatSync(resolved.path).mtimeMs\n } catch {}\n json(res, 200, {\n path: resolved.path,\n bytes: next.length,\n hash: hashBytes(next),\n modifiedAt: writtenAt,\n })\n return\n }\n\n json(res, 404, { error: 'not found' })\n}\n","import type { CreateSessionRequest } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\nimport type { AuthContext } from '../services/auth.ts'\n\n/**\n * The one create-validation ladder, run by both create doors — `POST /sessions` and the\n * `session` block of `POST /jobs`. The scope design claims the two are indistinguishable, so\n * the order and the refusals have to come from a single place rather than two copies that can\n * drift. Mutates `req`: strips inert fields and pins the resolved profile name.\n */\nexport function vetCreateRequest(\n ctx: ServerContext,\n req: CreateSessionRequest,\n auth: AuthContext,\n): { status: number; error: string } | null {\n const { availability, factory } = ctx\n const refusedScope = factory.applyScope(req, auth)\n if (refusedScope) {\n return refusedScope\n }\n const refused = factory.applyBypassPolicy(req)\n if (refused) {\n return { status: 403, error: refused }\n }\n const resolved = factory.resolveProfile(req.profile, auth.allowedProfiles)\n if (!resolved.ok) {\n return { status: resolved.status, error: resolved.error }\n }\n const unavailable = availability.checkAvailable(resolved.profile)\n if (unavailable) {\n return unavailable\n }\n const refusedCwd = factory.checkCwd(req, resolved.profile)\n if (refusedCwd) {\n return refusedCwd\n }\n const badRequest = factory.checkPermissionMode(req.permissionMode, resolved.profile) ?? factory.checkEngineGrants(req, resolved.profile)\n if (badRequest) {\n return { status: 400, error: badRequest }\n }\n factory.stripInertFields(req, resolved.profile)\n req.profile = resolved.profile?.name\n return null\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { CreateJobRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport { vetCreateRequest } from './create-vet.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleJobs(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, basePath, queue } = ctx\n if (!queue) {\n json(res, 404, { error: 'job queue not configured' })\n return\n }\n if (pathname === basePath + '/queue') {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (!authSvc.isOperator(auth)) {\n json(res, 404, { error: 'not found' })\n return\n }\n json(res, 200, { stats: await queue.stats() })\n return\n }\n const rest = pathname.slice((basePath + '/jobs').length).replace(/^\\//, '')\n if (rest === '') {\n if (req.method === 'GET') {\n const jobs = await queue.list()\n json(res, 200, { jobs: jobs.filter((job) => authSvc.canSeeJob(auth, job)) })\n return\n }\n if (req.method === 'POST') {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as CreateJobRequest\n if (!body.session || typeof body.session !== 'object') {\n json(res, 400, { error: 'session is required' })\n return\n }\n if (!body.session.prompt || typeof body.session.prompt !== 'string') {\n json(res, 400, { error: 'session.prompt is required' })\n return\n }\n const refusal = vetCreateRequest(ctx, body.session, auth)\n if (refusal) {\n json(res, refusal.status, { error: refusal.error })\n return\n }\n try {\n json(res, 201, { job: await queue.submit(body) })\n } catch (error) {\n json(res, 400, { error: error instanceof Error ? error.message : 'invalid job' })\n }\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const id = decodeURIComponent(rest)\n if (id.includes('/')) {\n json(res, 404, { error: 'not found' })\n return\n }\n if (req.method === 'GET') {\n const job = await queue.get(id)\n if (job && authSvc.canSeeJob(auth, job)) {\n json(res, 200, { job })\n } else {\n json(res, 404, { error: 'job not found' })\n }\n return\n }\n if (req.method === 'DELETE') {\n // Checked before the cancel: a refused caller must not be able to kill a run and then be told it does not exist.\n const existing = await queue.get(id)\n if (!existing || !authSvc.canSeeJob(auth, existing)) {\n json(res, 404, { error: 'job not found' })\n return\n }\n const job = await queue.cancel(id)\n if (job) {\n json(res, 200, { job })\n } else {\n json(res, 404, { error: 'job not found' })\n }\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ProfileInfo, UpdateProfileRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport { readProfileConfig } from '../lib/profile-env.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleProfiles(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n auth: AuthContext,\n): Promise<void> {\n const { auth: authSvc, availability, basePath, profiles } = ctx\n const saveManaged = async (incoming: ProfileInfo): Promise<void> => {\n const saved = await profiles.saveManaged(incoming)\n if (!saved.ok) {\n json(res, saved.status, { error: saved.error })\n } else {\n json(res, 200, { profile: saved.profile })\n }\n }\n const rest = pathname.slice((basePath + '/profiles').length).replace(/^\\//, '')\n if (rest === '') {\n if (req.method === 'GET') {\n const visible = auth.allowedProfiles ? profiles.all().filter((p) => auth.allowedProfiles!.includes(p.name)) : profiles.all()\n availability.refresh(visible)\n json(res, 200, {\n profiles: visible.map((p) => profiles.forResponse(p)),\n canManage: profiles.manageGuard(auth) === null,\n })\n return\n }\n if (req.method === 'POST') {\n const refused = profiles.manageGuard(auth)\n if (refused) {\n json(res, refused.status, { error: refused.error })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as ProfileInfo\n if (!body.name || typeof body.name !== 'string') {\n json(res, 400, { error: 'name is required' })\n return\n }\n if (profiles.get(body.name)) {\n json(res, 409, { error: `profile already exists: ${body.name}` })\n return\n }\n await saveManaged(body)\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const name = decodeURIComponent(rest)\n const profile = name.includes('/') ? undefined : profiles.get(name)\n if (!profile) {\n json(res, 404, { error: 'profile not found' })\n return\n }\n if (auth.allowedProfiles && !auth.allowedProfiles.includes(profile.name)) {\n json(res, 403, { error: `profile not allowed: ${profile.name}` })\n return\n }\n if (req.method === 'GET') {\n json(res, 200, {\n profile: profiles.forResponse(profile),\n config: authSvc.isOperator(auth) ? readProfileConfig(profile) : undefined,\n })\n return\n }\n if (req.method === 'PATCH' || req.method === 'DELETE') {\n const refused = profiles.manageGuard(auth) ?? profiles.declaredGuard(profile)\n if (refused) {\n json(res, refused.status, { error: refused.error })\n return\n }\n if (req.method === 'DELETE') {\n await ctx.options.profileStore!.delete(profile.name)\n await profiles.refreshStored()\n res.writeHead(204).end()\n return\n }\n const patch = (await readJsonBody(req, ctx.maxBodyBytes)) as UpdateProfileRequest\n await saveManaged({ ...profile, ...patch, name: profile.name })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { ProfileInfo, SdkSessionSummary } from '@workerdeck/protocol'\nimport { json } from '../lib/http.ts'\nimport { cwdAllowed, engineOf } from '../lib/profile-env.ts'\nimport type { SdkSessionLister } from '../options.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport type { ServerContext } from '../context.ts'\n\n// A summary with no `cwd` cannot be shown to be inside the roots, so it is dropped.\nfunction withinRoots(sessions: SdkSessionSummary[], roots: string[], limit?: number, offset = 0): SdkSessionSummary[] {\n const allowed = sessions.filter((s) => s.cwd !== undefined && cwdAllowed(s.cwd, roots)).sort((a, b) => b.lastModified - a.lastModified)\n return limit === undefined ? allowed.slice(offset) : allowed.slice(offset, offset + limit)\n}\n\nexport async function handleSdkSessions(ctx: ServerContext, req: IncomingMessage, res: ServerResponse, auth: AuthContext): Promise<void> {\n const { adapterFor, factory, profiles } = ctx\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const url = new URL(req.url ?? '/', 'http://internal')\n const dir = url.searchParams.get('dir') ?? undefined\n const roots = ctx.options.allowedCwdRoots\n const limit = Number(url.searchParams.get('limit') ?? '') || undefined\n const offset = Number(url.searchParams.get('offset') ?? '') || undefined\n const requested = url.searchParams.get('profile') ?? undefined\n let profile: ProfileInfo | undefined\n if (requested !== undefined) {\n const resolved = factory.resolveProfile(requested, auth.allowedProfiles)\n if (!resolved.ok) {\n json(res, resolved.status, { error: resolved.error })\n return\n }\n profile = resolved.profile\n } else {\n // Implicit only when unambiguous AND permitted: a caller scoped away from the one profile falls back to the legacy listing.\n const all = profiles.all()\n if (all.length === 1 && (!auth.allowedProfiles || auth.allowedProfiles.includes(all[0]!.name))) {\n profile = all[0]\n }\n }\n const adapter = adapterFor(profile?.engine)\n if (!adapter.capabilities.listSessions) {\n json(res, 400, {\n error: `profile '${profile?.name ?? 'default'}' runs the ${engineOf(profile)} engine, which has no browsable session store`,\n })\n return\n }\n const lister: SdkSessionLister =\n engineOf(profile) === 'claude' && ctx.listSdkSessions\n ? ctx.listSdkSessions\n : (params) => {\n if (!adapter.listSessions) {\n throw new Error(`the ${engineOf(profile)} engine does not implement session listing`)\n }\n return adapter.listSessions({\n ...params,\n profile,\n env: profile ? factory.sessionEnvFor(profile) : process.env,\n })\n }\n try {\n if (roots && roots.length > 0) {\n if (dir) {\n if (!cwdAllowed(dir, roots)) {\n json(res, 403, { error: 'dir is outside the allowed roots' })\n return\n }\n } else {\n // A bare listing spans every project on the host, so it filters after listing — which is why the paging is applied here too.\n json(res, 200, { sdkSessions: withinRoots(await lister({}), roots, limit, offset) })\n return\n }\n }\n json(res, 200, { sdkSessions: await lister({ dir, limit, offset }) })\n } catch (error) {\n json(res, 500, { error: error instanceof Error ? error.message : 'failed to list sessions' })\n }\n}\n","import { mkdir, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { ParkedExecution, RunnerSnapshot, SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type ParkedSessionRecord = {\n kind?: 'parked' | 'live'\n id: string\n info: SessionInfo\n profile?: string\n config: SessionRunnerConfig\n snapshot: RunnerSnapshot\n executions: ParkedExecution[]\n parkedAt: number\n}\n\nexport function isLiveRecord(record: StoredSessionRecord): boolean {\n return record.kind === 'live'\n}\n\nexport type DormantSessionRecord = {\n kind: 'dormant'\n id: string\n info: SessionInfo\n profile?: string\n config: SessionRunnerConfig\n sdkSessionId: string\n savedAt: number\n}\n\nexport type StoredSessionRecord = ParkedSessionRecord | DormantSessionRecord\n\nexport function isDormant(record: StoredSessionRecord): record is DormantSessionRecord {\n return record.kind === 'dormant'\n}\n\nexport interface SessionStore {\n save(record: StoredSessionRecord): Promise<void>\n get(id: string): Promise<StoredSessionRecord | null>\n list(): Promise<StoredSessionRecord[]>\n delete(id: string): Promise<boolean>\n}\n\nexport class MemorySessionStore implements SessionStore {\n #records = new Map<string, StoredSessionRecord>()\n\n save(record: StoredSessionRecord): Promise<void> {\n this.#records.set(record.id, record)\n return Promise.resolve()\n }\n\n get(id: string): Promise<StoredSessionRecord | null> {\n return Promise.resolve(this.#records.get(id) ?? null)\n }\n\n list(): Promise<StoredSessionRecord[]> {\n return Promise.resolve([...this.#records.values()])\n }\n\n delete(id: string): Promise<boolean> {\n return Promise.resolve(this.#records.delete(id))\n }\n}\n\nconst EPHEMERAL_CONFIG_KEYS = ['queryFn', 'historyFn', 'extraOptions', 'env'] as const\n\nexport function toDurableRecord<T extends StoredSessionRecord>(record: T): T {\n const config: SessionRunnerConfig = { ...record.config }\n for (const key of EPHEMERAL_CONFIG_KEYS) {\n delete config[key]\n }\n return { ...record, config }\n}\n\nconst FORMAT_VERSION = 1\n\nexport type FileSessionStoreOptions = {\n dir?: string\n onError?: (error: unknown, context: { path: string; op: 'save' | 'read' | 'delete' }) => void\n}\n\nexport function createFileSessionStore(options: FileSessionStoreOptions = {}): SessionStore {\n const dir = options.dir ?? join(process.cwd(), '.workerdeck', 'parked')\n // Encoded, not interpolated: an id is a runner-assigned string, and a '/' in one would otherwise write outside `dir`.\n const fileFor = (id: string): string => join(dir, `${encodeURIComponent(id)}.json`)\n\n const read = async (path: string): Promise<StoredSessionRecord | null> => {\n let raw: string\n try {\n raw = await readFile(path, 'utf8')\n } catch (error) {\n // Only absence is \"nothing parked\": reporting an EACCES as one is how a restart guard ends up saying the coast is clear.\n if (isMissing(error)) {\n return null\n }\n options.onError?.(error, { path, op: 'read' })\n return null\n }\n try {\n return parseRecord(JSON.parse(raw))\n } catch (error) {\n options.onError?.(error, { path, op: 'read' })\n return null\n }\n }\n\n return {\n save: async (record) => {\n const path = fileFor(record.id)\n let payload: string\n try {\n payload = JSON.stringify({ version: FORMAT_VERSION, record: toDurableRecord(record) })\n } catch (error) {\n options.onError?.(error, { path, op: 'save' })\n throw new Error(\n `parked session '${record.id}' is not JSON-serializable — a host-injected value ` +\n `reached its config or snapshot: ${String(error)}`,\n { cause: error },\n )\n }\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 })\n const temp = `${path}.${process.pid}.tmp`\n await writeFile(temp, payload, { mode: 0o600 })\n await rename(temp, path)\n } catch (error) {\n options.onError?.(error, { path, op: 'save' })\n throw error\n }\n },\n\n get: (id) => read(fileFor(id)),\n\n list: async () => {\n let names: string[]\n try {\n names = await readdir(dir)\n } catch (error) {\n if (isMissing(error)) {\n return []\n }\n options.onError?.(error, { path: dir, op: 'read' })\n throw error\n }\n const records = await Promise.all(\n names\n .filter((name) => name.endsWith('.json'))\n .map(async (name) => {\n const record = await read(join(dir, name))\n if (!record) {\n return null\n }\n // A record only answers `get`/`delete` under the name its id encodes to; one that arrived some other way would be unreachable.\n if (`${encodeURIComponent(record.id)}.json` === name) {\n return record\n }\n options.onError?.(new Error(`parked record '${record.id}' is stored as '${name}' and cannot be read back by id`), {\n path: join(dir, name),\n op: 'read',\n })\n return null\n }),\n )\n return records.filter((record): record is StoredSessionRecord => record !== null)\n },\n\n delete: async (id) => {\n const path = fileFor(id)\n try {\n await rm(path)\n return true\n } catch (error) {\n if (isMissing(error)) {\n return false\n }\n options.onError?.(error, { path, op: 'delete' })\n return false\n }\n },\n }\n}\n\nfunction isMissing(error: unknown): boolean {\n return (error as NodeJS.ErrnoException).code === 'ENOENT'\n}\n\nfunction parseRecord(value: unknown): StoredSessionRecord | null {\n if (!value || typeof value !== 'object') {\n return null\n }\n const envelope = value as { version?: unknown; record?: unknown }\n if (envelope.version !== FORMAT_VERSION) {\n return null\n }\n const record = envelope.record as Partial<StoredSessionRecord> | null\n if (!record || typeof record !== 'object') {\n return null\n }\n if (typeof record.id !== 'string') {\n return null\n }\n if (!record.info || !record.config) {\n return null\n }\n if (record.kind === 'dormant') {\n const dormant = record as Partial<DormantSessionRecord>\n if (typeof dormant.sdkSessionId !== 'string' || typeof dormant.savedAt !== 'number') {\n return null\n }\n return dormant as DormantSessionRecord\n }\n const parked = record as Partial<ParkedSessionRecord>\n if (typeof parked.parkedAt !== 'number' || !parked.snapshot) {\n return null\n }\n if (!Array.isArray(parked.executions)) {\n return null\n }\n return parked as ParkedSessionRecord\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { attachmentKind } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES, type SessionInfo } from '@workerdeck/protocol'\nimport { json, readRawBody, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleAttachments(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n sessionId: string,\n session: SessionInfo,\n attachmentId?: string,\n): Promise<void> {\n const { attachmentStore } = ctx\n if (req.method === 'POST' && attachmentId === undefined) {\n const url = new URL(req.url ?? '/', 'http://internal')\n const mediaType = req.headers['content-type']\n if (!mediaType) {\n json(res, 400, { error: 'content-type header is required' })\n return\n }\n const accepted = (session.capabilities ?? ENGINE_CAPABILITIES[session.engine ?? 'claude']).attachments\n const kind = attachmentKind(mediaType)\n if (kind && !accepted.includes(kind === 'document' ? 'pdf' : kind)) {\n json(res, 415, {\n error: `the ${session.engine ?? 'claude'} engine does not accept ${kind} attachments`,\n })\n return\n }\n let body: Buffer\n try {\n body = await readRawBody(req, attachmentStore.maxFileBytes)\n } catch {\n json(res, 413, { error: 'attachment is larger than the limit' })\n return\n }\n const result = attachmentStore.put(sessionId, url.searchParams.get('name') ?? 'attachment', mediaType, body)\n if (!result.ok) {\n const status = result.error.code === 'unsupported_type' ? 415 : result.error.code === 'empty' ? 400 : 413\n json(res, status, { error: result.error.message })\n return\n }\n json(res, 201, { attachment: result.attachment })\n return\n }\n if (req.method === 'GET' && attachmentId !== undefined) {\n const found = attachmentStore.get(sessionId, attachmentId)\n if (!found) {\n json(res, 404, { error: 'attachment not found' })\n return\n }\n const bytes = Buffer.from(found.data, 'base64')\n res.writeHead(200, untrustedDownloadHeaders(found.name, found.mediaType, bytes.length))\n res.end(bytes)\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { Runner } from '@workerdeck/core'\nimport type { McpServerActionRequest } from '@workerdeck/protocol'\nimport { json, readJsonBody } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleMcp(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n runner: Runner,\n serverName?: string,\n): Promise<void> {\n const listServers = async (): Promise<boolean> => {\n const servers = await runner.mcpServers?.()\n if (!servers) {\n json(res, 501, { error: 'this session does not report MCP servers' })\n return false\n }\n json(res, 200, { servers })\n return true\n }\n if (req.method === 'GET' && serverName === undefined) {\n await listServers()\n return\n }\n if (req.method === 'POST' && serverName !== undefined) {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as McpServerActionRequest\n if (body?.action !== 'reconnect' && body?.action !== 'enable' && body?.action !== 'disable') {\n json(res, 400, { error: \"action must be 'reconnect', 'enable' or 'disable'\" })\n return\n }\n const canAct =\n body.action === 'reconnect' ? typeof runner.reconnectMcpServer === 'function' : typeof runner.setMcpServerEnabled === 'function'\n if (!canAct) {\n json(res, 501, {\n error: `this session's engine cannot ${body.action} an MCP server`,\n })\n return\n }\n try {\n if (body.action === 'reconnect') {\n await runner.reconnectMcpServer?.(serverName)\n } else {\n await runner.setMcpServerEnabled?.(serverName, body.action === 'enable')\n }\n } catch (error) {\n json(res, 400, { error: error instanceof Error ? error.message : 'MCP action failed' })\n return\n }\n await listServers()\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import { createReadStream, statSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { contentTypeFor, json, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { ServerContext } from '../context.ts'\n\nexport async function handleProducedFiles(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n sessionId: string,\n fileId?: string,\n): Promise<void> {\n const { producedFiles } = ctx\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n if (fileId === undefined) {\n json(res, 200, {\n files: producedFiles.list(sessionId).map(({ fileId: id, path, mediaType, bytes }) => ({\n fileId: id,\n path,\n ...(mediaType ? { mediaType } : {}),\n ...(bytes !== undefined ? { bytes } : {}),\n })),\n })\n return\n }\n const found = producedFiles.get(sessionId, fileId)\n if (!found) {\n json(res, 404, { error: 'no such produced file' })\n return\n }\n // statSync follows symlinks deliberately: a link the engine created is part of what it produced, and there is no root to realpath against.\n let stat\n try {\n stat = statSync(found.path)\n } catch {\n json(res, 404, { error: 'produced file is no longer on disk' })\n return\n }\n if (!stat.isFile()) {\n json(res, 404, { error: 'produced file is not a regular file' })\n return\n }\n const filename = basename(found.path) || 'file'\n res.writeHead(200, untrustedDownloadHeaders(filename, found.mediaType ?? contentTypeFor(filename), stat.size))\n await new Promise<void>((done) => {\n const stream = createReadStream(found.path)\n stream.on('error', () => {\n res.destroy()\n done()\n })\n stream.on('close', () => done())\n stream.pipe(res)\n })\n}\n","import { createHash } from 'node:crypto'\nimport { lstatSync, realpathSync } from 'node:fs'\nimport { basename, dirname, isAbsolute, join, resolve } from 'node:path'\nimport type { ProjectIcon, ProjectInfo, SessionInfo } from '@workerdeck/protocol'\nimport { contained, readContained } from './host-files.ts'\n\nconst PROJECT_FILE = '.workerdeck.json'\nconst MAX_PROJECT_FILE_BYTES = 64 * 1024\nexport const MAX_PROJECT_ICON_BYTES = 512 * 1024\nconst MAX_NAME_CHARS = 80\nconst GLYPH_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/\n\nconst DEFAULT_TTL_MS = 30_000\nconst SWEEP_ABOVE = 256\n\ntype IconMediaType = 'image/png' | 'image/svg+xml'\n\nexport type ResolvedProjectIcon = { path: string; mediaType: IconMediaType; hash: string }\n\ntype Resolution = {\n project?: ProjectInfo\n icon?: ResolvedProjectIcon\n expiresAt: number\n}\n\nexport class ProjectInfoService {\n readonly #ttlMs: number\n readonly #byCwd = new Map<string, Resolution>()\n\n constructor(options: { ttlMs?: number } = {}) {\n this.#ttlMs = options.ttlMs ?? DEFAULT_TTL_MS\n }\n\n withProject(info: SessionInfo): SessionInfo {\n if (!info.cwd) {\n return info\n }\n const project = this.#resolve(info.cwd).project\n return project ? { ...info, project } : info\n }\n\n iconFor(cwd: string): ResolvedProjectIcon | undefined {\n if (!cwd) {\n return undefined\n }\n return this.#resolve(cwd).icon\n }\n\n #resolve(cwd: string): Resolution {\n const now = Date.now()\n const held = this.#byCwd.get(cwd)\n if (held && held.expiresAt > now) {\n return held\n }\n if (this.#byCwd.size > SWEEP_ABOVE) {\n for (const [key, entry] of this.#byCwd) {\n if (entry.expiresAt <= now) {\n this.#byCwd.delete(key)\n }\n }\n }\n const fresh = { ...discover(cwd), expiresAt: now + this.#ttlMs }\n this.#byCwd.set(cwd, fresh)\n return fresh\n }\n}\n\nfunction discover(cwd: string): Omit<Resolution, 'expiresAt'> {\n if (!isAbsolute(cwd) || cwd.includes('\\0')) {\n return {}\n }\n let dir: string\n try {\n dir = realpathSync(cwd)\n } catch {\n return {}\n }\n for (;;) {\n const found = tryLoad(join(dir, PROJECT_FILE), dir)\n if (found) {\n return found\n }\n const parent = dirname(dir)\n if (parent === dir) {\n return {}\n }\n dir = parent\n }\n}\n\nfunction tryLoad(file: string, root: string): Omit<Resolution, 'expiresAt'> | undefined {\n let stat\n try {\n stat = lstatSync(file)\n } catch {\n return undefined\n }\n // A symlinked project file is skipped, not followed — the agent writes this tree.\n if (!stat.isFile() || stat.size > MAX_PROJECT_FILE_BYTES) {\n return undefined\n }\n const read = readContained(file)\n if (!read.ok) {\n return undefined\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(read.data.toString('utf8'))\n } catch {\n return undefined\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return undefined\n }\n const raw = parsed as { name?: unknown; icon?: unknown }\n const name = typeof raw.name === 'string' && raw.name.trim() ? raw.name.trim().slice(0, MAX_NAME_CHARS) : basename(root)\n const icon = classifyIcon(raw.icon, root)\n return {\n project: { name, root, ...(icon ? { icon: icon.wire } : {}) },\n ...(icon?.resolved ? { icon: icon.resolved } : {}),\n }\n}\n\nfunction classifyIcon(value: unknown, root: string): { wire: ProjectIcon; resolved?: ResolvedProjectIcon } | undefined {\n if (typeof value !== 'string') {\n return undefined\n }\n const declared = value.trim()\n if (!declared || declared.includes('\\0') || declared.length > 512) {\n return undefined\n }\n const lower = declared.toLowerCase()\n const mediaType: IconMediaType | undefined = lower.endsWith('.png') ? 'image/png' : lower.endsWith('.svg') ? 'image/svg+xml' : undefined\n if (!mediaType) {\n if (!GLYPH_RE.test(declared) || declared.length > 64) {\n return undefined\n }\n return { wire: { type: 'glyph', name: declared } }\n }\n if (isAbsolute(declared) || declared.includes('\\\\')) {\n return undefined\n }\n let canonical: string\n try {\n canonical = realpathSync(resolve(root, declared))\n } catch {\n return undefined\n }\n if (!contained(root, canonical)) {\n return undefined\n }\n let stat\n try {\n stat = lstatSync(canonical)\n } catch {\n return undefined\n }\n if (!stat.isFile() || stat.size === 0 || stat.size > MAX_PROJECT_ICON_BYTES) {\n return undefined\n }\n const read = readContained(canonical)\n if (!read.ok || read.data.length > MAX_PROJECT_ICON_BYTES) {\n return undefined\n }\n const hash = createHash('sha256').update(read.data).digest('hex')\n return {\n wire: { type: 'image', mediaType, hash },\n resolved: { path: canonical, mediaType, hash },\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { json } from '../lib/http.ts'\nimport { readContained } from '../services/host-files.ts'\nimport { MAX_PROJECT_ICON_BYTES, type ProjectInfoService } from '../services/project-info.ts'\n\nexport function handleProjectIcon(projects: ProjectInfoService, req: IncomingMessage, res: ServerResponse, cwd: string): void {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const icon = projects.iconFor(cwd)\n if (!icon) {\n json(res, 404, { error: 'no project icon' })\n return\n }\n const etag = `\"${icon.hash}\"`\n if (req.headers['if-none-match'] === etag) {\n res.writeHead(304, { etag })\n res.end()\n return\n }\n const read = readContained(icon.path)\n if (!read.ok || read.data.length > MAX_PROJECT_ICON_BYTES) {\n json(res, 404, { error: 'no project icon' })\n return\n }\n res.writeHead(200, {\n 'content-type': icon.mediaType,\n 'content-length': read.data.length,\n etag,\n 'cache-control': 'private, max-age=300',\n 'content-disposition': 'attachment; filename=\"project-icon\"',\n 'x-content-type-options': 'nosniff',\n })\n res.end(read.data)\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { imagePartRef, type SessionEvent, type ToolResultBlock } from '@workerdeck/protocol'\nimport { json } from '../lib/http.ts'\n\nexport type EventLookup = ((seq: number) => SessionEvent | undefined) | undefined\n\nexport function handleToolResult(req: IncomingMessage, res: ServerResponse, lookup: EventLookup, seq: number): void {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const url = new URL(req.url ?? '/', 'http://internal')\n const toolUseId = url.searchParams.get('toolUseId')\n if (!toolUseId) {\n json(res, 400, { error: 'toolUseId is required' })\n return\n }\n if (!lookup) {\n json(res, 501, { error: 'engine does not serve stored events' })\n return\n }\n const event = lookup(seq)\n if (!event || event.type !== 'user_message' || !Array.isArray(event.message.content)) {\n json(res, 404, { error: 'no such event' })\n return\n }\n const block = event.message.content.find(\n (candidate): candidate is ToolResultBlock =>\n candidate.type === 'tool_result' && (candidate as ToolResultBlock).tool_use_id === toolUseId,\n )\n if (!block) {\n json(res, 404, { error: 'no such tool result in that event' })\n return\n }\n\n const partParam = url.searchParams.get('part')\n if (partParam !== null) {\n const index = Number(partParam)\n const parts = block.content\n const part = Number.isInteger(index) && Array.isArray(parts) ? parts[index] : undefined\n const ref = part ? imagePartRef(part, index) : undefined\n if (!ref) {\n json(res, 404, { error: 'no such image part in that tool result' })\n return\n }\n const source = (part as { source?: { data?: string } }).source\n const bytes = Buffer.from(source?.data ?? '', 'base64')\n res.writeHead(200, { 'content-type': ref.media_type, 'content-length': String(bytes.length) })\n res.end(bytes)\n return\n }\n\n const content =\n url.searchParams.get('imageRefs') === '1' && Array.isArray(block.content)\n ? block.content.map((part, index) => imagePartRef(part, index) ?? part)\n : (block.content ?? '')\n json(res, 200, { seq, toolUseId, content, isError: block.is_error === true })\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { CreateSessionRequest, ResolvePermissionRequest, UpdateSessionRequest } from '@workerdeck/protocol'\nimport { contentTypeFor, json, readJsonBody, untrustedDownloadHeaders } from '../lib/http.ts'\nimport type { SessionRoute } from '../lib/parse-route.ts'\nimport type { AuthContext } from '../services/auth.ts'\nimport { isDormant } from '../services/session-store.ts'\nimport type { ServerContext } from '../context.ts'\nimport { vetCreateRequest } from './create-vet.ts'\nimport { handleAttachments } from './attachments.ts'\nimport { handleMcp } from './mcp.ts'\nimport { handleProducedFiles } from './produced-files.ts'\nimport { handleProjectIcon } from './project-icon.ts'\nimport { handleToolResult } from './tool-results.ts'\n\nexport async function handleSessions(\n ctx: ServerContext,\n req: IncomingMessage,\n res: ServerResponse,\n route: SessionRoute,\n auth: AuthContext,\n): Promise<void> {\n const { attachmentStore, auth: authSvc, bridge, factory, parking, producedFiles, projects, registry } = ctx\n\n if (!route.id) {\n if (req.method === 'GET') {\n const sessions = [...registry.list(), ...(await parking.listInfo())]\n json(res, 200, {\n sessions: sessions.filter((session) => authSvc.canSee(auth, session)).map((session) => projects.withProject(session)),\n })\n return\n }\n if (req.method === 'POST') {\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as CreateSessionRequest\n const refusal = vetCreateRequest(ctx, body, auth)\n if (refusal) {\n json(res, refusal.status, { error: refusal.error })\n return\n }\n const runner = await factory.createRunner(factory.buildRunnerConfig(body))\n factory.watchAuthSource(runner)\n json(res, 201, { session: projects.withProject(runner.info()) })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n return\n }\n\n const runner = registry.get(route.id)\n const parked = runner ? null : await parking.get(route.id)\n if (!runner && !parked) {\n json(res, 404, { error: 'session not found' })\n return\n }\n if (!authSvc.canSee(auth, runner?.info() ?? parked!.info)) {\n json(res, 404, { error: 'session not found' })\n return\n }\n if (route.attachments) {\n await handleAttachments(ctx, req, res, route.id, runner?.info() ?? parked!.info, route.attachmentId)\n return\n }\n if (route.mcp) {\n if (!runner) {\n json(res, 409, { error: 'session is parked (wake it before asking about MCP)' })\n return\n }\n await handleMcp(ctx, req, res, runner, route.mcpServer)\n return\n }\n if (route.files) {\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const snapshotFiles = parked && !isDormant(parked) ? parked.snapshot.vfs : undefined\n const vfs =\n runner?.vfs ??\n (snapshotFiles && {\n list: () => Object.keys(snapshotFiles).sort(),\n read: (path: string) => snapshotFiles[path]!,\n })\n if (!vfs) {\n json(res, 404, { error: 'session has no file store' })\n return\n }\n if (route.filePath === undefined) {\n const files = vfs.list().map((path) => ({ path, bytes: vfs.read(path)?.length ?? 0 }))\n json(res, 200, { files })\n return\n }\n const content = vfs.read(route.filePath)\n if (content === undefined) {\n json(res, 404, { error: `no such file: ${route.filePath}` })\n return\n }\n const filename = route.filePath.split('/').pop() || 'file'\n res.writeHead(200, untrustedDownloadHeaders(filename, contentTypeFor(filename), Buffer.byteLength(content)))\n res.end(content)\n return\n }\n if (route.produced) {\n await handleProducedFiles(ctx, req, res, route.id, route.producedFileId)\n return\n }\n if (route.projectIcon) {\n handleProjectIcon(projects, req, res, (runner?.info() ?? parked!.info).cwd)\n return\n }\n if (route.resultSeq !== undefined) {\n const snapshot = parked && !isDormant(parked) ? parked.snapshot.events : undefined\n handleToolResult(\n req,\n res,\n runner?.eventAt?.bind(runner) ?? (snapshot && ((seq: number) => snapshot.find((event) => event.seq === seq))),\n route.resultSeq,\n )\n return\n }\n if (route.permissionId) {\n if (req.method !== 'POST') {\n json(res, 405, { error: 'method not allowed' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as ResolvePermissionRequest\n if (body?.behavior !== 'allow' && body?.behavior !== 'deny') {\n json(res, 400, { error: \"behavior must be 'allow' or 'deny'\" })\n return\n }\n if (!runner) {\n json(res, 409, { error: 'session is parked (it has no pending permission requests)' })\n return\n }\n if (!runner.resolvePermission(route.permissionId, body)) {\n json(res, 404, { error: 'permission request not found (already resolved or expired)' })\n return\n }\n json(res, 200, { resolved: true })\n return\n }\n if (req.method === 'GET') {\n json(res, 200, { session: projects.withProject(runner?.info() ?? parked!.info) })\n return\n }\n if (req.method === 'PATCH') {\n if (!runner) {\n json(res, 409, { error: 'session is parked (wake it before renaming)' })\n return\n }\n const body = (await readJsonBody(req, ctx.maxBodyBytes)) as UpdateSessionRequest\n if (body?.title !== undefined) {\n if (body.title !== null && typeof body.title !== 'string') {\n json(res, 400, { error: 'title must be a string or null' })\n return\n }\n const title = typeof body.title === 'string' ? body.title.trim() : ''\n runner.setTitle(title || undefined)\n parking.touch(runner)\n }\n json(res, 200, { session: projects.withProject(runner.info()) })\n return\n }\n if (req.method === 'DELETE') {\n registry.remove(route.id)\n bridge.remove(route.id)\n await parking.discard(route.id)\n attachmentStore.drop(route.id)\n producedFiles.drop(route.id)\n json(res, 200, {\n session: projects.withProject(runner?.info() ?? { ...parked!.info, status: 'closed' as const }),\n })\n return\n }\n json(res, 405, { error: 'method not allowed' })\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { WebSocket } from 'ws'\nimport type { Runner } from '@workerdeck/core'\nimport { PROTOCOL_VERSION, type ClientFrame, type ServerFrame } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\n\nexport function attachClient(ctx: ServerContext, ws: WebSocket, runner: Runner, req: IncomingMessage): void {\n const { bridge, parking } = ctx\n const url = new URL(req.url ?? '/', 'http://internal')\n const afterSeq = Number(url.searchParams.get('afterSeq') ?? '0') || 0\n const truncateResults = url.searchParams.get('truncateResults') === '1'\n const imageRefs = url.searchParams.get('imageRefs') === '1'\n\n const send = (frame: ServerFrame): void => {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(frame))\n }\n }\n\n send({\n type: 'attached',\n protocolVersion: PROTOCOL_VERSION,\n session: ctx.projects.withProject(runner.info()),\n replayingFrom: afterSeq,\n })\n const unsubscribe = runner.subscribe((event) => send({ type: 'event', event }), afterSeq, {\n coalesceReplay: true,\n truncateResults,\n imageRefs,\n })\n const detachBridge = bridge.attach(runner.id, send)\n\n ws.on('message', (data: Buffer) => {\n let frame: ClientFrame\n try {\n frame = JSON.parse(data.toString('utf8')) as ClientFrame\n } catch {\n send({ type: 'protocol_error', message: 'invalid JSON frame' })\n return\n }\n handleCommand(ctx, frame, runner).catch((error: unknown) => {\n send({\n type: 'protocol_error',\n message: error instanceof Error ? error.message : 'command failed',\n })\n })\n })\n ws.on('close', () => {\n unsubscribe()\n detachBridge()\n parking.onDetach(runner.id)\n })\n}\n\nasync function handleCommand(ctx: ServerContext, frame: ClientFrame, runner: Runner): Promise<void> {\n const { attachmentStore, bridge } = ctx\n switch (frame.type) {\n case 'user_message': {\n if (!frame.attachmentIds?.length) {\n runner.sendMessage(frame.text)\n return\n }\n const resolved = attachmentStore.resolve(runner.id, frame.attachmentIds)\n if (!resolved.ok) {\n throw new Error(`unknown attachment(s): ${resolved.missing.join(', ')}`)\n }\n runner.sendMessage(frame.text, resolved.attachments)\n return\n }\n case 'permission_decision': {\n if (frame.behavior === 'allow') {\n runner.resolvePermission(frame.requestId, {\n behavior: 'allow',\n updatedInput: frame.updatedInput,\n })\n } else {\n runner.resolvePermission(frame.requestId, {\n behavior: 'deny',\n message: frame.message,\n interrupt: frame.interrupt,\n })\n }\n return\n }\n case 'interrupt': {\n await runner.interrupt()\n return\n }\n case 'clear_context': {\n if (!runner.clearContext) {\n throw new Error(`the ${runner.info().engine ?? 'claude'} engine cannot clear a conversation`)\n }\n await runner.clearContext()\n return\n }\n case 'set_permission_mode': {\n if (frame.mode === 'bypassPermissions' && ctx.options.disableBypassPermissions) {\n throw new Error('bypassPermissions is disabled on this server (disableBypassPermissions)')\n }\n await runner.setPermissionMode(frame.mode)\n return\n }\n case 'set_model': {\n await runner.setModel(frame.model)\n return\n }\n case 'tool_call_result': {\n bridge.resolve(runner.id, frame.executionId, { output: frame.output, logs: frame.logs })\n return\n }\n case 'tool_call_error': {\n bridge.resolve(runner.id, frame.executionId, {\n reason: frame.reason,\n error: frame.error,\n logs: frame.logs,\n })\n return\n }\n case 'close': {\n runner.close('client')\n return\n }\n default: {\n throw new Error(`unknown command: ${(frame as { type?: string }).type}`)\n }\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { attachmentKind, normalizeMediaType, type AttachmentInput } from '@workerdeck/core'\nimport type { MessageAttachment } from '@workerdeck/protocol'\n\nexport type AttachmentStoreOptions = {\n maxFileBytes?: number\n maxSessionBytes?: number\n}\n\nexport type AttachmentRejection =\n | { code: 'too_large'; message: string }\n | { code: 'session_full'; message: string }\n | { code: 'unsupported_type'; message: string }\n | { code: 'empty'; message: string }\n\nexport type PutResult = { ok: true; attachment: MessageAttachment } | { ok: false; error: AttachmentRejection }\n\nconst DEFAULT_MAX_FILE_BYTES = 10 * 1024 * 1024\nconst DEFAULT_MAX_SESSION_BYTES = 64 * 1024 * 1024\n\nexport class AttachmentStore {\n #bySession = new Map<string, Map<string, AttachmentInput>>()\n #maxFileBytes: number\n #maxSessionBytes: number\n\n constructor(options: AttachmentStoreOptions = {}) {\n this.#maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES\n this.#maxSessionBytes = options.maxSessionBytes ?? DEFAULT_MAX_SESSION_BYTES\n }\n\n get maxFileBytes(): number {\n return this.#maxFileBytes\n }\n\n put(sessionId: string, name: string, mediaType: string, body: Buffer): PutResult {\n if (body.length === 0) {\n return { ok: false, error: { code: 'empty', message: 'attachment is empty' } }\n }\n if (body.length > this.#maxFileBytes) {\n return {\n ok: false,\n error: {\n code: 'too_large',\n message: `attachment is larger than the ${this.#maxFileBytes}-byte limit`,\n },\n }\n }\n const type = normalizeMediaType(mediaType)\n if (!attachmentKind(type)) {\n return {\n ok: false,\n error: { code: 'unsupported_type', message: `unsupported media type: ${type}` },\n }\n }\n const held = this.#bySession.get(sessionId) ?? new Map<string, AttachmentInput>()\n const heldBytes = [...held.values()].reduce((sum, a) => sum + a.bytes, 0)\n if (heldBytes + body.length > this.#maxSessionBytes) {\n return {\n ok: false,\n error: {\n code: 'session_full',\n message: `session is already holding ${heldBytes} bytes of attachments (limit ${this.#maxSessionBytes})`,\n },\n }\n }\n const attachment: AttachmentInput = {\n id: randomUUID(),\n name: safeName(name),\n mediaType: type,\n bytes: body.length,\n data: body.toString('base64'),\n }\n held.set(attachment.id, attachment)\n this.#bySession.set(sessionId, held)\n return { ok: true, attachment: ref(attachment) }\n }\n\n get(sessionId: string, id: string): AttachmentInput | undefined {\n return this.#bySession.get(sessionId)?.get(id)\n }\n\n resolve(sessionId: string, ids: readonly string[]): { ok: true; attachments: AttachmentInput[] } | { ok: false; missing: string[] } {\n const held = this.#bySession.get(sessionId)\n const attachments: AttachmentInput[] = []\n const missing: string[] = []\n for (const id of ids) {\n const found = held?.get(id)\n if (found) {\n attachments.push(found)\n } else {\n missing.push(id)\n }\n }\n return missing.length ? { ok: false, missing } : { ok: true, attachments }\n }\n\n drop(sessionId: string): void {\n this.#bySession.delete(sessionId)\n }\n}\n\nfunction ref(attachment: AttachmentInput): MessageAttachment {\n return {\n id: attachment.id,\n name: attachment.name,\n mediaType: attachment.mediaType,\n bytes: attachment.bytes,\n }\n}\n\nfunction safeName(name: string): string {\n const leaf = name.split(/[/\\\\]/).pop() ?? ''\n // oxlint-disable-next-line no-control-regex\n const cleaned = leaf.replace(/[\\u0000-\\u001f\\u007f\"<>]/g, '').trim()\n if (cleaned === '' || cleaned === '.' || cleaned === '..') {\n return 'attachment'\n }\n return cleaned.length > 120 ? cleaned.slice(0, 120) : cleaned\n}\n","const MAX_SCOPE_KEYS = 16\nconst MAX_SCOPE_LEN = 200\n\nexport function readScope(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return undefined\n }\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.some(([, v]) => typeof v !== 'string')) {\n return undefined\n }\n return Object.fromEntries(entries) as Record<string, string>\n}\n\nexport function checkScope(value: unknown): string | null {\n if (value === undefined) {\n return null\n }\n const scope = readScope(value)\n if (!scope) {\n return 'scope must be an object of string values'\n }\n const entries = Object.entries(scope)\n if (entries.length > MAX_SCOPE_KEYS) {\n return `scope may carry at most ${MAX_SCOPE_KEYS} keys`\n }\n for (const [key, val] of entries) {\n if (key.length === 0) {\n return 'scope keys must not be empty'\n }\n if (key.length > MAX_SCOPE_LEN || val.length > MAX_SCOPE_LEN) {\n return `scope keys and values must be at most ${MAX_SCOPE_LEN} characters`\n }\n }\n return null\n}\n\nexport function sameScope(a: Record<string, string> | undefined, b: Record<string, string> | undefined): boolean {\n const left = Object.entries(a ?? {}).sort(([x], [y]) => (x < y ? -1 : 1))\n const right = Object.entries(b ?? {}).sort(([x], [y]) => (x < y ? -1 : 1))\n return left.length === right.length && left.every(([key, value], i) => right[i]![0] === key && right[i]![1] === value)\n}\n\nexport function scopeMatches(principal: Record<string, string> | undefined, session: Record<string, string> | undefined): boolean {\n if (!principal) {\n return true\n }\n return Object.entries(principal).every(([key, value]) => session?.[key] === value)\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { JobInfo, SessionInfo } from '@workerdeck/protocol'\nimport { readScope, scopeMatches } from '../lib/scope.ts'\nimport type { LateBoundRefs, WorkerServerOptions } from '../options.ts'\n\nexport type AuthContext = {\n ok: boolean\n allowedProfiles?: string[]\n canManageProfiles?: boolean\n principal?: unknown\n scope?: Record<string, string>\n operator?: boolean\n}\n\nexport type AuthService = ReturnType<typeof createAuthService>\n\nexport function createAuthService(deps: {\n options: Pick<WorkerServerOptions, 'authenticate' | 'authorizeSession'>\n refs: Pick<LateBoundRefs, 'registry'>\n}) {\n const { options, refs } = deps\n\n const authenticate = async (req: IncomingMessage): Promise<AuthContext> => {\n if (!options.authenticate) {\n return { ok: true }\n }\n const principal = await options.authenticate(req)\n if (principal === null || principal === undefined || principal === false) {\n return { ok: false }\n }\n const allowed = (principal as { allowedProfiles?: unknown }).allowedProfiles\n const scope = readScope((principal as { scope?: unknown }).scope)\n return {\n ok: true,\n principal,\n scope: scope && Object.keys(scope).length > 0 ? scope : undefined,\n operator:\n typeof (principal as { operator?: unknown }).operator === 'boolean' ? (principal as { operator: boolean }).operator : undefined,\n allowedProfiles: Array.isArray(allowed) && allowed.every((p) => typeof p === 'string') ? (allowed as string[]) : undefined,\n canManageProfiles: (principal as { canManageProfiles?: unknown }).canManageProfiles === true,\n }\n }\n\n const canSee = (auth: AuthContext, session: SessionInfo): boolean => {\n if (!options.authorizeSession) {\n return scopeMatches(auth.scope, session.scope)\n }\n try {\n return options.authorizeSession(auth.principal, session) === true\n } catch {\n return false\n }\n }\n\n const canSeeJob = (auth: AuthContext, job: JobInfo): boolean => {\n const live = job.sessionId ? refs.registry!.get(job.sessionId)?.info() : undefined\n if (live) {\n return canSee(auth, live)\n }\n if (!options.authorizeSession) {\n return scopeMatches(auth.scope, job.scope)\n }\n return canSee(auth, {\n id: job.sessionId ?? job.id,\n status: job.status === 'running' ? 'running' : job.status === 'parked' ? 'parked' : job.status === 'queued' ? 'starting' : 'closed',\n cwd: job.cwd,\n profile: job.profile,\n createdAt: job.createdAt,\n lastSeq: 0,\n pendingPermissionCount: 0,\n scope: job.scope,\n })\n }\n\n const isOperator = (auth: AuthContext): boolean => auth.operator ?? (auth.scope === undefined && !options.authorizeSession)\n\n return { authenticate, canSee, canSeeJob, isOperator }\n}\n","import { checkClaudeAuth } from '@workerdeck/core'\nimport type { ClaudeAuthProbe, EngineAdapter, EngineAvailability } from '@workerdeck/core'\nimport type { ProfileEngine, ProfileInfo } from '@workerdeck/protocol'\nimport { engineOf } from '../lib/profile-env.ts'\nimport type { Refusal } from './profiles.ts'\n\nconst AVAILABILITY_TTL_MS = 60_000\n\nexport type AvailabilityTrackerOptions = {\n checkCredentials?: boolean | { probe?: ClaudeAuthProbe; timeoutMs?: number }\n requireAvailableProfile?: boolean\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n sessionEnvFor: (profile: ProfileInfo) => Record<string, string | undefined>\n}\n\nexport class AvailabilityTracker {\n readonly #verdicts = new Map<string, { verdict: EngineAvailability; at: number }>()\n readonly #warned = new Set<string>()\n readonly #opts: AvailabilityTrackerOptions\n\n constructor(opts: AvailabilityTrackerOptions) {\n this.#opts = opts\n }\n\n get(name: string): EngineAvailability | undefined {\n return this.#verdicts.get(name)?.verdict\n }\n\n probe(profile: ProfileInfo): void {\n const { checkCredentials, adapterFor, sessionEnvFor } = this.#opts\n if (!checkCredentials) {\n return\n }\n const conf = checkCredentials === true ? {} : checkCredentials\n // Mark in-flight immediately so concurrent GET /profiles don't re-spawn.\n this.#verdicts.set(profile.name, {\n verdict: this.#verdicts.get(profile.name)?.verdict ?? { available: 'unknown' },\n at: Date.now(),\n })\n const adapter = adapterFor(profile.engine)\n const claudeProbe: ClaudeAuthProbe | undefined =\n engineOf(profile) !== 'claude'\n ? undefined\n : (conf.probe ?? (conf.timeoutMs !== undefined ? (env) => checkClaudeAuth(env, { timeoutMs: conf.timeoutMs }) : undefined))\n const run: Promise<EngineAvailability> = claudeProbe\n ? claudeProbe(sessionEnvFor(profile)).then((status): EngineAvailability =>\n status === 'logged_in'\n ? { available: true }\n : status === 'logged_out'\n ? { available: false, reason: 'no usable Claude credentials for this profile' }\n : { available: 'unknown' },\n )\n : adapter.checkAvailability(profile, sessionEnvFor(profile))\n void run\n .then((verdict) => {\n this.#verdicts.set(profile.name, { verdict, at: Date.now() })\n if (verdict.available === false && !this.#warned.has(profile.name)) {\n this.#warned.add(profile.name)\n console.warn(\n `[workerdeck] Profile '${profile.name}' is unavailable: ${verdict.reason} ` + '(`checkCredentials: false` disables this check)',\n )\n }\n if (verdict.available === true) {\n this.#warned.delete(profile.name)\n }\n })\n .catch(() => {})\n }\n\n checkAvailable(profile: ProfileInfo | undefined): Refusal | null {\n if (!this.#opts.requireAvailableProfile || !profile) {\n return null\n }\n const verdict = this.get(profile.name)\n if (!verdict || verdict.available !== false) {\n return null\n }\n return {\n status: 503,\n error: `profile '${profile.name}' is unavailable: ${verdict.reason ?? 'no usable credentials'}`,\n }\n }\n\n preflight(profiles: ProfileInfo[]): void {\n for (const profile of profiles) {\n this.probe(profile)\n }\n }\n\n refresh(profiles: ProfileInfo[]): void {\n if (!this.#opts.checkCredentials) {\n return\n }\n const now = Date.now()\n for (const profile of profiles) {\n const cached = this.#verdicts.get(profile.name)\n if (!cached || now - cached.at > AVAILABILITY_TTL_MS) {\n this.probe(profile)\n }\n }\n }\n}\n","import { BrowserBridgeExecutor, type BridgeAnswer, type ToolExecutionResult } from '@workerdeck/core'\nimport type { ServerFrame, ToolCallRequestFrame } from '@workerdeck/protocol'\n\ntype SessionBridge = {\n sockets: Array<(frame: ServerFrame) => void>\n executor: BrowserBridgeExecutor\n}\n\nexport type BridgeHubOptions = {\n timeoutMs?: number\n onResult?: (sessionId: string, executionId: string, result: ToolExecutionResult) => void\n}\n\nexport class BridgeHub {\n #sessions = new Map<string, SessionBridge>()\n #options: BridgeHubOptions\n\n constructor(options: BridgeHubOptions = {}) {\n this.#options = options\n }\n\n executorFor(sessionId: string): BrowserBridgeExecutor {\n return this.#bridge(sessionId).executor\n }\n\n attachedCount(sessionId: string): number {\n return this.#sessions.get(sessionId)?.sockets.length ?? 0\n }\n\n attach(sessionId: string, send: (frame: ServerFrame) => void): () => void {\n const bridge = this.#bridge(sessionId)\n bridge.sockets.push(send)\n return () => {\n const index = bridge.sockets.indexOf(send)\n if (index >= 0) {\n bridge.sockets.splice(index, 1)\n }\n }\n }\n\n resolve(sessionId: string, executionId: string, answer: BridgeAnswer): boolean {\n return this.#sessions.get(sessionId)?.executor.resolve(executionId, answer) ?? false\n }\n\n remove(sessionId: string): void {\n const bridge = this.#sessions.get(sessionId)\n if (!bridge) {\n return\n }\n bridge.executor.registry.cancelAll('session_closed', 'the session was closed')\n this.#sessions.delete(sessionId)\n }\n\n #bridge(sessionId: string): SessionBridge {\n const existing = this.#sessions.get(sessionId)\n if (existing) {\n return existing\n }\n const bridge: SessionBridge = {\n sockets: [],\n executor: new BrowserBridgeExecutor({\n timeoutMs: this.#options.timeoutMs,\n send: (frame: ToolCallRequestFrame) => {\n const target = bridge.sockets[0]\n if (!target) {\n return false\n }\n target(frame)\n return true\n },\n cancel: (executionId, reason) => {\n for (const send of bridge.sockets) {\n send({ type: 'tool_call_canceled', executionId, reason })\n }\n },\n onResult: (executionId, result) => {\n this.#options.onResult?.(sessionId, executionId, result)\n },\n }),\n }\n this.#sessions.set(sessionId, bridge)\n return bridge\n }\n}\n","import type { SessionInfo, SessionNotification, SessionWebhookConfig } from '@workerdeck/protocol'\nimport type { Runner } from '@workerdeck/core'\n\nexport type SessionNotificationOptions = {\n webhook?: SessionWebhookConfig\n onNotification?: (notification: SessionNotification) => void\n attempts?: number\n retryDelayMs?: number\n decorateInfo?: (info: SessionInfo) => SessionInfo\n}\n\nexport class SessionNotifier {\n readonly #options: SessionNotificationOptions\n readonly #chains = new Map<string, Promise<void>>()\n\n constructor(options: SessionNotificationOptions) {\n this.#options = options\n }\n\n get idle(): boolean {\n return !this.#options.webhook && !this.#options.onNotification\n }\n\n watch(runner: Runner, afterSeq = runner.info().lastSeq): void {\n if (this.idle) {\n return\n }\n runner.subscribe((event) => {\n switch (event.type) {\n case 'permission_requested': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'permission_requested',\n preview: event.request.title ?? event.request.toolName,\n request: event.request,\n })\n return\n }\n case 'turn_result': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'turn_completed',\n preview: event.isError ? event.errors?.join('\\n') : event.result,\n result: {\n isError: event.isError,\n durationMs: event.durationMs,\n numTurns: event.numTurns,\n totalCostUsd: event.totalCostUsd,\n },\n })\n return\n }\n case 'session_error': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'session_error',\n preview: event.message,\n })\n return\n }\n case 'session_closed': {\n this.#emit(runner, event.seq, event.ts, {\n type: 'session_closed',\n reason: event.reason,\n })\n return\n }\n default: {\n return\n }\n }\n }, afterSeq)\n }\n\n #emit(runner: Runner, seq: number, ts: number, body: Omit<SessionNotification, 'sessionId' | 'session' | 'seq' | 'ts'>): void {\n queueMicrotask(() => this.#send(runner, seq, ts, body))\n }\n\n #send(runner: Runner, seq: number, ts: number, body: Omit<SessionNotification, 'sessionId' | 'session' | 'seq' | 'ts'>): void {\n const webhook = this.#options.webhook\n const wanted = !webhook?.events || webhook.events.includes(body.type)\n if (!webhook && !this.#options.onNotification) {\n return\n }\n\n const notification: SessionNotification = {\n ...body,\n sessionId: runner.id,\n session: (this.#options.decorateInfo ?? ((info) => info))(runner.info()),\n seq,\n ts,\n }\n\n try {\n this.#options.onNotification?.(notification)\n } catch {}\n\n if (!webhook || !wanted) {\n return\n }\n const previous = this.#chains.get(runner.id) ?? Promise.resolve()\n const next = previous.then(() => this.#deliver(webhook, notification))\n this.#chains.set(runner.id, next)\n void next.then(() => {\n if (this.#chains.get(runner.id) === next) {\n this.#chains.delete(runner.id)\n }\n })\n }\n\n async #deliver(webhook: SessionWebhookConfig, notification: SessionNotification): Promise<void> {\n const attempts = this.#options.attempts ?? 3\n const baseDelay = this.#options.retryDelayMs ?? 500\n for (let attempt = 0; attempt < attempts; attempt++) {\n try {\n const res = await fetch(webhook.url, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...webhook.headers },\n body: JSON.stringify(notification),\n })\n if (res.ok) {\n return\n }\n } catch {}\n if (attempt < attempts - 1) {\n await new Promise((resolve) => setTimeout(resolve, baseDelay * 2 ** attempt))\n }\n }\n }\n}\n","import type { ParkedExecution, Runner, SessionRunnerConfig, ToolExecutionResult } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES, type SessionInfo } from '@workerdeck/protocol'\nimport type { SessionRegistry } from './registry.ts'\nimport {\n isDormant,\n isLiveRecord,\n type DormantSessionRecord,\n type ParkedSessionRecord,\n type SessionStore,\n type StoredSessionRecord,\n} from './session-store.ts'\n\n// The context handed to parking's onError: which session, and which lifecycle step failed.\nexport type ParkErrorContext = { sessionId: string; phase: 'park' | 'remember' | 'resume' }\n\nexport type SessionParkOptions = {\n registry: SessionRegistry\n store: SessionStore\n rebuild: (record: StoredSessionRecord) => Promise<Runner>\n attachedCount: (sessionId: string) => number\n parkDelayMs?: number\n persistLive?: boolean\n expiredGraceMs?: number\n onParking?: (sessionId: string, executionId: string) => boolean\n onResumed?: (sessionId: string, runner: Runner) => void\n onError?: (error: unknown, context: ParkErrorContext) => void\n}\n\nexport class SessionParkManager {\n #options: SessionParkOptions\n #owners = new Map<string, string>()\n #settled = new Map<string, string>()\n #timers = new Map<string, ReturnType<typeof setTimeout>>()\n #resuming = new Map<string, Promise<Runner | undefined>>()\n #detachTimers = new Map<string, ReturnType<typeof setTimeout>>()\n #configs = new Map<string, SessionRunnerConfig>()\n #remembered = new Set<string>()\n #storeOps = new Map<string, Promise<void>>()\n #closed = false\n\n constructor(options: SessionParkOptions) {\n this.#options = options\n }\n\n remember(sessionId: string, config: SessionRunnerConfig): void {\n this.#configs.set(sessionId, config)\n }\n\n touch(runner: Runner): void {\n void this.#rememberDormant(runner)\n void this.#persistLive(runner)\n }\n\n async hydrate(): Promise<void> {\n const floor = Date.now() + (this.#options.expiredGraceMs ?? 60_000)\n for (const record of await this.#options.store.list()) {\n if (isDormant(record)) {\n continue\n }\n for (const execution of record.executions) {\n this.#track(record.id, execution, floor)\n }\n }\n }\n\n watch(runner: Runner, afterSeq = 0): () => void {\n return runner.subscribe((event) => {\n switch (event.type) {\n case 'execution_dispatched': {\n if (!event.deferred) {\n return\n }\n this.#track(runner.id, {\n executionId: event.executionId,\n toolName: event.toolName,\n expiresAt: event.expiresAt,\n })\n return\n }\n case 'execution_result':\n case 'execution_failed': {\n this.#forget(event.executionId)\n // One call of a multi-call park settling leaves the session parked on the rest, and no new status_changed will say so.\n if (runner.info().status === 'parked') {\n void this.#park(runner)\n }\n return\n }\n case 'status_changed': {\n if (event.status === 'parked') {\n void this.#park(runner)\n } else {\n void this.#rememberDormant(runner)\n }\n return\n }\n case 'turn_result': {\n void this.#persistLive(runner)\n return\n }\n case 'permission_mode_changed':\n case 'model_changed': {\n void this.#persistLive(runner)\n return\n }\n case 'system_init': {\n void this.#rememberDormant(runner)\n return\n }\n case 'conversation_reset': {\n void this.#rememberDormant(runner)\n void this.#persistLive(runner)\n return\n }\n case 'session_closed': {\n if (this.#closed) {\n return\n }\n void this.discard(runner.id)\n return\n }\n default: {\n return\n }\n }\n }, afterSeq)\n }\n\n onDetach(sessionId: string): void {\n if (this.#closed) {\n return\n }\n const runner = this.#options.registry.get(sessionId)\n if (!runner || runner.info().status !== 'parked') {\n return\n }\n clearTimeout(this.#detachTimers.get(sessionId))\n const timer = setTimeout(() => {\n this.#detachTimers.delete(sessionId)\n void this.#park(runner)\n }, this.#options.parkDelayMs ?? 2000)\n timer.unref?.()\n this.#detachTimers.set(sessionId, timer)\n }\n\n sessionFor(executionId: string): string | undefined {\n return this.#owners.get(executionId) ?? this.#settled.get(executionId)\n }\n\n get(id: string): Promise<StoredSessionRecord | null> {\n return this.#queue(id, () => this.#options.store.get(id))\n }\n\n async listInfo(): Promise<SessionInfo[]> {\n await Promise.all(this.#storeOps.values())\n const records = await this.#options.store.list()\n return records.filter((record) => this.#options.registry.get(record.id) === undefined).map((record) => record.info)\n }\n\n async ensureLive(id: string): Promise<Runner | undefined> {\n const live = this.#options.registry.get(id)\n if (live) {\n return live\n }\n return this.#resume(id)\n }\n\n async submitResult(executionId: string, result: ToolExecutionResult): Promise<{ applied: boolean; sessionId: string } | undefined> {\n const sessionId = this.#owners.get(executionId)\n if (sessionId === undefined) {\n const settled = this.#settled.get(executionId)\n return settled === undefined ? undefined : { applied: false, sessionId: settled }\n }\n const runner = await this.ensureLive(sessionId)\n if (!runner) {\n this.#forget(executionId)\n return undefined\n }\n // Clear the watchdog first: settling re-enters the agent loop, and a timeout firing behind it would fail a call that no longer exists.\n this.#clearTimer(executionId)\n const applied = runner.settleExecution?.(executionId, result) ?? false\n if (applied) {\n this.#forget(executionId)\n }\n return { applied, sessionId }\n }\n\n async discard(sessionId: string): Promise<void> {\n clearTimeout(this.#detachTimers.get(sessionId))\n this.#detachTimers.delete(sessionId)\n this.#configs.delete(sessionId)\n this.#remembered.delete(sessionId)\n for (const [executionId, owner] of this.#owners) {\n if (owner === sessionId) {\n this.#forget(executionId)\n }\n }\n for (const [executionId, owner] of this.#settled) {\n if (owner === sessionId) {\n this.#settled.delete(executionId)\n }\n }\n await this.#queue(sessionId, () => this.#options.store.delete(sessionId))\n }\n\n close(): void {\n this.#closed = true\n for (const timer of this.#timers.values()) {\n clearTimeout(timer)\n }\n for (const timer of this.#detachTimers.values()) {\n clearTimeout(timer)\n }\n this.#timers.clear()\n this.#detachTimers.clear()\n }\n\n async #rememberDormant(runner: Runner): Promise<void> {\n if (this.#closed) {\n return\n }\n const info = runner.info()\n const capabilities = info.capabilities ?? ENGINE_CAPABILITIES[info.engine ?? 'claude']\n if (!capabilities.resume) {\n return\n }\n const config = this.#configs.get(runner.id)\n if (!config) {\n return\n }\n if (this.#options.registry.get(runner.id) !== runner) {\n return\n }\n const sdkSessionId = info.sdkSessionId\n if (sdkSessionId === undefined) {\n // Checked last, behind the ownership guard: before the engine has ever named a session there is no record to remove.\n if (this.#remembered.has(runner.id)) {\n await this.#forgetDormant(runner.id)\n }\n return\n }\n const record: DormantSessionRecord = {\n kind: 'dormant',\n id: runner.id,\n info: { ...info, status: 'idle' },\n profile: info.profile,\n config: { ...config, meta: info.meta },\n sdkSessionId,\n savedAt: Date.now(),\n }\n try {\n // Marked before the write: a queued save already means a record may exist, and a reset arriving mid-write must not skip the forget.\n this.#remembered.add(runner.id)\n await this.#queue(runner.id, () => this.#options.store.save(record))\n } catch (error) {\n this.#options.onError?.(error, { sessionId: runner.id, phase: 'remember' })\n }\n }\n\n async #forgetDormant(sessionId: string): Promise<void> {\n this.#remembered.delete(sessionId)\n try {\n await this.#queue(sessionId, () => this.#options.store.delete(sessionId))\n } catch (error) {\n this.#options.onError?.(error, { sessionId, phase: 'remember' })\n }\n }\n\n async #persistLive(runner: Runner): Promise<void> {\n if (this.#closed || !this.#options.persistLive || !runner.snapshot) {\n return\n }\n const config = this.#configs.get(runner.id)\n if (!config) {\n return\n }\n if (this.#options.registry.get(runner.id) !== runner) {\n return\n }\n try {\n await this.#queue(runner.id, async () => {\n // Re-checked inside the queue: a park's record must not be overwritten by the live copy queued behind it.\n if (this.#closed || this.#options.registry.get(runner.id) !== runner) {\n return\n }\n const snapshot = runner.snapshot?.()\n if (!snapshot) {\n return\n }\n const info = runner.info()\n const record: ParkedSessionRecord = {\n kind: 'live',\n id: runner.id,\n info: { ...info, status: 'idle' },\n profile: info.profile,\n config: { ...config, meta: info.meta },\n snapshot,\n executions: snapshot.parked,\n parkedAt: Date.now(),\n }\n await this.#options.store.save(record)\n })\n } catch (error) {\n this.#options.onError?.(error, { sessionId: runner.id, phase: 'remember' })\n }\n }\n\n async #park(runner: Runner): Promise<void> {\n if (this.#closed || !runner.park) {\n return\n }\n const id = runner.id\n if (this.#options.registry.get(id) !== runner) {\n return\n }\n if (runner.info().status !== 'parked') {\n return\n }\n if (this.#options.attachedCount(id) > 0) {\n return\n }\n const executions = [...this.#owners].filter(([, owner]) => owner === id).map(([e]) => e)\n if (executions.length === 0) {\n return\n }\n const config = this.#configs.get(id)\n if (!config) {\n return\n }\n if (this.#options.onParking && !this.#options.onParking(id, executions[0]!)) {\n return\n }\n const snapshot = runner.park()\n if (!snapshot) {\n return\n }\n const info = { ...runner.info(), status: 'parked' as const }\n this.#options.registry.evict(id)\n const record: ParkedSessionRecord = {\n kind: 'parked',\n id,\n info,\n profile: info.profile,\n config,\n snapshot,\n executions: snapshot.parked,\n parkedAt: Date.now(),\n }\n for (const execution of snapshot.parked) {\n this.#track(id, execution)\n }\n try {\n await this.#queue(id, () => this.#options.store.save(record))\n } catch (error) {\n this.#options.onError?.(error, { sessionId: id, phase: 'park' })\n }\n }\n\n async #resume(id: string): Promise<Runner | undefined> {\n const inFlight = this.#resuming.get(id)\n if (inFlight) {\n return inFlight\n }\n const attempt = this.#rebuild(id)\n this.#resuming.set(id, attempt)\n try {\n return await attempt\n } finally {\n this.#resuming.delete(id)\n }\n }\n\n async #rebuild(id: string): Promise<Runner | undefined> {\n const record = await this.#queue(id, () => this.#options.store.get(id))\n if (!record) {\n return undefined\n }\n let runner: Runner\n try {\n runner = await this.#options.rebuild(record)\n } catch (error) {\n this.#options.onError?.(error, { sessionId: id, phase: 'resume' })\n throw error\n }\n if (runner.id !== id) {\n runner.close('error')\n const error = new Error(\n `rebuilt session has id '${runner.id}', expected '${id}' — the engine factory must ` +\n 'forward EngineRunnerContext.restore (or, without a snapshot, the session id) ' +\n 'to the runner config',\n )\n this.#options.onError?.(error, { sessionId: id, phase: 'resume' })\n throw error\n }\n this.#options.registry.register(runner)\n this.remember(id, record.config)\n // A park must not re-arm watchdogs from its own replayed events; a dormant session starts a fresh log, so it has no prior seq to skip.\n this.watch(runner, isDormant(record) ? 0 : record.snapshot.seq)\n this.#options.onResumed?.(id, runner)\n if (!isDormant(record) && !isLiveRecord(record)) {\n await this.#queue(id, () => this.#options.store.delete(id))\n }\n void runner.start()\n return runner\n }\n\n #queue<T>(sessionId: string, op: () => Promise<T>): Promise<T> {\n const previous = this.#storeOps.get(sessionId) ?? Promise.resolve()\n const result = previous.then(op)\n const settled = result.then(\n () => {},\n () => {},\n )\n this.#storeOps.set(sessionId, settled)\n void settled.then(() => {\n if (this.#storeOps.get(sessionId) === settled) {\n this.#storeOps.delete(sessionId)\n }\n })\n return result\n }\n\n #track(sessionId: string, execution: ParkedExecution, notBefore = 0): void {\n this.#owners.set(execution.executionId, sessionId)\n if (execution.expiresAt === undefined || this.#timers.has(execution.executionId)) {\n return\n }\n const expiresAt = Math.max(execution.expiresAt, notBefore)\n const timer = setTimeout(\n () => {\n this.#timers.delete(execution.executionId)\n void this.submitResult(execution.executionId, {\n status: 'failed',\n reason: 'timeout',\n error: `deferred execution '${execution.toolName}' produced no result before its deadline`,\n }).catch((error: unknown) => {\n this.#options.onError?.(error, { sessionId, phase: 'resume' })\n })\n },\n Math.max(0, expiresAt - Date.now()),\n )\n timer.unref?.()\n this.#timers.set(execution.executionId, timer)\n }\n\n #forget(executionId: string): void {\n this.#clearTimer(executionId)\n const owner = this.#owners.get(executionId)\n if (owner !== undefined) {\n this.#settled.set(executionId, owner)\n }\n this.#owners.delete(executionId)\n }\n\n #clearTimer(executionId: string): void {\n const timer = this.#timers.get(executionId)\n if (timer === undefined) {\n return\n }\n clearTimeout(timer)\n this.#timers.delete(executionId)\n }\n}\n","import type { Runner } from '@workerdeck/core'\n\nexport type ProducedFile = {\n fileId: string\n path: string\n mediaType?: string\n bytes?: number\n sessionId: string\n}\n\nexport class ProducedFileStore {\n #bySession = new Map<string, Map<string, ProducedFile>>()\n\n watch(runner: Runner): void {\n runner.subscribe((event) => {\n if (event.type !== 'file_produced') {\n return\n }\n const held = this.#bySession.get(runner.id) ?? new Map<string, ProducedFile>()\n held.set(event.fileId, {\n fileId: event.fileId,\n path: event.path,\n ...(event.mediaType ? { mediaType: event.mediaType } : {}),\n ...(event.bytes !== undefined ? { bytes: event.bytes } : {}),\n sessionId: runner.id,\n })\n this.#bySession.set(runner.id, held)\n }, 0)\n }\n\n get(sessionId: string, fileId: string): ProducedFile | undefined {\n return this.#bySession.get(sessionId)?.get(fileId)\n }\n\n list(sessionId: string): ProducedFile[] {\n return [...(this.#bySession.get(sessionId)?.values() ?? [])]\n }\n\n drop(sessionId: string): void {\n this.#bySession.delete(sessionId)\n }\n}\n","import { existsSync } from 'node:fs'\nimport { supportsPermissionMode, type ProfileEngine, type ProfileInfo } from '@workerdeck/protocol'\nimport type { EngineAdapter, EngineAvailability } from '@workerdeck/core'\nimport { cwdAllowed, engineOf, isProviderProfile } from '../lib/profile-env.ts'\nimport type { ProfileStore } from './profile-store.ts'\n\nexport type Refusal = { status: number; error: string }\n\nexport type ProfileServiceOptions = {\n declared: ProfileInfo[]\n store?: ProfileStore\n allowedConfigDirRoots?: string[]\n disableBypassPermissions?: boolean\n hasEngineRunnerFactory: boolean\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n decorate: {\n defaultModel: (name: string) => string | undefined\n availability: (name: string) => EngineAvailability | undefined\n usage: (name: string) => ProfileInfo['usage'] | undefined\n }\n}\n\nexport class ProfileService {\n readonly #declared: ProfileInfo[]\n readonly #declaredByName: Map<string, ProfileInfo>\n readonly #stored = new Map<string, ProfileInfo>()\n readonly #opts: ProfileServiceOptions\n\n constructor(opts: ProfileServiceOptions) {\n this.#opts = opts\n this.#declared = opts.declared\n this.#declaredByName = new Map(opts.declared.map((p) => [p.name, p]))\n if (this.#declaredByName.size !== opts.declared.length) {\n throw new Error('createWorkerServer: duplicate profile names in `profiles`')\n }\n }\n\n validate(p: ProfileInfo): string | null {\n const { adapterFor, disableBypassPermissions, hasEngineRunnerFactory } = this.#opts\n if (isProviderProfile(p)) {\n if (!p.provider?.id) {\n return `provider profile '${p.name}' is missing provider.id`\n }\n if (!hasEngineRunnerFactory) {\n return `profile '${p.name}' uses engine 'provider' but no ` + '`createEngineRunner` was provided to build one'\n }\n } else if (p.engine === 'codex') {\n if (p.codexHome && !existsSync(p.codexHome)) {\n return `profile '${p.name}' codexHome does not exist: ${p.codexHome}`\n }\n if (p.session?.instructions) {\n return (\n `profile '${p.name}' declares session.instructions, which the codex engine cannot ` +\n 'deliver — put instructions in the target repo’s AGENTS.md instead'\n )\n }\n } else if (!p.configDir || !existsSync(p.configDir)) {\n return `profile '${p.name}' configDir does not exist: ${p.configDir}`\n }\n if (disableBypassPermissions && p.defaults?.permissionMode === 'bypassPermissions') {\n return `profile '${p.name}' defaults to bypassPermissions but disableBypassPermissions is set`\n }\n const fallbackMode = p.defaults?.permissionMode\n if (fallbackMode && !supportsPermissionMode(p.engine, fallbackMode)) {\n return (\n `profile '${p.name}' defaults to permission mode '${fallbackMode}', which engine ` +\n `'${engineOf(p)}' does not support (supported: ` +\n `${adapterFor(engineOf(p)).capabilities.permissionModes.join(', ')})`\n )\n }\n return null\n }\n\n async refreshStored(): Promise<void> {\n if (!this.#opts.store) {\n return\n }\n this.#stored.clear()\n for (const p of await this.#opts.store.list()) {\n this.#stored.set(p.name, p)\n }\n }\n\n withManagedFlag(p: ProfileInfo): ProfileInfo {\n return this.#declaredByName.has(p.name) ? p : { ...p, managed: true }\n }\n\n forResponse(p: ProfileInfo): ProfileInfo {\n const { adapterFor, decorate } = this.#opts\n const adapter = adapterFor(p.engine)\n const base: ProfileInfo = {\n ...this.withManagedFlag(p),\n capabilities: adapter.capabilities,\n }\n if (adapter.catalog.models.length > 0) {\n base.models = adapter.catalog.models\n }\n const defaultModel = decorate.defaultModel(p.name)\n if (defaultModel) {\n base.defaultModel = defaultModel\n }\n const probed = decorate.availability(p.name)\n if (probed && probed.available !== 'unknown') {\n base.available = probed.available\n if (probed.available === false) {\n base.unavailableReason = probed.reason\n }\n }\n const usage = decorate.usage(p.name)\n if (usage) {\n base.usage = usage\n }\n return base\n }\n\n all(): ProfileInfo[] {\n return [...this.#declared, ...[...this.#stored.values()].filter((p) => !this.#declaredByName.has(p.name))]\n }\n\n get(name: string): ProfileInfo | undefined {\n return this.#declaredByName.get(name) ?? this.#stored.get(name)\n }\n\n manageGuard(auth: { canManageProfiles?: boolean }): Refusal | null {\n if (!this.#opts.store) {\n return { status: 404, error: 'profile management is not enabled on this server' }\n }\n if (!auth.canManageProfiles) {\n return { status: 403, error: 'not allowed to manage profiles' }\n }\n return null\n }\n\n declaredGuard(profile: ProfileInfo): Refusal | null {\n return this.#declaredByName.has(profile.name)\n ? {\n status: 403,\n error:\n `profile '${profile.name}' is declared in server options and cannot be changed ` +\n 'over the API — edit the `profiles` option instead',\n }\n : null\n }\n\n configDirGuard(profile: ProfileInfo): Refusal | null {\n if (isProviderProfile(profile)) {\n return null\n }\n const roots = this.#opts.allowedConfigDirRoots\n if (!roots || roots.length === 0) {\n return {\n status: 403,\n error: 'managed Claude profiles are disabled: set `allowedConfigDirRoots` to the ' + 'directories they may point at',\n }\n }\n return profile.configDir && cwdAllowed(profile.configDir, roots)\n ? null\n : { status: 403, error: 'configDir is outside the allowed roots' }\n }\n\n async saveManaged(incoming: ProfileInfo): Promise<{ ok: true; profile: ProfileInfo } | ({ ok: false } & Refusal)> {\n const { managed: _clientClaim, ...profile } = incoming\n const refused = this.configDirGuard(profile)\n if (refused) {\n return { ok: false, ...refused }\n }\n const invalid = this.validate(profile)\n if (invalid) {\n return { ok: false, status: 400, error: invalid }\n }\n await this.#opts.store!.save(profile)\n await this.refreshStored()\n return { ok: true, profile: this.withManagedFlag(profile) }\n }\n}\n","import type { Runner } from '@workerdeck/core'\nimport type { ProfileUsage, ProfileUsageWindow, RateLimitInfo } from '@workerdeck/protocol'\n\ntype HeldWindow = { info: RateLimitInfo; updatedAt: number }\n\nexport class ProfileUsageTracker {\n #profiles = new Map<string, Map<string, HeldWindow>>()\n\n watch(runner: Runner): void {\n const profile = runner.info().profile\n if (!profile) {\n return\n }\n runner.subscribe((event) => {\n if (event.type !== 'rate_limit') {\n return\n }\n const type = event.info.rateLimitType\n if (!type) {\n return\n }\n let windows = this.#profiles.get(profile)\n if (!windows) {\n this.#profiles.set(profile, (windows = new Map()))\n }\n const held = windows.get(type)\n if (held && held.updatedAt > event.ts) {\n return\n }\n windows.set(type, { info: event.info, updatedAt: event.ts })\n })\n }\n\n usage(profile: string, now = Date.now()): ProfileUsage | undefined {\n const windows = this.#profiles.get(profile)\n if (!windows || windows.size === 0) {\n return undefined\n }\n const out: ProfileUsage = {}\n for (const [type, held] of windows) {\n out[type] = serveWindow(held, now)\n }\n return out\n }\n}\n\n// `resetsAt` is epoch seconds (protocol contract); `now` is epoch ms.\nfunction serveWindow(held: HeldWindow, now: number): ProfileUsageWindow {\n const resetsAt = held.info.resetsAt\n if (resetsAt !== undefined && resetsAt * 1000 <= now) {\n return {\n info: {\n // The dropped `resetsAt`/`isUsingOverage` describe the window that rolled, not this one.\n status: 'allowed',\n rateLimitType: held.info.rateLimitType,\n utilization: 0,\n },\n updatedAt: held.updatedAt,\n inferredReset: true,\n }\n }\n return { info: held.info, updatedAt: held.updatedAt }\n}\n","import { SessionRunner, type Runner, type SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type SessionRegistryOptions = {\n onRegister?: (runner: Runner) => void\n}\n\nexport class SessionRegistry {\n #sessions = new Map<string, Runner>()\n #options: SessionRegistryOptions\n\n constructor(options: SessionRegistryOptions = {}) {\n this.#options = options\n }\n\n create(config: SessionRunnerConfig): Runner {\n return this.adopt(new SessionRunner(config))\n }\n\n prepare(config: SessionRunnerConfig): Runner {\n return this.register(new SessionRunner(config))\n }\n\n adopt(runner: Runner): Runner {\n this.register(runner)\n void runner.start()\n return runner\n }\n\n register(runner: Runner): Runner {\n const existing = this.#sessions.get(runner.id)\n this.#sessions.set(runner.id, runner)\n if (existing !== runner) {\n this.#options.onRegister?.(runner)\n }\n return runner\n }\n\n get(id: string): Runner | undefined {\n return this.#sessions.get(id)\n }\n\n list(): SessionInfo[] {\n return [...this.#sessions.values()].map((r) => r.info())\n }\n\n remove(id: string): boolean {\n const runner = this.#sessions.get(id)\n if (!runner) {\n return false\n }\n runner.close('server')\n return this.#sessions.delete(id)\n }\n\n evict(id: string): boolean {\n return this.#sessions.delete(id)\n }\n\n closeAll(): void {\n for (const runner of this.#sessions.values()) {\n runner.close('server')\n }\n }\n}\n","import {\n supportsPermissionMode,\n type CreateSessionRequest,\n type PermissionMode,\n type ProfileEngine,\n type ProfileInfo,\n} from '@workerdeck/protocol'\nimport type { EngineAdapter, Runner, RunnerSnapshot, SessionRunnerConfig } from '@workerdeck/core'\nimport { checkScope, sameScope } from '../lib/scope.ts'\nimport { claudeSessionEnv, cwdAllowed, engineOf, isProviderProfile } from '../lib/profile-env.ts'\nimport type { EngineRunnerContext, LateBoundRefs } from '../options.ts'\nimport type { ProfileService } from './profiles.ts'\n\nexport type SessionFactoryDeps = {\n adapterFor: (engine: ProfileEngine | undefined) => EngineAdapter\n profiles: ProfileService\n hostBuildRunnerConfig: (req: CreateSessionRequest) => SessionRunnerConfig\n createEngineRunner?: (context: EngineRunnerContext) => Runner | Promise<Runner>\n allowedCwdRoots?: string[]\n disableBypassPermissions?: boolean\n requireApiKey?: boolean\n refs: LateBoundRefs\n}\n\nexport type SessionFactory = ReturnType<typeof createSessionFactory>\n\nexport function createSessionFactory(deps: SessionFactoryDeps) {\n const { adapterFor, profiles, refs } = deps\n\n const subscriptionNoticeShown = new Set<string>()\n\n const applyBypassPolicy = (req: CreateSessionRequest): string | null => {\n if (!deps.disableBypassPermissions) {\n return null\n }\n if (req.permissionMode === 'bypassPermissions') {\n return 'bypassPermissions is disabled on this server (disableBypassPermissions)'\n }\n delete req.allowDangerouslySkipPermissions\n return null\n }\n\n const checkPermissionMode = (mode: PermissionMode | undefined, profile: ProfileInfo | undefined): string | null => {\n if (mode === undefined || supportsPermissionMode(profile?.engine, mode)) {\n return null\n }\n return (\n `permission mode '${mode}' is not supported by profile '${profile!.name}' ` +\n `(engine '${engineOf(profile)}') — supported: ` +\n adapterFor(profile?.engine).capabilities.permissionModes.join(', ')\n )\n }\n\n const checkEngineGrants = (req: CreateSessionRequest, profile: ProfileInfo | undefined): string | null => {\n const engine = engineOf(profile)\n const caps = adapterFor(profile?.engine).capabilities\n const name = profile?.name ?? 'default'\n if (!caps.sessionMcpServers && req.mcpServers && Object.keys(req.mcpServers).length > 0) {\n return (\n `profile '${name}' runs the ${engine} engine, whose MCP servers are declared ` +\n 'outside the session request — a request cannot add its own'\n )\n }\n if (!caps.budgets && (req.maxTurns !== undefined || req.maxBudgetUsd !== undefined)) {\n return `the ${engine} engine does not honor maxTurns/maxBudgetUsd`\n }\n if (!caps.settingSources && req.settingSources !== undefined) {\n return `the ${engine} engine does not load settingSources`\n }\n if (!caps.resume && req.resume !== undefined) {\n return `the ${engine} engine cannot resume a session`\n }\n if (req.forkSession && engine !== 'claude') {\n return `the ${engine} engine cannot fork a resumed session`\n }\n if (req.reasoningEffort !== undefined && (!caps.reasoningEfforts || caps.reasoningEfforts.length === 0)) {\n return `the ${engine} engine does not take a reasoningEffort`\n }\n if (!profile || !isProviderProfile(profile)) {\n return null\n }\n const granted = profile.session?.capabilities\n if (!req.capabilities || !granted) {\n return null\n }\n const ungranted = req.capabilities.filter((c) => !granted.includes(c))\n if (ungranted.length === 0) {\n return null\n }\n return (\n `profile '${profile.name}' does not grant: ${ungranted.join(', ')} ` +\n `(granted: ${granted.join(', ') || 'none'}) — a request may narrow capabilities, not widen them`\n )\n }\n\n const stripInertFields = (req: CreateSessionRequest, profile: ProfileInfo | undefined): void => {\n if (!adapterFor(profile?.engine).capabilities.interactiveApprovals) {\n delete req.questionBehavior\n }\n }\n\n const applyScope = (req: CreateSessionRequest, auth: { scope?: Record<string, string> }): { status: number; error: string } | null => {\n const invalid = checkScope(req.scope)\n if (invalid) {\n return { status: 400, error: invalid }\n }\n if (!auth.scope) {\n return null\n }\n const merged: Record<string, string> = { ...req.scope }\n for (const [key, value] of Object.entries(auth.scope)) {\n const claimed = merged[key]\n if (claimed !== undefined && claimed !== value) {\n return { status: 403, error: `scope '${key}' does not match the caller's` }\n }\n merged[key] = value\n }\n const tooBig = checkScope(merged)\n if (tooBig) {\n return { status: 400, error: tooBig }\n }\n req.scope = merged\n return null\n }\n\n const checkCwd = (req: CreateSessionRequest, profile: ProfileInfo | undefined): { status: number; error: string } | null => {\n if (req.cwd !== undefined && typeof req.cwd !== 'string') {\n return { status: 400, error: 'cwd must be a string' }\n }\n if (!req.cwd) {\n // Absent = true, so an engine record predating the field keeps the old always-required behaviour.\n return adapterFor(profile?.engine).capabilities.hostCwd === false ? null : { status: 400, error: 'cwd is required' }\n }\n return cwdAllowed(req.cwd, deps.allowedCwdRoots) ? null : { status: 403, error: 'cwd is outside the allowed roots' }\n }\n\n const withScope = (config: SessionRunnerConfig, scope: Record<string, string> | undefined): SessionRunnerConfig =>\n scope === undefined ? config : { ...config, scope }\n\n const buildRunnerConfig = (req: CreateSessionRequest): SessionRunnerConfig => {\n const profile = req.profile !== undefined ? profiles.get(req.profile) : undefined\n if (!profile) {\n return withScope(deps.hostBuildRunnerConfig(req), req.scope)\n }\n const config = withScope(\n deps.hostBuildRunnerConfig({\n ...req,\n model: req.model ?? profile.defaults?.model ?? profile.provider?.model,\n permissionMode: req.permissionMode ?? profile.defaults?.permissionMode,\n }),\n req.scope,\n )\n if (engineOf(profile) !== 'claude') {\n return config\n }\n const base = config.env ?? process.env\n const env = claudeSessionEnv(profile, base)\n // A skipped pin returns `base` itself — leaving the config alone keeps an unset `env` unset, so the SDK spawns on process.env.\n return env === base ? config : { ...config, env }\n }\n\n const sessionEnvFor = (profile: ProfileInfo): Record<string, string | undefined> => {\n try {\n return buildRunnerConfig({ cwd: process.cwd(), profile: profile.name }).env ?? process.env\n } catch {\n return engineOf(profile) === 'claude' ? claudeSessionEnv(profile, process.env) : process.env\n }\n }\n\n const buildRunner = async (config: SessionRunnerConfig, restore?: RunnerSnapshot, id?: string): Promise<Runner> => {\n const name = config.profile\n const profile = name !== undefined ? profiles.get(name) : undefined\n if (name !== undefined && !profile) {\n throw new Error(`unknown profile: ${name}`)\n }\n const runner =\n profile && isProviderProfile(profile)\n ? // Non-null: startup refuses a provider profile when no factory was wired.\n await deps.createEngineRunner!({ config, profile, bridge: refs.bridge!, restore, id })\n : // The in-repo adapters refuse `restore` themselves — neither binary can rebuild a parked session.\n await adapterFor(profile?.engine).createRunner({ config, profile, restore, id })\n const reported = runner.info().scope\n if (!sameScope(reported, config.scope)) {\n throw new Error(\n `runner for session ${runner.id} reports scope ${JSON.stringify(reported)}, ` +\n `expected ${JSON.stringify(config.scope)} — echo config.scope from info()`,\n )\n }\n return runner\n }\n\n const createRunner = async (config: SessionRunnerConfig): Promise<Runner> => {\n const runner = refs.registry!.register(await buildRunner(config))\n // Watchers first, then start: a session must not emit anything before the things that persist and account for it are listening.\n refs.parking!.remember(runner.id, config)\n refs.parking!.watch(runner)\n void runner.start()\n return runner\n }\n\n const resolveProfile = (\n name: unknown,\n allowedProfiles: string[] | undefined,\n ): { ok: true; profile?: ProfileInfo } | { ok: false; status: number; error: string } => {\n if (name !== undefined && typeof name !== 'string') {\n return { ok: false, status: 400, error: 'profile must be a string' }\n }\n const all = profiles.all()\n if (all.length === 0) {\n return name !== undefined ? { ok: false, status: 400, error: 'no profiles are configured on this server' } : { ok: true }\n }\n const effective = name ?? (all.length === 1 ? all[0]!.name : undefined)\n if (effective === undefined) {\n const available = all.map((p) => p.name).join(', ')\n return { ok: false, status: 400, error: `profile is required (available: ${available})` }\n }\n const profile = profiles.get(effective)\n if (!profile) {\n return { ok: false, status: 400, error: `unknown profile: ${effective}` }\n }\n if (allowedProfiles && !allowedProfiles.includes(profile.name)) {\n return { ok: false, status: 403, error: `profile not allowed: ${profile.name}` }\n }\n return { ok: true, profile }\n }\n\n const watchAuthSource = (runner: Runner): void => {\n let seen = false\n runner.subscribe((event) => {\n if (seen || event.type !== 'system_init') {\n return\n }\n seen = true\n if (event.apiKeySource !== 'oauth') {\n return\n }\n if (deps.requireApiKey) {\n runner.fail(\n 'This server requires API-key auth (requireApiKey), but the session initialized ' +\n \"with claude.ai subscription credentials (apiKeySource 'oauth'). Set \" +\n 'ANTHROPIC_API_KEY (or Bedrock/Vertex auth) in the server environment.',\n )\n } else {\n const profileName = runner.info().profile ?? ''\n if (subscriptionNoticeShown.has(profileName)) {\n return\n }\n subscriptionNoticeShown.add(profileName)\n const scope = profileName ? `Sessions under profile '${profileName}'` : 'Sessions'\n console.warn(\n `[workerdeck] ${scope} are using claude.ai subscription credentials ` +\n \"(apiKeySource 'oauth'), not an API key. That is only appropriate for personal, \" +\n 'single-user use of your own account. Unattended/scheduled or multi-user use ' +\n \"requires an API key under Anthropic's terms — set ANTHROPIC_API_KEY in the \" +\n 'server environment, or set requireApiKey: true to fail closed.',\n )\n }\n })\n }\n\n return {\n applyBypassPolicy,\n checkPermissionMode,\n checkEngineGrants,\n stripInertFields,\n applyScope,\n checkCwd,\n buildRunnerConfig,\n sessionEnvFor,\n buildRunner,\n createRunner,\n resolveProfile,\n watchAuthSource,\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { Duplex } from 'node:stream'\nimport { WebSocketServer, type WebSocket } from 'ws'\nimport { getEngineAdapter } from '@workerdeck/core'\nimport type { EngineAdapter } from '@workerdeck/core'\nimport { JobQueue } from '@workerdeck/queue'\nimport {\n PROTOCOL_VERSION,\n sessionState,\n type CreateSessionRequest,\n type JobEvent,\n type ProfileEngine,\n type QueueServerFrame,\n} from '@workerdeck/protocol'\nimport type { SessionRunnerConfig } from '@workerdeck/core'\nimport type { ServerContext } from './context.ts'\nimport { json } from './lib/http.ts'\nimport { detectDefaultProfiles } from './lib/profile-env.ts'\nimport { parseSessionRoute } from './lib/parse-route.ts'\nimport type { DrainReport, LateBoundRefs, WorkerServer, WorkerServerOptions } from './options.ts'\nimport { handleExecutionResult } from './routes/executions.ts'\nimport { handleHostFiles } from './routes/host-files.ts'\nimport { handleJobs } from './routes/jobs.ts'\nimport { handleProfiles } from './routes/profiles.ts'\nimport { handleSdkSessions } from './routes/sdk-sessions.ts'\nimport { handleSessions } from './routes/sessions.ts'\nimport { attachClient } from './routes/ws.ts'\nimport { AttachmentStore } from './services/attachments.ts'\nimport { createAuthService } from './services/auth.ts'\nimport { AvailabilityTracker } from './services/availability.ts'\nimport { BridgeHub } from './services/bridge.ts'\nimport { createHostFileRoots } from './services/host-files.ts'\nimport { SessionNotifier } from './services/notifications.ts'\nimport { SessionParkManager } from './services/parking.ts'\nimport { ProducedFileStore } from './services/produced-files.ts'\nimport { ProfileService } from './services/profiles.ts'\nimport { ProfileUsageTracker } from './services/profile-usage.ts'\nimport { ProjectInfoService } from './services/project-info.ts'\nimport { SessionRegistry } from './services/registry.ts'\nimport { createSessionFactory } from './services/session-factory.ts'\nimport { isDormant, MemorySessionStore } from './services/session-store.ts'\n\nexport type {\n Authenticator,\n EngineRunnerContext,\n QueueServerOptions,\n SdkSessionLister,\n WorkerServer,\n WorkerServerOptions,\n} from './options.ts'\n\n/** How long a client gets to acknowledge the shutdown close frame before its socket is torn down. */\nconst SOCKET_CLOSE_GRACE_MS = 250\n\n/**\n * Split live sessions into \"will finish by itself\" and \"needs a person\".\n *\n * `sessionState` is the vocabulary the dashboard, the session list and `workerdeck guard` already sort by, and it\n * draws exactly the line a drain needs: `working` covers starting/running and running subagents, while `attention`\n * covers a pending approval. Re-spelling that set here is how the two definitions would drift apart.\n */\nfunction surveyDrain(registry: SessionRegistry): DrainReport {\n const working: string[] = []\n const awaitingHuman: string[] = []\n for (const info of registry.list()) {\n const state = sessionState(info)\n if (state === 'working') {\n working.push(info.id)\n } else if (state === 'attention') {\n awaitingHuman.push(info.id)\n }\n }\n return { working, awaitingHuman, timedOut: false }\n}\n\nfunction sameDrain(a: DrainReport, b: DrainReport): boolean {\n return a.working.join() === b.working.join() && a.awaitingHuman.join() === b.awaitingHuman.join()\n}\n\nexport function createWorkerServer(options: WorkerServerOptions = {}): WorkerServer {\n if (!options.authenticate && !options.allowUnauthenticated) {\n throw new Error('createWorkerServer: provide `authenticate` or explicitly set `allowUnauthenticated: true`')\n }\n const basePath = options.basePath ?? '/v1'\n const fallback = options.fallback\n const corsOrigins = options.cors?.origins.length ? new Set(options.cors.origins) : undefined\n const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024\n const adapterFor = (engine: ProfileEngine | undefined): EngineAdapter => options.engines?.[engine ?? 'claude'] ?? getEngineAdapter(engine)\n\n const profileDefaultModels = new Map<string, string>()\n const profileUsage = new ProfileUsageTracker()\n const profiles = new ProfileService({\n declared: options.profiles ?? detectDefaultProfiles(),\n store: options.profileStore,\n allowedConfigDirRoots: options.allowedConfigDirRoots,\n disableBypassPermissions: options.disableBypassPermissions,\n hasEngineRunnerFactory: options.createEngineRunner !== undefined,\n adapterFor,\n decorate: {\n defaultModel: (name) => profileDefaultModels.get(name),\n availability: (name) => availability.get(name),\n usage: (name) => profileUsage.usage(name),\n },\n })\n for (const p of options.profiles ?? []) {\n const invalid = profiles.validate(p)\n if (invalid) {\n throw new Error(`createWorkerServer: ${invalid}`)\n }\n }\n\n const refs: LateBoundRefs = {}\n const factory = createSessionFactory({\n adapterFor,\n profiles,\n hostBuildRunnerConfig: options.buildRunnerConfig ?? ((req: CreateSessionRequest): SessionRunnerConfig => req),\n createEngineRunner: options.createEngineRunner,\n allowedCwdRoots: options.allowedCwdRoots,\n disableBypassPermissions: options.disableBypassPermissions,\n requireApiKey: options.requireApiKey,\n refs,\n })\n\n const availability = new AvailabilityTracker({\n checkCredentials: options.checkCredentials,\n requireAvailableProfile: options.requireAvailableProfile,\n adapterFor,\n sessionEnvFor: factory.sessionEnvFor,\n })\n\n const projects = new ProjectInfoService()\n const notifier = new SessionNotifier({\n ...options.notifications,\n decorateInfo: (info) => projects.withProject(info),\n })\n const producedFiles = new ProducedFileStore()\n const registry = new SessionRegistry({\n onRegister: (runner) => {\n notifier.watch(runner)\n producedFiles.watch(runner)\n profileUsage.watch(runner)\n const profile = runner.info().profile\n if (!profile) {\n return\n }\n runner.subscribe((event) => {\n if (event.type !== 'capabilities' || !event.defaultModel) {\n return\n }\n profileDefaultModels.set(profile, event.defaultModel)\n })\n },\n })\n const attachmentStore = new AttachmentStore(options.attachments)\n const bridge = new BridgeHub({\n ...options.bridge,\n onResult: (sessionId, executionId, result) => {\n registry.get(sessionId)?.settleExecution?.(executionId, result)\n options.bridge?.onResult?.(sessionId, executionId, result)\n },\n })\n const parking = new SessionParkManager({\n registry,\n store: options.parking?.store ?? new MemorySessionStore(),\n parkDelayMs: options.parking?.parkDelayMs,\n expiredGraceMs: options.parking?.expiredGraceMs,\n persistLive: options.parking?.persistLive,\n onError: options.parking?.onError,\n rebuild: (record) =>\n isDormant(record)\n ? factory.buildRunner(\n factory.buildRunnerConfig({\n ...record.config,\n prompt: undefined,\n meta: record.info.title ? { ...record.config.meta, title: record.info.title } : record.config.meta,\n resume: record.sdkSessionId,\n }),\n undefined,\n record.id,\n )\n : factory.buildRunner(record.config, record.snapshot),\n attachedCount: (sessionId) => bridge.attachedCount(sessionId),\n onParking: (sessionId, executionId) => queue?.onSessionParking(sessionId, executionId) ?? true,\n onResumed: (sessionId, runner) => queue?.onSessionResumed(sessionId, runner),\n })\n refs.registry = registry\n refs.parking = parking\n refs.bridge = bridge\n\n const auth = createAuthService({ options, refs })\n\n const wss = new WebSocketServer({ noServer: true })\n let closing: Promise<void> | undefined\n let draining = false\n\n const queueSockets = new Set<WebSocket>()\n const sendQueueFrame = (ws: WebSocket, frame: QueueServerFrame): void => {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(frame))\n }\n }\n const broadcastJobEvent = (event: JobEvent): void => {\n if (queueSockets.size === 0) {\n return\n }\n for (const ws of queueSockets) {\n sendQueueFrame(ws, { type: 'job_event', event })\n }\n if (event.type !== 'job_progress') {\n void queue\n ?.stats()\n .then((stats) => {\n for (const ws of queueSockets) {\n sendQueueFrame(ws, { type: 'queue_stats', stats })\n }\n })\n .catch(() => {})\n }\n }\n\n const queue = options.queue\n ? new JobQueue({\n ...options.queue,\n onEvent: (event) => {\n try {\n options.queue?.onEvent?.(event)\n } finally {\n broadcastJobEvent(event)\n }\n },\n createRunner: async (config) => {\n const runner = await factory.createRunner(config)\n factory.watchAuthSource(runner)\n return runner\n },\n buildRunnerConfig: factory.buildRunnerConfig,\n discardSession: (sessionId) => parking.discard(sessionId),\n })\n : undefined\n\n const hostFileRootPaths = options.hostFiles?.roots ?? options.allowedCwdRoots\n const hostFiles = hostFileRootPaths?.length ? createHostFileRoots(hostFileRootPaths) : null\n\n const ctx: ServerContext = {\n options,\n basePath,\n maxBodyBytes,\n adapterFor,\n listSdkSessions: options.listSdkSessions,\n profiles,\n availability,\n auth,\n factory,\n registry,\n parking,\n bridge,\n projects,\n queue,\n attachmentStore,\n producedFiles,\n hostFiles,\n hostFilesWritable: options.hostFiles?.write === true,\n maxHostFileBytes: options.hostFiles?.maxFileBytes ?? 1024 * 1024,\n maxHostDirEntries: options.hostFiles?.maxEntries ?? 5000,\n }\n\n const handleRequest = async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const pathname = new URL(req.url ?? '/', 'http://internal').pathname\n\n const origin = req.headers.origin\n const originAllowed = typeof origin === 'string' && corsOrigins !== undefined && corsOrigins.has(origin)\n if (originAllowed) {\n res.setHeader('access-control-allow-origin', origin)\n res.setHeader('vary', 'origin')\n }\n if (req.method === 'OPTIONS' && req.headers['access-control-request-method'] !== undefined) {\n if (!originAllowed) {\n res.writeHead(403)\n res.end()\n return\n }\n res.setHeader('access-control-allow-methods', 'GET, HEAD, POST, PATCH, PUT, DELETE')\n res.setHeader('access-control-allow-headers', 'authorization, content-type, x-workerdeck-key')\n res.setHeader('access-control-max-age', '600')\n // Chrome's Private Network Access: a public page reaching a private address (a tailnet, a LAN) preflights for this explicitly.\n if (req.headers['access-control-request-private-network'] === 'true') {\n res.setHeader('access-control-allow-private-network', 'true')\n }\n res.writeHead(204)\n res.end()\n return\n }\n\n if (fallback && pathname !== basePath && !pathname.startsWith(basePath + '/')) {\n await fallback(req, res)\n return\n }\n if (pathname === basePath + '/jobs' || pathname.startsWith(basePath + '/jobs/') || pathname === basePath + '/queue') {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleJobs(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname === basePath + '/profiles' || pathname.startsWith(basePath + '/profiles/')) {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleProfiles(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname.startsWith(basePath + '/executions/')) {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleExecutionResult(ctx, req, res, pathname, authCtx)\n return\n }\n if (pathname === basePath + '/sdk-sessions') {\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n if (!auth.isOperator(authCtx)) {\n json(res, 404, { error: 'not found' })\n return\n }\n await handleSdkSessions(ctx, req, res, authCtx)\n return\n }\n if (pathname.startsWith(basePath + '/fs/')) {\n // Authenticated before the 404-when-unconfigured answer: an unauthenticated caller must not learn whether a filesystem is exposed.\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n if (!auth.isOperator(authCtx)) {\n json(res, 404, { error: 'not found' })\n return\n }\n await handleHostFiles(ctx, req, res, pathname)\n return\n }\n const route = parseSessionRoute(basePath, req.url ?? '/')\n if (!route || route.ws) {\n json(res, 404, { error: 'not found' })\n return\n }\n // Starting a turn we have already promised to stop waiting for would make the drain unable to converge.\n // Existing sessions stay fully controllable — including approvals, which is how an operator unblocks one.\n if (draining && req.method === 'POST' && route.id === undefined) {\n json(res, 503, { error: 'server is shutting down' })\n return\n }\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n json(res, 401, { error: 'unauthorized' })\n return\n }\n await handleSessions(ctx, req, res, route, authCtx)\n }\n\n const server = createServer((req, res) => {\n handleRequest(req, res).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : 'internal error'\n if (!res.headersSent) {\n json(res, error instanceof SyntaxError ? 400 : 500, { error: message })\n } else {\n res.end()\n }\n })\n })\n\n server.on('upgrade', (req: IncomingMessage, socket: Duplex, head: Buffer) => {\n void (async () => {\n const pathname = new URL(req.url ?? '/', 'http://internal').pathname\n if (pathname === basePath + '/queue/ws') {\n if (!queue) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const queueAuth = await auth.authenticate(req)\n if (!queueAuth.ok) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n if (!auth.isOperator(queueAuth)) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n wss.handleUpgrade(req, socket, head, (ws) => {\n queueSockets.add(ws)\n ws.on('close', () => queueSockets.delete(ws))\n void queue\n .stats()\n .then((stats) => sendQueueFrame(ws, { type: 'queue_attached', protocolVersion: PROTOCOL_VERSION, stats }))\n .catch(() => {})\n })\n return\n }\n const route = parseSessionRoute(basePath, req.url ?? '/')\n if (!route?.ws || !route.id) {\n socket.destroy()\n return\n }\n const authCtx = await auth.authenticate(req)\n if (!authCtx.ok) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const known = registry.get(route.id)?.info() ?? (await parking.get(route.id))?.info\n if (known && !auth.canSee(authCtx, known)) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n const runner = await parking.ensureLive(route.id).catch(() => undefined)\n if (!runner || !auth.canSee(authCtx, runner.info())) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n')\n socket.destroy()\n return\n }\n wss.handleUpgrade(req, socket, head, (ws) => {\n attachClient(ctx, ws, runner, req)\n })\n })().catch(() => socket.destroy())\n })\n\n return {\n server,\n registry,\n queue,\n bridge,\n parking,\n listen: async (port, host) => {\n await profiles.refreshStored()\n await parking.hydrate()\n return new Promise((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => {\n availability.preflight(profiles.all())\n const address = server.address()\n resolve({ port: typeof address === 'object' && address ? address.port : port })\n })\n })\n },\n drain: async (drainOptions = {}) => {\n const { timeoutMs = 30_000, pollMs = 250, onProgress } = drainOptions\n draining = true\n const deadline = Date.now() + timeoutMs\n let report = surveyDrain(registry)\n onProgress?.(report)\n while (report.working.length > 0 && Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, pollMs))\n const next = surveyDrain(registry)\n // Only speak when something actually changed: a shutdown that reports on its own progress should be\n // readable, not a per-tick redraw of the same two lines.\n if (!sameDrain(next, report)) {\n onProgress?.(next)\n }\n report = next\n }\n report = { ...surveyDrain(registry), timedOut: false }\n report.timedOut = report.working.length > 0\n onProgress?.(report)\n return report\n },\n close: () => {\n // Idempotent by contract, not by luck: a second SIGINT re-enters here, and `http.Server.close()` on an\n // already-closed server only fires its callback because we ignore the ERR_SERVER_NOT_RUNNING it passes.\n // Returning the first promise makes the second call a no-op we can reason about.\n closing ??= new Promise((resolve) => {\n queue?.close()\n // Ordering is load-bearing: parking's `#closed` guard must be set before the registry closes runners with\n // reason 'server', or shutdown discards every dormant record. See docs/GOTCHAS.md.\n parking.close()\n registry.closeAll()\n // `wss` is `noServer`, so `wss.close()` neither closes nor terminates clients — it waits for `clients` to\n // empty — and `server.closeAllConnections()` does not reach upgraded sockets. Any attached session socket\n // therefore keeps `server.close()`'s callback from ever firing. Send close frames, then force what lingers.\n for (const ws of wss.clients) {\n ws.close(1001, 'server shutting down')\n }\n queueSockets.clear()\n const force = setTimeout(() => {\n for (const ws of wss.clients) {\n ws.terminate()\n }\n }, SOCKET_CLOSE_GRACE_MS)\n force.unref()\n wss.close()\n server.close(() => {\n clearTimeout(force)\n resolve()\n })\n server.closeAllConnections()\n })\n return closing\n },\n }\n}\n","import type { ProfileInfo, ProviderConfig, SessionCapability } from '@workerdeck/protocol'\n\nexport function sandboxedProviderProfile(\n name: string,\n provider: ProviderConfig,\n options: {\n description?: string\n instructions?: string\n defaults?: ProfileInfo['defaults']\n capabilities?: SessionCapability[]\n mcpServers?: string[]\n } = {},\n): ProfileInfo {\n return {\n name,\n engine: 'provider',\n provider,\n description: options.description ?? 'Sandboxed: no host filesystem, no shell, no egress',\n defaults: options.defaults,\n session: {\n capabilities: options.capabilities ?? [],\n mcpServers: options.mcpServers ?? [],\n instructions: options.instructions,\n },\n }\n}\n","import {\n createEngineSession,\n type EngineSessionOptions,\n type HostToolDefinition,\n type LanguageModel,\n type McpConnection,\n type Runner,\n type ToolExecutionCall,\n type ToolExecutor,\n type ToolSet,\n} from '@workerdeck/core'\nimport type { EngineRunnerContext } from '../options.ts'\n\nexport type ProviderRunnerOptions = {\n model: LanguageModel | ((modelId: string | undefined) => LanguageModel)\n executor: ToolExecutor | 'browser' | ((call: ToolExecutionCall) => ToolExecutor | 'browser')\n capabilities?: EngineSessionOptions['capabilities']\n tools?: Record<string, HostToolDefinition>\n mcp?: McpConnection\n mcpTools?: ToolSet\n instructions?: string\n executionLimits?: { timeoutMs?: number; memoryLimitBytes?: number }\n seedVfs?: Record<string, string>\n shouldApprove?: (call: { toolName: string; input: unknown }) => boolean\n approvalTimeoutMs?: number\n // Runs on park as well as close: parking releases the same per-session resources.\n onClose?: () => void | Promise<void>\n}\n\nexport async function createProviderRunner(ctx: EngineRunnerContext, options: ProviderRunnerOptions): Promise<Runner> {\n const { config, profile, bridge, restore, id } = ctx\n const resolveModel = (modelId: string | undefined): LanguageModel =>\n typeof options.model === 'function' ? options.model(modelId) : options.model\n const resolveBridged = (): ToolExecutor => ({\n dispatch: (call) => bridge.executorFor(call.sessionId).dispatch(call),\n })\n const resolveExecutor = (raw: ToolExecutor | 'browser'): ToolExecutor => (raw === 'browser' ? resolveBridged() : raw)\n\n const isPerCall = typeof options.executor === 'function'\n const selectExecutor: EngineSessionOptions['selectExecutor'] = isPerCall\n ? (call: ToolExecutionCall) => resolveExecutor((options.executor as (call: ToolExecutionCall) => ToolExecutor | 'browser')(call))\n : () => resolveExecutor(options.executor as ToolExecutor | 'browser')\n const backend: EngineSessionOptions['backend'] = isPerCall\n ? (call: ToolExecutionCall) => {\n const raw = (options.executor as (call: ToolExecutionCall) => ToolExecutor | 'browser')(call)\n return raw === 'browser' ? 'browser' : 'server'\n }\n : options.executor === 'browser'\n ? 'browser'\n : 'server'\n\n return createEngineSession({\n config: {\n ...config,\n languageModel: resolveModel(config.model),\n restore,\n onClose: options.onClose,\n },\n id,\n profile,\n resolveModel: (_profile, c) => resolveModel(c.model),\n selectExecutor,\n backend,\n capabilities: options.capabilities,\n tools: options.tools,\n mcp: options.mcp,\n mcpTools: options.mcpTools,\n instructions: options.instructions,\n executionLimits: options.executionLimits,\n shouldApprove: options.shouldApprove,\n approvalTimeoutMs: options.approvalTimeoutMs,\n seedVfs: options.seedVfs,\n })\n}\n","import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport type { ProfileInfo } from '@workerdeck/protocol'\n\nexport type ProfileStore = {\n list(): ProfileInfo[] | Promise<ProfileInfo[]>\n save(profile: ProfileInfo): void | Promise<void>\n delete(name: string): void | Promise<void>\n}\n\nexport function createMemoryProfileStore(seed: ProfileInfo[] = []): ProfileStore {\n const profiles = new Map(seed.map((p) => [p.name, p]))\n return {\n list: () => [...profiles.values()],\n save: (profile) => void profiles.set(profile.name, profile),\n delete: (name) => void profiles.delete(name),\n }\n}\n\nexport function createFileProfileStore(path = join(process.cwd(), '.workerdeck', 'profiles.json')): ProfileStore {\n const read = (): Map<string, ProfileInfo> => {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown\n if (!Array.isArray(parsed)) {\n return new Map()\n }\n const profiles = parsed as ProfileInfo[]\n return new Map(profiles.filter((p) => p && typeof p.name === 'string').map((p) => [p.name, p]))\n } catch {\n return new Map()\n }\n }\n const write = (profiles: Map<string, ProfileInfo>): void => {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.tmp`\n writeFileSync(temp, JSON.stringify([...profiles.values()], null, 2))\n renameSync(temp, path)\n }\n return {\n list: () => [...read().values()],\n save: (profile) => {\n const profiles = read()\n profiles.set(profile.name, profile)\n write(profiles)\n },\n delete: (name) => {\n const profiles = read()\n if (profiles.delete(name)) {\n write(profiles)\n }\n },\n }\n}\n"],"mappings":"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"}
|