{"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/emitter.ts","../src/session-handle.ts","../src/queue-handle.ts","../src/ws-url.ts","../src/host-url.ts","../src/host-auth.ts","../src/team-move.ts","../src/index.ts"],"sourcesContent":["export type Listener<T> = (payload: T) => void\n\n// The handles' listener registry. A throwing listener must never stop the ones queued behind it:\n// these fire from a socket callback, where an escaping error would take the connection with it.\nexport class Emitter<Events> {\n  #listeners = new Map<keyof Events, Set<Listener<never>>>()\n\n  on<K extends keyof Events>(kind: K, listener: Listener<Events[K]>): () => void {\n    let set = this.#listeners.get(kind)\n    if (!set) {\n      set = new Set()\n      this.#listeners.set(kind, set)\n    }\n    set.add(listener as Listener<never>)\n    return () => set.delete(listener as Listener<never>)\n  }\n\n  emit<K extends keyof Events>(kind: K, payload: Events[K]): void {\n    const set = this.#listeners.get(kind)\n    if (!set) {\n      return\n    }\n    for (const listener of set) {\n      try {\n        ;(listener as Listener<Events[K]>)(payload)\n      } catch {}\n    }\n  }\n}\n\n// 500ms doubling from a zero-based attempt count, capped at 10s.\nexport function reconnectDelay(retries: number): number {\n  return Math.min(500 * 2 ** retries, 10_000)\n}\n","import type {\n  AttachedFrame,\n  ClientFrame,\n  PermissionMode,\n  ServerFrame,\n  SessionEvent,\n  ShellInfo,\n  ToolCallRequestFrame,\n  ToolExecutionOutput,\n} from '@workerdeck/protocol'\nimport { chunkShellInput } from '@workerdeck/protocol'\nimport { Emitter, reconnectDelay, type Listener } from './lib/emitter.ts'\nimport type { WorkerDeckClient } from './index.ts'\n\nexport type AttachOptions = {\n  afterSeq?: number\n  reconnect?: boolean\n  truncateResults?: boolean\n  imageRefs?: boolean\n  // A past conversation of the session: a read-only socket that never moves the client's conversation token.\n  conversation?: number\n}\n\nexport type SessionHandleEvents = {\n  attached: AttachedFrame\n  event: SessionEvent\n  protocolError: string\n  connectionChange: boolean\n  reconnectAttempt: number\n  toolCallRequest: ToolCallRequestFrame\n  toolCallCanceled: { executionId: string; reason: string }\n  shellAttached: { shellId: string; shell: ShellInfo; cols: number; rows: number; scrollback: string }\n  shellOutput: { shellId: string; data: string }\n  shellDetached: { shellId: string; reason: string }\n  // A prompt the gateway refused before the engine saw it (its conversation ended, a rotation was in flight): the sender's to resubmit.\n  // `uncertain`: refused now, but whether an earlier attempt ran is no longer known.\n  undeliveredPrompt: { clientId: string; text: string; attachmentIds?: string[]; uncertain?: true }\n}\n\nexport class SessionHandle {\n  readonly sessionId: string\n  #client: WorkerDeckClient\n  #options: Required<Pick<AttachOptions, 'reconnect'>> & AttachOptions\n  #ws: WebSocket | undefined\n  #events = new Emitter<SessionHandleEvents>()\n  #lastSeq: number\n  #closed = false\n  #retries = 0\n  #outbox: Array<{ frame: ClientFrame; clientId?: string }> = []\n  #unacked = new Map<string, string>()\n  #everConnected = false\n  #attachedHere = false\n  #prompts = 0\n  // The conversation new commands are written for. Stamped onto a command when it is created and never rewritten, so a\n  // resend after a reconnect still names the conversation it was meant for and is refused if that one has ended.\n  #conversation: number | undefined\n  readonly #nonce = Math.random().toString(36).slice(2, 10) + Date.now().toString(36)\n  #connectTimer: ReturnType<typeof setTimeout> | undefined\n\n  constructor(client: WorkerDeckClient, sessionId: string, options: AttachOptions = {}) {\n    this.#client = client\n    this.sessionId = sessionId\n    this.#options = { reconnect: true, ...options }\n    this.#lastSeq = options.afterSeq ?? 0\n    this.#conversation = options.conversation ?? client.conversationOf(sessionId)\n    // Deferred a tick so a same-tick detach (React StrictMode's dev mount) never closes a WebSocket mid-upgrade, which breaks proxies.\n    this.#connectTimer = setTimeout(() => this.#connect(), 0)\n  }\n\n  get lastSeq(): number {\n    return this.#lastSeq\n  }\n\n  // False until a socket has opened once: a failing first attach never reached the gateway at all.\n  get everConnected(): boolean {\n    return this.#everConnected\n  }\n\n  on<K extends keyof SessionHandleEvents>(kind: K, listener: Listener<SessionHandleEvents[K]>): () => void {\n    return this.#events.on(kind, listener)\n  }\n\n  send(text: string, attachmentIds?: string[]): void {\n    const clientId = `${this.#nonce}.${++this.#prompts}`\n    this.#sendFrame(\n      {\n        type: 'user_message',\n        text,\n        attachmentIds: attachmentIds?.length ? attachmentIds : undefined,\n        clientId,\n      },\n      clientId,\n    )\n  }\n\n  approve(requestId: string, updatedInput?: Record<string, unknown>): void {\n    this.#sendFrame({ type: 'permission_decision', requestId, behavior: 'allow', updatedInput })\n  }\n\n  deny(requestId: string, message?: string, interrupt?: boolean): void {\n    this.#sendFrame({ type: 'permission_decision', requestId, behavior: 'deny', message, interrupt })\n  }\n\n  interrupt(): void {\n    this.#sendFrame({ type: 'interrupt' })\n  }\n\n  sleep(): void {\n    this.#sendFrame({ type: 'sleep' })\n  }\n\n  backgroundTask(toolUseId?: string): void {\n    this.#sendFrame({ type: 'background_task', toolUseId })\n  }\n\n  runShell(command: string): void {\n    this.#sendFrame({ type: 'shell_command', command })\n  }\n\n  attachShell(shellId: string, size: { cols: number; rows: number }): void {\n    this.#sendFrame({ type: 'shell_attach', shellId, cols: size.cols, rows: size.rows })\n  }\n\n  writeShell(shellId: string, data: string): void {\n    for (const chunk of chunkShellInput(data)) {\n      this.#sendFrame({ type: 'shell_input', shellId, data: chunk })\n    }\n  }\n\n  resizeShell(shellId: string, size: { cols: number; rows: number }): void {\n    this.#sendFrame({ type: 'shell_resize', shellId, cols: size.cols, rows: size.rows })\n  }\n\n  detachShell(shellId: string): void {\n    this.#sendFrame({ type: 'shell_detach', shellId })\n  }\n\n  clearContext(): void {\n    this.#sendFrame({ type: 'clear_context' })\n  }\n\n  setPermissionMode(mode: PermissionMode): void {\n    this.#sendFrame({ type: 'set_permission_mode', mode })\n  }\n\n  setModel(model?: string): void {\n    this.#sendFrame({ type: 'set_model', model })\n  }\n\n  setEffort(effort?: string): void {\n    this.#sendFrame({ type: 'set_effort', effort })\n  }\n\n  sendToolCallResult(executionId: string, output: ToolExecutionOutput, logs?: string[]): void {\n    this.#sendFrame({ type: 'tool_call_result', executionId, output, logs })\n  }\n\n  sendToolCallError(executionId: string, reason: string, error: string, logs?: string[]): void {\n    this.#sendFrame({ type: 'tool_call_error', executionId, reason, error, logs })\n  }\n\n  closeSession(): void {\n    this.#sendFrame({ type: 'close' })\n    this.detach()\n  }\n\n  // Skips the backoff wait only: a socket still in its handshake is left to finish, never doubled.\n  reconnectNow(): void {\n    const state = this.#ws?.readyState\n    if (this.#closed || state === 1) {\n      return\n    }\n    this.#retries = 0\n    this.#events.emit('reconnectAttempt', 0)\n    if (state === 0) {\n      return\n    }\n    clearTimeout(this.#connectTimer)\n    this.#connect()\n  }\n\n  detach(): void {\n    this.#closed = true\n    clearTimeout(this.#connectTimer)\n    this.#ws?.close()\n    this.#ws = undefined\n  }\n\n  get conversation(): number | undefined {\n    return this.#conversation\n  }\n\n  #sendFrame(frame: ClientFrame, clientId?: string): void {\n    const stamped = this.#conversation === undefined ? frame : { ...frame, generation: this.#conversation }\n    // readyState 1 === OPEN (avoid touching the WebSocket global; impl may be injected). A frame with no conversation\n    // yet waits for the attach that names one.\n    if (this.#ws && this.#ws.readyState === 1 && (this.#attachedHere || stamped.generation !== undefined)) {\n      this.#transmit(this.#ws, JSON.stringify(stamped), clientId)\n    } else {\n      this.#outbox.push({ frame: stamped, clientId })\n    }\n  }\n\n  #flushOutbox(ws: WebSocket): void {\n    for (const { frame, clientId } of this.#outbox.splice(0)) {\n      const stamped =\n        frame.generation === undefined && this.#conversation !== undefined ? { ...frame, generation: this.#conversation } : frame\n      this.#transmit(ws, JSON.stringify(stamped), clientId)\n    }\n  }\n\n  // A prompt stays until the gateway acks it, so a drop before the ack resends it on the next socket.\n  #transmit(ws: WebSocket, payload: string, clientId: string | undefined): void {\n    ws.send(payload)\n    if (clientId) {\n      this.#unacked.set(clientId, payload)\n    }\n  }\n\n  #connect(): void {\n    if (this.#closed) {\n      return\n    }\n    const ws = this.#client.openSocket(\n      this.sessionId,\n      this.#lastSeq,\n      this.#options.truncateResults,\n      this.#options.imageRefs,\n      this.#options.conversation,\n    )\n    this.#ws = ws\n    let opened = false\n    ws.onopen = () => {\n      opened = true\n      this.#everConnected = true\n      this.#retries = 0\n      this.#events.emit('connectionChange', true)\n      this.#attachedHere = false\n      const resend = [...this.#unacked]\n      this.#unacked.clear()\n      for (const [clientId, payload] of resend) {\n        this.#transmit(ws, payload, clientId)\n      }\n      if (this.#outbox.every(({ frame }) => frame.generation !== undefined)) {\n        this.#flushOutbox(ws)\n      }\n    }\n    ws.onmessage = (msg: MessageEvent) => {\n      const frame = JSON.parse(String(msg.data)) as ServerFrame\n      if (frame.type === 'attached') {\n        this.#attachedHere = true\n        const conversation = (frame.session as Partial<AttachedFrame['session']> | undefined)?.conversation\n        if (conversation !== undefined && this.#options.conversation === undefined) {\n          this.#conversation = conversation\n          this.#client.noteConversation(this.sessionId, conversation)\n        }\n        this.#flushOutbox(ws)\n        this.#events.emit('attached', frame)\n      } else if (frame.type === 'event') {\n        if (frame.event.seq <= this.#lastSeq) {\n          return\n        }\n        this.#lastSeq = frame.event.seq\n        this.#events.emit('event', frame.event)\n      } else if (frame.type === 'tool_call_request') {\n        this.#events.emit('toolCallRequest', frame)\n      } else if (frame.type === 'tool_call_canceled') {\n        this.#events.emit('toolCallCanceled', { executionId: frame.executionId, reason: frame.reason })\n      } else if (frame.type === 'shell_attached') {\n        this.#events.emit('shellAttached', {\n          shellId: frame.shellId,\n          shell: frame.shell,\n          cols: frame.cols,\n          rows: frame.rows,\n          scrollback: frame.scrollback,\n        })\n      } else if (frame.type === 'shell_output') {\n        this.#events.emit('shellOutput', { shellId: frame.shellId, data: frame.data })\n      } else if (frame.type === 'shell_detached') {\n        this.#events.emit('shellDetached', { shellId: frame.shellId, reason: frame.reason })\n      } else if (frame.type === 'ack') {\n        const payload = this.#unacked.get(frame.clientId)\n        this.#unacked.delete(frame.clientId)\n        if ((frame.notDelivered || frame.uncertain) && payload !== undefined) {\n          const sent = JSON.parse(payload) as Extract<ClientFrame, { type: 'user_message' }>\n          this.#events.emit('undeliveredPrompt', {\n            clientId: frame.clientId,\n            text: sent.text,\n            ...(sent.attachmentIds ? { attachmentIds: sent.attachmentIds } : {}),\n            ...(frame.uncertain ? { uncertain: true as const } : {}),\n          })\n        }\n      } else if (frame.type === 'protocol_error') {\n        this.#events.emit('protocolError', frame.message)\n      }\n    }\n    ws.onclose = () => {\n      if (opened) {\n        this.#events.emit('connectionChange', false)\n      }\n      if (this.#closed || !this.#options.reconnect) {\n        return\n      }\n      const delay = reconnectDelay(this.#retries++)\n      this.#events.emit('reconnectAttempt', this.#retries)\n      this.#connectTimer = setTimeout(() => this.#connect(), delay)\n    }\n    ws.onerror = () => {}\n  }\n}\n","import type { JobEvent, QueueServerFrame, QueueStats } from '@workerdeck/protocol'\nimport { Emitter, reconnectDelay, type Listener } from './lib/emitter.ts'\nimport type { WorkerDeckClient } from './index.ts'\n\nexport type QueueHandleEvents = {\n  attached: QueueStats\n  event: JobEvent\n  stats: QueueStats\n  connectionChange: boolean\n}\n\nexport class QueueHandle {\n  #client: WorkerDeckClient\n  #reconnect: boolean\n  #ws: WebSocket | undefined\n  #events = new Emitter<QueueHandleEvents>()\n  #closed = false\n  #retries = 0\n  #connectTimer: ReturnType<typeof setTimeout> | undefined\n\n  constructor(client: WorkerDeckClient, options: { reconnect?: boolean } = {}) {\n    this.#client = client\n    this.#reconnect = options.reconnect ?? true\n    // Deferred a tick for the same StrictMode reason as SessionHandle.\n    this.#connectTimer = setTimeout(() => this.#connect(), 0)\n  }\n\n  on<K extends keyof QueueHandleEvents>(kind: K, listener: Listener<QueueHandleEvents[K]>): () => void {\n    return this.#events.on(kind, listener)\n  }\n\n  detach(): void {\n    this.#closed = true\n    clearTimeout(this.#connectTimer)\n    this.#ws?.close()\n    this.#ws = undefined\n  }\n\n  #connect(): void {\n    if (this.#closed) {\n      return\n    }\n    const ws = this.#client.openQueueSocket()\n    this.#ws = ws\n    ws.onopen = () => {\n      this.#retries = 0\n      this.#events.emit('connectionChange', true)\n    }\n    ws.onmessage = (msg: MessageEvent) => {\n      const frame = JSON.parse(String(msg.data)) as QueueServerFrame\n      if (frame.type === 'queue_attached') {\n        this.#events.emit('attached', frame.stats)\n        this.#events.emit('stats', frame.stats)\n      } else if (frame.type === 'job_event') {\n        this.#events.emit('event', frame.event)\n      } else if (frame.type === 'queue_stats') {\n        this.#events.emit('stats', frame.stats)\n      }\n    }\n    ws.onclose = () => {\n      this.#events.emit('connectionChange', false)\n      if (this.#closed || !this.#reconnect) {\n        return\n      }\n      const delay = reconnectDelay(this.#retries++)\n      this.#connectTimer = setTimeout(() => this.#connect(), delay)\n    }\n    ws.onerror = () => {}\n  }\n}\n","export function sessionWsUrl(\n  baseUrl: string,\n  sessionId: string,\n  afterSeq: number,\n  truncateResults = false,\n  imageRefs = false,\n  conversation?: number,\n): string {\n  const query =\n    `afterSeq=${afterSeq}` +\n    (truncateResults ? '&truncateResults=1' : '') +\n    (imageRefs ? '&imageRefs=1' : '') +\n    (conversation === undefined ? '' : `&conversation=${conversation}`)\n  return `${baseUrl.replace(/^http/, 'ws')}/sessions/${encodeURIComponent(sessionId)}/ws?${query}`\n}\n","export type HostUrl = { baseUrl: string }\n\nexport function apiUrl(host: HostUrl): string | undefined {\n  let text = host.baseUrl.trim()\n  while (text.endsWith('/')) {\n    text = text.slice(0, -1)\n  }\n  if (text === '') {\n    return undefined\n  }\n  // A bare `mac.tailnet.ts.net:8787` is a host:port, not a scheme, and tailnet gateways are plain http.\n  if (!text.includes('://')) {\n    text = 'http://' + text\n  }\n  if (!text.endsWith('/v1')) {\n    text += '/v1'\n  }\n  try {\n    // Validation only - the string, not the URL object, is what we keep.\n    new URL(text)\n  } catch {\n    return undefined\n  }\n  return text\n}\n\nexport function isLoopbackHost(host: HostUrl): boolean {\n  const api = apiUrl(host)\n  if (!api) {\n    return false\n  }\n  try {\n    const { hostname } = new URL(api)\n    return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '::1' || hostname === '[::1]'\n  } catch {\n    return false\n  }\n}\n","import type { ClientOptions } from './index.ts'\nimport { sessionWsUrl } from './ws-url.ts'\n\nexport function hostAuth(options: { baseUrl: string; key: string }): Pick<ClientOptions, 'headers' | 'buildWsUrl' | 'buildQueueWsUrl'> {\n  const { baseUrl, key } = options\n  if (key === '') {\n    return {}\n  }\n\n  const wsRoot = baseUrl.replace(/^http/, 'ws')\n  const withKey = (url: string): string => `${url}${url.includes('?') ? '&' : '?'}key=${encodeURIComponent(key)}`\n\n  return {\n    headers: { authorization: `Bearer ${key}` },\n    buildWsUrl: (sessionId, afterSeq, truncateResults, imageRefs, conversation) =>\n      withKey(sessionWsUrl(baseUrl, sessionId, afterSeq, truncateResults, imageRefs, conversation)),\n    buildQueueWsUrl: () => withKey(`${wsRoot}/queue/ws`),\n  }\n}\n","import type { GatewayRelayMeta } from '@workerdeck/protocol'\nimport type { WorkerDeckClient } from './index.ts'\n\n// A drop in a session list, as the gateways see it. `lead: null` leaves the team; a mover without an agent is\n// named first (a PATCH, under the same id). `hostId` is the client's own name for a gateway, never its relay name. `crossOwner` carries the\n// person's confirmation that the mover and the lead belong to different owners.\nexport type TeamMovePlan = {\n  mover: { hostId: string; sessionId: string; agentId?: string; owner?: string }\n  lead: { hostId: string; agentId: string } | null\n  order?: number\n  siblings?: Array<{ hostId: string; agentId: string; order: number }>\n  crossOwner?: true\n}\n\n// `unknown`: the invite got no answer, so the lead's gateway may hold one; with no id there is nothing safe to withdraw.\nexport type TeamInvitation = {\n  hostId: string\n  leadAgentId: string\n  member: string\n  invite?: string\n  state: 'withdrawn' | 'open' | 'unknown'\n}\n\n// `committed: 'unknown'` means the gateway never answered the join, so it may still go through.\nexport type TeamMoveOutcome = {\n  committed: 'yes' | 'no' | 'unknown'\n  error?: string\n  adopted?: { hostId: string; agentId: string }\n  invitation?: TeamInvitation\n  unordered?: Array<{ hostId: string; agentId: string }>\n}\n\ntype Step<T = unknown> = { ok: true; response: T } | { ok: false; definite: boolean; error: string }\n\n// Across gateways a join takes two operator calls, one per side: the lead's gateway invites, then the mover's gateway\n// joins through the relay. Holding a key for both gateways is the consent. Throws only before its first change.\nexport async function runTeamMove(\n  plan: TeamMovePlan,\n  clientOf: (hostId: string) => WorkerDeckClient | undefined,\n  relayOf: (hostId: string) => GatewayRelayMeta | undefined = () => undefined,\n): Promise<TeamMoveOutcome> {\n  const client = clientOf(plan.mover.hostId)\n  if (!client) {\n    throw new Error('that gateway is not configured here')\n  }\n  const lead = plan.lead\n  let outcome: TeamMoveOutcome\n  if (!lead) {\n    outcome = plan.mover.agentId ? settle(await step(client.updateAgent(plan.mover.agentId, { lead: null }))) : { committed: 'yes' }\n  } else if (lead.hostId === plan.mover.hostId) {\n    outcome = await sameGateway(plan, client, lead.agentId)\n  } else {\n    const leadClient = clientOf(lead.hostId)\n    const leadRelay = relayOf(lead.hostId)\n    const moverRelay = relayOf(plan.mover.hostId)\n    if (!leadClient || !leadRelay || !moverRelay) {\n      throw new Error('a team spans gateways only through a relay both gateways dial')\n    }\n    outcome = await acrossGateways(\n      plan,\n      client,\n      leadClient,\n      { hostId: lead.hostId, agentId: lead.agentId, gateway: leadRelay.gateway },\n      moverRelay,\n    )\n  }\n  if (outcome.committed !== 'yes') {\n    return outcome\n  }\n  const unordered = [...(outcome.unordered ?? [])]\n  for (const sibling of plan.siblings ?? []) {\n    const done = await step(clientOf(sibling.hostId)?.updateAgent(sibling.agentId, { order: sibling.order }))\n    if (!done.ok) {\n      unordered.push({ hostId: sibling.hostId, agentId: sibling.agentId })\n    }\n  }\n  return unordered.length ? { ...outcome, unordered } : outcome\n}\n\nasync function sameGateway(move: TeamMovePlan, gateway: WorkerDeckClient, leadId: string): Promise<TeamMoveOutcome> {\n  const order = orderOf(move)\n  const crossOwner = move.crossOwner ? { crossOwner: true } : {}\n  if (move.mover.agentId) {\n    return settle(await step(gateway.updateAgent(move.mover.agentId, { lead: leadId, ...order, ...crossOwner })))\n  }\n  const named = await step(gateway.nameSession(move.mover.sessionId, { lead: leadId, ...crossOwner }))\n  if (!named.ok || move.order === undefined) {\n    return settle(named)\n  }\n  const agentId = move.mover.sessionId\n  const ordered = await step(gateway.updateAgent(agentId, order))\n  return ordered.ok ? { committed: 'yes' } : { committed: 'yes', unordered: [{ hostId: move.mover.hostId, agentId }] }\n}\n\nasync function acrossGateways(\n  move: TeamMovePlan,\n  gateway: WorkerDeckClient,\n  leadGateway: WorkerDeckClient,\n  target: { hostId: string; agentId: string; gateway: string },\n  moverRelay: GatewayRelayMeta,\n): Promise<TeamMoveOutcome> {\n  const order = orderOf(move)\n  let agentId = move.mover.agentId\n  let adopted: TeamMoveOutcome['adopted']\n  if (!agentId) {\n    const named = await step(gateway.nameSession(move.mover.sessionId, {}))\n    if (!named.ok) {\n      return settle(named)\n    }\n    agentId = move.mover.sessionId\n    adopted = { hostId: move.mover.hostId, agentId }\n  }\n  const kept = adopted ? { adopted } : {}\n  const member = `${moverRelay.gateway}:${agentId}`\n  const invited = await step(leadGateway.inviteRemoteMember(target.agentId, member, move.mover.owner))\n  if (!invited.ok) {\n    const unanswered = invited.definite\n      ? {}\n      : { invitation: { hostId: target.hostId, leadAgentId: target.agentId, member, state: 'unknown' as const } }\n    return { committed: 'no', error: invited.error, ...kept, ...unanswered }\n  }\n  const entry = invited.response.agent.remoteMembers?.find((candidate) => candidate.agent === member)\n  const invite = entry?.state === 'invited' ? entry.invite : undefined\n  const invitation: TeamInvitation | undefined =\n    invite === undefined ? undefined : { hostId: target.hostId, leadAgentId: target.agentId, member, invite, state: 'open' }\n  const joined = await step(gateway.updateAgent(agentId, { lead: `${target.gateway}:${target.agentId}`, ...order }))\n  if (joined.ok) {\n    return { committed: 'yes', ...kept }\n  }\n  if (!invitation || invite === undefined) {\n    return { committed: joined.definite ? 'no' : 'unknown', error: joined.error, ...kept }\n  }\n  if (!joined.definite) {\n    return { committed: 'unknown', error: joined.error, ...kept, invitation }\n  }\n  const withdrawn = await step(leadGateway.withdrawInvitation(target.agentId, member, invite))\n  return { committed: 'no', error: joined.error, ...kept, invitation: { ...invitation, state: withdrawn.ok ? 'withdrawn' : 'open' } }\n}\n\n// The safe next action for an open invitation: conditional on its id, so a join that went through meanwhile stays.\nexport async function withdrawTeamInvitation(\n  invitation: TeamInvitation,\n  clientOf: (hostId: string) => WorkerDeckClient | undefined,\n): Promise<void> {\n  const client = clientOf(invitation.hostId)\n  if (!client || invitation.invite === undefined) {\n    throw new Error(client ? 'that invitation has no id to withdraw by' : 'that gateway is not configured here')\n  }\n  await client.withdrawInvitation(invitation.leadAgentId, invitation.member, invitation.invite)\n}\n\n// The one sentence a host shows for a move that did not simply go through; undefined when there is nothing to say.\nexport function teamMoveMessage(outcome: TeamMoveOutcome): string | undefined {\n  const parts: string[] = []\n  if (outcome.committed === 'no') {\n    parts.push(sentence(outcome.error ?? 'The move was refused'))\n  } else if (outcome.committed === 'unknown') {\n    parts.push(`The gateway did not answer, so the join may still go through${outcome.error ? ` (${outcome.error})` : ''}.`)\n  }\n  if (outcome.committed !== 'yes' && outcome.adopted) {\n    parts.push('The session stays an agent.')\n  }\n  if (outcome.invitation?.state === 'withdrawn') {\n    parts.push('The invitation was withdrawn.')\n  } else if (outcome.invitation?.state === 'open') {\n    parts.push('The invitation stays open for up to 10 minutes.')\n  } else if (outcome.invitation?.state === 'unknown') {\n    parts.push(\"The lead's gateway may hold an invitation; it lapses within 10 minutes.\")\n  }\n  if (outcome.unordered?.length) {\n    const count = outcome.unordered.length\n    parts.push(`The team order of ${count} agent${count === 1 ? '' : 's'} was not saved; drag again to reorder.`)\n  }\n  return parts.length ? parts.join(' ') : undefined\n}\n\nasync function step<T>(call: Promise<T> | undefined): Promise<Step<T>> {\n  if (!call) {\n    return { ok: false, definite: true, error: 'that gateway is not configured here' }\n  }\n  try {\n    return { ok: true, response: await call }\n  } catch (error) {\n    const status = (error as { status?: unknown }).status\n    return {\n      ok: false,\n      definite: typeof status === 'number' && status < 500,\n      error: error instanceof Error ? error.message : String(error),\n    }\n  }\n}\n\nfunction orderOf(move: TeamMovePlan): { order?: number } {\n  return move.order === undefined ? {} : { order: move.order }\n}\n\nfunction settle(result: Step): TeamMoveOutcome {\n  if (result.ok) {\n    return { committed: 'yes' }\n  }\n  return { committed: result.definite ? 'no' : 'unknown', error: result.error }\n}\n\nfunction sentence(text: string): string {\n  const trimmed = text.trim()\n  const capital = trimmed.charAt(0).toUpperCase() + trimmed.slice(1)\n  return /[.!?]$/.test(capital) ? capital : `${capital}.`\n}\n","import type {\n  AgentInfo,\n  AgentResponse,\n  CompleteAccountRequest,\n  CompleteAccountResponse,\n  RenameOwnerRequest,\n  RenameOwnerResponse,\n  ConnectAccountResponse,\n  ConversationHistoryResponse,\n  ConversationsResponse,\n  CreateAgentRequest,\n  DiscardAndCutRequest,\n  NewConversationRequest,\n  NewConversationResponse,\n  RetireAgentRequest,\n  SessionAgentRequest,\n  RetiredAgentInfo,\n  UpdateAgentRequest,\n  CreateJobRequest,\n  CreateProfileRequest,\n  CreateSessionRequest,\n  JobInfo,\n  FindHostFilesResponse,\n  GatewayMeta,\n  GetProfileResponse,\n  ListHostDirResponse,\n  ListHostRootsResponse,\n  ListProfilesResponse,\n  ListSessionFilesResponse,\n  McpServerActionRequest,\n  McpServersResponse,\n  McpServerStatusInfo,\n  PeerSessionSummary,\n  PeerSessionsResponse,\n  MessageAttachment,\n  ReadHostFileResponse,\n  UploadAttachmentResponse,\n  WriteHostFileRequest,\n  WriteHostFileResponse,\n  HostEntryResponse,\n  ProfileInfo,\n  QueueStats,\n  ResolvePermissionRequest,\n  ShellInfo,\n  UpdateSessionRequest,\n  SubmitExecutionResultRequest,\n  SubmitExecutionResultResponse,\n  SaveProfileResponse,\n  SdkSessionSummary,\n  SessionFileInfo,\n  SessionInfo,\n  UpdateProfileRequest,\n  ToolResultBlock,\n  UnconfirmedInputRefusal,\n  EraseConversationResponse,\n  SessionSettingsPatch,\n  UpdateSessionResponse,\n} from '@workerdeck/protocol'\nimport { GENERATION_HEADER, INPUT_CHANGED_CODE, UNCONFIRMED_INPUT_CODE } from '@workerdeck/protocol'\nimport { SessionHandle, type AttachOptions } from './session-handle.ts'\nimport { QueueHandle } from './queue-handle.ts'\nimport { sessionWsUrl } from './ws-url.ts'\n\ntype ToolResultResponse = { seq: number; toolUseId: string; content: ToolResultBlock['content']; isError: boolean }\n\nexport type FetchBody = NonNullable<NonNullable<Parameters<typeof fetch>[1]>['body']>\n\nexport type ClientOptions = {\n  baseUrl: string\n  headers?: Record<string, string>\n  buildWsUrl?: (sessionId: string, afterSeq: number, truncateResults?: boolean, imageRefs?: boolean, conversation?: number) => string\n  buildQueueWsUrl?: () => string\n  WebSocketImpl?: typeof WebSocket\n  fetchImpl?: typeof fetch\n}\n\nexport class WorkerDeckError extends Error {\n  readonly status: number\n  readonly code: string | undefined\n  // The refusal's whole JSON body, for one a client acts on (`unconfirmedInputOf`).\n  readonly body: Record<string, unknown> | undefined\n  constructor(message: string, status: number, body?: Record<string, unknown>) {\n    super(message)\n    this.name = 'WorkerDeckError'\n    this.status = status\n    this.code = typeof body?.code === 'string' ? body.code : undefined\n    this.body = body\n  }\n}\n\n// A cut refused because the engine cannot confirm its queued input was consumed (or, on a discard, because input\n// arrived since): what the confirmation shows and binds. Undefined for any other error.\nexport function unconfirmedInputOf(error: unknown): UnconfirmedInputRefusal | undefined {\n  if (!(error instanceof WorkerDeckError) || error.status !== 409 || !error.body) {\n    return undefined\n  }\n  const body = error.body\n  if (\n    (body.code !== UNCONFIRMED_INPUT_CODE && body.code !== INPUT_CHANGED_CODE) ||\n    typeof body.conversation !== 'number' ||\n    typeof body.inputRevision !== 'string'\n  ) {\n    return undefined\n  }\n  return {\n    error: error.message,\n    code: body.code,\n    conversation: body.conversation,\n    inputRevision: body.inputRevision,\n    pendingInput: typeof body.pendingInput === 'number' ? body.pendingInput : 0,\n    mayIncludePeer: body.mayIncludePeer !== false,\n  }\n}\n\nexport class WorkerDeckClient {\n  #options: ClientOptions\n  #conversations = new Map<string, number>()\n  #fetch: typeof fetch\n  #WebSocketImpl: typeof WebSocket\n\n  constructor(options: ClientOptions) {\n    this.#options = options\n    this.#fetch = options.fetchImpl ?? fetch.bind(globalThis)\n    this.#WebSocketImpl = options.WebSocketImpl ?? WebSocket\n  }\n\n  get identityKey(): string {\n    const headers = Object.entries(this.#options.headers ?? {}).map(([name, value]) => [name.toLowerCase(), value] as const)\n    headers.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n    return JSON.stringify([this.#options.baseUrl, headers])\n  }\n\n  async createSession(request: CreateSessionRequest): Promise<SessionInfo> {\n    return await this.#pick('POST', '/sessions', 'session', request)\n  }\n\n  async listSessions(): Promise<SessionInfo[]> {\n    return await this.#pick('GET', '/sessions', 'sessions')\n  }\n\n  async getSession(id: string): Promise<SessionInfo> {\n    return await this.#pick('GET', this.#sess(id), 'session')\n  }\n\n  async updateSession(id: string, patch: UpdateSessionRequest): Promise<SessionInfo> {\n    return await this.#pick('PATCH', this.#sess(id), 'session', patch)\n  }\n\n  // Names the session (what the UI calls an agent) under the same id; operator only.\n  async nameSession(id: string, agent: SessionAgentRequest): Promise<SessionInfo> {\n    return await this.updateSession(id, { agent })\n  }\n\n  // Refused (409) while the session leads or belongs to a team.\n  async unnameSession(id: string): Promise<SessionInfo> {\n    return await this.updateSession(id, { agent: null })\n  }\n\n  // What the next conversation starts from; it applies at the next cut, never to the running one. `null` clears a setting.\n  async updateSessionSettings(id: string, config: SessionSettingsPatch): Promise<UpdateSessionResponse> {\n    return await this.#call('PATCH', this.#sess(id), { config })\n  }\n\n  async conversations(id: string): Promise<ConversationsResponse> {\n    return await this.#call('GET', this.#sess(id, '/conversations'))\n  }\n\n  async conversationHistory(id: string, conversation: number): Promise<ConversationHistoryResponse> {\n    return await this.#call('GET', this.#sess(id, `/conversations/${conversation}`))\n  }\n\n  // Operator only. Forgets the gateway's copy of a past conversation; n stays, marked unavailable. Refused (409) for the current one.\n  async eraseConversation(id: string, conversation: number): Promise<EraseConversationResponse> {\n    return await this.#call('DELETE', this.#sess(id, `/conversations/${conversation}`))\n  }\n\n  // The cut: conversation n+1 under the same id. `expectedGeneration` is the conversation the caller is looking at.\n  async newConversation(id: string, request: NewConversationRequest): Promise<NewConversationResponse> {\n    return await this.#call('POST', this.#sess(id, '/conversations'), request)\n  }\n\n  // After a person confirmed losing the pending input `unconfirmedInputOf` reported: refused (409) if any arrived since.\n  async discardAndCut(id: string, request: DiscardAndCutRequest): Promise<NewConversationResponse> {\n    return await this.#call('POST', this.#sess(id, '/conversations/discard'), request)\n  }\n\n  async retryConversationStart(id: string, expectedGeneration: number): Promise<NewConversationResponse> {\n    return await this.#call('POST', this.#sess(id, '/conversations/retry'), { expectedGeneration })\n  }\n\n  async settlePendingPrompt(id: string, send: boolean, expectedGeneration: number): Promise<void> {\n    await this.#call('POST', this.#sess(id, '/conversations/pending'), { expectedGeneration, send })\n  }\n\n  async sleepSession(id: string): Promise<SessionInfo> {\n    return await this.#pick('POST', this.#sess(id, '/sleep'), 'session')\n  }\n\n  async deleteSession(id: string): Promise<SessionInfo> {\n    return await this.#pick('DELETE', this.#sess(id), 'session')\n  }\n\n  async listSessionFiles(sessionId: string): Promise<SessionFileInfo[]> {\n    return await this.#pick<ListSessionFilesResponse['files']>('GET', this.#sess(sessionId, '/files'), 'files')\n  }\n\n  async fetchSessionFile(sessionId: string, path: string): Promise<string> {\n    const res = await this.#callRaw(this.sessionFileUrl(sessionId, path), { headers: this.#options.headers }, 'GET file failed')\n    return await res.text()\n  }\n\n  async uploadAttachment(sessionId: string, file: { name: string; mediaType: string; data: FetchBody }): Promise<MessageAttachment> {\n    const url = `${this.#options.baseUrl}${this.#sess(sessionId, '/attachments')}?name=${encodeURIComponent(file.name)}`\n    const res = await this.#callRaw(\n      url,\n      {\n        method: 'POST',\n        headers: {\n          ...this.#generationHeader('POST', this.#sess(sessionId, '/attachments')),\n          ...this.#options.headers,\n          'content-type': file.mediaType,\n        },\n        body: file.data,\n      },\n      'upload failed',\n    )\n    return ((await res.json()) as UploadAttachmentResponse).attachment\n  }\n\n  attachmentUrl(sessionId: string, attachmentId: string): string {\n    return `${this.#options.baseUrl}${this.#sess(sessionId, `/attachments/${encodeURIComponent(attachmentId)}`)}`\n  }\n\n  producedFileUrl(sessionId: string, fileId: string): string {\n    return `${this.#options.baseUrl}${this.#sess(sessionId, `/produced/${encodeURIComponent(fileId)}`)}`\n  }\n\n  async readProducedFile(sessionId: string, fileId: string): Promise<Blob> {\n    return await this.#blob(this.producedFileUrl(sessionId, fileId), 'produced file request failed')\n  }\n\n  projectIconUrl(sessionId: string): string {\n    return `${this.#options.baseUrl}${this.#sess(sessionId, '/project/icon')}`\n  }\n\n  async projectIcon(sessionId: string): Promise<Blob> {\n    return await this.#blob(this.projectIconUrl(sessionId), 'project icon request failed')\n  }\n\n  // Operator-only: a gateway without agents, or a scoped caller, answers 404.\n  async listAgents(): Promise<AgentInfo[]> {\n    return await this.#pick('GET', '/agents', 'agents')\n  }\n\n  // Deleted agents, kept for their conversation history.\n  async retiredAgents(): Promise<RetiredAgentInfo[]> {\n    return await this.#pick('GET', '/agents?retired=1', 'retired')\n  }\n\n  async createAgent(request: CreateAgentRequest): Promise<AgentResponse> {\n    return await this.#call('POST', '/agents', request)\n  }\n\n  async getAgent(id: string): Promise<AgentResponse> {\n    return await this.#call('GET', this.#agent(id))\n  }\n\n  async updateAgent(id: string, patch: UpdateAgentRequest): Promise<AgentResponse> {\n    return await this.#call('PATCH', this.#agent(id), patch)\n  }\n\n  // Lead side of a cross-gateway join: a 10 minute invitation for `agent` (`gateway:agentId`) to join this lead.\n  // `owner` is the invitee's, when it differs from the lead's: the join is refused unless it matches.\n  async inviteRemoteMember(id: string, agent: string, owner?: string): Promise<AgentResponse> {\n    return await this.#call('POST', this.#agent(id, '/remote-members'), owner === undefined ? { agent } : { agent, owner })\n  }\n\n  // Withdraws only that still-open invitation (409 once the agent joined or a newer invitation replaced it).\n  async withdrawInvitation(id: string, agent: string, invite: string): Promise<AgentResponse> {\n    return await this.#call('DELETE', this.#agent(id, `/remote-members/${encodeURIComponent(agent)}?invite=${encodeURIComponent(invite)}`))\n  }\n\n  async removeRemoteMember(id: string, agent: string): Promise<AgentResponse> {\n    return await this.#call('DELETE', this.#agent(id, `/remote-members/${encodeURIComponent(agent)}`))\n  }\n\n  async retireAgent(id: string, request: RetireAgentRequest): Promise<{ retired: string[]; released: string[] }> {\n    return await this.#call('DELETE', this.#agent(id), request)\n  }\n\n  // A new avatar for the agent: `seed` picks a known one (a preview's), none rolls a random one.\n  async changeAgentAvatar(id: string, seed?: string): Promise<AgentResponse> {\n    return await this.#call('POST', this.#agent(id, '/avatar'), seed === undefined ? {} : { seed })\n  }\n\n  agentAvatarPreviewUrl(id: string, seed: string): string {\n    return `${this.#options.baseUrl}${this.#agent(id, `/avatar-preview.png?seed=${encodeURIComponent(seed)}`)}`\n  }\n\n  async agentAvatarPreview(id: string, seed: string): Promise<Blob> {\n    const res = await this.#callRaw(\n      this.agentAvatarPreviewUrl(id, seed),\n      { headers: { ...this.#options.headers } },\n      'avatar preview request failed',\n    )\n    return await res.blob()\n  }\n\n  agentAvatarUrl(id: string, busy = false): string {\n    return `${this.#options.baseUrl}${this.#agent(id, busy ? '/avatar-busy.png' : '/avatar.png')}`\n  }\n\n  // `durations` is set on the busy strip only: one entry per frame, frames laid out left to right.\n  async agentAvatar(id: string, busy = false): Promise<{ blob: Blob; durations?: number[] }> {\n    const res = await this.#callRaw(this.agentAvatarUrl(id, busy), { headers: { ...this.#options.headers } }, 'agent avatar request failed')\n    const header = res.headers.get('x-frame-durations')\n    const durations = header\n      ? header\n          .split(',')\n          .map(Number)\n          .filter((n) => Number.isFinite(n) && n > 0)\n      : undefined\n    return durations?.length ? { blob: await res.blob(), durations } : { blob: await res.blob() }\n  }\n\n  // The sessions this one may address, relay included: what its `peers_list` tool answers.\n  async listPeers(sessionId: string): Promise<PeerSessionSummary[]> {\n    return await this.#pick<PeerSessionsResponse['peers']>('GET', this.#sess(sessionId, '/peers'), 'peers')\n  }\n\n  async listMcpServers(sessionId: string): Promise<McpServerStatusInfo[]> {\n    return await this.#pick<McpServersResponse['servers']>('GET', this.#sess(sessionId, '/mcp'), 'servers')\n  }\n\n  async mcpServerAction(sessionId: string, serverName: string, action: McpServerActionRequest['action']): Promise<McpServerStatusInfo[]> {\n    const path = this.#sess(sessionId, `/mcp/${encodeURIComponent(serverName)}`)\n    return await this.#pick<McpServersResponse['servers']>('POST', path, 'servers', { action })\n  }\n\n  sessionFileUrl(sessionId: string, path: string): string {\n    const encoded = path.split('/').filter(Boolean).map(encodeURIComponent).join('/')\n    return `${this.#options.baseUrl}${this.#sess(sessionId, `/files/${encoded}`)}`\n  }\n\n  async resolvePermission(sessionId: string, requestId: string, decision: ResolvePermissionRequest): Promise<void> {\n    await this.#call('POST', this.#sess(sessionId, `/permissions/${encodeURIComponent(requestId)}`), decision)\n  }\n\n  async submitExecutionResult(executionId: string, result: SubmitExecutionResultRequest): Promise<SubmitExecutionResultResponse> {\n    return await this.#call('POST', `/executions/${encodeURIComponent(executionId)}/result`, result)\n  }\n\n  async listProfiles(): Promise<ListProfilesResponse> {\n    return await this.#call('GET', '/profiles')\n  }\n\n  async getProfile(name: string): Promise<GetProfileResponse> {\n    return await this.#call('GET', `/profiles/${encodeURIComponent(name)}`)\n  }\n\n  async createProfile(profile: CreateProfileRequest): Promise<ProfileInfo> {\n    return await this.#pick<SaveProfileResponse['profile']>('POST', '/profiles', 'profile', profile)\n  }\n\n  async updateProfile(name: string, patch: UpdateProfileRequest): Promise<ProfileInfo> {\n    return await this.#pick<SaveProfileResponse['profile']>('PATCH', `/profiles/${encodeURIComponent(name)}`, 'profile', patch)\n  }\n\n  async deleteProfile(name: string): Promise<void> {\n    await this.#call('DELETE', `/profiles/${encodeURIComponent(name)}`)\n  }\n\n  async connectAccount(profile: string): Promise<ConnectAccountResponse> {\n    return await this.#call('POST', `/profiles/${encodeURIComponent(profile)}/account/connect`)\n  }\n\n  async completeAccount(profile: string, request: CompleteAccountRequest): Promise<ProfileInfo> {\n    return await this.#pick<SaveProfileResponse['profile']>(\n      'POST',\n      `/profiles/${encodeURIComponent(profile)}/account/complete`,\n      'profile',\n      request,\n    )\n  }\n\n  // One wait on a device-code sign-in (codex): answers `pending` until the user finishes in the browser, so call it in a loop.\n  async awaitAccount(profile: string, attemptId: string): Promise<CompleteAccountResponse> {\n    return await this.#call('POST', `/profiles/${encodeURIComponent(profile)}/account/complete`, { attemptId })\n  }\n\n  async disconnectAccount(profile: string): Promise<ProfileInfo> {\n    return await this.#pick<SaveProfileResponse['profile']>('DELETE', `/profiles/${encodeURIComponent(profile)}/account`, 'profile')\n  }\n\n  // Operator-only: moves every agent and session stamped `from` to `to` on this gateway.\n  async renameOwner(request: RenameOwnerRequest): Promise<RenameOwnerResponse> {\n    return await this.#call('POST', '/owners/rename', request)\n  }\n\n  async listSdkSessions(params?: { dir?: string; limit?: number; offset?: number; profile?: string }): Promise<SdkSessionSummary[]> {\n    const qs = query({ dir: params?.dir || undefined, limit: params?.limit, offset: params?.offset, profile: params?.profile || undefined })\n    return await this.#pick('GET', `/sdk-sessions${qs}`, 'sdkSessions')\n  }\n\n  async listHostRoots(): Promise<ListHostRootsResponse> {\n    return await this.#call('GET', '/fs/roots')\n  }\n\n  async meta(): Promise<GatewayMeta> {\n    return await this.#call('GET', '/meta')\n  }\n\n  async listHostDir(path: string): Promise<ListHostDirResponse> {\n    return await this.#call('GET', `/fs/list${query({ path })}`)\n  }\n\n  async findHostFiles(path: string, q = '', limit?: number): Promise<FindHostFilesResponse> {\n    return await this.#call('GET', `/fs/find${query({ path, q, limit })}`)\n  }\n\n  async readHostFile(path: string): Promise<ReadHostFileResponse> {\n    return await this.#call('GET', `/fs/read${query({ path })}`)\n  }\n\n  async writeHostFile(request: WriteHostFileRequest): Promise<WriteHostFileResponse> {\n    return await this.#call('PUT', '/fs/write', request)\n  }\n\n  async makeHostDir(path: string): Promise<HostEntryResponse> {\n    return await this.#call('POST', '/fs/mkdir', { path })\n  }\n\n  async deleteHostEntry(path: string, recursive = false): Promise<HostEntryResponse> {\n    return await this.#call('POST', '/fs/delete', { path, recursive })\n  }\n\n  async renameHostEntry(from: string, to: string): Promise<HostEntryResponse> {\n    return await this.#call('POST', '/fs/rename', { from, to })\n  }\n\n  async createJob(request: CreateJobRequest): Promise<JobInfo> {\n    return await this.#pick('POST', '/jobs', 'job', request)\n  }\n\n  async listJobs(): Promise<JobInfo[]> {\n    return await this.#pick('GET', '/jobs', 'jobs')\n  }\n\n  async getJob(id: string): Promise<JobInfo> {\n    return await this.#pick('GET', `/jobs/${encodeURIComponent(id)}`, 'job')\n  }\n\n  async cancelJob(id: string): Promise<JobInfo> {\n    return await this.#pick('DELETE', `/jobs/${encodeURIComponent(id)}`, 'job')\n  }\n\n  async queueStats(): Promise<QueueStats> {\n    return await this.#pick('GET', '/queue', 'stats')\n  }\n\n  async listShells(sessionId: string): Promise<ShellInfo[]> {\n    return await this.#pick('GET', this.#sess(sessionId, '/shells'), 'shells')\n  }\n\n  async getShell(sessionId: string, shellId: string): Promise<ShellInfo> {\n    return await this.#pick('GET', this.#shell(sessionId, shellId), 'shell')\n  }\n\n  async shellOutput(sessionId: string, shellId: string, options?: { view?: 'text' | 'raw' | 'screen'; tail?: number }): Promise<string> {\n    const qs = query({ view: options?.view || undefined, tail: options?.tail })\n    const res = await this.#callRaw(\n      `${this.#options.baseUrl}${this.#shell(sessionId, shellId, `/output${qs}`)}`,\n      { headers: { ...this.#options.headers } },\n      'shell output request failed',\n    )\n    return await res.text()\n  }\n\n  async killShell(sessionId: string, shellId: string): Promise<ShellInfo> {\n    return await this.#pick('POST', this.#shell(sessionId, shellId, '/kill'), 'shell')\n  }\n\n  async stopTask(sessionId: string, toolUseId: string): Promise<void> {\n    await this.#call('POST', this.#sess(sessionId, `/tasks/${encodeURIComponent(toolUseId)}/stop`))\n  }\n\n  async backgroundTask(sessionId: string, toolUseId?: string): Promise<void> {\n    const path = toolUseId === undefined ? '/tasks/background' : `/tasks/${encodeURIComponent(toolUseId)}/background`\n    await this.#call('POST', this.#sess(sessionId, path))\n  }\n\n  async setShellAgentWrite(sessionId: string, shellId: string, enabled: boolean): Promise<ShellInfo> {\n    return await this.#pick('POST', this.#shell(sessionId, shellId, '/agent-write'), 'shell', { enabled })\n  }\n\n  // The last conversation this client saw a session on: the token every mutating call for it carries.\n  conversationOf(sessionId: string): number | undefined {\n    return this.#conversations.get(sessionId)\n  }\n\n  noteConversation(sessionId: string, conversation: number): void {\n    this.#conversations.set(sessionId, conversation)\n  }\n\n  #noteSessions(payload: unknown): void {\n    const body = payload as { session?: SessionInfo; sessions?: SessionInfo[] } | null\n    for (const info of [...(body?.session ? [body.session] : []), ...(Array.isArray(body?.sessions) ? body.sessions : [])]) {\n      if (typeof info?.id === 'string' && typeof info.conversation === 'number') {\n        this.noteConversation(info.id, info.conversation)\n      }\n    }\n  }\n\n  // Protocol 2: a mutating session route names the conversation it is for. The history routes carry their own.\n  #generationHeader(method: string, path: string): Record<string, string> {\n    const match = /^\\/sessions\\/([^/?]+)(\\/[^?]*)?/.exec(path)\n    if (method === 'GET' || !match || match[2]?.startsWith('/conversations')) {\n      return {}\n    }\n    const conversation = this.#conversations.get(decodeURIComponent(match[1]!))\n    return conversation === undefined ? {} : { [GENERATION_HEADER]: String(conversation) }\n  }\n\n  attach(sessionId: string, options?: AttachOptions): SessionHandle {\n    return new SessionHandle(this, sessionId, options)\n  }\n\n  attachQueue(options?: { reconnect?: boolean }): QueueHandle {\n    return new QueueHandle(this, options)\n  }\n\n  openSocket(sessionId: string, afterSeq: number, truncateResults = false, imageRefs = false, conversation?: number): WebSocket {\n    const url =\n      this.#options.buildWsUrl?.(sessionId, afterSeq, truncateResults, imageRefs, conversation) ??\n      sessionWsUrl(this.#options.baseUrl, sessionId, afterSeq, truncateResults, imageRefs, conversation)\n    return new this.#WebSocketImpl(url)\n  }\n\n  async toolResult(sessionId: string, seq: number, toolUseId: string, options?: { imageRefs?: boolean }): Promise<ToolResultResponse> {\n    return await this.#call(\n      'GET',\n      this.#sess(sessionId, `/events/${seq}/result${query({ toolUseId, imageRefs: options?.imageRefs ? 1 : undefined })}`),\n    )\n  }\n\n  async toolResultImage(sessionId: string, seq: number, toolUseId: string, partIndex: number): Promise<Blob> {\n    const url = `${this.#options.baseUrl}${this.#sess(sessionId, `/events/${seq}/result${query({ toolUseId, part: partIndex })}`)}`\n    return await this.#blob(url, 'image part request failed')\n  }\n\n  openQueueSocket(): WebSocket {\n    const url = this.#options.buildQueueWsUrl?.() ?? `${this.#options.baseUrl.replace(/^http/, 'ws')}/queue/ws`\n    return new this.#WebSocketImpl(url)\n  }\n\n  // The byte-serving routes' shared failure arm: `#call` owns the same rule for JSON routes.\n  async #callRaw(url: string, init: NonNullable<Parameters<typeof fetch>[1]>, failure: string): Promise<Response> {\n    const res = await this.#fetch(url, init)\n    if (!res.ok) {\n      const payload = (await res.json().catch(() => ({}))) as { error?: string }\n      throw new WorkerDeckError(payload.error ?? `${failure} with ${res.status}`, res.status)\n    }\n    return res\n  }\n\n  #sess(sessionId: string, suffix = ''): string {\n    return `/sessions/${encodeURIComponent(sessionId)}${suffix}`\n  }\n\n  #agent(id: string, suffix = ''): string {\n    return `/agents/${encodeURIComponent(id)}${suffix}`\n  }\n\n  #shell(sessionId: string, shellId: string, suffix = ''): string {\n    return this.#sess(sessionId, `/shells/${encodeURIComponent(shellId)}${suffix}`)\n  }\n\n  async #blob(url: string, failure: string): Promise<Blob> {\n    const res = await this.#callRaw(url, { headers: { ...this.#options.headers } }, failure)\n    return await res.blob()\n  }\n\n  async #pick<T>(method: string, path: string, key: string, body?: unknown): Promise<T> {\n    const payload = await this.#call<Record<string, T>>(method, path, body)\n    return payload[key]!\n  }\n\n  async #call<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n    const res = await this.#fetch(`${this.#options.baseUrl}${path}`, {\n      method,\n      headers: {\n        ...(body !== undefined ? { 'content-type': 'application/json' } : {}),\n        ...this.#generationHeader(method, path),\n        ...this.#options.headers,\n      },\n      body: body !== undefined ? JSON.stringify(body) : undefined,\n    })\n    const payload = (await res.json().catch(() => ({}))) as { error?: string }\n    if (!res.ok) {\n      throw new WorkerDeckError(payload.error ?? `${method} ${path} failed with ${res.status}`, res.status, payload)\n    }\n    this.#noteSessions(payload)\n    return payload as T\n  }\n}\n\nfunction query(params: Record<string, string | number | undefined>): string {\n  const search = new URLSearchParams()\n  for (const [name, value] of Object.entries(params)) {\n    if (value !== undefined) {\n      search.set(name, String(value))\n    }\n  }\n  return search.size > 0 ? `?${search.toString()}` : ''\n}\n\nexport { SessionHandle } from './session-handle.ts'\nexport type { AttachOptions, SessionHandleEvents } from './session-handle.ts'\nexport { QueueHandle } from './queue-handle.ts'\nexport type { QueueHandleEvents } from './queue-handle.ts'\nexport { apiUrl, isLoopbackHost } from './host-url.ts'\nexport type { HostUrl } from './host-url.ts'\nexport { hostAuth } from './host-auth.ts'\nexport {\n  runTeamMove,\n  teamMoveMessage,\n  withdrawTeamInvitation,\n  type TeamInvitation,\n  type TeamMoveOutcome,\n  type TeamMovePlan,\n} from './team-move.ts'\n"],"mappings":"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"}