pelican-cc 0.2.3 → 0.3.1
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/CHANGELOG.md +154 -0
- package/README.md +120 -37
- package/dist/server/index.js +4014 -911
- package/dist/server/index.js.map +4 -4
- package/dist/web/assets/Chat-DC8P9wgJ.js +73 -0
- package/dist/web/assets/Chat-DC8P9wgJ.js.br +0 -0
- package/dist/web/assets/Chat-DC8P9wgJ.js.gz +0 -0
- package/dist/web/assets/ModelSheet-DYv_cBVT.js +1 -0
- package/dist/web/assets/ModelSheet-DYv_cBVT.js.br +0 -0
- package/dist/web/assets/ModelSheet-DYv_cBVT.js.gz +0 -0
- package/dist/web/assets/Settings-Bmvthzji.js +3 -0
- package/dist/web/assets/Settings-Bmvthzji.js.br +0 -0
- package/dist/web/assets/Settings-Bmvthzji.js.gz +0 -0
- package/dist/web/assets/index-BFIIo7_h.css +2 -0
- package/dist/web/assets/index-BFIIo7_h.css.br +0 -0
- package/dist/web/assets/index-BFIIo7_h.css.gz +0 -0
- package/dist/web/assets/index-D0THzVL2.js +30 -0
- package/dist/web/assets/index-D0THzVL2.js.br +0 -0
- package/dist/web/assets/index-D0THzVL2.js.gz +0 -0
- package/dist/web/index.html +3 -3
- package/dist/web/index.html.br +0 -0
- package/dist/web/index.html.gz +0 -0
- package/dist/web/manifest.webmanifest +1 -1
- package/dist/web/preview.html +15 -0
- package/dist/web/sw.js.br +0 -0
- package/dist/web/sw.js.gz +0 -0
- package/npm-shrinkwrap.json +6710 -0
- package/package.json +17 -8
- package/dist/web/assets/index-BrFr7i2Q.js +0 -81
- package/dist/web/assets/index-DlTrFrpv.css +0 -2
package/dist/server/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../package.json", "../../src/server/config.ts", "../../src/server/security.ts", "../../src/server/auth.ts", "../../src/server/demo-image.ts", "../../src/server/demo-visuals.ts", "../../src/server/demo.ts", "../../src/shared/tasks.ts", "../../src/server/archive.ts", "../../src/server/folders.ts", "../../src/server/live.ts", "../../src/server/normalize.ts", "../../src/server/history.ts", "../../src/server/transcripts.ts", "../../src/server/sessions.ts", "../../src/server/actions.ts", "../../src/server/feed.ts", "../../src/server/files.ts", "../../src/server/trust.ts", "../../src/server/models.ts", "../../src/server/git.ts", "../../src/server/project-files.ts", "../../src/server/push.ts", "../../src/server/shell.ts", "../../src/server/usage.ts", "../../src/server/runner.ts", "../../src/server/workspace.ts", "../../src/server/app.ts", "../../src/server/
|
|
4
|
-
"sourcesContent": ["{\n \"name\": \"pelican-cc\",\n \"version\": \"0.2.3\",\n \"description\": \"Your Claude Code sessions, from any browser: a phone-first web app that runs next to Claude Code.\",\n \"keywords\": [\n \"claude\",\n \"claude-code\",\n \"agent\",\n \"mobile\",\n \"web-ui\",\n \"ai-coding\"\n ],\n \"homepage\": \"https://github.com/Ki-Seki/pelican#readme\",\n \"bugs\": \"https://github.com/Ki-Seki/pelican/issues\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Ki-Seki/pelican.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Shichao Song\",\n \"type\": \"module\",\n \"bin\": {\n \"pelican\": \"dist/server/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"CHANGELOG.md\"\n ],\n \"engines\": {\n \"node\": \">=22.12\"\n },\n \"scripts\": {\n \"dev\": \"node scripts/dev.mjs\",\n \"demo\": \"node dist/server/index.js --demo\",\n \"build\": \"vite build && node scripts/build-server.mjs\",\n \"start\": \"node dist/server/index.js\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"test\": \"vitest run\",\n \"screenshots\": \"node scripts/screenshots.mjs\",\n \"prepublishOnly\": \"npm run typecheck && npm test && npm run build\"\n },\n \"dependencies\": {\n \"@anthropic-ai/claude-agent-sdk\": \"^0.3.318\",\n \"@hono/node-server\": \"^2.1.6\",\n \"hono\": \"^4.13.16\",\n \"qrcode-generator\": \"^1.4.4\",\n \"web-push\": \"^3.6.7\",\n \"ws\": \"^8.22.1\"\n },\n \"devDependencies\": {\n \"@tailwindcss/vite\": \"^4.3.4\",\n \"@tanstack/react-query\": \"^5.105.3\",\n \"@testing-library/react\": \"^16.3.0\",\n \"@types/node\": \"^24.0.0\",\n \"@types/react\": \"^19.1.0\",\n \"@types/react-dom\": \"^19.1.0\",\n \"@types/web-push\": \"^3.6.4\",\n \"@types/ws\": \"^8.18.1\",\n \"@vitejs/plugin-react\": \"^6.2.1\",\n \"diff\": \"^9.0.0\",\n \"esbuild\": \"^0.27.0\",\n \"jsdom\": \"^27.0.0\",\n \"lucide-react\": \"^1.68.0\",\n \"playwright-core\": \"^1.64.1\",\n \"react\": \"^19.3.1\",\n \"react-dom\": \"^19.3.1\",\n \"react-markdown\": \"^10.1.0\",\n \"rehype-highlight\": \"^7.0.2\",\n \"remark-breaks\": \"^4.0.0\",\n \"remark-gfm\": \"^4.0.1\",\n \"tailwindcss\": \"^4.3.4\",\n \"tsx\": \"^4.23.15\",\n \"typescript\": \"^7.0.2\",\n \"vite\": \"^8.3.5\",\n \"vitest\": \"^5.1.0\"\n }\n}\n", "import { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst here = path.dirname(fileURLToPath(import.meta.url));\nconst home = os.homedir();\n\n/** Directory of the built web app: next to the bundled server, or `dist/web` when run from source. */\nfunction findWebDir(): string | undefined {\n for (const candidate of [path.join(here, '../web'), path.join(here, '../../dist/web')]) {\n if (existsSync(path.join(candidate, 'index.html'))) return candidate;\n }\n return undefined;\n}\n\nconst list = (value: string | undefined) => (value ?? '').split(',').map((s) => s.trim()).filter(Boolean);\n\n/** Settings Pelican could not use, said once at start (cli.ts). */\nexport const configWarnings: string[] = [];\n\n/**\n * Web origins (`https://host[:port]`), and nothing looser: no `*`, no `null`, no bare scheme,\n * no path. With `wildcardHost`, `https://*.example.com` is allowed too (for frame-ancestors).\n */\nfunction origins(name: string, value: string | undefined, wildcardHost = false): string[] {\n const kept: string[] = [];\n for (const entry of (value ?? '').split(/[\\s,]+/).filter(Boolean)) {\n const wildcard = wildcardHost && /^https?:\\/\\/\\*\\.[^*]+$/i.test(entry);\n let url: URL | undefined;\n try {\n url = /^https?:\\/\\//i.test(entry) ? new URL(wildcard ? entry.replace('*.', 'wildcard.') : entry) : undefined;\n } catch {\n url = undefined;\n }\n const origin = url && (wildcard ? url.origin.replace('://wildcard.', '://*.') : url.origin);\n // Host names of letters, digits, dots and dashes (or an IPv6 address): a URL may hold\n // characters such as `;` that would end a header's directive.\n if (url && origin && url.pathname === '/' && !url.search && !url.hash && !url.username && !url.password\n && (wildcard ? /^https?:\\/\\/\\*\\.[a-z0-9.-]+(:\\d+)?$/ : /^https?:\\/\\/([a-z0-9.-]+|\\[[0-9a-f:.]+\\])(:\\d+)?$/).test(origin)) {\n kept.push(origin);\n } else {\n configWarnings.push(`${name}: ignored \"${entry}\"; use an origin like https://pelican.example.com`);\n }\n }\n return kept;\n}\n\nexport type AuthMode = 'auto' | 'none';\n\n/**\n * Settings from the environment; the command line (`cli.ts`) overrides some of\n * them before the server starts.\n */\nexport const config = {\n host: process.env.PELICAN_HOST ?? '127.0.0.1',\n port: Number(process.env.PELICAN_PORT ?? 7860),\n /** Name shown in the app, for telling machines apart. */\n machine: process.env.PELICAN_MACHINE ?? (os.hostname().split('.')[0] || 'local'),\n home,\n claudeHome: process.env.CLAUDE_CONFIG_DIR ?? path.join(home, '.claude'),\n /** The password hash lives here. */\n configDir: process.env.PELICAN_CONFIG_DIR ?? path.join(home, '.config', 'pelican'),\n /** Uploads, push keys and subscriptions. */\n stateDir: process.env.PELICAN_STATE_DIR ?? path.join(home, '.local', 'state', 'pelican'),\n webDir: findWebDir(),\n /**\n * auto: sign in with the password when one is set (`pelican password`), else\n * with the access token in the link Pelican prints. none: no sign-in, for\n * when something in front already authenticates (a proxy, a gateway).\n */\n auth: (process.env.PELICAN_AUTH === 'none' ? 'none' : 'auto') as AuthMode,\n /** Origins, besides the page's own, allowed to send requests (for example a proxy's public URL). */\n allowedOrigins: origins('PELICAN_ALLOWED_ORIGINS', process.env.PELICAN_ALLOWED_ORIGINS),\n /** Host names the server answers to, besides this machine's own names and addresses (and *.ts.net). */\n allowedHosts: list(process.env.PELICAN_ALLOWED_HOSTS),\n /**\n * A proxy on this machine (Tailscale, Caddy, nginx) sets X-Forwarded-For truthfully: limit sign-in\n * attempts by the client it names. Off by default, since anyone can write that header.\n */\n trustedProxy: process.env.PELICAN_TRUSTED_PROXY === '1',\n /** Pages, besides Pelican's own origin, that may show Pelican in a frame (space or comma separated). */\n frameAncestors: origins('PELICAN_FRAME_ANCESTORS', process.env.PELICAN_FRAME_ANCESTORS, true),\n /** Where a tapped notification opens a session; `{id}` is replaced. Default: the page that subscribed. */\n sessionUrl: process.env.PELICAN_SESSION_URL || undefined,\n /** A Claude process with nothing to do is closed after this long; the next message resumes the session. */\n idleCloseMs: Number(process.env.PELICAN_IDLE_CLOSE_MS ?? 30 * 60 * 1000),\n /** A transcript written by someone else this recently counts as live. */\n liveWindowMs: 45_000,\n claudeExecutable: process.env.PELICAN_CLAUDE_PATH || undefined,\n /** Demo mode: made-up sessions, nothing runs. */\n demo: false,\n};\n\nexport type Config = typeof config;\n", "import os from 'node:os';\n\nimport { config } from './config.js';\n\nconst hostname = (host: string) => {\n const h = host.trim().toLowerCase();\n if (h.startsWith('[')) return h.slice(1, h.indexOf(']'));\n const colon = h.lastIndexOf(':');\n return colon > -1 && h.indexOf(':') === colon ? h.slice(0, colon) : h;\n};\n\nexport function isLoopback(host: string): boolean {\n const h = hostname(host);\n return h === 'localhost' || h.endsWith('.localhost') || h === '::1' || /^127(\\.\\d{1,3}){3}$/.test(h);\n}\n\n/** True for addresses that only this machine can reach. */\nexport function listensLocally(host: string): boolean {\n return isLoopback(host);\n}\n\nfunction knownHosts(): Set<string> {\n const names = new Set<string>();\n const machine = os.hostname().toLowerCase();\n names.add(machine);\n names.add(machine.split('.')[0]!);\n // This computer's own addresses: a phone on the network may open it by IP.\n for (const address of Object.values(os.networkInterfaces()).flat()) if (address) names.add(address.address.toLowerCase());\n if (config.host !== '0.0.0.0' && config.host !== '::') names.add(hostname(config.host));\n for (const host of config.allowedHosts) {\n const name = hostname(host);\n if (name) names.add(name);\n }\n for (const origin of config.allowedOrigins) {\n try {\n names.add(new URL(origin).hostname.toLowerCase().replace(/^\\[(.*)\\]$/, '$1'));\n } catch {\n // Not a URL; ignored.\n }\n }\n return names;\n}\n\n/**\n * The server answers only to names that point at it: this computer's names and\n * addresses, loopback, Tailscale names (*.ts.net, which only Tailscale can point\n * anywhere) and configured ones. Otherwise a web page could rebind its own\n * domain to 127.0.0.1 (DNS rebinding) and use Pelican through your browser.\n */\nexport function hostAllowed(host: string | undefined): boolean {\n if (!host) return false;\n const name = hostname(host);\n if (!name) return false;\n if (isLoopback(host)) return true;\n if (name.endsWith('.ts.net')) return true;\n return knownHosts().has(name);\n}\n\n/**\n * Requests that change something must come from this app's own page, or from\n * an origin allowed in the config, so a page on another site cannot drive Claude.\n */\nexport function originAllowed(origin: string | undefined, ...hosts: Array<string | undefined>): boolean {\n if (!origin) return true;\n let url: URL;\n try {\n url = new URL(origin);\n } catch {\n return false;\n }\n if (config.allowedOrigins.includes(url.origin)) return true;\n return hosts.flatMap((h) => (h ? h.split(',').map((s) => s.trim()) : [])).includes(url.host);\n}\n", "import { createHash, createHmac, randomBytes, scrypt, timingSafeEqual } from 'node:crypto';\nimport { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * Who may use Pelican. Pelican runs commands as you, so nothing gets in\n * without proof, also on this computer, where every account and process can\n * reach 127.0.0.1:\n *\n * - token (the default): a random access token, kept in the config folder and\n * printed in the link Pelican shows at start. Opening that link, or pasting\n * the token, signs the browser in, the way Jupyter does.\n * - password: set on the computer with `pelican password` (never over the\n * network), stored as a scrypt hash. For reaching Pelican from a phone.\n * - none: `--no-auth`, for when something in front already authenticates\n * (a reverse proxy, a gateway), and for the demo, which holds nothing private.\n *\n * Signing in sets a cookie signed with a secret that belongs to the token or\n * the password and changes with it, so resetting either signs every browser out.\n */\nexport type AuthMode = 'none' | 'password' | 'token';\n\ntype Password = { version: 1; salt: string; hash: string; secret: string; N: number; r: number; p: number };\ntype Token = { version: 1; token: string; secret: string };\n\nconst passwordFile = () => path.join(config.configDir, 'auth.json');\nconst tokenFile = () => path.join(config.configDir, 'token.json');\nconst SESSION_DAYS = 30;\nconst PARAMS = { N: 16384, r: 8, p: 1 };\n\nlet password: Password | undefined;\nlet token: Token | undefined;\nlet loaded = false;\n\nfunction derive(text: string, salt: Buffer, params: { N: number; r: number; p: number }): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n scrypt(text.normalize('NFKC'), salt, 32, { ...params, maxmem: 64 * 1024 * 1024 }, (error, key) => (error ? reject(error) : resolve(key)));\n });\n}\n\nasync function writePrivate(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n await writeFile(file, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n}\n\nconst readJson = async <T>(file: string): Promise<T | undefined> => {\n try {\n return JSON.parse(await readFile(file, 'utf8')) as T;\n } catch {\n return undefined;\n }\n};\n\n/** Reads the password and the access token, making the token on first use. */\nexport async function loadAuth(): Promise<void> {\n if (loaded) return;\n password = await readJson<Password>(passwordFile());\n if (config.auth !== 'none') {\n token = await readJson<Token>(tokenFile());\n if (!token?.token || !token.secret) await resetToken();\n }\n loaded = true;\n}\n\nexport function authMode(): AuthMode {\n if (config.auth === 'none') return 'none';\n return password ? 'password' : 'token';\n}\n\nexport function passwordSet(): boolean {\n return Boolean(password);\n}\n\n/** The access token, for the link Pelican prints; undefined when it is not in use. */\nexport function accessToken(): string | undefined {\n return authMode() === 'token' ? token?.token : undefined;\n}\n\n/** A new access token: links and browsers signed in with the old one stop working. */\nexport async function resetToken(): Promise<string> {\n token = { version: 1, token: randomBytes(24).toString('base64url'), secret: randomBytes(32).toString('base64') };\n await writePrivate(tokenFile(), token);\n return token.token;\n}\n\nexport async function setPassword(text: string): Promise<void> {\n const salt = randomBytes(16);\n const hash = await derive(text, salt, PARAMS);\n password = { version: 1, salt: salt.toString('base64'), hash: hash.toString('base64'), secret: randomBytes(32).toString('base64'), ...PARAMS };\n await writePrivate(passwordFile(), password);\n loaded = true;\n}\n\nexport async function clearPassword(): Promise<void> {\n await rm(passwordFile(), { force: true });\n password = undefined;\n}\n\nexport async function checkPassword(text: string): Promise<boolean> {\n if (!password) return false;\n const expected = Buffer.from(password.hash, 'base64');\n const actual = await derive(text, Buffer.from(password.salt, 'base64'), password);\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\nconst same = (a: string, b: string) => {\n const x = createHash('sha256').update(a).digest();\n const y = createHash('sha256').update(b).digest();\n return timingSafeEqual(x, y);\n};\n\n/** Whether `given` is the access token (only while the token is how Pelican signs in). */\nexport function checkToken(given: string | undefined): boolean {\n const current = accessToken();\n return Boolean(current && given && same(given, current));\n}\n\n/** The secret that signs cookies in the current mode. */\nconst secret = () => (authMode() === 'password' ? password?.secret : authMode() === 'token' ? token?.secret : undefined);\n\n/** Cookie name: one per secret, so two Pelicans on one origin do not sign each other out. */\nexport function cookieName(): string {\n const value = secret();\n return `pelican_${value ? createHash('sha256').update(value).digest('hex').slice(0, 8) : 'none'}`;\n}\n\nfunction sign(expires: number): string {\n return createHmac('sha256', Buffer.from(secret() ?? '', 'base64')).update(String(expires)).digest('base64url');\n}\n\nexport function newSessionCookie(): { name: string; value: string; maxAge: number } {\n const maxAge = SESSION_DAYS * 24 * 3600;\n const expires = Date.now() + maxAge * 1000;\n return { name: cookieName(), value: `${expires}.${sign(expires)}`, maxAge };\n}\n\nfunction cookieValue(header: string | undefined, name: string): string | undefined {\n for (const part of (header ?? '').split(';')) {\n const [key, ...rest] = part.trim().split('=');\n if (key === name) return rest.join('=');\n }\n return undefined;\n}\n\n/**\n * Whether a request may use Pelican: always when nothing is required, else with a\n * valid session cookie, or (token mode) the token as `Authorization: Bearer <token>`.\n */\nexport function signedIn(cookieHeader: string | undefined, authorization?: string): boolean {\n const mode = authMode();\n if (mode === 'none') return true;\n if (mode === 'token' && authorization?.startsWith('Bearer ') && checkToken(authorization.slice(7).trim())) return true;\n if (!secret()) return false;\n const value = cookieValue(cookieHeader, cookieName());\n if (!value) return false;\n const [expires, mac] = value.split('.');\n const when = Number(expires);\n if (!mac || !Number.isFinite(when) || when < Date.now()) return false;\n const expected = Buffer.from(sign(when));\n const given = Buffer.from(mac);\n return expected.length === given.length && timingSafeEqual(expected, given);\n}\n\n// Failed sign-ins: at most 10 per client and 30 in all every 10 minutes, so neither\n// a rotating client key nor many clients together can guess for long.\nconst WINDOW_MS = 10 * 60_000;\nconst PER_CLIENT = 10;\nconst IN_ALL = 30;\nconst failures = new Map<string, number[]>();\nlet allFailures: number[] = [];\n\nconst recent = (times: number[], now: number) => times.filter((t) => now - t < WINDOW_MS);\n\n/** Whether this client may try to sign in now. */\nexport function attemptAllowed(client: string, now = Date.now()): boolean {\n allFailures = recent(allFailures, now);\n if (allFailures.length >= IN_ALL) return false;\n return recent(failures.get(client) ?? [], now).length < PER_CLIENT;\n}\n\n/** Counts a wrong password or token against the client and against everyone. */\nexport function noteFailure(client: string, now = Date.now()): void {\n allFailures.push(now);\n failures.set(client, [...recent(failures.get(client) ?? [], now), now]);\n // Forget clients whose failures have all expired, and never keep more than a few thousand.\n if (failures.size > 1000) {\n for (const [key, times] of failures) if (recent(times, now).length === 0) failures.delete(key);\n while (failures.size > 5000) failures.delete(failures.keys().next().value!);\n }\n}\n\n/**\n * Starts a sign-in attempt: counted as a failure at once, before the slow check, so many\n * requests sent together cannot all get past the limit. Returns undefined when the client\n * is over the limit, else a function that takes the attempt back once it succeeded.\n */\nexport function beginAttempt(client: string, now = Date.now()): (() => void) | undefined {\n if (!attemptAllowed(client, now)) return undefined;\n noteFailure(client, now);\n return () => {\n const drop = (times: number[] | undefined) => {\n const at = times?.lastIndexOf(now) ?? -1;\n if (times && at >= 0) times.splice(at, 1);\n };\n drop(allFailures);\n drop(failures.get(client));\n };\n}\n\n/** For tests: start counting afresh. */\nexport function resetAttempts(): void {\n failures.clear();\n allFailures = [];\n}\n\n// One-time sign-in codes, for the QR code that opens Pelican on a phone: the page never sees\n// the access token or the password, and a photo of the code is useless after two minutes.\nconst CODE_MS = 2 * 60_000;\nconst codes = new Map<string, number>();\n\n/** A new code that signs one browser in, once, within two minutes. */\nexport function issueCode(now = Date.now()): string {\n for (const [code, expires] of codes) if (expires <= now) codes.delete(code);\n while (codes.size >= 20) codes.delete(codes.keys().next().value!);\n const code = randomBytes(18).toString('base64url');\n codes.set(code, now + CODE_MS);\n return code;\n}\n\n/** Whether `given` is a live code; using it ends it. */\nexport function redeemCode(given: string | undefined, now = Date.now()): boolean {\n if (!given || authMode() === 'none') return false;\n for (const [code, expires] of codes) {\n if (same(code, given)) {\n codes.delete(code);\n return expires > now;\n }\n }\n return false;\n}\n", "// A made-up screenshot the demo's first prompt attaches: a settings page before its dark theme.\nexport const SETTINGS_SCREENSHOT = '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';\n", "// The demo session that draws: a chart as a Claude Desktop visual, and a page Claude writes.\n\nconst DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];\nconst SIGNUPS = [1420, 1588, 1710, 2214, 1966, 1702, 1880];\n\nexport const SIGNUPS_CSV = `day,signups\\n${DAYS.map((d, i) => `${d},${SIGNUPS[i]}`).join('\\n')}\\n`;\n\n/** A bar chart in the vocabulary of Claude Desktop's visuals (box, th, ts, c-*), sized to read on a phone. */\nexport function signupsChart(): string {\n const max = Math.max(...SIGNUPS);\n const bars = SIGNUPS.map((value, i) => {\n const h = Math.round((value / max) * 128);\n const x = 26 + i * 52;\n const y = 196 - h;\n const tone = value === max ? 'c-purple' : 'c-teal';\n return `<g class=\"${tone}\"><rect x=\"${x}\" y=\"${y}\" width=\"38\" height=\"${h}\" rx=\"6\"/></g>`\n + `<text class=\"ts\" x=\"${x + 19}\" y=\"${y - 8}\" text-anchor=\"middle\">${(value / 1000).toFixed(1)}k</text>`\n + `<text class=\"ts\" x=\"${x + 19}\" y=\"216\" text-anchor=\"middle\">${DAYS[i]}</text>`;\n }).join('');\n return `<svg width=\"100%\" viewBox=\"0 0 400 228\" role=\"img\"><title>Signups by day, last week</title>`\n + `<text class=\"th\" x=\"16\" y=\"24\">Signups by day \u00B7 last week</text>`\n + `<text class=\"ts\" x=\"16\" y=\"42\">12,480 in total, 18% more than the week before</text>`\n + `<line x1=\"16\" y1=\"196.5\" x2=\"384\" y2=\"196.5\" style=\"stroke:var(--line)\"/>`\n + `${bars}</svg>`;\n}\n\nexport const REPORT_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Signups \u00B7 week 45</title>\n<style>\n :root { color-scheme: light dark; --ink: #17181a; --soft: #6b6e75; --line: #e6e6e3; --card: #fff; --bg: #f6f6f3; --a: #0e7490; --b: #7c6cf2; }\n @media (prefers-color-scheme: dark) { :root { --ink: #ececea; --soft: #a5a8ae; --line: #2a2d31; --card: #16181b; --bg: #0e0f11; --a: #3ba7bd; --b: #9d90f5; } }\n * { box-sizing: border-box; margin: 0; }\n body { background: var(--bg); color: var(--ink); font: 15px/1.55 -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; padding: 28px 20px 40px; }\n main { max-width: 640px; margin: 0 auto; }\n .eyebrow { color: var(--a); font-weight: 600; font-size: 13px; letter-spacing: .02em; }\n h1 { margin-top: 6px; font-size: 30px; line-height: 1.1; letter-spacing: -.03em; }\n .kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 22px; }\n .kpi { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 14px; }\n .kpi b { display: block; font-size: 24px; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }\n .kpi span { color: var(--soft); font-size: 12.5px; }\n .up { color: #16a34a; }\n .chart { margin-top: 14px; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px 14px 10px; }\n .bars { display: flex; align-items: flex-end; gap: 8px; height: 170px; }\n .bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 100%; }\n .bar i { display: block; width: 100%; border-radius: 8px 8px 4px 4px; background: color-mix(in srgb, var(--a) 75%, transparent); height: 0; transition: height .9s cubic-bezier(.2,.8,.2,1); }\n .bar.top i { background: var(--b); }\n .bar small { color: var(--soft); font-size: 11.5px; }\n p.note { margin-top: 16px; color: var(--soft); }\n</style>\n</head>\n<body>\n<main>\n <div class=\"eyebrow\">Growth \u00B7 week 45</div>\n <h1>Signups grew 18%, and Thursday led the week</h1>\n <div class=\"kpis\">\n <div class=\"kpi\"><b data-count=\"12480\">0</b><span>signups</span></div>\n <div class=\"kpi\"><b class=\"up\">+18%</b><span>on week 44</span></div>\n <div class=\"kpi\"><b>Thu</b><span>best day, 2,214</span></div>\n </div>\n <div class=\"chart\"><div class=\"bars\" id=\"bars\"></div></div>\n <p class=\"note\">Thursday's newsletter brought the peak; the weekend held above the weekday average.</p>\n</main>\n<script>\n const days = ${JSON.stringify(DAYS)};\n const values = ${JSON.stringify(SIGNUPS)};\n const max = Math.max(...values);\n const bars = document.getElementById('bars');\n values.forEach((v, i) => {\n const bar = document.createElement('div');\n bar.className = 'bar' + (v === max ? ' top' : '');\n bar.innerHTML = '<small>' + v.toLocaleString() + '</small><i></i><small>' + days[i] + '</small>';\n bars.append(bar);\n requestAnimationFrame(() => requestAnimationFrame(() => { bar.querySelector('i').style.height = (v / max * 120) + 'px'; }));\n });\n for (const el of document.querySelectorAll('[data-count]')) {\n const end = Number(el.dataset.count); const start = performance.now();\n const step = (t) => { const k = Math.min(1, (t - start) / 900); el.textContent = Math.round(end * (1 - Math.pow(1 - k, 3))).toLocaleString(); if (k < 1) requestAnimationFrame(step); };\n requestAnimationFrame(step);\n }\n</script>\n</body>\n</html>\n`;\n", "import { execFile } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport type { ModelOption, RunState } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { SETTINGS_SCREENSHOT } from './demo-image.js';\nimport { REPORT_HTML, SIGNUPS_CSV, signupsChart } from './demo-visuals.js';\n\n/**\n * `pelican --demo`: a made-up home with a few sessions, for trying Pelican\n * without Claude Code and for screenshots that show no real work. It is\n * written fresh on every start, with times relative to now. Nothing runs.\n */\n\nconst run = promisify(execFile);\nconst MIN = 60_000;\nconst HOUR = 60 * MIN;\n\ntype Block = Record<string, unknown>;\ntype Row = { role: 'user' | 'assistant'; content: string | Block[]; at: number };\n\nconst tool = (id: string, name: string, input: Record<string, unknown>): Block => ({ type: 'tool_use', id, name, input });\nconst result = (id: string, content: string, isError = false): Block => ({ type: 'tool_result', tool_use_id: id, content, ...(isError ? { is_error: true } : {}) });\nconst text = (value: string): Block => ({ type: 'text', text: value });\n\nfunction numbered(source: string): string {\n return source.split('\\n').map((line, i) => `${String(i + 1).padStart(6)}\\t${line}`).join('\\n');\n}\n\ntype DemoSession = { id: string; title: string; project: string; branch: string; rows: (cwd: string) => Row[]; scratch?: boolean };\n\nconst THEME_CSS = `:root {\n --bg: #ffffff;\n --fg: #111111;\n --muted: #6b6b6b;\n --accent: #2563eb;\n}\n\nbody {\n background: var(--bg);\n color: var(--fg);\n}`;\n\nconst SESSIONS: DemoSession[] = [\n {\n id: 'a3f1c2d4-1111-4a1b-8c3d-000000000001',\n title: 'Add a dark theme to the settings page',\n project: 'acme-web',\n branch: 'feat/dark-theme',\n rows: (cwd) => {\n const t = Date.now() - 4 * MIN;\n return [\n {\n role: 'user',\n at: t,\n content: [\n { type: 'image', source: { type: 'base64', media_type: 'image/png', data: SETTINGS_SCREENSHOT } },\n text('Add a dark theme to the settings page, with a toggle. Keep the colors in CSS variables.'),\n ],\n },\n { role: 'assistant', at: t + 4000, content: [text(\"I'll look at how the colors are set up first.\"), tool('t1', 'Read', { file_path: `${cwd}/src/styles/theme.css` })] },\n { role: 'user', at: t + 5000, content: [result('t1', numbered(THEME_CSS))] },\n {\n role: 'assistant',\n at: t + 9000,\n content: [\n text('The colors are already variables, so a dark theme is one more set of values plus a toggle that switches them.'),\n tool('t2', 'TodoWrite', {\n todos: [\n { content: 'Add dark color values', status: 'completed', activeForm: 'Adding dark color values' },\n { content: 'Add the toggle to Settings', status: 'in_progress', activeForm: 'Adding the toggle to Settings' },\n { content: 'Remember the choice', status: 'pending', activeForm: 'Remembering the choice' },\n { content: 'Run the tests', status: 'pending', activeForm: 'Running the tests' },\n ],\n }),\n ],\n },\n { role: 'user', at: t + 9500, content: [result('t2', 'Todos have been modified successfully.')] },\n {\n role: 'assistant',\n at: t + 14000,\n content: [tool('t3', 'Edit', {\n file_path: `${cwd}/src/styles/theme.css`,\n old_string: ' --accent: #2563eb;\\n}',\n new_string: \" --accent: #2563eb;\\n}\\n\\n:root[data-theme='dark'] {\\n --bg: #0b0b0c;\\n --fg: #ededed;\\n --muted: #a1a1a1;\\n --accent: #60a5fa;\\n}\",\n })],\n },\n { role: 'user', at: t + 15000, content: [result('t3', `The file ${cwd}/src/styles/theme.css has been updated successfully.`)] },\n { role: 'assistant', at: t + 19000, content: [text('Now the toggle itself, next to the other display settings:')] },\n ];\n },\n },\n {\n id: 'b7e2a9c1-2222-4b2c-9d4e-000000000002',\n title: 'Why is the nightly export slow?',\n project: 'data-pipeline',\n branch: 'main',\n rows: (cwd) => {\n const t = Date.now() - 26 * MIN;\n return [\n { role: 'user', at: t, content: 'The nightly export went from 4 minutes to 40. Can you find out why?' },\n { role: 'assistant', at: t + 5000, content: [tool('g1', 'Grep', { pattern: 'def export_rows', path: `${cwd}/pipeline` })] },\n { role: 'user', at: t + 6000, content: [result('g1', 'pipeline/export.py:41:def export_rows(batch):')] },\n { role: 'assistant', at: t + 9000, content: [tool('g2', 'Read', { file_path: `${cwd}/pipeline/export.py`, offset: 35, limit: 30 })] },\n { role: 'user', at: t + 10000, content: [result('g2', numbered('def export_rows(batch):\\n for row in batch:\\n owner = db.fetch_owner(row.owner_id)\\n write(row, owner)'))] },\n { role: 'assistant', at: t + 15000, content: [tool('g3', 'Bash', { command: 'python -m cProfile -s cumtime -m pipeline.export --sample 5000 | head -8', description: 'Profile the export on a 5,000-row sample' })] },\n {\n role: 'user',\n at: t + 31000,\n content: [result('g3', ' ncalls tottime cumtime filename:lineno(function)\\n 5000 0.412 61.902 db.py:88(fetch_owner)\\n 1 0.020 62.410 export.py:41(export_rows)\\n 5000 0.301 0.488 writer.py:12(write)')],\n },\n {\n role: 'assistant',\n at: t + 40000,\n content: [text([\n 'Found it: `export_rows` looks up each row\\'s owner one query at a time. Since the owners table grew past a million rows that lookup is no longer cached, so 5,000 rows cost 5,000 round trips.',\n '',\n '| | Before | After batching |',\n '|---|---|---|',\n '| Queries per 5,000 rows | 5,000 | 1 |',\n '| Time on the sample | 62.4 s | 0.9 s |',\n '',\n 'The fix fetches the owners for the whole batch at once:',\n '',\n '```python',\n 'owners = db.fetch_owners({row.owner_id for row in batch})',\n 'for row in batch:',\n ' write(row, owners[row.owner_id])',\n '```',\n '',\n 'Want me to apply it and add a test that counts the queries?',\n ].join('\\n'))],\n },\n ];\n },\n },\n {\n id: 'c9d3b8e2-3333-4c3d-ae5f-000000000003',\n title: 'Fix the flaky login test',\n project: 'acme-web',\n branch: 'fix/login-test',\n rows: (cwd) => {\n const t = Date.now() - 3 * HOUR;\n return [\n { role: 'user', at: t, content: 'The login test fails about one run in five on CI. Plan a fix first.' },\n {\n role: 'assistant',\n at: t + 30000,\n content: [tool('p1', 'ExitPlanMode', {\n plan: '## Fix the flaky login test\\n\\nThe test clicks **Sign in** before the form has loaded its CSRF token, so the request is sometimes rejected.\\n\\n1. Wait for the token field to be filled before submitting.\\n2. Replace the fixed 500 ms sleep with that wait.\\n3. Run the test 50 times in a row to confirm.',\n })],\n },\n { role: 'user', at: t + 90000, content: [result('p1', 'User has approved your plan. You can now start coding.')] },\n {\n role: 'assistant',\n at: t + 95000,\n content: [tool('p2', 'Edit', {\n file_path: `${cwd}/tests/login.spec.ts`,\n old_string: \" await page.waitForTimeout(500);\\n await page.click('text=Sign in');\",\n new_string: \" await expect(page.locator('input[name=csrf]')).not.toHaveValue('');\\n await page.click('text=Sign in');\",\n })],\n },\n { role: 'user', at: t + 96000, content: [result('p2', `The file ${cwd}/tests/login.spec.ts has been updated successfully.`)] },\n { role: 'assistant', at: t + 99000, content: [tool('p3', 'Bash', { command: 'npx playwright test tests/login.spec.ts --repeat-each=50', description: 'Run the login test 50 times' })] },\n { role: 'user', at: t + 160000, content: [result('p3', 'Running 50 tests using 4 workers\\n\\n 50 passed (58.2s)')] },\n { role: 'assistant', at: t + 165000, content: [text('All 50 runs pass now. The test waits for the CSRF token instead of sleeping, so it is also about 400 ms faster.')] },\n ];\n },\n },\n {\n id: 'd1e4c7f3-4444-4d4e-bf60-000000000004',\n title: 'Release notes for v2.4',\n project: 'docs-site',\n branch: 'main',\n rows: () => {\n const t = Date.now() - 26 * HOUR;\n return [\n { role: 'user', at: t, content: 'Write the release notes for v2.4 from the merged pull requests.' },\n {\n role: 'assistant',\n at: t + 50000,\n content: [text('## v2.4\\n\\n**Highlights**\\n\\n- A dark theme, which follows your system setting or can be chosen in Settings.\\n- Exports are about 60 times faster on large accounts.\\n\\n**Fixes**\\n\\n- The login page no longer fails when submitted right after it opens.\\n- Long project names no longer push the menu off screen on phones.')],\n },\n ];\n },\n },\n {\n id: 'f3a6e9b5-6666-4f60-9182-000000000006',\n title: \"Chart last week's signups\",\n project: 'data-pipeline',\n branch: 'main',\n rows: (cwd) => {\n const t = Date.now() - 50 * MIN;\n return [\n { role: 'user', at: t, content: \"Chart last week's signups by day, and make me a one-page summary I can share.\" },\n { role: 'assistant', at: t + 3000, content: [text(\"I'll read the numbers first.\"), tool('v1', 'Read', { file_path: `${cwd}/data/signups.csv` })] },\n { role: 'user', at: t + 4000, content: [result('v1', numbered(SIGNUPS_CSV.trimEnd()))] },\n { role: 'assistant', at: t + 9000, content: [tool('v2', 'mcp__visualize__show_widget', { title: 'signups_by_day', loading_messages: ['Stacking the bars'], widget_code: signupsChart() })] },\n { role: 'user', at: t + 10000, content: [result('v2', 'Shown to the user.')] },\n { role: 'assistant', at: t + 16000, content: [tool('v3', 'Write', { file_path: `${cwd}/reports/signups-week-45.html`, content: REPORT_HTML })] },\n { role: 'user', at: t + 17000, content: [result('v3', `File created successfully at: ${cwd}/reports/signups-week-45.html`)] },\n {\n role: 'assistant',\n at: t + 21000,\n content: [text('Signups grew **18%** to 12,480. Thursday was the best day (2,214), the day the newsletter went out, and the weekend stayed above the weekday average.\\n\\nThe one-pager is in `reports/signups-week-45.html`: the three numbers that matter and the chart. Open it from the step above.')],\n },\n ];\n },\n },\n {\n id: 'e2f5d8a4-5555-4e5f-8071-000000000005',\n title: 'Turn this CSV into JSON',\n project: 'scratch',\n branch: '',\n scratch: true,\n rows: (cwd) => {\n const t = Date.now() - 29 * HOUR;\n return [\n { role: 'user', at: t, content: 'Turn contacts.csv into a JSON array, one object per row.' },\n { role: 'assistant', at: t + 6000, content: [tool('s1', 'Bash', { command: \"python3 -c \\\"import csv, json; print(json.dumps(list(csv.DictReader(open('contacts.csv'))), indent=2))\\\" > contacts.json && wc -l contacts.json\", description: 'Convert the CSV to JSON' })] },\n { role: 'user', at: t + 8000, content: [result('s1', ` 1203 ${cwd}/contacts.json`)] },\n { role: 'assistant', at: t + 10000, content: [text('Done: `contacts.json` has 200 objects, with the CSV header as keys.')] },\n ];\n },\n },\n];\n\nconst SETTINGS_TSX = `import { FontSizePicker } from './FontSizePicker';\nimport { Section } from './Section';\n\nexport function Settings() {\n return (\n <Section title=\"Display\">\n <FontSizePicker />\n </Section>\n );\n}\n`;\n\nconst TOGGLE_TSX = `type Theme = 'light' | 'dark';\n\n/** Switches the page between the light and dark color values in theme.css. */\nexport function ThemeToggle({ value, onChange }: { value: Theme; onChange: (theme: Theme) => void }) {\n return (\n <label className=\"row\">\n Dark theme\n <input type=\"checkbox\" checked={value === 'dark'} onChange={(e) => onChange(e.target.checked ? 'dark' : 'light')} />\n </label>\n );\n}\n`;\n\nconst DARK_CSS = `${THEME_CSS.replace(' --accent: #2563eb;\\n}', \" --accent: #2563eb;\\n}\\n\\n:root[data-theme='dark'] {\\n --bg: #0b0b0c;\\n --fg: #ededed;\\n --muted: #a1a1a1;\\n --accent: #60a5fa;\\n}\")}\\n`;\n\nconst FILE_TEXT: Record<string, string> = {\n 'acme-web/src/styles/theme.css': `${THEME_CSS}\\n`,\n 'acme-web/src/settings/Settings.tsx': SETTINGS_TSX,\n 'acme-web/README.md': '# acme-web\\n\\nThe Acme web app.\\n',\n 'data-pipeline/README.md': '# data-pipeline\\n\\nNightly exports and the numbers behind them.\\n',\n 'data-pipeline/data/signups.csv': SIGNUPS_CSV,\n 'data-pipeline/reports/signups-week-45.html': REPORT_HTML,\n 'docs-site/README.md': '# docs-site\\n\\nThe public docs.\\n',\n};\n\n/**\n * The first project is a git repository with Claude's work so far left\n * uncommitted, so the Changes panel has something to show. Skipped without git.\n */\nasync function demoRepository(dir: string): Promise<void> {\n const env = { ...process.env, GIT_AUTHOR_NAME: 'Demo', GIT_AUTHOR_EMAIL: 'demo@example.com', GIT_COMMITTER_NAME: 'Demo', GIT_COMMITTER_EMAIL: 'demo@example.com' };\n // Your own git setup (hooks, templates, signing) has no say in the demo's repository.\n const git = (args: string[]) => run('git', ['-c', 'commit.gpgsign=false', '-c', 'core.hooksPath=/dev/null', '-c', 'core.fsmonitor=false', '-c', 'init.templateDir=', ...args], { cwd: dir, env, timeout: 10_000 });\n try {\n await git(['init', '-q', '-b', 'feat/dark-theme']);\n await rm(path.join(dir, 'src/settings/ThemeToggle.tsx'), { force: true });\n await git(['add', '-A']);\n await git(['commit', '-q', '--no-verify', '-m', 'Settings page']);\n await writeFile(path.join(dir, 'src/styles/theme.css'), DARK_CSS);\n await writeFile(path.join(dir, 'src/settings/ThemeToggle.tsx'), TOGGLE_TSX);\n } catch {\n // No git here; the panel shows the files only.\n }\n}\n\nconst DEMO_FILES: Record<string, string[]> = {\n 'acme-web': ['README.md', 'package.json', 'src/app.tsx', 'src/settings/Settings.tsx', 'src/settings/ThemeToggle.tsx', 'src/styles/theme.css', 'tests/login.spec.ts'],\n 'data-pipeline': ['README.md', 'data/signups.csv', 'pipeline/export.py', 'pipeline/db.py', 'pipeline/writer.py', 'reports/signups-week-45.html', 'tests/test_export.py'],\n 'docs-site': ['README.md', 'docs/releases.md'],\n};\n\n/** Writes the demo home and points the config (and the Claude Agent SDK) at it. */\nexport async function prepareDemo(): Promise<void> {\n const root = path.join(config.stateDir, 'demo');\n await rm(root, { recursive: true, force: true });\n const claudeHome = path.join(root, '.claude');\n for (const [project, files] of Object.entries(DEMO_FILES)) {\n for (const file of files) {\n const full = path.join(root, 'code', project, file);\n await mkdir(path.dirname(full), { recursive: true });\n await writeFile(full, FILE_TEXT[`${project}/${file}`] ?? '');\n }\n }\n await demoRepository(path.join(root, 'code', 'acme-web'));\n for (const session of SESSIONS) {\n const cwd = session.scratch ? path.join(root, 'scratch', '2026-11-04-7c2e') : path.join(root, 'code', session.project);\n await mkdir(cwd, { recursive: true });\n const dir = path.join(claudeHome, 'projects', cwd.replace(/[^a-zA-Z0-9]/g, '-'));\n await mkdir(dir, { recursive: true });\n let parent: string | null = null;\n const lines: string[] = [JSON.stringify({ type: 'custom-title', customTitle: session.title, sessionId: session.id })];\n for (const row of session.rows(cwd)) {\n const uuid = randomUUID();\n const message = row.role === 'assistant'\n ? { id: `msg_demo_${uuid.slice(0, 8)}`, type: 'message', role: 'assistant', model: 'claude-opus-5-5', content: row.content }\n : { role: 'user', content: row.content };\n lines.push(JSON.stringify({\n parentUuid: parent, isSidechain: false, userType: 'external', cwd, sessionId: session.id, version: '2.1.318',\n gitBranch: session.branch, type: row.role, message, uuid, timestamp: new Date(row.at).toISOString(),\n }));\n parent = uuid;\n }\n await writeFile(path.join(dir, `${session.id}.jsonl`), `${lines.join('\\n')}\\n`);\n }\n config.home = root;\n config.claudeHome = claudeHome;\n // Its own config and state too: the demo never reads or writes your password, token or push keys.\n config.configDir = path.join(root, 'config');\n config.stateDir = path.join(root, 'state');\n process.env.CLAUDE_CONFIG_DIR = claudeHome;\n process.env.PELICAN_SCRATCH_DIR = path.join(root, 'scratch');\n}\n\nexport const DEMO_MODELS: ModelOption[] = [\n { value: 'default', label: 'Default (recommended)', description: 'Opus \u00B7 best for everyday, complex tasks', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: true, resolvedModel: 'claude-opus-5-5' },\n { value: 'opus', label: 'Opus', description: 'For complex work', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: true, resolvedModel: 'claude-opus-5-5' },\n { value: 'sonnet', label: 'Sonnet', description: 'Efficient for everyday tasks', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: false, resolvedModel: 'claude-sonnet-5-5' },\n { value: 'haiku', label: 'Haiku', description: 'Fastest for quick answers', efforts: [], supportsFast: false, resolvedModel: 'claude-haiku-5-5' },\n];\n\n/** The first demo session waits for an approval; another one is busy in Claude Desktop. */\nexport function demoRunState(sessionId: string): RunState | undefined {\n const first = SESSIONS[0]!;\n if (sessionId !== first.id) return undefined;\n const cwd = path.join(config.home, 'code', first.project);\n return {\n sessionId,\n cwd,\n busy: true,\n settings: { model: 'default', effort: 'high', permissionMode: 'default' },\n partial: [],\n permissions: [{\n id: 'demo-permission',\n sessionId,\n toolName: 'Edit',\n input: {\n file_path: `${cwd}/src/settings/Settings.tsx`,\n old_string: ' <FontSizePicker />\\n </Section>',\n new_string: ' <FontSizePicker />\\n <ThemeToggle value={theme} onChange={setTheme} />\\n </Section>',\n },\n canRemember: true,\n createdAt: Date.now() - 20_000,\n }],\n context: { percent: 31, tokens: 62_000, max: 200_000 },\n };\n}\n\nexport const DEMO_LIVE_SESSION = SESSIONS[1]!.id;\nexport const DEMO_WAITING_SESSION = SESSIONS[0]!.id;\n", "import type { ChatMessage } from './protocol';\n\nexport type Todo = { content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string };\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\nconst STATUSES = new Set(['pending', 'in_progress', 'completed']);\n\n/** The items of a TodoWrite call. */\nexport function todosOf(input: Record<string, unknown>): Todo[] {\n return Array.isArray(input.todos) ? (input.todos as Todo[]).filter((t) => t && typeof t.content === 'string') : [];\n}\n\n/**\n * Claude's task list as it stands after these messages. TodoWrite replaces\n * the whole list; TaskCreate adds one task and TaskUpdate changes one, by the\n * number Claude Code gave it (\"Task #3 created successfully\").\n */\nexport function currentTasks(messages: ChatMessage[]): Todo[] {\n const results = new Map<string, string>();\n for (const message of messages) {\n for (const block of message.blocks) {\n if (block.type !== 'tool_result') continue;\n const text = typeof block.content === 'string' ? block.content : block.content.map((c) => (c.type === 'text' ? c.text : '')).join('');\n results.set(block.tool_use_id, text);\n }\n }\n let tasks: Array<Todo & { id?: string }> = [];\n for (const message of messages) {\n if (message.role !== 'assistant' || message.parentToolUseId) continue;\n for (const block of message.blocks) {\n if (block.type !== 'tool_use') continue;\n const input = block.input;\n if (block.name === 'TodoWrite') {\n tasks = todosOf(input).map((t) => ({ ...t }));\n } else if (block.name === 'TaskCreate') {\n const id = results.get(block.id)?.match(/Task #(\\w+)/)?.[1] ?? String(tasks.length + 1);\n const activeForm = str(input.activeForm);\n tasks.push({ id, content: str(input.subject) ?? str(input.description) ?? 'Task', status: 'pending', ...(activeForm ? { activeForm } : {}) });\n } else if (block.name === 'TaskUpdate') {\n const task = tasks.find((t) => t.id !== undefined && t.id === String(input.taskId));\n if (!task) continue;\n const status = str(input.status);\n if (status === 'deleted') {\n tasks = tasks.filter((t) => t !== task);\n continue;\n }\n if (status && STATUSES.has(status)) task.status = status as Todo['status'];\n if (str(input.subject)) task.content = str(input.subject)!;\n if (str(input.activeForm)) task.activeForm = str(input.activeForm)!;\n }\n }\n }\n return tasks.map(({ id: _id, ...task }) => task);\n}\n", "import { randomUUID } from 'node:crypto';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * Sessions put away from the list. Only Pelican keeps this, in its state folder: the transcripts\n * are not touched, so every Claude Code app still has the session, and unarchiving is instant.\n */\nconst file = () => path.join(config.stateDir, 'archived.json');\nlet loaded: Promise<Set<string>> | undefined;\nlet writing: Promise<void> = Promise.resolve();\n\nasync function load(): Promise<Set<string>> {\n let text: string;\n try {\n text = await readFile(file(), 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return new Set();\n throw error;\n }\n try {\n const ids = (JSON.parse(text) as { ids?: unknown }).ids;\n return new Set(Array.isArray(ids) ? ids.filter((id): id is string => typeof id === 'string') : []);\n } catch {\n // Not ours to throw away: kept beside, and the list starts over.\n await rename(file(), `${file()}.bad-${Date.now()}`).catch(() => undefined);\n console.warn('[pelican] archived.json could not be read; it was set aside and the archive starts empty');\n return new Set();\n }\n}\n\nfunction archived(): Promise<Set<string>> {\n loaded ??= load().catch((error: Error) => {\n loaded = undefined;\n throw error;\n });\n return loaded;\n}\n\n/** The archived session ids, for the list. */\nexport async function archivedIds(): Promise<Set<string>> {\n return archived().catch(() => new Set<string>());\n}\n\n/** Archives or unarchives; writes go one at a time, each with the whole list as it is then. */\nexport async function setArchived(sessionId: string, on: boolean): Promise<void> {\n const ids = await archived();\n const before = ids.has(sessionId);\n if (on) ids.add(sessionId);\n else ids.delete(sessionId);\n const write = writing.then(async () => {\n await mkdir(path.dirname(file()), { recursive: true, mode: 0o700 });\n const temp = `${file()}.${randomUUID()}.tmp`;\n await writeFile(temp, `${JSON.stringify({ ids: [...ids] }, null, 2)}\\n`, { mode: 0o600 });\n await rename(temp, file());\n });\n writing = write.catch(() => undefined);\n try {\n await write;\n } catch (error) {\n if (before) ids.add(sessionId);\n else ids.delete(sessionId);\n throw error;\n }\n}\n", "import { randomBytes } from 'node:crypto';\nimport { realpathSync } from 'node:fs';\nimport { mkdir, stat } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\nconst realpath = (p: string) => {\n try {\n return realpathSync(p);\n } catch {\n return p;\n }\n};\n\n/** Where \"New scratch session\" makes its folders. */\nexport const scratchRoot = process.env.PELICAN_SCRATCH_DIR ?? path.join(config.home, 'scratch');\n\n/**\n * Folders nobody chose as a project: the system's temp directories (Claude\n * Code's per-session scratchpads live there, and so do the folders tools\n * make inside them), Claude Desktop's scratch workspaces, and our own scratch\n * folders. Sessions in them are real conversations, but the folders are not\n * places to start new work in.\n */\nconst tempRoots = [...new Set(['/tmp', '/private/tmp', '/var/folders', '/private/var/folders', os.tmpdir(), realpath(os.tmpdir())])]\n .map((p) => p.replace(/\\/+$/, ''));\nconst scratchRoots = [path.join(config.home, 'Library/Application Support/Claude/scratch-workspaces'), scratchRoot]\n .map((p) => p.replace(/\\/+$/, ''));\n\nconst under = (dir: string, roots: string[]) => {\n const p = dir.replace(/\\/+$/, '');\n return roots.some((root) => p === root || p.startsWith(`${root}/`));\n};\n\n/**\n * temp: inside the system's temp directory. Mostly runs another session\n * started (Claude Code's per-session scratchpads live there); the OS cleans\n * these folders up. scratch: a session you started without a project, in\n * Claude Desktop or here; a real conversation in a throwaway folder.\n */\nexport function folderKind(dir: string): 'project' | 'scratch' | 'temp' {\n // The demo's made-up home can itself be in a temp folder (the scripts that record it put it\n // there): its folders are what they pretend to be.\n if (config.demo && under(dir, [config.home.replace(/\\/+$/, '')])) return under(dir, scratchRoots) ? 'scratch' : 'project';\n if (under(dir, tempRoots)) return 'temp';\n if (under(dir, scratchRoots)) return 'scratch';\n return 'project';\n}\n\nexport function isScratchFolder(dir: string): boolean {\n return folderKind(dir) !== 'project';\n}\n\nexport async function isDirectory(dir: string): Promise<boolean> {\n return stat(dir).then((s) => s.isDirectory(), () => false);\n}\n\n/** A new empty folder like `~/scratch/2026-11-05-a1b2`, for a session that belongs to no project. */\nexport async function createScratchFolder(): Promise<string> {\n const now = new Date();\n const day = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;\n const dir = path.join(scratchRoot, `${day}-${randomBytes(2).toString('hex')}`);\n await mkdir(dir, { recursive: true });\n return dir;\n}\n", "import { execFile } from 'node:child_process';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { config } from './config.js';\nimport { DEMO_LIVE_SESSION } from './demo.js';\n\n/**\n * A Claude Code process outside this app with a session open: busy, or idle and holding the\n * conversation as it last saw it. `updatedAt` is when it last worked on it.\n */\nexport type LiveProcess = { app?: string; busy: boolean; updatedAt?: number };\n\nconst run = promisify(execFile);\n\ntype Proc = { ppid: number; comm: string };\n\n/** Every process's parent and name, in one `ps` (none when ps is not there). */\nasync function processes(): Promise<Map<number, Proc> | undefined> {\n try {\n const { stdout } = await run('ps', ['-A', '-o', 'pid=,ppid=,comm='], { timeout: 3000, maxBuffer: 8 * 1024 * 1024 });\n const map = new Map<number, Proc>();\n for (const line of stdout.split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(\\d+)\\s+(.*)$/.exec(line);\n if (match) map.set(Number(match[1]), { ppid: Number(match[2]), comm: match[3]!.trim() });\n }\n return map;\n } catch {\n return undefined;\n }\n}\n\n/** Started by this app, directly or through a wrapper. */\nfunction descends(pid: number, procs: Map<number, Proc>): boolean {\n for (let p = procs.get(pid)?.ppid, hops = 0; p && hops < 8; p = procs.get(p)?.ppid, hops += 1) {\n if (p === process.pid) return true;\n }\n return false;\n}\n\n/**\n * Claude Code's own clients, by the entrypoint they record. Any other program\n * that runs Claude Code is just \"elsewhere\": Pelican assumes nothing about it.\n */\nconst CLAUDE_CLIENTS: Record<string, string> = {\n 'claude-desktop': 'Claude Desktop',\n cli: 'the terminal',\n 'claude-vscode': 'VS Code',\n};\n\nlet cache: { at: number; byId: Map<string, LiveProcess> } | undefined;\n\nfunction alive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\n/**\n * Sessions other apps are running, from Claude Code's own registry: every\n * Claude Code process writes `~/.claude/sessions/<pid>.json` with its session\n * id, the app that started it and whether it is busy. This sees a turn that\n * is several minutes into a long command, which writes nothing to the\n * transcript meanwhile. Entries of exited processes are ignored.\n */\nexport async function liveProcesses(): Promise<Map<string, LiveProcess>> {\n if (config.demo) return new Map([[DEMO_LIVE_SESSION, { app: 'Claude Desktop', busy: true }]]);\n if (cache && Date.now() - cache.at < 1500) return cache.byId;\n const dir = path.join(config.claudeHome, 'sessions');\n const byId = new Map<string, LiveProcess>();\n let names: string[] = [];\n try {\n names = (await readdir(dir)).filter((n) => /^\\d+\\.json$/.test(n));\n } catch {\n // Older Claude Code, or none running.\n }\n type Entry = { pid?: number; sessionId?: string; status?: string; entrypoint?: string; updatedAt?: number; statusUpdatedAt?: number };\n const entries = (await Promise.all(names.map(async (name) => {\n try {\n const entry = JSON.parse(await readFile(path.join(dir, name), 'utf8')) as Entry;\n return entry.sessionId && typeof entry.pid === 'number' && entry.pid !== process.pid && alive(entry.pid) ? entry : undefined;\n } catch {\n return undefined; // Being rewritten; the next read gets it.\n }\n }))).filter((e): e is Entry & { pid: number; sessionId: string } => Boolean(e));\n // This app's own Claude processes descend from it; when that cannot be told, those of the SDK.\n // A pid now used by something that is not Claude Code is a registry entry left behind.\n const procs = await processes();\n for (const entry of entries) {\n const proc = procs?.get(entry.pid);\n if (procs && (!proc || !/claude|node|bun|disclaimer/i.test(proc.comm))) continue;\n const ours = procs ? descends(entry.pid, procs) : entry.entrypoint === 'sdk-ts';\n if (ours) continue;\n const busy = entry.status !== undefined && entry.status !== 'idle';\n const app = CLAUDE_CLIENTS[entry.entrypoint ?? ''];\n const known = byId.get(entry.sessionId);\n // When it last changed between working and idle: other writes to the registry are not work.\n const worked = typeof entry.statusUpdatedAt === 'number' ? entry.statusUpdatedAt : entry.updatedAt;\n const updatedAt = Math.max(known?.updatedAt ?? 0, typeof worked === 'number' ? worked : 0) || undefined;\n // A session open in two places: the busy one is what matters.\n const pick = !known || (busy && !known.busy) ? { ...(app ? { app } : {}), busy } : known;\n byId.set(entry.sessionId, { ...pick, ...(updatedAt ? { updatedAt } : {}) });\n }\n cache = { at: Date.now(), byId };\n return byId;\n}\n", "import type { Block, ChatMessage, ImageBlock, TextBlock } from '../shared/protocol.js';\n\nconst MAX_TEXT = 60_000;\nconst MAX_RESULT_TEXT = 24_000;\nconst MAX_IMAGE_BASE64 = 2_500_000;\n\ntype Raw = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Raw => typeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction clip(text: string, max: number): TextBlock {\n return text.length > max\n ? { type: 'text', text: `${text.slice(0, max)}\\n\u2026`, truncated: true }\n : { type: 'text', text };\n}\n\nfunction image(raw: Raw): ImageBlock | undefined {\n const source = raw.source;\n if (!isRecord(source)) return undefined;\n if (source.type === 'base64' && typeof source.data === 'string') {\n const mediaType = typeof source.media_type === 'string' ? source.media_type : 'image/png';\n return source.data.length > MAX_IMAGE_BASE64\n ? { type: 'image', source: { type: 'base64', media_type: mediaType, data: '' }, omitted: true }\n : { type: 'image', source: { type: 'base64', media_type: mediaType, data: source.data } };\n }\n if (source.type === 'url' && typeof source.url === 'string') return { type: 'image', source: { type: 'url', url: source.url } };\n return undefined;\n}\n\nfunction resultContent(content: unknown): { content: string | Array<TextBlock | ImageBlock>; truncated: boolean } {\n if (typeof content === 'string') {\n const clipped = clip(content, MAX_RESULT_TEXT);\n return { content: clipped.text, truncated: Boolean(clipped.truncated) };\n }\n if (!Array.isArray(content)) return { content: '', truncated: false };\n let truncated = false;\n const parts: Array<TextBlock | ImageBlock> = [];\n for (const part of content) {\n if (!isRecord(part)) continue;\n if (part.type === 'text' && typeof part.text === 'string') {\n const clipped = clip(part.text, MAX_RESULT_TEXT);\n truncated ||= Boolean(clipped.truncated);\n parts.push(clipped);\n } else if (part.type === 'image') {\n const img = image(part);\n if (img) parts.push(img);\n }\n }\n return { content: parts, truncated };\n}\n\nfunction blocks(content: unknown): Block[] {\n if (typeof content === 'string') return content ? [clip(content, MAX_TEXT)] : [];\n if (!Array.isArray(content)) return [];\n const out: Block[] = [];\n for (const raw of content) {\n if (!isRecord(raw)) continue;\n switch (raw.type) {\n case 'text':\n if (typeof raw.text === 'string' && raw.text) out.push(clip(raw.text, MAX_TEXT));\n break;\n case 'thinking':\n if (typeof raw.thinking === 'string' && raw.thinking.trim()) out.push({ type: 'thinking', thinking: raw.thinking });\n break;\n case 'tool_use':\n case 'server_tool_use':\n if (typeof raw.id === 'string' && typeof raw.name === 'string') {\n out.push({ type: 'tool_use', id: raw.id, name: raw.name, input: isRecord(raw.input) ? raw.input : {} });\n }\n break;\n case 'tool_result': {\n if (typeof raw.tool_use_id !== 'string') break;\n const { content: resultBody, truncated } = resultContent(raw.content);\n out.push({\n type: 'tool_result',\n tool_use_id: raw.tool_use_id,\n content: resultBody,\n ...(raw.is_error === true ? { is_error: true } : {}),\n ...(truncated ? { truncated: true } : {}),\n });\n break;\n }\n case 'web_search_tool_result':\n if (typeof raw.tool_use_id === 'string') {\n const results = Array.isArray(raw.content) ? raw.content.filter(isRecord) : [];\n const text = results.map((r) => `${String(r.title ?? '')} ${String(r.url ?? '')}`.trim()).join('\\n');\n out.push({ type: 'tool_result', tool_use_id: raw.tool_use_id, content: text });\n }\n break;\n case 'image': {\n const img = image(raw);\n if (img) out.push(img);\n break;\n }\n case 'document':\n out.push({ type: 'text', text: '[document]' });\n break;\n default:\n break;\n }\n }\n return out;\n}\n\n/**\n * Converts a transcript message (`getSessionMessages`) or a streamed SDK message\n * into the shape the app renders. Returns undefined for messages with nothing\n * to show.\n */\nexport function toChatMessage(raw: Raw): ChatMessage | undefined {\n const type = raw.type;\n if (type !== 'user' && type !== 'assistant') return undefined;\n if (typeof raw.uuid !== 'string') return undefined;\n const message = isRecord(raw.message) ? raw.message : {};\n const out: ChatMessage = {\n uuid: raw.uuid,\n role: type,\n blocks: blocks(message.content),\n };\n if (out.blocks.length === 0) return undefined;\n const timestamp = typeof raw.timestamp === 'string' ? Date.parse(raw.timestamp) : NaN;\n if (!Number.isNaN(timestamp)) out.timestamp = timestamp;\n const parent = raw.parent_tool_use_id;\n if (typeof parent === 'string') out.parentToolUseId = parent;\n if (type === 'assistant') {\n if (typeof message.model === 'string') out.model = message.model;\n if (typeof message.id === 'string') out.messageId = message.id;\n }\n // Text Claude Code adds itself (an image's scale note, skill text) is meta in the transcript\n // and synthetic in the live stream; either way it is not something you typed.\n if (raw.is_meta === true || raw.isMeta === true || raw.isSynthetic === true) out.meta = true;\n if (raw.isCompactSummary === true) out.compactSummary = true;\n return out;\n}\n", "import { open, stat } from 'node:fs/promises';\n\nimport type { ChatMessage, RecordedSettings } from '../shared/protocol.js';\nimport { toChatMessage } from './normalize.js';\n\n/**\n * A session's whole conversation, read from its transcript, across compactions.\n *\n * Each row of a transcript points at the one before it (`parentUuid`), so the\n * conversation is the chain from the newest message back to the first. A\n * compaction starts a new chain: its boundary row has no parent and points\n * back only through `logicalParentUuid`. Claude Code's own reader stops there,\n * which would leave everything before the last compaction out of reach; here\n * the walk carries on through every boundary. When a boundary points at a row\n * that was never written, the walk carries on from the last message the\n * compaction kept, or else from the row just before the boundary.\n *\n * The messages a compaction keeps verbatim stay where they were, before the\n * boundary; Claude Code's reader shows them again after the summary.\n *\n * A transcript only grows while its session runs, so it is read incrementally:\n * each read parses only the bytes added since the last one.\n */\n\ntype Node = {\n uuid: string;\n parent: string | undefined;\n /** On a compaction boundary: the last row before the compaction, and the last message it kept verbatim. */\n logicalParent: string | undefined;\n preservedTail: string | undefined;\n /** Position among the rows that have a uuid, in file order. */\n index: number;\n /** What the app shows for this row; rows like attachments only link the chain. */\n message: ChatMessage | undefined;\n};\n\ntype Transcript = {\n /** The settings the session last ran with, in file order. */\n recorded: RecordedSettings;\n ino: number;\n /** Bytes parsed so far, and the start of a line not finished yet. */\n offset: number;\n carry: Buffer;\n nodes: Map<string, Node>;\n order: Node[];\n /** The newest user or assistant row: where the conversation ends. */\n leaf: Node | undefined;\n /** The last walk, reused when the conversation only grew. */\n chain: Node[];\n chainIndex: Map<string, number>;\n chainLeaf: string | undefined;\n messages: ChatMessage[];\n};\n\nconst CHUNK = 8 * 1024 * 1024;\nconst MAX_FILES = 16;\nconst transcripts = new Map<string, Transcript>();\nconst locks = new Map<string, Promise<unknown>>();\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\n\nfunction empty(ino: number): Transcript {\n return {\n recorded: {}, ino, offset: 0, carry: Buffer.alloc(0), nodes: new Map(), order: [], leaf: undefined,\n chain: [], chainIndex: new Map(), chainLeaf: undefined, messages: [],\n };\n}\n\nconst MODES = new Set(['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions']);\n\n/** Keeps the settings a row shows the session ran with: the latest row wins. */\nfunction note(recorded: RecordedSettings, row: Record<string, unknown>): void {\n if (row.type === 'assistant') {\n const model = str(row.requestedModel) ?? str((row.message as { model?: unknown } | undefined)?.model);\n if (model && !model.startsWith('<')) recorded.model = model;\n if (str(row.effort)) recorded.effort = str(row.effort);\n const speed = str((row.message as { usage?: { speed?: unknown } } | undefined)?.usage?.speed);\n if (speed) recorded.fast = speed === 'fast';\n recorded.ultracode ??= false;\n } else if (row.type === 'user' && str(row.permissionMode) && MODES.has(str(row.permissionMode)!)) {\n recorded.permissionMode = str(row.permissionMode) as RecordedSettings['permissionMode'];\n } else if (row.type === 'attachment') {\n const kind = str((row.attachment as { type?: unknown } | undefined)?.type) ?? '';\n // Claude Code notes ultracode turning on (and off) as attachments.\n if (kind === 'ultra_effort_enter') recorded.ultracode = true;\n else if (/^ultra_effort_(exit|leave|off)/.test(kind)) recorded.ultracode = false;\n }\n}\n\n/**\n * A message the user sent while Claude was working, which Claude read at its\n * next step: Claude Code records it as a `queued_command` attachment where it\n * was taken in, not as a user row.\n */\nfunction steeredMessage(row: Record<string, unknown>, uuid: string): ChatMessage | undefined {\n const attachment = row.attachment as { type?: string; prompt?: unknown; source_uuid?: unknown; commandMode?: unknown } | undefined;\n if (row.type !== 'attachment' || attachment?.type !== 'queued_command') return undefined;\n if (attachment.commandMode !== undefined && attachment.commandMode !== 'prompt') return undefined;\n const message = toChatMessage({ type: 'user', uuid, timestamp: row.timestamp, message: { role: 'user', content: attachment.prompt } });\n if (!message) return undefined;\n const source = str(attachment.source_uuid);\n return { ...message, steered: true, ...(source ? { sourceUuid: source } : {}) };\n}\n\nfunction addLine(t: Transcript, line: string): void {\n // Rows that take part in the conversation carry a uuid; skip the rest (titles, costs, requests) unparsed.\n if (line.length < 2 || line.charCodeAt(0) !== 123 || !line.includes('\"uuid\"')) return;\n let row: Record<string, unknown>;\n try {\n row = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return;\n }\n const uuid = str(row.uuid);\n if (!uuid || row.isSidechain === true) return;\n note(t.recorded, row);\n const turn = row.type === 'user' || row.type === 'assistant';\n const message = turn ? toChatMessage(row) : steeredMessage(row, uuid);\n const existing = t.nodes.get(uuid);\n if (existing) {\n existing.message = message;\n return;\n }\n const metadata = row.compactMetadata as { preservedSegment?: { tailUuid?: unknown } } | undefined;\n const node: Node = {\n uuid,\n parent: str(row.parentUuid),\n logicalParent: str(row.logicalParentUuid),\n preservedTail: str(metadata?.preservedSegment?.tailUuid),\n index: t.order.length,\n message,\n };\n t.nodes.set(uuid, node);\n t.order.push(node);\n if (turn) t.leaf = node;\n}\n\nasync function readNew(file: string, t: Transcript, size: number): Promise<void> {\n const handle = await open(file, 'r');\n try {\n let position = t.offset;\n while (position < size) {\n const buffer = Buffer.allocUnsafe(Math.min(CHUNK, size - position));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n if (bytesRead <= 0) break;\n position += bytesRead;\n const data = t.carry.length > 0 ? Buffer.concat([t.carry, buffer.subarray(0, bytesRead)]) : buffer.subarray(0, bytesRead);\n const lastBreak = data.lastIndexOf(0x0a);\n if (lastBreak < 0) {\n t.carry = Buffer.from(data);\n continue;\n }\n t.carry = Buffer.from(data.subarray(lastBreak + 1));\n for (const line of data.subarray(0, lastBreak).toString('utf8').split('\\n')) addLine(t, line);\n }\n t.offset = position;\n // A last row without its newline yet: use it if it is whole; it is read again with the rest later.\n if (t.carry.length > 0) addLine(t, t.carry.toString('utf8'));\n } finally {\n await handle.close();\n }\n}\n\n/**\n * The row a compaction boundary continues from. Its logical parent when that\n * was written; otherwise the last message the compaction kept, or the row\n * just before the boundary in the file.\n */\nfunction before(t: Transcript, boundary: Node): Node | undefined {\n return t.nodes.get(boundary.logicalParent!)\n ?? (boundary.preservedTail ? t.nodes.get(boundary.preservedTail) : undefined)\n ?? (boundary.index > 0 ? t.order[boundary.index - 1] : undefined);\n}\n\n/** The chain from `from` back to the start, oldest first; stops early where it meets `known`. */\nfunction walk(t: Transcript, from: Node, known?: Map<string, number>): { nodes: Node[]; joinedAt: number } {\n const out: Node[] = [];\n const seen = new Set<string>();\n let node: Node | undefined = from;\n while (node && !seen.has(node.uuid)) {\n const at = known?.get(node.uuid);\n if (at !== undefined) return { nodes: out.reverse(), joinedAt: at };\n seen.add(node.uuid);\n out.push(node);\n if (node.parent) node = t.nodes.get(node.parent);\n else if (node.logicalParent) node = before(t, node);\n else node = undefined;\n }\n return { nodes: out.reverse(), joinedAt: -1 };\n}\n\nfunction conversation(t: Transcript): ChatMessage[] {\n const leaf = t.leaf;\n if (!leaf) return [];\n if (t.chainLeaf === leaf.uuid) return t.messages;\n const { nodes, joinedAt } = walk(t, leaf, t.chainIndex);\n t.chain = joinedAt >= 0 ? t.chain.slice(0, joinedAt + 1).concat(nodes) : nodes;\n t.chainIndex = new Map(t.chain.map((n, i) => [n.uuid, i]));\n t.chainLeaf = leaf.uuid;\n t.messages = t.chain.flatMap((n) => (n.message ? [n.message] : []));\n return t.messages;\n}\n\nasync function read(file: string): Promise<ChatMessage[]> {\n let info;\n try {\n info = await stat(file);\n } catch {\n transcripts.delete(file);\n return [];\n }\n let t = transcripts.get(file);\n // Replaced or cut short: start over.\n if (!t || t.ino !== info.ino || info.size < t.offset) t = empty(info.ino);\n transcripts.delete(file);\n transcripts.set(file, t);\n while (transcripts.size > MAX_FILES) transcripts.delete(transcripts.keys().next().value!);\n if (info.size > t.offset) await readNew(file, t, info.size);\n return conversation(t);\n}\n\n/** What the session in a transcript file last ran with. */\nexport async function readRecordedSettings(file: string): Promise<RecordedSettings> {\n await readHistory(file);\n return { ...(transcripts.get(file)?.recorded ?? {}) };\n}\n\n/** The conversation in a transcript file, oldest message first. */\nexport function readHistory(file: string): Promise<ChatMessage[]> {\n // One read per file at a time: reads build on each other's state.\n const previous = locks.get(file) ?? Promise.resolve();\n const next = previous.catch(() => undefined).then(() => read(file));\n locks.set(file, next);\n void next.finally(() => {\n if (locks.get(file) === next) locks.delete(file);\n }).catch(() => undefined);\n return next;\n}\n", "import { createReadStream } from 'node:fs';\nimport { open, readdir, stat } from 'node:fs/promises';\nimport readline from 'node:readline';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\nconst projectsDir = () => path.join(config.claudeHome, 'projects');\n\nlet index = new Map<string, string>();\nlet indexBuiltAt = 0;\n\n/** Rebuilds the sessionId \u2192 transcript path index from `~/.claude/projects/<dir>/<id>.jsonl`. */\nasync function rebuildIndex(): Promise<void> {\n const next = new Map<string, string>();\n let dirs: string[] = [];\n try {\n dirs = await readdir(projectsDir());\n } catch {\n // No projects yet.\n }\n await Promise.all(dirs.map(async (dir) => {\n try {\n for (const name of await readdir(path.join(projectsDir(), dir))) {\n if (name.endsWith('.jsonl')) next.set(name.slice(0, -'.jsonl'.length), path.join(projectsDir(), dir, name));\n }\n } catch {\n // Not a directory, or removed meanwhile.\n }\n }));\n index = next;\n indexBuiltAt = Date.now();\n}\n\n/** Path of a session's transcript, or undefined when it does not exist (yet). */\nexport async function transcriptPath(sessionId: string): Promise<string | undefined> {\n if (!index.has(sessionId) && Date.now() - indexBuiltAt > 1000) await rebuildIndex();\n return index.get(sessionId);\n}\n\nexport async function refreshTranscriptIndex(): Promise<void> {\n await rebuildIndex();\n}\n\nconst CHUNK = 256 * 1024;\nconst MAX_SCAN = 16 * 1024 * 1024;\n\n/** Text blocks of an assistant row, as one line for a session-list preview. */\nfunction replyText(row: { message?: { content?: unknown } }): string | undefined {\n const content = row.message?.content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((b): b is { type: string; text: string } => b?.type === 'text' && typeof b.text === 'string')\n .map((b) => b.text)\n .join(' ')\n .replace(/[`*_#>|]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n return text ? text.slice(0, 160) : undefined;\n}\n\n/**\n * The last user or assistant row, read backwards from the end: its time, the\n * folder and branch it ran in, and the text of Claude's latest reply.\n *\n * Claude Desktop appends metadata rows (titles, cost state) and queued\n * notifications to idle sessions, which moves the file's mtime although\n * nothing was said; only turns count as activity.\n */\nexport type LastTurn = {\n time: number; cwd?: string; gitBranch?: string; preview?: string;\n /** The row was copied from another session by a fork (it carries `forkedFrom`): nothing ran here then. */\n copied?: boolean;\n};\n\n/** After the last turn, how far back to look for a reply with text (tool calls in between). */\nconst PREVIEW_SCAN = 4 * 1024 * 1024;\n\nexport async function readLastTurn(file: string): Promise<LastTurn | undefined> {\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n let found: LastTurn | undefined;\n let foundAt = 0;\n try {\n handle = await open(file, 'r');\n const { size } = await handle.stat();\n let end = size;\n let carry = Buffer.alloc(0);\n while (end > 0 && size - end < MAX_SCAN && !(found && foundAt - end > PREVIEW_SCAN)) {\n const start = Math.max(0, end - CHUNK);\n const chunk = Buffer.alloc(end - start);\n await handle.read(chunk, 0, chunk.length, start);\n let data = Buffer.concat([chunk, carry]);\n end = start;\n if (start > 0) {\n const firstBreak = data.indexOf(0x0a);\n if (firstBreak < 0) {\n carry = data;\n continue;\n }\n carry = data.subarray(0, firstBreak);\n data = data.subarray(firstBreak + 1);\n }\n const lines = data.toString('utf8').split('\\n');\n for (let i = lines.length - 1; i >= 0; i -= 1) {\n const line = lines[i]!;\n if (!line.includes('\"timestamp\"') || !(line.includes('\"type\":\"user\"') || line.includes('\"type\":\"assistant\"'))) continue;\n // Past the last turn, only rows with text matter: a reply, or the prompt that started the turn.\n if (found && !line.includes('\"type\":\"text\"') && !line.includes('\"content\":\"')) continue;\n try {\n const row = JSON.parse(line) as {\n type?: string; timestamp?: string; isSidechain?: boolean; cwd?: unknown; gitBranch?: unknown; message?: { content?: unknown }; forkedFrom?: unknown;\n };\n if ((row.type !== 'user' && row.type !== 'assistant') || row.isSidechain || typeof row.timestamp !== 'string') continue;\n if (!found) {\n const time = Date.parse(row.timestamp);\n if (Number.isNaN(time)) continue;\n found = {\n time,\n ...(typeof row.cwd === 'string' ? { cwd: row.cwd } : {}),\n ...(typeof row.gitBranch === 'string' ? { gitBranch: row.gitBranch } : {}),\n ...(row.forkedFrom ? { copied: true } : {}),\n };\n foundAt = end;\n }\n if (row.type === 'assistant') {\n const preview = replyText(row);\n if (preview) return { ...found, preview };\n } else if (found && row.type === 'user' && typeof (row.message as { content?: unknown })?.content === 'string') {\n // Reached the prompt before any reply text: the turn has said nothing yet.\n return found;\n }\n } catch {\n // A row can be half-written while Claude is streaming into the file.\n }\n }\n }\n } catch {\n // Missing or unreadable.\n } finally {\n await handle?.close();\n }\n return found;\n}\n\nconst lastTurnCache = new Map<string, { size: number; mtimeMs: number; value: LastTurn | undefined }>();\n\n/**\n * `readLastTurn`, cached by file size and mtime. The row also gives the\n * session's folder and branch, which the SDK misses when Desktop has put\n * metadata rows at the head of the file.\n */\nexport async function lastTurnTime(file: string): Promise<{ lastTurn?: LastTurn; mtimeMs: number; size: number } | undefined> {\n let info;\n try {\n info = await stat(file);\n } catch {\n return undefined;\n }\n const cached = lastTurnCache.get(file);\n if (cached && cached.size === info.size && cached.mtimeMs === info.mtimeMs) {\n return { lastTurn: cached.value, mtimeMs: info.mtimeMs, size: info.size };\n }\n const value = await readLastTurn(file);\n lastTurnCache.set(file, { size: info.size, mtimeMs: info.mtimeMs, value });\n return { lastTurn: value, mtimeMs: info.mtimeMs, size: info.size };\n}\n\nconst HEAD_SCAN = 64 * 1024 * 1024;\nconst headCache = new Map<string, string | null>();\n\n/**\n * The session id on the first prompt or reply of a transcript. It is the file's own id, except\n * in a copy of another session: Claude Desktop's side chats start with the whole conversation\n * they came from, rows and ids unchanged. A file only grows at its end, so an answer is kept;\n * a file that holds no turn yet is asked again next time.\n */\nexport async function firstTurnSession(file: string): Promise<string | undefined> {\n const cached = headCache.get(file);\n if (cached !== undefined) return cached ?? undefined;\n let found: string | undefined;\n let read = 0;\n try {\n const input = createReadStream(file);\n const lines = readline.createInterface({ input, crlfDelay: Infinity });\n try {\n for await (const line of lines) {\n read += line.length + 1;\n if (read > HEAD_SCAN) break;\n if (!line.includes('\"sessionId\"') || !(line.includes('\"type\":\"user\"') || line.includes('\"type\":\"assistant\"'))) continue;\n try {\n const row = JSON.parse(line) as { type?: string; sessionId?: unknown; isSidechain?: boolean };\n if ((row.type === 'user' || row.type === 'assistant') && !row.isSidechain && typeof row.sessionId === 'string') {\n found = row.sessionId;\n break;\n }\n } catch {\n // A row being written.\n }\n }\n } finally {\n lines.close();\n input.destroy();\n }\n } catch {\n return undefined; // Missing or unreadable.\n }\n if (found) {\n if (headCache.size > 10_000) headCache.clear();\n headCache.set(file, found);\n }\n return found;\n}\n\n/** An image of a prompt as the transcript holds it, in full (the message list leaves big ones out). */\nexport type RawImage = { type: 'base64'; mediaType: string; data: string } | { type: 'url' };\n\n/** One row of a transcript, as written: what it follows in the chain, and its content. */\nexport type RawEntry = { parentUuid: string | null; content: unknown };\n\n/** The transcript row with this uuid, read from the file itself. */\nexport async function rawEntry(file: string, uuid: string): Promise<RawEntry | undefined> {\n const needle = `\"uuid\":\"${uuid}\"`;\n const input = createReadStream(file);\n const lines = readline.createInterface({ input, crlfDelay: Infinity });\n try {\n for await (const line of lines) {\n if (!line.includes(needle)) continue;\n let row: { uuid?: unknown; parentUuid?: unknown; type?: unknown; message?: { content?: unknown }; attachment?: { type?: unknown; prompt?: unknown } };\n try {\n row = JSON.parse(line) as typeof row;\n } catch {\n continue;\n }\n if (row.uuid !== uuid) continue;\n // A message sent while Claude worked is an attachment row; its prompt is the content.\n const content = row.type === 'attachment' && row.attachment?.type === 'queued_command' ? row.attachment.prompt : row.message?.content;\n return { parentUuid: typeof row.parentUuid === 'string' ? row.parentUuid : null, content };\n }\n } catch {\n return undefined;\n } finally {\n lines.close();\n input.destroy();\n }\n return undefined;\n}\n\n/**\n * The images of one message, in the order and by the rules the message list uses (base64 and\n * url images; anything else is not an image there), read from the transcript row itself.\n */\nexport async function rawImages(file: string, uuid: string): Promise<RawImage[]> {\n const content = (await rawEntry(file, uuid))?.content;\n if (!Array.isArray(content)) return [];\n const images: RawImage[] = [];\n for (const block of content as Array<{ type?: unknown; source?: { type?: unknown; data?: unknown; media_type?: unknown; url?: unknown } }>) {\n if (block?.type !== 'image' || !block.source) continue;\n if (block.source.type === 'base64' && typeof block.source.data === 'string') {\n images.push({ type: 'base64', mediaType: typeof block.source.media_type === 'string' ? block.source.media_type : 'image/png', data: block.source.data });\n } else if (block.source.type === 'url' && typeof block.source.url === 'string') {\n images.push({ type: 'url' });\n }\n }\n return images;\n}\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { getSessionInfo, getSubagentMessages, listSessions, renameSession } from '@anthropic-ai/claude-agent-sdk';\nimport type { SDKSessionInfo } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { ChatMessage, MessagesPage, RecordedSettings, SessionStatus, SessionSummary } from '../shared/protocol.js';\nimport { archivedIds } from './archive.js';\nimport { config } from './config.js';\nimport { folderKind } from './folders.js';\nimport { type LiveProcess, liveProcesses } from './live.js';\nimport { readHistory, readRecordedSettings } from './history.js';\nimport { toChatMessage } from './normalize.js';\nimport { firstTurnSession, lastTurnTime, transcriptPath } from './transcripts.js';\n\nexport type StatusSource = (sessionId: string) => SessionStatus | undefined;\n\nconst infoCache = new Map<string, SDKSessionInfo>();\n\nfunction titleOf(info: SDKSessionInfo): string {\n const title = info.customTitle || info.summary || info.firstPrompt || '';\n return title.replace(/\\s+/g, ' ').trim() || 'Untitled session';\n}\n\nasync function summarize(info: SDKSessionInfo, status: StatusSource, live: Map<string, LiveProcess>, archived: Set<string>): Promise<SessionSummary> {\n const file = await transcriptPath(info.sessionId);\n const times = file ? await lastTurnTime(file) : undefined;\n const lastTurn = times?.lastTurn;\n const lastActivity = lastTurn?.time ?? info.lastModified;\n const own = status(info.sessionId);\n let state: SessionStatus = own ?? 'idle';\n // Another app's Claude process says it is busy; failing that, a turn written moments ago\n // (not one a fork just copied over: a new branch is idle until someone sends to it).\n const other = live.get(info.sessionId);\n const elsewhere = own ? undefined : other;\n const recent = lastTurn && !lastTurn.copied && Date.now() - lastTurn.time < config.liveWindowMs;\n if (!own && (elsewhere?.busy || recent)) state = 'live';\n // Idle here but working in another app: that is what the session is doing.\n else if (own === 'idle' && other?.busy) state = 'live';\n const cwd = info.cwd || lastTurn?.cwd || '';\n if (!info.cwd && cwd) infoCache.set(info.sessionId, { ...info, cwd });\n const gitBranch = lastTurn?.gitBranch ?? info.gitBranch;\n const title = titleOf(info);\n // Claude Desktop's side chats: a copy of a conversation with a question or two of its own.\n const copiedFrom = file && title === 'Side chat' ? await firstTurnSession(file) : undefined;\n const sideChatOf = copiedFrom && copiedFrom !== info.sessionId ? copiedFrom : undefined;\n return {\n id: info.sessionId,\n title,\n cwd,\n project: cwd ? path.basename(cwd) : '',\n ...(gitBranch && gitBranch !== 'HEAD' ? { gitBranch } : {}),\n lastActivity,\n ...(info.createdAt ? { createdAt: info.createdAt } : {}),\n status: state,\n ...(info.fileSize ? { sizeBytes: info.fileSize } : {}),\n ...(cwd && folderKind(cwd) === 'scratch' ? { scratch: true } : {}),\n ...(cwd && folderKind(cwd) === 'temp' ? { temp: true } : {}),\n ...(state === 'live' && other?.busy && other.app ? { runningIn: other.app } : {}),\n ...(lastTurn?.preview ? { preview: lastTurn.preview } : {}),\n ...(sideChatOf ? { sideChatOf } : {}),\n ...(archived.has(info.sessionId) ? { archived: true } : {}),\n // Open, idle, in another app too: its Claude does not see what is sent here until it reopens.\n ...(other && !other.busy ? { openIn: other.app ?? 'another app' } : {}),\n };\n}\n\n/** Every session on this machine, newest activity first. */\nexport async function listSummaries(status: StatusSource): Promise<SessionSummary[]> {\n const infos = await listSessions({ includeProgrammatic: true });\n for (const info of infos) infoCache.set(info.sessionId, info);\n const [live, archived] = await Promise.all([liveProcesses(), archivedIds()]);\n const summaries = await Promise.all(infos.map((info) => summarize(info, status, live, archived)));\n return summaries.sort((a, b) => b.lastActivity - a.lastActivity);\n}\n\nexport async function sessionInfo(sessionId: string): Promise<SDKSessionInfo | undefined> {\n // Without a project dir, `getSessionInfo` leaves `cwd` out; the list has it.\n if (!infoCache.has(sessionId)) {\n for (const info of await listSessions({ includeProgrammatic: true }).catch(() => [])) infoCache.set(info.sessionId, info);\n }\n const cached = infoCache.get(sessionId);\n const info = await getSessionInfo(sessionId, cached?.cwd ? { dir: cached.cwd } : {}).catch(() => undefined);\n if (!info) return cached;\n let cwd = info.cwd || cached?.cwd;\n if (!cwd) {\n const file = await transcriptPath(sessionId);\n cwd = file ? (await lastTurnTime(file))?.lastTurn?.cwd : undefined;\n }\n const merged = { ...cached, ...info, ...(cwd ? { cwd } : {}) };\n infoCache.set(sessionId, merged);\n return merged;\n}\n\nexport async function sessionSummary(sessionId: string, status: StatusSource): Promise<SessionSummary | undefined> {\n const info = await sessionInfo(sessionId);\n return info ? summarize(info, status, await liveProcesses(), await archivedIds()) : undefined;\n}\n\nexport async function renameSessionTitle(sessionId: string, title: string): Promise<void> {\n const dir = infoCache.get(sessionId)?.cwd;\n await renameSession(sessionId, title, dir ? { dir } : {});\n infoCache.delete(sessionId);\n}\n\n/** What the session last ran with, from its transcript; empty for a session not written yet. */\nexport async function recordedSettings(sessionId: string): Promise<RecordedSettings> {\n const file = await transcriptPath(sessionId);\n return file ? readRecordedSettings(file) : {};\n}\n\n/** The whole conversation, oldest first, including what came before each compaction. */\nexport async function loadMessages(sessionId: string): Promise<ChatMessage[]> {\n const file = await transcriptPath(sessionId);\n return file ? readHistory(file) : [];\n}\n\n/**\n * Files Claude handed to the user in a session (SendUserFile, Artifact): the\n * only files outside the session's folder the app may show, and only these paths.\n */\nexport async function sentFiles(sessionId: string): Promise<Set<string>> {\n const paths = new Set<string>();\n for (const message of await loadMessages(sessionId)) {\n if (message.role !== 'assistant') continue;\n for (const block of message.blocks) {\n if (block.type !== 'tool_use') continue;\n if (block.name === 'SendUserFile' && Array.isArray(block.input.files)) {\n for (const file of block.input.files) if (typeof file === 'string') paths.add(file);\n } else if (block.name === 'Artifact' && typeof block.input.file_path === 'string') {\n paths.add(block.input.file_path);\n }\n }\n }\n return paths;\n}\n\n/** What a subagent did inside an Agent call: its own transcript, next to the session's. */\nexport async function loadSubagent(sessionId: string, agentId: string): Promise<ChatMessage[]> {\n if (!/^[\\w-]{1,80}$/.test(agentId)) return [];\n const dir = infoCache.get(sessionId)?.cwd;\n const raw = await getSubagentMessages(sessionId, agentId, dir ? { dir } : {}).catch(() => []);\n return raw\n .map((message) => toChatMessage(message as unknown as Record<string, unknown>))\n .filter((message): message is ChatMessage => Boolean(message));\n}\n\n/** A page of messages ending before index `before` (default: the end). */\nexport async function loadPage(sessionId: string, before: number | undefined, limit: number): Promise<MessagesPage> {\n const all = await loadMessages(sessionId);\n const end = Math.min(before ?? all.length, all.length);\n const offset = Math.max(0, end - limit);\n return { messages: all.slice(offset, end), total: all.length, offset };\n}\n", "import { deleteSession, forkSession } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { ChatMessage } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { loadMessages, sessionInfo } from './sessions.js';\nimport { refreshTranscriptIndex } from './transcripts.js';\n\n/**\n * A copy of the session to carry on separately. With `upTo`, the copy ends at\n * that message, which is how \"edit and resend\" works: the conversation\n * branches before the prompt you change, and the original stays as it was.\n */\nexport async function fork(sessionId: string, upTo?: string, title?: string): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing changes.');\n const info = await sessionInfo(sessionId);\n const result = await forkSession(sessionId, {\n ...(info?.cwd ? { dir: info.cwd } : {}),\n ...(upTo ? { upToMessageId: upTo } : {}),\n ...(title ? { title } : {}),\n });\n await refreshTranscriptIndex();\n return result.sessionId;\n}\n\n/**\n * Where a branch that rewrites the message `uuid` starts: the message just\n * before it, or null when `uuid` is the first one (the branch is then a new\n * session in the same folder). Undefined when the message is not there.\n */\nexport async function messageBefore(sessionId: string, uuid: string): Promise<string | null | undefined> {\n const messages = await loadMessages(sessionId);\n const at = messages.findIndex((m) => m.uuid === uuid);\n if (at < 0) return undefined;\n return at === 0 ? null : messages[at - 1]!.uuid;\n}\n\nexport async function remove(sessionId: string): Promise<void> {\n if (config.demo) throw new Error('This is the demo: nothing changes.');\n const info = await sessionInfo(sessionId);\n await deleteSession(sessionId, info?.cwd ? { dir: info.cwd } : {});\n await refreshTranscriptIndex();\n}\n\nconst toolLine = (name: string, input: Record<string, unknown>) => {\n const target = ['file_path', 'command', 'pattern', 'url', 'query', 'description'].map((k) => input[k]).find((v) => typeof v === 'string');\n return `- ${name}${target ? `: \\`${String(target).split('\\n')[0]}\\`` : ''}`;\n};\n\n/** The conversation as Markdown: prompts and replies in full, tool calls as one line each. */\nexport async function exportMarkdown(sessionId: string): Promise<{ title: string; markdown: string }> {\n const info = await sessionInfo(sessionId);\n const title = info?.customTitle || info?.summary || 'Claude Code session';\n const messages: ChatMessage[] = await loadMessages(sessionId);\n const out: string[] = [`# ${title}`, ''];\n if (info?.cwd) out.push(`Folder: \\`${info.cwd}\\``, '');\n let speaker: string | undefined;\n for (const message of messages) {\n if (message.meta || message.parentToolUseId) continue;\n const parts: string[] = [];\n const tools: string[] = [];\n for (const block of message.blocks) {\n if (block.type === 'text' && block.text.trim()) parts.push(block.text.trim());\n else if (block.type === 'tool_use') tools.push(toolLine(block.name, block.input));\n }\n if (parts.length === 0 && tools.length === 0) continue;\n const who = message.role === 'user' ? 'You' : 'Claude';\n if (who !== speaker) {\n out.push(`## ${who}`, '');\n speaker = who;\n }\n if (tools.length > 0) out.push(...tools, '');\n if (parts.length > 0) out.push(parts.join('\\n\\n'), '');\n }\n return { title, markdown: `${out.join('\\n').trim()}\\n` };\n}\n", "import { stat } from 'node:fs/promises';\n\nimport type { ChatMessage, ServerEvent } from '../shared/protocol.js';\nimport { loadMessages } from './sessions.js';\nimport { transcriptPath } from './transcripts.js';\n\nexport type Listener = (event: ServerEvent) => void;\n\nconst POLL_MS = 1000;\n\n/**\n * Delivers one session's messages to the clients viewing it.\n *\n * Messages come from two places: the stream of a turn this app runs, and the\n * transcript file, which other clients (Desktop, the terminal) also write.\n * Both carry the same ids, so each message is delivered once. The file is\n * polled while anyone is watching; a stat per second is cheap and works the\n * same on macOS and Linux, unlike file watchers across atomic rewrites.\n */\nclass Feed {\n readonly listeners = new Set<Listener>();\n private delivered = new Set<string>();\n /** Recently published messages, replayed to a client that subscribes late (a new session's first prompt). */\n private recent: ChatMessage[] = [];\n /** Ids last read from the file; one that disappears means the conversation was rewound. */\n private fromFile = new Set<string>();\n private primed?: Promise<void>;\n private size = -1;\n private mtimeMs = -1;\n private timer?: NodeJS.Timeout;\n private checking = false;\n\n constructor(readonly sessionId: string) {}\n\n private async prime(): Promise<void> {\n this.primed ??= (async () => {\n const file = await transcriptPath(this.sessionId);\n if (file) {\n const info = await stat(file).catch(() => undefined);\n if (info) {\n this.size = info.size;\n this.mtimeMs = info.mtimeMs;\n }\n }\n for (const message of await loadMessages(this.sessionId)) {\n this.delivered.add(message.uuid);\n this.fromFile.add(message.uuid);\n }\n })();\n return this.primed;\n }\n\n broadcast(event: ServerEvent): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // A closed socket; its unsubscribe follows.\n }\n }\n }\n\n /** Publishes still on their way (priming reads the transcript first). */\n publishing = 0;\n\n async publish(message: ChatMessage): Promise<void> {\n this.publishing += 1;\n try {\n await this.prime();\n if (this.delivered.has(message.uuid)) return;\n this.delivered.add(message.uuid);\n this.recent.push(message);\n if (this.recent.length > 40) this.recent.shift();\n this.broadcast({ type: 'message', sessionId: this.sessionId, message });\n } finally {\n this.publishing -= 1;\n }\n }\n\n get hasRecent(): boolean {\n return this.recent.length > 0;\n }\n\n replayRecent(listener: Listener): void {\n for (const message of this.recent) listener({ type: 'message', sessionId: this.sessionId, message });\n }\n\n watch(): void {\n if (this.timer) return;\n void this.prime();\n this.timer = setInterval(() => {\n void this.check().then((changed) => {\n if (changed) sessionsChanged();\n });\n }, POLL_MS);\n }\n\n unwatch(): void {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n\n get watching(): boolean {\n return Boolean(this.timer);\n }\n\n async check(): Promise<boolean> {\n if (this.checking) return false;\n this.checking = true;\n try {\n await this.prime();\n const file = await transcriptPath(this.sessionId);\n if (!file) return false;\n const info = await stat(file).catch(() => undefined);\n if (!info || (info.size === this.size && info.mtimeMs === this.mtimeMs)) return false;\n this.size = info.size;\n this.mtimeMs = info.mtimeMs;\n const messages = await loadMessages(this.sessionId);\n const present = new Set(messages.map((m) => m.uuid));\n for (const uuid of this.fromFile) {\n if (!present.has(uuid)) {\n this.fromFile = present;\n this.delivered = new Set(present);\n this.broadcast({ type: 'reload', sessionId: this.sessionId });\n return true;\n }\n }\n this.fromFile = present;\n for (const message of messages) {\n if (this.delivered.has(message.uuid)) continue;\n this.delivered.add(message.uuid);\n this.broadcast({ type: 'message', sessionId: this.sessionId, message });\n }\n return true;\n } finally {\n this.checking = false;\n }\n }\n}\n\nconst feeds = new Map<string, Feed>();\nconst everyone = new Set<Listener>();\nlet changedTimer: NodeJS.Timeout | undefined;\n\nexport function feedFor(sessionId: string): Feed {\n let feed = feeds.get(sessionId);\n if (!feed) {\n feed = new Feed(sessionId);\n feeds.set(sessionId, feed);\n }\n return feed;\n}\n\n/** Tells every connected client the session list changed, at most every 2 s. */\nexport function sessionsChanged(): void {\n if (changedTimer) return;\n changedTimer = setTimeout(() => {\n changedTimer = undefined;\n for (const listener of everyone) {\n try {\n listener({ type: 'sessions_changed' });\n } catch {\n // Closed socket.\n }\n }\n }, 2000);\n}\n\nexport function broadcastAll(event: ServerEvent): void {\n for (const listener of everyone) {\n try {\n listener(event);\n } catch {\n // Closed socket.\n }\n }\n}\n\nexport function connect(listener: Listener): () => void {\n everyone.add(listener);\n return () => everyone.delete(listener);\n}\n\nexport function subscribe(sessionId: string, listener: Listener): () => void {\n const feed = feedFor(sessionId);\n feed.listeners.add(listener);\n feed.replayRecent(listener);\n feed.watch();\n return () => {\n feed.listeners.delete(listener);\n if (feed.listeners.size > 0) return;\n feed.unwatch();\n // Nobody watches and no run has published into it: forget it, so feeds do not pile up\n // for every session ever opened. A run's feed stays, for a client that comes back to it.\n if (!feed.hasRecent && feed.publishing === 0 && feeds.get(sessionId) === feed) feeds.delete(sessionId);\n };\n}\n", "import { randomUUID } from 'node:crypto';\nimport { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { Attachment } from '../shared/protocol.js';\nimport { config } from './config.js';\n\nconst uploadsDir = () => path.join(config.stateDir, 'uploads');\nexport const MAX_UPLOAD_BYTES = 25 * 1024 * 1024;\n\nconst safeName = (name: string) => name.replace(/[/\\\\\\0]/g, '_').replace(/^\\.+/, '_').slice(0, 120) || 'file';\n\n/** Saves an uploaded file where Claude can read it, and returns its handle. */\nexport async function saveUpload(file: File): Promise<Attachment> {\n if (file.size > MAX_UPLOAD_BYTES) throw new Error(`File is larger than ${MAX_UPLOAD_BYTES / 1024 / 1024} MB`);\n const id = randomUUID();\n const dir = path.join(uploadsDir(), id);\n await mkdir(dir, { recursive: true, mode: 0o700 });\n const name = safeName(file.name);\n const filePath = path.join(dir, name);\n await writeFile(filePath, Buffer.from(await file.arrayBuffer()), { mode: 0o600 });\n return { id, name, mime: file.type || 'application/octet-stream', size: file.size, path: filePath };\n}\n\n/** Looks an upload up by id; the path is rebuilt here, never taken from the client. */\nexport async function findUpload(id: string): Promise<Attachment | undefined> {\n if (!/^[0-9a-f-]{36}$/.test(id)) return undefined;\n const dir = path.join(uploadsDir(), id);\n try {\n const [name] = await readdir(dir);\n if (!name) return undefined;\n const filePath = path.join(dir, name);\n const info = await stat(filePath);\n return { id, name, mime: mimeOf(name), size: info.size, path: filePath };\n } catch {\n return undefined;\n }\n}\n\nexport async function readUpload(id: string): Promise<{ attachment: Attachment; data: Buffer } | undefined> {\n const attachment = await findUpload(id);\n if (!attachment) return undefined;\n return { attachment, data: await readFile(attachment.path) };\n}\n\nconst MIME: Record<string, string> = {\n png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp',\n pdf: 'application/pdf', txt: 'text/plain', md: 'text/markdown', json: 'application/json', csv: 'text/csv',\n};\nconst mimeOf = (name: string) => MIME[name.split('.').pop()?.toLowerCase() ?? ''] ?? 'application/octet-stream';\n\nexport type DirListing = { path: string; parent?: string; dirs: Array<{ name: string; path: string }> };\n\n/** Subfolders of a folder, for choosing where a new session runs. */\nexport async function listDirs(dir: string | undefined, showHidden: boolean): Promise<DirListing> {\n const target = path.resolve(dir || config.home);\n const entries = await readdir(target, { withFileTypes: true });\n const dirs = entries\n .filter((e) => (e.isDirectory() || e.isSymbolicLink()) && (showHidden || !e.name.startsWith('.')))\n .map((e) => ({ name: e.name, path: path.join(target, e.name) }))\n .sort((a, b) => a.name.localeCompare(b.name));\n const parent = path.dirname(target);\n return { path: target, ...(parent !== target ? { parent } : {}), dirs };\n}\n\n/** Removes an upload (made for a message that was never sent). */\nexport async function removeUpload(id: string): Promise<void> {\n if (!/^[0-9a-f-]{36}$/.test(id)) return;\n await rm(path.join(uploadsDir(), id), { recursive: true, force: true });\n}\n", "import { realpath } from 'node:fs/promises';\nimport os from 'node:os';\n\nimport { listSessions } from '@anthropic-ai/claude-agent-sdk';\n\nimport { lastTurnTime, transcriptPath } from './transcripts.js';\n\n/** A yes holds for a while; a no is asked again soon (the folder's first session may be starting). */\nconst YES_MS = 30_000;\nconst NO_MS = 3_000;\nconst cache = new Map<string, { at: number; value: boolean }>();\n\n/**\n * Whether Claude Code has run in this very folder, so what the folder brings (its project\n * settings, hooks and MCP servers, its git config with filters and hooks) is something the user\n * already let run. A folder Pelican is only shown (a fresh clone, a download, an address another\n * site opened) runs nothing of its own: probes get the user's settings only, and git does not run.\n *\n * Claude Code files sessions by the folder's path with punctuation turned into dashes, so `a.b`\n * and `a-b` share a list, and the list may fill in a session's folder from that shared name. A\n * session counts only by the folder its own transcript records, and only if it is this one.\n */\nexport async function claudeRanIn(folder: string): Promise<boolean> {\n const dir = await realpath(folder).catch(() => folder);\n if (dir === os.homedir()) return true;\n const cached = cache.get(dir);\n if (cached && Date.now() - cached.at < (cached.value ? YES_MS : NO_MS)) return cached.value;\n let value = false;\n const sessions = await listSessions({ dir, limit: 50, includeWorktrees: false }).catch(() => []);\n for (const session of sessions) {\n const file = await transcriptPath(session.sessionId);\n const recorded = file ? (await lastTurnTime(file))?.lastTurn?.cwd : undefined;\n if (!recorded) continue;\n if (recorded === dir || (await realpath(recorded).catch(() => '')) === dir) {\n value = true;\n break;\n }\n }\n if (cache.size > 2000) cache.clear();\n cache.set(dir, { at: Date.now(), value });\n return value;\n}\n", "import { realpath } from 'node:fs/promises';\nimport os from 'node:os';\n\nimport { query } from '@anthropic-ai/claude-agent-sdk';\nimport type { McpServerStatus, ModelInfo, SDKControlGetUsageResponse, SDKUserMessage, SlashCommand } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { Account, Agent, Command, McpServer, ModelOption, PlanUsage } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { DEMO_MODELS } from './demo.js';\nimport { claudeRanIn } from './trust.js';\n\nconst TTL_MS = 10 * 60 * 1000;\nconst PROBE_TIMEOUT_MS = 30_000;\nconst MAX_PROBES = 2;\n\n/** A prompt stream that never yields: the process starts, answers control requests, and sends no turn. */\nconst idlePrompt: AsyncIterable<SDKUserMessage> = {\n [Symbol.asyncIterator]: () => ({ next: () => new Promise<never>(() => {}) }),\n};\n\nlet running = 0;\nconst waiting: (() => void)[] = [];\n\n/** At most MAX_PROBES Claude processes at a time, however many requests ask. */\nasync function slot<T>(work: () => Promise<T>): Promise<T> {\n if (running >= MAX_PROBES) await new Promise<void>((resolve) => waiting.push(resolve));\n running += 1;\n try {\n return await work();\n } finally {\n running -= 1;\n waiting.shift()?.();\n }\n}\n\nconst inflight = new Map<string, Promise<unknown>>();\n\n/**\n * Starts Claude Code without a conversation in `cwd`, asks it something, and\n * stops it. Costs no tokens and writes no transcript. One probe per folder and\n * question at a time; it gives up after PROBE_TIMEOUT_MS.\n */\nasync function probe<T>(key: string, cwd: string, ask: (q: ReturnType<typeof query>) => Promise<T>): Promise<T> {\n const dir = await realpath(cwd);\n const id = `${key}:${dir}`;\n const pending = inflight.get(id);\n if (pending) return pending as Promise<T>;\n const work = slot(async () => {\n const q = query({\n prompt: idlePrompt,\n options: {\n cwd: dir,\n persistSession: false,\n settingSources: (await claudeRanIn(dir)) ? ['user', 'project', 'local'] : ['user'],\n ...(config.claudeExecutable ? { pathToClaudeCodeExecutable: config.claudeExecutable } : {}),\n },\n });\n let timer: NodeJS.Timeout | undefined;\n try {\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Claude Code did not answer in time.')), PROBE_TIMEOUT_MS);\n });\n return await Promise.race([ask(q), timeout]);\n } finally {\n clearTimeout(timer);\n q.close();\n }\n }).finally(() => inflight.delete(id));\n inflight.set(id, work);\n return work;\n}\n\nfunction toOption(info: ModelInfo): ModelOption {\n return {\n value: info.value,\n label: info.displayName || info.value,\n description: info.description ?? '',\n efforts: info.supportedEffortLevels ?? [],\n supportsFast: Boolean(info.supportsFastMode),\n ...(info.supportsAutoMode !== undefined ? { supportsAuto: info.supportsAutoMode } : {}),\n ...(info.resolvedModel ? { resolvedModel: info.resolvedModel } : {}),\n };\n}\n\nexport type ModelList = { models: ModelOption[]; signedIn: boolean | null; account?: Account };\n\nlet cache: { at: number; value: ModelList } | undefined;\n\n/**\n * The models this account can use, with their effort levels and fast-mode\n * support, as Claude Code reports them, and whether Claude Code is signed in.\n */\nexport async function listModels(): Promise<ModelList> {\n if (config.demo) return { models: DEMO_MODELS, signedIn: true, account: { email: 'you@example.com', plan: 'max' } };\n if (cache && Date.now() - cache.at < TTL_MS) return cache.value;\n const asking = probe('models', os.homedir(), async (q) => {\n const models = (await q.supportedModels()).map(toOption);\n const account = await q.accountInfo().catch(() => undefined);\n const signedIn = account ? Boolean(account.email || account.tokenSource || account.apiKeySource || account.apiProvider) : null;\n const who: Account | undefined = account?.email || account?.organization || account?.subscriptionType\n ? {\n ...(account.email ? { email: account.email } : {}),\n ...(account.organization ? { organization: account.organization } : {}),\n ...(account.subscriptionType ? { plan: account.subscriptionType } : {}),\n }\n : undefined;\n return { models, signedIn, ...(who ? { account: who } : {}) };\n })\n .then((value) => {\n cache = { at: Date.now(), value };\n return value;\n });\n try {\n return await asking;\n } catch (error) {\n if (cache) return cache.value;\n throw error;\n }\n}\n\nconst DEMO_COMMANDS: Command[] = [\n { name: 'compact', description: 'Summarize the conversation so far to free up context', argumentHint: '' },\n { name: 'review', description: 'Review the changes on this branch', argumentHint: '' },\n { name: 'init', description: 'Write a CLAUDE.md for this project', argumentHint: '' },\n];\nconst DEMO_AGENTS: Agent[] = [{ name: 'code-reviewer', description: 'Reviews a change for bugs and style' }];\n\nexport type Completions = { commands: Command[]; agents: Agent[] };\nconst completionCache = new Map<string, { at: number; value: Completions }>();\n\n/** Slash commands (built-in, the project's and the user's, skills) and subagents available in a folder. */\nexport async function listCompletions(cwd: string): Promise<Completions> {\n if (config.demo) return { commands: DEMO_COMMANDS, agents: DEMO_AGENTS };\n const dir = await realpath(cwd);\n const cached = completionCache.get(dir);\n if (cached && Date.now() - cached.at < TTL_MS) return cached.value;\n const value = await probe('completions', dir, async (q) => {\n const [commands, agents] = await Promise.all([q.supportedCommands(), q.supportedAgents().catch(() => [])]);\n return {\n commands: commands.map((c: SlashCommand) => ({ name: c.name, description: c.description ?? '', argumentHint: c.argumentHint ?? '' })),\n agents: agents.map((a) => ({ name: a.name, description: a.description ?? '' })),\n };\n });\n completionCache.set(dir, { at: Date.now(), value });\n return value;\n}\n\nexport function toMcpServers(list: McpServerStatus[]): McpServer[] {\n return list.map((server) => ({\n name: server.name,\n status: server.status,\n ...(server.error ? { error: server.error } : {}),\n tools: server.tools?.length ?? 0,\n ...(server.scope ? { scope: server.scope } : {}),\n }));\n}\n\nconst mcpCache = new Map<string, { at: number; servers: McpServer[] }>();\n\n/** The MCP servers a session in this folder gets, and whether they connect, when no Claude runs there. */\nexport async function probeMcpServers(cwd: string): Promise<McpServer[]> {\n if (config.demo) return [{ name: 'github', status: 'connected', tools: 26, scope: 'user' }, { name: 'linear', status: 'needs-auth', tools: 0, scope: 'project' }];\n const dir = await realpath(cwd);\n const cached = mcpCache.get(dir);\n if (cached && Date.now() - cached.at < 60_000) return cached.servers;\n const servers = toMcpServers(await probe('mcp', dir, (q) => q.mcpServerStatus()));\n mcpCache.set(dir, { at: Date.now(), servers });\n return servers;\n}\n\nconst DEMO_PLAN: PlanUsage = {\n windows: [\n { type: 'five_hour', utilization: 0.42, resetsAt: Date.now() + 2.4 * 3600_000 },\n { type: 'seven_day', utilization: 0.18, resetsAt: Date.now() + 3.5 * 86400_000 },\n ],\n};\n\ntype Window = { utilization: number | null; resets_at: string | null } | null | undefined;\nlet planCache: { at: number; value: PlanUsage | null } | undefined;\n\n/**\n * The plan's usage, as Claude Code's `/usage` reads it from claude.ai: the windows of a Pro or\n * Max plan, and the monthly cap on extra usage that Team and Enterprise plans have instead.\n * Null where plan limits do not apply (an API key, Bedrock, Vertex) or the answer is not there.\n * The SDK marks this call experimental, so anything unexpected is no answer, not an error.\n */\nexport async function planUsage(): Promise<PlanUsage | null> {\n if (config.demo) return DEMO_PLAN;\n if (planCache && Date.now() - planCache.at < 60_000) return planCache.value;\n const value = await probe('usage', os.homedir(), async (q) => {\n const ask = (q as unknown as { usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET?: (o: { skipBehaviors: boolean }) => Promise<SDKControlGetUsageResponse> })\n .usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET;\n if (typeof ask !== 'function') return null;\n const answer = await ask.call(q, { skipBehaviors: true });\n const limits = answer?.rate_limits;\n if (!answer?.rate_limits_available || !limits) return null;\n const windows: PlanUsage['windows'] = [];\n const add = (type: string, window: Window, label?: string) => {\n if (!window || typeof window.utilization !== 'number') return;\n const resetsAt = window.resets_at ? Date.parse(window.resets_at) : NaN;\n windows.push({ type, ...(label ? { label } : {}), utilization: window.utilization / 100, ...(Number.isFinite(resetsAt) ? { resetsAt } : {}) });\n };\n add('five_hour', limits.five_hour);\n add('seven_day', limits.seven_day);\n add('seven_day_opus', limits.seven_day_opus);\n add('seven_day_sonnet', limits.seven_day_sonnet);\n for (const scoped of limits.model_scoped ?? []) add(`model:${scoped.display_name}`, scoped, `Weekly ${scoped.display_name} limit`);\n const extra = limits.extra_usage;\n return {\n windows,\n ...(extra ? {\n extra: {\n enabled: Boolean(extra.is_enabled),\n ...(typeof extra.used_credits === 'number' ? { usedCents: extra.used_credits } : {}),\n ...(typeof extra.monthly_limit === 'number' ? { limitCents: extra.monthly_limit } : {}),\n ...(typeof extra.utilization === 'number' ? { utilization: extra.utilization / 100 } : {}),\n ...(extra.currency ? { currency: extra.currency } : {}),\n },\n } : {}),\n };\n }).catch(() => null);\n planCache = { at: Date.now(), value };\n return value;\n}\n", "import { execFile } from 'node:child_process';\nimport { realpathSync } from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { config } from './config.js';\n\nconst run = promisify(execFile);\n\n/**\n * Git runs only in folders Claude Code has worked in (see trust.ts), where the repository's\n * config is the user's own. Even there Pelican only reads, so it starts nothing git would start\n * on the side: no hooks, no file-system monitor, no external diff or text converter. It takes\n * no locks the user's own git would trip over, never asks for credentials, reads pathspecs\n * literally (`:/` is a name, not \"the top of the repository\"), and leaves submodules' work\n * trees alone.\n */\nconst SAFE = ['-c', 'core.fsmonitor=false', '-c', 'core.hooksPath=/dev/null', '-c', 'safe.bareRepository=explicit', '-c', 'core.quotepath=off'];\n\nfunction environment(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = { ...process.env, GIT_OPTIONAL_LOCKS: '0', GIT_TERMINAL_PROMPT: '0', GIT_LITERAL_PATHSPECS: '1' };\n // The folder decides the repository, not whatever the server was started with.\n for (const name of Object.keys(env)) {\n if (/^GIT_(DIR|WORK_TREE|INDEX_FILE|COMMON_DIR|OBJECT_DIRECTORY|ALTERNATE_OBJECT_DIRECTORIES|NAMESPACE|CONFIG_PARAMETERS|CONFIG_COUNT|CONFIG_KEY_\\d+|CONFIG_VALUE_\\d+|CEILING_DIRECTORIES)$/.test(name)) delete env[name];\n }\n if (config.demo) {\n // The demo's folders may sit inside a repository of yours (a home folder kept in git):\n // git must not look above the demo for one.\n try {\n env.GIT_CEILING_DIRECTORIES = path.dirname(realpathSync(config.home));\n } catch {\n env.GIT_CEILING_DIRECTORIES = path.dirname(config.home);\n }\n }\n return env;\n}\n\n/** Runs a read-only git command in `cwd`; rejects on a non-zero exit, with stdout on the error. */\nexport async function git(cwd: string, args: string[], timeout = 15_000): Promise<string> {\n const command = args[0]!;\n const extra = command === 'diff' ? ['--no-ext-diff', '--no-textconv', '--ignore-submodules=dirty']\n : command === 'status' ? ['--ignore-submodules=dirty']\n : [];\n const { stdout } = await run('git', [...SAFE, command, ...extra, ...args.slice(1)], { cwd, env: environment(), maxBuffer: 32 * 1024 * 1024, timeout });\n return stdout;\n}\n", "import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\nimport { git } from './git.js';\nimport { claudeRanIn } from './trust.js';\n\nconst cache = new Map<string, { at: number; files: string[] }>();\nconst TTL_MS = 30_000;\nconst SKIP = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.venv', 'venv', '__pycache__', 'target', '.cache']);\nconst MAX_FILES = 20_000;\n\n/** Files of a folder as `git ls-files` sees them (ignored ones left out), or by walking it. */\nasync function projectFiles(cwd: string): Promise<string[]> {\n const cached = cache.get(cwd);\n if (cached && Date.now() - cached.at < TTL_MS) return cached.files;\n let files: string[];\n try {\n // Git only where Claude Code has run; anywhere else the folder is walked.\n if (!config.demo && !(await claudeRanIn(cwd))) throw new Error('not trusted');\n const stdout = await git(cwd, ['ls-files', '--cached', '--others', '--exclude-standard'], 5000);\n files = stdout.split('\\n').filter(Boolean).slice(0, MAX_FILES);\n } catch {\n files = [];\n const walk = async (dir: string, depth: number): Promise<void> => {\n if (depth > 8 || files.length >= MAX_FILES) return;\n let entries;\n try {\n entries = await readdir(path.join(cwd, dir), { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (files.length >= MAX_FILES) return;\n if (entry.name.startsWith('.') || SKIP.has(entry.name)) continue;\n const rel = dir ? `${dir}/${entry.name}` : entry.name;\n if (entry.isDirectory()) await walk(rel, depth + 1);\n else files.push(rel);\n }\n };\n await walk('', 0);\n }\n cache.set(cwd, { at: Date.now(), files });\n return files;\n}\n\n/** How well `query` matches `file`: higher is better, -1 for no match. */\nfunction score(file: string, query: string): number {\n const f = file.toLowerCase();\n const q = query.toLowerCase();\n const base = f.slice(f.lastIndexOf('/') + 1);\n if (base === q) return 1000;\n if (base.startsWith(q)) return 800 - base.length;\n if (base.includes(q)) return 600 - base.length;\n if (f.includes(q)) return 400 - f.length / 10;\n // Every character in order: \"stset\" finds \"src/settings/Settings.tsx\".\n let at = 0;\n for (const char of q) {\n at = f.indexOf(char, at);\n if (at === -1) return -1;\n at += 1;\n }\n return 100 - f.length / 10;\n}\n\n/** Files and folders matching a query, for `@` mentions in the composer. */\nexport async function searchFiles(cwd: string, query: string, limit = 30): Promise<string[]> {\n const files = await projectFiles(cwd);\n const dirs = new Set<string>();\n for (const file of files) {\n let cut = file.lastIndexOf('/');\n while (cut > 0) {\n dirs.add(`${file.slice(0, cut)}/`);\n cut = file.lastIndexOf('/', cut - 1);\n }\n }\n const candidates = [...files, ...dirs];\n if (!query) return files.slice().sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b)).slice(0, limit);\n return candidates\n .map((file) => ({ file, score: score(file, query) }))\n .filter((m) => m.score >= 0)\n .sort((a, b) => b.score - a.score || a.file.localeCompare(b.file))\n .slice(0, limit)\n .map((m) => m.file);\n}\n", "import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport webpush from 'web-push';\n\nimport { config } from './config.js';\n\ntype Subscription = webpush.PushSubscription & { openUrl?: string };\n\nconst keysFile = () => path.join(config.stateDir, 'vapid.json');\nconst subsFile = () => path.join(config.stateDir, 'push-subscriptions.json');\n\nlet keys: { publicKey: string; privateKey: string } | undefined;\nlet subscriptions: Subscription[] = [];\n\nasync function save(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n await writeFile(file, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\n/** Loads this machine's VAPID keys (created on first start) and the saved subscriptions. */\nexport async function initPush(): Promise<void> {\n try {\n keys = JSON.parse(await readFile(keysFile(), 'utf8'));\n } catch {\n keys = webpush.generateVAPIDKeys();\n await save(keysFile(), keys);\n }\n webpush.setVapidDetails('https://github.com/Ki-Seki/pelican', keys!.publicKey, keys!.privateKey);\n try {\n subscriptions = JSON.parse(await readFile(subsFile(), 'utf8'));\n } catch {\n subscriptions = [];\n }\n}\n\nexport function pushKey(): string | undefined {\n return keys?.publicKey;\n}\n\nexport async function addSubscription(subscription: Subscription): Promise<void> {\n subscriptions = subscriptions.filter((s) => s.endpoint !== subscription.endpoint);\n subscriptions.push(subscription);\n await save(subsFile(), subscriptions);\n}\n\nexport async function removeSubscription(endpoint: string): Promise<void> {\n subscriptions = subscriptions.filter((s) => s.endpoint !== endpoint);\n await save(subsFile(), subscriptions);\n}\n\nexport type PushPayload = { title: string; body: string; sessionId: string; tag: string };\n\n/** Sends a notification to every subscribed device; drops subscriptions the push service rejects. */\nexport async function notify(payload: PushPayload): Promise<void> {\n if (!keys || subscriptions.length === 0) return;\n const gone: string[] = [];\n await Promise.all(subscriptions.map(async (subscription) => {\n // PELICAN_SESSION_URL wins (for a page that embeds Pelican); otherwise the page that subscribed.\n const id = encodeURIComponent(payload.sessionId);\n const url = config.sessionUrl ? config.sessionUrl.replaceAll('{id}', id)\n : subscription.openUrl ? `${subscription.openUrl}${id}` : undefined;\n const body = JSON.stringify({ ...payload, url });\n try {\n await webpush.sendNotification(subscription, body, { TTL: 3600, urgency: 'high' });\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode;\n if (status === 404 || status === 410) gone.push(subscription.endpoint);\n else console.warn('[pelican] push failed', status ?? (error as Error).message);\n }\n }));\n if (gone.length > 0) {\n subscriptions = subscriptions.filter((s) => !gone.includes(s.endpoint));\n await save(subsFile(), subscriptions);\n }\n}\n", "import { spawn } from 'node:child_process';\n\nimport type { ShellResult } from '../shared/protocol.js';\n\nconst MAX_OUTPUT = 200_000;\nconst TIMEOUT_MS = 2 * 60_000;\n\n/**\n * Runs one `!` command in a session's folder through the user's login shell,\n * like Claude Code's bash mode: no terminal, output captured up to a limit,\n * stopped after two minutes.\n */\nexport function runCommand(cwd: string, command: string): Promise<ShellResult> {\n const shell = process.env.SHELL || '/bin/bash';\n const started = Date.now();\n return new Promise((resolve) => {\n let stdout = '';\n let stderr = '';\n let truncated = false;\n const child = spawn(shell, ['-lc', command], { cwd, env: { ...process.env, PAGER: 'cat', GIT_PAGER: 'cat', TERM: 'dumb' }, stdio: ['ignore', 'pipe', 'pipe'] });\n const take = (current: string, chunk: Buffer) => {\n if (current.length >= MAX_OUTPUT) {\n truncated = true;\n return current;\n }\n const next = current + chunk.toString('utf8');\n if (next.length > MAX_OUTPUT) truncated = true;\n return next.slice(0, MAX_OUTPUT);\n };\n child.stdout.on('data', (chunk: Buffer) => { stdout = take(stdout, chunk); });\n child.stderr.on('data', (chunk: Buffer) => { stderr = take(stderr, chunk); });\n const timer = setTimeout(() => child.kill('SIGKILL'), TIMEOUT_MS);\n const finish = (code: number | null, error?: Error) => {\n clearTimeout(timer);\n resolve({\n command,\n stdout,\n stderr: error ? `${stderr}${error.message}` : stderr,\n code,\n durationMs: Date.now() - started,\n ...(truncated ? { truncated: true } : {}),\n });\n };\n child.on('error', (error) => finish(null, error));\n child.on('close', (code, signal) => finish(signal ? null : code));\n });\n}\n\nconst escape = (text: string) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\n/** The command and its output the way Claude Code's bash mode writes them into the conversation. */\nexport function bashModeText(result: ShellResult): string {\n const note = result.code === null ? '\\n(stopped after two minutes)' : result.code !== 0 ? `\\n(exit code ${result.code})` : '';\n return `<bash-input>${escape(result.command)}</bash-input><bash-stdout>${escape(result.stdout)}</bash-stdout><bash-stderr>${escape(result.stderr + note)}</bash-stderr>`;\n}\n", "import type { SDKRateLimitInfo } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { UsageLimit } from '../shared/protocol.js';\n\n/** The account's usage limits as Claude Code last reported them, one per kind of limit. */\nconst limits = new Map<string, UsageLimit>();\n\nexport function recordLimit(info: SDKRateLimitInfo): void {\n const type = info.rateLimitType ?? 'unknown';\n limits.set(type, {\n type,\n status: info.status,\n ...(typeof info.utilization === 'number' ? { utilization: info.utilization } : {}),\n ...(typeof info.resetsAt === 'number' ? { resetsAt: info.resetsAt < 1e12 ? info.resetsAt * 1000 : info.resetsAt } : {}),\n at: Date.now(),\n });\n}\n\nexport function usageLimits(): UsageLimit[] {\n const now = Date.now();\n // A limit that has reset since it was reported says nothing any more.\n return [...limits.values()].filter((limit) => !limit.resetsAt || limit.resetsAt > now);\n}\n", "import { randomUUID } from 'node:crypto';\nimport { readFile, stat } from 'node:fs/promises';\n\nimport { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n CanUseTool,\n EffortLevel,\n Options,\n PermissionResult,\n PermissionUpdate,\n Query,\n SDKMessage,\n SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\n\nimport type {\n Attachment,\n BackgroundTask,\n ChatMessage,\n McpServer,\n PartialBlock,\n PermissionDecision,\n PermissionRequest,\n RewindResult,\n RunSettings,\n RunState,\n SendMode,\n SessionStatus,\n ShellResult,\n} from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { DEMO_WAITING_SESSION, demoRunState } from './demo.js';\nimport { toMcpServers } from './models.js';\nimport { broadcastAll, feedFor, sessionsChanged } from './feed.js';\nimport { liveProcesses } from './live.js';\nimport { toChatMessage } from './normalize.js';\nimport { notify } from './push.js';\nimport { sessionInfo } from './sessions.js';\nimport { bashModeText } from './shell.js';\nimport { lastTurnTime, refreshTranscriptIndex, transcriptPath } from './transcripts.js';\nimport { recordLimit } from './usage.js';\n\n/** Messages the user sends, handed to the Claude process as they come. */\nclass InputQueue implements AsyncIterable<SDKUserMessage> {\n private items: SDKUserMessage[] = [];\n private waiters: Array<(result: IteratorResult<SDKUserMessage>) => void> = [];\n private done = false;\n\n push(item: SDKUserMessage): void {\n const waiter = this.waiters.shift();\n if (waiter) waiter({ value: item, done: false });\n else this.items.push(item);\n }\n\n close(): void {\n this.done = true;\n for (const waiter of this.waiters.splice(0)) waiter({ value: undefined, done: true });\n }\n\n [Symbol.asyncIterator](): AsyncIterator<SDKUserMessage> {\n return {\n next: () => {\n const item = this.items.shift();\n if (item) return Promise.resolve({ value: item, done: false });\n if (this.done) return Promise.resolve({ value: undefined, done: true });\n return new Promise((resolve) => this.waiters.push(resolve));\n },\n };\n }\n}\n\ntype Pending = {\n request: PermissionRequest;\n input: Record<string, unknown>;\n suggestions?: PermissionUpdate[];\n resolve: (result: PermissionResult) => void;\n};\n\nexport type SendInput = {\n text: string;\n attachments: Attachment[];\n settings: RunSettings;\n /** Id for the user message, so the client's optimistic copy matches the transcript row. */\n uuid?: string;\n /** While a turn runs: join it at Claude's next step, or wait for it to end. */\n mode?: SendMode;\n};\n\nconst sdkModel = (model: string | undefined) => (model && model !== 'default' ? model : undefined);\n\n/** One Claude Code process driving one session. It stays alive between turns until idle. */\n/** Claude Code's error, or what it means for someone who edited their last prompt. */\nfunction readableError(text: string): string {\n if (text.includes('Resume rejected by --resume-drops-turn')) {\n return 'The conversation changed after that prompt (another app added to it), so the prompt was not replaced. Reload, then edit it again or send a new message.';\n }\n return text;\n}\n\nexport class SessionRun {\n busy = false;\n closed = false;\n error?: string;\n lastActive = Date.now();\n private partial: PartialBlock[] = [];\n private completedBlocks = 0;\n private permissions = new Map<string, Pending>();\n private input = new InputQueue();\n private q?: Query;\n private emitTimer?: NodeJS.Timeout;\n private title = '';\n /** Set by Stop: the turn then ends with an error result that is not a failure. */\n private interrupted = false;\n private lastTurn?: RunState['lastTurn'];\n private context?: RunState['context'];\n private activity?: RunState['activity'];\n private tasks: BackgroundTask[] = [];\n\n get hasBackgroundTasks(): boolean {\n return this.tasks.length > 0;\n }\n /** Messages waiting for the turn to end, published when it does. */\n private queued: ChatMessage[] = [];\n private started!: { resolve: () => void; reject: (error: Error) => void };\n /** Settles once Claude has started (its first message), or fails when it ends before that. */\n readonly ready = new Promise<void>((resolve, reject) => {\n this.started = { resolve, reject };\n });\n // Most callers never wait for it: a failure here must not count as unhandled.\n private readonly readyHandled = this.ready.catch(() => undefined);\n private suggestion?: string;\n\n constructor(\n readonly sessionId: string,\n readonly cwd: string,\n private settings: RunSettings,\n private readonly resume: boolean,\n /** Resume only up to this entry, dropping the turn after it (an edited last prompt). */\n private readonly resumeAt?: { entry: string; dropsTurn: string },\n ) {}\n\n start(): void {\n const settings = this.settings;\n const options: Options = {\n cwd: this.cwd,\n ...(this.resume ? { resume: this.sessionId } : { sessionId: this.sessionId }),\n // Claude Code checks that everything past the entry belongs to the dropped turn, so a\n // message another app added meanwhile is never thrown away unseen.\n ...(this.resume && this.resumeAt ? { resumeSessionAt: this.resumeAt.entry, resumeDropsTurn: this.resumeAt.dropsTurn } : {}),\n ...(sdkModel(settings.model) ? { model: sdkModel(settings.model) } : {}),\n ...(settings.effort ? { effort: settings.effort as EffortLevel } : {}),\n permissionMode: settings.permissionMode ?? 'default',\n allowDangerouslySkipPermissions: true,\n ...(settings.fast || settings.ultracode ? {\n settings: {\n ...(settings.fast ? { fastMode: true } : {}),\n // Ultracode needs workflows; both are session settings, like the CLI's --settings.\n ...(settings.ultracode ? { ultracode: true, enableWorkflows: true } : {}),\n },\n } : {}),\n includePartialMessages: true,\n // Lets \"Rewind code\" put files back the way they were before a prompt.\n enableFileCheckpointing: true,\n promptSuggestions: true,\n settingSources: ['user', 'project', 'local'],\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n tools: { type: 'preset', preset: 'claude_code' },\n canUseTool: this.canUseTool,\n ...(config.claudeExecutable ? { pathToClaudeCodeExecutable: config.claudeExecutable } : {}),\n stderr: (data) => {\n if (process.env.PELICAN_DEBUG) process.stderr.write(`[claude ${this.sessionId.slice(0, 8)}] ${data}`);\n },\n };\n this.q = query({ prompt: this.input, options });\n void this.pump();\n void sessionInfo(this.sessionId).then((info) => {\n if (info) this.title = info.customTitle || info.summary || '';\n });\n }\n\n state(): RunState {\n return {\n sessionId: this.sessionId,\n cwd: this.cwd,\n busy: this.busy,\n settings: this.settings,\n permissions: [...this.permissions.values()].map((p) => p.request),\n partial: this.partial.slice(this.completedBlocks).filter(Boolean),\n ...(this.error ? { error: this.error } : {}),\n ...(this.lastTurn ? { lastTurn: this.lastTurn } : {}),\n ...(this.context ? { context: this.context } : {}),\n ...(this.activity ? { activity: this.activity } : {}),\n ...(this.tasks.length > 0 ? { tasks: this.tasks } : {}),\n ...(this.queued.length > 0 ? { queued: this.queued.map((m) => m.uuid) } : {}),\n ...(this.suggestion && !this.busy ? { suggestion: this.suggestion } : {}),\n };\n }\n\n status(): SessionStatus {\n if (this.permissions.size > 0) return 'waiting';\n return this.busy ? 'running' : 'idle';\n }\n\n /** Sends the run state now, or within 80 ms when called for streamed text. */\n private emit(soon = false): void {\n if (soon) {\n if (this.emitTimer) return;\n this.emitTimer = setTimeout(() => {\n this.emitTimer = undefined;\n this.emitNow();\n }, 80);\n return;\n }\n clearTimeout(this.emitTimer);\n this.emitTimer = undefined;\n this.emitNow();\n }\n\n private lastStatus?: SessionStatus;\n\n private emitNow(): void {\n const state = this.state();\n feedFor(this.sessionId).broadcast({ type: 'run', state });\n // Session lists only care about the status; streamed text stays with the session's viewers.\n const status = this.status();\n if (status !== this.lastStatus) {\n this.lastStatus = status;\n broadcastAll({ type: 'status', sessionId: this.sessionId, status });\n }\n }\n\n private setBusy(busy: boolean): void {\n if (this.busy === busy) return;\n this.busy = busy;\n this.lastActive = Date.now();\n if (!busy) {\n this.partial = [];\n this.completedBlocks = 0;\n }\n this.emit();\n sessionsChanged();\n }\n\n async send(input: SendInput): Promise<void> {\n await this.applySettings(input.settings);\n const uuid = input.uuid ?? randomUUID();\n const content: Array<Record<string, unknown>> = [];\n const fileLines: string[] = [];\n for (const attachment of input.attachments) {\n if (attachment.mime.startsWith('image/') && attachment.size <= 5 * 1024 * 1024) {\n const data = await readFile(attachment.path).catch(() => undefined);\n if (data) {\n content.push({ type: 'image', source: { type: 'base64', media_type: attachment.mime, data: data.toString('base64') } });\n continue;\n }\n }\n fileLines.push(`- ${attachment.path} (${attachment.name})`);\n }\n let text = input.text;\n if (fileLines.length > 0) text = `${text}${text ? '\\n\\n' : ''}Attached files:\\n${fileLines.join('\\n')}`;\n if (text) content.push({ type: 'text', text });\n // A running turn takes a new message at Claude's next step, unless it should wait for the turn to end.\n const queue = this.busy && input.mode === 'queue';\n const message = {\n type: 'user',\n uuid,\n session_id: this.sessionId,\n parent_tool_use_id: null,\n origin: { kind: 'human' },\n ...(this.busy ? { priority: queue ? 'later' : 'next' } : {}),\n message: { role: 'user', content },\n } as unknown as SDKUserMessage;\n this.error = undefined;\n this.suggestion = undefined;\n const chat = toChatMessage({ type: 'user', uuid, message: { role: 'user', content } });\n if (queue) {\n if (chat) this.queued.push({ ...chat, timestamp: Date.now() });\n this.emit();\n } else {\n this.setBusy(true);\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: Date.now() });\n }\n this.input.push(message);\n }\n\n /**\n * Adds a `!` command and its output to the conversation without starting a\n * turn, the way Claude Code's bash mode does: Claude reads it with the next message.\n */\n async appendShell(result: ShellResult): Promise<void> {\n const uuid = randomUUID();\n const text = bashModeText(result);\n const message = {\n type: 'user',\n uuid,\n session_id: this.sessionId,\n parent_tool_use_id: null,\n origin: { kind: 'human' },\n shouldQuery: false,\n message: { role: 'user', content: text },\n } as unknown as SDKUserMessage;\n const chat = toChatMessage({ type: 'user', uuid, message: { role: 'user', content: text } });\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: Date.now() });\n this.input.push(message);\n }\n\n /** Puts files back the way they were before the prompt `uuid`; `dryRun` only says what would change. */\n async rewind(uuid: string, dryRun: boolean): Promise<RewindResult> {\n if (!this.q) throw new Error('Claude is not running in this session');\n const result = await this.q.rewindFiles(uuid, { dryRun });\n return {\n canRewind: result.canRewind,\n ...(result.error ? { error: result.error } : {}),\n ...(result.filesChanged ? { files: result.filesChanged } : {}),\n ...(typeof result.insertions === 'number' ? { insertions: result.insertions } : {}),\n ...(typeof result.deletions === 'number' ? { deletions: result.deletions } : {}),\n };\n }\n\n async mcpServers(): Promise<McpServer[]> {\n if (!this.q) return [];\n return toMcpServers(await this.q.mcpServerStatus());\n }\n\n async setMcpServer(name: string, change: { enabled?: boolean; reconnect?: boolean }): Promise<void> {\n if (!this.q) throw new Error('Claude is not running in this session');\n if (change.reconnect) await this.q.reconnectMcpServer(name);\n if (change.enabled !== undefined) await this.q.toggleMcpServer(name, change.enabled);\n }\n\n async stopTask(taskId: string): Promise<void> {\n await this.q?.stopTask(taskId);\n }\n\n async applySettings(next: RunSettings): Promise<void> {\n const q = this.q;\n if (!q) return;\n const prev = this.settings;\n try {\n if ((next.model ?? 'default') !== (prev.model ?? 'default')) await q.setModel(sdkModel(next.model));\n // A new effort level sent without the ultracode key turns ultracode off, so both go together.\n if ((next.effort ?? '') !== (prev.effort ?? '') || Boolean(next.ultracode) !== Boolean(prev.ultracode)) {\n await q.applyFlagSettings({\n effortLevel: (next.effort as EffortLevel) ?? null,\n ultracode: Boolean(next.ultracode),\n ...(next.ultracode ? { enableWorkflows: true } : {}),\n });\n }\n if (Boolean(next.fast) !== Boolean(prev.fast)) await q.applyFlagSettings({ fastMode: Boolean(next.fast) });\n if (next.permissionMode && next.permissionMode !== (prev.permissionMode ?? 'default')) await q.setPermissionMode(next.permissionMode);\n } catch (error) {\n console.warn('[pelican] could not apply settings', (error as Error).message);\n }\n this.settings = { ...prev, ...next };\n }\n\n async setPermissionMode(mode: RunSettings['permissionMode']): Promise<void> {\n await this.applySettings({ ...this.settings, permissionMode: mode });\n this.emit();\n }\n\n /** Settings changed in the composer, applied to Claude now: from its next step, also mid-turn. */\n async updateSettings(next: RunSettings): Promise<void> {\n await this.applySettings({ ...this.settings, ...next });\n this.emit();\n }\n\n private canUseTool: CanUseTool = (toolName, input, { signal, suggestions, blockedPath, decisionReason }) => {\n const id = randomUUID();\n const request: PermissionRequest = {\n id,\n sessionId: this.sessionId,\n toolName,\n input,\n canRemember: Boolean(suggestions && suggestions.length > 0),\n ...(decisionReason ? { reason: decisionReason } : {}),\n ...(blockedPath ? { blockedPath } : {}),\n createdAt: Date.now(),\n };\n return new Promise<PermissionResult>((resolve) => {\n this.permissions.set(id, { request, input, ...(suggestions ? { suggestions } : {}), resolve });\n signal.addEventListener('abort', () => {\n if (this.permissions.delete(id)) {\n resolve({ behavior: 'deny', message: 'Cancelled.' });\n this.emit();\n sessionsChanged();\n }\n });\n this.emit();\n sessionsChanged();\n const what = toolName === 'AskUserQuestion' ? 'has a question for you'\n : toolName === 'ExitPlanMode' ? 'has a plan for you to review'\n : `wants to use ${toolName}`;\n void notify({ title: this.title || 'Claude Code', body: `Claude ${what}`, sessionId: this.sessionId, tag: `${this.sessionId}:ask` });\n });\n };\n\n decide(id: string, decision: PermissionDecision): boolean {\n const pending = this.permissions.get(id);\n if (!pending) return false;\n this.permissions.delete(id);\n if (decision.behavior === 'allow') {\n pending.resolve({\n behavior: 'allow',\n updatedInput: decision.updatedInput ?? pending.input,\n ...(decision.remember && pending.suggestions ? { updatedPermissions: pending.suggestions } : {}),\n });\n if (decision.permissionMode) void this.setPermissionMode(decision.permissionMode);\n } else {\n pending.resolve({ behavior: 'deny', message: decision.message?.trim() || 'The user declined this.' });\n }\n this.emit();\n sessionsChanged();\n return true;\n }\n\n async interrupt(): Promise<void> {\n this.interrupted = true;\n for (const [id] of this.permissions) this.decide(id, { behavior: 'deny', message: 'Interrupted by the user.' });\n try {\n await this.q?.interrupt();\n } catch (error) {\n console.warn('[pelican] interrupt failed', (error as Error).message);\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n for (const [id] of this.permissions) this.decide(id, { behavior: 'deny', message: 'Session closed.' });\n this.input.close();\n try {\n this.q?.close();\n } catch {\n // Already exited.\n }\n }\n\n /** How full the context window is now; shown in the session header. */\n private async readContext(): Promise<void> {\n try {\n const usage = await this.q?.getContextUsage();\n if (!usage) return;\n this.context = { percent: Math.round(usage.percentage), tokens: usage.totalTokens, max: usage.maxTokens };\n this.emit();\n } catch {\n // Older Claude Code; the header just shows no meter.\n }\n }\n\n private onStream(event: Record<string, unknown>): void {\n const index = typeof event.index === 'number' ? event.index : -1;\n switch (event.type) {\n case 'message_start':\n this.partial = [];\n this.completedBlocks = 0;\n break;\n case 'content_block_start': {\n const block = (event.content_block ?? {}) as Record<string, unknown>;\n if (block.type === 'text') this.partial[index] = { type: 'text', text: '' };\n else if (block.type === 'thinking') this.partial[index] = { type: 'thinking', thinking: '' };\n else if (block.type === 'tool_use' || block.type === 'server_tool_use') {\n this.partial[index] = { type: 'tool_use', name: String(block.name ?? ''), inputJson: '' };\n }\n break;\n }\n case 'content_block_delta': {\n const delta = (event.delta ?? {}) as Record<string, unknown>;\n const block = this.partial[index];\n if (!block) break;\n if (block.type === 'text' && delta.type === 'text_delta') block.text += String(delta.text ?? '');\n else if (block.type === 'thinking' && delta.type === 'thinking_delta') block.thinking += String(delta.thinking ?? '');\n else if (block.type === 'tool_use' && delta.type === 'input_json_delta') block.inputJson += String(delta.partial_json ?? '');\n break;\n }\n default:\n return;\n }\n this.setBusy(true);\n this.emit(true);\n }\n\n private async pump(): Promise<void> {\n const q = this.q!;\n try {\n for await (const message of q as AsyncIterable<SDKMessage>) {\n this.lastActive = Date.now();\n this.started.resolve();\n const raw = message as unknown as Record<string, unknown>;\n switch (message.type) {\n case 'stream_event':\n if (!message.parent_tool_use_id) this.onStream(message.event as unknown as Record<string, unknown>);\n break;\n case 'assistant':\n case 'user': {\n if (raw.parent_tool_use_id) break;\n if (message.type === 'assistant') this.completedBlocks += 1;\n if (this.activity?.kind === 'retrying') this.activity = undefined;\n const chat = toChatMessage(raw);\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: chat.timestamp ?? Date.now() } satisfies ChatMessage);\n this.emit(true);\n break;\n }\n case 'system':\n if (message.subtype === 'session_state_changed') {\n const state = (raw as { state?: string }).state;\n if (state === 'running' || state === 'requires_action') this.setBusy(true);\n else if (state === 'idle') this.setBusy(false);\n } else if (message.subtype === 'init') {\n void refreshTranscriptIndex().then(sessionsChanged);\n } else if (message.subtype === 'status') {\n this.activity = message.status === 'compacting' ? { kind: 'compacting' } : undefined;\n this.emit();\n } else if (message.subtype === 'api_retry') {\n this.activity = { kind: 'retrying', attempt: message.attempt, max: message.max_retries, delayMs: message.retry_delay_ms };\n this.emit();\n } else if (message.subtype === 'background_tasks_changed') {\n this.tasks = message.tasks\n .filter((t) => !t.ambient)\n .map((t) => ({ id: t.task_id, description: t.description, type: t.subagent_type ?? t.task_type }));\n this.emit();\n }\n break;\n case 'rate_limit_event':\n recordLimit(message.rate_limit_info);\n break;\n case 'prompt_suggestion':\n this.suggestion = message.suggestion;\n this.emit();\n break;\n case 'result': {\n const stopped = this.interrupted;\n this.interrupted = false;\n const failed = !stopped && (message.subtype !== 'success' || message.is_error);\n this.error = failed\n ? readableError('errors' in message && message.errors.length > 0 ? message.errors.join('\\n') : ('result' in message ? String(message.result) : message.subtype))\n : undefined;\n this.lastTurn = {\n durationMs: message.duration_ms,\n ...(typeof message.total_cost_usd === 'number' ? { costUsd: message.total_cost_usd } : {}),\n ...(typeof message.usage?.output_tokens === 'number' ? { outputTokens: message.usage.output_tokens } : {}),\n };\n this.activity = undefined;\n // Messages that waited for this turn go in now: the next turn answers them.\n for (const waiting of this.queued.splice(0)) await feedFor(this.sessionId).publish(waiting);\n this.setBusy(false);\n this.emit();\n void this.readContext();\n if (!stopped) {\n void notify({\n title: this.title || 'Claude Code',\n body: failed ? `Stopped: ${this.error ?? 'error'}`.slice(0, 180) : 'Finished',\n sessionId: this.sessionId,\n tag: `${this.sessionId}:done`,\n });\n }\n break;\n }\n default:\n break;\n }\n }\n } catch (error) {\n this.error = readableError((error as Error).message);\n console.warn(`[pelican] session ${this.sessionId.slice(0, 8)} ended with an error:`, this.error);\n } finally {\n this.closed = true;\n this.started.reject(new Error(this.error ?? 'Claude Code stopped before it started'));\n for (const [, pending] of this.permissions) pending.resolve({ behavior: 'deny', message: 'Session closed.' });\n this.permissions.clear();\n this.setBusy(false);\n this.emit();\n // A newer run may have taken this session's place already (see sendMessage).\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId);\n sessionsChanged();\n }\n }\n}\n\nconst runs = new Map<string, SessionRun>();\n\nexport function getRun(sessionId: string): SessionRun | undefined {\n const run = runs.get(sessionId);\n return run && !run.closed ? run : undefined;\n}\n\n/** Status of a session this app runs; undefined when it has no Claude process here. */\nexport function runStatus(sessionId: string): SessionStatus | undefined {\n if (config.demo) return sessionId === DEMO_WAITING_SESSION ? 'waiting' : undefined;\n return getRun(sessionId)?.status();\n}\n\nexport function runState(sessionId: string): RunState | undefined {\n if (config.demo) return demoRunState(sessionId);\n return getRun(sessionId)?.state();\n}\n\nasync function isDirectory(dir: string): Promise<boolean> {\n return stat(dir).then((s) => s.isDirectory(), () => false);\n}\n\n/**\n * Sends a message, starting (or resuming) the session's Claude process when\n * none is running. Without a session id a new session starts in `cwd`.\n */\n/**\n * Whether another app (Claude Desktop, the terminal) has worked on the session since this\n * run's Claude last did. Its process then holds a conversation this one has not seen, and a\n * message sent to it would continue an old version, beside the other: it is started afresh.\n */\nasync function staleRun(run: SessionRun): Promise<boolean> {\n if (run.busy || run.hasBackgroundTasks) return false;\n const other = (await liveProcesses()).get(run.sessionId);\n if (other?.updatedAt && other.updatedAt > run.lastActive) return true;\n // An app that has closed since leaves no process to ask: a turn in the transcript newer than\n // anything this run did is the sign.\n const file = await transcriptPath(run.sessionId);\n const last = file ? (await lastTurnTime(file))?.lastTurn : undefined;\n return Boolean(last && !last.copied && last.time > run.lastActive + 2000);\n}\n\n/** The session's run, unless it holds an older version of the conversation: then it is closed. */\nasync function currentRun(sessionId: string): Promise<SessionRun | undefined> {\n const run = getRun(sessionId);\n if (run && (await staleRun(run))) {\n run.close();\n if (runs.get(sessionId) === run) runs.delete(sessionId);\n return getRun(sessionId);\n }\n return run;\n}\n\nexport async function sendMessage(target: { sessionId?: string; cwd?: string }, input: SendInput): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing runs. Start Pelican without --demo to talk to Claude.');\n if (target.sessionId) {\n const existing = await currentRun(target.sessionId);\n if (existing) {\n await existing.send(input);\n return existing.sessionId;\n }\n const info = await sessionInfo(target.sessionId);\n const cwd = info?.cwd ?? target.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`The session's folder is missing: ${cwd ?? '(unknown)'}`);\n // Another request may have started one while this one looked the folder up.\n const started = getRun(target.sessionId);\n if (started) {\n await started.send(input);\n return started.sessionId;\n }\n const run = new SessionRun(target.sessionId, cwd, input.settings, true);\n runs.set(run.sessionId, run);\n run.start();\n await run.send(input);\n return run.sessionId;\n }\n const cwd = target.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`Not a folder: ${cwd ?? '(none)'}`);\n const run = new SessionRun(randomUUID(), cwd, input.settings, false);\n runs.set(run.sessionId, run);\n run.start();\n await run.send(input);\n return run.sessionId;\n}\n\n/**\n * Replaces the session's last turn: Claude resumes it up to `entry` (the row just before the\n * prompt being replaced) and gets `input` instead, in the same session, as rewinding does in\n * Claude Code. The old turn stays in the transcript, off the conversation's line.\n */\nexport async function replaceLastTurn(sessionId: string, cwd: string, entry: string, prompt: string, input: SendInput): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing runs.');\n const existing = getRun(sessionId);\n if (existing?.busy) throw new Error('Stop Claude before editing a prompt.');\n if (existing) {\n existing.close();\n runs.delete(sessionId);\n }\n const run = new SessionRun(sessionId, cwd, input.settings, true, { entry, dropsTurn: prompt });\n runs.set(sessionId, run);\n run.start();\n await run.send(input);\n return sessionId;\n}\n\n/**\n * The session's Claude process, started (resumed, with no turn) when there is\n * none: for what only a running process can do, like rewinding files.\n */\nexport async function ensureRun(sessionId: string, settings: RunSettings = {}): Promise<SessionRun> {\n if (config.demo) throw new Error('This is the demo: nothing runs.');\n const existing = await currentRun(sessionId);\n if (existing) return existing;\n const info = await sessionInfo(sessionId);\n const cwd = info?.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`The session's folder is missing: ${cwd ?? '(unknown)'}`);\n const started = getRun(sessionId);\n if (started) return started;\n const run = new SessionRun(sessionId, cwd, settings, true);\n runs.set(sessionId, run);\n run.start();\n return run;\n}\n\n/** Closes Claude processes that have been idle for a while; the next message resumes them. */\nsetInterval(() => {\n for (const run of runs.values()) {\n if (!run.busy && run.status() === 'idle' && Date.now() - run.lastActive > config.idleCloseMs) run.close();\n }\n}, 60_000).unref();\n\nexport function closeAll(): void {\n for (const run of runs.values()) run.close();\n}\n", "import { open, readdir, realpath, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { FileContent, GitFile, GitStatus, TreeEntry } from '../shared/protocol.js';\nimport { git } from './git.js';\n\nconst MAX_FILE = 512 * 1024;\nconst MAX_DIFF = 400_000;\n\n\nconst OUTSIDE = 'That path is outside the session\u2019s folder';\nconst within = (root: string, full: string) => full === root || full.startsWith(`${root}${path.sep}`);\n\n/**\n * A path inside the session's folder, or an error: the panels never reach outside it. No `..`\n * at all: resolving it by the text would cancel a linked folder before the link is checked\n * (`link/../x`), and the panels never ask for one.\n */\nexport function inside(cwd: string, relative: string): string {\n if ((relative ?? '').split(/[\\\\/]/).includes('..')) throw new Error(OUTSIDE);\n const root = path.resolve(cwd);\n const full = path.resolve(root, relative || '.');\n if (!within(root, full)) throw new Error(OUTSIDE);\n return full;\n}\n\n/** The same, for a path that exists, with links followed: a link may not lead out of the folder either. */\nasync function insideReal(cwd: string, relative: string): Promise<string> {\n const full = inside(cwd, relative);\n const [root, real] = await Promise.all([realpath(cwd), realpath(full)]);\n if (!within(root, real)) throw new Error(OUTSIDE);\n return real;\n}\n\nconst KIND: Record<string, GitFile['status']> = { M: 'modified', T: 'modified', A: 'added', D: 'deleted', R: 'renamed', C: 'added', U: 'conflicted' };\n\n/**\n * The repository the folder is in, when its work tree is the folder or a folder above it. A\n * repository whose config points its work tree somewhere else (core.worktree) would show files\n * from outside: Pelican treats that as no repository.\n */\nasync function repositoryOf(cwd: string): Promise<string | undefined> {\n try {\n const top = (await git(cwd, ['rev-parse', '--show-toplevel'], 5000)).trim();\n if (!top) return undefined;\n const [root, folder] = await Promise.all([realpath(top), realpath(cwd)]);\n return within(root, folder) ? root : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What changed in the session's folder since the last commit, with line counts. */\nexport async function gitStatus(cwd: string): Promise<GitStatus> {\n if (!(await repositoryOf(cwd))) return { repo: false };\n let raw: string;\n let prefix = '';\n try {\n // A session in a folder inside a repository sees that folder's changes, by its own paths.\n prefix = (await git(cwd, ['rev-parse', '--show-prefix'], 5000)).trim();\n raw = await git(cwd, ['status', '--porcelain=v2', '--branch', '-z', '--untracked-files=all', '--', '.']);\n } catch {\n return { repo: false };\n }\n const local = (file: string | undefined) => (file && prefix && file.startsWith(prefix) ? file.slice(prefix.length) : file);\n const out: { repo: true; branch?: string; ahead?: number; behind?: number; files: GitFile[] } = { repo: true, files: [] };\n const entries = raw.split('\\0');\n for (let i = 0; i < entries.length; i += 1) {\n const entry = entries[i]!;\n if (entry.startsWith('# branch.head ')) {\n const head = entry.slice(14);\n if (head !== '(detached)') out.branch = head;\n } else if (entry.startsWith('# branch.ab ')) {\n const [ahead, behind] = entry.slice(12).split(' ');\n out.ahead = Number(ahead?.slice(1)) || 0;\n out.behind = Number(behind?.slice(1)) || 0;\n } else if (entry.startsWith('1 ') || entry.startsWith('2 ') || entry.startsWith('u ')) {\n const parts = entry.split(' ');\n const xy = parts[1] ?? '..';\n const code = xy[0] !== '.' ? xy[0]! : xy[1]!;\n const file = entry.startsWith('1 ') ? parts.slice(8).join(' ') : entry.startsWith('2 ') ? parts.slice(9).join(' ') : parts.slice(10).join(' ');\n const status = entry.startsWith('u ') ? 'conflicted' : KIND[code] ?? 'modified';\n const item: GitFile = { path: local(file)!, status };\n if (entry.startsWith('2 ')) {\n const from = local(entries[i + 1]);\n if (from) item.from = from;\n i += 1;\n }\n out.files.push(item);\n } else if (entry.startsWith('? ')) {\n out.files.push({ path: local(entry.slice(2))!, status: 'untracked' });\n }\n }\n // Line counts against the last commit (or the empty tree before the first one).\n try {\n const base = await git(cwd, ['rev-parse', '--verify', '-q', 'HEAD']).then(() => 'HEAD', () => '4b825dc642cb6eb9a060e54bf8d69288fbee4904');\n const numstat = await git(cwd, ['diff', '--numstat', '--relative', '-z', base]);\n const counts = new Map<string, { added?: number; removed?: number }>();\n const fields = numstat.split('\\0');\n for (let i = 0; i < fields.length; i += 1) {\n const field = fields[i]!;\n if (!field) continue;\n const [added, removed, name] = field.split('\\t');\n // A rename lists its old and new paths in the next two fields.\n const file = name === '' ? fields[(i += 2)] : name;\n if (!file) continue;\n counts.set(file, { ...(added !== '-' ? { added: Number(added) } : {}), ...(removed !== '-' ? { removed: Number(removed) } : {}) });\n }\n for (const file of out.files) Object.assign(file, counts.get(file.path) ?? {});\n } catch {\n // Counts are a nicety.\n }\n // A new file is all added lines; git does not count those for files it does not track yet.\n await Promise.all(out.files.filter((f) => f.status === 'untracked').slice(0, 200).map(async (file) => {\n try {\n const content = await readProjectFile(cwd, file.path);\n if (content.text !== undefined) file.added = content.text.split('\\n').length - (content.text.endsWith('\\n') ? 1 : 0);\n } catch {\n // Unreadable; no count.\n }\n }));\n return out;\n}\n\n/** The diff of one file against the last commit; an untracked file shows as all added. */\nexport async function gitDiff(cwd: string, file: string): Promise<string> {\n if (!(await repositoryOf(cwd))) return '';\n // The file itself may be gone (a deleted file has a diff), but the folder it is in may not lead\n // out of the session's folder through a link.\n const full = inside(cwd, file);\n const [root, parent] = await Promise.all([realpath(cwd), realpath(path.dirname(full)).catch(() => undefined)]);\n if (parent && !within(root, parent)) throw new Error(OUTSIDE);\n let diff = '';\n try {\n diff = await git(cwd, ['diff', 'HEAD', '--', file]);\n } catch {\n diff = '';\n }\n if (!diff) {\n // Untracked (or no commits yet): git diff --no-index exits with 1 when the files differ.\n // `./`: a file named `-` would otherwise be read from stdin.\n diff = await git(cwd, ['diff', '--no-index', '--', '/dev/null', `./${file}`]).catch((error: { stdout?: string }) => error.stdout ?? '');\n }\n return diff.length > MAX_DIFF ? `${diff.slice(0, MAX_DIFF)}\\n\u2026 (diff cut short)` : diff;\n}\n\nconst HIDDEN = new Set(['.git', 'node_modules', '.DS_Store']);\n\n/** One folder of the session's tree: folders first, then files. */\nexport async function listTree(cwd: string, relative: string): Promise<TreeEntry[]> {\n const dir = await insideReal(cwd, relative);\n const names = await readdir(dir, { withFileTypes: true });\n const entries: TreeEntry[] = [];\n for (const entry of names) {\n if (HIDDEN.has(entry.name)) continue;\n const rel = path.join(relative, entry.name);\n if (entry.isDirectory()) entries.push({ name: entry.name, path: rel, dir: true });\n else if (entry.isFile() || entry.isSymbolicLink()) {\n const size = await stat(path.join(dir, entry.name)).then((s) => (s.isDirectory() ? -1 : s.size), () => undefined);\n if (size === -1) entries.push({ name: entry.name, path: rel, dir: true });\n else entries.push({ name: entry.name, path: rel, dir: false, ...(size !== undefined ? { size } : {}) });\n }\n }\n return entries.sort((a, b) => Number(b.dir) - Number(a.dir) || a.name.localeCompare(b.name, undefined, { numeric: true }));\n}\n\nconst IMAGE: Record<string, string> = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml' };\n\n/** A file to read on the phone: text up to half a megabyte, images as data, other binaries named only. */\nexport async function readProjectFile(cwd: string, relative: string): Promise<FileContent> {\n const full = await insideReal(cwd, relative);\n const info = await stat(full);\n const ext = path.extname(full).slice(1).toLowerCase();\n const handle = await open(full, 'r');\n try {\n if (IMAGE[ext] && info.size <= 4 * 1024 * 1024) {\n const data = Buffer.alloc(info.size);\n await handle.read(data, 0, info.size, 0);\n return { path: relative, size: info.size, image: `data:${IMAGE[ext]};base64,${data.toString('base64')}` };\n }\n const length = Math.min(info.size, MAX_FILE);\n const data = Buffer.alloc(length);\n await handle.read(data, 0, length, 0);\n if (data.subarray(0, 8000).includes(0)) return { path: relative, size: info.size, binary: true };\n return { path: relative, size: info.size, text: data.toString('utf8'), ...(info.size > MAX_FILE ? { truncated: true } : {}) };\n } finally {\n await handle.close();\n }\n}\n", "import { readFile, realpath, stat } from 'node:fs/promises';\nimport { isIP } from 'node:net';\nimport path from 'node:path';\n\nimport { getConnInfo } from '@hono/node-server/conninfo';\nimport { type Context, Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\n\nimport pkg from '../../package.json' with { type: 'json' };\nimport type { Attachment, ChatMessage, PermissionDecision, PermissionMode, RunSettings, SendMode, ServerInfo } from '../shared/protocol.js';\nimport { currentTasks } from '../shared/tasks.js';\nimport { exportMarkdown, fork, messageBefore, remove } from './actions.js';\nimport { setArchived } from './archive.js';\nimport { authMode, beginAttempt, checkPassword, checkToken, cookieName, issueCode, newSessionCookie, redeemCode, signedIn } from './auth.js';\nimport { config } from './config.js';\nimport { sessionsChanged } from './feed.js';\nimport { findUpload, listDirs, MAX_UPLOAD_BYTES, readUpload, removeUpload, saveUpload } from './files.js';\nimport { createScratchFolder, isDirectory } from './folders.js';\nimport { listCompletions, listModels, planUsage, probeMcpServers } from './models.js';\nimport { searchFiles } from './project-files.js';\nimport { addSubscription, pushKey, removeSubscription } from './push.js';\nimport { ensureRun, getRun, replaceLastTurn, runState, runStatus, sendMessage } from './runner.js';\nimport { runCommand } from './shell.js';\nimport { usageLimits } from './usage.js';\nimport { gitDiff, gitStatus, listTree, readProjectFile } from './workspace.js';\nimport { hostAllowed, isLoopback, originAllowed } from './security.js';\nimport { listSummaries, loadMessages, loadPage, loadSubagent, recordedSettings, renameSessionTitle, sentFiles, sessionInfo, sessionSummary } from './sessions.js';\nimport { rawEntry, rawImages, transcriptPath } from './transcripts.js';\nimport { claudeRanIn } from './trust.js';\n\nexport const app = new Hono();\n\n/**\n * Who is asking, for limiting sign-in attempts: the address of the connection.\n * Behind a proxy on this machine that says so (PELICAN_TRUSTED_PROXY=1), the\n * client the proxy added last to X-Forwarded-For, when that is an IP address.\n * Anyone can write that header, so it is never believed otherwise.\n */\nfunction clientAddress(c: Context): string {\n let remote = 'unknown';\n try {\n remote = getConnInfo(c).remote.address ?? 'unknown';\n } catch {\n // Not served by Node (tests): one bucket for all.\n }\n const address = remote.replace(/^::ffff:/, '');\n if (config.trustedProxy && isLoopback(address)) {\n const forwarded = c.req.header('x-forwarded-for')?.split(',').at(-1)?.trim();\n if (forwarded && isIP(forwarded)) return forwarded;\n }\n return address;\n}\n\nconst secure = (c: { req: { header: (name: string) => string | undefined; url: string } }) =>\n c.req.header('x-forwarded-proto') === 'https' || c.req.url.startsWith('https:');\n\nconst cookieHeader = (c: Context, name: string, value: string, maxAge: number) =>\n `${name}=${value}; Path=/; Max-Age=${maxAge}; HttpOnly; SameSite=Strict${secure(c) ? '; Secure' : ''}`;\n\n/** Answers only to host names that point at this server (DNS rebinding). */\napp.use('*', async (c, next) => {\n if (!hostAllowed(c.req.header('host'))) {\n return c.text('This host name is not allowed. Add it to PELICAN_ALLOWED_HOSTS.', 403);\n }\n await next();\n});\n\n/** What the page loads without fetch, so it cannot mark: an uploaded image, a download. */\nconst unmarked = (c: Context) => c.req.method === 'GET'\n && (/^\\/api\\/uploads\\/[^/]+$/.test(c.req.path) || /^\\/api\\/sessions\\/[^/]+\\/export$/.test(c.req.path));\n\n/** The Origin header as an origin (`null`, garbage and missing are none). */\nfunction originOf(header: string | undefined): string | undefined {\n if (!header || header === 'null') return undefined;\n try {\n return new URL(header).origin;\n } catch {\n return undefined;\n }\n}\n\napp.use('/api/*', async (c, next) => {\n const origin = c.req.header('origin');\n const parsed = originOf(origin);\n const allowedOrigin = Boolean(parsed && config.allowedOrigins.includes(parsed));\n // Another site's page can make a browser send requests here, reads included, and some reads\n // run programs (git, Claude Code). Browsers say where a request comes from: only Pelican's own\n // page, or a page the config allows, gets in.\n const site = c.req.header('sec-fetch-site');\n if (site && site !== 'same-origin' && site !== 'none' && !allowedOrigin) {\n return c.json({ error: 'Request from another site' }, 403);\n }\n // Pelican's page also marks every request. Another site cannot add a header without asking\n // first (CORS), and Pelican never says yes, so this holds in browsers that send no Sec-Fetch-Site.\n if (!unmarked(c) && c.req.header('x-pelican') !== '1') {\n return c.json({ error: 'Requests must come from Pelican (send the header X-Pelican: 1)' }, 403);\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD'\n && !originAllowed(origin, c.req.header('host'), c.req.header('x-forwarded-host'))) {\n return c.json({ error: 'Request from another site' }, 403);\n }\n if (!c.req.path.startsWith('/api/auth') && !signedIn(c.req.header('cookie'), c.req.header('authorization'))) {\n return c.json({ error: 'Sign in to continue', signIn: true }, 401);\n }\n if (config.demo && c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return c.json({ error: 'This is the demo: nothing runs and nothing changes. Start Pelican without --demo to talk to Claude.' }, 403);\n }\n await next();\n});\n\n// Bodies are small, except an upload; nothing is buffered past these sizes. Only signed-in\n// requests get this far, apart from signing in itself, whose limit is 4 KB.\nconst tooLarge = (c: Context) => c.json({ error: 'Request too large' }, 413);\nconst limits = {\n auth: bodyLimit({ maxSize: 4 * 1024, onError: tooLarge }),\n upload: bodyLimit({ maxSize: MAX_UPLOAD_BYTES + 64 * 1024, onError: tooLarge }),\n json: bodyLimit({ maxSize: 1024 * 1024, onError: tooLarge }),\n};\napp.use('/api/*', (c, next) => (c.req.path.startsWith('/api/auth') ? limits.auth : c.req.path === '/api/uploads' ? limits.upload : limits.json)(c, next));\n\napp.onError((error, c) => {\n console.warn('[pelican]', c.req.method, c.req.path, error.message);\n return c.json({ error: error.message }, 500);\n});\n\napp.get('/api/auth', (c) => c.json({\n required: authMode() !== 'none',\n mode: authMode(),\n signedIn: signedIn(c.req.header('cookie'), c.req.header('authorization')),\n}));\n\napp.post('/api/auth/login', async (c) => {\n const succeeded = beginAttempt(clientAddress(c));\n if (!succeeded) return c.json({ error: 'Too many attempts. Try again in a few minutes.' }, 429);\n const body = await c.req.json<{ password?: unknown; token?: unknown }>().catch(() => ({} as { password?: unknown; token?: unknown }));\n const mode = authMode();\n const ok = mode === 'password' ? typeof body.password === 'string' && (await checkPassword(body.password))\n : mode === 'token' ? typeof body.token === 'string' && checkToken(body.token.trim())\n : false;\n if (!ok) return c.json({ error: mode === 'token' ? 'That is not the access token' : 'Wrong password', mode }, 401);\n succeeded();\n const cookie = newSessionCookie();\n c.header('Set-Cookie', cookieHeader(c, cookie.name, cookie.value, cookie.maxAge));\n return c.json({ ok: true });\n});\n\napp.post('/api/auth/logout', (c) => {\n c.header('Set-Cookie', cookieHeader(c, cookieName(), '', 0));\n return c.json({ ok: true });\n});\n\n/** A one-time code for the QR code that signs a phone in: good once, for two minutes. */\napp.post('/api/access/code', (c) => {\n if (authMode() === 'none') return c.json({ code: null });\n return c.json({ code: issueCode() });\n});\n\napp.get('/api/info', (c) => {\n const info: ServerInfo = { machine: config.machine, home: config.home, version: pkg.version, auth: authMode() !== 'none', demo: config.demo };\n const key = pushKey();\n if (key) info.pushKey = key;\n return c.json(info);\n});\n\napp.get('/api/sessions', async (c) => c.json({ sessions: await listSummaries(runStatus) }));\n\napp.get('/api/sessions/:id', async (c) => {\n const id = c.req.param('id');\n const session = await sessionSummary(id, runStatus);\n const run = runState(id);\n if (!session && !run) return c.json({ error: 'No such session' }, 404);\n // The task list needs the whole conversation; the page may only have loaded its end.\n const tasks = currentTasks(await loadMessages(id));\n return c.json({ session: session ?? null, run: run ?? null, tasks, settings: await recordedSettings(id) });\n});\n\napp.get('/api/sessions/:id/messages', async (c) => {\n const before = c.req.query('before');\n const limit = Math.min(Number(c.req.query('limit') ?? 120) || 120, 500);\n return c.json(await loadPage(c.req.param('id'), before === undefined ? undefined : Number(before), limit));\n});\n\ntype SendBody = { text?: string; attachments?: string[]; settings?: RunSettings; uuid?: string; cwd?: string; scratch?: boolean; mode?: SendMode };\n\nconst PERMISSION_MODES: PermissionMode[] = ['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions'];\nconst permissionMode = (value: unknown): PermissionMode | undefined =>\n (PERMISSION_MODES as unknown[]).includes(value) ? (value as PermissionMode) : undefined;\n\n/** The settings a request may carry, and only those, each of its own type. */\nfunction cleanSettings(raw: unknown): RunSettings {\n const value = (raw && typeof raw === 'object' ? raw : {}) as Record<string, unknown>;\n const text = (v: unknown, max: number) => (typeof v === 'string' && v.length > 0 && v.length <= max ? v : undefined);\n const out: RunSettings = {};\n const model = text(value.model, 200);\n const effort = text(value.effort, 20);\n const mode = permissionMode(value.permissionMode);\n if (model) out.model = model;\n if (effort) out.effort = effort;\n if (typeof value.fast === 'boolean') out.fast = value.fast;\n if (typeof value.ultracode === 'boolean') out.ultracode = value.ultracode;\n if (mode) out.permissionMode = mode;\n return out;\n}\n\nconst sendMode = (value: unknown): SendMode | undefined => (value === 'steer' || value === 'queue' ? value : undefined);\nconst uuidOf = (value: unknown) => (typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) ? value : undefined);\n\n/** A message body of the right types, or why not: a wrong one is the client's error (400), not ours. */\nfunction sendBody(raw: unknown): SendBody | string {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return 'Not a message';\n const body = raw as Record<string, unknown>;\n if (body.text !== undefined && typeof body.text !== 'string') return 'The text must be a string';\n if (body.attachments !== undefined && (!Array.isArray(body.attachments) || body.attachments.length > 50 || !body.attachments.every((a) => typeof a === 'string'))) return 'Attachments must be upload ids';\n if (body.settings !== undefined && (typeof body.settings !== 'object' || body.settings === null)) return 'Settings must be an object';\n if (body.cwd !== undefined && typeof body.cwd !== 'string') return 'The folder must be a path';\n if (body.scratch !== undefined && typeof body.scratch !== 'boolean') return 'scratch must be true or false';\n return body as SendBody;\n}\n\nasync function attachmentsFrom(ids: string[] | undefined): Promise<Attachment[]> {\n const found = await Promise.all((ids ?? []).map((id) => findUpload(id)));\n return found.filter((a): a is Attachment => Boolean(a));\n}\n\napp.post('/api/sessions', async (c) => {\n const body = sendBody(await c.req.json().catch(() => undefined));\n if (typeof body === 'string') return c.json({ error: body }, 400);\n // A scratch session gets its folder only when its first message is sent, so backing out leaves nothing behind.\n const cwd = body.scratch ? await createScratchFolder() : await checkedFolder(body.cwd);\n if (!cwd) return c.json({ error: 'No such folder' }, 400);\n const uuid = uuidOf(body.uuid);\n const sessionId = await sendMessage({ cwd }, {\n text: typeof body.text === 'string' ? body.text : '',\n attachments: await attachmentsFrom(body.attachments),\n settings: cleanSettings(body.settings),\n ...(uuid ? { uuid } : {}),\n });\n return c.json({ sessionId });\n});\n\napp.post('/api/sessions/:id/messages', async (c) => {\n const body = sendBody(await c.req.json().catch(() => undefined));\n if (typeof body === 'string') return c.json({ error: body }, 400);\n const uuid = uuidOf(body.uuid);\n const mode = sendMode(body.mode);\n const sessionId = await sendMessage({ sessionId: c.req.param('id') }, {\n text: typeof body.text === 'string' ? body.text : '',\n attachments: await attachmentsFrom(body.attachments),\n settings: cleanSettings(body.settings),\n ...(uuid ? { uuid } : {}),\n ...(mode ? { mode } : {}),\n });\n return c.json({ sessionId });\n});\n\n/** Edits made, and being made, by the id the editor gave them: a retry gets the same result, never a second one. */\ntype Edited = { sessionId: string; inPlace: boolean };\nconst edits = new Map<string, { at: number } & Edited>();\nconst editing = new Map<string, Promise<Edited>>();\n\n/** A prompt the user wrote (text or images), not a tool's result or injected context. */\nconst isPrompt = (m: ChatMessage) => m.role === 'user' && !m.meta && m.blocks.some((b) => b.type === 'text' || b.type === 'image');\n\n/** The images of a prompt, saved as uploads again so the edited prompt carries the ones kept. */\nasync function imagesOf(sessionId: string, uuid: string, keep: unknown): Promise<Attachment[]> {\n const file = await transcriptPath(sessionId);\n if (!file) return [];\n const images = await rawImages(file, uuid);\n const wanted = Array.isArray(keep) ? new Set(keep.filter((i): i is number => Number.isInteger(i))) : new Set(images.map((_, i) => i));\n const kept: Attachment[] = [];\n for (const [i, image] of images.entries()) {\n if (!wanted.has(i) || image.type !== 'base64' || !image.data) continue;\n const ext = image.mediaType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'png';\n kept.push(await saveUpload(new File([Buffer.from(image.data, 'base64')], `image-${i + 1}.${ext}`, { type: image.mediaType })));\n }\n return kept;\n}\n\n/**\n * Edit a prompt and send it again, as one request.\n * - The last prompt is replaced in place, as rewinding does in Claude Code: the session goes on\n * from just before it with the new text (the old turn stays in the transcript, off the line).\n * - An earlier one branches: a copy of the conversation up to just before it gets the new text\n * (the first prompt: a new session in the same folder), and this session stays as it was.\n * A branch is new work: it never starts in Bypass.\n * If the send fails, a branch and the copied images are removed, so nothing is left behind.\n */\ntype EditFailure = { error: string; status: 404 | 409 };\n\n/** Waits until the Claude of a session it just started is running; a start that fails throws. */\nasync function claudeStarted(sessionId: string): Promise<void> {\n const run = getRun(sessionId);\n if (!run) return;\n let timer: NodeJS.Timeout | undefined;\n try {\n await Promise.race([run.ready, new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 45_000);\n })]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function makeEdit(id: string, before: string, body: { text: string; settings?: unknown; keepImages?: unknown }, key: string): Promise<Edited | EditFailure> {\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return { error: 'The session\u2019s folder is missing', status: 404 };\n if (getRun(id)?.busy) return { error: 'Stop Claude before editing an earlier prompt.', status: 409 };\n const messages = await loadMessages(id);\n const at = messages.findIndex((m) => m.uuid === before);\n if (at < 0) return { error: 'That message is not in this session', status: 404 };\n const previous = at === 0 ? null : messages[at - 1]!.uuid;\n const last = !messages.slice(at + 1).some(isPrompt);\n const file = await transcriptPath(id);\n // In place only for the last prompt, after another one (the first has nothing to go on from),\n // when no background task would be cut off by restarting Claude.\n const entry = last && previous !== null && file && !getRun(id)?.hasBackgroundTasks ? (await rawEntry(file, before))?.parentUuid : undefined;\n const settings = cleanSettings(body.settings);\n if (!entry && settings.permissionMode === 'bypassPermissions') settings.permissionMode = 'default';\n const attachments = await imagesOf(id, before, body.keepImages);\n const message = { text: body.text, attachments, settings, uuid: key };\n let branch: string | undefined;\n let started: string | undefined;\n try {\n if (entry) {\n started = await replaceLastTurn(id, info.cwd, entry, before, message);\n await claudeStarted(started);\n return { sessionId: started, inPlace: true };\n }\n if (previous !== null) branch = await fork(id, previous);\n started = await sendMessage(branch ? { sessionId: branch } : { cwd: info.cwd }, message);\n // Only a Claude that started makes the branch real; one that could not start leaves nothing.\n await claudeStarted(started);\n return { sessionId: started, inPlace: false };\n } catch (error) {\n if (branch) await remove(branch).catch(() => undefined);\n else if (started && !entry) await remove(started).catch(() => undefined);\n await Promise.all(attachments.map((a) => removeUpload(a.id)));\n throw error;\n }\n}\n\n/**\n * Edit a prompt and send it again, as one request.\n * - The last prompt is replaced in place, as rewinding does in Claude Code: the session goes on\n * from just before it with the new text (the old turn stays in the transcript, off the line).\n * - An earlier one branches: a copy of the conversation up to just before it gets the new text\n * (the first prompt: a new session in the same folder), and this session stays as it was.\n * A branch is new work: it never starts in Bypass.\n * If Claude cannot start, a branch and the copied images are removed, so nothing is left behind.\n * Requests with the same `uuid` share one edit, also while it is still being made.\n */\napp.post('/api/sessions/:id/edit', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json<{ before?: unknown; text?: unknown; settings?: unknown; uuid?: unknown; keepImages?: unknown }>()\n .catch(() => ({}) as Record<string, unknown>);\n const key = uuidOf(body.uuid);\n const before = uuidOf(body.before);\n if (!key || !before || typeof body.text !== 'string' || !body.text.trim()) return c.json({ error: 'Nothing to send' }, 400);\n for (const [k, v] of edits) if (Date.now() - v.at > 10 * 60_000) edits.delete(k);\n const done = edits.get(key);\n if (done) return c.json({ sessionId: done.sessionId, inPlace: done.inPlace });\n // Registered before anything is awaited, so a second request with this id waits for this one.\n let work = editing.get(key) as Promise<Edited | EditFailure> | undefined;\n if (!work) {\n const made = makeEdit(id, before, { text: body.text, settings: body.settings, keepImages: body.keepImages }, key);\n work = made;\n editing.set(key, made as Promise<Edited>);\n void made.then((result) => {\n if (!('error' in result)) edits.set(key, { at: Date.now(), ...result });\n }, () => undefined).finally(() => editing.delete(key));\n }\n const result = await work;\n if ('error' in result) return c.json({ error: result.error }, result.status);\n return c.json(result);\n});\n\napp.post('/api/sessions/:id/interrupt', async (c) => {\n await getRun(c.req.param('id'))?.interrupt();\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/permissions/:requestId', async (c) => {\n const decision = await c.req.json<PermissionDecision>().catch(() => undefined);\n const raw = (decision ?? {}) as Record<string, unknown>;\n const valid = (raw.behavior === 'allow' || raw.behavior === 'deny')\n && (raw.message === undefined || typeof raw.message === 'string')\n && (raw.remember === undefined || typeof raw.remember === 'boolean')\n && (raw.updatedInput === undefined || (typeof raw.updatedInput === 'object' && raw.updatedInput !== null && !Array.isArray(raw.updatedInput)))\n && (raw.permissionMode === undefined || Boolean(permissionMode(raw.permissionMode)));\n if (!decision || !valid) return c.json({ error: 'Not a decision' }, 400);\n const ok = getRun(c.req.param('id'))?.decide(c.req.param('requestId'), decision) ?? false;\n return ok ? c.json({ ok }) : c.json({ error: 'That request is no longer pending' }, 409);\n});\n\n/** Model, effort, speed, ultracode or mode changed while Claude runs: it switches at its next step. */\napp.post('/api/sessions/:id/settings', async (c) => {\n const body = await c.req.json<{ settings?: unknown }>().catch(() => ({}) as { settings?: unknown });\n if (!body.settings || typeof body.settings !== 'object') return c.json({ error: 'No settings' }, 400);\n await getRun(c.req.param('id'))?.updateSettings(cleanSettings(body.settings));\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/mode', async (c) => {\n const body = await c.req.json<{ permissionMode?: unknown }>();\n const mode = permissionMode(body.permissionMode);\n if (!mode) return c.json({ error: 'No such mode' }, 400);\n await getRun(c.req.param('id'))?.setPermissionMode(mode);\n return c.json({ ok: true });\n});\n\napp.patch('/api/sessions/:id', async (c) => {\n const { title } = await c.req.json<{ title?: string }>();\n if (!title?.trim()) return c.json({ error: 'Title is empty' }, 400);\n await renameSessionTitle(c.req.param('id'), title.trim());\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/fork', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json<{ upTo?: string; before?: string; title?: string }>().catch(() => ({} as { upTo?: string; before?: string; title?: string }));\n let upTo = body.upTo;\n if (body.before) {\n const previous = await messageBefore(id, body.before);\n if (previous === undefined) return c.json({ error: 'That message is not in this session' }, 404);\n // Nothing comes before the first prompt: the caller starts a new session instead.\n if (previous === null) return c.json({ sessionId: null });\n upTo = previous;\n }\n return c.json({ sessionId: await fork(id, upTo, body.title) });\n});\n\n/** Put a session away from the list, or bring it back; nothing else changes. */\napp.post('/api/sessions/:id/archive', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const body = await c.req.json<{ archived?: unknown }>().catch(() => ({}) as { archived?: unknown });\n if (!id || typeof body.archived !== 'boolean') return c.json({ error: 'Say archived: true or false' }, 400);\n await setArchived(id, body.archived);\n sessionsChanged();\n return c.json({ ok: true });\n});\n\napp.delete('/api/sessions/:id', async (c) => {\n const id = c.req.param('id');\n if (getRun(id)?.busy) return c.json({ error: 'Stop Claude in this session before deleting it.' }, 409);\n getRun(id)?.close();\n await remove(id);\n return c.json({ ok: true });\n});\n\napp.get('/api/sessions/:id/export', async (c) => {\n const { title, markdown } = await exportMarkdown(c.req.param('id'));\n const name = `${title.replace(/[^\\p{L}\\p{N} _-]+/gu, '').trim().slice(0, 60) || 'session'}.md`;\n return c.body(markdown, 200, {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(name)}`,\n 'X-Content-Type-Options': 'nosniff',\n });\n});\n\napp.get('/api/models', async (c) => c.json(await listModels()));\n\napp.get('/api/commands', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ commands: [], agents: [] });\n return c.json(await listCompletions(cwd));\n});\n\n/** What `/usage` shows in Claude Code: asked of claude.ai when Settings opens, kept a minute. */\napp.get('/api/usage/plan', async (c) => c.json({ plan: await planUsage() }));\n\napp.get('/api/usage', (c) => c.json({\n limits: config.demo\n ? [\n { type: 'five_hour', status: 'allowed', utilization: 0.42, resetsAt: Date.now() + 2.4 * 3600_000, at: Date.now() },\n { type: 'seven_day', status: 'allowed', utilization: 0.18, resetsAt: Date.now() + 3.5 * 86400_000, at: Date.now() },\n ]\n : usageLimits(),\n}));\n\n/** The folder a workspace request is about: the session's own, which must exist. */\n/** Whether a path is inside the demo's own folder (the demo never shows anything else). */\nasync function inDemo(dir: string): Promise<boolean> {\n try {\n const [real, root] = await Promise.all([realpath(dir), realpath(config.home)]);\n return real === root || real.startsWith(`${root}${path.sep}`);\n } catch {\n return false;\n }\n}\n\n/** A folder named in a request: an existing absolute path, and in the demo only the demo's own. */\nasync function checkedFolder(cwd: string | undefined): Promise<string | undefined> {\n if (!cwd || !path.isAbsolute(cwd) || !(await isDirectory(cwd))) return undefined;\n if (config.demo && !(await inDemo(cwd))) return undefined;\n return cwd;\n}\n\nconst folderOf = (c: Context) => checkedFolder(c.req.query('cwd'));\n\n/** Whether a folder is in a git repository, by its `.git` and its parents' (this runs nothing). */\nasync function insideRepository(cwd: string): Promise<boolean> {\n for (let dir = path.resolve(cwd); ; dir = path.dirname(dir)) {\n if (await stat(path.join(dir, '.git')).then(() => true, () => false)) return true;\n if (path.dirname(dir) === dir) return false;\n }\n}\n\n/** Git runs only where Claude Code has run: a folder you are only shown runs nothing of its own. */\nconst gitAllowed = (cwd: string) => (config.demo ? Promise.resolve(true) : claudeRanIn(cwd));\n\napp.get('/api/git', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ error: 'No such folder' }, 404);\n if (!(await gitAllowed(cwd))) return c.json(await insideRepository(cwd) ? { repo: false, untrusted: true } : { repo: false });\n return c.json(await gitStatus(cwd));\n});\n\napp.get('/api/git/diff', async (c) => {\n const cwd = await folderOf(c);\n const file = c.req.query('path');\n if (!cwd || !file) return c.json({ error: 'No such file' }, 404);\n if (!(await gitAllowed(cwd))) return c.json({ diff: '' });\n return c.json({ diff: await gitDiff(cwd, file) });\n});\n\napp.get('/api/tree', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ error: 'No such folder' }, 404);\n return c.json({ entries: await listTree(cwd, c.req.query('path') ?? '') });\n});\n\napp.get('/api/file', async (c) => {\n const cwd = await folderOf(c);\n const file = c.req.query('path');\n if (!cwd || !file) return c.json({ error: 'No such file' }, 404);\n return c.json(await readProjectFile(cwd, file));\n});\n\napp.post('/api/sessions/:id/shell', async (c) => {\n const id = c.req.param('id');\n const { command } = await c.req.json<{ command?: string }>().catch(() => ({ command: undefined }));\n if (!command?.trim()) return c.json({ error: 'No command' }, 400);\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return c.json({ error: 'The session\u2019s folder is missing' }, 404);\n const result = await runCommand(info.cwd, command.trim());\n // Into the conversation without a turn: Claude reads it with the next message.\n await (await ensureRun(id)).appendShell(result);\n return c.json(result);\n});\n\napp.post('/api/sessions/:id/rewind', async (c) => {\n const { uuid, dryRun } = await c.req.json<{ uuid?: string; dryRun?: boolean }>().catch(() => ({ uuid: undefined, dryRun: undefined }));\n if (!uuid) return c.json({ error: 'Which prompt?' }, 400);\n const run = await ensureRun(c.req.param('id'));\n if (run.busy) return c.json({ error: 'Stop Claude before rewinding files.' }, 409);\n return c.json(await run.rewind(uuid, dryRun !== false));\n});\n\napp.get('/api/sessions/:id/mcp', async (c) => {\n const id = c.req.param('id');\n const run = getRun(id);\n if (run) return c.json({ servers: await run.mcpServers(), live: true });\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return c.json({ servers: [], live: false });\n return c.json({ servers: await probeMcpServers(info.cwd), live: false });\n});\n\napp.post('/api/sessions/:id/mcp/:name', async (c) => {\n const run = getRun(c.req.param('id'));\n if (!run) return c.json({ error: 'Claude is not running in this session' }, 409);\n const change = await c.req.json<{ enabled?: boolean; reconnect?: boolean }>().catch(() => ({}));\n await run.setMcpServer(c.req.param('name'), change);\n return c.json({ servers: await run.mcpServers() });\n});\n\napp.post('/api/sessions/:id/tasks/:task/stop', async (c) => {\n await getRun(c.req.param('id'))?.stopTask(c.req.param('task'));\n return c.json({ ok: true });\n});\n\napp.get('/api/sessions/:id/sent', async (c) => {\n const file = c.req.query('path') ?? '';\n if (!file || !(await sentFiles(c.req.param('id'))).has(file)) return c.json({ error: 'Not a file Claude sent in this session' }, 404);\n try {\n return c.json(await readProjectFile(path.dirname(file), path.basename(file)));\n } catch {\n return c.json({ error: 'The file is gone' }, 404);\n }\n});\n\napp.get('/api/sessions/:id/agents/:agent', async (c) => {\n return c.json({ messages: await loadSubagent(c.req.param('id'), c.req.param('agent')) });\n});\n\napp.get('/api/files', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ files: [] });\n return c.json({ files: await searchFiles(cwd, c.req.query('q') ?? '') });\n});\n\n/**\n * Folders to start a new session in: those of recent sessions, without temp\n * and scratch folders and without folders that are gone. Two folders with the\n * same name are told apart by their parent.\n */\napp.get('/api/projects', async (c) => {\n const seen = new Map<string, { path: string; name: string; lastActivity: number; sessions: number }>();\n for (const s of await listSummaries(runStatus)) {\n if (!s.cwd || s.scratch || s.temp) continue;\n const entry = seen.get(s.cwd);\n if (entry) entry.sessions += 1;\n else seen.set(s.cwd, { path: s.cwd, name: s.project, lastActivity: s.lastActivity, sessions: 1 });\n }\n const existing = (await Promise.all([...seen.values()].map(async (p) => ((await isDirectory(p.path)) ? p : undefined))))\n .filter((p): p is NonNullable<typeof p> => Boolean(p));\n const counts = new Map<string, number>();\n for (const p of existing) counts.set(p.name, (counts.get(p.name) ?? 0) + 1);\n for (const p of existing) {\n if ((counts.get(p.name) ?? 0) > 1) p.name = `${path.basename(path.dirname(p.path))}/${p.name}`;\n }\n return c.json({ projects: existing });\n});\n\napp.get('/api/dirs', async (c) => {\n const asked = c.req.query('path');\n if (config.demo && asked && !(await inDemo(asked))) return c.json({ error: 'Not part of the demo' }, 404);\n try {\n return c.json(await listDirs(asked, c.req.query('hidden') === '1'));\n } catch (error) {\n return c.json({ error: (error as Error).message }, 400);\n }\n});\n\napp.post('/api/uploads', async (c) => {\n const body = await c.req.parseBody();\n const file = body.file;\n if (!(file instanceof File)) return c.json({ error: 'No file' }, 400);\n return c.json({ attachment: await saveUpload(file) });\n});\n\napp.get('/api/uploads/:id', async (c) => {\n const found = await readUpload(c.req.param('id'));\n if (!found) return c.notFound();\n // Shown in the page only as an image; anything else downloads. Either way it runs nothing:\n // no sniffing, no scripts, no frames.\n const image = found.attachment.mime.startsWith('image/') && found.attachment.mime !== 'image/svg+xml';\n return c.body(new Uint8Array(found.data), 200, {\n 'Content-Type': found.attachment.mime,\n 'Cache-Control': 'private, max-age=86400',\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Security-Policy': \"sandbox; default-src 'none'; img-src 'self' data:; frame-ancestors 'self'\",\n 'X-Frame-Options': 'SAMEORIGIN',\n ...(image ? {} : { 'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(found.attachment.name)}` }),\n });\n});\n\napp.get('/api/push/key', (c) => c.json({ key: pushKey() ?? null }));\n\n/** A push subscription as browsers make them: an https endpoint, a P-256 key, a 16-byte secret. */\nfunction validSubscription(value: unknown): value is { endpoint: string; keys: { p256dh: string; auth: string } } {\n const { endpoint, keys } = (value ?? {}) as { endpoint?: unknown; keys?: { p256dh?: unknown; auth?: unknown } };\n const bytes = (text: unknown) => (typeof text === 'string' && /^[\\w-]+=*$/.test(text) ? Buffer.from(text, 'base64url').length : -1);\n return typeof endpoint === 'string' && endpoint.length <= 2048 && endpoint.startsWith('https://')\n && bytes(keys?.p256dh) === 65 && bytes(keys?.auth) === 16;\n}\n\nconst pageUrl = (value: unknown) => typeof value === 'string' && value.length <= 2048 && /^https?:\\/\\//.test(value);\n\napp.post('/api/push/subscribe', async (c) => {\n const body = await c.req.json<{ subscription?: unknown; openUrl?: unknown }>().catch(() => ({}) as { subscription?: unknown; openUrl?: unknown });\n if (!validSubscription(body.subscription)) return c.json({ error: 'Not a push subscription' }, 400);\n const { endpoint, keys } = body.subscription;\n await addSubscription({ endpoint, keys: { p256dh: keys.p256dh, auth: keys.auth }, ...(pageUrl(body.openUrl) ? { openUrl: body.openUrl as string } : {}) });\n return c.json({ ok: true });\n});\n\napp.post('/api/push/unsubscribe', async (c) => {\n const { endpoint } = await c.req.json<{ endpoint?: unknown }>().catch(() => ({ endpoint: undefined }));\n if (typeof endpoint !== 'string') return c.json({ error: 'No endpoint' }, 400);\n await removeSubscription(endpoint);\n return c.json({ ok: true });\n});\n\napp.all('/api/*', (c) => c.json({ error: 'Not found' }, 404));\n\nconst TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml', '.png': 'image/png', '.ico': 'image/x-icon', '.webmanifest': 'application/manifest+json',\n '.json': 'application/json', '.woff2': 'font/woff2', '.txt': 'text/plain; charset=utf-8',\n};\n\n/**\n * - Only Pelican's own origin, and pages the config names, may show it in a frame: any other page\n * could lay its own buttons over Pelican's and have you approve something (clickjacking).\n * - Images and media come only from Pelican: a picture in Claude's reply, or in a page it wrote,\n * could otherwise carry what is in the conversation to another server just by loading. The\n * preview frames inherit this, on top of their own policy (Preview.tsx).\n */\nconst POLICY: Record<string, string> = {\n 'Content-Security-Policy': [\n `frame-ancestors 'self'${config.frameAncestors.map((o) => ` ${o}`).join('')}`,\n \"frame-src 'self' blob: data:\",\n \"img-src 'self' data: blob:\",\n \"media-src 'self' data: blob:\",\n \"object-src 'none'\",\n \"base-uri 'self'\",\n ].join('; '),\n ...(config.frameAncestors.length === 0 ? { 'X-Frame-Options': 'SAMEORIGIN' } : {}),\n};\n\n/** The web app. Every URL in it is relative, so it works under any path a proxy mounts it at. */\napp.get('/*', async (c) => {\n if (!config.webDir) return c.text('The web app is not built. Run `npm run build`, or use `npm run dev`.', 503);\n const root = config.webDir;\n let pathname: string;\n try {\n pathname = decodeURIComponent(new URL(c.req.url).pathname);\n } catch {\n return c.text('Bad path', 400);\n }\n // Opening the link Pelican printed (\u2026/?token=\u2026), or the QR code from Settings (\u2026/?code=\u2026),\n // signs this browser in, then drops the secret from the address.\n const token = c.req.query('token');\n const code = c.req.query('code');\n if (token !== undefined || code !== undefined) {\n const url = new URL(c.req.url);\n url.searchParams.delete('token');\n url.searchParams.delete('code');\n // Relative to where the page is, so it works under a proxy's path prefix, and can never\n // name another site (`//other.example/` would).\n const location = `./${url.pathname.split('/').pop() ?? ''}${url.search}`;\n const ok = token !== undefined ? checkToken(token) : redeemCode(code);\n if (!ok) return c.body(null, 302, { Location: location, 'Cache-Control': 'no-store' });\n const cookie = newSessionCookie();\n return c.body(null, 302, { Location: location, 'Set-Cookie': cookieHeader(c, cookie.name, cookie.value, cookie.maxAge), 'Cache-Control': 'no-store' });\n }\n const requested = path.normalize(pathname).replace(/^(\\.\\.[/\\\\])+/, '');\n let file = path.join(root, requested);\n if (!file.startsWith(root) || requested === '/' || !path.extname(file)) file = path.join(root, 'index.html');\n try {\n const data = await readFile(file);\n const ext = path.extname(file);\n const hashed = file.includes(`${path.sep}assets${path.sep}`);\n return c.body(new Uint8Array(data), 200, {\n 'Content-Type': TYPES[ext] ?? 'application/octet-stream',\n 'Cache-Control': hashed ? 'public, max-age=31536000, immutable' : 'no-cache',\n 'X-Content-Type-Options': 'nosniff',\n 'Referrer-Policy': 'same-origin',\n ...POLICY,\n });\n } catch {\n return c.notFound();\n }\n});\n", "import type { IncomingMessage } from 'node:http';\n\nimport { serve } from '@hono/node-server';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nimport type { ClientEvent, ServerEvent } from '../shared/protocol.js';\nimport { app } from './app.js';\nimport { loadAuth, signedIn } from './auth.js';\nimport { config } from './config.js';\nimport { connect, subscribe } from './feed.js';\nimport { initPush } from './push.js';\nimport { closeAll, runState } from './runner.js';\nimport { hostAllowed, originAllowed } from './security.js';\n\nconst SESSION_ID = /^[\\w-]{1,100}$/;\n/** A browser follows a handful of sessions at once; more from one socket is not a browser. */\nconst MAX_SUBSCRIPTIONS = 64;\n\n/** A client event, or undefined for anything else. */\nfunction clientEvent(text: string): ClientEvent | undefined {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (!value || typeof value !== 'object') return undefined;\n const { type, sessionId } = value as Record<string, unknown>;\n if ((type !== 'subscribe' && type !== 'unsubscribe') || typeof sessionId !== 'string' || !SESSION_ID.test(sessionId)) return undefined;\n return { type, sessionId };\n}\n\n/** Starts the HTTP server and the WebSocket that streams sessions. Resolves once it listens. */\nexport async function startServer(): Promise<{ url: string }> {\n await loadAuth();\n await initPush();\n\n const url = await new Promise<string>((resolve, reject) => {\n const server = serve({ fetch: app.fetch, hostname: config.host, port: config.port }, (info) => {\n const host = info.family === 'IPv6' ? `[${info.address}]` : info.address;\n resolve(`http://${host}:${info.port}/`);\n });\n server.on('error', reject);\n\n // Client events are a few hundred bytes; nothing bigger is read.\n const wss = new WebSocketServer({ noServer: true, maxPayload: 64 * 1024 });\n\n server.on('upgrade', (req: IncomingMessage, socket, head) => {\n const pathname = new URL(req.url ?? '/', 'http://x').pathname;\n const forwarded = req.headers['x-forwarded-host'];\n // The same checks as every request: a known Host, a page of Pelican's own, a signed-in browser.\n const ok = pathname.endsWith('/api/ws')\n && hostAllowed(req.headers.host)\n && originAllowed(req.headers.origin, req.headers.host, Array.isArray(forwarded) ? forwarded[0] : forwarded)\n && signedIn(req.headers.cookie, req.headers.authorization);\n if (!ok) {\n socket.destroy();\n return;\n }\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n });\n\n wss.on('connection', (ws: WebSocket) => {\n const send = (event: ServerEvent) => {\n if (ws.readyState === ws.OPEN) ws.send(JSON.stringify(event));\n };\n const disconnect = connect(send);\n const subscriptions = new Map<string, () => void>();\n // Proxies close idle sockets (Cloudflare after 100 s); a ping every 25 s keeps it open.\n const ping = setInterval(() => ws.ping(), 25_000);\n // A frame too large or malformed closes this socket; unheard, the error would stop the server.\n ws.on('error', () => ws.terminate());\n\n ws.on('message', (data) => {\n const event = clientEvent(String(data));\n if (!event) return;\n if (event.type === 'subscribe' && !subscriptions.has(event.sessionId)) {\n if (subscriptions.size >= MAX_SUBSCRIPTIONS) return;\n subscriptions.set(event.sessionId, subscribe(event.sessionId, send));\n const state = runState(event.sessionId);\n if (state) send({ type: 'run', state });\n } else if (event.type === 'unsubscribe') {\n subscriptions.get(event.sessionId)?.();\n subscriptions.delete(event.sessionId);\n }\n });\n\n ws.on('close', () => {\n clearInterval(ping);\n disconnect();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n });\n });\n\n const shutdown = () => {\n closeAll();\n server.close();\n setTimeout(() => process.exit(0), 500).unref();\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n return { url };\n}\n", "import qrcode from 'qrcode-generator';\n\nconst QUIET = 2;\n\n/** The dark and light modules of a QR code for `text`, with a quiet border. */\nexport function qrModules(text: string): boolean[][] {\n const qr = qrcode(0, 'M');\n qr.addData(text);\n qr.make();\n const size = qr.getModuleCount();\n const rows: boolean[][] = [];\n for (let y = -QUIET; y < size + QUIET; y += 1) {\n const row: boolean[] = [];\n for (let x = -QUIET; x < size + QUIET; x += 1) row.push(x >= 0 && y >= 0 && x < size && y < size && qr.isDark(y, x));\n rows.push(row);\n }\n return rows;\n}\n\n/** The same code as an SVG, black on white whatever the theme. */\nexport function qrSvg(text: string): string {\n const rows = qrModules(text);\n const size = rows.length;\n let path = '';\n rows.forEach((row, y) => row.forEach((dark, x) => {\n if (dark) path += `M${x} ${y}h1v1h-1z`;\n }));\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${size} ${size}\" shape-rendering=\"crispEdges\"><rect width=\"${size}\" height=\"${size}\" fill=\"#fff\"/><path d=\"${path}\" fill=\"#000\"/></svg>`;\n}\n", "import { qrModules } from '../shared/qr.js';\n\n/** A QR code for a terminal: two rows per line, drawn in black and white whatever the theme. */\nexport function qrTerminal(text: string): string {\n const rows = qrModules(text);\n const lines: string[] = [];\n for (let y = 0; y < rows.length; y += 2) {\n let line = '';\n for (let x = 0; x < rows[y]!.length; x += 1) {\n const top = rows[y]![x] ? 16 : 231;\n const bottom = rows[y + 1]?.[x] ? 16 : 231;\n line += `\\x1b[38;5;${top};48;5;${bottom}m\u2580`;\n }\n lines.push(`${line}\\x1b[0m`);\n }\n return lines.join('\\n');\n}\n", "import { spawn } from 'node:child_process';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { parseArgs } from 'node:util';\n\nimport pkg from '../../package.json' with { type: 'json' };\nimport { config } from './config.js';\nimport { listensLocally } from './security.js';\n\nconst DOCS = 'https://ki-seki.github.io/pelican/docs.html';\n\nconst HELP = `Pelican ${pkg.version}: your Claude Code sessions, from any browser.\n\nUsage\n pelican [options] Start the server\n pelican token Print the link that signs a browser in\n pelican token --reset Make a new access token; old links stop working\n pelican password Sign in with a password instead of the token\n pelican password --off Remove the password; the token signs in again\n\nOptions\n -p, --port <port> Port to listen on (default 7860, or PELICAN_PORT)\n -H, --host <address> Address to listen on (default 127.0.0.1, or PELICAN_HOST)\n --name <name> Name shown for this machine (default: its host name)\n --no-auth Ask no one to sign in. Only when something in front\n of Pelican already authenticates.\n --demo Show made-up sessions; nothing runs\n --open Open the browser\n -v, --version Print the version\n -h, --help Show this help\n\nPelican runs Claude Code, and so commands, as you. It listens on 127.0.0.1, and\nevery browser signs in, with the access token in the link Pelican prints or\nwith your password. To use it from your phone, see ${DOCS}#phone\n`;\n\n/** Reads a line from the terminal without echoing it. */\nfunction askHidden(prompt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const input = process.stdin;\n if (!input.isTTY) {\n reject(new Error('Run `pelican password` in a terminal, or pipe the password in with --stdin.'));\n return;\n }\n process.stdout.write(prompt);\n input.setRawMode(true);\n input.resume();\n input.setEncoding('utf8');\n let value = '';\n const onData = (chunk: string) => {\n for (const char of chunk) {\n if (char === '\\r' || char === '\\n') {\n input.setRawMode(false);\n input.pause();\n input.off('data', onData);\n process.stdout.write('\\n');\n resolve(value);\n return;\n }\n if (char === '\\u0003') {\n process.stdout.write('\\n');\n process.exit(130);\n }\n if (char === '\\u007f' || char === '\\b') value = value.slice(0, -1);\n else value += char;\n }\n };\n input.on('data', onData);\n });\n}\n\nasync function readStdin(): Promise<string> {\n let data = '';\n for await (const chunk of process.stdin) data += chunk;\n return data.replace(/\\r?\\n$/, '');\n}\n\nasync function passwordCommand(off: boolean, stdin: boolean): Promise<void> {\n const { clearPassword, loadAuth, setPassword } = await import('./auth.js');\n await loadAuth();\n if (off) {\n await clearPassword();\n console.log('Password removed: browsers sign in with the access token again (`pelican token`). Restart Pelican to apply.');\n return;\n }\n const password = stdin ? await readStdin() : await askHidden('New password: ');\n if (password.length < 8) throw new Error('Use at least 8 characters.');\n if (!stdin && (await askHidden('Repeat it: ')) !== password) throw new Error('The two did not match.');\n await setPassword(password);\n console.log(`Password saved in ${config.configDir}. Restart Pelican to apply; signed-in browsers are signed out.`);\n}\n\n/** The link with the access token, for this computer's own address. */\nconst tokenLink = (base: string, token: string) => `${base}?token=${token}`;\n\n/** Pelican's address on this computer: localhost, unless it listens on one other address only. */\nfunction localAddress(): string {\n const h = config.host;\n const host = ['0.0.0.0', '::', '127.0.0.1', 'localhost', '::1'].includes(h) ? 'localhost' : h.includes(':') ? `[${h}]` : h;\n return `http://${host}:${config.port}/`;\n}\n\nasync function tokenCommand(reset: boolean): Promise<void> {\n const { accessToken, authMode, loadAuth, resetToken } = await import('./auth.js');\n await loadAuth();\n if (authMode() === 'none') {\n console.log('Sign-in is off (--no-auth or PELICAN_AUTH=none), so there is no access token.');\n return;\n }\n if (reset) {\n await resetToken();\n console.log('New access token made. Restart Pelican to apply; browsers signed in with the old one are signed out.');\n }\n if (authMode() === 'password') {\n console.log('A password is set, so browsers sign in with it. `pelican password --off` goes back to the token.');\n return;\n }\n const token = accessToken();\n if (token) console.log(tokenLink(localAddress(), token));\n}\n\n/**\n * Opens Pelican in the browser. The link with the token is never put on a command line, where\n * other accounts could read it: on macOS a page only you can read redirects to it (and is\n * removed); elsewhere, where a browser may not open such a page, Pelican opens to its sign-in.\n */\nasync function openPelican(address: string, token: string | undefined): Promise<void> {\n if (!token || process.platform !== 'darwin') {\n openBrowser(address);\n return;\n }\n const file = path.join(config.configDir, 'open.html');\n try {\n await mkdir(config.configDir, { recursive: true, mode: 0o700 });\n await rm(file, { force: true });\n const link = tokenLink(address, token);\n await writeFile(file, `<!doctype html><meta http-equiv=\"refresh\" content=\"0;url=${link}\"><a href=\"${link}\">Open Pelican</a>\\n`, { mode: 0o600 });\n openBrowser(pathToFileURL(file).href);\n setTimeout(() => void rm(file, { force: true }), 30_000).unref();\n } catch {\n openBrowser(address);\n }\n}\n\nfunction openBrowser(url: string): void {\n const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n try {\n spawn(opener, [url], { stdio: 'ignore', detached: true, shell: process.platform === 'win32' }).on('error', () => {}).unref();\n } catch {\n // Opening a browser is a convenience; the address is printed above.\n }\n}\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n allowPositionals: true,\n options: {\n port: { type: 'string', short: 'p' },\n host: { type: 'string', short: 'H' },\n name: { type: 'string' },\n 'no-auth': { type: 'boolean' },\n demo: { type: 'boolean' },\n open: { type: 'boolean' },\n off: { type: 'boolean' },\n reset: { type: 'boolean' },\n stdin: { type: 'boolean' },\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n if (values.help) return void process.stdout.write(HELP);\n if (values.version) return void console.log(pkg.version);\n\n if (values.port) config.port = Number(values.port);\n if (values.host) config.host = values.host;\n if (values.name) config.machine = values.name;\n if (values['no-auth']) config.auth = 'none';\n if (!Number.isInteger(config.port) || config.port <= 0 || config.port > 65535) throw new Error(`Not a port: ${values.port}`);\n\n if (positionals[0] === 'password') return passwordCommand(Boolean(values.off), Boolean(values.stdin));\n if (positionals[0] === 'token') return tokenCommand(Boolean(values.reset));\n if (positionals.length > 0) throw new Error(`Unknown command: ${positionals.join(' ')}. See pelican --help.`);\n\n // --no-auth, or PELICAN_AUTH=none, is an explicit choice; the demo asks no one to sign in on its own.\n const noAuth = config.auth === 'none';\n if (values.demo) {\n config.demo = true;\n const { prepareDemo } = await import('./demo.js');\n await prepareDemo();\n if (!values.name) config.machine = 'demo';\n }\n\n const local = listensLocally(config.host);\n if (config.demo) {\n // The demo holds nothing private, but it signs no one in: beyond this computer only when asked to.\n if (!local && !noAuth) throw new Error('The demo signs no one in, so it listens on 127.0.0.1 only. Pass --no-auth to show it on your network.');\n config.auth = 'none';\n }\n const { accessToken, authMode, loadAuth } = await import('./auth.js');\n await loadAuth();\n\n const { configWarnings } = await import('./config.js');\n for (const warning of configWarnings) console.warn(`pelican: ${warning}`);\n\n const { startServer } = await import('./server.js');\n const { url } = await startServer();\n const shown = url.replace('://127.0.0.1:', '://localhost:');\n const token = accessToken();\n const mode = authMode();\n // The link with the token is a standing key: shown on a terminal, never written to a log\n // (a service's output file, the journal). `pelican token` prints it on demand.\n const interactive = Boolean(process.stdout.isTTY);\n const open = token && interactive ? tokenLink(shown, token) : shown;\n const protection = config.demo ? 'demo: made-up sessions, nothing runs'\n : mode === 'password' ? 'browsers sign in with your password'\n : mode === 'token' ? (interactive ? 'the link signs a browser in (`pelican token` prints it again)' : 'browsers sign in with the link `pelican token` prints')\n : local ? 'no sign-in (--no-auth)' : 'no sign-in (--no-auth): anyone who reaches this address can run commands as you';\n console.log(`\\n Pelican ${pkg.version} \u00B7 ${config.machine}\\n ${open}\\n ${protection}\\n`);\n if (!config.webDir) console.log(' The web app is not built: run `npm run build` (or use `npm run dev`).\\n');\n // Listening beyond this computer: the address a phone on the same network can open, as a QR code.\n if (!local) {\n const { qrTerminal } = await import('./qr.js');\n const lan = Object.values(os.networkInterfaces()).flat().find((a) => a && a.family === 'IPv4' && !a.internal);\n const base = config.host === '0.0.0.0' || config.host === '::' ? (lan ? `http://${lan.address}:${config.port}/` : undefined) : url;\n const phone = base && token && interactive ? tokenLink(base, token) : base;\n if (phone) console.log(` On your phone: ${phone}\\n${interactive ? `\\n${qrTerminal(phone).replace(/^/gm, ' ')}\\n` : ''}`);\n } else if (!config.demo) {\n console.log(` From your phone: ${DOCS}#phone\\n`);\n }\n if (values.open) await openPelican(shown, token);\n}\n\nmain().catch((error: Error) => {\n console.error(`pelican: ${error.message}`);\n process.exit(1);\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["os", "path", "text", "file", "cookieHeader", "code", "mkdir", "rm", "writeFile", "path", "git", "file", "text", "randomUUID", "mkdir", "readFile", "writeFile", "path", "text", "loaded", "before", "randomBytes", "mkdir", "os", "path", "execFile", "readFile", "path", "promisify", "run", "app", "text", "stat", "
|
|
3
|
+
"sources": ["../../package.json", "../../src/server/config.ts", "../../src/server/running.ts", "../../src/server/security.ts", "../../src/server/auth.ts", "../../src/shared/qr.ts", "../../src/server/qr.ts", "../../src/server/phone.ts", "../../src/server/service.ts", "../../src/server/claude-code.ts", "../../src/server/demo-image.ts", "../../src/server/demo-visuals.ts", "../../src/server/demo.ts", "../../src/shared/modes.ts", "../../src/shared/preview-policy.ts", "../../src/shared/tasks.ts", "../../src/shared/titles.ts", "../../src/server/archive.ts", "../../src/server/folders.ts", "../../src/server/live.ts", "../../src/server/normalize.ts", "../../src/server/open.ts", "../../src/server/history.ts", "../../src/shared/errors.ts", "../../src/server/transcripts.ts", "../../src/server/sessions.ts", "../../src/server/actions.ts", "../../src/server/feed.ts", "../../src/server/files.ts", "../../src/server/trust.ts", "../../src/server/models.ts", "../../src/server/git.ts", "../../src/server/project-files.ts", "../../src/server/push.ts", "../../src/shared/model-names.ts", "../../src/server/approvals.ts", "../../src/server/shell.ts", "../../src/server/usage.ts", "../../src/server/runner.ts", "../../src/server/stream.ts", "../../src/server/workspace.ts", "../../src/server/app.ts", "../../src/server/waiting.ts", "../../src/server/server.ts", "../../src/server/awake.ts", "../../src/server/cli.ts", "../../src/server/local.ts"],
|
|
4
|
+
"sourcesContent": ["{\n \"name\": \"pelican-cc\",\n \"version\": \"0.3.1\",\n \"description\": \"Every Claude Code session on your computer, on your phone. No wrapper, no relay, no account.\",\n \"keywords\": [\n \"claude\",\n \"claude-code\",\n \"claude-agent-sdk\",\n \"anthropic\",\n \"agent\",\n \"ai-coding\",\n \"mobile\",\n \"phone\",\n \"pwa\",\n \"web-ui\",\n \"self-hosted\",\n \"remote\",\n \"tailscale\"\n ],\n \"homepage\": \"https://ki-seki.github.io/pelican/\",\n \"bugs\": \"https://github.com/Ki-Seki/pelican/issues\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Ki-Seki/pelican.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Shichao Song\",\n \"type\": \"module\",\n \"bin\": {\n \"pelican\": \"dist/server/index.js\",\n \"pelican-cc\": \"dist/server/index.js\"\n },\n \"files\": [\n \"dist\",\n \"npm-shrinkwrap.json\",\n \"README.md\",\n \"LICENSE\",\n \"CHANGELOG.md\"\n ],\n \"engines\": {\n \"node\": \">=22.12\"\n },\n \"scripts\": {\n \"dev\": \"node scripts/dev.mjs\",\n \"demo\": \"node dist/server/index.js --demo\",\n \"build\": \"vite build && node scripts/build-server.mjs\",\n \"start\": \"node dist/server/index.js\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"test\": \"vitest run\",\n \"screenshots\": \"node scripts/screenshots.mjs\",\n \"prepublishOnly\": \"npm run typecheck && npm test && npm run build\"\n },\n \"dependencies\": {\n \"@anthropic-ai/claude-agent-sdk\": \"0.3.318\",\n \"@hono/node-server\": \"^2.1.6\",\n \"hono\": \"^4.13.16\",\n \"qrcode-generator\": \"^2.0.4\",\n \"web-push\": \"^3.6.7\",\n \"ws\": \"^8.22.1\"\n },\n \"devDependencies\": {\n \"@tailwindcss/vite\": \"^4.3.4\",\n \"@tanstack/react-query\": \"^5.105.3\",\n \"@testing-library/react\": \"^16.3.0\",\n \"@types/node\": \"^24.0.0\",\n \"@types/react\": \"^19.1.0\",\n \"@types/react-dom\": \"^19.1.0\",\n \"@types/web-push\": \"^3.6.4\",\n \"@types/ws\": \"^8.18.1\",\n \"@vitejs/plugin-react\": \"^6.2.1\",\n \"diff\": \"^9.0.0\",\n \"esbuild\": \"^0.28.2\",\n \"jsdom\": \"^27.0.0\",\n \"lucide-react\": \"^1.68.0\",\n \"playwright-core\": \"^1.64.1\",\n \"react\": \"^19.3.1\",\n \"react-dom\": \"^19.3.1\",\n \"react-markdown\": \"^10.1.0\",\n \"rehype-highlight\": \"^7.0.2\",\n \"remark-breaks\": \"^4.0.0\",\n \"remark-gfm\": \"^4.0.1\",\n \"tailwindcss\": \"^4.3.4\",\n \"tsx\": \"^4.23.15\",\n \"typescript\": \"^7.0.2\",\n \"vite\": \"^8.3.5\",\n \"vitest\": \"^5.1.0\"\n }\n}\n", "import { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst here = path.dirname(fileURLToPath(import.meta.url));\nconst home = os.homedir();\n\n/** Directory of the built web app: next to the bundled server, or `dist/web` when run from source. */\nfunction findWebDir(): string | undefined {\n for (const candidate of [path.join(here, '../web'), path.join(here, '../../dist/web')]) {\n if (existsSync(path.join(candidate, 'index.html'))) return candidate;\n }\n return undefined;\n}\n\nconst list = (value: string | undefined) => (value ?? '').split(',').map((s) => s.trim()).filter(Boolean);\n\n/** Settings Pelican could not use, said once at start (cli.ts). */\nexport const configWarnings: string[] = [];\n\n/**\n * Web origins (`https://host[:port]`), and nothing looser: no `*`, no `null`, no bare scheme,\n * no path. With `wildcardHost`, `https://*.example.com` is allowed too (for frame-ancestors).\n */\nfunction origins(name: string, value: string | undefined, wildcardHost = false): string[] {\n const kept: string[] = [];\n for (const entry of (value ?? '').split(/[\\s,]+/).filter(Boolean)) {\n const wildcard = wildcardHost && /^https?:\\/\\/\\*\\.[^*]+$/i.test(entry);\n let url: URL | undefined;\n try {\n url = /^https?:\\/\\//i.test(entry) ? new URL(wildcard ? entry.replace('*.', 'wildcard.') : entry) : undefined;\n } catch {\n url = undefined;\n }\n const origin = url && (wildcard ? url.origin.replace('://wildcard.', '://*.') : url.origin);\n // Host names of letters, digits, dots and dashes (or an IPv6 address): a URL may hold\n // characters such as `;` that would end a header's directive.\n if (url && origin && url.pathname === '/' && !url.search && !url.hash && !url.username && !url.password\n && (wildcard ? /^https?:\\/\\/\\*\\.[a-z0-9.-]+(:\\d+)?$/ : /^https?:\\/\\/([a-z0-9.-]+|\\[[0-9a-f:.]+\\])(:\\d+)?$/).test(origin)) {\n kept.push(origin);\n } else {\n configWarnings.push(`${name}: ignored \"${entry}\"; use an origin like https://pelican.example.com`);\n }\n }\n return kept;\n}\n\n/**\n * The address phones use to reach Pelican (a tunnel's, a proxy's): an http(s) URL, perhaps under a\n * path, with nothing else in it. It is Pelican's own address, so its origin is allowed too.\n */\nfunction publicUrl(value: string | undefined): string | undefined {\n if (!value?.trim()) return undefined;\n let url: URL | undefined;\n try {\n url = new URL(value.trim());\n } catch {\n url = undefined;\n }\n if (url && /^https?:$/.test(url.protocol) && !url.username && !url.password && !url.search && !url.hash\n && /^([a-z0-9.-]+|\\[[0-9a-f:.]+\\])$/.test(url.hostname)) {\n if (!url.pathname.endsWith('/')) url.pathname += '/';\n return url.href;\n }\n configWarnings.push(`PELICAN_PUBLIC_URL: ignored \"${value}\"; use an address like https://laptop.example.ts.net/`);\n return undefined;\n}\n\nconst publicAddress = publicUrl(process.env.PELICAN_PUBLIC_URL);\nconst allowedOrigins = origins('PELICAN_ALLOWED_ORIGINS', process.env.PELICAN_ALLOWED_ORIGINS);\nif (publicAddress && !allowedOrigins.includes(new URL(publicAddress).origin)) allowedOrigins.push(new URL(publicAddress).origin);\n\nexport type AuthMode = 'auto' | 'none';\n\n/**\n * Settings from the environment; the command line (`cli.ts`) overrides some of\n * them before the server starts.\n */\nexport const config = {\n host: process.env.PELICAN_HOST ?? '127.0.0.1',\n port: Number(process.env.PELICAN_PORT ?? 7860),\n /** Name shown in the app, for telling machines apart. */\n machine: process.env.PELICAN_MACHINE ?? (os.hostname().split('.')[0] || 'local'),\n home,\n claudeHome: process.env.CLAUDE_CONFIG_DIR ?? path.join(home, '.claude'),\n /** The password hash lives here. */\n configDir: process.env.PELICAN_CONFIG_DIR ?? path.join(home, '.config', 'pelican'),\n /** Uploads, push keys and subscriptions. */\n stateDir: process.env.PELICAN_STATE_DIR ?? path.join(home, '.local', 'state', 'pelican'),\n webDir: findWebDir(),\n /**\n * auto: sign in with the password when one is set (`pelican password`), else\n * with the access token in the link Pelican prints. none: no sign-in, for\n * when something in front already authenticates (a proxy, a gateway).\n */\n auth: (process.env.PELICAN_AUTH === 'none' ? 'none' : 'auto') as AuthMode,\n /** Origins, besides the page's own, allowed to send requests (for example a proxy's public URL). */\n allowedOrigins,\n /** The address phones use, when it is not this computer's own (PELICAN_PUBLIC_URL). */\n publicUrl: publicAddress,\n /** Host names the server answers to, besides this machine's own names and addresses (and *.ts.net). */\n allowedHosts: list(process.env.PELICAN_ALLOWED_HOSTS),\n /**\n * A proxy on this machine (Tailscale, Caddy, nginx) sets X-Forwarded-For truthfully: limit sign-in\n * attempts by the client it names. Off by default, since anyone can write that header.\n */\n trustedProxy: process.env.PELICAN_TRUSTED_PROXY === '1',\n /** Pages, besides Pelican's own origin, that may show Pelican in a frame (space or comma separated). */\n frameAncestors: origins('PELICAN_FRAME_ANCESTORS', process.env.PELICAN_FRAME_ANCESTORS, true),\n /** Where a tapped notification opens a session; `{id}` is replaced. Default: the page that subscribed. */\n sessionUrl: process.env.PELICAN_SESSION_URL || undefined,\n /** A Claude process with nothing to do is closed after this long; the next message resumes the session. */\n idleCloseMs: Number(process.env.PELICAN_IDLE_CLOSE_MS ?? 30 * 60 * 1000),\n /** A transcript written by someone else this recently counts as live. */\n liveWindowMs: 45_000,\n claudeExecutable: process.env.PELICAN_CLAUDE_PATH || undefined,\n /** Keep the computer from sleeping while Claude works; PELICAN_KEEP_AWAKE=0 turns it off. */\n keepAwake: process.env.PELICAN_KEEP_AWAKE !== '0',\n /** Demo mode: made-up sessions, nothing runs. */\n demo: false,\n};\n\nexport type Config = typeof config;\n", "import { randomBytes } from 'node:crypto';\nimport { readFileSync, rmSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * The Pelican running on this computer, for the commands that talk to it (`pelican token`,\n * `pelican phone`): they find its port without being told, and tell it apart from another Pelican,\n * or another server, behind an address.\n */\n\n/** This server, told apart from any other: not a secret, it only says \"the same one\". */\nexport const instance = randomBytes(9).toString('base64url');\n\nexport type Running = { pid: number; port: number; host: string; url: string; instance: string; version: string };\n\nconst file = () => path.join(config.stateDir, 'server.json');\n\nexport function alive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\n/** Notes this server as the one running, until it exits. */\nexport async function recordRunning(info: Omit<Running, 'pid' | 'instance'>): Promise<void> {\n const written = file();\n const record: Running = { pid: process.pid, instance, ...info };\n await mkdir(path.dirname(written), { recursive: true, mode: 0o700 });\n await writeFile(written, `${JSON.stringify(record, null, 2)}\\n`, { mode: 0o600 });\n process.on('exit', () => {\n // Only our own note: another Pelican may have started since and written its own.\n try {\n if ((JSON.parse(readFileSync(written, 'utf8')) as Partial<Running>).pid === process.pid) rmSync(written, { force: true });\n } catch {\n // Gone already.\n }\n });\n}\n\n/** The Pelican that last started with this state folder, if it still runs. */\nexport async function runningServer(): Promise<Running | undefined> {\n try {\n const record = JSON.parse(await readFile(file(), 'utf8')) as Running;\n if (typeof record.pid !== 'number' || typeof record.port !== 'number' || typeof record.url !== 'string') return undefined;\n return alive(record.pid) ? record : undefined;\n } catch {\n return undefined;\n }\n}\n", "import os from 'node:os';\n\nimport { config } from './config.js';\n\nconst hostname = (host: string) => {\n const h = host.trim().toLowerCase();\n if (h.startsWith('[')) return h.slice(1, h.indexOf(']'));\n const colon = h.lastIndexOf(':');\n return colon > -1 && h.indexOf(':') === colon ? h.slice(0, colon) : h;\n};\n\nexport function isLoopback(host: string): boolean {\n const h = hostname(host);\n return h === 'localhost' || h.endsWith('.localhost') || h === '::1' || /^127(\\.\\d{1,3}){3}$/.test(h);\n}\n\n/** True for addresses that only this machine can reach. */\nexport function listensLocally(host: string): boolean {\n return isLoopback(host);\n}\n\nfunction knownHosts(): Set<string> {\n const names = new Set<string>();\n const machine = os.hostname().toLowerCase();\n names.add(machine);\n names.add(machine.split('.')[0]!);\n // This computer's own addresses: a phone on the network may open it by IP.\n for (const address of Object.values(os.networkInterfaces()).flat()) if (address) names.add(address.address.toLowerCase());\n if (config.host !== '0.0.0.0' && config.host !== '::') names.add(hostname(config.host));\n for (const host of config.allowedHosts) {\n const name = hostname(host);\n if (name) names.add(name);\n }\n for (const origin of config.allowedOrigins) {\n try {\n names.add(new URL(origin).hostname.toLowerCase().replace(/^\\[(.*)\\]$/, '$1'));\n } catch {\n // Not a URL; ignored.\n }\n }\n return names;\n}\n\n/**\n * The server answers only to names that point at it: this computer's names and\n * addresses, loopback, Tailscale names (*.ts.net, which only Tailscale can point\n * anywhere) and configured ones. Otherwise a web page could rebind its own\n * domain to 127.0.0.1 (DNS rebinding) and use Pelican through your browser.\n */\nexport function hostAllowed(host: string | undefined): boolean {\n if (!host) return false;\n const name = hostname(host);\n if (!name) return false;\n if (isLoopback(host)) return true;\n if (name.endsWith('.ts.net')) return true;\n return knownHosts().has(name);\n}\n\n/**\n * Requests that change something must come from this app's own page, or from\n * an origin allowed in the config, so a page on another site cannot drive Claude.\n */\nexport function originAllowed(origin: string | undefined, ...hosts: Array<string | undefined>): boolean {\n if (!origin) return true;\n let url: URL;\n try {\n url = new URL(origin);\n } catch {\n return false;\n }\n if (config.allowedOrigins.includes(url.origin)) return true;\n return hosts.flatMap((h) => (h ? h.split(',').map((s) => s.trim()) : [])).includes(url.host);\n}\n", "import { createHash, createHmac, randomBytes, scrypt, timingSafeEqual } from 'node:crypto';\nimport { readFileSync, statSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * Who may use Pelican. Pelican runs commands as you, so nothing gets in\n * without proof, also on this computer, where every account and process can\n * reach 127.0.0.1:\n *\n * - token (the default): a random access token, kept in the config folder and\n * printed in the link Pelican shows at start. Opening that link, or pasting\n * the token, signs the browser in, the way Jupyter does.\n * - password: set on the computer with `pelican password` (never over the\n * network), stored as a scrypt hash. For reaching Pelican from a phone.\n * - none: `--no-auth`, for when something in front already authenticates\n * (a reverse proxy, a gateway), and for the demo, which holds nothing private.\n *\n * Signing in sets a cookie signed with a secret that belongs to the token or\n * the password and changes with it, so resetting either signs every browser out.\n * The running server notices a change made with `pelican token --reset` or\n * `pelican password` within a second; no restart is needed. A cookie in use is\n * renewed, so a browser stays signed in until it goes unused for 30 days.\n */\nexport type AuthMode = 'none' | 'password' | 'token';\n\ntype Password = { version: 1; salt: string; hash: string; secret: string; N: number; r: number; p: number };\ntype Token = { version: 1; token: string; secret: string };\n\nconst passwordFile = () => path.join(config.configDir, 'auth.json');\nconst tokenFile = () => path.join(config.configDir, 'token.json');\nconst SESSION_DAYS = 30;\n/** A cookie with less than this left is replaced by a fresh one when it is used. */\nconst RENEW_BELOW_MS = (SESSION_DAYS - 1) * 24 * 3600_000;\nconst PARAMS = { N: 16384, r: 8, p: 1 };\n\nlet password: Password | undefined;\nlet token: Token | undefined;\nlet loaded = false;\n/** The two files as last read, and when they were last looked at. */\nlet seen: string | undefined;\nlet checkedAt = 0;\n\nconst signature = (file: string) => {\n try {\n const info = statSync(file);\n return `${info.ino}:${info.size}:${info.mtimeMs}`;\n } catch {\n return '-';\n }\n};\nconst filesSignature = () => `${signature(passwordFile())}|${signature(tokenFile())}`;\n\nconst readJsonSync = <T>(file: string): T | undefined => {\n try {\n return JSON.parse(readFileSync(file, 'utf8')) as T;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Reads the files again when another process changed them (`pelican token --reset`, `pelican\n * password`), at most once a second. One-time codes made under the old secret stop working too:\n * a reset is what you do when a link leaked, and a code is as good as the link for two minutes.\n */\nexport function refreshAuth(now = Date.now(), force = false): void {\n if (!loaded || (!force && now - checkedAt < 1000)) return;\n checkedAt = now;\n const current = filesSignature();\n if (current === seen) return;\n seen = current;\n const before = secret();\n // A file that cannot be read whole is read again next time; until then nothing changes.\n const nextPassword = readJsonSync<Password>(passwordFile());\n if (nextPassword?.hash && nextPassword.secret) password = nextPassword;\n else if (signature(passwordFile()) === '-') password = undefined;\n else seen = undefined;\n if (config.auth !== 'none') {\n const next = readJsonSync<Token>(tokenFile());\n // Removed by hand: the token in use stays until a new one is made.\n if (next?.token && next.secret) token = next;\n else if (signature(tokenFile()) !== '-') seen = undefined;\n }\n if (secret() !== before) codes.clear();\n}\n\nfunction derive(text: string, salt: Buffer, params: { N: number; r: number; p: number }): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n scrypt(text.normalize('NFKC'), salt, 32, { ...params, maxmem: 64 * 1024 * 1024 }, (error, key) => (error ? reject(error) : resolve(key)));\n });\n}\n\n/** Written whole or not at all: a running server reading it meanwhile never sees half of it. */\nasync function writePrivate(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const temp = `${file}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n await writeFile(temp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n await rename(temp, file);\n}\n\nconst readJson = async <T>(file: string): Promise<T | undefined> => {\n try {\n return JSON.parse(await readFile(file, 'utf8')) as T;\n } catch {\n return undefined;\n }\n};\n\n/** Reads the password and the access token, making the token on first use. */\nexport async function loadAuth(): Promise<void> {\n if (loaded) return;\n password = await readJson<Password>(passwordFile());\n if (config.auth !== 'none') {\n token = await readJson<Token>(tokenFile());\n if (!token?.token || !token.secret) await resetToken();\n }\n seen = filesSignature();\n checkedAt = Date.now();\n loaded = true;\n}\n\nexport function authMode(): AuthMode {\n if (config.auth === 'none') return 'none';\n refreshAuth();\n return password ? 'password' : 'token';\n}\n\nexport function passwordSet(): boolean {\n return Boolean(password);\n}\n\n/** The access token, for the link Pelican prints; undefined when it is not in use. */\nexport function accessToken(): string | undefined {\n return authMode() === 'token' ? token?.token : undefined;\n}\n\n/** A new access token: links and browsers signed in with the old one stop working. */\nexport async function resetToken(): Promise<string> {\n token = { version: 1, token: randomBytes(24).toString('base64url'), secret: randomBytes(32).toString('base64') };\n await writePrivate(tokenFile(), token);\n return token.token;\n}\n\nexport async function setPassword(text: string): Promise<void> {\n const salt = randomBytes(16);\n const hash = await derive(text, salt, PARAMS);\n password = { version: 1, salt: salt.toString('base64'), hash: hash.toString('base64'), secret: randomBytes(32).toString('base64'), ...PARAMS };\n await writePrivate(passwordFile(), password);\n loaded = true;\n}\n\nexport async function clearPassword(): Promise<void> {\n await rm(passwordFile(), { force: true });\n password = undefined;\n}\n\nexport async function checkPassword(text: string): Promise<boolean> {\n if (!password) return false;\n const expected = Buffer.from(password.hash, 'base64');\n const actual = await derive(text, Buffer.from(password.salt, 'base64'), password);\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\nconst same = (a: string, b: string) => {\n const x = createHash('sha256').update(a).digest();\n const y = createHash('sha256').update(b).digest();\n return timingSafeEqual(x, y);\n};\n\n/** Whether `given` is the access token (only while the token is how Pelican signs in). */\nexport function checkToken(given: string | undefined): boolean {\n const current = accessToken();\n return Boolean(current && given && same(given, current));\n}\n\n/** The secret that signs cookies in the current mode. */\nconst secret = () => (authMode() === 'password' ? password?.secret : authMode() === 'token' ? token?.secret : undefined);\n\n/** Cookie name: one per secret, so two Pelicans on one origin do not sign each other out. */\nexport function cookieName(): string {\n const value = secret();\n return `pelican_${value ? createHash('sha256').update(value).digest('hex').slice(0, 8) : 'none'}`;\n}\n\nfunction sign(expires: number): string {\n return createHmac('sha256', Buffer.from(secret() ?? '', 'base64')).update(String(expires)).digest('base64url');\n}\n\nexport function newSessionCookie(now = Date.now()): { name: string; value: string; maxAge: number } {\n const maxAge = SESSION_DAYS * 24 * 3600;\n const expires = now + maxAge * 1000;\n return { name: cookieName(), value: `${expires}.${sign(expires)}`, maxAge };\n}\n\n/**\n * How a command on this computer (`pelican phone`) proves it may ask the running Pelican for a\n * phone code: with the sign-in secret it can read in the config folder, for one request to one\n * server, good for a minute and once. Never a cookie: what it sends to the port grants nothing\n * else, nowhere else and not for long, should something other than Pelican be listening there.\n */\nconst PROOF_MS = 60_000;\nconst proofsUsed = new Map<string, number>();\n\nfunction proofMac(method: string, route: string, instance: string, at: number): string {\n // Its own wording, so a proof is never a cookie's signature, nor one the other way round.\n return createHmac('sha256', Buffer.from(secret() ?? '', 'base64')).update(`pelican command\\n${method}\\n${route}\\n${instance}\\n${at}`).digest('base64url');\n}\n\n/** The proof for one request (`X-Pelican-Proof`) to the server with this id. */\nexport function commandProof(method: string, route: string, instance: string, now = Date.now()): string {\n return `${now}.${proofMac(method, route, instance, now)}`;\n}\n\n/** Whether a request carries a proof made for it, for this server, within the minute, not used before. */\nexport function proofValid(header: string | undefined, method: string, route: string, instance: string, now = Date.now()): boolean {\n if (!header || !secret()) return false;\n const [at, mac, ...rest] = header.split('.');\n const when = Number(at);\n if (!mac || rest.length > 0 || !Number.isSafeInteger(when) || Math.abs(now - when) > PROOF_MS) return false;\n const expected = Buffer.from(proofMac(method, route, instance, when));\n const given = Buffer.from(mac);\n if (expected.length !== given.length || !timingSafeEqual(expected, given)) return false;\n for (const [used, stamp] of proofsUsed) if (Math.abs(now - stamp) > PROOF_MS) proofsUsed.delete(used);\n if (proofsUsed.has(mac)) return false;\n proofsUsed.set(mac, when);\n return true;\n}\n\nfunction cookieValue(header: string | undefined, name: string): string | undefined {\n for (const part of (header ?? '').split(';')) {\n const [key, ...rest] = part.trim().split('=');\n if (key === name) return rest.join('=');\n }\n return undefined;\n}\n\n/**\n * Whether a request may use Pelican: always when nothing is required, else with a\n * valid session cookie, or (token mode) the token as `Authorization: Bearer <token>`.\n */\nexport function signedIn(cookieHeader: string | undefined, authorization?: string): boolean {\n const mode = authMode();\n if (mode === 'none') return true;\n if (mode === 'token' && authorization?.startsWith('Bearer ') && checkToken(authorization.slice(7).trim())) return true;\n return cookieExpiry(cookieHeader) !== undefined;\n}\n\n/** When the request's sign-in cookie expires, if it carries a valid one. */\nfunction cookieExpiry(cookieHeader: string | undefined, now = Date.now()): number | undefined {\n if (!secret()) return undefined;\n const value = cookieValue(cookieHeader, cookieName());\n if (!value) return undefined;\n const [expires, mac, ...rest] = value.split('.');\n const when = Number(expires);\n if (!mac || rest.length > 0 || !Number.isFinite(when) || when < now) return undefined;\n const expected = Buffer.from(sign(when));\n const given = Buffer.from(mac);\n return expected.length === given.length && timingSafeEqual(expected, given) ? when : undefined;\n}\n\n/**\n * A fresh cookie for a browser whose cookie is valid but no longer new, so that using Pelican keeps\n * it signed in; undefined when there is nothing to renew.\n */\nexport function renewedCookie(cookieHeader: string | undefined, now = Date.now()): ReturnType<typeof newSessionCookie> | undefined {\n if (authMode() === 'none') return undefined;\n const expires = cookieExpiry(cookieHeader, now);\n return expires !== undefined && expires - now < RENEW_BELOW_MS ? newSessionCookie(now) : undefined;\n}\n\n// Failed sign-ins: at most 10 per client and 30 in all every 10 minutes, so neither\n// a rotating client key nor many clients together can guess for long.\nconst WINDOW_MS = 10 * 60_000;\nconst PER_CLIENT = 10;\nconst IN_ALL = 30;\nconst failures = new Map<string, number[]>();\nlet allFailures: number[] = [];\n\nconst recent = (times: number[], now: number) => times.filter((t) => now - t < WINDOW_MS);\n\n/** Whether this client may try to sign in now. */\nexport function attemptAllowed(client: string, now = Date.now()): boolean {\n allFailures = recent(allFailures, now);\n if (allFailures.length >= IN_ALL) return false;\n return recent(failures.get(client) ?? [], now).length < PER_CLIENT;\n}\n\n/** Counts a wrong password or token against the client and against everyone. */\nexport function noteFailure(client: string, now = Date.now()): void {\n allFailures.push(now);\n failures.set(client, [...recent(failures.get(client) ?? [], now), now]);\n // Forget clients whose failures have all expired, and never keep more than a few thousand.\n if (failures.size > 1000) {\n for (const [key, times] of failures) if (recent(times, now).length === 0) failures.delete(key);\n while (failures.size > 5000) failures.delete(failures.keys().next().value!);\n }\n}\n\n/**\n * Starts a sign-in attempt: counted as a failure at once, before the slow check, so many\n * requests sent together cannot all get past the limit. Returns undefined when the client\n * is over the limit, else a function that takes the attempt back once it succeeded.\n */\nexport function beginAttempt(client: string, now = Date.now()): (() => void) | undefined {\n if (!attemptAllowed(client, now)) return undefined;\n noteFailure(client, now);\n return () => {\n const drop = (times: number[] | undefined) => {\n const at = times?.lastIndexOf(now) ?? -1;\n if (times && at >= 0) times.splice(at, 1);\n };\n drop(allFailures);\n drop(failures.get(client));\n };\n}\n\n/** For tests: start counting afresh. */\nexport function resetAttempts(): void {\n failures.clear();\n allFailures = [];\n}\n\n// One-time sign-in codes, for the QR code that opens Pelican on a phone: the page never sees\n// the access token or the password, and a photo of the code is useless after two minutes.\nconst CODE_MS = 2 * 60_000;\nconst codes = new Map<string, number>();\n\n/** A new code that signs one browser in, once, within two minutes. */\nexport function issueCode(now = Date.now()): string {\n for (const [code, expires] of codes) if (expires <= now) codes.delete(code);\n while (codes.size >= 20) codes.delete(codes.keys().next().value!);\n const code = randomBytes(18).toString('base64url');\n codes.set(code, now + CODE_MS);\n return code;\n}\n\n/** Whether `given` is a live code; using it ends it. */\nexport function redeemCode(given: string | undefined, now = Date.now()): boolean {\n if (!given || authMode() === 'none') return false;\n for (const [code, expires] of codes) {\n if (same(code, given)) {\n codes.delete(code);\n return expires > now;\n }\n }\n return false;\n}\n", "import qrcode from 'qrcode-generator';\n\nconst QUIET = 2;\n\n/** The dark and light modules of a QR code for `text`, with a quiet border. */\nexport function qrModules(text: string): boolean[][] {\n const qr = qrcode(0, 'M');\n qr.addData(text);\n qr.make();\n const size = qr.getModuleCount();\n const rows: boolean[][] = [];\n for (let y = -QUIET; y < size + QUIET; y += 1) {\n const row: boolean[] = [];\n for (let x = -QUIET; x < size + QUIET; x += 1) row.push(x >= 0 && y >= 0 && x < size && y < size && qr.isDark(y, x));\n rows.push(row);\n }\n return rows;\n}\n\n/** The same code as an SVG, black on white whatever the theme. */\nexport function qrSvg(text: string): string {\n const rows = qrModules(text);\n const size = rows.length;\n let path = '';\n rows.forEach((row, y) => row.forEach((dark, x) => {\n if (dark) path += `M${x} ${y}h1v1h-1z`;\n }));\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${size} ${size}\" shape-rendering=\"crispEdges\"><rect width=\"${size}\" height=\"${size}\" fill=\"#fff\"/><path d=\"${path}\" fill=\"#000\"/></svg>`;\n}\n", "import { qrModules } from '../shared/qr.js';\n\n/** A QR code for a terminal: two rows per line, drawn in black and white whatever the theme. */\nexport function qrTerminal(text: string): string {\n const rows = qrModules(text);\n const lines: string[] = [];\n for (let y = 0; y < rows.length; y += 2) {\n let line = '';\n for (let x = 0; x < rows[y]!.length; x += 1) {\n const top = rows[y]![x] ? 16 : 231;\n const bottom = rows[y + 1]?.[x] ? 16 : 231;\n line += `\\x1b[38;5;${top};48;5;${bottom}m\u2580`;\n }\n lines.push(`${line}\\x1b[0m`);\n }\n return lines.join('\\n');\n}\n", "import { execFile } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport os from 'node:os';\n\nimport { config } from './config.js';\nimport { qrTerminal } from './qr.js';\nimport { isLoopback, listensLocally } from './security.js';\n\n/**\n * Getting onto the phone: the address a phone uses to reach this Pelican, and a QR code for it that\n * carries a one-time sign-in code (never the access token), good once and for two minutes.\n */\n\nexport type PhoneAddress = {\n url: string;\n /** Where the address came from, said when it is shown. */\n from: string;\n /** Tailscale Funnel: the address is open to the whole internet, not just your tailnet. */\n funnel?: boolean;\n};\n\n/** What a phone could use, or what is known that helps set one up. */\nexport type PhoneSearch = { address?: PhoneAddress; tailscale?: { cli: string; name?: string } };\n\n/** A read-only command's output; undefined when it is missing, fails or takes too long. */\nfunction read(file: string, args: string[], timeout = 3000): Promise<string | undefined> {\n return new Promise((resolve) => {\n execFile(file, args, { timeout, maxBuffer: 4 * 1024 * 1024 }, (error, stdout) => resolve(error ? undefined : String(stdout)));\n });\n}\n\nconst json = (text: string | undefined): Record<string, unknown> | undefined => {\n try {\n const value = text ? JSON.parse(text) as unknown : undefined;\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\n } catch {\n return undefined;\n }\n};\n\n/** Tailscale's command line: on PATH, or inside the macOS app, which does not put it there. */\nasync function tailscaleCli(): Promise<string | undefined> {\n if (await read('tailscale', ['version'])) return 'tailscale';\n const app = '/Applications/Tailscale.app/Contents/MacOS/Tailscale';\n if (process.platform === 'darwin' && existsSync(app) && (await read(app, ['version']))) return app;\n return undefined;\n}\n\n/** Whether a serve handler's target is this Pelican: a loopback address on its port. */\nfunction forwardsTo(proxy: unknown, port: number): boolean {\n if (typeof proxy !== 'string' || !proxy) return false;\n const target = /^\\d+$/.test(proxy) ? `http://127.0.0.1:${proxy}` : /^[a-z][a-z0-9+.-]*:\\/\\//i.test(proxy) ? proxy : `http://${proxy}`;\n try {\n const url = new URL(target);\n const targetPort = Number(url.port || (url.protocol === 'https:' ? 443 : 80));\n return targetPort === port && (isLoopback(url.hostname) || url.hostname === '[::1]');\n } catch {\n return false;\n }\n}\n\nconst record = (value: unknown): Record<string, unknown> => (value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {});\n\n/**\n * The address `tailscale serve` gives this Pelican, from its config (`tailscale serve status\n * --json`): a name of this tailnet whose handler forwards to Pelican's port.\n */\nexport function servedAddress(serve: unknown, port: number): PhoneAddress | undefined {\n const configs = [record(serve), ...Object.values(record(record(serve).Foreground)).map(record)];\n for (const served of configs) {\n for (const [hostPort, web] of Object.entries(record(served.Web))) {\n for (const [mount, handler] of Object.entries(record(record(web).Handlers))) {\n if (!forwardsTo(record(handler).Proxy, port)) continue;\n const cut = hostPort.lastIndexOf(':');\n const host = cut > 0 ? hostPort.slice(0, cut) : hostPort;\n const webPort = cut > 0 ? hostPort.slice(cut + 1) : '443';\n const tcp = record(record(served.TCP)[webPort]);\n const scheme = tcp.HTTPS === undefined && tcp.HTTP === true ? 'http' : 'https';\n const shown = (scheme === 'https' && webPort === '443') || (scheme === 'http' && webPort === '80') ? '' : `:${webPort}`;\n const path = mount.startsWith('/') ? mount : `/${mount}`;\n return {\n url: `${scheme}://${host}${shown}${path.endsWith('/') ? path : `${path}/`}`,\n from: 'tailscale serve',\n ...(record(served.AllowFunnel)[hostPort] === true ? { funnel: true } : {}),\n };\n }\n }\n }\n return undefined;\n}\n\n/** An address as typed: a scheme added when missing (https), a slash at the end. */\nexport function normalAddress(text: string): string {\n const value = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(text.trim()) ? text.trim() : `https://${text.trim()}`;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`Not an address: ${text}`);\n }\n if (!/^https?:$/.test(url.protocol) || url.username || url.password) throw new Error(`Not an address: ${text}`);\n url.search = '';\n url.hash = '';\n if (!url.pathname.endsWith('/')) url.pathname += '/';\n return url.href;\n}\n\n/** This computer's address on the local network, for a Pelican that listens beyond it. */\nfunction networkAddress(host: string, port: number): string | undefined {\n if (host === '0.0.0.0' || host === '::') {\n const lan = Object.values(os.networkInterfaces()).flat().find((a) => a && a.family === 'IPv4' && !a.internal);\n return lan ? `http://${lan.address}:${port}/` : undefined;\n }\n return `http://${host.includes(':') ? `[${host}]` : host}:${port}/`;\n}\n\n/**\n * The address a phone uses, in this order: the one given, PELICAN_PUBLIC_URL, a `tailscale serve`\n * that forwards to this Pelican, the one origin PELICAN_ALLOWED_ORIGINS names, and the local\n * network's when Pelican listens beyond this computer. Tailscale is only read, never changed.\n */\nexport async function findPhoneAddress(port: number, host: string, given?: string): Promise<PhoneSearch> {\n if (given) return { address: { url: normalAddress(given), from: 'the address given' } };\n if (config.publicUrl) return { address: { url: config.publicUrl, from: 'PELICAN_PUBLIC_URL' } };\n const cli = await tailscaleCli();\n if (cli) {\n const address = servedAddress(json(await read(cli, ['serve', 'status', '--json'])), port);\n if (address) return { address };\n }\n if (config.allowedOrigins.length === 1) return { address: { url: `${config.allowedOrigins[0]}/`, from: 'PELICAN_ALLOWED_ORIGINS' } };\n if (!listensLocally(host)) {\n const url = networkAddress(host, port);\n if (url) return { address: { url, from: 'your network' } };\n }\n if (!cli) return {};\n const status = json(await read(cli, ['status', '--json']));\n const self = record(status?.Self);\n const name = status?.BackendState === 'Running' && typeof self.DNSName === 'string' && self.DNSName ? self.DNSName.replace(/\\.$/, '') : undefined;\n return { tailscale: { cli, ...(name ? { name } : {}) } };\n}\n\n/** What to do when no address is known: the one command that makes one, where it is known. */\nexport function setupHint(search: PhoneSearch, port: number, command: string): string[] {\n const lines = ['Pelican listens only on this computer, and your phone needs an address that reaches it.'];\n if (search.tailscale?.name) {\n lines.push(`Tailscale is on here. This serves Pelican at https://${search.tailscale.name}/ to your tailnet:`);\n lines.push('', ` ${search.tailscale.cli} serve --bg ${port}`, '', `Then run \\`${command} phone\\` again.`);\n } else {\n lines.push(`With Tailscale on the computer and the phone: \\`tailscale serve --bg ${port}\\`, then \\`${command} phone\\`.`);\n lines.push(`Any other address that reaches this computer: \\`${command} phone https://\u2026\\`.`);\n }\n return lines;\n}\n\n/**\n * Whether an address reaches this very Pelican. Only its public sign-in state is asked for, so\n * no secret goes to an address that turns out to be someone else's; the answer names the server.\n */\nexport async function checkAddress(url: string, instance: string): Promise<string | undefined> {\n let response: Response;\n try {\n response = await fetch(new URL('api/auth', url), { headers: { 'X-Pelican': '1' }, redirect: 'manual', signal: AbortSignal.timeout(6000) });\n } catch (error) {\n const reason = (error as { cause?: { code?: string } }).cause?.code ?? (error as Error).message;\n return `Could not reach ${url} from this computer (${reason}).`;\n }\n const text = await response.text().catch(() => '');\n if (response.status === 403 && text.includes('host name is not allowed')) {\n return `${new URL(url).host} reaches Pelican, but Pelican does not answer to that name. Start it with PELICAN_PUBLIC_URL=${url}`;\n }\n const answer = json(text);\n if (!answer || typeof answer.mode !== 'string') return `${url} is not Pelican (it answered ${response.status}).`;\n if (answer.instance !== instance) return `${url} reaches another Pelican, not the one running here.`;\n return undefined;\n}\n\n/** The block a terminal shows: the address, its QR code with a one-time code, and how long it works. */\nexport function phoneBlock(address: PhoneAddress, code: string | null): string {\n const link = code ? `${address.url}?code=${encodeURIComponent(code)}` : address.url;\n const lines = [\n ` On your phone: ${address.url}${address.from === 'the address given' ? '' : ` (${address.from})`}`,\n ...(address.funnel ? [' Tailscale Funnel: this address is open to the whole internet.'] : []),\n '',\n qrTerminal(link).replace(/^/gm, ' '),\n '',\n code ? ' Scan it with the camera to sign in. It works once, for two minutes.' : ' Scan it with the camera.',\n ];\n return `${lines.join('\\n')}\\n`;\n}\n", "import { execFile } from 'node:child_process';\nimport { realpathSync } from 'node:fs';\nimport { chmod, mkdir, rm, stat, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\n/**\n * `pelican service`: keeps Pelican running, started at login and again if it stops, as a launchd\n * agent on macOS or a systemd user unit on Linux. The service gets the installing shell's PATH (a\n * login item's own is too thin to find Node, `npx` MCP servers or the tools `!` commands use) and\n * Pelican's settings, never a secret. Its output goes to a log, where Pelican prints no sign-in link.\n */\n\nexport const LABEL = 'io.github.ki-seki.pelican';\nconst UNIT = 'pelican.service';\n\nexport type Run = (command: string, args: string[]) => Promise<{ code: number; stdout: string; stderr: string }>;\n\nexport type ServiceContext = {\n platform: NodeJS.Platform;\n home: string;\n uid: number;\n user: string;\n /** Node and Pelican's own script, as the service starts them. */\n node: string;\n script: string;\n /** Flags for Pelican: --port, --host, --name, --no-auth. */\n args: string[];\n env: NodeJS.ProcessEnv;\n run: Run;\n};\n\nexport const runCommand: Run = (command, args) => new Promise((resolve) => {\n execFile(command, args, { timeout: 30_000 }, (error, stdout, stderr) => {\n const code = error ? (typeof (error as { code?: unknown }).code === 'number' ? (error as { code: number }).code : 127) : 0;\n resolve({ code, stdout: String(stdout), stderr: String(stderr || (error && code === 127 ? error.message : '')) });\n });\n});\n\n/** Variables the service carries over from the installing shell. */\nconst KEEP = /^(PATH|SHELL|LANG|LC_[A-Z]+|TZ|PELICAN_.+|CLAUDE_CONFIG_DIR|CLAUDE_CODE_.+|ANTHROPIC_.+|AWS_PROFILE|AWS_REGION|CLOUD_ML_REGION|NODE_EXTRA_CA_CERTS|(HTTPS?|NO|ALL)_PROXY|(https?|no|all)_proxy)$/;\n/**\n * Never written to a file: a service has no business holding them, and Claude Code keeps its own\n * sign-in. By name (a key, a token, headers such as ANTHROPIC_CUSTOM_HEADERS), or by value: an\n * address with a user name or a password in it (a proxy's `http://user:pass@host`).\n */\nconst SECRET = /KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|HEADER/i;\nconst WITH_LOGIN = /[a-z][a-z0-9+.-]*:\\/\\/[^\\s]*@/i;\n\n/** The environment written into the service, and the names left out because they look like secrets. */\nexport function serviceEnvironment(env: NodeJS.ProcessEnv): { kept: Record<string, string>; secrets: string[] } {\n const kept: Record<string, string> = {};\n const secrets: string[] = [];\n for (const [name, value] of Object.entries(env).sort(([a], [b]) => a.localeCompare(b))) {\n if (value === undefined || !KEEP.test(name)) continue;\n if (SECRET.test(name) || WITH_LOGIN.test(value)) secrets.push(name);\n else kept[name] = value;\n }\n return { kept, secrets };\n}\n\n/** Written readable only by you, also over a file that was there before: writeFile's mode is for a new one only. */\nasync function writeOwn(file: string, text: string): Promise<void> {\n await writeFile(file, text, { mode: 0o600 });\n await chmod(file, 0o600);\n}\n\nexport const plistFile = (home: string) => path.join(home, 'Library', 'LaunchAgents', `${LABEL}.plist`);\nexport const unitFile = (home: string) => path.join(home, '.config', 'systemd', 'user', UNIT);\nexport const logFile = (home: string) => path.join(home, 'Library', 'Logs', 'pelican.log');\n\nconst xml = (text: string) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\n/** The launchd agent: started at login, started again when it stops with an error. */\nexport function launchdPlist(ctx: ServiceContext): string {\n const { kept } = serviceEnvironment(ctx.env);\n const strings = (values: string[]) => values.map((v) => ` <string>${xml(v)}</string>`).join('\\n');\n const env = Object.entries(kept).map(([k, v]) => ` <key>${xml(k)}</key>\\n <string>${xml(v)}</string>`).join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n${strings([ctx.node, ctx.script, ...ctx.args])}\n </array>\n <key>EnvironmentVariables</key>\n <dict>\n${env}\n </dict>\n <key>WorkingDirectory</key>\n <string>${xml(ctx.home)}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>StandardOutPath</key>\n <string>${xml(logFile(ctx.home))}</string>\n <key>StandardErrorPath</key>\n <string>${xml(logFile(ctx.home))}</string>\n</dict>\n</plist>\n`;\n}\n\n/** A value for a unit file: quoted, with systemd's specifiers and variables kept literal. */\nconst unitQuote = (text: string) => `\"${text.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/%/g, '%%').replace(/\\$/g, '$$$$')}\"`;\n\n/** The systemd user unit: started with the user's session (or at boot, with lingering on), again on failure. */\nexport function systemdUnit(ctx: ServiceContext): string {\n const { kept } = serviceEnvironment(ctx.env);\n const env = Object.entries(kept).map(([k, v]) => `Environment=${unitQuote(`${k}=${v}`)}`).join('\\n');\n return `[Unit]\nDescription=Pelican: Claude Code sessions from your phone\n\n[Service]\nExecStart=${[ctx.node, ctx.script, ...ctx.args].map(unitQuote).join(' ')}\n${env}\nWorkingDirectory=%h\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;\n}\n\n/** Why the service cannot be set up from here, if it cannot. */\nexport async function cannotInstall(ctx: ServiceContext): Promise<string | undefined> {\n if (ctx.platform === 'win32') return 'Not available on Windows. Run Pelican in WSL, next to Claude Code; there `pelican service install` sets up a systemd service.';\n if (ctx.platform !== 'darwin' && ctx.platform !== 'linux') return `Not available on ${ctx.platform}: start Pelican from your own login script.`;\n if (!ctx.script.endsWith('.js')) return 'Build Pelican first (npm run build), or install it with npm install -g pelican-cc.';\n // npx keeps its copy in a cache that may be cleared at any time, taking the service with it.\n if (/[\\\\/]_npx[\\\\/]/.test(ctx.script)) return 'Install Pelican first (npm install -g pelican-cc), then run `pelican service install`: the copy npx runs can be removed at any time.';\n if (ctx.platform === 'linux' && (await ctx.run('systemctl', ['--user', 'show-environment'])).code !== 0) {\n return 'systemd is not running for your user here, so there is no service to set up. Keep Pelican running in tmux or screen instead.';\n }\n return undefined;\n}\n\nconst domain = (ctx: ServiceContext) => `gui/${ctx.uid}`;\nconst target = (ctx: ServiceContext) => `${domain(ctx)}/${LABEL}`;\n\nasync function failed(result: { code: number; stderr: string; stdout: string }, what: string): Promise<never> {\n throw new Error(`${what} failed: ${(result.stderr || result.stdout).trim() || `exit code ${result.code}`}`);\n}\n\n/** Writes the service and starts it; lines to print go to `say`. */\nexport async function installService(ctx: ServiceContext, say: (line: string) => void): Promise<void> {\n const problem = await cannotInstall(ctx);\n if (problem) throw new Error(problem);\n const { secrets } = serviceEnvironment(ctx.env);\n if (ctx.platform === 'darwin') {\n const file = plistFile(ctx.home);\n await mkdir(path.dirname(file), { recursive: true });\n await mkdir(path.dirname(logFile(ctx.home)), { recursive: true });\n await writeOwn(file, launchdPlist(ctx));\n // Loaded already (an earlier install): unload it first, so the new file applies.\n if ((await ctx.run('launchctl', ['print', target(ctx)])).code === 0) await ctx.run('launchctl', ['bootout', target(ctx)]);\n await ctx.run('launchctl', ['enable', target(ctx)]);\n const loaded = await ctx.run('launchctl', ['bootstrap', domain(ctx), file]);\n if (loaded.code !== 0) await failed(loaded, 'launchctl bootstrap');\n say(`Pelican runs as a login item now (${file}).`);\n say(`Its log: ${logFile(ctx.home)}`);\n } else {\n const file = unitFile(ctx.home);\n await mkdir(path.dirname(file), { recursive: true });\n await writeOwn(file, systemdUnit(ctx));\n for (const args of [['daemon-reload'], ['enable', UNIT], ['restart', UNIT]]) {\n const result = await ctx.run('systemctl', ['--user', ...args]);\n if (result.code !== 0) await failed(result, `systemctl --user ${args.join(' ')}`);\n }\n say(`Pelican runs as a systemd user service now (${file}).`);\n say('Its log: journalctl --user -u pelican');\n const linger = await ctx.run('loginctl', ['show-user', ctx.user, '--property=Linger']);\n if (linger.code === 0 && /Linger=no/.test(linger.stdout)) {\n say('It stops when you log out. To keep it running then, and to start it at boot: loginctl enable-linger');\n }\n }\n if (secrets.length > 0) say(`Left out of the service, as secrets: ${secrets.join(', ')}.`);\n}\n\n/** Stops the service and removes it. */\nexport async function uninstallService(ctx: ServiceContext, say: (line: string) => void): Promise<void> {\n if (ctx.platform === 'darwin') {\n const file = plistFile(ctx.home);\n const had = await stat(file).then(() => true, () => false);\n await ctx.run('launchctl', ['bootout', target(ctx)]);\n await rm(file, { force: true });\n say(had ? 'Pelican no longer runs as a login item.' : 'Pelican was not set up as a login item.');\n } else if (ctx.platform === 'linux') {\n const file = unitFile(ctx.home);\n const had = await stat(file).then(() => true, () => false);\n await ctx.run('systemctl', ['--user', 'disable', '--now', UNIT]);\n await rm(file, { force: true });\n await ctx.run('systemctl', ['--user', 'daemon-reload']);\n say(had ? 'Pelican no longer runs as a systemd user service.' : 'Pelican was not set up as a systemd user service.');\n } else {\n throw new Error((await cannotInstall(ctx)) ?? 'Not available here.');\n }\n}\n\n/** Starts the service again (after an update, or a change to its settings). */\nexport async function restartService(ctx: ServiceContext, say: (line: string) => void): Promise<void> {\n if (!(await serviceInstalled(ctx))) throw new Error('Pelican is not set up as a service: `pelican service install` sets it up.');\n const result = ctx.platform === 'darwin'\n ? await ctx.run('launchctl', ['kickstart', '-k', target(ctx)])\n : await ctx.run('systemctl', ['--user', 'restart', UNIT]);\n if (result.code !== 0) await failed(result, 'Restarting Pelican');\n say('Pelican is starting again.');\n}\n\nexport async function serviceInstalled(ctx: ServiceContext): Promise<boolean> {\n const file = ctx.platform === 'darwin' ? plistFile(ctx.home) : ctx.platform === 'linux' ? unitFile(ctx.home) : undefined;\n return file ? stat(file).then(() => true, () => false) : false;\n}\n\nexport type ServiceState = { installed: boolean; running: boolean; pid?: number; lastExit?: string };\n\n/** Whether the service is set up and running, as launchd or systemd say. */\nexport async function serviceState(ctx: ServiceContext): Promise<ServiceState> {\n const installed = await serviceInstalled(ctx);\n if (!installed) return { installed, running: false };\n if (ctx.platform === 'darwin') {\n const { code, stdout } = await ctx.run('launchctl', ['print', target(ctx)]);\n if (code !== 0) return { installed, running: false };\n const pid = Number(/^\\s*pid = (\\d+)/m.exec(stdout)?.[1]);\n const lastExit = /^\\s*last exit code = (.+)$/m.exec(stdout)?.[1]?.trim();\n return { installed, running: /^\\s*state = running/m.test(stdout), ...(pid ? { pid } : {}), ...(lastExit ? { lastExit } : {}) };\n }\n const { stdout } = await ctx.run('systemctl', ['--user', 'show', UNIT, '--property=ActiveState,MainPID,ExecMainStatus']);\n const value = (name: string) => new RegExp(`^${name}=(.*)$`, 'm').exec(stdout)?.[1]?.trim();\n const pid = Number(value('MainPID'));\n const status = value('ExecMainStatus');\n return { installed, running: value('ActiveState') === 'active', ...(pid ? { pid } : {}), ...(status && status !== '0' ? { lastExit: status } : {}) };\n}\n\n/** `node` on PATH when it is the very Node running now: a stable path that survives a Node update. */\nexport function stableNode(execPath: string, pathValue: string | undefined): string {\n let real: string;\n try {\n real = realpathSync(execPath);\n } catch {\n return execPath;\n }\n for (const dir of (pathValue ?? '').split(path.delimiter).filter(Boolean)) {\n const candidate = path.join(dir, process.platform === 'win32' ? 'node.exe' : 'node');\n try {\n if (realpathSync(candidate) === real) return candidate;\n } catch {\n // Not there.\n }\n }\n return execPath;\n}\n\n/** The context for this computer and this Pelican. */\nexport function thisComputer(args: string[]): ServiceContext {\n let script = process.argv[1] ?? '';\n try {\n script = realpathSync(script);\n } catch {\n // Kept as given; cannotInstall says what is wrong with it.\n }\n return {\n platform: process.platform,\n home: os.homedir(),\n uid: process.getuid?.() ?? 0,\n user: os.userInfo().username,\n node: stableNode(process.execPath, process.env.PATH),\n script,\n args,\n env: process.env,\n run: runCommand,\n };\n}\n", "import { execFile, spawn } from 'node:child_process';\nimport { constants, existsSync, readFileSync } from 'node:fs';\nimport { access, stat } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * The Claude Code that Pelican runs: the one the Agent SDK bundles, or the one PELICAN_CLAUDE_PATH\n * names. Bug reports need its version, and the start banner says whether it is signed in, since a\n * signed-out Claude Code otherwise shows only when the first message fails. The banner and About\n * also say when the user's own `claude` is newer, since its new features reach Pelican only with\n * an update.\n */\n\nconst require = createRequire(import.meta.url);\n\n/** The Agent SDK's package.json: its own version and the version of the Claude Code it bundles. */\nexport function sdkPackage(): { version?: string; claudeCodeVersion?: string } {\n try {\n const entry = require.resolve('@anthropic-ai/claude-agent-sdk');\n return JSON.parse(readFileSync(path.join(path.dirname(entry), 'package.json'), 'utf8')) as { version?: string; claudeCodeVersion?: string };\n } catch {\n return {};\n }\n}\n\n/** The bundled binary, found the way the SDK finds it (its platform package). */\nexport function bundledClaude(): string | undefined {\n const exe = process.platform === 'win32' ? '.exe' : '';\n const base = `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}`;\n const names = process.platform === 'linux' ? [base, `${base}-musl`] : [base];\n for (const name of names) {\n try {\n const file = require.resolve(`${name}/claude${exe}`);\n if (existsSync(file)) return file;\n } catch {\n // Not installed for this platform; try the next.\n }\n }\n return undefined;\n}\n\n/** The binary Pelican starts: PELICAN_CLAUDE_PATH, else the bundled one. */\nexport const claudeBinary = (): string | undefined => config.claudeExecutable ?? bundledClaude();\n\ntype Output = { code: number; stdout: string };\n\nfunction run(file: string, args: string[], timeout: number): Promise<Output | undefined> {\n return new Promise((resolve) => {\n execFile(file, args, { timeout, maxBuffer: 1024 * 1024, env: process.env }, (error, stdout) => {\n const code = error ? (typeof (error as { code?: unknown }).code === 'number' ? (error as { code: number }).code : -1) : 0;\n // Missing or not runnable: no answer at all.\n if (error && code === -1) resolve(undefined);\n else resolve({ code, stdout: String(stdout) });\n });\n });\n}\n\nexport type ClaudeCodeInfo = { version?: string; path?: string; missing?: boolean };\n\nlet info: Promise<ClaudeCodeInfo> | undefined;\n\n/**\n * Which Claude Code runs and its version: the bundled one's from the SDK's package.json (nothing\n * runs), one named by PELICAN_CLAUDE_PATH by asking it. `path` is set only for the latter.\n */\nexport function claudeCodeInfo(): Promise<ClaudeCodeInfo> {\n info ??= (async () => {\n if (!config.claudeExecutable) {\n const version = sdkPackage().claudeCodeVersion;\n return bundledClaude() ? { ...(version ? { version } : {}) } : { missing: true };\n }\n const answer = await run(config.claudeExecutable, ['--version'], 5000);\n const version = answer?.stdout.match(/\\d+\\.\\d+\\.\\d+/)?.[0];\n return { path: config.claudeExecutable, ...(version ? { version } : {}), ...(answer ? {} : { missing: true }) };\n })();\n return info;\n}\n\n/** Whether version `a` (x.y.z) comes after `b`. */\nexport function isNewer(a: string, b: string): boolean {\n const [x, y] = [a, b].map((version) => version.split('.').map((part) => Number.parseInt(part, 10) || 0));\n for (let i = 0; i < 3; i += 1) {\n const difference = (x?.[i] ?? 0) - (y?.[i] ?? 0);\n if (difference) return difference > 0;\n }\n return false;\n}\n\n/**\n * The first `claude` on PATH, as a shell finds it, but in absolute folders only: an empty or\n * relative entry would run a `claude` from whatever folder Pelican was started in.\n */\nexport async function claudeOnPath(PATH = process.env.PATH ?? ''): Promise<string | undefined> {\n const name = process.platform === 'win32' ? 'claude.exe' : 'claude';\n for (const dir of PATH.split(path.delimiter)) {\n if (!path.isAbsolute(dir)) continue;\n const file = path.join(dir, name);\n try {\n await access(file, constants.X_OK);\n if ((await stat(file)).isFile()) return file;\n } catch {\n // Not in this folder.\n }\n }\n return undefined;\n}\n\n/** The version of the `claude` on PATH when it is newer than `ours`; undefined when not, or when it cannot say in time. */\nexport async function newerOnPath(ours: string, PATH?: string, timeout = 3000): Promise<string | undefined> {\n const file = await claudeOnPath(PATH);\n if (!file) return undefined;\n const answer = await run(file, ['--version'], timeout);\n const version = answer?.code === 0 ? /\\d+\\.\\d+\\.\\d+/.exec(answer.stdout)?.[0] : undefined;\n return version && isNewer(version, ours) ? version : undefined;\n}\n\nlet newer: Promise<string | undefined> | undefined;\nlet newerFound: string | undefined;\n\n/**\n * The version of the user's own `claude` when it is newer than the Claude Code Pelican brings:\n * that one has what Pelican gets only from an update. Asked once, at start, in the background.\n * Not when PELICAN_CLAUDE_PATH names the Claude Code to run, the user's choice already, nor in\n * the demo, which runs nothing.\n */\nexport function checkNewerClaude(): Promise<string | undefined> {\n newer ??= (async () => {\n const ours = config.claudeExecutable || config.demo ? undefined : (await claudeCodeInfo()).version;\n newerFound = ours ? await newerOnPath(ours) : undefined;\n return newerFound;\n })();\n return newer;\n}\n\n/** What the check at start found so far, without waiting for it. */\nexport const newerClaude = (): string | undefined => newerFound;\n\n/** The banner's line when the user's own `claude` is newer than the Claude Code Pelican runs. */\nexport const newerClaudeLine = (version: string): string => `Your claude is newer (${version}): update Pelican to get it`;\n\nexport type SignIn = { loggedIn: boolean; email?: string } | undefined;\n\n/** Whether Claude Code is signed in on this computer, as `claude auth status` says; undefined if it cannot say. */\nexport async function claudeSignIn(timeout = 5000): Promise<SignIn> {\n const binary = claudeBinary();\n if (!binary) return undefined;\n const answer = await run(binary, ['auth', 'status', '--json'], timeout);\n if (!answer) return undefined;\n try {\n const status = JSON.parse(answer.stdout) as { loggedIn?: unknown; email?: unknown };\n if (typeof status.loggedIn !== 'boolean') return undefined;\n return { loggedIn: status.loggedIn, ...(typeof status.email === 'string' && status.email ? { email: status.email } : {}) };\n } catch {\n return undefined;\n }\n}\n\n/** One line for the start banner: which Claude Code, and whether it can work. */\nexport function claudeCodeLine(code: ClaudeCodeInfo, signIn: SignIn, login: string): string {\n if (code.missing) {\n return code.path\n ? `Claude Code not found at ${code.path} (PELICAN_CLAUDE_PATH)`\n : 'Claude Code is missing: reinstall Pelican (npm install -g pelican-cc)';\n }\n const name = `Claude Code ${code.version ?? ''}`.trim() + (code.path ? ` (${code.path})` : '');\n if (!signIn) return name;\n return signIn.loggedIn\n ? `${name} \u00B7 signed in${signIn.email ? ` as ${signIn.email}` : ''}`\n : `${name} \u00B7 not signed in: run \\`${login}\\``;\n}\n\n/** Signs Claude Code in with its own `auth login`, in this terminal; resolves to its exit code. */\nexport function claudeLogin(): Promise<number> {\n const binary = claudeBinary();\n if (!binary) return Promise.reject(new Error('Claude Code is missing: reinstall Pelican (npm install -g pelican-cc).'));\n return new Promise((resolve, reject) => {\n const child = spawn(binary, ['auth', 'login'], { stdio: 'inherit' });\n child.on('error', reject);\n child.on('exit', (code) => resolve(code ?? 1));\n });\n}\n", "// A made-up screenshot the demo's first prompt attaches: a settings page before its dark theme.\nexport const SETTINGS_SCREENSHOT = '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';\n", "// The demo session that draws: a chart as a Claude Desktop visual, and a page Claude writes.\n\nconst DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];\nconst SIGNUPS = [1420, 1588, 1710, 2214, 1966, 1702, 1880];\n\nexport const SIGNUPS_CSV = `day,signups\\n${DAYS.map((d, i) => `${d},${SIGNUPS[i]}`).join('\\n')}\\n`;\n\n/** A bar chart in the vocabulary of Claude Desktop's visuals (box, th, ts, c-*), sized to read on a phone. */\nexport function signupsChart(): string {\n const max = Math.max(...SIGNUPS);\n const bars = SIGNUPS.map((value, i) => {\n const h = Math.round((value / max) * 128);\n const x = 26 + i * 52;\n const y = 196 - h;\n const tone = value === max ? 'c-purple' : 'c-teal';\n return `<g class=\"${tone}\"><rect x=\"${x}\" y=\"${y}\" width=\"38\" height=\"${h}\" rx=\"6\"/></g>`\n + `<text class=\"ts\" x=\"${x + 19}\" y=\"${y - 8}\" text-anchor=\"middle\">${(value / 1000).toFixed(1)}k</text>`\n + `<text class=\"ts\" x=\"${x + 19}\" y=\"216\" text-anchor=\"middle\">${DAYS[i]}</text>`;\n }).join('');\n return `<svg width=\"100%\" viewBox=\"0 0 400 228\" role=\"img\"><title>Signups by day, last week</title>`\n + `<text class=\"th\" x=\"16\" y=\"24\">Signups by day \u00B7 last week</text>`\n + `<text class=\"ts\" x=\"16\" y=\"42\">12,480 in total, 18% more than the week before</text>`\n + `<line x1=\"16\" y1=\"196.5\" x2=\"384\" y2=\"196.5\" style=\"stroke:var(--line)\"/>`\n + `${bars}</svg>`;\n}\n\nexport const REPORT_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Signups \u00B7 week 45</title>\n<style>\n :root { color-scheme: light dark; --ink: #17181a; --soft: #6b6e75; --line: #e6e6e3; --card: #fff; --bg: #f6f6f3; --a: #0e7490; --b: #7c6cf2; }\n @media (prefers-color-scheme: dark) { :root { --ink: #ececea; --soft: #a5a8ae; --line: #2a2d31; --card: #16181b; --bg: #0e0f11; --a: #3ba7bd; --b: #9d90f5; } }\n * { box-sizing: border-box; margin: 0; }\n body { background: var(--bg); color: var(--ink); font: 15px/1.55 -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; padding: 28px 20px 40px; }\n main { max-width: 640px; margin: 0 auto; }\n .eyebrow { color: var(--a); font-weight: 600; font-size: 13px; letter-spacing: .02em; }\n h1 { margin-top: 6px; font-size: 30px; line-height: 1.1; letter-spacing: -.03em; }\n .kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 22px; }\n .kpi { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 14px; }\n .kpi b { display: block; font-size: 24px; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }\n .kpi span { color: var(--soft); font-size: 12.5px; }\n .up { color: #16a34a; }\n .chart { margin-top: 14px; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 16px 14px 10px; }\n .bars { display: flex; align-items: flex-end; gap: 8px; height: 170px; }\n .bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 100%; }\n .bar i { display: block; width: 100%; border-radius: 8px 8px 4px 4px; background: color-mix(in srgb, var(--a) 75%, transparent); height: 0; transition: height .9s cubic-bezier(.2,.8,.2,1); }\n .bar.top i { background: var(--b); }\n .bar small { color: var(--soft); font-size: 11.5px; }\n p.note { margin-top: 16px; color: var(--soft); }\n</style>\n</head>\n<body>\n<main>\n <div class=\"eyebrow\">Growth \u00B7 week 45</div>\n <h1>Signups grew 18%, and Thursday led the week</h1>\n <div class=\"kpis\">\n <div class=\"kpi\"><b data-count=\"12480\">0</b><span>signups</span></div>\n <div class=\"kpi\"><b class=\"up\">+18%</b><span>on week 44</span></div>\n <div class=\"kpi\"><b>Thu</b><span>best day, 2,214</span></div>\n </div>\n <div class=\"chart\"><div class=\"bars\" id=\"bars\"></div></div>\n <p class=\"note\">Thursday's newsletter brought the peak; the weekend held above the weekday average.</p>\n</main>\n<script>\n const days = ${JSON.stringify(DAYS)};\n const values = ${JSON.stringify(SIGNUPS)};\n const max = Math.max(...values);\n const bars = document.getElementById('bars');\n values.forEach((v, i) => {\n const bar = document.createElement('div');\n bar.className = 'bar' + (v === max ? ' top' : '');\n bar.innerHTML = '<small>' + v.toLocaleString() + '</small><i></i><small>' + days[i] + '</small>';\n bars.append(bar);\n requestAnimationFrame(() => requestAnimationFrame(() => { bar.querySelector('i').style.height = (v / max * 120) + 'px'; }));\n });\n for (const el of document.querySelectorAll('[data-count]')) {\n const end = Number(el.dataset.count); const start = performance.now();\n const step = (t) => { const k = Math.min(1, (t - start) / 900); el.textContent = Math.round(end * (1 - Math.pow(1 - k, 3))).toLocaleString(); if (k < 1) requestAnimationFrame(step); };\n requestAnimationFrame(step);\n }\n</script>\n</body>\n</html>\n`;\n", "import { execFile } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport type { ModelOption, RunState } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { SETTINGS_SCREENSHOT } from './demo-image.js';\nimport { REPORT_HTML, SIGNUPS_CSV, signupsChart } from './demo-visuals.js';\n\n/**\n * `pelican --demo`: a made-up home with a few sessions, for trying Pelican\n * without Claude Code and for screenshots that show no real work. It is\n * written fresh on every start, with times relative to now. Nothing runs.\n */\n\nconst run = promisify(execFile);\nconst MIN = 60_000;\nconst HOUR = 60 * MIN;\n\ntype Block = Record<string, unknown>;\ntype Row = { role: 'user' | 'assistant'; content: string | Block[]; at: number };\n\nconst tool = (id: string, name: string, input: Record<string, unknown>): Block => ({ type: 'tool_use', id, name, input });\nconst result = (id: string, content: string, isError = false): Block => ({ type: 'tool_result', tool_use_id: id, content, ...(isError ? { is_error: true } : {}) });\nconst text = (value: string): Block => ({ type: 'text', text: value });\n\nfunction numbered(source: string): string {\n return source.split('\\n').map((line, i) => `${String(i + 1).padStart(6)}\\t${line}`).join('\\n');\n}\n\ntype DemoSession = { id: string; title: string; project: string; branch: string; rows: (cwd: string) => Row[]; scratch?: boolean };\n\nconst THEME_CSS = `:root {\n --bg: #ffffff;\n --fg: #111111;\n --muted: #6b6b6b;\n --accent: #2563eb;\n}\n\nbody {\n background: var(--bg);\n color: var(--fg);\n}`;\n\nconst SESSIONS: DemoSession[] = [\n {\n id: 'a3f1c2d4-1111-4a1b-8c3d-000000000001',\n title: 'Add a dark theme to the settings page',\n project: 'acme-web',\n branch: 'feat/dark-theme',\n rows: (cwd) => {\n const t = Date.now() - 4 * MIN;\n return [\n {\n role: 'user',\n at: t,\n content: [\n { type: 'image', source: { type: 'base64', media_type: 'image/png', data: SETTINGS_SCREENSHOT } },\n text('Add a dark theme to the settings page, with a toggle. Keep the colors in CSS variables.'),\n ],\n },\n { role: 'assistant', at: t + 4000, content: [text(\"I'll look at how the colors are set up first.\"), tool('t1', 'Read', { file_path: `${cwd}/src/styles/theme.css` })] },\n { role: 'user', at: t + 5000, content: [result('t1', numbered(THEME_CSS))] },\n {\n role: 'assistant',\n at: t + 9000,\n content: [\n text('The colors are already variables, so a dark theme is one more set of values plus a toggle that switches them.'),\n tool('t2', 'TodoWrite', {\n todos: [\n { content: 'Add dark color values', status: 'completed', activeForm: 'Adding dark color values' },\n { content: 'Add the toggle to Settings', status: 'in_progress', activeForm: 'Adding the toggle to Settings' },\n { content: 'Remember the choice', status: 'pending', activeForm: 'Remembering the choice' },\n { content: 'Run the tests', status: 'pending', activeForm: 'Running the tests' },\n ],\n }),\n ],\n },\n { role: 'user', at: t + 9500, content: [result('t2', 'Todos have been modified successfully.')] },\n {\n role: 'assistant',\n at: t + 14000,\n content: [tool('t3', 'Edit', {\n file_path: `${cwd}/src/styles/theme.css`,\n old_string: ' --accent: #2563eb;\\n}',\n new_string: \" --accent: #2563eb;\\n}\\n\\n:root[data-theme='dark'] {\\n --bg: #0b0b0c;\\n --fg: #ededed;\\n --muted: #a1a1a1;\\n --accent: #60a5fa;\\n}\",\n })],\n },\n { role: 'user', at: t + 15000, content: [result('t3', `The file ${cwd}/src/styles/theme.css has been updated successfully.`)] },\n { role: 'assistant', at: t + 19000, content: [text('Now the toggle itself, next to the other display settings:')] },\n ];\n },\n },\n {\n id: 'b7e2a9c1-2222-4b2c-9d4e-000000000002',\n title: 'Why is the nightly export slow?',\n project: 'data-pipeline',\n branch: 'main',\n rows: (cwd) => {\n const t = Date.now() - 26 * MIN;\n return [\n { role: 'user', at: t, content: 'The nightly export went from 4 minutes to 40. Can you find out why?' },\n { role: 'assistant', at: t + 5000, content: [tool('g1', 'Grep', { pattern: 'def export_rows', path: `${cwd}/pipeline` })] },\n { role: 'user', at: t + 6000, content: [result('g1', 'pipeline/export.py:41:def export_rows(batch):')] },\n { role: 'assistant', at: t + 9000, content: [tool('g2', 'Read', { file_path: `${cwd}/pipeline/export.py`, offset: 35, limit: 30 })] },\n { role: 'user', at: t + 10000, content: [result('g2', numbered('def export_rows(batch):\\n for row in batch:\\n owner = db.fetch_owner(row.owner_id)\\n write(row, owner)'))] },\n { role: 'assistant', at: t + 15000, content: [tool('g3', 'Bash', { command: 'python -m cProfile -s cumtime -m pipeline.export --sample 5000 | head -8', description: 'Profile the export on a 5,000-row sample' })] },\n {\n role: 'user',\n at: t + 31000,\n content: [result('g3', ' ncalls tottime cumtime filename:lineno(function)\\n 5000 0.412 61.902 db.py:88(fetch_owner)\\n 1 0.020 62.410 export.py:41(export_rows)\\n 5000 0.301 0.488 writer.py:12(write)')],\n },\n {\n role: 'assistant',\n at: t + 40000,\n content: [text([\n 'Found it: `export_rows` looks up each row\\'s owner one query at a time. Since the owners table grew past a million rows that lookup is no longer cached, so 5,000 rows cost 5,000 round trips.',\n '',\n '| | Before | After batching |',\n '|---|---|---|',\n '| Queries per 5,000 rows | 5,000 | 1 |',\n '| Time on the sample | 62.4 s | 0.9 s |',\n '',\n 'The fix fetches the owners for the whole batch at once:',\n '',\n '```python',\n 'owners = db.fetch_owners({row.owner_id for row in batch})',\n 'for row in batch:',\n ' write(row, owners[row.owner_id])',\n '```',\n '',\n 'Want me to apply it and add a test that counts the queries?',\n ].join('\\n'))],\n },\n ];\n },\n },\n {\n id: 'c9d3b8e2-3333-4c3d-ae5f-000000000003',\n title: 'Fix the flaky login test',\n project: 'acme-web',\n branch: 'fix/login-test',\n rows: (cwd) => {\n const t = Date.now() - 3 * HOUR;\n return [\n { role: 'user', at: t, content: 'The login test fails about one run in five on CI. Plan a fix first.' },\n {\n role: 'assistant',\n at: t + 30000,\n content: [tool('p1', 'ExitPlanMode', {\n plan: '## Fix the flaky login test\\n\\nThe test clicks **Sign in** before the form has loaded its CSRF token, so the request is sometimes rejected.\\n\\n1. Wait for the token field to be filled before submitting.\\n2. Replace the fixed 500 ms sleep with that wait.\\n3. Run the test 50 times in a row to confirm.',\n })],\n },\n { role: 'user', at: t + 90000, content: [result('p1', 'User has approved your plan. You can now start coding.')] },\n {\n role: 'assistant',\n at: t + 95000,\n content: [tool('p2', 'Edit', {\n file_path: `${cwd}/tests/login.spec.ts`,\n old_string: \" await page.waitForTimeout(500);\\n await page.click('text=Sign in');\",\n new_string: \" await expect(page.locator('input[name=csrf]')).not.toHaveValue('');\\n await page.click('text=Sign in');\",\n })],\n },\n { role: 'user', at: t + 96000, content: [result('p2', `The file ${cwd}/tests/login.spec.ts has been updated successfully.`)] },\n { role: 'assistant', at: t + 99000, content: [tool('p3', 'Bash', { command: 'npx playwright test tests/login.spec.ts --repeat-each=50', description: 'Run the login test 50 times' })] },\n { role: 'user', at: t + 160000, content: [result('p3', 'Running 50 tests using 4 workers\\n\\n 50 passed (58.2s)')] },\n { role: 'assistant', at: t + 165000, content: [text('All 50 runs pass now. The test waits for the CSRF token instead of sleeping, so it is also about 400 ms faster.')] },\n ];\n },\n },\n {\n id: 'd1e4c7f3-4444-4d4e-bf60-000000000004',\n title: 'Release notes for v2.4',\n project: 'docs-site',\n branch: 'main',\n rows: () => {\n const t = Date.now() - 26 * HOUR;\n return [\n { role: 'user', at: t, content: 'Write the release notes for v2.4 from the merged pull requests.' },\n {\n role: 'assistant',\n at: t + 50000,\n content: [text('## v2.4\\n\\n**Highlights**\\n\\n- A dark theme, which follows your system setting or can be chosen in Settings.\\n- Exports are about 60 times faster on large accounts.\\n\\n**Fixes**\\n\\n- The login page no longer fails when submitted right after it opens.\\n- Long project names no longer push the menu off screen on phones.')],\n },\n ];\n },\n },\n {\n id: 'f3a6e9b5-6666-4f60-9182-000000000006',\n title: \"Chart last week's signups\",\n project: 'data-pipeline',\n branch: 'main',\n rows: (cwd) => {\n const t = Date.now() - 50 * MIN;\n return [\n { role: 'user', at: t, content: \"Chart last week's signups by day, and make me a one-page summary I can share.\" },\n { role: 'assistant', at: t + 3000, content: [text(\"I'll read the numbers first.\"), tool('v1', 'Read', { file_path: `${cwd}/data/signups.csv` })] },\n { role: 'user', at: t + 4000, content: [result('v1', numbered(SIGNUPS_CSV.trimEnd()))] },\n { role: 'assistant', at: t + 9000, content: [tool('v2', 'mcp__visualize__show_widget', { title: 'signups_by_day', loading_messages: ['Stacking the bars'], widget_code: signupsChart() })] },\n { role: 'user', at: t + 10000, content: [result('v2', 'Shown to the user.')] },\n { role: 'assistant', at: t + 16000, content: [tool('v3', 'Write', { file_path: `${cwd}/reports/signups-week-45.html`, content: REPORT_HTML })] },\n { role: 'user', at: t + 17000, content: [result('v3', `File created successfully at: ${cwd}/reports/signups-week-45.html`)] },\n {\n role: 'assistant',\n at: t + 21000,\n content: [text('Signups grew **18%** to 12,480. Thursday was the best day (2,214), the day the newsletter went out, and the weekend stayed above the weekday average.\\n\\nThe one-pager is in `reports/signups-week-45.html`: the three numbers that matter and the chart. Open it from the step above.')],\n },\n ];\n },\n },\n // A scheduled check: every run is a session of its own, with the same folder and prompt.\n // The list folds them into the newest.\n ...[1, 7, 13].map((hours, i): DemoSession => ({\n id: `a8b9c0d1-7777-4a7b-8c7d-00000000000${7 + i}`,\n title: 'Check the export queue',\n project: 'data-pipeline',\n branch: 'main',\n rows: () => {\n const t = Date.now() - hours * HOUR;\n const id = `q${i}`;\n return [\n { role: 'user', at: t, content: 'Check the export queue: is anything stuck or failing?' },\n { role: 'assistant', at: t + 4000, content: [tool(id, 'Bash', { command: 'python3 pipeline/queue.py --status', description: 'Show the queue' })] },\n { role: 'user', at: t + 6000, content: [result(id, ['queued 0 running 1 failed 0', 'queued 3 running 1 failed 0', 'queued 0 running 0 failed 0'][i]!)] },\n { role: 'assistant', at: t + 8000, content: [text(['All clear: one export running, nothing stuck.', 'Three exports waiting behind one that runs; none failed.', 'All clear: the queue is empty.'][i]!)] },\n ];\n },\n })),\n {\n id: 'e2f5d8a4-5555-4e5f-8071-000000000005',\n title: 'Turn this CSV into JSON',\n project: 'scratch',\n branch: '',\n scratch: true,\n rows: (cwd) => {\n const t = Date.now() - 29 * HOUR;\n return [\n { role: 'user', at: t, content: 'Turn contacts.csv into a JSON array, one object per row.' },\n { role: 'assistant', at: t + 6000, content: [tool('s1', 'Bash', { command: \"python3 -c \\\"import csv, json; print(json.dumps(list(csv.DictReader(open('contacts.csv'))), indent=2))\\\" > contacts.json && wc -l contacts.json\", description: 'Convert the CSV to JSON' })] },\n { role: 'user', at: t + 8000, content: [result('s1', ` 1203 ${cwd}/contacts.json`)] },\n { role: 'assistant', at: t + 10000, content: [text('Done: `contacts.json` has 200 objects, with the CSV header as keys.')] },\n ];\n },\n },\n];\n\nconst SETTINGS_TSX = `import { FontSizePicker } from './FontSizePicker';\nimport { Section } from './Section';\n\nexport function Settings() {\n return (\n <Section title=\"Display\">\n <FontSizePicker />\n </Section>\n );\n}\n`;\n\nconst TOGGLE_TSX = `type Theme = 'light' | 'dark';\n\n/** Switches the page between the light and dark color values in theme.css. */\nexport function ThemeToggle({ value, onChange }: { value: Theme; onChange: (theme: Theme) => void }) {\n return (\n <label className=\"row\">\n Dark theme\n <input type=\"checkbox\" checked={value === 'dark'} onChange={(e) => onChange(e.target.checked ? 'dark' : 'light')} />\n </label>\n );\n}\n`;\n\nconst DARK_CSS = `${THEME_CSS.replace(' --accent: #2563eb;\\n}', \" --accent: #2563eb;\\n}\\n\\n:root[data-theme='dark'] {\\n --bg: #0b0b0c;\\n --fg: #ededed;\\n --muted: #a1a1a1;\\n --accent: #60a5fa;\\n}\")}\\n`;\n\nconst FILE_TEXT: Record<string, string> = {\n 'acme-web/src/styles/theme.css': `${THEME_CSS}\\n`,\n 'acme-web/src/settings/Settings.tsx': SETTINGS_TSX,\n 'acme-web/README.md': '# acme-web\\n\\nThe Acme web app.\\n',\n 'data-pipeline/README.md': '# data-pipeline\\n\\nNightly exports and the numbers behind them.\\n',\n 'data-pipeline/data/signups.csv': SIGNUPS_CSV,\n 'data-pipeline/reports/signups-week-45.html': REPORT_HTML,\n 'docs-site/README.md': '# docs-site\\n\\nThe public docs.\\n',\n};\n\n/**\n * The first project is a git repository with Claude's work so far left\n * uncommitted, so the Changes panel has something to show. Skipped without git.\n */\nasync function demoRepository(dir: string): Promise<void> {\n const env = { ...process.env, GIT_AUTHOR_NAME: 'Demo', GIT_AUTHOR_EMAIL: 'demo@example.com', GIT_COMMITTER_NAME: 'Demo', GIT_COMMITTER_EMAIL: 'demo@example.com' };\n // Your own git setup (hooks, templates, signing) has no say in the demo's repository.\n const git = (args: string[]) => run('git', ['-c', 'commit.gpgsign=false', '-c', 'core.hooksPath=/dev/null', '-c', 'core.fsmonitor=false', '-c', 'init.templateDir=', ...args], { cwd: dir, env, timeout: 10_000 });\n try {\n await git(['init', '-q', '-b', 'feat/dark-theme']);\n await rm(path.join(dir, 'src/settings/ThemeToggle.tsx'), { force: true });\n await git(['add', '-A']);\n await git(['commit', '-q', '--no-verify', '-m', 'Settings page']);\n await writeFile(path.join(dir, 'src/styles/theme.css'), DARK_CSS);\n await writeFile(path.join(dir, 'src/settings/ThemeToggle.tsx'), TOGGLE_TSX);\n } catch {\n // No git here; the panel shows the files only.\n }\n}\n\nconst DEMO_FILES: Record<string, string[]> = {\n 'acme-web': ['README.md', 'package.json', 'src/app.tsx', 'src/settings/Settings.tsx', 'src/settings/ThemeToggle.tsx', 'src/styles/theme.css', 'tests/login.spec.ts'],\n 'data-pipeline': ['README.md', 'data/signups.csv', 'pipeline/export.py', 'pipeline/db.py', 'pipeline/writer.py', 'reports/signups-week-45.html', 'tests/test_export.py'],\n 'docs-site': ['README.md', 'docs/releases.md'],\n};\n\n/** Writes the demo home and points the config (and the Claude Agent SDK) at it. */\nexport async function prepareDemo(): Promise<void> {\n const root = path.join(config.stateDir, 'demo');\n await rm(root, { recursive: true, force: true });\n const claudeHome = path.join(root, '.claude');\n for (const [project, files] of Object.entries(DEMO_FILES)) {\n for (const file of files) {\n const full = path.join(root, 'code', project, file);\n await mkdir(path.dirname(full), { recursive: true });\n await writeFile(full, FILE_TEXT[`${project}/${file}`] ?? '');\n }\n }\n await demoRepository(path.join(root, 'code', 'acme-web'));\n for (const session of SESSIONS) {\n const cwd = session.scratch ? path.join(root, 'scratch', '2026-11-04-7c2e') : path.join(root, 'code', session.project);\n await mkdir(cwd, { recursive: true });\n const dir = path.join(claudeHome, 'projects', cwd.replace(/[^a-zA-Z0-9]/g, '-'));\n await mkdir(dir, { recursive: true });\n let parent: string | null = null;\n const lines: string[] = [JSON.stringify({ type: 'custom-title', customTitle: session.title, sessionId: session.id })];\n for (const row of session.rows(cwd)) {\n const uuid = randomUUID();\n const message = row.role === 'assistant'\n ? { id: `msg_demo_${uuid.slice(0, 8)}`, type: 'message', role: 'assistant', model: 'claude-opus-5-5', content: row.content }\n : { role: 'user', content: row.content };\n lines.push(JSON.stringify({\n parentUuid: parent, isSidechain: false, userType: 'external', cwd, sessionId: session.id, version: '2.1.318',\n gitBranch: session.branch, type: row.role, message, uuid, timestamp: new Date(row.at).toISOString(),\n }));\n parent = uuid;\n }\n await writeFile(path.join(dir, `${session.id}.jsonl`), `${lines.join('\\n')}\\n`);\n }\n config.home = root;\n config.claudeHome = claudeHome;\n // Its own config and state too: the demo never reads or writes your password, token or push keys.\n config.configDir = path.join(root, 'config');\n config.stateDir = path.join(root, 'state');\n process.env.CLAUDE_CONFIG_DIR = claudeHome;\n process.env.PELICAN_SCRATCH_DIR = path.join(root, 'scratch');\n}\n\nexport const DEMO_MODELS: ModelOption[] = [\n { value: 'default', label: 'Default (recommended)', description: 'Opus \u00B7 best for everyday, complex tasks', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: true, resolvedModel: 'claude-opus-5-5' },\n { value: 'opus', label: 'Opus', description: 'For complex work', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: true, resolvedModel: 'claude-opus-5-5' },\n { value: 'sonnet', label: 'Sonnet', description: 'Efficient for everyday tasks', efforts: ['low', 'medium', 'high', 'xhigh', 'max'], supportsFast: false, resolvedModel: 'claude-sonnet-5-5' },\n { value: 'haiku', label: 'Haiku', description: 'Fastest for quick answers', efforts: [], supportsFast: false, resolvedModel: 'claude-haiku-5-5' },\n];\n\n/** The first demo session waits for an approval; another one is busy in Claude Desktop. */\nexport function demoRunState(sessionId: string): RunState | undefined {\n const first = SESSIONS[0]!;\n if (sessionId !== first.id) return undefined;\n const cwd = path.join(config.home, 'code', first.project);\n return {\n sessionId,\n cwd,\n busy: true,\n settings: { model: 'default', effort: 'high', permissionMode: 'default' },\n partial: [],\n permissions: [{\n // The web app's demo (src/web/lib/demo.ts) plays out Allow on this id with a reply of its own.\n id: 'demo-permission',\n sessionId,\n toolName: 'Edit',\n input: {\n file_path: `${cwd}/src/settings/Settings.tsx`,\n old_string: ' <FontSizePicker />\\n </Section>',\n new_string: ' <FontSizePicker />\\n <ThemeToggle value={theme} onChange={setTheme} />\\n </Section>',\n },\n always: 'Allow all edits this session',\n createdAt: Date.now() - 20_000,\n }],\n context: { percent: 31, tokens: 62_000, max: 200_000 },\n };\n}\n\nexport const DEMO_LIVE_SESSION = SESSIONS[1]!.id;\nexport const DEMO_WAITING_SESSION = SESSIONS[0]!.id;\n", "import type { PermissionMode as ClaudeCodeMode } from '@anthropic-ai/claude-agent-sdk';\n\n/** Claude Code's permission modes, in the order its Shift+Tab cycles through them. */\nexport const PERMISSION_MODES = ['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions', 'dontAsk'] as const;\n\nexport type PermissionMode = (typeof PERMISSION_MODES)[number];\n\n// Claude Code adding or dropping a mode fails the typecheck here instead of a session silently\n// falling back to Manual.\ntype Same<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false;\ntype Assert<T extends true> = T;\nexport type ModesMatchClaudeCode = Assert<Same<PermissionMode, ClaudeCodeMode>>;\n\nexport const isPermissionMode = (value: unknown): value is PermissionMode =>\n (PERMISSION_MODES as readonly unknown[]).includes(value);\n\n/**\n * Names as Claude Code, Claude Desktop and the docs give them, and what runs without asking in\n * each (code.claude.com/docs/en/permission-modes). `now` is said when a session switches to the\n * mode without it being picked here.\n */\nexport const MODE_INFO: Record<PermissionMode, { label: string; short: string; description: string; now: string }> = {\n default: {\n label: 'Manual',\n short: 'Manual',\n description: 'Asks before edits and commands',\n now: 'Now asking before edits and commands.',\n },\n acceptEdits: {\n label: 'Accept edits',\n short: 'Accept edits',\n description: 'Edits files and runs mkdir, mv, rm\u2026 here without asking',\n now: 'Now accepting edits for this session.',\n },\n plan: {\n label: 'Plan',\n short: 'Plan',\n description: 'Reads and plans; changes nothing until you approve',\n now: 'Now planning: nothing changes until you approve the plan.',\n },\n auto: {\n label: 'Auto',\n short: 'Auto',\n description: 'Runs everything, with safety checks in the background',\n now: 'Now in auto mode.',\n },\n bypassPermissions: {\n label: 'Bypass permissions',\n short: 'Bypass',\n description: 'Runs everything without asking. Only for isolated machines',\n now: 'Now running everything without asking.',\n },\n dontAsk: {\n label: 'Don\u2019t ask',\n short: 'Don\u2019t ask',\n description: 'Runs only what is allowed already; denies the rest',\n now: 'Now denying anything that would ask you.',\n },\n};\n\n/**\n * The modes Pelican offers to pick. Don't ask is Claude Code's mode for scripts and CI: a\n * session in it keeps it and shows it, but it is never offered.\n */\nexport const OFFERED_MODES: readonly PermissionMode[] = PERMISSION_MODES.filter((mode) => mode !== 'dontAsk');\n\n/**\n * The modes new sessions may start in, as Settings offers them. Bypass is never among them: it is\n * picked in a session, for that session alone.\n */\nexport const START_MODES: readonly PermissionMode[] = ['default', 'acceptEdits', 'plan', 'auto'];\n\n/**\n * The mode a new session starts in: the one picked in Settings, else Claude Code's own\n * permissions.defaultMode, else Auto; Manual where the model has no Auto mode. Never Bypass,\n * whatever asks for it: a new session, a branch, an edited earlier prompt or a /clear.\n */\nexport function startMode(picked: PermissionMode | undefined, claudeCode: PermissionMode | undefined, model: { supportsAuto?: boolean } | undefined): PermissionMode {\n const mode = [picked, claudeCode].find((m) => m && m !== 'bypassPermissions') ?? 'auto';\n return mode === 'auto' && model?.supportsAuto === false ? 'default' : mode;\n}\n", "/**\n * What a preview of a page or a visual Claude made may load: scripts, styles and fonts from the\n * public CDNs; images only from itself; no other server. Both sides use it: the app puts it first\n * in every preview, and the server sends it with the document running previews load into.\n */\nexport const PREVIEW_CDNS = 'https://cdnjs.cloudflare.com https://cdn.jsdelivr.net https://unpkg.com';\n\nexport const PREVIEW_POLICY = [\n \"default-src 'none'\",\n `script-src 'unsafe-inline' 'unsafe-eval' ${PREVIEW_CDNS}`,\n `style-src 'unsafe-inline' https://fonts.googleapis.com ${PREVIEW_CDNS}`,\n `font-src data: https://fonts.gstatic.com ${PREVIEW_CDNS}`,\n 'img-src data: blob:',\n 'media-src data: blob:',\n `connect-src ${PREVIEW_CDNS}`,\n 'worker-src blob:',\n \"form-action 'none'\",\n \"base-uri 'none'\",\n].join('; ');\n", "import type { ChatMessage } from './protocol';\n\nexport type Todo = { content: string; status: 'pending' | 'in_progress' | 'completed'; activeForm?: string };\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\nconst STATUSES = new Set(['pending', 'in_progress', 'completed']);\n\n/** The items of a TodoWrite call. */\nexport function todosOf(input: Record<string, unknown>): Todo[] {\n return Array.isArray(input.todos) ? (input.todos as Todo[]).filter((t) => t && typeof t.content === 'string') : [];\n}\n\n/**\n * Claude's task list as it stands after these messages. TodoWrite replaces\n * the whole list; TaskCreate adds one task and TaskUpdate changes one, by the\n * number Claude Code gave it (\"Task #3 created successfully\").\n */\nexport function currentTasks(messages: ChatMessage[]): Todo[] {\n const results = new Map<string, string>();\n for (const message of messages) {\n for (const block of message.blocks) {\n if (block.type !== 'tool_result') continue;\n const text = typeof block.content === 'string' ? block.content : block.content.map((c) => (c.type === 'text' ? c.text : '')).join('');\n results.set(block.tool_use_id, text);\n }\n }\n let tasks: Array<Todo & { id?: string }> = [];\n for (const message of messages) {\n if (message.role !== 'assistant' || message.parentToolUseId) continue;\n for (const block of message.blocks) {\n if (block.type !== 'tool_use') continue;\n const input = block.input;\n if (block.name === 'TodoWrite') {\n tasks = todosOf(input).map((t) => ({ ...t }));\n } else if (block.name === 'TaskCreate') {\n const id = results.get(block.id)?.match(/Task #(\\w+)/)?.[1] ?? String(tasks.length + 1);\n const activeForm = str(input.activeForm);\n tasks.push({ id, content: str(input.subject) ?? str(input.description) ?? 'Task', status: 'pending', ...(activeForm ? { activeForm } : {}) });\n } else if (block.name === 'TaskUpdate') {\n const task = tasks.find((t) => t.id !== undefined && t.id === String(input.taskId));\n if (!task) continue;\n const status = str(input.status);\n if (status === 'deleted') {\n tasks = tasks.filter((t) => t !== task);\n continue;\n }\n if (status && STATUSES.has(status)) task.status = status as Todo['status'];\n if (str(input.subject)) task.content = str(input.subject)!;\n if (str(input.activeForm)) task.activeForm = str(input.activeForm)!;\n }\n }\n }\n return tasks.map(({ id: _id, ...task }) => task);\n}\n", "/**\n * A session with no title of its own is called by the text of a prompt, which can be a pasted\n * page. As a title it is one line of about 60 columns, a CJK character taking two, cut where the\n * words allow and marked with an ellipsis; a title someone gave the session is never cut.\n */\n\n/** Characters drawn two columns wide: CJK, kana, Hangul, full-width forms and emoji. */\nconst WIDE = /[\u1100-\u115F\u2E80-\u303E\u3041-\u33FF\u3400-\u4DBF\u4E00-\u9FFF\uA000-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE6F\uFF00-\uFF60\uFFE0-\uFFE6\\u{20000}-\\u{3fffd}]|\\p{Emoji_Presentation}/u;\n\nconst width = (char: string) => (WIDE.test(char) ? 2 : 1);\n\n/** How many columns text takes on one line. */\nexport function columns(text: string): number {\n let total = 0;\n for (const char of text) total += width(char);\n return total;\n}\n\n/** Punctuation that ends a phrase in CJK text, where no space follows it. */\nconst CJK_STOP = /[\uFF0C\u3002\uFF1B\uFF1A\u3001\uFF01\uFF1F]/u;\nconst ASCII_STOP = /[,.;:!?]/;\n\n/**\n * Whether a title may end just before `chars[i]`: at a space or CJK punctuation, or at ASCII\n * punctuation that ends a phrase (`Chat.tsx`, `v2.4` and `10:30` hold none).\n */\nfunction breaksAt(chars: string[], i: number): boolean {\n const char = chars[i];\n if (char === undefined) return true;\n if (char === ' ' || CJK_STOP.test(char)) return true;\n if (!ASCII_STOP.test(char)) return false;\n const next = chars[i + 1];\n return next === undefined || next === ' ' || WIDE.test(next) || WIDE.test(chars[i - 1] ?? '');\n}\n\nconst TRAILING = /[\\s,.;:!?\uFF0C\u3002\uFF1B\uFF1A\u3001\uFF01\uFF1F\\-\u2013\u2014]+$/u;\n\n/** `text` on one line, at most `max` columns: cut at the last natural break, else where the limit falls. */\nexport function shortTitle(text: string, max = 60): string {\n const flat = text.replace(/\\s+/g, ' ').trim();\n if (columns(flat) <= max) return flat;\n const chars = [...flat];\n // The longest start that leaves a column for the ellipsis\u2026\n let fit = 0;\n let used = 0;\n while (fit < chars.length && used + width(chars[fit]!) <= max - 1) {\n used += width(chars[fit]!);\n fit += 1;\n }\n // \u2026ended at its last break, unless that would leave less than half of it.\n let cut = fit;\n let upTo = used;\n for (let i = fit; i > 0; i -= 1) {\n if (breaksAt(chars, i)) {\n cut = upTo >= max / 2 ? i : fit;\n break;\n }\n upTo -= width(chars[i - 1]!);\n }\n const kept = chars.slice(0, cut).join('').replace(TRAILING, '') || chars.slice(0, fit).join('');\n return `${kept}\u2026`;\n}\n", "import { randomUUID } from 'node:crypto';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\n/**\n * Sessions put away from the list. Only Pelican keeps this, in its state folder: the transcripts\n * are not touched, so every Claude Code app still has the session, and unarchiving is instant.\n */\nconst file = () => path.join(config.stateDir, 'archived.json');\nlet loaded: Promise<Set<string>> | undefined;\nlet writing: Promise<void> = Promise.resolve();\n\nasync function load(): Promise<Set<string>> {\n let text: string;\n try {\n text = await readFile(file(), 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return new Set();\n throw error;\n }\n try {\n const ids = (JSON.parse(text) as { ids?: unknown }).ids;\n return new Set(Array.isArray(ids) ? ids.filter((id): id is string => typeof id === 'string') : []);\n } catch {\n // Not ours to throw away: kept beside, and the list starts over.\n await rename(file(), `${file()}.bad-${Date.now()}`).catch(() => undefined);\n console.warn('[pelican] archived.json could not be read; it was set aside and the archive starts empty');\n return new Set();\n }\n}\n\nfunction archived(): Promise<Set<string>> {\n loaded ??= load().catch((error: Error) => {\n loaded = undefined;\n throw error;\n });\n return loaded;\n}\n\n/** The archived session ids, for the list. */\nexport async function archivedIds(): Promise<Set<string>> {\n return archived().catch(() => new Set<string>());\n}\n\n/** Archives or unarchives; writes go one at a time, each with the whole list as it is then. */\nexport async function setArchived(sessionId: string, on: boolean): Promise<void> {\n const ids = await archived();\n const before = ids.has(sessionId);\n if (on) ids.add(sessionId);\n else ids.delete(sessionId);\n const write = writing.then(async () => {\n await mkdir(path.dirname(file()), { recursive: true, mode: 0o700 });\n const temp = `${file()}.${randomUUID()}.tmp`;\n await writeFile(temp, `${JSON.stringify({ ids: [...ids] }, null, 2)}\\n`, { mode: 0o600 });\n await rename(temp, file());\n });\n writing = write.catch(() => undefined);\n try {\n await write;\n } catch (error) {\n if (before) ids.add(sessionId);\n else ids.delete(sessionId);\n throw error;\n }\n}\n", "import { randomBytes } from 'node:crypto';\nimport { realpathSync } from 'node:fs';\nimport { mkdir, stat } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { config } from './config.js';\n\nconst realpath = (p: string) => {\n try {\n return realpathSync(p);\n } catch {\n return p;\n }\n};\n\n/** Where \"New scratch session\" makes its folders. */\nexport const scratchRoot = process.env.PELICAN_SCRATCH_DIR ?? path.join(config.home, 'scratch');\n\n/**\n * Folders nobody chose as a project: the system's temp directories (Claude\n * Code's per-session scratchpads live there, and so do the folders tools\n * make inside them), Claude Desktop's scratch workspaces, and our own scratch\n * folders. Sessions in them are real conversations, but the folders are not\n * places to start new work in.\n */\nconst tempRoots = [...new Set(['/tmp', '/private/tmp', '/var/folders', '/private/var/folders', os.tmpdir(), realpath(os.tmpdir())])]\n .map((p) => p.replace(/\\/+$/, ''));\nconst scratchRoots = [path.join(config.home, 'Library/Application Support/Claude/scratch-workspaces'), scratchRoot]\n .map((p) => p.replace(/\\/+$/, ''));\n\nconst under = (dir: string, roots: string[]) => {\n const p = dir.replace(/\\/+$/, '');\n return roots.some((root) => p === root || p.startsWith(`${root}/`));\n};\n\n/**\n * temp: inside the system's temp directory. Mostly runs another session\n * started (Claude Code's per-session scratchpads live there); the OS cleans\n * these folders up. scratch: a session you started without a project, in\n * Claude Desktop or here; a real conversation in a throwaway folder.\n */\nexport function folderKind(dir: string): 'project' | 'scratch' | 'temp' {\n // The demo's made-up home can itself be in a temp folder (the scripts that record it put it\n // there): its folders are what they pretend to be.\n if (config.demo && under(dir, [config.home.replace(/\\/+$/, '')])) return under(dir, scratchRoots) ? 'scratch' : 'project';\n if (under(dir, tempRoots)) return 'temp';\n if (under(dir, scratchRoots)) return 'scratch';\n return 'project';\n}\n\nexport function isScratchFolder(dir: string): boolean {\n return folderKind(dir) !== 'project';\n}\n\nexport async function isDirectory(dir: string): Promise<boolean> {\n return stat(dir).then((s) => s.isDirectory(), () => false);\n}\n\n/** A new empty folder like `~/scratch/2026-11-05-a1b2`, for a session that belongs to no project. */\nexport async function createScratchFolder(): Promise<string> {\n const now = new Date();\n const day = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;\n const dir = path.join(scratchRoot, `${day}-${randomBytes(2).toString('hex')}`);\n await mkdir(dir, { recursive: true });\n return dir;\n}\n", "import { execFile } from 'node:child_process';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { config } from './config.js';\nimport { DEMO_LIVE_SESSION } from './demo.js';\n\n/**\n * A Claude Code process outside this app with a session open: busy, or idle and holding the\n * conversation as it last saw it. `updatedAt` is when it last worked on it.\n */\nexport type LiveProcess = {\n app?: string;\n /** Working on the session, or waiting there for an answer. */\n busy: boolean;\n /** What it waits for, in Claude Code's words (\"permission prompt\", \"input needed\"), when it waits. */\n waiting?: string;\n /** When it began waiting, ms since epoch. */\n waitingSince?: number;\n updatedAt?: number;\n};\n\nconst run = promisify(execFile);\n\ntype Proc = { ppid: number; comm: string };\n\n/** Every process's parent and name, in one `ps` (none when ps is not there). */\nasync function processes(): Promise<Map<number, Proc> | undefined> {\n try {\n const { stdout } = await run('ps', ['-A', '-o', 'pid=,ppid=,comm='], { timeout: 3000, maxBuffer: 8 * 1024 * 1024 });\n const map = new Map<number, Proc>();\n for (const line of stdout.split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(\\d+)\\s+(.*)$/.exec(line);\n if (match) map.set(Number(match[1]), { ppid: Number(match[2]), comm: match[3]!.trim() });\n }\n return map;\n } catch {\n return undefined;\n }\n}\n\n/** Started by this app, directly or through a wrapper. */\nfunction descends(pid: number, procs: Map<number, Proc>): boolean {\n for (let p = procs.get(pid)?.ppid, hops = 0; p && hops < 8; p = procs.get(p)?.ppid, hops += 1) {\n if (p === process.pid) return true;\n }\n return false;\n}\n\n/**\n * Claude Code's own clients, by the entrypoint they record. Any other program\n * that runs Claude Code is just \"elsewhere\": Pelican assumes nothing about it.\n */\nconst CLAUDE_CLIENTS: Record<string, string> = {\n 'claude-desktop': 'Claude Desktop',\n cli: 'the terminal',\n 'claude-vscode': 'VS Code',\n};\n\nlet cache: { at: number; byId: Map<string, LiveProcess> } | undefined;\n\nfunction alive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\ntype Entry = {\n pid: number; sessionId: string; status?: string; waitingFor?: unknown; entrypoint?: string; updatedAt?: number; statusUpdatedAt?: number;\n};\n\n/** The registry's entries of processes that are still running, as written (this app's own included). */\nexport async function registry(): Promise<Entry[]> {\n const dir = path.join(config.claudeHome, 'sessions');\n let names: string[] = [];\n try {\n names = (await readdir(dir)).filter((n) => /^\\d+\\.json$/.test(n));\n } catch {\n // Older Claude Code, or none running.\n }\n return (await Promise.all(names.map(async (name) => {\n try {\n const entry = JSON.parse(await readFile(path.join(dir, name), 'utf8')) as Partial<Entry>;\n return entry.sessionId && typeof entry.pid === 'number' && entry.pid !== process.pid && alive(entry.pid) ? entry as Entry : undefined;\n } catch {\n return undefined; // Being rewritten; the next read gets it.\n }\n }))).filter((e): e is Entry => Boolean(e));\n}\n\n/**\n * Sessions other apps are running, from Claude Code's own registry: every\n * Claude Code process writes `~/.claude/sessions/<pid>.json` with its session\n * id, the app that started it and whether it is busy, or waiting for an\n * answer (a permission prompt, a question). This sees a turn that is several\n * minutes into a long command, which writes nothing to the transcript\n * meanwhile. Entries of exited processes are ignored.\n */\nexport async function liveProcesses(): Promise<Map<string, LiveProcess>> {\n if (config.demo) return new Map([[DEMO_LIVE_SESSION, { app: 'Claude Desktop', busy: true }]]);\n if (cache && Date.now() - cache.at < 1500) return cache.byId;\n const byId = new Map<string, LiveProcess>();\n const entries = await registry();\n // This app's own Claude processes descend from it; when that cannot be told, those of the SDK.\n // A pid now used by something that is not Claude Code is a registry entry left behind.\n const procs = entries.length > 0 ? await processes() : undefined;\n for (const entry of entries) {\n const proc = procs?.get(entry.pid);\n // Node 24 on Linux names its main thread, so ps shows a Claude Code run by Node as MainThread.\n if (procs && (!proc || !/claude|node|bun|disclaimer|MainThread/i.test(proc.comm))) continue;\n const ours = procs ? descends(entry.pid, procs) : entry.entrypoint === 'sdk-ts';\n if (ours) continue;\n const busy = entry.status !== undefined && entry.status !== 'idle';\n const waiting = entry.status === 'waiting' ? (typeof entry.waitingFor === 'string' && entry.waitingFor) || 'input' : undefined;\n const app = CLAUDE_CLIENTS[entry.entrypoint ?? ''];\n const known = byId.get(entry.sessionId);\n // When it last changed between working and idle: other writes to the registry are not work.\n const worked = typeof entry.statusUpdatedAt === 'number' ? entry.statusUpdatedAt : entry.updatedAt;\n const updatedAt = Math.max(known?.updatedAt ?? 0, typeof worked === 'number' ? worked : 0) || undefined;\n // A session open in two places: one waiting for you matters most, then one at work.\n const rank = (p: { busy: boolean; waiting?: string } | undefined) => (p?.waiting ? 2 : p?.busy ? 1 : 0);\n const self = {\n ...(app ? { app } : {}),\n busy,\n ...(waiting ? { waiting, ...(typeof worked === 'number' ? { waitingSince: worked } : {}) } : {}),\n };\n const pick = !known || rank(self) > rank(known) ? self : known;\n byId.set(entry.sessionId, { ...pick, ...(updatedAt ? { updatedAt } : {}) });\n }\n cache = { at: Date.now(), byId };\n return byId;\n}\n", "import type { Block, ChatMessage, ImageBlock, TextBlock } from '../shared/protocol.js';\n\nconst MAX_TEXT = 60_000;\nconst MAX_RESULT_TEXT = 24_000;\nconst MAX_IMAGE_BASE64 = 2_500_000;\n\ntype Raw = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Raw => typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * The start of a long text, as a copy: a slice would keep the whole text in memory, so a clipped\n * 500 KB tool result would still cost 500 KB in every cache that holds the message.\n */\nconst head = (text: string, max: number) => structuredClone(`${text.slice(0, max)}\\n\u2026`);\n\nfunction clip(text: string, max: number): TextBlock {\n return text.length > max ? { type: 'text', text: head(text, max), truncated: true } : { type: 'text', text };\n}\n\n/** A tool call's input with its long texts cut (a Write carries the whole file); the page shows their start. */\nfunction clipInput(input: Raw): Raw {\n let clipped: Raw | undefined;\n for (const [key, value] of Object.entries(input)) {\n if (typeof value !== 'string' || value.length <= MAX_TEXT) continue;\n clipped ??= { ...input };\n clipped[key] = head(value, MAX_TEXT);\n }\n return clipped ?? input;\n}\n\n/**\n * Where a page loads the `n`th picture a message holds as data (see `storedImages`). With one, a\n * message carries addresses instead of the pictures; without, the pictures themselves (a message\n * streaming in, before the transcript has it).\n */\nexport type ImageAddress = (n: number) => string;\n\ntype Images = { address?: ImageAddress; n: number };\n\nfunction image(raw: Raw, images: Images): ImageBlock | undefined {\n const source = raw.source;\n if (!isRecord(source)) return undefined;\n if (source.type === 'base64' && typeof source.data === 'string') {\n const n = images.n;\n images.n += 1;\n if (images.address) return { type: 'image', source: { type: 'url', url: images.address(n) } };\n const mediaType = typeof source.media_type === 'string' ? source.media_type : 'image/png';\n return source.data.length > MAX_IMAGE_BASE64\n ? { type: 'image', source: { type: 'base64', media_type: mediaType, data: '' }, omitted: true }\n : { type: 'image', source: { type: 'base64', media_type: mediaType, data: source.data } };\n }\n if (source.type === 'url' && typeof source.url === 'string') return { type: 'image', source: { type: 'url', url: source.url } };\n return undefined;\n}\n\n/**\n * The pictures a message's content holds as data, in the order `ImageAddress` numbers them: its\n * own, and those inside its tool results, as `toChatMessage` meets them.\n */\nexport function storedImages(content: unknown): Array<{ mediaType: string; data: string }> {\n const found: Array<{ mediaType: string; data: string }> = [];\n const take = (raw: unknown) => {\n if (!isRecord(raw) || raw.type !== 'image' || !isRecord(raw.source)) return;\n const { type, data, media_type: mediaType } = raw.source;\n if (type === 'base64' && typeof data === 'string') found.push({ mediaType: typeof mediaType === 'string' ? mediaType : 'image/png', data });\n };\n if (!Array.isArray(content)) return found;\n for (const block of content) {\n if (!isRecord(block)) continue;\n if (block.type === 'image') take(block);\n else if (block.type === 'tool_result' && typeof block.tool_use_id === 'string' && Array.isArray(block.content)) block.content.forEach(take);\n }\n return found;\n}\n\nfunction resultContent(content: unknown, images: Images): { content: string | Array<TextBlock | ImageBlock>; truncated: boolean } {\n if (typeof content === 'string') {\n const clipped = clip(content, MAX_RESULT_TEXT);\n return { content: clipped.text, truncated: Boolean(clipped.truncated) };\n }\n if (!Array.isArray(content)) return { content: '', truncated: false };\n let truncated = false;\n const parts: Array<TextBlock | ImageBlock> = [];\n for (const part of content) {\n if (!isRecord(part)) continue;\n if (part.type === 'text' && typeof part.text === 'string') {\n const clipped = clip(part.text, MAX_RESULT_TEXT);\n truncated ||= Boolean(clipped.truncated);\n parts.push(clipped);\n } else if (part.type === 'image') {\n const img = image(part, images);\n if (img) parts.push(img);\n }\n }\n return { content: parts, truncated };\n}\n\nfunction blocks(content: unknown, images: Images): Block[] {\n if (typeof content === 'string') return content ? [clip(content, MAX_TEXT)] : [];\n if (!Array.isArray(content)) return [];\n const out: Block[] = [];\n for (const raw of content) {\n if (!isRecord(raw)) continue;\n switch (raw.type) {\n case 'text':\n if (typeof raw.text === 'string' && raw.text) out.push(clip(raw.text, MAX_TEXT));\n break;\n case 'thinking':\n if (typeof raw.thinking === 'string' && raw.thinking.trim()) out.push({ type: 'thinking', thinking: raw.thinking });\n break;\n case 'tool_use':\n case 'server_tool_use':\n if (typeof raw.id === 'string' && typeof raw.name === 'string') {\n out.push({ type: 'tool_use', id: raw.id, name: raw.name, input: isRecord(raw.input) ? clipInput(raw.input) : {} });\n }\n break;\n case 'tool_result': {\n if (typeof raw.tool_use_id !== 'string') break;\n const { content: resultBody, truncated } = resultContent(raw.content, images);\n out.push({\n type: 'tool_result',\n tool_use_id: raw.tool_use_id,\n content: resultBody,\n ...(raw.is_error === true ? { is_error: true } : {}),\n ...(truncated ? { truncated: true } : {}),\n });\n break;\n }\n case 'web_search_tool_result':\n if (typeof raw.tool_use_id === 'string') {\n const results = Array.isArray(raw.content) ? raw.content.filter(isRecord) : [];\n const text = results.map((r) => `${String(r.title ?? '')} ${String(r.url ?? '')}`.trim()).join('\\n');\n out.push({ type: 'tool_result', tool_use_id: raw.tool_use_id, content: text });\n }\n break;\n case 'image': {\n const img = image(raw, images);\n if (img) out.push(img);\n break;\n }\n case 'document':\n out.push({ type: 'text', text: '[document]' });\n break;\n default:\n break;\n }\n }\n return out;\n}\n\n/**\n * Converts a transcript message (`getSessionMessages`) or a streamed SDK message\n * into the shape the app renders. Returns undefined for messages with nothing\n * to show. With `address`, pictures held as data are referred to by address.\n */\nexport function toChatMessage(raw: Raw, address?: ImageAddress): ChatMessage | undefined {\n const type = raw.type;\n if (type !== 'user' && type !== 'assistant') return undefined;\n if (typeof raw.uuid !== 'string') return undefined;\n const message = isRecord(raw.message) ? raw.message : {};\n const out: ChatMessage = {\n uuid: raw.uuid,\n role: type,\n blocks: blocks(message.content, { ...(address ? { address } : {}), n: 0 }),\n };\n if (out.blocks.length === 0) return undefined;\n const timestamp = typeof raw.timestamp === 'string' ? Date.parse(raw.timestamp) : NaN;\n if (!Number.isNaN(timestamp)) out.timestamp = timestamp;\n const parent = raw.parent_tool_use_id;\n if (typeof parent === 'string') out.parentToolUseId = parent;\n if (type === 'assistant') {\n if (typeof message.model === 'string') out.model = message.model;\n if (typeof message.id === 'string') out.messageId = message.id;\n // Claude Code notes a failed API call as a reply of its own (in the stream: an `error` on a synthetic message).\n if (raw.isApiErrorMessage === true || (typeof raw.error === 'string' && message.model === '<synthetic>')) {\n out.apiError = true;\n if (typeof raw.error === 'string') out.error = raw.error;\n }\n }\n // Text Claude Code adds itself (an image's scale note, skill text) is meta in the transcript\n // and synthetic in the live stream; either way it is not something you typed.\n if (raw.is_meta === true || raw.isMeta === true || raw.isSynthetic === true) out.meta = true;\n if (raw.isCompactSummary === true) out.compactSummary = true;\n // Claude Code marks the row that answers a refused call; its text alone may be just the user's note.\n if (typeof raw.toolDenialKind === 'string' && raw.toolDenialKind !== 'interrupted') {\n for (const block of out.blocks) if (block.type === 'tool_result') block.denied = true;\n }\n return out;\n}\n", "import { constants } from 'node:fs';\nimport { type FileHandle, open } from 'node:fs/promises';\n\n/**\n * Opens a regular file to read. A named pipe or a device in its place is refused without waiting:\n * opening a pipe blocks one of Node's few file threads until something writes to it, and a few\n * such opens would stall every file read of the server.\n */\nexport async function openRegular(file: string): Promise<FileHandle> {\n const handle = await open(file, constants.O_RDONLY | (constants.O_NONBLOCK ?? 0));\n try {\n if (!(await handle.stat()).isFile()) throw new Error('Not a regular file');\n return handle;\n } catch (error) {\n await handle.close();\n throw error;\n }\n}\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { isPermissionMode } from '../shared/modes.js';\nimport type { ChatMessage, RecordedSettings } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { type ImageAddress, storedImages, toChatMessage } from './normalize.js';\nimport { openRegular } from './open.js';\n\n/**\n * A session's whole conversation, read from its transcript, across compactions.\n *\n * Each row of a transcript points at the one before it (`parentUuid`), so the\n * conversation is the chain from the newest message back to the first. A\n * compaction starts a new chain: its boundary row has no parent and points\n * back only through `logicalParentUuid`. Claude Code's own reader stops there,\n * which would leave everything before the last compaction out of reach; here\n * the walk carries on through every boundary. When a boundary points at a row\n * that was never written, the walk carries on from the last message the\n * compaction kept, or else from the row just before the boundary.\n *\n * The messages a compaction keeps verbatim stay where they were, before the\n * boundary; Claude Code's reader shows them again after the summary.\n *\n * A transcript only grows while its session runs, so it is read incrementally:\n * each read parses only the bytes added since the last one.\n */\n\ntype Node = {\n uuid: string;\n parent: string | undefined;\n /** On a compaction boundary: the last row before the compaction, and the last message it kept verbatim. */\n logicalParent: string | undefined;\n preservedTail: string | undefined;\n /** Position among the rows that have a uuid, in file order. */\n index: number;\n /** Where the row is in the file, in bytes: its pictures are read from there when a page asks. */\n at: number;\n bytes: number;\n /** What the app shows for this row; rows like attachments only link the chain. */\n message: ChatMessage | undefined;\n /** Roughly what the message keeps in memory. */\n weight: number;\n};\n\ntype Transcript = {\n /** Where pages load the pictures its messages hold as data. */\n address: ((uuid: string) => ImageAddress) | undefined;\n /** The settings the session last ran with, in file order. */\n recorded: RecordedSettings;\n ino: number;\n /** Bytes parsed so far, and the start of a line not finished yet. */\n offset: number;\n carry: Buffer;\n nodes: Map<string, Node>;\n order: Node[];\n /** The newest user or assistant row: where the conversation ends. */\n leaf: Node | undefined;\n /** The last walk, reused when the conversation only grew. */\n chain: Node[];\n chainIndex: Map<string, number>;\n chainLeaf: string | undefined;\n messages: ChatMessage[];\n /** What its messages keep in memory, roughly, and when it was last read. */\n weight: number;\n readAt: number;\n};\n\nconst CHUNK = 8 * 1024 * 1024;\n/**\n * Parsed transcripts are kept, so a page or a poll reads only what was added since. They are let\n * go oldest first past this much text (a few long sessions, not a count of files that may each be\n * hundreds of megabytes), and once nobody has read them for a while.\n */\nconst MAX_WEIGHT = 64 * 1024 * 1024;\nconst MAX_FILES = 32;\nconst KEEP_UNREAD_MS = 10 * 60_000;\n/**\n * A transcript read this recently is in use (a page follows its session, which grows): it is kept\n * past the budget, or two long sessions in use at once would each evict the other, and every look\n * at one would parse it whole again.\n */\nconst IN_USE_MS = 60_000;\nconst transcripts = new Map<string, Transcript>();\nconst locks = new Map<string, Promise<unknown>>();\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\n\n/** Roughly the characters a value holds: what a parsed message costs to keep. */\nfunction weightOf(value: unknown, depth = 0): number {\n if (typeof value === 'string') return value.length;\n if (value === null || typeof value !== 'object' || depth > 6) return 8;\n let weight = 32;\n for (const item of Array.isArray(value) ? value : Object.values(value)) weight += weightOf(item, depth + 1);\n return weight;\n}\n\nfunction empty(file: string, ino: number): Transcript {\n // The demo's pages are saved as files for the project site, which has no server to ask for a picture.\n const id = encodeURIComponent(path.basename(file, '.jsonl'));\n const address = config.demo ? undefined : (uuid: string) => (n: number) => `api/sessions/${id}/images/${encodeURIComponent(uuid)}/${n}`;\n return {\n address, recorded: {}, ino, offset: 0, carry: Buffer.alloc(0), nodes: new Map(), order: [], leaf: undefined,\n chain: [], chainIndex: new Map(), chainLeaf: undefined, messages: [], weight: 0, readAt: Date.now(),\n };\n}\n\n/**\n * Lets go of transcripts nobody has read for a while, then of the least recently read past the\n * budget, but not of those in use. The one read last stays, however large. One let go while a read\n * of it is under way only means the next read parses it again.\n */\nfunction trim(now = Date.now()): void {\n const newest = [...transcripts.keys()].at(-1);\n let total = 0;\n for (const [file, t] of transcripts) {\n if (file !== newest && now - t.readAt > KEEP_UNREAD_MS) transcripts.delete(file);\n else total += t.weight;\n }\n // In the order they were last read: past the first one in use, all are.\n for (const [file, t] of transcripts) {\n if (file === newest || now - t.readAt < IN_USE_MS || (total <= MAX_WEIGHT && transcripts.size <= MAX_FILES)) break;\n transcripts.delete(file);\n total -= t.weight;\n }\n}\n\nsetInterval(() => trim(), 60_000).unref();\n\n/** Keeps the settings a row shows the session ran with: the latest row wins. */\nfunction note(recorded: RecordedSettings, row: Record<string, unknown>): void {\n if (row.type === 'assistant') {\n const model = str(row.requestedModel) ?? str((row.message as { model?: unknown } | undefined)?.model);\n if (model && !model.startsWith('<')) recorded.model = model;\n if (str(row.effort)) recorded.effort = str(row.effort);\n const speed = str((row.message as { usage?: { speed?: unknown } } | undefined)?.usage?.speed);\n if (speed) recorded.fast = speed === 'fast';\n recorded.ultracode ??= false;\n } else if (row.type === 'user' && isPermissionMode(row.permissionMode)) {\n recorded.permissionMode = row.permissionMode;\n } else if (row.type === 'attachment') {\n const kind = str((row.attachment as { type?: unknown } | undefined)?.type) ?? '';\n // Claude Code notes ultracode turning on (and off) as attachments.\n if (kind === 'ultra_effort_enter') recorded.ultracode = true;\n else if (/^ultra_effort_(exit|leave|off)/.test(kind)) recorded.ultracode = false;\n }\n}\n\n/**\n * A message the user sent while Claude was working, which Claude read at its\n * next step: Claude Code records it as a `queued_command` attachment where it\n * was taken in, not as a user row.\n */\nfunction steeredMessage(row: Record<string, unknown>, uuid: string, address: ImageAddress | undefined): ChatMessage | undefined {\n const attachment = row.attachment as { type?: string; prompt?: unknown; source_uuid?: unknown; commandMode?: unknown } | undefined;\n if (row.type !== 'attachment' || attachment?.type !== 'queued_command') return undefined;\n if (attachment.commandMode !== undefined && attachment.commandMode !== 'prompt') return undefined;\n const message = toChatMessage({ type: 'user', uuid, timestamp: row.timestamp, message: { role: 'user', content: attachment.prompt } }, address);\n if (!message) return undefined;\n const source = str(attachment.source_uuid);\n return { ...message, steered: true, ...(source ? { sourceUuid: source } : {}) };\n}\n\n/** A line of Claude Code's own in the conversation, shown as a note, never as a prompt. */\nfunction noteOf(row: Record<string, unknown>, uuid: string, text: string | undefined): ChatMessage | undefined {\n if (!text?.trim()) return undefined;\n const timestamp = typeof row.timestamp === 'string' ? Date.parse(row.timestamp) : NaN;\n return { uuid, role: 'system', blocks: [{ type: 'text', text }], ...(Number.isNaN(timestamp) ? {} : { timestamp }) };\n}\n\n/**\n * What Claude Code wrote into the conversation itself when a command ran in it locally (/cost,\n * /context): the command and its output.\n */\nfunction localCommand(row: Record<string, unknown>, uuid: string): ChatMessage | undefined {\n return row.type === 'system' && row.subtype === 'local_command' ? noteOf(row, uuid, str(row.content)) : undefined;\n}\n\n/**\n * Hook feedback (why a tool call was blocked), warnings and notices, as the run showed them while\n * the turn ran, under the same id: without them here, a page that reads the transcript again once\n * the turn ends would lose them. A hook's message is an attachment, which Claude Code says as\n * \"<hook> says: \u2026\" line by line; 'info' lines are the terminal's transcript view only.\n */\nfunction notice(row: Record<string, unknown>, uuid: string): ChatMessage | undefined {\n if (row.type === 'system' && row.subtype === 'informational') return row.level === 'info' ? undefined : noteOf(row, uuid, str(row.content));\n const hook = row.attachment as { type?: unknown; content?: unknown; hookName?: unknown } | undefined;\n if (row.type !== 'attachment' || hook?.type !== 'hook_system_message' || !str(hook.content)) return undefined;\n const lines = (text: string) => text.replace(/\\r\\n?|[\\v\\f\\u0085\\u2028\\u2029]/g, '\\n').split('\\n');\n const says = `${lines(str(hook.hookName) ?? '').join(' ')} says: `;\n return noteOf(row, uuid, lines(str(hook.content)!).map((line) => says + line).join('\\n'));\n}\n\n/** Adds one row, found `at` bytes into the file and `bytes` long. */\nfunction addLine(t: Transcript, line: string, at: number, bytes: number): void {\n // Rows that take part in the conversation carry a uuid; skip the rest (titles, costs, requests) unparsed.\n if (line.length < 2 || line.charCodeAt(0) !== 123 || !line.includes('\"uuid\"')) return;\n let row: Record<string, unknown>;\n try {\n row = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return;\n }\n const uuid = str(row.uuid);\n if (!uuid || row.isSidechain === true) return;\n note(t.recorded, row);\n const turn = row.type === 'user' || row.type === 'assistant';\n const address = t.address?.(uuid);\n const message = turn ? toChatMessage(row, address) : steeredMessage(row, uuid, address) ?? localCommand(row, uuid) ?? notice(row, uuid);\n const weight = message ? weightOf(message.blocks) : 0;\n const existing = t.nodes.get(uuid);\n if (existing) {\n t.weight += weight - existing.weight;\n Object.assign(existing, { message, weight, at, bytes });\n return;\n }\n const metadata = row.compactMetadata as { preservedSegment?: { tailUuid?: unknown } } | undefined;\n const node: Node = {\n uuid,\n parent: str(row.parentUuid),\n logicalParent: str(row.logicalParentUuid),\n preservedTail: str(metadata?.preservedSegment?.tailUuid),\n index: t.order.length,\n at,\n bytes,\n message,\n weight,\n };\n t.nodes.set(uuid, node);\n t.order.push(node);\n t.weight += weight + 200;\n if (turn) t.leaf = node;\n}\n\nasync function readNew(file: string, t: Transcript, size: number): Promise<void> {\n const handle = await openRegular(file);\n try {\n // The offset moves with each chunk, together with the line it may leave unfinished: a read\n // that fails part way carries on from there next time, without reading a line twice.\n while (t.offset < size) {\n const buffer = Buffer.allocUnsafe(Math.min(CHUNK, size - t.offset));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, t.offset);\n if (bytesRead <= 0) break;\n const data = t.carry.length > 0 ? Buffer.concat([t.carry, buffer.subarray(0, bytesRead)]) : buffer.subarray(0, bytesRead);\n // Where `data` starts in the file.\n const start = t.offset - t.carry.length;\n const lastBreak = data.lastIndexOf(0x0a);\n t.offset += bytesRead;\n if (lastBreak < 0) {\n t.carry = Buffer.from(data);\n continue;\n }\n t.carry = Buffer.from(data.subarray(lastBreak + 1));\n for (let from = 0; from <= lastBreak;) {\n const end = data.indexOf(0x0a, from);\n addLine(t, data.toString('utf8', from, end), start + from, end - from);\n from = end + 1;\n }\n }\n // A last row without its newline yet: use it if it is whole; it is read again with the rest later.\n if (t.carry.length > 0) addLine(t, t.carry.toString('utf8'), t.offset - t.carry.length, t.carry.length);\n } finally {\n await handle.close();\n }\n}\n\n/**\n * The row a compaction boundary continues from. Its logical parent when that\n * was written; otherwise the last message the compaction kept, or the row\n * just before the boundary in the file.\n */\nfunction before(t: Transcript, boundary: Node): Node | undefined {\n return t.nodes.get(boundary.logicalParent!)\n ?? (boundary.preservedTail ? t.nodes.get(boundary.preservedTail) : undefined)\n ?? (boundary.index > 0 ? t.order[boundary.index - 1] : undefined);\n}\n\n/** The chain from `from` back to the start, oldest first; stops early where it meets `known`. */\nfunction walk(t: Transcript, from: Node, known?: Map<string, number>): { nodes: Node[]; joinedAt: number } {\n const out: Node[] = [];\n const seen = new Set<string>();\n let node: Node | undefined = from;\n while (node && !seen.has(node.uuid)) {\n const at = known?.get(node.uuid);\n if (at !== undefined) return { nodes: out.reverse(), joinedAt: at };\n seen.add(node.uuid);\n out.push(node);\n if (node.parent) node = t.nodes.get(node.parent);\n else if (node.logicalParent) node = before(t, node);\n else node = undefined;\n }\n return { nodes: out.reverse(), joinedAt: -1 };\n}\n\nfunction conversation(t: Transcript): ChatMessage[] {\n const leaf = t.leaf;\n if (!leaf) return [];\n if (t.chainLeaf === leaf.uuid) return t.messages;\n const { nodes, joinedAt } = walk(t, leaf, t.chainIndex);\n t.chain = joinedAt >= 0 ? t.chain.slice(0, joinedAt + 1).concat(nodes) : nodes;\n t.chainIndex = new Map(t.chain.map((n, i) => [n.uuid, i]));\n t.chainLeaf = leaf.uuid;\n t.messages = t.chain.flatMap((n) => (n.message ? [n.message] : []));\n return t.messages;\n}\n\nasync function read(file: string): Promise<ChatMessage[]> {\n let info;\n try {\n info = await stat(file);\n } catch {\n transcripts.delete(file);\n return [];\n }\n let t = transcripts.get(file);\n // Replaced or cut short: start over.\n if (!t || t.ino !== info.ino || info.size < t.offset) t = empty(file, info.ino);\n transcripts.delete(file);\n transcripts.set(file, t);\n t.readAt = Date.now();\n if (info.size > t.offset) await readNew(file, t, info.size);\n trim();\n return conversation(t);\n}\n\n/** What the session in a transcript file last ran with. */\nexport async function readRecordedSettings(file: string): Promise<RecordedSettings> {\n await readHistory(file);\n return { ...(transcripts.get(file)?.recorded ?? {}) };\n}\n\n/** The conversation in a transcript file, oldest message first. */\nexport function readHistory(file: string): Promise<ChatMessage[]> {\n // One read per file at a time: reads build on each other's state.\n const previous = locks.get(file) ?? Promise.resolve();\n const next = previous.catch(() => undefined).then(() => read(file));\n locks.set(file, next);\n void next.finally(() => {\n if (locks.get(file) === next) locks.delete(file);\n }).catch(() => undefined);\n return next;\n}\n\n/**\n * The `n`th picture a transcript row holds as data (`storedImages`), decoded: what a page loads\n * by the address its message carries. Read from the row's own place in the file.\n */\nexport async function transcriptImage(file: string, uuid: string, n: number): Promise<{ mediaType: string; data: Buffer } | undefined> {\n await readHistory(file);\n const node = transcripts.get(file)?.nodes.get(uuid);\n if (!node) return undefined;\n let row: { uuid?: unknown; type?: unknown; message?: { content?: unknown }; attachment?: { type?: unknown; prompt?: unknown } };\n const handle = await openRegular(file);\n try {\n const buffer = Buffer.alloc(node.bytes);\n await handle.read(buffer, 0, node.bytes, node.at);\n row = JSON.parse(buffer.toString('utf8')) as typeof row;\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n if (row.uuid !== uuid) return undefined;\n // A message sent while Claude worked is an attachment row; its prompt is the content.\n const content = row.type === 'attachment' && row.attachment?.type === 'queued_command' ? row.attachment.prompt : row.message?.content;\n const image = storedImages(content)[n];\n return image && { mediaType: image.mediaType, data: Buffer.from(image.data, 'base64') };\n}\n", "/**\n * Claude Code's errors (an API failure it noted in the conversation, or why a turn ended) in plain\n * words: what happened and what to do, without the API's JSON.\n */\n\ntype Kind = 'signed-out' | 'too-long' | 'credit' | 'limit' | 'overloaded' | 'api' | 'offline' | 'too-long-reply';\n\n/** Claude Code's own codes for a failed API call (the SDK's SDKAssistantMessageError), where its words say no more. */\nconst CODES: Record<string, Kind> = {\n authentication_failed: 'signed-out',\n billing_error: 'credit',\n rate_limit: 'limit',\n overloaded: 'overloaded',\n server_error: 'api',\n max_output_tokens: 'too-long-reply',\n};\n\n/** What went wrong: from the words first, which say more (when a limit resets), else from the code. */\nfunction kindOf(text: string, code?: string): Kind | undefined {\n const t = text.trim();\n if (/prompt is too long/i.test(t)) return 'too-long';\n if (/Not logged in|Please run \\/login|Invalid API key|OAuth token (has )?expired|API Error: 401\\b|authentication_failed/i.test(t)) return 'signed-out';\n if (/Credit balance is too low/i.test(t)) return 'credit';\n if (/^You['\u2019]ve hit your (?:\\w+ )?limit/i.test(t)) return 'limit';\n if (/\\b529\\b|overloaded/i.test(t)) return 'overloaded';\n if (/API Error: 5\\d\\d\\b|\"type\":\"api_error\"|Internal server error/i.test(t)) return 'api';\n if (/API Error: (?:Request timed out|Connection error)|ECONNRESET|ETIMEDOUT|fetch failed/i.test(t)) return 'offline';\n if (/exceeded the \\d+ output token maximum/i.test(t)) return 'too-long-reply';\n return code ? CODES[code] : undefined;\n}\n\n/**\n * The error in plain words, for the place it shows now (the turn that just failed, a\n * notification). Undefined for text that is not one of these; it is then shown as it is.\n * `code`: Claude Code's code for it, when it gave one.\n */\nexport function plainError(text: string, machine = 'your computer', code?: string): string | undefined {\n switch (kindOf(text, code)) {\n case 'too-long':\n return 'The conversation is too long for the model. Send /compact to shorten it, or start a new session.';\n case 'signed-out':\n return `Claude Code is not signed in on ${machine}. Run claude in a terminal there and sign in with /login.`;\n case 'credit':\n return 'The API account\u2019s credit balance is too low. Add credits in the Claude Console.';\n case 'limit': {\n const resets = text.trim().match(/^You['\u2019]ve hit your (?:\\w+ )?limit\\s*\u00B7\\s*(resets [^\\n]+)/i)?.[1];\n return `You have reached your usage limit.${resets ? ` It ${resets.trim().replace(/\\.$/, '')}.` : ''}`;\n }\n case 'overloaded':\n return 'Anthropic\u2019s API is overloaded. Try again in a moment.';\n case 'api':\n return 'Anthropic\u2019s API had a problem. Try again in a moment.';\n case 'offline':\n return `Claude Code could not reach Anthropic\u2019s API from ${machine}. Check its connection, then try again.`;\n default:\n return undefined;\n }\n}\n\n/**\n * The error as a line in the conversation, which stays there: what happened then, and for a\n * Claude Code that was signed out, what to do on the computer it runs on (it may be signed in by\n * the time the line is read).\n */\nexport function errorLine(text: string, machine = 'your computer', code?: string): string | undefined {\n if (kindOf(text, code) === 'signed-out') {\n return `Claude Code was not signed in on ${machine}, so Claude did not answer. Run claude in a terminal there and sign in with /login.`;\n }\n return plainError(text, machine, code);\n}\n\nconst STOPPED: Record<Kind, string> = {\n 'signed-out': 'not signed in',\n 'too-long': 'conversation too long',\n credit: 'credit balance too low',\n limit: 'usage limit reached',\n overloaded: 'API overloaded',\n api: 'API error',\n offline: 'API out of reach',\n 'too-long-reply': 'reply too long',\n};\n\n/** Why a turn ended on an error, in a few words for the session list (\"not signed in\"). */\nexport function stoppedBecause(text: string, code?: string): string {\n const kind = kindOf(text, code);\n return kind ? STOPPED[kind] : 'API error';\n}\n", "import { readdir, stat } from 'node:fs/promises';\nimport readline from 'node:readline';\nimport path from 'node:path';\n\nimport { stoppedBecause } from '../shared/errors.js';\nimport { config } from './config.js';\nimport { openRegular } from './open.js';\n\nconst projectsDir = () => path.join(config.claudeHome, 'projects');\n\nlet index = new Map<string, string>();\nlet indexBuiltAt = 0;\n\n/** A session's transcript, as Claude Code names it: `<session uuid>.jsonl`. */\nconst TRANSCRIPT = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\.jsonl$/i;\n\nexport type TranscriptFile = { id: string; file: string };\n\n/**\n * Rebuilds the sessionId \u2192 transcript path index from `~/.claude/projects/<dir>/<id>.jsonl`, and\n * returns every transcript found (a session copied into two projects has two).\n */\nasync function rebuildIndex(): Promise<TranscriptFile[]> {\n const next = new Map<string, string>();\n const found: TranscriptFile[] = [];\n let dirs: string[] = [];\n try {\n dirs = await readdir(projectsDir());\n } catch {\n // No projects yet.\n }\n await Promise.all(dirs.map(async (dir) => {\n try {\n for (const name of await readdir(path.join(projectsDir(), dir))) {\n if (!name.endsWith('.jsonl')) continue;\n const file = path.join(projectsDir(), dir, name);\n next.set(name.slice(0, -'.jsonl'.length), file);\n const id = TRANSCRIPT.exec(name)?.[1];\n if (id) found.push({ id, file });\n }\n } catch {\n // Not a directory, or removed meanwhile.\n }\n }));\n index = next;\n indexBuiltAt = Date.now();\n return found;\n}\n\n/** Every session transcript on this machine, looked up afresh. */\nexport function transcriptFiles(): Promise<TranscriptFile[]> {\n return rebuildIndex();\n}\n\n/** Runs at most `max` of the jobs given to it at a time; the others wait their turn. */\nexport function limiter(max: number): <T>(job: () => Promise<T>) => Promise<T> {\n let active = 0;\n const waiting: Array<() => void> = [];\n return async (job) => {\n if (active >= max) await new Promise<void>((resolve) => waiting.push(resolve));\n active += 1;\n try {\n return await job();\n } finally {\n active -= 1;\n waiting.shift()?.();\n }\n };\n}\n\n/** Path of a session's transcript, or undefined when it does not exist (yet). */\nexport async function transcriptPath(sessionId: string): Promise<string | undefined> {\n if (!index.has(sessionId) && Date.now() - indexBuiltAt > 1000) await rebuildIndex();\n return index.get(sessionId);\n}\n\nexport async function refreshTranscriptIndex(): Promise<void> {\n await rebuildIndex();\n}\n\n/** The last turn is usually in the last few kilobytes; each read back takes twice the one before. */\nconst FIRST_CHUNK = 32 * 1024;\nconst MAX_CHUNK = 1024 * 1024;\nconst MAX_SCAN = 16 * 1024 * 1024;\n\n/**\n * Markdown as one line of plain text. Marks go by where they stand, not wherever the characters\n * appear: `export_rows`, `__init__.py` and `a > b` keep theirs, which a coding session's replies\n * are full of.\n */\nexport function plainText(markdown: string): string {\n return markdown\n .replace(/^ {0,3}(`{3,}|~{3,}).*$/gm, '')\n .replace(/^[\\s|:-]*-{3,}[\\s|:-]*$/gm, '')\n .replace(/^ {0,3}#{1,6}\\s+/gm, '')\n .replace(/^ {0,3}(?:>\\s?)+/gm, '')\n .replace(/!?\\[([^\\]\\n]*)\\]\\([^)\\s]*\\)/g, '$1')\n // Code as it is; emphasis unwrapped only around whole words, so `__init__.py` stays.\n .replace(INLINE, (_, ticks: string | undefined, code: string, before: string, _mark: string, inner: string) => (ticks ? code : `${before}${inner}`))\n .replace(/`+/g, '')\n .replace(/\\|/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * A code span, or emphasis around words: `**`, `__`, `*` or `_`, closed before a space, punctuation\n * or the end. Emphasis spans a few hundred characters at most: a mark that never closes is then\n * looked past in that many steps, not in as many as the rest of its line has, which made a long line\n * of `_names` take seconds.\n */\nconst INLINE = /(`+)([^`]*?)\\1|(^|[\\s(])(\\*\\*|__|\\*|_)(?![*_\\s])(.{0,300}?[^*_\\s])\\4(?=$|\\s|[).,;:!?](?:\\s|$))/gm;\n\n/** How much of a reply can reach its 160-character preview, with room for the marks it loses on the way. */\nconst PREVIEW_SOURCE = 4000;\n\n/** The text blocks of a row's message, joined. */\nfunction textOf(row: { message?: { content?: unknown } }): string {\n const content = row.message?.content;\n if (!Array.isArray(content)) return '';\n return content\n .filter((b): b is { type: string; text: string } => b?.type === 'text' && typeof b.text === 'string')\n .map((b) => b.text)\n .join('\\n\\n');\n}\n\n/** Text blocks of an assistant row, as one line for a session-list preview: only its start is read. */\nfunction replyText(row: { message?: { content?: unknown } }): string | undefined {\n const text = plainText(textOf(row).slice(0, PREVIEW_SOURCE));\n return text ? text.slice(0, 160) : undefined;\n}\n\ntype Row = {\n type?: string; timestamp?: string; isSidechain?: boolean; cwd?: unknown; gitBranch?: unknown; forkedFrom?: unknown;\n message?: { content?: unknown; model?: unknown }; isApiErrorMessage?: unknown; error?: unknown;\n};\n\n/** Claude Code's note that the API call failed, written as a reply of its own (in the stream: an `error` on a synthetic message). */\nconst apiError = (row: Row) => row.isApiErrorMessage === true || (typeof row.error === 'string' && row.message?.model === '<synthetic>');\n\n/**\n * The last user or assistant row, read backwards from the end: its time, the\n * folder and branch it ran in, and the text of Claude's latest reply.\n *\n * Claude Desktop appends metadata rows (titles, cost state) and queued\n * notifications to idle sessions, which moves the file's mtime although\n * nothing was said; only turns count as activity.\n */\nexport type LastTurn = {\n time: number; cwd?: string; gitBranch?: string; preview?: string;\n /** The latest turn ended on an API error Claude Code noted in place of a reply: why, in a few words. */\n stopped?: string;\n /** The row was copied from another session by a fork (it carries `forkedFrom`): nothing ran here then. */\n copied?: boolean;\n /** After its last turn the session went on in another one (a background session handed off). */\n continuedIn?: string;\n /**\n * The end of the file holds a summary Claude Code wrote and no last prompt: the SDK titles the\n * session with that summary, not with a prompt (see sessionTitle).\n */\n summarized?: boolean;\n};\n\n/** After the last turn, how far back to look for a reply with text (tool calls in between). */\nconst PREVIEW_SCAN = 4 * 1024 * 1024;\n\nexport async function readLastTurn(file: string): Promise<LastTurn | undefined> {\n let handle: Awaited<ReturnType<typeof openRegular>> | undefined;\n let found: LastTurn | undefined;\n let foundAt = 0;\n let continuedIn: string | undefined;\n let summarized: boolean | undefined;\n const done = (turn: LastTurn | undefined) => (turn && summarized ? { ...turn, summarized: true } : turn);\n try {\n handle = await openRegular(file);\n const { size } = await handle.stat();\n let end = size;\n let carry = Buffer.alloc(0);\n let step = FIRST_CHUNK;\n while (end > 0 && size - end < MAX_SCAN && !(found && foundAt - end > PREVIEW_SCAN)) {\n const start = Math.max(0, end - step);\n step = Math.min(step * 2, MAX_CHUNK);\n const chunk = Buffer.alloc(end - start);\n await handle.read(chunk, 0, chunk.length, start);\n let data = Buffer.concat([chunk, carry]);\n end = start;\n if (start > 0) {\n const firstBreak = data.indexOf(0x0a);\n if (firstBreak < 0) {\n carry = data;\n continue;\n }\n carry = data.subarray(0, firstBreak);\n data = data.subarray(firstBreak + 1);\n }\n const text = data.toString('utf8');\n // Where the SDK finds a session's title: a last prompt, else a summary row, in the file's end.\n summarized ??= !text.includes('\"lastPrompt\":\"') && text.includes('\"type\":\"summary\"');\n const lines = text.split('\\n');\n for (let i = lines.length - 1; i >= 0; i -= 1) {\n const line = lines[i]!;\n if (!found && !continuedIn && line.includes('\"type\":\"continued-in\"')) {\n try {\n const id = (JSON.parse(line) as { continuedInSessionId?: unknown }).continuedInSessionId;\n if (typeof id === 'string') continuedIn = id;\n } catch {\n // Half written.\n }\n continue;\n }\n if (!line.includes('\"timestamp\"') || !(line.includes('\"type\":\"user\"') || line.includes('\"type\":\"assistant\"'))) continue;\n // Past the last turn, only rows with text matter: a reply, or the prompt that started the turn.\n if (found && !line.includes('\"type\":\"text\"') && !line.includes('\"content\":\"')) continue;\n try {\n const row = JSON.parse(line) as Row;\n if ((row.type !== 'user' && row.type !== 'assistant') || row.isSidechain || typeof row.timestamp !== 'string') continue;\n if (!found) {\n const time = Date.parse(row.timestamp);\n if (Number.isNaN(time)) continue;\n found = {\n time,\n ...(typeof row.cwd === 'string' ? { cwd: row.cwd } : {}),\n ...(typeof row.gitBranch === 'string' ? { gitBranch: row.gitBranch } : {}),\n ...(row.forkedFrom ? { copied: true } : {}),\n ...(continuedIn ? { continuedIn } : {}),\n };\n foundAt = end;\n }\n if (row.type === 'assistant') {\n // Not Claude's words: the list says why the turn stopped instead.\n if (apiError(row)) return done({ ...found, stopped: stoppedBecause(textOf(row), typeof row.error === 'string' ? row.error : undefined) });\n const preview = replyText(row);\n if (preview) return done({ ...found, preview });\n } else if (found && row.type === 'user' && typeof row.message?.content === 'string') {\n // Reached the prompt before any reply text: the turn has said nothing yet.\n return done(found);\n }\n } catch {\n // A row can be half-written while Claude is streaming into the file.\n }\n }\n }\n } catch {\n // Missing or unreadable.\n } finally {\n await handle?.close();\n }\n return done(found);\n}\n\nconst lastTurnCache = new Map<string, { size: number; mtimeMs: number; value: LastTurn | undefined }>();\n/** A first list after a start reads every transcript's end: a few at a time, not thousands at once. */\nconst reading = limiter(16);\n\n/**\n * `readLastTurn`, cached by file size and mtime. The row also gives the\n * session's folder and branch, which the SDK misses when Desktop has put\n * metadata rows at the head of the file. `known` is a stat the caller made\n * just now.\n */\nexport async function lastTurnTime(file: string, known?: { size: number; mtimeMs: number }): Promise<{ lastTurn?: LastTurn; mtimeMs: number; size: number } | undefined> {\n let info = known;\n if (!info) {\n try {\n info = await stat(file);\n } catch {\n return undefined;\n }\n }\n const { size, mtimeMs } = info;\n const cached = lastTurnCache.get(file);\n if (cached && cached.size === size && cached.mtimeMs === mtimeMs) return { lastTurn: cached.value, mtimeMs, size };\n const value = await reading(() => readLastTurn(file));\n lastTurnCache.set(file, { size, mtimeMs, value });\n return { lastTurn: value, mtimeMs, size };\n}\n\n/** Forgets what was read of files that are gone. */\nexport function forgetTranscripts(present: Set<string>): void {\n for (const file of lastTurnCache.keys()) if (!present.has(file)) lastTurnCache.delete(file);\n}\n\nconst HEAD_SCAN = 64 * 1024 * 1024;\nconst headCache = new Map<string, string | null>();\n\n/**\n * The session id on the first prompt or reply of a transcript. It is the file's own id, except\n * in a copy of another session: Claude Desktop's side chats start with the whole conversation\n * they came from, rows and ids unchanged. A file only grows at its end, so an answer is kept;\n * a file that holds no turn yet is asked again next time.\n */\nexport async function firstTurnSession(file: string): Promise<string | undefined> {\n const cached = headCache.get(file);\n if (cached !== undefined) return cached ?? undefined;\n let found: string | undefined;\n let read = 0;\n try {\n const input = (await openRegular(file)).createReadStream();\n const lines = readline.createInterface({ input, crlfDelay: Infinity });\n try {\n for await (const line of lines) {\n read += line.length + 1;\n if (read > HEAD_SCAN) break;\n if (!line.includes('\"sessionId\"') || !(line.includes('\"type\":\"user\"') || line.includes('\"type\":\"assistant\"'))) continue;\n try {\n const row = JSON.parse(line) as { type?: string; sessionId?: unknown; isSidechain?: boolean };\n if ((row.type === 'user' || row.type === 'assistant') && !row.isSidechain && typeof row.sessionId === 'string') {\n found = row.sessionId;\n break;\n }\n } catch {\n // A row being written.\n }\n }\n } finally {\n lines.close();\n input.destroy();\n }\n } catch {\n return undefined; // Missing or unreadable.\n }\n if (found) {\n if (headCache.size > 10_000) headCache.clear();\n headCache.set(file, found);\n }\n return found;\n}\n\n/** An image of a prompt as the transcript holds it, in full (the message list leaves big ones out). */\nexport type RawImage = { type: 'base64'; mediaType: string; data: string } | { type: 'url' };\n\n/** One row of a transcript, as written: what it follows in the chain, and its content. */\nexport type RawEntry = { parentUuid: string | null; content: unknown };\n\n/** The transcript row with this uuid, read from the file itself. */\nexport async function rawEntry(file: string, uuid: string): Promise<RawEntry | undefined> {\n const needle = `\"uuid\":\"${uuid}\"`;\n const input = await openRegular(file).then((handle) => handle.createReadStream(), () => undefined);\n if (!input) return undefined;\n const lines = readline.createInterface({ input, crlfDelay: Infinity });\n try {\n for await (const line of lines) {\n if (!line.includes(needle)) continue;\n let row: { uuid?: unknown; parentUuid?: unknown; type?: unknown; message?: { content?: unknown }; attachment?: { type?: unknown; prompt?: unknown } };\n try {\n row = JSON.parse(line) as typeof row;\n } catch {\n continue;\n }\n if (row.uuid !== uuid) continue;\n // A message sent while Claude worked is an attachment row; its prompt is the content.\n const content = row.type === 'attachment' && row.attachment?.type === 'queued_command' ? row.attachment.prompt : row.message?.content;\n return { parentUuid: typeof row.parentUuid === 'string' ? row.parentUuid : null, content };\n }\n } catch {\n return undefined;\n } finally {\n lines.close();\n input.destroy();\n }\n return undefined;\n}\n\n/**\n * The images of one message, in the order and by the rules the message list uses (base64 and\n * url images; anything else is not an image there), read from the transcript row itself.\n */\nexport async function rawImages(file: string, uuid: string): Promise<RawImage[]> {\n const content = (await rawEntry(file, uuid))?.content;\n if (!Array.isArray(content)) return [];\n const images: RawImage[] = [];\n for (const block of content as Array<{ type?: unknown; source?: { type?: unknown; data?: unknown; media_type?: unknown; url?: unknown } }>) {\n if (block?.type !== 'image' || !block.source) continue;\n if (block.source.type === 'base64' && typeof block.source.data === 'string') {\n images.push({ type: 'base64', mediaType: typeof block.source.media_type === 'string' ? block.source.media_type : 'image/png', data: block.source.data });\n } else if (block.source.type === 'url' && typeof block.source.url === 'string') {\n images.push({ type: 'url' });\n }\n }\n return images;\n}\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { getSessionInfo, getSubagentMessages, renameSession } from '@anthropic-ai/claude-agent-sdk';\nimport type { SDKSessionInfo } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { ChatMessage, MessagesPage, RecordedSettings, SessionStatus, SessionSummary } from '../shared/protocol.js';\nimport { shortTitle } from '../shared/titles.js';\nimport { archivedIds } from './archive.js';\nimport { config } from './config.js';\nimport { folderKind } from './folders.js';\nimport { type LiveProcess, liveProcesses } from './live.js';\nimport { readHistory, readRecordedSettings } from './history.js';\nimport { toChatMessage } from './normalize.js';\nimport { firstTurnSession, forgetTranscripts, lastTurnTime, limiter, transcriptFiles, transcriptPath } from './transcripts.js';\n\nexport type StatusSource = (sessionId: string) => SessionStatus | undefined;\n/** How much background work runs in a session this app runs (runner's runTasks). */\nexport type TaskSource = (sessionId: string) => number;\n\nconst infoCache = new Map<string, SDKSessionInfo>();\n\nconst oneLine = (text: string) => text.replace(/\\s+/g, ' ').trim();\n\n/**\n * What a session is called. A title it was given (a /rename, or the one Claude Code wrote for it)\n * and a summary Claude Code wrote stay as they are. Without either, the SDK names it by the text\n * of a prompt, the last or the first, a pasted page as likely as a line: that is shortened to a\n * title (shortTitle). `summarized`: the transcript ends on a summary Claude Code wrote, with no\n * last prompt after it, which is then what the SDK gives as `summary`.\n */\nexport function sessionTitle(info: SDKSessionInfo, summarized = false): string | undefined {\n if (info.customTitle && oneLine(info.customTitle)) return oneLine(info.customTitle);\n if (summarized && info.summary && oneLine(info.summary)) return oneLine(info.summary);\n return shortTitle(info.summary || info.firstPrompt || '') || undefined;\n}\n\n/** `fresh`: the transcript as the list stat'ed it just now; otherwise it is looked at here. */\nasync function summarize(\n info: SDKSessionInfo, status: StatusSource, tasks: TaskSource, live: Map<string, LiveProcess>, archived: Set<string>, fresh?: Seen,\n): Promise<SessionSummary> {\n const file = fresh?.file ?? await transcriptPath(info.sessionId);\n const times = file ? await lastTurnTime(file, fresh) : undefined;\n const lastTurn = times?.lastTurn;\n const lastActivity = lastTurn?.time ?? info.lastModified;\n const own = status(info.sessionId);\n const working = own ? tasks(info.sessionId) : 0;\n let state: SessionStatus = own ?? 'idle';\n // Another app's Claude process says it waits for an answer, or is busy; failing that, a turn\n // written moments ago (not one a fork just copied over: a new branch is idle until someone\n // sends to it). Idle here but at work in another app: that is what the session is doing.\n const other = live.get(info.sessionId);\n const elsewhere = !own || own === 'idle' ? other : undefined;\n const recent = lastTurn && !lastTurn.copied && Date.now() - lastTurn.time < config.liveWindowMs;\n if (elsewhere?.waiting) state = 'waiting';\n else if (elsewhere?.busy || (!own && recent)) state = 'live';\n // Where it needs you, or works: always said for a wait, since one in this app looks the same.\n const runningIn = state === 'waiting' && elsewhere?.waiting ? elsewhere.app ?? 'another app'\n : state === 'live' && elsewhere?.busy ? elsewhere.app : undefined;\n const cwd = info.cwd || lastTurn?.cwd || '';\n if (!info.cwd && cwd) infoCache.set(info.sessionId, { ...info, cwd });\n const gitBranch = lastTurn?.gitBranch ?? info.gitBranch;\n const title = sessionTitle(info, lastTurn?.summarized) ?? 'Untitled session';\n // Claude Desktop's side chats: a copy of a conversation with a question or two of its own.\n const copiedFrom = file && title === 'Side chat' ? await firstTurnSession(file) : undefined;\n const sideChatOf = copiedFrom && copiedFrom !== info.sessionId ? copiedFrom : undefined;\n return {\n id: info.sessionId,\n title,\n cwd,\n project: cwd ? path.basename(cwd) : '',\n ...(gitBranch && gitBranch !== 'HEAD' ? { gitBranch } : {}),\n lastActivity,\n ...(info.createdAt ? { createdAt: info.createdAt } : {}),\n status: state,\n ...(info.fileSize ? { sizeBytes: info.fileSize } : {}),\n ...(cwd && folderKind(cwd) === 'scratch' ? { scratch: true } : {}),\n ...(cwd && folderKind(cwd) === 'temp' ? { temp: true } : {}),\n ...(runningIn ? { runningIn } : {}),\n ...(lastTurn?.stopped ? { stopped: lastTurn.stopped } : lastTurn?.preview ? { preview: lastTurn.preview } : {}),\n ...(working > 0 ? { tasks: working } : {}),\n ...(sideChatOf ? { sideChatOf } : {}),\n ...(archived.has(info.sessionId) ? { archived: true } : {}),\n // Open, idle, in another app too: its Claude does not see what is sent here until it reopens.\n ...(other && !other.busy ? { openIn: other.app ?? 'another app' } : {}),\n };\n}\n\nconst defined = <T extends object>(value: T): Partial<T> =>\n Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial<T>;\n\n/** A transcript as the list last saw it: its size and time then, and what the SDK made of it (null: nothing to list). */\ntype Seen = { id: string; file: string; size: number; mtimeMs: number; info: SDKSessionInfo | null; continuedIn?: string };\n\n/** Every transcript the list has seen, by path. */\nconst seen = new Map<string, Seen>();\n/** The transcript each listed session is shown from. */\nconst files = new Map<string, Seen>();\nconst statting = limiter(32);\nconst asking = limiter(8);\nlet refreshing: Promise<SDKSessionInfo[]> | undefined;\n\n/**\n * Every session's info, as the SDK's `listSessions` gives it, without reading every transcript\n * each time: files are only stat'ed, and only those new or changed since the last look are read\n * again (`getSessionInfo`), a few at a time, so even a first look at thousands never stalls the\n * server. As in the SDK's listing, the newest copy of a session counts, and a session that went\n * on in another one with a transcript of its own is that one.\n */\nasync function refresh(): Promise<SDKSessionInfo[]> {\n const found = await transcriptFiles();\n const stats = await Promise.all(found.map(({ id, file }) => statting(async () => {\n const info = await stat(file).catch(() => undefined);\n return info?.isFile() ? { id, file, size: info.size, mtimeMs: info.mtimeMs } : undefined;\n })));\n const present = new Set<string>();\n const changed: Array<Omit<Seen, 'info'>> = [];\n for (const entry of stats) {\n if (!entry) continue;\n present.add(entry.file);\n const before = seen.get(entry.file);\n if (!before || before.size !== entry.size || before.mtimeMs !== entry.mtimeMs) changed.push(entry);\n }\n for (const file of seen.keys()) if (!present.has(file)) seen.delete(file);\n forgetTranscripts(present);\n await Promise.all(changed.map((entry) => asking(async () => {\n const turn = (await lastTurnTime(entry.file, entry))?.lastTurn;\n // The folder it ran in leads straight to the file; without one, every project is searched.\n const dir = seen.get(entry.file)?.info?.cwd ?? turn?.cwd;\n const info = (dir ? await getSessionInfo(entry.id, { dir }).catch(() => undefined) : undefined)\n ?? await getSessionInfo(entry.id).catch(() => undefined);\n seen.set(entry.file, { ...entry, info: info ?? null, ...(turn?.continuedIn ? { continuedIn: turn.continuedIn } : {}) });\n })));\n files.clear();\n for (const entry of seen.values()) {\n if (!entry.info) continue;\n const other = files.get(entry.id);\n if (!other || entry.mtimeMs > other.mtimeMs) files.set(entry.id, entry);\n }\n for (const [id, entry] of files) if (entry.continuedIn && files.has(entry.continuedIn)) files.delete(id);\n const infos = [...files.values()].map((entry) => entry.info!);\n // What a later look found (a folder the head of the file does not name) stays.\n for (const info of infos) infoCache.set(info.sessionId, { ...infoCache.get(info.sessionId), ...defined(info), sessionId: info.sessionId, summary: info.summary, lastModified: info.lastModified });\n return infos;\n}\n\n/** Requests that ask while one is being worked out share it. */\nfunction sessionInfos(): Promise<SDKSessionInfo[]> {\n refreshing ??= refresh().finally(() => {\n refreshing = undefined;\n });\n return refreshing;\n}\n\n/** Every session on this machine, newest activity first. */\nexport async function listSummaries(status: StatusSource, tasks: TaskSource = () => 0): Promise<SessionSummary[]> {\n const infos = await sessionInfos();\n const [live, archived] = await Promise.all([liveProcesses(), archivedIds()]);\n const summaries = await Promise.all(infos.map((info) => summarize(infoCache.get(info.sessionId) ?? info, status, tasks, live, archived, files.get(info.sessionId))));\n return summaries.sort((a, b) => b.lastActivity - a.lastActivity);\n}\n\nexport async function sessionInfo(sessionId: string): Promise<SDKSessionInfo | undefined> {\n // Without a project dir, `getSessionInfo` searches every project and may leave `cwd` out; the\n // list has both. One it has not seen yet is searched for, never a whole listing.\n const cached = infoCache.get(sessionId);\n // The folder it last ran in may not be the one its transcript is filed under: then search.\n const info = (cached?.cwd ? await getSessionInfo(sessionId, { dir: cached.cwd }).catch(() => undefined) : undefined)\n ?? await getSessionInfo(sessionId).catch(() => undefined);\n if (!info) return cached;\n let cwd = info.cwd || cached?.cwd;\n if (!cwd) {\n const file = await transcriptPath(sessionId);\n cwd = file ? (await lastTurnTime(file))?.lastTurn?.cwd : undefined;\n }\n const merged = { ...cached, ...defined(info), sessionId, summary: info.summary, lastModified: info.lastModified, ...(cwd ? { cwd } : {}) };\n infoCache.set(sessionId, merged);\n return merged;\n}\n\nexport async function sessionSummary(sessionId: string, status: StatusSource, tasks: TaskSource = () => 0): Promise<SessionSummary | undefined> {\n const info = await sessionInfo(sessionId);\n return info ? summarize(info, status, tasks, await liveProcesses(), await archivedIds()) : undefined;\n}\n\nexport async function renameSessionTitle(sessionId: string, title: string): Promise<void> {\n const dir = infoCache.get(sessionId)?.cwd;\n await renameSession(sessionId, title, dir ? { dir } : {});\n infoCache.delete(sessionId);\n}\n\n/** What the session last ran with, from its transcript; empty for a session not written yet. */\nexport async function recordedSettings(sessionId: string): Promise<RecordedSettings> {\n const file = await transcriptPath(sessionId);\n return file ? readRecordedSettings(file) : {};\n}\n\n/** The whole conversation, oldest first, including what came before each compaction. */\nexport async function loadMessages(sessionId: string): Promise<ChatMessage[]> {\n const file = await transcriptPath(sessionId);\n return file ? readHistory(file) : [];\n}\n\n/**\n * Files Claude handed to the user in a session (SendUserFile, Artifact): the\n * only files outside the session's folder the app may show, and only these paths.\n */\nexport async function sentFiles(sessionId: string): Promise<Set<string>> {\n const messages = await loadMessages(sessionId);\n // Only calls that ran: one Claude only wrote (no app answered it, or it failed) hands over nothing.\n const ran = new Set<string>();\n for (const message of messages) {\n for (const block of message.blocks) if (block.type === 'tool_result' && !block.is_error) ran.add(block.tool_use_id);\n }\n const paths = new Set<string>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const block of message.blocks) {\n if (block.type !== 'tool_use' || !ran.has(block.id)) continue;\n if (block.name === 'SendUserFile' && Array.isArray(block.input.files)) {\n for (const file of block.input.files) if (typeof file === 'string') paths.add(file);\n } else if (block.name === 'Artifact' && typeof block.input.file_path === 'string') {\n paths.add(block.input.file_path);\n }\n }\n }\n return paths;\n}\n\n/** What a subagent did inside an Agent call: its own transcript, next to the session's. */\nexport async function loadSubagent(sessionId: string, agentId: string): Promise<ChatMessage[]> {\n if (!/^[\\w-]{1,80}$/.test(agentId)) return [];\n const dir = infoCache.get(sessionId)?.cwd;\n const raw = await getSubagentMessages(sessionId, agentId, dir ? { dir } : {}).catch(() => []);\n return raw\n .map((message) => toChatMessage(message as unknown as Record<string, unknown>))\n .filter((message): message is ChatMessage => Boolean(message));\n}\n\n/** A page of messages ending before index `before` (default: the end). */\nexport async function loadPage(sessionId: string, before: number | undefined, limit: number): Promise<MessagesPage> {\n const all = await loadMessages(sessionId);\n const end = Math.min(before ?? all.length, all.length);\n const offset = Math.max(0, end - limit);\n return { messages: all.slice(offset, end), total: all.length, offset };\n}\n", "import { deleteSession, forkSession } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { ChatMessage } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { loadMessages, sessionInfo } from './sessions.js';\nimport { refreshTranscriptIndex } from './transcripts.js';\n\n/**\n * A copy of the session to carry on separately. With `upTo`, the copy ends at\n * that message, which is how \"edit and resend\" works: the conversation\n * branches before the prompt you change, and the original stays as it was.\n */\nexport async function fork(sessionId: string, upTo?: string, title?: string): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing changes.');\n const info = await sessionInfo(sessionId);\n const result = await forkSession(sessionId, {\n ...(info?.cwd ? { dir: info.cwd } : {}),\n ...(upTo ? { upToMessageId: upTo } : {}),\n ...(title ? { title } : {}),\n });\n await refreshTranscriptIndex();\n return result.sessionId;\n}\n\n/**\n * Where a branch that rewrites the message `uuid` starts: the message just\n * before it, or null when `uuid` is the first one (the branch is then a new\n * session in the same folder). Undefined when the message is not there.\n */\nexport async function messageBefore(sessionId: string, uuid: string): Promise<string | null | undefined> {\n const messages = await loadMessages(sessionId);\n const at = messages.findIndex((m) => m.uuid === uuid);\n if (at < 0) return undefined;\n return at === 0 ? null : messages[at - 1]!.uuid;\n}\n\nexport async function remove(sessionId: string): Promise<void> {\n if (config.demo) throw new Error('This is the demo: nothing changes.');\n const info = await sessionInfo(sessionId);\n await deleteSession(sessionId, info?.cwd ? { dir: info.cwd } : {});\n await refreshTranscriptIndex();\n}\n\nconst toolLine = (name: string, input: Record<string, unknown>) => {\n const target = ['file_path', 'command', 'pattern', 'url', 'query', 'description'].map((k) => input[k]).find((v) => typeof v === 'string');\n return `- ${name}${target ? `: \\`${String(target).split('\\n')[0]}\\`` : ''}`;\n};\n\n/** The conversation as Markdown: prompts and replies in full, tool calls as one line each. */\nexport async function exportMarkdown(sessionId: string): Promise<{ title: string; markdown: string }> {\n const info = await sessionInfo(sessionId);\n const title = info?.customTitle || info?.summary || 'Claude Code session';\n const messages: ChatMessage[] = await loadMessages(sessionId);\n const out: string[] = [`# ${title}`, ''];\n if (info?.cwd) out.push(`Folder: \\`${info.cwd}\\``, '');\n let speaker: string | undefined;\n for (const message of messages) {\n // Claude Code's own notes (a local command's output) are neither side of the conversation.\n if (message.meta || message.parentToolUseId || message.role === 'system') continue;\n const parts: string[] = [];\n const tools: string[] = [];\n for (const block of message.blocks) {\n if (block.type === 'text' && block.text.trim()) parts.push(block.text.trim());\n else if (block.type === 'tool_use') tools.push(toolLine(block.name, block.input));\n }\n if (parts.length === 0 && tools.length === 0) continue;\n const who = message.role === 'user' ? 'You' : 'Claude';\n if (who !== speaker) {\n out.push(`## ${who}`, '');\n speaker = who;\n }\n if (tools.length > 0) out.push(...tools, '');\n if (parts.length > 0) out.push(parts.join('\\n\\n'), '');\n }\n return { title, markdown: `${out.join('\\n').trim()}\\n` };\n}\n", "import { stat } from 'node:fs/promises';\n\nimport type { ChatMessage, ServerEvent } from '../shared/protocol.js';\nimport { loadMessages } from './sessions.js';\nimport { transcriptPath } from './transcripts.js';\n\nexport type Listener = (event: ServerEvent) => void;\n\nconst POLL_MS = 1000;\n/**\n * How long a published message waits for a client that subscribes late (a new session's first\n * prompt, sent before the page could subscribe). Later ones come from the transcript.\n */\nconst RECENT_MS = 2 * 60_000;\n\n/**\n * Delivers one session's messages to the clients viewing it.\n *\n * Messages come from two places: the stream of a turn this app runs, and the\n * transcript file, which other clients (Desktop, the terminal) also write.\n * Both carry the same ids, so each message is delivered once. The file is\n * polled while anyone is watching; a stat per second is cheap and works the\n * same on macOS and Linux, unlike file watchers across atomic rewrites.\n */\nclass Feed {\n readonly listeners = new Set<Listener>();\n private delivered = new Set<string>();\n /** Recently published messages, replayed to a client that subscribes late (a new session's first prompt). */\n private recent: Array<{ message: ChatMessage; at: number }> = [];\n /** Ids last read from the file; one that disappears means the conversation was rewound. */\n private fromFile = new Set<string>();\n private primed?: Promise<void>;\n private size = -1;\n private mtimeMs = -1;\n private timer?: NodeJS.Timeout;\n private checking = false;\n\n constructor(readonly sessionId: string) {}\n\n private async prime(): Promise<void> {\n this.primed ??= (async () => {\n const file = await transcriptPath(this.sessionId);\n if (file) {\n const info = await stat(file).catch(() => undefined);\n if (info) {\n this.size = info.size;\n this.mtimeMs = info.mtimeMs;\n }\n }\n for (const message of await loadMessages(this.sessionId)) {\n this.delivered.add(message.uuid);\n this.fromFile.add(message.uuid);\n }\n // Clients could not load it either while it failed: they read it whole now.\n if (this.unprimed) this.broadcast({ type: 'reload', sessionId: this.sessionId });\n this.unprimed = false;\n })().catch((error: unknown) => {\n // Tried again at the next poll: the file may be readable by then (a write finished, its owner changed).\n this.primed = undefined;\n this.unprimed = true;\n throw error;\n });\n return this.primed;\n }\n\n private unprimed = false;\n\n /** Said once until reading works again, not once a second. */\n private failing = false;\n\n private failed(error: unknown): void {\n if (this.failing) return;\n this.failing = true;\n console.warn(`[pelican] cannot read the transcript of ${this.sessionId.slice(0, 8)}: ${(error as Error).message ?? error}`);\n }\n\n broadcast(event: ServerEvent): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // A closed socket; its unsubscribe follows.\n }\n }\n }\n\n /** Publishes still on their way (priming reads the transcript first). */\n publishing = 0;\n\n async publish(message: ChatMessage): Promise<void> {\n this.publishing += 1;\n try {\n // A transcript that cannot be read must not stop the run publishing: the message goes out anyway.\n await this.prime().catch((error: unknown) => this.failed(error));\n if (this.delivered.has(message.uuid)) return;\n this.delivered.add(message.uuid);\n this.recent.push({ message, at: Date.now() });\n if (this.recent.length > 40) this.recent.shift();\n this.broadcast({ type: 'message', sessionId: this.sessionId, message });\n } finally {\n this.publishing -= 1;\n }\n }\n\n /** Whether it still holds messages for a late subscriber; older ones are let go. */\n hasRecent(now = Date.now()): boolean {\n this.recent = this.recent.filter((r) => now - r.at < RECENT_MS);\n return this.recent.length > 0;\n }\n\n /**\n * What a late subscriber missed: messages published that the transcript does not hold yet. The\n * rest its page reads from the transcript, pictures by address, not as megabytes of data again.\n */\n async unwritten(): Promise<ChatMessage[]> {\n if (!this.hasRecent()) return [];\n const recent = this.recent.map((r) => r.message);\n // Unreadable, it is no help to the page either: everything goes, as published.\n const messages = await loadMessages(this.sessionId).catch(() => []);\n const written = new Set(messages.flatMap((m) => (m.sourceUuid ? [m.uuid, m.sourceUuid] : [m.uuid])));\n return recent.filter((message) => !written.has(message.uuid));\n }\n\n /** Nobody watches, nothing is on its way, nothing waits for a late subscriber: it can go. */\n get idle(): boolean {\n return this.listeners.size === 0 && this.publishing === 0 && !this.hasRecent();\n }\n\n watch(): void {\n if (this.timer) return;\n void this.prime().catch((error: unknown) => this.failed(error));\n this.timer = setInterval(() => {\n void this.check().then((changed) => {\n if (changed) sessionsChanged();\n });\n }, POLL_MS);\n }\n\n unwatch(): void {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n\n get watching(): boolean {\n return Boolean(this.timer);\n }\n\n /** Delivers what the transcript gained since the last look; never fails (a poll nobody awaits). */\n async check(): Promise<boolean> {\n if (this.checking) return false;\n this.checking = true;\n try {\n return await this.read();\n } catch (error) {\n this.failed(error);\n return false;\n } finally {\n this.checking = false;\n }\n }\n\n private async read(): Promise<boolean> {\n await this.prime();\n const file = await transcriptPath(this.sessionId);\n if (!file) return false;\n const info = await stat(file).catch(() => undefined);\n if (!info || (info.size === this.size && info.mtimeMs === this.mtimeMs)) return false;\n const messages = await loadMessages(this.sessionId);\n // Only once it was read: a file that could not be is tried again at the next poll.\n this.size = info.size;\n this.mtimeMs = info.mtimeMs;\n this.failing = false;\n const present = new Set(messages.map((m) => m.uuid));\n for (const uuid of this.fromFile) {\n if (!present.has(uuid)) {\n this.fromFile = present;\n this.delivered = new Set(present);\n this.broadcast({ type: 'reload', sessionId: this.sessionId });\n return true;\n }\n }\n this.fromFile = present;\n for (const message of messages) {\n if (this.delivered.has(message.uuid)) continue;\n this.delivered.add(message.uuid);\n this.broadcast({ type: 'message', sessionId: this.sessionId, message });\n }\n return true;\n }\n}\n\nconst feeds = new Map<string, Feed>();\nconst everyone = new Set<Listener>();\nlet changedTimer: NodeJS.Timeout | undefined;\n\nexport function feedFor(sessionId: string): Feed {\n let feed = feeds.get(sessionId);\n if (!feed) {\n feed = new Feed(sessionId);\n feeds.set(sessionId, feed);\n }\n return feed;\n}\n\n/** Tells every connected client the session list changed, at most every 2 s. */\nexport function sessionsChanged(): void {\n if (changedTimer) return;\n changedTimer = setTimeout(() => {\n changedTimer = undefined;\n for (const listener of everyone) {\n try {\n listener({ type: 'sessions_changed' });\n } catch {\n // Closed socket.\n }\n }\n }, 2000);\n}\n\nexport function broadcastAll(event: ServerEvent): void {\n for (const listener of everyone) {\n try {\n listener(event);\n } catch {\n // Closed socket.\n }\n }\n}\n\nexport function connect(listener: Listener): () => void {\n everyone.add(listener);\n return () => everyone.delete(listener);\n}\n\nexport function subscribe(sessionId: string, listener: Listener): () => void {\n const feed = feedFor(sessionId);\n // A late subscriber gets what it missed first; what happens meanwhile waits, to come after it.\n let waiting: ServerEvent[] | undefined = feed.hasRecent() ? [] : undefined;\n const subscriber: Listener = (event) => (waiting ? waiting.push(event) : listener(event));\n feed.listeners.add(subscriber);\n if (waiting) {\n void feed.unwritten().catch((): ChatMessage[] => []).then((missed) => {\n const meanwhile = waiting ?? [];\n waiting = undefined;\n if (!feed.listeners.has(subscriber)) return;\n try {\n for (const message of missed) listener({ type: 'message', sessionId, message });\n for (const event of meanwhile) listener(event);\n } catch {\n // A closed socket; its unsubscribe follows.\n }\n });\n }\n feed.watch();\n return () => {\n feed.listeners.delete(subscriber);\n if (feed.listeners.size > 0) return;\n feed.unwatch();\n // Forgotten once idle, so feeds do not pile up for every session ever opened or run. A run\n // that publishes again gets a new one, which reads the transcript first like any other.\n if (feed.idle && feeds.get(sessionId) === feed) feeds.delete(sessionId);\n };\n}\n\n/** Feeds of runs that published with nobody watching go too, once their messages are old. */\nfunction sweep(): void {\n for (const [sessionId, feed] of feeds) if (feed.idle) feeds.delete(sessionId);\n}\n\nsetInterval(sweep, 60_000).unref();\n\n/** How many feeds are kept, for tests. */\nexport const feedCount = () => feeds.size;\n", "import { randomUUID } from 'node:crypto';\nimport { mkdir, readdir, readFile, realpath, rm, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { Attachment } from '../shared/protocol.js';\nimport { config } from './config.js';\n\nconst uploadsDir = () => path.join(config.stateDir, 'uploads');\nexport const MAX_UPLOAD_BYTES = 25 * 1024 * 1024;\n\nconst safeName = (name: string) => name.replace(/[/\\\\\\0]/g, '_').replace(/^\\.+/, '_').slice(0, 120) || 'file';\n\n/** Saves an uploaded file where Claude can read it, and returns its handle. */\nexport async function saveUpload(file: File): Promise<Attachment> {\n if (file.size > MAX_UPLOAD_BYTES) throw new Error(`File is larger than ${MAX_UPLOAD_BYTES / 1024 / 1024} MB`);\n const id = randomUUID();\n const dir = path.join(uploadsDir(), id);\n await mkdir(dir, { recursive: true, mode: 0o700 });\n const name = safeName(file.name);\n const filePath = path.join(dir, name);\n await writeFile(filePath, Buffer.from(await file.arrayBuffer()), { mode: 0o600 });\n return { id, name, mime: file.type || 'application/octet-stream', size: file.size, path: filePath };\n}\n\n/** Looks an upload up by id; the path is rebuilt here, never taken from the client. */\nexport async function findUpload(id: string): Promise<Attachment | undefined> {\n if (!/^[0-9a-f-]{36}$/.test(id)) return undefined;\n const dir = path.join(uploadsDir(), id);\n try {\n const [name] = await readdir(dir);\n if (!name) return undefined;\n const filePath = path.join(dir, name);\n const info = await stat(filePath);\n return { id, name, mime: mimeOf(name), size: info.size, path: filePath };\n } catch {\n return undefined;\n }\n}\n\nexport async function readUpload(id: string): Promise<{ attachment: Attachment; data: Buffer } | undefined> {\n const attachment = await findUpload(id);\n if (!attachment) return undefined;\n return { attachment, data: await readFile(attachment.path) };\n}\n\nconst MIME: Record<string, string> = {\n png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp',\n pdf: 'application/pdf', txt: 'text/plain', md: 'text/markdown', json: 'application/json', csv: 'text/csv',\n};\nconst mimeOf = (name: string) => MIME[name.split('.').pop()?.toLowerCase() ?? ''] ?? 'application/octet-stream';\n\nexport type DirListing = { path: string; parent?: string; dirs: Array<{ name: string; path: string }> };\n\n/** Subfolders of a folder, for choosing where a new session runs. */\nexport async function listDirs(dir: string | undefined, showHidden: boolean): Promise<DirListing> {\n const target = path.resolve(dir || config.home);\n const entries = await readdir(target, { withFileTypes: true });\n const dirs = entries\n .filter((e) => (e.isDirectory() || e.isSymbolicLink()) && (showHidden || !e.name.startsWith('.')))\n .map((e) => ({ name: e.name, path: path.join(target, e.name) }))\n .sort((a, b) => a.name.localeCompare(b.name));\n const parent = path.dirname(target);\n return { path: target, ...(parent !== target ? { parent } : {}), dirs };\n}\n\n/** Why a folder could not be made, said to the person who asked, with the HTTP status that fits. */\nexport class FolderError extends Error {\n constructor(message: string, readonly status: 400 | 403 | 404 | 409) {\n super(message);\n }\n}\n\n/**\n * Makes a folder for a new session inside the one being browsed, as a system folder picker's New\n * Folder does: one level, a plain name, never an existing folder. It runs nothing in it.\n */\nexport async function makeDir(parent: string, name: string): Promise<string> {\n const clean = name.trim();\n if (!clean || clean === '.' || clean === '..' || clean.length > 255 || /[/\\\\]/.test(clean) || /[\\u0000-\\u001f\\u007f]/.test(clean)) {\n throw new FolderError('Use a folder name without slashes', 400);\n }\n let base: string;\n try {\n base = await realpath(path.resolve(parent));\n if (!(await stat(base)).isDirectory()) throw new Error('not a folder');\n } catch {\n throw new FolderError('That folder is gone', 404);\n }\n const target = path.join(base, clean);\n try {\n await mkdir(target);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'EEXIST') throw new FolderError(`There is already a ${clean} here`, 409);\n if (code === 'EACCES' || code === 'EPERM' || code === 'EROFS') throw new FolderError('You cannot make a folder here', 403);\n throw error;\n }\n return target;\n}\n\n/** Removes an upload (made for a message that was never sent). */\nexport async function removeUpload(id: string): Promise<void> {\n if (!/^[0-9a-f-]{36}$/.test(id)) return;\n await rm(path.join(uploadsDir(), id), { recursive: true, force: true });\n}\n\n/**\n * How long Claude Code keeps sessions: `cleanupPeriodDays` in its settings, 30 days unless set.\n * Uploads are kept as long: past that, the conversations that used them are gone too.\n */\nexport async function keepDays(): Promise<number> {\n try {\n const days = (JSON.parse(await readFile(path.join(config.claudeHome, 'settings.json'), 'utf8')) as { cleanupPeriodDays?: unknown }).cleanupPeriodDays;\n // 0 keeps no transcripts at all; an upload still lives through the day it is sent.\n if (typeof days === 'number' && Number.isFinite(days) && days >= 0) return Math.max(1, days);\n } catch {\n // No settings, or not JSON: Claude Code's default.\n }\n return 30;\n}\n\n/** Removes uploads older than `maxAgeMs`; returns how many went. */\nexport async function sweepUploads(maxAgeMs: number, now = Date.now()): Promise<number> {\n let names: string[];\n try {\n names = await readdir(uploadsDir());\n } catch {\n return 0;\n }\n let removed = 0;\n for (const name of names) {\n if (!/^[0-9a-f-]{36}$/.test(name)) continue;\n const dir = path.join(uploadsDir(), name);\n const info = await stat(dir).catch(() => undefined);\n if (!info?.isDirectory() || now - info.mtimeMs < maxAgeMs) continue;\n await rm(dir, { recursive: true, force: true });\n removed += 1;\n }\n return removed;\n}\n", "import { execFile } from 'node:child_process';\nimport { mkdir, readdir, realpath, rename, stat, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { listSessions } from '@anthropic-ai/claude-agent-sdk';\n\nimport { config } from './config.js';\nimport { openRegular } from './open.js';\nimport { lastTurnTime, transcriptPath } from './transcripts.js';\n\n/**\n * Folder trust. A folder can bring programs of its own: hooks, MCP servers, helper commands and\n * environment variables in its Claude Code settings, commands, skills and agents that run a shell\n * or tools without asking, filters in its git config. Claude Code asks before it runs them in an\n * interactive session, but an SDK session never asks, so Pelican asks instead, before the first\n * Claude Code process in a folder nobody has trusted.\n *\n * A folder is trusted when Claude Code's own record says so (the CLI's trust dialog, read and never\n * written), when it was trusted in Pelican, when Pelican made it (a scratch folder), or when Claude\n * Code has already run there. \"Use my settings only\" starts Claude Code there with the user's\n * settings and none of the folder's, and with the folder's git programs turned off.\n */\n\nexport type TrustChoice = 'trusted' | 'user-only';\nexport type SettingSource = 'user' | 'project' | 'local';\n\n/** How Claude Code is started in a folder. */\nexport type Launch = { settingSources: SettingSource[]; env?: Record<string, string> };\n\nexport const FULL_SETTINGS: Launch = { settingSources: ['user', 'project', 'local'] };\n\n/** Starting Claude Code would run what the folder brings, and nobody has said it may. */\nexport class NeedsTrust extends Error {\n constructor(readonly folder: string, readonly brings: string[]) {\n super('Trust this folder before Claude Code starts in it.');\n }\n}\n\nconst exists = (file: string) => stat(file).then(() => true, () => false);\nconst real = (folder: string) => realpath(folder).catch(() => path.resolve(folder));\n\n/** Larger than any settings file; a folder could otherwise make the server read without end. */\nconst MAX_READ = 16 * 1024 * 1024;\n\n/**\n * A file's text, read only when it is a regular file of a sane size (`odd` when something else is\n * there): a named pipe in its place would hold one of Node's few file threads until someone wrote\n * to it, and a folder from a tarball can bring one.\n */\nasync function readText(file: string): Promise<{ text?: string; odd?: true }> {\n let handle: Awaited<ReturnType<typeof openRegular>>;\n try {\n handle = await openRegular(file);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n return code === 'ENOENT' || code === 'ENOTDIR' ? {} : { odd: true };\n }\n try {\n if ((await handle.stat()).size > MAX_READ) return { odd: true };\n return { text: await handle.readFile('utf8') };\n } catch {\n return { odd: true };\n } finally {\n await handle.close();\n }\n}\n\n/** A JSON file's value (undefined when it is missing or not JSON), and whether it is not a regular file. */\nasync function readJsonFile(file: string): Promise<{ value: unknown; odd?: true }> {\n const { text, odd } = await readText(file);\n try {\n return { value: text === undefined ? undefined : JSON.parse(text) as unknown, ...(odd ? { odd } : {}) };\n } catch {\n return { value: undefined };\n }\n}\n\nconst readJson = async (file: string): Promise<unknown> => (await readJsonFile(file)).value;\n\nconst isObject = (value: unknown): value is Record<string, unknown> => Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n\n/** Whether a folder is itself a git directory (HEAD, objects, refs), which git takes as a repository. */\nasync function isGitDirectory(dir: string): Promise<boolean> {\n const [head, objects, refs] = await Promise.all(['HEAD', 'objects', 'refs'].map((name) => stat(path.join(dir, name)).catch(() => undefined)));\n return Boolean(head?.isFile() && objects?.isDirectory() && refs?.isDirectory());\n}\n\n/** The top of the git repository a folder is in, by its `.git`, or a git directory git would use (this runs nothing). */\nasync function gitRoot(dir: string): Promise<string | undefined> {\n for (let d = dir; ; d = path.dirname(d)) {\n if ((await exists(path.join(d, '.git'))) || (await isGitDirectory(d))) return d;\n if (path.dirname(d) === d) return undefined;\n }\n}\n\n/** The folder and the parents Claude Code looks at for its trust: up to the repository's top, else to the root. */\nasync function lineage(dir: string): Promise<string[]> {\n const top = await gitRoot(dir);\n const dirs: string[] = [];\n for (let d = dir; ; d = path.dirname(d)) {\n dirs.push(d);\n if (d === top || path.dirname(d) === d) return dirs;\n }\n}\n\n// A yes holds for a while; a no is asked again soon (the folder's first session may be starting).\nconst YES_MS = 30_000;\nconst NO_MS = 3_000;\nconst ranCache = new Map<string, { at: number; value: boolean }>();\n\n/**\n * Whether Claude Code has run in this very folder, so what the folder brings is something the user\n * already let run.\n *\n * Claude Code files sessions by the folder's path with punctuation turned into dashes, so `a.b`\n * and `a-b` share a list, and the list may fill in a session's folder from that shared name. A\n * session counts only by the folder its own transcript records, and only if it is this one.\n */\nexport async function claudeRanIn(folder: string): Promise<boolean> {\n const dir = await realpath(folder).catch(() => folder);\n if (dir === os.homedir() || dir === (await real(os.homedir()))) return true;\n const cached = ranCache.get(dir);\n if (cached && Date.now() - cached.at < (cached.value ? YES_MS : NO_MS)) return cached.value;\n let value = false;\n const sessions = await listSessions({ dir, limit: 50, includeWorktrees: false }).catch(() => []);\n for (const session of sessions) {\n const file = await transcriptPath(session.sessionId);\n const recorded = file ? (await lastTurnTime(file))?.lastTurn?.cwd : undefined;\n if (!recorded) continue;\n if (recorded === dir || (await realpath(recorded).catch(() => '')) === dir) {\n value = true;\n break;\n }\n }\n if (ranCache.size > 2000) ranCache.clear();\n ranCache.set(dir, { at: Date.now(), value });\n return value;\n}\n\n/** Claude Code's global config, where the CLI's trust dialog records its answer. */\nconst claudeJson = () => path.join(process.env.CLAUDE_CONFIG_DIR || os.homedir(), '.claude.json');\nlet claudeConfig: { file: string; mtimeMs: number; size: number; projects: Record<string, unknown> } | undefined;\n\nasync function claudeProjects(): Promise<Record<string, unknown>> {\n const file = claudeJson();\n const info = await stat(file).catch(() => undefined);\n if (!info) return {};\n if (claudeConfig?.file === file && claudeConfig.mtimeMs === info.mtimeMs && claudeConfig.size === info.size) return claudeConfig.projects;\n const parsed = await readJson(file);\n const projects = isObject(parsed) && isObject(parsed.projects) ? parsed.projects : {};\n claudeConfig = { file, mtimeMs: info.mtimeMs, size: info.size, projects };\n return projects;\n}\n\n/** Whether the CLI's trust dialog was accepted for this folder or, as Claude Code reads it, a parent. */\nexport async function claudeCodeTrusts(folder: string): Promise<boolean> {\n const projects = await claudeProjects();\n const accepted = (dir: string) => [dir, dir.normalize('NFC')].some((key) => {\n const entry = projects[key];\n return isObject(entry) && entry.hasTrustDialogAccepted === true;\n });\n const given = path.resolve(folder);\n const dirs = new Set([...(await lineage(await real(folder))), ...(await lineage(given))]);\n for (const dir of dirs) if (accepted(dir)) return true;\n return false;\n}\n\n// What the user answered in Pelican, by the folder the answer was for (the repository's top, as\n// Claude Code keeps its own), oldest first; at most this many answers to trust.\nconst MAX_CHOICES = 1000;\nconst choicesFile = () => path.join(config.stateDir, 'trust.json');\nlet choices: { file: string; folders: Map<string, TrustChoice> } | undefined;\n\nasync function loadChoices(): Promise<Map<string, TrustChoice>> {\n const file = choicesFile();\n if (choices?.file === file) return choices.folders;\n const parsed = await readJson(file);\n const folders = new Map<string, TrustChoice>();\n if (isObject(parsed) && isObject(parsed.folders)) {\n for (const [folder, choice] of Object.entries(parsed.folders)) {\n if (path.isAbsolute(folder) && (choice === 'trusted' || choice === 'user-only')) folders.set(folder, choice);\n }\n }\n choices = { file, folders };\n return folders;\n}\n\nasync function saveChoices(folders: Map<string, TrustChoice>): Promise<void> {\n const file = choicesFile();\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const temp = `${file}.${process.pid}.tmp`;\n await writeFile(temp, `${JSON.stringify({ version: 1, folders: Object.fromEntries(folders) }, null, 2)}\\n`, { mode: 0o600 });\n await rename(temp, file);\n}\n\n/** What the user said in Pelican about this folder, or a parent of it in the same repository. */\nexport async function pelicanChoice(folder: string): Promise<TrustChoice | undefined> {\n const folders = await loadChoices();\n if (folders.size === 0) return undefined;\n for (const dir of await lineage(await real(folder))) {\n const choice = folders.get(dir);\n if (choice) return choice;\n }\n return undefined;\n}\n\n/** Whether `outer` is `inner` or a folder that holds it. */\nconst holds = (outer: string, inner: string) => inner === outer || inner.startsWith(outer.endsWith(path.sep) ? outer : `${outer}${path.sep}`);\n\n/**\n * Keeps the user's answer for the folder's repository (or the folder itself, outside one), never\n * for the home folder or above it: a home folder kept in git would otherwise answer for all of it.\n */\nexport async function rememberChoice(folder: string, choice: TrustChoice): Promise<void> {\n const dir = await real(folder);\n const top = await gitRoot(dir);\n const home = await real(os.homedir());\n const key = top && !holds(top, home) ? top : dir;\n const folders = await loadChoices();\n folders.delete(key);\n folders.set(key, choice);\n // Answers to trust are kept up to a number, the oldest going first (each scratch session gives\n // one). \"Use my settings only\" is never let go of: the folder would count as trusted again,\n // through the very sessions started that way.\n let trusted = [...folders.values()].filter((kept) => kept === 'trusted').length;\n for (const [folder, kept] of folders) {\n if (trusted <= MAX_CHOICES) break;\n if (kept !== 'trusted') continue;\n folders.delete(folder);\n trusted -= 1;\n }\n await saveChoices(folders);\n}\n\n/**\n * Whether what the folder brings may run: Claude Code's record or Pelican's says so, or Claude Code\n * has run there and the user did not ask Pelican to leave the folder's settings out.\n */\nexport async function folderTrusted(folder: string): Promise<boolean> {\n if (config.demo) return true;\n const dir = await real(folder);\n const choice = await pelicanChoice(dir);\n if (choice === 'trusted' || (await claudeCodeTrusts(dir))) return true;\n if (choice === 'user-only') return false;\n return claudeRanIn(dir);\n}\n\nconst strings = (value: unknown) => (Array.isArray(value) ? value.filter((v): v is string => typeof v === 'string') : []);\n\n/** Settings that run a command of the folder's choosing, as Claude Code's trust dialog lists them. */\nconst HELPERS = ['apiKeyHelper', 'awsAuthRefresh', 'awsCredentialExport', 'gcpAuthRefresh', 'otelHeadersHelper', 'proxyAuthHelper'];\n\nfunction fromSettings(settings: unknown): string[] {\n if (!isObject(settings)) return [];\n const found: string[] = [];\n if (isObject(settings.hooks)) {\n for (const [event, groups] of Object.entries(settings.hooks)) {\n for (const group of Array.isArray(groups) ? groups : []) {\n for (const hook of isObject(group) && Array.isArray(group.hooks) ? group.hooks : []) {\n if (!isObject(hook)) continue;\n const what = typeof hook.command === 'string' ? hook.command : typeof hook.url === 'string' ? hook.url : String(hook.type ?? 'hook');\n found.push(`${event} hook: ${what}`);\n }\n }\n }\n }\n for (const name of HELPERS) if (typeof settings[name] === 'string') found.push(`${name}: ${settings[name] as string}`);\n if (isObject(settings.env) && Object.keys(settings.env).length > 0) found.push(`Environment variables: ${Object.keys(settings.env).join(', ')}`);\n const permissions = isObject(settings.permissions) ? settings.permissions : {};\n if (strings(permissions.allow).length > 0) found.push(`Allowed without asking: ${strings(permissions.allow).join(', ')}`);\n if (strings(permissions.additionalDirectories).length > 0) found.push(`Extra folders: ${strings(permissions.additionalDirectories).join(', ')}`);\n if (typeof permissions.defaultMode === 'string' && !['default', 'plan', 'dontAsk'].includes(permissions.defaultMode)) {\n found.push(`Permission mode: ${permissions.defaultMode}`);\n }\n const plugins = isObject(settings.enabledPlugins) ? Object.entries(settings.enabledPlugins).filter(([, on]) => on).map(([name]) => name) : [];\n if (plugins.length > 0) found.push(`Plugins: ${plugins.join(', ')}`);\n if (isObject(settings.extraKnownMarketplaces) && Object.keys(settings.extraKnownMarketplaces).length > 0) {\n found.push(`Plugin marketplaces: ${Object.keys(settings.extraKnownMarketplaces).join(', ')}`);\n }\n if (typeof settings.autoMemoryDirectory === 'string') found.push(`Memory folder: ${settings.autoMemoryDirectory}`);\n return found;\n}\n\nfunction fromMcp(file: unknown): string[] {\n if (!isObject(file) || !isObject(file.mcpServers)) return [];\n return Object.entries(file.mcpServers).map(([name, server]) => {\n if (!isObject(server)) return `MCP server ${name}`;\n const command = typeof server.command === 'string' ? [server.command, ...strings(server.args)].join(' ') : undefined;\n const target = command ?? (typeof server.url === 'string' ? server.url : undefined);\n const helper = typeof server.headersHelper === 'string' ? ` (headersHelper: ${server.headersHelper})` : '';\n return `MCP server ${name}${target ? `: ${target}` : ''}${helper}`;\n });\n}\n\n/** Frontmatter keys that give a command, skill or agent powers of its own (Claude Code reads them in any case and with `_` for `-`). */\nconst POWERS = /(?:^|[{,])[ \\t]*[\"']?(allowed[-_]?tools|hooks|mcp[-_]?servers|permission[-_]?mode)[\"']?[ \\t]*:(.*)$/i;\n\n/**\n * What a project's command, skill or agent may run without asking: tools its frontmatter allows,\n * hooks, MCP servers, a permission mode; and for a command or a skill, the shell it runs as it\n * starts (`!` and a command in backticks, or a ```! block), as Claude Code finds them.\n */\nfunction fromMarkdown(what: string, text: string, shell: boolean): string[] {\n const found: string[] = [];\n // Found as Claude Code finds it: the closing --- may end a line rather than stand on its own.\n const front = /^\\uFEFF?---\\s*\\n([\\s\\S]*?)---\\s*\\n?/.exec(text.replace(/\\r\\n/g, '\\n'))?.[1];\n const lines = front?.split(/\\r?\\n/) ?? [];\n const indent = (line: string) => /^[ \\t]*/.exec(line)![0].length;\n // Keys of the frontmatter itself, not of a map inside it.\n const top = indent(lines.find((line) => line.trim() && !line.trim().startsWith('#')) ?? '');\n const under = (line: string) => !line.trim() || indent(line) > top || (indent(line) === top && line.trim().startsWith('-'));\n lines.forEach((line, i) => {\n const power = POWERS.exec(line);\n if (!power || (indent(line) !== top && !line.includes('{'))) return;\n // The value, with the lines under it (a list, a map), on one line.\n const value = [power[2]!.trim()];\n for (let j = i + 1; j < lines.length && under(lines[j]!); j += 1) if (lines[j]!.trim()) value.push(lines[j]!.trim());\n const mode = value.join(' ').replace(/^[\"']|[\"']$/g, '');\n if (/^permission/i.test(power[1]!) && ['default', 'plan', 'dontAsk'].includes(mode)) return;\n found.push(`${what}: ${line.includes('{') ? line.trim() : `${power[1]}: ${value.filter(Boolean).join(' ')}`}`);\n });\n // YAML says the same thing in more ways than a line scan reads (escapes, ? keys, tags, flow maps):\n // frontmatter that uses them and names a power anywhere is asked about.\n if (front && found.length === 0 && /allowed|hook|mcp|permission/i.test(front) && /\\\\|^[ \\t]*\\?|!!|\\{/m.test(front)) {\n found.push(`${what}: settings Pelican cannot read in full`);\n }\n if (shell) {\n for (const block of text.matchAll(/```!\\s*\\n?([\\s\\S]*?)\\n?```/g)) found.push(`${what} runs: ${block[1]!.trim()}`);\n for (const inline of text.matchAll(/(?<=^|\\s)!`([^`]+)`/g)) found.push(`${what} runs: ${inline[1]!}`);\n }\n return found;\n}\n\n/** Where Claude Code finds a project's commands, skills and agents in each folder's `.claude`. */\nconst MARKDOWN = [['commands', 'Command'], ['skills', 'Skill'], ['agents', 'Agent']] as const;\n\n/**\n * More than any project has: past this many files (or entries looked at), the folder is asked\n * about instead of being read without end.\n */\ntype Budget = { files: number; entries: number };\nconst budgetFor = (): Budget => ({ files: 500, entries: 10_000 });\nconst spent = (budget: Budget) => budget.files < 0 || budget.entries < 0;\n\n/** The Markdown files in a folder and its subfolders, as Claude Code finds them (through links too). */\nasync function markdownIn(root: string, budget: Budget): Promise<string[]> {\n const files: string[] = [];\n const seen = new Set<string>();\n const walk = async (dir: string, depth: number): Promise<void> => {\n const key = await realpath(dir).catch(() => dir);\n if (seen.has(key) || depth > 10) return;\n seen.add(key);\n for (const entry of await readdir(dir, { withFileTypes: true }).catch(() => [])) {\n if (spent(budget) || (budget.entries -= 1) < 0) return;\n const full = path.join(dir, entry.name);\n const isDir = entry.isSymbolicLink() ? await stat(full).then((s) => s.isDirectory(), () => false) : entry.isDirectory();\n if (isDir) await walk(full, depth + 1);\n else if (entry.name.endsWith('.md') && (budget.files -= 1) >= 0) files.push(full);\n }\n };\n await walk(root, 0);\n return files;\n}\n\n/** What a folder's own commands, skills and agents bring (see fromMarkdown). */\nasync function fromClaudeFolder(dir: string, from: string, budget: Budget): Promise<string[]> {\n const found: string[] = [];\n for (const [kind, what] of MARKDOWN) {\n const root = path.join(dir, '.claude', kind);\n for (const file of await markdownIn(root, budget)) {\n const skill = /^skill\\.md$/i.test(path.basename(file));\n // A skill is its SKILL.md; the other files in its folder are documents Claude may read.\n if (kind === 'skills' && !skill && path.dirname(file) !== root) continue;\n const { text, odd } = await readText(file);\n if (odd || text === undefined) {\n found.push(`Cannot be read: ${path.relative(from, file)}`);\n continue;\n }\n const name = path.relative(root, skill ? path.dirname(file) : file.slice(0, -'.md'.length)) || path.basename(root);\n found.push(...fromMarkdown(`${what} ${kind === 'commands' ? '/' : ''}${name}`, text, kind !== 'agents'));\n }\n }\n return found;\n}\n\n/** A setting of a git config as git reads it: its name in git's spelling, its value, the file it is in. */\ntype GitEntry = { name: string; value: string; file: string };\n\n/** The repository's own git config, as far as it could be read, and every file it includes. */\ntype GitConfig = { entries: GitEntry[]; includes: string[]; unread: boolean };\n\n/** `filter.Evil.clean`: section `filter`, subsection `Evil` (its case kept, as git keeps it), key `clean`. */\nfunction nameParts(name: string): { section: string; subsection?: string; key: string } {\n const first = name.indexOf('.');\n const last = name.lastIndexOf('.');\n const section = name.slice(0, first);\n return first === last ? { section, key: name.slice(last + 1) } : { section, subsection: name.slice(first + 1, last), key: name.slice(last + 1) };\n}\n\nconst isInclude = (entry: GitEntry) => entry.name === 'include.path' || /^includeif\\..+\\.path$/.test(entry.name);\n\n/** git found no repository there: nothing of a repository's config can run. */\nclass NoRepository extends Error {}\n\n/**\n * Settings of a git config, as git itself reads them: `git config` starts no filter, hook or\n * monitor. Without the git settings of Pelican's own environment, with a time limit (an included\n * file can be a pipe nobody writes to), and also in a repository another account owns, which the\n * user's own git may be told to trust.\n */\nfunction gitConfig(top: string, which: string[]): Promise<GitEntry[]> {\n const env: NodeJS.ProcessEnv = {};\n for (const [name, value] of Object.entries(process.env)) if (!name.startsWith('GIT_')) env[name] = value;\n Object.assign(env, { GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: os.devNull, GIT_TERMINAL_PROMPT: '0', LC_ALL: 'C' });\n const args = ['-c', 'safe.directory=*', 'config', ...which, '--list', '-z', '--show-origin', '--includes'];\n return new Promise((resolve, reject) => {\n execFile('git', args, { cwd: top, env, timeout: 5000, killSignal: 'SIGKILL', maxBuffer: 16 * 1024 * 1024 }, (error, stdout, stderr) => {\n if (error) {\n // A repository without a config file of its own has nothing in it to run.\n if (/unable to read config file '[^']*': No such file or directory/.test(String(stderr))) resolve([]);\n else reject(/not a git repository|can only be used inside a git repository/i.test(String(stderr)) ? new NoRepository() : error);\n return;\n }\n // `file:<path>` NUL `<name>` newline `<value>` NUL, a path relative to the top of the work tree.\n const fields = String(stdout).split('\\0');\n const entries: GitEntry[] = [];\n for (let i = 0; i + 1 < fields.length; i += 2) {\n const origin = fields[i]!;\n const item = fields[i + 1]!;\n const cut = item.indexOf('\\n');\n entries.push({\n file: origin.startsWith('file:') ? path.resolve(top, origin.slice('file:'.length)) : origin,\n name: cut < 0 ? item : item.slice(0, cut),\n value: cut < 0 ? '' : item.slice(cut + 1),\n });\n }\n resolve(entries);\n });\n });\n}\n\n/** Where an include points, as git resolves it; undefined where only git knows (`~user/`, `%(prefix)/`). */\nfunction includeTarget(value: string, from: string): string | undefined {\n if (value.startsWith('~/')) return path.join(process.env.HOME || os.homedir(), value.slice(2));\n if (value.startsWith('~') || value.startsWith('%(')) return undefined;\n return path.resolve(path.dirname(from), value);\n}\n\n/**\n * The repository's own config, its worktree's and the files they include, through git, which reads\n * same-line keys, `[filter.Name]` and includes as nothing else does. An include whose condition\n * does not hold now (another branch) can hold later, so every included file is read; one that\n * cannot be read leaves the config unread. Rejects when git could not read it; undefined when git\n * is not there to run anything, or finds no repository.\n */\nasync function repositoryConfig(top: string): Promise<GitConfig | undefined> {\n let entries: GitEntry[];\n try {\n entries = await gitConfig(top, ['--local']);\n // config.worktree counts whenever git reads extensions.worktreeConfig as true, however it is\n // spelled (2, 1k, 0x1 and -1 are true too): ask git rather than parse it. With the extension\n // off, --worktree reads the same file as --local, or refuses where there are several worktrees.\n const seen = new Set(entries.map((e) => e.file));\n try {\n entries.push(...(await gitConfig(top, ['--worktree'])).filter((e) => !seen.has(e.file)));\n } catch (error) {\n if (!/worktreeConfig is enabled|extension worktreeConfig/i.test(String((error as Error).message))) throw error;\n }\n } catch (error) {\n if (error instanceof NoRepository || !(await gitRuns())) return undefined;\n throw error;\n }\n const repo: GitConfig = { entries, includes: [], unread: false };\n const read = new Set(entries.map((e) => e.file));\n const pending = entries.filter(isInclude);\n while (pending.length > 0) {\n const include = pending.shift()!;\n repo.includes.push(include.value);\n const file = includeTarget(include.value, include.file);\n if (!file) repo.unread = true;\n if (!file || read.has(file)) continue;\n read.add(file);\n const info = await stat(file).catch(() => undefined);\n // Not there (yet): nothing to read now, and the include is listed.\n if (!info) continue;\n // A pipe or a device is not read, nor a chain of includes longer than any real one.\n const more = info.isFile() && read.size <= 50 ? await gitConfig(top, ['--file', file]).catch(() => undefined) : undefined;\n if (!more) {\n repo.unread = true;\n continue;\n }\n for (const entry of more) {\n if (isInclude(entry)) pending.push(entry);\n read.add(entry.file);\n }\n repo.entries.push(...more);\n }\n return repo;\n}\n\n/** Whether git can run here at all; where it cannot, it runs nothing a repository sets up either. */\nlet gitWorks: Promise<boolean> | undefined;\nfunction gitRuns(): Promise<boolean> {\n gitWorks ??= new Promise((resolve) => {\n execFile('git', ['--version'], { cwd: os.tmpdir(), timeout: 5000 }, (error, stdout) => {\n const code = (error as NodeJS.ErrnoException | null)?.code as unknown;\n // Not there, or a stand-in that exits with an error (one that only offers to install git):\n // no git. A failure that says nothing of git (no process could start) counts as git.\n resolve(error ? !(code === 'ENOENT' || typeof code === 'number') : /^git version/.test(String(stdout)));\n });\n });\n return gitWorks;\n}\n\nconst UNREAD_GIT = 'Git config that git could not read';\n\n/** Programs the repository's git config makes git start on its own, even for `git status`. */\nfunction gitPrograms(repo: GitConfig): string[] {\n const found: string[] = [];\n for (const entry of repo.entries) {\n const { section, subsection, key } = nameParts(entry.name);\n if (section === 'filter' && ['clean', 'smudge', 'process'].includes(key) && entry.value) {\n found.push(`Git filter ${subsection ?? ''}: ${entry.value}`);\n } else if (section === 'core' && key === 'fsmonitor' && !['false', 'true', '0', '1', 'no', 'yes', 'off', 'on', ''].includes(entry.value.toLowerCase())) {\n found.push(`Git fsmonitor: ${entry.value}`);\n } else if (section === 'core' && key === 'hookspath' && entry.value) {\n found.push(`Git hooks folder: ${entry.value}`);\n }\n }\n // An included file can change (another branch, a pull), and with it what git runs.\n for (const include of repo.includes) found.push(`Git config includes: ${include}`);\n if (repo.unread) found.push(UNREAD_GIT);\n return found;\n}\n\n/** What git would run of the repository's own config, also when git could not read it all. */\nasync function gitBrings(top: string): Promise<string[]> {\n try {\n const repo = await repositoryConfig(top);\n return repo ? gitPrograms(repo) : [];\n } catch {\n return [UNREAD_GIT];\n }\n}\n\n/**\n * What the folder brings: read from its files, nothing run. Settings, MCP servers, commands,\n * skills and agents of the folder and its parents up to the repository's top (Claude Code reads\n * the project's from there), never those of the home folder, which are the user's own (by either\n * of its paths: the folder's is a real one); and what the repository's git config runs.\n */\nexport async function folderBrings(folder: string): Promise<string[]> {\n const dir = await real(folder);\n const homes = new Set([os.homedir(), await real(os.homedir())]);\n const top = await gitRoot(dir);\n const found: string[] = [];\n // A file of the folder's that is not a regular file is not read, and is asked about instead.\n const json = async (file: string): Promise<unknown> => {\n const { value, odd } = await readJsonFile(file);\n if (odd) found.push(`Cannot be read: ${path.relative(dir, file)}`);\n return value;\n };\n const budget = budgetFor();\n for (let d = dir; !homes.has(d); d = path.dirname(d)) {\n for (const name of ['settings.json', 'settings.local.json']) found.push(...fromSettings(await json(path.join(d, '.claude', name))));\n found.push(...fromMcp(await json(path.join(d, '.mcp.json'))));\n found.push(...(await fromClaudeFolder(d, dir, budget)));\n if (d === top || path.dirname(d) === d) break;\n }\n if (spent(budget)) found.push('More commands, skills and agents than Pelican reads');\n if (top) found.push(...(await gitBrings(top)));\n // Every item, each whole: the part of a command that matters can come after any amount of\n // padding, or after any number of harmless items (the sheet scrolls).\n return [...new Set(found)];\n}\n\n/**\n * Git settings, for Claude Code and every git it starts, that turn off what the repository's own\n * config makes git run (filters, a file-system monitor, a hooks folder): the folder's settings are\n * left out, so are its programs. Names as git spells them, so `[filter.Evil]` is turned off as\n * `filter.evil`. A config git could not read in full cannot be turned off, so nothing starts.\n */\nasync function gitOff(dir: string): Promise<Record<string, string>> {\n const top = await gitRoot(dir);\n if (!top) return {};\n const repo = await repositoryConfig(top).catch((): GitConfig => ({ entries: [], includes: [], unread: true }));\n if (!repo) return {};\n if (repo.unread) throw new Error('Git could not read this folder\u2019s git config, so Claude Code cannot start in it with your settings only.');\n const off: Array<[string, string]> = [];\n const parts = repo.entries.map((e) => nameParts(e.name));\n for (const name of new Set(parts.filter((p) => p.section === 'filter' && p.subsection !== undefined).map((p) => p.subsection!))) {\n off.push([`filter.${name}.clean`, ''], [`filter.${name}.smudge`, ''], [`filter.${name}.process`, ''], [`filter.${name}.required`, 'false']);\n }\n if (parts.some((p) => p.section === 'core' && p.key === 'fsmonitor')) off.push(['core.fsmonitor', 'false']);\n if (parts.some((p) => p.section === 'core' && p.key === 'hookspath')) off.push(['core.hooksPath', '/dev/null']);\n if (off.length === 0) return {};\n // After any the environment already holds, which git reads first.\n const start = Number(process.env.GIT_CONFIG_COUNT) || 0;\n const env: Record<string, string> = { GIT_CONFIG_COUNT: String(start + off.length) };\n off.forEach(([key, value], i) => {\n env[`GIT_CONFIG_KEY_${start + i}`] = key;\n env[`GIT_CONFIG_VALUE_${start + i}`] = value;\n });\n return env;\n}\n\n/**\n * For a new session: what the folder would run when nobody has trusted it, so the user can be\n * asked first; undefined when there is nothing to ask (trusted, or it brings nothing).\n */\nexport async function trustQuestion(folder: string): Promise<{ folder: string; brings: string[] } | undefined> {\n if (await folderTrusted(folder)) return undefined;\n const brings = await folderBrings(folder);\n return brings.length > 0 ? { folder: await real(folder), brings } : undefined;\n}\n\n/**\n * How to start Claude Code in a folder: with every setting where the folder is trusted or brings\n * nothing, with the user's own only where the user chose that, and not at all otherwise.\n */\nexport async function launchFor(folder: string): Promise<Launch> {\n if (config.demo || (await folderTrusted(folder))) return FULL_SETTINGS;\n const dir = await real(folder);\n if ((await pelicanChoice(dir)) === 'user-only') {\n const env = await gitOff(dir);\n return { settingSources: ['user'], ...(Object.keys(env).length > 0 ? { env } : {}) };\n }\n const brings = await folderBrings(dir);\n if (brings.length === 0) return FULL_SETTINGS;\n throw new NeedsTrust(dir, brings);\n}\n\n/** For tests: forget what was read. */\nexport function forgetTrust(): void {\n ranCache.clear();\n claudeConfig = undefined;\n choices = undefined;\n gitWorks = undefined;\n}\n", "import { realpath } from 'node:fs/promises';\nimport os from 'node:os';\n\nimport { filterEscalatingDefaultMode, query, resolveSettings } from '@anthropic-ai/claude-agent-sdk';\nimport type { AccountInfo, AgentInfo, McpServerStatus, ModelInfo, SDKControlGetUsageResponse, SDKUserMessage, SettingSource, SlashCommand } from '@anthropic-ai/claude-agent-sdk';\n\nimport { isPermissionMode, type PermissionMode } from '../shared/modes.js';\nimport type { Account, Agent, Command, McpServer, ModelOption, PlanUsage } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport { DEMO_MODELS } from './demo.js';\nimport { folderTrusted } from './trust.js';\n\nconst TTL_MS = 10 * 60 * 1000;\nconst PROBE_TIMEOUT_MS = 30_000;\nconst MAX_PROBES = 2;\n\n/** A prompt stream that never yields: the process starts, answers control requests, and sends no turn. */\nconst idlePrompt: AsyncIterable<SDKUserMessage> = {\n [Symbol.asyncIterator]: () => ({ next: () => new Promise<never>(() => {}) }),\n};\n\nlet running = 0;\nconst waiting: (() => void)[] = [];\n\n/** At most MAX_PROBES Claude processes at a time, however many requests ask. */\nasync function slot<T>(work: () => Promise<T>): Promise<T> {\n if (running >= MAX_PROBES) await new Promise<void>((resolve) => waiting.push(resolve));\n running += 1;\n try {\n return await work();\n } finally {\n running -= 1;\n waiting.shift()?.();\n }\n}\n\nconst inflight = new Map<string, Promise<unknown>>();\n\n/**\n * Starts Claude Code without a conversation in `cwd`, asks it something, and\n * stops it. Costs no tokens and writes no transcript. One probe per folder and\n * question at a time; it gives up after PROBE_TIMEOUT_MS.\n *\n * A probe is only a look, so it fires no hooks. In a folder nobody trusted it starts in the home\n * folder with the user's settings only: Claude Code runs git where it starts, and the folder's own\n * git config can name programs git runs (trust.ts).\n */\nasync function probe<T>(key: string, cwd: string, ask: (q: ReturnType<typeof query>) => Promise<T>): Promise<T> {\n const dir = await realpath(cwd);\n const id = `${key}:${dir}`;\n const pending = inflight.get(id);\n if (pending) return pending as Promise<T>;\n const work = slot(async () => {\n const trusted = await folderTrusted(dir);\n const q = query({\n prompt: idlePrompt,\n options: {\n cwd: trusted ? dir : os.homedir(),\n persistSession: false,\n settingSources: trusted ? ['user', 'project', 'local'] : ['user'],\n settings: { disableAllHooks: true },\n ...(config.claudeExecutable ? { pathToClaudeCodeExecutable: config.claudeExecutable } : {}),\n },\n });\n let timer: NodeJS.Timeout | undefined;\n try {\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Claude Code did not answer in time.')), PROBE_TIMEOUT_MS);\n });\n return await Promise.race([ask(q), timeout]);\n } finally {\n clearTimeout(timer);\n q.close();\n }\n }).finally(() => inflight.delete(id));\n inflight.set(id, work);\n return work;\n}\n\nfunction toOption(info: ModelInfo): ModelOption {\n return {\n value: info.value,\n label: info.displayName || info.value,\n description: info.description ?? '',\n efforts: info.supportedEffortLevels ?? [],\n supportsFast: Boolean(info.supportsFastMode),\n ...(info.supportsAutoMode !== undefined ? { supportsAuto: info.supportsAutoMode } : {}),\n ...(info.resolvedModel ? { resolvedModel: info.resolvedModel } : {}),\n };\n}\n\nexport type ModelList = { models: ModelOption[]; signedIn: boolean | null; account?: Account; version?: string };\n\nlet cache: { at: number; value: ModelList } | undefined;\n\n/**\n * Whether Claude Code has a way to call the API. Signed out, it still names the first-party API\n * as its provider, and its token source as 'none'; a third-party provider (Bedrock, Vertex, a\n * gateway) signs in outside Claude Code, so it counts as signed in.\n */\nexport function signedInFrom(account: AccountInfo): boolean {\n const some = (value: string | undefined) => Boolean(value && value !== 'none');\n return Boolean(account.email || account.subscriptionType || some(account.apiKeySource) || some(account.tokenSource)\n || (account.apiProvider && account.apiProvider !== 'firstParty'));\n}\n\n/**\n * Claude Code failing to start, in Pelican's words: the SDK's own text names an option of the\n * SDK, not the setting a Pelican user has.\n */\nexport function startError(text: string): string | undefined {\n const missing = text.match(/(?:native binary|Claude Code executable) not found at (.+?)\\. (?:Please|Is)/);\n if (!missing && !/native binary not found|Claude Code executable not found/.test(text)) return undefined;\n const at = missing?.[1] ? ` at ${missing[1]}` : '';\n return `Pelican could not find Claude Code${at}. Set PELICAN_CLAUDE_PATH to the claude program on ${config.machine}, or reinstall Pelican.`;\n}\n\n/**\n * The models this account can use, with their effort levels and fast-mode\n * support, as Claude Code reports them, and whether Claude Code is signed in.\n */\nexport async function listModels(): Promise<ModelList> {\n if (config.demo) return { models: DEMO_MODELS, signedIn: true, account: { email: 'you@example.com', plan: 'max' } };\n if (cache && Date.now() - cache.at < TTL_MS) return cache.value;\n const asking = probe('models', os.homedir(), async (q) => {\n const init = await q.initializationResult();\n const models = init.models.map(toOption);\n const account: AccountInfo | undefined = init.account;\n const who: Account | undefined = account?.email || account?.organization || account?.subscriptionType\n ? {\n ...(account.email ? { email: account.email } : {}),\n ...(account.organization ? { organization: account.organization } : {}),\n ...(account.subscriptionType ? { plan: account.subscriptionType } : {}),\n }\n : undefined;\n return {\n models,\n signedIn: account ? signedInFrom(account) : null,\n ...(who ? { account: who } : {}),\n ...(init.claude_code_version ? { version: init.claude_code_version } : {}),\n };\n })\n .then((value) => {\n cache = { at: Date.now(), value };\n return value;\n });\n try {\n return await asking;\n } catch (error) {\n if (cache) return cache.value;\n const readable = startError((error as Error).message);\n throw readable ? new Error(readable) : error;\n }\n}\n\n/** The model list as last read, without starting Claude Code to read it. */\nexport const knownModels = (): ModelOption[] | undefined => (config.demo ? DEMO_MODELS : cache?.value.models);\n\n/** Whether the account pays through a Claude plan (Pro, Max, Team\u2026), as last read; then dollar costs mean nothing to it. */\nexport const onSubscription = (): boolean => Boolean(cache?.value.account?.plan);\n\n/**\n * Claude Code's state on this machine for a line at start-up: its version and whether it is\n * signed in, or why it cannot start.\n */\nexport async function claudeCodeStatus(): Promise<{ version?: string; signedIn: boolean | null } | { error: string }> {\n try {\n const list = await listModels();\n return { signedIn: list.signedIn, ...(list.version ? { version: list.version } : {}) };\n } catch (error) {\n return { error: (error as Error).message };\n }\n}\n\n/**\n * The mode new sessions start in, as Claude Code decides it from the settings: the folder's own\n * once Claude has run there (an escalating mode only from the user's own files, as Claude Code\n * does), else the user's. Bypass is left out: Pelican enters it only when it is picked.\n * Reading settings starts nothing.\n */\nexport async function defaultMode(cwd?: string): Promise<PermissionMode | undefined> {\n if (config.demo) return undefined;\n const dir = cwd ? await realpath(cwd).catch(() => undefined) : undefined;\n const read = async (settingSources: SettingSource[]) => {\n const resolved = await resolveSettings({ cwd: dir ?? os.homedir(), settingSources });\n return filterEscalatingDefaultMode(resolved).permissions?.defaultMode;\n };\n const trusted = dir ? await folderTrusted(dir) : false;\n const mode = (await read(trusted ? ['user', 'project', 'local'] : ['user']).catch(() => undefined))\n ?? (trusted ? await read(['user']).catch(() => undefined) : undefined);\n return isPermissionMode(mode) && mode !== 'bypassPermissions' ? mode : undefined;\n}\n\nconst DEMO_COMMANDS: Command[] = [\n { name: 'compact', description: 'Summarize the conversation so far to free up context', argumentHint: '' },\n { name: 'review', description: 'Review the changes on this branch', argumentHint: '' },\n { name: 'init', description: 'Write a CLAUDE.md for this project', argumentHint: '' },\n];\nconst DEMO_AGENTS: Agent[] = [{ name: 'code-reviewer', description: 'Reviews a change for bugs and style' }];\n\nexport type Completions = { commands: Command[]; agents: Agent[] };\nconst completionCache = new Map<string, { at: number; value: Completions }>();\n\n/**\n * Commands whose screen is Claude Code's terminal; a phone has nowhere to show them. Claude Code\n * names more in each session's start (`terminal_slash_commands`), which runs add here.\n */\nconst terminalCommands = new Set(['exit', 'quit', 'statusline', 'terminal-setup', 'theme', 'doctor', 'color', 'focus', 'vim', 'keybindings', 'ide']);\n\nexport function noteTerminalCommands(names: string[]): void {\n for (const name of names) terminalCommands.add(name);\n}\n\n/** The commands and agents Claude Code lists, in the app's terms, without the terminal's own. */\nexport function toCompletions(commands: SlashCommand[], agents: AgentInfo[]): Completions {\n return {\n commands: commands\n .filter((c) => !terminalCommands.has(c.name))\n .map((c) => ({ name: c.name, description: c.description ?? '', argumentHint: c.argumentHint ?? '' })),\n agents: agents.map((a) => ({ name: a.name, description: a.description ?? '' })),\n };\n}\n\n/** A folder's list changed (Claude Code found skills while it worked there): asked again next time. */\nexport async function forgetCompletions(cwd: string): Promise<void> {\n completionCache.delete(await realpath(cwd).catch(() => cwd));\n}\n\n/** Slash commands (built-in, the project's and the user's, skills) and subagents available in a folder. */\nexport async function listCompletions(cwd: string): Promise<Completions> {\n if (config.demo) return { commands: DEMO_COMMANDS, agents: DEMO_AGENTS };\n const dir = await realpath(cwd);\n const cached = completionCache.get(dir);\n if (cached && Date.now() - cached.at < TTL_MS) return cached.value;\n const value = await probe('completions', dir, async (q) => {\n const [commands, agents] = await Promise.all([q.supportedCommands(), q.supportedAgents().catch(() => [])]);\n return toCompletions(commands, agents);\n });\n completionCache.set(dir, { at: Date.now(), value });\n return value;\n}\n\nexport function toMcpServers(list: McpServerStatus[]): McpServer[] {\n return list.map((server) => ({\n name: server.name,\n status: server.status,\n ...(server.error ? { error: server.error } : {}),\n tools: server.tools?.length ?? 0,\n ...(server.scope ? { scope: server.scope } : {}),\n }));\n}\n\nconst mcpCache = new Map<string, { at: number; servers: McpServer[] }>();\n\n/** The MCP servers a session in this folder gets, and whether they connect, when no Claude runs there. */\nexport async function probeMcpServers(cwd: string): Promise<McpServer[]> {\n if (config.demo) return [{ name: 'github', status: 'connected', tools: 26, scope: 'user' }, { name: 'linear', status: 'needs-auth', tools: 0, scope: 'project' }];\n const dir = await realpath(cwd);\n const cached = mcpCache.get(dir);\n if (cached && Date.now() - cached.at < 60_000) return cached.servers;\n const servers = toMcpServers(await probe('mcp', dir, (q) => q.mcpServerStatus()));\n mcpCache.set(dir, { at: Date.now(), servers });\n return servers;\n}\n\nconst DEMO_PLAN: PlanUsage = {\n windows: [\n { type: 'five_hour', utilization: 0.42, resetsAt: Date.now() + 2.4 * 3600_000 },\n { type: 'seven_day', utilization: 0.18, resetsAt: Date.now() + 3.5 * 86400_000 },\n ],\n};\n\ntype Window = { utilization: number | null; resets_at: string | null } | null | undefined;\nlet planCache: { at: number; value: PlanUsage | null } | undefined;\n\n/**\n * The plan's usage, as Claude Code's `/usage` reads it from claude.ai: the windows of a Pro or\n * Max plan, and the monthly cap on extra usage that Team and Enterprise plans have instead.\n * Null where plan limits do not apply (an API key, Bedrock, Vertex) or the answer is not there.\n * The SDK marks this call experimental, so anything unexpected is no answer, not an error.\n */\nexport async function planUsage(): Promise<PlanUsage | null> {\n if (config.demo) return DEMO_PLAN;\n if (planCache && Date.now() - planCache.at < 60_000) return planCache.value;\n const value = await probe('usage', os.homedir(), async (q) => {\n const ask = (q as unknown as { usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET?: (o: { skipBehaviors: boolean }) => Promise<SDKControlGetUsageResponse> })\n .usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET;\n if (typeof ask !== 'function') return null;\n const answer = await ask.call(q, { skipBehaviors: true });\n const limits = answer?.rate_limits;\n if (!answer?.rate_limits_available || !limits) return null;\n const windows: PlanUsage['windows'] = [];\n const add = (type: string, window: Window, label?: string) => {\n if (!window || typeof window.utilization !== 'number') return;\n const resetsAt = window.resets_at ? Date.parse(window.resets_at) : NaN;\n windows.push({ type, ...(label ? { label } : {}), utilization: window.utilization / 100, ...(Number.isFinite(resetsAt) ? { resetsAt } : {}) });\n };\n add('five_hour', limits.five_hour);\n add('seven_day', limits.seven_day);\n add('seven_day_opus', limits.seven_day_opus);\n add('seven_day_sonnet', limits.seven_day_sonnet);\n for (const scoped of limits.model_scoped ?? []) add(`model:${scoped.display_name}`, scoped, `Weekly ${scoped.display_name} limit`);\n const extra = limits.extra_usage;\n return {\n windows,\n ...(extra ? {\n extra: {\n enabled: Boolean(extra.is_enabled),\n ...(typeof extra.used_credits === 'number' ? { usedCents: extra.used_credits } : {}),\n ...(typeof extra.monthly_limit === 'number' ? { limitCents: extra.monthly_limit } : {}),\n ...(typeof extra.utilization === 'number' ? { utilization: extra.utilization / 100 } : {}),\n ...(extra.currency ? { currency: extra.currency } : {}),\n },\n } : {}),\n };\n }).catch(() => null);\n planCache = { at: Date.now(), value };\n return value;\n}\n", "import { execFile } from 'node:child_process';\nimport { realpathSync } from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { config } from './config.js';\n\nconst run = promisify(execFile);\n\n/**\n * Git runs only in folders Claude Code has worked in (see trust.ts), where the repository's\n * config is the user's own. Even there Pelican only reads, so it starts nothing git would start\n * on the side: no hooks, no file-system monitor, no external diff or text converter. It takes\n * no locks the user's own git would trip over, never asks for credentials, reads pathspecs\n * literally (`:/` is a name, not \"the top of the repository\"), and leaves submodules' work\n * trees alone.\n */\nconst SAFE = ['-c', 'core.fsmonitor=false', '-c', 'core.hooksPath=/dev/null', '-c', 'safe.bareRepository=explicit', '-c', 'core.quotepath=off'];\n\nfunction environment(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = { ...process.env, GIT_OPTIONAL_LOCKS: '0', GIT_TERMINAL_PROMPT: '0', GIT_LITERAL_PATHSPECS: '1' };\n // The folder decides the repository, not whatever the server was started with.\n for (const name of Object.keys(env)) {\n if (/^GIT_(DIR|WORK_TREE|INDEX_FILE|COMMON_DIR|OBJECT_DIRECTORY|ALTERNATE_OBJECT_DIRECTORIES|NAMESPACE|CONFIG_PARAMETERS|CONFIG_COUNT|CONFIG_KEY_\\d+|CONFIG_VALUE_\\d+|CEILING_DIRECTORIES)$/.test(name)) delete env[name];\n }\n if (config.demo) {\n // The demo's folders may sit inside a repository of yours (a home folder kept in git):\n // git must not look above the demo for one.\n try {\n env.GIT_CEILING_DIRECTORIES = path.dirname(realpathSync(config.home));\n } catch {\n env.GIT_CEILING_DIRECTORIES = path.dirname(config.home);\n }\n }\n return env;\n}\n\n/** Runs a read-only git command in `cwd`; rejects on a non-zero exit, with stdout on the error. */\nexport async function git(cwd: string, args: string[], timeout = 15_000): Promise<string> {\n const command = args[0]!;\n const extra = command === 'diff' ? ['--no-ext-diff', '--no-textconv', '--ignore-submodules=dirty']\n : command === 'status' ? ['--ignore-submodules=dirty']\n : [];\n const { stdout } = await run('git', [...SAFE, command, ...extra, ...args.slice(1)], { cwd, env: environment(), maxBuffer: 32 * 1024 * 1024, timeout });\n return stdout;\n}\n", "import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { git } from './git.js';\nimport { folderTrusted } from './trust.js';\n\nconst cache = new Map<string, { at: number; files: string[] }>();\nconst TTL_MS = 30_000;\nconst SKIP = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.venv', 'venv', '__pycache__', 'target', '.cache']);\nconst MAX_FILES = 20_000;\n\n/** Files of a folder as `git ls-files` sees them (ignored ones left out), or by walking it. */\nasync function projectFiles(cwd: string): Promise<string[]> {\n const cached = cache.get(cwd);\n if (cached && Date.now() - cached.at < TTL_MS) return cached.files;\n let files: string[];\n try {\n // Git only in a trusted folder (trust.ts); anywhere else the folder is walked.\n if (!(await folderTrusted(cwd))) throw new Error('not trusted');\n const stdout = await git(cwd, ['ls-files', '--cached', '--others', '--exclude-standard'], 5000);\n files = stdout.split('\\n').filter(Boolean).slice(0, MAX_FILES);\n } catch {\n files = [];\n const walk = async (dir: string, depth: number): Promise<void> => {\n if (depth > 8 || files.length >= MAX_FILES) return;\n let entries;\n try {\n entries = await readdir(path.join(cwd, dir), { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (files.length >= MAX_FILES) return;\n if (entry.name.startsWith('.') || SKIP.has(entry.name)) continue;\n const rel = dir ? `${dir}/${entry.name}` : entry.name;\n if (entry.isDirectory()) await walk(rel, depth + 1);\n else files.push(rel);\n }\n };\n await walk('', 0);\n }\n cache.set(cwd, { at: Date.now(), files });\n return files;\n}\n\n/** How well `query` matches `file`: higher is better, -1 for no match. */\nfunction score(file: string, query: string): number {\n const f = file.toLowerCase();\n const q = query.toLowerCase();\n const base = f.slice(f.lastIndexOf('/') + 1);\n if (base === q) return 1000;\n if (base.startsWith(q)) return 800 - base.length;\n if (base.includes(q)) return 600 - base.length;\n if (f.includes(q)) return 400 - f.length / 10;\n // Every character in order: \"stset\" finds \"src/settings/Settings.tsx\".\n let at = 0;\n for (const char of q) {\n at = f.indexOf(char, at);\n if (at === -1) return -1;\n at += 1;\n }\n return 100 - f.length / 10;\n}\n\n/** Files and folders matching a query, for `@` mentions in the composer. */\nexport async function searchFiles(cwd: string, query: string, limit = 30): Promise<string[]> {\n const files = await projectFiles(cwd);\n const dirs = new Set<string>();\n for (const file of files) {\n let cut = file.lastIndexOf('/');\n while (cut > 0) {\n dirs.add(`${file.slice(0, cut)}/`);\n cut = file.lastIndexOf('/', cut - 1);\n }\n }\n const candidates = [...files, ...dirs];\n if (!query) return files.slice().sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b)).slice(0, limit);\n return candidates\n .map((file) => ({ file, score: score(file, query) }))\n .filter((m) => m.score >= 0)\n .sort((a, b) => b.score - a.score || a.file.localeCompare(b.file))\n .slice(0, limit)\n .map((m) => m.file);\n}\n", "import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport webpush from 'web-push';\n\nimport { cookieName } from './auth.js';\nimport { config } from './config.js';\n\n/**\n * A device that asked for notifications, and under which sign-in: `signer` names the secret that\n * signed browsers in then (the cookie's name, which is derived from it). A new token or password\n * signs every browser out, and so stops their notifications too.\n */\ntype Subscription = webpush.PushSubscription & { openUrl?: string; signer?: string };\n\nconst keysFile = () => path.join(config.stateDir, 'vapid.json');\nconst subsFile = () => path.join(config.stateDir, 'push-subscriptions.json');\n\nlet keys: { publicKey: string; privateKey: string } | undefined;\nlet subscriptions: Subscription[] = [];\n\nasync function save(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n await writeFile(file, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\n/** Loads this machine's VAPID keys (created on first start) and the saved subscriptions. */\nexport async function initPush(): Promise<void> {\n try {\n keys = JSON.parse(await readFile(keysFile(), 'utf8'));\n } catch {\n keys = webpush.generateVAPIDKeys();\n await save(keysFile(), keys);\n }\n webpush.setVapidDetails('https://github.com/Ki-Seki/pelican', keys!.publicKey, keys!.privateKey);\n try {\n subscriptions = JSON.parse(await readFile(subsFile(), 'utf8'));\n } catch {\n subscriptions = [];\n }\n // Saved before subscriptions knew their sign-in: they belong to the current one.\n if (subscriptions.some((s) => !s.signer)) {\n subscriptions = subscriptions.map((s) => ({ ...s, signer: s.signer ?? cookieName() }));\n await save(subsFile(), subscriptions);\n }\n}\n\nexport function pushKey(): string | undefined {\n return keys?.publicKey;\n}\n\nexport async function addSubscription(subscription: Subscription): Promise<void> {\n subscriptions = subscriptions.filter((s) => s.endpoint !== subscription.endpoint);\n subscriptions.push({ ...subscription, signer: cookieName() });\n await save(subsFile(), subscriptions);\n}\n\nexport async function removeSubscription(endpoint: string): Promise<void> {\n subscriptions = subscriptions.filter((s) => s.endpoint !== endpoint);\n await save(subsFile(), subscriptions);\n}\n\nexport type PushPayload = { title: string; body: string; sessionId: string; tag: string };\n\n/** Sends a notification to every subscribed device; drops subscriptions the push service rejects. */\nexport async function notify(payload: PushPayload): Promise<void> {\n if (!keys || subscriptions.length === 0) return;\n // Devices signed out by a new token or password get nothing more, and are forgotten.\n const signer = cookieName();\n const gone = subscriptions.filter((s) => s.signer !== signer).map((s) => s.endpoint);\n await Promise.all(subscriptions.filter((s) => s.signer === signer).map(async (subscription) => {\n // PELICAN_SESSION_URL wins (for a page that embeds Pelican); otherwise the page that subscribed.\n const id = encodeURIComponent(payload.sessionId);\n const url = config.sessionUrl ? config.sessionUrl.replaceAll('{id}', id)\n : subscription.openUrl ? `${subscription.openUrl}${id}` : undefined;\n const body = JSON.stringify({ ...payload, url });\n try {\n await webpush.sendNotification({ endpoint: subscription.endpoint, keys: subscription.keys }, body, { TTL: 3600, urgency: 'high' });\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode;\n if (status === 404 || status === 410) gone.push(subscription.endpoint);\n else console.warn('[pelican] push failed', status ?? (error as Error).message);\n }\n }));\n if (gone.length > 0) {\n subscriptions = subscriptions.filter((s) => !gone.includes(s.endpoint));\n // Callers do not wait for a notification: a failed save is said here, not left to reject.\n await save(subsFile(), subscriptions).catch((error: Error) => console.warn('[pelican] could not save push subscriptions', error.message));\n }\n}\n\n/** For tests: the endpoints notifications would go to now. */\nexport function subscribedEndpoints(): string[] {\n const signer = cookieName();\n return subscriptions.filter((s) => s.signer === signer).map((s) => s.endpoint);\n}\n", "import type { ModelOption } from './protocol';\n\n/**\n * The picker's name for a model id Claude Code reports (claude-opus-5-5), which several aliases\n * may resolve to (Default and Opus 5.5 both do): `chosen` while it still resolves to that id, else\n * the id's own entry, else an alias other than Default, else the id itself.\n */\nexport function pickerValue(id: string, models: ModelOption[] | undefined, chosen?: string): string {\n const resolves = (value: string | undefined): value is string =>\n value !== undefined && (value === id || models?.find((m) => m.value === value)?.resolvedModel === id);\n if (resolves(chosen)) return chosen;\n const exact = models?.find((m) => m.value === id);\n const resolving = models?.filter((m) => m.resolvedModel === id) ?? [];\n return exact?.value ?? (resolving.find((m) => m.value !== 'default') ?? resolving[0])?.value ?? id;\n}\n", "import type { PermissionMode, PermissionUpdate } from '@anthropic-ai/claude-agent-sdk';\n\nimport { MODE_INFO } from '../shared/modes.js';\n\n/** Longer than this, a choice no longer reads at a glance; Claude Code drops such a choice too. */\nconst MAX_LABEL = 200;\n\nconst LATER = /:\\*$/;\n\n/** A path as a rule spells it (`//abs/**`, `./rel`, `~/x`), short and readable. */\nfunction pathOf(rule: string, home: string): string {\n const plain = rule.replace(/\\/\\*\\*$/, '').replace(/^\\.\\//, '').replace(/^\\/\\//, '/');\n return home && (plain === home || plain.startsWith(`${home}/`)) ? `~${plain.slice(home.length)}` : plain;\n}\n\nconst FILE_EDITS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);\n\n/** One rule in words: the command pattern, the site, the folder or the tool it lets through. */\nfunction ruleText(rule: { toolName: string; ruleContent?: string }, home: string): string {\n const { toolName, ruleContent: content } = rule;\n if (toolName.startsWith('mcp__')) {\n const [, server, tool] = toolName.split('__');\n return tool ? `${server} \u00B7 ${tool}` : `every ${server} tool`;\n }\n if (!content) return toolName;\n if (toolName === 'Bash' || toolName === 'PowerShell') return content.replace(LATER, ' *');\n if (toolName === 'WebFetch' && content.startsWith('domain:')) return `fetching ${content.slice('domain:'.length)}`;\n if (toolName === 'Read') return `reading ${pathOf(content, home)}`;\n if (FILE_EDITS.has(toolName)) return `edits in ${pathOf(content, home)}`;\n return `${toolName} ${content}`;\n}\n\ntype Scope = 'session' | 'project' | 'everywhere';\n\nfunction scopeOf(destination: string): Scope {\n if (destination === 'userSettings') return 'everywhere';\n if (destination === 'projectSettings' || destination === 'localSettings') return 'project';\n return 'session';\n}\n\nconst join = (items: string[]) => (items.length <= 1 ? items.join('') : `${items.slice(0, -1).join(', ')} and ${items.at(-1)}`);\n\n/**\n * What \"always\" would save, in words, from the suggestions Claude Code sent with a request. Like\n * Claude Code it is one choice that applies them all, and it names everything it applies, so a\n * rule saved from it never covers more than it said. Undefined when a suggestion cannot be put in\n * plain words (or there are none): then only a one-time approval is offered.\n */\nexport function describeAlways(suggestions: PermissionUpdate[] | undefined, home: string): string | undefined {\n if (!suggestions || suggestions.length === 0) return undefined;\n const parts: string[] = [];\n const rules = new Map<Scope, string[]>();\n const dirs = new Map<Scope, string[]>();\n for (const update of suggestions) {\n if (update.type === 'setMode') {\n if (!(update.mode in MODE_INFO)) return undefined;\n const scope = scopeOf(update.destination);\n if (update.mode === 'acceptEdits' && scope === 'session') parts.push('Allow all edits this session');\n else parts.push(`Switch to ${MODE_INFO[update.mode].label} ${scope === 'session' ? 'for this session' : scope === 'project' ? 'in this project' : 'everywhere'}`);\n } else if (update.type === 'addRules') {\n if (update.behavior !== 'allow' || update.rules.length === 0) return undefined;\n const list = rules.get(scopeOf(update.destination)) ?? [];\n for (const rule of update.rules) list.push(ruleText(rule, home));\n rules.set(scopeOf(update.destination), list);\n } else if (update.type === 'addDirectories') {\n if (update.directories.length === 0) return undefined;\n const list = dirs.get(scopeOf(update.destination)) ?? [];\n for (const dir of update.directories) list.push(pathOf(dir, home));\n dirs.set(scopeOf(update.destination), list);\n } else {\n // Removing or replacing rules is never what \"allow\" should mean.\n return undefined;\n }\n }\n for (const [scope, list] of rules) {\n const items = [...new Set(list)];\n parts.push(scope === 'session' ? `Allow ${join(items)} for this session` : `Always allow ${join(items)} ${scope === 'project' ? 'in this project' : 'in every project'}`);\n }\n for (const [scope, list] of dirs) {\n const items = [...new Set(list)];\n parts.push(`Allow access to ${join(items)} ${scope === 'session' ? 'for this session' : scope === 'project' ? 'from this project' : 'from every project'}`);\n }\n const label = parts.map((part, i) => (i === 0 ? part : part.charAt(0).toLowerCase() + part.slice(1))).join('; ');\n return label && label.length <= MAX_LABEL ? label : undefined;\n}\n\n/** The mode a set of suggestions switches this session to, if any. */\nexport function sessionModeOf(suggestions: PermissionUpdate[] | undefined): PermissionMode | undefined {\n const update = suggestions?.find((s) => s.type === 'setMode' && scopeOf(s.destination) === 'session');\n return update?.type === 'setMode' ? update.mode : undefined;\n}\n", "import { spawn } from 'node:child_process';\n\nimport type { ShellResult } from '../shared/protocol.js';\n\nconst MAX_OUTPUT = 200_000;\nconst TIMEOUT_MS = 2 * 60_000;\n/** After the shell exits, how long output still on its way may take to arrive. */\nconst DRAIN_MS = 200;\n\n/** On Windows there are no process groups to start or stop. */\nconst groups = process.platform !== 'win32';\n\n/** Whether anything of the process group `pgid` is still running. */\nfunction running(pgid: number): boolean {\n try {\n process.kill(-pgid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Runs one `!` command in a session's folder through the user's login shell,\n * like Claude Code's bash mode: no terminal, output captured up to a limit,\n * stopped after two minutes.\n *\n * The command gets a process group of its own. It is done when its shell is: a\n * process it left in the background (`npm run dev &`) keeps running, and the\n * result says so, instead of holding the request open for its whole life by\n * keeping the output pipes. Stopping it stops everything it started, not just\n * the shell, whose children would otherwise run on.\n */\nexport function runCommand(cwd: string, command: string, timeoutMs = TIMEOUT_MS): Promise<ShellResult> {\n const shell = process.env.SHELL || '/bin/bash';\n const started = Date.now();\n return new Promise((resolve) => {\n let stdout = '';\n let stderr = '';\n let truncated = false;\n let done = false;\n let stopped = false;\n const child = spawn(shell, ['-lc', command], {\n cwd,\n env: { ...process.env, PAGER: 'cat', GIT_PAGER: 'cat', TERM: 'dumb' },\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: groups,\n });\n const take = (current: string, chunk: Buffer) => {\n if (current.length >= MAX_OUTPUT) {\n truncated = true;\n return current;\n }\n const next = current + chunk.toString('utf8');\n if (next.length > MAX_OUTPUT) truncated = true;\n return next.slice(0, MAX_OUTPUT);\n };\n child.stdout.on('data', (chunk: Buffer) => {\n if (!done) stdout = take(stdout, chunk);\n });\n child.stderr.on('data', (chunk: Buffer) => {\n if (!done) stderr = take(stderr, chunk);\n });\n const timer = setTimeout(() => {\n stopped = true;\n try {\n if (groups && child.pid) process.kill(-child.pid, 'SIGKILL');\n else child.kill('SIGKILL');\n } catch {\n // Already gone.\n }\n }, timeoutMs);\n let drain: NodeJS.Timeout | undefined;\n const finish = (code: number | null, error?: Error) => {\n if (done) return;\n done = true;\n clearTimeout(timer);\n clearTimeout(drain);\n const background = groups && !stopped && child.pid !== undefined && running(child.pid);\n resolve({\n command,\n stdout,\n stderr: error ? `${stderr}${error.message}` : stderr,\n code: stopped ? null : code,\n durationMs: Date.now() - started,\n ...(truncated ? { truncated: true } : {}),\n ...(background ? { background: true } : {}),\n });\n };\n child.on('error', (error) => finish(null, error));\n // 'close' waits for every process holding the pipes; 'exit' is the shell itself.\n child.on('close', (code, signal) => finish(signal ? null : code));\n child.on('exit', (code, signal) => {\n drain = setTimeout(() => finish(signal ? null : code), DRAIN_MS);\n });\n // Not waited for: what it left running exits on its own, or with the server.\n child.unref();\n });\n}\n\nconst escape = (text: string) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\n/** The command and its output the way Claude Code's bash mode writes them into the conversation. */\nexport function bashModeText(result: ShellResult): string {\n const note = result.code === null ? '\\n(stopped after two minutes)'\n : result.code !== 0 ? `\\n(exit code ${result.code})`\n : result.background ? '\\n(still running in the background)' : '';\n return `<bash-input>${escape(result.command)}</bash-input><bash-stdout>${escape(result.stdout)}</bash-stdout><bash-stderr>${escape(result.stderr + note)}</bash-stderr>`;\n}\n", "import type { SDKRateLimitInfo } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { UsageLimit } from '../shared/protocol.js';\n\n/** The account's usage limits as Claude Code last reported them, one per kind of limit. */\nconst limits = new Map<string, UsageLimit>();\n\nexport function recordLimit(info: SDKRateLimitInfo): void {\n const type = info.rateLimitType ?? 'unknown';\n limits.set(type, {\n type,\n status: info.status,\n ...(typeof info.utilization === 'number' ? { utilization: info.utilization } : {}),\n ...(typeof info.resetsAt === 'number' ? { resetsAt: info.resetsAt < 1e12 ? info.resetsAt * 1000 : info.resetsAt } : {}),\n at: Date.now(),\n });\n}\n\nexport function usageLimits(): UsageLimit[] {\n const now = Date.now();\n // A limit that has reset since it was reported says nothing any more.\n return [...limits.values()].filter((limit) => !limit.resetsAt || limit.resetsAt > now);\n}\n", "import { randomUUID, type UUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\n\nimport { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n CanUseTool,\n EffortLevel,\n ElicitationResult,\n OnElicitation,\n Options,\n PermissionResult,\n PermissionUpdate,\n Query,\n SDKMessage,\n SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\n\nimport { plainError } from '../shared/errors.js';\nimport { pickerValue } from '../shared/model-names.js';\nimport type { PermissionMode } from '../shared/modes.js';\nimport type {\n Attachment,\n BackgroundTask,\n ChatMessage,\n McpServer,\n PartialBlock,\n PermissionDecision,\n PermissionRequest,\n QueuedPrompt,\n RewindResult,\n RunSettings,\n RunState,\n ScheduledCheck,\n SendMode,\n SessionStatus,\n ShellResult,\n TaskOutput,\n TaskProgress,\n} from '../shared/protocol.js';\nimport { describeAlways, sessionModeOf } from './approvals.js';\nimport { config } from './config.js';\nimport { DEMO_WAITING_SESSION, demoRunState } from './demo.js';\nimport { type Completions, forgetCompletions, knownModels, noteTerminalCommands, onSubscription, startError, toCompletions, toMcpServers } from './models.js';\nimport { broadcastAll, feedFor, sessionsChanged } from './feed.js';\nimport { isDirectory } from './folders.js';\nimport { liveProcesses } from './live.js';\nimport { toChatMessage } from './normalize.js';\nimport { notify } from './push.js';\nimport { sessionInfo, sessionTitle } from './sessions.js';\nimport { bashModeText } from './shell.js';\nimport { lastTurnTime, refreshTranscriptIndex, transcriptPath } from './transcripts.js';\nimport { FULL_SETTINGS, type Launch, launchFor } from './trust.js';\nimport { recordLimit } from './usage.js';\n\n/** Messages the user sends, handed to the Claude process as they come. */\nclass InputQueue implements AsyncIterable<SDKUserMessage> {\n private items: SDKUserMessage[] = [];\n private waiters: Array<(result: IteratorResult<SDKUserMessage>) => void> = [];\n private done = false;\n\n push(item: SDKUserMessage): void {\n const waiter = this.waiters.shift();\n if (waiter) waiter({ value: item, done: false });\n else this.items.push(item);\n }\n\n close(): void {\n this.done = true;\n for (const waiter of this.waiters.splice(0)) waiter({ value: undefined, done: true });\n }\n\n [Symbol.asyncIterator](): AsyncIterator<SDKUserMessage> {\n return {\n next: () => {\n const item = this.items.shift();\n if (item) return Promise.resolve({ value: item, done: false });\n if (this.done) return Promise.resolve({ value: undefined, done: true });\n return new Promise((resolve) => this.waiters.push(resolve));\n },\n };\n }\n}\n\n/** A request Claude Code waits on: a tool to approve, or an MCP server asking for input. */\ntype Pending =\n | {\n kind: 'tool';\n request: PermissionRequest;\n input: Record<string, unknown>;\n /** What \"always\" applies, when the request offers it. */\n suggestions?: PermissionUpdate[];\n /** Asked in the main conversation, not by a subagent: a plain Deny ends the turn there. */\n main: boolean;\n resolve: (result: PermissionResult) => void;\n }\n | { kind: 'elicitation'; request: PermissionRequest; resolve: (result: ElicitationResult) => void };\n\nexport type SendInput = {\n text: string;\n attachments: Attachment[];\n settings: RunSettings;\n /** Id for the user message, so the client's optimistic copy matches the transcript row. */\n uuid?: string;\n /** While a turn runs: join it at Claude's next step, or wait for it to end. */\n mode?: SendMode;\n};\n\ntype Prompt = { uuid: string; text: string; attachments: Attachment[] };\n\n/** The run closed while a message to it was on its way: it never reached Claude, and can go to another. */\nclass RunClosed extends Error {\n constructor() {\n super('Claude Code stopped in this session');\n }\n}\n\n/** What a user message holds, as the SDK types it, so an SDK change fails the typecheck here. */\ntype UserContent = Exclude<Extract<SDKUserMessage['message'], { role: 'user' }>['content'], string>;\n\nconst sdkModel = (model: string | undefined) => (model && model !== 'default' ? model : undefined);\n\n/** The image types the API takes inline; other pictures go to Claude as files to read. */\nconst INLINE_IMAGES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] as const;\nconst inlineImage = (mime: string): mime is (typeof INLINE_IMAGES)[number] => (INLINE_IMAGES as readonly string[]).includes(mime);\n\nasync function contentOf(text: string, attachments: Attachment[]): Promise<UserContent> {\n const content: UserContent = [];\n const fileLines: string[] = [];\n for (const attachment of attachments) {\n const mime = attachment.mime;\n if (inlineImage(mime) && attachment.size <= 5 * 1024 * 1024) {\n const data = await readFile(attachment.path).catch(() => undefined);\n if (data) {\n content.push({ type: 'image', source: { type: 'base64', media_type: mime, data: data.toString('base64') } });\n continue;\n }\n }\n fileLines.push(`- ${attachment.path} (${attachment.name})`);\n }\n let body = text;\n if (fileLines.length > 0) body = `${body}${body ? '\\n\\n' : ''}Attached files:\\n${fileLines.join('\\n')}`;\n if (body) content.push({ type: 'text', text: body });\n return content;\n}\n\n/** Claude Code's own words for a refused tool use, so Claude takes a Deny here as it takes the CLI's No. */\nconst REFUSED = 'The user doesn\\'t want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file).';\nconst STOP_AND_WAIT = `${REFUSED} STOP what you are doing and wait for the user to tell you how to proceed.`;\nconst refusedWith = (note: string) => `${REFUSED} To tell you how to proceed, the user said:\\n${note}`;\n\n/** /clear and its aliases start a new conversation inside the same Claude Code process, under a new id. */\nconst CLEARS = /^\\/(clear|reset|new)(\\s|$)/;\nconst AFRESH = 'To start afresh, open a new session in this folder.';\n\n/** Claude Code's error, or what it means for someone who edited their last prompt, in plain words. */\nexport function readableError(text: string): string {\n if (text.includes('Resume rejected by --resume-drops-turn')) {\n return 'The conversation changed after that prompt (another app added to it), so the prompt was not replaced. Reload, then edit it again or send a new message.';\n }\n return startError(text) ?? plainError(text, config.machine) ?? text;\n}\n\n/** Text for a lock screen: one line, short, without control or direction-changing characters. */\nexport function oneLine(text: string, max = 120): string {\n // eslint-disable-next-line no-control-regex\n const flat = text.replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u202a-\\u202e\\u2066-\\u2069\\ufeff]+/g, ' ').replace(/\\s+/g, ' ').trim();\n return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;\n}\n\nconst str = (value: unknown) => (typeof value === 'string' ? value : '');\n\n/** What a waiting request asks for, as a notification says it: the command, the file, the question. */\nexport function askedFor(request: PermissionRequest, cwd: string): string {\n const input = request.input;\n const file = (value: unknown) => {\n const full = str(value);\n return full.startsWith(`${cwd}/`) ? full.slice(cwd.length + 1) : full;\n };\n if (request.elicitation) return `${request.elicitation.server}: ${request.elicitation.message}`;\n switch (request.toolName) {\n case 'AskUserQuestion': {\n const first = Array.isArray(input.questions) ? (input.questions[0] as Record<string, unknown> | undefined) : undefined;\n return str(first?.question) || 'Claude has a question for you';\n }\n case 'ExitPlanMode':\n return 'Claude\u2019s plan is ready for you to review';\n case 'Bash':\n case 'PowerShell':\n return str(input.description) || `Run ${str(input.command).split('\\n')[0]}`;\n case 'Edit':\n case 'MultiEdit':\n return `Edit ${file(input.file_path)}`;\n case 'NotebookEdit':\n return `Edit ${file(input.notebook_path)}`;\n case 'Write':\n return `Write ${file(input.file_path)}`;\n case 'WebFetch': {\n try {\n return `Fetch ${new URL(str(input.url)).host}`;\n } catch {\n return 'Fetch a page';\n }\n }\n default:\n return request.title || `Use ${request.toolName.startsWith('mcp__') ? request.toolName.split('__').slice(1).join(' \u00B7 ') : request.toolName}`;\n }\n}\n\n/** Form values as an MCP server takes them: strings, numbers, booleans and lists of strings. */\nfunction formValues(input: Record<string, unknown>): Record<string, string | number | boolean | string[]> {\n const out: Record<string, string | number | boolean | string[]> = {};\n for (const [key, value] of Object.entries(input)) {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') out[key] = value;\n else if (Array.isArray(value) && value.every((v) => typeof v === 'string')) out[key] = value;\n }\n return out;\n}\n\n/** A scheduled check stays counted this long after it was due, in case it fires late. */\nconst DUE_GRACE_MS = 10 * 60_000;\n/** Claude Code lets a recurring check go this long after it was made (CronCreate: \"auto-expired after 7 days\"). */\nconst RECURRING_MAX_AGE_MS = 7 * 24 * 3600_000;\n\n/** One Claude Code process driving one session. It stays alive between turns until idle. */\nexport class SessionRun {\n busy = false;\n /** When the running turn began: the chat counts its time from here, not from when it was opened. */\n private startedAt?: number;\n closed = false;\n error?: string;\n lastActive = Date.now();\n private partial: PartialBlock[] = [];\n private completedBlocks = 0;\n private permissions = new Map<string, Pending>();\n private input = new InputQueue();\n private q?: Query;\n private emitTimer?: NodeJS.Timeout;\n private title = '';\n /** Set by Stop during a turn: it then ends with an error result that is not a failure. */\n private interrupted = false;\n private lastTurn?: RunState['lastTurn'];\n private context?: RunState['context'];\n private activity?: RunState['activity'];\n /** Background tasks to show (and stop), and how many run in all, watchers included. */\n private tasks: BackgroundTask[] = [];\n private taskCount = 0;\n /** What each running subagent or task last reported, the tool call that started it, and its name. */\n private progress = new Map<string, TaskProgress>();\n private taskTools = new Map<string, string>();\n private agentNames = new Map<string, string>();\n /** Claude's calls to schedule tools, until their results say what was scheduled. */\n private scheduling = new Map<string, { name: string; input: Record<string, unknown> }>();\n private wakeup?: ScheduledCheck;\n private crons = new Map<string, ScheduledCheck>();\n /** When Claude Code lets each recurring check go. */\n private cronEnds = new Map<string, number>();\n /** Prompts waiting for the turn to end; Claude gets them together when it does. */\n private queued: Prompt[] = [];\n /** The turn ended with prompts waiting, which went out at once: the idle that follows is not the end. */\n private continuing = false;\n /** Of the prompts that went out when a turn ended, those no result has answered yet: Claude goes on with them. */\n private unanswered = new Set<string>();\n /** The session's total cost after the last turn; unknown for a resumed session until its first turn. */\n private costSoFar?: number;\n /** While settings picked here are being applied, Claude Code's reports of the old ones are stale. */\n private applying = 0;\n private modeChanged?: PermissionMode;\n private modeBeforePlan?: PermissionMode;\n private lastReply = '';\n private started!: { resolve: () => void; reject: (error: Error) => void };\n /** Settles once Claude has started (its first message), or fails when it ends before that. */\n readonly ready = new Promise<void>((resolve, reject) => {\n this.started = { resolve, reject };\n });\n // Most callers never wait for it: a failure here must not count as unhandled.\n private readonly readyHandled = this.ready.catch(() => undefined);\n /** Claude Code said something: it started, and the session is there to resume. */\n private began = false;\n private suggestion?: string;\n\n constructor(\n readonly sessionId: string,\n readonly cwd: string,\n private settings: RunSettings,\n private readonly resume: boolean,\n /** Resume only up to this entry, dropping the turn after it (an edited last prompt). */\n private readonly resumeAt?: { entry: string; dropsTurn: string },\n /** Which settings Claude Code loads: a folder nobody trusted runs none of its own (trust.ts). */\n private readonly launch: Launch = FULL_SETTINGS,\n ) {\n if (!resume) this.costSoFar = 0;\n }\n\n /**\n * Work in this process that ends with it and says nothing while it runs: background tasks\n * (watchers included), a wake-up Claude scheduled, session crons. Closing or restarting the\n * process would cut it off.\n */\n get hasBackgroundTasks(): boolean {\n if (this.forgetPastChecks()) this.emit();\n return this.taskCount > 0 || Boolean(this.wakeup) || this.crons.size > 0;\n }\n\n /**\n * How much of that work there is to show: background tasks and subagents (watchers aside, which\n * Claude Code says are no activity) and the checks Claude stays running for. A session with some,\n * and no turn running, is still at work.\n */\n get backgroundCount(): number {\n if (this.forgetPastChecks()) this.emit();\n return this.work();\n }\n\n private work(): number {\n return this.tasks.length + (this.wakeup ? 1 : 0) + this.crons.size;\n }\n\n /**\n * The checks still to come at `now`: not one-off checks long past due, nor recurring ones Claude\n * Code has let go. A recurring check that fired shows no time: Claude Code works out the next one\n * as it goes, its own way, and a time gone by would say it is late.\n */\n private checksAt(now: number): { wakeup: ScheduledCheck | undefined; crons: Map<string, ScheduledCheck> } {\n const wakeup = this.wakeup && (this.wakeup.next ?? 0) + DUE_GRACE_MS < now ? undefined : this.wakeup;\n const crons = new Map<string, ScheduledCheck>();\n for (const [id, cron] of this.crons) {\n if (cron.repeats ? (this.cronEnds.get(id) ?? Infinity) < now : (cron.next ?? 0) + DUE_GRACE_MS < now) continue;\n if (cron.repeats && cron.next !== undefined && cron.next < now) {\n const { next: _fired, ...rest } = cron;\n crons.set(id, rest);\n } else {\n crons.set(id, cron);\n }\n }\n return { wakeup, crons };\n }\n\n /** Keeps only the checks still to come; whether that changed anything. */\n private forgetPastChecks(now = Date.now()): boolean {\n const { wakeup, crons } = this.checksAt(now);\n const changed = wakeup !== this.wakeup || crons.size !== this.crons.size || [...crons].some(([id, cron]) => this.crons.get(id) !== cron);\n this.wakeup = wakeup;\n this.crons = crons;\n for (const id of this.cronEnds.keys()) if (!crons.has(id)) this.cronEnds.delete(id);\n return changed;\n }\n\n start(): void {\n const settings = this.settings;\n const options: Options = {\n cwd: this.cwd,\n ...(this.resume ? { resume: this.sessionId } : { sessionId: this.sessionId }),\n // Claude Code checks that everything past the entry belongs to the dropped turn, so a\n // message another app added meanwhile is never thrown away unseen.\n ...(this.resume && this.resumeAt ? { resumeSessionAt: this.resumeAt.entry, resumeDropsTurn: this.resumeAt.dropsTurn } : {}),\n ...(sdkModel(settings.model) ? { model: sdkModel(settings.model) } : {}),\n ...(settings.effort ? { effort: settings.effort as EffortLevel } : {}),\n permissionMode: settings.permissionMode ?? 'default',\n allowDangerouslySkipPermissions: true,\n ...(settings.fast || settings.ultracode ? {\n settings: {\n ...(settings.fast ? { fastMode: true } : {}),\n // Ultracode needs workflows; both are session settings, like the CLI's --settings.\n ...(settings.ultracode ? { ultracode: true, enableWorkflows: true } : {}),\n },\n } : {}),\n includePartialMessages: true,\n // Lets \"Rewind code\" put files back the way they were before a prompt.\n enableFileCheckpointing: true,\n promptSuggestions: true,\n // Running subagents say what they are doing, for the line under their step.\n agentProgressSummaries: true,\n // Each background task has its own Stop here, so Stop ends the turn and spares them, as Esc does.\n perTaskStopAffordance: true,\n toolConfig: { askUserQuestion: { previewFormat: 'markdown' } },\n settingSources: this.launch.settingSources,\n ...(this.launch.env ? { env: { ...process.env, ...this.launch.env } } : {}),\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n tools: { type: 'preset', preset: 'claude_code' },\n canUseTool: this.canUseTool,\n onElicitation: this.onElicitation,\n ...(config.claudeExecutable ? { pathToClaudeCodeExecutable: config.claudeExecutable } : {}),\n stderr: (data) => {\n if (process.env.PELICAN_DEBUG) process.stderr.write(`[claude ${this.sessionId.slice(0, 8)}] ${data}`);\n },\n };\n this.q = query({ prompt: this.input, options });\n void this.pump();\n void sessionInfo(this.sessionId).then((info) => {\n if (info) this.title = sessionTitle(info) ?? '';\n });\n }\n\n state(): RunState {\n const progress = Object.fromEntries([...this.progress].flatMap(([task, report]) => {\n const tool = this.taskTools.get(task);\n return tool ? [[tool, report]] : [];\n }));\n const checks = this.checksAt(Date.now());\n const scheduled = [...(checks.wakeup ? [checks.wakeup] : []), ...checks.crons.values()];\n return {\n sessionId: this.sessionId,\n cwd: this.cwd,\n busy: this.busy,\n ...(this.busy && this.startedAt ? { startedAt: this.startedAt } : {}),\n settings: this.settings,\n permissions: [...this.permissions.values()].map((p) => p.request),\n partial: this.partial.slice(this.completedBlocks).filter(Boolean),\n ...(this.error ? { error: this.error } : {}),\n ...(this.lastTurn ? { lastTurn: this.lastTurn } : {}),\n ...(this.context ? { context: this.context } : {}),\n ...(this.activity ? { activity: this.activity } : {}),\n ...(this.tasks.length > 0 ? {\n tasks: this.tasks.map((task) => {\n const report = this.progress.get(task.id);\n const summary = report?.summary ?? report?.lastTool;\n return summary ? { ...task, summary } : task;\n }),\n } : {}),\n ...(this.queued.length > 0 ? { queued: this.queued.map(queuedPrompt) } : {}),\n ...(this.busy && this.interrupted ? { stopping: true } : {}),\n ...(Object.keys(progress).length > 0 ? { progress } : {}),\n ...(scheduled.length > 0 ? { scheduled } : {}),\n ...(this.modeChanged ? { modeChanged: this.modeChanged } : {}),\n ...(this.suggestion && !this.busy ? { suggestion: this.suggestion } : {}),\n };\n }\n\n status(): SessionStatus {\n if (this.permissions.size > 0) return 'waiting';\n return this.busy ? 'running' : 'idle';\n }\n\n /** Sends the run state now, or within 80 ms when called for streamed text. */\n private emit(soon = false): void {\n if (soon) {\n if (this.emitTimer) return;\n this.emitTimer = setTimeout(() => {\n this.emitTimer = undefined;\n this.emitNow();\n }, 80);\n return;\n }\n clearTimeout(this.emitTimer);\n this.emitTimer = undefined;\n this.emitNow();\n }\n\n private lastStatus?: string;\n /** Its process has ended and its last word is said: nothing it does after that reaches a page. */\n private finished = false;\n\n /**\n * A newer run has taken the session (an edited last prompt, a restart): what this one, closed,\n * still says while its process exits would undo the newer one's state on every page.\n */\n private replaced(): boolean {\n const current = runs.get(this.sessionId);\n return current !== undefined && current !== this;\n }\n\n private emitNow(): void {\n if (this.finished || this.replaced()) return;\n this.forgetPastChecks();\n const state = this.state();\n feedFor(this.sessionId).broadcast({ type: 'run', state });\n this.sayStatus();\n }\n\n /** Session lists only care about the status and the work left running; streamed text stays with the session's viewers. */\n private sayStatus(): void {\n const status = this.status();\n const tasks = this.work();\n if (`${status}:${tasks}` !== this.lastStatus) {\n this.lastStatus = `${status}:${tasks}`;\n broadcastAll({ type: 'status', sessionId: this.sessionId, status, ...(tasks > 0 ? { tasks } : {}) });\n }\n }\n\n private setBusy(busy: boolean): void {\n if (this.busy === busy) return;\n this.busy = busy;\n this.lastActive = Date.now();\n this.startedAt = busy ? this.lastActive : undefined;\n if (!busy) {\n this.partial = [];\n this.completedBlocks = 0;\n }\n this.emit();\n sessionsChanged();\n }\n\n async send(input: SendInput): Promise<void> {\n // In the same process Claude Code would go on under a new id, beside this session's.\n if (CLEARS.test(input.text.trim())) throw new Error(AFRESH);\n await this.applySettings(input.settings);\n // Closed meanwhile (the idle close, an exit): queued or sent, it would wait for nobody.\n if (this.closed) throw new RunClosed();\n const prompt = { uuid: input.uuid ?? randomUUID(), text: input.text, attachments: input.attachments };\n // Queued: not part of the conversation until the turn ends and Claude gets it.\n if (this.busy && input.mode === 'queue') {\n this.queued.push(prompt);\n this.emit();\n return;\n }\n // While a turn runs, Claude reads it at its next step.\n await this.deliver(prompt, this.busy);\n }\n\n private async deliver(prompt: Prompt, steer: boolean): Promise<void> {\n const content = await contentOf(prompt.text, prompt.attachments);\n if (this.closed) throw new RunClosed();\n const message: SDKUserMessage = {\n type: 'user',\n uuid: prompt.uuid as UUID,\n session_id: this.sessionId,\n parent_tool_use_id: null,\n origin: { kind: 'human' },\n ...(steer ? { priority: 'next' as const } : {}),\n message: { role: 'user', content },\n };\n this.error = undefined;\n this.suggestion = undefined;\n this.modeChanged = undefined;\n if (!this.busy) {\n this.interrupted = false;\n this.lastReply = '';\n }\n this.setBusy(true);\n const chat = toChatMessage({ type: 'user', uuid: prompt.uuid, message: { role: 'user', content } });\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: Date.now() });\n // Shown already: the Claude it goes to instead publishes it under the same id, which the feed has.\n if (this.closed) throw new RunClosed();\n this.input.push(message);\n }\n\n /** Takes a queued prompt back before Claude gets it; false when it is not waiting any more. */\n unqueue(uuid: string): boolean {\n const before = this.queued.length;\n this.queued = this.queued.filter((p) => p.uuid !== uuid);\n if (this.queued.length === before) return false;\n this.emit();\n return true;\n }\n\n /**\n * Adds a `!` command and its output to the conversation without starting a\n * turn, the way Claude Code's bash mode does: Claude reads it with the next message.\n */\n async appendShell(result: ShellResult): Promise<void> {\n const uuid = randomUUID();\n const text = bashModeText(result);\n const message: SDKUserMessage = {\n type: 'user',\n uuid,\n session_id: this.sessionId,\n parent_tool_use_id: null,\n origin: { kind: 'human' },\n shouldQuery: false,\n message: { role: 'user', content: text },\n };\n const chat = toChatMessage({ type: 'user', uuid, message: { role: 'user', content: text } });\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: Date.now() });\n this.input.push(message);\n }\n\n /** Puts files back the way they were before the prompt `uuid`; `dryRun` only says what would change. */\n async rewind(uuid: string, dryRun: boolean): Promise<RewindResult> {\n if (!this.q) throw new Error('Claude is not running in this session');\n const result = await this.q.rewindFiles(uuid, { dryRun });\n return {\n canRewind: result.canRewind,\n ...(result.error ? { error: result.error } : {}),\n ...(result.filesChanged ? { files: result.filesChanged } : {}),\n ...(typeof result.insertions === 'number' ? { insertions: result.insertions } : {}),\n ...(typeof result.deletions === 'number' ? { deletions: result.deletions } : {}),\n };\n }\n\n async mcpServers(): Promise<McpServer[]> {\n if (!this.q) return [];\n return toMcpServers(await this.q.mcpServerStatus());\n }\n\n async setMcpServer(name: string, change: { enabled?: boolean; reconnect?: boolean }): Promise<void> {\n if (!this.q) throw new Error('Claude is not running in this session');\n if (change.reconnect) await this.q.reconnectMcpServer(name);\n if (change.enabled !== undefined) await this.q.toggleMcpServer(name, change.enabled);\n }\n\n /** The commands and agents of this very session, up to date (skills it found as it worked included). */\n async completions(): Promise<Completions> {\n if (!this.q) throw new Error('Claude is not running in this session');\n const [commands, agents] = await Promise.all([this.q.supportedCommands(), this.q.supportedAgents().catch(() => [])]);\n return toCompletions(commands, agents);\n }\n\n async stopTask(taskId: string): Promise<void> {\n await this.q?.stopTask(taskId);\n }\n\n /** The end of what a background command printed (the last 8 KiB), as the terminal's /tasks shows it. */\n async taskOutput(taskId: string): Promise<TaskOutput> {\n // A control request the SDK has but does not type yet.\n const q = this.q as (Query & { getTaskOutput?: (taskId: string) => Promise<{ output: string; truncated: boolean }> }) | undefined;\n if (!q?.getTaskOutput) throw new Error('This Claude Code cannot show a task\u2019s output');\n const answer = await q.getTaskOutput(taskId);\n return { output: String(answer?.output ?? ''), truncated: Boolean(answer?.truncated) };\n }\n\n /**\n * Settings picked here, applied to Claude now: from its next step, also mid-turn. A mode picked\n * here (`pick`) is always sent, even when Pelican thinks Claude is in it already.\n *\n * They are all the settings the page has: one left out is its default (Default effort is no\n * effort at all), which Claude gets and the run then says it has. Only the mode stays as it is\n * when none is given, as Claude Code changes it too.\n */\n async applySettings(next: RunSettings, pick = false): Promise<void> {\n const q = this.q;\n if (!q) return;\n const prev = this.settings;\n const mode = next.permissionMode ?? prev.permissionMode;\n this.settings = { ...next, ...(mode ? { permissionMode: mode } : {}) };\n if (next.permissionMode) this.modeChanged = undefined;\n if (next.permissionMode === 'plan' && prev.permissionMode !== 'plan') this.modeBeforePlan = prev.permissionMode ?? 'default';\n this.applying += 1;\n try {\n if ((next.model ?? 'default') !== (prev.model ?? 'default')) await q.setModel(sdkModel(next.model));\n // A new effort level sent without the ultracode key turns ultracode off, so both go together.\n if ((next.effort ?? '') !== (prev.effort ?? '') || Boolean(next.ultracode) !== Boolean(prev.ultracode)) {\n await q.applyFlagSettings({\n effortLevel: (next.effort as EffortLevel) ?? null,\n ultracode: Boolean(next.ultracode),\n ...(next.ultracode ? { enableWorkflows: true } : {}),\n });\n }\n if (Boolean(next.fast) !== Boolean(prev.fast)) await q.applyFlagSettings({ fastMode: Boolean(next.fast) });\n if (next.permissionMode && (pick || next.permissionMode !== (prev.permissionMode ?? 'default'))) await q.setPermissionMode(next.permissionMode);\n } catch (error) {\n console.warn('[pelican] could not apply settings', (error as Error).message);\n } finally {\n this.applying -= 1;\n }\n }\n\n async setPermissionMode(mode: PermissionMode): Promise<void> {\n await this.applySettings({ ...this.settings, permissionMode: mode }, true);\n this.emit();\n }\n\n /** Settings changed in the composer, all of them, applied to Claude now: from its next step, also mid-turn. */\n async updateSettings(next: RunSettings): Promise<void> {\n await this.applySettings(next);\n this.emit();\n }\n\n /** The mode Claude Code says the session is in now; said once when it was not picked here. */\n private noteMode(mode: PermissionMode): void {\n if (this.applying > 0) return;\n const before = this.settings.permissionMode ?? 'default';\n if (mode === before) return;\n if (mode === 'plan') this.modeBeforePlan = before;\n this.settings = { ...this.settings, permissionMode: mode };\n this.modeChanged = mode;\n this.emit();\n }\n\n /** Each turn starts with what it runs with: the chips show that, not what was last picked. */\n private noteInit(init: Extract<SDKMessage, { type: 'system'; subtype: 'init' }>): void {\n if (init.terminal_slash_commands) noteTerminalCommands(init.terminal_slash_commands);\n if (this.applying > 0) return;\n const next = { ...this.settings };\n // Named as the picker names it: an id the list does not know would show raw, so it is left.\n const models = knownModels();\n if (init.model && models?.some((m) => m.value === init.model || m.resolvedModel === init.model)) next.model = pickerValue(init.model, models, next.model ?? 'default');\n if (typeof init.effort === 'string') next.effort = init.effort;\n if (init.fast_mode_state === 'on' || init.fast_mode_state === 'off') next.fast = init.fast_mode_state === 'on';\n const changed = JSON.stringify(next) !== JSON.stringify(this.settings);\n this.settings = next;\n if (init.permissionMode) this.noteMode(init.permissionMode);\n if (changed) this.emit();\n }\n\n /** Whether auto mode can carry out a plan with the model this session runs, when that is known. */\n private autoAvailable(): boolean {\n const model = this.settings.model ?? 'default';\n return knownModels()?.find((m) => m.value === model)?.supportsAuto === true;\n }\n\n private park(pending: Pending, signal: AbortSignal, onAbort: () => void): void {\n const id = pending.request.id;\n this.permissions.set(id, pending);\n signal.addEventListener('abort', () => {\n if (this.permissions.delete(id)) {\n onAbort();\n this.emit();\n sessionsChanged();\n }\n });\n this.emit();\n sessionsChanged();\n void notify({ title: this.title || 'Claude Code', body: oneLine(askedFor(pending.request, this.cwd)), sessionId: this.sessionId, tag: `${this.sessionId}:ask` });\n }\n\n private canUseTool: CanUseTool = (toolName, input, options) => {\n const { signal, suggestions, blockedPath, decisionReason, title, description, defaultToNo, suppressAlwaysAllowRule, agentID, mcpServer } = options;\n // No \"always\" where Claude Code says the rule would grant more than this request, or a plugin asked.\n const always = suppressAlwaysAllowRule ? undefined : describeAlways(suggestions, config.home);\n const agent = agentID ? this.agentNames.get(agentID) ?? 'a subagent' : undefined;\n const request: PermissionRequest = {\n id: randomUUID(),\n sessionId: this.sessionId,\n toolName,\n input,\n ...(always ? { always } : {}),\n ...(title ? { title } : {}),\n ...(description ? { description } : {}),\n ...(defaultToNo ? { defaultToNo: true } : {}),\n ...(agent ? { agent } : {}),\n ...(mcpServer?.name ? { server: mcpServer.name } : {}),\n ...(toolName === 'ExitPlanMode' ? { plan: { ...(this.modeBeforePlan ? { before: this.modeBeforePlan } : {}), auto: this.autoAvailable() } } : {}),\n ...(decisionReason ? { reason: decisionReason } : {}),\n ...(blockedPath ? { blockedPath } : {}),\n createdAt: Date.now(),\n };\n return new Promise<PermissionResult>((resolve) => {\n this.park(\n { kind: 'tool', request, input, ...(always && suggestions ? { suggestions } : {}), main: !agentID, resolve },\n signal,\n () => resolve({ behavior: 'deny', message: 'Cancelled.' }),\n );\n });\n };\n\n private onElicitation: OnElicitation = (asked, { signal }) => {\n // Only a web page may be offered to open.\n const url = asked.mode === 'url' && asked.url && /^https?:\\/\\//i.test(asked.url) ? asked.url : undefined;\n const request: PermissionRequest = {\n id: randomUUID(),\n sessionId: this.sessionId,\n toolName: `mcp__${asked.serverName}`,\n input: {},\n ...(asked.title ? { title: asked.title } : {}),\n ...(asked.description ? { description: asked.description } : {}),\n elicitation: {\n server: asked.serverName,\n message: asked.message,\n mode: asked.mode === 'url' ? 'url' : 'form',\n ...(url ? { url } : {}),\n ...(asked.requestedSchema ? { schema: asked.requestedSchema } : {}),\n },\n createdAt: Date.now(),\n };\n return new Promise<ElicitationResult>((resolve) => {\n this.park({ kind: 'elicitation', request, resolve }, signal, () => resolve({ action: 'cancel' }));\n });\n };\n\n decide(id: string, decision: PermissionDecision): boolean {\n const pending = this.permissions.get(id);\n if (!pending) return false;\n this.permissions.delete(id);\n if (pending.kind === 'elicitation') {\n pending.resolve(decision.behavior === 'allow'\n ? { action: 'accept', ...(decision.updatedInput ? { content: formValues(decision.updatedInput) } : {}) }\n : { action: 'decline' });\n } else if (decision.behavior === 'allow') {\n const remember = Boolean(decision.remember && pending.suggestions);\n // A plan approved into a mode: Claude Code switches with the approval, as its own options do.\n const updates: PermissionUpdate[] = [\n ...(remember ? pending.suggestions! : []),\n ...(decision.permissionMode ? [{ type: 'setMode' as const, mode: decision.permissionMode, destination: 'session' as const }] : []),\n ];\n const mode = sessionModeOf(updates);\n if (mode) {\n if (mode === 'plan' && this.settings.permissionMode !== 'plan') this.modeBeforePlan = this.settings.permissionMode ?? 'default';\n this.settings = { ...this.settings, permissionMode: mode };\n this.modeChanged = undefined;\n }\n pending.resolve({\n behavior: 'allow',\n updatedInput: decision.updatedInput ?? pending.input,\n ...(updates.length > 0 ? { updatedPermissions: updates } : {}),\n decisionClassification: remember ? 'user_permanent' : 'user_temporary',\n });\n } else {\n pending.resolve(this.refusal(pending, decision.message));\n }\n this.emit();\n sessionsChanged();\n return true;\n }\n\n /** A Deny, as Claude Code's No: without a note the turn stops and Claude waits; with one, Claude goes on with it. */\n private refusal(pending: Extract<Pending, { kind: 'tool' }>, message: string | undefined): PermissionResult {\n const note = message?.trim();\n // A question skipped and a plan sent back are answers, not refusals: Claude carries on with them.\n if (pending.request.toolName === 'AskUserQuestion' || pending.request.toolName === 'ExitPlanMode') {\n return { behavior: 'deny', message: note || 'The user declined this.', decisionClassification: 'user_reject' };\n }\n if (note) return { behavior: 'deny', message: refusedWith(note), decisionClassification: 'user_reject' };\n // A subagent's request ends only that step of the subagent, as in Claude Code.\n if (!pending.main) return { behavior: 'deny', message: STOP_AND_WAIT, decisionClassification: 'user_reject' };\n if (this.busy) this.interrupted = true;\n return { behavior: 'deny', message: STOP_AND_WAIT, interrupt: true, decisionClassification: 'user_reject' };\n }\n\n /** Answers a request nobody decided: the turn was stopped, or the session closed. */\n private settleAll(why: string): void {\n for (const [id, pending] of this.permissions) {\n this.permissions.delete(id);\n if (pending.kind === 'elicitation') pending.resolve({ action: 'cancel' });\n else pending.resolve({ behavior: 'deny', message: why });\n }\n }\n\n async interrupt(): Promise<void> {\n // A Stop that comes after the turn ended stops nothing, and must not cost the next turn its notice.\n if (!this.busy) return;\n this.interrupted = true;\n this.settleAll('Interrupted by the user.');\n this.emit();\n sessionsChanged();\n try {\n await this.q?.interrupt();\n } catch (error) {\n console.warn('[pelican] interrupt failed', (error as Error).message);\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.settleAll('Session closed.');\n this.input.close();\n try {\n this.q?.close();\n } catch {\n // Already exited.\n }\n }\n\n /** How full the context window is now; shown in the session header. */\n private async readContext(): Promise<void> {\n try {\n // The summary comes from the last response's usage: no token-count calls after every turn.\n const usage = await this.q?.getContextUsage({ detail: 'summary' });\n if (!usage) return;\n this.context = { percent: Math.round(usage.percentage), tokens: usage.totalTokens, max: usage.maxTokens };\n this.emit();\n } catch {\n // Older Claude Code; the header just shows no meter.\n }\n }\n\n /** This turn's cost: the result carries the session's running total. */\n private turnCost(total: number | undefined): number | undefined {\n if (typeof total !== 'number' || !Number.isFinite(total)) return undefined;\n const before = this.costSoFar;\n this.costSoFar = total;\n if (before === undefined) return undefined;\n // A total that went down started again (/clear, or a result after a crash).\n return total >= before ? total - before : total;\n }\n\n /** Remembers Claude's calls to the tools that schedule work, to read what their results scheduled. */\n private noteCalls(content: unknown): void {\n if (!Array.isArray(content)) return;\n for (const block of content as Array<Record<string, unknown>>) {\n if (block?.type !== 'tool_use' || typeof block.id !== 'string') continue;\n const name = str(block.name);\n if (name === 'ScheduleWakeup' || name === 'CronCreate' || name === 'CronDelete') {\n this.scheduling.set(block.id, { name, input: (block.input ?? {}) as Record<string, unknown> });\n }\n }\n }\n\n private noteResults(raw: Record<string, unknown>): void {\n const content = (raw.message as { content?: unknown } | undefined)?.content;\n if (!Array.isArray(content)) return;\n for (const block of content as Array<Record<string, unknown>>) {\n if (block?.type !== 'tool_result' || typeof block.tool_use_id !== 'string') continue;\n const call = this.scheduling.get(block.tool_use_id);\n if (!call) continue;\n this.scheduling.delete(block.tool_use_id);\n if (block.is_error === true) continue;\n const output = (raw.tool_use_result ?? {}) as Record<string, unknown>;\n if (call.name === 'ScheduleWakeup') {\n const at = typeof output.scheduledFor === 'number' ? output.scheduledFor : undefined;\n this.wakeup = call.input.stop === true || !at ? undefined : { id: 'wakeup', what: str(call.input.reason) || 'Claude checks back', next: at, repeats: false };\n } else if (call.name === 'CronCreate') {\n const id = str(output.id);\n if (!id) continue;\n const prompt = str(call.input.prompt);\n const repeats = output.recurring !== false;\n this.crons.set(id, {\n id,\n what: oneLine(`${str(output.humanSchedule) || str(call.input.cron)}${prompt ? `: ${prompt}` : ''}`, 100),\n ...(typeof output.nextFireAt === 'number' ? { next: output.nextFireAt } : {}),\n repeats,\n });\n if (repeats) this.cronEnds.set(id, Date.now() + RECURRING_MAX_AGE_MS);\n } else {\n this.crons.delete(str(call.input.id));\n this.cronEnds.delete(str(call.input.id));\n }\n }\n }\n\n private onStream(event: Record<string, unknown>): void {\n const index = typeof event.index === 'number' ? event.index : -1;\n switch (event.type) {\n case 'message_start':\n this.partial = [];\n this.completedBlocks = 0;\n break;\n case 'content_block_start': {\n const block = (event.content_block ?? {}) as Record<string, unknown>;\n if (block.type === 'text') this.partial[index] = { type: 'text', text: '' };\n else if (block.type === 'thinking') this.partial[index] = { type: 'thinking', thinking: '' };\n else if (block.type === 'tool_use' || block.type === 'server_tool_use') {\n this.partial[index] = { type: 'tool_use', name: String(block.name ?? ''), inputJson: '' };\n }\n break;\n }\n case 'content_block_delta': {\n const delta = (event.delta ?? {}) as Record<string, unknown>;\n const block = this.partial[index];\n if (!block) break;\n if (block.type === 'text' && delta.type === 'text_delta') block.text += String(delta.text ?? '');\n else if (block.type === 'thinking' && delta.type === 'thinking_delta') block.thinking += String(delta.thinking ?? '');\n else if (block.type === 'tool_use' && delta.type === 'input_json_delta') block.inputJson += String(delta.partial_json ?? '');\n break;\n }\n default:\n return;\n }\n this.setBusy(true);\n this.emit(true);\n }\n\n /** A line Claude Code shows in the conversation that is no message of Claude's: hook feedback, a command's output. */\n private async publishNotice(uuid: string, text: string): Promise<void> {\n if (!text.trim()) return;\n await feedFor(this.sessionId).publish({ uuid, role: 'system', blocks: [{ type: 'text', text }], timestamp: Date.now() });\n }\n\n private async pump(): Promise<void> {\n const q = this.q!;\n try {\n for await (const message of q as AsyncIterable<SDKMessage>) {\n this.lastActive = Date.now();\n this.began = true;\n this.started.resolve();\n const raw = message as unknown as Record<string, unknown>;\n switch (message.type) {\n case 'stream_event':\n if (!message.parent_tool_use_id) this.onStream(message.event as unknown as Record<string, unknown>);\n break;\n case 'assistant':\n case 'user': {\n if (raw.parent_tool_use_id) break;\n if (message.type === 'assistant') {\n this.completedBlocks += 1;\n this.noteCalls(message.message.content);\n const text = message.message.content.flatMap((b) => (b.type === 'text' ? [b.text] : [])).join('\\n').trim();\n if (text) this.lastReply = text;\n } else {\n this.noteResults(raw);\n }\n if (this.activity?.kind === 'retrying') this.activity = undefined;\n const chat = toChatMessage(raw);\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: chat.timestamp ?? Date.now() } satisfies ChatMessage);\n this.emit(true);\n break;\n }\n case 'system':\n if (message.subtype === 'session_state_changed') {\n const state = (raw as { state?: string }).state;\n if (state === 'running' || state === 'requires_action') {\n this.continuing = false;\n if (!this.busy) this.interrupted = false;\n this.setBusy(true);\n } else if (state === 'idle') {\n if (this.continuing) this.continuing = false;\n else this.setBusy(false);\n }\n } else if (message.subtype === 'init') {\n this.noteInit(message);\n void refreshTranscriptIndex().then(sessionsChanged);\n } else if (message.subtype === 'status') {\n this.activity = message.status === 'compacting' ? { kind: 'compacting' } : undefined;\n if (message.permissionMode) this.noteMode(message.permissionMode);\n this.emit();\n } else if (message.subtype === 'api_retry') {\n this.activity = { kind: 'retrying', attempt: message.attempt, max: message.max_retries, delayMs: message.retry_delay_ms };\n this.emit();\n } else if (message.subtype === 'background_tasks_changed') {\n // Watchers count for keeping Claude running, not as something to show.\n this.taskCount = message.tasks.length;\n this.tasks = message.tasks\n .filter((t) => !t.ambient)\n .map((t) => ({\n id: t.task_id,\n description: t.description,\n type: t.subagent_type ?? t.task_type,\n ...(t.task_type === 'local_bash' || t.task_type.startsWith('monitor') ? { output: true } : {}),\n }));\n this.emit();\n } else if (message.subtype === 'task_started') {\n if (message.tool_use_id) this.taskTools.set(message.task_id, message.tool_use_id);\n if (message.subagent_type) this.agentNames.set(message.task_id, message.subagent_type);\n } else if (message.subtype === 'task_progress') {\n if (message.tool_use_id) this.taskTools.set(message.task_id, message.tool_use_id);\n this.progress.set(message.task_id, {\n ...(message.summary ? { summary: message.summary } : {}),\n ...(message.last_tool_name ? { lastTool: message.last_tool_name } : {}),\n toolUses: message.usage.tool_uses,\n durationMs: message.usage.duration_ms,\n });\n this.emit(true);\n } else if (message.subtype === 'task_notification') {\n this.progress.delete(message.task_id);\n this.taskTools.delete(message.task_id);\n this.agentNames.delete(message.task_id);\n this.emit(true);\n } else if (message.subtype === 'commands_changed') {\n void forgetCompletions(this.cwd);\n } else if (message.subtype === 'informational') {\n // Hook feedback (why a prompt was blocked), warnings and notices; 'info' lines are the terminal's transcript view only.\n if (message.level !== 'info') await this.publishNotice(message.uuid, message.content);\n } else if (message.subtype === 'local_command_output') {\n await this.publishNotice(message.uuid, `<local-command-stdout>${message.content}</local-command-stdout>`);\n }\n break;\n case 'rate_limit_event':\n recordLimit(message.rate_limit_info);\n break;\n case 'prompt_suggestion':\n this.suggestion = message.suggestion;\n this.emit();\n break;\n case 'result': {\n const stopped = this.interrupted;\n this.interrupted = false;\n this.continuing = false;\n const failed = !stopped && (message.subtype !== 'success' || message.is_error);\n this.error = failed\n ? readableError('errors' in message && message.errors.length > 0 ? message.errors.join('\\n') : ('result' in message ? String(message.result) : message.subtype))\n : undefined;\n const cost = this.turnCost(message.total_cost_usd);\n this.lastTurn = {\n durationMs: message.duration_ms,\n // A plan's subscription pays, not per turn: a dollar figure would only mislead.\n ...(cost !== undefined && !onSubscription() ? { costUsd: cost } : {}),\n ...(typeof message.usage?.output_tokens === 'number' ? { outputTokens: message.usage.output_tokens } : {}),\n };\n this.activity = undefined;\n // A turn Claude starts on its own (a scheduled check) may say nothing: it must not repeat the last reply.\n const reply = this.lastReply;\n this.lastReply = '';\n // Claude Code says which prompts a result answers. One that answers none of those still\n // waiting is about something else, or from a Claude Code that does not say: the turn ends.\n const answered = message.user_message_uuids ?? (message.user_message_uuid ? [message.user_message_uuid] : []);\n const before = this.unanswered.size;\n for (const uuid of answered) this.unanswered.delete(uuid);\n if (this.unanswered.size === before) this.unanswered.clear();\n // What waited for this turn goes out now, each prompt as it was typed, as Claude Code takes\n // what is typed while it works: plain prompts together, a command as a command. Joined\n // into one text, a command would take the prompts after it as its arguments.\n const waiting = this.queued.splice(0);\n if (waiting.length > 0) {\n this.continuing = true;\n // A turn of its own: its time counts from now, not from the turn that just ended.\n this.startedAt = Date.now();\n for (const prompt of waiting) {\n this.unanswered.add(prompt.uuid);\n await this.deliver(prompt, false);\n }\n }\n // A command is answered on its own, before the prompts that went with it.\n const goesOn = this.unanswered.size > 0;\n if (!goesOn) this.setBusy(false);\n this.emit();\n void this.readContext();\n if (!stopped && !goesOn) {\n void notify({\n title: this.title || 'Claude Code',\n body: failed ? oneLine(`Stopped: ${this.error ?? 'error'}`, 180) : oneLine(reply.split('\\n').find((line) => line.trim()) ?? '') || 'Finished',\n sessionId: this.sessionId,\n tag: `${this.sessionId}:done`,\n });\n }\n break;\n }\n default:\n break;\n }\n }\n } catch (error) {\n // Closed here while what was queued went out: no error of Claude's.\n if (!(error instanceof RunClosed)) {\n this.error = readableError((error as Error).message);\n console.warn(`[pelican] session ${this.sessionId.slice(0, 8)} ended with an error:`, this.error);\n }\n } finally {\n // Closed here (idle, replaced, Pelican shutting down), or ended on its own: a crash, a kill.\n const closedHere = this.closed;\n this.closed = true;\n this.started.reject(new Error(this.error ?? 'Claude Code stopped before it started'));\n this.settleAll('Session closed.');\n const leftover = this.queued.splice(0);\n // Its background work and checks ended with the process, and what they last said with it.\n this.tasks = [];\n this.taskCount = 0;\n this.wakeup = undefined;\n this.crons.clear();\n this.cronEnds.clear();\n this.progress.clear();\n this.taskTools.clear();\n this.activity = undefined;\n this.busy = false;\n this.startedAt = undefined;\n this.partial = [];\n this.completedBlocks = 0;\n clearTimeout(this.emitTimer);\n this.emitTimer = undefined;\n // A newer run may have taken the session's place already (an edited last prompt, a restart):\n // it speaks for the session, and this one says nothing more.\n if (!this.replaced()) {\n runs.delete(this.sessionId);\n // Pages show why it ended, if it did on an error, until they next ask and find no run;\n // otherwise they forget it now, as a page opened now finds no run.\n if (this.error) {\n this.emit();\n } else {\n feedFor(this.sessionId).broadcast({ type: 'run', sessionId: this.sessionId, state: null });\n this.sayStatus();\n }\n // What waited for the turn goes when it ends, also when Claude Code ended it by exiting: to the\n // session's Claude, resumed. Not when Pelican closed it (shutting down closes every one), nor\n // when it never started: that one would only fail again.\n if (leftover.length > 0 && !closedHere && this.began) void sendLeftovers(this.sessionId, this.cwd, this.settings, leftover);\n }\n this.finished = true;\n sessionsChanged();\n }\n }\n}\n\nconst queuedPrompt = ({ uuid, text, attachments }: Prompt): QueuedPrompt => ({ uuid, text, ...(attachments.length > 0 ? { attachments } : {}) });\n\n/**\n * Prompts queued for a turn whose Claude Code ended part way, sent to the session's Claude, resumed,\n * in order: the first starts a turn and the others wait for it, listed, as they waited before.\n */\nasync function sendLeftovers(sessionId: string, cwd: string, settings: RunSettings, prompts: Prompt[]): Promise<void> {\n for (const { uuid, text, attachments } of prompts) {\n try {\n await sendMessage({ sessionId, cwd }, { text, attachments, settings, uuid, mode: 'queue' });\n } catch (error) {\n console.warn(`[pelican] what was queued in ${sessionId.slice(0, 8)} could not be sent:`, (error as Error).message);\n return;\n }\n }\n}\n\nconst runs = new Map<string, SessionRun>();\n\nexport function getRun(sessionId: string): SessionRun | undefined {\n const run = runs.get(sessionId);\n return run && !run.closed ? run : undefined;\n}\n\n/** A Claude running in this folder, to ask instead of starting another. */\nexport function runIn(cwd: string): SessionRun | undefined {\n for (const run of runs.values()) if (!run.closed && run.cwd === cwd) return run;\n return undefined;\n}\n\n/** Status of a session this app runs; undefined when it has no Claude process here. */\nexport function runStatus(sessionId: string): SessionStatus | undefined {\n if (config.demo) return sessionId === DEMO_WAITING_SESSION ? 'waiting' : undefined;\n return getRun(sessionId)?.status();\n}\n\n/** Background work running in a session this app runs (see SessionRun.backgroundCount); 0 for none. */\nexport function runTasks(sessionId: string): number {\n if (config.demo) return 0;\n return getRun(sessionId)?.backgroundCount ?? 0;\n}\n\nexport function runState(sessionId: string): RunState | undefined {\n if (config.demo) return demoRunState(sessionId);\n return getRun(sessionId)?.state();\n}\n\n/**\n * Whether another app (Claude Desktop, the terminal) has worked on the session since this\n * run's Claude last did. Its process then holds a conversation this one has not seen, and a\n * message sent to it would continue an old version, beside the other: it is started afresh.\n */\nasync function staleRun(run: SessionRun): Promise<boolean> {\n if (run.busy || run.hasBackgroundTasks) return false;\n const other = (await liveProcesses()).get(run.sessionId);\n if (other?.updatedAt && other.updatedAt > run.lastActive) return true;\n // An app that has closed since leaves no process to ask: a turn in the transcript newer than\n // anything this run did is the sign.\n const file = await transcriptPath(run.sessionId);\n const last = file ? (await lastTurnTime(file))?.lastTurn : undefined;\n return Boolean(last && !last.copied && last.time > run.lastActive + 2000);\n}\n\n/** The session's run, unless it holds an older version of the conversation: then it is closed. */\nasync function currentRun(sessionId: string): Promise<SessionRun | undefined> {\n const run = getRun(sessionId);\n if (run && (await staleRun(run))) {\n run.close();\n if (runs.get(sessionId) === run) runs.delete(sessionId);\n return getRun(sessionId);\n }\n // It may have closed while that was looked into (the idle close, an exit): then it is not current.\n return run?.closed ? getRun(sessionId) : run;\n}\n\n/** Sends to a run that is there; false when it closed before the message reached it, for the caller to resume the session. */\nasync function sentTo(run: SessionRun, input: SendInput): Promise<boolean> {\n try {\n await run.send(input);\n return true;\n } catch (error) {\n if (error instanceof RunClosed) return false;\n throw error;\n }\n}\n\n/**\n * Sends a message, starting (or resuming) the session's Claude process when\n * none is running. Without a session id a new session starts in `cwd`.\n */\nexport async function sendMessage(target: { sessionId?: string; cwd?: string }, input: SendInput): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing runs. Start Pelican without --demo to talk to Claude.');\n if (CLEARS.test(input.text.trim())) throw new Error(AFRESH);\n if (target.sessionId) {\n const existing = await currentRun(target.sessionId);\n if (existing && (await sentTo(existing, input))) return existing.sessionId;\n const info = await sessionInfo(target.sessionId);\n const cwd = info?.cwd ?? target.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`The session's folder is missing: ${cwd ?? '(unknown)'}`);\n const launch = await launchFor(cwd);\n // Another request may have started one while this one looked the folder up.\n const started = getRun(target.sessionId);\n if (started && (await sentTo(started, input))) return started.sessionId;\n const run = new SessionRun(target.sessionId, cwd, input.settings, true, undefined, launch);\n runs.set(run.sessionId, run);\n run.start();\n await run.send(input);\n return run.sessionId;\n }\n const cwd = target.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`Not a folder: ${cwd ?? '(none)'}`);\n const run = new SessionRun(randomUUID(), cwd, input.settings, false, undefined, await launchFor(cwd));\n runs.set(run.sessionId, run);\n run.start();\n await run.send(input);\n return run.sessionId;\n}\n\n/**\n * Replaces the session's last turn: Claude resumes it up to `entry` (the row just before the\n * prompt being replaced) and gets `input` instead, in the same session, as rewinding does in\n * Claude Code. The old turn stays in the transcript, off the conversation's line.\n */\nexport async function replaceLastTurn(sessionId: string, cwd: string, entry: string, prompt: string, input: SendInput): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing runs.');\n // Turned away before anything changes: the running Claude stays as it is.\n if (CLEARS.test(input.text.trim())) throw new Error(AFRESH);\n const launch = await launchFor(cwd);\n const existing = getRun(sessionId);\n if (existing?.busy) throw new Error('Stop Claude before editing a prompt.');\n if (existing) {\n existing.close();\n runs.delete(sessionId);\n }\n const run = new SessionRun(sessionId, cwd, input.settings, true, { entry, dropsTurn: prompt }, launch);\n runs.set(sessionId, run);\n run.start();\n try {\n await run.send(input);\n } catch (error) {\n // This Claude resumed from before the last turn: left running, it would take the next message\n // and the last turn would drop out of the conversation. Without it, that message resumes it whole.\n run.close();\n if (runs.get(sessionId) === run) runs.delete(sessionId);\n throw error;\n }\n return sessionId;\n}\n\n/**\n * The session's Claude process, started (resumed, with no turn) when there is\n * none: for what only a running process can do, like rewinding files.\n */\nexport async function ensureRun(sessionId: string, settings: RunSettings = {}): Promise<SessionRun> {\n if (config.demo) throw new Error('This is the demo: nothing runs.');\n const existing = await currentRun(sessionId);\n if (existing) return existing;\n const info = await sessionInfo(sessionId);\n const cwd = info?.cwd;\n if (!cwd || !(await isDirectory(cwd))) throw new Error(`The session's folder is missing: ${cwd ?? '(unknown)'}`);\n const launch = await launchFor(cwd);\n const started = getRun(sessionId);\n if (started) return started;\n const run = new SessionRun(sessionId, cwd, settings, true, undefined, launch);\n runs.set(sessionId, run);\n run.start();\n return run;\n}\n\n/**\n * Closes Claude processes that have been idle for a while; the next message resumes them. Not\n * those with work that says nothing while it runs (a dev server, a watcher, a scheduled check):\n * Claude Code ends that work with the process, where the terminal and Desktop keep it going.\n */\nexport function closeIdle(now = Date.now()): void {\n for (const run of runs.values()) {\n if (!run.busy && run.status() === 'idle' && !run.hasBackgroundTasks && now - run.lastActive > config.idleCloseMs) run.close();\n }\n}\n\nsetInterval(() => closeIdle(), 60_000).unref();\n\nexport function closeAll(): void {\n for (const run of runs.values()) run.close();\n}\n\n/** Whether Claude is in a turn in any session this app runs (working, or waiting for an answer). */\nexport function anyRunBusy(): boolean {\n for (const run of runs.values()) if (!run.closed && run.busy) return true;\n return false;\n}\n", "import type { PartialAppend, PartialBlock, RunState, ServerEvent } from '../shared/protocol.js';\n\n/**\n * How much of a tool call's input streams to the page: enough for the fields that name the call\n * (path, command, pattern, address), never the file being written.\n */\nexport const PARTIAL_INPUT_MAX = 2048;\n\nconst textOf = (block: PartialBlock) => (block.type === 'text' ? block.text : block.type === 'thinking' ? block.thinking : block.inputJson);\n\n/**\n * A block as the page gets it, always a copy: the run adds each piece of text to its blocks in\n * place, so a block kept as it was sent would grow with them and show nothing to append.\n */\nexport const shown = (block: PartialBlock): PartialBlock =>\n (block.type === 'tool_use' && block.inputJson.length > PARTIAL_INPUT_MAX ? { ...block, inputJson: block.inputJson.slice(0, PARTIAL_INPUT_MAX) } : { ...block });\n\n/** A run as a page gets it, by any way: its blocks as shown, never the whole file being written. */\nexport const shownRun = (state: RunState): RunState => ({ ...state, partial: state.partial.map(shown) });\n\nconst restOf = new WeakMap<RunState, string>();\n\n/** The state without its streamed blocks, as text; worked out once per state, however many clients watch. */\nfunction rest(state: RunState): string {\n let text = restOf.get(state);\n if (text === undefined) {\n const { partial: _partial, ...others } = state;\n text = JSON.stringify(others);\n restOf.set(state, text);\n }\n return text;\n}\n\n/** What `after` adds to `before` at the ends of its blocks, or undefined when it changes more than that. */\nfunction appendsTo(before: PartialBlock[], after: PartialBlock[]): PartialAppend[] | undefined {\n if (before.length !== after.length) return undefined;\n const appends: PartialAppend[] = [];\n for (const [index, block] of after.entries()) {\n const old = before[index]!;\n if (old.type !== block.type || (old.type === 'tool_use' && block.type === 'tool_use' && old.name !== block.name)) return undefined;\n const from = textOf(old);\n const to = textOf(block);\n if (to.length < from.length || !to.startsWith(from)) return undefined;\n if (to.length > from.length) appends.push({ index, from: from.length, text: to.slice(from.length) });\n }\n return appends;\n}\n\n/**\n * One client's copy of one session's run. The run sends its whole state many times a second\n * while Claude writes; this turns each into what the client lacks: nothing when it has it, the\n * text added when only that grew, and the whole state otherwise (a block starts or ends, the\n * status or anything else changes). Data then grows with the answer, not with its square.\n */\nexport class RunChannel {\n private sent?: { rest: string; blocks: PartialBlock[] };\n\n constructor(readonly sessionId: string) {}\n\n /** The event that brings the client to `state`; undefined when it has it already. */\n next(state: RunState | null): ServerEvent | undefined {\n if (!state) {\n this.sent = undefined;\n return { type: 'run', sessionId: this.sessionId, state: null };\n }\n const blocks = state.partial.map(shown);\n const now = rest(state);\n const before = this.sent;\n this.sent = { rest: now, blocks };\n if (before && before.rest === now) {\n const appends = appendsTo(before.blocks, blocks);\n if (appends) return appends.length > 0 ? { type: 'partial', sessionId: this.sessionId, appends } : undefined;\n }\n return { type: 'run', sessionId: this.sessionId, state: { ...state, partial: blocks } };\n }\n\n /** The client may have missed something: it gets the whole state next. */\n reset(): void {\n this.sent = undefined;\n }\n}\n", "import { readdir, realpath, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { FileContent, GitFile, GitStatus, TreeEntry } from '../shared/protocol.js';\nimport { git } from './git.js';\nimport { openRegular } from './open.js';\n\nconst MAX_FILE = 512 * 1024;\nconst MAX_DIFF = 400_000;\n\n\nconst OUTSIDE = 'That path is outside the session\u2019s folder';\nconst within = (root: string, full: string) => full === root || full.startsWith(`${root}${path.sep}`);\n\n/**\n * A path inside the session's folder, or an error: the panels never reach outside it. No `..`\n * at all: resolving it by the text would cancel a linked folder before the link is checked\n * (`link/../x`), and the panels never ask for one.\n */\nexport function inside(cwd: string, relative: string): string {\n if ((relative ?? '').split(/[\\\\/]/).includes('..')) throw new Error(OUTSIDE);\n const root = path.resolve(cwd);\n const full = path.resolve(root, relative || '.');\n if (!within(root, full)) throw new Error(OUTSIDE);\n return full;\n}\n\n/** The same, for a path that exists, with links followed: a link may not lead out of the folder either. */\nasync function insideReal(cwd: string, relative: string): Promise<string> {\n const full = inside(cwd, relative);\n const [root, real] = await Promise.all([realpath(cwd), realpath(full)]);\n if (!within(root, real)) throw new Error(OUTSIDE);\n return real;\n}\n\nconst KIND: Record<string, GitFile['status']> = { M: 'modified', T: 'modified', A: 'added', D: 'deleted', R: 'renamed', C: 'added', U: 'conflicted' };\n\n/**\n * The repository the folder is in, when its work tree is the folder or a folder above it. A\n * repository whose config points its work tree somewhere else (core.worktree) would show files\n * from outside: Pelican treats that as no repository.\n */\nasync function repositoryOf(cwd: string): Promise<string | undefined> {\n try {\n const top = (await git(cwd, ['rev-parse', '--show-toplevel'], 5000)).trim();\n if (!top) return undefined;\n const [root, folder] = await Promise.all([realpath(top), realpath(cwd)]);\n return within(root, folder) ? root : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What changed in the session's folder since the last commit, with line counts. */\nexport async function gitStatus(cwd: string): Promise<GitStatus> {\n if (!(await repositoryOf(cwd))) return { repo: false };\n let raw: string;\n let prefix = '';\n try {\n // A session in a folder inside a repository sees that folder's changes, by its own paths.\n prefix = (await git(cwd, ['rev-parse', '--show-prefix'], 5000)).trim();\n raw = await git(cwd, ['status', '--porcelain=v2', '--branch', '-z', '--untracked-files=all', '--', '.']);\n } catch {\n return { repo: false };\n }\n const local = (file: string | undefined) => (file && prefix && file.startsWith(prefix) ? file.slice(prefix.length) : file);\n const out: { repo: true; branch?: string; ahead?: number; behind?: number; files: GitFile[] } = { repo: true, files: [] };\n const entries = raw.split('\\0');\n for (let i = 0; i < entries.length; i += 1) {\n const entry = entries[i]!;\n if (entry.startsWith('# branch.head ')) {\n const head = entry.slice(14);\n if (head !== '(detached)') out.branch = head;\n } else if (entry.startsWith('# branch.ab ')) {\n const [ahead, behind] = entry.slice(12).split(' ');\n out.ahead = Number(ahead?.slice(1)) || 0;\n out.behind = Number(behind?.slice(1)) || 0;\n } else if (entry.startsWith('1 ') || entry.startsWith('2 ') || entry.startsWith('u ')) {\n const parts = entry.split(' ');\n const xy = parts[1] ?? '..';\n const code = xy[0] !== '.' ? xy[0]! : xy[1]!;\n const file = entry.startsWith('1 ') ? parts.slice(8).join(' ') : entry.startsWith('2 ') ? parts.slice(9).join(' ') : parts.slice(10).join(' ');\n const status = entry.startsWith('u ') ? 'conflicted' : KIND[code] ?? 'modified';\n const item: GitFile = { path: local(file)!, status };\n if (entry.startsWith('2 ')) {\n const from = local(entries[i + 1]);\n if (from) item.from = from;\n i += 1;\n }\n out.files.push(item);\n } else if (entry.startsWith('? ')) {\n out.files.push({ path: local(entry.slice(2))!, status: 'untracked' });\n }\n }\n // Line counts against the last commit (or the empty tree before the first one).\n try {\n const base = await git(cwd, ['rev-parse', '--verify', '-q', 'HEAD']).then(() => 'HEAD', () => '4b825dc642cb6eb9a060e54bf8d69288fbee4904');\n const numstat = await git(cwd, ['diff', '--numstat', '--relative', '-z', base]);\n const counts = new Map<string, { added?: number; removed?: number }>();\n const fields = numstat.split('\\0');\n for (let i = 0; i < fields.length; i += 1) {\n const field = fields[i]!;\n if (!field) continue;\n const [added, removed, name] = field.split('\\t');\n // A rename lists its old and new paths in the next two fields.\n const file = name === '' ? fields[(i += 2)] : name;\n if (!file) continue;\n counts.set(file, { ...(added !== '-' ? { added: Number(added) } : {}), ...(removed !== '-' ? { removed: Number(removed) } : {}) });\n }\n for (const file of out.files) Object.assign(file, counts.get(file.path) ?? {});\n } catch {\n // Counts are a nicety.\n }\n // A new file is all added lines; git does not count those for files it does not track yet.\n await Promise.all(out.files.filter((f) => f.status === 'untracked').slice(0, 200).map(async (file) => {\n try {\n const content = await readProjectFile(cwd, file.path);\n if (content.text !== undefined) file.added = content.text.split('\\n').length - (content.text.endsWith('\\n') ? 1 : 0);\n } catch {\n // Unreadable; no count.\n }\n }));\n return out;\n}\n\n/** The diff of one file against the last commit; an untracked file shows as all added. */\nexport async function gitDiff(cwd: string, file: string): Promise<string> {\n if (!(await repositoryOf(cwd))) return '';\n // The file itself may be gone (a deleted file has a diff), but the folder it is in may not lead\n // out of the session's folder through a link.\n const full = inside(cwd, file);\n const [root, parent] = await Promise.all([realpath(cwd), realpath(path.dirname(full)).catch(() => undefined)]);\n if (parent && !within(root, parent)) throw new Error(OUTSIDE);\n let diff = '';\n try {\n diff = await git(cwd, ['diff', 'HEAD', '--', file]);\n } catch {\n diff = '';\n }\n if (!diff) {\n // Untracked (or no commits yet): git diff --no-index exits with 1 when the files differ.\n // `./`: a file named `-` would otherwise be read from stdin.\n diff = await git(cwd, ['diff', '--no-index', '--', '/dev/null', `./${file}`]).catch((error: { stdout?: string }) => error.stdout ?? '');\n }\n return diff.length > MAX_DIFF ? `${diff.slice(0, MAX_DIFF)}\\n\u2026 (diff cut short)` : diff;\n}\n\nconst HIDDEN = new Set(['.git', 'node_modules', '.DS_Store']);\n\n/** One folder of the session's tree: folders first, then files. */\nexport async function listTree(cwd: string, relative: string): Promise<TreeEntry[]> {\n const dir = await insideReal(cwd, relative);\n const names = await readdir(dir, { withFileTypes: true });\n const entries: TreeEntry[] = [];\n for (const entry of names) {\n if (HIDDEN.has(entry.name)) continue;\n const rel = path.join(relative, entry.name);\n if (entry.isDirectory()) entries.push({ name: entry.name, path: rel, dir: true });\n else if (entry.isFile() || entry.isSymbolicLink()) {\n const size = await stat(path.join(dir, entry.name)).then((s) => (s.isDirectory() ? -1 : s.size), () => undefined);\n if (size === -1) entries.push({ name: entry.name, path: rel, dir: true });\n else entries.push({ name: entry.name, path: rel, dir: false, ...(size !== undefined ? { size } : {}) });\n }\n }\n return entries.sort((a, b) => Number(b.dir) - Number(a.dir) || a.name.localeCompare(b.name, undefined, { numeric: true }));\n}\n\nconst IMAGE: Record<string, string> = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml' };\n\n/**\n * A file to read on the phone: text up to half a megabyte, images as data, other binaries named\n * only. A named pipe or a device is not read (`openRegular`): opening one could hold up every\n * file read of the server.\n */\nexport async function readProjectFile(cwd: string, relative: string): Promise<FileContent> {\n const full = await insideReal(cwd, relative);\n const ext = path.extname(full).slice(1).toLowerCase();\n const handle = await openRegular(full);\n try {\n const info = await handle.stat();\n if (IMAGE[ext] && info.size <= 4 * 1024 * 1024) {\n const data = Buffer.alloc(info.size);\n await handle.read(data, 0, info.size, 0);\n return { path: relative, size: info.size, image: `data:${IMAGE[ext]};base64,${data.toString('base64')}` };\n }\n const length = Math.min(info.size, MAX_FILE);\n const data = Buffer.alloc(length);\n await handle.read(data, 0, length, 0);\n if (data.subarray(0, 8000).includes(0)) return { path: relative, size: info.size, binary: true };\n return { path: relative, size: info.size, text: data.toString('utf8'), ...(info.size > MAX_FILE ? { truncated: true } : {}) };\n } finally {\n await handle.close();\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { readFile, realpath, stat } from 'node:fs/promises';\nimport { isIP } from 'node:net';\nimport path from 'node:path';\n\nimport { getConnInfo } from '@hono/node-server/conninfo';\nimport { type Context, Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { compress } from 'hono/compress';\n\nimport pkg from '../../package.json' with { type: 'json' };\nimport { isPermissionMode, START_MODES, startMode } from '../shared/modes.js';\nimport { PREVIEW_CDNS, PREVIEW_POLICY } from '../shared/preview-policy.js';\nimport type { Attachment, ChatMessage, PermissionDecision, RunSettings, SendMode, ServerInfo } from '../shared/protocol.js';\nimport { currentTasks } from '../shared/tasks.js';\nimport { exportMarkdown, fork, messageBefore, remove } from './actions.js';\nimport { setArchived } from './archive.js';\nimport { authMode, beginAttempt, checkPassword, checkToken, cookieName, issueCode, newSessionCookie, proofValid, redeemCode, renewedCookie, signedIn } from './auth.js';\nimport { config } from './config.js';\nimport { sessionsChanged } from './feed.js';\nimport { findUpload, FolderError, listDirs, makeDir, MAX_UPLOAD_BYTES, removeUpload, saveUpload } from './files.js';\nimport { claudeCodeInfo, newerClaude } from './claude-code.js';\nimport { createScratchFolder, isDirectory } from './folders.js';\nimport { defaultMode, knownModels, listCompletions, listModels, planUsage, probeMcpServers } from './models.js';\nimport { searchFiles } from './project-files.js';\nimport { findPhoneAddress } from './phone.js';\nimport { addSubscription, pushKey, removeSubscription } from './push.js';\nimport { ensureRun, getRun, replaceLastTurn, runIn, runState, runStatus, runTasks, sendMessage } from './runner.js';\nimport { runCommand } from './shell.js';\nimport { shownRun } from './stream.js';\nimport { usageLimits } from './usage.js';\nimport { gitDiff, gitStatus, listTree, readProjectFile } from './workspace.js';\nimport { hostAllowed, isLoopback, originAllowed } from './security.js';\nimport { listSummaries, loadMessages, loadPage, loadSubagent, recordedSettings, renameSessionTitle, sentFiles, sessionInfo, sessionSummary } from './sessions.js';\nimport { transcriptImage } from './history.js';\nimport { instance } from './running.js';\nimport { rawEntry, rawImages, transcriptPath } from './transcripts.js';\nimport { folderTrusted, NeedsTrust, rememberChoice, type TrustChoice, trustQuestion } from './trust.js';\n\nexport const app = new Hono();\n\n/**\n * Who is asking, for limiting sign-in attempts: the address of the connection.\n * Behind a proxy on this machine that says so (PELICAN_TRUSTED_PROXY=1), the\n * client the proxy added last to X-Forwarded-For, when that is an IP address.\n * Anyone can write that header, so it is never believed otherwise.\n */\nfunction clientAddress(c: Context): string {\n let remote = 'unknown';\n try {\n remote = getConnInfo(c).remote.address ?? 'unknown';\n } catch {\n // Not served by Node (tests): one bucket for all.\n }\n const address = remote.replace(/^::ffff:/, '');\n if (config.trustedProxy && isLoopback(address)) {\n const forwarded = c.req.header('x-forwarded-for')?.split(',').at(-1)?.trim();\n if (forwarded && isIP(forwarded)) return forwarded;\n }\n return address;\n}\n\nconst secure = (c: { req: { header: (name: string) => string | undefined; url: string } }) =>\n c.req.header('x-forwarded-proto') === 'https' || c.req.url.startsWith('https:');\n\nconst cookieHeader = (c: Context, name: string, value: string, maxAge: number) =>\n `${name}=${value}; Path=/; Max-Age=${maxAge}; HttpOnly; SameSite=Strict${secure(c) ? '; Secure' : ''}`;\n\n/** Answers only to host names that point at this server (DNS rebinding). */\napp.use('*', async (c, next) => {\n if (!hostAllowed(c.req.header('host'))) {\n return c.text('This host name is not allowed. Add it to PELICAN_ALLOWED_HOSTS.', 403);\n }\n await next();\n});\n\n/** What the page loads without fetch, so it cannot mark: an uploaded image, a picture in a message, a download. */\nconst unmarked = (c: Context) => c.req.method === 'GET'\n && (/^\\/api\\/uploads\\/[^/]+$/.test(c.req.path) || /^\\/api\\/sessions\\/[^/]+\\/export$/.test(c.req.path)\n || /^\\/api\\/sessions\\/[^/]+\\/images\\/[^/]+\\/\\d+$/.test(c.req.path));\n\n/** The Origin header as an origin (`null`, garbage and missing are none). */\nfunction originOf(header: string | undefined): string | undefined {\n if (!header || header === 'null') return undefined;\n try {\n return new URL(header).origin;\n } catch {\n return undefined;\n }\n}\n\n/** `pelican phone` asking for a phone code, with a proof made for this very request (auth.ts), not a cookie. */\nconst commandAsks = (c: Context) => c.req.method === 'POST' && c.req.path === '/api/access/code'\n && proofValid(c.req.header('x-pelican-proof'), 'POST', '/api/access/code', instance);\n\napp.use('/api/*', async (c, next) => {\n const origin = c.req.header('origin');\n const parsed = originOf(origin);\n const allowedOrigin = Boolean(parsed && config.allowedOrigins.includes(parsed));\n // Another site's page can make a browser send requests here, reads included, and some reads\n // run programs (git, Claude Code). Browsers say where a request comes from: only Pelican's own\n // page, or a page the config allows, gets in.\n const site = c.req.header('sec-fetch-site');\n if (site && site !== 'same-origin' && site !== 'none' && !allowedOrigin) {\n return c.json({ error: 'Request from another site' }, 403);\n }\n // Pelican's page also marks every request. Another site cannot add a header without asking\n // first (CORS), and Pelican never says yes, so this holds in browsers that send no Sec-Fetch-Site.\n if (!unmarked(c) && c.req.header('x-pelican') !== '1') {\n return c.json({ error: 'Requests must come from Pelican (send the header X-Pelican: 1)' }, 403);\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD'\n && !originAllowed(origin, c.req.header('host'), c.req.header('x-forwarded-host'))) {\n return c.json({ error: 'Request from another site' }, 403);\n }\n if (!c.req.path.startsWith('/api/auth') && !signedIn(c.req.header('cookie'), c.req.header('authorization')) && !commandAsks(c)) {\n return c.json({ error: 'Sign in to continue', signIn: true }, 401);\n }\n // Use keeps a browser signed in: its cookie is replaced by a fresh one (at most once a day).\n const renewed = c.req.path.startsWith('/api/auth/logout') ? undefined : renewedCookie(c.req.header('cookie'));\n if (renewed) c.header('Set-Cookie', cookieHeader(c, renewed.name, renewed.value, renewed.maxAge));\n if (config.demo && c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return c.json({ error: 'This is the demo: nothing runs and nothing changes. Start Pelican without --demo to talk to Claude.' }, 403);\n }\n await next();\n});\n\n// Bodies are small, except an upload; nothing is buffered past these sizes. Only signed-in\n// requests get this far, apart from signing in itself, whose limit is 4 KB.\nconst tooLarge = (c: Context) => c.json({ error: 'Request too large' }, 413);\nconst limits = {\n auth: bodyLimit({ maxSize: 4 * 1024, onError: tooLarge }),\n upload: bodyLimit({ maxSize: MAX_UPLOAD_BYTES + 64 * 1024, onError: tooLarge }),\n json: bodyLimit({ maxSize: 1024 * 1024, onError: tooLarge }),\n};\napp.use('/api/*', (c, next) => (c.req.path.startsWith('/api/auth') ? limits.auth : c.req.path === '/api/uploads' ? limits.upload : limits.json)(c, next));\n\n// Answers are JSON that compresses well (a long session list or a page of messages, ten times\n// over), and the proxies a phone comes through pass them on as they are. Images are left alone.\napp.use('/api/*', compress({ threshold: 1024 }));\n\napp.onError((error, c) => {\n // Starting Claude Code in a folder nobody trusted: the page asks, then sends again with the answer.\n if (error instanceof NeedsTrust) return c.json({ error: error.message, needsTrust: true, brings: error.brings }, 409);\n console.warn('[pelican]', c.req.method, c.req.path, error.message);\n return c.json({ error: error.message }, 500);\n});\n\napp.get('/api/auth', (c) => c.json({\n required: authMode() !== 'none',\n mode: authMode(),\n signedIn: signedIn(c.req.header('cookie'), c.req.header('authorization')),\n // Not a secret: lets `pelican phone` tell this server from another behind an address.\n instance,\n}));\n\napp.post('/api/auth/login', async (c) => {\n const succeeded = beginAttempt(clientAddress(c));\n if (!succeeded) return c.json({ error: 'Too many attempts. Try again in a few minutes.' }, 429);\n const body = await c.req.json<{ password?: unknown; token?: unknown }>().catch(() => ({} as { password?: unknown; token?: unknown }));\n const mode = authMode();\n const ok = mode === 'password' ? typeof body.password === 'string' && (await checkPassword(body.password))\n : mode === 'token' ? typeof body.token === 'string' && checkToken(body.token.trim())\n : false;\n if (!ok) return c.json({ error: mode === 'token' ? 'That is not the access token' : 'Wrong password', mode }, 401);\n succeeded();\n const cookie = newSessionCookie();\n c.header('Set-Cookie', cookieHeader(c, cookie.name, cookie.value, cookie.maxAge));\n return c.json({ ok: true });\n});\n\napp.post('/api/auth/logout', (c) => {\n c.header('Set-Cookie', cookieHeader(c, cookieName(), '', 0));\n // What the browser kept of Pelican (a conversation's pictures) goes too; where the browser does\n // not take this (an http address that is not this computer), the pictures are checked anyway.\n c.header('Clear-Site-Data', '\"cache\"');\n return c.json({ ok: true });\n});\n\n/** A one-time code for the QR code that signs a phone in: good once, for two minutes. */\napp.post('/api/access/code', (c) => {\n if (authMode() === 'none') return c.json({ code: null });\n return c.json({ code: issueCode() });\n});\n\n/** The address a phone uses to reach this Pelican, when one is known: looked up at most once a minute. */\nlet phoneLookup: { at: number; url: Promise<string | null> } | undefined;\napp.get('/api/access/phone', async (c) => {\n if (config.demo) return c.json({ url: null });\n if (!phoneLookup || Date.now() - phoneLookup.at > 60_000) {\n phoneLookup = { at: Date.now(), url: findPhoneAddress(config.port, config.host).then((found) => found.address?.url ?? null, () => null) };\n }\n return c.json({ url: await phoneLookup.url });\n});\n\napp.get('/api/info', async (c) => {\n const info: ServerInfo = { machine: config.machine, home: config.home, version: pkg.version, auth: authMode() !== 'none', demo: config.demo };\n const key = pushKey();\n if (key) info.pushKey = key;\n // Which Claude Code this Pelican runs, for About (and bug reports), and the user's own when newer.\n const code = await claudeCodeInfo();\n const newer = newerClaude();\n if (code.version || code.path) {\n info.claudeCode = { ...(code.version ? { version: code.version } : {}), ...(code.path ? { path: code.path } : {}), ...(newer ? { newer } : {}) };\n }\n return c.json(info);\n});\n\napp.get('/api/sessions', async (c) => c.json({ sessions: await listSummaries(runStatus, runTasks) }));\n\napp.get('/api/sessions/:id', async (c) => {\n const id = c.req.param('id');\n const session = await sessionSummary(id, runStatus, runTasks);\n const run = runState(id);\n if (!session && !run) return c.json({ error: 'No such session' }, 404);\n // The task list needs the whole conversation; the page may only have loaded its end.\n const tasks = currentTasks(await loadMessages(id));\n return c.json({ session: session ?? null, run: run ? shownRun(run) : null, tasks, settings: await recordedSettings(id) });\n});\n\napp.get('/api/sessions/:id/messages', async (c) => {\n const before = c.req.query('before');\n const limit = Math.min(Number(c.req.query('limit') ?? 120) || 120, 500);\n return c.json(await loadPage(c.req.param('id'), before === undefined ? undefined : Number(before), limit));\n});\n\ntype SendBody = { text?: string; attachments?: string[]; settings?: RunSettings; uuid?: string; cwd?: string; scratch?: boolean; mode?: SendMode; trust?: TrustChoice };\n\nconst permissionMode = (value: unknown) => (isPermissionMode(value) ? value : undefined);\n\n/** The settings a request may carry, and only those, each of its own type. */\nfunction cleanSettings(raw: unknown): RunSettings {\n const value = (raw && typeof raw === 'object' ? raw : {}) as Record<string, unknown>;\n const text = (v: unknown, max: number) => (typeof v === 'string' && v.length > 0 && v.length <= max ? v : undefined);\n const out: RunSettings = {};\n const model = text(value.model, 200);\n const effort = text(value.effort, 20);\n const mode = permissionMode(value.permissionMode);\n if (model) out.model = model;\n if (effort) out.effort = effort;\n if (typeof value.fast === 'boolean') out.fast = value.fast;\n if (typeof value.ultracode === 'boolean') out.ultracode = value.ultracode;\n if (mode) out.permissionMode = mode;\n return out;\n}\n\nconst sendMode = (value: unknown): SendMode | undefined => (value === 'steer' || value === 'queue' ? value : undefined);\nconst uuidOf = (value: unknown) => (typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) ? value : undefined);\n\n/** A message body of the right types, or why not: a wrong one is the client's error (400), not ours. */\nfunction sendBody(raw: unknown): SendBody | string {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return 'Not a message';\n const body = raw as Record<string, unknown>;\n if (body.text !== undefined && typeof body.text !== 'string') return 'The text must be a string';\n if (body.attachments !== undefined && (!Array.isArray(body.attachments) || body.attachments.length > 50 || !body.attachments.every((a) => typeof a === 'string'))) return 'Attachments must be upload ids';\n if (body.settings !== undefined && (typeof body.settings !== 'object' || body.settings === null)) return 'Settings must be an object';\n if (body.cwd !== undefined && typeof body.cwd !== 'string') return 'The folder must be a path';\n if (body.scratch !== undefined && typeof body.scratch !== 'boolean') return 'scratch must be true or false';\n if (body.trust !== undefined && body.trust !== 'trusted' && body.trust !== 'user-only') return 'trust must be trusted or user-only';\n return body as SendBody;\n}\n\nasync function attachmentsFrom(ids: string[] | undefined): Promise<Attachment[]> {\n const found = await Promise.all((ids ?? []).map((id) => findUpload(id)));\n return found.filter((a): a is Attachment => Boolean(a));\n}\n\napp.post('/api/sessions', async (c) => {\n const body = sendBody(await c.req.json().catch(() => undefined));\n if (typeof body === 'string') return c.json({ error: body }, 400);\n // A scratch session gets its folder only when its first message is sent, so backing out leaves nothing behind.\n const cwd = body.scratch ? await createScratchFolder() : await checkedFolder(body.cwd);\n if (!cwd) return c.json({ error: 'No such folder' }, 400);\n // A folder Pelican made is trusted; any other that nobody trusted is asked about first, every new\n // session, until the answer is to trust it.\n if (body.scratch) await rememberChoice(cwd, 'trusted');\n else if (body.trust) await rememberChoice(cwd, body.trust);\n else {\n const question = await trustQuestion(cwd);\n if (question) return c.json({ error: 'Trust this folder before Claude Code starts in it.', needsTrust: true, brings: question.brings }, 409);\n }\n const uuid = uuidOf(body.uuid);\n const sessionId = await sendMessage({ cwd }, {\n text: typeof body.text === 'string' ? body.text : '',\n attachments: await attachmentsFrom(body.attachments),\n settings: cleanSettings(body.settings),\n ...(uuid ? { uuid } : {}),\n });\n return c.json({ sessionId });\n});\n\napp.post('/api/sessions/:id/messages', async (c) => {\n const body = sendBody(await c.req.json().catch(() => undefined));\n if (typeof body === 'string') return c.json({ error: body }, 400);\n if (body.trust) {\n const folder = getRun(c.req.param('id'))?.cwd ?? (await sessionInfo(c.req.param('id')))?.cwd;\n if (folder && (await isDirectory(folder))) await rememberChoice(folder, body.trust);\n }\n const uuid = uuidOf(body.uuid);\n const mode = sendMode(body.mode);\n const sessionId = await sendMessage({ sessionId: c.req.param('id') }, {\n text: typeof body.text === 'string' ? body.text : '',\n attachments: await attachmentsFrom(body.attachments),\n settings: cleanSettings(body.settings),\n ...(uuid ? { uuid } : {}),\n ...(mode ? { mode } : {}),\n });\n return c.json({ sessionId });\n});\n\n/** Edits made, and being made, by the id the editor gave them: a retry gets the same result, never a second one. */\ntype Edited = { sessionId: string; inPlace: boolean };\nconst edits = new Map<string, { at: number } & Edited>();\nconst editing = new Map<string, Promise<Edited>>();\n\n/** A prompt the user wrote (text or images), not a tool's result or injected context. */\nconst isPrompt = (m: ChatMessage) => m.role === 'user' && !m.meta && m.blocks.some((b) => b.type === 'text' || b.type === 'image');\n\n/** The images of a prompt, saved as uploads again so the edited prompt carries the ones kept. */\nasync function imagesOf(sessionId: string, uuid: string, keep: unknown): Promise<Attachment[]> {\n const file = await transcriptPath(sessionId);\n if (!file) return [];\n const images = await rawImages(file, uuid);\n const wanted = Array.isArray(keep) ? new Set(keep.filter((i): i is number => Number.isInteger(i))) : new Set(images.map((_, i) => i));\n const kept: Attachment[] = [];\n for (const [i, image] of images.entries()) {\n if (!wanted.has(i) || image.type !== 'base64' || !image.data) continue;\n const ext = image.mediaType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'png';\n kept.push(await saveUpload(new File([Buffer.from(image.data, 'base64')], `image-${i + 1}.${ext}`, { type: image.mediaType })));\n }\n return kept;\n}\n\n/**\n * Edit a prompt and send it again, as one request.\n * - The last prompt is replaced in place, as rewinding does in Claude Code: the session goes on\n * from just before it with the new text (the old turn stays in the transcript, off the line).\n * - An earlier one branches: a copy of the conversation up to just before it gets the new text\n * (the first prompt: a new session in the same folder), and this session stays as it was.\n * A branch is new work: it never starts in Bypass, but in the mode a new session would.\n * If the send fails, a branch and the copied images are removed, so nothing is left behind.\n */\ntype EditFailure = { error: string; status: 404 | 409 };\n\n/** Waits until the Claude of a session it just started is running; a start that fails throws. */\nasync function claudeStarted(sessionId: string): Promise<void> {\n const run = getRun(sessionId);\n if (!run) return;\n let timer: NodeJS.Timeout | undefined;\n try {\n await Promise.race([run.ready, new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 45_000);\n })]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function makeEdit(id: string, before: string, body: { text: string; settings?: unknown; keepImages?: unknown; startMode?: unknown }, key: string): Promise<Edited | EditFailure> {\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return { error: 'The session\u2019s folder is missing', status: 404 };\n if (getRun(id)?.busy) return { error: 'Stop Claude before editing an earlier prompt.', status: 409 };\n const messages = await loadMessages(id);\n const at = messages.findIndex((m) => m.uuid === before);\n if (at < 0) return { error: 'That message is not in this session', status: 404 };\n const previous = at === 0 ? null : messages[at - 1]!.uuid;\n const last = !messages.slice(at + 1).some(isPrompt);\n const file = await transcriptPath(id);\n // In place only for the last prompt, after another one (the first has nothing to go on from),\n // when no background task would be cut off by restarting Claude.\n const entry = last && previous !== null && file && !getRun(id)?.hasBackgroundTasks ? (await rawEntry(file, before))?.parentUuid : undefined;\n const settings = cleanSettings(body.settings);\n if (!entry && settings.permissionMode === 'bypassPermissions') {\n // The mode a new session there starts in: the page's pick in Settings, else Claude Code's own default, else Auto.\n const picked = START_MODES.find((mode) => mode === body.startMode);\n settings.permissionMode = startMode(picked, await defaultMode(info.cwd), knownModels()?.find((m) => m.value === (settings.model ?? 'default')));\n }\n const attachments = await imagesOf(id, before, body.keepImages);\n const message = { text: body.text, attachments, settings, uuid: key };\n let branch: string | undefined;\n let started: string | undefined;\n try {\n if (entry) {\n started = await replaceLastTurn(id, info.cwd, entry, before, message);\n await claudeStarted(started);\n return { sessionId: started, inPlace: true };\n }\n if (previous !== null) branch = await fork(id, previous);\n started = await sendMessage(branch ? { sessionId: branch } : { cwd: info.cwd }, message);\n // Only a Claude that started makes the branch real; one that could not start leaves nothing.\n await claudeStarted(started);\n return { sessionId: started, inPlace: false };\n } catch (error) {\n if (branch) await remove(branch).catch(() => undefined);\n else if (started && !entry) await remove(started).catch(() => undefined);\n await Promise.all(attachments.map((a) => removeUpload(a.id)));\n throw error;\n }\n}\n\n/**\n * Edit a prompt and send it again, as one request.\n * - The last prompt is replaced in place, as rewinding does in Claude Code: the session goes on\n * from just before it with the new text (the old turn stays in the transcript, off the line).\n * - An earlier one branches: a copy of the conversation up to just before it gets the new text\n * (the first prompt: a new session in the same folder), and this session stays as it was.\n * A branch is new work: it never starts in Bypass, but in the mode a new session would.\n * If Claude cannot start, a branch and the copied images are removed, so nothing is left behind.\n * Requests with the same `uuid` share one edit, also while it is still being made.\n */\napp.post('/api/sessions/:id/edit', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json<{ before?: unknown; text?: unknown; settings?: unknown; uuid?: unknown; keepImages?: unknown; startMode?: unknown }>()\n .catch(() => ({}) as Record<string, unknown>);\n const key = uuidOf(body.uuid);\n const before = uuidOf(body.before);\n if (!key || !before || typeof body.text !== 'string' || !body.text.trim()) return c.json({ error: 'Nothing to send' }, 400);\n for (const [k, v] of edits) if (Date.now() - v.at > 10 * 60_000) edits.delete(k);\n const done = edits.get(key);\n if (done) return c.json({ sessionId: done.sessionId, inPlace: done.inPlace });\n // Registered before anything is awaited, so a second request with this id waits for this one.\n let work = editing.get(key) as Promise<Edited | EditFailure> | undefined;\n if (!work) {\n const made = makeEdit(id, before, { text: body.text, settings: body.settings, keepImages: body.keepImages, startMode: body.startMode }, key);\n work = made;\n editing.set(key, made as Promise<Edited>);\n void made.then((result) => {\n if (!('error' in result)) edits.set(key, { at: Date.now(), ...result });\n }, () => undefined).finally(() => editing.delete(key));\n }\n const result = await work;\n if ('error' in result) return c.json({ error: result.error }, result.status);\n return c.json(result);\n});\n\napp.post('/api/sessions/:id/interrupt', async (c) => {\n await getRun(c.req.param('id'))?.interrupt();\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/permissions/:requestId', async (c) => {\n const decision = await c.req.json<PermissionDecision>().catch(() => undefined);\n const raw = (decision ?? {}) as Record<string, unknown>;\n const valid = (raw.behavior === 'allow' || raw.behavior === 'deny')\n && (raw.message === undefined || typeof raw.message === 'string')\n && (raw.remember === undefined || typeof raw.remember === 'boolean')\n && (raw.updatedInput === undefined || (typeof raw.updatedInput === 'object' && raw.updatedInput !== null && !Array.isArray(raw.updatedInput)))\n && (raw.permissionMode === undefined || Boolean(permissionMode(raw.permissionMode)));\n if (!decision || !valid) return c.json({ error: 'Not a decision' }, 400);\n const ok = getRun(c.req.param('id'))?.decide(c.req.param('requestId'), decision) ?? false;\n return ok ? c.json({ ok }) : c.json({ error: 'That request is no longer pending' }, 409);\n});\n\n/** Model, effort, speed, ultracode or mode changed while Claude runs: it switches at its next step. */\napp.post('/api/sessions/:id/settings', async (c) => {\n const body = await c.req.json<{ settings?: unknown }>().catch(() => ({}) as { settings?: unknown });\n if (!body.settings || typeof body.settings !== 'object') return c.json({ error: 'No settings' }, 400);\n await getRun(c.req.param('id'))?.updateSettings(cleanSettings(body.settings));\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/mode', async (c) => {\n const body = await c.req.json<{ permissionMode?: unknown }>();\n const mode = permissionMode(body.permissionMode);\n if (!mode) return c.json({ error: 'No such mode' }, 400);\n await getRun(c.req.param('id'))?.setPermissionMode(mode);\n return c.json({ ok: true });\n});\n\napp.patch('/api/sessions/:id', async (c) => {\n const { title } = await c.req.json<{ title?: string }>();\n if (!title?.trim()) return c.json({ error: 'Title is empty' }, 400);\n await renameSessionTitle(c.req.param('id'), title.trim());\n return c.json({ ok: true });\n});\n\napp.post('/api/sessions/:id/fork', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json<{ upTo?: string; before?: string; title?: string }>().catch(() => ({} as { upTo?: string; before?: string; title?: string }));\n let upTo = body.upTo;\n if (body.before) {\n const previous = await messageBefore(id, body.before);\n if (previous === undefined) return c.json({ error: 'That message is not in this session' }, 404);\n // Nothing comes before the first prompt: the caller starts a new session instead.\n if (previous === null) return c.json({ sessionId: null });\n upTo = previous;\n }\n return c.json({ sessionId: await fork(id, upTo, body.title) });\n});\n\n/** Put a session away from the list, or bring it back; nothing else changes. */\napp.post('/api/sessions/:id/archive', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const body = await c.req.json<{ archived?: unknown }>().catch(() => ({}) as { archived?: unknown });\n if (!id || typeof body.archived !== 'boolean') return c.json({ error: 'Say archived: true or false' }, 400);\n await setArchived(id, body.archived);\n sessionsChanged();\n return c.json({ ok: true });\n});\n\napp.delete('/api/sessions/:id', async (c) => {\n const id = c.req.param('id');\n if (getRun(id)?.busy) return c.json({ error: 'Stop Claude in this session before deleting it.' }, 409);\n getRun(id)?.close();\n await remove(id);\n return c.json({ ok: true });\n});\n\napp.get('/api/sessions/:id/export', async (c) => {\n const { title, markdown } = await exportMarkdown(c.req.param('id'));\n const name = `${title.replace(/[^\\p{L}\\p{N} _-]+/gu, '').trim().slice(0, 60) || 'session'}.md`;\n return c.body(markdown, 200, {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(name)}`,\n 'X-Content-Type-Options': 'nosniff',\n });\n});\n\napp.get('/api/models', async (c) => c.json(await listModels()));\n\napp.get('/api/commands', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ commands: [], agents: [] });\n // A Claude running there knows its list as it is now, and asking it starts nothing.\n const live = await runIn(cwd)?.completions().catch(() => undefined);\n return c.json(live ?? await listCompletions(cwd));\n});\n\n/** What a new session in a folder starts with, from the user's Claude Code settings (no folder: a scratch session). */\napp.get('/api/defaults', async (c) => {\n const asked = c.req.query('cwd');\n const cwd = asked ? await checkedFolder(asked) : undefined;\n if (asked && !cwd) return c.json({ error: 'No such folder' }, 404);\n return c.json({ permissionMode: (await defaultMode(cwd)) ?? null });\n});\n\n/** What `/usage` shows in Claude Code: asked of claude.ai when Settings opens, kept a minute. */\napp.get('/api/usage/plan', async (c) => c.json({ plan: await planUsage() }));\n\napp.get('/api/usage', (c) => c.json({\n limits: config.demo\n ? [\n { type: 'five_hour', status: 'allowed', utilization: 0.42, resetsAt: Date.now() + 2.4 * 3600_000, at: Date.now() },\n { type: 'seven_day', status: 'allowed', utilization: 0.18, resetsAt: Date.now() + 3.5 * 86400_000, at: Date.now() },\n ]\n : usageLimits(),\n}));\n\n/** The folder a workspace request is about: the session's own, which must exist. */\n/** Whether a path is inside the demo's own folder (the demo never shows anything else). */\nasync function inDemo(dir: string): Promise<boolean> {\n try {\n const [real, root] = await Promise.all([realpath(dir), realpath(config.home)]);\n return real === root || real.startsWith(`${root}${path.sep}`);\n } catch {\n return false;\n }\n}\n\n/** A folder named in a request: an existing absolute path, and in the demo only the demo's own. */\nasync function checkedFolder(cwd: string | undefined): Promise<string | undefined> {\n if (!cwd || !path.isAbsolute(cwd) || !(await isDirectory(cwd))) return undefined;\n if (config.demo && !(await inDemo(cwd))) return undefined;\n return cwd;\n}\n\nconst folderOf = (c: Context) => checkedFolder(c.req.query('cwd'));\n\n/** Whether a folder is in a git repository, by its `.git` and its parents' (this runs nothing). */\nasync function insideRepository(cwd: string): Promise<boolean> {\n for (let dir = path.resolve(cwd); ; dir = path.dirname(dir)) {\n if (await stat(path.join(dir, '.git')).then(() => true, () => false)) return true;\n if (path.dirname(dir) === dir) return false;\n }\n}\n\n/** Git runs only in a trusted folder (trust.ts): a folder you are only shown runs nothing of its own. */\nconst gitAllowed = (cwd: string) => folderTrusted(cwd);\n\napp.get('/api/git', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ error: 'No such folder' }, 404);\n if (!(await gitAllowed(cwd))) return c.json(await insideRepository(cwd) ? { repo: false, untrusted: true } : { repo: false });\n return c.json(await gitStatus(cwd));\n});\n\napp.get('/api/git/diff', async (c) => {\n const cwd = await folderOf(c);\n const file = c.req.query('path');\n if (!cwd || !file) return c.json({ error: 'No such file' }, 404);\n if (!(await gitAllowed(cwd))) return c.json({ diff: '' });\n return c.json({ diff: await gitDiff(cwd, file) });\n});\n\napp.get('/api/tree', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ error: 'No such folder' }, 404);\n return c.json({ entries: await listTree(cwd, c.req.query('path') ?? '') });\n});\n\napp.get('/api/file', async (c) => {\n const cwd = await folderOf(c);\n const file = c.req.query('path');\n if (!cwd || !file) return c.json({ error: 'No such file' }, 404);\n return c.json(await readProjectFile(cwd, file));\n});\n\napp.post('/api/sessions/:id/shell', async (c) => {\n const id = c.req.param('id');\n const { command } = await c.req.json<{ command?: string }>().catch(() => ({ command: undefined }));\n if (!command?.trim()) return c.json({ error: 'No command' }, 400);\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return c.json({ error: 'The session\u2019s folder is missing' }, 404);\n const result = await runCommand(info.cwd, command.trim());\n // Into the conversation without a turn: Claude reads it with the next message.\n await (await ensureRun(id)).appendShell(result);\n return c.json(result);\n});\n\napp.post('/api/sessions/:id/rewind', async (c) => {\n const { uuid, dryRun } = await c.req.json<{ uuid?: string; dryRun?: boolean }>().catch(() => ({ uuid: undefined, dryRun: undefined }));\n if (!uuid) return c.json({ error: 'Which prompt?' }, 400);\n const run = await ensureRun(c.req.param('id'));\n if (run.busy) return c.json({ error: 'Stop Claude before rewinding files.' }, 409);\n return c.json(await run.rewind(uuid, dryRun !== false));\n});\n\napp.get('/api/sessions/:id/mcp', async (c) => {\n const id = c.req.param('id');\n const run = getRun(id);\n if (run) return c.json({ servers: await run.mcpServers(), live: true });\n const info = await sessionInfo(id);\n if (!info?.cwd || !(await isDirectory(info.cwd))) return c.json({ servers: [], live: false });\n return c.json({ servers: await probeMcpServers(info.cwd), live: false });\n});\n\napp.post('/api/sessions/:id/mcp/:name', async (c) => {\n const run = getRun(c.req.param('id'));\n if (!run) return c.json({ error: 'Claude is not running in this session' }, 409);\n const change = await c.req.json<{ enabled?: boolean; reconnect?: boolean }>().catch(() => ({}));\n await run.setMcpServer(c.req.param('name'), change);\n return c.json({ servers: await run.mcpServers() });\n});\n\napp.post('/api/sessions/:id/tasks/:task/stop', async (c) => {\n await getRun(c.req.param('id'))?.stopTask(c.req.param('task'));\n return c.json({ ok: true });\n});\n\n/** The end of what a background command printed, read while it runs. */\napp.get('/api/sessions/:id/tasks/:task/output', async (c) => {\n const run = getRun(c.req.param('id'));\n if (!run) return c.json({ error: 'Claude is not running in this session' }, 409);\n return c.json(await run.taskOutput(c.req.param('task')));\n});\n\n/** Takes back a prompt waiting for the turn to end, before Claude gets it. */\napp.delete('/api/sessions/:id/queued/:uuid', (c) => {\n const ok = getRun(c.req.param('id'))?.unqueue(c.req.param('uuid')) ?? false;\n return ok ? c.json({ ok }) : c.json({ error: 'That message is no longer waiting' }, 409);\n});\n\napp.get('/api/sessions/:id/sent', async (c) => {\n const file = c.req.query('path') ?? '';\n if (!file || !(await sentFiles(c.req.param('id'))).has(file)) return c.json({ error: 'Not a file Claude sent in this session' }, 404);\n try {\n return c.json(await readProjectFile(path.dirname(file), path.basename(file)));\n } catch {\n return c.json({ error: 'The file is gone' }, 404);\n }\n});\n\napp.get('/api/sessions/:id/agents/:agent', async (c) => {\n return c.json({ messages: await loadSubagent(c.req.param('id'), c.req.param('agent')) });\n});\n\napp.get('/api/files', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ files: [] });\n return c.json({ files: await searchFiles(cwd, c.req.query('q') ?? '') });\n});\n\n/**\n * Folders to start a new session in: those of recent sessions, without temp\n * and scratch folders and without folders that are gone. Two folders with the\n * same name are told apart by their parent.\n */\napp.get('/api/projects', async (c) => {\n const seen = new Map<string, { path: string; name: string; lastActivity: number; sessions: number }>();\n for (const s of await listSummaries(runStatus)) {\n if (!s.cwd || s.scratch || s.temp) continue;\n const entry = seen.get(s.cwd);\n if (entry) entry.sessions += 1;\n else seen.set(s.cwd, { path: s.cwd, name: s.project, lastActivity: s.lastActivity, sessions: 1 });\n }\n const existing = (await Promise.all([...seen.values()].map(async (p) => ((await isDirectory(p.path)) ? p : undefined))))\n .filter((p): p is NonNullable<typeof p> => Boolean(p));\n const counts = new Map<string, number>();\n for (const p of existing) counts.set(p.name, (counts.get(p.name) ?? 0) + 1);\n for (const p of existing) {\n if ((counts.get(p.name) ?? 0) > 1) p.name = `${path.basename(path.dirname(p.path))}/${p.name}`;\n }\n return c.json({ projects: existing });\n});\n\napp.get('/api/dirs', async (c) => {\n const asked = c.req.query('path');\n if (config.demo && asked && !(await inDemo(asked))) return c.json({ error: 'Not part of the demo' }, 404);\n try {\n return c.json(await listDirs(asked, c.req.query('hidden') === '1'));\n } catch (error) {\n return c.json({ error: (error as Error).message }, 400);\n }\n});\n\n// A new folder to start a session in (the folder browser's New folder). The demo changes nothing.\napp.post('/api/dirs', async (c) => {\n const body = await c.req.json<{ parent?: unknown; name?: unknown }>().catch(() => ({}) as { parent?: unknown; name?: unknown });\n if (typeof body.parent !== 'string' || !path.isAbsolute(body.parent) || typeof body.name !== 'string') return c.json({ error: 'Say where, and the name' }, 400);\n try {\n return c.json({ path: await makeDir(body.parent, body.name) });\n } catch (error) {\n if (error instanceof FolderError) return c.json({ error: error.message }, error.status);\n throw error;\n }\n});\n\napp.post('/api/uploads', async (c) => {\n const body = await c.req.parseBody();\n const file = body.file;\n if (!(file instanceof File)) return c.json({ error: 'No file' }, 400);\n return c.json({ attachment: await saveUpload(file) });\n});\n\n/** What a file the page loads by address may do: show as itself, nothing more, and only here. */\nconst INERT = {\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Security-Policy': \"sandbox; default-src 'none'; img-src 'self' data:; frame-ancestors 'self'\",\n 'X-Frame-Options': 'SAMEORIGIN',\n 'Cross-Origin-Resource-Policy': 'same-origin',\n};\n\n/**\n * Pictures and files of a conversation: a browser keeps them, but asks the server each time it shows\n * one, so a browser signed out (or whose sign-in was reset) is refused instead of showing its copy.\n * The answer to a browser that has the very one is short: no picture again.\n */\nconst KEPT_ASKING = 'private, no-cache';\nconst unchanged = (c: Context, tag: string) => (c.req.header('if-none-match') ?? '').split(',').some((t) => t.trim().replace(/^W\\//, '') === tag);\n\napp.get('/api/uploads/:id', async (c) => {\n const upload = await findUpload(c.req.param('id'));\n if (!upload) return c.notFound();\n // An upload never changes under its id.\n const tag = `\"${upload.id}\"`;\n if (unchanged(c, tag)) return c.body(null, 304, { ETag: tag, 'Cache-Control': KEPT_ASKING });\n const data = await readFile(upload.path).catch(() => undefined);\n if (!data) return c.notFound();\n // Shown in the page only as an image; anything else downloads. Either way it runs nothing:\n // no sniffing, no scripts, no frames.\n const image = upload.mime.startsWith('image/') && upload.mime !== 'image/svg+xml';\n return c.body(new Uint8Array(data), 200, {\n 'Content-Type': upload.mime,\n 'Cache-Control': KEPT_ASKING,\n ETag: tag,\n ...INERT,\n ...(image ? {} : { 'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(upload.name)}` }),\n });\n});\n\n/** The picture types Claude takes; nothing else a transcript holds is sent as an image. */\nconst PICTURES = new Set(['image/png', 'image/jpeg', 'image/gif', 'image/webp']);\n\n/**\n * A picture a message holds (a screenshot, an image sent with a prompt): pages carry its address\n * instead of the data, so a page of messages stays small and a picture loads only when shown.\n * The same message and position always hold the same picture: its address is its version, so a\n * browser that has it is told so without the transcript being read.\n */\napp.get('/api/sessions/:id/images/:uuid/:n', async (c) => {\n const n = Number(c.req.param('n'));\n const file = await transcriptPath(c.req.param('id'));\n if (!file || !Number.isSafeInteger(n)) return c.json({ error: 'No such picture' }, 404);\n const tag = `\"${createHash('sha256').update(`${c.req.param('id')}\\0${c.req.param('uuid')}\\0${n}`).digest('base64url').slice(0, 27)}\"`;\n if (unchanged(c, tag)) return c.body(null, 304, { ETag: tag, 'Cache-Control': KEPT_ASKING });\n const image = await transcriptImage(file, c.req.param('uuid'), n);\n if (!image || !PICTURES.has(image.mediaType)) return c.json({ error: 'No such picture' }, 404);\n return c.body(new Uint8Array(image.data), 200, {\n 'Content-Type': image.mediaType,\n 'Cache-Control': KEPT_ASKING,\n ETag: tag,\n ...INERT,\n });\n});\n\napp.get('/api/push/key', (c) => c.json({ key: pushKey() ?? null }));\n\n/** A push subscription as browsers make them: an https endpoint, a P-256 key, a 16-byte secret. */\nfunction validSubscription(value: unknown): value is { endpoint: string; keys: { p256dh: string; auth: string } } {\n const { endpoint, keys } = (value ?? {}) as { endpoint?: unknown; keys?: { p256dh?: unknown; auth?: unknown } };\n const bytes = (text: unknown) => (typeof text === 'string' && /^[\\w-]+=*$/.test(text) ? Buffer.from(text, 'base64url').length : -1);\n return typeof endpoint === 'string' && endpoint.length <= 2048 && endpoint.startsWith('https://')\n && bytes(keys?.p256dh) === 65 && bytes(keys?.auth) === 16;\n}\n\nconst pageUrl = (value: unknown) => typeof value === 'string' && value.length <= 2048 && /^https?:\\/\\//.test(value);\n\napp.post('/api/push/subscribe', async (c) => {\n const body = await c.req.json<{ subscription?: unknown; openUrl?: unknown }>().catch(() => ({}) as { subscription?: unknown; openUrl?: unknown });\n if (!validSubscription(body.subscription)) return c.json({ error: 'Not a push subscription' }, 400);\n const { endpoint, keys } = body.subscription;\n await addSubscription({ endpoint, keys: { p256dh: keys.p256dh, auth: keys.auth }, ...(pageUrl(body.openUrl) ? { openUrl: body.openUrl as string } : {}) });\n return c.json({ ok: true });\n});\n\napp.post('/api/push/unsubscribe', async (c) => {\n const { endpoint } = await c.req.json<{ endpoint?: unknown }>().catch(() => ({ endpoint: undefined }));\n if (typeof endpoint !== 'string') return c.json({ error: 'No endpoint' }, 400);\n await removeSubscription(endpoint);\n return c.json({ ok: true });\n});\n\napp.all('/api/*', (c) => c.json({ error: 'Not found' }, 404));\n\nconst TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml', '.png': 'image/png', '.ico': 'image/x-icon', '.webmanifest': 'application/manifest+json',\n '.json': 'application/json', '.woff2': 'font/woff2', '.txt': 'text/plain; charset=utf-8',\n};\n\nconst ANCESTORS = `frame-ancestors 'self'${config.frameAncestors.map((o) => ` ${o}`).join('')}`;\nconst FRAMING: Record<string, string> = config.frameAncestors.length === 0 ? { 'X-Frame-Options': 'SAMEORIGIN' } : {};\n\n/** A host name as browsers send it, and nothing that could end a directive. */\nconst plainHost = (value: string | undefined) => (value && /^([a-z0-9.-]+|\\[[0-9a-f:.]+\\])(:\\d+)?$/i.test(value) ? value : undefined);\n\n/**\n * The app's own page:\n * - Only Pelican's own origin, and pages the config names, may show it in a frame: any other page\n * could lay its own buttons over Pelican's and have you approve something (clickjacking).\n * - Scripts only from Pelican, and requests only to Pelican: were something ever to slip HTML into\n * the page, it could neither run nor send anything (and here a script could run commands).\n * - Images and media come only from Pelican: a picture in Claude's reply, or in a page it wrote,\n * could otherwise carry what is in the conversation to another server just by loading. A still\n * preview inherits this, on top of its own policy; the styles and fonts it may load from the\n * public CDNs are allowed here for that reason only (Preview.tsx).\n */\nfunction pagePolicy(c: Context): string {\n // The page's WebSocket, by the names it reaches Pelican at (older Safari does not count ws: as 'self').\n const hosts = [...new Set([plainHost(c.req.header('host')), plainHost(c.req.header('x-forwarded-host')?.split(',')[0]?.trim())])].filter(Boolean);\n return [\n ANCESTORS,\n \"default-src 'self'\",\n \"script-src 'self'\",\n `style-src 'self' 'unsafe-inline' https://fonts.googleapis.com ${PREVIEW_CDNS}`,\n `font-src 'self' data: https://fonts.gstatic.com ${PREVIEW_CDNS}`,\n \"img-src 'self' data: blob:\",\n \"media-src 'self' data: blob:\",\n `connect-src 'self'${hosts.map((h) => ` ws://${h} wss://${h}`).join('')}`,\n \"frame-src 'self'\",\n \"worker-src 'self'\",\n \"manifest-src 'self'\",\n \"object-src 'none'\",\n \"base-uri 'self'\",\n \"form-action 'self'\",\n ].join('; ');\n}\n\n/** The document a preview runs in once its scripts may run: the preview policy, as a header that stays. */\nconst RUNNING_PREVIEW = `${PREVIEW_POLICY}; ${ANCESTORS}`;\n\n/** Compressed copies the build wrote next to each file, best first. */\nconst ENCODINGS = [['br', '.br'], ['gzip', '.gz']] as const;\n\n/** The encodings a request takes (`Accept-Encoding`), without those it refuses with q=0. */\nfunction acceptedEncodings(header: string | undefined): Set<string> {\n const accepted = new Set<string>();\n for (const part of (header ?? '').toLowerCase().split(',')) {\n const [name, ...params] = part.split(';').map((p) => p.trim());\n const q = params.find((p) => p.startsWith('q='));\n if (name && !(q && Number(q.slice(2)) <= 0)) accepted.add(name);\n }\n return accepted;\n}\n\n/** Hashed assets never change under their name: kept in memory once read, each copy by its path. */\nconst assetCache = new Map<string, Buffer>();\n\nasync function readStatic(file: string, hashed: boolean): Promise<Buffer | undefined> {\n const cached = assetCache.get(file);\n if (cached) return cached;\n const data = await readFile(file).catch(() => undefined);\n if (data && hashed) assetCache.set(file, data);\n return data;\n}\n\n/** The web app. Every URL in it is relative, so it works under any path a proxy mounts it at. */\napp.get('/*', async (c) => {\n if (!config.webDir) return c.text('The web app is not built. Run `npm run build`, or use `npm run dev`.', 503);\n const root = config.webDir;\n let pathname: string;\n try {\n pathname = decodeURIComponent(new URL(c.req.url).pathname);\n } catch {\n return c.text('Bad path', 400);\n }\n // Opening the link Pelican printed (\u2026/?token=\u2026), or the QR code from Settings (\u2026/?code=\u2026),\n // signs this browser in, then drops the secret from the address.\n const token = c.req.query('token');\n const code = c.req.query('code');\n if (token !== undefined || code !== undefined) {\n const url = new URL(c.req.url);\n url.searchParams.delete('token');\n url.searchParams.delete('code');\n url.searchParams.delete('signin');\n const ok = token !== undefined ? checkToken(token) : redeemCode(code);\n // The sign-in page says why a link or a code did not work (it carries no secret), unless this\n // browser is signed in anyway.\n if (!ok && !signedIn(c.req.header('cookie'))) url.searchParams.set('signin', token !== undefined ? 'link' : 'code');\n // Relative to where the page is, so it works under a proxy's path prefix, and can never\n // name another site (`//other.example/` would).\n const location = `./${url.pathname.split('/').pop() ?? ''}${url.search}`;\n if (!ok) return c.body(null, 302, { Location: location, 'Cache-Control': 'no-store' });\n const cookie = newSessionCookie();\n return c.body(null, 302, { Location: location, 'Set-Cookie': cookieHeader(c, cookie.name, cookie.value, cookie.maxAge), 'Cache-Control': 'no-store' });\n }\n const requested = path.normalize(pathname).replace(/^(\\.\\.[/\\\\])+/, '');\n let file = path.join(root, requested);\n if (!file.startsWith(root) || requested === '/' || !path.extname(file)) file = path.join(root, 'index.html');\n const ext = path.extname(file);\n const hashed = file.includes(`${path.sep}assets${path.sep}`);\n const accepted = acceptedEncodings(c.req.header('accept-encoding'));\n let encoding: string | undefined;\n let data: Buffer | undefined;\n for (const [name, suffix] of ENCODINGS) {\n if (!accepted.has(name) && !accepted.has('*')) continue;\n data = await readStatic(`${file}${suffix}`, hashed);\n if (data) {\n encoding = name;\n break;\n }\n }\n data ??= await readStatic(file, hashed);\n if (!data) return c.notFound();\n return c.body(new Uint8Array(data), 200, {\n 'Content-Type': TYPES[ext] ?? 'application/octet-stream',\n 'Cache-Control': hashed ? 'public, max-age=31536000, immutable' : 'no-cache',\n ...(encoding ? { 'Content-Encoding': encoding } : {}),\n Vary: 'Accept-Encoding',\n 'X-Content-Type-Options': 'nosniff',\n 'Referrer-Policy': 'same-origin',\n 'Content-Security-Policy': file === path.join(root, 'preview.html') ? RUNNING_PREVIEW : pagePolicy(c),\n ...FRAMING,\n });\n});\n", "import { config } from './config.js';\nimport { sessionsChanged } from './feed.js';\nimport { type LiveProcess, liveProcesses, registry } from './live.js';\nimport { notify } from './push.js';\nimport { sessionInfo, sessionTitle } from './sessions.js';\n\n/**\n * How long Claude waits in another app before the phone hears of it. Someone at the keyboard\n * usually answers first; Claude Code itself waits a few seconds before its own notification.\n */\nexport const NOTIFY_AFTER_MS = 20_000;\nconst POLL_MS = 5_000;\n\n/** Sessions waiting for an answer in another app, from when, and whether the phone was told. */\nconst waits = new Map<string, { since: number; told: boolean }>();\n\n/** Claude Code's words for what it waits for, said the way a notification says it. */\nfunction what(waiting: string): string {\n if (/permission|sandbox|worker/.test(waiting)) return 'is asking for permission';\n if (/input/.test(waiting)) return 'needs your input';\n return 'is waiting for you';\n}\n\nasync function tell(sessionId: string, process: LiveProcess): Promise<void> {\n const info = await sessionInfo(sessionId).catch(() => undefined);\n await notify({\n title: (info && sessionTitle(info)) || 'Claude Code',\n body: `Claude ${what(process.waiting ?? '')} in ${process.app ?? 'another app'}`,\n sessionId,\n // The same tag as this app's own questions: one notification per session, the latest.\n tag: `${sessionId}:ask`,\n });\n}\n\n/**\n * Looks at what other apps' sessions are doing: one that starts or stops waiting for an answer\n * changes the lists at once, and one still waiting after a while sends one notification.\n */\nexport async function checkWaiting(now = Date.now()): Promise<void> {\n // Reading the registry is cheap; asking which processes are whose (ps) only when something waits.\n if (waits.size === 0 && !(await registry()).some((entry) => entry.status === 'waiting')) return;\n const live = await liveProcesses();\n let changed = false;\n for (const [sessionId, process] of live) {\n if (!process.waiting) continue;\n let wait = waits.get(sessionId);\n if (!wait) {\n wait = { since: Math.min(process.waitingSince ?? now, now), told: false };\n waits.set(sessionId, wait);\n changed = true;\n }\n if (!wait.told && now - wait.since >= NOTIFY_AFTER_MS) {\n wait.told = true;\n void tell(sessionId, process).catch((error: Error) => console.warn('[pelican] could not notify', error.message));\n }\n }\n for (const sessionId of [...waits.keys()]) {\n if (live.get(sessionId)?.waiting) continue;\n // Answered, or the app closed: the next wait is told of again.\n waits.delete(sessionId);\n changed = true;\n }\n if (changed) sessionsChanged();\n}\n\n/** Keeps looking every few seconds while the server runs; returns how to stop. */\nexport function watchWaiting(): () => void {\n if (config.demo) return () => {};\n let checking = false;\n const timer = setInterval(() => {\n if (checking) return;\n checking = true;\n void checkWaiting().catch(() => undefined).finally(() => {\n checking = false;\n });\n }, POLL_MS);\n timer.unref();\n return () => clearInterval(timer);\n}\n", "import type { IncomingMessage } from 'node:http';\nimport type { AddressInfo } from 'node:net';\n\nimport { serve } from '@hono/node-server';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nimport type { ClientEvent, RunState, ServerEvent } from '../shared/protocol.js';\nimport { app } from './app.js';\nimport { loadAuth, signedIn } from './auth.js';\nimport { config } from './config.js';\nimport { connect, subscribe } from './feed.js';\nimport { keepDays, sweepUploads } from './files.js';\nimport { initPush } from './push.js';\nimport { closeAll, runState } from './runner.js';\nimport { hostAllowed, originAllowed } from './security.js';\nimport { RunChannel } from './stream.js';\nimport { watchWaiting } from './waiting.js';\n\nconst SESSION_ID = /^[\\w-]{1,100}$/;\n/** A browser follows a handful of sessions at once; more from one socket is not a browser. */\nconst MAX_SUBSCRIPTIONS = 64;\n/** Proxies close idle sockets (Cloudflare after 100 s); a ping this often keeps them open and finds dead ones. */\nconst HEARTBEAT_MS = 25_000;\n/**\n * Unsent bytes past which a socket gets no more run updates until it catches up (a phone on a slow\n * link): each update replaces the last, so only the newest is sent once the backlog is gone.\n */\nconst MAX_BUFFERED = 256 * 1024;\nconst DAY_MS = 24 * 3600_000;\n\n/** A client event, or undefined for anything else. */\nfunction clientEvent(text: string): ClientEvent | undefined {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (!value || typeof value !== 'object') return undefined;\n const { type, sessionId } = value as Record<string, unknown>;\n if ((type !== 'subscribe' && type !== 'unsubscribe') || typeof sessionId !== 'string' || !SESSION_ID.test(sessionId)) return undefined;\n return { type, sessionId };\n}\n\nlet guarded = false;\n\n/**\n * Work nobody waits for (a poll, a notification) must not take the server down when it fails:\n * Node would exit, and every turn Claude is running with it. It is said in the log instead.\n * A thrown exception stays fatal: state may be broken then.\n */\nfunction guardRejections(): void {\n if (guarded) return;\n guarded = true;\n process.on('unhandledRejection', (error) => {\n console.warn('[pelican] unexpected error:', error instanceof Error ? (error.stack ?? error.message) : error);\n });\n}\n\n/** The path of a request target, without parsing it: a malformed target must not throw. */\nconst pathOf = (url: string | undefined) => (url ?? '/').split('?')[0] ?? '/';\n\n/**\n * Starts the HTTP server and the WebSocket that streams sessions. Resolves once it listens.\n * Port 0 takes any free port; `url` says which.\n */\nexport async function startServer(): Promise<{ url: string; close: () => Promise<void> }> {\n guardRejections();\n await loadAuth();\n await initPush();\n\n // Client events are a few hundred bytes; nothing bigger is read. What goes out is mostly JSON,\n // compressed: Tailscale Serve and SSH tunnels pass it on as it is.\n const wss = new WebSocketServer({ noServer: true, maxPayload: 64 * 1024, perMessageDeflate: { threshold: 1024 } });\n\n const { url, server } = await new Promise<{ url: string; server: ReturnType<typeof serve> }>((resolve, reject) => {\n const server = serve({ fetch: app.fetch, hostname: config.host, port: config.port }, (info: AddressInfo) => {\n const host = info.family === 'IPv6' ? `[${info.address}]` : info.address;\n resolve({ url: `http://${host}:${info.port}/`, server });\n });\n server.on('error', reject);\n });\n\n server.on('upgrade', (req: IncomingMessage, socket, head) => {\n // A connection that breaks before the handshake ends here, not in an unheard 'error'.\n socket.on('error', () => socket.destroy());\n try {\n const forwarded = req.headers['x-forwarded-host'];\n // The same checks as every request: a known Host, a page of Pelican's own, a signed-in browser.\n const ok = pathOf(req.url).endsWith('/api/ws')\n && hostAllowed(req.headers.host)\n && originAllowed(req.headers.origin, req.headers.host, Array.isArray(forwarded) ? forwarded[0] : forwarded)\n && signedIn(req.headers.cookie, req.headers.authorization);\n if (!ok) {\n socket.destroy();\n return;\n }\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n } catch {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws: WebSocket) => {\n const send = (event: ServerEvent) => {\n if (ws.readyState === ws.OPEN) ws.send(JSON.stringify(event));\n };\n const disconnect = connect(send);\n const subscriptions = new Map<string, () => void>();\n const channels = new Map<string, RunChannel>();\n /** Sessions whose run updates were held back while the socket was full. */\n const behind = new Set<string>();\n let catchingUp: NodeJS.Timeout | undefined;\n\n const sendRun = (sessionId: string, state: RunState | null) => {\n const channel = channels.get(sessionId);\n if (!channel || ws.readyState !== ws.OPEN) return;\n if (ws.bufferedAmount > MAX_BUFFERED) {\n channel.reset();\n behind.add(sessionId);\n catchingUp ??= setInterval(() => {\n if (ws.readyState !== ws.OPEN || ws.bufferedAmount > MAX_BUFFERED / 2) return;\n clearInterval(catchingUp);\n catchingUp = undefined;\n for (const id of [...behind]) {\n behind.delete(id);\n sendRun(id, runState(id) ?? null);\n }\n }, 250);\n return;\n }\n const event = channel.next(state);\n if (event) send(event);\n };\n\n // A socket that does not answer a ping is gone (a phone that changed networks, a closed lid):\n // it is dropped with its subscriptions, instead of being polled for until TCP gives up. A ping\n // waits behind what was sent before it, though: a phone on a slow link still reading pictures\n // is kept while its backlog goes down. That shows only once a whole message has gone out, and\n // one large message can take longer than a heartbeat, so a backlog gets a second heartbeat.\n // Pages cannot see pings, so a tick tells them the socket still works.\n let answered = true;\n /** What was still to send at the last heartbeat, and heartbeats since that last went down. */\n let backlog = 0;\n let stalled = 0;\n ws.on('pong', () => {\n answered = true;\n });\n const heartbeat = setInterval(() => {\n const left = ws.bufferedAmount;\n if (answered) {\n answered = false;\n backlog = left;\n stalled = 0;\n ws.ping();\n send({ type: 'tick' });\n return;\n }\n stalled = left < backlog ? 0 : stalled + 1;\n backlog = left;\n if (stalled > (left > 0 ? 1 : 0)) ws.terminate();\n }, HEARTBEAT_MS);\n // A frame too large or malformed closes this socket; unheard, the error would stop the server.\n ws.on('error', () => ws.terminate());\n\n ws.on('message', (data) => {\n const event = clientEvent(String(data));\n if (!event) return;\n const id = event.sessionId;\n if (event.type === 'subscribe') {\n if (!subscriptions.has(id)) {\n if (subscriptions.size >= MAX_SUBSCRIPTIONS) return;\n channels.set(id, new RunChannel(id));\n subscriptions.set(id, subscribe(id, (update) => (update.type === 'run' ? sendRun(id, update.state) : send(update))));\n }\n // Every subscribe is answered with the run as it is now, or with none, also a repeated\n // one: a page that comes back after a while asks again and is set right, whatever it missed.\n channels.get(id)!.reset();\n sendRun(id, runState(id) ?? null);\n } else {\n subscriptions.get(id)?.();\n subscriptions.delete(id);\n channels.delete(id);\n behind.delete(id);\n }\n });\n\n ws.on('close', () => {\n clearInterval(heartbeat);\n clearInterval(catchingUp);\n disconnect();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n });\n });\n\n const stopWatching = watchWaiting();\n\n // Every attachment is saved for Claude to read; they go when Claude Code lets go of sessions.\n const sweep = () => void keepDays().then((days) => sweepUploads(days * DAY_MS)).catch(() => undefined);\n sweep();\n const sweeping = setInterval(sweep, DAY_MS);\n sweeping.unref();\n\n const shutdown = () => {\n closeAll();\n server.close();\n setTimeout(() => process.exit(0), 500).unref();\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n const close = async () => {\n stopWatching();\n clearInterval(sweeping);\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n for (const client of wss.clients) client.terminate();\n wss.close();\n await new Promise<void>((resolve) => server.close(() => resolve()));\n };\n return { url, close };\n}\n", "import { type ChildProcess, spawn } from 'node:child_process';\n\n/**\n * Keeps the computer from sleeping while Claude works, so a turn started from the phone is not cut\n * off when the computer would idle to sleep, and the phone finds Pelican when it comes back. The\n * system's own tools hold the assertion and release it when Pelican exits, even if it crashes:\n * `caffeinate -i -w <pid>` on macOS, `systemd-inhibit` around `tail --pid` on Linux. A closed\n * laptop lid still sleeps, unless the computer is on power with a display attached.\n */\n\nexport type Holder = { command: string; args: string[] };\n\n/** The command that holds the computer awake for as long as it runs; none where there is no such tool. */\nexport function holderFor(platform: NodeJS.Platform, pid: number): Holder | undefined {\n if (platform === 'darwin') return { command: 'caffeinate', args: ['-i', '-w', String(pid)] };\n if (platform === 'linux') {\n return {\n command: 'systemd-inhibit',\n args: ['--what=idle:sleep', '--who=Pelican', '--why=Claude is working', '--mode=block', 'tail', `--pid=${pid}`, '-f', '/dev/null'],\n };\n }\n return undefined;\n}\n\n/** What is needed of the process that holds the computer awake. */\nexport type Held = {\n kill: () => unknown;\n on(event: 'error', listener: (error: Error) => void): unknown;\n on(event: 'exit', listener: (code: number | null) => void): unknown;\n};\nexport type Spawner = (command: string, args: string[]) => Held;\n\nconst defaultSpawn: Spawner = (command, args) => {\n const child: ChildProcess = spawn(command, args, { stdio: 'ignore' });\n child.unref();\n return child;\n};\n\n/**\n * Watches whether Claude is working, and holds the computer awake while it is.\n * `working` is asked every `everyMs`; the holder starts and stops with it.\n */\nexport function keepAwake({\n working,\n platform = process.platform,\n pid = process.pid,\n everyMs = 15_000,\n spawner = defaultSpawn,\n}: {\n working: () => boolean | Promise<boolean>;\n platform?: NodeJS.Platform;\n pid?: number;\n everyMs?: number;\n spawner?: Spawner;\n}): { check: () => Promise<void>; stop: () => void } {\n const holder = holderFor(platform, pid);\n let held: Held | undefined;\n // A tool that is missing, or that may not hold the computer awake here, is not tried again.\n let failed = !holder;\n\n const release = () => {\n held?.kill();\n held = undefined;\n };\n\n const check = async () => {\n if (failed) return;\n const busy = await Promise.resolve(working()).catch(() => false);\n if (busy && !held) {\n const child = spawner(holder!.command, holder!.args);\n held = child;\n child.on('error', () => {\n failed = true;\n if (held === child) held = undefined;\n });\n child.on('exit', (code) => {\n if (held !== child) return;\n held = undefined;\n // Exiting by itself, without being released: it could not hold the computer awake.\n if (code !== 0 && code !== null) failed = true;\n });\n } else if (!busy && held) {\n release();\n }\n };\n\n const timer = setInterval(() => void check(), everyMs);\n timer.unref();\n process.on('exit', release);\n return {\n check,\n stop: () => {\n clearInterval(timer);\n process.off('exit', release);\n release();\n },\n };\n}\n", "import { spawn } from 'node:child_process';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { parseArgs } from 'node:util';\n\nimport pkg from '../../package.json' with { type: 'json' };\nimport { config } from './config.js';\nimport { askLocal, callable, pelicanAt, reachable, thisPelican } from './local.js';\nimport { listensLocally } from './security.js';\n\nconst DOCS = 'https://ki-seki.github.io/pelican/docs.html';\n\n/** The name this was started by: `pelican-cc` where another program owns `pelican`. */\nconst NAME = /^pelican-cc(\\.js)?$/.test(path.basename(process.argv[1] ?? '')) ? 'pelican-cc' : 'pelican';\n\nconst HELP = `Every Claude Code session on your computer, on your phone.\nNo wrapper, no relay, no account.\n\nUsage\n ${NAME} [options] Start Pelican\n ${NAME} phone [address] Show a QR code that opens Pelican on your phone, signed in\n ${NAME} token Print the link that signs a browser in\n ${NAME} token --reset Make a new access token; old links stop working\n ${NAME} password Sign in with a password instead of the token\n ${NAME} password --stdin The same, reading the password from standard input\n ${NAME} password --off Remove the password; the token signs in again\n ${NAME} service install Keep Pelican running: start it at login, and again if it stops\n ${NAME} service status Also: restart, uninstall\n ${NAME} login Sign Claude Code in, when it is not\n\nOptions\n -p, --port <port> Port to listen on (default 7860, or PELICAN_PORT)\n -H, --host <address> Address to listen on (default 127.0.0.1, or PELICAN_HOST)\n --name <name> Name shown for this machine (default: its host name)\n --no-auth Ask no one to sign in. Only when something in front\n of Pelican already authenticates.\n --demo Show made-up sessions; nothing runs\n --open Open the browser\n -v, --version Print the versions of Pelican and the Claude Code it runs\n -h, --help Show this help\n\nEnvironment\n PELICAN_PUBLIC_URL The address your phone uses, when it is not this computer's own\n PELICAN_KEEP_AWAKE=0 Let the computer sleep while Claude works\n PELICAN_CLAUDE_PATH Run this Claude Code instead of the one Pelican brings\n\nPelican ${pkg.version} runs Claude Code, and so commands, as you. It listens on 127.0.0.1,\nand every browser signs in, with the link Pelican prints or with your password.\nMore: ${DOCS}\n`;\n\n/** A mistake in how the command was typed: said plainly, with exit code 2. */\nclass UsageError extends Error {}\n\nconst OPTIONS = {\n port: { type: 'string', short: 'p' },\n host: { type: 'string', short: 'H' },\n name: { type: 'string' },\n 'no-auth': { type: 'boolean' },\n demo: { type: 'boolean' },\n open: { type: 'boolean' },\n off: { type: 'boolean' },\n reset: { type: 'boolean' },\n stdin: { type: 'boolean' },\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n} as const;\n\n/** How many single-character edits turn one word into the other. */\nfunction distance(a: string, b: string): number {\n const row = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i += 1) {\n let previous = row[0]!;\n row[0] = i;\n for (let j = 1; j <= b.length; j += 1) {\n const current = row[j]!;\n row[j] = Math.min(row[j]! + 1, row[j - 1]! + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1));\n previous = current;\n }\n }\n return row[b.length]!;\n}\n\nfunction parse() {\n try {\n return parseArgs({ allowPositionals: true, options: OPTIONS });\n } catch (error) {\n const message = (error as Error).message;\n const unknown = /Unknown option '(-{1,2}[^']+)'/.exec(message)?.[1];\n if (unknown) {\n const name = unknown.replace(/^-+/, '');\n const near = Object.keys(OPTIONS).find((option) => distance(option, name) <= 2);\n throw new UsageError(`unknown option ${unknown}${near ? ` (did you mean --${near}?)` : ''}. See ${NAME} --help.`);\n }\n const missing = /Option '(?:-\\w, )?(--[\\w-]+)[^']*' argument missing/.exec(message)?.[1];\n if (missing) throw new UsageError(`${missing} needs a value. See ${NAME} --help.`);\n throw new UsageError(`${message} See ${NAME} --help.`);\n }\n}\n\n/** Reads a line from the terminal without echoing it. */\nfunction askHidden(prompt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const input = process.stdin;\n if (!input.isTTY) {\n reject(new Error(`Run \\`${NAME} password\\` in a terminal, or pipe the password in with --stdin.`));\n return;\n }\n process.stdout.write(prompt);\n input.setRawMode(true);\n input.resume();\n input.setEncoding('utf8');\n let value = '';\n const onData = (chunk: string) => {\n for (const char of chunk) {\n if (char === '\\r' || char === '\\n') {\n input.setRawMode(false);\n input.pause();\n input.off('data', onData);\n process.stdout.write('\\n');\n resolve(value);\n return;\n }\n if (char === '\\u0003') {\n process.stdout.write('\\n');\n process.exit(130);\n }\n if (char === '\\u007f' || char === '\\b') value = value.slice(0, -1);\n else value += char;\n }\n };\n input.on('data', onData);\n });\n}\n\nasync function readStdin(): Promise<string> {\n let data = '';\n for await (const chunk of process.stdin) data += chunk;\n return data.replace(/\\r?\\n$/, '');\n}\n\n// A running Pelican notices a new token or password within a second (auth.ts): no restart.\nasync function passwordCommand(off: boolean, stdin: boolean): Promise<void> {\n const { clearPassword, loadAuth, setPassword } = await import('./auth.js');\n await loadAuth();\n if (off) {\n await clearPassword();\n console.log(`Password removed: browsers sign in with the access token again (\\`${NAME} token\\`).`);\n return;\n }\n const password = stdin ? await readStdin() : await askHidden('New password: ');\n if (password.length < 8) throw new Error('Use at least 8 characters.');\n if (!stdin && (await askHidden('Repeat it: ')) !== password) throw new Error('The two did not match.');\n await setPassword(password);\n console.log(`Password saved in ${config.configDir}. Browsers signed in before are signed out.`);\n}\n\n/** The link with the access token, for this computer's own address. */\nconst tokenLink = (base: string, token: string) => `${base}?token=${token}`;\n\n/** An address for a host Pelican listens on: localhost, unless it listens on one other address only. */\nfunction addressFor(host: string, port: number): string {\n const name = ['0.0.0.0', '::', '127.0.0.1', 'localhost', '::1'].includes(host) ? 'localhost' : host.includes(':') ? `[${host}]` : host;\n return `http://${name}:${port}/`;\n}\n\n/**\n * The Pelican a command is about: the one running with this state folder, unless a port was given;\n * otherwise the port and host of the settings.\n */\nasync function target(portGiven: boolean): Promise<{ port: number; host: string; running: boolean }> {\n const { runningServer } = await import('./running.js');\n const running = portGiven ? undefined : await runningServer();\n return running ? { port: running.port, host: running.host, running: true } : { port: config.port, host: config.host, running: false };\n}\n\nasync function tokenCommand(reset: boolean, portGiven: boolean): Promise<void> {\n const { accessToken, authMode, loadAuth, resetToken } = await import('./auth.js');\n await loadAuth();\n if (authMode() === 'none') {\n console.log('Sign-in is off (--no-auth or PELICAN_AUTH=none), so there is no access token.');\n return;\n }\n if (reset) {\n await resetToken();\n console.log('New access token made: links and browsers signed in with the old one stop working.');\n }\n if (authMode() === 'password') {\n console.log(`A password is set, so browsers sign in with it. \\`${NAME} password --off\\` goes back to the token.`);\n return;\n }\n const token = accessToken();\n const { port, host } = await target(portGiven);\n if (token) console.log(tokenLink(addressFor(host, port), token));\n}\n\n/**\n * `pelican phone`: a QR code that opens Pelican on the phone, signed in with a one-time code that\n * the running Pelican makes. It talks only to the Pelican this account started (the note in the\n * state folder names it, local.ts), and asks for each code with a proof made with the secret the\n * server signs with, good for that one request and a minute (auth.ts): never a cookie, and no\n * token or password goes anywhere.\n */\nasync function phoneCommand(given: string | undefined, portGiven: boolean): Promise<void> {\n const { findPhoneAddress, checkAddress, setupHint } = await import('./phone.js');\n const asked = portGiven ? config.port : undefined;\n const local = await thisPelican(asked);\n if (!local) {\n const port = asked ?? (await target(false)).port;\n // Something answers there, but not as the Pelican of these settings: it is asked nothing more.\n if (await pelicanAt(callable(config.host, port))) {\n throw new Error(`What answers on port ${port} is not the Pelican started with these settings. Run \\`${NAME} phone\\` with the settings it runs with (PELICAN_STATE_DIR, PELICAN_CONFIG_DIR).`);\n }\n throw new Error(`Pelican is not running on port ${port}. Start it with \\`${NAME}\\` (or keep it running with \\`${NAME} service install\\`), then run \\`${NAME} phone\\` again.`);\n }\n const { running } = local;\n const search = await findPhoneAddress(running.port, running.host, given);\n if (!search.address) {\n console.log(setupHint(search, running.port, NAME).join('\\n'));\n console.log(`More: ${DOCS}#phone`);\n process.exitCode = 1;\n return;\n }\n const address = search.address;\n const problem = await checkAddress(address.url, running.instance);\n if (problem) throw new Error(problem);\n const { commandProof, loadAuth } = await import('./auth.js');\n await loadAuth();\n const mint = async (): Promise<string | null> => {\n // Found again each time: a Pelican started again since is another server, with another id.\n const now = await thisPelican(running.port);\n if (!now) throw new Error(`Pelican is no longer running on port ${running.port}.`);\n if (now.mode === 'none') return null;\n const proof = commandProof('POST', '/api/access/code', now.running.instance);\n const response = await askLocal(now.running.url, 'access/code', { method: 'POST', headers: { 'X-Pelican-Proof': proof } });\n if (response.status === 401) throw new Error('This Pelican keeps its sign-in in another folder (PELICAN_CONFIG_DIR): run this command with the same settings it runs with.');\n if (!response.ok) throw new Error(`Pelican did not make a code (${response.status}).`);\n return ((await response.json()) as { code: string | null }).code;\n };\n await showPhone(address, mint);\n}\n\n/** Prints the phone's QR code, and a new one each time Enter is pressed (on a terminal). */\nasync function showPhone(address: import('./phone.js').PhoneAddress, mint: () => Promise<string | null>): Promise<void> {\n const { phoneBlock } = await import('./phone.js');\n const code = await mint();\n process.stdout.write(`\\n${phoneBlock(address, code)}`);\n if (!code || !process.stdin.isTTY || !process.stdout.isTTY) return;\n process.stdout.write(' Press Enter for a new code, Ctrl-C to stop.\\n');\n let expiry: NodeJS.Timeout | undefined;\n const later = () => {\n clearTimeout(expiry);\n expiry = setTimeout(() => process.stdout.write(' That code has expired. Press Enter for a new one.\\n'), 120_000);\n };\n later();\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', () => {\n void mint().then((next) => {\n process.stdout.write(`\\n${phoneBlock(address, next)} Press Enter for a new code, Ctrl-C to stop.\\n`);\n later();\n }, (error: Error) => {\n console.error(`${NAME}: ${error.message}`);\n process.exit(1);\n });\n });\n process.stdin.on('end', () => process.exit(0));\n await new Promise<never>(() => {});\n}\n\n/** The flags a service starts Pelican with: those given to `pelican service install`. */\nfunction serviceFlags(values: ReturnType<typeof parse>['values']): string[] {\n return [\n ...(values.port ? ['--port', values.port] : []),\n ...(values.host ? ['--host', values.host] : []),\n ...(values.name ? ['--name', values.name] : []),\n ...(values['no-auth'] ? ['--no-auth'] : []),\n ];\n}\n\nasync function serviceCommand(action: string, flags: string[]): Promise<void> {\n const service = await import('./service.js');\n const { runningServer } = await import('./running.js');\n const ctx = service.thisComputer(flags);\n const say = (line: string) => console.log(line);\n if (action === 'install') {\n const problem = await service.cannotInstall(ctx);\n if (problem) throw new Error(problem);\n // Another Pelican on the same port would take it, and the service would stop at once.\n const running = await runningServer();\n const state = await service.serviceState(ctx);\n if (running && running.port === config.port && running.pid !== state.pid) {\n throw new Error(`Pelican is already running here (pid ${running.pid}, port ${running.port}). Stop it, then run \\`${NAME} service install\\` again.`);\n }\n await service.installService(ctx, say);\n await afterStart(ctx, running?.pid);\n } else if (action === 'uninstall') {\n await service.uninstallService(ctx, say);\n } else if (action === 'restart') {\n const before = (await runningServer())?.pid;\n await service.restartService(ctx, say);\n await afterStart(ctx, before);\n } else {\n const state = await service.serviceState(ctx);\n if (!state.installed) {\n say(`Pelican is not set up as a service. \\`${NAME} service install\\` keeps it running.`);\n return;\n }\n // Where the service listens is what it was installed with, which the note its process left\n // says; the shell's own settings only when there is no such note.\n const running = await runningServer();\n const ours = running && state.pid !== undefined && running.pid === state.pid ? running : undefined;\n const answering = Boolean(await pelicanAt(ours?.url ?? callable(config.host, config.port)));\n const address = ours ? addressFor(ours.host, ours.port) : addressFor(config.host, config.port);\n say(state.running ? `Running${state.pid ? ` (pid ${state.pid})` : ''}${answering ? `, at ${address}` : ', but not answering yet'}.` : `Not running${state.lastExit ? ` (last exit: ${state.lastExit})` : ''}.`);\n say(ctx.platform === 'darwin' ? `Log: ${service.logFile(ctx.home)}` : 'Log: journalctl --user -u pelican');\n }\n}\n\n/**\n * Once a service (re)starts: wait until it answers, then say how to sign in, as at a start in a\n * terminal. It is the Pelican whose note is not the one from before (`before`, the process it\n * replaced), wherever it listens; the link with the token is shown only for it.\n */\nasync function afterStart(ctx: import('./service.js').ServiceContext, before: number | undefined): Promise<void> {\n let found: Awaited<ReturnType<typeof thisPelican>>;\n for (let i = 0; i < 40 && !found; i += 1) {\n await new Promise((resolve) => setTimeout(resolve, 250));\n const pelican = await thisPelican();\n if (pelican && pelican.running.pid !== before) found = pelican;\n }\n const { logFile } = await import('./service.js');\n if (!found) {\n console.log(`Pelican has not answered yet. See ${ctx.platform === 'darwin' ? logFile(ctx.home) : 'journalctl --user -u pelican'}, or \\`${NAME} service status\\`.`);\n return;\n }\n const { accessToken, loadAuth } = await import('./auth.js');\n await loadAuth();\n const address = addressFor(found.running.host, found.running.port);\n // The link with the token goes to a terminal only, never into a pipe or a log.\n const token = found.mode === 'token' && process.stdout.isTTY ? accessToken() : undefined;\n const signIn = found.mode === 'token' && !token ? `\\n \\`${NAME} token\\` prints the link that signs a browser in` : '';\n console.log(`\\n ${token ? tokenLink(address, token) : address}${signIn}\\n On your phone: \\`${NAME} phone\\`\\n`);\n}\n\n/** One line with every version a bug report needs. */\nasync function versionLine(): Promise<string> {\n const { claudeCodeInfo, sdkPackage } = await import('./claude-code.js');\n const code = await claudeCodeInfo();\n const claude = code.missing ? 'not found' : `${code.version ?? '?'}${code.path ? ` (${code.path})` : ''}`;\n return `${pkg.version} (Pelican) \u00B7 Claude Code ${claude} \u00B7 Agent SDK ${sdkPackage().version ?? '?'} \u00B7 Node ${process.version} \u00B7 ${process.platform}-${process.arch}`;\n}\n\n/**\n * Opens Pelican in the browser. The link with the token is never put on a command line, where\n * other accounts could read it: on macOS a page only you can read redirects to it (and is\n * removed); elsewhere, where a browser may not open such a page, Pelican opens to its sign-in.\n */\nasync function openPelican(address: string, token: string | undefined): Promise<void> {\n if (!token || process.platform !== 'darwin') {\n openBrowser(address);\n return;\n }\n const file = path.join(config.configDir, 'open.html');\n try {\n await mkdir(config.configDir, { recursive: true, mode: 0o700 });\n await rm(file, { force: true });\n const link = tokenLink(address, token);\n await writeFile(file, `<!doctype html><meta http-equiv=\"refresh\" content=\"0;url=${link}\"><a href=\"${link}\">Open Pelican</a>\\n`, { mode: 0o600 });\n openBrowser(pathToFileURL(file).href);\n setTimeout(() => void rm(file, { force: true }), 30_000).unref();\n } catch {\n openBrowser(address);\n }\n}\n\nfunction openBrowser(url: string): void {\n const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n try {\n spawn(opener, [url], { stdio: 'ignore', detached: true, shell: process.platform === 'win32' }).on('error', () => {}).unref();\n } catch {\n // Opening a browser is a convenience; the address is printed above.\n }\n}\n\n/**\n * Something on the port already: the Pelican this account started (say so and stop), or another\n * program, which may answer as Pelican does. That is an error, so a service starts again and gets\n * the port back once the other program lets go of it.\n */\nasync function portTaken(): Promise<void> {\n const pelican = await thisPelican(config.port);\n if (pelican) {\n console.log(`Pelican is already running at ${addressFor(pelican.running.host, pelican.running.port)}. \\`${NAME} token\\` prints the link that signs you in.`);\n return;\n }\n throw new Error(`Port ${config.port} is in use by another program. Start Pelican on another one: ${NAME} --port ${config.port === 65535 ? 7861 : config.port + 1} (or set PELICAN_PORT).`);\n}\n\nconst within = <T>(work: Promise<T>, ms: number, fallback: T): Promise<T> =>\n Promise.race([work, new Promise<T>((resolve) => setTimeout(() => resolve(fallback), ms).unref())]);\n\nasync function main(): Promise<void> {\n const { values, positionals } = parse();\n if (values.help) return void process.stdout.write(HELP);\n if (values.version) return void console.log(await versionLine());\n\n if (values.port) config.port = Number(values.port);\n if (values.host) config.host = values.host;\n if (values.name) config.machine = values.name;\n if (values['no-auth']) config.auth = 'none';\n if (!Number.isInteger(config.port) || config.port <= 0 || config.port > 65535) {\n throw new UsageError(`Not a port: ${values.port ?? `${process.env.PELICAN_PORT} (PELICAN_PORT)`}`);\n }\n\n const [command, ...rest] = positionals;\n const most = (count: number, usage: string) => {\n if (rest.length > count) throw new UsageError(`${rest.slice(count).join(' ')}: one too many. Usage: ${NAME} ${usage}`);\n };\n switch (command) {\n case undefined:\n break;\n case 'help':\n most(0, 'help');\n return void process.stdout.write(HELP);\n case 'password':\n most(0, 'password [--stdin | --off]');\n return passwordCommand(Boolean(values.off), Boolean(values.stdin));\n case 'token':\n most(0, 'token [--reset]');\n return tokenCommand(Boolean(values.reset), Boolean(values.port));\n case 'phone':\n most(1, 'phone [address]');\n return phoneCommand(rest[0], Boolean(values.port));\n case 'login': {\n most(0, 'login');\n const { claudeLogin } = await import('./claude-code.js');\n process.exitCode = await claudeLogin();\n return;\n }\n case 'service':\n if (rest.length !== 1 || !['install', 'uninstall', 'restart', 'status'].includes(rest[0]!)) {\n throw new UsageError(`Usage: ${NAME} service install | uninstall | restart | status`);\n }\n return serviceCommand(rest[0]!, serviceFlags(values));\n default:\n throw new UsageError(`Unknown command: ${command}. See ${NAME} --help.`);\n }\n\n if (process.platform === 'win32') console.warn('pelican: Pelican is untested on Windows. It works best in WSL, next to Claude Code there.');\n\n // --no-auth, or PELICAN_AUTH=none, is an explicit choice; the demo asks no one to sign in on its own.\n const noAuth = config.auth === 'none';\n if (values.demo) {\n config.demo = true;\n const { prepareDemo } = await import('./demo.js');\n await prepareDemo();\n if (!values.name) config.machine = 'demo';\n }\n\n const local = listensLocally(config.host);\n if (config.demo) {\n // The demo holds nothing private, but it signs no one in: beyond this computer only when asked to.\n if (!local && !noAuth) throw new Error('The demo signs no one in, so it listens on 127.0.0.1 only. Pass --no-auth to show it on your network.');\n config.auth = 'none';\n }\n const { accessToken, authMode, issueCode, loadAuth } = await import('./auth.js');\n await loadAuth();\n\n const { configWarnings } = await import('./config.js');\n for (const warning of configWarnings) console.warn(`pelican: ${warning}`);\n\n const { startServer } = await import('./server.js');\n let url: string;\n try {\n ({ url } = await startServer());\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EADDRINUSE') return portTaken();\n throw error;\n }\n // Where it really listens (`localhost` may be ::1), so the commands that talk to it reach it.\n const { recordRunning } = await import('./running.js');\n await recordRunning({ port: config.port, host: config.host, url: reachable(url), version: pkg.version }).catch(() => undefined);\n\n const shown = url.replace('://127.0.0.1:', '://localhost:');\n const token = accessToken();\n const mode = authMode();\n // The link with the token is a standing key: shown on a terminal, never written to a log\n // (a service's output file, the journal). `pelican token` prints it on demand.\n const interactive = Boolean(process.stdout.isTTY);\n const open = token && interactive ? tokenLink(shown, token) : shown;\n const protection = config.demo ? 'demo: made-up sessions, nothing runs'\n : mode === 'password' ? 'browsers sign in with your password'\n : mode === 'token' ? (interactive ? `the link signs a browser in (\\`${NAME} token\\` prints it again)` : `browsers sign in with the link \\`${NAME} token\\` prints`)\n : local ? 'no sign-in (--no-auth)' : 'no sign-in (--no-auth): anyone who reaches this address can run commands as you';\n\n const { checkNewerClaude, claudeCodeInfo, claudeCodeLine, claudeSignIn, newerClaudeLine } = await import('./claude-code.js');\n const { findPhoneAddress, phoneBlock } = await import('./phone.js');\n const nothing: import('./phone.js').PhoneSearch = {};\n const [code, signIn, search, newer] = await Promise.all([\n claudeCodeInfo(),\n config.demo ? undefined : within(claudeSignIn(), 4000, undefined),\n config.demo && local ? nothing : within(findPhoneAddress(config.port, config.host), 4000, nothing),\n within(checkNewerClaude(), 4000, undefined),\n ]);\n const claude = config.demo ? '' : `\\n ${claudeCodeLine(code, signIn, `${NAME} login`)}${newer ? `\\n ${newerClaudeLine(newer)}` : ''}`;\n console.log(`\\n Pelican ${pkg.version} \u00B7 ${config.machine}\\n ${open}\\n ${protection}${claude}\\n`);\n if (!config.webDir) console.log(' The web app is not built: run `npm run build` (or use `npm run dev`).\\n');\n\n // The phone: a QR code with a one-time code (never the token) where the address is known. Shown\n // once: the terminal is never read here, or a Pelican started in the background (`pelican &`)\n // would be stopped by the terminal (SIGTTIN). `pelican phone` makes a new code, on Enter too.\n if (search.address && interactive) {\n const code = mode === 'none' ? null : issueCode();\n process.stdout.write(`${phoneBlock(search.address, code)}${code ? ` A new one: \\`${NAME} phone\\`\\n` : ''}\\n`);\n } else if (search.address) {\n console.log(` On your phone: ${search.address.url}\\n`);\n } else if (!config.demo) {\n console.log(` On your phone: \\`${NAME} phone\\`\\n`);\n }\n\n if (!config.demo && config.keepAwake) {\n const [{ keepAwake }, { anyRunBusy }, { liveProcesses }] = await Promise.all([import('./awake.js'), import('./runner.js'), import('./live.js')]);\n // Claude working here, or in another app on this computer (not one waiting there for an answer).\n keepAwake({\n working: async () => anyRunBusy() || [...(await liveProcesses()).values()].some((p) => p.busy && !(p as { waiting?: boolean }).waiting),\n });\n }\n if (values.open) await openPelican(shown, token);\n}\n\nmain().catch((error: Error) => {\n console.error(`${NAME}: ${error.message}`);\n process.exit(error instanceof UsageError ? 2 : 1);\n});\n", "import { type Running, runningServer } from './running.js';\n\n/**\n * The Pelican a command talks to (`pelican phone`, `pelican service`, a second start): where this\n * computer reaches it, and whether what answers there is the very Pelican this account started.\n * Anything can listen on a port, another account's program too, so only the note a running\n * Pelican leaves in the state folder (readable only by you) says which server is ours.\n */\n\n/**\n * Where this computer reaches a Pelican that listens on `host`: a wildcard address on loopback,\n * `::1` as itself, a name as it resolves (Node tries each address `localhost` has, as listening did).\n */\nexport function callable(host: string, port: number): string {\n if (host === '0.0.0.0' || host === '127.0.0.1') return `http://127.0.0.1:${port}/`;\n if (host === '::' || host === '::1') return `http://[::1]:${port}/`;\n return `http://${host.includes(':') ? `[${host}]` : host}:${port}/`;\n}\n\n/** The address a server reports it listens at, as this computer reaches it (a wildcard on loopback). */\nexport const reachable = (url: string) => url.replace('://0.0.0.0:', '://127.0.0.1:').replace('://[::]:', '://[::1]:');\n\n/** Asks a local Pelican something, the way its page does. */\nexport async function askLocal(base: string, route: string, init: RequestInit = {}): Promise<Response> {\n return fetch(new URL(`api/${route}`, base), { ...init, headers: { 'X-Pelican': '1', ...(init.headers as Record<string, string> | undefined) }, signal: AbortSignal.timeout(5000) });\n}\n\n/** The answer of whatever listens at an address, if it is a Pelican: its sign-in state and its id. */\nexport async function pelicanAt(base: string): Promise<{ mode: string; instance?: string } | undefined> {\n try {\n const answer = await (await askLocal(base, 'auth')).json() as { mode?: unknown; instance?: unknown };\n return typeof answer.mode === 'string' ? { mode: answer.mode, ...(typeof answer.instance === 'string' ? { instance: answer.instance } : {}) } : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The Pelican this account runs (on `port`, when one is given), when it is what answers: the note\n * names a live process, and the server at the note's address gives the note's id. Undefined\n * otherwise, also when something else holds the port.\n */\nexport async function thisPelican(port?: number): Promise<{ running: Running; mode: string } | undefined> {\n const running = await runningServer();\n if (!running || (port !== undefined && running.port !== port) || typeof running.instance !== 'string') return undefined;\n const answer = await pelicanAt(running.url);\n return answer && answer.instance === running.instance ? { running, mode: answer.mode } : undefined;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "info", "record", "os", "randomBytes", "readFileSync", "mkdir", "readFile", "writeFile", "path", "before", "text", "file", "instance", "rest", "cookieHeader", "code", "info", "text", "text", "init_qr", "existsSync", "os", "file", "app", "target", "serve", "shown", "path", "text", "instance", "init_qr", "execFile", "mkdir", "rm", "writeFile", "os", "path", "file", "text", "strings", "result", "what", "loaded", "stdout", "pid", "real", "home", "execFile", "existsSync", "readFileSync", "stat", "path", "require", "file", "version", "execFile", "mkdir", "rm", "writeFile", "path", "git", "run", "files", "file", "text", "text", "randomUUID", "mkdir", "readFile", "rename", "writeFile", "path", "text", "file", "loaded", "before", "randomBytes", "realpathSync", "mkdir", "stat", "os", "path", "execFile", "readFile", "path", "promisify", "run", "alive", "waiting", "app", "text", "constants", "file", "stat", "path", "file", "str", "text", "seen", "read", "info", "image", "text", "readdir", "stat", "path", "file", "waiting", "before", "text", "info", "read", "stat", "path", "info", "archived", "file", "recent", "before", "seen", "text", "info", "result", "target", "stat", "waiting", "file", "info", "recent", "randomUUID", "mkdir", "readdir", "readFile", "realpath", "rm", "stat", "writeFile", "path", "file", "info", "target", "execFile", "mkdir", "readdir", "realpath", "rename", "stat", "writeFile", "os", "path", "file", "text", "head", "info", "readJson", "home", "folder", "groups", "what", "target", "under", "files", "seen", "walk", "read", "json", "realpath", "os", "info", "text", "cache", "asking", "read", "list", "limits", "execFile", "realpathSync", "path", "promisify", "run", "readdir", "path", "cache", "TTL_MS", "files", "MAX_FILES", "walk", "file", "query", "mkdir", "readFile", "writeFile", "path", "file", "home", "tool", "list", "spawn", "running", "runCommand", "result", "note", "text", "info", "oneLine", "randomUUID", "readFile", "query", "text", "file", "str", "run", "target", "info", "cwd", "note", "rest", "tool", "before", "result", "index", "failed", "waiting", "text", "before", "index", "textOf", "blocks", "readdir", "realpath", "stat", "path", "real", "file", "head", "info", "data", "createHash", "readFile", "realpath", "stat", "path", "text", "file", "image", "run", "before", "info", "real", "keys", "limits", "newer", "result", "runCommand", "seen", "token", "waiting", "process", "info", "POLL_MS", "text", "server", "info", "head", "pathOf", "subscriptions", "sweep", "spawn", "failed", "spawn", "mkdir", "rm", "writeFile", "path", "running", "path", "clearPassword", "loadAuth", "setPassword", "password", "token", "target", "runningServer", "running", "accessToken", "authMode", "resetToken", "findPhoneAddress", "checkAddress", "setupHint", "commandProof", "phoneBlock", "before", "logFile", "claudeCodeInfo", "sdkPackage", "file", "mkdir", "rm", "writeFile", "spawn", "within", "rest", "claudeLogin", "prepareDemo", "issueCode", "configWarnings", "startServer", "recordRunning", "shown", "open", "checkNewerClaude", "claudeCodeLine", "claudeSignIn", "newerClaudeLine", "newer", "code", "keepAwake", "anyRunBusy", "liveProcesses"]
|
|
7
7
|
}
|