@workerdeck/server 2.12.0 → 2.13.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["resolvePath","osConstants","profiles"],"sources":["../src/lib/http.ts","../src/lib/profile-env.ts","../src/lib/parse-route.ts","../src/lib/reload-plan.ts","../src/routes/executions.ts","../src/services/host-files.ts","../src/services/host-file-search.ts","../src/routes/fs.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/services/shell.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/spend-ledger.ts","../src/services/peers.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 codexHomeDir(env: Record<string, string | undefined>): string {\n return env.CODEX_HOME ?? join(homedir(), '.codex')\n}\n\n// Detection is by credential directory, not by binary: a directory that exists is one the operator\n// has already logged into, and a profile pointing at an engine that is not installed reports itself\n// unavailable rather than failing at session start.\nexport function detectDefaultProfiles(env: Record<string, string | undefined> = process.env): ProfileInfo[] {\n const detected: ProfileInfo[] = []\n const claude = cliConfigDir(env)\n if (existsSync(claude)) {\n detected.push({ name: 'default', configDir: claude })\n }\n const codex = codexHomeDir(env)\n if (existsSync(codex)) {\n detected.push({ name: 'codex', engine: 'codex', codexHome: codex })\n }\n return detected\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 { Runner } from '@workerdeck/core'\nimport { isJobRun } from '@workerdeck/protocol'\n\n// What a hot reload may do with a live session. `carry` hands the runner object itself to the next generation,\n// which is the only way an engine child process, its subagents and its shell grandchildren survive; `persist` is\n// the ordinary restart story through the store; `drop` lets the session end with the generation.\nexport type ReloadPlan = 'carry' | 'persist' | 'drop'\n\nexport function reloadPlan(runner: Runner): ReloadPlan {\n const info = runner.info()\n if (info.status === 'closed' || info.status === 'failed') {\n return 'drop'\n }\n // The queue owns a job's session: a carried one would be a row nothing will ever finalize.\n if (isJobRun(info)) {\n return 'drop'\n }\n // Keyed on the capability, never on the engine name: \"can this session persist itself\" is the actual question,\n // and a runner that can snapshot has in-process executors closed over this generation's bridge hub, which after\n // the swap has no sockets. Carrying one does not orphan a call in flight, it breaks every later bridged call.\n if (runner.snapshot !== undefined) {\n return 'persist'\n }\n return 'carry'\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// 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.\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 { CostLedgerState, 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 cost?: CostLedgerState\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 cost?: CostLedgerState\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', 'peers'] 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]+)*$/\nconst SHORTCODE_RE = /^[A-Z0-9]{2,5}$/\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; shortcode?: 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 const shortcode = classifyShortcode(raw.shortcode)\n return {\n project: { name, root, ...(icon ? { icon: icon.wire } : {}), ...(shortcode ? { shortcode } : {}) },\n ...(icon?.resolved ? { icon: icon.resolved } : {}),\n }\n}\n\nfunction classifyShortcode(value: unknown): string | undefined {\n return typeof value === 'string' && SHORTCODE_RE.test(value) ? value : undefined\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 { spawn } from 'node:child_process'\nimport { constants as osConstants } from 'node:os'\nimport type { Runner } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES } from '@workerdeck/protocol'\n\nexport const SHELL_DEFAULT_TIMEOUT_MS = 120_000\nexport const SHELL_DEFAULT_MAX_OUTPUT_BYTES = 32 * 1024\nconst TIMEOUT_EXIT_CODE = 124\nconst SPAWN_FAILURE_EXIT_CODE = 127\nconst KILLED_EXIT_CODE = 128 + osConstants.signals.SIGKILL\n\nexport type ShellServiceOptions = {\n timeoutMs?: number\n maxOutputBytes?: number\n}\n\nexport type ShellRunResult = {\n command: string\n stdout: string\n stderr: string\n exitCode: number\n durationMs: number\n}\n\nexport type ShellChild = {\n result: Promise<ShellRunResult>\n kill: (reason: string) => void\n}\n\nexport type ShellService = ReturnType<typeof createShellService>\n\nexport function shellPermitted(shell: ShellService | null, runner: Runner, operator: boolean): boolean {\n if (shell === null || !operator) {\n return false\n }\n const info = runner.info()\n const capabilities = info.capabilities ?? (info.engine ? ENGINE_CAPABILITIES[info.engine] : undefined)\n return capabilities?.hostCwd === true\n}\n\n// A spawn env replaces the inherited one wholesale, so the copy has to be complete; the gateway's own environment is\n// what the operator's terminal would have given the same command.\nexport function shellChildEnv(base: Record<string, string | undefined>): Record<string, string> {\n const env: Record<string, string> = {}\n for (const [key, value] of Object.entries(base)) {\n if (value !== undefined) {\n env[key] = value\n }\n }\n return env\n}\n\nexport function createShellService(options: ShellServiceOptions = {}) {\n const timeoutMs = options.timeoutMs ?? SHELL_DEFAULT_TIMEOUT_MS\n const maxOutputBytes = options.maxOutputBytes ?? SHELL_DEFAULT_MAX_OUTPUT_BYTES\n const active = new Map<string, ShellChild>()\n\n const run = async (sessionId: string, cwd: string, command: string): Promise<ShellRunResult> => {\n if (active.has(sessionId)) {\n throw new Error('a shell command is still running on this session')\n }\n const child = spawnShell({ command, cwd, env: shellChildEnv(process.env), timeoutMs, maxOutputBytes })\n active.set(sessionId, child)\n try {\n return await child.result\n } finally {\n if (active.get(sessionId) === child) {\n active.delete(sessionId)\n }\n }\n }\n\n const kill = (sessionId: string, reason = 'session closed'): void => {\n active.get(sessionId)?.kill(reason)\n }\n\n const watch = (runner: Runner): (() => void) =>\n runner.subscribe((event) => {\n if (event.type === 'session_closed') {\n kill(runner.id, 'session closed')\n } else if (event.type === 'status_changed' && event.status === 'parked') {\n kill(runner.id, 'session parked')\n }\n }, runner.info().lastSeq)\n\n const killAll = (): void => {\n for (const sessionId of active.keys()) {\n kill(sessionId, 'server shutting down')\n }\n }\n\n const running = (sessionId: string): boolean => active.has(sessionId)\n\n return { run, kill, watch, killAll, running, timeoutMs, maxOutputBytes }\n}\n\ntype SpawnShellInput = {\n command: string\n cwd: string\n env: Record<string, string>\n timeoutMs: number\n maxOutputBytes: number\n}\n\nclass BoundedOutput {\n #chunks: Buffer[] = []\n #kept = 0\n #dropped = 0\n #budget: { remaining: number }\n\n constructor(budget: { remaining: number }) {\n this.#budget = budget\n }\n\n push(chunk: Buffer): void {\n const take = Math.min(chunk.length, this.#budget.remaining)\n if (take > 0) {\n this.#chunks.push(take === chunk.length ? chunk : chunk.subarray(0, take))\n this.#kept += take\n this.#budget.remaining -= take\n }\n this.#dropped += chunk.length - take\n }\n\n text(): string {\n const head = Buffer.concat(this.#chunks, this.#kept).toString('utf8')\n return this.#dropped > 0 ? `${head}\\n[output truncated: ${this.#dropped} more bytes dropped]` : head\n }\n}\n\nexport function spawnShell(input: SpawnShellInput): ShellChild {\n const startedAt = Date.now()\n const budget = { remaining: input.maxOutputBytes }\n const stdout = new BoundedOutput(budget)\n const stderr = new BoundedOutput(budget)\n let settle: ((result: ShellRunResult) => void) | undefined\n const result = new Promise<ShellRunResult>((resolve) => {\n settle = resolve\n })\n let done = false\n const finish = (exitCode: number, note?: string): void => {\n if (done) {\n return\n }\n done = true\n clearTimeout(timer)\n const captured = stderr.text()\n const stderrText = note ? (captured ? `${captured}\\n[${note}]` : `[${note}]`) : captured\n settle?.({ command: input.command, stdout: stdout.text(), stderr: stderrText, exitCode, durationMs: Date.now() - startedAt })\n }\n\n // The child leads its own process group so a kill reaches the pipeline it started, not just the shell.\n const child = spawn('/bin/sh', ['-c', input.command], {\n cwd: input.cwd,\n env: { ...input.env, PWD: input.cwd },\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true,\n })\n child.stdout.on('data', (chunk: Buffer) => stdout.push(chunk))\n child.stderr.on('data', (chunk: Buffer) => stderr.push(chunk))\n\n const killGroup = (): void => {\n if (child.pid === undefined) {\n return\n }\n try {\n process.kill(-child.pid, 'SIGKILL')\n } catch {\n try {\n child.kill('SIGKILL')\n } catch {}\n }\n child.stdout.destroy()\n child.stderr.destroy()\n }\n const kill = (reason: string, exitCode = KILLED_EXIT_CODE): void => {\n if (done) {\n return\n }\n killGroup()\n finish(exitCode, `killed: ${reason}`)\n }\n\n const timer = setTimeout(() => kill(`timed out after ${Math.round(input.timeoutMs / 1000)}s`, TIMEOUT_EXIT_CODE), input.timeoutMs)\n child.on('error', (error) => finish(SPAWN_FAILURE_EXIT_CODE, error.message))\n child.on('close', (code, signal) => {\n const signalCode = signal ? (osConstants.signals[signal] ?? 0) : 0\n finish(code ?? (signalCode ? 128 + signalCode : 1), signal ? `killed by ${signal}` : undefined)\n })\n\n return { result, kill: (reason) => kill(reason) }\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { WebSocket } from 'ws'\nimport { isSlashCommand, type Runner } from '@workerdeck/core'\nimport { PROTOCOL_VERSION, SHELL_COMMAND_MAX, type ClientFrame, type ServerFrame } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\nimport { shellPermitted } from '../services/shell.ts'\n\n// What the upgrade established about the principal; computed once there so the attach never re-authenticates.\nexport type AttachAccess = { operator: boolean }\n\nexport function attachClient(ctx: ServerContext, ws: WebSocket, runner: Runner, req: IncomingMessage, access: AttachAccess): 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 ...(shellPermitted(ctx.shell, runner, access.operator) ? { shell: true } : {}),\n ...(ctx.pricingOverrides ? { pricingOverrides: ctx.pricingOverrides } : {}),\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 // After the replay is wired, so a fresh reading arrives as a live event behind the history rather than racing it.\n // The replay faithfully re-installs whatever this session last heard, which on an idle session can be days old,\n // and until now nothing in an attach asked for a newer one. Throttled inside the runner; failures are silent by\n // design (the control request is experimental, and a missing usage reading is not an attach failure).\n void runner.refreshUsage?.().catch(() => {})\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, access).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, access: AttachAccess): Promise<void> {\n const { attachmentStore, bridge } = ctx\n switch (frame.type) {\n case 'user_message': {\n // The one place `mentions` is ever set: this frame is a person typing. A slash command is\n // matched on the whole message by the CLI, so nothing may be appended to one, and a failure\n // to resolve is silent - a hint must never lose the text it was a hint about.\n const mentions = ctx.peers && !isSlashCommand(frame.text) ? await ctx.peers.mentions(runner.id, frame.text).catch(() => []) : []\n const options = mentions.length > 0 ? { mentions } : undefined\n if (!frame.attachmentIds?.length) {\n runner.sendMessage(frame.text, undefined, options)\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, options)\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 'shell_command': {\n if (!shellPermitted(ctx.shell, runner, access.operator) || ctx.shell === null) {\n throw new Error('shell commands are not available on this session')\n }\n if (typeof frame.command !== 'string' || frame.command.includes('\\0')) {\n throw new Error('shell command must be a string')\n }\n if (frame.command.length > SHELL_COMMAND_MAX) {\n throw new Error(`shell command exceeds ${SHELL_COMMAND_MAX} characters`)\n }\n if (frame.command.trim() === '') {\n throw new Error('shell command is empty')\n }\n if (!runner.queueLocalCommand) {\n throw new Error(`the ${runner.info().engine ?? 'claude'} engine cannot take shell output`)\n }\n const result = await ctx.shell.run(runner.id, runner.info().cwd, frame.command)\n runner.queueLocalCommand(result)\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 return 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 #watches = new Map<string, () => 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 // The unsubscribe is retained, not merely returned. Every caller drops it, and `#track` has neither the `#closed`\n // guard the writers have nor an ownership check: a deferred dispatch reaching a closed manager still arms a\n // watchdog, and when that fires it rebuilds the session through the registry and factory of a generation that is\n // over. `release()` is the only thing that can take the listener off a runner nobody closed.\n watch(runner: Runner, afterSeq = 0): () => void {\n this.#watches.get(runner.id)?.()\n const unsubscribe = 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 const detach = (): void => {\n if (this.#watches.get(runner.id) === detach) {\n this.#watches.delete(runner.id)\n }\n unsubscribe()\n }\n this.#watches.set(runner.id, detach)\n return detach\n }\n\n // Hands a live session to another manager: stops watching it, forgets what this manager knows about it, and\n // returns the one fact the next manager cannot rederive. A durable record strips `env`, `queryFn`, `historyFn`\n // and `extraOptions`, and before `system_init` there is no record at all, so `#configs` is not recoverable from\n // the store. Deliberately leaves the store alone: the record is the point of the handover, not a casualty of it.\n release(sessionId: string): SessionRunnerConfig | undefined {\n this.#watches.get(sessionId)?.()\n this.#watches.delete(sessionId)\n clearTimeout(this.#detachTimers.get(sessionId))\n this.#detachTimers.delete(sessionId)\n const config = this.#configs.get(sessionId)\n this.#configs.delete(sessionId)\n this.#remembered.delete(sessionId)\n return config\n }\n\n // The order is what `#rememberDormant`'s ownership guard turns into a silent no-write if reversed: `touch()`\n // writes nothing for a runner this manager's registry does not hold, so the register comes first. `#rebuild` does\n // the same four steps for the same reason. `lastSeq`, never 0: replaying a long session's history queues one\n // dormant re-save per historical `status_changed`, and the single `touch()` is what writes the current record.\n adopt(runner: Runner, config?: SessionRunnerConfig): void {\n this.#options.registry.register(runner)\n if (config) {\n this.remember(runner.id, config)\n }\n this.watch(runner, runner.info().lastSeq)\n this.touch(runner)\n }\n\n // `touch()` is fire-and-forget for the PATCH route that has no one to report to. A caller that is about to close\n // this manager, or to let another one write the same files, needs to know the write landed.\n async flush(sessionId?: string): Promise<void> {\n if (sessionId === undefined) {\n await Promise.all(this.#storeOps.values())\n return\n }\n await this.#storeOps.get(sessionId)\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 // Dropped rather than run: `discard` is reached from the `session_closed` arm of the very subscription this\n // handle unsubscribes, and the runner drops its subscribers on close anyway.\n this.#watches.delete(sessionId)\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 cost: runner.costState?.(),\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 cost: runner.costState?.(),\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 cost = runner.costState?.()\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 cost,\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 runner.carryCost?.(record.cost ?? { byModel: record.info.usageByModel, reportedCostUsd: record.info.totalCostUsd })\n this.#options.registry.register(runner)\n // The config the runner was actually built with, not the one on the record: a dormant wake\n // bumps the epoch, and the next park must carry the new one rather than resurrect the old.\n this.remember(id, { ...record.config, epoch: runner.info().epoch })\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 return 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 seed?: 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 spend?: (name: string) => ProfileInfo['spend'] | 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 // Auto-detected profiles land in the store, not in `declared`, so the first thing an operator sees\n // is a profile they can rename, retarget or delete. Seeding only an empty store is what keeps it a\n // first-launch act: once a profile exists, detection never writes again.\n async seedStore(): Promise<void> {\n const seed = this.#opts.seed ?? []\n if (!this.#opts.store || seed.length === 0 || this.#stored.size > 0) {\n return\n }\n for (const p of seed) {\n if (this.validate(p) === null) {\n await this.#opts.store.save(p)\n }\n }\n await this.refreshStored()\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 const spend = decorate.spend?.(p.name)\n if (spend) {\n base.spend = spend\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 codex = engineOf(profile) === 'codex'\n const dir = codex ? profile.codexHome : profile.configDir\n // A codex profile that names no CODEX_HOME runs on the server's own environment, which every\n // session already inherits - there is no separate credential store for the roots to bound.\n if (codex && !dir) {\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 and Codex profiles are disabled: set `allowedConfigDirRoots` to the ' + 'directories they may point at',\n }\n }\n return dir && cwdAllowed(dir, roots)\n ? null\n : { status: 403, error: `${codex ? 'codexHome' : '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 return 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 { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { Runner } from '@workerdeck/core'\nimport { type ByModel, type ProfileSpend, costOfByModel, mergeByModel, subscriptionComparison } from '@workerdeck/protocol'\n\nexport type SpendRecord = { days: Record<string, Record<string, ByModel>> }\n\nexport type SpendStore = {\n load(): Promise<SpendRecord | undefined>\n save(record: SpendRecord): Promise<void>\n}\n\nexport type SpendLedgerOptions = {\n store?: SpendStore\n monthlySubscriptionUsd?: (profile: string) => number | undefined\n retentionDays?: number\n saveDebounceMs?: number\n onError?: (error: unknown) => void\n}\n\nconst DEFAULT_RETENTION_DAYS = 92\n\nconst DEFAULT_SAVE_DEBOUNCE_MS = 2_000\n\nexport function dayKey(at: number): string {\n const d = new Date(at)\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nfunction daysBack(now: number, count: number): string[] {\n const out: string[] = []\n for (let i = 0; i < count; i += 1) {\n out.push(dayKey(now - i * 86_400_000))\n }\n return out\n}\n\nfunction subtract(current: ByModel, previous: ByModel): ByModel {\n const delta: ByModel = {}\n for (const [model, usage] of Object.entries(current)) {\n const was = previous[model]\n const row = {\n input: usage.input - (was?.input ?? 0),\n output: usage.output - (was?.output ?? 0),\n cacheWrite5m: usage.cacheWrite5m - (was?.cacheWrite5m ?? 0),\n cacheWrite1h: usage.cacheWrite1h - (was?.cacheWrite1h ?? 0),\n cacheRead: usage.cacheRead - (was?.cacheRead ?? 0),\n }\n // A negative delta means the session's cumulative figure went backwards, which only happens when the reading\n // we diffed against was not this session's. Recording nothing beats recording a negative day.\n if (Object.values(row).some((value) => value < 0)) {\n continue\n }\n if (Object.values(row).some((value) => value > 0)) {\n delta[model] = row\n }\n }\n return delta\n}\n\n// `turn_result.usageByModel` is session-cumulative, so the ledger records the difference from what this session\n// last contributed. The baseline is seeded from the runner's own info at watch time, which is what keeps a woken\n// session's carried spend from being banked a second time as if it had just been earned.\nexport class SpendLedger {\n #days: Record<string, Record<string, ByModel>> = {}\n #lastBanked = new Map<string, ByModel>()\n #options: SpendLedgerOptions\n #saveTimer: ReturnType<typeof setTimeout> | undefined\n #loaded: Promise<void> | undefined\n\n constructor(options: SpendLedgerOptions = {}) {\n this.#options = options\n }\n\n load(): Promise<void> {\n this.#loaded ??= this.#load()\n return this.#loaded\n }\n\n async #load(): Promise<void> {\n const store = this.#options.store\n if (!store) {\n return\n }\n try {\n const record = await store.load()\n if (record?.days) {\n this.#days = record.days\n }\n } catch (error) {\n this.#options.onError?.(error)\n }\n }\n\n watch(runner: Runner): () => void {\n const info = runner.info()\n const profile = info.profile\n if (!profile) {\n return () => {}\n }\n this.#lastBanked.set(runner.id, info.usageByModel ?? {})\n const unsubscribe = runner.subscribe((event) => {\n if (event.type !== 'turn_result' || !event.usageByModel) {\n return\n }\n this.#bank(profile, event.usageByModel, runner.id, event.ts)\n })\n return () => {\n unsubscribe()\n this.#lastBanked.delete(runner.id)\n }\n }\n\n #bank(profile: string, cumulative: ByModel, sessionId: string, at: number): void {\n const previous = this.#lastBanked.get(sessionId) ?? {}\n const delta = subtract(cumulative, previous)\n this.#lastBanked.set(sessionId, cumulative)\n if (Object.keys(delta).length === 0) {\n return\n }\n const key = dayKey(at)\n const day = (this.#days[key] ??= {})\n day[profile] = mergeByModel(day[profile] ?? {}, delta)\n this.#scheduleSave()\n }\n\n spend(profile: string, now = Date.now()): ProfileSpend | undefined {\n const week = this.#window(profile, daysBack(now, 7))\n const month = this.#window(profile, daysBack(now, 30))\n if (Object.keys(month).length === 0) {\n return undefined\n }\n const weekCost = costOfByModel(week)\n const monthlySubscriptionUsd = this.#options.monthlySubscriptionUsd?.(profile)\n return {\n weekUsd: weekCost.total,\n monthUsd: costOfByModel(month).total,\n weekByModel: week,\n unpricedShare: weekCost.unpricedShare,\n monthlySubscriptionUsd,\n subscription: monthlySubscriptionUsd ? subscriptionComparison(weekCost.total, monthlySubscriptionUsd) : undefined,\n }\n }\n\n #window(profile: string, keys: string[]): ByModel {\n let out: ByModel = {}\n for (const key of keys) {\n const day = this.#days[key]?.[profile]\n if (day) {\n out = mergeByModel(out, day)\n }\n }\n return out\n }\n\n #scheduleSave(): void {\n if (!this.#options.store || this.#saveTimer) {\n return\n }\n this.#saveTimer = setTimeout(() => {\n this.#saveTimer = undefined\n void this.flush()\n }, this.#options.saveDebounceMs ?? DEFAULT_SAVE_DEBOUNCE_MS)\n this.#saveTimer.unref?.()\n }\n\n async flush(): Promise<void> {\n const store = this.#options.store\n if (!store) {\n return\n }\n this.#prune()\n try {\n await store.save({ days: this.#days })\n } catch (error) {\n this.#options.onError?.(error)\n }\n }\n\n #prune(): void {\n const keep = new Set(daysBack(Date.now(), this.#options.retentionDays ?? DEFAULT_RETENTION_DAYS))\n for (const key of Object.keys(this.#days)) {\n if (!keep.has(key)) {\n delete this.#days[key]\n }\n }\n }\n\n close(): void {\n clearTimeout(this.#saveTimer)\n this.#saveTimer = undefined\n }\n}\n\nexport function createFileSpendStore(path: string, onError?: (error: unknown) => void): SpendStore {\n return {\n async load() {\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as unknown\n if (parsed === null || typeof parsed !== 'object' || typeof (parsed as SpendRecord).days !== 'object') {\n return undefined\n }\n return parsed as SpendRecord\n } catch {\n return undefined\n }\n },\n async save(record) {\n try {\n await mkdir(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.tmp`\n await writeFile(temp, JSON.stringify(record))\n await rename(temp, path)\n } catch (error) {\n onError?.(error)\n }\n },\n }\n}\n","import {\n PEER_MESSAGE_MAX_CHARS,\n PEER_RECENT_DEFAULT,\n PEER_RECENT_MAX,\n peerSummary,\n recentLines,\n type PeerDirectory,\n type PeerPeek,\n type PeerSendOptions,\n type PeerSendResult,\n type PeerMention,\n type PeerSessionSummary,\n type Runner,\n} from '@workerdeck/core'\nimport {\n PEER_MENTION_MAX,\n peerMentionKey,\n peerMentionSlug,\n scanPeerMentions,\n type MessageOrigin,\n type SessionEvent,\n type SessionInfo,\n} from '@workerdeck/protocol'\nimport { scopeMatches } from '../lib/scope.ts'\nimport type { LateBoundRefs } from '../options.ts'\nimport type { ProjectInfoService } from './project-info.ts'\nimport type { SessionRegistry } from './registry.ts'\n\nexport type PeerServiceOptions = {\n enabled?: boolean\n maxMessageChars?: number\n perMinute?: number\n maxHops?: number\n}\n\nexport type PeerServiceDeps = {\n refs: LateBoundRefs\n projects: ProjectInfoService\n options?: PeerServiceOptions\n}\n\nconst DEFAULT_PER_MINUTE = 10\nconst DEFAULT_MAX_HOPS = 12\nconst WINDOW_MS = 60_000\n\nfunction visible(from: SessionInfo, to: SessionInfo): boolean {\n return to.id !== from.id && scopeMatches(from.scope, to.scope)\n}\n\nexport type PeerService = PeerDirectory & {\n watch(runner: Runner): () => void\n // The `#Name` tokens in a message a person typed, resolved to the peers that session can see.\n mentions(from: string, text: string): Promise<PeerMention[]>\n}\n\n// Session-to-session messaging inside one gateway. Visibility is the session-scope rule the HTTP routes enforce,\n// applied with the *sender's* scope as the principal: a scoped session sees the sessions a scoped client would.\nexport function createPeerService(deps: PeerServiceDeps): PeerService {\n const perMinute = deps.options?.perMinute ?? DEFAULT_PER_MINUTE\n const maxChars = deps.options?.maxMessageChars ?? PEER_MESSAGE_MAX_CHARS\n const maxHops = deps.options?.maxHops ?? DEFAULT_MAX_HOPS\n const sent = new Map<string, number[]>()\n // The chain of sessions that led to the last peer message each session received, cleared when a human speaks to\n // it: two agents answering each other without a person in the loop is the loop this bounds.\n const inbound = new Map<string, string[]>()\n\n const registry = (): SessionRegistry => {\n const found = deps.refs.registry\n if (!found) {\n throw new Error('peer messaging is not ready')\n }\n return found\n }\n\n const allSessions = async (): Promise<SessionInfo[]> => {\n const live = registry().list()\n const dormant = (await deps.refs.parking?.listInfo()) ?? []\n return [...live, ...dormant].map((info) => deps.projects.withProject(info))\n }\n\n const infoOf = async (id: string): Promise<SessionInfo | undefined> => {\n const live = registry().get(id)?.info()\n if (live) {\n return deps.projects.withProject(live)\n }\n const record = await deps.refs.parking?.get(id)\n return record ? deps.projects.withProject(record.info) : undefined\n }\n\n const sender = async (from: string): Promise<SessionInfo> => {\n const info = await infoOf(from)\n if (!info) {\n throw new Error(`unknown sender session: ${from}`)\n }\n return info\n }\n\n const underRateLimit = (from: string, to: string): boolean => {\n const key = `${from}->${to}`\n const now = Date.now()\n const recent = (sent.get(key) ?? []).filter((at) => now - at < WINDOW_MS)\n if (recent.length >= perMinute) {\n sent.set(key, recent)\n return false\n }\n recent.push(now)\n sent.set(key, recent)\n return true\n }\n\n const list = async (from: string): Promise<PeerSessionSummary[]> => {\n const me = await sender(from)\n return (await allSessions())\n .filter((info) => visible(me, info))\n .sort((a, b) => (b.lastActivityAt ?? b.createdAt) - (a.lastActivityAt ?? a.createdAt))\n .map(peerSummary)\n }\n\n const peek = async (from: string, sessionId: string, options?: { recent?: number }): Promise<PeerPeek | undefined> => {\n const me = await sender(from)\n const info = await infoOf(sessionId)\n if (!info || !visible(me, info)) {\n return undefined\n }\n const limit = Math.min(Math.max(options?.recent ?? PEER_RECENT_DEFAULT, 0), PEER_RECENT_MAX)\n const runner = registry().get(sessionId)\n const events: SessionEvent[] = []\n if (runner && limit > 0) {\n runner.subscribe((event) => events.push(event), 0, { truncateResults: true, imageRefs: true })()\n }\n return {\n ...peerSummary(info),\n live: runner !== undefined,\n checklist: info.checklist,\n pendingApprovals: runner ? runner.pendingApprovals.map((request) => request.title ?? request.toolName) : [],\n recent: recentLines(events, limit),\n }\n }\n\n const send = async (from: string, sessionId: string, text: string, options?: PeerSendOptions): Promise<PeerSendResult> => {\n const me = await sender(from)\n if (sessionId === from) {\n return { delivered: false, reason: 'that is this session' }\n }\n if (text.length > maxChars) {\n return {\n delivered: false,\n reason: `message is ${text.length} characters; the limit is ${maxChars}. Write it to a file and send the path.`,\n }\n }\n const target = await infoOf(sessionId)\n if (!target || !visible(me, target)) {\n return { delivered: false, reason: `no such session: ${sessionId}` }\n }\n if (target.status === 'closed' || target.status === 'failed') {\n return { delivered: false, reason: `session ${sessionId} is ${target.status}` }\n }\n const hops = [...(options?.hops ?? inbound.get(from) ?? []), from]\n if (hops.length > maxHops) {\n return {\n delivered: false,\n reason: `${hops.length} messages have passed between sessions without a person speaking; stop and ask your user before continuing.`,\n }\n }\n if (!underRateLimit(from, sessionId)) {\n return { delivered: false, reason: `rate limit: at most ${perMinute} messages a minute to one session. Batch what you have to say.` }\n }\n const runner = (await deps.refs.parking?.ensureLive(sessionId)) ?? registry().get(sessionId)\n if (!runner) {\n return { delivered: false, reason: `session ${sessionId} could not be woken` }\n }\n const before = runner.info().status\n const origin: MessageOrigin = { kind: 'peer', sessionId: from, name: me.title, engine: me.engine, hops }\n try {\n runner.sendMessage(text, undefined, { origin })\n } catch (error) {\n return { delivered: false, reason: error instanceof Error ? error.message : String(error) }\n }\n inbound.set(sessionId, hops)\n return { delivered: true, sessionId, name: target.title, queued: before === 'running' || before === 'awaiting_approval' }\n }\n\n // A session id is a handle a person may paste, so a full id and an unambiguous prefix resolve too.\n const mentions = async (from: string, text: string): Promise<PeerMention[]> => {\n const tokens = scanPeerMentions(text)\n if (tokens.length === 0) {\n return []\n }\n const rows = await list(from)\n const byKey = new Map<string, PeerSessionSummary[]>()\n const add = (key: string, row: PeerSessionSummary) => {\n const held = byKey.get(key)\n if (held) {\n held.push(row)\n } else {\n byKey.set(key, [row])\n }\n }\n for (const row of rows) {\n add(peerMentionKey(peerMentionSlug(row.title, row.id)), row)\n add(peerMentionKey(row.id), row)\n }\n const resolved: PeerMention[] = []\n const seen = new Set<string>()\n for (const token of tokens) {\n const key = peerMentionKey(token.body)\n const exact = byKey.get(key)\n // `list` is newest-first, so a shared title resolves to the session that moved last and the\n // envelope names the others rather than choosing silently.\n const matches = exact ?? (key.length >= 4 ? rows.filter((row) => row.id.startsWith(key)) : [])\n const target = matches[0]\n if (!target || (matches.length > 1 && !exact)) {\n continue\n }\n if (seen.has(target.id)) {\n continue\n }\n seen.add(target.id)\n const others = matches.slice(1, 4).map((row) => row.id)\n resolved.push({\n typed: token.body,\n id: target.id,\n name: target.title,\n engine: target.engine,\n status: target.status,\n cwd: target.cwd,\n ...(others.length ? { ambiguousWith: others } : {}),\n })\n if (resolved.length >= PEER_MENTION_MAX) {\n break\n }\n }\n return resolved\n }\n\n const watch = (runner: Runner): (() => void) =>\n runner.subscribe((event) => {\n if (event.type === 'user_message' && !event.origin && !event.synthetic && event.parentToolUseId == null && !event.replay) {\n inbound.delete(runner.id)\n }\n }, runner.info().lastSeq)\n\n return { list, peek, send, mentions, watch }\n}\n","import { SessionRunner, type Runner, type SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type SessionRegistryOptions = {\n // A returned function is a detach: run when the runner leaves this registry, whether it was closed or handed to\n // another one. Typed `unknown` rather than `void | (() => void)` on purpose: TypeScript only forgives a\n // non-void return against a bare `void`, so the narrower union would break every embedder whose hook is a\n // one-expression arrow (`(r) => seen.push(r)`). The function check is at the retaining end instead.\n onRegister?: (runner: Runner) => unknown\n}\n\nexport class SessionRegistry {\n #sessions = new Map<string, Runner>()\n #options: SessionRegistryOptions\n #observers = new Set<(runner: Runner) => unknown>()\n // The watchers a registration attached, kept because the objects that attached them are exactly what a hot\n // reload discards: nobody else is in a position to take them off a runner that outlives its generation.\n #detachers = new Map<string, (() => void)[]>()\n\n constructor(options: SessionRegistryOptions = {}) {\n this.#options = options\n }\n\n // `onRegister` for a caller that only has the built server - an embedding host, or the CLI. Replays what is already\n // registered so a late observer cannot miss a session, which is the whole difference from reading the option.\n observe(listener: (runner: Runner) => unknown): () => void {\n this.#observers.add(listener)\n for (const runner of this.#sessions.values()) {\n this.#retain(runner.id, listener(runner))\n }\n return () => void this.#observers.delete(listener)\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.#retain(runner.id, this.#options.onRegister?.(runner))\n for (const listener of this.#observers) {\n this.#retain(runner.id, listener(runner))\n }\n }\n return runner\n }\n\n // For a watcher attached outside `onRegister` - `watchAuthSource` is the one in this package - that must still\n // come off when the runner leaves. Without it a released runner keeps a listener from a discarded generation.\n retain(id: string, detach: () => void): void {\n this.#retain(id, detach)\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 this.#detach(id)\n return this.#sessions.delete(id)\n }\n\n evict(id: string): boolean {\n this.#detach(id)\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 #retain(id: string, detach: unknown): void {\n if (typeof detach !== 'function') {\n return\n }\n const run = detach as () => void\n const existing = this.#detachers.get(id)\n if (existing) {\n existing.push(run)\n return\n }\n this.#detachers.set(id, [run])\n }\n\n #detach(id: string): void {\n for (const detach of this.#detachers.get(id) ?? []) {\n detach()\n }\n this.#detachers.delete(id)\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, PeerDirectory, 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 approvalTimeoutMs?: number | null\n requireApiKey?: boolean\n peers?: PeerDirectory\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 // The gateway's default reaches every engine through the config, so a runner rebuilt from a parked\n // record gets the same deadline policy as the one it replaces.\n const withApprovalDefault = (config: SessionRunnerConfig): SessionRunnerConfig =>\n deps.approvalTimeoutMs === undefined ? config : { ...config, defaultApprovalTimeoutMs: deps.approvalTimeoutMs }\n\n const buildRunnerConfig = (req: CreateSessionRequest): SessionRunnerConfig => {\n const profile = req.profile !== undefined ? profiles.get(req.profile) : undefined\n if (!profile) {\n return withApprovalDefault(withScope(deps.hostBuildRunnerConfig(req), req.scope))\n }\n const config = withApprovalDefault(\n 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 )\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 (built: SessionRunnerConfig, restore?: RunnerSnapshot, id?: string): Promise<Runner> => {\n // Applied here rather than in buildRunnerConfig so a parked record, which stores its config, gets it too.\n const config = deps.peers ? { ...built, peers: deps.peers } : built\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 // One profile needs no naming, and neither does a set that still carries the auto-detected\n // `default` - otherwise choosing is the caller's, because a profile is a credential store.\n const effective = name ?? (all.length === 1 ? all[0]!.name : all.find((p) => p.name === 'default')?.name)\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 return 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, installPeerDirectory, peerDirectoryHandle } from '@workerdeck/core'\nimport type { EngineAdapter } from '@workerdeck/core'\nimport { JobQueue } from '@workerdeck/queue'\nimport {\n PROTOCOL_VERSION,\n sessionState,\n setPricingOverrides,\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 { reloadPlan } from './lib/reload-plan.ts'\nimport type { DrainReport, LateBoundRefs, WorkerServer, WorkerServerOptions } from './options.ts'\nimport { handleExecutionResult } from './routes/executions.ts'\nimport { handleHostFiles } from './routes/fs.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 { SpendLedger } from './services/spend-ledger.ts'\nimport { createPeerService } from './services/peers.ts'\nimport { ProjectInfoService } from './services/project-info.ts'\nimport { SessionRegistry } from './services/registry.ts'\nimport { createSessionFactory } from './services/session-factory.ts'\nimport { createShellService } from './services/shell.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// The outer bound on close(): it resolves by then whether or not the runtime ever reports the drains complete.\nconst CLOSE_DEADLINE_MS = 1_000\n\n// How old the account-level rate-limit reading may be before a profiles read asks a live session for a newer one.\n// Generous: the windows move over hours, and the point is to bound staleness at minutes rather than at days.\nconst USAGE_STALE_MS = 5 * 60_000\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.\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 pricing = setPricingOverrides(options.pricing?.overrides)\n if (pricing.dropped.length > 0) {\n console.warn(\n `[workerdeck] Ignoring pricing.overrides for ${pricing.dropped.join(', ')}: ` +\n 'each entry needs input, output, cacheWrite5m, cacheWrite1h and cacheRead in USD per million tokens',\n )\n }\n\n const profileDefaultModels = new Map<string, string>()\n const profileUsage = new ProfileUsageTracker()\n const spendLedger = new SpendLedger({\n store: options.spend?.store,\n monthlySubscriptionUsd: (name) => options.spend?.monthlySubscriptionUsd?.[name] ?? options.spend?.monthlySubscriptionUsd?.['*'],\n onError: (error) => options.spend?.onError?.(error),\n })\n void spendLedger.load()\n // The backstop behind the attach-time refresh, for the surface that reads the account number without opening a\n // session at all. Fire and forget: this request still answers with what is known, and the newer reading arrives\n // as a `rate_limit` event moments later. One session per profile is enough - the reading is account-level - and\n // the runner's own throttle is what keeps a page of profiles from becoming a page of control requests.\n const refreshStaleUsage = (name: string): void => {\n const held = profileUsage.usage(name)\n const newest = Math.max(0, ...Object.values(held ?? {}).map((window) => window.updatedAt ?? 0))\n if (Date.now() - newest < USAGE_STALE_MS) {\n return\n }\n for (const info of refs.registry?.list() ?? []) {\n if (info.profile !== name) {\n continue\n }\n const runner = refs.registry?.get(info.id)\n if (runner?.refreshUsage) {\n void runner.refreshUsage().catch(() => {})\n return\n }\n }\n }\n // With a store in play, detection seeds it on first launch instead of declaring anything: a\n // declared profile cannot be edited over the API, and an auto-detected one is exactly the profile\n // an operator most wants to rename or retarget.\n const detected = options.profiles ? [] : detectDefaultProfiles()\n const profiles = new ProfileService({\n declared: options.profiles ?? (options.profileStore ? [] : detected),\n seed: detected,\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) => {\n refreshStaleUsage(name)\n return profileUsage.usage(name)\n },\n spend: (name) => spendLedger.spend(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 projects = new ProjectInfoService()\n const peers = options.peers?.enabled === false ? undefined : createPeerService({ refs, projects, options: options.peers })\n if (peers) {\n installPeerDirectory(peers)\n }\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 approvalTimeoutMs: options.approvalTimeoutMs,\n requireApiKey: options.requireApiKey,\n peers: peers ? peerDirectoryHandle() : undefined,\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 notifier = new SessionNotifier({\n ...options.notifications,\n decorateInfo: (info) => projects.withProject(info),\n })\n const producedFiles = new ProducedFileStore()\n const shell = options.shell?.enabled === true ? createShellService(options.shell) : null\n const registry = new SessionRegistry({\n // Every watcher here hands back its detach, and the registry runs them when the runner leaves. A hot reload is\n // the case that needs it: the runner outlives this server, and these closures would otherwise keep delivering\n // webhooks and pushes from a generation that is over, one extra copy per reload.\n onRegister: (runner) => {\n const detachers = [\n notifier.watch(runner),\n producedFiles.watch(runner),\n profileUsage.watch(runner),\n spendLedger.watch(runner),\n shell?.watch(runner),\n peers?.watch(runner),\n ]\n const profile = runner.info().profile\n if (profile) {\n detachers.push(\n runner.subscribe((event) => {\n if (event.type !== 'capabilities' || !event.defaultModel) {\n return\n }\n profileDefaultModels.set(profile, event.defaultModel)\n }),\n )\n }\n return () => {\n for (const detach of detachers) {\n detach?.()\n }\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 {\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 // Applied after the host's hook, which is free to rebuild the config from the\n // request and would drop a field it has never heard of.\n epoch: (record.info.epoch ?? 0) + 1,\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 peers,\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 shell,\n pricingOverrides: Object.keys(pricing.overrides).length > 0 ? pricing.overrides : undefined,\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, { operator: auth.isOperator(authCtx) })\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 profiles.seedStore()\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 releaseSession: (id) => {\n const runner = registry.get(id)\n if (!runner) {\n return undefined\n }\n const plan = reloadPlan(runner)\n if (plan !== 'carry') {\n throw new Error(`session ${id} cannot be carried by identity (${plan})`)\n }\n const config = parking.release(id)\n registry.evict(id)\n return { runner, config }\n },\n adoptSession: ({ runner, config }) => {\n // Re-checked here, not only at release: a runner held across a failed generation may have ended in the\n // meantime, and adopting a dead one would list a session nothing can answer.\n if (reloadPlan(runner) !== 'carry') {\n return false\n }\n parking.adopt(runner, config)\n registry.retain(runner.id, factory.watchAuthSource(runner))\n return true\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 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 shell?.killAll()\n // `wss` is `noServer`, so `wss.close()` only waits for `clients` to empty, and `server.closeAllConnections()`\n // never reaches an upgraded socket: close every client ourselves, then terminate what has not acknowledged.\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 const deadline = setTimeout(() => resolve(), CLOSE_DEADLINE_MS)\n deadline.unref()\n const drained = Promise.all([\n new Promise<void>((done) => wss.close(() => done())),\n new Promise<void>((done) => server.close(() => done())),\n ])\n server.closeAllConnections()\n void drained.then(() => {\n clearTimeout(force)\n clearTimeout(deadline)\n resolve()\n })\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 | null\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: config.defaultApprovalTimeoutMs === undefined ? options.approvalTimeoutMs : config.defaultApprovalTimeoutMs,\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","osConstants","profiles"],"sources":["../src/lib/http.ts","../src/lib/profile-env.ts","../src/lib/parse-route.ts","../src/lib/reload-plan.ts","../src/routes/executions.ts","../src/services/host-files.ts","../src/services/host-file-search.ts","../src/routes/fs.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/services/shell.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/spend-ledger.ts","../src/services/peers.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 codexHomeDir(env: Record<string, string | undefined>): string {\n return env.CODEX_HOME ?? join(homedir(), '.codex')\n}\n\n// Detection is by credential directory, not by binary: a directory that exists is one the operator\n// has already logged into, and a profile pointing at an engine that is not installed reports itself\n// unavailable rather than failing at session start.\nexport function detectDefaultProfiles(env: Record<string, string | undefined> = process.env): ProfileInfo[] {\n const detected: ProfileInfo[] = []\n const claude = cliConfigDir(env)\n if (existsSync(claude)) {\n detected.push({ name: 'default', configDir: claude })\n }\n const codex = codexHomeDir(env)\n if (existsSync(codex)) {\n detected.push({ name: 'codex', engine: 'codex', codexHome: codex })\n }\n return detected\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 { Runner } from '@workerdeck/core'\nimport { isJobRun } from '@workerdeck/protocol'\n\n// What a hot reload may do with a live session. `carry` hands the runner object itself to the next generation,\n// which is the only way an engine child process, its subagents and its shell grandchildren survive; `persist` is\n// the ordinary restart story through the store; `drop` lets the session end with the generation.\nexport type ReloadPlan = 'carry' | 'persist' | 'drop'\n\nexport function reloadPlan(runner: Runner): ReloadPlan {\n const info = runner.info()\n if (info.status === 'closed' || info.status === 'failed') {\n return 'drop'\n }\n // The queue owns a job's session: a carried one would be a row nothing will ever finalize.\n if (isJobRun(info)) {\n return 'drop'\n }\n // Keyed on the capability, never on the engine name: \"can this session persist itself\" is the actual question,\n // and a runner that can snapshot has in-process executors closed over this generation's bridge hub, which after\n // the swap has no sockets. Carrying one does not orphan a call in flight, it breaks every later bridged call.\n if (runner.snapshot !== undefined) {\n return 'persist'\n }\n return 'carry'\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 { pickCreateSessionRequest, type CreateSessionRequest } from '@workerdeck/protocol'\nimport type { AiSdkRunnerConfig, CodexRunnerConfig, SessionRunnerConfig } from '@workerdeck/core'\nimport type { ServerContext } from '../context.ts'\nimport type { AuthContext } from '../services/auth.ts'\n\ntype HostOnlyKey = Exclude<keyof SessionRunnerConfig | keyof CodexRunnerConfig | keyof AiSdkRunnerConfig, keyof CreateSessionRequest>\n\n// Every runner-config key that is not on the wire type. Typed as a record over that difference so a\n// host-only field added to any engine's config without an entry here fails typecheck, as does an\n// entry that has since been promoted onto CreateSessionRequest.\nconst HOST_ONLY_KEY_SET: Record<HostOnlyKey, true> = {\n epoch: true,\n queryFn: true,\n env: true,\n pathToClaudeCodeExecutable: true,\n extraOptions: true,\n instructions: true,\n defaultApprovalTimeoutMs: true,\n backfillHistory: true,\n historyFn: true,\n sessionInfoFn: true,\n peers: true,\n connectFn: true,\n codexHome: true,\n codexPathOverride: true,\n languageModel: true,\n tools: true,\n maxSteps: true,\n executor: true,\n executableTools: true,\n vfs: true,\n executionLimits: true,\n executionBackend: true,\n toolTitles: true,\n shouldApprove: true,\n resolveModel: true,\n reportMcpServers: true,\n onClose: true,\n restore: true,\n}\n\nexport const HOST_ONLY_KEYS: ReadonlySet<string> = new Set(Object.keys(HOST_ONLY_KEY_SET))\n\nexport type VettedCreateRequest = { ok: true; request: CreateSessionRequest } | { ok: false; status: number; error: string }\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. The body is untrusted JSON: it is projected onto the wire type, never cast to it, and\n// the projected object is what the ladder mutates (inert fields stripped, profile name pinned)\n// and what the caller must hand on.\nexport function vetCreateRequest(ctx: ServerContext, body: unknown, auth: AuthContext): VettedCreateRequest {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) {\n return { ok: false, status: 400, error: 'request body must be a JSON object' }\n }\n const hostOnly = Object.keys(body).filter((key) => HOST_ONLY_KEYS.has(key))\n if (hostOnly.length > 0) {\n return {\n ok: false,\n status: 400,\n error:\n `host-only runner config is not accepted on a session request: ${hostOnly.join(', ')} ` +\n \"(set it from the gateway's buildRunnerConfig hook)\",\n }\n }\n const req = pickCreateSessionRequest(body as Record<string, unknown>)\n const { availability, factory } = ctx\n const refusedScope = factory.applyScope(req, auth)\n if (refusedScope) {\n return { ok: false, ...refusedScope }\n }\n const refused = factory.applyBypassPolicy(req)\n if (refused) {\n return { ok: false, status: 403, error: refused }\n }\n const resolved = factory.resolveProfile(req.profile, auth.allowedProfiles)\n if (!resolved.ok) {\n return { ok: false, status: resolved.status, error: resolved.error }\n }\n const unavailable = availability.checkAvailable(resolved.profile)\n if (unavailable) {\n return { ok: false, ...unavailable }\n }\n const refusedCwd = factory.checkCwd(req, resolved.profile)\n if (refusedCwd) {\n return { ok: false, ...refusedCwd }\n }\n const badRequest = factory.checkPermissionMode(req.permissionMode, resolved.profile) ?? factory.checkEngineGrants(req, resolved.profile)\n if (badRequest) {\n return { ok: false, status: 400, error: badRequest }\n }\n factory.stripInertFields(req, resolved.profile)\n req.profile = resolved.profile?.name\n return { ok: true, request: req }\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 | null\n if (!body?.session || typeof body.session !== 'object') {\n json(res, 400, { error: 'session is required' })\n return\n }\n const prompt = body.session.prompt\n if (!prompt || typeof prompt !== 'string') {\n json(res, 400, { error: 'session.prompt is required' })\n return\n }\n const vetted = vetCreateRequest(ctx, body.session, auth)\n if (!vetted.ok) {\n json(res, vetted.status, { error: vetted.error })\n return\n }\n try {\n // The projected block is what gets stored: the queue spreads the record's session into a runner config later.\n json(res, 201, { job: await queue.submit({ ...body, session: { ...vetted.request, prompt } }) })\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 { CostLedgerState, 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 cost?: CostLedgerState\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 cost?: CostLedgerState\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', 'peers', 'instructions'] 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]+)*$/\nconst SHORTCODE_RE = /^[A-Z0-9]{2,5}$/\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; shortcode?: 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 const shortcode = classifyShortcode(raw.shortcode)\n return {\n project: { name, root, ...(icon ? { icon: icon.wire } : {}), ...(shortcode ? { shortcode } : {}) },\n ...(icon?.resolved ? { icon: icon.resolved } : {}),\n }\n}\n\nfunction classifyShortcode(value: unknown): string | undefined {\n return typeof value === 'string' && SHORTCODE_RE.test(value) ? value : undefined\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 { 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 vetted = vetCreateRequest(ctx, await readJsonBody(req, ctx.maxBodyBytes), auth)\n if (!vetted.ok) {\n json(res, vetted.status, { error: vetted.error })\n return\n }\n const runner = await factory.createRunner(factory.buildRunnerConfig(vetted.request))\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 const decision: ResolvePermissionRequest =\n body.behavior === 'allow'\n ? { behavior: 'allow', updatedInput: body.updatedInput }\n : { behavior: 'deny', message: body.message, interrupt: body.interrupt }\n if (!runner.resolvePermission(route.permissionId, decision)) {\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 { spawn } from 'node:child_process'\nimport { constants as osConstants } from 'node:os'\nimport type { Runner } from '@workerdeck/core'\nimport { ENGINE_CAPABILITIES } from '@workerdeck/protocol'\n\nexport const SHELL_DEFAULT_TIMEOUT_MS = 120_000\nexport const SHELL_DEFAULT_MAX_OUTPUT_BYTES = 32 * 1024\nconst TIMEOUT_EXIT_CODE = 124\nconst SPAWN_FAILURE_EXIT_CODE = 127\nconst KILLED_EXIT_CODE = 128 + osConstants.signals.SIGKILL\n\nexport type ShellServiceOptions = {\n timeoutMs?: number\n maxOutputBytes?: number\n}\n\nexport type ShellRunResult = {\n command: string\n stdout: string\n stderr: string\n exitCode: number\n durationMs: number\n}\n\nexport type ShellChild = {\n result: Promise<ShellRunResult>\n kill: (reason: string) => void\n}\n\nexport type ShellService = ReturnType<typeof createShellService>\n\nexport function shellPermitted(shell: ShellService | null, runner: Runner, operator: boolean): boolean {\n if (shell === null || !operator) {\n return false\n }\n const info = runner.info()\n const capabilities = info.capabilities ?? (info.engine ? ENGINE_CAPABILITIES[info.engine] : undefined)\n return capabilities?.hostCwd === true\n}\n\n// A spawn env replaces the inherited one wholesale, so the copy has to be complete; the gateway's own environment is\n// what the operator's terminal would have given the same command.\nexport function shellChildEnv(base: Record<string, string | undefined>): Record<string, string> {\n const env: Record<string, string> = {}\n for (const [key, value] of Object.entries(base)) {\n if (value !== undefined) {\n env[key] = value\n }\n }\n return env\n}\n\nexport function createShellService(options: ShellServiceOptions = {}) {\n const timeoutMs = options.timeoutMs ?? SHELL_DEFAULT_TIMEOUT_MS\n const maxOutputBytes = options.maxOutputBytes ?? SHELL_DEFAULT_MAX_OUTPUT_BYTES\n const active = new Map<string, ShellChild>()\n\n const run = async (sessionId: string, cwd: string, command: string): Promise<ShellRunResult> => {\n if (active.has(sessionId)) {\n throw new Error('a shell command is still running on this session')\n }\n const child = spawnShell({ command, cwd, env: shellChildEnv(process.env), timeoutMs, maxOutputBytes })\n active.set(sessionId, child)\n try {\n return await child.result\n } finally {\n if (active.get(sessionId) === child) {\n active.delete(sessionId)\n }\n }\n }\n\n const kill = (sessionId: string, reason = 'session closed'): void => {\n active.get(sessionId)?.kill(reason)\n }\n\n const watch = (runner: Runner): (() => void) =>\n runner.subscribe((event) => {\n if (event.type === 'session_closed') {\n kill(runner.id, 'session closed')\n } else if (event.type === 'status_changed' && event.status === 'parked') {\n kill(runner.id, 'session parked')\n }\n }, runner.info().lastSeq)\n\n const killAll = (): void => {\n for (const sessionId of active.keys()) {\n kill(sessionId, 'server shutting down')\n }\n }\n\n const running = (sessionId: string): boolean => active.has(sessionId)\n\n return { run, kill, watch, killAll, running, timeoutMs, maxOutputBytes }\n}\n\ntype SpawnShellInput = {\n command: string\n cwd: string\n env: Record<string, string>\n timeoutMs: number\n maxOutputBytes: number\n}\n\nclass BoundedOutput {\n #chunks: Buffer[] = []\n #kept = 0\n #dropped = 0\n #budget: { remaining: number }\n\n constructor(budget: { remaining: number }) {\n this.#budget = budget\n }\n\n push(chunk: Buffer): void {\n const take = Math.min(chunk.length, this.#budget.remaining)\n if (take > 0) {\n this.#chunks.push(take === chunk.length ? chunk : chunk.subarray(0, take))\n this.#kept += take\n this.#budget.remaining -= take\n }\n this.#dropped += chunk.length - take\n }\n\n text(): string {\n const head = Buffer.concat(this.#chunks, this.#kept).toString('utf8')\n return this.#dropped > 0 ? `${head}\\n[output truncated: ${this.#dropped} more bytes dropped]` : head\n }\n}\n\nexport function spawnShell(input: SpawnShellInput): ShellChild {\n const startedAt = Date.now()\n const budget = { remaining: input.maxOutputBytes }\n const stdout = new BoundedOutput(budget)\n const stderr = new BoundedOutput(budget)\n let settle: ((result: ShellRunResult) => void) | undefined\n const result = new Promise<ShellRunResult>((resolve) => {\n settle = resolve\n })\n let done = false\n const finish = (exitCode: number, note?: string): void => {\n if (done) {\n return\n }\n done = true\n clearTimeout(timer)\n const captured = stderr.text()\n const stderrText = note ? (captured ? `${captured}\\n[${note}]` : `[${note}]`) : captured\n settle?.({ command: input.command, stdout: stdout.text(), stderr: stderrText, exitCode, durationMs: Date.now() - startedAt })\n }\n\n // The child leads its own process group so a kill reaches the pipeline it started, not just the shell.\n const child = spawn('/bin/sh', ['-c', input.command], {\n cwd: input.cwd,\n env: { ...input.env, PWD: input.cwd },\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true,\n })\n child.stdout.on('data', (chunk: Buffer) => stdout.push(chunk))\n child.stderr.on('data', (chunk: Buffer) => stderr.push(chunk))\n\n const killGroup = (): void => {\n if (child.pid === undefined) {\n return\n }\n try {\n process.kill(-child.pid, 'SIGKILL')\n } catch {\n try {\n child.kill('SIGKILL')\n } catch {}\n }\n child.stdout.destroy()\n child.stderr.destroy()\n }\n const kill = (reason: string, exitCode = KILLED_EXIT_CODE): void => {\n if (done) {\n return\n }\n killGroup()\n finish(exitCode, `killed: ${reason}`)\n }\n\n const timer = setTimeout(() => kill(`timed out after ${Math.round(input.timeoutMs / 1000)}s`, TIMEOUT_EXIT_CODE), input.timeoutMs)\n child.on('error', (error) => finish(SPAWN_FAILURE_EXIT_CODE, error.message))\n child.on('close', (code, signal) => {\n const signalCode = signal ? (osConstants.signals[signal] ?? 0) : 0\n finish(code ?? (signalCode ? 128 + signalCode : 1), signal ? `killed by ${signal}` : undefined)\n })\n\n return { result, kill: (reason) => kill(reason) }\n}\n","import type { IncomingMessage } from 'node:http'\nimport type { WebSocket } from 'ws'\nimport { isSlashCommand, type Runner } from '@workerdeck/core'\nimport { PROTOCOL_VERSION, SHELL_COMMAND_MAX, type ClientFrame, type ServerFrame } from '@workerdeck/protocol'\nimport type { ServerContext } from '../context.ts'\nimport { shellPermitted } from '../services/shell.ts'\n\n// What the upgrade established about the principal; computed once there so the attach never re-authenticates.\nexport type AttachAccess = { operator: boolean }\n\nexport function attachClient(ctx: ServerContext, ws: WebSocket, runner: Runner, req: IncomingMessage, access: AttachAccess): 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 ...(shellPermitted(ctx.shell, runner, access.operator) ? { shell: true } : {}),\n ...(ctx.pricingOverrides ? { pricingOverrides: ctx.pricingOverrides } : {}),\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 // After the replay is wired, so a fresh reading arrives as a live event behind the history rather than racing it.\n // The replay faithfully re-installs whatever this session last heard, which on an idle session can be days old,\n // and until now nothing in an attach asked for a newer one. Throttled inside the runner; failures are silent by\n // design (the control request is experimental, and a missing usage reading is not an attach failure).\n void runner.refreshUsage?.().catch(() => {})\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, access).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, access: AttachAccess): Promise<void> {\n const { attachmentStore, bridge } = ctx\n switch (frame.type) {\n case 'user_message': {\n // The one place `mentions` is ever set: this frame is a person typing. A slash command is\n // matched on the whole message by the CLI, so nothing may be appended to one, and a failure\n // to resolve is silent - a hint must never lose the text it was a hint about.\n const mentions = ctx.peers && !isSlashCommand(frame.text) ? await ctx.peers.mentions(runner.id, frame.text).catch(() => []) : []\n const options = mentions.length > 0 ? { mentions } : undefined\n if (!frame.attachmentIds?.length) {\n runner.sendMessage(frame.text, undefined, options)\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, options)\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 'shell_command': {\n if (!shellPermitted(ctx.shell, runner, access.operator) || ctx.shell === null) {\n throw new Error('shell commands are not available on this session')\n }\n if (typeof frame.command !== 'string' || frame.command.includes('\\0')) {\n throw new Error('shell command must be a string')\n }\n if (frame.command.length > SHELL_COMMAND_MAX) {\n throw new Error(`shell command exceeds ${SHELL_COMMAND_MAX} characters`)\n }\n if (frame.command.trim() === '') {\n throw new Error('shell command is empty')\n }\n if (!runner.queueLocalCommand) {\n throw new Error(`the ${runner.info().engine ?? 'claude'} engine cannot take shell output`)\n }\n const result = await ctx.shell.run(runner.id, runner.info().cwd, frame.command)\n runner.queueLocalCommand(result)\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 return 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 #watches = new Map<string, () => 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 // The unsubscribe is retained, not merely returned. Every caller drops it, and `#track` has neither the `#closed`\n // guard the writers have nor an ownership check: a deferred dispatch reaching a closed manager still arms a\n // watchdog, and when that fires it rebuilds the session through the registry and factory of a generation that is\n // over. `release()` is the only thing that can take the listener off a runner nobody closed.\n watch(runner: Runner, afterSeq = 0): () => void {\n this.#watches.get(runner.id)?.()\n const unsubscribe = 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 const detach = (): void => {\n if (this.#watches.get(runner.id) === detach) {\n this.#watches.delete(runner.id)\n }\n unsubscribe()\n }\n this.#watches.set(runner.id, detach)\n return detach\n }\n\n // Hands a live session to another manager: stops watching it, forgets what this manager knows about it, and\n // returns the one fact the next manager cannot rederive. A durable record strips `env`, `queryFn`, `historyFn`\n // and `extraOptions`, and before `system_init` there is no record at all, so `#configs` is not recoverable from\n // the store. Deliberately leaves the store alone: the record is the point of the handover, not a casualty of it.\n release(sessionId: string): SessionRunnerConfig | undefined {\n this.#watches.get(sessionId)?.()\n this.#watches.delete(sessionId)\n clearTimeout(this.#detachTimers.get(sessionId))\n this.#detachTimers.delete(sessionId)\n const config = this.#configs.get(sessionId)\n this.#configs.delete(sessionId)\n this.#remembered.delete(sessionId)\n return config\n }\n\n // The order is what `#rememberDormant`'s ownership guard turns into a silent no-write if reversed: `touch()`\n // writes nothing for a runner this manager's registry does not hold, so the register comes first. `#rebuild` does\n // the same four steps for the same reason. `lastSeq`, never 0: replaying a long session's history queues one\n // dormant re-save per historical `status_changed`, and the single `touch()` is what writes the current record.\n adopt(runner: Runner, config?: SessionRunnerConfig): void {\n this.#options.registry.register(runner)\n if (config) {\n this.remember(runner.id, config)\n }\n this.watch(runner, runner.info().lastSeq)\n this.touch(runner)\n }\n\n // `touch()` is fire-and-forget for the PATCH route that has no one to report to. A caller that is about to close\n // this manager, or to let another one write the same files, needs to know the write landed.\n async flush(sessionId?: string): Promise<void> {\n if (sessionId === undefined) {\n await Promise.all(this.#storeOps.values())\n return\n }\n await this.#storeOps.get(sessionId)\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 // Dropped rather than run: `discard` is reached from the `session_closed` arm of the very subscription this\n // handle unsubscribes, and the runner drops its subscribers on close anyway.\n this.#watches.delete(sessionId)\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 cost: runner.costState?.(),\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 cost: runner.costState?.(),\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 cost = runner.costState?.()\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 cost,\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 runner.carryCost?.(record.cost ?? { byModel: record.info.usageByModel, reportedCostUsd: record.info.totalCostUsd })\n this.#options.registry.register(runner)\n // The config the runner was actually built with, not the one on the record: a dormant wake\n // bumps the epoch, and the next park must carry the new one rather than resurrect the old.\n this.remember(id, { ...record.config, epoch: runner.info().epoch })\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 return 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 seed?: 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 spend?: (name: string) => ProfileInfo['spend'] | 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 } 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 // Auto-detected profiles land in the store, not in `declared`, so the first thing an operator sees\n // is a profile they can rename, retarget or delete. Seeding only an empty store is what keeps it a\n // first-launch act: once a profile exists, detection never writes again.\n async seedStore(): Promise<void> {\n const seed = this.#opts.seed ?? []\n if (!this.#opts.store || seed.length === 0 || this.#stored.size > 0) {\n return\n }\n for (const p of seed) {\n if (this.validate(p) === null) {\n await this.#opts.store.save(p)\n }\n }\n await this.refreshStored()\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 const spend = decorate.spend?.(p.name)\n if (spend) {\n base.spend = spend\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 codex = engineOf(profile) === 'codex'\n const dir = codex ? profile.codexHome : profile.configDir\n // A codex profile that names no CODEX_HOME runs on the server's own environment, which every\n // session already inherits - there is no separate credential store for the roots to bound.\n if (codex && !dir) {\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 and Codex profiles are disabled: set `allowedConfigDirRoots` to the ' + 'directories they may point at',\n }\n }\n return dir && cwdAllowed(dir, roots)\n ? null\n : { status: 403, error: `${codex ? 'codexHome' : '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 return 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 { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { Runner } from '@workerdeck/core'\nimport { type ByModel, type ProfileSpend, costOfByModel, mergeByModel, subscriptionComparison } from '@workerdeck/protocol'\n\nexport type SpendRecord = { days: Record<string, Record<string, ByModel>> }\n\nexport type SpendStore = {\n load(): Promise<SpendRecord | undefined>\n save(record: SpendRecord): Promise<void>\n}\n\nexport type SpendLedgerOptions = {\n store?: SpendStore\n monthlySubscriptionUsd?: (profile: string) => number | undefined\n retentionDays?: number\n saveDebounceMs?: number\n onError?: (error: unknown) => void\n}\n\nconst DEFAULT_RETENTION_DAYS = 92\n\nconst DEFAULT_SAVE_DEBOUNCE_MS = 2_000\n\nexport function dayKey(at: number): string {\n const d = new Date(at)\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nfunction daysBack(now: number, count: number): string[] {\n const out: string[] = []\n for (let i = 0; i < count; i += 1) {\n out.push(dayKey(now - i * 86_400_000))\n }\n return out\n}\n\nfunction subtract(current: ByModel, previous: ByModel): ByModel {\n const delta: ByModel = {}\n for (const [model, usage] of Object.entries(current)) {\n const was = previous[model]\n const row = {\n input: usage.input - (was?.input ?? 0),\n output: usage.output - (was?.output ?? 0),\n cacheWrite5m: usage.cacheWrite5m - (was?.cacheWrite5m ?? 0),\n cacheWrite1h: usage.cacheWrite1h - (was?.cacheWrite1h ?? 0),\n cacheRead: usage.cacheRead - (was?.cacheRead ?? 0),\n }\n // A negative delta means the session's cumulative figure went backwards, which only happens when the reading\n // we diffed against was not this session's. Recording nothing beats recording a negative day.\n if (Object.values(row).some((value) => value < 0)) {\n continue\n }\n if (Object.values(row).some((value) => value > 0)) {\n delta[model] = row\n }\n }\n return delta\n}\n\n// `turn_result.usageByModel` is session-cumulative, so the ledger records the difference from what this session\n// last contributed. The baseline is seeded from the runner's own info at watch time, which is what keeps a woken\n// session's carried spend from being banked a second time as if it had just been earned.\nexport class SpendLedger {\n #days: Record<string, Record<string, ByModel>> = {}\n #lastBanked = new Map<string, ByModel>()\n #options: SpendLedgerOptions\n #saveTimer: ReturnType<typeof setTimeout> | undefined\n #loaded: Promise<void> | undefined\n\n constructor(options: SpendLedgerOptions = {}) {\n this.#options = options\n }\n\n load(): Promise<void> {\n this.#loaded ??= this.#load()\n return this.#loaded\n }\n\n async #load(): Promise<void> {\n const store = this.#options.store\n if (!store) {\n return\n }\n try {\n const record = await store.load()\n if (record?.days) {\n this.#days = record.days\n }\n } catch (error) {\n this.#options.onError?.(error)\n }\n }\n\n watch(runner: Runner): () => void {\n const info = runner.info()\n const profile = info.profile\n if (!profile) {\n return () => {}\n }\n this.#lastBanked.set(runner.id, info.usageByModel ?? {})\n const unsubscribe = runner.subscribe((event) => {\n if (event.type !== 'turn_result' || !event.usageByModel) {\n return\n }\n this.#bank(profile, event.usageByModel, runner.id, event.ts)\n })\n return () => {\n unsubscribe()\n this.#lastBanked.delete(runner.id)\n }\n }\n\n #bank(profile: string, cumulative: ByModel, sessionId: string, at: number): void {\n const previous = this.#lastBanked.get(sessionId) ?? {}\n const delta = subtract(cumulative, previous)\n this.#lastBanked.set(sessionId, cumulative)\n if (Object.keys(delta).length === 0) {\n return\n }\n const key = dayKey(at)\n const day = (this.#days[key] ??= {})\n day[profile] = mergeByModel(day[profile] ?? {}, delta)\n this.#scheduleSave()\n }\n\n spend(profile: string, now = Date.now()): ProfileSpend | undefined {\n const week = this.#window(profile, daysBack(now, 7))\n const month = this.#window(profile, daysBack(now, 30))\n if (Object.keys(month).length === 0) {\n return undefined\n }\n const weekCost = costOfByModel(week)\n const monthlySubscriptionUsd = this.#options.monthlySubscriptionUsd?.(profile)\n return {\n weekUsd: weekCost.total,\n monthUsd: costOfByModel(month).total,\n weekByModel: week,\n unpricedShare: weekCost.unpricedShare,\n monthlySubscriptionUsd,\n subscription: monthlySubscriptionUsd ? subscriptionComparison(weekCost.total, monthlySubscriptionUsd) : undefined,\n }\n }\n\n #window(profile: string, keys: string[]): ByModel {\n let out: ByModel = {}\n for (const key of keys) {\n const day = this.#days[key]?.[profile]\n if (day) {\n out = mergeByModel(out, day)\n }\n }\n return out\n }\n\n #scheduleSave(): void {\n if (!this.#options.store || this.#saveTimer) {\n return\n }\n this.#saveTimer = setTimeout(() => {\n this.#saveTimer = undefined\n void this.flush()\n }, this.#options.saveDebounceMs ?? DEFAULT_SAVE_DEBOUNCE_MS)\n this.#saveTimer.unref?.()\n }\n\n async flush(): Promise<void> {\n const store = this.#options.store\n if (!store) {\n return\n }\n this.#prune()\n try {\n await store.save({ days: this.#days })\n } catch (error) {\n this.#options.onError?.(error)\n }\n }\n\n #prune(): void {\n const keep = new Set(daysBack(Date.now(), this.#options.retentionDays ?? DEFAULT_RETENTION_DAYS))\n for (const key of Object.keys(this.#days)) {\n if (!keep.has(key)) {\n delete this.#days[key]\n }\n }\n }\n\n close(): void {\n clearTimeout(this.#saveTimer)\n this.#saveTimer = undefined\n }\n}\n\nexport function createFileSpendStore(path: string, onError?: (error: unknown) => void): SpendStore {\n return {\n async load() {\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as unknown\n if (parsed === null || typeof parsed !== 'object' || typeof (parsed as SpendRecord).days !== 'object') {\n return undefined\n }\n return parsed as SpendRecord\n } catch {\n return undefined\n }\n },\n async save(record) {\n try {\n await mkdir(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.tmp`\n await writeFile(temp, JSON.stringify(record))\n await rename(temp, path)\n } catch (error) {\n onError?.(error)\n }\n },\n }\n}\n","import {\n PEER_MESSAGE_MAX_CHARS,\n PEER_RECENT_DEFAULT,\n PEER_RECENT_MAX,\n peerSummary,\n recentLines,\n type PeerDirectory,\n type PeerPeek,\n type PeerSendOptions,\n type PeerSendResult,\n type PeerMention,\n type PeerSessionSummary,\n type Runner,\n} from '@workerdeck/core'\nimport {\n PEER_MENTION_MAX,\n peerMentionKey,\n peerMentionSlug,\n scanPeerMentions,\n type MessageOrigin,\n type SessionEvent,\n type SessionInfo,\n} from '@workerdeck/protocol'\nimport { scopeMatches } from '../lib/scope.ts'\nimport type { LateBoundRefs } from '../options.ts'\nimport type { ProjectInfoService } from './project-info.ts'\nimport type { SessionRegistry } from './registry.ts'\n\nexport type PeerServiceOptions = {\n enabled?: boolean\n maxMessageChars?: number\n perMinute?: number\n maxHops?: number\n}\n\nexport type PeerServiceDeps = {\n refs: LateBoundRefs\n projects: ProjectInfoService\n options?: PeerServiceOptions\n}\n\nconst DEFAULT_PER_MINUTE = 10\nconst DEFAULT_MAX_HOPS = 12\nconst WINDOW_MS = 60_000\n\nfunction visible(from: SessionInfo, to: SessionInfo): boolean {\n return to.id !== from.id && scopeMatches(from.scope, to.scope)\n}\n\nexport type PeerService = PeerDirectory & {\n watch(runner: Runner): () => void\n // The `#Name` tokens in a message a person typed, resolved to the peers that session can see.\n mentions(from: string, text: string): Promise<PeerMention[]>\n}\n\n// Session-to-session messaging inside one gateway. Visibility is the session-scope rule the HTTP routes enforce,\n// applied with the *sender's* scope as the principal: a scoped session sees the sessions a scoped client would.\nexport function createPeerService(deps: PeerServiceDeps): PeerService {\n const perMinute = deps.options?.perMinute ?? DEFAULT_PER_MINUTE\n const maxChars = deps.options?.maxMessageChars ?? PEER_MESSAGE_MAX_CHARS\n const maxHops = deps.options?.maxHops ?? DEFAULT_MAX_HOPS\n const sent = new Map<string, number[]>()\n // The chain of sessions that led to the last peer message each session received, cleared when a human speaks to\n // it: two agents answering each other without a person in the loop is the loop this bounds.\n const inbound = new Map<string, string[]>()\n\n const registry = (): SessionRegistry => {\n const found = deps.refs.registry\n if (!found) {\n throw new Error('peer messaging is not ready')\n }\n return found\n }\n\n const allSessions = async (): Promise<SessionInfo[]> => {\n const live = registry().list()\n const dormant = (await deps.refs.parking?.listInfo()) ?? []\n return [...live, ...dormant].map((info) => deps.projects.withProject(info))\n }\n\n const infoOf = async (id: string): Promise<SessionInfo | undefined> => {\n const live = registry().get(id)?.info()\n if (live) {\n return deps.projects.withProject(live)\n }\n const record = await deps.refs.parking?.get(id)\n return record ? deps.projects.withProject(record.info) : undefined\n }\n\n const sender = async (from: string): Promise<SessionInfo> => {\n const info = await infoOf(from)\n if (!info) {\n throw new Error(`unknown sender session: ${from}`)\n }\n return info\n }\n\n const underRateLimit = (from: string, to: string): boolean => {\n const key = `${from}->${to}`\n const now = Date.now()\n const recent = (sent.get(key) ?? []).filter((at) => now - at < WINDOW_MS)\n if (recent.length >= perMinute) {\n sent.set(key, recent)\n return false\n }\n recent.push(now)\n sent.set(key, recent)\n return true\n }\n\n const list = async (from: string): Promise<PeerSessionSummary[]> => {\n const me = await sender(from)\n return (await allSessions())\n .filter((info) => visible(me, info))\n .sort((a, b) => (b.lastActivityAt ?? b.createdAt) - (a.lastActivityAt ?? a.createdAt))\n .map(peerSummary)\n }\n\n const peek = async (from: string, sessionId: string, options?: { recent?: number }): Promise<PeerPeek | undefined> => {\n const me = await sender(from)\n const info = await infoOf(sessionId)\n if (!info || !visible(me, info)) {\n return undefined\n }\n const limit = Math.min(Math.max(options?.recent ?? PEER_RECENT_DEFAULT, 0), PEER_RECENT_MAX)\n const runner = registry().get(sessionId)\n const events: SessionEvent[] = []\n if (runner && limit > 0) {\n runner.subscribe((event) => events.push(event), 0, { truncateResults: true, imageRefs: true })()\n }\n return {\n ...peerSummary(info),\n live: runner !== undefined,\n checklist: info.checklist,\n pendingApprovals: runner ? runner.pendingApprovals.map((request) => request.title ?? request.toolName) : [],\n recent: recentLines(events, limit),\n }\n }\n\n const send = async (from: string, sessionId: string, text: string, options?: PeerSendOptions): Promise<PeerSendResult> => {\n const me = await sender(from)\n if (sessionId === from) {\n return { delivered: false, reason: 'that is this session' }\n }\n if (text.length > maxChars) {\n return {\n delivered: false,\n reason: `message is ${text.length} characters; the limit is ${maxChars}. Write it to a file and send the path.`,\n }\n }\n const target = await infoOf(sessionId)\n if (!target || !visible(me, target)) {\n return { delivered: false, reason: `no such session: ${sessionId}` }\n }\n if (target.status === 'closed' || target.status === 'failed') {\n return { delivered: false, reason: `session ${sessionId} is ${target.status}` }\n }\n const hops = [...(options?.hops ?? inbound.get(from) ?? []), from]\n if (hops.length > maxHops) {\n return {\n delivered: false,\n reason: `${hops.length} messages have passed between sessions without a person speaking; stop and ask your user before continuing.`,\n }\n }\n if (!underRateLimit(from, sessionId)) {\n return { delivered: false, reason: `rate limit: at most ${perMinute} messages a minute to one session. Batch what you have to say.` }\n }\n const runner = (await deps.refs.parking?.ensureLive(sessionId)) ?? registry().get(sessionId)\n if (!runner) {\n return { delivered: false, reason: `session ${sessionId} could not be woken` }\n }\n const before = runner.info().status\n const origin: MessageOrigin = { kind: 'peer', sessionId: from, name: me.title, engine: me.engine, hops }\n try {\n runner.sendMessage(text, undefined, { origin })\n } catch (error) {\n return { delivered: false, reason: error instanceof Error ? error.message : String(error) }\n }\n inbound.set(sessionId, hops)\n return { delivered: true, sessionId, name: target.title, queued: before === 'running' || before === 'awaiting_approval' }\n }\n\n // A session id is a handle a person may paste, so a full id and an unambiguous prefix resolve too.\n const mentions = async (from: string, text: string): Promise<PeerMention[]> => {\n const tokens = scanPeerMentions(text)\n if (tokens.length === 0) {\n return []\n }\n const rows = await list(from)\n const byKey = new Map<string, PeerSessionSummary[]>()\n const add = (key: string, row: PeerSessionSummary) => {\n const held = byKey.get(key)\n if (held) {\n held.push(row)\n } else {\n byKey.set(key, [row])\n }\n }\n for (const row of rows) {\n add(peerMentionKey(peerMentionSlug(row.title, row.id)), row)\n add(peerMentionKey(row.id), row)\n }\n const resolved: PeerMention[] = []\n const seen = new Set<string>()\n for (const token of tokens) {\n const key = peerMentionKey(token.body)\n const exact = byKey.get(key)\n // `list` is newest-first, so a shared title resolves to the session that moved last and the\n // envelope names the others rather than choosing silently.\n const matches = exact ?? (key.length >= 4 ? rows.filter((row) => row.id.startsWith(key)) : [])\n const target = matches[0]\n if (!target || (matches.length > 1 && !exact)) {\n continue\n }\n if (seen.has(target.id)) {\n continue\n }\n seen.add(target.id)\n const others = matches.slice(1, 4).map((row) => row.id)\n resolved.push({\n typed: token.body,\n id: target.id,\n name: target.title,\n engine: target.engine,\n status: target.status,\n cwd: target.cwd,\n ...(others.length ? { ambiguousWith: others } : {}),\n })\n if (resolved.length >= PEER_MENTION_MAX) {\n break\n }\n }\n return resolved\n }\n\n const watch = (runner: Runner): (() => void) =>\n runner.subscribe((event) => {\n if (event.type === 'user_message' && !event.origin && !event.synthetic && event.parentToolUseId == null && !event.replay) {\n inbound.delete(runner.id)\n }\n }, runner.info().lastSeq)\n\n return { list, peek, send, mentions, watch }\n}\n","import { SessionRunner, type Runner, type SessionRunnerConfig } from '@workerdeck/core'\nimport type { SessionInfo } from '@workerdeck/protocol'\n\nexport type SessionRegistryOptions = {\n // A returned function is a detach: run when the runner leaves this registry, whether it was closed or handed to\n // another one. Typed `unknown` rather than `void | (() => void)` on purpose: TypeScript only forgives a\n // non-void return against a bare `void`, so the narrower union would break every embedder whose hook is a\n // one-expression arrow (`(r) => seen.push(r)`). The function check is at the retaining end instead.\n onRegister?: (runner: Runner) => unknown\n}\n\nexport class SessionRegistry {\n #sessions = new Map<string, Runner>()\n #options: SessionRegistryOptions\n #observers = new Set<(runner: Runner) => unknown>()\n // The watchers a registration attached, kept because the objects that attached them are exactly what a hot\n // reload discards: nobody else is in a position to take them off a runner that outlives its generation.\n #detachers = new Map<string, (() => void)[]>()\n\n constructor(options: SessionRegistryOptions = {}) {\n this.#options = options\n }\n\n // `onRegister` for a caller that only has the built server - an embedding host, or the CLI. Replays what is already\n // registered so a late observer cannot miss a session, which is the whole difference from reading the option.\n observe(listener: (runner: Runner) => unknown): () => void {\n this.#observers.add(listener)\n for (const runner of this.#sessions.values()) {\n this.#retain(runner.id, listener(runner))\n }\n return () => void this.#observers.delete(listener)\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.#retain(runner.id, this.#options.onRegister?.(runner))\n for (const listener of this.#observers) {\n this.#retain(runner.id, listener(runner))\n }\n }\n return runner\n }\n\n // For a watcher attached outside `onRegister` - `watchAuthSource` is the one in this package - that must still\n // come off when the runner leaves. Without it a released runner keeps a listener from a discarded generation.\n retain(id: string, detach: () => void): void {\n this.#retain(id, detach)\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 this.#detach(id)\n return this.#sessions.delete(id)\n }\n\n evict(id: string): boolean {\n this.#detach(id)\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 #retain(id: string, detach: unknown): void {\n if (typeof detach !== 'function') {\n return\n }\n const run = detach as () => void\n const existing = this.#detachers.get(id)\n if (existing) {\n existing.push(run)\n return\n }\n this.#detachers.set(id, [run])\n }\n\n #detach(id: string): void {\n for (const detach of this.#detachers.get(id) ?? []) {\n detach()\n }\n this.#detachers.delete(id)\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, PeerDirectory, 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 approvalTimeoutMs?: number | null\n requireApiKey?: boolean\n peers?: PeerDirectory\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 // The gateway's default reaches every engine through the config, so a runner rebuilt from a parked\n // record gets the same deadline policy as the one it replaces.\n const withApprovalDefault = (config: SessionRunnerConfig): SessionRunnerConfig =>\n deps.approvalTimeoutMs === undefined ? config : { ...config, defaultApprovalTimeoutMs: deps.approvalTimeoutMs }\n\n const buildRunnerConfig = (req: CreateSessionRequest): SessionRunnerConfig => {\n const profile = req.profile !== undefined ? profiles.get(req.profile) : undefined\n if (!profile) {\n return withApprovalDefault(withScope(deps.hostBuildRunnerConfig(req), req.scope))\n }\n const config = withApprovalDefault(\n 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 )\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 (built: SessionRunnerConfig, restore?: RunnerSnapshot, id?: string): Promise<Runner> => {\n // Applied here rather than in buildRunnerConfig so a parked record, which stores its config, gets it too.\n const config = deps.peers ? { ...built, peers: deps.peers } : built\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 capabilities = profile?.capabilities ?? adapterFor(profile?.engine).capabilities\n if (config.instructions !== undefined && capabilities.systemInstructions === false) {\n throw new Error(`the ${engineOf(profile)} engine cannot deliver system instructions`)\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 // One profile needs no naming, and neither does a set that still carries the auto-detected\n // `default` - otherwise choosing is the caller's, because a profile is a credential store.\n const effective = name ?? (all.length === 1 ? all[0]!.name : all.find((p) => p.name === 'default')?.name)\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 return 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, installPeerDirectory, peerDirectoryHandle } from '@workerdeck/core'\nimport type { EngineAdapter } from '@workerdeck/core'\nimport { JobQueue } from '@workerdeck/queue'\nimport {\n PROTOCOL_VERSION,\n sessionState,\n setPricingOverrides,\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 { reloadPlan } from './lib/reload-plan.ts'\nimport type { DrainReport, LateBoundRefs, WorkerServer, WorkerServerOptions } from './options.ts'\nimport { handleExecutionResult } from './routes/executions.ts'\nimport { handleHostFiles } from './routes/fs.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 { SpendLedger } from './services/spend-ledger.ts'\nimport { createPeerService } from './services/peers.ts'\nimport { ProjectInfoService } from './services/project-info.ts'\nimport { SessionRegistry } from './services/registry.ts'\nimport { createSessionFactory } from './services/session-factory.ts'\nimport { createShellService } from './services/shell.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// The outer bound on close(): it resolves by then whether or not the runtime ever reports the drains complete.\nconst CLOSE_DEADLINE_MS = 1_000\n\n// How old the account-level rate-limit reading may be before a profiles read asks a live session for a newer one.\n// Generous: the windows move over hours, and the point is to bound staleness at minutes rather than at days.\nconst USAGE_STALE_MS = 5 * 60_000\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.\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 pricing = setPricingOverrides(options.pricing?.overrides)\n if (pricing.dropped.length > 0) {\n console.warn(\n `[workerdeck] Ignoring pricing.overrides for ${pricing.dropped.join(', ')}: ` +\n 'each entry needs input, output, cacheWrite5m, cacheWrite1h and cacheRead in USD per million tokens',\n )\n }\n\n const profileDefaultModels = new Map<string, string>()\n const profileUsage = new ProfileUsageTracker()\n const spendLedger = new SpendLedger({\n store: options.spend?.store,\n monthlySubscriptionUsd: (name) => options.spend?.monthlySubscriptionUsd?.[name] ?? options.spend?.monthlySubscriptionUsd?.['*'],\n onError: (error) => options.spend?.onError?.(error),\n })\n void spendLedger.load()\n // The backstop behind the attach-time refresh, for the surface that reads the account number without opening a\n // session at all. Fire and forget: this request still answers with what is known, and the newer reading arrives\n // as a `rate_limit` event moments later. One session per profile is enough - the reading is account-level - and\n // the runner's own throttle is what keeps a page of profiles from becoming a page of control requests.\n const refreshStaleUsage = (name: string): void => {\n const held = profileUsage.usage(name)\n const newest = Math.max(0, ...Object.values(held ?? {}).map((window) => window.updatedAt ?? 0))\n if (Date.now() - newest < USAGE_STALE_MS) {\n return\n }\n for (const info of refs.registry?.list() ?? []) {\n if (info.profile !== name) {\n continue\n }\n const runner = refs.registry?.get(info.id)\n if (runner?.refreshUsage) {\n void runner.refreshUsage().catch(() => {})\n return\n }\n }\n }\n // With a store in play, detection seeds it on first launch instead of declaring anything: a\n // declared profile cannot be edited over the API, and an auto-detected one is exactly the profile\n // an operator most wants to rename or retarget.\n const detected = options.profiles ? [] : detectDefaultProfiles()\n const profiles = new ProfileService({\n declared: options.profiles ?? (options.profileStore ? [] : detected),\n seed: detected,\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) => {\n refreshStaleUsage(name)\n return profileUsage.usage(name)\n },\n spend: (name) => spendLedger.spend(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 projects = new ProjectInfoService()\n const peers = options.peers?.enabled === false ? undefined : createPeerService({ refs, projects, options: options.peers })\n if (peers) {\n installPeerDirectory(peers)\n }\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 approvalTimeoutMs: options.approvalTimeoutMs,\n requireApiKey: options.requireApiKey,\n peers: peers ? peerDirectoryHandle() : undefined,\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 notifier = new SessionNotifier({\n ...options.notifications,\n decorateInfo: (info) => projects.withProject(info),\n })\n const producedFiles = new ProducedFileStore()\n const shell = options.shell?.enabled === true ? createShellService(options.shell) : null\n const registry = new SessionRegistry({\n // Every watcher here hands back its detach, and the registry runs them when the runner leaves. A hot reload is\n // the case that needs it: the runner outlives this server, and these closures would otherwise keep delivering\n // webhooks and pushes from a generation that is over, one extra copy per reload.\n onRegister: (runner) => {\n const detachers = [\n notifier.watch(runner),\n producedFiles.watch(runner),\n profileUsage.watch(runner),\n spendLedger.watch(runner),\n shell?.watch(runner),\n peers?.watch(runner),\n ]\n const profile = runner.info().profile\n if (profile) {\n detachers.push(\n runner.subscribe((event) => {\n if (event.type !== 'capabilities' || !event.defaultModel) {\n return\n }\n profileDefaultModels.set(profile, event.defaultModel)\n }),\n )\n }\n return () => {\n for (const detach of detachers) {\n detach?.()\n }\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 {\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 // Applied after the host's hook, which is free to rebuild the config from the\n // request and would drop a field it has never heard of.\n epoch: (record.info.epoch ?? 0) + 1,\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 peers,\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 shell,\n pricingOverrides: Object.keys(pricing.overrides).length > 0 ? pricing.overrides : undefined,\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, { operator: auth.isOperator(authCtx) })\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 profiles.seedStore()\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 releaseSession: (id) => {\n const runner = registry.get(id)\n if (!runner) {\n return undefined\n }\n const plan = reloadPlan(runner)\n if (plan !== 'carry') {\n throw new Error(`session ${id} cannot be carried by identity (${plan})`)\n }\n const config = parking.release(id)\n registry.evict(id)\n return { runner, config }\n },\n adoptSession: ({ runner, config }) => {\n // Re-checked here, not only at release: a runner held across a failed generation may have ended in the\n // meantime, and adopting a dead one would list a session nothing can answer.\n if (reloadPlan(runner) !== 'carry') {\n return false\n }\n parking.adopt(runner, config)\n registry.retain(runner.id, factory.watchAuthSource(runner))\n return true\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 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 shell?.killAll()\n // `wss` is `noServer`, so `wss.close()` only waits for `clients` to empty, and `server.closeAllConnections()`\n // never reaches an upgraded socket: close every client ourselves, then terminate what has not acknowledged.\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 const deadline = setTimeout(() => resolve(), CLOSE_DEADLINE_MS)\n deadline.unref()\n const drained = Promise.all([\n new Promise<void>((done) => wss.close(() => done())),\n new Promise<void>((done) => server.close(() => done())),\n ])\n server.closeAllConnections()\n void drained.then(() => {\n clearTimeout(force)\n clearTimeout(deadline)\n resolve()\n })\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 SessionInstructions,\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?: SessionInstructions\n executionLimits?: { timeoutMs?: number; memoryLimitBytes?: number }\n seedVfs?: Record<string, string>\n shouldApprove?: (call: { toolName: string; input: unknown }) => boolean\n approvalTimeoutMs?: number | null\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: config.defaultApprovalTimeoutMs === undefined ? options.approvalTimeoutMs : config.defaultApprovalTimeoutMs,\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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"}