adhdev 0.9.40 → 0.9.42

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,"sources":["../src/index.ts","../src/buffer.ts","../src/registry.ts","../src/defaults.ts","../src/runtime-labels.ts","../src/ipc.ts","../src/spawn-env.ts"],"sourcesContent":["export type {\n AcquireWritePayload,\n AttachSessionPayload,\n ClearSessionBufferPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ForceDetachClientPayload,\n GetHostDiagnosticsPayload,\n GetSnapshotPayload,\n PruneDuplicateSessionsPayload,\n ReleaseWritePayload,\n ResumeSessionPayload,\n RestartSessionPayload,\n ResizeSessionPayload,\n SendSignalPayload,\n SendInputPayload,\n UpdateSessionMetaPayload,\n SessionAttachedClient,\n SessionBufferSnapshot,\n SessionClientType,\n SessionHostDiagnostics,\n SessionHostDuplicateSessionGroup,\n SessionHostCategory,\n SessionHostSurfaceKind,\n SessionHostEvent,\n SessionHostEventEnvelope,\n SessionHostLogEntry,\n SessionHostPruneDuplicatesResult,\n SessionHostRecord,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostRequestTrace,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostRuntimeTransition,\n SessionLaunchCommand,\n SessionLifecycle,\n SessionOwnerType,\n SessionTransport,\n SessionHostWireEnvelope,\n SessionWriteOwner,\n StopSessionPayload,\n} from './types.js';\n\nexport { SessionRingBuffer } from './buffer.js';\nexport type { SessionRingBufferOptions } from './buffer.js';\nexport { SessionHostRegistry } from './registry.js';\nexport {\n buildRuntimeDisplayName,\n buildRuntimeKey,\n formatRuntimeOwner,\n getSessionHostRecoveryLabel,\n getSessionHostSurfaceKind,\n getWorkspaceLabel,\n isSessionHostLiveRuntime,\n isSessionHostRecoverySnapshot,\n resolveAttachableRuntimeRecord,\n resolveRuntimeRecord,\n} from './runtime-labels.js';\nexport {\n SessionHostClient,\n createLineParser,\n createResponseEnvelope,\n getDefaultSessionHostEndpoint,\n writeEnvelope,\n} from './ipc.js';\nexport type { SessionHostClientOptions, SessionHostEndpoint } from './ipc.js';\nexport {\n DEFAULT_SESSION_HOST_COLS,\n DEFAULT_SESSION_HOST_ROWS,\n resolveSessionHostCols,\n resolveSessionHostRows,\n} from './defaults.js';\nexport {\n sanitizeSpawnEnv,\n applyTerminalColorEnv,\n ensureNodePtySpawnHelperPermissions,\n} from './spawn-env.js';\n","import type { SessionBufferSnapshot } from './types.js';\n\nexport interface SessionRingBufferOptions {\n maxBytes?: number;\n}\n\nexport class SessionRingBuffer {\n private maxBytes: number;\n private chunks: { seq: number; data: string; bytes: number }[] = [];\n private nextSeq = 1;\n private totalBytes = 0;\n\n constructor(options: SessionRingBufferOptions = {}) {\n this.maxBytes = options.maxBytes ?? 512 * 1024;\n }\n\n append(data: string): number {\n const normalized = typeof data === 'string' ? data : String(data ?? '');\n const bytes = Buffer.byteLength(normalized, 'utf8');\n const seq = this.nextSeq++;\n\n this.chunks.push({ seq, data: normalized, bytes });\n this.totalBytes += bytes;\n this.trim();\n return seq;\n }\n\n snapshot(sinceSeq?: number): SessionBufferSnapshot {\n const relevant = typeof sinceSeq === 'number'\n ? this.chunks.filter(chunk => chunk.seq > sinceSeq)\n : this.chunks;\n\n const text = relevant.map(chunk => chunk.data).join('');\n const truncated = !!this.chunks[0] && typeof sinceSeq === 'number' && sinceSeq < this.chunks[0].seq - 1;\n\n return {\n seq: this.nextSeq - 1,\n text,\n truncated,\n };\n }\n\n getState(): { scrollbackBytes: number; snapshotSeq: number } {\n return {\n scrollbackBytes: this.totalBytes,\n snapshotSeq: this.nextSeq - 1,\n };\n }\n\n clear(): void {\n this.chunks = [];\n this.totalBytes = 0;\n this.nextSeq = 1;\n }\n\n restore(snapshot: { seq: number; text: string }): void {\n this.clear();\n const text = String(snapshot.text || '');\n if (!text) {\n this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);\n return;\n }\n const bytes = Buffer.byteLength(text, 'utf8');\n const seq = Math.max(1, Number(snapshot.seq || 1));\n this.chunks = [{ seq, data: text, bytes }];\n this.totalBytes = bytes;\n this.nextSeq = seq + 1;\n this.trim();\n }\n\n private trim(): void {\n while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {\n const removed = this.chunks.shift();\n if (!removed) break;\n this.totalBytes -= removed.bytes;\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type {\n AcquireWritePayload,\n AttachSessionPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ReleaseWritePayload,\n SessionAttachedClient,\n SessionHostRecord,\n} from './types.js';\nimport { SessionRingBuffer } from './buffer.js';\nimport { resolveSessionHostCols, resolveSessionHostRows } from './defaults.js';\nimport { buildRuntimeDisplayName, buildRuntimeKey, getWorkspaceLabel } from './runtime-labels.js';\n\ninterface SessionRuntimeState {\n record: SessionHostRecord;\n buffer: SessionRingBuffer;\n}\n\nexport class SessionHostRegistry {\n private sessions = new Map<string, SessionRuntimeState>();\n\n createSession(payload: CreateSessionPayload): SessionHostRecord {\n const sessionId = payload.sessionId || randomUUID();\n if (this.sessions.has(sessionId)) {\n throw new Error(`Session already exists: ${sessionId}`);\n }\n const now = Date.now();\n const initialClient = payload.clientId\n ? [{\n clientId: payload.clientId,\n type: payload.clientType || 'daemon',\n readOnly: false,\n attachedAt: now,\n lastSeenAt: now,\n } satisfies SessionAttachedClient]\n : [];\n\n const record: SessionHostRecord = {\n sessionId,\n runtimeKey: buildRuntimeKey(\n payload,\n Array.from(this.sessions.values(), (state) => state.record.runtimeKey),\n ),\n displayName: buildRuntimeDisplayName(payload),\n workspaceLabel: getWorkspaceLabel(payload.workspace),\n transport: 'pty',\n providerType: payload.providerType,\n category: payload.category,\n workspace: payload.workspace,\n launchCommand: payload.launchCommand,\n createdAt: now,\n lastActivityAt: now,\n lifecycle: 'starting',\n writeOwner: null,\n attachedClients: initialClient,\n buffer: {\n scrollbackBytes: 0,\n snapshotSeq: 0,\n },\n meta: payload.meta || {},\n };\n\n record.meta = {\n sessionHostCols: resolveSessionHostCols(payload.cols),\n sessionHostRows: resolveSessionHostRows(payload.rows),\n ...record.meta,\n };\n\n this.sessions.set(sessionId, {\n record,\n buffer: new SessionRingBuffer(),\n });\n\n return this.cloneRecord(record);\n }\n\n restoreSession(record: SessionHostRecord, snapshot?: { seq: number; text: string } | null): SessionHostRecord {\n const cloned = this.cloneRecord(record);\n this.sessions.set(cloned.sessionId, {\n record: cloned,\n buffer: (() => {\n const buffer = new SessionRingBuffer();\n if (snapshot) buffer.restore(snapshot);\n return buffer;\n })(),\n });\n return this.cloneRecord(cloned);\n }\n\n listSessions(): SessionHostRecord[] {\n return Array.from(this.sessions.values())\n .map(state => this.cloneRecord(state.record))\n .sort((a, b) => b.lastActivityAt - a.lastActivityAt);\n }\n\n getSession(sessionId: string): SessionHostRecord | null {\n const state = this.sessions.get(sessionId);\n return state ? this.cloneRecord(state.record) : null;\n }\n\n attachClient(payload: AttachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const now = Date.now();\n let removedDaemonOwner = false;\n\n if (payload.clientType === 'daemon') {\n const staleDaemonClientIds = state.record.attachedClients\n .filter(client => client.type === 'daemon' && client.clientId !== payload.clientId)\n .map(client => client.clientId);\n if (staleDaemonClientIds.length > 0) {\n state.record.attachedClients = state.record.attachedClients.filter(\n client => !(client.type === 'daemon' && client.clientId !== payload.clientId),\n );\n if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {\n removedDaemonOwner = true;\n }\n }\n }\n\n const existing = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n\n if (existing) {\n existing.type = payload.clientType;\n existing.readOnly = !!payload.readOnly;\n existing.lastSeenAt = now;\n } else {\n state.record.attachedClients.push({\n clientId: payload.clientId,\n type: payload.clientType,\n readOnly: !!payload.readOnly,\n attachedAt: now,\n lastSeenAt: now,\n });\n }\n\n if (removedDaemonOwner) {\n state.record.writeOwner = null;\n }\n\n state.record.lastActivityAt = now;\n return this.cloneRecord(state.record);\n }\n\n detachClient(payload: DetachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n state.record.attachedClients = state.record.attachedClients.filter(client => client.clientId !== payload.clientId);\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n acquireWrite(payload: AcquireWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {\n throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);\n }\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n state.record.writeOwner = {\n clientId: payload.clientId,\n ownerType: payload.ownerType,\n acquiredAt: Date.now(),\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n releaseWrite(payload: ReleaseWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n appendOutput(sessionId: string, data: string): { record: SessionHostRecord; seq: number } {\n const state = this.requireSession(sessionId);\n const seq = state.buffer.append(data);\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return { record: this.cloneRecord(state.record), seq };\n }\n\n getSnapshot(sessionId: string, sinceSeq?: number) {\n const state = this.requireSession(sessionId);\n state.record.buffer = state.buffer.getState();\n return state.buffer.snapshot(sinceSeq);\n }\n\n clearBuffer(sessionId: string): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.buffer.clear();\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n updateSessionMeta(sessionId: string, meta: Record<string, unknown>, replace = false): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.meta = replace\n ? { ...meta }\n : {\n ...(state.record.meta || {}),\n ...meta,\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStarted(sessionId: string, pid?: number): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = 'running';\n state.record.startedAt = state.record.startedAt || Date.now();\n if (typeof pid === 'number') state.record.osPid = pid;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStopped(sessionId: string, lifecycle: 'stopped' | 'failed' = 'stopped'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n setLifecycle(sessionId: string, lifecycle: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n deleteSession(sessionId: string): boolean {\n return this.sessions.delete(sessionId);\n }\n\n private requireSession(sessionId: string): SessionRuntimeState {\n const state = this.sessions.get(sessionId);\n if (!state) throw new Error(`Unknown session: ${sessionId}`);\n return state;\n }\n\n private cloneRecord(record: SessionHostRecord): SessionHostRecord {\n return {\n ...record,\n launchCommand: {\n ...record.launchCommand,\n args: [...record.launchCommand.args],\n env: record.launchCommand.env ? { ...record.launchCommand.env } : undefined,\n },\n writeOwner: record.writeOwner ? { ...record.writeOwner } : null,\n attachedClients: record.attachedClients.map(client => ({ ...client })),\n buffer: { ...record.buffer },\n meta: { ...record.meta },\n };\n }\n}\n","export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n","import * as path from 'path';\nimport type { CreateSessionPayload, SessionHostRecord, SessionHostSurfaceKind } from './types.js';\n\nfunction normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n}\n\nfunction normalizeValue(input: string): string {\n return input.trim().toLowerCase();\n}\n\nexport function getWorkspaceLabel(workspace: string): string {\n const trimmed = workspace.trim();\n if (!trimmed) return 'workspace';\n const normalized = trimmed.replace(/[\\\\/]+$/, '');\n const base = path.basename(normalized);\n return base || normalized;\n}\n\nexport function buildRuntimeDisplayName(payload: Pick<CreateSessionPayload, 'displayName' | 'providerType' | 'workspace'>): string {\n const explicit = payload.displayName?.trim();\n if (explicit) return explicit;\n const workspaceLabel = getWorkspaceLabel(payload.workspace);\n const providerLabel = payload.providerType.trim() || 'runtime';\n return `${providerLabel} @ ${workspaceLabel}`;\n}\n\nexport function buildRuntimeKey(\n payload: Pick<CreateSessionPayload, 'runtimeKey' | 'displayName' | 'providerType' | 'workspace'>,\n existingKeys: Iterable<string>,\n): string {\n const requested = payload.runtimeKey?.trim();\n const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));\n const displayName = buildRuntimeDisplayName(payload);\n const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || 'runtime') || 'runtime';\n if (!existing.has(baseKey)) return baseKey;\n\n let suffix = 2;\n let candidate = `${baseKey}-${suffix}`;\n while (existing.has(candidate)) {\n suffix += 1;\n candidate = `${baseKey}-${suffix}`;\n }\n return candidate;\n}\n\nexport interface SessionHostSurfaceRecordLike {\n lifecycle?: string | null;\n surfaceKind?: SessionHostSurfaceKind | null;\n meta?: Record<string, unknown> | null;\n}\n\nconst LIVE_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'interrupted']);\n\nexport function isSessionHostLiveRuntime(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'live_runtime') return true;\n if (record.surfaceKind === 'recovery_snapshot' || record.surfaceKind === 'inactive_record') return false;\n const lifecycle = String(record.lifecycle || '').trim();\n return LIVE_LIFECYCLES.has(lifecycle);\n}\n\nexport function getSessionHostRecoveryLabel(meta: Record<string, unknown> | null | undefined): string | null {\n const recoveryState = typeof meta?.runtimeRecoveryState === 'string'\n ? String(meta.runtimeRecoveryState).trim()\n : '';\n if (!recoveryState) return null;\n if (recoveryState === 'auto_resumed') return 'restored after restart';\n if (recoveryState === 'resume_failed') return 'restore failed';\n if (recoveryState === 'host_restart_interrupted') return 'host restart interrupted';\n if (recoveryState === 'orphan_snapshot') return 'snapshot recovered';\n return recoveryState.replace(/_/g, ' ');\n}\n\nexport function isSessionHostRecoverySnapshot(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'recovery_snapshot') return true;\n if (record.surfaceKind === 'live_runtime' || record.surfaceKind === 'inactive_record') return false;\n if (isSessionHostLiveRuntime(record)) return false;\n\n const lifecycle = String(record.lifecycle || '').trim();\n if (lifecycle && lifecycle !== 'stopped' && lifecycle !== 'failed') {\n return false;\n }\n\n const meta = record.meta || undefined;\n if (meta?.restoredFromStorage === true) return true;\n return getSessionHostRecoveryLabel(meta) !== null;\n}\n\nexport function getSessionHostSurfaceKind(record: SessionHostSurfaceRecordLike | null | undefined): SessionHostSurfaceKind {\n if (record?.surfaceKind === 'live_runtime' || record?.surfaceKind === 'recovery_snapshot' || record?.surfaceKind === 'inactive_record') {\n return record.surfaceKind;\n }\n if (isSessionHostLiveRuntime(record)) return 'live_runtime';\n if (isSessionHostRecoverySnapshot(record)) return 'recovery_snapshot';\n return 'inactive_record';\n}\n\nexport function resolveAttachableRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const record = resolveRuntimeRecord(records, identifier);\n const surfaceKind = getSessionHostSurfaceKind(record);\n if (surfaceKind === 'live_runtime') {\n return record;\n }\n if (surfaceKind === 'recovery_snapshot') {\n throw new Error(`Runtime ${record.runtimeKey} is a recovery snapshot, not a live attach target. Resume or recover it first.`);\n }\n throw new Error(`Runtime ${record.runtimeKey} is ${record.lifecycle}, not a live attach target.`);\n}\n\nfunction uniqueMatch(records: SessionHostRecord[], predicate: (record: SessionHostRecord) => boolean): SessionHostRecord | null {\n const matches = records.filter(predicate);\n if (matches.length === 1) return matches[0] || null;\n if (matches.length === 0) return null;\n const labels = matches.map((record) => `${record.runtimeKey} (${record.sessionId})`).join(', ');\n throw new Error(`Ambiguous runtime target. Matches: ${labels}`);\n}\n\nexport function resolveRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const target = identifier.trim();\n if (!target) {\n throw new Error('Runtime target is required');\n }\n\n const exact = uniqueMatch(records, (record) =>\n record.sessionId === target ||\n normalizeValue(record.runtimeKey) === normalizeValue(target) ||\n normalizeValue(record.displayName) === normalizeValue(target),\n );\n if (exact) return exact;\n\n const prefix = uniqueMatch(records, (record) =>\n record.sessionId.startsWith(target) ||\n normalizeValue(record.runtimeKey).startsWith(normalizeValue(target)),\n );\n if (prefix) return prefix;\n\n throw new Error(`Unknown runtime target: ${target}`);\n}\n\nexport function formatRuntimeOwner(record: Pick<SessionHostRecord, 'writeOwner'>): string {\n if (!record.writeOwner) return 'none';\n return `${record.writeOwner.ownerType}:${record.writeOwner.clientId}`;\n}\n","import * as os from 'os';\nimport * as path from 'path';\nimport * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport type {\n SessionHostEvent,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostWireEnvelope,\n} from './types.js';\n\nexport interface SessionHostEndpoint {\n kind: 'unix' | 'pipe';\n path: string;\n}\n\nexport function getDefaultSessionHostEndpoint(appName = 'adhdev'): SessionHostEndpoint {\n if (process.platform === 'win32') {\n return {\n kind: 'pipe',\n path: `\\\\\\\\.\\\\pipe\\\\${appName}-session-host`,\n };\n }\n\n return {\n kind: 'unix',\n path: path.join(os.tmpdir(), `${appName}-session-host.sock`),\n };\n}\n\nfunction serializeEnvelope(envelope: SessionHostWireEnvelope): string {\n return `${JSON.stringify(envelope)}\\n`;\n}\n\nfunction createLineParser(onEnvelope: (envelope: SessionHostWireEnvelope) => void) {\n let buffer = '';\n return (chunk: Buffer | string) => {\n buffer += chunk.toString();\n let newlineIndex = buffer.indexOf('\\n');\n while (newlineIndex >= 0) {\n const rawLine = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n if (rawLine) {\n onEnvelope(JSON.parse(rawLine) as SessionHostWireEnvelope);\n }\n newlineIndex = buffer.indexOf('\\n');\n }\n };\n}\n\nexport interface SessionHostClientOptions {\n endpoint?: SessionHostEndpoint;\n appName?: string;\n}\n\nexport class SessionHostClient {\n readonly endpoint: SessionHostEndpoint;\n\n private socket: net.Socket | null = null;\n private requestWaiters = new Map<string, { resolve: (value: SessionHostResponse) => void; reject: (error: Error) => void }>();\n private eventListeners = new Set<(event: SessionHostEvent) => void>();\n\n constructor(options: SessionHostClientOptions = {}) {\n this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || 'adhdev');\n }\n\n async connect(): Promise<void> {\n if (this.socket && !this.socket.destroyed) return;\n // Cleanup stale socket reference left after error/disconnect\n if (this.socket) {\n try { this.socket.destroy(); } catch { /* noop */ }\n this.socket = null;\n }\n\n const socket = net.createConnection(this.endpoint.path);\n this.socket = socket;\n\n socket.on('data', createLineParser((envelope) => {\n if (envelope.kind === 'response') {\n const waiter = this.requestWaiters.get(envelope.requestId);\n if (waiter) {\n this.requestWaiters.delete(envelope.requestId);\n waiter.resolve(envelope.response);\n }\n return;\n }\n\n if (envelope.kind === 'event') {\n for (const listener of this.eventListeners) listener(envelope.event);\n }\n }));\n\n socket.on('error', (error) => {\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(error);\n }\n this.requestWaiters.clear();\n // Clear the dead socket reference so the next connect() creates a fresh connection\n // instead of skipping reconnection on the `!this.socket.destroyed` guard.\n if (this.socket === socket) {\n this.socket = null;\n }\n try { socket.destroy(); } catch { /* noop */ }\n });\n\n await new Promise<void>((resolve, reject) => {\n socket.once('connect', () => resolve());\n socket.once('error', reject);\n });\n }\n\n onEvent(listener: (event: SessionHostEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n async request<T = unknown>(request: SessionHostRequest): Promise<SessionHostResponse<T>> {\n await this.connect();\n if (!this.socket) throw new Error('Session host socket unavailable');\n\n const requestId = randomUUID();\n const envelope: SessionHostRequestEnvelope = {\n kind: 'request',\n requestId,\n request,\n };\n\n const response = await new Promise<SessionHostResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.requestWaiters.delete(requestId);\n reject(new Error(`Session host request timed out after 30s (${request.type})`));\n }, 30_000);\n this.requestWaiters.set(requestId, {\n resolve: (value) => { clearTimeout(timeout); resolve(value); },\n reject: (error) => { clearTimeout(timeout); reject(error); },\n });\n this.socket?.write(serializeEnvelope(envelope));\n });\n\n return response as SessionHostResponse<T>;\n }\n\n async close(): Promise<void> {\n if (!this.socket) return;\n const socket = this.socket;\n this.socket = null;\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(new Error('Session host client closed'));\n }\n this.requestWaiters.clear();\n await new Promise<void>((resolve) => {\n let settled = false;\n const done = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n socket.once('close', done);\n socket.end();\n socket.destroy();\n setTimeout(done, 50);\n });\n }\n}\n\nexport function createResponseEnvelope(requestId: string, response: SessionHostResponse): SessionHostResponseEnvelope {\n return {\n kind: 'response',\n requestId,\n response,\n };\n}\n\nexport function writeEnvelope(socket: Pick<net.Socket, 'write'>, envelope: SessionHostWireEnvelope): void {\n socket.write(serializeEnvelope(envelope));\n}\n\nexport { createLineParser };\n","/**\n * Shared PTY spawn environment utilities.\n *\n * Centralises npm/pnpm/yarn env variable stripping, terminal colour env\n * injection, and node-pty spawn-helper permission fixing.\n *\n * Used by daemon-core (provider-cli-adapter), session-host-daemon (runtime),\n * and daemon-cloud (session-host).\n */\n\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Strip package-manager injected environment variables that can interfere\n * with child CLI processes and apply terminal colour defaults.\n */\nexport function sanitizeSpawnEnv(\n baseEnv: NodeJS.ProcessEnv,\n overrides?: Record<string, string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const source = { ...baseEnv, ...(overrides || {}) } as NodeJS.ProcessEnv;\n\n for (const [key, value] of Object.entries(source)) {\n if (typeof value !== 'string') continue;\n env[key] = value;\n }\n\n for (const key of Object.keys(env)) {\n if (\n key === 'INIT_CWD'\n || key === 'npm_command'\n || key === 'npm_execpath'\n || key === 'npm_node_execpath'\n || key.startsWith('npm_')\n || key.startsWith('npm_config_')\n || key.startsWith('npm_package_')\n || key.startsWith('npm_lifecycle_')\n || key.startsWith('PNPM_')\n || key.startsWith('YARN_')\n || key.startsWith('BUN_')\n || key.startsWith('VSCODE_')\n || key.startsWith('ELECTRON_')\n ) {\n delete env[key];\n }\n }\n\n // Do not leak the parent Codex app/extension thread identity into child CLIs.\n // Those variables cause codex-cli to attach to the current IDE thread instead\n // of creating or resuming its own standalone CLI thread, which breaks\n // providerSessionId discovery and reconnect semantics.\n delete env.CODEX_THREAD_ID;\n delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;\n\n applyTerminalColorEnv(env);\n return env;\n}\n\n/**\n * Apply preferred terminal colour environment variables.\n * Ensures TERM is set to xterm-256color and enables colour on Windows.\n */\nexport function applyTerminalColorEnv(env: Record<string, string>): void {\n if (env.NO_COLOR) return;\n\n if (!env.TERM || env.TERM === 'xterm-color') {\n env.TERM = 'xterm-256color';\n }\n if (!env.COLORTERM) env.COLORTERM = 'truecolor';\n\n if (process.platform === 'win32') {\n if (!env.FORCE_COLOR) env.FORCE_COLOR = '1';\n if (!env.CLICOLOR) env.CLICOLOR = '1';\n }\n}\n\n/**\n * Ensure node-pty's spawn-helper binary has execute permissions.\n *\n * npm's default umask can strip +x from the prebuilt spawn-helper on macOS/Linux,\n * causing EACCES when node-pty tries to fork. Best-effort fix.\n *\n * @param logFn Optional log callback for reporting the fix.\n */\nexport function ensureNodePtySpawnHelperPermissions(\n logFn?: (msg: string) => void,\n): void {\n if (os.platform() === 'win32') return;\n try {\n const fs = require('fs');\n const ptyDir = path.resolve(path.dirname(require.resolve('node-pty')), '..');\n const platformArch = `${os.platform()}-${os.arch()}`;\n const helper = path.join(ptyDir, 'prebuilds', platformArch, 'spawn-helper');\n if (fs.existsSync(helper)) {\n const stat = fs.statSync(helper);\n if (!(stat.mode & 0o111)) {\n fs.chmodSync(helper, stat.mode | 0o755);\n logFn?.(`Fixed spawn-helper permissions: ${helper}`);\n }\n }\n } catch {\n // best-effort: node-pty still works on most installs without this\n }\n}\n"],"mappings":"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","names":["path","import_crypto","resolve","os","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/buffer.ts","../src/registry.ts","../src/defaults.ts","../src/runtime-labels.ts","../src/ipc.ts","../src/spawn-env.ts"],"sourcesContent":["export type {\n AcquireWritePayload,\n AttachSessionPayload,\n ClearSessionBufferPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ForceDetachClientPayload,\n GetHostDiagnosticsPayload,\n GetSnapshotPayload,\n PruneDuplicateSessionsPayload,\n ReleaseWritePayload,\n ResumeSessionPayload,\n RestartSessionPayload,\n ResizeSessionPayload,\n SendSignalPayload,\n SendInputPayload,\n UpdateSessionMetaPayload,\n SessionAttachedClient,\n SessionBufferSnapshot,\n SessionClientType,\n SessionHostDiagnostics,\n SessionHostDuplicateSessionGroup,\n SessionHostCategory,\n SessionHostSurfaceKind,\n SessionHostEvent,\n SessionHostEventEnvelope,\n SessionHostLogEntry,\n SessionHostPruneDuplicatesResult,\n SessionHostRecord,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostRequestTrace,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostRuntimeTransition,\n SessionLaunchCommand,\n SessionLifecycle,\n SessionOwnerType,\n SessionTransport,\n SessionHostWireEnvelope,\n SessionWriteOwner,\n StopSessionPayload,\n} from './types.js';\n\nexport { DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, SessionRingBuffer } from './buffer.js';\nexport type { SessionRingBufferOptions } from './buffer.js';\nexport { SessionHostRegistry } from './registry.js';\nexport {\n buildRuntimeDisplayName,\n buildRuntimeKey,\n formatRuntimeOwner,\n getSessionHostRecoveryLabel,\n getSessionHostSurfaceKind,\n getWorkspaceLabel,\n isSessionHostLiveRuntime,\n isSessionHostRecoverySnapshot,\n resolveAttachableRuntimeRecord,\n resolveRuntimeRecord,\n} from './runtime-labels.js';\nexport {\n SessionHostClient,\n createLineParser,\n createResponseEnvelope,\n getDefaultSessionHostEndpoint,\n writeEnvelope,\n} from './ipc.js';\nexport type { SessionHostClientOptions, SessionHostEndpoint } from './ipc.js';\nexport {\n DEFAULT_SESSION_HOST_COLS,\n DEFAULT_SESSION_HOST_ROWS,\n resolveSessionHostCols,\n resolveSessionHostRows,\n} from './defaults.js';\nexport {\n sanitizeSpawnEnv,\n applyTerminalColorEnv,\n ensureNodePtySpawnHelperPermissions,\n} from './spawn-env.js';\n","import type { SessionBufferSnapshot } from './types.js';\n\nexport interface SessionRingBufferOptions {\n maxBytes?: number;\n}\n\n// Manual \"Load older terminal output\" replays this raw ring buffer into the\n// browser terminal. 512KiB was too small for long Claude/Codex conversations:\n// by the time the user scrolled to the top and clicked the loader, the output\n// they were trying to recover was often already trimmed.\nexport const DEFAULT_SESSION_RING_BUFFER_MAX_BYTES = 4 * 1024 * 1024;\n\nexport class SessionRingBuffer {\n private maxBytes: number;\n private chunks: { seq: number; data: string; bytes: number }[] = [];\n private nextSeq = 1;\n private totalBytes = 0;\n\n constructor(options: SessionRingBufferOptions = {}) {\n this.maxBytes = options.maxBytes ?? DEFAULT_SESSION_RING_BUFFER_MAX_BYTES;\n }\n\n append(data: string): number {\n const normalized = typeof data === 'string' ? data : String(data ?? '');\n const bytes = Buffer.byteLength(normalized, 'utf8');\n const seq = this.nextSeq++;\n\n this.chunks.push({ seq, data: normalized, bytes });\n this.totalBytes += bytes;\n this.trim();\n return seq;\n }\n\n snapshot(sinceSeq?: number): SessionBufferSnapshot {\n const relevant = typeof sinceSeq === 'number'\n ? this.chunks.filter(chunk => chunk.seq > sinceSeq)\n : this.chunks;\n\n const text = relevant.map(chunk => chunk.data).join('');\n const truncated = !!this.chunks[0] && typeof sinceSeq === 'number' && sinceSeq < this.chunks[0].seq - 1;\n\n return {\n seq: this.nextSeq - 1,\n text,\n truncated,\n };\n }\n\n getState(): { scrollbackBytes: number; snapshotSeq: number } {\n return {\n scrollbackBytes: this.totalBytes,\n snapshotSeq: this.nextSeq - 1,\n };\n }\n\n clear(): void {\n this.chunks = [];\n this.totalBytes = 0;\n this.nextSeq = 1;\n }\n\n restore(snapshot: { seq: number; text: string }): void {\n this.clear();\n const text = String(snapshot.text || '');\n if (!text) {\n this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);\n return;\n }\n const bytes = Buffer.byteLength(text, 'utf8');\n const seq = Math.max(1, Number(snapshot.seq || 1));\n this.chunks = [{ seq, data: text, bytes }];\n this.totalBytes = bytes;\n this.nextSeq = seq + 1;\n this.trim();\n }\n\n private trim(): void {\n while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {\n const removed = this.chunks.shift();\n if (!removed) break;\n this.totalBytes -= removed.bytes;\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type {\n AcquireWritePayload,\n AttachSessionPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ReleaseWritePayload,\n SessionAttachedClient,\n SessionHostRecord,\n} from './types.js';\nimport { SessionRingBuffer } from './buffer.js';\nimport { resolveSessionHostCols, resolveSessionHostRows } from './defaults.js';\nimport { buildRuntimeDisplayName, buildRuntimeKey, getWorkspaceLabel } from './runtime-labels.js';\n\ninterface SessionRuntimeState {\n record: SessionHostRecord;\n buffer: SessionRingBuffer;\n}\n\nexport class SessionHostRegistry {\n private sessions = new Map<string, SessionRuntimeState>();\n\n createSession(payload: CreateSessionPayload): SessionHostRecord {\n const sessionId = payload.sessionId || randomUUID();\n if (this.sessions.has(sessionId)) {\n throw new Error(`Session already exists: ${sessionId}`);\n }\n const now = Date.now();\n const initialClient = payload.clientId\n ? [{\n clientId: payload.clientId,\n type: payload.clientType || 'daemon',\n readOnly: false,\n attachedAt: now,\n lastSeenAt: now,\n } satisfies SessionAttachedClient]\n : [];\n\n const record: SessionHostRecord = {\n sessionId,\n runtimeKey: buildRuntimeKey(\n payload,\n Array.from(this.sessions.values(), (state) => state.record.runtimeKey),\n ),\n displayName: buildRuntimeDisplayName(payload),\n workspaceLabel: getWorkspaceLabel(payload.workspace),\n transport: 'pty',\n providerType: payload.providerType,\n category: payload.category,\n workspace: payload.workspace,\n launchCommand: payload.launchCommand,\n createdAt: now,\n lastActivityAt: now,\n lifecycle: 'starting',\n writeOwner: null,\n attachedClients: initialClient,\n buffer: {\n scrollbackBytes: 0,\n snapshotSeq: 0,\n },\n meta: payload.meta || {},\n };\n\n record.meta = {\n sessionHostCols: resolveSessionHostCols(payload.cols),\n sessionHostRows: resolveSessionHostRows(payload.rows),\n ...record.meta,\n };\n\n this.sessions.set(sessionId, {\n record,\n buffer: new SessionRingBuffer(),\n });\n\n return this.cloneRecord(record);\n }\n\n restoreSession(record: SessionHostRecord, snapshot?: { seq: number; text: string } | null): SessionHostRecord {\n const cloned = this.cloneRecord(record);\n this.sessions.set(cloned.sessionId, {\n record: cloned,\n buffer: (() => {\n const buffer = new SessionRingBuffer();\n if (snapshot) buffer.restore(snapshot);\n return buffer;\n })(),\n });\n return this.cloneRecord(cloned);\n }\n\n listSessions(): SessionHostRecord[] {\n return Array.from(this.sessions.values())\n .map(state => this.cloneRecord(state.record))\n .sort((a, b) => b.lastActivityAt - a.lastActivityAt);\n }\n\n getSession(sessionId: string): SessionHostRecord | null {\n const state = this.sessions.get(sessionId);\n return state ? this.cloneRecord(state.record) : null;\n }\n\n attachClient(payload: AttachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const now = Date.now();\n let removedDaemonOwner = false;\n\n if (payload.clientType === 'daemon') {\n const staleDaemonClientIds = state.record.attachedClients\n .filter(client => client.type === 'daemon' && client.clientId !== payload.clientId)\n .map(client => client.clientId);\n if (staleDaemonClientIds.length > 0) {\n state.record.attachedClients = state.record.attachedClients.filter(\n client => !(client.type === 'daemon' && client.clientId !== payload.clientId),\n );\n if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {\n removedDaemonOwner = true;\n }\n }\n }\n\n const existing = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n\n if (existing) {\n existing.type = payload.clientType;\n existing.readOnly = !!payload.readOnly;\n existing.lastSeenAt = now;\n } else {\n state.record.attachedClients.push({\n clientId: payload.clientId,\n type: payload.clientType,\n readOnly: !!payload.readOnly,\n attachedAt: now,\n lastSeenAt: now,\n });\n }\n\n if (removedDaemonOwner) {\n state.record.writeOwner = null;\n }\n\n state.record.lastActivityAt = now;\n return this.cloneRecord(state.record);\n }\n\n detachClient(payload: DetachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n state.record.attachedClients = state.record.attachedClients.filter(client => client.clientId !== payload.clientId);\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n acquireWrite(payload: AcquireWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {\n throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);\n }\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n state.record.writeOwner = {\n clientId: payload.clientId,\n ownerType: payload.ownerType,\n acquiredAt: Date.now(),\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n releaseWrite(payload: ReleaseWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n appendOutput(sessionId: string, data: string): { record: SessionHostRecord; seq: number } {\n const state = this.requireSession(sessionId);\n const seq = state.buffer.append(data);\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return { record: this.cloneRecord(state.record), seq };\n }\n\n getSnapshot(sessionId: string, sinceSeq?: number) {\n const state = this.requireSession(sessionId);\n state.record.buffer = state.buffer.getState();\n return state.buffer.snapshot(sinceSeq);\n }\n\n clearBuffer(sessionId: string): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.buffer.clear();\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n updateSessionMeta(sessionId: string, meta: Record<string, unknown>, replace = false): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.meta = replace\n ? { ...meta }\n : {\n ...(state.record.meta || {}),\n ...meta,\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStarted(sessionId: string, pid?: number): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = 'running';\n state.record.startedAt = state.record.startedAt || Date.now();\n if (typeof pid === 'number') state.record.osPid = pid;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStopped(sessionId: string, lifecycle: 'stopped' | 'failed' = 'stopped'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n setLifecycle(sessionId: string, lifecycle: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n deleteSession(sessionId: string): boolean {\n return this.sessions.delete(sessionId);\n }\n\n private requireSession(sessionId: string): SessionRuntimeState {\n const state = this.sessions.get(sessionId);\n if (!state) throw new Error(`Unknown session: ${sessionId}`);\n return state;\n }\n\n private cloneRecord(record: SessionHostRecord): SessionHostRecord {\n return {\n ...record,\n launchCommand: {\n ...record.launchCommand,\n args: [...record.launchCommand.args],\n env: record.launchCommand.env ? { ...record.launchCommand.env } : undefined,\n },\n writeOwner: record.writeOwner ? { ...record.writeOwner } : null,\n attachedClients: record.attachedClients.map(client => ({ ...client })),\n buffer: { ...record.buffer },\n meta: { ...record.meta },\n };\n }\n}\n","export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n","import * as path from 'path';\nimport type { CreateSessionPayload, SessionHostRecord, SessionHostSurfaceKind } from './types.js';\n\nfunction normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n}\n\nfunction normalizeValue(input: string): string {\n return input.trim().toLowerCase();\n}\n\nexport function getWorkspaceLabel(workspace: string): string {\n const trimmed = workspace.trim();\n if (!trimmed) return 'workspace';\n const normalized = trimmed.replace(/[\\\\/]+$/, '');\n const base = path.basename(normalized);\n return base || normalized;\n}\n\nexport function buildRuntimeDisplayName(payload: Pick<CreateSessionPayload, 'displayName' | 'providerType' | 'workspace'>): string {\n const explicit = payload.displayName?.trim();\n if (explicit) return explicit;\n const workspaceLabel = getWorkspaceLabel(payload.workspace);\n const providerLabel = payload.providerType.trim() || 'runtime';\n return `${providerLabel} @ ${workspaceLabel}`;\n}\n\nexport function buildRuntimeKey(\n payload: Pick<CreateSessionPayload, 'runtimeKey' | 'displayName' | 'providerType' | 'workspace'>,\n existingKeys: Iterable<string>,\n): string {\n const requested = payload.runtimeKey?.trim();\n const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));\n const displayName = buildRuntimeDisplayName(payload);\n const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || 'runtime') || 'runtime';\n if (!existing.has(baseKey)) return baseKey;\n\n let suffix = 2;\n let candidate = `${baseKey}-${suffix}`;\n while (existing.has(candidate)) {\n suffix += 1;\n candidate = `${baseKey}-${suffix}`;\n }\n return candidate;\n}\n\nexport interface SessionHostSurfaceRecordLike {\n lifecycle?: string | null;\n surfaceKind?: SessionHostSurfaceKind | null;\n meta?: Record<string, unknown> | null;\n}\n\nconst LIVE_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'interrupted']);\n\nexport function isSessionHostLiveRuntime(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'live_runtime') return true;\n if (record.surfaceKind === 'recovery_snapshot' || record.surfaceKind === 'inactive_record') return false;\n const lifecycle = String(record.lifecycle || '').trim();\n return LIVE_LIFECYCLES.has(lifecycle);\n}\n\nexport function getSessionHostRecoveryLabel(meta: Record<string, unknown> | null | undefined): string | null {\n const recoveryState = typeof meta?.runtimeRecoveryState === 'string'\n ? String(meta.runtimeRecoveryState).trim()\n : '';\n if (!recoveryState) return null;\n if (recoveryState === 'auto_resumed') return 'restored after restart';\n if (recoveryState === 'resume_failed') return 'restore failed';\n if (recoveryState === 'host_restart_interrupted') return 'host restart interrupted';\n if (recoveryState === 'orphan_snapshot') return 'snapshot recovered';\n return recoveryState.replace(/_/g, ' ');\n}\n\nexport function isSessionHostRecoverySnapshot(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'recovery_snapshot') return true;\n if (record.surfaceKind === 'live_runtime' || record.surfaceKind === 'inactive_record') return false;\n if (isSessionHostLiveRuntime(record)) return false;\n\n const lifecycle = String(record.lifecycle || '').trim();\n if (lifecycle && lifecycle !== 'stopped' && lifecycle !== 'failed') {\n return false;\n }\n\n const meta = record.meta || undefined;\n if (meta?.restoredFromStorage === true) return true;\n return getSessionHostRecoveryLabel(meta) !== null;\n}\n\nexport function getSessionHostSurfaceKind(record: SessionHostSurfaceRecordLike | null | undefined): SessionHostSurfaceKind {\n if (record?.surfaceKind === 'live_runtime' || record?.surfaceKind === 'recovery_snapshot' || record?.surfaceKind === 'inactive_record') {\n return record.surfaceKind;\n }\n if (isSessionHostLiveRuntime(record)) return 'live_runtime';\n if (isSessionHostRecoverySnapshot(record)) return 'recovery_snapshot';\n return 'inactive_record';\n}\n\nexport function resolveAttachableRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const record = resolveRuntimeRecord(records, identifier);\n const surfaceKind = getSessionHostSurfaceKind(record);\n if (surfaceKind === 'live_runtime') {\n return record;\n }\n if (surfaceKind === 'recovery_snapshot') {\n throw new Error(`Runtime ${record.runtimeKey} is a recovery snapshot, not a live attach target. Resume or recover it first.`);\n }\n throw new Error(`Runtime ${record.runtimeKey} is ${record.lifecycle}, not a live attach target.`);\n}\n\nfunction uniqueMatch(records: SessionHostRecord[], predicate: (record: SessionHostRecord) => boolean): SessionHostRecord | null {\n const matches = records.filter(predicate);\n if (matches.length === 1) return matches[0] || null;\n if (matches.length === 0) return null;\n const labels = matches.map((record) => `${record.runtimeKey} (${record.sessionId})`).join(', ');\n throw new Error(`Ambiguous runtime target. Matches: ${labels}`);\n}\n\nexport function resolveRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const target = identifier.trim();\n if (!target) {\n throw new Error('Runtime target is required');\n }\n\n const exact = uniqueMatch(records, (record) =>\n record.sessionId === target ||\n normalizeValue(record.runtimeKey) === normalizeValue(target) ||\n normalizeValue(record.displayName) === normalizeValue(target),\n );\n if (exact) return exact;\n\n const prefix = uniqueMatch(records, (record) =>\n record.sessionId.startsWith(target) ||\n normalizeValue(record.runtimeKey).startsWith(normalizeValue(target)),\n );\n if (prefix) return prefix;\n\n throw new Error(`Unknown runtime target: ${target}`);\n}\n\nexport function formatRuntimeOwner(record: Pick<SessionHostRecord, 'writeOwner'>): string {\n if (!record.writeOwner) return 'none';\n return `${record.writeOwner.ownerType}:${record.writeOwner.clientId}`;\n}\n","import * as os from 'os';\nimport * as path from 'path';\nimport * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport type {\n SessionHostEvent,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostWireEnvelope,\n} from './types.js';\n\nexport interface SessionHostEndpoint {\n kind: 'unix' | 'pipe';\n path: string;\n}\n\nexport function getDefaultSessionHostEndpoint(appName = 'adhdev'): SessionHostEndpoint {\n if (process.platform === 'win32') {\n return {\n kind: 'pipe',\n path: `\\\\\\\\.\\\\pipe\\\\${appName}-session-host`,\n };\n }\n\n return {\n kind: 'unix',\n path: path.join(os.tmpdir(), `${appName}-session-host.sock`),\n };\n}\n\nfunction serializeEnvelope(envelope: SessionHostWireEnvelope): string {\n return `${JSON.stringify(envelope)}\\n`;\n}\n\nfunction createLineParser(onEnvelope: (envelope: SessionHostWireEnvelope) => void) {\n let buffer = '';\n return (chunk: Buffer | string) => {\n buffer += chunk.toString();\n let newlineIndex = buffer.indexOf('\\n');\n while (newlineIndex >= 0) {\n const rawLine = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n if (rawLine) {\n onEnvelope(JSON.parse(rawLine) as SessionHostWireEnvelope);\n }\n newlineIndex = buffer.indexOf('\\n');\n }\n };\n}\n\nexport interface SessionHostClientOptions {\n endpoint?: SessionHostEndpoint;\n appName?: string;\n}\n\nexport class SessionHostClient {\n readonly endpoint: SessionHostEndpoint;\n\n private socket: net.Socket | null = null;\n private requestWaiters = new Map<string, { resolve: (value: SessionHostResponse) => void; reject: (error: Error) => void }>();\n private eventListeners = new Set<(event: SessionHostEvent) => void>();\n\n constructor(options: SessionHostClientOptions = {}) {\n this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || 'adhdev');\n }\n\n async connect(): Promise<void> {\n if (this.socket && !this.socket.destroyed) return;\n // Cleanup stale socket reference left after error/disconnect\n if (this.socket) {\n try { this.socket.destroy(); } catch { /* noop */ }\n this.socket = null;\n }\n\n const socket = net.createConnection(this.endpoint.path);\n this.socket = socket;\n\n socket.on('data', createLineParser((envelope) => {\n if (envelope.kind === 'response') {\n const waiter = this.requestWaiters.get(envelope.requestId);\n if (waiter) {\n this.requestWaiters.delete(envelope.requestId);\n waiter.resolve(envelope.response);\n }\n return;\n }\n\n if (envelope.kind === 'event') {\n for (const listener of this.eventListeners) listener(envelope.event);\n }\n }));\n\n socket.on('error', (error) => {\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(error);\n }\n this.requestWaiters.clear();\n // Clear the dead socket reference so the next connect() creates a fresh connection\n // instead of skipping reconnection on the `!this.socket.destroyed` guard.\n if (this.socket === socket) {\n this.socket = null;\n }\n try { socket.destroy(); } catch { /* noop */ }\n });\n\n await new Promise<void>((resolve, reject) => {\n socket.once('connect', () => resolve());\n socket.once('error', reject);\n });\n }\n\n onEvent(listener: (event: SessionHostEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n async request<T = unknown>(request: SessionHostRequest): Promise<SessionHostResponse<T>> {\n await this.connect();\n if (!this.socket) throw new Error('Session host socket unavailable');\n\n const requestId = randomUUID();\n const envelope: SessionHostRequestEnvelope = {\n kind: 'request',\n requestId,\n request,\n };\n\n const response = await new Promise<SessionHostResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.requestWaiters.delete(requestId);\n reject(new Error(`Session host request timed out after 30s (${request.type})`));\n }, 30_000);\n this.requestWaiters.set(requestId, {\n resolve: (value) => { clearTimeout(timeout); resolve(value); },\n reject: (error) => { clearTimeout(timeout); reject(error); },\n });\n this.socket?.write(serializeEnvelope(envelope));\n });\n\n return response as SessionHostResponse<T>;\n }\n\n async close(): Promise<void> {\n if (!this.socket) return;\n const socket = this.socket;\n this.socket = null;\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(new Error('Session host client closed'));\n }\n this.requestWaiters.clear();\n await new Promise<void>((resolve) => {\n let settled = false;\n const done = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n socket.once('close', done);\n socket.end();\n socket.destroy();\n setTimeout(done, 50);\n });\n }\n}\n\nexport function createResponseEnvelope(requestId: string, response: SessionHostResponse): SessionHostResponseEnvelope {\n return {\n kind: 'response',\n requestId,\n response,\n };\n}\n\nexport function writeEnvelope(socket: Pick<net.Socket, 'write'>, envelope: SessionHostWireEnvelope): void {\n socket.write(serializeEnvelope(envelope));\n}\n\nexport { createLineParser };\n","/**\n * Shared PTY spawn environment utilities.\n *\n * Centralises npm/pnpm/yarn env variable stripping, terminal colour env\n * injection, and node-pty spawn-helper permission fixing.\n *\n * Used by daemon-core (provider-cli-adapter), session-host-daemon (runtime),\n * and daemon-cloud (session-host).\n */\n\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Strip package-manager injected environment variables that can interfere\n * with child CLI processes and apply terminal colour defaults.\n */\nexport function sanitizeSpawnEnv(\n baseEnv: NodeJS.ProcessEnv,\n overrides?: Record<string, string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const source = { ...baseEnv, ...(overrides || {}) } as NodeJS.ProcessEnv;\n\n for (const [key, value] of Object.entries(source)) {\n if (typeof value !== 'string') continue;\n env[key] = value;\n }\n\n for (const key of Object.keys(env)) {\n if (\n key === 'INIT_CWD'\n || key === 'npm_command'\n || key === 'npm_execpath'\n || key === 'npm_node_execpath'\n || key.startsWith('npm_')\n || key.startsWith('npm_config_')\n || key.startsWith('npm_package_')\n || key.startsWith('npm_lifecycle_')\n || key.startsWith('PNPM_')\n || key.startsWith('YARN_')\n || key.startsWith('BUN_')\n || key.startsWith('VSCODE_')\n || key.startsWith('ELECTRON_')\n ) {\n delete env[key];\n }\n }\n\n // Do not leak the parent Codex app/extension thread identity into child CLIs.\n // Those variables cause codex-cli to attach to the current IDE thread instead\n // of creating or resuming its own standalone CLI thread, which breaks\n // providerSessionId discovery and reconnect semantics.\n delete env.CODEX_THREAD_ID;\n delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;\n\n applyTerminalColorEnv(env);\n return env;\n}\n\n/**\n * Apply preferred terminal colour environment variables.\n * Ensures TERM is set to xterm-256color and enables colour on Windows.\n */\nexport function applyTerminalColorEnv(env: Record<string, string>): void {\n if (env.NO_COLOR) return;\n\n if (!env.TERM || env.TERM === 'xterm-color') {\n env.TERM = 'xterm-256color';\n }\n if (!env.COLORTERM) env.COLORTERM = 'truecolor';\n\n if (process.platform === 'win32') {\n if (!env.FORCE_COLOR) env.FORCE_COLOR = '1';\n if (!env.CLICOLOR) env.CLICOLOR = '1';\n }\n}\n\n/**\n * Ensure node-pty's spawn-helper binary has execute permissions.\n *\n * npm's default umask can strip +x from the prebuilt spawn-helper on macOS/Linux,\n * causing EACCES when node-pty tries to fork. Best-effort fix.\n *\n * @param logFn Optional log callback for reporting the fix.\n */\nexport function ensureNodePtySpawnHelperPermissions(\n logFn?: (msg: string) => void,\n): void {\n if (os.platform() === 'win32') return;\n try {\n const fs = require('fs');\n const ptyDir = path.resolve(path.dirname(require.resolve('node-pty')), '..');\n const platformArch = `${os.platform()}-${os.arch()}`;\n const helper = path.join(ptyDir, 'prebuilds', platformArch, 'spawn-helper');\n if (fs.existsSync(helper)) {\n const stat = fs.statSync(helper);\n if (!(stat.mode & 0o111)) {\n fs.chmodSync(helper, stat.mode | 0o755);\n logFn?.(`Fixed spawn-helper permissions: ${helper}`);\n }\n }\n } catch {\n // best-effort: node-pty still works on most installs without this\n }\n}\n"],"mappings":"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","names":["path","import_crypto","resolve","os","path"]}
@@ -6,13 +6,14 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  });
7
7
 
