@holdpoint/live-daemon 0.1.0-alpha.2 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/singleton.ts","../src/server.ts","../src/auth.ts","../src/store.ts","../src/conflict-tracker.ts","../src/project-identity.ts","../src/router.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { createServer } from \"node:net\";\nimport os from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const DaemonLockSchema = z.object({\n version: z.string().min(1),\n pid: z.number().int().positive(),\n port: z.number().int().positive(),\n token: z.string().min(1),\n started_at: z.number().int().nonnegative(),\n host: z.string().min(1),\n});\n\nexport type DaemonLock = z.infer<typeof DaemonLockSchema>;\n\nexport function resolveHoldpointHome(homeDir?: string): string {\n return resolve(homeDir ?? process.env.HOLDPOINT_HOME ?? join(os.homedir(), \".holdpoint\"));\n}\n\nexport function ensureHoldpointHome(homeDir?: string): string {\n const root = resolveHoldpointHome(homeDir);\n mkdirSync(root, { recursive: true, mode: 0o700 });\n return root;\n}\n\nexport function getDaemonLockPath(homeDir?: string): string {\n return join(resolveHoldpointHome(homeDir), \"daemon.lock\");\n}\n\nexport function readDaemonLock(homeDir?: string): DaemonLock | null {\n const lockPath = getDaemonLockPath(homeDir);\n if (!existsSync(lockPath)) return null;\n try {\n return DaemonLockSchema.parse(JSON.parse(readFileSync(lockPath, \"utf8\")));\n } catch {\n return null;\n }\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function findFreePort(host = \"127.0.0.1\"): Promise<number> {\n return await new Promise<number>((resolvePromise, reject) => {\n const server = createServer();\n server.listen(0, host, () => {\n const address = server.address();\n if (!address || typeof address === \"string\") {\n server.close();\n reject(new Error(\"Expected TCP address\"));\n return;\n }\n const { port } = address;\n server.close((err) => {\n if (err) reject(err);\n else resolvePromise(port);\n });\n });\n server.on(\"error\", reject);\n });\n}\n\nexport function createDaemonLock(port: number, version: string): DaemonLock {\n return {\n version,\n pid: process.pid,\n port,\n token: randomBytes(32).toString(\"hex\"),\n started_at: Date.now(),\n host: `${os.platform()}-${os.arch()}`,\n };\n}\n\nexport function writeDaemonLockExclusive(lock: DaemonLock, homeDir?: string): void {\n ensureHoldpointHome(homeDir);\n writeFileSync(getDaemonLockPath(homeDir), JSON.stringify(lock, null, 2) + \"\\n\", {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n}\n\nexport function removeDaemonLock(homeDir?: string, expectedToken?: string): void {\n const lockPath = getDaemonLockPath(homeDir);\n if (!existsSync(lockPath)) return;\n if (expectedToken) {\n const lock = readDaemonLock(homeDir);\n if (!lock || lock.token !== expectedToken) {\n return;\n }\n }\n try {\n unlinkSync(lockPath);\n } catch {\n /* ignore cleanup races */\n }\n}\n\nasync function fetchHealth(port: number, timeoutMs: number): Promise<boolean> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: controller.signal,\n });\n return response.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport async function waitForDaemonHealthy(\n lock: DaemonLock,\n timeoutMs = 5_000,\n pollMs = 100,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await fetchHealth(lock.port, Math.min(pollMs, timeoutMs))) {\n return true;\n }\n await new Promise((resolvePromise) => setTimeout(resolvePromise, pollMs));\n }\n return false;\n}\n\nexport async function readHealthyDaemonLock(homeDir?: string): Promise<DaemonLock | null> {\n const lock = readDaemonLock(homeDir);\n if (!lock) return null;\n if (!isProcessAlive(lock.pid)) {\n removeDaemonLock(homeDir);\n return null;\n }\n if (!(await waitForDaemonHealthy(lock, 300, 100))) {\n removeDaemonLock(homeDir);\n return null;\n }\n return lock;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { randomUUID } from \"node:crypto\";\nimport { createReadStream, existsSync } from \"node:fs\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\nimport type { EventV1, ServerMessage } from \"@holdpoint/live-protocol\";\nimport {\n ClientMessageSchema,\n ControlRequestSchema,\n EventV1Schema,\n EventsBatchSchema,\n} from \"@holdpoint/live-protocol\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n authorizeRequest,\n authorizeWebSocket,\n readJsonBody,\n writeJson,\n writeUiAuthCookie,\n} from \"./auth.js\";\nimport { matchesSubscription, type Subscription } from \"./router.js\";\nimport type { LiveStore } from \"./store.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst LIVE_UI_DIR = join(__dirname, \"live-ui\");\nconst CONTENT_SECURITY_POLICY =\n \"default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: http:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'\";\nconst MIME: Record<string, string> = {\n \".css\": \"text/css; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".ico\": \"image/x-icon\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml\",\n};\n\nexport interface StartLiveServerOptions {\n host?: string;\n port: number;\n token: string;\n version: string;\n startedAt: number;\n store: LiveStore;\n}\n\nexport interface RunningLiveServer {\n host: string;\n port: number;\n close(): Promise<void>;\n closed: Promise<void>;\n}\n\nfunction sendSocketMessage(socket: WebSocket, message: ServerMessage): void {\n socket.send(JSON.stringify(message));\n}\n\nfunction decodeRawData(raw: RawData): string {\n if (typeof raw === \"string\") return raw;\n if (raw instanceof Buffer) return raw.toString(\"utf8\");\n if (Array.isArray(raw)) return Buffer.concat(raw).toString(\"utf8\");\n return Buffer.from(new Uint8Array(raw)).toString(\"utf8\");\n}\n\nfunction getEventsForScope(\n store: LiveStore,\n subscription: Subscription,\n sinceSeq: number,\n): EventV1[] {\n switch (subscription.scope) {\n case \"all\":\n return store.getAllEvents(sinceSeq);\n case \"project\":\n return subscription.key ? store.getProjectEvents(subscription.key, sinceSeq) : [];\n case \"session\":\n return subscription.key ? store.getSessionEvents(subscription.key, sinceSeq) : [];\n }\n}\n\nfunction buildControlStateEvent(\n session: {\n project_hash: string;\n engine: string;\n session_id: string;\n cwd: string;\n caps?: EventV1[\"caps\"];\n },\n controlOnline: boolean,\n): EventV1 {\n return {\n v: 1,\n id: randomUUID(),\n ts: Date.now(),\n engine: session.engine,\n session_id: session.session_id,\n project_hash: session.project_hash,\n cwd: session.cwd,\n caps: {\n ...(session.caps ?? {}),\n can_control: session.caps?.can_control ?? true,\n control_online: controlOnline,\n },\n type: \"meta\",\n payload: {\n kind: controlOnline ? \"control_socket_registered\" : \"control_socket_disconnected\",\n },\n };\n}\n\nfunction servePlaceholder(res: ServerResponse): void {\n res.writeHead(200, {\n \"cache-control\": \"no-store\",\n \"content-security-policy\": CONTENT_SECURITY_POLICY,\n \"content-type\": \"text/html; charset=utf-8\",\n });\n res.end(\n '<!doctype html><title>Holdpoint Live</title><body style=\"font-family:system-ui;background:#0b0f14;color:#f5f1e8;padding:32px\"><h1>Holdpoint Live</h1><p>Live UI assets were not found in this build. Rebuild the monorepo with <code>pnpm turbo build</code>.</p></body>',\n );\n}\n\nfunction serveUiAsset(res: ServerResponse, filePath: string): void {\n const mime = MIME[extname(filePath)] ?? \"application/octet-stream\";\n const headers: Record<string, string> = {\n \"cache-control\": \"no-store\",\n \"content-type\": mime,\n };\n if (filePath.endsWith(\".html\")) {\n headers[\"content-security-policy\"] = CONTENT_SECURITY_POLICY;\n }\n res.writeHead(200, headers);\n createReadStream(filePath).pipe(res);\n}\n\nfunction resolveUiFilePath(pathname: string): string | null {\n const requested = pathname === \"/\" ? \"index.html\" : pathname.replace(/^\\//, \"\");\n const candidate = resolve(LIVE_UI_DIR, requested);\n if (!candidate.startsWith(LIVE_UI_DIR)) {\n return null;\n }\n if (existsSync(candidate)) {\n return candidate;\n }\n return existsSync(join(LIVE_UI_DIR, \"index.html\")) ? join(LIVE_UI_DIR, \"index.html\") : null;\n}\n\nexport async function startLiveServer(options: StartLiveServerOptions): Promise<RunningLiveServer> {\n const host = options.host ?? \"127.0.0.1\";\n const subscriptions = new Map<WebSocket, Subscription[]>();\n const controlSockets = new Map<string, WebSocket>();\n const socketControlKeys = new Map<WebSocket, Set<string>>();\n const server = createServer((req, res) => {\n void handleRequest(req, res, options, subscriptions).catch((error: unknown) => {\n writeJson(res, 500, { ok: false, error: (error as Error).message });\n });\n });\n const wss = new WebSocketServer({ noServer: true });\n\n const broadcastEvent = (event: EventV1): void => {\n for (const [socket, socketSubscriptions] of subscriptions.entries()) {\n if (socket.readyState !== WebSocket.OPEN) continue;\n if (socketSubscriptions.some((subscription) => matchesSubscription(subscription, event))) {\n sendSocketMessage(socket, { type: \"event\", event });\n }\n }\n };\n\n const ingestAndBroadcast = async (event: EventV1): Promise<EventV1[]> => {\n const accepted = await options.store.ingest(event);\n for (const acceptedEvent of accepted) {\n broadcastEvent(acceptedEvent);\n }\n return accepted;\n };\n\n const emitControlState = async (sessionKey: string, controlOnline: boolean): Promise<void> => {\n const summary = options.store.getSessionSummary(sessionKey);\n if (!summary) return;\n await ingestAndBroadcast(buildControlStateEvent(summary, controlOnline));\n };\n\n const registerControlSocket = async (sessionKey: string, socket: WebSocket): Promise<void> => {\n const previous = controlSockets.get(sessionKey);\n if (previous && previous !== socket) {\n socketControlKeys.get(previous)?.delete(sessionKey);\n }\n controlSockets.set(sessionKey, socket);\n const keys = socketControlKeys.get(socket) ?? new Set<string>();\n keys.add(sessionKey);\n socketControlKeys.set(socket, keys);\n await emitControlState(sessionKey, true);\n };\n\n const unregisterControlSocket = async (sessionKey: string, socket: WebSocket): Promise<void> => {\n if (controlSockets.get(sessionKey) !== socket) return;\n controlSockets.delete(sessionKey);\n const keys = socketControlKeys.get(socket);\n keys?.delete(sessionKey);\n if (keys && keys.size === 0) {\n socketControlKeys.delete(socket);\n }\n await emitControlState(sessionKey, false);\n };\n\n const unregisterSocketControls = async (socket: WebSocket): Promise<void> => {\n const keys = [...(socketControlKeys.get(socket) ?? [])];\n for (const sessionKey of keys) {\n await unregisterControlSocket(sessionKey, socket);\n }\n };\n\n wss.on(\"connection\", (socket: WebSocket) => {\n subscriptions.set(socket, []);\n socket.on(\"message\", (raw: RawData) => {\n void (async () => {\n let message: unknown;\n try {\n message = JSON.parse(decodeRawData(raw));\n } catch {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"invalid_json\",\n message: \"Expected JSON message\",\n });\n return;\n }\n\n const parsed = ClientMessageSchema.safeParse(message);\n if (!parsed.success) {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"invalid_message\",\n message: parsed.error.errors[0]?.message ?? \"Invalid message\",\n });\n return;\n }\n\n switch (parsed.data.type) {\n case \"subscribe\": {\n if (parsed.data.scope !== \"all\" && !parsed.data.key) {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"missing_key\",\n message: \"Expected a key for session/project subscriptions\",\n });\n return;\n }\n\n const subscription =\n parsed.data.key !== undefined\n ? { scope: parsed.data.scope, key: parsed.data.key }\n : { scope: parsed.data.scope };\n const next = subscriptions.get(socket) ?? [];\n next.push(subscription);\n subscriptions.set(socket, next);\n\n const backlog = getEventsForScope(\n options.store,\n subscription,\n parsed.data.since_seq ?? 0,\n );\n if (backlog.length > 0) {\n sendSocketMessage(socket, { type: \"events_batch\", events: backlog });\n }\n sendSocketMessage(socket, {\n type: \"ack\",\n for: parsed.data.scope === \"all\" ? \"all\" : (parsed.data.key ?? parsed.data.scope),\n });\n break;\n }\n case \"register_control\": {\n await registerControlSocket(parsed.data.session_key, socket);\n sendSocketMessage(socket, { type: \"ack\", for: parsed.data.session_key });\n break;\n }\n case \"unsubscribe\": {\n const key = parsed.data.key;\n const next = (subscriptions.get(socket) ?? []).filter(\n (subscription) => subscription.key !== key,\n );\n subscriptions.set(socket, next);\n sendSocketMessage(socket, { type: \"ack\", for: key });\n break;\n }\n case \"publish_event\": {\n const accepted = await options.store.ingest(parsed.data.event);\n for (const event of accepted) {\n broadcastEvent(event);\n }\n sendSocketMessage(socket, { type: \"ack\", for: parsed.data.event.id });\n break;\n }\n case \"ping\":\n sendSocketMessage(socket, { type: \"pong\" });\n break;\n }\n })();\n });\n\n socket.on(\"close\", () => {\n subscriptions.delete(socket);\n void unregisterSocketControls(socket).catch(() => {});\n });\n });\n\n server.on(\"upgrade\", (req, socket, head) => {\n const url = new URL(req.url ?? \"/\", `http://${host}:${options.port}`);\n if (url.pathname !== \"/v1/stream\" || !authorizeWebSocket(req, options.token, options.port)) {\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n\n wss.handleUpgrade(req, socket, head, (ws: WebSocket) => {\n wss.emit(\"connection\", ws, req);\n });\n });\n\n await new Promise<void>((resolvePromise, reject) => {\n server.listen(options.port, host, resolvePromise);\n server.on(\"error\", reject);\n });\n\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"Expected TCP address\");\n }\n const actualPort = address.port;\n\n const closed = new Promise<void>((resolvePromise, reject) => {\n server.on(\"close\", () => resolvePromise());\n server.on(\"error\", reject);\n });\n\n async function close(): Promise<void> {\n for (const socket of subscriptions.keys()) {\n socket.close();\n }\n await new Promise<void>((resolvePromise, reject) => {\n wss.close((err?: Error) => (err ? reject(err) : resolvePromise()));\n });\n await new Promise<void>((resolvePromise, reject) => {\n server.close((err) => (err ? reject(err) : resolvePromise()));\n });\n }\n\n async function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n state: StartLiveServerOptions,\n _subscriptions: Map<WebSocket, Subscription[]>,\n ): Promise<void> {\n const url = new URL(req.url ?? \"/\", `http://${host}:${actualPort}`);\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n writeJson(res, 200, { ok: true, version: state.version, started_at: state.startedAt });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/__holdpoint/live-auth\") {\n if (url.searchParams.get(\"token\") !== state.token) {\n writeJson(res, 401, { ok: false, error: \"Unauthorized\" });\n return;\n }\n\n const redirectUrl = new URL(\"/\", `http://${host}:${actualPort}`);\n for (const [key, value] of url.searchParams.entries()) {\n if (key !== \"token\") {\n redirectUrl.searchParams.set(key, value);\n }\n }\n writeUiAuthCookie(res, state.token);\n res.writeHead(302, {\n location: redirectUrl.toString(),\n \"cache-control\": \"no-store\",\n });\n res.end();\n return;\n }\n\n if (url.pathname.startsWith(\"/v1/\") && !authorizeRequest(req, res, state.token, actualPort)) {\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/events\") {\n const event = EventV1Schema.parse(await readJsonBody(req));\n const accepted = await ingestAndBroadcast(event);\n writeJson(res, 200, { ok: true, accepted: accepted.length });\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/events/batch\") {\n const events = EventsBatchSchema.parse(await readJsonBody(req));\n const accepted: EventV1[] = [];\n for (const event of events) {\n accepted.push(...(await ingestAndBroadcast(event)));\n }\n writeJson(res, 200, { ok: true, accepted: accepted.length });\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/control\") {\n const request = ControlRequestSchema.parse(await readJsonBody(req));\n const session = state.store.getSessionSummary(request.session_key);\n if (!session) {\n writeJson(res, 404, { ok: false, error: \"Session not found\" });\n return;\n }\n\n const controlSocket = controlSockets.get(request.session_key);\n if (!controlSocket || controlSocket.readyState !== WebSocket.OPEN) {\n writeJson(res, 409, { ok: false, error: \"Control socket not connected\" });\n return;\n }\n\n await ingestAndBroadcast({\n v: 1,\n id: randomUUID(),\n ts: Date.now(),\n engine: session.engine,\n session_id: session.session_id,\n project_hash: session.project_hash,\n cwd: session.cwd,\n type: \"control\",\n payload: request.command,\n });\n sendSocketMessage(controlSocket, {\n type: \"control\",\n session_key: request.session_key,\n command: request.command,\n });\n writeJson(res, 200, { ok: true, delivered: true });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v1/projects\") {\n writeJson(res, 200, { projects: state.store.listProjects() });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v1/sessions\") {\n const projectHash = url.searchParams.get(\"project_hash\") ?? undefined;\n writeJson(res, 200, { sessions: state.store.listSessions(projectHash) });\n return;\n }\n\n if (\n req.method === \"GET\" &&\n url.pathname.startsWith(\"/v1/sessions/\") &&\n url.pathname.endsWith(\"/events\")\n ) {\n const sessionKey = decodeURIComponent(\n url.pathname.replace(\"/v1/sessions/\", \"\").replace(/\\/events$/, \"\"),\n );\n const sinceSeq = Number(\n url.searchParams.get(\"since_seq\") ?? url.searchParams.get(\"since\") ?? \"0\",\n );\n const limit = Number(url.searchParams.get(\"limit\") ?? \"500\");\n writeJson(res, 200, {\n session_key: sessionKey,\n since_seq: Number.isFinite(sinceSeq) ? sinceSeq : 0,\n max_seq: state.store.getSessionLatestSeq(sessionKey),\n events: state.store.getSessionEvents(\n sessionKey,\n Number.isFinite(sinceSeq) ? sinceSeq : 0,\n Number.isFinite(limit) ? limit : 500,\n ),\n });\n return;\n }\n\n if (req.method === \"DELETE\" && url.pathname.startsWith(\"/v1/sessions/\")) {\n const sessionKey = decodeURIComponent(url.pathname.replace(\"/v1/sessions/\", \"\"));\n const removed = await state.store.purgeSession(sessionKey);\n writeJson(\n res,\n removed ? 200 : 404,\n removed ? { ok: true } : { ok: false, error: \"Session not found\" },\n );\n return;\n }\n\n if (req.method === \"GET\") {\n const filePath = resolveUiFilePath(url.pathname);\n if (!filePath) {\n servePlaceholder(res);\n return;\n }\n serveUiAsset(res, filePath);\n return;\n }\n\n writeJson(res, 404, { ok: false, error: \"Not found\" });\n }\n\n return {\n host,\n port: actualPort,\n close,\n closed,\n };\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport const LIVE_UI_COOKIE = \"holdpoint_live_token\";\n\nfunction parseCookies(raw: string | undefined): Map<string, string> {\n const cookies = new Map<string, string>();\n if (!raw) {\n return cookies;\n }\n\n for (const part of raw.split(\";\")) {\n const [name, ...valueParts] = part.trim().split(\"=\");\n if (!name) continue;\n cookies.set(name, decodeURIComponent(valueParts.join(\"=\")));\n }\n\n return cookies;\n}\n\nfunction getRequestToken(req: IncomingMessage): string | null {\n const auth = req.headers.authorization;\n if (auth?.startsWith(\"Bearer \")) {\n return auth.slice(\"Bearer \".length);\n }\n\n return parseCookies(req.headers.cookie).get(LIVE_UI_COOKIE) ?? null;\n}\n\nexport function writeJson(\n res: ServerResponse,\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n): void {\n res.writeHead(statusCode, {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json; charset=utf-8\",\n ...headers,\n });\n res.end(JSON.stringify(body));\n}\n\nexport async function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n if (chunks.length === 0) return null;\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n}\n\nexport function authorizeRequest(\n req: IncomingMessage,\n res: ServerResponse,\n token: string,\n port: number,\n): boolean {\n const origin = req.headers.origin;\n if (origin && origin !== `http://127.0.0.1:${port}`) {\n writeJson(res, 403, { ok: false, error: \"Origin not allowed\" });\n return false;\n }\n\n if (getRequestToken(req) !== token) {\n writeJson(res, 401, { ok: false, error: \"Unauthorized\" });\n return false;\n }\n\n return true;\n}\n\nexport function authorizeWebSocket(req: IncomingMessage, token: string, port: number): boolean {\n const origin = req.headers.origin;\n if (origin && origin !== `http://127.0.0.1:${port}`) {\n return false;\n }\n\n if (getRequestToken(req) === token) {\n return true;\n }\n\n const raw = req.headers[\"sec-websocket-protocol\"];\n const protocols = (typeof raw === \"string\" ? [raw] : [])\n .flatMap((entry) => entry.split(\",\"))\n .map((entry) => entry.trim())\n .filter(Boolean);\n\n return protocols.includes(`holdpoint-${token}`);\n}\n\nexport function writeUiAuthCookie(res: ServerResponse, token: string): void {\n res.setHeader(\n \"set-cookie\",\n `${LIVE_UI_COOKIE}=${encodeURIComponent(token)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=3600`,\n );\n}\n","import { appendFile, mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { EventV1, ProjectSummary, SessionSummary } from \"@holdpoint/live-protocol\";\nimport { EventV1Schema } from \"@holdpoint/live-protocol\";\nimport { ConflictTracker } from \"./conflict-tracker.js\";\nimport { identifyProject } from \"./project-identity.js\";\n\ninterface StoredProject extends ProjectSummary {\n root: string;\n}\n\ninterface StoredSession extends SessionSummary {\n events: EventV1[];\n filePath: string;\n}\n\nfunction sessionFileName(engine: string, sessionId: string): string {\n return `${encodeURIComponent(engine)}-${encodeURIComponent(sessionId)}.jsonl`;\n}\n\nasync function readJsonl(filePath: string): Promise<EventV1[]> {\n const raw = await readFile(filePath, \"utf8\");\n return raw\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .flatMap((line) => {\n try {\n return [EventV1Schema.parse(JSON.parse(line))];\n } catch {\n return [];\n }\n });\n}\n\nexport function buildSessionKey(\n event: Pick<EventV1, \"project_hash\" | \"engine\" | \"session_id\">,\n): string {\n return `${event.project_hash}:${event.engine}:${event.session_id}`;\n}\n\nexport class LiveStore {\n private readonly homeDir: string;\n private readonly projects = new Map<string, StoredProject>();\n private readonly sessions = new Map<string, StoredSession>();\n private readonly projectIdentityCache = new Map<string, ReturnType<typeof identifyProject>>();\n private readonly conflictTracker = new ConflictTracker();\n private nextSeq = 1;\n\n private constructor(homeDir: string) {\n this.homeDir = homeDir;\n }\n\n static async create(homeDir: string): Promise<LiveStore> {\n const store = new LiveStore(homeDir);\n await store.hydrate();\n return store;\n }\n\n async replayPending(): Promise<void> {\n const pendingDir = join(this.homeDir, \"spool\", \"pending\");\n if (!existsSync(pendingDir)) return;\n const entries = await readdir(pendingDir);\n for (const entry of entries.filter((name) => name.endsWith(\".jsonl\"))) {\n const filePath = join(pendingDir, entry);\n const events = await readJsonl(filePath);\n if (events.length > 0) {\n await this.ingestMany(events);\n }\n await rm(filePath, { force: true });\n }\n }\n\n async ingestMany(events: EventV1[]): Promise<EventV1[]> {\n const accepted: EventV1[] = [];\n for (const event of events) {\n accepted.push(...(await this.ingest(event)));\n }\n return accepted;\n }\n\n async ingest(event: EventV1): Promise<EventV1[]> {\n const accepted: EventV1[] = [];\n const storedPrimary = await this.persistEvent(event);\n accepted.push(storedPrimary);\n\n for (const derivedEvent of this.conflictTracker.handleEvent(storedPrimary)) {\n accepted.push(await this.persistEvent(derivedEvent));\n }\n\n return accepted;\n }\n\n listProjects(): ProjectSummary[] {\n return [...this.projects.values()].sort((a, b) => b.last_active - a.last_active);\n }\n\n listSessions(projectHash?: string): SessionSummary[] {\n return [...this.sessions.values()]\n .filter((session) => !projectHash || session.project_hash === projectHash)\n .sort((a, b) => b.last_event_at - a.last_event_at)\n .map(({ events: _events, filePath: _filePath, ...summary }) => summary);\n }\n\n getSessionEvents(sessionKey: string, sinceSeq = 0, limit = 500): EventV1[] {\n const session = this.sessions.get(sessionKey);\n if (!session) return [];\n return session.events.filter((event) => (event.seq ?? 0) > sinceSeq).slice(-limit);\n }\n\n getProjectEvents(projectHash: string, sinceSeq = 0, limit = 500): EventV1[] {\n return [...this.sessions.values()]\n .filter((session) => session.project_hash === projectHash)\n .flatMap((session) => session.events)\n .filter((event) => (event.seq ?? 0) > sinceSeq)\n .sort((left, right) => (left.seq ?? 0) - (right.seq ?? 0))\n .slice(-limit);\n }\n\n getAllEvents(sinceSeq = 0, limit = 1_000): EventV1[] {\n return [...this.sessions.values()]\n .flatMap((session) => session.events)\n .filter((event) => (event.seq ?? 0) > sinceSeq)\n .sort((left, right) => (left.seq ?? 0) - (right.seq ?? 0))\n .slice(-limit);\n }\n\n getLatestSeq(projectHash?: string): number {\n const sessions = [...this.sessions.values()].filter(\n (session) => !projectHash || session.project_hash === projectHash,\n );\n return sessions.reduce((maxSeq, session) => Math.max(maxSeq, session.last_seq ?? 0), 0);\n }\n\n getSessionLatestSeq(sessionKey: string): number {\n return this.sessions.get(sessionKey)?.last_seq ?? 0;\n }\n\n getSessionSummary(sessionKey: string): SessionSummary | null {\n const session = this.sessions.get(sessionKey);\n if (!session) return null;\n return {\n key: session.key,\n project_hash: session.project_hash,\n engine: session.engine,\n session_id: session.session_id,\n cwd: session.cwd,\n last_event_at: session.last_event_at,\n last_seq: session.last_seq,\n event_count: session.event_count,\n caps: session.caps,\n };\n }\n\n async purgeSession(sessionKey: string): Promise<boolean> {\n const session = this.sessions.get(sessionKey);\n if (!session) return false;\n this.sessions.delete(sessionKey);\n await rm(session.filePath, { force: true });\n\n const project = this.projects.get(session.project_hash);\n if (!project) {\n return true;\n }\n\n const remainingSessions = [...this.sessions.values()].filter(\n (candidate) => candidate.project_hash === session.project_hash,\n );\n if (remainingSessions.length === 0) {\n this.projects.delete(session.project_hash);\n return true;\n }\n\n project.session_count = remainingSessions.length;\n project.last_active = remainingSessions.reduce(\n (latest, candidate) => Math.max(latest, candidate.last_event_at),\n 0,\n );\n\n const projectDir = join(this.homeDir, \"sessions\", session.project_hash);\n await writeFile(join(projectDir, \"meta.json\"), JSON.stringify(project, null, 2) + \"\\n\", {\n encoding: \"utf8\",\n mode: 0o600,\n });\n return true;\n }\n\n private async persistEvent(event: EventV1): Promise<EventV1> {\n const storedEvent: EventV1 = {\n ...event,\n seq: event.seq ?? this.nextSeq++,\n };\n\n this.upsertProject(storedEvent);\n const session = this.upsertSession(storedEvent);\n const projectDir = join(this.homeDir, \"sessions\", storedEvent.project_hash);\n await mkdir(projectDir, { recursive: true, mode: 0o700 });\n await appendFile(session.filePath, JSON.stringify(storedEvent) + \"\\n\", {\n encoding: \"utf8\",\n mode: 0o600,\n });\n await writeFile(\n join(projectDir, \"meta.json\"),\n JSON.stringify(this.projects.get(storedEvent.project_hash), null, 2) + \"\\n\",\n { encoding: \"utf8\", mode: 0o600 },\n );\n\n return storedEvent;\n }\n\n private upsertProject(event: EventV1): void {\n const identity = this.getProjectIdentity(event.cwd);\n const existing = this.projects.get(event.project_hash);\n const sessionCount = existing?.session_count ?? 0;\n this.projects.set(event.project_hash, {\n project_hash: event.project_hash,\n name: existing?.name ?? identity.name,\n root: existing?.root ?? identity.root,\n last_active: Math.max(existing?.last_active ?? 0, event.ts),\n session_count: sessionCount,\n });\n }\n\n private upsertSession(event: EventV1): StoredSession {\n const key = buildSessionKey(event);\n const existing = this.sessions.get(key);\n const filePath =\n existing?.filePath ??\n join(\n this.homeDir,\n \"sessions\",\n event.project_hash,\n sessionFileName(event.engine, event.session_id),\n );\n const events = [...(existing?.events ?? []), event];\n const session: StoredSession = {\n key,\n project_hash: event.project_hash,\n engine: event.engine,\n session_id: event.session_id,\n cwd: event.cwd,\n last_event_at: event.ts,\n last_seq: event.seq,\n event_count: events.length,\n caps: event.caps ?? existing?.caps,\n events,\n filePath,\n };\n this.sessions.set(key, session);\n\n const project = this.projects.get(event.project_hash);\n if (project) {\n project.session_count = [...this.sessions.values()].filter(\n (candidate) => candidate.project_hash === event.project_hash,\n ).length;\n project.last_active = Math.max(project.last_active, event.ts);\n }\n\n return session;\n }\n\n private getProjectIdentity(cwd: string): ReturnType<typeof identifyProject> {\n const cached = this.projectIdentityCache.get(cwd);\n if (cached) {\n return cached;\n }\n const identity = identifyProject(cwd);\n this.projectIdentityCache.set(cwd, identity);\n return identity;\n }\n\n private async hydrate(): Promise<void> {\n const sessionsRoot = join(this.homeDir, \"sessions\");\n if (!existsSync(sessionsRoot)) return;\n\n const projectEntries = await readdir(sessionsRoot, { withFileTypes: true });\n for (const projectDirEntry of projectEntries) {\n if (!projectDirEntry.isDirectory()) continue;\n const projectHash = projectDirEntry.name;\n const projectDir = join(sessionsRoot, projectHash);\n const files = await readdir(projectDir);\n let loadedProject: StoredProject | undefined;\n const metaPath = join(projectDir, \"meta.json\");\n if (existsSync(metaPath)) {\n try {\n loadedProject = JSON.parse(await readFile(metaPath, \"utf8\")) as StoredProject;\n } catch {\n loadedProject = undefined;\n }\n }\n\n for (const file of files.filter((entry) => entry.endsWith(\".jsonl\"))) {\n const filePath = join(projectDir, file);\n const rawEvents = await readJsonl(filePath);\n if (rawEvents.length === 0) continue;\n\n const events = rawEvents\n .sort((left, right) => {\n const leftSeq = left.seq ?? 0;\n const rightSeq = right.seq ?? 0;\n if (leftSeq !== rightSeq) return leftSeq - rightSeq;\n return left.ts - right.ts;\n })\n .map((event) => {\n const seq = event.seq ?? this.nextSeq++;\n this.nextSeq = Math.max(this.nextSeq, seq + 1);\n return {\n ...event,\n seq,\n };\n });\n\n const first = events[0];\n const last = events[events.length - 1];\n if (!first || !last) continue;\n const key = buildSessionKey(first);\n this.sessions.set(key, {\n key,\n project_hash: first.project_hash,\n engine: first.engine,\n session_id: first.session_id,\n cwd: first.cwd,\n last_event_at: last.ts,\n last_seq: last.seq,\n event_count: events.length,\n caps: last.caps,\n events,\n filePath,\n });\n\n if (!loadedProject) {\n const identity = this.getProjectIdentity(first.cwd);\n loadedProject = {\n project_hash: first.project_hash,\n name: identity.name,\n root: identity.root,\n last_active: last.ts,\n session_count: 0,\n };\n } else {\n loadedProject.last_active = Math.max(loadedProject.last_active, last.ts);\n }\n }\n\n if (loadedProject) {\n loadedProject.session_count = [...this.sessions.values()].filter(\n (session) => session.project_hash === projectHash,\n ).length;\n this.projects.set(projectHash, loadedProject);\n }\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { EventV1 } from \"@holdpoint/live-protocol\";\n\nconst DEFAULT_LOCK_TTL_MS = 30_000;\n\ninterface FileLock {\n sessionKey: string;\n engine: string;\n sessionId: string;\n expiresAt: number;\n}\n\ntype LockEvent = Extract<EventV1, { type: \"tool_pre\" | \"tool_post\" | \"tool_failure\" }>;\n\nfunction buildSessionKey(event: Pick<EventV1, \"project_hash\" | \"engine\" | \"session_id\">): string {\n return `${event.project_hash}:${event.engine}:${event.session_id}`;\n}\n\nfunction normalizeWriteTarget(cwd: string, target: string): string {\n const resolved = resolve(cwd, target);\n return existsSync(resolved) ? realpathSync.native(resolved) : resolved;\n}\n\nfunction getWriteTargets(event: LockEvent, activeTargets: Map<string, string[]>): string[] {\n const toolKey = `${buildSessionKey(event)}:${event.payload.tool_use_id}`;\n if (event.type === \"tool_pre\") {\n return (event.payload.write_targets ?? []).map((target: string) =>\n normalizeWriteTarget(event.cwd, target),\n );\n }\n\n return (\n (event.type === \"tool_post\"\n ? event.payload.write_targets?.map((target: string) =>\n normalizeWriteTarget(event.cwd, target),\n )\n : undefined) ??\n activeTargets.get(toolKey) ??\n []\n );\n}\n\nexport class ConflictTracker {\n private readonly lockTtlMs: number;\n private readonly locksByProject = new Map<string, Map<string, FileLock>>();\n private readonly activeTargets = new Map<string, string[]>();\n private readonly emittedConflicts = new Map<string, number>();\n\n constructor(lockTtlMs = DEFAULT_LOCK_TTL_MS) {\n this.lockTtlMs = lockTtlMs;\n }\n\n handleEvent(event: EventV1): EventV1[] {\n switch (event.type) {\n case \"tool_pre\":\n return this.handleToolPre(event);\n case \"tool_post\":\n case \"tool_failure\":\n this.releaseLocks(event);\n return [];\n default:\n return [];\n }\n }\n\n private handleToolPre(event: Extract<EventV1, { type: \"tool_pre\" }>): EventV1[] {\n const sessionKey = buildSessionKey(event);\n const toolKey = `${sessionKey}:${event.payload.tool_use_id}`;\n const writeTargets = getWriteTargets(event, this.activeTargets);\n if (writeTargets.length === 0) {\n return [];\n }\n\n this.activeTargets.set(toolKey, writeTargets);\n const projectLocks = this.getProjectLocks(event.project_hash);\n this.pruneExpiredLocks(projectLocks, event.ts);\n\n const conflicts: EventV1[] = [];\n for (const filePath of writeTargets) {\n const existing = projectLocks.get(filePath);\n if (!existing) {\n projectLocks.set(filePath, {\n sessionKey,\n engine: event.engine,\n sessionId: event.session_id,\n expiresAt: event.ts + this.lockTtlMs,\n });\n continue;\n }\n\n if (existing.sessionKey === sessionKey) {\n existing.expiresAt = event.ts + this.lockTtlMs;\n continue;\n }\n\n const dedupeKey = `${event.project_hash}:${filePath}:${existing.sessionKey}:${sessionKey}`;\n const previousEmission = this.emittedConflicts.get(dedupeKey) ?? 0;\n if (previousEmission > event.ts) {\n continue;\n }\n\n this.emittedConflicts.set(dedupeKey, event.ts + this.lockTtlMs);\n conflicts.push({\n v: 1,\n id: randomUUID(),\n ts: event.ts,\n engine: event.engine,\n session_id: event.session_id,\n project_hash: event.project_hash,\n cwd: event.cwd,\n type: \"conflict\",\n payload: {\n kind: \"file_write\",\n file_path: filePath,\n holder: {\n engine: existing.engine,\n session_id: existing.sessionId,\n },\n requester: {\n engine: event.engine,\n session_id: event.session_id,\n },\n },\n });\n }\n\n return conflicts;\n }\n\n private releaseLocks(event: Extract<EventV1, { type: \"tool_post\" | \"tool_failure\" }>): void {\n const sessionKey = buildSessionKey(event);\n const toolKey = `${sessionKey}:${event.payload.tool_use_id}`;\n const projectLocks = this.getProjectLocks(event.project_hash);\n const writeTargets = getWriteTargets(event, this.activeTargets);\n\n for (const filePath of writeTargets) {\n const existing = projectLocks.get(filePath);\n if (existing?.sessionKey === sessionKey) {\n projectLocks.delete(filePath);\n }\n }\n\n this.activeTargets.delete(toolKey);\n this.pruneExpiredLocks(projectLocks, event.ts);\n }\n\n private getProjectLocks(projectHash: string): Map<string, FileLock> {\n let existing = this.locksByProject.get(projectHash);\n if (!existing) {\n existing = new Map<string, FileLock>();\n this.locksByProject.set(projectHash, existing);\n }\n return existing;\n }\n\n private pruneExpiredLocks(projectLocks: Map<string, FileLock>, now: number): void {\n for (const [filePath, lock] of projectLocks.entries()) {\n if (lock.expiresAt <= now) {\n projectLocks.delete(filePath);\n }\n }\n\n for (const [key, expiresAt] of this.emittedConflicts.entries()) {\n if (expiresAt <= now) {\n this.emittedConflicts.delete(key);\n }\n }\n }\n}\n","import { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { basename } from \"node:path\";\n\nexport interface ProjectIdentity {\n hash: string;\n name: string;\n root: string;\n}\n\nfunction sha12(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 12);\n}\n\nexport function identifyProject(cwd: string): ProjectIdentity {\n try {\n const root = realpathSync(\n execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim(),\n );\n return {\n hash: sha12(root),\n name: basename(root),\n root,\n };\n } catch {\n const root = realpathSync(cwd);\n return {\n hash: sha12(root),\n name: basename(root),\n root,\n };\n }\n}\n","import type { EventV1 } from \"@holdpoint/live-protocol\";\nimport { buildSessionKey } from \"./store.js\";\n\nexport interface Subscription {\n scope: \"project\" | \"session\" | \"all\";\n key?: string;\n}\n\nexport function matchesSubscription(subscription: Subscription, event: EventV1): boolean {\n switch (subscription.scope) {\n case \"all\":\n return true;\n case \"project\":\n return subscription.key === event.project_hash;\n case \"session\":\n return subscription.key === buildSessionKey(event);\n }\n}\n","import {\n removeDaemonLock,\n createDaemonLock,\n findFreePort,\n readHealthyDaemonLock,\n type DaemonLock,\n writeDaemonLockExclusive,\n resolveHoldpointHome,\n} from \"./singleton.js\";\nimport { startLiveServer, type RunningLiveServer } from \"./server.js\";\nimport { LiveStore } from \"./store.js\";\n\nexport class DaemonAlreadyRunningError extends Error {\n readonly info: DaemonLock;\n\n constructor(info: DaemonLock) {\n super(`Holdpoint daemon already running on port ${info.port}`);\n this.info = info;\n }\n}\n\nexport interface StartDaemonProcessOptions {\n homeDir?: string;\n port?: number;\n version: string;\n}\n\nexport interface StartedDaemon {\n info: DaemonLock;\n server: RunningLiveServer;\n store: LiveStore;\n close(): Promise<void>;\n closed: Promise<void>;\n}\n\nexport async function startDaemonProcess(\n options: StartDaemonProcessOptions,\n): Promise<StartedDaemon> {\n const existing = await readHealthyDaemonLock(options.homeDir);\n if (existing) {\n throw new DaemonAlreadyRunningError(existing);\n }\n\n const port = options.port ?? (await findFreePort());\n const info = createDaemonLock(port, options.version);\n writeDaemonLockExclusive(info, options.homeDir);\n\n const store = await LiveStore.create(resolveHoldpointHome(options.homeDir));\n await store.replayPending();\n\n let server: RunningLiveServer;\n try {\n server = await startLiveServer({\n port,\n token: info.token,\n version: options.version,\n startedAt: info.started_at,\n store,\n });\n } catch (error) {\n removeDaemonLock(options.homeDir, info.token);\n throw error;\n }\n\n let closed = false;\n const cleanup = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n removeDaemonLock(options.homeDir, info.token);\n await server.close();\n };\n\n const onSignal = (): void => {\n void cleanup().finally(() => process.exit(0));\n };\n\n process.once(\"SIGTERM\", onSignal);\n process.once(\"SIGINT\", onSignal);\n\n return {\n info,\n server,\n store,\n close: cleanup,\n closed: server.closed.finally(() => {\n process.off(\"SIGTERM\", onSignal);\n process.off(\"SIGINT\", onSignal);\n }),\n };\n}\n\nexport {\n createDaemonLock,\n ensureHoldpointHome,\n findFreePort,\n getDaemonLockPath,\n isProcessAlive,\n readDaemonLock,\n readHealthyDaemonLock,\n removeDaemonLock,\n resolveHoldpointHome,\n waitForDaemonHealthy,\n writeDaemonLockExclusive,\n} from \"./singleton.js\";\nexport { identifyProject } from \"./project-identity.js\";\nexport { startLiveServer } from \"./server.js\";\nexport { buildSessionKey, LiveStore } from \"./store.js\";\nexport type { ProjectIdentity } from \"./project-identity.js\";\nexport type { RunningLiveServer } from \"./server.js\";\nexport type { DaemonLock } from \"./singleton.js\";\n"],"mappings":"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","names":["createServer","randomUUID","existsSync","join","resolve","EventV1Schema","existsSync","join","existsSync","resolve","realpathSync","buildSessionKey","join","existsSync","buildSessionKey","join","randomUUID","resolve","existsSync","createServer","EventV1Schema"]}
1
+ {"version":3,"sources":["../src/singleton.ts","../src/server.ts","../src/auth.ts","../src/store.ts","../src/conflict-tracker.ts","../src/project-identity.ts","../src/router.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { createServer } from \"node:net\";\nimport os from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const DaemonLockSchema = z.object({\n version: z.string().min(1),\n pid: z.number().int().positive(),\n port: z.number().int().positive(),\n token: z.string().min(1),\n started_at: z.number().int().nonnegative(),\n host: z.string().min(1),\n});\n\nexport type DaemonLock = z.infer<typeof DaemonLockSchema>;\n\nexport function resolveHoldpointHome(homeDir?: string): string {\n return resolve(homeDir ?? process.env.HOLDPOINT_HOME ?? join(os.homedir(), \".holdpoint\"));\n}\n\nexport function ensureHoldpointHome(homeDir?: string): string {\n const root = resolveHoldpointHome(homeDir);\n mkdirSync(root, { recursive: true, mode: 0o700 });\n return root;\n}\n\nexport function getDaemonLockPath(homeDir?: string): string {\n return join(resolveHoldpointHome(homeDir), \"daemon.lock\");\n}\n\nexport function readDaemonLock(homeDir?: string): DaemonLock | null {\n const lockPath = getDaemonLockPath(homeDir);\n if (!existsSync(lockPath)) return null;\n try {\n return DaemonLockSchema.parse(JSON.parse(readFileSync(lockPath, \"utf8\")));\n } catch {\n return null;\n }\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function findFreePort(host = \"127.0.0.1\"): Promise<number> {\n return await new Promise<number>((resolvePromise, reject) => {\n const server = createServer();\n server.listen(0, host, () => {\n const address = server.address();\n if (!address || typeof address === \"string\") {\n server.close();\n reject(new Error(\"Expected TCP address\"));\n return;\n }\n const { port } = address;\n server.close((err) => {\n if (err) reject(err);\n else resolvePromise(port);\n });\n });\n server.on(\"error\", reject);\n });\n}\n\nexport function createDaemonLock(port: number, version: string): DaemonLock {\n return {\n version,\n pid: process.pid,\n port,\n token: randomBytes(32).toString(\"hex\"),\n started_at: Date.now(),\n host: `${os.platform()}-${os.arch()}`,\n };\n}\n\nexport function writeDaemonLockExclusive(lock: DaemonLock, homeDir?: string): void {\n ensureHoldpointHome(homeDir);\n writeFileSync(getDaemonLockPath(homeDir), JSON.stringify(lock, null, 2) + \"\\n\", {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n}\n\nexport function removeDaemonLock(homeDir?: string, expectedToken?: string): void {\n const lockPath = getDaemonLockPath(homeDir);\n if (!existsSync(lockPath)) return;\n if (expectedToken) {\n const lock = readDaemonLock(homeDir);\n if (!lock || lock.token !== expectedToken) {\n return;\n }\n }\n try {\n unlinkSync(lockPath);\n } catch {\n /* ignore cleanup races */\n }\n}\n\nasync function fetchHealth(port: number, timeoutMs: number): Promise<boolean> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: controller.signal,\n });\n return response.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport async function waitForDaemonHealthy(\n lock: DaemonLock,\n timeoutMs = 5_000,\n pollMs = 100,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await fetchHealth(lock.port, Math.min(pollMs, timeoutMs))) {\n return true;\n }\n await new Promise((resolvePromise) => setTimeout(resolvePromise, pollMs));\n }\n return false;\n}\n\nexport async function readHealthyDaemonLock(homeDir?: string): Promise<DaemonLock | null> {\n const lock = readDaemonLock(homeDir);\n if (!lock) return null;\n if (!isProcessAlive(lock.pid)) {\n removeDaemonLock(homeDir);\n return null;\n }\n if (!(await waitForDaemonHealthy(lock, 300, 100))) {\n removeDaemonLock(homeDir);\n return null;\n }\n return lock;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { randomUUID } from \"node:crypto\";\nimport { createReadStream, existsSync } from \"node:fs\";\nimport { dirname, extname, join, resolve, sep } from \"node:path\";\nimport { fileURLToPath, URL } from \"node:url\";\nimport type { EventV1, ServerMessage } from \"@holdpoint/live-protocol\";\nimport {\n ClientMessageSchema,\n ControlRequestSchema,\n EventV1Schema,\n EventsBatchSchema,\n} from \"@holdpoint/live-protocol\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n authorizeRequest,\n authorizeWebSocket,\n readJsonBody,\n writeJson,\n writeUiAuthCookie,\n} from \"./auth.js\";\nimport { matchesSubscription, type Subscription } from \"./router.js\";\nimport type { LiveStore } from \"./store.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst LIVE_UI_DIR = join(__dirname, \"live-ui\");\nconst BUILDER_UI_DIR = join(__dirname, \"builder-ui\");\nconst CONTENT_SECURITY_POLICY =\n \"default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: http:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'\";\nconst MIME: Record<string, string> = {\n \".css\": \"text/css; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".ico\": \"image/x-icon\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml\",\n};\n\nexport interface StartLiveServerOptions {\n host?: string;\n port: number;\n token: string;\n version: string;\n startedAt: number;\n store: LiveStore;\n}\n\nexport interface RunningLiveServer {\n host: string;\n port: number;\n close(): Promise<void>;\n closed: Promise<void>;\n}\n\ninterface RegisteredProject {\n hash: string;\n name?: string;\n root: string;\n}\n\nfunction sendSocketMessage(socket: WebSocket, message: ServerMessage): void {\n socket.send(JSON.stringify(message));\n}\n\nfunction decodeRawData(raw: RawData): string {\n if (typeof raw === \"string\") return raw;\n if (raw instanceof Buffer) return raw.toString(\"utf8\");\n if (Array.isArray(raw)) return Buffer.concat(raw).toString(\"utf8\");\n return Buffer.from(new Uint8Array(raw)).toString(\"utf8\");\n}\n\nfunction getEventsForScope(\n store: LiveStore,\n subscription: Subscription,\n sinceSeq: number,\n): EventV1[] {\n switch (subscription.scope) {\n case \"all\":\n return store.getAllEvents(sinceSeq);\n case \"project\":\n return subscription.key ? store.getProjectEvents(subscription.key, sinceSeq) : [];\n case \"session\":\n return subscription.key ? store.getSessionEvents(subscription.key, sinceSeq) : [];\n }\n}\n\nfunction buildControlStateEvent(\n session: {\n project_hash: string;\n engine: string;\n session_id: string;\n cwd: string;\n caps?: EventV1[\"caps\"];\n },\n controlOnline: boolean,\n): EventV1 {\n return {\n v: 1,\n id: randomUUID(),\n ts: Date.now(),\n engine: session.engine,\n session_id: session.session_id,\n project_hash: session.project_hash,\n cwd: session.cwd,\n caps: {\n ...(session.caps ?? {}),\n can_control: session.caps?.can_control ?? true,\n control_online: controlOnline,\n },\n type: \"meta\",\n payload: {\n kind: controlOnline ? \"control_socket_registered\" : \"control_socket_disconnected\",\n },\n };\n}\n\nfunction servePlaceholder(res: ServerResponse, appName = \"Holdpoint Live\"): void {\n res.writeHead(200, {\n \"cache-control\": \"no-store\",\n \"content-security-policy\": CONTENT_SECURITY_POLICY,\n \"content-type\": \"text/html; charset=utf-8\",\n });\n res.end(\n `<!doctype html><title>${appName}</title><body style=\"font-family:system-ui;background:#0b0f14;color:#f5f1e8;padding:32px\"><h1>${appName}</h1><p>UI assets were not found in this build. Rebuild the monorepo with <code>pnpm turbo build</code>.</p></body>`,\n );\n}\n\nfunction serveUiAsset(res: ServerResponse, filePath: string): void {\n const mime = MIME[extname(filePath)] ?? \"application/octet-stream\";\n const headers: Record<string, string> = {\n \"cache-control\": \"no-store\",\n \"content-type\": mime,\n };\n if (filePath.endsWith(\".html\")) {\n headers[\"content-security-policy\"] = CONTENT_SECURITY_POLICY;\n }\n res.writeHead(200, headers);\n createReadStream(filePath).pipe(res);\n}\n\nfunction isWithinRoot(candidate: string, root: string): boolean {\n return candidate === root || candidate.startsWith(root + sep);\n}\n\nfunction resolveUiFilePath(uiDir: string, requestedPath: string): string | null {\n const requested = requestedPath === \"\" || requestedPath === \"/\" ? \"index.html\" : requestedPath;\n const candidate = resolve(uiDir, requested.replace(/^\\//, \"\"));\n if (!isWithinRoot(candidate, uiDir)) {\n return null;\n }\n if (existsSync(candidate)) {\n return candidate;\n }\n return existsSync(join(uiDir, \"index.html\")) ? join(uiDir, \"index.html\") : null;\n}\n\nfunction normalizeUiPath(path: string | null): \"/live/\" | \"/builder/\" {\n if (!path) return \"/live/\";\n if (path === \"/live\" || path.startsWith(\"/live/\")) return \"/live/\";\n if (path === \"/builder\" || path.startsWith(\"/builder/\")) return \"/builder/\";\n return \"/live/\";\n}\n\nfunction registerProjectFromAuthUrl(\n url: URL,\n registeredProjects: Map<string, RegisteredProject>,\n): void {\n const hash = url.searchParams.get(\"project\");\n const root = url.searchParams.get(\"root\");\n if (!hash || !root || root.includes(\"\\0\")) {\n return;\n }\n const name = url.searchParams.get(\"name\");\n registeredProjects.set(hash, {\n hash,\n ...(name ? { name } : {}),\n root: resolve(root),\n });\n}\n\nfunction getProjectForRequest(\n url: URL,\n registeredProjects: Map<string, RegisteredProject>,\n): RegisteredProject | null {\n const hash = url.searchParams.get(\"project\");\n if (hash) {\n return registeredProjects.get(hash) ?? null;\n }\n if (registeredProjects.size === 1) {\n return [...registeredProjects.values()][0] ?? null;\n }\n return null;\n}\n\nexport async function startLiveServer(options: StartLiveServerOptions): Promise<RunningLiveServer> {\n const host = options.host ?? \"127.0.0.1\";\n const subscriptions = new Map<WebSocket, Subscription[]>();\n const controlSockets = new Map<string, WebSocket>();\n const socketControlKeys = new Map<WebSocket, Set<string>>();\n const registeredProjects = new Map<string, RegisteredProject>();\n const server = createServer((req, res) => {\n void handleRequest(req, res, options, subscriptions, registeredProjects).catch(\n (error: unknown) => {\n writeJson(res, 500, { ok: false, error: (error as Error).message });\n },\n );\n });\n const wss = new WebSocketServer({ noServer: true });\n\n const broadcastEvent = (event: EventV1): void => {\n for (const [socket, socketSubscriptions] of subscriptions.entries()) {\n if (socket.readyState !== WebSocket.OPEN) continue;\n if (socketSubscriptions.some((subscription) => matchesSubscription(subscription, event))) {\n sendSocketMessage(socket, { type: \"event\", event });\n }\n }\n };\n\n const ingestAndBroadcast = async (event: EventV1): Promise<EventV1[]> => {\n const accepted = await options.store.ingest(event);\n for (const acceptedEvent of accepted) {\n broadcastEvent(acceptedEvent);\n }\n return accepted;\n };\n\n const emitControlState = async (sessionKey: string, controlOnline: boolean): Promise<void> => {\n const summary = options.store.getSessionSummary(sessionKey);\n if (!summary) return;\n await ingestAndBroadcast(buildControlStateEvent(summary, controlOnline));\n };\n\n const registerControlSocket = async (sessionKey: string, socket: WebSocket): Promise<void> => {\n const previous = controlSockets.get(sessionKey);\n if (previous && previous !== socket) {\n socketControlKeys.get(previous)?.delete(sessionKey);\n }\n controlSockets.set(sessionKey, socket);\n const keys = socketControlKeys.get(socket) ?? new Set<string>();\n keys.add(sessionKey);\n socketControlKeys.set(socket, keys);\n await emitControlState(sessionKey, true);\n };\n\n const unregisterControlSocket = async (sessionKey: string, socket: WebSocket): Promise<void> => {\n if (controlSockets.get(sessionKey) !== socket) return;\n controlSockets.delete(sessionKey);\n const keys = socketControlKeys.get(socket);\n keys?.delete(sessionKey);\n if (keys && keys.size === 0) {\n socketControlKeys.delete(socket);\n }\n await emitControlState(sessionKey, false);\n };\n\n const unregisterSocketControls = async (socket: WebSocket): Promise<void> => {\n const keys = [...(socketControlKeys.get(socket) ?? [])];\n for (const sessionKey of keys) {\n await unregisterControlSocket(sessionKey, socket);\n }\n };\n\n wss.on(\"connection\", (socket: WebSocket) => {\n subscriptions.set(socket, []);\n socket.on(\"message\", (raw: RawData) => {\n void (async () => {\n let message: unknown;\n try {\n message = JSON.parse(decodeRawData(raw));\n } catch {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"invalid_json\",\n message: \"Expected JSON message\",\n });\n return;\n }\n\n const parsed = ClientMessageSchema.safeParse(message);\n if (!parsed.success) {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"invalid_message\",\n message: parsed.error.issues[0]?.message ?? \"Invalid message\",\n });\n return;\n }\n\n switch (parsed.data.type) {\n case \"subscribe\": {\n if (parsed.data.scope !== \"all\" && !parsed.data.key) {\n sendSocketMessage(socket, {\n type: \"error\",\n code: \"missing_key\",\n message: \"Expected a key for session/project subscriptions\",\n });\n return;\n }\n\n const subscription =\n parsed.data.key !== undefined\n ? { scope: parsed.data.scope, key: parsed.data.key }\n : { scope: parsed.data.scope };\n const next = subscriptions.get(socket) ?? [];\n next.push(subscription);\n subscriptions.set(socket, next);\n\n const backlog = getEventsForScope(\n options.store,\n subscription,\n parsed.data.since_seq ?? 0,\n );\n if (backlog.length > 0) {\n sendSocketMessage(socket, { type: \"events_batch\", events: backlog });\n }\n sendSocketMessage(socket, {\n type: \"ack\",\n for: parsed.data.scope === \"all\" ? \"all\" : (parsed.data.key ?? parsed.data.scope),\n });\n break;\n }\n case \"register_control\": {\n await registerControlSocket(parsed.data.session_key, socket);\n sendSocketMessage(socket, { type: \"ack\", for: parsed.data.session_key });\n break;\n }\n case \"unsubscribe\": {\n const key = parsed.data.key;\n const next = (subscriptions.get(socket) ?? []).filter(\n (subscription) => subscription.key !== key,\n );\n subscriptions.set(socket, next);\n sendSocketMessage(socket, { type: \"ack\", for: key });\n break;\n }\n case \"publish_event\": {\n const accepted = await options.store.ingest(parsed.data.event);\n for (const event of accepted) {\n broadcastEvent(event);\n }\n sendSocketMessage(socket, { type: \"ack\", for: parsed.data.event.id });\n break;\n }\n case \"ping\":\n sendSocketMessage(socket, { type: \"pong\" });\n break;\n }\n })();\n });\n\n socket.on(\"close\", () => {\n subscriptions.delete(socket);\n void unregisterSocketControls(socket).catch(() => {});\n });\n });\n\n server.on(\"upgrade\", (req, socket, head) => {\n const url = new URL(req.url ?? \"/\", `http://${host}:${options.port}`);\n if (url.pathname !== \"/v1/stream\" || !authorizeWebSocket(req, options.token, options.port)) {\n socket.write(\"HTTP/1.1 401 Unauthorized\\r\\n\\r\\n\");\n socket.destroy();\n return;\n }\n\n wss.handleUpgrade(req, socket, head, (ws: WebSocket) => {\n wss.emit(\"connection\", ws, req);\n });\n });\n\n await new Promise<void>((resolvePromise, reject) => {\n server.listen(options.port, host, resolvePromise);\n server.on(\"error\", reject);\n });\n\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"Expected TCP address\");\n }\n const actualPort = address.port;\n\n const closed = new Promise<void>((resolvePromise, reject) => {\n server.on(\"close\", () => resolvePromise());\n server.on(\"error\", reject);\n });\n\n async function close(): Promise<void> {\n for (const socket of subscriptions.keys()) {\n socket.close();\n }\n await new Promise<void>((resolvePromise, reject) => {\n wss.close((err?: Error) => (err ? reject(err) : resolvePromise()));\n });\n await new Promise<void>((resolvePromise, reject) => {\n server.close((err) => (err ? reject(err) : resolvePromise()));\n });\n }\n\n async function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n state: StartLiveServerOptions,\n _subscriptions: Map<WebSocket, Subscription[]>,\n registered: Map<string, RegisteredProject>,\n ): Promise<void> {\n const url = new URL(req.url ?? \"/\", `http://${host}:${actualPort}`);\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n writeJson(res, 200, { ok: true, version: state.version, started_at: state.startedAt });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/__holdpoint/live-auth\") {\n if (url.searchParams.get(\"token\") !== state.token) {\n writeJson(res, 401, { ok: false, error: \"Unauthorized\" });\n return;\n }\n\n registerProjectFromAuthUrl(url, registered);\n\n const redirectPath = normalizeUiPath(url.searchParams.get(\"path\"));\n const redirectUrl = new URL(`http://${host}:${actualPort}`);\n redirectUrl.pathname = redirectPath;\n for (const [key, value] of url.searchParams.entries()) {\n if (key !== \"token\" && key !== \"path\") {\n redirectUrl.searchParams.set(key, value);\n }\n }\n writeUiAuthCookie(res, state.token);\n res.writeHead(302, {\n location: redirectUrl.toString(),\n \"cache-control\": \"no-store\",\n });\n res.end();\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/__holdpoint/initial-yaml\") {\n if (!authorizeRequest(req, res, state.token, actualPort)) {\n return;\n }\n const project = getProjectForRequest(url, registered);\n if (!project) {\n writeJson(res, 404, { ok: false, error: \"Project not registered for this UI session\" });\n return;\n }\n const checksPath = resolve(project.root, \"checks.yaml\");\n if (!isWithinRoot(checksPath, project.root) || !existsSync(checksPath)) {\n writeJson(res, 404, { ok: false, error: \"checks.yaml not found for this project\" });\n return;\n }\n res.writeHead(200, {\n \"cache-control\": \"no-store\",\n \"content-type\": \"text/yaml; charset=utf-8\",\n });\n createReadStream(checksPath).pipe(res);\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/__holdpoint/initial-reports\") {\n if (!authorizeRequest(req, res, state.token, actualPort)) {\n return;\n }\n const project = getProjectForRequest(url, registered);\n if (!project) {\n writeJson(res, 404, { ok: false, error: \"Project not registered for this UI session\" });\n return;\n }\n const reportsPath = resolve(project.root, \".holdpoint\", \"check-reports.json\");\n if (!isWithinRoot(reportsPath, project.root) || !existsSync(reportsPath)) {\n writeJson(res, 404, { ok: false, error: \"No check reports found for this project\" });\n return;\n }\n res.writeHead(200, {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json; charset=utf-8\",\n });\n createReadStream(reportsPath).pipe(res);\n return;\n }\n\n if (url.pathname.startsWith(\"/v1/\") && !authorizeRequest(req, res, state.token, actualPort)) {\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/events\") {\n const event = EventV1Schema.parse(await readJsonBody(req));\n const accepted = await ingestAndBroadcast(event);\n writeJson(res, 200, { ok: true, accepted: accepted.length });\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/events/batch\") {\n const events = EventsBatchSchema.parse(await readJsonBody(req));\n const accepted: EventV1[] = [];\n for (const event of events) {\n accepted.push(...(await ingestAndBroadcast(event)));\n }\n writeJson(res, 200, { ok: true, accepted: accepted.length });\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v1/control\") {\n const request = ControlRequestSchema.parse(await readJsonBody(req));\n const session = state.store.getSessionSummary(request.session_key);\n if (!session) {\n writeJson(res, 404, { ok: false, error: \"Session not found\" });\n return;\n }\n\n const controlSocket = controlSockets.get(request.session_key);\n if (!controlSocket || controlSocket.readyState !== WebSocket.OPEN) {\n writeJson(res, 409, { ok: false, error: \"Control socket not connected\" });\n return;\n }\n\n await ingestAndBroadcast({\n v: 1,\n id: randomUUID(),\n ts: Date.now(),\n engine: session.engine,\n session_id: session.session_id,\n project_hash: session.project_hash,\n cwd: session.cwd,\n type: \"control\",\n payload: request.command,\n });\n sendSocketMessage(controlSocket, {\n type: \"control\",\n session_key: request.session_key,\n command: request.command,\n });\n writeJson(res, 200, { ok: true, delivered: true });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v1/projects\") {\n writeJson(res, 200, { projects: state.store.listProjects() });\n return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v1/sessions\") {\n const projectHash = url.searchParams.get(\"project_hash\") ?? undefined;\n writeJson(res, 200, { sessions: state.store.listSessions(projectHash) });\n return;\n }\n\n if (\n req.method === \"GET\" &&\n url.pathname.startsWith(\"/v1/sessions/\") &&\n url.pathname.endsWith(\"/events\")\n ) {\n const sessionKey = decodeURIComponent(\n url.pathname.replace(\"/v1/sessions/\", \"\").replace(/\\/events$/, \"\"),\n );\n const sinceSeq = Number(\n url.searchParams.get(\"since_seq\") ?? url.searchParams.get(\"since\") ?? \"0\",\n );\n const limit = Number(url.searchParams.get(\"limit\") ?? \"500\");\n writeJson(res, 200, {\n session_key: sessionKey,\n since_seq: Number.isFinite(sinceSeq) ? sinceSeq : 0,\n max_seq: state.store.getSessionLatestSeq(sessionKey),\n events: state.store.getSessionEvents(\n sessionKey,\n Number.isFinite(sinceSeq) ? sinceSeq : 0,\n Number.isFinite(limit) ? limit : 500,\n ),\n });\n return;\n }\n\n if (req.method === \"DELETE\" && url.pathname.startsWith(\"/v1/sessions/\")) {\n const sessionKey = decodeURIComponent(url.pathname.replace(\"/v1/sessions/\", \"\"));\n const removed = await state.store.purgeSession(sessionKey);\n writeJson(\n res,\n removed ? 200 : 404,\n removed ? { ok: true } : { ok: false, error: \"Session not found\" },\n );\n return;\n }\n\n if (req.method === \"GET\") {\n if (url.pathname === \"/\") {\n res.writeHead(302, { location: \"/live/\", \"cache-control\": \"no-store\" });\n res.end();\n return;\n }\n\n if (url.pathname === \"/live\" || url.pathname === \"/builder\") {\n res.writeHead(302, { location: `${url.pathname}/`, \"cache-control\": \"no-store\" });\n res.end();\n return;\n }\n\n const uiRoute = url.pathname.startsWith(\"/builder/\")\n ? {\n appName: \"Holdpoint Builder\",\n dir: BUILDER_UI_DIR,\n path: url.pathname.replace(/^\\/builder\\/?/, \"\"),\n }\n : url.pathname.startsWith(\"/live/\")\n ? {\n appName: \"Holdpoint Live\",\n dir: LIVE_UI_DIR,\n path: url.pathname.replace(/^\\/live\\/?/, \"\"),\n }\n : null;\n\n if (!uiRoute) {\n res.writeHead(302, { location: \"/live/\", \"cache-control\": \"no-store\" });\n res.end();\n return;\n }\n\n const filePath = resolveUiFilePath(uiRoute.dir, uiRoute.path);\n if (!filePath) {\n servePlaceholder(res, uiRoute.appName);\n return;\n }\n serveUiAsset(res, filePath);\n return;\n }\n\n writeJson(res, 404, { ok: false, error: \"Not found\" });\n }\n\n return {\n host,\n port: actualPort,\n close,\n closed,\n };\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport const LIVE_UI_COOKIE = \"holdpoint_live_token\";\n\nfunction parseCookies(raw: string | undefined): Map<string, string> {\n const cookies = new Map<string, string>();\n if (!raw) {\n return cookies;\n }\n\n for (const part of raw.split(\";\")) {\n const [name, ...valueParts] = part.trim().split(\"=\");\n if (!name) continue;\n cookies.set(name, decodeURIComponent(valueParts.join(\"=\")));\n }\n\n return cookies;\n}\n\nfunction getRequestToken(req: IncomingMessage): string | null {\n const auth = req.headers.authorization;\n if (auth?.startsWith(\"Bearer \")) {\n return auth.slice(\"Bearer \".length);\n }\n\n return parseCookies(req.headers.cookie).get(LIVE_UI_COOKIE) ?? null;\n}\n\nexport function writeJson(\n res: ServerResponse,\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n): void {\n res.writeHead(statusCode, {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json; charset=utf-8\",\n ...headers,\n });\n res.end(JSON.stringify(body));\n}\n\nexport async function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n if (chunks.length === 0) return null;\n return JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n}\n\nexport function authorizeRequest(\n req: IncomingMessage,\n res: ServerResponse,\n token: string,\n port: number,\n): boolean {\n const origin = req.headers.origin;\n if (origin && origin !== `http://127.0.0.1:${port}`) {\n writeJson(res, 403, { ok: false, error: \"Origin not allowed\" });\n return false;\n }\n\n if (getRequestToken(req) !== token) {\n writeJson(res, 401, { ok: false, error: \"Unauthorized\" });\n return false;\n }\n\n return true;\n}\n\nexport function authorizeWebSocket(req: IncomingMessage, token: string, port: number): boolean {\n const origin = req.headers.origin;\n if (origin && origin !== `http://127.0.0.1:${port}`) {\n return false;\n }\n\n if (getRequestToken(req) === token) {\n return true;\n }\n\n const raw = req.headers[\"sec-websocket-protocol\"];\n const protocols = (typeof raw === \"string\" ? [raw] : [])\n .flatMap((entry) => entry.split(\",\"))\n .map((entry) => entry.trim())\n .filter(Boolean);\n\n return protocols.includes(`holdpoint-${token}`);\n}\n\nexport function writeUiAuthCookie(res: ServerResponse, token: string): void {\n res.setHeader(\n \"set-cookie\",\n `${LIVE_UI_COOKIE}=${encodeURIComponent(token)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=3600`,\n );\n}\n","import { appendFile, mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { EventV1, ProjectSummary, SessionSummary } from \"@holdpoint/live-protocol\";\nimport { EventV1Schema } from \"@holdpoint/live-protocol\";\nimport { ConflictTracker } from \"./conflict-tracker.js\";\nimport { identifyProject } from \"./project-identity.js\";\n\ninterface StoredProject extends ProjectSummary {\n root: string;\n}\n\ninterface StoredSession extends SessionSummary {\n events: EventV1[];\n filePath: string;\n}\n\nfunction sessionFileName(engine: string, sessionId: string): string {\n return `${encodeURIComponent(engine)}-${encodeURIComponent(sessionId)}.jsonl`;\n}\n\nasync function readJsonl(filePath: string): Promise<EventV1[]> {\n const raw = await readFile(filePath, \"utf8\");\n return raw\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .flatMap((line) => {\n try {\n return [EventV1Schema.parse(JSON.parse(line))];\n } catch {\n return [];\n }\n });\n}\n\nexport function buildSessionKey(\n event: Pick<EventV1, \"project_hash\" | \"engine\" | \"session_id\">,\n): string {\n return `${event.project_hash}:${event.engine}:${event.session_id}`;\n}\n\nexport class LiveStore {\n private readonly homeDir: string;\n private readonly projects = new Map<string, StoredProject>();\n private readonly sessions = new Map<string, StoredSession>();\n private readonly projectIdentityCache = new Map<string, ReturnType<typeof identifyProject>>();\n private readonly conflictTracker = new ConflictTracker();\n private nextSeq = 1;\n\n private constructor(homeDir: string) {\n this.homeDir = homeDir;\n }\n\n static async create(homeDir: string): Promise<LiveStore> {\n const store = new LiveStore(homeDir);\n await store.hydrate();\n return store;\n }\n\n async replayPending(): Promise<void> {\n const pendingDir = join(this.homeDir, \"spool\", \"pending\");\n if (!existsSync(pendingDir)) return;\n const entries = await readdir(pendingDir);\n for (const entry of entries.filter((name) => name.endsWith(\".jsonl\"))) {\n const filePath = join(pendingDir, entry);\n const events = await readJsonl(filePath);\n if (events.length > 0) {\n await this.ingestMany(events);\n }\n await rm(filePath, { force: true });\n }\n }\n\n async ingestMany(events: EventV1[]): Promise<EventV1[]> {\n const accepted: EventV1[] = [];\n for (const event of events) {\n accepted.push(...(await this.ingest(event)));\n }\n return accepted;\n }\n\n async ingest(event: EventV1): Promise<EventV1[]> {\n const accepted: EventV1[] = [];\n const storedPrimary = await this.persistEvent(event);\n accepted.push(storedPrimary);\n\n for (const derivedEvent of this.conflictTracker.handleEvent(storedPrimary)) {\n accepted.push(await this.persistEvent(derivedEvent));\n }\n\n return accepted;\n }\n\n listProjects(): ProjectSummary[] {\n return [...this.projects.values()].sort((a, b) => b.last_active - a.last_active);\n }\n\n listSessions(projectHash?: string): SessionSummary[] {\n return [...this.sessions.values()]\n .filter((session) => !projectHash || session.project_hash === projectHash)\n .sort((a, b) => b.last_event_at - a.last_event_at)\n .map(({ events: _events, filePath: _filePath, ...summary }) => summary);\n }\n\n getSessionEvents(sessionKey: string, sinceSeq = 0, limit = 500): EventV1[] {\n const session = this.sessions.get(sessionKey);\n if (!session) return [];\n return session.events.filter((event) => (event.seq ?? 0) > sinceSeq).slice(-limit);\n }\n\n getProjectEvents(projectHash: string, sinceSeq = 0, limit = 500): EventV1[] {\n return [...this.sessions.values()]\n .filter((session) => session.project_hash === projectHash)\n .flatMap((session) => session.events)\n .filter((event) => (event.seq ?? 0) > sinceSeq)\n .sort((left, right) => (left.seq ?? 0) - (right.seq ?? 0))\n .slice(-limit);\n }\n\n getAllEvents(sinceSeq = 0, limit = 1_000): EventV1[] {\n return [...this.sessions.values()]\n .flatMap((session) => session.events)\n .filter((event) => (event.seq ?? 0) > sinceSeq)\n .sort((left, right) => (left.seq ?? 0) - (right.seq ?? 0))\n .slice(-limit);\n }\n\n getLatestSeq(projectHash?: string): number {\n const sessions = [...this.sessions.values()].filter(\n (session) => !projectHash || session.project_hash === projectHash,\n );\n return sessions.reduce((maxSeq, session) => Math.max(maxSeq, session.last_seq ?? 0), 0);\n }\n\n getSessionLatestSeq(sessionKey: string): number {\n return this.sessions.get(sessionKey)?.last_seq ?? 0;\n }\n\n getSessionSummary(sessionKey: string): SessionSummary | null {\n const session = this.sessions.get(sessionKey);\n if (!session) return null;\n return {\n key: session.key,\n project_hash: session.project_hash,\n engine: session.engine,\n session_id: session.session_id,\n cwd: session.cwd,\n last_event_at: session.last_event_at,\n last_seq: session.last_seq,\n event_count: session.event_count,\n caps: session.caps,\n };\n }\n\n async purgeSession(sessionKey: string): Promise<boolean> {\n const session = this.sessions.get(sessionKey);\n if (!session) return false;\n this.sessions.delete(sessionKey);\n await rm(session.filePath, { force: true });\n\n const project = this.projects.get(session.project_hash);\n if (!project) {\n return true;\n }\n\n const remainingSessions = [...this.sessions.values()].filter(\n (candidate) => candidate.project_hash === session.project_hash,\n );\n if (remainingSessions.length === 0) {\n this.projects.delete(session.project_hash);\n return true;\n }\n\n project.session_count = remainingSessions.length;\n project.last_active = remainingSessions.reduce(\n (latest, candidate) => Math.max(latest, candidate.last_event_at),\n 0,\n );\n\n const projectDir = join(this.homeDir, \"sessions\", session.project_hash);\n await writeFile(join(projectDir, \"meta.json\"), JSON.stringify(project, null, 2) + \"\\n\", {\n encoding: \"utf8\",\n mode: 0o600,\n });\n return true;\n }\n\n private async persistEvent(event: EventV1): Promise<EventV1> {\n const storedEvent: EventV1 = {\n ...event,\n seq: event.seq ?? this.nextSeq++,\n };\n\n this.upsertProject(storedEvent);\n const session = this.upsertSession(storedEvent);\n const projectDir = join(this.homeDir, \"sessions\", storedEvent.project_hash);\n await mkdir(projectDir, { recursive: true, mode: 0o700 });\n await appendFile(session.filePath, JSON.stringify(storedEvent) + \"\\n\", {\n encoding: \"utf8\",\n mode: 0o600,\n });\n await writeFile(\n join(projectDir, \"meta.json\"),\n JSON.stringify(this.projects.get(storedEvent.project_hash), null, 2) + \"\\n\",\n { encoding: \"utf8\", mode: 0o600 },\n );\n\n return storedEvent;\n }\n\n private upsertProject(event: EventV1): void {\n const identity = this.getProjectIdentity(event.cwd);\n const existing = this.projects.get(event.project_hash);\n const sessionCount = existing?.session_count ?? 0;\n this.projects.set(event.project_hash, {\n project_hash: event.project_hash,\n name: existing?.name ?? identity.name,\n root: existing?.root ?? identity.root,\n last_active: Math.max(existing?.last_active ?? 0, event.ts),\n session_count: sessionCount,\n });\n }\n\n private upsertSession(event: EventV1): StoredSession {\n const key = buildSessionKey(event);\n const existing = this.sessions.get(key);\n const filePath =\n existing?.filePath ??\n join(\n this.homeDir,\n \"sessions\",\n event.project_hash,\n sessionFileName(event.engine, event.session_id),\n );\n const events = [...(existing?.events ?? []), event];\n const session: StoredSession = {\n key,\n project_hash: event.project_hash,\n engine: event.engine,\n session_id: event.session_id,\n cwd: event.cwd,\n last_event_at: event.ts,\n last_seq: event.seq,\n event_count: events.length,\n caps: event.caps ?? existing?.caps,\n events,\n filePath,\n };\n this.sessions.set(key, session);\n\n const project = this.projects.get(event.project_hash);\n if (project) {\n project.session_count = [...this.sessions.values()].filter(\n (candidate) => candidate.project_hash === event.project_hash,\n ).length;\n project.last_active = Math.max(project.last_active, event.ts);\n }\n\n return session;\n }\n\n private getProjectIdentity(cwd: string): ReturnType<typeof identifyProject> {\n const cached = this.projectIdentityCache.get(cwd);\n if (cached) {\n return cached;\n }\n const identity = identifyProject(cwd);\n this.projectIdentityCache.set(cwd, identity);\n return identity;\n }\n\n private async hydrate(): Promise<void> {\n const sessionsRoot = join(this.homeDir, \"sessions\");\n if (!existsSync(sessionsRoot)) return;\n\n const projectEntries = await readdir(sessionsRoot, { withFileTypes: true });\n for (const projectDirEntry of projectEntries) {\n if (!projectDirEntry.isDirectory()) continue;\n const projectHash = projectDirEntry.name;\n const projectDir = join(sessionsRoot, projectHash);\n const files = await readdir(projectDir);\n let loadedProject: StoredProject | undefined;\n const metaPath = join(projectDir, \"meta.json\");\n if (existsSync(metaPath)) {\n try {\n loadedProject = JSON.parse(await readFile(metaPath, \"utf8\")) as StoredProject;\n } catch {\n loadedProject = undefined;\n }\n }\n\n for (const file of files.filter((entry) => entry.endsWith(\".jsonl\"))) {\n const filePath = join(projectDir, file);\n const rawEvents = await readJsonl(filePath);\n if (rawEvents.length === 0) continue;\n\n const events = rawEvents\n .sort((left, right) => {\n const leftSeq = left.seq ?? 0;\n const rightSeq = right.seq ?? 0;\n if (leftSeq !== rightSeq) return leftSeq - rightSeq;\n return left.ts - right.ts;\n })\n .map((event) => {\n const seq = event.seq ?? this.nextSeq++;\n this.nextSeq = Math.max(this.nextSeq, seq + 1);\n return {\n ...event,\n seq,\n };\n });\n\n const first = events[0];\n const last = events[events.length - 1];\n if (!first || !last) continue;\n const key = buildSessionKey(first);\n this.sessions.set(key, {\n key,\n project_hash: first.project_hash,\n engine: first.engine,\n session_id: first.session_id,\n cwd: first.cwd,\n last_event_at: last.ts,\n last_seq: last.seq,\n event_count: events.length,\n caps: last.caps,\n events,\n filePath,\n });\n\n if (!loadedProject) {\n const identity = this.getProjectIdentity(first.cwd);\n loadedProject = {\n project_hash: first.project_hash,\n name: identity.name,\n root: identity.root,\n last_active: last.ts,\n session_count: 0,\n };\n } else {\n loadedProject.last_active = Math.max(loadedProject.last_active, last.ts);\n }\n }\n\n if (loadedProject) {\n loadedProject.session_count = [...this.sessions.values()].filter(\n (session) => session.project_hash === projectHash,\n ).length;\n this.projects.set(projectHash, loadedProject);\n }\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { EventV1 } from \"@holdpoint/live-protocol\";\n\nconst DEFAULT_LOCK_TTL_MS = 30_000;\n\ninterface FileLock {\n sessionKey: string;\n engine: string;\n sessionId: string;\n expiresAt: number;\n}\n\ntype LockEvent = Extract<EventV1, { type: \"tool_pre\" | \"tool_post\" | \"tool_failure\" }>;\n\nfunction buildSessionKey(event: Pick<EventV1, \"project_hash\" | \"engine\" | \"session_id\">): string {\n return `${event.project_hash}:${event.engine}:${event.session_id}`;\n}\n\nfunction normalizeWriteTarget(cwd: string, target: string): string {\n const resolved = resolve(cwd, target);\n return existsSync(resolved) ? realpathSync.native(resolved) : resolved;\n}\n\nfunction getWriteTargets(event: LockEvent, activeTargets: Map<string, string[]>): string[] {\n const toolKey = `${buildSessionKey(event)}:${event.payload.tool_use_id}`;\n if (event.type === \"tool_pre\") {\n return (event.payload.write_targets ?? []).map((target: string) =>\n normalizeWriteTarget(event.cwd, target),\n );\n }\n\n return (\n (event.type === \"tool_post\"\n ? event.payload.write_targets?.map((target: string) =>\n normalizeWriteTarget(event.cwd, target),\n )\n : undefined) ??\n activeTargets.get(toolKey) ??\n []\n );\n}\n\nexport class ConflictTracker {\n private readonly lockTtlMs: number;\n private readonly locksByProject = new Map<string, Map<string, FileLock>>();\n private readonly activeTargets = new Map<string, string[]>();\n private readonly emittedConflicts = new Map<string, number>();\n\n constructor(lockTtlMs = DEFAULT_LOCK_TTL_MS) {\n this.lockTtlMs = lockTtlMs;\n }\n\n handleEvent(event: EventV1): EventV1[] {\n switch (event.type) {\n case \"tool_pre\":\n return this.handleToolPre(event);\n case \"tool_post\":\n case \"tool_failure\":\n this.releaseLocks(event);\n return [];\n default:\n return [];\n }\n }\n\n private handleToolPre(event: Extract<EventV1, { type: \"tool_pre\" }>): EventV1[] {\n const sessionKey = buildSessionKey(event);\n const toolKey = `${sessionKey}:${event.payload.tool_use_id}`;\n const writeTargets = getWriteTargets(event, this.activeTargets);\n if (writeTargets.length === 0) {\n return [];\n }\n\n this.activeTargets.set(toolKey, writeTargets);\n const projectLocks = this.getProjectLocks(event.project_hash);\n this.pruneExpiredLocks(projectLocks, event.ts);\n\n const conflicts: EventV1[] = [];\n for (const filePath of writeTargets) {\n const existing = projectLocks.get(filePath);\n if (!existing) {\n projectLocks.set(filePath, {\n sessionKey,\n engine: event.engine,\n sessionId: event.session_id,\n expiresAt: event.ts + this.lockTtlMs,\n });\n continue;\n }\n\n if (existing.sessionKey === sessionKey) {\n existing.expiresAt = event.ts + this.lockTtlMs;\n continue;\n }\n\n const dedupeKey = `${event.project_hash}:${filePath}:${existing.sessionKey}:${sessionKey}`;\n const previousEmission = this.emittedConflicts.get(dedupeKey) ?? 0;\n if (previousEmission > event.ts) {\n continue;\n }\n\n this.emittedConflicts.set(dedupeKey, event.ts + this.lockTtlMs);\n conflicts.push({\n v: 1,\n id: randomUUID(),\n ts: event.ts,\n engine: event.engine,\n session_id: event.session_id,\n project_hash: event.project_hash,\n cwd: event.cwd,\n type: \"conflict\",\n payload: {\n kind: \"file_write\",\n file_path: filePath,\n holder: {\n engine: existing.engine,\n session_id: existing.sessionId,\n },\n requester: {\n engine: event.engine,\n session_id: event.session_id,\n },\n },\n });\n }\n\n return conflicts;\n }\n\n private releaseLocks(event: Extract<EventV1, { type: \"tool_post\" | \"tool_failure\" }>): void {\n const sessionKey = buildSessionKey(event);\n const toolKey = `${sessionKey}:${event.payload.tool_use_id}`;\n const projectLocks = this.getProjectLocks(event.project_hash);\n const writeTargets = getWriteTargets(event, this.activeTargets);\n\n for (const filePath of writeTargets) {\n const existing = projectLocks.get(filePath);\n if (existing?.sessionKey === sessionKey) {\n projectLocks.delete(filePath);\n }\n }\n\n this.activeTargets.delete(toolKey);\n this.pruneExpiredLocks(projectLocks, event.ts);\n }\n\n private getProjectLocks(projectHash: string): Map<string, FileLock> {\n let existing = this.locksByProject.get(projectHash);\n if (!existing) {\n existing = new Map<string, FileLock>();\n this.locksByProject.set(projectHash, existing);\n }\n return existing;\n }\n\n private pruneExpiredLocks(projectLocks: Map<string, FileLock>, now: number): void {\n for (const [filePath, lock] of projectLocks.entries()) {\n if (lock.expiresAt <= now) {\n projectLocks.delete(filePath);\n }\n }\n\n for (const [key, expiresAt] of this.emittedConflicts.entries()) {\n if (expiresAt <= now) {\n this.emittedConflicts.delete(key);\n }\n }\n }\n}\n","import { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { basename } from \"node:path\";\n\nexport interface ProjectIdentity {\n hash: string;\n name: string;\n root: string;\n}\n\nfunction sha12(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 12);\n}\n\nexport function identifyProject(cwd: string): ProjectIdentity {\n try {\n const root = realpathSync(\n execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim(),\n );\n return {\n hash: sha12(root),\n name: basename(root),\n root,\n };\n } catch {\n const root = realpathSync(cwd);\n return {\n hash: sha12(root),\n name: basename(root),\n root,\n };\n }\n}\n","import type { EventV1 } from \"@holdpoint/live-protocol\";\nimport { buildSessionKey } from \"./store.js\";\n\nexport interface Subscription {\n scope: \"project\" | \"session\" | \"all\";\n key?: string;\n}\n\nexport function matchesSubscription(subscription: Subscription, event: EventV1): boolean {\n switch (subscription.scope) {\n case \"all\":\n return true;\n case \"project\":\n return subscription.key === event.project_hash;\n case \"session\":\n return subscription.key === buildSessionKey(event);\n }\n}\n","import {\n removeDaemonLock,\n createDaemonLock,\n findFreePort,\n readHealthyDaemonLock,\n type DaemonLock,\n writeDaemonLockExclusive,\n resolveHoldpointHome,\n} from \"./singleton.js\";\nimport { startLiveServer, type RunningLiveServer } from \"./server.js\";\nimport { LiveStore } from \"./store.js\";\n\nexport class DaemonAlreadyRunningError extends Error {\n readonly info: DaemonLock;\n\n constructor(info: DaemonLock) {\n super(`Holdpoint daemon already running on port ${info.port}`);\n this.info = info;\n }\n}\n\nexport interface StartDaemonProcessOptions {\n homeDir?: string;\n port?: number;\n version: string;\n}\n\nexport interface StartedDaemon {\n info: DaemonLock;\n server: RunningLiveServer;\n store: LiveStore;\n close(): Promise<void>;\n closed: Promise<void>;\n}\n\nexport async function startDaemonProcess(\n options: StartDaemonProcessOptions,\n): Promise<StartedDaemon> {\n const existing = await readHealthyDaemonLock(options.homeDir);\n if (existing) {\n throw new DaemonAlreadyRunningError(existing);\n }\n\n const port = options.port ?? (await findFreePort());\n const info = createDaemonLock(port, options.version);\n writeDaemonLockExclusive(info, options.homeDir);\n\n const store = await LiveStore.create(resolveHoldpointHome(options.homeDir));\n await store.replayPending();\n\n let server: RunningLiveServer;\n try {\n server = await startLiveServer({\n port,\n token: info.token,\n version: options.version,\n startedAt: info.started_at,\n store,\n });\n } catch (error) {\n removeDaemonLock(options.homeDir, info.token);\n throw error;\n }\n\n let closed = false;\n const cleanup = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n removeDaemonLock(options.homeDir, info.token);\n await server.close();\n };\n\n const onSignal = (): void => {\n void cleanup().finally(() => process.exit(0));\n };\n\n process.once(\"SIGTERM\", onSignal);\n process.once(\"SIGINT\", onSignal);\n\n return {\n info,\n server,\n store,\n close: cleanup,\n closed: server.closed.finally(() => {\n process.off(\"SIGTERM\", onSignal);\n process.off(\"SIGINT\", onSignal);\n }),\n };\n}\n\nexport {\n createDaemonLock,\n ensureHoldpointHome,\n findFreePort,\n getDaemonLockPath,\n isProcessAlive,\n readDaemonLock,\n readHealthyDaemonLock,\n removeDaemonLock,\n resolveHoldpointHome,\n waitForDaemonHealthy,\n writeDaemonLockExclusive,\n} from \"./singleton.js\";\nexport { identifyProject } from \"./project-identity.js\";\nexport { startLiveServer } from \"./server.js\";\nexport { buildSessionKey, LiveStore } from \"./store.js\";\nexport type { ProjectIdentity } from \"./project-identity.js\";\nexport type { RunningLiveServer } from \"./server.js\";\nexport type { DaemonLock } from \"./singleton.js\";\n"],"mappings":"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","names":["createServer","randomUUID","existsSync","join","resolve","EventV1Schema","existsSync","join","existsSync","resolve","realpathSync","buildSessionKey","join","existsSync","buildSessionKey","join","randomUUID","resolve","existsSync","createServer","EventV1Schema"]}