8
8
  // src/buffer.ts
9
+ var DEFAULT_SESSION_RING_BUFFER_MAX_BYTES = 4 * 1024 * 1024;
9
10
  var SessionRingBuffer = class {
10
11
  maxBytes;
11
12
  chunks = [];
12
13
  nextSeq = 1;
13
14
  totalBytes = 0;
14
15
  constructor(options = {}) {
15
- this.maxBytes = options.maxBytes ?? 512 * 1024;
16
+ this.maxBytes = options.maxBytes ?? DEFAULT_SESSION_RING_BUFFER_MAX_BYTES;
16
17
  }
17
18
  append(data) {
18
19
  const normalized = typeof data === "string" ? data : String(data ?? "");
@@ -620,6 +621,7 @@ function ensureNodePtySpawnHelperPermissions(logFn) {
620
621
  export {
621
622
  DEFAULT_SESSION_HOST_COLS,
622
623
  DEFAULT_SESSION_HOST_ROWS,
624
+ DEFAULT_SESSION_RING_BUFFER_MAX_BYTES,
623
625
  SessionHostClient,
624
626
  SessionHostRegistry,
625
627
  SessionRingBuffer,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/buffer.ts","../src/registry.ts","../src/defaults.ts","../src/runtime-labels.ts","../src/ipc.ts","../src/spawn-env.ts"],"sourcesContent":["import type { SessionBufferSnapshot } from './types.js';\n\nexport interface SessionRingBufferOptions {\n maxBytes?: number;\n}\n\nexport class SessionRingBuffer {\n private maxBytes: number;\n private chunks: { seq: number; data: string; bytes: number }[] = [];\n private nextSeq = 1;\n private totalBytes = 0;\n\n constructor(options: SessionRingBufferOptions = {}) {\n this.maxBytes = options.maxBytes ?? 512 * 1024;\n }\n\n append(data: string): number {\n const normalized = typeof data === 'string' ? data : String(data ?? '');\n const bytes = Buffer.byteLength(normalized, 'utf8');\n const seq = this.nextSeq++;\n\n this.chunks.push({ seq, data: normalized, bytes });\n this.totalBytes += bytes;\n this.trim();\n return seq;\n }\n\n snapshot(sinceSeq?: number): SessionBufferSnapshot {\n const relevant = typeof sinceSeq === 'number'\n ? this.chunks.filter(chunk => chunk.seq > sinceSeq)\n : this.chunks;\n\n const text = relevant.map(chunk => chunk.data).join('');\n const truncated = !!this.chunks[0] && typeof sinceSeq === 'number' && sinceSeq < this.chunks[0].seq - 1;\n\n return {\n seq: this.nextSeq - 1,\n text,\n truncated,\n };\n }\n\n getState(): { scrollbackBytes: number; snapshotSeq: number } {\n return {\n scrollbackBytes: this.totalBytes,\n snapshotSeq: this.nextSeq - 1,\n };\n }\n\n clear(): void {\n this.chunks = [];\n this.totalBytes = 0;\n this.nextSeq = 1;\n }\n\n restore(snapshot: { seq: number; text: string }): void {\n this.clear();\n const text = String(snapshot.text || '');\n if (!text) {\n this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);\n return;\n }\n const bytes = Buffer.byteLength(text, 'utf8');\n const seq = Math.max(1, Number(snapshot.seq || 1));\n this.chunks = [{ seq, data: text, bytes }];\n this.totalBytes = bytes;\n this.nextSeq = seq + 1;\n this.trim();\n }\n\n private trim(): void {\n while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {\n const removed = this.chunks.shift();\n if (!removed) break;\n this.totalBytes -= removed.bytes;\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type {\n AcquireWritePayload,\n AttachSessionPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ReleaseWritePayload,\n SessionAttachedClient,\n SessionHostRecord,\n} from './types.js';\nimport { SessionRingBuffer } from './buffer.js';\nimport { resolveSessionHostCols, resolveSessionHostRows } from './defaults.js';\nimport { buildRuntimeDisplayName, buildRuntimeKey, getWorkspaceLabel } from './runtime-labels.js';\n\ninterface SessionRuntimeState {\n record: SessionHostRecord;\n buffer: SessionRingBuffer;\n}\n\nexport class SessionHostRegistry {\n private sessions = new Map<string, SessionRuntimeState>();\n\n createSession(payload: CreateSessionPayload): SessionHostRecord {\n const sessionId = payload.sessionId || randomUUID();\n if (this.sessions.has(sessionId)) {\n throw new Error(`Session already exists: ${sessionId}`);\n }\n const now = Date.now();\n const initialClient = payload.clientId\n ? [{\n clientId: payload.clientId,\n type: payload.clientType || 'daemon',\n readOnly: false,\n attachedAt: now,\n lastSeenAt: now,\n } satisfies SessionAttachedClient]\n : [];\n\n const record: SessionHostRecord = {\n sessionId,\n runtimeKey: buildRuntimeKey(\n payload,\n Array.from(this.sessions.values(), (state) => state.record.runtimeKey),\n ),\n displayName: buildRuntimeDisplayName(payload),\n workspaceLabel: getWorkspaceLabel(payload.workspace),\n transport: 'pty',\n providerType: payload.providerType,\n category: payload.category,\n workspace: payload.workspace,\n launchCommand: payload.launchCommand,\n createdAt: now,\n lastActivityAt: now,\n lifecycle: 'starting',\n writeOwner: null,\n attachedClients: initialClient,\n buffer: {\n scrollbackBytes: 0,\n snapshotSeq: 0,\n },\n meta: payload.meta || {},\n };\n\n record.meta = {\n sessionHostCols: resolveSessionHostCols(payload.cols),\n sessionHostRows: resolveSessionHostRows(payload.rows),\n ...record.meta,\n };\n\n this.sessions.set(sessionId, {\n record,\n buffer: new SessionRingBuffer(),\n });\n\n return this.cloneRecord(record);\n }\n\n restoreSession(record: SessionHostRecord, snapshot?: { seq: number; text: string } | null): SessionHostRecord {\n const cloned = this.cloneRecord(record);\n this.sessions.set(cloned.sessionId, {\n record: cloned,\n buffer: (() => {\n const buffer = new SessionRingBuffer();\n if (snapshot) buffer.restore(snapshot);\n return buffer;\n })(),\n });\n return this.cloneRecord(cloned);\n }\n\n listSessions(): SessionHostRecord[] {\n return Array.from(this.sessions.values())\n .map(state => this.cloneRecord(state.record))\n .sort((a, b) => b.lastActivityAt - a.lastActivityAt);\n }\n\n getSession(sessionId: string): SessionHostRecord | null {\n const state = this.sessions.get(sessionId);\n return state ? this.cloneRecord(state.record) : null;\n }\n\n attachClient(payload: AttachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const now = Date.now();\n let removedDaemonOwner = false;\n\n if (payload.clientType === 'daemon') {\n const staleDaemonClientIds = state.record.attachedClients\n .filter(client => client.type === 'daemon' && client.clientId !== payload.clientId)\n .map(client => client.clientId);\n if (staleDaemonClientIds.length > 0) {\n state.record.attachedClients = state.record.attachedClients.filter(\n client => !(client.type === 'daemon' && client.clientId !== payload.clientId),\n );\n if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {\n removedDaemonOwner = true;\n }\n }\n }\n\n const existing = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n\n if (existing) {\n existing.type = payload.clientType;\n existing.readOnly = !!payload.readOnly;\n existing.lastSeenAt = now;\n } else {\n state.record.attachedClients.push({\n clientId: payload.clientId,\n type: payload.clientType,\n readOnly: !!payload.readOnly,\n attachedAt: now,\n lastSeenAt: now,\n });\n }\n\n if (removedDaemonOwner) {\n state.record.writeOwner = null;\n }\n\n state.record.lastActivityAt = now;\n return this.cloneRecord(state.record);\n }\n\n detachClient(payload: DetachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n state.record.attachedClients = state.record.attachedClients.filter(client => client.clientId !== payload.clientId);\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n acquireWrite(payload: AcquireWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {\n throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);\n }\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n state.record.writeOwner = {\n clientId: payload.clientId,\n ownerType: payload.ownerType,\n acquiredAt: Date.now(),\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n releaseWrite(payload: ReleaseWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n appendOutput(sessionId: string, data: string): { record: SessionHostRecord; seq: number } {\n const state = this.requireSession(sessionId);\n const seq = state.buffer.append(data);\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return { record: this.cloneRecord(state.record), seq };\n }\n\n getSnapshot(sessionId: string, sinceSeq?: number) {\n const state = this.requireSession(sessionId);\n state.record.buffer = state.buffer.getState();\n return state.buffer.snapshot(sinceSeq);\n }\n\n clearBuffer(sessionId: string): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.buffer.clear();\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n updateSessionMeta(sessionId: string, meta: Record<string, unknown>, replace = false): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.meta = replace\n ? { ...meta }\n : {\n ...(state.record.meta || {}),\n ...meta,\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStarted(sessionId: string, pid?: number): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = 'running';\n state.record.startedAt = state.record.startedAt || Date.now();\n if (typeof pid === 'number') state.record.osPid = pid;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStopped(sessionId: string, lifecycle: 'stopped' | 'failed' = 'stopped'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n setLifecycle(sessionId: string, lifecycle: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n deleteSession(sessionId: string): boolean {\n return this.sessions.delete(sessionId);\n }\n\n private requireSession(sessionId: string): SessionRuntimeState {\n const state = this.sessions.get(sessionId);\n if (!state) throw new Error(`Unknown session: ${sessionId}`);\n return state;\n }\n\n private cloneRecord(record: SessionHostRecord): SessionHostRecord {\n return {\n ...record,\n launchCommand: {\n ...record.launchCommand,\n args: [...record.launchCommand.args],\n env: record.launchCommand.env ? { ...record.launchCommand.env } : undefined,\n },\n writeOwner: record.writeOwner ? { ...record.writeOwner } : null,\n attachedClients: record.attachedClients.map(client => ({ ...client })),\n buffer: { ...record.buffer },\n meta: { ...record.meta },\n };\n }\n}\n","export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n","import * as path from 'path';\nimport type { CreateSessionPayload, SessionHostRecord, SessionHostSurfaceKind } from './types.js';\n\nfunction normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n}\n\nfunction normalizeValue(input: string): string {\n return input.trim().toLowerCase();\n}\n\nexport function getWorkspaceLabel(workspace: string): string {\n const trimmed = workspace.trim();\n if (!trimmed) return 'workspace';\n const normalized = trimmed.replace(/[\\\\/]+$/, '');\n const base = path.basename(normalized);\n return base || normalized;\n}\n\nexport function buildRuntimeDisplayName(payload: Pick<CreateSessionPayload, 'displayName' | 'providerType' | 'workspace'>): string {\n const explicit = payload.displayName?.trim();\n if (explicit) return explicit;\n const workspaceLabel = getWorkspaceLabel(payload.workspace);\n const providerLabel = payload.providerType.trim() || 'runtime';\n return `${providerLabel} @ ${workspaceLabel}`;\n}\n\nexport function buildRuntimeKey(\n payload: Pick<CreateSessionPayload, 'runtimeKey' | 'displayName' | 'providerType' | 'workspace'>,\n existingKeys: Iterable<string>,\n): string {\n const requested = payload.runtimeKey?.trim();\n const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));\n const displayName = buildRuntimeDisplayName(payload);\n const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || 'runtime') || 'runtime';\n if (!existing.has(baseKey)) return baseKey;\n\n let suffix = 2;\n let candidate = `${baseKey}-${suffix}`;\n while (existing.has(candidate)) {\n suffix += 1;\n candidate = `${baseKey}-${suffix}`;\n }\n return candidate;\n}\n\nexport interface SessionHostSurfaceRecordLike {\n lifecycle?: string | null;\n surfaceKind?: SessionHostSurfaceKind | null;\n meta?: Record<string, unknown> | null;\n}\n\nconst LIVE_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'interrupted']);\n\nexport function isSessionHostLiveRuntime(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'live_runtime') return true;\n if (record.surfaceKind === 'recovery_snapshot' || record.surfaceKind === 'inactive_record') return false;\n const lifecycle = String(record.lifecycle || '').trim();\n return LIVE_LIFECYCLES.has(lifecycle);\n}\n\nexport function getSessionHostRecoveryLabel(meta: Record<string, unknown> | null | undefined): string | null {\n const recoveryState = typeof meta?.runtimeRecoveryState === 'string'\n ? String(meta.runtimeRecoveryState).trim()\n : '';\n if (!recoveryState) return null;\n if (recoveryState === 'auto_resumed') return 'restored after restart';\n if (recoveryState === 'resume_failed') return 'restore failed';\n if (recoveryState === 'host_restart_interrupted') return 'host restart interrupted';\n if (recoveryState === 'orphan_snapshot') return 'snapshot recovered';\n return recoveryState.replace(/_/g, ' ');\n}\n\nexport function isSessionHostRecoverySnapshot(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'recovery_snapshot') return true;\n if (record.surfaceKind === 'live_runtime' || record.surfaceKind === 'inactive_record') return false;\n if (isSessionHostLiveRuntime(record)) return false;\n\n const lifecycle = String(record.lifecycle || '').trim();\n if (lifecycle && lifecycle !== 'stopped' && lifecycle !== 'failed') {\n return false;\n }\n\n const meta = record.meta || undefined;\n if (meta?.restoredFromStorage === true) return true;\n return getSessionHostRecoveryLabel(meta) !== null;\n}\n\nexport function getSessionHostSurfaceKind(record: SessionHostSurfaceRecordLike | null | undefined): SessionHostSurfaceKind {\n if (record?.surfaceKind === 'live_runtime' || record?.surfaceKind === 'recovery_snapshot' || record?.surfaceKind === 'inactive_record') {\n return record.surfaceKind;\n }\n if (isSessionHostLiveRuntime(record)) return 'live_runtime';\n if (isSessionHostRecoverySnapshot(record)) return 'recovery_snapshot';\n return 'inactive_record';\n}\n\nexport function resolveAttachableRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const record = resolveRuntimeRecord(records, identifier);\n const surfaceKind = getSessionHostSurfaceKind(record);\n if (surfaceKind === 'live_runtime') {\n return record;\n }\n if (surfaceKind === 'recovery_snapshot') {\n throw new Error(`Runtime ${record.runtimeKey} is a recovery snapshot, not a live attach target. Resume or recover it first.`);\n }\n throw new Error(`Runtime ${record.runtimeKey} is ${record.lifecycle}, not a live attach target.`);\n}\n\nfunction uniqueMatch(records: SessionHostRecord[], predicate: (record: SessionHostRecord) => boolean): SessionHostRecord | null {\n const matches = records.filter(predicate);\n if (matches.length === 1) return matches[0] || null;\n if (matches.length === 0) return null;\n const labels = matches.map((record) => `${record.runtimeKey} (${record.sessionId})`).join(', ');\n throw new Error(`Ambiguous runtime target. Matches: ${labels}`);\n}\n\nexport function resolveRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const target = identifier.trim();\n if (!target) {\n throw new Error('Runtime target is required');\n }\n\n const exact = uniqueMatch(records, (record) =>\n record.sessionId === target ||\n normalizeValue(record.runtimeKey) === normalizeValue(target) ||\n normalizeValue(record.displayName) === normalizeValue(target),\n );\n if (exact) return exact;\n\n const prefix = uniqueMatch(records, (record) =>\n record.sessionId.startsWith(target) ||\n normalizeValue(record.runtimeKey).startsWith(normalizeValue(target)),\n );\n if (prefix) return prefix;\n\n throw new Error(`Unknown runtime target: ${target}`);\n}\n\nexport function formatRuntimeOwner(record: Pick<SessionHostRecord, 'writeOwner'>): string {\n if (!record.writeOwner) return 'none';\n return `${record.writeOwner.ownerType}:${record.writeOwner.clientId}`;\n}\n","import * as os from 'os';\nimport * as path from 'path';\nimport * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport type {\n SessionHostEvent,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostWireEnvelope,\n} from './types.js';\n\nexport interface SessionHostEndpoint {\n kind: 'unix' | 'pipe';\n path: string;\n}\n\nexport function getDefaultSessionHostEndpoint(appName = 'adhdev'): SessionHostEndpoint {\n if (process.platform === 'win32') {\n return {\n kind: 'pipe',\n path: `\\\\\\\\.\\\\pipe\\\\${appName}-session-host`,\n };\n }\n\n return {\n kind: 'unix',\n path: path.join(os.tmpdir(), `${appName}-session-host.sock`),\n };\n}\n\nfunction serializeEnvelope(envelope: SessionHostWireEnvelope): string {\n return `${JSON.stringify(envelope)}\\n`;\n}\n\nfunction createLineParser(onEnvelope: (envelope: SessionHostWireEnvelope) => void) {\n let buffer = '';\n return (chunk: Buffer | string) => {\n buffer += chunk.toString();\n let newlineIndex = buffer.indexOf('\\n');\n while (newlineIndex >= 0) {\n const rawLine = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n if (rawLine) {\n onEnvelope(JSON.parse(rawLine) as SessionHostWireEnvelope);\n }\n newlineIndex = buffer.indexOf('\\n');\n }\n };\n}\n\nexport interface SessionHostClientOptions {\n endpoint?: SessionHostEndpoint;\n appName?: string;\n}\n\nexport class SessionHostClient {\n readonly endpoint: SessionHostEndpoint;\n\n private socket: net.Socket | null = null;\n private requestWaiters = new Map<string, { resolve: (value: SessionHostResponse) => void; reject: (error: Error) => void }>();\n private eventListeners = new Set<(event: SessionHostEvent) => void>();\n\n constructor(options: SessionHostClientOptions = {}) {\n this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || 'adhdev');\n }\n\n async connect(): Promise<void> {\n if (this.socket && !this.socket.destroyed) return;\n // Cleanup stale socket reference left after error/disconnect\n if (this.socket) {\n try { this.socket.destroy(); } catch { /* noop */ }\n this.socket = null;\n }\n\n const socket = net.createConnection(this.endpoint.path);\n this.socket = socket;\n\n socket.on('data', createLineParser((envelope) => {\n if (envelope.kind === 'response') {\n const waiter = this.requestWaiters.get(envelope.requestId);\n if (waiter) {\n this.requestWaiters.delete(envelope.requestId);\n waiter.resolve(envelope.response);\n }\n return;\n }\n\n if (envelope.kind === 'event') {\n for (const listener of this.eventListeners) listener(envelope.event);\n }\n }));\n\n socket.on('error', (error) => {\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(error);\n }\n this.requestWaiters.clear();\n // Clear the dead socket reference so the next connect() creates a fresh connection\n // instead of skipping reconnection on the `!this.socket.destroyed` guard.\n if (this.socket === socket) {\n this.socket = null;\n }\n try { socket.destroy(); } catch { /* noop */ }\n });\n\n await new Promise<void>((resolve, reject) => {\n socket.once('connect', () => resolve());\n socket.once('error', reject);\n });\n }\n\n onEvent(listener: (event: SessionHostEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n async request<T = unknown>(request: SessionHostRequest): Promise<SessionHostResponse<T>> {\n await this.connect();\n if (!this.socket) throw new Error('Session host socket unavailable');\n\n const requestId = randomUUID();\n const envelope: SessionHostRequestEnvelope = {\n kind: 'request',\n requestId,\n request,\n };\n\n const response = await new Promise<SessionHostResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.requestWaiters.delete(requestId);\n reject(new Error(`Session host request timed out after 30s (${request.type})`));\n }, 30_000);\n this.requestWaiters.set(requestId, {\n resolve: (value) => { clearTimeout(timeout); resolve(value); },\n reject: (error) => { clearTimeout(timeout); reject(error); },\n });\n this.socket?.write(serializeEnvelope(envelope));\n });\n\n return response as SessionHostResponse<T>;\n }\n\n async close(): Promise<void> {\n if (!this.socket) return;\n const socket = this.socket;\n this.socket = null;\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(new Error('Session host client closed'));\n }\n this.requestWaiters.clear();\n await new Promise<void>((resolve) => {\n let settled = false;\n const done = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n socket.once('close', done);\n socket.end();\n socket.destroy();\n setTimeout(done, 50);\n });\n }\n}\n\nexport function createResponseEnvelope(requestId: string, response: SessionHostResponse): SessionHostResponseEnvelope {\n return {\n kind: 'response',\n requestId,\n response,\n };\n}\n\nexport function writeEnvelope(socket: Pick<net.Socket, 'write'>, envelope: SessionHostWireEnvelope): void {\n socket.write(serializeEnvelope(envelope));\n}\n\nexport { createLineParser };\n","/**\n * Shared PTY spawn environment utilities.\n *\n * Centralises npm/pnpm/yarn env variable stripping, terminal colour env\n * injection, and node-pty spawn-helper permission fixing.\n *\n * Used by daemon-core (provider-cli-adapter), session-host-daemon (runtime),\n * and daemon-cloud (session-host).\n */\n\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Strip package-manager injected environment variables that can interfere\n * with child CLI processes and apply terminal colour defaults.\n */\nexport function sanitizeSpawnEnv(\n baseEnv: NodeJS.ProcessEnv,\n overrides?: Record<string, string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const source = { ...baseEnv, ...(overrides || {}) } as NodeJS.ProcessEnv;\n\n for (const [key, value] of Object.entries(source)) {\n if (typeof value !== 'string') continue;\n env[key] = value;\n }\n\n for (const key of Object.keys(env)) {\n if (\n key === 'INIT_CWD'\n || key === 'npm_command'\n || key === 'npm_execpath'\n || key === 'npm_node_execpath'\n || key.startsWith('npm_')\n || key.startsWith('npm_config_')\n || key.startsWith('npm_package_')\n || key.startsWith('npm_lifecycle_')\n || key.startsWith('PNPM_')\n || key.startsWith('YARN_')\n || key.startsWith('BUN_')\n || key.startsWith('VSCODE_')\n || key.startsWith('ELECTRON_')\n ) {\n delete env[key];\n }\n }\n\n // Do not leak the parent Codex app/extension thread identity into child CLIs.\n // Those variables cause codex-cli to attach to the current IDE thread instead\n // of creating or resuming its own standalone CLI thread, which breaks\n // providerSessionId discovery and reconnect semantics.\n delete env.CODEX_THREAD_ID;\n delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;\n\n applyTerminalColorEnv(env);\n return env;\n}\n\n/**\n * Apply preferred terminal colour environment variables.\n * Ensures TERM is set to xterm-256color and enables colour on Windows.\n */\nexport function applyTerminalColorEnv(env: Record<string, string>): void {\n if (env.NO_COLOR) return;\n\n if (!env.TERM || env.TERM === 'xterm-color') {\n env.TERM = 'xterm-256color';\n }\n if (!env.COLORTERM) env.COLORTERM = 'truecolor';\n\n if (process.platform === 'win32') {\n if (!env.FORCE_COLOR) env.FORCE_COLOR = '1';\n if (!env.CLICOLOR) env.CLICOLOR = '1';\n }\n}\n\n/**\n * Ensure node-pty's spawn-helper binary has execute permissions.\n *\n * npm's default umask can strip +x from the prebuilt spawn-helper on macOS/Linux,\n * causing EACCES when node-pty tries to fork. Best-effort fix.\n *\n * @param logFn Optional log callback for reporting the fix.\n */\nexport function ensureNodePtySpawnHelperPermissions(\n logFn?: (msg: string) => void,\n): void {\n if (os.platform() === 'win32') return;\n try {\n const fs = require('fs');\n const ptyDir = path.resolve(path.dirname(require.resolve('node-pty')), '..');\n const platformArch = `${os.platform()}-${os.arch()}`;\n const helper = path.join(ptyDir, 'prebuilds', platformArch, 'spawn-helper');\n if (fs.existsSync(helper)) {\n const stat = fs.statSync(helper);\n if (!(stat.mode & 0o111)) {\n fs.chmodSync(helper, stat.mode | 0o755);\n logFn?.(`Fixed spawn-helper permissions: ${helper}`);\n }\n }\n } catch {\n // best-effort: node-pty still works on most installs without this\n }\n}\n"],"mappings":"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","names":["path","randomUUID","resolve","os","path"]}
1
+ {"version":3,"sources":["../src/buffer.ts","../src/registry.ts","../src/defaults.ts","../src/runtime-labels.ts","../src/ipc.ts","../src/spawn-env.ts"],"sourcesContent":["import type { SessionBufferSnapshot } from './types.js';\n\nexport interface SessionRingBufferOptions {\n maxBytes?: number;\n}\n\n// Manual \"Load older terminal output\" replays this raw ring buffer into the\n// browser terminal. 512KiB was too small for long Claude/Codex conversations:\n// by the time the user scrolled to the top and clicked the loader, the output\n// they were trying to recover was often already trimmed.\nexport const DEFAULT_SESSION_RING_BUFFER_MAX_BYTES = 4 * 1024 * 1024;\n\nexport class SessionRingBuffer {\n private maxBytes: number;\n private chunks: { seq: number; data: string; bytes: number }[] = [];\n private nextSeq = 1;\n private totalBytes = 0;\n\n constructor(options: SessionRingBufferOptions = {}) {\n this.maxBytes = options.maxBytes ?? DEFAULT_SESSION_RING_BUFFER_MAX_BYTES;\n }\n\n append(data: string): number {\n const normalized = typeof data === 'string' ? data : String(data ?? '');\n const bytes = Buffer.byteLength(normalized, 'utf8');\n const seq = this.nextSeq++;\n\n this.chunks.push({ seq, data: normalized, bytes });\n this.totalBytes += bytes;\n this.trim();\n return seq;\n }\n\n snapshot(sinceSeq?: number): SessionBufferSnapshot {\n const relevant = typeof sinceSeq === 'number'\n ? this.chunks.filter(chunk => chunk.seq > sinceSeq)\n : this.chunks;\n\n const text = relevant.map(chunk => chunk.data).join('');\n const truncated = !!this.chunks[0] && typeof sinceSeq === 'number' && sinceSeq < this.chunks[0].seq - 1;\n\n return {\n seq: this.nextSeq - 1,\n text,\n truncated,\n };\n }\n\n getState(): { scrollbackBytes: number; snapshotSeq: number } {\n return {\n scrollbackBytes: this.totalBytes,\n snapshotSeq: this.nextSeq - 1,\n };\n }\n\n clear(): void {\n this.chunks = [];\n this.totalBytes = 0;\n this.nextSeq = 1;\n }\n\n restore(snapshot: { seq: number; text: string }): void {\n this.clear();\n const text = String(snapshot.text || '');\n if (!text) {\n this.nextSeq = Math.max(1, Number(snapshot.seq || 0) + 1);\n return;\n }\n const bytes = Buffer.byteLength(text, 'utf8');\n const seq = Math.max(1, Number(snapshot.seq || 1));\n this.chunks = [{ seq, data: text, bytes }];\n this.totalBytes = bytes;\n this.nextSeq = seq + 1;\n this.trim();\n }\n\n private trim(): void {\n while (this.totalBytes > this.maxBytes && this.chunks.length > 1) {\n const removed = this.chunks.shift();\n if (!removed) break;\n this.totalBytes -= removed.bytes;\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type {\n AcquireWritePayload,\n AttachSessionPayload,\n CreateSessionPayload,\n DetachSessionPayload,\n ReleaseWritePayload,\n SessionAttachedClient,\n SessionHostRecord,\n} from './types.js';\nimport { SessionRingBuffer } from './buffer.js';\nimport { resolveSessionHostCols, resolveSessionHostRows } from './defaults.js';\nimport { buildRuntimeDisplayName, buildRuntimeKey, getWorkspaceLabel } from './runtime-labels.js';\n\ninterface SessionRuntimeState {\n record: SessionHostRecord;\n buffer: SessionRingBuffer;\n}\n\nexport class SessionHostRegistry {\n private sessions = new Map<string, SessionRuntimeState>();\n\n createSession(payload: CreateSessionPayload): SessionHostRecord {\n const sessionId = payload.sessionId || randomUUID();\n if (this.sessions.has(sessionId)) {\n throw new Error(`Session already exists: ${sessionId}`);\n }\n const now = Date.now();\n const initialClient = payload.clientId\n ? [{\n clientId: payload.clientId,\n type: payload.clientType || 'daemon',\n readOnly: false,\n attachedAt: now,\n lastSeenAt: now,\n } satisfies SessionAttachedClient]\n : [];\n\n const record: SessionHostRecord = {\n sessionId,\n runtimeKey: buildRuntimeKey(\n payload,\n Array.from(this.sessions.values(), (state) => state.record.runtimeKey),\n ),\n displayName: buildRuntimeDisplayName(payload),\n workspaceLabel: getWorkspaceLabel(payload.workspace),\n transport: 'pty',\n providerType: payload.providerType,\n category: payload.category,\n workspace: payload.workspace,\n launchCommand: payload.launchCommand,\n createdAt: now,\n lastActivityAt: now,\n lifecycle: 'starting',\n writeOwner: null,\n attachedClients: initialClient,\n buffer: {\n scrollbackBytes: 0,\n snapshotSeq: 0,\n },\n meta: payload.meta || {},\n };\n\n record.meta = {\n sessionHostCols: resolveSessionHostCols(payload.cols),\n sessionHostRows: resolveSessionHostRows(payload.rows),\n ...record.meta,\n };\n\n this.sessions.set(sessionId, {\n record,\n buffer: new SessionRingBuffer(),\n });\n\n return this.cloneRecord(record);\n }\n\n restoreSession(record: SessionHostRecord, snapshot?: { seq: number; text: string } | null): SessionHostRecord {\n const cloned = this.cloneRecord(record);\n this.sessions.set(cloned.sessionId, {\n record: cloned,\n buffer: (() => {\n const buffer = new SessionRingBuffer();\n if (snapshot) buffer.restore(snapshot);\n return buffer;\n })(),\n });\n return this.cloneRecord(cloned);\n }\n\n listSessions(): SessionHostRecord[] {\n return Array.from(this.sessions.values())\n .map(state => this.cloneRecord(state.record))\n .sort((a, b) => b.lastActivityAt - a.lastActivityAt);\n }\n\n getSession(sessionId: string): SessionHostRecord | null {\n const state = this.sessions.get(sessionId);\n return state ? this.cloneRecord(state.record) : null;\n }\n\n attachClient(payload: AttachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const now = Date.now();\n let removedDaemonOwner = false;\n\n if (payload.clientType === 'daemon') {\n const staleDaemonClientIds = state.record.attachedClients\n .filter(client => client.type === 'daemon' && client.clientId !== payload.clientId)\n .map(client => client.clientId);\n if (staleDaemonClientIds.length > 0) {\n state.record.attachedClients = state.record.attachedClients.filter(\n client => !(client.type === 'daemon' && client.clientId !== payload.clientId),\n );\n if (state.record.writeOwner && staleDaemonClientIds.includes(state.record.writeOwner.clientId)) {\n removedDaemonOwner = true;\n }\n }\n }\n\n const existing = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n\n if (existing) {\n existing.type = payload.clientType;\n existing.readOnly = !!payload.readOnly;\n existing.lastSeenAt = now;\n } else {\n state.record.attachedClients.push({\n clientId: payload.clientId,\n type: payload.clientType,\n readOnly: !!payload.readOnly,\n attachedAt: now,\n lastSeenAt: now,\n });\n }\n\n if (removedDaemonOwner) {\n state.record.writeOwner = null;\n }\n\n state.record.lastActivityAt = now;\n return this.cloneRecord(state.record);\n }\n\n detachClient(payload: DetachSessionPayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n state.record.attachedClients = state.record.attachedClients.filter(client => client.clientId !== payload.clientId);\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n acquireWrite(payload: AcquireWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n if (state.record.writeOwner && state.record.writeOwner.clientId !== payload.clientId && !payload.force) {\n throw new Error(`Write owned by ${state.record.writeOwner.clientId}`);\n }\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n state.record.writeOwner = {\n clientId: payload.clientId,\n ownerType: payload.ownerType,\n acquiredAt: Date.now(),\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n releaseWrite(payload: ReleaseWritePayload): SessionHostRecord {\n const state = this.requireSession(payload.sessionId);\n const attachedClient = state.record.attachedClients.find(client => client.clientId === payload.clientId);\n if (attachedClient) {\n attachedClient.readOnly = false;\n attachedClient.lastSeenAt = Date.now();\n }\n if (state.record.writeOwner?.clientId === payload.clientId) {\n state.record.writeOwner = null;\n }\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n appendOutput(sessionId: string, data: string): { record: SessionHostRecord; seq: number } {\n const state = this.requireSession(sessionId);\n const seq = state.buffer.append(data);\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return { record: this.cloneRecord(state.record), seq };\n }\n\n getSnapshot(sessionId: string, sinceSeq?: number) {\n const state = this.requireSession(sessionId);\n state.record.buffer = state.buffer.getState();\n return state.buffer.snapshot(sinceSeq);\n }\n\n clearBuffer(sessionId: string): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.buffer.clear();\n state.record.buffer = state.buffer.getState();\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n updateSessionMeta(sessionId: string, meta: Record<string, unknown>, replace = false): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.meta = replace\n ? { ...meta }\n : {\n ...(state.record.meta || {}),\n ...meta,\n };\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStarted(sessionId: string, pid?: number): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = 'running';\n state.record.startedAt = state.record.startedAt || Date.now();\n if (typeof pid === 'number') state.record.osPid = pid;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n markStopped(sessionId: string, lifecycle: 'stopped' | 'failed' = 'stopped'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n setLifecycle(sessionId: string, lifecycle: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted'): SessionHostRecord {\n const state = this.requireSession(sessionId);\n state.record.lifecycle = lifecycle;\n state.record.lastActivityAt = Date.now();\n return this.cloneRecord(state.record);\n }\n\n deleteSession(sessionId: string): boolean {\n return this.sessions.delete(sessionId);\n }\n\n private requireSession(sessionId: string): SessionRuntimeState {\n const state = this.sessions.get(sessionId);\n if (!state) throw new Error(`Unknown session: ${sessionId}`);\n return state;\n }\n\n private cloneRecord(record: SessionHostRecord): SessionHostRecord {\n return {\n ...record,\n launchCommand: {\n ...record.launchCommand,\n args: [...record.launchCommand.args],\n env: record.launchCommand.env ? { ...record.launchCommand.env } : undefined,\n },\n writeOwner: record.writeOwner ? { ...record.writeOwner } : null,\n attachedClients: record.attachedClients.map(client => ({ ...client })),\n buffer: { ...record.buffer },\n meta: { ...record.meta },\n };\n }\n}\n","export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n","import * as path from 'path';\nimport type { CreateSessionPayload, SessionHostRecord, SessionHostSurfaceKind } from './types.js';\n\nfunction normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n}\n\nfunction normalizeValue(input: string): string {\n return input.trim().toLowerCase();\n}\n\nexport function getWorkspaceLabel(workspace: string): string {\n const trimmed = workspace.trim();\n if (!trimmed) return 'workspace';\n const normalized = trimmed.replace(/[\\\\/]+$/, '');\n const base = path.basename(normalized);\n return base || normalized;\n}\n\nexport function buildRuntimeDisplayName(payload: Pick<CreateSessionPayload, 'displayName' | 'providerType' | 'workspace'>): string {\n const explicit = payload.displayName?.trim();\n if (explicit) return explicit;\n const workspaceLabel = getWorkspaceLabel(payload.workspace);\n const providerLabel = payload.providerType.trim() || 'runtime';\n return `${providerLabel} @ ${workspaceLabel}`;\n}\n\nexport function buildRuntimeKey(\n payload: Pick<CreateSessionPayload, 'runtimeKey' | 'displayName' | 'providerType' | 'workspace'>,\n existingKeys: Iterable<string>,\n): string {\n const requested = payload.runtimeKey?.trim();\n const existing = new Set(Array.from(existingKeys, (key) => key.toLowerCase()));\n const displayName = buildRuntimeDisplayName(payload);\n const baseKey = normalizeSlug(requested || displayName || getWorkspaceLabel(payload.workspace) || payload.providerType || 'runtime') || 'runtime';\n if (!existing.has(baseKey)) return baseKey;\n\n let suffix = 2;\n let candidate = `${baseKey}-${suffix}`;\n while (existing.has(candidate)) {\n suffix += 1;\n candidate = `${baseKey}-${suffix}`;\n }\n return candidate;\n}\n\nexport interface SessionHostSurfaceRecordLike {\n lifecycle?: string | null;\n surfaceKind?: SessionHostSurfaceKind | null;\n meta?: Record<string, unknown> | null;\n}\n\nconst LIVE_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'interrupted']);\n\nexport function isSessionHostLiveRuntime(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'live_runtime') return true;\n if (record.surfaceKind === 'recovery_snapshot' || record.surfaceKind === 'inactive_record') return false;\n const lifecycle = String(record.lifecycle || '').trim();\n return LIVE_LIFECYCLES.has(lifecycle);\n}\n\nexport function getSessionHostRecoveryLabel(meta: Record<string, unknown> | null | undefined): string | null {\n const recoveryState = typeof meta?.runtimeRecoveryState === 'string'\n ? String(meta.runtimeRecoveryState).trim()\n : '';\n if (!recoveryState) return null;\n if (recoveryState === 'auto_resumed') return 'restored after restart';\n if (recoveryState === 'resume_failed') return 'restore failed';\n if (recoveryState === 'host_restart_interrupted') return 'host restart interrupted';\n if (recoveryState === 'orphan_snapshot') return 'snapshot recovered';\n return recoveryState.replace(/_/g, ' ');\n}\n\nexport function isSessionHostRecoverySnapshot(record: SessionHostSurfaceRecordLike | null | undefined): boolean {\n if (!record) return false;\n if (record.surfaceKind === 'recovery_snapshot') return true;\n if (record.surfaceKind === 'live_runtime' || record.surfaceKind === 'inactive_record') return false;\n if (isSessionHostLiveRuntime(record)) return false;\n\n const lifecycle = String(record.lifecycle || '').trim();\n if (lifecycle && lifecycle !== 'stopped' && lifecycle !== 'failed') {\n return false;\n }\n\n const meta = record.meta || undefined;\n if (meta?.restoredFromStorage === true) return true;\n return getSessionHostRecoveryLabel(meta) !== null;\n}\n\nexport function getSessionHostSurfaceKind(record: SessionHostSurfaceRecordLike | null | undefined): SessionHostSurfaceKind {\n if (record?.surfaceKind === 'live_runtime' || record?.surfaceKind === 'recovery_snapshot' || record?.surfaceKind === 'inactive_record') {\n return record.surfaceKind;\n }\n if (isSessionHostLiveRuntime(record)) return 'live_runtime';\n if (isSessionHostRecoverySnapshot(record)) return 'recovery_snapshot';\n return 'inactive_record';\n}\n\nexport function resolveAttachableRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const record = resolveRuntimeRecord(records, identifier);\n const surfaceKind = getSessionHostSurfaceKind(record);\n if (surfaceKind === 'live_runtime') {\n return record;\n }\n if (surfaceKind === 'recovery_snapshot') {\n throw new Error(`Runtime ${record.runtimeKey} is a recovery snapshot, not a live attach target. Resume or recover it first.`);\n }\n throw new Error(`Runtime ${record.runtimeKey} is ${record.lifecycle}, not a live attach target.`);\n}\n\nfunction uniqueMatch(records: SessionHostRecord[], predicate: (record: SessionHostRecord) => boolean): SessionHostRecord | null {\n const matches = records.filter(predicate);\n if (matches.length === 1) return matches[0] || null;\n if (matches.length === 0) return null;\n const labels = matches.map((record) => `${record.runtimeKey} (${record.sessionId})`).join(', ');\n throw new Error(`Ambiguous runtime target. Matches: ${labels}`);\n}\n\nexport function resolveRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord {\n const target = identifier.trim();\n if (!target) {\n throw new Error('Runtime target is required');\n }\n\n const exact = uniqueMatch(records, (record) =>\n record.sessionId === target ||\n normalizeValue(record.runtimeKey) === normalizeValue(target) ||\n normalizeValue(record.displayName) === normalizeValue(target),\n );\n if (exact) return exact;\n\n const prefix = uniqueMatch(records, (record) =>\n record.sessionId.startsWith(target) ||\n normalizeValue(record.runtimeKey).startsWith(normalizeValue(target)),\n );\n if (prefix) return prefix;\n\n throw new Error(`Unknown runtime target: ${target}`);\n}\n\nexport function formatRuntimeOwner(record: Pick<SessionHostRecord, 'writeOwner'>): string {\n if (!record.writeOwner) return 'none';\n return `${record.writeOwner.ownerType}:${record.writeOwner.clientId}`;\n}\n","import * as os from 'os';\nimport * as path from 'path';\nimport * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport type {\n SessionHostEvent,\n SessionHostRequest,\n SessionHostRequestEnvelope,\n SessionHostResponse,\n SessionHostResponseEnvelope,\n SessionHostWireEnvelope,\n} from './types.js';\n\nexport interface SessionHostEndpoint {\n kind: 'unix' | 'pipe';\n path: string;\n}\n\nexport function getDefaultSessionHostEndpoint(appName = 'adhdev'): SessionHostEndpoint {\n if (process.platform === 'win32') {\n return {\n kind: 'pipe',\n path: `\\\\\\\\.\\\\pipe\\\\${appName}-session-host`,\n };\n }\n\n return {\n kind: 'unix',\n path: path.join(os.tmpdir(), `${appName}-session-host.sock`),\n };\n}\n\nfunction serializeEnvelope(envelope: SessionHostWireEnvelope): string {\n return `${JSON.stringify(envelope)}\\n`;\n}\n\nfunction createLineParser(onEnvelope: (envelope: SessionHostWireEnvelope) => void) {\n let buffer = '';\n return (chunk: Buffer | string) => {\n buffer += chunk.toString();\n let newlineIndex = buffer.indexOf('\\n');\n while (newlineIndex >= 0) {\n const rawLine = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n if (rawLine) {\n onEnvelope(JSON.parse(rawLine) as SessionHostWireEnvelope);\n }\n newlineIndex = buffer.indexOf('\\n');\n }\n };\n}\n\nexport interface SessionHostClientOptions {\n endpoint?: SessionHostEndpoint;\n appName?: string;\n}\n\nexport class SessionHostClient {\n readonly endpoint: SessionHostEndpoint;\n\n private socket: net.Socket | null = null;\n private requestWaiters = new Map<string, { resolve: (value: SessionHostResponse) => void; reject: (error: Error) => void }>();\n private eventListeners = new Set<(event: SessionHostEvent) => void>();\n\n constructor(options: SessionHostClientOptions = {}) {\n this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || 'adhdev');\n }\n\n async connect(): Promise<void> {\n if (this.socket && !this.socket.destroyed) return;\n // Cleanup stale socket reference left after error/disconnect\n if (this.socket) {\n try { this.socket.destroy(); } catch { /* noop */ }\n this.socket = null;\n }\n\n const socket = net.createConnection(this.endpoint.path);\n this.socket = socket;\n\n socket.on('data', createLineParser((envelope) => {\n if (envelope.kind === 'response') {\n const waiter = this.requestWaiters.get(envelope.requestId);\n if (waiter) {\n this.requestWaiters.delete(envelope.requestId);\n waiter.resolve(envelope.response);\n }\n return;\n }\n\n if (envelope.kind === 'event') {\n for (const listener of this.eventListeners) listener(envelope.event);\n }\n }));\n\n socket.on('error', (error) => {\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(error);\n }\n this.requestWaiters.clear();\n // Clear the dead socket reference so the next connect() creates a fresh connection\n // instead of skipping reconnection on the `!this.socket.destroyed` guard.\n if (this.socket === socket) {\n this.socket = null;\n }\n try { socket.destroy(); } catch { /* noop */ }\n });\n\n await new Promise<void>((resolve, reject) => {\n socket.once('connect', () => resolve());\n socket.once('error', reject);\n });\n }\n\n onEvent(listener: (event: SessionHostEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n async request<T = unknown>(request: SessionHostRequest): Promise<SessionHostResponse<T>> {\n await this.connect();\n if (!this.socket) throw new Error('Session host socket unavailable');\n\n const requestId = randomUUID();\n const envelope: SessionHostRequestEnvelope = {\n kind: 'request',\n requestId,\n request,\n };\n\n const response = await new Promise<SessionHostResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.requestWaiters.delete(requestId);\n reject(new Error(`Session host request timed out after 30s (${request.type})`));\n }, 30_000);\n this.requestWaiters.set(requestId, {\n resolve: (value) => { clearTimeout(timeout); resolve(value); },\n reject: (error) => { clearTimeout(timeout); reject(error); },\n });\n this.socket?.write(serializeEnvelope(envelope));\n });\n\n return response as SessionHostResponse<T>;\n }\n\n async close(): Promise<void> {\n if (!this.socket) return;\n const socket = this.socket;\n this.socket = null;\n for (const waiter of this.requestWaiters.values()) {\n waiter.reject(new Error('Session host client closed'));\n }\n this.requestWaiters.clear();\n await new Promise<void>((resolve) => {\n let settled = false;\n const done = () => {\n if (settled) return;\n settled = true;\n resolve();\n };\n socket.once('close', done);\n socket.end();\n socket.destroy();\n setTimeout(done, 50);\n });\n }\n}\n\nexport function createResponseEnvelope(requestId: string, response: SessionHostResponse): SessionHostResponseEnvelope {\n return {\n kind: 'response',\n requestId,\n response,\n };\n}\n\nexport function writeEnvelope(socket: Pick<net.Socket, 'write'>, envelope: SessionHostWireEnvelope): void {\n socket.write(serializeEnvelope(envelope));\n}\n\nexport { createLineParser };\n","/**\n * Shared PTY spawn environment utilities.\n *\n * Centralises npm/pnpm/yarn env variable stripping, terminal colour env\n * injection, and node-pty spawn-helper permission fixing.\n *\n * Used by daemon-core (provider-cli-adapter), session-host-daemon (runtime),\n * and daemon-cloud (session-host).\n */\n\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Strip package-manager injected environment variables that can interfere\n * with child CLI processes and apply terminal colour defaults.\n */\nexport function sanitizeSpawnEnv(\n baseEnv: NodeJS.ProcessEnv,\n overrides?: Record<string, string>,\n): Record<string, string> {\n const env: Record<string, string> = {};\n const source = { ...baseEnv, ...(overrides || {}) } as NodeJS.ProcessEnv;\n\n for (const [key, value] of Object.entries(source)) {\n if (typeof value !== 'string') continue;\n env[key] = value;\n }\n\n for (const key of Object.keys(env)) {\n if (\n key === 'INIT_CWD'\n || key === 'npm_command'\n || key === 'npm_execpath'\n || key === 'npm_node_execpath'\n || key.startsWith('npm_')\n || key.startsWith('npm_config_')\n || key.startsWith('npm_package_')\n || key.startsWith('npm_lifecycle_')\n || key.startsWith('PNPM_')\n || key.startsWith('YARN_')\n || key.startsWith('BUN_')\n || key.startsWith('VSCODE_')\n || key.startsWith('ELECTRON_')\n ) {\n delete env[key];\n }\n }\n\n // Do not leak the parent Codex app/extension thread identity into child CLIs.\n // Those variables cause codex-cli to attach to the current IDE thread instead\n // of creating or resuming its own standalone CLI thread, which breaks\n // providerSessionId discovery and reconnect semantics.\n delete env.CODEX_THREAD_ID;\n delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;\n\n applyTerminalColorEnv(env);\n return env;\n}\n\n/**\n * Apply preferred terminal colour environment variables.\n * Ensures TERM is set to xterm-256color and enables colour on Windows.\n */\nexport function applyTerminalColorEnv(env: Record<string, string>): void {\n if (env.NO_COLOR) return;\n\n if (!env.TERM || env.TERM === 'xterm-color') {\n env.TERM = 'xterm-256color';\n }\n if (!env.COLORTERM) env.COLORTERM = 'truecolor';\n\n if (process.platform === 'win32') {\n if (!env.FORCE_COLOR) env.FORCE_COLOR = '1';\n if (!env.CLICOLOR) env.CLICOLOR = '1';\n }\n}\n\n/**\n * Ensure node-pty's spawn-helper binary has execute permissions.\n *\n * npm's default umask can strip +x from the prebuilt spawn-helper on macOS/Linux,\n * causing EACCES when node-pty tries to fork. Best-effort fix.\n *\n * @param logFn Optional log callback for reporting the fix.\n */\nexport function ensureNodePtySpawnHelperPermissions(\n logFn?: (msg: string) => void,\n): void {\n if (os.platform() === 'win32') return;\n try {\n const fs = require('fs');\n const ptyDir = path.resolve(path.dirname(require.resolve('node-pty')), '..');\n const platformArch = `${os.platform()}-${os.arch()}`;\n const helper = path.join(ptyDir, 'prebuilds', platformArch, 'spawn-helper');\n if (fs.existsSync(helper)) {\n const stat = fs.statSync(helper);\n if (!(stat.mode & 0o111)) {\n fs.chmodSync(helper, stat.mode | 0o755);\n logFn?.(`Fixed spawn-helper permissions: ${helper}`);\n }\n }\n } catch {\n // best-effort: node-pty still works on most installs without this\n }\n}\n"],"mappings":";;;;;;;;AAUO,IAAM,wCAAwC,IAAI,OAAO;AAEzD,IAAM,oBAAN,MAAwB;AAAA,EACrB;AAAA,EACA,SAAyD,CAAC;AAAA,EAC1D,UAAU;AAAA,EACV,aAAa;AAAA,EAErB,YAAY,UAAoC,CAAC,GAAG;AAClD,SAAK,WAAW,QAAQ,YAAY;AAAA,EACtC;AAAA,EAEA,OAAO,MAAsB;AAC3B,UAAM,aAAa,OAAO,SAAS,WAAW,OAAO,OAAO,QAAQ,EAAE;AACtE,UAAM,QAAQ,OAAO,WAAW,YAAY,MAAM;AAClD,UAAM,MAAM,KAAK;AAEjB,SAAK,OAAO,KAAK,EAAE,KAAK,MAAM,YAAY,MAAM,CAAC;AACjD,SAAK,cAAc;AACnB,SAAK,KAAK;AACV,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,UAA0C;AACjD,UAAM,WAAW,OAAO,aAAa,WACjC,KAAK,OAAO,OAAO,WAAS,MAAM,MAAM,QAAQ,IAChD,KAAK;AAET,UAAM,OAAO,SAAS,IAAI,WAAS,MAAM,IAAI,EAAE,KAAK,EAAE;AACtD,UAAM,YAAY,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,OAAO,aAAa,YAAY,WAAW,KAAK,OAAO,CAAC,EAAE,MAAM;AAEtG,WAAO;AAAA,MACL,KAAK,KAAK,UAAU;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAA6D;AAC3D,WAAO;AAAA,MACL,iBAAiB,KAAK;AAAA,MACtB,aAAa,KAAK,UAAU;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,SAAS,CAAC;AACf,SAAK,aAAa;AAClB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,QAAQ,UAA+C;AACrD,SAAK,MAAM;AACX,UAAM,OAAO,OAAO,SAAS,QAAQ,EAAE;AACvC,QAAI,CAAC,MAAM;AACT,WAAK,UAAU,KAAK,IAAI,GAAG,OAAO,SAAS,OAAO,CAAC,IAAI,CAAC;AACxD;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,WAAW,MAAM,MAAM;AAC5C,UAAM,MAAM,KAAK,IAAI,GAAG,OAAO,SAAS,OAAO,CAAC,CAAC;AACjD,SAAK,SAAS,CAAC,EAAE,KAAK,MAAM,MAAM,MAAM,CAAC;AACzC,SAAK,aAAa;AAClB,SAAK,UAAU,MAAM;AACrB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEQ,OAAa;AACnB,WAAO,KAAK,aAAa,KAAK,YAAY,KAAK,OAAO,SAAS,GAAG;AAChE,YAAM,UAAU,KAAK,OAAO,MAAM;AAClC,UAAI,CAAC,QAAS;AACd,WAAK,cAAc,QAAQ;AAAA,IAC7B;AAAA,EACF;AACF;;;ACnFA,SAAS,kBAAkB;;;ACApB,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAEzC,SAAS,8BAA8B,OAA2B,UAA0B;AAC1F,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACjE,QAAM,UAAU,KAAK,MAAM,KAAK;AAChC,SAAO,UAAU,IAAI,UAAU;AACjC;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;;;ACfA,YAAY,UAAU;AAGtB,SAAS,cAAc,OAAuB;AAC5C,SAAO,MACJ,KAAK,EACL,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE;AAChB;AAEA,SAAS,eAAe,OAAuB;AAC7C,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;AAEO,SAAS,kBAAkB,WAA2B;AAC3D,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,aAAa,QAAQ,QAAQ,WAAW,EAAE;AAChD,QAAM,OAAY,cAAS,UAAU;AACrC,SAAO,QAAQ;AACjB;AAEO,SAAS,wBAAwB,SAA2F;AACjI,QAAM,WAAW,QAAQ,aAAa,KAAK;AAC3C,MAAI,SAAU,QAAO;AACrB,QAAM,iBAAiB,kBAAkB,QAAQ,SAAS;AAC1D,QAAM,gBAAgB,QAAQ,aAAa,KAAK,KAAK;AACrD,SAAO,GAAG,aAAa,MAAM,cAAc;AAC7C;AAEO,SAAS,gBACd,SACA,cACQ;AACR,QAAM,YAAY,QAAQ,YAAY,KAAK;AAC3C,QAAM,WAAW,IAAI,IAAI,MAAM,KAAK,cAAc,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC;AAC7E,QAAM,cAAc,wBAAwB,OAAO;AACnD,QAAM,UAAU,cAAc,aAAa,eAAe,kBAAkB,QAAQ,SAAS,KAAK,QAAQ,gBAAgB,SAAS,KAAK;AACxI,MAAI,CAAC,SAAS,IAAI,OAAO,EAAG,QAAO;AAEnC,MAAI,SAAS;AACb,MAAI,YAAY,GAAG,OAAO,IAAI,MAAM;AACpC,SAAO,SAAS,IAAI,SAAS,GAAG;AAC9B,cAAU;AACV,gBAAY,GAAG,OAAO,IAAI,MAAM;AAAA,EAClC;AACA,SAAO;AACT;AAQA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,YAAY,WAAW,YAAY,aAAa,CAAC;AAE3E,SAAS,yBAAyB,QAAkE;AACzG,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,gBAAgB,eAAgB,QAAO;AAClD,MAAI,OAAO,gBAAgB,uBAAuB,OAAO,gBAAgB,kBAAmB,QAAO;AACnG,QAAM,YAAY,OAAO,OAAO,aAAa,EAAE,EAAE,KAAK;AACtD,SAAO,gBAAgB,IAAI,SAAS;AACtC;AAEO,SAAS,4BAA4B,MAAiE;AAC3G,QAAM,gBAAgB,OAAO,MAAM,yBAAyB,WACxD,OAAO,KAAK,oBAAoB,EAAE,KAAK,IACvC;AACJ,MAAI,CAAC,cAAe,QAAO;AAC3B,MAAI,kBAAkB,eAAgB,QAAO;AAC7C,MAAI,kBAAkB,gBAAiB,QAAO;AAC9C,MAAI,kBAAkB,2BAA4B,QAAO;AACzD,MAAI,kBAAkB,kBAAmB,QAAO;AAChD,SAAO,cAAc,QAAQ,MAAM,GAAG;AACxC;AAEO,SAAS,8BAA8B,QAAkE;AAC9G,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,gBAAgB,oBAAqB,QAAO;AACvD,MAAI,OAAO,gBAAgB,kBAAkB,OAAO,gBAAgB,kBAAmB,QAAO;AAC9F,MAAI,yBAAyB,MAAM,EAAG,QAAO;AAE7C,QAAM,YAAY,OAAO,OAAO,aAAa,EAAE,EAAE,KAAK;AACtD,MAAI,aAAa,cAAc,aAAa,cAAc,UAAU;AAClE,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,OAAO,QAAQ;AAC5B,MAAI,MAAM,wBAAwB,KAAM,QAAO;AAC/C,SAAO,4BAA4B,IAAI,MAAM;AAC/C;AAEO,SAAS,0BAA0B,QAAiF;AACzH,MAAI,QAAQ,gBAAgB,kBAAkB,QAAQ,gBAAgB,uBAAuB,QAAQ,gBAAgB,mBAAmB;AACtI,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,yBAAyB,MAAM,EAAG,QAAO;AAC7C,MAAI,8BAA8B,MAAM,EAAG,QAAO;AAClD,SAAO;AACT;AAEO,SAAS,+BAA+B,SAA8B,YAAuC;AAClH,QAAM,SAAS,qBAAqB,SAAS,UAAU;AACvD,QAAM,cAAc,0BAA0B,MAAM;AACpD,MAAI,gBAAgB,gBAAgB;AAClC,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,qBAAqB;AACvC,UAAM,IAAI,MAAM,WAAW,OAAO,UAAU,gFAAgF;AAAA,EAC9H;AACA,QAAM,IAAI,MAAM,WAAW,OAAO,UAAU,OAAO,OAAO,SAAS,6BAA6B;AAClG;AAEA,SAAS,YAAY,SAA8B,WAA6E;AAC9H,QAAM,UAAU,QAAQ,OAAO,SAAS;AACxC,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC,KAAK;AAC/C,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,SAAS,QAAQ,IAAI,CAAC,WAAW,GAAG,OAAO,UAAU,KAAK,OAAO,SAAS,GAAG,EAAE,KAAK,IAAI;AAC9F,QAAM,IAAI,MAAM,sCAAsC,MAAM,EAAE;AAChE;AAEO,SAAS,qBAAqB,SAA8B,YAAuC;AACxG,QAAM,SAAS,WAAW,KAAK;AAC/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,QAAQ;AAAA,IAAY;AAAA,IAAS,CAAC,WAClC,OAAO,cAAc,UACrB,eAAe,OAAO,UAAU,MAAM,eAAe,MAAM,KAC3D,eAAe,OAAO,WAAW,MAAM,eAAe,MAAM;AAAA,EAC9D;AACA,MAAI,MAAO,QAAO;AAElB,QAAM,SAAS;AAAA,IAAY;AAAA,IAAS,CAAC,WACnC,OAAO,UAAU,WAAW,MAAM,KAClC,eAAe,OAAO,UAAU,EAAE,WAAW,eAAe,MAAM,CAAC;AAAA,EACrE;AACA,MAAI,OAAQ,QAAO;AAEnB,QAAM,IAAI,MAAM,2BAA2B,MAAM,EAAE;AACrD;AAEO,SAAS,mBAAmB,QAAuD;AACxF,MAAI,CAAC,OAAO,WAAY,QAAO;AAC/B,SAAO,GAAG,OAAO,WAAW,SAAS,IAAI,OAAO,WAAW,QAAQ;AACrE;;;AFlIO,IAAM,sBAAN,MAA0B;AAAA,EACvB,WAAW,oBAAI,IAAiC;AAAA,EAExD,cAAc,SAAkD;AAC9D,UAAM,YAAY,QAAQ,aAAa,WAAW;AAClD,QAAI,KAAK,SAAS,IAAI,SAAS,GAAG;AAChC,YAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,IACxD;AACA,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,gBAAgB,QAAQ,WAC1B,CAAC;AAAA,MACC,UAAU,QAAQ;AAAA,MAClB,MAAM,QAAQ,cAAc;AAAA,MAC5B,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IACd,CAAiC,IACjC,CAAC;AAEL,UAAM,SAA4B;AAAA,MAChC;AAAA,MACA,YAAY;AAAA,QACV;AAAA,QACA,MAAM,KAAK,KAAK,SAAS,OAAO,GAAG,CAAC,UAAU,MAAM,OAAO,UAAU;AAAA,MACvE;AAAA,MACA,aAAa,wBAAwB,OAAO;AAAA,MAC5C,gBAAgB,kBAAkB,QAAQ,SAAS;AAAA,MACnD,WAAW;AAAA,MACX,cAAc,QAAQ;AAAA,MACtB,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,MACvB,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,aAAa;AAAA,MACf;AAAA,MACA,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACzB;AAEA,WAAO,OAAO;AAAA,MACZ,iBAAiB,uBAAuB,QAAQ,IAAI;AAAA,MACpD,iBAAiB,uBAAuB,QAAQ,IAAI;AAAA,MACpD,GAAG,OAAO;AAAA,IACZ;AAEA,SAAK,SAAS,IAAI,WAAW;AAAA,MAC3B;AAAA,MACA,QAAQ,IAAI,kBAAkB;AAAA,IAChC,CAAC;AAED,WAAO,KAAK,YAAY,MAAM;AAAA,EAChC;AAAA,EAEA,eAAe,QAA2B,UAAoE;AAC5G,UAAM,SAAS,KAAK,YAAY,MAAM;AACtC,SAAK,SAAS,IAAI,OAAO,WAAW;AAAA,MAClC,QAAQ;AAAA,MACR,SAAS,MAAM;AACb,cAAM,SAAS,IAAI,kBAAkB;AACrC,YAAI,SAAU,QAAO,QAAQ,QAAQ;AACrC,eAAO;AAAA,MACT,GAAG;AAAA,IACL,CAAC;AACD,WAAO,KAAK,YAAY,MAAM;AAAA,EAChC;AAAA,EAEA,eAAoC;AAClC,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EACrC,IAAI,WAAS,KAAK,YAAY,MAAM,MAAM,CAAC,EAC3C,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc;AAAA,EACvD;AAAA,EAEA,WAAW,WAA6C;AACtD,UAAM,QAAQ,KAAK,SAAS,IAAI,SAAS;AACzC,WAAO,QAAQ,KAAK,YAAY,MAAM,MAAM,IAAI;AAAA,EAClD;AAAA,EAEA,aAAa,SAAkD;AAC7D,UAAM,QAAQ,KAAK,eAAe,QAAQ,SAAS;AACnD,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,qBAAqB;AAEzB,QAAI,QAAQ,eAAe,UAAU;AACnC,YAAM,uBAAuB,MAAM,OAAO,gBACvC,OAAO,YAAU,OAAO,SAAS,YAAY,OAAO,aAAa,QAAQ,QAAQ,EACjF,IAAI,YAAU,OAAO,QAAQ;AAChC,UAAI,qBAAqB,SAAS,GAAG;AACnC,cAAM,OAAO,kBAAkB,MAAM,OAAO,gBAAgB;AAAA,UAC1D,YAAU,EAAE,OAAO,SAAS,YAAY,OAAO,aAAa,QAAQ;AAAA,QACtE;AACA,YAAI,MAAM,OAAO,cAAc,qBAAqB,SAAS,MAAM,OAAO,WAAW,QAAQ,GAAG;AAC9F,+BAAqB;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,OAAO,gBAAgB,KAAK,YAAU,OAAO,aAAa,QAAQ,QAAQ;AAEjG,QAAI,UAAU;AACZ,eAAS,OAAO,QAAQ;AACxB,eAAS,WAAW,CAAC,CAAC,QAAQ;AAC9B,eAAS,aAAa;AAAA,IACxB,OAAO;AACL,YAAM,OAAO,gBAAgB,KAAK;AAAA,QAChC,UAAU,QAAQ;AAAA,QAClB,MAAM,QAAQ;AAAA,QACd,UAAU,CAAC,CAAC,QAAQ;AAAA,QACpB,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,QAAI,oBAAoB;AACtB,YAAM,OAAO,aAAa;AAAA,IAC5B;AAEA,UAAM,OAAO,iBAAiB;AAC9B,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,aAAa,SAAkD;AAC7D,UAAM,QAAQ,KAAK,eAAe,QAAQ,SAAS;AACnD,UAAM,OAAO,kBAAkB,MAAM,OAAO,gBAAgB,OAAO,YAAU,OAAO,aAAa,QAAQ,QAAQ;AACjH,QAAI,MAAM,OAAO,YAAY,aAAa,QAAQ,UAAU;AAC1D,YAAM,OAAO,aAAa;AAAA,IAC5B;AACA,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,aAAa,SAAiD;AAC5D,UAAM,QAAQ,KAAK,eAAe,QAAQ,SAAS;AACnD,QAAI,MAAM,OAAO,cAAc,MAAM,OAAO,WAAW,aAAa,QAAQ,YAAY,CAAC,QAAQ,OAAO;AACtG,YAAM,IAAI,MAAM,kBAAkB,MAAM,OAAO,WAAW,QAAQ,EAAE;AAAA,IACtE;AACA,UAAM,iBAAiB,MAAM,OAAO,gBAAgB,KAAK,YAAU,OAAO,aAAa,QAAQ,QAAQ;AACvG,QAAI,gBAAgB;AAClB,qBAAe,WAAW;AAC1B,qBAAe,aAAa,KAAK,IAAI;AAAA,IACvC;AACA,UAAM,OAAO,aAAa;AAAA,MACxB,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,YAAY,KAAK,IAAI;AAAA,IACvB;AACA,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,aAAa,SAAiD;AAC5D,UAAM,QAAQ,KAAK,eAAe,QAAQ,SAAS;AACnD,UAAM,iBAAiB,MAAM,OAAO,gBAAgB,KAAK,YAAU,OAAO,aAAa,QAAQ,QAAQ;AACvG,QAAI,gBAAgB;AAClB,qBAAe,WAAW;AAC1B,qBAAe,aAAa,KAAK,IAAI;AAAA,IACvC;AACA,QAAI,MAAM,OAAO,YAAY,aAAa,QAAQ,UAAU;AAC1D,YAAM,OAAO,aAAa;AAAA,IAC5B;AACA,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,aAAa,WAAmB,MAA0D;AACxF,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,MAAM,MAAM,OAAO,OAAO,IAAI;AACpC,UAAM,OAAO,SAAS,MAAM,OAAO,SAAS;AAC5C,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,YAAY,MAAM,MAAM,GAAG,IAAI;AAAA,EACvD;AAAA,EAEA,YAAY,WAAmB,UAAmB;AAChD,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,SAAS,MAAM,OAAO,SAAS;AAC5C,WAAO,MAAM,OAAO,SAAS,QAAQ;AAAA,EACvC;AAAA,EAEA,YAAY,WAAsC;AAChD,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,MAAM;AACnB,UAAM,OAAO,SAAS,MAAM,OAAO,SAAS;AAC5C,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,kBAAkB,WAAmB,MAA+B,UAAU,OAA0B;AACtG,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,OAAO,UAChB,EAAE,GAAG,KAAK,IACV;AAAA,MACE,GAAI,MAAM,OAAO,QAAQ,CAAC;AAAA,MAC1B,GAAG;AAAA,IACL;AACJ,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,YAAY,WAAmB,KAAiC;AAC9D,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,YAAY;AACzB,UAAM,OAAO,YAAY,MAAM,OAAO,aAAa,KAAK,IAAI;AAC5D,QAAI,OAAO,QAAQ,SAAU,OAAM,OAAO,QAAQ;AAClD,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,YAAY,WAAmB,YAAkC,WAA8B;AAC7F,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,YAAY;AACzB,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,aAAa,WAAmB,WAA0G;AACxI,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,UAAM,OAAO,YAAY;AACzB,UAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,WAAO,KAAK,YAAY,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,cAAc,WAA4B;AACxC,WAAO,KAAK,SAAS,OAAO,SAAS;AAAA,EACvC;AAAA,EAEQ,eAAe,WAAwC;AAC7D,UAAM,QAAQ,KAAK,SAAS,IAAI,SAAS;AACzC,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,oBAAoB,SAAS,EAAE;AAC3D,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,QAA8C;AAChE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,eAAe;AAAA,QACb,GAAG,OAAO;AAAA,QACV,MAAM,CAAC,GAAG,OAAO,cAAc,IAAI;AAAA,QACnC,KAAK,OAAO,cAAc,MAAM,EAAE,GAAG,OAAO,cAAc,IAAI,IAAI;AAAA,MACpE;AAAA,MACA,YAAY,OAAO,aAAa,EAAE,GAAG,OAAO,WAAW,IAAI;AAAA,MAC3D,iBAAiB,OAAO,gBAAgB,IAAI,aAAW,EAAE,GAAG,OAAO,EAAE;AAAA,MACrE,QAAQ,EAAE,GAAG,OAAO,OAAO;AAAA,MAC3B,MAAM,EAAE,GAAG,OAAO,KAAK;AAAA,IACzB;AAAA,EACF;AACF;;;AG5QA,YAAY,QAAQ;AACpB,YAAYA,WAAU;AACtB,YAAY,SAAS;AACrB,SAAS,cAAAC,mBAAkB;AAepB,SAAS,8BAA8B,UAAU,UAA+B;AACrF,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,gBAAgB,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAW,WAAQ,UAAO,GAAG,GAAG,OAAO,oBAAoB;AAAA,EAC7D;AACF;AAEA,SAAS,kBAAkB,UAA2C;AACpE,SAAO,GAAG,KAAK,UAAU,QAAQ,CAAC;AAAA;AACpC;AAEA,SAAS,iBAAiB,YAAyD;AACjF,MAAI,SAAS;AACb,SAAO,CAAC,UAA2B;AACjC,cAAU,MAAM,SAAS;AACzB,QAAI,eAAe,OAAO,QAAQ,IAAI;AACtC,WAAO,gBAAgB,GAAG;AACxB,YAAM,UAAU,OAAO,MAAM,GAAG,YAAY,EAAE,KAAK;AACnD,eAAS,OAAO,MAAM,eAAe,CAAC;AACtC,UAAI,SAAS;AACX,mBAAW,KAAK,MAAM,OAAO,CAA4B;AAAA,MAC3D;AACA,qBAAe,OAAO,QAAQ,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAOO,IAAM,oBAAN,MAAwB;AAAA,EACpB;AAAA,EAED,SAA4B;AAAA,EAC5B,iBAAiB,oBAAI,IAA+F;AAAA,EACpH,iBAAiB,oBAAI,IAAuC;AAAA,EAEpE,YAAY,UAAoC,CAAC,GAAG;AAClD,SAAK,WAAW,QAAQ,YAAY,8BAA8B,QAAQ,WAAW,QAAQ;AAAA,EAC/F;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,UAAU,CAAC,KAAK,OAAO,UAAW;AAE3C,QAAI,KAAK,QAAQ;AACf,UAAI;AAAE,aAAK,OAAO,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAAa;AAClD,WAAK,SAAS;AAAA,IAChB;AAEA,UAAM,SAAa,qBAAiB,KAAK,SAAS,IAAI;AACtD,SAAK,SAAS;AAEd,WAAO,GAAG,QAAQ,iBAAiB,CAAC,aAAa;AAC/C,UAAI,SAAS,SAAS,YAAY;AAChC,cAAM,SAAS,KAAK,eAAe,IAAI,SAAS,SAAS;AACzD,YAAI,QAAQ;AACV,eAAK,eAAe,OAAO,SAAS,SAAS;AAC7C,iBAAO,QAAQ,SAAS,QAAQ;AAAA,QAClC;AACA;AAAA,MACF;AAEA,UAAI,SAAS,SAAS,SAAS;AAC7B,mBAAW,YAAY,KAAK,eAAgB,UAAS,SAAS,KAAK;AAAA,MACrE;AAAA,IACF,CAAC,CAAC;AAEF,WAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,iBAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,eAAO,OAAO,KAAK;AAAA,MACrB;AACA,WAAK,eAAe,MAAM;AAG1B,UAAI,KAAK,WAAW,QAAQ;AAC1B,aAAK,SAAS;AAAA,MAChB;AACA,UAAI;AAAE,eAAO,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAAa;AAAA,IAC/C,CAAC;AAED,UAAM,IAAI,QAAc,CAACC,UAAS,WAAW;AAC3C,aAAO,KAAK,WAAW,MAAMA,SAAQ,CAAC;AACtC,aAAO,KAAK,SAAS,MAAM;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,QAAQ,UAAyD;AAC/D,SAAK,eAAe,IAAI,QAAQ;AAChC,WAAO,MAAM;AACX,WAAK,eAAe,OAAO,QAAQ;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,QAAqB,SAA8D;AACvF,UAAM,KAAK,QAAQ;AACnB,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,iCAAiC;AAEnE,UAAM,YAAYD,YAAW;AAC7B,UAAM,WAAuC;AAAA,MAC3C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,IAAI,QAA6B,CAACC,UAAS,WAAW;AAC3E,YAAM,UAAU,WAAW,MAAM;AAC/B,aAAK,eAAe,OAAO,SAAS;AACpC,eAAO,IAAI,MAAM,6CAA6C,QAAQ,IAAI,GAAG,CAAC;AAAA,MAChF,GAAG,GAAM;AACT,WAAK,eAAe,IAAI,WAAW;AAAA,QACjC,SAAS,CAAC,UAAU;AAAE,uBAAa,OAAO;AAAG,UAAAA,SAAQ,KAAK;AAAA,QAAG;AAAA,QAC7D,QAAQ,CAAC,UAAU;AAAE,uBAAa,OAAO;AAAG,iBAAO,KAAK;AAAA,QAAG;AAAA,MAC7D,CAAC;AACD,WAAK,QAAQ,MAAM,kBAAkB,QAAQ,CAAC;AAAA,IAChD,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,SAAS,KAAK;AACpB,SAAK,SAAS;AACd,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,aAAO,OAAO,IAAI,MAAM,4BAA4B,CAAC;AAAA,IACvD;AACA,SAAK,eAAe,MAAM;AAC1B,UAAM,IAAI,QAAc,CAACA,aAAY;AACnC,UAAI,UAAU;AACd,YAAM,OAAO,MAAM;AACjB,YAAI,QAAS;AACb,kBAAU;AACV,QAAAA,SAAQ;AAAA,MACV;AACA,aAAO,KAAK,SAAS,IAAI;AACzB,aAAO,IAAI;AACX,aAAO,QAAQ;AACf,iBAAW,MAAM,EAAE;AAAA,IACrB,CAAC;AAAA,EACH;AACF;AAEO,SAAS,uBAAuB,WAAmB,UAA4D;AACpH,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,cAAc,QAAmC,UAAyC;AACxG,SAAO,MAAM,kBAAkB,QAAQ,CAAC;AAC1C;;;ACzKA,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AAMf,SAAS,iBACZ,SACA,WACsB;AACtB,QAAM,MAA8B,CAAC;AACrC,QAAM,SAAS,EAAE,GAAG,SAAS,GAAI,aAAa,CAAC,EAAG;AAElD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,OAAO,UAAU,SAAU;AAC/B,QAAI,GAAG,IAAI;AAAA,EACf;AAEA,aAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAChC,QACI,QAAQ,cACL,QAAQ,iBACR,QAAQ,kBACR,QAAQ,uBACR,IAAI,WAAW,MAAM,KACrB,IAAI,WAAW,aAAa,KAC5B,IAAI,WAAW,cAAc,KAC7B,IAAI,WAAW,gBAAgB,KAC/B,IAAI,WAAW,OAAO,KACtB,IAAI,WAAW,OAAO,KACtB,IAAI,WAAW,MAAM,KACrB,IAAI,WAAW,SAAS,KACxB,IAAI,WAAW,WAAW,GAC/B;AACE,aAAO,IAAI,GAAG;AAAA,IAClB;AAAA,EACJ;AAMA,SAAO,IAAI;AACX,SAAO,IAAI;AAEX,wBAAsB,GAAG;AACzB,SAAO;AACX;AAMO,SAAS,sBAAsB,KAAmC;AACrE,MAAI,IAAI,SAAU;AAElB,MAAI,CAAC,IAAI,QAAQ,IAAI,SAAS,eAAe;AACzC,QAAI,OAAO;AAAA,EACf;AACA,MAAI,CAAC,IAAI,UAAW,KAAI,YAAY;AAEpC,MAAI,QAAQ,aAAa,SAAS;AAC9B,QAAI,CAAC,IAAI,YAAa,KAAI,cAAc;AACxC,QAAI,CAAC,IAAI,SAAU,KAAI,WAAW;AAAA,EACtC;AACJ;AAUO,SAAS,oCACZ,OACI;AACJ,MAAO,aAAS,MAAM,QAAS;AAC/B,MAAI;AACA,UAAM,KAAK,UAAQ,IAAI;AACvB,UAAM,SAAc,cAAa,cAAQ,UAAQ,QAAQ,UAAU,CAAC,GAAG,IAAI;AAC3E,UAAM,eAAe,GAAM,aAAS,CAAC,IAAO,SAAK,CAAC;AAClD,UAAM,SAAc,WAAK,QAAQ,aAAa,cAAc,cAAc;AAC1E,QAAI,GAAG,WAAW,MAAM,GAAG;AACvB,YAAM,OAAO,GAAG,SAAS,MAAM;AAC/B,UAAI,EAAE,KAAK,OAAO,KAAQ;AACtB,WAAG,UAAU,QAAQ,KAAK,OAAO,GAAK;AACtC,gBAAQ,mCAAmC,MAAM,EAAE;AAAA,MACvD;AAAA,IACJ;AAAA,EACJ,QAAQ;AAAA,EAER;AACJ;","names":["path","randomUUID","resolve","os","path"]}
@@ -323,6 +323,7 @@ type SessionHostWireEnvelope = SessionHostRequestEnvelope | SessionHostResponseE
323
323
  interface SessionRingBufferOptions {
324
324
  maxBytes?: number;
325
325
  }
326
+ declare const DEFAULT_SESSION_RING_BUFFER_MAX_BYTES: number;
326
327
  declare class SessionRingBuffer {
327
328
  private maxBytes;
328
329
  private chunks;
@@ -440,4 +441,4 @@ declare function applyTerminalColorEnv(env: Record<string, string>): void;
440
441
  */
441
442
  declare function ensureNodePtySpawnHelperPermissions(logFn?: (msg: string) => void): void;
442
443
 
443
- export { type AcquireWritePayload, type AttachSessionPayload, type ClearSessionBufferPayload, type CreateSessionPayload, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostDiagnostics, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSurfaceKind, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, createLineParser, createResponseEnvelope, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, resolveAttachableRuntimeRecord, resolveRuntimeRecord, sanitizeSpawnEnv, writeEnvelope };
444
+ export { type AcquireWritePayload, type AttachSessionPayload, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostDiagnostics, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSurfaceKind, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, createLineParser, createResponseEnvelope, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, resolveAttachableRuntimeRecord, resolveRuntimeRecord, sanitizeSpawnEnv, writeEnvelope };
@@ -323,6 +323,7 @@ type SessionHostWireEnvelope = SessionHostRequestEnvelope | SessionHostResponseE
323
323
  interface SessionRingBufferOptions {
324
324
  maxBytes?: number;
325
325
  }
326
+ declare const DEFAULT_SESSION_RING_BUFFER_MAX_BYTES: number;
326
327
  declare class SessionRingBuffer {
327
328
  private maxBytes;
328
329
  private chunks;
@@ -440,4 +441,4 @@ declare function applyTerminalColorEnv(env: Record<string, string>): void;
440
441
  */
441
442
  declare function ensureNodePtySpawnHelperPermissions(logFn?: (msg: string) => void): void;
442
443
 
443
- export { type AcquireWritePayload, type AttachSessionPayload, type ClearSessionBufferPayload, type CreateSessionPayload, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostDiagnostics, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSurfaceKind, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, createLineParser, createResponseEnvelope, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, resolveAttachableRuntimeRecord, resolveRuntimeRecord, sanitizeSpawnEnv, writeEnvelope };
444
+ export { type AcquireWritePayload, type AttachSessionPayload, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostDiagnostics, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSurfaceKind, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, createLineParser, createResponseEnvelope, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, resolveAttachableRuntimeRecord, resolveRuntimeRecord, sanitizeSpawnEnv, writeEnvelope };
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  DEFAULT_SESSION_HOST_COLS: () => DEFAULT_SESSION_HOST_COLS,
34
34
  DEFAULT_SESSION_HOST_ROWS: () => DEFAULT_SESSION_HOST_ROWS,
35
+ DEFAULT_SESSION_RING_BUFFER_MAX_BYTES: () => DEFAULT_SESSION_RING_BUFFER_MAX_BYTES,
35
36
  SessionHostClient: () => SessionHostClient,
36
37
  SessionHostRegistry: () => SessionHostRegistry,
37
38
  SessionRingBuffer: () => SessionRingBuffer,
@@ -58,13 +59,14 @@ __export(index_exports, {
58
59
  module.exports = __toCommonJS(index_exports);
59
60
 
60
61
  // src/buffer.ts
62
+ var DEFAULT_SESSION_RING_BUFFER_MAX_BYTES = 4 * 1024 * 1024;
61
63
  var SessionRingBuffer = class {
62
64
  maxBytes;
63
65
  chunks = [];
64
66
  nextSeq = 1;
65
67
  totalBytes = 0;
66
68
  constructor(options = {}) {
67
- this.maxBytes = options.maxBytes ?? 512 * 1024;
69
+ this.maxBytes = options.maxBytes ?? DEFAULT_SESSION_RING_BUFFER_MAX_BYTES;
68
70
  }
69
71
  append(data) {
70
72
  const normalized = typeof data === "string" ? data : String(data ?? "");
@@ -673,6 +675,7 @@ function ensureNodePtySpawnHelperPermissions(logFn) {
673
675
  0 && (module.exports = {
674
676
  DEFAULT_SESSION_HOST_COLS,
675
677
  DEFAULT_SESSION_HOST_ROWS,
678
+ DEFAULT_SESSION_RING_BUFFER_MAX_BYTES,
676
679
  SessionHostClient,
677
680
  SessionHostRegistry,
678
681
  SessionRingBuffer,