pelican-cc 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +8 -6
  3. package/dist/server/index.js +6238 -1001
  4. package/dist/server/index.js.map +4 -4
  5. package/dist/web/assets/Chat-hw_dVyZ5.js +101 -0
  6. package/dist/web/assets/Chat-hw_dVyZ5.js.br +0 -0
  7. package/dist/web/assets/Chat-hw_dVyZ5.js.gz +0 -0
  8. package/dist/web/assets/ModelSheet-DDh0NARP.js +1 -0
  9. package/dist/web/assets/ModelSheet-DDh0NARP.js.br +0 -0
  10. package/dist/web/assets/ModelSheet-DDh0NARP.js.gz +0 -0
  11. package/dist/web/assets/Settings-ByxVBoK1.js +4 -0
  12. package/dist/web/assets/Settings-ByxVBoK1.js.br +0 -0
  13. package/dist/web/assets/Settings-ByxVBoK1.js.gz +0 -0
  14. package/dist/web/assets/Usage-DvP3bGmY.js +1 -0
  15. package/dist/web/assets/Usage-DvP3bGmY.js.br +0 -0
  16. package/dist/web/assets/Usage-DvP3bGmY.js.gz +0 -0
  17. package/dist/web/assets/WorkspaceChanges-Cnv5Vi7J.js +1 -0
  18. package/dist/web/assets/WorkspaceChanges-Cnv5Vi7J.js.br +0 -0
  19. package/dist/web/assets/WorkspaceChanges-Cnv5Vi7J.js.gz +0 -0
  20. package/dist/web/assets/WorkspaceFiles-CSlYqC41.js +1 -0
  21. package/dist/web/assets/WorkspaceFiles-CSlYqC41.js.br +0 -0
  22. package/dist/web/assets/WorkspaceFiles-CSlYqC41.js.gz +0 -0
  23. package/dist/web/assets/index-Ck4Wpk8v.css +2 -0
  24. package/dist/web/assets/index-Ck4Wpk8v.css.br +0 -0
  25. package/dist/web/assets/index-Ck4Wpk8v.css.gz +0 -0
  26. package/dist/web/assets/index-fRwaTlu9.js +40 -0
  27. package/dist/web/assets/index-fRwaTlu9.js.br +0 -0
  28. package/dist/web/assets/index-fRwaTlu9.js.gz +0 -0
  29. package/dist/web/assets/usage-CHTS1DtT.js +1 -0
  30. package/dist/web/assets/usage-CHTS1DtT.js.br +0 -0
  31. package/dist/web/assets/usage-CHTS1DtT.js.gz +0 -0
  32. package/dist/web/index.html +2 -2
  33. package/dist/web/index.html.br +0 -0
  34. package/dist/web/index.html.gz +0 -0
  35. package/dist/web/sw.js +56 -14
  36. package/dist/web/sw.js.br +0 -0
  37. package/dist/web/sw.js.gz +0 -0
  38. package/npm-shrinkwrap.json +114 -598
  39. package/package.json +3 -3
  40. package/dist/web/assets/Chat-BZ4Kv_y0.js +0 -73
  41. package/dist/web/assets/Chat-BZ4Kv_y0.js.br +0 -0
  42. package/dist/web/assets/Chat-BZ4Kv_y0.js.gz +0 -0
  43. package/dist/web/assets/ModelSheet-CrgB7jGC.js +0 -1
  44. package/dist/web/assets/ModelSheet-CrgB7jGC.js.br +0 -0
  45. package/dist/web/assets/ModelSheet-CrgB7jGC.js.gz +0 -0
  46. package/dist/web/assets/Settings-BYSfCOfJ.js +0 -3
  47. package/dist/web/assets/Settings-BYSfCOfJ.js.br +0 -0
  48. package/dist/web/assets/Settings-BYSfCOfJ.js.gz +0 -0
  49. package/dist/web/assets/index-DTXoHe9U.js +0 -30
  50. package/dist/web/assets/index-DTXoHe9U.js.br +0 -0
  51. package/dist/web/assets/index-DTXoHe9U.js.gz +0 -0
  52. package/dist/web/assets/index-DYo6H59g.css +0 -2
  53. package/dist/web/assets/index-DYo6H59g.css.br +0 -0
  54. package/dist/web/assets/index-DYo6H59g.css.gz +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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.0\",\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\": \"^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\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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\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"]
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/shared/line-diff.ts", "../../src/server/demo-image.ts", "../../src/server/demo-usage.ts", "../../src/server/demo-workflows.ts", "../../src/server/demo-visuals.ts", "../../src/server/demo.ts", "../../src/shared/modes.ts", "../../src/shared/usage.ts", "../../src/shared/preview-policy.ts", "../../src/shared/tasks.ts", "../../src/shared/workflows.ts", "../../src/shared/errors.ts", "../../src/web/lib/turns.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/server/transcripts.ts", "../../src/server/side-chat.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/shared/hidden.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/shell-runs.ts", "../../src/server/stream.ts", "../../src/server/workspace.ts", "../../src/server/search.ts", "../../src/server/changes.ts", "../../src/server/stats.ts", "../../src/server/workflows.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.4.0\",\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 { readFileSync, 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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/**\n * How long launchd waits for a job it stops before it ends it, when the job does not say: 5\n * seconds on macOS now (`exit timeout = 5` in `launchctl print`).\n */\nexport const LAUNCHD_EXIT_TIMEOUT_S = 5;\n/**\n * How long Pelican's login item asks launchd to wait (ExitTimeOut) once it asks Pelican to stop:\n * long enough for `!` commands to tidy up (see SHUTDOWN_GRACE_MS) and for Pelican to end what is\n * left of them and exit.\n */\nconst EXIT_TIMEOUT_S = 20;\n\n/** The launchd job that started this Pelican, by its label, if one did (see launchdExitTimeout). */\nexport function launchdJob(ctx: Pick<ServiceContext, 'platform' | 'env'>): string | undefined {\n const label = ctx.env.XPC_SERVICE_NAME;\n return ctx.platform === 'darwin' && label && label !== '0' && !label.startsWith('application.') ? label : undefined;\n}\n\n/**\n * How long launchd waits, once it asks this Pelican to stop, before it ends it, when a launchd job\n * started Pelican (the job's label is in XPC_SERVICE_NAME; a terminal says 0, an app application.\u2026):\n * the job's exit timeout as `launchctl print` says it, else launchd's default. Undefined elsewhere.\n */\nexport async function launchdExitTimeout(ctx: Pick<ServiceContext, 'platform' | 'env' | 'uid' | 'run'>): Promise<number | undefined> {\n const label = launchdJob(ctx);\n if (!label) return undefined;\n const { code, stdout } = await ctx.run('launchctl', ['print', `gui/${ctx.uid}/${label}`]);\n const seconds = Number(/^\\s*exit timeout = (\\d+)$/m.exec(stdout)?.[1]);\n return code === 0 && seconds > 0 ? seconds : LAUNCHD_EXIT_TIMEOUT_S;\n}\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>ExitTimeOut</key>\n <integer>${EXIT_TIMEOUT_S}</integer>\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/**\n * Whether the service manager asked every process of Pelican's service to end, its `!` commands\n * too, with the signal Pelican got: systemd stopping a unit sends SIGTERM to each process in it at\n * once (KillMode=control-group, its default, which the unit below keeps). Pelican, started by\n * systemd itself (its parent, and the INVOCATION_ID it gives a service), takes a SIGTERM as that.\n */\nexport function askedBySystemd(signal: NodeJS.Signals, env: NodeJS.ProcessEnv = process.env, parent: () => string | undefined = parentCommand): boolean {\n return signal === 'SIGTERM' && Boolean(env.INVOCATION_ID) && parent() === 'systemd';\n}\n\n/** The name of the program that started Pelican, where the system says it (Linux). */\nfunction parentCommand(): string | undefined {\n try {\n return process.platform === 'linux' ? readFileSync(`/proc/${process.ppid}/comm`, 'utf8').trim() : undefined;\n } catch {\n return undefined;\n }\n}\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", "/**\n * A line diff (Myers' O(ND) algorithm), for the server, which bundles no diff library: what one\n * turn changed in a file Claude edited several times is the difference between the file before\n * its first edit and after its last. Lines the two texts share at either end are set aside first,\n * so an edit in a long file costs about as much as the edit. Past `maxD` differing lines it gives\n * up (undefined) and the caller shows the edits one by one instead.\n */\nexport type LineOp = { kind: 'same' | 'del' | 'add'; text: string };\n\nexport function splitLines(text: string): string[] {\n if (!text) return [];\n const lines = text.split('\\n');\n if (lines.at(-1) === '') lines.pop();\n return lines;\n}\n\nexport function lineDiff(a: readonly string[], b: readonly string[], maxD = 1000): LineOp[] | undefined {\n let start = 0;\n while (start < a.length && start < b.length && a[start] === b[start]) start += 1;\n let endA = a.length;\n let endB = b.length;\n while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) {\n endA -= 1;\n endB -= 1;\n }\n const middle = myers(a.slice(start, endA), b.slice(start, endB), maxD);\n if (!middle) return undefined;\n return [\n ...a.slice(0, start).map((text): LineOp => ({ kind: 'same', text })),\n ...middle,\n ...a.slice(endA).map((text): LineOp => ({ kind: 'same', text })),\n ];\n}\n\nfunction myers(a: readonly string[], b: readonly string[], maxD: number): LineOp[] | undefined {\n const n = a.length;\n const m = b.length;\n if (n === 0) return b.map((text) => ({ kind: 'add', text }));\n if (m === 0) return a.map((text) => ({ kind: 'del', text }));\n const max = Math.min(n + m, maxD);\n const offset = max + 1;\n const v = new Int32Array(2 * max + 3);\n // How far each diagonal reached before each step, only the diagonals that step can read\n // (k from -d to d, at k + d): walking back from the end needs them, and no more.\n const trace: Int32Array[] = [];\n for (let d = 0; d <= max; d += 1) {\n trace.push(v.slice(offset - d, offset + d + 1));\n for (let k = -d; k <= d; k += 2) {\n let x = k === -d || (k !== d && v[offset + k - 1]! < v[offset + k + 1]!) ? v[offset + k + 1]! : v[offset + k - 1]! + 1;\n let y = x - k;\n while (x < n && y < m && a[x] === b[y]) {\n x += 1;\n y += 1;\n }\n v[offset + k] = x;\n if (x >= n && y >= m) return walkBack(trace, a, b, d);\n }\n }\n return undefined;\n}\n\nfunction walkBack(trace: readonly Int32Array[], a: readonly string[], b: readonly string[], steps: number): LineOp[] {\n const ops: LineOp[] = [];\n let x = a.length;\n let y = b.length;\n for (let d = steps; d > 0; d -= 1) {\n const before = trace[d]!;\n const at = (k: number) => before[k + d]!;\n const k = x - y;\n const down = k === -d || (k !== d && at(k - 1) < at(k + 1));\n const prevK = down ? k + 1 : k - 1;\n const prevX = at(prevK);\n const prevY = prevX - prevK;\n while (x > prevX && y > prevY) {\n x -= 1;\n y -= 1;\n ops.push({ kind: 'same', text: a[x]! });\n }\n if (down) {\n y -= 1;\n ops.push({ kind: 'add', text: b[y]! });\n } else {\n x -= 1;\n ops.push({ kind: 'del', text: a[x]! });\n }\n }\n while (x > 0 && y > 0) {\n x -= 1;\n y -= 1;\n ops.push({ kind: 'same', text: a[x]! });\n }\n return ops.reverse();\n}\n\n/** How many lines a diff adds and removes. */\nexport function diffCounts(ops: readonly LineOp[]): { added: number; removed: number } {\n let added = 0;\n let removed = 0;\n for (const op of ops) {\n if (op.kind === 'add') added += 1;\n else if (op.kind === 'del') removed += 1;\n }\n return { added, removed };\n}\n\nexport type Hunk = { oldStart: number; oldLines: number; newStart: number; newLines: number; lines: string[] };\n\n/** A diff as unified hunks with `context` lines around each change, numbered as git numbers them. */\nexport function toHunks(ops: readonly LineOp[], context = 3): Hunk[] {\n const hunks: Hunk[] = [];\n const changed = ops.flatMap((op, i) => (op.kind === 'same' ? [] : [i]));\n if (changed.length === 0) return hunks;\n // Line numbers before each op, in the old file and the new one.\n const oldAt: number[] = [];\n const newAt: number[] = [];\n let o = 1;\n let n = 1;\n for (const op of ops) {\n oldAt.push(o);\n newAt.push(n);\n if (op.kind !== 'add') o += 1;\n if (op.kind !== 'del') n += 1;\n }\n let from = Math.max(0, changed[0]! - context);\n let to = Math.min(ops.length, changed[0]! + context + 1);\n const close = () => {\n const part = ops.slice(from, to);\n hunks.push({\n oldStart: part.some((op) => op.kind !== 'add') ? oldAt[from]! : oldAt[from]! - 1,\n oldLines: part.filter((op) => op.kind !== 'add').length,\n newStart: part.some((op) => op.kind !== 'del') ? newAt[from]! : newAt[from]! - 1,\n newLines: part.filter((op) => op.kind !== 'del').length,\n lines: part.map((op) => `${op.kind === 'add' ? '+' : op.kind === 'del' ? '-' : ' '}${op.text}`),\n });\n };\n for (const i of changed.slice(1)) {\n if (i - context <= to) {\n to = Math.min(ops.length, i + context + 1);\n } else {\n close();\n from = i - context;\n to = Math.min(ops.length, i + context + 1);\n }\n }\n close();\n return hunks;\n}\n\n/** Hunks as the text of a unified diff for one file, as `git diff` writes it. */\nexport function unifiedDiff(path: string, hunks: readonly Hunk[]): string {\n if (hunks.length === 0) return '';\n const range = (start: number, lines: number) => (lines === 1 ? `${start}` : `${start},${lines}`);\n return [\n `--- a/${path}`,\n `+++ b/${path}`,\n ...hunks.flatMap((h) => [`@@ -${range(h.oldStart, h.oldLines)} +${range(h.newStart, h.newLines)} @@`, ...h.lines]),\n ].join('\\n').concat('\\n');\n}\n\n/**\n * Applies hunks to a text, as a tool's structured patch was made from it: the text after the\n * edit, or undefined when a hunk does not fit (the file was not what the patch says it was).\n */\nexport function applyHunks(text: string, hunks: readonly Hunk[]): string | undefined {\n const lines = splitLines(text);\n const endsInBreak = text.endsWith('\\n') || text === '';\n const out: string[] = [];\n let at = 0;\n for (const hunk of hunks) {\n const start = Math.max(0, hunk.oldStart - (hunk.oldLines === 0 ? 0 : 1));\n if (start < at || start > lines.length) return undefined;\n out.push(...lines.slice(at, start));\n at = start;\n for (const line of hunk.lines) {\n const mark = line[0];\n const body = line.slice(1);\n if (mark === ' ' || mark === '-') {\n if (lines[at] !== body) return undefined;\n at += 1;\n if (mark === ' ') out.push(body);\n } else if (mark === '+') {\n out.push(body);\n }\n // \"\\" and the like change nothing here.\n }\n }\n out.push(...lines.slice(at));\n return out.length === 0 ? '' : `${out.join('\\n')}${endsInBreak ? '\\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", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Usage for `pelican --demo`, kept plausible: the tokens each reply reports, the app each session\n * ran in, a few weeks of older sessions, Claude Code's own stats from before them, and how long\n * Claude waited for answers in the sessions Pelican ran. Times are relative to now, like the rest\n * of the demo.\n */\n\nconst MIN = 60_000;\nconst HOUR = 60 * MIN;\nconst DAY = 24 * HOUR;\n\n/** The app each of the demo's sessions ran in (its Claude Code entrypoint); the others are Claude Desktop's. */\nconst APPS: Record<string, string> = {\n 'a3f1c2d4-1111-4a1b-8c3d-000000000001': 'sdk-ts',\n 'c9d3b8e2-3333-4c3d-ae5f-000000000003': 'sdk-ts',\n 'd1e4c7f3-4444-4d4e-bf60-000000000004': 'claude-vscode',\n};\n\n/** Sessions Pelican ran: the Agent SDK's rows in them are Pelican's. */\nconst PELICAN = ['a3f1c2d4-1111-4a1b-8c3d-000000000001', 'c9d3b8e2-3333-4c3d-ae5f-000000000003', 'e6c1a7d2-9999-4e1c-8d2a-00000000000d'];\n\n/**\n * What a reply in the demo reports, from where it sits in its session: the first writes the\n * system prompt and tools to the cache, later ones read a context that grows a little each time.\n */\nfunction replyUsage(seed: number, index: number) {\n const wiggle = (n: number) => Math.round(n * (0.8 + (((seed * 7919 + index * 104729) % 97) / 97) * 0.4));\n return {\n input_tokens: wiggle(6),\n output_tokens: wiggle(220 + 140 * (index % 5)),\n cache_read_input_tokens: index === 0 ? wiggle(12_400) : wiggle(21_000 + 7_400 * index),\n cache_creation_input_tokens: index === 0 ? wiggle(18_600) : wiggle(1_300 + 600 * (index % 3)),\n service_tier: 'standard',\n };\n}\n\nconst replies = new Map<string, number>();\n\n/** The fields a demo row gets for usage, in the order the session's rows are written: its app, and for a reply its usage and request. */\nexport function demoRowUsage(sessionId: string, role: 'user' | 'assistant'): { entrypoint: string; usage?: ReturnType<typeof replyUsage>; requestId?: string } {\n const entrypoint = APPS[sessionId] ?? 'claude-desktop';\n if (role !== 'assistant') return { entrypoint };\n const index = replies.get(sessionId) ?? 0;\n replies.set(sessionId, index + 1);\n const seed = Number.parseInt(sessionId.slice(-4), 16);\n return { entrypoint, usage: replyUsage(seed, index), requestId: `req_demo_${sessionId.slice(-6)}_${index}` };\n}\n\ntype Earlier = { id: string; title: string; project: string; daysAgo: number; hour: number; app: string; model: string; replies: number; prompt: string; reply: string; compacted?: number; limit?: string };\n\n/** Older sessions, over the last three weeks: a usual mix of projects, apps and models. */\nconst EARLIER: Earlier[] = [\n {\n id: 'e1a2b3c4-aaaa-4a1a-8b1b-00000000000a', title: 'Add a CSV export to the reports page', project: 'acme-web', daysAgo: 2, hour: 10, app: 'claude-desktop', model: 'claude-opus-5-5', replies: 9,\n prompt: 'Add a CSV export to the reports page, with the same columns as the table.',\n reply: 'Export is in place: **Download CSV** above the table writes the visible columns, in the table\\'s order, and respects the current filters.',\n },\n {\n id: 'e2b3c4d5-bbbb-4b2b-9c2c-00000000000b', title: 'Explain how the retry queue works', project: 'data-pipeline', daysAgo: 3, hour: 16, app: 'cli', model: 'claude-sonnet-5-5', replies: 4,\n prompt: 'How does the retry queue decide when to try an export again?',\n reply: 'A failed export goes back on the queue with a delay that doubles each time, from 1 to 32 minutes; after six tries it is marked failed and the owner gets an email.',\n },\n {\n id: 'e3c4d5e6-cccc-4c3c-ad3d-00000000000c', title: 'Upgrade the test runner', project: 'acme-web', daysAgo: 5, hour: 13, app: 'claude-vscode', model: 'claude-opus-5-5', replies: 16, compacted: 3,\n prompt: 'Upgrade the test runner to the new major version and fix whatever breaks.',\n reply: 'The upgrade is done and all 412 tests pass. Three things changed: the config file moved to `test.config.ts`, snapshot names lost their numeric suffix, and two tests needed `await` on `expect(...).resolves`.',\n limit: \"You've hit your 5-hour limit \u00B7 resets 6pm\",\n },\n {\n id: 'e6c1a7d2-9999-4e1c-8d2a-00000000000d', title: 'Draft the Q4 roadmap page', project: 'docs-site', daysAgo: 8, hour: 11, app: 'sdk-ts', model: 'claude-opus-5-5', replies: 5,\n prompt: 'Draft a roadmap page for Q4 from the issues labelled q4.',\n reply: 'The draft is in `docs/roadmap.md`: three themes (speed, exports, accounts), each with its issues and a one-line why.',\n },\n {\n id: 'e5e6f7a8-eeee-4e5e-8f5f-00000000000e', title: 'Speed up the signup query', project: 'data-pipeline', daysAgo: 12, hour: 14, app: 'cli', model: 'claude-opus-5-5', replies: 8,\n prompt: 'The signups dashboard takes 9 seconds to load. Find out why and fix it.',\n reply: 'An index on `signups(created_at, plan)` brings the query from 8.7 s to 40 ms; the migration is in `migrations/0042_signup_index.sql`.',\n limit: \"You've hit your 5-hour limit \u00B7 resets 5pm\",\n },\n {\n id: 'e7f8a9b0-ffff-4f7f-9a7a-00000000000f', title: 'Fix the date picker on Safari', project: 'acme-web', daysAgo: 19, hour: 9, app: 'claude-desktop', model: 'claude-sonnet-5-5', replies: 5,\n prompt: 'The date picker shows the wrong month on Safari. Fix it.',\n reply: 'Safari reads `2026-10-01` without a time as UTC, so west of Greenwich it became September 30. The picker now builds dates from their parts.',\n },\n];\n\nconst compactSummary = (title: string) => `This session is being continued from a previous conversation that ran out of context. Summary: working on \"${title}\"; the work so far and the files touched are noted above.`;\n\n/** Writes the older sessions, Claude Code's own stats from before them, and Pelican's record of its sessions. */\nexport async function writeDemoUsage(root: string, claudeHome: string): Promise<void> {\n const now = Date.now();\n let roadmapWait = now - 8 * DAY;\n for (const session of EARLIER) {\n const cwd = path.join(root, 'code', session.project);\n const dir = path.join(claudeHome, 'projects', cwd.replace(/[^a-zA-Z0-9]/g, '-'));\n await mkdir(dir, { recursive: true });\n const start = new Date(now - session.daysAgo * DAY);\n start.setHours(session.hour, 12, 0, 0);\n let t = start.getTime();\n let parent: string | null = null;\n const lines: string[] = [JSON.stringify({ type: 'custom-title', customTitle: session.title, sessionId: session.id })];\n let n = 0;\n const row = (type: string, extra: Record<string, unknown>) => {\n const uuid = `${session.id.slice(0, 24)}${String(n).padStart(12, '0')}`;\n n += 1;\n lines.push(JSON.stringify({\n parentUuid: parent, isSidechain: false, userType: 'external', cwd, sessionId: session.id, version: '2.1.318',\n gitBranch: 'main', type, uuid, timestamp: new Date(t).toISOString(), entrypoint: session.app, ...extra,\n }));\n parent = uuid;\n };\n row('user', { message: { role: 'user', content: session.prompt } });\n const seed = Number.parseInt(session.id.slice(-4), 16);\n const compactEvery = session.compacted ? Math.floor(session.replies / (session.compacted + 1)) : 0;\n for (let i = 0; i < session.replies; i += 1) {\n t += (3 + (i % 4)) * MIN;\n if (compactEvery && i > 0 && i % compactEvery === 0 && i / compactEvery <= session.compacted!) {\n const before = parent;\n lines.push(JSON.stringify({\n parentUuid: null, logicalParentUuid: before, isSidechain: false, type: 'system', subtype: 'compact_boundary', content: 'Conversation compacted',\n compactMetadata: { trigger: 'auto', preTokens: 168_000 }, uuid: `${session.id.slice(0, 24)}c${String(i).padStart(11, '0')}`, timestamp: new Date(t).toISOString(),\n cwd, sessionId: session.id, version: '2.1.318', entrypoint: session.app,\n }));\n parent = `${session.id.slice(0, 24)}c${String(i).padStart(11, '0')}`;\n row('user', { isCompactSummary: true, isVisibleInTranscriptOnly: true, message: { role: 'user', content: compactSummary(session.title) } });\n }\n if (session.limit && i === Math.floor(session.replies * 0.6)) {\n // Claude Code's note that the 5-hour limit was reached, in place of a reply; the work goes on after the reset.\n row('assistant', {\n message: { id: `msg_limit_${session.id.slice(-6)}`, model: '<synthetic>', role: 'assistant', type: 'message', content: [{ type: 'text', text: session.limit }] },\n isApiErrorMessage: true, error: 'rate_limit',\n });\n t += 2 * HOUR;\n row('user', { message: { role: 'user', content: 'Carry on.' } });\n }\n const last = i === session.replies - 1;\n if (session.id === PELICAN[2] && i === 2) {\n roadmapWait = t;\n t += 4 * MIN;\n }\n row('assistant', {\n requestId: `req_demo_${session.id.slice(-6)}_${i}`,\n message: {\n id: `msg_demo_${session.id.slice(-6)}_${i}`, type: 'message', role: 'assistant', model: session.model,\n content: [{ type: 'text', text: last ? session.reply : i === 0 ? 'I\u2019ll start by reading the code involved.' : 'Next step.' }],\n usage: replyUsage(seed, i),\n },\n });\n }\n await writeFile(path.join(dir, `${session.id}.jsonl`), `${lines.join('\\n')}\\n`);\n }\n\n // Claude Code's own stats, as /stats left them three weeks ago: the days before the oldest transcript here.\n const through = Math.floor((now - 21 * DAY) / DAY);\n const iso = (day: number) => new Date(day * DAY).toISOString().slice(0, 10);\n const dailyActivity: Array<{ date: string; messageCount: number; sessionCount: number; toolCallCount: number }> = [];\n for (let back = 40; back >= 0; back -= 1) {\n // About four days a week.\n if ([1, 4, 6].includes((back * 5 + 3) % 7)) continue;\n const sessions = 1 + ((back * 3) % 3);\n dailyActivity.push({ date: iso(through - back), messageCount: 40 * sessions + (back % 9) * 6, sessionCount: sessions, toolCallCount: 14 * sessions });\n }\n await writeFile(path.join(claudeHome, 'stats-cache.json'), JSON.stringify({\n version: 5,\n lastComputedDate: iso(through),\n dailyActivity,\n dailyModelTokens: [],\n modelUsage: {},\n totalSessions: dailyActivity.reduce((sum, d) => sum + d.sessionCount, 0),\n totalMessages: dailyActivity.reduce((sum, d) => sum + d.messageCount, 0),\n longestSession: { sessionId: 'e0d1c2b3-0000-4000-8000-000000000010', duration: 3 * HOUR + 42 * MIN, messageCount: 310, timestamp: new Date((through - 12) * DAY + 9 * HOUR).toISOString() },\n firstSessionDate: new Date((through - 40) * DAY + 10 * HOUR).toISOString(),\n hourCounts: {},\n }, null, 2));\n\n // The sessions Pelican ran, and the time Claude waited there for an approval or an answer.\n const wait = (id: string, at: number, ms: number): [string, number, number] => [id, at, at + ms];\n await mkdir(path.join(root, 'state', 'usage'), { recursive: true });\n await writeFile(path.join(root, 'state', 'usage', 'pelican.json'), JSON.stringify({\n sessions: Object.fromEntries(PELICAN.map((id) => [id, now - 9 * DAY])),\n // The flaky-test plan waited a minute for its approval; the roadmap's draft four minutes for an answer.\n waits: [\n wait(PELICAN[1]!, now - 3 * HOUR + 30_000, 60_000),\n wait(PELICAN[2]!, roadmapWait, 4 * MIN),\n ],\n }));\n}\n", "import type { RunState, Workflow, WorkflowAgent } from '../shared/protocol.js';\nimport type { DemoSession, Row } from './demo.js';\n\n\n/**\n * The demo's workflows: a session in which Claude reviewed the checkout flow with a workflow that\n * finished, then started one that still runs. Its run folders are written next to its transcript as\n * Claude Code writes them (a record, a journal, each agent's transcript and meta file, the scripts),\n * all made up, with times relative to now.\n */\n\nconst MIN = 60_000;\nexport const WORKFLOW_SESSION = 'b5c8e1f4-cccc-4b5c-8d6e-000000000013';\n\nconst REVIEW = { call: 'toolu_demo_wf_review', task: 'w4k9qz2mx', run: 'wf_3f9c1a2b-7d4', name: 'checkout-review' } as const;\nconst FIXES = { call: 'toolu_demo_wf_fixes', task: 'w7p3m0rtc', run: 'wf_8e2d5b1c-a60', name: 'checkout-fixes' } as const;\n\nconst REVIEW_SCRIPT = `export const meta = {\n name: 'checkout-review',\n description: 'Review the checkout flow in two areas, then have a skeptic check each finding',\n phases: [\n { title: 'Review', detail: 'one agent per area' },\n { title: 'Verify', detail: 'a skeptic re-checks each finding' },\n ],\n}\n\nconst FINDINGS = { type: 'object', required: ['findings'], properties: { findings: { type: 'array', items: { type: 'object' } } } }\nconst VERDICTS = { type: 'object', required: ['verdicts'], properties: { verdicts: { type: 'array', items: { type: 'object' } } } }\n\nconst results = await pipeline(['server', 'client'],\n (area) => agent(\\`Review the \\${area} side of the checkout flow and list real defects.\\`, { label: \\`review:\\${area}\\`, phase: 'Review', schema: FINDINGS }),\n (found, area) => agent(\\`Re-check each finding for the \\${area}: \\${JSON.stringify(found)}\\`, { label: \\`verify:\\${area}\\`, phase: 'Verify', schema: VERDICTS }),\n)\nlog(\\`\\${results.filter(Boolean).length} areas verified\\`)\nreturn results\n`;\n\nconst FIXES_SCRIPT = `export const meta = {\n name: 'checkout-fixes',\n description: 'Fix the two confirmed findings, then run the checkout tests again',\n phases: [\n { title: 'Fix', detail: 'one agent per finding' },\n { title: 'Test', detail: 'the checkout tests, with the fixes in' },\n ],\n}\n\nconst fixed = await parallel(args.findings.map((finding) =>\n agent(\\`Fix this finding, with a test that fails without the fix: \\${finding.title} (\\${finding.file})\\`, { label: \\`fix:\\${finding.slug}\\`, phase: 'Fix' }),\n))\nreturn agent('Run the checkout tests and report what fails.', { label: 'test:checkout', phase: 'Test' })\n`;\n\nconst RESULT = [\n { verdicts: [{ finding: 'The checkout accepts an empty card holder name', file: 'src/server/checkout.ts:6', verdict: 'confirmed' }] },\n { verdicts: [{ finding: 'The order summary shows the customer name unescaped', file: 'src/checkout/Summary.tsx:5', verdict: 'confirmed' }] },\n];\n\nconst launchText = (flow: { task: string; run: string; name: string }, summary: string, dir: string) => {\n const script = `${dir}/workflows/scripts/${flow.name}-${flow.run}.js`;\n return [\n `Workflow launched in background. Task ID: ${flow.task}`,\n `Summary: ${summary}`,\n `Transcript dir: ${dir}/subagents/workflows/${flow.run}`,\n `Script file: ${script}`,\n `(Edit this file with Write/Edit and re-invoke Workflow with {scriptPath: \"${script}\"} to iterate without resending the script.)`,\n `Run ID: ${flow.run}`,\n `To resume after editing the script: Workflow({scriptPath: \"${script}\", resumeFromRunId: \"${flow.run}\"}) \u2014 completed agents return cached results (cached results may themselves be empty \u2014 inspect journal.jsonl before assuming there is something to recover).`,\n '',\n 'You will be notified when it completes. Use /workflows to watch live progress.',\n ].join('\\n');\n};\n\nconst launched = (flow: { task: string; run: string; name: string }, summary: string, dir: string) => ({\n status: 'async_launched', taskId: flow.task, taskType: 'local_workflow', workflowName: flow.name, runId: flow.run, summary,\n transcriptDir: `${dir}/subagents/workflows/${flow.run}`, scriptPath: `${dir}/workflows/scripts/${flow.name}-${flow.run}.js`,\n});\n\nconst REVIEW_SUMMARY = 'Review the checkout flow in two areas, then have a skeptic check each finding';\nconst FIXES_SUMMARY = 'Fix the two confirmed findings, then run the checkout tests again';\n\nconst tool = (id: string, name: string, input: Record<string, unknown>) => ({ type: 'tool_use', id, name, input });\nconst text = (value: string) => ({ type: 'text', text: value });\n\n/** How many tool calls an agent made: as many as its transcript holds, so its figures and its steps agree. */\nfunction toolCalls(agentId: string): number {\n const own = steps('')[agentId]?.steps ?? [];\n return own.filter((s) => s.role === 'assistant').flatMap((s) => s.content).filter((b) => (b as { type?: unknown }).type === 'tool_use').length;\n}\n\n/** The finished review: when it started and ended, and its agents as Claude Code's record keeps them. */\nfunction reviewAgents(start: number): WorkflowAgent[] {\n const agent = (index: number, label: string, phase: 1 | 2, agentId: string, at: number, ms: number, tokens: number, result: unknown, prompt: string, lastToolName: string): WorkflowAgent => ({\n index, label, phaseIndex: phase, phaseTitle: phase === 1 ? 'Review' : 'Verify', agentId, model: 'claude-opus-5-5', state: 'done',\n queuedAt: start + at, startedAt: start + at, lastProgressAt: start + at + ms, durationMs: ms, tokens, toolCalls: toolCalls(agentId), attempt: 1, lastToolName,\n resultPreview: JSON.stringify(result), promptPreview: prompt,\n });\n return [\n agent(1, 'review:server', 1, 'a1c3e5a7b9d1f3a52', 20, 181_000, 120_800, { findings: [{ title: 'The checkout accepts an empty card holder name', file: 'src/server/checkout.ts:6' }] }, 'Review the server side of the checkout flow and list real defects.', 'StructuredOutput'),\n agent(2, 'review:client', 1, 'a2d4f6b8c0e2a4b63', 22, 95_300, 88_200, { findings: [{ title: 'The order summary shows the customer name unescaped', file: 'src/checkout/Summary.tsx:5' }] }, 'Review the client side of the checkout flow and list real defects.', 'StructuredOutput'),\n agent(3, 'verify:server', 2, 'a3e5a7c9d1f3b5c74', 181_100, 180_000, 131_900, RESULT[0], 'Re-check each finding for the server: [The checkout accepts an empty card holder name]', 'StructuredOutput'),\n agent(4, 'verify:client', 2, 'a4f6b8d0e2a4c6d85', 95_400, 52_000, 71_400, RESULT[1], 'Re-check each finding for the client: [The order summary shows the customer name unescaped]', 'StructuredOutput'),\n ];\n}\n\n/** The review's totals, as Claude Code sums its agents'. */\nconst reviewTotals = () => {\n const agents = reviewAgents(0);\n return { tokens: agents.reduce((sum, a) => sum + (a.tokens ?? 0), 0), toolCalls: agents.reduce((sum, a) => sum + (a.toolCalls ?? 0), 0) };\n};\n\n/** The fixes, still at work: one agent done, one running (its edit under way), the tests up next. */\nfunction fixAgents(start: number, now: number): WorkflowAgent[] {\n return [\n {\n index: 1, label: 'fix:empty-name', phaseIndex: 1, phaseTitle: 'Fix', agentId: 'b1a3c5e7d9f1a3b52', model: 'claude-opus-5-5', state: 'done',\n queuedAt: start + 30, startedAt: start + 30, lastProgressAt: start + 61_000, durationMs: 61_000, tokens: 54_300, toolCalls: toolCalls('b1a3c5e7d9f1a3b52'), attempt: 1,\n lastToolName: 'Bash', resultPreview: 'The checkout now refuses an empty card holder name, with a test that fails without the fix.',\n promptPreview: 'Fix this finding, with a test that fails without the fix: The checkout accepts an empty card holder name (src/server/checkout.ts:6)',\n },\n {\n index: 2, label: 'fix:unescaped-name', phaseIndex: 1, phaseTitle: 'Fix', agentId: 'b2b4d6f8e0a2b4c63', model: 'claude-opus-5-5', state: 'progress',\n queuedAt: start + 32, startedAt: start + 32, lastProgressAt: now - 6_000, tokens: 48_200, toolCalls: toolCalls('b2b4d6f8e0a2b4c63'), attempt: 1,\n lastToolName: 'Edit', lastToolSummary: 'src/checkout/Summary.tsx',\n promptPreview: 'Fix this finding, with a test that fails without the fix: The order summary shows the customer name unescaped (src/checkout/Summary.tsx:5)',\n },\n ];\n}\n\n/**\n * The fixes as this Pelican's Claude would report them while they run: as the runner sends them,\n * without the agents' prompts and results, which an agent opened reads from its own files (one\n * still queued, with none yet, keeps its prompt's preview).\n */\nexport function demoFixes(now = Date.now()): Workflow {\n const start = now - 2 * MIN - 41_000;\n const agents = fixAgents(start, now).map(({ promptPreview, resultPreview: _result, ...agent }) => (agent.agentId || !promptPreview ? agent : { ...agent, promptPreview }));\n return {\n runId: FIXES.run, taskId: FIXES.task, name: FIXES.name, description: FIXES_SUMMARY, status: 'running', startedAt: start,\n totalTokens: agents.reduce((sum, a) => sum + (a.tokens ?? 0), 0), totalToolCalls: agents.reduce((sum, a) => sum + (a.toolCalls ?? 0), 0),\n phases: [{ title: 'Fix', detail: 'one agent per finding' }, { title: 'Test', detail: 'the checkout tests, with the fixes in' }],\n agents, source: 'live',\n };\n}\n\n/** The session's run: Claude is done with its turn, and the fixes run on in the background. */\nexport function demoWorkflowRun(sessionId: string, cwd: string): RunState | undefined {\n if (sessionId !== WORKFLOW_SESSION) return undefined;\n const fixes = demoFixes();\n return {\n sessionId,\n cwd,\n busy: false,\n settings: { model: 'default', effort: 'high', permissionMode: 'acceptEdits' },\n partial: [],\n permissions: [],\n tasks: [{ id: FIXES.task, description: FIXES.name, type: 'local_workflow', summary: `${fixes.agents.filter((a) => a.state === 'done').length}/${fixes.agents.length} agents` }],\n workflows: { [FIXES.call]: fixes },\n lastTurn: { durationMs: 9_000, outputTokens: 610 },\n context: { percent: 18, tokens: 36_000, max: 200_000 },\n };\n}\n\n/** An agent's own transcript, as Claude Code writes one: a side chain, its prompt framed. */\nfunction agentTranscript(agentId: string, cwd: string, sessionId: string, prompt: string, steps: Array<{ at: number; content: unknown[]; role: 'user' | 'assistant' }>, start: number): string {\n let parent: string | null = null;\n const lines: string[] = [];\n const row = (uuid: string, type: 'user' | 'assistant', message: Record<string, unknown>, at: number) => {\n lines.push(JSON.stringify({ parentUuid: parent, isSidechain: true, agentId, type, message, uuid, timestamp: new Date(at).toISOString(), userType: 'external', cwd, sessionId, version: '2.1.318' }));\n parent = uuid;\n };\n const framed = `[Workflow harness \u2014 computed task] The task text below was computed at runtime by a workflow script. The computed task text follows:\\n${prompt.split('\\n').map((line) => ` ${line}`).join('\\n')}`;\n row(`${agentId}-0`, 'user', { role: 'user', content: framed }, start);\n steps.forEach((step, i) => {\n row(`${agentId}-${i + 1}`, step.role, step.role === 'assistant'\n ? { id: `msg_demo_${agentId}_${i}`, type: 'message', role: 'assistant', model: 'claude-opus-5-5', content: step.content }\n : { role: 'user', content: step.content }, start + step.at);\n });\n return `${lines.join('\\n')}\\n`;\n}\n\nconst result = (id: string, content: string) => ({ type: 'tool_result', tool_use_id: id, content });\n\n/** The steps each agent took, a few tool calls and what it returned. */\nfunction steps(cwd: string): Record<string, { prompt: string; steps: Array<{ at: number; role: 'user' | 'assistant'; content: unknown[] }> }> {\n const read = (id: string, file: string) => tool(id, 'Read', { file_path: `${cwd}/${file}` });\n const done = (id: string, value: unknown) => tool(id, 'StructuredOutput', value as Record<string, unknown>);\n return {\n a1c3e5a7b9d1f3a52: {\n prompt: 'Review the server side of the checkout flow and list real defects.',\n steps: [\n { at: 4_000, role: 'assistant', content: [tool('s1', 'Grep', { pattern: 'cardHolder', path: `${cwd}/src/server` })] },\n { at: 5_000, role: 'user', content: [result('s1', 'src/server/checkout.ts:6: const cardHolder = body.cardHolder ?? \\'\\'')] },\n { at: 9_000, role: 'assistant', content: [read('s2', 'src/server/checkout.ts')] },\n { at: 10_000, role: 'user', content: [result('s2', ' 46\\texport async function placeOrder(body: OrderBody) {\\n 47\\t const items = await cart.items(body.cartId)\\n 48\\t const cardHolder = body.cardHolder ?? \\'\\'\\n 49\\t return payments.charge({ items, cardHolder })\\n 50\\t}')] },\n { at: 30_000, role: 'assistant', content: [tool('s3', 'Bash', { command: 'npm test -- checkout', description: 'Run the checkout tests' })] },\n { at: 70_000, role: 'user', content: [result('s3', ' PASS test/checkout.test.ts (14 tests)\\n\\nTests: 14 passed, 14 total')] },\n { at: 180_000, role: 'assistant', content: [done('s4', { findings: [{ title: 'The checkout accepts an empty card holder name', file: 'src/server/checkout.ts:6' }] })] },\n { at: 181_000, role: 'user', content: [result('s4', 'Structured output provided successfully')] },\n ],\n },\n a2d4f6b8c0e2a4b63: {\n prompt: 'Review the client side of the checkout flow and list real defects.',\n steps: [\n { at: 3_000, role: 'assistant', content: [read('c1', 'src/checkout/Summary.tsx')] },\n { at: 4_000, role: 'user', content: [result('c1', ' 20\\t<h2>Order for</h2>\\n 21\\t<div dangerouslySetInnerHTML={{ __html: order.customerName }} />')] },\n { at: 40_000, role: 'assistant', content: [tool('c2', 'Grep', { pattern: 'dangerouslySetInnerHTML', path: `${cwd}/src` })] },\n { at: 41_000, role: 'user', content: [result('c2', 'src/checkout/Summary.tsx:5')] },\n { at: 95_000, role: 'assistant', content: [done('c3', { findings: [{ title: 'The order summary shows the customer name unescaped', file: 'src/checkout/Summary.tsx:5' }] })] },\n { at: 95_300, role: 'user', content: [result('c3', 'Structured output provided successfully')] },\n ],\n },\n a3e5a7c9d1f3b5c74: {\n prompt: 'Re-check each finding for the server: [The checkout accepts an empty card holder name]',\n steps: [\n { at: 5_000, role: 'assistant', content: [read('v1', 'src/server/checkout.ts')] },\n { at: 6_000, role: 'user', content: [result('v1', ' 48\\t const cardHolder = body.cardHolder ?? \\'\\'')] },\n { at: 60_000, role: 'assistant', content: [tool('v2', 'Bash', { command: 'curl -s -X POST localhost:3000/api/orders -d \\'{\"cartId\":\"c1\",\"cardHolder\":\"\"}\\'', description: 'Place an order with an empty name' })] },\n { at: 62_000, role: 'user', content: [result('v2', '{\"ok\":true,\"order\":\"o_1042\"}')] },\n { at: 179_000, role: 'assistant', content: [done('v3', RESULT[0])] },\n { at: 180_000, role: 'user', content: [result('v3', 'Structured output provided successfully')] },\n ],\n },\n a4f6b8d0e2a4c6d85: {\n prompt: 'Re-check each finding for the client: [The order summary shows the customer name unescaped]',\n steps: [\n { at: 20_000, role: 'assistant', content: [read('w1', 'src/checkout/Summary.tsx')] },\n { at: 21_000, role: 'user', content: [result('w1', ' 21\\t<div dangerouslySetInnerHTML={{ __html: order.customerName }} />')] },\n { at: 51_000, role: 'assistant', content: [done('w2', RESULT[1])] },\n { at: 52_000, role: 'user', content: [result('w2', 'Structured output provided successfully')] },\n ],\n },\n b1a3c5e7d9f1a3b52: {\n prompt: 'Fix this finding, with a test that fails without the fix: The checkout accepts an empty card holder name (src/server/checkout.ts:6)',\n steps: [\n { at: 3_000, role: 'assistant', content: [read('f1', 'src/server/checkout.ts')] },\n { at: 4_000, role: 'user', content: [result('f1', ' 48\\t const cardHolder = body.cardHolder ?? \\'\\'')] },\n { at: 20_000, role: 'assistant', content: [tool('f2', 'Edit', { file_path: `${cwd}/src/server/checkout.ts`, old_string: \" const cardHolder = body.cardHolder ?? ''\", new_string: \" const cardHolder = body.cardHolder?.trim()\\n if (!cardHolder) throw new OrderError('The card holder name is missing')\" })] },\n { at: 21_000, role: 'user', content: [result('f2', `The file ${cwd}/src/server/checkout.ts has been updated successfully.`)] },\n { at: 45_000, role: 'assistant', content: [tool('f3', 'Bash', { command: 'npm test -- checkout', description: 'Run the checkout tests' })] },\n { at: 59_000, role: 'user', content: [result('f3', ' PASS test/checkout.test.ts (15 tests)\\n\\nTests: 15 passed, 15 total')] },\n { at: 61_000, role: 'assistant', content: [text('The checkout now refuses an empty card holder name, with a test that fails without the fix.')] },\n ],\n },\n b2b4d6f8e0a2b4c63: {\n prompt: 'Fix this finding, with a test that fails without the fix: The order summary shows the customer name unescaped (src/checkout/Summary.tsx:5)',\n steps: [\n { at: 4_000, role: 'assistant', content: [read('g1', 'src/checkout/Summary.tsx')] },\n { at: 5_000, role: 'user', content: [result('g1', ' 21\\t<div dangerouslySetInnerHTML={{ __html: order.customerName }} />')] },\n { at: 50_000, role: 'assistant', content: [tool('g2', 'Grep', { pattern: 'customerName', path: `${cwd}/src` })] },\n { at: 51_000, role: 'user', content: [result('g2', 'src/checkout/Summary.tsx:5\\nsrc/checkout/Receipt.tsx:9')] },\n // At work on it now: the edit its row names, not answered yet.\n { at: 95_000, role: 'assistant', content: [tool('g3', 'Edit', { file_path: `${cwd}/src/checkout/Summary.tsx`, old_string: ' <div dangerouslySetInnerHTML={{ __html: order.customerName }} />', new_string: ' <div>{order.customerName}</div>' })] },\n ],\n },\n };\n}\n\nconst meta = (label: string, phase: string) => JSON.stringify({ agentType: 'workflow-subagent', isBuiltIn: true, description: label, workflowPhase: phase, spawnDepth: 1, requestShape: 'foreground', requestNonInteractive: true, pickedEffortModel: 'claude-opus-5-5' });\n\nconst key = (n: number) => `v2:${n.toString(16).padStart(64, '0')}`;\n\n/** The session's own folder, as Claude Code leaves it: the record, the journals, the agents, the scripts. */\nfunction files(cwd: string, dir: string, sessionId: string, reviewStart: number, fixesStart: number): Record<string, string> {\n const review = reviewAgents(reviewStart);\n const fixes = fixAgents(fixesStart, Date.now());\n const all = steps(cwd);\n const out: Record<string, string> = {\n [`workflows/scripts/${REVIEW.name}-${REVIEW.run}.js`]: REVIEW_SCRIPT,\n [`workflows/scripts/${FIXES.name}-${FIXES.run}.js`]: FIXES_SCRIPT,\n [`workflows/${REVIEW.run}.json`]: JSON.stringify({\n runId: REVIEW.run, timestamp: new Date(reviewStart + 361_250).toISOString(), taskId: REVIEW.task, script: REVIEW_SCRIPT,\n scriptPath: `${dir}/workflows/scripts/${REVIEW.name}-${REVIEW.run}.js`, result: RESULT, agentCount: 4, logs: ['2 areas verified'],\n durationMs: 361_250, summary: REVIEW_SUMMARY, workflowName: REVIEW.name, status: 'completed', startTime: reviewStart,\n phases: [{ title: 'Review', detail: 'one agent per area' }, { title: 'Verify', detail: 'a skeptic re-checks each finding' }], defaultModel: 'claude-opus-5-5',\n workflowProgress: [{ type: 'workflow_phase', index: 1, title: 'Review' }, { type: 'workflow_phase', index: 2, title: 'Verify' }, ...review.map((a) => ({ type: 'workflow_agent', ...a }))],\n totalTokens: reviewTotals().tokens, totalToolCalls: reviewTotals().toolCalls,\n }),\n };\n const journal = (run: string, agents: WorkflowAgent[]) => [\n JSON.stringify({ type: 'launched' }),\n ...agents.flatMap((a, i) => [\n JSON.stringify({ type: 'started', key: key(i + 1), agentId: a.agentId, label: a.label, phase: a.phaseTitle }),\n ...(a.state === 'done' ? [JSON.stringify({ type: 'result', key: key(i + 1), agentId: a.agentId, result: JSON.parse(a.resultPreview!.startsWith('{') ? a.resultPreview! : JSON.stringify(a.resultPreview)), remoteControlDeviceReport: false, toolsUsed: ['Read', 'StructuredOutput'] })] : []),\n ]),\n ].join('\\n');\n out[`subagents/workflows/${REVIEW.run}/journal.jsonl`] = `${journal(REVIEW.run, review)}\\n`;\n out[`subagents/workflows/${FIXES.run}/journal.jsonl`] = `${journal(FIXES.run, fixes)}\\n`;\n for (const [run, agents] of [[REVIEW.run, review], [FIXES.run, fixes]] as const) {\n for (const agent of agents) {\n const own = all[agent.agentId!]!;\n out[`subagents/workflows/${run}/agent-${agent.agentId}.meta.json`] = meta(agent.label, agent.phaseTitle!);\n out[`subagents/workflows/${run}/agent-${agent.agentId}.jsonl`] = agentTranscript(agent.agentId!, cwd, sessionId, own.prompt, own.steps, agent.startedAt!);\n }\n }\n return out;\n}\n\nconst notice = () => [\n '<task-notification>',\n `<task-id>${REVIEW.task}</task-id>`,\n `<tool-use-id>${REVIEW.call}</tool-use-id>`,\n `<output-file>/tmp/claude-501/demo/${WORKFLOW_SESSION}/tasks/${REVIEW.task}.output</output-file>`,\n '<status>completed</status>',\n `<summary>Dynamic workflow \"${REVIEW_SUMMARY}\" completed</summary>`,\n `<result>${JSON.stringify(RESULT)}</result>`,\n '<usage><agent_count>4</agent_count><agents_done>4</agents_done><agents_error>0</agents_error><agents_skipped>0</agents_skipped><agents_empty_result>0</agents_empty_result>'\n + `<subagent_tokens>${reviewTotals().tokens}</subagent_tokens><tool_uses>${reviewTotals().toolCalls}</tool_uses><duration_ms>${361_250}</duration_ms></usage>`,\n '</task-notification>',\n].join('\\n');\n\n/** The session itself: the request, the review, what held up, and the fixes it started. */\nexport const WORKFLOW_DEMO: DemoSession = {\n id: WORKFLOW_SESSION,\n title: 'Review the checkout flow before the release',\n project: 'acme-web',\n branch: 'fix/checkout',\n rows: (cwd, dir = cwd) => {\n const { reviewStart, fixesStart } = times();\n const t = reviewStart - 6_000;\n const rows: Row[] = [\n { role: 'user', at: t, content: 'Review the checkout flow before the release: the server and the client, with a second look at each finding. Then fix what holds up.' },\n {\n role: 'assistant',\n at: t + 5_000,\n content: [text('I\\'ll run it as a workflow: one reviewer per area, then a skeptic re-checks what each one found.'), tool(REVIEW.call, 'Workflow', { script: REVIEW_SCRIPT })],\n },\n { role: 'user', at: reviewStart, content: [result(REVIEW.call, launchText(REVIEW, REVIEW_SUMMARY, dir))], result: launched(REVIEW, REVIEW_SUMMARY, dir) },\n { role: 'assistant', at: reviewStart + 3_000, content: [text('The review is running in the background. I\\'ll read the findings when it is done.')] },\n { role: 'user', at: reviewStart + 361_300, content: notice() },\n {\n role: 'assistant',\n at: reviewStart + 380_000,\n content: [\n text('Both findings held up:\\n\\n- **The checkout accepts an empty card holder name** (`src/server/checkout.ts:6`): the order goes through and the payment fails later.\\n- **The order summary shows the customer name unescaped** (`src/checkout/Summary.tsx:5`): a name with markup in it runs in the page.\\n\\nI\\'ll fix both, each with a test, then run the checkout tests again.'),\n tool(FIXES.call, 'Workflow', { script: FIXES_SCRIPT, args: { findings: [{ slug: 'empty-name', title: RESULT[0]!.verdicts[0]!.finding, file: 'src/server/checkout.ts:6' }, { slug: 'unescaped-name', title: RESULT[1]!.verdicts[0]!.finding, file: 'src/checkout/Summary.tsx:5' }] } }),\n ],\n },\n { role: 'user', at: fixesStart, content: [result(FIXES.call, launchText(FIXES, FIXES_SUMMARY, dir))], result: launched(FIXES, FIXES_SUMMARY, dir) },\n { role: 'assistant', at: fixesStart + 4_000, content: [text('The fixes are running in the background, one agent per finding, then the tests. I\\'ll say what the tests find.')] },\n ];\n return rows;\n },\n files: (cwd, dir) => {\n const { reviewStart, fixesStart } = times();\n return files(cwd, dir, WORKFLOW_SESSION, reviewStart, fixesStart);\n },\n};\n\n/** When the review ran and the fixes started: written once, when the demo starts. */\nlet started: { reviewStart: number; fixesStart: number } | undefined;\nfunction times() {\n if (!started) {\n const fixesStart = Date.now() - 2 * MIN - 41_000;\n started = { reviewStart: fixesStart - 361_250 - 50_000, fixesStart };\n }\n return started;\n}\n\nexport const DEMO_WORKFLOW_FILES = {\n 'src/server/checkout.ts': \"import { cart } from './cart';\\nimport { payments } from './payments';\\n\\nexport async function placeOrder(body: OrderBody) {\\n const items = await cart.items(body.cartId)\\n const cardHolder = body.cardHolder ?? ''\\n return payments.charge({ items, cardHolder })\\n}\\n\",\n 'src/checkout/Summary.tsx': \"export function Summary({ order }: { order: Order }) {\\n return (\\n <section>\\n <h2>Order for</h2>\\n <div dangerouslySetInnerHTML={{ __html: order.customerName }} />\\n </section>\\n );\\n}\\n\",\n};\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 { lineDiff, splitLines, toHunks } from '../shared/line-diff.js';\nimport type { ModelOption, RunState, SessionStatus, TaskOutput } from '../shared/protocol.js';\nimport { config } from './config.js';\nimport type { LiveProcess } from './live.js';\nimport { SETTINGS_SCREENSHOT } from './demo-image.js';\nimport { demoRowUsage, writeDemoUsage } from './demo-usage.js';\nimport { DEMO_WORKFLOW_FILES, demoWorkflowRun, WORKFLOW_DEMO } from './demo-workflows.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>;\n/**\n * A transcript row. `model` and `extra`: what Claude Code writes on rows that are not a reply of\n * the model's own (an API error). `result`: what Claude Code records of a tool's result next to it\n * (an edit's structured patch); `checkpoint`: Claude Code kept the files as they were before this prompt.\n */\nexport type Row = { role: 'user' | 'assistant'; content: string | Block[]; at: number; model?: string; extra?: Record<string, unknown>; result?: Record<string, unknown>; checkpoint?: boolean };\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, from = 1): string {\n return source.split('\\n').map((line, i) => `${String(i + from).padStart(6)}\\t${line}`).join('\\n');\n}\n\n/** The line a text's first line starting with `start` is on. */\nconst lineOf = (text: string, start: string) => text.split('\\n').findIndex((line) => line.startsWith(start)) + 1;\n\n/** What Claude Code's Read shows of a file from line `offset` on, `limit` lines at most. */\nconst read = (text: string, offset: number, limit: number) => numbered(text.replace(/\\n$/, '').split('\\n').slice(offset - 1, offset - 1 + limit).join('\\n'), offset);\n\nconst EXPORT_PY = `\"\"\"The nightly export: every account, with its owner, to the warehouse, in batches.\"\"\"\n\nimport argparse\nimport logging\nimport time\n\nfrom pipeline import db\nfrom pipeline.writer import write\n\nlog = logging.getLogger(__name__)\n\nBATCH_SIZE = 5_000\n\n\ndef batches(rows, size=BATCH_SIZE):\n \"\"\"Yields the rows in batches, the last one shorter.\"\"\"\n batch = []\n for row in rows:\n batch.append(row)\n if len(batch) == size:\n yield batch\n batch = []\n if batch:\n yield batch\n\n\ndef run(sample=None):\n \"\"\"Exports every account, or only a sample of them.\"\"\"\n started = time.monotonic()\n for batch in batches(db.account_rows(limit=sample)):\n export_rows(batch)\n log.info(\"exported in %.1f s\", time.monotonic() - started)\n\n\ndef export_rows(batch):\n for row in batch:\n owner = db.fetch_owner(row.owner_id)\n write(row, owner)\n\n\nif __name__ == \"__main__\":\n parser = argparse.ArgumentParser()\n parser.add_argument(\"--sample\", type=int, help=\"export only this many accounts\")\n run(parser.parse_args().sample)\n`;\n\nconst DB_PY = `\"\"\"The accounts database, read only.\"\"\"\n\nimport os\n\nimport psycopg\nfrom psycopg.rows import namedtuple_row\n\n_conn = None\n\n\ndef connect():\n global _conn\n if _conn is None:\n _conn = psycopg.connect(os.environ[\"DATABASE_URL\"], row_factory=namedtuple_row)\n return _conn\n\n\ndef account_rows(limit=None):\n \"\"\"Every account, oldest first.\"\"\"\n sql = \"SELECT id, owner_id, plan, created_at FROM accounts ORDER BY id\"\n if limit:\n sql += f\" LIMIT {int(limit)}\"\n with connect().cursor() as cur:\n cur.execute(sql)\n yield from cur\n\n\ndef fetch_owner(owner_id):\n \"\"\"One account's owner: a query of its own.\"\"\"\n with connect().cursor() as cur:\n cur.execute(\"SELECT id, name, email FROM owners WHERE id = %s\", (owner_id,))\n return cur.fetchone()\n`;\n\nconst WRITER_PY = `\"\"\"Writes the export as CSV, one account a line.\"\"\"\n\nimport csv\nimport sys\n\n_out = csv.writer(sys.stdout)\n\n\ndef write(row, owner):\n \"\"\"An account with its owner's name and email.\"\"\"\n _out.writerow([row.id, row.plan, row.created_at.isoformat(), owner.name, owner.email])\n`;\n\nconst TEST_EXPORT_PY = `from pipeline import export\n\n\nclass Row:\n def __init__(self, id, owner_id):\n self.id = id\n self.owner_id = owner_id\n\n\ndef test_every_row_is_written_with_its_owner(monkeypatch):\n written = []\n monkeypatch.setattr(export.db, \"fetch_owner\", lambda owner_id: f\"owner {owner_id}\")\n monkeypatch.setattr(export, \"write\", lambda row, owner: written.append((row.id, owner)))\n export.export_rows([Row(1, 10), Row(2, 20)])\n assert written == [(1, \"owner 10\"), (2, \"owner 20\")]\n`;\n\n/** Where the slow export's loop is, as the session finds it. */\nconst EXPORT_AT = lineOf(EXPORT_PY, 'def export_rows');\n\n/** What Claude Code records of an Edit: the file before, and the patch it made of it. */\nfunction edited(file: string, before: string, oldString: string, newString: string): Record<string, unknown> {\n const after = before.replace(oldString, newString);\n return {\n filePath: file, oldString, newString, originalFile: before,\n structuredPatch: toHunks(lineDiff(splitLines(before), splitLines(after)) ?? []), userModified: false, replaceAll: false,\n };\n}\n\n/** What Claude Code records of a Write that made a file. */\nconst created = (file: string, content: string) => ({ type: 'create', filePath: file, content, structuredPatch: [], originalFile: null });\n\n/**\n * `copies`: a side chat's session, whose conversation it starts with (as forkSession copies one).\n * `files`: what Claude Code keeps in the session's own folder (`dir`), next to its transcript.\n */\nexport type DemoSession = {\n id: string; title: string; project: string; branch: string; rows: (cwd: string, dir?: string) => Row[]; scratch?: boolean; copies?: string;\n files?: (cwd: string, dir: string) => Record<string, string>;\n};\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 DARK_OLD = ' --accent: #2563eb;\\n}';\nconst DARK_NEW = \" --accent: #2563eb;\\n}\\n\\n:root[data-theme='dark'] {\\n --bg: #0b0b0c;\\n --fg: #ededed;\\n --muted: #a1a1a1;\\n --accent: #60a5fa;\\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 LOGIN_OLD = \" await page.waitForTimeout(500);\\n await page.click('text=Sign in');\";\nconst LOGIN_NEW = \" await expect(page.locator('input[name=csrf]')).not.toHaveValue('');\\n await page.click('text=Sign in');\";\n\n/** The login test as the fix left it. */\nconst LOGIN_SPEC = `import { expect, test } from '@playwright/test';\n\ntest('signs in with a valid password', async ({ page }) => {\n await page.goto('/login');\n await page.fill('input[name=email]', 'ada@example.com');\n await page.fill('input[name=password]', 'correct horse');\n${LOGIN_NEW}\n await expect(page).toHaveURL('/settings');\n});\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 checkpoint: true,\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: DARK_OLD,\n new_string: DARK_NEW,\n })],\n },\n {\n role: 'user',\n at: t + 15000,\n content: [result('t3', `The file ${cwd}/src/styles/theme.css has been updated successfully.`)],\n result: edited(`${cwd}/src/styles/theme.css`, `${THEME_CSS}\\n`, DARK_OLD, DARK_NEW),\n },\n { role: 'assistant', at: t + 17000, content: [tool('t4', 'Write', { file_path: `${cwd}/src/settings/ThemeToggle.tsx`, content: TOGGLE_TSX })] },\n {\n role: 'user',\n at: t + 18000,\n content: [result('t4', `File created successfully at: ${cwd}/src/settings/ThemeToggle.tsx`)],\n result: created(`${cwd}/src/settings/ThemeToggle.tsx`, TOGGLE_TSX),\n },\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:${EXPORT_AT}:def export_rows(batch):`)] },\n { role: 'assistant', at: t + 9000, content: [tool('g2', 'Read', { file_path: `${cwd}/pipeline/export.py`, offset: EXPORT_AT, limit: 30 })] },\n { role: 'user', at: t + 10000, content: [result('g2', read(EXPORT_PY, EXPORT_AT, 30))] },\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:${lineOf(DB_PY, 'def fetch_owner')}(fetch_owner)\\n 1 0.020 62.410 export.py:${EXPORT_AT}(export_rows)\\n 5000 0.301 0.488 writer.py:${lineOf(WRITER_PY, 'def write')}(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, checkpoint: true, 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: LOGIN_OLD,\n new_string: LOGIN_NEW,\n })],\n },\n {\n role: 'user',\n at: t + 96000,\n content: [result('p2', `The file ${cwd}/tests/login.spec.ts has been updated successfully.`)],\n result: edited(`${cwd}/tests/login.spec.ts`, LOGIN_SPEC.replace(LOGIN_NEW, LOGIN_OLD), LOGIN_OLD, LOGIN_NEW),\n },\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, checkpoint: true, 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 {\n role: 'user',\n at: t + 17000,\n content: [result('v3', `File created successfully at: ${cwd}/reports/signups-week-45.html`)],\n result: created(`${cwd}/reports/signups-week-45.html`, REPORT_HTML),\n },\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 // A side question asked while Claude waited on the toggle's edit: listed under that session.\n {\n id: 'a3f1c2d4-1111-4a1b-8c3d-0000000000a1',\n title: 'Side chat',\n project: 'acme-web',\n branch: 'feat/dark-theme',\n copies: 'a3f1c2d4-1111-4a1b-8c3d-000000000001',\n rows: () => {\n const t = Date.now() - 2 * MIN;\n return [\n { role: 'user', at: t, content: 'Why CSS variables, and not a theme context in React?' },\n {\n role: 'assistant',\n at: t + 7000,\n content: [text('The colors already live in `theme.css` as variables, so switching `data-theme` on the root changes them everywhere at once, plain CSS included, without rendering any component again. A context reaches only React components, and each one that reads it renders again on every switch.')],\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 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 PACKAGE_JSON = `${JSON.stringify({\n name: 'acme-web',\n version: '1.4.0',\n private: true,\n type: 'module',\n scripts: { dev: 'vite', build: 'vite build', test: 'playwright test' },\n dependencies: { react: '^19.2.0', 'react-dom': '^19.2.0' },\n devDependencies: { '@playwright/test': '^1.56.0', vite: '^7.1.4' },\n}, null, 2)}\\n`;\n\nconst APP_TSX = `import { createRoot } from 'react-dom/client';\n\nimport { Settings } from './settings/Settings';\nimport './styles/theme.css';\n\ncreateRoot(document.getElementById('root')!).render(<Settings />);\n`;\n\nconst RELEASES_MD = `# Releases\n\n## v2.3\n\n- Projects can be shared with a link that expires.\n- The export page shows how far an export got.\n- Fixed: two-factor codes from some authenticator apps were refused.\n\n## v2.2\n\n- Invite your team from Settings.\n- Search is faster in large projects.\n`;\n\n/** Every demo file has text, as the conversations show it; ThemeToggle.tsx also where git is missing. */\nconst FILE_TEXT: Record<string, string> = {\n 'acme-web/package.json': PACKAGE_JSON,\n 'acme-web/src/app.tsx': APP_TSX,\n 'acme-web/src/styles/theme.css': `${THEME_CSS}\\n`,\n 'acme-web/src/settings/Settings.tsx': SETTINGS_TSX,\n 'acme-web/src/settings/ThemeToggle.tsx': TOGGLE_TSX,\n 'acme-web/README.md': '# acme-web\\n\\nThe Acme web app.\\n',\n 'acme-web/tests/login.spec.ts': LOGIN_SPEC,\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/pipeline/export.py': EXPORT_PY,\n 'data-pipeline/pipeline/db.py': DB_PY,\n 'data-pipeline/pipeline/writer.py': WRITER_PY,\n 'data-pipeline/reports/signups-week-45.html': REPORT_HTML,\n 'data-pipeline/tests/test_export.py': TEST_EXPORT_PY,\n 'docs-site/README.md': '# docs-site\\n\\nThe public docs.\\n',\n 'docs-site/docs/releases.md': RELEASES_MD,\n};\n\n/**\n * The first project is a git repository: main, a branch with one commit of its own, and Claude's\n * work so far left uncommitted, so Changes has something to show since the last commit and since\n * the branch split. It has a remote, as a repository you push from does, at an address nothing\n * answers (nothing in the demo contacts it). 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', 'main']);\n await git(['remote', 'add', 'origin', 'https://git.example.com/acme/acme-web.git']);\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 git(['switch', '-q', '-c', 'feat/dark-theme']);\n await writeFile(path.join(dir, 'README.md'), README_THEMES);\n await git(['commit', '-q', '--no-verify', '-am', 'Say in the README where the colors live']);\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 README_THEMES = '# acme-web\\n\\nThe Acme web app.\\n\\n## Colors\\n\\nEvery color is a CSS variable in `src/styles/theme.css`.\\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// ---- What runs on and what waits (0.4.0): a command still running after its turn, a turn that\n// ---- stopped on an API error, and a session waiting for an answer in the terminal.\n\nconst DEV_SERVER: DemoSession = {\n id: 'c4b7d2e9-8888-4c8d-9e1f-000000000010',\n title: 'Try the dark theme on my phone',\n project: 'acme-web',\n branch: 'feat/dark-theme',\n rows: () => {\n const t = Date.now() - 41 * MIN;\n return [\n { role: 'user', at: t, content: 'Start the dev server so I can try the dark theme on my phone.' },\n { role: 'assistant', at: t + 4000, content: [tool('d1', 'Bash', { command: 'npm run dev -- --host', description: 'Start the dev server', run_in_background: true })] },\n { role: 'user', at: t + 6000, content: [result('d1', 'Command running in background with ID: bash_1')] },\n {\n role: 'assistant',\n at: t + 11000,\n content: [text('The dev server is up. On your phone, open **http://192.168.1.24:5173** and switch the theme under Settings \u203A Display.\\n\\nIt keeps running after this; stop it when you are done.')],\n },\n ];\n },\n};\n\n/** What the dev server printed, for its Output sheet. */\nconst DEV_SERVER_OUTPUT = '> acme-web@1.4.0 dev\\n> vite --host\\n\\n VITE v7.1.4 ready in 412 ms\\n\\n \u279C Local: http://localhost:5173/\\n \u279C Network: http://192.168.1.24:5173/\\n';\n\nconst GETTING_STARTED = `# Getting started\n\nInstall the CLI, then sign in:\n\n\\`\\`\\`\nnpm install -g acme-cli\nacme login\n\\`\\`\\`\n\nYour first project is created for you. Open it with \\`acme open\\`, and invite your team from Settings.\n`;\n\nconst STOPPED_ON_ERROR: DemoSession = {\n id: 'e6f9a3b1-9999-4e9f-a0b2-000000000011',\n title: 'Proofread the getting started guide',\n project: 'docs-site',\n branch: 'main',\n rows: (cwd) => {\n const t = Date.now() - 2 * HOUR - 12 * MIN;\n return [\n { role: 'user', at: t, content: 'Proofread docs/getting-started.md. Fix typos only, keep the wording.' },\n {\n role: 'assistant',\n at: t + 3000,\n content: [\n { type: 'thinking', thinking: 'Typos only, so sentences stay as they are even where I would phrase them differently. I will read the whole guide before changing anything.', signature: 'demo' },\n tool('e1', 'Read', { file_path: `${cwd}/docs/getting-started.md` }),\n ],\n },\n { role: 'user', at: t + 4000, content: [result('e1', numbered(GETTING_STARTED.trimEnd()))] },\n // Claude Code's note that the call failed, written in place of a reply.\n {\n role: 'assistant',\n at: t + 70000,\n model: '<synthetic>',\n extra: { isApiErrorMessage: true, error: 'overloaded' },\n content: [text('API Error: 529 {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"}}')],\n },\n ];\n },\n};\n\nconst WAITING_IN_TERMINAL: DemoSession = {\n id: 'f7a1b4c2-aaaa-4fa1-b2c3-000000000012',\n title: 'Clean up old exports',\n project: 'data-pipeline',\n branch: 'main',\n rows: () => {\n const t = Date.now() - 7 * MIN;\n return [\n { role: 'user', at: t, content: 'Delete the exports older than 30 days, but tell me how many first.' },\n { role: 'assistant', at: t + 4000, content: [tool('w1', 'Bash', { command: \"find exports -name '*.csv' -mtime +30 | wc -l\", description: 'Count exports older than 30 days' })] },\n { role: 'user', at: t + 5000, content: [result('w1', ' 214')] },\n {\n role: 'assistant',\n at: t + 9000,\n content: [\n text('214 exports are older than 30 days. Deleting them now.'),\n tool('w2', 'Bash', { command: \"find exports -name '*.csv' -mtime +30 -delete\", description: 'Delete exports older than 30 days' }),\n ],\n },\n ];\n },\n};\n\nSESSIONS.push(DEV_SERVER, STOPPED_ON_ERROR, WAITING_IN_TERMINAL);\nDEMO_FILES['docs-site']!.push('docs/getting-started.md');\nFILE_TEXT['docs-site/docs/getting-started.md'] = GETTING_STARTED;\n\n// A review run as a workflow that finished, and the fixes it led to, still running.\nSESSIONS.push(WORKFLOW_DEMO);\nfor (const [file, content] of Object.entries(DEMO_WORKFLOW_FILES)) {\n DEMO_FILES['acme-web']!.push(file);\n FILE_TEXT[`acme-web/${file}`] = content;\n}\n\nconst DEV_TASK = { id: 'bash_1', description: 'Start the dev server', type: 'local_bash', output: true };\n\n/** The dev server Claude left running: its session is idle, with one task. */\nfunction devServerRun(sessionId: string): RunState | undefined {\n if (sessionId !== DEV_SERVER.id) return undefined;\n return {\n sessionId,\n cwd: path.join(config.home, 'code', DEV_SERVER.project),\n busy: false,\n settings: { model: 'default', effort: 'high', permissionMode: 'default' },\n partial: [],\n permissions: [],\n tasks: [DEV_TASK],\n lastTurn: { durationMs: 11_000, outputTokens: 184 },\n context: { percent: 12, tokens: 24_000, max: 200_000 },\n };\n}\n\n/** What a demo task printed, for its Output sheet. */\nexport function demoTaskOutput(sessionId: string, taskId: string): TaskOutput | undefined {\n return sessionId === DEV_SERVER.id && taskId === DEV_TASK.id ? { output: DEV_SERVER_OUTPUT, truncated: false } : undefined;\n}\n\n/** Sessions other apps have: one at work in Claude Desktop, one waiting in the terminal for a permission. */\nexport function demoLiveProcesses(): Map<string, LiveProcess> {\n return new Map<string, LiveProcess>([\n [DEMO_LIVE_SESSION, { app: 'Claude Desktop', busy: true }],\n [WAITING_IN_TERMINAL.id, { app: 'the terminal', busy: true, waiting: 'permission prompt', waitingSince: Date.now() - 6 * MIN }],\n ]);\n}\n\n/** What the demo's own runs are doing, as runStatus says it for a real one. */\nexport function demoRunStatus(sessionId: string): SessionStatus | undefined {\n const run = demoRunState(sessionId);\n return run && (run.permissions.length > 0 ? 'waiting' : run.busy ? 'running' : 'idle');\n}\n\n/** Work a demo run has going between turns, as runTasks counts it. */\nexport function demoRunTasks(sessionId: string): number {\n const run = demoRunState(sessionId);\n return run && !run.busy ? (run.tasks?.length ?? 0) + (run.scheduled?.length ?? 0) : 0;\n}\n\n// ---- End of what runs on and what waits.\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 const written = new Map<string, Array<{ row: Row; uuid: string; message: Record<string, unknown>; meta: Record<string, unknown> }>>();\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 // A side chat starts with the conversation it is about, as the Agent SDK's forkSession leaves\n // one: each row under the copy's id, as it was written there, saying which row it came from.\n const copied = (session.copies ? written.get(session.copies) ?? [] : []).map((entry) => ({ ...entry, uuid: randomUUID(), from: entry.uuid as string | undefined }));\n const own = session.rows(cwd, path.join(dir, session.id)).map((row) => {\n const uuid = randomUUID();\n // A row the model did not write (an API error) used no tokens.\n const { usage, ...meta } = demoRowUsage(session.id, row.role === 'assistant' && !row.model ? 'assistant' : 'user');\n const message = row.role === 'assistant'\n ? { id: `msg_demo_${uuid.slice(0, 8)}`, type: 'message', role: 'assistant', model: row.model ?? 'claude-opus-5-5', content: row.content, ...(usage ? { usage } : {}) }\n : { role: 'user', content: row.content };\n return { row, uuid, message, meta, from: undefined as string | undefined };\n });\n written.set(session.id, own);\n for (const { row, uuid, message, meta, from } of [...copied, ...own]) {\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(), ...meta, ...row.extra,\n ...(row.result ? { toolUseResult: row.result } : {}),\n ...(from && session.copies ? { forkedFrom: { sessionId: session.copies, messageUuid: from } } : {}),\n }));\n // Files kept for a prompt of the session's own: forkSession copies no checkpoints with the rows.\n if (row.checkpoint && !from) {\n const at = new Date(row.at).toISOString();\n lines.push(JSON.stringify({ type: 'file-history-snapshot', messageId: uuid, snapshot: { messageId: uuid, trackedFileBackups: {}, timestamp: at }, isSnapshotUpdate: false }));\n }\n parent = uuid;\n }\n await writeFile(path.join(dir, `${session.id}.jsonl`), `${lines.join('\\n')}\\n`);\n for (const [file, content] of Object.entries(session.files?.(cwd, path.join(dir, session.id)) ?? {})) {\n const full = path.join(dir, session.id, file);\n await mkdir(path.dirname(full), { recursive: true });\n await writeFile(full, content);\n }\n }\n await writeDemoUsage(root, claudeHome);\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 devServer = devServerRun(sessionId);\n if (devServer) return devServer;\n const workflows = demoWorkflowRun(sessionId, path.join(config.home, 'code', WORKFLOW_DEMO.project));\n if (workflows) return workflows;\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\n/** The session Claude Desktop is busy with. */\nconst DEMO_LIVE_SESSION = SESSIONS[1]!.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", "// Usage and activity: what the page and the session menu show, and the rules both sides follow.\n\n/** The periods the page offers, as Claude Code's /stats does: the last 7 days, the last 30, everything. */\nexport type UsageRange = '7d' | '30d' | 'all';\nexport const USAGE_RANGES: UsageRange[] = ['7d', '30d', 'all'];\n\n/** Tokens by kind, as the API reports them for each reply and Claude Code's /usage names them. */\nexport type Tokens = { input: number; output: number; cacheRead: number; cacheWrite: number };\n\nexport const noTokens = (): Tokens => ({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });\nexport const tokenTotal = (t: Tokens): number => t.input + t.output + t.cacheRead + t.cacheWrite;\n\n/**\n * The share of input served from the prompt cache, as Claude Code's \"Prompt cache\" line counts it:\n * cache reads over everything sent (new input, cache writes and cache reads). Undefined with no input.\n */\nexport function cacheShare(t: Tokens): number | undefined {\n const sent = t.input + t.cacheWrite + t.cacheRead;\n return sent > 0 ? t.cacheRead / sent : undefined;\n}\n\n/** The apps a session can run in, by what Claude Code records as each row's entrypoint. */\nexport type AppName = 'Terminal' | 'Claude Desktop' | 'VS Code' | 'Pelican' | 'Agent SDK' | 'Cowork' | 'Other';\n\n/**\n * Claude Code's own clients by their entrypoint, in Claude Code's names. The Agent SDK covers\n * `claude -p` too (Claude Code counts it as the SDK). Rows a session got from Pelican are the SDK's\n * (`sdk-ts`); `pelican` says that this session is one Pelican ran. Anything else is \"Other\":\n * Pelican assumes nothing about programs it does not know.\n */\nexport function appOf(entrypoint: string | undefined, pelican: boolean): AppName {\n switch (entrypoint) {\n case 'cli':\n return 'Terminal';\n case 'claude-desktop':\n case 'claude-desktop-3p':\n case 'remote_desktop':\n return 'Claude Desktop';\n case 'claude-vscode':\n return 'VS Code';\n case 'local-agent':\n case 'local_agent':\n case 'remote_cowork':\n return 'Cowork';\n case 'sdk-ts':\n case 'sdk-py':\n return pelican ? 'Pelican' : 'Agent SDK';\n case 'sdk-cli':\n return 'Agent SDK';\n default:\n return 'Other';\n }\n}\n\n/** Which usage limit a Claude Code \"You've hit your \u2026 limit\" line is about, in Claude Code's own terms. */\nexport type LimitKind = 'session' | 'weekly' | 'model';\n\n/**\n * The limit a usage-limit error names, as Claude Code itself classifies it: the 5-hour (session)\n * limit, the weekly one, or a model's weekly one (spend and fast-mode limits are none of these).\n * Older versions said only \"You've hit your limit \u00B7 resets 3pm\": the 5-hour one when it resets at\n * a time of day, the weekly one when it names a day.\n */\nexport function limitKind(text: string): LimitKind | undefined {\n const t = text.trim();\n if (/^You(?:'|\u2019)ve hit your limit\\b/.test(t)) {\n const resets = /resets\\s+([^\\n(]+)/i.exec(t)?.[1]?.trim() ?? '';\n if (!resets) return undefined;\n return /^\\d{1,2}(:\\d\\d)?\\s*(am|pm)?$/i.test(resets) ? 'session' : 'weekly';\n }\n const name = /^You(?:'|\u2019)ve hit your (.+?) limit/.exec(t)?.[1]?.toLowerCase();\n if (name === '5-hour' || name === 'session') return 'session';\n if (name === 'weekly') return 'weekly';\n if (name && /^(opus|sonnet|haiku|fable)$/.test(name)) return 'model';\n return undefined;\n}\n\n/**\n * A model id as people say it: claude-opus-5-5 is Opus 5.5, us.anthropic.claude-sonnet-4-5-20250929-v1:0\n * and claude-sonnet-4-5@20250929 are Sonnet 4.5. An id of another shape stays as it is.\n */\nexport function modelName(id: string): string {\n const bare = id.replace(/^.*?(?=claude-)/, '').replace(/^claude-/, '').replace(/\\[.*?\\]/g, '').replace(/[@:].*$/, '').replace(/-v\\d+$/, '');\n const parts = bare.split('-').filter((p) => !/^\\d{8}$/.test(p));\n const family = parts.find((p) => /^[a-z]+$/.test(p));\n if (!family || !id.includes('claude')) return id;\n const version = parts.filter((p) => /^\\d{1,2}$/.test(p));\n return `${family[0]!.toUpperCase()}${family.slice(1)}${version.length > 0 ? ` ${version.join('.')}` : ''}`;\n}\n\n/**\n * Whether dollar figures mean anything to this account. On a Claude plan (Pro, Max, Team,\n * Enterprise) usage counts against the plan's limits, which the page shows instead; with an API\n * key or a cloud provider it is billed per token, and Claude Code's own estimate at API prices\n * helps. Unknown (the account not read yet, or not signed in): no figure.\n */\nexport function costShown(account: { signedIn?: boolean | null; plan?: string | undefined }): boolean {\n return account.signedIn === true && !account.plan;\n}\n\n/** How every dollar figure is labeled: it is Claude Code's estimate, not a bill. */\nexport const COST_LABEL = 'estimated at API prices';\n\n/**\n * A cost figure in words, as the page and the session menu say it. `without`: sessions in it for\n * which Claude Code kept no estimate (older versions, or a session in progress elsewhere).\n */\nexport function costWords(usd: number, without = 0): string {\n const amount = usd >= 100 ? `$${Math.round(usd).toLocaleString('en')}` : `$${usd.toFixed(2)}`;\n const missing = without > 0 ? `; ${without} ${without === 1 ? 'session has' : 'sessions have'} no estimate` : '';\n return `${amount}, ${COST_LABEL}${missing}`;\n}\n\nexport type UsageProgress = {\n /** Transcripts found, and read so far (each read once, then only what it gains). */\n files: number;\n read: number;\n ready: boolean;\n};\n\n/** One bar of the chart: a UTC day (or the Monday of a UTC week), and the tokens of that day or week. */\nexport type UsagePoint = { day: string; tokens: number };\n\nexport type UsageSession = {\n id: string;\n title: string;\n project: string;\n app: AppName;\n tokens: number;\n /** ms since epoch: the session's last activity in the period. */\n at: number;\n};\n\nexport type UsageSummary = {\n range: UsageRange;\n /** The UTC days the period covers, first and last, as Claude Code's /stats counts days. */\n from: string;\n to: string;\n tokens: Tokens;\n /** The first day with tokens, when the transcripts go back less far than the period. */\n tokensSince?: string;\n series: { unit: 'day' | 'week'; points: UsagePoint[] };\n models: Array<{ model: string; name: string; tokens: number }>;\n projects: Array<{ cwd: string; name: string; tokens: number; sessions: number }>;\n apps: Array<{ app: AppName; tokens: number; sessions: number }>;\n /** The sessions that used the most, most first. */\n sessions: UsageSession[];\n activity: {\n sessions: number;\n activeDays: number;\n days: number;\n currentStreak: number;\n longestStreak: number;\n /** `at`: when it started; `title` when the session is still on this computer. */\n longest?: { id: string; title?: string; ms: number; at: number };\n /** The first day of activity anyone recorded, when Claude Code's own stats go back further than the transcripts. */\n since?: string;\n };\n /** Usage limits reached in the period, each once, by when Claude Code said so. */\n limits: Array<{ kind: LimitKind; at: number }>;\n /** Sessions compacted three times or more in the period, most first. */\n compacted: Array<{ id: string; title: string; times: number }>;\n /** How long Claude waited for an answer (an approval, a question, a plan) in sessions Pelican ran. */\n waits?: { ms: number; count: number; longest: number };\n /** Only for an API key or a cloud provider (costShown): Claude Code's own estimates. */\n cost?: { usd: number; without: number };\n progress: UsageProgress;\n};\n\nexport type SessionUsage = {\n tokens: Tokens;\n models: Array<{ model: string; name: string; tokens: number }>;\n compactions: number;\n waits?: { ms: number; count: number };\n cost?: { usd: number };\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", "// Workflows as Claude Code describes them: what a script says about itself, what a run's agents\n// and phases are doing, and the words Claude Code uses for them, in the CLI and in Claude Desktop.\n\nimport type { ToolResultBlock, Workflow, WorkflowAgent, WorkflowLaunch, WorkflowPhase, WorkflowStatus } from './protocol';\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n\n// ---- The script's meta ------------------------------------------------------------------------\n\n/** What a workflow script says about itself: `export const meta = { name, description, phases }`. */\nexport type WorkflowMeta = { name?: string; description?: string; phases: WorkflowPhase[]; whenToUse?: string };\n\n/** The meta block is a few hundred bytes; no more than this is looked at. */\nconst META_MAX = 16 * 1024;\n\nclass NotALiteral extends Error {}\n\n/**\n * Reads a JavaScript literal (objects, arrays, strings, numbers, true, false, null) from the start\n * of a script, as Claude Code requires the meta to be: \"pure literal, no computed values\". Strings\n * joined with `+` are joined, since scripts do that to wrap long descriptions. Anything else, a\n * template with `${\u2026}` included, is no literal: nothing is ever evaluated.\n */\nclass Literal {\n private at = 0;\n\n constructor(private readonly text: string) {}\n\n private fail(): never {\n throw new NotALiteral();\n }\n\n space(): void {\n for (;;) {\n const c = this.text.charCodeAt(this.at);\n // Spaces, tabs, line breaks, a byte order mark and no-break spaces.\n if (c === 32 || (c >= 9 && c <= 13) || c === 0xfeff || c === 0xa0 || c === 0x2028 || c === 0x2029) {\n this.at += 1;\n } else if (this.text.startsWith('//', this.at)) {\n const end = this.text.indexOf('\\n', this.at);\n this.at = end < 0 ? this.text.length : end + 1;\n } else if (this.text.startsWith('/*', this.at)) {\n const end = this.text.indexOf('*/', this.at + 2);\n if (end < 0) this.fail();\n this.at = end + 2;\n } else {\n return;\n }\n }\n }\n\n word(word: string): boolean {\n this.space();\n if (!this.text.startsWith(word, this.at) || /[\\w$]/.test(this.text[this.at + word.length] ?? '')) return false;\n this.at += word.length;\n return true;\n }\n\n expect(char: string): void {\n this.space();\n if (this.text[this.at] !== char) this.fail();\n this.at += 1;\n }\n\n value(depth = 0): unknown {\n if (depth > 8) this.fail();\n this.space();\n const c = this.text[this.at];\n let value: unknown;\n if (c === '{') value = this.object(depth);\n else if (c === '[') value = this.array(depth);\n else if (c === \"'\" || c === '\"' || c === '`') value = this.string();\n else if (c !== undefined && /[-+.\\d]/.test(c)) value = this.number();\n else if (this.word('true')) value = true;\n else if (this.word('false')) value = false;\n else if (this.word('null')) value = null;\n else this.fail();\n // 'Review the server ' + 'and the client'\n for (;;) {\n this.space();\n if (typeof value !== 'string' || this.text[this.at] !== '+') return value;\n this.at += 1;\n this.space();\n const next = this.text[this.at];\n if (next !== \"'\" && next !== '\"' && next !== '`') this.fail();\n value += this.string();\n }\n }\n\n private object(depth: number): Record<string, unknown> {\n this.at += 1;\n const out: Record<string, unknown> = {};\n for (;;) {\n this.space();\n if (this.text[this.at] === '}') {\n this.at += 1;\n return out;\n }\n const key = this.key();\n this.expect(':');\n const value = this.value(depth + 1);\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') out[key] = value;\n this.space();\n if (this.text[this.at] === ',') this.at += 1;\n else if (this.text[this.at] !== '}') this.fail();\n }\n }\n\n private array(depth: number): unknown[] {\n this.at += 1;\n const out: unknown[] = [];\n for (;;) {\n this.space();\n if (this.text[this.at] === ']') {\n this.at += 1;\n return out;\n }\n out.push(this.value(depth + 1));\n this.space();\n if (this.text[this.at] === ',') this.at += 1;\n else if (this.text[this.at] !== ']') this.fail();\n }\n }\n\n private key(): string {\n this.space();\n const c = this.text[this.at];\n if (c === \"'\" || c === '\"') return this.string();\n const match = /^[A-Za-z_$][\\w$]*|^\\d+/.exec(this.text.slice(this.at, this.at + 128));\n if (!match) this.fail();\n this.at += match[0].length;\n return match[0];\n }\n\n private number(): number {\n const match = /^[-+]?(?:\\d[\\d_]*\\.?[\\d_]*|\\.\\d[\\d_]*)(?:[eE][-+]?\\d+)?/.exec(this.text.slice(this.at, this.at + 64));\n if (!match) this.fail();\n this.at += match[0].length;\n const value = Number(match[0].replace(/_/g, ''));\n if (!Number.isFinite(value)) this.fail();\n return value;\n }\n\n private string(): string {\n const quote = this.text[this.at]!;\n this.at += 1;\n let out = '';\n for (;;) {\n if (this.at >= this.text.length) this.fail();\n const c = this.text[this.at]!;\n this.at += 1;\n if (c === quote) return out;\n if (quote === '`' && c === '$' && this.text[this.at] === '{') this.fail();\n if (c === '\\\\') {\n out += this.escape();\n } else if ((c === '\\n' || c === '\\r') && quote !== '`') {\n this.fail();\n } else {\n out += c;\n }\n }\n }\n\n private escape(): string {\n const c = this.text[this.at];\n this.at += 1;\n const hex = (length: number) => {\n const digits = this.text.slice(this.at, this.at + length);\n if (!new RegExp(`^[0-9a-fA-F]{${length}}$`).test(digits)) this.fail();\n this.at += length;\n return parseInt(digits, 16);\n };\n switch (c) {\n case 'n': return '\\n';\n case 't': return '\\t';\n case 'r': return '\\r';\n case 'b': return '\\b';\n case 'f': return '\\f';\n case 'v': return '\\v';\n case '0': return '\\0';\n case 'x': return String.fromCharCode(hex(2));\n case 'u': {\n if (this.text[this.at] !== '{') return String.fromCharCode(hex(4));\n // `\\u{1F600}`: one to six hex digits, no sign, no more than the last code point.\n const end = this.text.indexOf('}', this.at);\n const digits = end < 0 ? '' : this.text.slice(this.at + 1, end);\n if (!/^[0-9a-fA-F]{1,6}$/.test(digits)) this.fail();\n const code = parseInt(digits, 16);\n if (code > 0x10ffff) this.fail();\n this.at = end + 1;\n return String.fromCodePoint(code);\n }\n case '\\r':\n if (this.text[this.at] === '\\n') this.at += 1;\n return '';\n case '\\n':\n case '\\u2028':\n case '\\u2029':\n return '';\n case undefined:\n return this.fail();\n default:\n return c;\n }\n }\n}\n\nfunction metaOf(value: unknown): WorkflowMeta | undefined {\n if (!isRecord(value)) return undefined;\n const phases = (Array.isArray(value.phases) ? value.phases : [])\n .filter(isRecord)\n .flatMap((phase): WorkflowPhase[] => {\n const title = str(phase.title)?.trim();\n const detail = str(phase.detail)?.trim();\n return title ? [{ title, ...(detail ? { detail } : {}) }] : [];\n });\n const name = str(value.name)?.trim();\n const description = str(value.description)?.trim();\n const whenToUse = str(value.whenToUse)?.trim();\n return { ...(name ? { name } : {}), ...(description ? { description } : {}), phases, ...(whenToUse ? { whenToUse } : {}) };\n}\n\n/**\n * The meta a workflow script starts with, read as a literal and never run; undefined when the\n * script does not start with one Claude Code would take. The script is whatever Claude wrote, so\n * nothing in it may throw: a call that shows nothing is better than a session that cannot be read.\n */\nexport function parseMeta(script: string): WorkflowMeta | undefined {\n try {\n const reader = new Literal(script.slice(0, META_MAX));\n if (!reader.word('export') || !reader.word('const') || !reader.word('meta')) return undefined;\n reader.expect('=');\n reader.space();\n return metaOf(reader.value());\n } catch {\n return undefined;\n }\n}\n\n/** A string field of a meta not written out yet (a call still streaming in), when its value is. */\nfunction partialField(script: string, field: string): string | undefined {\n const match = new RegExp(`\\\\b${field}\\\\s*:\\\\s*(['\"\\`])((?:\\\\\\\\.|(?!\\\\1)[^\\\\\\\\\\\\n])*)\\\\1`).exec(script.slice(0, META_MAX));\n if (!match) return undefined;\n try {\n return new Literal(`${match[1]}${match[2]}${match[1]}`).value() as string;\n } catch {\n return undefined;\n }\n}\n\n/** The script file's own name, as Claude Code names its copies: `<name>-<run id>.js` shows as `<name>`. */\nexport function scriptName(file: string): string {\n const base = file.split(/[\\\\/]/).pop() ?? file;\n return base.replace(/-wf_[a-z0-9-]+\\.js$/, '').replace(/\\.js$/, '');\n}\n\n/**\n * A Workflow call's name and description, from what it was given: the script's meta, a predefined\n * workflow's name, or the script file it runs. A meta still streaming in gives what it has so far.\n */\nexport function workflowOf(input: Record<string, unknown>): { name?: string; description?: string; meta?: WorkflowMeta; file?: string } {\n try {\n const script = str(input.script);\n const file = str(input.scriptPath);\n const meta = script ? parseMeta(script) : undefined;\n // A meta not written out yet: its first fields, as far as they came.\n const partial = script && !meta;\n const name = meta?.name ?? (partial ? partialField(script, 'name') : undefined) ?? str(input.name) ?? (file ? scriptName(file) : undefined);\n const description = meta?.description ?? (partial ? partialField(script, 'description') : undefined);\n return { ...(name ? { name } : {}), ...(description ? { description } : {}), ...(meta ? { meta } : {}), ...(file ? { file } : {}) };\n } catch {\n // Pages render this from what Claude wrote: it never takes them down.\n return {};\n }\n}\n\n// ---- What a call launched, and how it ended ---------------------------------------------------\n\n/** Claude Code's run ids: `wf_` and twelve characters of a UUID. */\nexport const RUN_ID = /^wf_[a-z0-9-]{6,64}$/;\n\n/** What a Workflow call's result says it launched: recorded next to it, or else in its words. */\nexport function launchOf(result: ToolResultBlock | undefined): WorkflowLaunch | undefined {\n if (!result || result.is_error) return undefined;\n if (result.workflow) return result.workflow;\n const text = typeof result.content === 'string' ? result.content : result.content.map((p) => (p.type === 'text' ? p.text : '')).join('\\n');\n const runId = /^Run ID: (wf_[a-z0-9-]+)$/m.exec(text)?.[1];\n const taskId = /Task ID: ([\\w-]+)/.exec(text)?.[1];\n if (!runId && !/^Workflow launched/.test(text)) return undefined;\n const summary = /^Summary: (.+)$/m.exec(text)?.[1]?.trim();\n const scriptFile = /^Script file: (.+)$/m.exec(text)?.[1]?.trim().split(/[\\\\/]/).pop();\n return {\n ...(runId && RUN_ID.test(runId) ? { runId } : {}),\n ...(taskId ? { taskId } : {}),\n ...(summary ? { summary } : {}),\n ...(scriptFile && /^[\\w.-]{1,200}\\.js$/.test(scriptFile) ? { scriptFile } : {}),\n };\n}\n\n/** What Claude Code's `<task-notification>` says about a background task that ended. */\nexport type TaskNotice = {\n taskId?: string;\n toolUseId?: string;\n status?: 'completed' | 'failed' | 'killed' | 'stopped';\n /** Claude Code's sentence: `Dynamic workflow \"\u2026\" completed`. */\n summary: string;\n /** For a failed run: why, as Claude Code gives it. */\n error?: string;\n result?: string;\n usage?: { agents?: number; done?: number; failed?: number; skipped?: number; tokens?: number; toolUses?: number; durationMs?: number };\n /**\n * Written by a Claude Code that found the task in the session without a record of its end: it\n * may still be running in the Claude Code that started it, which then says how it really ended.\n */\n orphan?: boolean;\n};\n\nconst unescapeXml = (text: string) => text.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '\"').replace(/&#39;/g, \"'\").replace(/&amp;/g, '&');\n\nfunction tagOf(text: string, name: string): string | undefined {\n const match = new RegExp(`<${name}>([\\\\s\\\\S]*?)</${name}>`).exec(text);\n return match ? match[1]!.trim() : undefined;\n}\n\nconst count = (text: string | undefined, name: string) => {\n const value = text ? tagOf(text, name) : undefined;\n return value !== undefined && /^\\d+$/.test(value) ? Number(value) : undefined;\n};\n\n/** A `<task-notification>` Claude Code wrote into the conversation, read; undefined for any other text. */\nexport function parseTaskNotice(text: string): TaskNotice | undefined {\n const body = text.trim();\n if (!body.startsWith('<task-notification>')) return undefined;\n const status = tagOf(body, 'status');\n const summary = unescapeXml(tagOf(body, 'summary') ?? '');\n const usageText = tagOf(body, 'usage');\n const result = tagOf(body, 'result');\n const usage = usageText ? {\n agents: count(usageText, 'agent_count'),\n done: count(usageText, 'agents_done'),\n failed: count(usageText, 'agents_error'),\n skipped: count(usageText, 'agents_skipped'),\n tokens: count(usageText, 'subagent_tokens') ?? count(usageText, 'total_tokens'),\n toolUses: count(usageText, 'tool_uses'),\n durationMs: count(usageText, 'duration_ms'),\n } : undefined;\n const known = status === 'completed' || status === 'failed' || status === 'killed' || status === 'stopped' ? status : undefined;\n // `Dynamic workflow \"x\" failed: TypeError: \u2026`: the reason is said apart, as Desktop does.\n const failed = known === 'failed' ? /^(.*? failed): ([\\s\\S]+)$/.exec(summary) : null;\n const taskId = tagOf(body, 'task-id');\n const toolUseId = tagOf(body, 'tool-use-id');\n const cleanUsage = usage && Object.fromEntries(Object.entries(usage).filter(([, v]) => v !== undefined));\n return {\n ...(taskId ? { taskId } : {}),\n ...(toolUseId ? { toolUseId } : {}),\n ...(known ? { status: known } : {}),\n summary: failed ? failed[1]! : summary,\n ...(failed ? { error: failed[2]!.trim() } : {}),\n ...(result ? { result: unescapeXml(result) } : {}),\n ...(cleanUsage && Object.keys(cleanUsage).length > 0 ? { usage: cleanUsage } : {}),\n ...(tagOf(body, 'note') !== undefined && !tagOf(body, 'output-file') ? { orphan: true } : {}),\n };\n}\n\n// ---- Agents and phases, by Claude Code's rules ------------------------------------------------\n\n/**\n * A run at work: its agents run, its time counts. Only `running`, as in the CLI's run view: a pause\n * aborts the run (its agents stop with it), and a wait at a usage limit stays `running`.\n */\nexport const isRunning = (status: WorkflowStatus) => status === 'running';\n\n/** A run that has not ended: one paused can still be stopped, and may yet be saved as it ends. */\nexport const isLive = (status: WorkflowStatus) => status === 'running' || status === 'paused';\n\n/** What Claude Code calls an agent's state: the CLI's run view, and its words for it. */\nexport type AgentStatus = 'queued' | 'running' | 'done' | 'failed' | 'skipped' | 'blocked' | 'stopped';\n\nexport const AGENT_WORDS: Record<AgentStatus, string> = {\n queued: 'Queued', running: 'Running', done: 'Completed', failed: 'Failed', skipped: 'Skipped', blocked: 'Blocked', stopped: 'Stopped',\n};\n\n/** What Claude Code writes on the agents a run left unfinished when it ended. */\nconst STOP_REASON = /^Stopped because the workflow (was stopped|failed|finished without waiting for it)/;\n\n/**\n * An agent's state as the CLI tells it: an error is a skip, a block, a failure, or (when the run\n * ended and took it along) a stop; an agent that never finished in a run that ended was stopped.\n */\nexport function agentStatus(agent: WorkflowAgent, runStatus: WorkflowStatus): AgentStatus {\n if (agent.state === 'done') return 'done';\n if (agent.state === 'error') {\n if (agent.skipped) return 'skipped';\n if (agent.blocked) return 'blocked';\n return STOP_REASON.test(agent.error ?? '') && !isRunning(runStatus) ? 'stopped' : 'failed';\n }\n if (!isRunning(runStatus)) return 'stopped';\n return agent.queuedAt !== undefined && agent.startedAt === undefined ? 'queued' : 'running';\n}\n\n/** An agent quiet for this long is idle (the CLI) and, past Desktop's mark, stalled. */\nexport const IDLE_MS = 30_000;\nexport const STALLED_MS = 90_000;\n\nexport type PhaseStatus = 'running' | 'done' | 'failed' | 'stopped' | 'pending';\n\nexport type PhaseGroup = {\n title: string;\n detail?: string;\n agents: Array<WorkflowAgent & { status: AgentStatus }>;\n status: PhaseStatus;\n done: number;\n failed: number;\n};\n\nconst norm = (text: string) => text.trim().toLowerCase();\n\n/** The CLI's match of a phase to a group of agents: the same title in any case, or one a prefix of the other. */\nconst same = (a: string, b: string) => {\n const x = norm(a);\n const y = norm(b);\n return x.length > 0 && y.length > 0 && (x.startsWith(y) || y.startsWith(x));\n};\n\n/**\n * A phase the run opened (a `workflow_phase` item), added after the script's own unless one of\n * those is it already: a phase the CLI would show as that one is not listed twice.\n */\nexport function addPhase(phases: WorkflowPhase[], title: string): void {\n if (!phases.some((p) => same(p.title, title))) phases.push({ title });\n}\n\n/**\n * The run's phases in order, each with its agents, as the CLI groups them (its run view): agents\n * by the phase they were started in (its index, else its title), each group matched to one of the\n * script's phases at most, in order, the same title first and then a prefix either way. Groups no\n * phase took follow, then agents of no phase, as \"Agents\" (Desktop's \"Other agents\" when there\n * are phases). A group with no title of its own is \"Phase N\".\n */\nexport function phaseGroups(workflow: Pick<Workflow, 'phases' | 'agents' | 'status'>): PhaseGroup[] {\n type Run = { title: string; agents: WorkflowAgent[]; order: number };\n const runs = new Map<string, Run>();\n const unphased: WorkflowAgent[] = [];\n for (const agent of [...workflow.agents].sort((a, b) => a.index - b.index)) {\n const title = agent.phaseTitle?.trim();\n const key = agent.phaseIndex !== undefined ? `#${agent.phaseIndex}` : title ? `=${norm(title)}` : undefined;\n if (!key) {\n unphased.push(agent);\n continue;\n }\n let run = runs.get(key);\n if (!run) {\n run = { title: title || `Phase ${agent.phaseIndex}`, agents: [], order: agent.phaseIndex ?? Number.POSITIVE_INFINITY };\n runs.set(key, run);\n }\n run.agents.push(agent);\n }\n // In the order the run first used them: by index, then those only a title names.\n const ordered = [...runs.values()].sort((a, b) => a.order - b.order);\n const taken = new Set<Run>();\n const matched = new Map<number, Run>();\n const take = (fits: (run: Run, title: string) => boolean) => workflow.phases.forEach((phase, i) => {\n if (matched.has(i)) return;\n const run = ordered.find((r) => !taken.has(r) && fits(r, phase.title));\n if (run) {\n taken.add(run);\n matched.set(i, run);\n }\n });\n take((run, title) => norm(run.title) === norm(title));\n take((run, title) => same(run.title, title));\n const tag = (agents: WorkflowAgent[]) => agents.map((agent) => ({ ...agent, status: agentStatus(agent, workflow.status) }));\n const group = (title: string, agents: WorkflowAgent[], detail?: string): PhaseGroup => ({\n title, ...(detail ? { detail } : {}), agents: tag(agents), status: 'pending', done: 0, failed: 0,\n });\n const groups: PhaseGroup[] = workflow.phases.map((phase, i) => group(phase.title, matched.get(i)?.agents ?? [], phase.detail));\n for (const run of ordered) if (!taken.has(run)) groups.push(group(run.title, run.agents));\n if (unphased.length > 0) groups.push(group(groups.length > 0 ? 'Other agents' : 'Agents', unphased));\n const running = isRunning(workflow.status);\n for (const group of groups) {\n group.done = group.agents.filter((a) => a.status === 'done').length;\n group.failed = group.agents.filter((a) => a.status === 'failed' || a.status === 'blocked').length;\n const live = group.agents.some((a) => a.status === 'running' || a.status === 'queued');\n group.status = group.agents.length === 0 ? 'pending'\n : live && running ? 'running'\n : group.failed > 0 ? 'failed'\n : group.agents.every((a) => a.status === 'done' || a.status === 'skipped') ? 'done'\n : 'stopped';\n }\n return groups;\n}\n\n/** A run's agents counted as Desktop counts them for its grid of cells. */\nexport function agentCounts(agents: WorkflowAgent[], status: WorkflowStatus, now = Date.now()) {\n const counts = { total: agents.length, done: 0, running: 0, stalled: 0, failed: 0, stopped: 0, queued: 0 };\n for (const agent of agents) {\n const state = agentStatus(agent, status);\n if (state === 'done') counts.done += 1;\n else if (state === 'running') {\n counts.running += 1;\n if (agent.lastProgressAt !== undefined && now - agent.lastProgressAt > STALLED_MS) counts.stalled += 1;\n } else if (state === 'failed' || state === 'blocked') counts.failed += 1;\n else if (state === 'queued') counts.queued += 1;\n else counts.stopped += 1;\n }\n return counts;\n}\n\n/** Claude Code's word for a run's status. */\nexport function statusWord(status: WorkflowStatus): string {\n switch (status) {\n case 'running': return 'Running';\n case 'paused': return 'Paused';\n case 'completed': return 'Completed';\n case 'failed': return 'Failed';\n default: return 'Stopped';\n }\n}\n\n// ---- Claude Code's numbers ----------------------------------------------------------------------\n\n/** Tokens as Claude Code writes them: 412.3k, 2.8m, 1k, 950. */\nexport function tokensText(n: number): string {\n const trim = (value: number) => value.toFixed(1).replace(/\\.0$/, '');\n if (n < 1000) return String(Math.max(0, Math.round(n)));\n if (n < 999_950) return `${trim(n / 1000)}k`;\n return `${trim(n / 1_000_000)}m`;\n}\n\n/** A length of time as Claude Code writes it: 45s, 6m 1s, 1h 3m 5s. */\nexport function durationText(ms: number): string {\n const total = Math.max(0, Math.floor(ms / 1000));\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n if (h > 0) return `${h}h ${m}m ${s}s`;\n if (m > 0) return `${m}m ${s}s`;\n return `${s}s`;\n}\n\n/** Claude Code's mark for a workflow larger than most: past 25 agents or 1.5M tokens. */\nexport const isLarge = (agents: number, tokens: number) => agents > 25 || tokens > 1_500_000;\n\n/**\n * The time an agent took, or has taken so far while it runs. One the run's end stopped ran until\n * it was last heard from: its time does not count on.\n */\nexport function agentTime(agent: WorkflowAgent, status: AgentStatus, now = Date.now()): number | undefined {\n if (agent.durationMs !== undefined) return agent.durationMs;\n if (agent.startedAt === undefined) return undefined;\n if (status === 'running') return Math.max(0, now - agent.startedAt);\n if (status === 'stopped' && agent.lastProgressAt !== undefined) return Math.max(0, agent.lastProgressAt - agent.startedAt);\n return undefined;\n}\n\n/** The sum of the agents' tokens, as Claude Code totals a run while it runs. */\nexport const agentTokens = (agents: WorkflowAgent[]) => agents.reduce((sum, a) => sum + (a.tokens ?? 0), 0);\n\n/** The prompt an agent was given, without the frame the workflow harness puts around it. */\nexport function unframedPrompt(text: string): string {\n const marker = 'The computed task text follows:\\n';\n const at = text.lastIndexOf(marker);\n if (at < 0 || !text.trimStart().startsWith('[Workflow harness')) return text.trim();\n return text.slice(at + marker.length).split('\\n').map((line) => (line.startsWith(' ') ? line.slice(2) : line)).join('\\n').trim();\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-]+ ){0,2}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 // Claude Code names the limit (\"5-hour\", \"weekly\", \"Opus\", \"usage credit\") and when it resets.\n const hit = text.trim().match(/^You['\u2019]ve hit your ((?:[\\w-]+ ){0,2})limit(?:\\s*\u00B7\\s*(resets [^\\n\u00B7]+))?/i);\n const name = hit?.[1]?.trim();\n const resets = hit?.[2]?.trim().replace(/\\.$/, '');\n return `You have reached your ${name ? `${name} limit` : 'usage limit'}.${resets ? ` It ${resets}.` : ''}`;\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/**\n * What can be done about the error from here: shorten the conversation (/compact) when it is too\n * long for the model, else send the prompt again once the cause is gone.\n */\nexport const nextStep = (text: string, code?: string): 'compact' | 'retry' => (kindOf(text, code) === 'too-long' ? 'compact' : 'retry');\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 { errorLine, nextStep } from '../../shared/errors';\nimport type { ChatMessage, ImageBlock, ToolResultBlock, TurnChanges } from '../../shared/protocol';\nimport { todosOf } from '../../shared/tasks';\nimport { launchOf, parseTaskNotice, type TaskNotice, workflowOf } from '../../shared/workflows';\n\nexport type ToolCall = {\n id: string;\n name: string;\n input: Record<string, unknown>;\n result?: ToolResultBlock;\n /** A TodoWrite that only moves the same tasks along, which a line says better than the whole list again. */\n sameTasks?: true;\n /** A Workflow call: how Claude Code said its run ended, in the conversation. */\n ended?: TaskNotice;\n /** A Workflow call whose run a later call resumed (its id): that call's card shows the run. */\n resumedBy?: string;\n};\n\n/** Where a notice about a workflow's end leads: its card, and what the line says of it. */\nexport type WorkflowNotice = { toolUseId: string; name?: string; status?: TaskNotice['status']; durationMs?: number };\n\nexport type Part =\n | { kind: 'text'; key: string; text: string }\n | { kind: 'thinking'; key: string; text: string }\n | { kind: 'tool'; key: string; call: ToolCall }\n | { kind: 'image'; key: string; image: ImageBlock };\n\n/** A file sent with a prompt; `id` is its upload and `path` where Claude reads it, once the server has written the prompt down. */\nexport type SentFile = { name: string; id?: string; path?: string };\n\nexport type Item =\n | {\n kind: 'user';\n key: string;\n text: string;\n images: ImageBlock[];\n files: SentFile[];\n command?: { name: string; args: string };\n timestamp?: number;\n pending?: boolean;\n queued?: boolean;\n steered?: boolean;\n }\n | { kind: 'assistant'; key: string; parts: Part[]; timestamp?: number; model?: string }\n | {\n kind: 'notice'; key: string; tone: 'output' | 'task' | 'interrupt' | 'info' | 'error'; text: string; detail?: string;\n /** For an API error: what can be done about it from here. */\n next?: 'compact' | 'retry';\n /** A workflow's end, shown in its card: the line leads there. */\n workflow?: WorkflowNotice;\n }\n | { kind: 'compact'; key: string; summary: string }\n /**\n * `saved`: the file Claude Code saved all of a long output in, by its name in the session's\n * tool-results folder. `ended`: the record says it did not go well, as Claude Code's does.\n */\n | { kind: 'shell'; key: string; command: string; stdout: string; stderr: string; saved?: string; ended?: ShellEnd; timestamp?: number }\n | { kind: 'day'; key: string; timestamp: number };\n\nconst tag = (text: string, name: string) => {\n const match = text.match(new RegExp(`<${name}>([\\\\s\\\\S]*?)</${name}>`));\n return match?.[1]?.trim();\n};\n\n/* eslint-disable no-control-regex */\n/**\n * Output as a terminal would leave it on screen: colors, links and other escape codes gone (a\n * link keeps its text), a line rewritten with \\r (a progress bar) as it ended, and Claude Code's\n * error tags taken off.\n */\nexport function cleanOutput(text: string): string {\n const unwrapped = text.match(/^\\s*<tool_use_error>([\\s\\S]*)<\\/tool_use_error>\\s*$/)?.[1] ?? text;\n return unwrapped\n // OSC, DCS and the like run to BEL or ST; one cut off ends at the line's end.\n .replace(/\\u001b[P\\]X^_][^\\u0007\\u001b\\n]*(?:\\u0007|\\u001b\\\\)?/g, '')\n .replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/g, '')\n .replace(/\\u001b[ -/]*[0-~]/g, '')\n .replace(/\\r\\n/g, '\\n')\n .split('\\n')\n .map((line) => (line.includes('\\r') ? line.split('\\r').filter(Boolean).at(-1) ?? '' : line))\n .join('\\n')\n .replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]/g, '');\n}\n/* eslint-enable no-control-regex */\n\n/** How a `!` command's record says it ended, when not well: it failed, or Pelican stopped it. */\nexport type ShellEnd = 'failed' | 'stopped';\n\ntype Recorded = { stdout: string; stderr: string; saved?: string; ended?: ShellEnd };\n\ntype Classified =\n | { kind: 'user'; text: string; images: ImageBlock[]; command?: { name: string; args: string } }\n | { kind: 'notice'; tone: 'output' | 'task' | 'interrupt' | 'info'; text: string; detail?: string; task?: TaskNotice }\n | ({ kind: 'shell'; command: string } & Recorded)\n /** The output of the `!` command just before, in a message of its own, as Claude Code writes it. */\n | ({ kind: 'shell-output' } & Recorded);\n\n/**\n * The files sent with a prompt, out of its text. Pelican tells Claude where they are in an\n * \"Attached files:\" block of paths, which is for Claude, not for reading; a prompt still on its\n * way names them on lines of their own, \"\uD83D\uDCCE name\".\n */\nexport function splitFiles(text: string, pending = false): { text: string; files: SentFile[] } {\n const block = text.match(/(?:^|\\n\\n)Attached files:\\n((?:- .+ \\(.+\\)(?:\\n|$))+)$/);\n if (block) {\n const files = block[1]!.trimEnd().split('\\n').map((line): SentFile => {\n // The path ends in the file's own name, which may hold \" (\" itself.\n const upload = line.match(/^- (.*\\/uploads\\/([0-9a-f-]{36})\\/(.+)) \\(\\3\\)$/);\n if (upload) return { name: upload[3]!, id: upload[2]!, path: upload[1]! };\n const other = line.match(/^- (.+) \\((.+)\\)$/);\n return other ? { name: other[2]!, path: other[1]! } : { name: line.slice(2) };\n });\n return { text: text.slice(0, block.index).trimEnd(), files };\n }\n if (pending) {\n const lines = text.split('\\n');\n let at = lines.length;\n while (at > 0 && lines[at - 1]!.startsWith('\uD83D\uDCCE ')) at -= 1;\n if (at < lines.length) return { text: lines.slice(0, at).join('\\n').trimEnd(), files: lines.slice(at).map((line) => ({ name: line.slice(3) })) };\n }\n return { text, files: [] };\n}\n\n/** A prompt's text with its files' block put back, for sending it again with the same files. */\nexport function withFiles(text: string, files: SentFile[]): string {\n const lines = files.flatMap((file) => (file.path ? [`- ${file.path} (${file.name})`] : []));\n return lines.length > 0 ? `${text}${text ? '\\n\\n' : ''}Attached files:\\n${lines.join('\\n')}` : text;\n}\n\nconst unescape = (text: string) => text.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');\n\n/** A file Claude Code names in a session's tool-results folder, as the server reads one. */\nconst SAVED_NAME = /^[A-Za-z0-9_-]{1,128}\\.(?:txt|json)$/;\n\n/**\n * A `!` command's output as it shows: unescaped, or, for one too long for the conversation, what\n * Claude Code saved in its place (`<persisted-output>`, written as it came) unwrapped: the start\n * Claude got, then Claude Code's line saying where all of it is, with that file's name (`saved`).\n */\nfunction shellOutput(raw: string): { text: string; saved?: string } {\n const persisted = /^<persisted-output>\\n([^\\n]*)\\n\\n(?:Preview \\([^)\\n]*\\):\\n)?([\\s\\S]*?)\\n?<\\/persisted-output>$/.exec(raw);\n if (!persisted) return { text: unescape(raw) };\n const name = /saved to: (.+)$/.exec(persisted[1]!)?.[1]?.split(/[\\\\/]/).at(-1);\n return { text: `${persisted[2]!.replace(/\\n+$/, '')}\\n${persisted[1]}`, ...(name && SAVED_NAME.test(name) ? { saved: name } : {}) };\n}\n\n/**\n * The output of a `!` command's record, as the card shows it: Claude Code's word that a command\n * printed nothing is for Claude, and the card shows nothing in its place. How it ended, as the\n * record tells it: Claude Code's bash mode puts the output of one that went well under stdout, or\n * its word that it printed none, and that of one that failed under stderr, with stdout empty; one\n * Pelican stopped says so at its end. Before Claude Code 2.1.80, and in Pelican's records before\n * 0.4 (one message, with \"(exit code N)\" at the end of a failed one's stderr), a command that went\n * well could leave stdout empty too: those say how they ended only by such a note.\n */\nfunction shellRecord(text: string, version?: string): Recorded {\n const out = tag(text, 'bash-stdout');\n const err = tag(text, 'bash-stderr');\n const stdout = shellOutput(out ?? '');\n const stderr = shellOutput(err ?? '');\n const saved = stdout.saved ?? stderr.saved;\n const note = /(?:^|\\n)\\((stopped(?: after [^)\\n]+)?|exit code -?\\d+)\\)$/.exec(stderr.text)?.[1];\n const shaped = err !== undefined && !out && sharesStdoutOnSuccess(version);\n const ended: ShellEnd | undefined = note?.startsWith('stopped') ? 'stopped' : note || shaped ? 'failed' : undefined;\n return { stdout: stdout.text === '(Bash completed with no output)' ? '' : stdout.text, stderr: stderr.text, ...(saved ? { saved } : {}), ...(ended ? { ended } : {}) };\n}\n\n/** Whether a Claude Code's `!` output row says under stdout that a command went well: 2.1.80 on. */\nfunction sharesStdoutOnSuccess(version: string | undefined): boolean {\n const [major, minor, patch] = (version ?? '').split('.').map((n) => Number.parseInt(n, 10));\n if (major === undefined || minor === undefined || patch === undefined || [major, minor, patch].some(Number.isNaN)) return false;\n return major > 2 || (major === 2 && (minor > 1 || (minor === 1 && patch >= 80)));\n}\n\n/** Splits what Claude Code wraps in tags out of a user message's text. */\nfunction classifyUserText(raw: string, version?: string): Classified | undefined {\n const text = raw.replace(/<system-reminder>[\\s\\S]*?<\\/system-reminder>/g, '').trim();\n if (!text) return undefined;\n if (text.includes('<local-command-caveat>')) return undefined;\n // A `!` command and its output (Claude Code's bash mode), from any client.\n const bash = tag(text, 'bash-input');\n // One message holding the command and its output is a record of Pelican's before 0.4 (or another\n // client's): only a note at its end says it did not go well.\n if (bash !== undefined) return { kind: 'shell', command: unescape(bash), ...shellRecord(text) };\n if (text.startsWith('<bash-stdout>') || text.startsWith('<bash-stderr>')) return { kind: 'shell-output', ...shellRecord(text, version) };\n const commandName = tag(text, 'command-name');\n if (commandName) {\n return { kind: 'user', text: '', images: [], command: { name: commandName, args: tag(text, 'command-args') ?? '' } };\n }\n const stdout = tag(text, 'local-command-stdout') ?? tag(text, 'local-command-stderr');\n if (stdout !== undefined) {\n const clean = cleanOutput(stdout).trim();\n return clean ? { kind: 'notice', tone: 'output', text: clean } : undefined;\n }\n const task = parseTaskNotice(text);\n if (task) return { kind: 'notice', tone: 'task', text: task.summary || 'Background task update', ...(task.result ? { detail: task.result } : {}), task };\n if (/^\\[Request interrupted by user/.test(text)) return { kind: 'notice', tone: 'interrupt', text: 'Interrupted' };\n return { kind: 'user', text, images: [] };\n}\n\nconst dayOf = (ms: number) => new Date(ms).toDateString();\n\n/**\n * Groups a conversation into what the chat shows: prompts, Claude's turns, and notices.\n * `machine`: the computer Claude Code runs on, named where an error line says what to do there.\n */\nexport function buildItems(messages: ChatMessage[], machine?: string): Item[] {\n const results = new Map<string, ToolResultBlock>();\n for (const message of messages) {\n for (const block of message.blocks) if (block.type === 'tool_result') results.set(block.tool_use_id, block);\n }\n\n const items: Item[] = [];\n /** The `!` commands whose output has been seen: what comes after it is not theirs. */\n const withOutput = new Set<string>();\n let turn: Extract<Item, { kind: 'assistant' }> | undefined;\n let lastDay: string | undefined;\n let tasks: { names: string; done: boolean } | undefined;\n /** Workflow calls so far, by id, for their ends to join them; and each run's calls, in order. */\n const workflows = new Map<string, ToolCall>();\n const runs = new Map<string, ToolCall[]>();\n\n const push = (item: Item, timestamp?: number) => {\n if (timestamp && item.kind === 'user') {\n const day = dayOf(timestamp);\n if (lastDay && day !== lastDay) items.push({ kind: 'day', key: `day-${item.key}`, timestamp });\n lastDay = day;\n } else if (timestamp && !lastDay) {\n lastDay = dayOf(timestamp);\n }\n items.push(item);\n };\n\n for (const message of messages) {\n if (message.parentToolUseId) continue;\n // A compaction's summary is injected text too, but it marks where Claude's memory was condensed.\n if (message.compactSummary) {\n const summary = message.blocks.map((b) => (b.type === 'text' ? b.text : '')).join('\\n').trim();\n push({ kind: 'compact', key: message.uuid, summary });\n turn = undefined;\n continue;\n }\n if (message.meta) continue;\n // Lines Claude Code adds itself (a local command and its output, hook feedback): notes, never prompts.\n if (message.role === 'system') {\n const classified = classifyUserText(message.blocks.map((b) => (b.type === 'text' ? b.text : '')).join('\\n'));\n if (!classified) continue;\n if (classified.kind === 'user' && !classified.command) push({ kind: 'notice', key: message.uuid, tone: 'info', text: classified.text });\n else if (classified.kind === 'user') push({ ...classified, files: [], key: message.uuid, ...(message.timestamp ? { timestamp: message.timestamp } : {}) }, message.timestamp);\n else if (classified.kind === 'notice') push({ ...classified, key: message.uuid });\n turn = undefined;\n continue;\n }\n // A failed API call is not Claude's reply: one line saying what went wrong, in plain words.\n if (message.apiError) {\n const text = message.blocks.map((b) => (b.type === 'text' ? b.text : '')).join('\\n').trim();\n push({ kind: 'notice', key: message.uuid, tone: 'error', text: errorLine(text, machine, message.error) ?? text, next: nextStep(text, message.error) });\n turn = undefined;\n continue;\n }\n if (message.role === 'user') {\n const texts = message.blocks.filter((b) => b.type === 'text').map((b) => (b.type === 'text' ? b.text : ''));\n const images = message.blocks.filter((b): b is ImageBlock => b.type === 'image');\n if (texts.length === 0 && images.length === 0) continue;\n const classified: Classified | undefined = texts.length > 0 ? classifyUserText(texts.join('\\n\\n'), message.version) : { kind: 'user', text: '', images: [] };\n if (!classified) continue;\n if (classified.kind === 'user') {\n push({\n ...classified,\n ...splitFiles(classified.text, message.pending),\n key: message.uuid,\n images,\n ...(message.timestamp ? { timestamp: message.timestamp } : {}),\n ...(message.pending ? { pending: true } : {}),\n ...(message.queued ? { queued: true } : {}),\n ...(message.steered ? { steered: true } : {}),\n }, message.timestamp);\n turn = undefined;\n } else if (classified.kind === 'shell') {\n push({ ...classified, key: message.uuid, ...(message.timestamp ? { timestamp: message.timestamp } : {}) });\n // A record of the CLI's older shape holds its output with the command.\n if (texts.some((t) => /<bash-std(?:out|err)>/.test(t))) withOutput.add(message.uuid);\n turn = undefined;\n } else if (classified.kind === 'shell-output') {\n // It goes with its command; on its own, it is nothing to show.\n const last = items.at(-1);\n if (last?.kind === 'shell' && !withOutput.has(last.key)) {\n withOutput.add(last.key);\n last.stdout = classified.stdout;\n last.stderr = classified.stderr;\n if (classified.saved) last.saved = classified.saved;\n if (classified.ended) last.ended = classified.ended;\n }\n } else {\n // A workflow's end goes into its card; here a line names it and leads there. One from a\n // Claude Code that found the run without its end gives way to the word of the one that ran it.\n const { task, ...notice } = classified;\n const call = task?.toolUseId ? workflows.get(task.toolUseId) : undefined;\n if (call && task) {\n if (!call.ended || call.ended.orphan || !task.orphan) call.ended = task;\n const name = launchOf(call.result)?.name ?? workflowOf(call.input).name;\n const { detail: _shownInTheCard, ...line } = notice;\n push({\n ...line,\n key: message.uuid,\n workflow: { toolUseId: call.id, ...(name ? { name } : {}), ...(task.status ? { status: task.status } : {}), ...(task.usage?.durationMs !== undefined ? { durationMs: task.usage.durationMs } : {}) },\n });\n } else {\n push({ ...notice, key: message.uuid });\n }\n // Claude's answer to a background task's note comes after the note, as a turn of its own.\n if (task || notice.tone === 'task') turn = undefined;\n }\n continue;\n }\n if (message.role !== 'assistant') continue;\n if (!turn) {\n turn = {\n kind: 'assistant',\n key: message.uuid,\n parts: [],\n ...(message.timestamp ? { timestamp: message.timestamp } : {}),\n ...(message.model ? { model: message.model } : {}),\n };\n push(turn, message.timestamp);\n }\n message.blocks.forEach((block, i) => {\n const key = `${message.uuid}:${i}`;\n if (block.type === 'text') turn!.parts.push({ kind: 'text', key, text: block.text });\n else if (block.type === 'thinking') turn!.parts.push({ kind: 'thinking', key, text: block.thinking });\n else if (block.type === 'image') turn!.parts.push({ kind: 'image', key, image: block });\n else if (block.type === 'tool_use') {\n const result = results.get(block.id);\n let sameTasks = false;\n if (block.name === 'TodoWrite') {\n // The list shows in full when it is new, its tasks change, or the last one is done;\n // an update that only moves along the same tasks shows as one line.\n const todos = todosOf(block.input);\n const next = { names: JSON.stringify(todos.map((t) => t.content)), done: todos.length > 0 && todos.every((t) => t.status === 'completed') };\n sameTasks = next.names === tasks?.names && !(next.done && !tasks.done);\n tasks = next;\n }\n const call: ToolCall = { id: block.id, name: block.name, input: block.input, ...(result ? { result } : {}), ...(sameTasks ? { sameTasks: true } : {}) };\n if (block.name === 'Workflow') {\n workflows.set(block.id, call);\n const runId = launchOf(result)?.runId;\n if (runId) runs.set(runId, [...(runs.get(runId) ?? []), call]);\n }\n turn!.parts.push({ kind: 'tool', key, call });\n }\n });\n }\n // A run resumed by a later call (the same run id) is that call's to show.\n for (const calls of runs.values()) calls.slice(0, -1).forEach((call, i) => (call.resumedBy = calls[i + 1]!.id));\n return items;\n}\n\n/**\n * Where each turn's \"files changed\" goes: under the last of Claude's answers in it. Turns end\n * where Claude Code's /diff ends them (see changes.ts), at the next row it counts as a prompt: a\n * prompt with words, files or a `/` command, a `!` command, a background task's note, an\n * interruption, a compaction. A `/` command's output belongs to it, and a picture sent without\n * words is no new turn.\n */\nexport function filesChangedUnder(items: readonly Item[], turns: readonly TurnChanges[]): Map<string, TurnChanges> {\n const byStart = new Map(turns.map((turn) => [turn.uuid, turn]));\n const under = new Map<string, TurnChanges>();\n let start: string | undefined;\n let answer: string | undefined;\n const close = () => {\n const turn = start ? byStart.get(start) : undefined;\n if (turn && answer) under.set(answer, turn);\n };\n for (const item of items) {\n // A message of files alone is text to /diff: its \"Attached files:\" block.\n const starts = item.kind === 'user' ? !item.steered && (Boolean(item.text) || Boolean(item.command) || item.files.length > 0)\n : item.kind === 'notice' ? item.tone === 'task' || item.tone === 'interrupt'\n : item.kind === 'shell' || item.kind === 'compact';\n if (starts) {\n close();\n start = item.key;\n answer = undefined;\n } else if (item.kind === 'assistant') {\n answer = item.key;\n }\n }\n close();\n return under;\n}\n\n/** Text of a tool result, with images left out. */\nexport function resultText(result: ToolResultBlock | undefined): string {\n if (!result) return '';\n if (typeof result.content === 'string') return result.content;\n return result.content.map((part) => (part.type === 'text' ? part.text : '')).join('\\n');\n}\n\nexport function resultImages(result: ToolResultBlock | undefined): ImageBlock[] {\n if (!result || typeof result.content === 'string') return [];\n return result.content.filter((part): part is ImageBlock => part.type === 'image');\n}\n\n/**\n * How a tool call ended. Refused (denied: by you, a rule or auto mode) and stopped (interrupted)\n * are not failures: the call never ran, or was cut short, and its result is only a note to Claude.\n */\nexport type Outcome =\n | { kind: 'pending' }\n | { kind: 'done' }\n | { kind: 'failed' }\n | { kind: 'denied'; note?: string }\n | { kind: 'stopped' };\n\n// What Claude Code answers in place of a refused call, before the user's own words if any.\nconst REFUSED = [\n \"The user doesn't want to proceed with this tool use.\",\n 'Permission for this tool use was denied.',\n 'The agent proposed a plan that was rejected by the user.',\n 'User rejected tool use',\n];\nconst SAID = /[Tt]he user said:\\n([\\s\\S]*)$/;\n// What Pelican itself answered a refusal with, before it used Claude Code's words.\nconst PELICAN_REFUSED = new Set(['The user declined this.', 'The user chose not to answer.']);\n// Claude Code's notes for a call cut short (Stop, a message that ended the turn, a session that\n// ended), and Pelican's own for a request Stop or closing answered.\nconst STOPPED = /this call was stopped while running|^The user doesn't want to take this action right now\\.|^\\[(?:Request interrupted|Tool call|Agent call interrupted)|^Interrupted by the user\\.$|^Cancelled\\.$|^Session closed\\.$/;\n\nexport function outcomeOf(call: ToolCall): Outcome {\n const result = call.result;\n if (!result) return { kind: 'pending' };\n if (!result.is_error) return { kind: 'done' };\n const text = resultText(result).trim();\n if (STOPPED.test(text)) return { kind: 'stopped' };\n if (REFUSED.some((start) => text.startsWith(start))) {\n // A plan sent back without a word carries the plan after it, which is not a note.\n const note = text.match(SAID)?.[1]?.trim();\n return { kind: 'denied', ...(note ? { note } : {}) };\n }\n if (PELICAN_REFUSED.has(text)) return { kind: 'denied' };\n // A refusal in other words (Pelican's with a note) is known by the transcript, or by the tool:\n // a plan or a question can only fail by being turned down, unless Claude Code says otherwise.\n const tagged = /^<tool_use_error>/.test(text);\n if (result.denied || (!tagged && (call.name === 'ExitPlanMode' || call.name === 'AskUserQuestion'))) {\n return { kind: 'denied', ...(text ? { note: text } : {}) };\n }\n return { kind: 'failed' };\n}\n\nexport type Answer = { answer?: string; notes?: string };\n\n/**\n * Your answers to Claude's questions, from the text Claude Code gave Claude for them:\n * `\"question\"=\"answer\"` pairs, each maybe with ` notes: \u2026`, in the order asked. The questions\n * are known, so an answer may hold quotes and commas.\n */\nexport function answersOf(questions: string[], text: string): Record<string, Answer> {\n const found = questions\n .map((question) => ({ question, at: text.indexOf(`\"${question}\"=`) }))\n .filter((f) => f.at >= 0)\n .sort((a, b) => a.at - b.at);\n const out: Record<string, Answer> = {};\n found.forEach(({ question, at }, i) => {\n const next = found[i + 1];\n let part = text.slice(at + question.length + 3, next?.at);\n part = next ? part.replace(/,\\s*$/, '') : part.replace(/\\.(?: You can now continue[\\s\\S]*| Read the answers carefully[\\s\\S]*| They also wrote: [\\s\\S]*| Call [\\s\\S]*)?$/, '');\n let answer: string | undefined;\n if (part.startsWith('\"')) {\n const ends = ['\" selected preview:\\n', '\" notes: '].map((end) => part.indexOf(end)).filter((end) => end > 0);\n const end = ends.length > 0 ? Math.min(...ends) : part.lastIndexOf('\"');\n answer = part.slice(1, end > 0 ? end : undefined);\n part = end > 0 ? part.slice(end + 1) : '';\n }\n const notes = part.match(/ notes: ([\\s\\S]*)$/)?.[1]?.trim();\n out[question] = { ...(answer ? { answer } : {}), ...(notes ? { notes } : {}) };\n });\n return out;\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 { demoLiveProcesses } 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 demoLiveProcesses();\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, WorkflowLaunch } from '../shared/protocol.js';\nimport { RUN_ID } from '../shared/workflows.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\n/** `omit`: pictures held as data are left out (a page that has no address to load them from). */\ntype Images = { address?: ImageAddress; omit?: boolean; 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 if (images.omit) return { type: 'image', source: { type: 'base64', media_type: mediaType, data: '' }, omitted: true };\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 * What a Workflow call launched, from what Claude Code records of its result (`toolUseResult` in a\n * transcript, `tool_use_result` in the stream): the run its agents write to, and its task.\n */\nfunction workflowLaunch(output: Raw): WorkflowLaunch | undefined {\n const text = (value: unknown, max = 2000) => (typeof value === 'string' && value && value.length <= max ? value : undefined);\n const runId = text(output.runId, 80);\n const name = text(output.workflowName, 200);\n if (output.taskType !== 'local_workflow' && !(runId && RUN_ID.test(runId)) && !name) return undefined;\n const taskId = text(output.taskId, 80);\n const summary = text(output.summary);\n const sessionUrl = text(output.sessionUrl);\n const scriptFile = text(output.scriptPath)?.split(/[\\\\/]/).pop();\n return {\n ...(runId && RUN_ID.test(runId) ? { runId } : {}),\n ...(taskId ? { taskId } : {}),\n ...(name ? { name } : {}),\n ...(summary ? { summary } : {}),\n ...(sessionUrl && /^https:\\/\\//.test(sessionUrl) ? { sessionUrl } : {}),\n ...(scriptFile && /^[\\w.-]{1,200}\\.js$/.test(scriptFile) ? { scriptFile } : {}),\n };\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; with `omit`, they are\n * left out.\n */\nexport function toChatMessage(raw: Raw, address?: ImageAddress | 'omit'): 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 === 'omit' ? { omit: true } : 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 // A `!` command's output row is read by the Claude Code that wrote it (ChatMessage.version).\n if (type === 'user' && typeof raw.version === 'string' && raw.version.length <= 32 && out.blocks.some((b) => b.type === 'text' && /^\\s*<bash-std(?:out|err)>/.test(b.text))) out.version = raw.version;\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 const output = isRecord(raw.toolUseResult) ? raw.toolUseResult : isRecord(raw.tool_use_result) ? raw.tool_use_result : undefined;\n const launch = output && workflowLaunch(output);\n const results = launch ? out.blocks.filter((b) => b.type === 'tool_result') : [];\n if (launch && results.length === 1 && results[0]!.type === 'tool_result') results[0]!.workflow = launch;\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 /** A subagent's own transcript, whose rows are all on a side chain; its pictures are left out. */\n sidechain: boolean;\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, sidechain: boolean): 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 || sidechain ? undefined : (uuid: string) => (n: number) => `api/sessions/${id}/images/${encodeURIComponent(uuid)}/${n}`;\n return {\n address, sidechain, 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/**\n * A background task's end that came while Claude worked (a workflow's, a command's): Claude Code\n * keeps it as a queued command where Claude took it in, with the same `<task-notification>` it\n * writes as a message of its own between turns.\n */\nfunction queuedNotice(row: Record<string, unknown>, uuid: string): ChatMessage | undefined {\n const attachment = row.attachment as { type?: string; prompt?: unknown; commandMode?: unknown } | undefined;\n if (row.type !== 'attachment' || attachment?.type !== 'queued_command' || attachment.commandMode !== 'task-notification') return undefined;\n if (typeof attachment.prompt !== 'string' || !attachment.prompt.trimStart().startsWith('<task-notification>')) return undefined;\n return toChatMessage({ type: 'user', uuid, timestamp: row.timestamp, message: { role: 'user', content: attachment.prompt } });\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 && !t.sidechain)) 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\n ? toChatMessage(row, t.sidechain ? 'omit' : address)\n : steeredMessage(row, uuid, address) ?? queuedNotice(row, uuid) ?? 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, sidechain: boolean): 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.sidechain !== sidechain) t = empty(file, info.ino, sidechain);\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/**\n * The conversation in a transcript file, oldest message first. `sidechain`: a subagent's own\n * transcript (a workflow agent's), read the same way, without its pictures.\n */\nexport function readHistory(file: string, { sidechain = false }: { sidechain?: boolean } = {}): 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, sidechain));\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 * A transcript row as Claude Code wrote it, read again from its own place in the file (one row,\n * however long the file): for what its message does not carry, such as its pictures' data or the\n * session it was copied from.\n */\nexport async function transcriptRow(file: string, uuid: string): Promise<Record<string, unknown> | undefined> {\n await readHistory(file);\n const node = transcripts.get(file)?.nodes.get(uuid);\n if (!node) return undefined;\n let row: Record<string, 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 Record<string, unknown>;\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n return row.uuid === uuid ? row : undefined;\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 const row = await transcriptRow(file, uuid) as { type?: unknown; message?: { content?: unknown }; attachment?: { type?: unknown; prompt?: unknown } } | undefined;\n if (!row) 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", "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 for (const key of titleScans.keys()) if (!present.has(key.slice(0, key.lastIndexOf('\\n')))) titleScans.delete(key);\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, and the Agent SDK's forks (Pelican's side chats) with\n * rows that carry the copy's id and name the session each came from (`forkedFrom`). A file only\n * grows at its end, so an answer is kept; 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 const own = path.basename(file, '.jsonl');\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; forkedFrom?: { sessionId?: unknown } };\n if ((row.type === 'user' || row.type === 'assistant') && !row.isSidechain && typeof row.sessionId === 'string') {\n const from = row.forkedFrom?.sessionId;\n found = row.sessionId === own && typeof from === 'string' && from ? from : 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/** How much of a transcript a look for a title reads at a time. */\nexport const TITLE_READ = 1024 * 1024;\n/** A title row is far shorter: a line longer than this is something else, and is not kept while it is read. */\nconst TITLE_LINE = 64 * 1024;\nconst titleScans = new Map<string, { ino: number; size: number; offset: number; found: boolean }>();\n\n/**\n * Whether a transcript's session was ever given this title, anywhere in the file: a custom-title\n * row under the file's own id, not one copied with another session's rows. Claude Code and Claude\n * Desktop add title rows as they go, so the last title need not be it. A file only grows at its\n * end: each look reads on from the last whole line the one before read, and a title once found\n * stays found.\n */\nexport async function everTitled(file: string, title: string): Promise<boolean> {\n const key = `${file}\\n${title}`;\n const known = titleScans.get(key);\n if (known?.found) return true;\n const own = path.basename(file, '.jsonl');\n // As Claude Code writes the row; quotes inside a string are escaped, so text that names it never matches.\n const needle = Buffer.from(`\"customTitle\":${JSON.stringify(title)}`);\n const isTitle = (line: Buffer) => {\n if (!line.includes(needle)) return false;\n try {\n const row = JSON.parse(line.toString('utf8')) as { type?: unknown; customTitle?: unknown; sessionId?: unknown };\n return row.type === 'custom-title' && row.customTitle === title && row.sessionId === own;\n } catch {\n return false;\n }\n };\n let handle: Awaited<ReturnType<typeof openRegular>> | undefined;\n try {\n handle = await openRegular(file);\n const { size, ino } = await handle.stat();\n // Rewritten rather than grown: from the start again.\n const again = !known || known.ino !== ino || known.size > size;\n if (!again && known.size === size) return false;\n let offset = again ? 0 : known.offset;\n let found = false;\n // The start of the line the last read left open; undefined once it is too long to be a title row.\n let open: Buffer | undefined = Buffer.alloc(0);\n for (let position = offset; position < size && !found;) {\n const chunk = Buffer.alloc(Math.min(TITLE_READ, size - position));\n const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);\n if (bytesRead === 0) break;\n const data = chunk.subarray(0, bytesRead);\n position += bytesRead;\n const first = data.indexOf(0x0a);\n if (first < 0) {\n open = open && open.length + data.length <= TITLE_LINE ? Buffer.concat([open, data]) : undefined;\n continue;\n }\n if (open && open.length + first <= TITLE_LINE && isTitle(Buffer.concat([open, data.subarray(0, first)]))) found = true;\n const last = data.lastIndexOf(0x0a);\n for (let at = data.indexOf(needle, first); at >= 0 && at < last && !found; at = data.indexOf(needle, at + 1)) {\n if (isTitle(data.subarray(data.lastIndexOf(0x0a, at) + 1, data.indexOf(0x0a, at)))) found = true;\n }\n const rest = data.subarray(last + 1);\n open = rest.length <= TITLE_LINE ? rest : undefined;\n offset = position - rest.length;\n }\n titleScans.set(key, { ino, size, offset, found });\n return found;\n } catch {\n return false; // Missing or unreadable.\n } finally {\n await handle?.close();\n }\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 path from 'node:path';\n\nimport type { CanUseTool, Options } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { RunSettings } from '../shared/protocol.js';\nimport { everTitled, firstTurnSession, transcriptPath } from './transcripts.js';\n\n/**\n * Side chats, as Claude Desktop has them (\"Ask a side question without derailing the session\"):\n * a copy of the session so far, titled as Desktop titles its own, where Claude answers questions\n * about the session. It reads the conversation and the folder and changes nothing, and nothing in\n * it goes back to the session. On disk it is a session like any other, so it goes on in the CLI\n * and Desktop too; the session list folds it under the session it copies.\n */\nexport const SIDE_CHAT_TITLE = 'Side chat';\n\n/** All a side chat can use: Claude Code's tools that only read. */\nexport const SIDE_CHAT_TOOLS = ['Read', 'Grep', 'Glob'];\n\n/** The mode a side chat runs in: anything not already allowed is refused, never asked about, and Bypass never applies. */\nexport const SIDE_CHAT_MODE = 'dontAsk' as const;\n\n/**\n * Said to Claude with each question in a side chat, so it answers rather than reaching for tools\n * that do not run there: the session's tools are still listed to it, as they were.\n */\nconst SIDE_CHAT_NOTE = 'This is a side chat about the conversation above. Here you can only read, with Read, Grep and Glob, in the working folder: any other tool listed is refused, so do not call one. Answer the user\\'s questions, reading files when that helps. Nothing you say or do here reaches the main session.';\n\n/**\n * A question as a side chat sends it to Claude: after the note, in a system reminder, as Claude\n * Desktop sends its own. Not in the system prompt, which Claude Code keeps as the session had it\n * when it resumes a copy. Pelican shows the question alone, as Desktop does; the terminal shows\n * the note as well, as it does for Desktop's.\n */\nexport const sideChatPrompt = (text: string) => `<system-reminder>\\n${SIDE_CHAT_NOTE}\\n</system-reminder>\\n\\n${text}`;\n\n/** Whatever Claude Code would still ask about in a side chat is refused: there is nobody there to ask. */\nconst refuse: CanUseTool = async () => ({ behavior: 'deny', message: 'A side chat only reads. Ask in the session itself for anything else.' });\n\n/**\n * What a side chat's Claude runs with, over a session's own options:\n * - the reading tools and nothing else, and no MCP server at all (strictMcpConfig, with none\n * given), whatever the folder or the user's settings configure;\n * - Don't ask, with Bypass not allowed, so a mode picked elsewhere never reaches it;\n * - no checkpoints, since it changes no file, and no prompt suggestions, which nobody reads there.\n * Its system prompt stays the session's (see sideChatPrompt).\n */\nexport function sideChatOptions(): Partial<Options> {\n return {\n tools: [...SIDE_CHAT_TOOLS],\n strictMcpConfig: true,\n mcpServers: {},\n permissionMode: SIDE_CHAT_MODE,\n allowDangerouslySkipPermissions: false,\n canUseTool: refuse,\n enableFileCheckpointing: false,\n promptSuggestions: false,\n };\n}\n\n/** The settings a side chat takes from its session: the model, effort and speed, in its own mode. */\nexport function sideChatSettings(settings: RunSettings): RunSettings {\n const { model, effort, fast } = settings;\n return { ...(model ? { model } : {}), ...(effort ? { effort } : {}), ...(fast ? { fast } : {}), permissionMode: SIDE_CHAT_MODE };\n}\n\n/** A / command, which a side chat does not take: one could run what the folder brings. */\nexport const SIDE_CHAT_COMMAND = /^\\/[\\w:.-]+(?:\\s|$)/;\n\n/** How many copies of copies are followed back to the session they all start from. */\nconst COPIES_FOLLOWED = 8;\n\n/**\n * The session a transcript's side chat copies; undefined for any other transcript. A side chat\n * starts as a copy of another session (transcripts.ts, firstTurnSession) and was titled \"Side\n * chat\" under its own id, wherever in the file: after it, Claude Code writes the title it resumed\n * with, the session's own, when its Claude exits, as it does in most of Claude Desktop's. A copy\n * of a side chat (a branch from one of its questions) is a side chat of the same session.\n */\nexport async function sideChatSource(file: string, followed = 0): Promise<string | undefined> {\n const from = await firstTurnSession(file);\n if (!from || from === path.basename(file, '.jsonl')) return undefined;\n const copied = followed < COPIES_FOLLOWED ? await transcriptPath(from) : undefined;\n const outer = copied ? await sideChatSource(copied, followed + 1) : undefined;\n if (outer) return outer;\n return (await everTitled(file, SIDE_CHAT_TITLE)) ? from : undefined;\n}\n\n/** The session a side chat copies, as the session list tells them; undefined for any other session. */\nexport async function sideChatOf(sessionId: string): Promise<string | undefined> {\n const file = await transcriptPath(sessionId);\n return file ? sideChatSource(file) : undefined;\n}\n\nexport const isSideChat = async (sessionId: string): Promise<boolean> => Boolean(await sideChatOf(sessionId));\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 { sideChatSource } from './side-chat.js';\nimport { 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 // Side chats, Claude Desktop's and Pelican's: a copy of a conversation with a question or two of its own.\n const sideChatOf = fresh ? fresh.sideChatOf : file ? await sideChatSource(file) : 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/**\n * A transcript as the list last saw it: its size and time then, what the SDK made of it (null:\n * nothing to list), and the session it is a side chat of.\n */\ntype Seen = { id: string; file: string; size: number; mtimeMs: number; info: SDKSessionInfo | null; continuedIn?: string; sideChatOf?: 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 const sideChatOf = info ? await sideChatSource(entry.file) : undefined;\n seen.set(entry.file, { ...entry, info: info ?? null, ...(turn?.continuedIn ? { continuedIn: turn.continuedIn } : {}), ...(sideChatOf ? { sideChatOf } : {}) });\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 { durationText } from '../shared/workflows.js';\n// The conversation as the app shows it: the export leaves out what the view leaves out.\nimport { buildItems, cleanOutput, type SentFile, type WorkflowNotice } from '../web/lib/turns.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\n/** Backticks around code, more of them than any run inside it, so nothing in it ends the code. */\nconst fence = (code: string, fewest: number) => '`'.repeat(Math.max(fewest, ...Array.from(code.matchAll(/`+/g), (run) => run[0].length + 1)));\nconst inlineCode = (code: string) => (code.includes('`') ? `${fence(code, 1)} ${code} ${fence(code, 1)}` : `\\`${code}\\``);\nconst codeBlock = (code: string) => `${fence(code, 3)}\\n${code}\\n${fence(code, 3)}`;\n/** A command as typed: inline, or a block of its own when it has more lines, which would end inline code. */\nconst asCode = (code: string) => (/[\\r\\n]/.test(code) ? codeBlock(code) : inlineCode(code));\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 ? `: ${inlineCode(String(target).split(/\\r\\n?|\\n/)[0]!)}` : ''}`;\n};\n\n/**\n * A line of Claude Code's own, such as Interrupted, a failed request or a hook's word, in italics\n * as it is written: nothing in it is taken as Markdown.\n */\nconst note = (text: string) => text.split(/\\r\\n?|\\n/).map((line) => line.trim()).filter(Boolean)\n .map((line) => `*${line.replace(/[\\\\`*_[\\]<>&~|]/g, '\\\\$&')}*`).join('\\n');\n\n/** What a prompt carried besides its words: pictures, which have no names, and files by name. */\nconst attached = (pictures: number, files: SentFile[]) => {\n const all = [...(pictures === 1 ? ['a picture'] : pictures > 1 ? [`${pictures} pictures`] : []), ...files.map((file) => file.name)];\n return all.length > 0 ? [`Attached: ${all.join(', ')}`] : [];\n};\n\n/** A workflow's end, in the words of its line in the conversation. */\nconst workflowEnded = ({ name, status, durationMs }: WorkflowNotice) =>\n `Workflow ${name ? `${name} ` : ''}${status === 'completed' ? 'completed' : status === 'failed' ? 'failed' : 'stopped'}${durationMs !== undefined ? ` \u00B7 ${durationText(durationMs)}` : ''}`;\n\n/**\n * The conversation as Markdown, with all the conversation shows, as Claude Code's /export has all\n * its screen shows: prompts and replies in full with what was attached, `!` and `/` commands as\n * code with their output, tool calls as one line each, and Claude Code's own lines (a background\n * task's note, Interrupted, a failed request, a hook's word, a compaction) in italics. What the\n * conversation leaves out stays out: the notes Claude Code and Pelican give Claude with a prompt (a\n * side chat's note, in a system reminder), the tags around commands and a compaction's summary.\n * The days the conversation is marked off by are left out, as the terminal has none.\n */\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 const say = (who: 'You' | 'Claude', blocks: string[]) => {\n if (blocks.length === 0) return;\n if (who !== speaker) out.push(`## ${who}`, '');\n speaker = who;\n for (const block of blocks) out.push(block, '');\n };\n // What the conversation view shows, read the same way.\n for (const item of buildItems(messages, config.machine)) {\n if (item.kind === 'user') {\n const words = item.command ? [asCode(`${item.command.name} ${item.command.args}`.trim())] : item.text ? [item.text] : [];\n say('You', [...words, ...attached(item.images.length, item.files)]);\n } else if (item.kind === 'shell') {\n const output = [item.stdout, item.stderr].map(cleanOutput).filter((part) => part.trim()).join('\\n').replace(/^\\s*\\n/, '').trimEnd();\n // How it ended when not well, as the conversation marks it.\n const ended = item.ended ? note(item.ended === 'stopped' ? 'Stopped' : 'Failed') : '';\n say('You', [asCode(`!${item.command}`), ...(output ? [codeBlock(output)] : []), ...(ended ? [ended] : [])]);\n } else if (item.kind === 'notice' && item.tone === 'output') {\n // A `/` command's output, under the command.\n out.push(codeBlock(item.text), '');\n } else if (item.kind === 'notice') {\n const line = note(item.workflow ? workflowEnded(item.workflow) : item.text);\n if (line) out.push(line, '');\n speaker = undefined;\n } else if (item.kind === 'assistant') {\n const blocks: string[] = [];\n let tools: string[] = [];\n for (const part of item.parts) {\n if (part.kind === 'tool') tools.push(toolLine(part.call.name, part.call.input));\n else if (part.kind === 'text' && part.text.trim()) {\n if (tools.length > 0) blocks.push(tools.join('\\n'));\n tools = [];\n blocks.push(part.text.trim());\n }\n }\n if (tools.length > 0) blocks.push(tools.join('\\n'));\n say('Claude', blocks);\n } else if (item.kind === 'compact') {\n out.push(note('Context compacted'), '');\n speaker = undefined;\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", "/**\n * Characters that change how text reads without being seen: zero-width ones, and direction\n * overrides and isolates. A command can read as an echo while the shell runs something else.\n */\nconst HIDDEN = /[\\u061c\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u2064\\u2066-\\u2069\\ufeff]/g;\n\n/** The text with each such character shown as a token (\u27E8U+202E\u27E9), and whether there were any. */\nexport function revealHidden(text: string): { text: string; hidden: boolean } {\n let hidden = false;\n const shown = text.replace(HIDDEN, (ch) => {\n hidden = true;\n return `\u27E8U+${ch.codePointAt(0)!.toString(16).toUpperCase().padStart(4, '0')}\u27E9`;\n });\n return { text: shown, hidden };\n}\n\n/**\n * An emoji as the conversation shows it, with the invisible characters that are part of it: a\n * keycap, a flag of two letters or of a region's tags, or a picture with its text or emoji style,\n * its skin tone, and the joiners that make several pictures one.\n */\nexport const EMOJI = /[#*0-9]\\ufe0f?\\u20e3|\\p{RI}\\p{RI}|\\u{1f3f4}[\\u{e0061}-\\u{e007a}]{2}[\\u{e0030}-\\u{e0039}\\u{e0061}-\\u{e007a}]{1,4}\\u{e007f}|\\p{ExtPict}(?:\\p{EMod}|[\\ufe0e\\ufe0f])?(?:\\u200d\\p{ExtPict}(?:\\p{EMod}|\\ufe0f)?)*/u;\n", "import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport webpush from 'web-push';\n\nimport { EMOJI } from '../shared/hidden.js';\nimport type { PermissionRequest } from '../shared/protocol.js';\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 = {\n title: string;\n body: string;\n sessionId: string;\n tag: string;\n /** A request the notification can answer: Allow and Deny, where the device shows buttons. */\n request?: string;\n /** The command fits the one line of it Android's pop-up shows beside the buttons: Android offers them only then. */\n fitsOneLine?: true;\n};\n\n/** Characters a lock screen leaves out, outside an emoji: controls, line breaks, invisible and direction-changing ones. */\nconst UNSHOWN = /[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}\\p{Default_Ignorable_Code_Point}]+/u;\nconst EMOJI_OR_UNSHOWN = new RegExp(`(${EMOJI.source})|${UNSHOWN.source}`, 'gu');\nconst graphemes = new Intl.Segmenter('en', { granularity: 'grapheme' });\n\n/**\n * Text for a lock screen: one line, without control, invisible or direction-changing characters\n * (an emoji keeps those it is made of), and short. It ends at `max` characters as they show, cut\n * between them, never inside one (an emoji, a letter and its accents), and sooner where they take\n * more than 4 bytes each on average, and so as many code points: one character can hold any\n * number of them, and a push carries 4 KB. A character too long for that is left out, with the\n * rest of the text.\n */\nexport function oneLine(text: string, max = 120): string {\n const flat = text.replace(EMOJI_OR_UNSHOWN, (_, emoji?: string) => emoji ?? ' ').replace(/\\s+/g, ' ').trim();\n const most = 4 * max;\n let characters = 0;\n let bytes = 0;\n // Where a cut leaves room for the ellipsis, one character of 3 bytes.\n let cut = 0;\n for (const { segment, index } of graphemes.segment(flat)) {\n characters += 1;\n bytes += Buffer.byteLength(segment);\n if (characters > max || bytes > most) return `${flat.slice(0, cut)}\u2026`;\n if (characters < max && bytes + 3 <= most) cut = index + segment.length;\n }\n return flat;\n}\n\n/**\n * Text every notification shows as it is, in any system font: printable ASCII, one space between\n * words. Any other character may be drawn wider than counted (an emoji, CJK), blank (a Braille\n * blank, U+FFFC), joined to its neighbours, or not at all, and a command could then read as one\n * thing and run as another.\n */\nconst PLAIN = /^[!-~]+(?: [!-~]+)*$/;\n\n/**\n * How wide each printable ASCII character may be drawn, in tenths of an em: the widest of SF Pro\n * (macOS), Helvetica and Arial (as Roboto, on Android) and Tahoma (as Segoe UI, on Windows), as\n * Chrome measures them, rounded up.\n */\nconst WIDTHS: ReadonlyArray<readonly [number, string]> = [\n [3, \"'ijl\"],\n [4, ' !(),./:;I[\\\\]frt|'],\n [5, '\"-{}'],\n [6, '*127?JL_`acehknosuvxyz'],\n [7, '$0345689ABEFKPSTVXYZbdgpq'],\n [8, '#&+<=>CDGHNOQRU^w~'],\n [9, 'Mm'],\n [10, '%W'],\n [11, '@'],\n];\nconst tenths = new Map(WIDTHS.flatMap(([width, chars]) => [...chars].map((char) => [char, width] as const)));\n/** How wide text may be drawn; a character the table does not have is wider than any line. */\nconst widthOf = (text: string) => [...text].reduce((sum, char) => sum + (tenths.get(char) ?? Infinity), 0);\n\n/**\n * Where a notification's text is narrowest: how wide a line is, in tenths of an em, and how many\n * lines show. A macOS banner beside the site's icon has about 220 px of 13 px text (17 em) on two\n * lines, and 16.5 em leaves a margin; Windows' toasts and GNOME's banners are wider. Android's\n * pop-up shows the title and one line of the text beside the buttons, the rest only once it is\n * expanded: on a phone 360 dp wide, next to the site's icon, about 175 to 200 dp of 14 sp text\n * (12.5 to 14 em), and 12 em leaves a margin.\n */\nexport type Layout = { width: number; lines: number };\nexport const BANNER: Layout = { width: 165, lines: 2 };\nexport const ANDROID_POP_UP: Layout = { width: 120, lines: 1 };\n\n/**\n * Whether a line may break at the space between two words on every device. Unicode's line\n * breaking (UAX #14, rules LB13 to LB15) never breaks before ) ] } ! ? , . : ; or /, after ( [ or\n * {, or between a quote and an opening bracket, even at a space.\n */\nconst breaksBetween = (before: string, after: string) => {\n const last = before.at(-1)!;\n const first = after[0]!;\n return !')]}!?,.:;/'.includes(first) && !'([{'.includes(last) && !('\"\\''.includes(last) && '([{'.includes(first));\n};\n\n/**\n * Whether plain text shows whole in a layout: within its lines, wrapped only where every device may\n * break a line, which takes the most lines, and with no word wider than a line, since devices cut\n * those in different places.\n */\nexport function fits(text: string, { width: line, lines: most }: Layout): boolean {\n const words = text.split(' ');\n const space = tenths.get(' ')!;\n // The widths of what no device breaks: words, joined across a space no line breaks at.\n const pieces = [widthOf(words[0]!)];\n for (let i = 1; i < words.length; i += 1) {\n const width = widthOf(words[i]!);\n pieces.push(breaksBetween(words[i - 1]!, words[i]!) ? width : pieces.pop()! + space + width);\n }\n let lines = 0;\n let room = 0;\n for (const width of pieces) {\n if (width > line) return false;\n if (lines > 0 && space + width <= room) {\n room -= space + width;\n } else {\n lines += 1;\n room = line - width;\n }\n }\n return lines <= most;\n}\n\n/** What a Bash or PowerShell request may hold besides its command, none of which changes what runs. */\nconst BESIDES_COMMAND = new Set(['description', 'timeout', 'run_in_background']);\n\n/**\n * The command of a request, when a notification surely shows all that Allow would approve: Bash\n * or PowerShell with nothing more that changes how it runs (such as leaving the sandbox), in\n * printable ASCII with one space between words, short enough to show whole in two lines of the\n * narrowest notification. Never Claude's own description of it.\n */\nfunction shownWhole(request: PermissionRequest): string | undefined {\n if (request.toolName !== 'Bash' && request.toolName !== 'PowerShell') return undefined;\n const { command, ...rest } = request.input;\n if (typeof command !== 'string' || !PLAIN.test(command) || !fits(command, BANNER)) return undefined;\n const more = Object.entries(rest).some(([key, value]) => !BESIDES_COMMAND.has(key) && value !== undefined && value !== null && value !== false);\n return more ? undefined : command;\n}\n\n/**\n * What a notification for a request may answer, Allow and Deny, and the body it then has: a\n * command Claude wants to run, shown whole, since only then does the notification show all that\n * Allow approves; on Android only one that fits the one line its pop-up shows beside the buttons\n * (`fitsOneLine`, which the service worker checks there). Anything else opens the session: an\n * edit, an MCP tool or another tool whose input it does not show, a command too long or with other\n * characters, a question or a plan, and a request Claude Code says must not be allowed by a stray\n * tap. Not even Deny is offered there: it would answer, unseen, a request the page shows in full,\n * and one rule for when a notification answers stays clear.\n */\nexport function answerable(request: PermissionRequest): Partial<Pick<PushPayload, 'body' | 'request' | 'fitsOneLine'>> {\n const command = request.elicitation || request.defaultToNo ? undefined : shownWhole(request);\n if (command === undefined) return {};\n return { body: command, request: request.id, ...(fits(command, ANDROID_POP_UP) ? { fitsOneLine: true } : {}) };\n}\n\n/**\n * What a push carries: push services take 4,096 bytes (RFC 8030), and its encryption (aes128gcm,\n * RFC 8188) takes 103 of them, a header of 86, a padding byte and a tag of 16. A push over it is\n * refused, and nobody hears that Claude waits.\n */\nconst PUSH_BYTES = 4096 - 103;\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 // Whoever sends it, its words are a lock screen's: at most 480 bytes of title and 720 of text, far\n // within a push. The title is the session's, which can hold what hides text or turns it around.\n const shown = { ...payload, title: oneLine(payload.title) || 'Claude Code', body: oneLine(payload.body, 180) };\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 linked = JSON.stringify({ ...shown, url });\n // A link too long to go with it (an address of kilobytes) is left out, not the notification.\n const body = Buffer.byteLength(linked) <= PUSH_BYTES ? linked : JSON.stringify(shown);\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';\nimport { randomBytes, randomUUID } from 'node:crypto';\nimport { closeSync, openSync, read, unlinkSync, writeSync } from 'node:fs';\nimport { mkdir, open, realpath, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { StringDecoder } from 'node:string_decoder';\nimport { promisify } from 'node:util';\n\nimport { resolveSettings } from '@anthropic-ai/claude-agent-sdk';\n\nimport type { SavedOutputPage } from '../shared/protocol.js';\nimport { openRegular } from './open.js';\nimport { readHistory, transcriptRow } from './history.js';\nimport { transcriptPath } from './transcripts.js';\nimport { launchFor } from './trust.js';\n\n/** What the pages keep of a running command's output, in characters, before the rest is left out of them; the command runs on. */\nexport const MAX_OUTPUT = 200_000;\n/**\n * How long a command may run. Its output shows as it comes and Stop ends it, so this only ends\n * one nobody came back to: longer than a build or a test run takes, and said when it is hit.\n */\nexport const MAX_RUN_MS = 30 * 60_000;\n/** After the shell exits, how long output still on its way may take to arrive. */\nconst DRAIN_MS = 200;\n/** Ending a command asks first (SIGTERM: a test runner can tidy up), then insists. */\nconst KILL_AFTER_MS = 2000;\n\n/**\n * How much of a command's output Claude Code's bash mode reads back, in bytes, and how much of\n * what it read Claude gets inline, in characters: its `bashOutputMaxChars` setting for both, held\n * to 4,000 to 128,000; unset, it reads as much as the BASH_MAX_OUTPUT_LENGTH variable says, from 1\n * to 150,000 (H1 in Claude Code), and gives 30,000 inline. Neither set: 30,000 of both.\n */\nexport const OUTPUT_LIMITS = { standard: 30_000, least: 4_000, most: 128_000, variableMost: 150_000 };\n/** Claude Code's two limits for a command's output, as bashModeSettings finds them. */\nexport type OutputLimits = { readMax: number; inlineMax: number };\nconst STANDARD_LIMITS: OutputLimits = { readMax: OUTPUT_LIMITS.standard, inlineMax: OUTPUT_LIMITS.standard };\n/** How much of a longer output Claude Code saves to a file: 64 MB, from which on it says it cut it. */\nexport const SAVED_BYTES = 64 * 1024 * 1024;\n/** How much of an output saved to a file Claude Code shows Claude in its place, in characters. */\nconst PREVIEW_CHARS = 2_000;\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\nconst readAt = promisify(read);\n\n/**\n * What a `!` command printed, stdout and stderr together in the order it wrote them, kept as\n * Claude Code keeps it: its start at hand, as much as Claude Code ever reads back of one, and when\n * there is more, all of it, up to the 64 MB Claude Code saves of one, written to a file as it comes\n * rather than held. The file has no name once open (it goes with Pelican, whatever happens).\n */\nexport class CommandOutput {\n /** All it printed, in bytes, also past what is kept. */\n bytes = 0;\n private head: Buffer[] = [];\n private held = 0;\n private spill: { fd: number; written: number; name?: string } | undefined;\n /** The file could not be written: only the start is kept. */\n private lost = false;\n\n add(chunk: Buffer): void {\n const before = this.bytes;\n this.bytes += chunk.length;\n if (this.held < OUTPUT_LIMITS.variableMost) {\n const part = chunk.subarray(0, OUTPUT_LIMITS.variableMost - this.held);\n this.head.push(part);\n this.held += part.length;\n }\n if (this.bytes <= OUTPUT_LIMITS.variableMost || this.lost) return;\n if (this.spill) {\n this.write(chunk);\n return;\n }\n // The first bytes past the start: the file gets the start, then the rest as it comes.\n try {\n const name = path.join(os.tmpdir(), `pelican-${randomUUID()}.out`);\n const fd = openSync(name, 'wx+', 0o600);\n this.spill = { fd, written: 0, name };\n unlinkSync(name);\n delete this.spill.name;\n } catch {\n if (!this.spill) {\n this.lost = true;\n return;\n }\n }\n this.write(Buffer.concat(this.head));\n this.write(chunk.subarray(OUTPUT_LIMITS.variableMost - before));\n }\n\n private write(data: Buffer): void {\n const spill = this.spill;\n if (!spill) return;\n const part = data.subarray(0, Math.max(0, SAVED_BYTES - spill.written));\n if (part.length === 0) return;\n try {\n for (let at = 0; at < part.length;) at += writeSync(spill.fd, part, at, part.length - at, spill.written + at);\n spill.written += part.length;\n } catch {\n this.lost = true;\n this.release();\n }\n }\n\n /** Its first `max` bytes as text; a character cut in two at the end reads as U+FFFD, as in Claude Code. */\n text(max: number): string {\n return Buffer.concat(this.head).subarray(0, max).toString('utf8');\n }\n\n /** All of it, up to Claude Code's 64 MB, written to `file`, which must not exist yet; readable only by you. */\n async saveTo(file: string): Promise<void> {\n if (this.bytes <= OUTPUT_LIMITS.variableMost) {\n await writeFile(file, Buffer.concat(this.head), { flag: 'wx', mode: 0o600 });\n return;\n }\n if (!this.spill || this.lost) throw new Error('The output could not be kept');\n const { fd, written } = this.spill;\n const target = await open(file, 'wx', 0o600);\n try {\n const buffer = Buffer.alloc(1024 * 1024);\n for (let at = 0; at < written;) {\n const { bytesRead } = await readAt(fd, buffer, 0, Math.min(buffer.length, written - at), at);\n if (bytesRead === 0) throw new Error('The output file came up short');\n await target.write(buffer, 0, bytesRead, at);\n at += bytesRead;\n }\n } finally {\n await target.close();\n }\n }\n\n /** Lets go of the file it went to: done with, once in the conversation. */\n release(): void {\n const spill = this.spill;\n if (!spill) return;\n this.spill = undefined;\n this.lost = true;\n try {\n closeSync(spill.fd);\n } catch {\n // Closed already.\n }\n if (spill.name) {\n try {\n unlinkSync(spill.name);\n } catch {\n // Gone already.\n }\n }\n }\n}\n\n/** A `!` command run in the session's folder, once it is done; it goes into the conversation as Claude Code's bash mode writes it. */\nexport type ShellResult = {\n command: string;\n /** What it printed, stdout and stderr together as it wrote them. */\n output: CommandOutput;\n /** Exit code; null when it did not finish on its own (see `endedBy`). */\n code: number | null;\n durationMs: number;\n /** Ended by Stop, or by Pelican once it ran past the limit (`limitMs`), rather than on its own. */\n endedBy?: 'stop' | 'limit';\n /** The limit it ran under, for saying it when it was hit. */\n limitMs?: number;\n};\n\n/** A `!` command under way. */\nexport type CommandRun = {\n /** Settles when the command's shell is done: on its own, by Stop, or at the limit. */\n readonly result: Promise<ShellResult>;\n /** Ends it and everything it started, the whole process group, not just the shell: asked, then made to. */\n stop: () => void;\n /**\n * Asks it to end, as Pelican does when it shuts down, with no timer of its own to insist: `kill`\n * does that, when the time to tidy up is over. `signal: false`: it was asked already (by systemd).\n */\n ask: (signal: boolean) => void;\n /** Whether anything it started still runs (its process group; on Windows, its shell). */\n alive: () => boolean;\n /** Ends at once what is left of a command asked to stop, which did not: for when Pelican exits. */\n kill: () => void;\n};\n\n/**\n * Runs one `!` command in a session's folder through the user's login shell, like Claude Code's\n * bash mode: no terminal, stdout and stderr into one pipe, so they stay in the order the command\n * wrote them, as in the file Claude Code gives both; the output handed on as it comes\n * (`onOutput`) and kept as Claude Code keeps it (CommandOutput); ended by Stop or after `limitMs`.\n * `env` is what Claude Code itself gets in the folder (trust.ts, launchFor): in one kept to the\n * user's settings only, git runs none of the repository's own programs, for a `!` command as for\n * Claude's.\n *\n * The command gets a process group of its own. It is done when its shell is: a process it left in\n * the background (`npm run dev &`) keeps running, instead of holding the command open for its\n * whole life by keeping the output pipe. Ending it ends everything it started, not just the shell,\n * whose children would otherwise run on.\n */\nexport function startCommand(cwd: string, command: string, options: { limitMs?: number; onOutput?: (text: string) => void; env?: Record<string, string> } = {}): CommandRun {\n const limitMs = options.limitMs ?? MAX_RUN_MS;\n const shell = process.env.SHELL || '/bin/bash';\n const started = Date.now();\n const output = new CommandOutput();\n const decoder = new StringDecoder('utf8');\n let done = false;\n let endedBy: ShellResult['endedBy'];\n let settle!: (result: ShellResult) => void;\n const result = new Promise<ShellResult>((resolve) => {\n settle = resolve;\n });\n // The login shell is started by sh with its stderr on its stdout: one pipe for both.\n const child = spawn(groups ? '/bin/sh' : shell, groups ? ['-c', 'exec \"$0\" -lc \"$1\" 2>&1', shell, command] : ['-lc', command], {\n cwd,\n env: { ...process.env, ...options.env, PAGER: 'cat', GIT_PAGER: 'cat', TERM: 'dumb' },\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: groups,\n });\n const signal = (name: NodeJS.Signals) => {\n try {\n if (groups && child.pid) process.kill(-child.pid, name);\n else child.kill(name);\n } catch {\n // Already gone.\n }\n };\n const end = (by: NonNullable<ShellResult['endedBy']>, { ask = true, insist = true } = {}) => {\n // Once its shell has exited it is done: what it left in the background is meant to run on.\n if (done || endedBy || child.exitCode !== null || child.signalCode !== null) return;\n endedBy = by;\n if (ask) signal('SIGTERM');\n // What ignores the request still goes, also once the shell itself has exited.\n if (insist) setTimeout(() => signal('SIGKILL'), KILL_AFTER_MS).unref();\n };\n // Kept as Claude Code keeps it, and handed on as text, a character split between two reads kept whole.\n const take = (chunk: Buffer) => {\n if (done) return;\n output.add(chunk);\n const text = decoder.write(chunk);\n if (text) options.onOutput?.(text);\n };\n child.stdout.on('data', take);\n // Only sh's own word, should it fail to start the shell (on Windows, the shell's stderr).\n child.stderr.on('data', take);\n const timer = setTimeout(() => end('limit'), limitMs);\n let drain: NodeJS.Timeout | undefined;\n const finish = (code: number | null, error?: Error) => {\n if (done) return;\n if (error) take(Buffer.from(error.message));\n const rest = decoder.end();\n if (rest) options.onOutput?.(rest);\n done = true;\n clearTimeout(timer);\n clearTimeout(drain);\n settle({\n command,\n output,\n code: endedBy ? null : code,\n durationMs: Date.now() - started,\n ...(endedBy ? { endedBy, ...(endedBy === 'limit' ? { limitMs } : {}) } : {}),\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, sig) => finish(sig ? null : code));\n child.on('exit', (code, sig) => {\n drain = setTimeout(() => finish(sig ? 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 return {\n result,\n stop: () => end('stop'),\n ask: (asking) => end('stop', { ask: asking, insist: false }),\n alive: () => (groups && child.pid !== undefined ? running(child.pid) : child.exitCode === null && child.signalCode === null),\n // Only one that was asked to end: what a finished command left in the background runs on.\n kill: () => {\n if (endedBy) signal('SIGKILL');\n },\n };\n}\n\nconst escape = (text: string) => text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nconst count = (n: number, unit: string) => `${n} ${unit}${n === 1 ? '' : 's'}`;\nconst spoken = (ms: number) => (ms >= 60_000 ? count(Math.round(ms / 60_000), 'minute') : count(Math.max(1, Math.round(ms / 1000)), 'second'));\n\n/** How a command Pelican ended says so, where Claude Code has no word for it: Stop, the time limit. */\nfunction ending(result: ShellResult): string {\n if (result.endedBy === 'stop') return '\\n(stopped)';\n if (result.endedBy === 'limit') return `\\n(stopped after ${spoken(result.limitMs ?? MAX_RUN_MS)})`;\n return '';\n}\n\n/** `bashOutputMaxChars` as Claude Code takes it: a whole number above 0, held to 4,000 to 128,000; else unset. */\nconst settingLimit = (setting: unknown) => (typeof setting === 'number' && Number.isSafeInteger(setting) && setting > 0\n ? Math.min(OUTPUT_LIMITS.most, Math.max(OUTPUT_LIMITS.least, setting))\n : undefined);\n\n/**\n * A number in a variable as Claude Code reads one (its Up): `5000`, `5e3`, `5,000`, `5_000` and\n * `5 000` alike, else the whole number it starts with.\n */\nfunction numberIn(raw: string): number {\n const text = raw.trim();\n if (text.length <= 32) {\n if (/^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)[eE][+-]?\\d+$/.test(text)) {\n const n = Number(text);\n return Number.isInteger(n) ? n : NaN;\n }\n if (/^[+-]?\\d{1,3}([_,\\u00a0\\u202f ])\\d{3}(?:\\1\\d{3})*$/.test(text)) return parseInt(text.replace(/[_,\\u00a0\\u202f ]/g, ''), 10);\n }\n return parseInt(text, 10);\n}\n\n/** BASH_MAX_OUTPUT_LENGTH as Claude Code takes it: a number from 1, 150,000 at most; else 30,000. */\nfunction variableLimit(value: string | undefined): number {\n if (!value) return OUTPUT_LIMITS.standard;\n const n = numberIn(value);\n return Number.isNaN(n) || n <= 0 ? OUTPUT_LIMITS.standard : Math.min(n, OUTPUT_LIMITS.variableMost);\n}\n\n/** Commands whose exit code 1 is an answer, not a failure, as Claude Code reads them: no match, files differ, false. */\nconst ANSWERS = new Set(['grep', 'rg', 'egrep', 'fgrep', 'find', 'diff', 'test', '[']);\n/** A command line longer than this Claude Code reads whole, without taking it apart. */\nconst PARSED_MAX = 10_000;\n\n/** Whether a word starts at `i`: the line's start, or after a blank or a character that ends a word. */\nconst startsWord = (line: string, i: number) => i === 0 || /[ \\t\\r\\n;&|()<>]/.test(line[i - 1]!);\n/** Whether a word ends at `i`: the line's end, a blank or a character that ends a word. */\nconst endsWord = (line: string, i: number) => i >= line.length || /[ \\t\\r\\n;&|()<>]/.test(line[i]!);\n\n/**\n * Where a here-document whose `<<` ends at `from` stops: past the line that is its word alone (with\n * `<<-`, after tabs), or at the end. Undefined when no word follows, which makes it none.\n */\nfunction hereDocumentEnd(line: string, from: number): number | undefined {\n let i = from;\n const tabs = line[i] === '-';\n if (tabs) i += 1;\n while (line[i] === ' ' || line[i] === '\\t') i += 1;\n let word = '';\n while (i < line.length && !endsWord(line, i)) {\n const c = line[i]!;\n if (c === '\\'' || c === '\"') {\n const close = line.indexOf(c, i + 1);\n const stop = close < 0 ? line.length : close;\n word += line.slice(i + 1, stop);\n i = stop + 1;\n } else if (c === '\\\\') {\n word += line[i + 1] ?? '';\n i += 2;\n } else {\n word += c;\n i += 1;\n }\n }\n if (!word) return undefined;\n // The rest of its line goes with it, then its body.\n for (let at = line.indexOf('\\n', i); at >= 0;) {\n const next = line.indexOf('\\n', at + 1);\n const text = line.slice(at + 1, next < 0 ? line.length : next);\n if ((tabs ? text.replace(/^\\t+/, '') : text) === word) return next < 0 ? line.length : next;\n at = next;\n }\n return line.length;\n}\n\n/**\n * The statements of a command line, as Claude Code's bash mode takes one apart to read what its\n * exit code means (its own parser: the line's lists and pipelines taken apart, each statement in\n * them whole). They end at `;`, `&`, `&&`, `||`, `|`, `|&` and line ends, never inside quotes,\n * `(\u2026)`, `$(\u2026)`, `${\u2026}`, backquotes or `[[ \u2026 ]]`, so a subshell or a group is one statement, its\n * first word `(grep` or `{`. A comment, from a `#` that starts a word, is none, whatever it holds;\n * a here-document's line from its `<<` on, and its body, are part of the statement before them.\n * Some lines no shell takes come apart as that parser takes them: a `)` or a `}` with nothing open,\n * or a `;` with nothing before it, is a statement of its own, and words after a subshell or a\n * `[[ \u2026 ]]` that starts a statement start another.\n */\nfunction statements(line: string): string[] {\n if (line.length > PARSED_MAX) return [line];\n const out: string[] = [];\n /** What is open, by what closes it: `)`, `}` (of `${`), a backquote, `\"`, `]]`. */\n const open: string[] = [];\n let start = 0;\n /** Where the statement under way began a subshell or a `[[`, which ends it once closed. */\n let leads: number | undefined;\n /** The last separator was one after which a statement may start: not a pipe, not `&&` or `||`. */\n let free = true;\n /** A statement ended with no separator after it yet (a subshell that led it, a `}` of its own). */\n let ended = false;\n /** The statement under way has a redirection after its words, which the rest of it then belongs to, a `#` too. */\n let redirected = false;\n const end = (at: number, next: number) => {\n const text = line.slice(start, at).trim();\n if (text) out.push(text);\n start = next;\n leads = undefined;\n redirected = false;\n };\n const alone = (at: number, text: string) => {\n end(at, at + text.length);\n out.push(text);\n ended = true;\n };\n const blank = (at: number) => line.slice(start, at).trim() === '';\n for (let i = 0; i < line.length; i += 1) {\n const c = line[i]!;\n const top = open.at(-1);\n if (top === '\"') {\n if (c === '\\\\') i += 1;\n else if (c === '\"') open.pop();\n else if (c === '`') open.push('`');\n else if (c === '$' && (line[i + 1] === '(' || line[i + 1] === '{')) {\n open.push(line[i + 1] === '(' ? ')' : '}');\n i += 1;\n }\n continue;\n }\n if (c === '\\\\') {\n i += 1;\n continue;\n }\n if (c === '\\'') {\n const close = line.indexOf('\\'', i + 1);\n i = close < 0 ? line.length : close;\n continue;\n }\n if (c === '$' && line[i + 1] === '\\'') {\n // $'\u2026' takes backslashes.\n let j = i + 2;\n while (j < line.length && line[j] !== '\\'') j += line[j] === '\\\\' ? 2 : 1;\n i = j;\n continue;\n }\n if (c === '\"') {\n open.push('\"');\n continue;\n }\n if (c === '`') {\n if (top === '`') open.pop();\n else open.push('`');\n continue;\n }\n if (c === '$' && line[i + 1] === '{') {\n open.push('}');\n i += 1;\n continue;\n }\n if (c === '(') {\n if (open.length === 0 && blank(i)) leads = i;\n open.push(')');\n continue;\n }\n if (c === ')') {\n if (top === ')') {\n open.pop();\n if (open.length === 0 && leads !== undefined) {\n end(i + 1, i + 1);\n ended = true;\n }\n } else if (open.length === 0) {\n alone(i, ')');\n }\n continue;\n }\n if (c === '}' && top === '}') {\n open.pop();\n continue;\n }\n if (c === '#' && top !== '}' && !(redirected && open.length === 0) && startsWord(line, i)) {\n const eol = line.indexOf('\\n', i);\n const stop = eol < 0 ? line.length : eol;\n if (open.length === 0) end(i, stop);\n i = stop - 1;\n continue;\n }\n if (top === ']]') {\n if (c === ']' && line[i + 1] === ']' && startsWord(line, i) && endsWord(line, i + 2)) {\n open.pop();\n i += 1;\n if (leads !== undefined) {\n end(i + 1, i + 1);\n ended = true;\n }\n }\n continue;\n }\n if (open.length > 0) continue;\n if (c === '[' && line[i + 1] === '[' && startsWord(line, i) && endsWord(line, i + 2)) {\n if (blank(i)) leads = i;\n open.push(']]');\n i += 1;\n continue;\n }\n if (c === '}' && blank(i) && endsWord(line, i + 1)) {\n alone(i, '}');\n continue;\n }\n // A redirection after a command's words (not a `[ \u2026 ]`'s) takes the words after it, `#` among them.\n if ((c === '>' || (c === '<' && line[i + 1] !== '<')) && line[i + 1] !== '(' && !blank(i) && !/^\\[\\s/.test(line.slice(start, i).trimStart())) redirected = true;\n if (c === '<' && line[i + 1] === '<') {\n // `<<<` gives a string: no here-document, and what follows it is the command's again.\n const string = line[i + 2] === '<';\n const stop = string ? undefined : hereDocumentEnd(line, i + 2);\n if (string) redirected = false;\n if (stop === undefined) {\n i += string ? 2 : 1;\n } else {\n end(i, stop);\n i = stop - 1;\n }\n continue;\n }\n if (c === ';' || c === '\\n') {\n const both = c === ';' && line[i + 1] === ';';\n if (c === ';' && blank(i) && free && !ended) out.push(both ? ';;' : ';');\n end(i, i + (both ? 2 : 1));\n if (both) i += 1;\n free = true;\n ended = false;\n continue;\n }\n if (c === '|') {\n // `>|` writes over a file.\n if (line[i - 1] === '>') continue;\n const two = line[i + 1] === '|' || line[i + 1] === '&';\n end(i, i + (two ? 2 : 1));\n if (two) i += 1;\n free = false;\n ended = false;\n continue;\n }\n if (c === '&') {\n if (line[i + 1] === '&') {\n end(i, i + 2);\n i += 1;\n free = false;\n ended = false;\n continue;\n }\n // `2>&1`, `<&0`, `&>file`: redirections.\n if (line[i - 1] === '>' || line[i - 1] === '<' || line[i + 1] === '>') continue;\n end(i, i + 1);\n free = true;\n ended = false;\n }\n }\n end(line.length, line.length);\n return out;\n}\n\n/**\n * Whether a command that ended on its own failed, as Claude Code's bash mode decides it: a code\n * other than 0, except 1 from a command for which 1 is an answer (grep finding nothing, diff\n * finding files differ, test being false, also `git diff` and `git grep`), which went well. The\n * command is the first word of the line's last statement (see statements), as Claude Code reads it.\n */\nfunction failed(command: string, code: number): boolean {\n const words = (statements(command).at(-1) || command).trim().split(/\\s+/);\n const answers = words[0] === 'git' ? ['diff', 'grep'].includes(gitCommand(words) ?? '') : ANSWERS.has(words[0] ?? '');\n return answers ? code >= 2 : code !== 0;\n}\n\n/** The git command a command line runs (`diff` in `git -C app diff --stat`). */\nfunction gitCommand(words: readonly string[]): string | undefined {\n for (let i = 1; i < words.length; i += 1) {\n const word = words[i]!;\n if (word === '-C' || word === '-c') i += 1;\n else if (!word.startsWith('-')) return word;\n }\n return undefined;\n}\n\n/** A command that went well, as Claude Code's bash mode tells them apart: it ended on its own, and did not fail. */\nconst succeeded = (result: ShellResult) => !result.endedBy && result.code !== null && !failed(result.command, result.code);\n\n/** The first `end` characters, a character Unicode writes as two kept whole. */\nfunction head(text: string, end: number): string {\n const at = Math.min(end, text.length);\n const code = text.charCodeAt(at - 1);\n return text.slice(0, at < text.length && code >= 0xd800 && code <= 0xdbff ? at - 1 : at);\n}\n\n/** Sizes as Claude Code says them: 2KB, 97.7KB, 1.2MB, in bytes. */\nfunction sizeText(size: number): string {\n const kb = size / 1024;\n if (kb < 1) return `${size} bytes`;\n if (kb < 1024) return `${kb.toFixed(1).replace(/\\.0$/, '')}KB`;\n const mb = kb / 1024;\n if (mb < 1024) return `${mb.toFixed(1).replace(/\\.0$/, '')}MB`;\n return `${(mb / 1024).toFixed(1).replace(/\\.0$/, '')}GB`;\n}\n\n/**\n * The output of a command that went well as Claude Code's bash mode gives it to Claude: blank lines\n * at its start and space at its end trimmed, and the hints some programs print for Claude Code\n * (`<claude-code-hint \u2026 />` on a line of its own) taken out.\n */\nfunction trimmed(text: string): string {\n const lines = `${text.trimEnd()}\\n`.split('\\n');\n let from = 0;\n while (from < lines.length && lines[from]!.trim() === '') from += 1;\n let to = lines.length - 1;\n while (to >= from && lines[to]!.trim() === '') to -= 1;\n let out = lines.slice(from, to + 1).join('\\n');\n if (out.includes('<claude-code-hint')) {\n const stripped = out.replace(/^[ \\t]*<claude-code-hint[ \\t][^>\\r\\n]*\\/>[ \\t]*(?=\\r|\\n|$)/gm, '');\n if (stripped !== out) out = stripped.replace(/\\n{3,}/g, '\\n\\n');\n }\n return out.replace(/^(\\s*\\n)+/, '').trimEnd();\n}\n\n/**\n * What Claude Code puts in the conversation in place of an output too long to go there, word for\n * word: where all of it was saved and how big it is (from 64 MB on, that only the first 64 MB were\n * saved), then its start as Claude would have had it, up to 2KB, ending with a line when one ends\n * past halfway. As in Claude Code, the start is not escaped.\n */\nfunction persistedOutput(text: string, file: string, size: number): string {\n const saved = size >= SAVED_BYTES\n ? `Output exceeded the ${sizeText(SAVED_BYTES)} persist limit; only the first ${sizeText(SAVED_BYTES)} were saved to: ${file}`\n : `Output too large (${sizeText(size)}). Full output saved to: ${file}`;\n const more = text.length > PREVIEW_CHARS;\n const line = text.slice(0, PREVIEW_CHARS).lastIndexOf('\\n');\n const preview = more ? head(text, line > PREVIEW_CHARS / 2 ? line : PREVIEW_CHARS) : text;\n return `<persisted-output>\\n${saved}\\n\\nPreview (first ${sizeText(PREVIEW_CHARS)}):\\n${preview}${more ? '\\n...\\n' : '\\n'}</persisted-output>`;\n}\n\n/** A command's result as it goes to Claude: Claude Code's limits for it, and where it was saved when it went past them. */\nexport type ForClaude = ShellResult & Partial<OutputLimits> & {\n /** Where the output was saved in place of the conversation, as Claude Code saves it (the session's tool-results folder). */\n savedTo?: string;\n /** How big Claude Code says that is: the text it read, in characters, when that is what it saved; else all of it, in bytes. */\n savedSize?: number;\n};\n\n/**\n * The output as Claude Code's bash mode puts it in the conversation, from what it reads back of it\n * (`readMax` bytes). A command that went well: in `<bash-stdout>`, trimmed (see trimmed), or Claude\n * Code's word that it printed nothing; saved in place of the conversation, Claude Code's preview of\n * the file (`savedTo`). One that failed: in `<bash-stderr>` as it came, cut there. Escaped so it\n * cannot end its tags. One Pelican ended (Stop, the time limit), which Claude Code has no record of\n * its own for, as one that failed, with a word on how it ended.\n */\nfunction outputText(result: ForClaude): string {\n const tags = (stdout: string, stderr: string) => `<bash-stdout>${stdout}</bash-stdout><bash-stderr>${stderr}</bash-stderr>`;\n const start = result.output.text(result.readMax ?? OUTPUT_LIMITS.standard);\n if (!succeeded(result)) return tags('', escape(start + ending(result)));\n const text = trimmed(start);\n if (result.savedTo) return tags(persistedOutput(text, result.savedTo, result.savedSize ?? result.output.bytes), '');\n return tags(escape(text || '(Bash completed with no output)'), '');\n}\n\n/**\n * What Claude Code's bash mode puts first when Claude is not to answer, in its own words: Claude\n * keeps the command as context and does not reply to it.\n */\nexport const BASH_CAVEAT = '<local-command-caveat>The command below was run directly in Claude Code, not sent to you as a request, and its output goes straight to the user. It\\'s recorded here as context for later messages.</local-command-caveat>';\n\n/**\n * A command and its output as Claude Code's bash mode adds them to the conversation, so the CLI\n * and Desktop show Pelican's the same way, and the other way round: the command as typed, then\n * its output (outputText), with the caveat first when Claude is not to answer.\n */\nexport function bashModeMessages(result: ForClaude, respond: boolean): Array<{ text: string; meta?: true }> {\n return [\n ...(respond ? [] : [{ text: BASH_CAVEAT, meta: true as const }]),\n { text: `<bash-input>${result.command}</bash-input>` },\n { text: outputText(result) },\n ];\n}\n\nconst SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst NAME_LETTERS = '0123456789abcdefghijklmnopqrstuvwxyz';\n\n/** A session's tool-results folder, where Claude Code saves what is too long for the conversation: beside its transcript. */\nasync function toolResultsFolder(sessionId: string): Promise<string | undefined> {\n if (!SESSION_ID.test(sessionId)) return undefined;\n const transcript = await transcriptPath(sessionId);\n return transcript ? path.join(path.dirname(transcript), sessionId, 'tool-results') : undefined;\n}\n\n/** A file Claude Code names in a session's tool-results folder: `b` and eight letters for a `!` command's, a tool call's id for others'. */\nconst SAVED_NAME = /^[A-Za-z0-9_-]{1,128}\\.(?:txt|json)$/;\n/** How much of a saved output one read gives: a page a phone takes in, the next a tap away. */\nexport const SAVED_PAGE_BYTES = 256 * 1024;\n\n/**\n * The session the record of a long output in this one was copied from, by its name, where that\n * is the session its saved file's path names: Claude Code's forkSession copies a session's rows,\n * each saying where from (`forkedFrom`), and leaves the files where they were. The record is found\n * among the conversation's messages, as read for its pages, and its own row read again, alone.\n */\nasync function copiedFrom(sessionId: string, name: string): Promise<string | undefined> {\n const transcript = SESSION_ID.test(sessionId) ? await transcriptPath(sessionId) : undefined;\n if (!transcript) return undefined;\n for (const message of await readHistory(transcript)) {\n if (message.role !== 'user') continue;\n const text = message.blocks.map((block) => (block.type === 'text' ? block.text : '')).join('');\n if (!text.includes('<persisted-output>')) continue;\n for (const [, file] of text.matchAll(/saved to: ([^\\n]+)/g)) {\n const parts = file!.split(/[\\\\/]/);\n const owner = parts.at(-3);\n if (parts.at(-1) !== name || parts.at(-2) !== 'tool-results' || !owner || !SESSION_ID.test(owner) || owner === sessionId) continue;\n const forked = (await transcriptRow(transcript, message.uuid))?.forkedFrom as { sessionId?: unknown } | undefined;\n if (forked?.sessionId === owner) return owner;\n }\n }\n return undefined;\n}\n\n/**\n * One page of an output Claude Code saved in place of one too long for the conversation (a long\n * `!` command's, as its record names it), from `from` bytes in, whole lines where it can, whole\n * characters always: read by its name alone from that session's own tool-results folder, or, for\n * a record a fork copied, from the folder of the session it was copied from (copiedFrom). Only a\n * regular file reached through no link and with no other name (no hard link to it). Undefined for\n * anything else, or once Claude Code has let it go.\n */\nexport async function savedOutputPage(sessionId: string, name: string, from: number): Promise<SavedOutputPage | undefined> {\n if (!SAVED_NAME.test(name) || !Number.isSafeInteger(from) || from < 0) return undefined;\n return await pageIn(sessionId, name, from) ?? await pageIn(await copiedFrom(sessionId, name), name, from);\n}\n\nasync function pageIn(sessionId: string | undefined, name: string, from: number): Promise<SavedOutputPage | undefined> {\n const folder = sessionId ? await toolResultsFolder(sessionId) : undefined;\n if (!sessionId || !folder) return undefined;\n try {\n // Where it must be, with only the projects' own folders resolved: a link on the way leads elsewhere.\n const expected = path.join(await realpath(path.dirname(path.dirname(folder))), sessionId, 'tool-results', name);\n if (await realpath(path.join(folder, name)) !== expected) return undefined;\n const handle = await openRegular(expected);\n try {\n const { size, nlink } = await handle.stat();\n // Claude Code writes each one anew; one with another name is another file, put there.\n if (nlink > 1) return undefined;\n const start = Math.min(from, size);\n const buffer = Buffer.alloc(Math.min(SAVED_PAGE_BYTES, size - start));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, start);\n let begin = 0;\n // Asked for from inside a character: from the next whole one.\n while (start > 0 && begin < bytesRead && (buffer[begin]! & 0xc0) === 0x80) begin += 1;\n let end = bytesRead;\n if (start + bytesRead < size) {\n // A page ends with a line, where one ends in its second half, and never inside a character.\n const line = buffer.subarray(0, end).lastIndexOf(0x0a);\n if (line >= begin + (end - begin) / 2) end = line + 1;\n else {\n let lead = end - 1;\n while (lead > begin && (buffer[lead]! & 0xc0) === 0x80) lead -= 1;\n const byte = buffer[lead]!;\n const length = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n if (lead + length > end) end = lead;\n }\n }\n const next = start + end;\n return { text: buffer.toString('utf8', begin, end), from: start + begin, size, ...(next < size ? { next } : {}) };\n } finally {\n await handle.close();\n }\n } catch {\n return undefined;\n }\n}\n\n/**\n * A command's result as it goes to Claude, as Claude Code's bash mode sends it, saved where Claude\n * Code saves one, in the session's tool-results folder beside its transcript. One that went well\n * and printed more than Claude Code reads back (`readMax` bytes): all of it, up to 64 MB, under a\n * name of the bash tool's kind (`b` and eight letters or digits). One read back whole whose text is\n * still longer than Claude gets inline (`inlineMax` characters, which only BASH_MAX_OUTPUT_LENGTH\n * above 30,000 leaves room for): that text, under a call's id, as Claude Code saves a long tool\n * result. Written once, never over a file already there, readable only by you; when it cannot be,\n * Claude gets the text inline, as from Claude Code when its copy fails.\n */\nexport async function forClaude(sessionId: string, result: ShellResult, limits: OutputLimits = STANDARD_LIMITS): Promise<ForClaude> {\n const out: ForClaude = { ...result, ...limits };\n if (!succeeded(result)) return out;\n const whole = result.output.bytes <= limits.readMax;\n const text = whole ? trimmed(result.output.text(limits.readMax)) : '';\n if (whole && text.length <= limits.inlineMax) return out;\n const dir = await toolResultsFolder(sessionId);\n if (!dir) return out;\n try {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n if (whole) {\n const file = path.join(dir, `${randomUUID()}.txt`);\n await writeFile(file, text, { flag: 'wx', mode: 0o600 });\n return { ...out, savedTo: file, savedSize: text.length };\n }\n const file = path.join(dir, `b${[...randomBytes(8)].map((byte) => NAME_LETTERS[byte % NAME_LETTERS.length]).join('')}.txt`);\n await result.output.saveTo(file);\n return { ...out, savedTo: file };\n } catch {\n return out;\n }\n}\n\n/**\n * How Claude Code's bash mode treats a command in this folder, from the settings Claude Code runs\n * with there (the user's own only, where the folder's are not used): whether Claude answers it,\n * unless `respondToBashCommands` is false, and its limits for the output (OUTPUT_LIMITS), from\n * `bashOutputMaxChars`, else BASH_MAX_OUTPUT_LENGTH as Claude Code gets it: from the settings'\n * `env`, which it sets over the one it started with, else from Pelican's, which it inherits.\n * Reading settings runs nothing.\n */\nexport async function bashModeSettings(cwd: string): Promise<{ respond: boolean } & OutputLimits> {\n try {\n const { settingSources } = await launchFor(cwd);\n const dir = await realpath(cwd).catch(() => cwd);\n const { effective } = await resolveSettings({ cwd: dir, settingSources });\n const set = settingLimit(effective.bashOutputMaxChars);\n const env: unknown = (effective.env as Record<string, unknown> | undefined)?.BASH_MAX_OUTPUT_LENGTH;\n const variable = typeof env === 'string' ? env : typeof env === 'number' ? String(env) : process.env.BASH_MAX_OUTPUT_LENGTH;\n return { respond: effective.respondToBashCommands !== false, readMax: set ?? variableLimit(variable), inlineMax: set ?? OUTPUT_LIMITS.standard };\n } catch {\n // Settings that cannot be read, or an SDK without the call: Claude Code's defaults.\n return { respond: true, ...STANDARD_LIMITS };\n }\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 TaskOutput,\n TaskProgress,\n Workflow,\n WorkflowAgent,\n WorkflowPhase,\n WorkflowStatus,\n} from '../shared/protocol.js';\nimport { addPhase, agentTokens, parseMeta, RUN_ID } from '../shared/workflows.js';\nimport { fork, remove } from './actions.js';\nimport { describeAlways, sessionModeOf } from './approvals.js';\nimport { sdkPackage } from './claude-code.js';\nimport { config } from './config.js';\nimport { demoRunState, demoRunStatus, demoRunTasks } 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 { answerable, notify, oneLine } from './push.js';\nimport { sessionInfo, sessionTitle } from './sessions.js';\nimport { bashModeMessages, type ForClaude } from './shell.js';\nimport { isSideChat, SIDE_CHAT_COMMAND, SIDE_CHAT_TITLE, sideChatOptions, sideChatPrompt, sideChatSettings } from './side-chat.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\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 // The command itself, never Claude's words about it; of several lines, the first and \"\u2026\".\n const lines = str(input.command).split(/\\r?\\n/).filter((line) => line.trim());\n return lines.length > 1 ? `${lines[0]} \u2026` : lines[0] || 'Run a command';\n }\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/**\n * A workflow Claude runs in this process, as its task events tell it: started, its progress (the\n * whole list of its phases and agents, on the frames that carry one), its status, its end.\n */\ntype LiveFlow = {\n taskId: string;\n toolUseId?: string;\n runId?: string;\n name?: string;\n description?: string;\n status: WorkflowStatus;\n startedAt: number;\n endedAt?: number;\n /** When it was paused, which stops it as a stop does. */\n pausedAt?: number;\n /** The script's own phases, with their details. */\n phases: WorkflowPhase[];\n /** Progress items by `type:index`, as Claude Code merges them: a newer one replaces the old whole. */\n items: Map<string, Record<string, unknown>>;\n /** Claude Code's totals, from its notification at the end. */\n totals?: { tokens: number; toolUses: number; durationMs: number };\n error?: string;\n /** The page's copy, made again only when something changed. */\n shown?: Workflow;\n};\n\n/** An ended workflow stays in the run state this long: its card then reads Claude Code's record of it. */\nconst FLOW_KEEP_MS = 2 * 60_000;\n\nconst num = (value: unknown) => (typeof value === 'number' && Number.isFinite(value) ? value : undefined);\nconst clipped = (value: unknown, max: number) => (typeof value === 'string' && value ? (value.length > max ? `${value.slice(0, max - 1)}\u2026` : value) : undefined);\n\n/** A `workflow_agent` item as pages get it: Claude Code's fields, its long texts cut. */\nfunction liveAgent(item: Record<string, unknown>): WorkflowAgent | undefined {\n const index = num(item.index);\n const state = item.state;\n if (index === undefined || (state !== 'start' && state !== 'progress' && state !== 'done' && state !== 'error')) return undefined;\n const text = (key: string, max = 200) => clipped(item[key], max);\n const out: WorkflowAgent = { index, label: text('label', 200) ?? `Agent ${index}`, state };\n for (const key of ['phaseIndex', 'tokens', 'toolCalls', 'durationMs', 'queuedAt', 'startedAt', 'lastProgressAt', 'attempt'] as const) {\n const value = num(item[key]);\n if (value !== undefined) out[key] = value;\n }\n for (const key of ['phaseTitle', 'agentId', 'agentType', 'model', 'fallbackModel', 'lastToolName'] as const) {\n const value = text(key, 120);\n if (value) out[key] = value;\n }\n // Its prompt and what it returned are not sent with every frame: nothing shows them but the\n // agent opened, which reads them from its transcript and the run's journal. One with no\n // transcript yet (queued, or ended before it started) has only Claude Code's preview of its\n // prompt (400 characters at most) to show.\n const error = text('error', 600);\n const tool = text('lastToolSummary', 160);\n const prompt = out.agentId ? undefined : text('promptPreview', 401);\n if (error) out.error = error;\n if (tool) out.lastToolSummary = tool;\n if (prompt) out.promptPreview = prompt;\n if (item.isolation === 'worktree' || item.isolation === 'remote') out.isolation = item.isolation;\n if (item.lastAttemptReason === 'stalled' || item.lastAttemptReason === 'throttled' || item.lastAttemptReason === 'user-retry') out.lastAttemptReason = item.lastAttemptReason;\n for (const key of ['skipped', 'blocked', 'cached'] as const) if (item[key] === true) out[key] = true;\n return out;\n}\n\n/** A workflow as pages show it: the script's phases and those the run opened, and its agents. */\nfunction liveWorkflow(flow: LiveFlow): Workflow {\n if (flow.shown) return flow.shown;\n const phases = [...flow.phases];\n const agents: WorkflowAgent[] = [];\n for (const item of flow.items.values()) {\n if (item.type === 'workflow_phase') {\n const title = clipped(item.title, 120);\n if (title) addPhase(phases, title);\n } else if (item.type === 'workflow_agent') {\n const agent = liveAgent(item);\n if (agent) agents.push(agent);\n }\n }\n const tokens = flow.totals?.tokens ?? agentTokens(agents);\n const toolUses = flow.totals?.toolUses ?? agents.reduce((sum, a) => sum + (a.toolCalls ?? 0), 0);\n flow.shown = {\n ...(flow.runId ? { runId: flow.runId } : {}),\n taskId: flow.taskId,\n ...(flow.name ? { name: flow.name } : {}),\n ...(flow.description ? { description: flow.description } : {}),\n status: flow.status,\n startedAt: flow.startedAt,\n ...(flow.totals ? { durationMs: flow.totals.durationMs }\n : flow.endedAt ? { durationMs: flow.endedAt - flow.startedAt }\n : flow.status === 'paused' && flow.pausedAt ? { durationMs: flow.pausedAt - flow.startedAt } : {}),\n ...(tokens > 0 ? { totalTokens: tokens } : {}),\n ...(toolUses > 0 ? { totalToolCalls: toolUses } : {}),\n phases,\n agents,\n ...(flow.error ? { error: clipped(flow.error, 2000)! } : {}),\n source: 'live',\n };\n return flow.shown;\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 /** Workflows running in this process, by task id. */\n private flows = new Map<string, LiveFlow>();\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 /** A side chat (side-chat.ts): it reads, changes nothing, and runs in its own mode whatever is picked. */\n readonly sideChat = false,\n ) {\n if (!resume) this.costSoFar = 0;\n if (sideChat) this.settings = sideChatSettings(settings);\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 // Last, so nothing above can give a side chat a tool, a server or a mode of the session's.\n ...(this.sideChat ? sideChatOptions() : {}),\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 // A workflow, by its name, as Claude Code's task panel lists it, with how far its agents got.\n const flow = this.flows.get(task.id);\n if (flow) {\n const { agents } = liveWorkflow(flow);\n const done = agents.filter((a) => a.state === 'done').length;\n return { ...task, description: flow.name ?? task.description, ...(agents.length > 0 ? { summary: `${done}/${agents.length} agents` } : {}) };\n }\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 ...(this.flows.size > 0 ? { workflows: this.workflowStates() } : {}),\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 /** The workflows Claude runs here, by the Workflow call that started each. */\n private workflowStates(): Record<string, Workflow> {\n return Object.fromEntries([...this.flows.values()].flatMap((flow) => (flow.toolUseId ? [[flow.toolUseId, liveWorkflow(flow)]] : [])));\n }\n\n /** What this process knows of a workflow it runs, by its Workflow call. */\n workflow(toolUseId: string): Workflow | undefined {\n for (const flow of this.flows.values()) if (flow.toolUseId === toolUseId) return liveWorkflow(flow);\n return undefined;\n }\n\n /** A workflow agent asking for something, by the label its script gave it, cut as its card cuts it. */\n private workflowAgent(agentId: string): string | undefined {\n for (const flow of this.flows.values()) {\n for (const item of flow.items.values()) {\n if (item.type === 'workflow_agent' && item.agentId === agentId) return clipped(item.label, 200);\n }\n }\n return undefined;\n }\n\n /** A workflow's task event: it started, made progress, changed status or ended. */\n private noteFlow(message: Record<string, unknown>): boolean {\n const taskId = str(message.task_id);\n const subtype = message.subtype;\n let flow = this.flows.get(taskId);\n if (subtype === 'task_started') {\n if (message.task_type !== 'local_workflow') return false;\n const meta = typeof message.prompt === 'string' ? parseMeta(message.prompt) : undefined;\n flow = {\n taskId,\n ...(str(message.tool_use_id) ? { toolUseId: str(message.tool_use_id) } : {}),\n ...(str(message.workflow_name) || meta?.name ? { name: str(message.workflow_name) || meta!.name! } : {}),\n ...(str(message.description) ? { description: str(message.description) } : {}),\n status: 'running',\n startedAt: Date.now(),\n phases: meta?.phases ?? [],\n items: new Map(),\n };\n this.flows.set(taskId, flow);\n this.emit();\n return true;\n }\n const items = (message as { workflow_progress?: unknown }).workflow_progress;\n // A frame of a workflow this process saw start before Pelican listened, or a late start.\n if (!flow && subtype === 'task_progress' && Array.isArray(items) && taskId) {\n flow = { taskId, ...(str(message.tool_use_id) ? { toolUseId: str(message.tool_use_id) } : {}), status: 'running', startedAt: Date.now(), phases: [], items: new Map() };\n this.flows.set(taskId, flow);\n }\n if (!flow) return false;\n flow.shown = undefined;\n if (subtype === 'task_progress') {\n flow.toolUseId ??= str(message.tool_use_id) || undefined;\n // Only some frames carry the list, and each carries it whole; the others only tick usage.\n if (!Array.isArray(items)) return true;\n for (const item of items) {\n if (!item || typeof item !== 'object') continue;\n const { type, index } = item as { type?: unknown; index?: unknown };\n if ((type === 'workflow_agent' || type === 'workflow_phase') && typeof index === 'number') flow.items.set(`${type}:${index}`, item as Record<string, unknown>);\n }\n this.emit(true);\n return true;\n }\n if (subtype === 'task_updated') {\n const patch = (message.patch ?? {}) as { status?: unknown; error?: unknown; end_time?: unknown };\n const status = patch.status;\n if (status === 'running' || status === 'pending') flow.status = 'running';\n else if (status === 'paused' || status === 'completed' || status === 'failed' || status === 'killed') flow.status = status;\n if (typeof patch.error === 'string' && patch.error) flow.error = patch.error;\n if (typeof patch.end_time === 'number') flow.endedAt = patch.end_time;\n // A pause stops the run, as a stop does: its time stops there.\n if (status === 'paused') flow.pausedAt ??= Date.now();\n else if (status === 'running') flow.pausedAt = undefined;\n this.emit();\n return true;\n }\n if (subtype === 'task_notification') {\n const status = message.status;\n flow.status = status === 'completed' ? 'completed' : status === 'failed' ? 'failed' : 'killed';\n flow.endedAt ??= Date.now();\n const usage = message.usage as { total_tokens?: unknown; tool_uses?: unknown; duration_ms?: unknown } | undefined;\n if (usage && num(usage.total_tokens) !== undefined) {\n flow.totals = { tokens: num(usage.total_tokens)!, toolUses: num(usage.tool_uses) ?? 0, durationMs: num(usage.duration_ms) ?? flow.endedAt - flow.startedAt };\n }\n // A while after, the card reads Claude Code's own record of the run.\n const ended = flow;\n setTimeout(() => {\n if (this.flows.get(taskId) !== ended) return;\n this.flows.delete(taskId);\n this.emit();\n }, FLOW_KEEP_MS).unref();\n this.emit();\n return true;\n }\n return false;\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 if (this.sideChat && SIDE_CHAT_COMMAND.test(input.text.trim())) throw new Error('A side chat takes questions, not / commands.');\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(this.sideChat ? sideChatPrompt(prompt.text) : 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 the way Claude Code's bash mode does:\n * the command, then what it printed, as typed text that is no prompt to expand. With `respond`\n * Claude answers it, as the CLI's Claude does; without, Claude keeps it for later and the caveat\n * before it says so. `uuid`: the id of the message holding the command.\n */\n async appendShell(result: ForClaude, respond: boolean, uuid: string = randomUUID()): Promise<void> {\n if (this.closed) throw new RunClosed();\n const parts = bashModeMessages(result, respond);\n const messages = parts.map(({ text, meta }, i): SDKUserMessage => ({\n type: 'user',\n uuid: (i === parts.length - 2 ? uuid : randomUUID()) as UUID,\n session_id: this.sessionId,\n parent_tool_use_id: null,\n origin: { kind: 'human' },\n // Typed as it stands: an @ or a / in the output is no file to attach or command to run.\n client_composed: true,\n ...(meta ? { isSynthetic: true } : {}),\n shouldQuery: respond && i === parts.length - 1,\n message: { role: 'user', content: text },\n }));\n // Rows of the shape Claude Code's bash mode writes from 2.1.80 on (Pelican builds them so), which\n // the page reads by that version, as it reads the transcript's.\n const version = sdkPackage().claudeCodeVersion ?? '2.1.80';\n for (const message of messages) {\n const chat = toChatMessage({ type: 'user', uuid: message.uuid, version, ...(message.isSynthetic ? { isMeta: true } : {}), message: message.message });\n if (chat) await feedFor(this.sessionId).publish({ ...chat, timestamp: Date.now() });\n }\n if (this.closed) throw new RunClosed();\n if (respond) {\n // A turn starts with the output, as with a prompt: the page shows Claude at work at once.\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 }\n for (const message of messages) 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(asked: RunSettings, pick = false): Promise<void> {\n const q = this.q;\n if (!q) return;\n // A side chat keeps its own mode, whatever its session's is.\n const next = this.sideChat ? sideChatSettings(asked) : asked;\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 if (this.sideChat) return;\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 // A notification that can answer says, as its whole body, all that Allow approves.\n void notify({ title: this.title || 'Claude Code', body: oneLine(askedFor(pending.request, this.cwd)), sessionId: this.sessionId, tag: `${this.sessionId}:ask`, ...answerable(pending.request) });\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) ?? this.workflowAgent(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 // A workflow's run id is only in its call's result: the folder its agents write to.\n const launched = (raw.tool_use_result ?? {}) as { taskId?: unknown; runId?: unknown };\n const flow = typeof launched.taskId === 'string' ? this.flows.get(launched.taskId) : undefined;\n if (flow && typeof launched.runId === 'string' && RUN_ID.test(launched.runId)) {\n flow.runId = launched.runId;\n // The call it answers, should its start not have said.\n const answered = (content as Array<Record<string, unknown>>).find((b) => b?.type === 'tool_result' && typeof b.tool_use_id === 'string');\n flow.toolUseId ??= answered?.tool_use_id as string | undefined;\n flow.shown = undefined;\n this.emit(true);\n }\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' || message.subtype === 'task_progress' || message.subtype === 'task_updated' || message.subtype === 'task_notification')\n && this.noteFlow(raw)) {\n // A workflow's: its card shows it, from what noteFlow kept.\n if (message.subtype === 'task_notification') this.taskTools.delete(message.task_id);\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 // A side chat is answered while it is looked at; its session's own turns are what to hear about.\n if (!stopped && !goesOn && !this.sideChat) {\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.agentNames.clear();\n this.flows.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 demoRunStatus(sessionId);\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 demoRunTasks(sessionId);\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; sideChat?: boolean }, 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 // A side chat goes on as one, whichever app made it and wherever it is continued from.\n const side = target.sideChat === true || (await isSideChat(target.sessionId));\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, side);\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 side = await isSideChat(sessionId);\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, side);\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 side = await isSideChat(sessionId);\n const started = getRun(sessionId);\n if (started) return started;\n const run = new SessionRun(sessionId, cwd, settings, true, undefined, launch, side);\n runs.set(sessionId, run);\n run.start();\n return run;\n}\n\n/**\n * Asks a side question about a session, as Claude Desktop's side chats do: the session so far is\n * copied (the Agent SDK's forkSession) under Desktop's title for one, and the copy's own Claude,\n * which only reads, answers there. The session itself, running or not, is not touched. A copy the\n * question could not be sent to is removed again, so nothing is left behind; one whose Claude\n * fails later stays, with the question, to be asked again.\n */\nexport async function startSideChat(sessionId: string, input: Omit<SendInput, 'attachments' | 'mode'>): Promise<string> {\n if (config.demo) throw new Error('This is the demo: nothing runs.');\n if (!input.text.trim()) throw new Error('Ask a question');\n if (SIDE_CHAT_COMMAND.test(input.text.trim())) throw new Error('A side chat takes questions, not / commands.');\n const side = await fork(sessionId, undefined, SIDE_CHAT_TITLE);\n try {\n await sendMessage({ sessionId: side, sideChat: true }, { ...input, attachments: [] });\n } catch (error) {\n getRun(side)?.close();\n await remove(side).catch(() => undefined);\n throw error;\n }\n return side;\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 { randomUUID } from 'node:crypto';\n\nimport type { LiveShell, ServerEvent } from '../shared/protocol.js';\nimport { feedFor } from './feed.js';\nimport { ensureRun, getRun } from './runner.js';\nimport { bashModeSettings, type CommandRun, forClaude, MAX_OUTPUT, type ShellResult, startCommand } from './shell.js';\n\n/**\n * The `!` commands running in each session, shown to its pages as their output comes, and added to\n * the conversation once done, as Claude Code's bash mode adds them: inline up to its limit, past it\n * saved to a file Claude gets the start of. Then Claude answers, as in the CLI, unless the user's\n * settings say not to (`respondToBashCommands: false`), or the command did not finish on its own\n * (Stop, the time limit).\n */\n\n/** Output goes to the pages at most this often. */\nconst FLUSH_MS = 100;\n/** While Claude is in a turn, a finished command waits for it to end; this is how often it looks. */\nconst WAIT_MS = 500;\n/** A command whose record could not be written stays on show this long, saying why. */\nconst FAILED_SHOWN_MS = 2 * 60_000;\n\n/** `pending`: output not sent to the pages yet; `cut`: some went past what they keep. */\ntype Entry = { shell: LiveShell; run: CommandRun; pending: string; cut?: boolean; flush?: NodeJS.Timeout };\n\nconst bySession = new Map<string, Map<string, Entry>>();\n\n/** The session's commands still on show, oldest first, as they are now. */\nexport function liveShells(sessionId: string): LiveShell[] {\n return [...(bySession.get(sessionId)?.values() ?? [])].map((entry) => ({ ...entry.shell }));\n}\n\n/** What a page subscribing to the session is told of its commands: all of them, as they are now. */\nexport const shellsEvent = (sessionId: string): ServerEvent => ({ type: 'shells', sessionId, shells: liveShells(sessionId) });\n\nconst tell = (sessionId: string) => feedFor(sessionId).broadcast(shellsEvent(sessionId));\n\n/** What came since the last look goes out in one piece; once some was left out, the pages are told. */\nfunction flush(sessionId: string, entry: Entry): void {\n clearTimeout(entry.flush);\n entry.flush = undefined;\n if (entry.pending) {\n const from = entry.shell.output.length;\n entry.shell.output += entry.pending;\n feedFor(sessionId).broadcast({ type: 'shell_output', sessionId, id: entry.shell.id, from, text: entry.pending });\n entry.pending = '';\n }\n if (entry.cut && !entry.shell.truncated) {\n entry.shell.truncated = true;\n tell(sessionId);\n }\n}\n\n/**\n * Output as it comes, held until the next look only up to what the page keeps: past that it is\n * let go as it comes, since a command can print gigabytes (`!yes`) and keep at it for its half hour.\n */\nfunction take(sessionId: string, entry: Entry, text: string): void {\n const room = MAX_OUTPUT - entry.shell.output.length - entry.pending.length;\n if (text.length > room) entry.cut = true;\n if (room > 0) entry.pending += text.length > room ? text.slice(0, room) : text;\n else if (entry.shell.truncated) return;\n entry.flush ??= setTimeout(() => flush(sessionId, entry), FLUSH_MS);\n}\n\nfunction forget(sessionId: string, id: string): void {\n const entries = bySession.get(sessionId);\n entries?.delete(id);\n if (entries?.size === 0) bySession.delete(sessionId);\n tell(sessionId);\n}\n\n/** Claude's turn there is over, or there is none: its record can go in, and Claude may answer it. */\nasync function turnOver(sessionId: string): Promise<void> {\n while (getRun(sessionId)?.busy) await new Promise((resolve) => setTimeout(resolve, WAIT_MS));\n}\n\n/**\n * Adds a finished command to the conversation. While Claude is in a turn it waits for the turn to\n * end, as a `!` command queued in the CLI does, so the conversation holds it where Claude Code\n * writes it, and Claude answers it then.\n */\nasync function record(sessionId: string, cwd: string, id: string, result: ShellResult): Promise<void> {\n try {\n await turnOver(sessionId);\n // Pelican is closing its Claude processes: none is started again for this.\n if (shuttingDown) return;\n const settings = await bashModeSettings(cwd);\n const respond = result.endedBy === undefined && settings.respond;\n const toClaude = await forClaude(sessionId, result, settings);\n const run = await ensureRun(sessionId);\n // It may have started a turn while the settings were read: then the record waits no more, and Claude reads it later.\n await run.appendShell(toClaude, respond && !run.busy, id);\n } finally {\n // What was kept of its output past the start (a file with no name) goes once it is recorded.\n result.output.release();\n }\n}\n\n/**\n * Starts a `!` command in the session's folder, with the environment Claude Code gets there\n * (`env`, from launchFor). Its pages see it at once and its output as it comes; once done it goes\n * into the conversation under the command's id.\n */\nexport function startShell(sessionId: string, cwd: string, command: string, env?: Record<string, string>): LiveShell {\n const id = randomUUID();\n const shell: LiveShell = { id, command, startedAt: Date.now(), output: '' };\n let entry: Entry | undefined;\n const run = startCommand(cwd, command, {\n ...(env ? { env } : {}),\n onOutput: (text) => {\n if (entry) take(sessionId, entry, text);\n },\n });\n entry = { shell, run, pending: '' };\n let entries = bySession.get(sessionId);\n if (!entries) {\n entries = new Map();\n bySession.set(sessionId, entries);\n }\n entries.set(id, entry);\n tell(sessionId);\n const started = entry;\n void run.result.then(async (result) => {\n flush(sessionId, started);\n started.shell.done = { code: result.code, ...(getRun(sessionId)?.busy ? { waiting: true } : {}) };\n tell(sessionId);\n try {\n await record(sessionId, cwd, id, result);\n forget(sessionId, id);\n } catch (error) {\n started.shell.error = `Could not add it to the conversation: ${(error as Error).message}`;\n tell(sessionId);\n setTimeout(() => forget(sessionId, id), FAILED_SHOWN_MS).unref();\n }\n });\n return shell;\n}\n\n/** Stop: ends the command and everything it started. False when it is not running (any more). */\nexport function stopShell(sessionId: string, id: string): boolean {\n const entry = bySession.get(sessionId)?.get(id);\n if (!entry || entry.shell.done) return false;\n entry.run.stop();\n entry.shell.stopping = true;\n tell(sessionId);\n return true;\n}\n\nlet shuttingDown = false;\n/** Pelican was told twice to stop (a second Ctrl+C): what still runs ends now. */\nlet hurried = false;\n\n/**\n * How long the `!` commands still running get to tidy up when Pelican shuts down, before they are\n * made to end: 15 seconds. docker compose gives its containers 10 to stop (Claude Code's own bash\n * mode gives a command 1.5). Under systemd that is well inside the 90 seconds it waits for a\n * service (TimeoutStopSec), and past them it ends every process of the service itself. launchd\n * waits only as long as the job says (ExitTimeOut: 20 for Pelican's login item, 5 where unset),\n * then ends Pelican alone, and once Pelican has gone nothing would end them: see shutdownGrace.\n */\nexport const SHUTDOWN_GRACE_MS = 15_000;\n\n/**\n * The time to tidy up, inside what launchd allows when it stops Pelican (`exitTimeoutS`, see\n * launchdExitTimeout): a second and a half before its end, for Pelican to end what is left and exit.\n */\nexport const shutdownGrace = (exitTimeoutS?: number) => (exitTimeoutS === undefined\n ? SHUTDOWN_GRACE_MS\n : Math.max(1000, Math.min(SHUTDOWN_GRACE_MS, exitTimeoutS * 1000 - 1500)));\n/** How often it looks whether they have. */\nconst SHUTDOWN_LOOK_MS = 50;\n\nconst running = () => [...bySession.values()].flatMap((entries) => [...entries.values()]).filter((entry) => !entry.shell.done);\n\n/** How many `!` commands are running now, in every session. */\nexport const runningShells = () => running().length;\n\n/** Ends at once what stopAllShells still gives time to: Pelican was told to stop again. */\nexport function hurryShells(): void {\n hurried = true;\n}\n\n/**\n * Pelican is shutting down: what still runs ends with it, as a `!` command ends with the CLI. Each\n * is asked to end (SIGTERM: a dev server or docker compose tidies up), unless it has been already\n * (`asked`: systemd stopping the service asks every process of it at once, and a second request\n * makes docker compose stop its containers in a hurry), and given time; then what is left of any\n * of them is made to (SIGKILL), while Pelican is still there to do it. Settles once nothing of\n * them runs.\n */\nexport async function stopAllShells(graceMs = SHUTDOWN_GRACE_MS, { asked = false } = {}): Promise<void> {\n shuttingDown = true;\n hurried = false;\n const entries = running();\n for (const entry of entries) entry.run.ask(!asked);\n const until = Date.now() + graceMs;\n const left = () => entries.some((entry) => entry.run.alive());\n while (!hurried && left() && Date.now() < until) await new Promise((resolve) => setTimeout(resolve, SHUTDOWN_LOOK_MS));\n for (const entry of entries) entry.run.kill();\n // Made to end, they are gone in a moment; that moment is waited for.\n const gone = Date.now() + 1000;\n while (left() && Date.now() < gone) await new Promise((resolve) => setTimeout(resolve, SHUTDOWN_LOOK_MS));\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/**\n * The repository's default branch, as Claude Code's /diff compares against it (\"since your branch\n * split from the default branch\"): the one the remote's HEAD names, else a local main or master.\n * `ref` is what git compares with; `name` what people call it.\n */\nasync function defaultBranch(cwd: string): Promise<{ name: string; ref: string } | undefined> {\n const remote = await git(cwd, ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'], 5000).then((out) => out.trim(), () => '');\n if (/^origin\\/[\\w./-]+$/.test(remote) && !remote.includes('..')) return { name: remote.slice('origin/'.length), ref: `refs/remotes/${remote}` };\n for (const name of ['main', 'master']) {\n if (await git(cwd, ['rev-parse', '--verify', '--quiet', `refs/heads/${name}`], 5000).then(() => true, () => false)) return { name, ref: `refs/heads/${name}` };\n }\n return undefined;\n}\n\n/** Where the branch split from the default branch, when it is another branch: a commit's full id. */\nasync function splitPoint(cwd: string, branch: string | undefined): Promise<string | undefined> {\n const base = await defaultBranch(cwd);\n if (!base || !branch || branch === base.name) return undefined;\n const sha = await git(cwd, ['merge-base', 'HEAD', base.ref], 5000).then((out) => out.trim(), () => '');\n return /^[0-9a-f]{40,64}$/.test(sha) ? sha : undefined;\n}\n\n/**\n * The files changed since a commit, by git's own letters (`git diff --name-status`), renames found\n * as git finds them: committed since then and not, as `git diff <commit>` compares the work tree.\n */\nasync function changedSince(cwd: string, commit: string): Promise<GitFile[]> {\n const raw = await git(cwd, ['diff', '--name-status', '-M', '-z', '--relative', commit]);\n const fields = raw.split('\\0');\n const files: GitFile[] = [];\n for (let i = 0; i < fields.length; i += 1) {\n const code = fields[i]!;\n if (!code) continue;\n const kind = code[0]!;\n if (kind === 'R' || kind === 'C') {\n const from = fields[i + 1];\n const to = fields[i + 2];\n i += 2;\n if (to) files.push({ path: to, status: kind === 'R' ? 'renamed' : 'added', ...(kind === 'R' && from ? { from } : {}) });\n } else {\n const file = fields[(i += 1)];\n if (file) files.push({ path: file, status: KIND[kind] ?? 'modified' });\n }\n }\n return files;\n}\n\n/**\n * What changed in the session's folder, with line counts: since the last commit (`uncommitted`,\n * the default), or since the branch split from the default branch (`base`), its commits and what\n * is not committed yet, new files included. Also the branch, its upstream, and the default branch.\n */\nexport async function gitStatus(cwd: string, scope: 'uncommitted' | 'base' = 'uncommitted'): 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: Extract<GitStatus, { repo: true }> = { 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.upstream ')) {\n out.upstream = entry.slice(18);\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 const base = await defaultBranch(cwd).catch(() => undefined);\n if (base) out.base = base.name;\n // Somewhere to push to: a remote with an address, read from the config, which contacts nothing.\n // Not `git remote`, which also names one that has only a fetch line (a system or managed git\n // config may set `remote.origin.fetch`), and so names origin in every repository.\n if (await git(cwd, ['config', '--get-regexp', '^remote\\\\..+\\\\.(push)?url$'], 5000).then((found) => found.trim() !== '', () => false)) out.remote = true;\n // Since the branch split: what git diff says changed since then, and the new files status found.\n let since: string | undefined;\n if (scope === 'base') {\n since = await splitPoint(cwd, out.branch);\n if (!since) return { ...out, files: [] };\n const untracked = out.files.filter((f) => f.status === 'untracked');\n try {\n out.files = [...await changedSince(cwd, since), ...untracked];\n } catch {\n out.files = untracked;\n }\n }\n // Line counts against the last commit (or the empty tree before the first one), or the split.\n try {\n const against = since ?? await git(cwd, ['rev-parse', '--verify', '-q', 'HEAD']).then(() => 'HEAD', () => '4b825dc642cb6eb9a060e54bf8d69288fbee4904');\n const numstat = await git(cwd, ['diff', '--numstat', '-M', '--relative', '-z', against]);\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 await countUntracked(cwd, out.files);\n return out;\n}\n\n/**\n * Untracked files counted, at most, for their lines: the first ones, small ones, and only so much\n * in all. Each status read used to read up to 200 of them whole (100 MB), every few seconds.\n */\nexport const UNTRACKED_COUNTED = { files: 100, bytesEach: 256 * 1024, bytesInAll: 4 * 1024 * 1024 };\n\n/**\n * A new file is all added lines; git does not count those for files it does not track yet. Files\n * past the limits, binary ones and special ones get no count (the list shows none).\n */\nasync function countUntracked(cwd: string, files: GitFile[]): Promise<void> {\n let budget = UNTRACKED_COUNTED.bytesInAll;\n for (const file of files.filter((f) => f.status === 'untracked').slice(0, UNTRACKED_COUNTED.files)) {\n if (budget <= 0) return;\n try {\n const handle = await openRegular(await insideReal(cwd, file.path));\n try {\n const { size } = await handle.stat();\n if (size > UNTRACKED_COUNTED.bytesEach || size > budget) continue;\n budget -= size;\n const data = Buffer.alloc(size);\n await handle.read(data, 0, size, 0);\n if (data.subarray(0, 8000).includes(0)) continue;\n let lines = 0;\n for (let at = data.indexOf(0x0a); at !== -1; at = data.indexOf(0x0a, at + 1)) lines += 1;\n file.added = lines + (size > 0 && data[size - 1] !== 0x0a ? 1 : 0);\n } finally {\n await handle.close();\n }\n } catch {\n // Unreadable, or a link that leads out of the folder: no count.\n }\n }\n}\n\n/**\n * A path a diff is asked for: inside the session's folder, as is the folder it is in. The file\n * itself may be gone (a deleted file, a renamed one's old path, has a diff), but its folder may\n * not lead out through a link.\n */\nasync function diffPath(cwd: string, file: string): Promise<void> {\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}\n\n/**\n * The diff of one file against the last commit, or (`base`) against where the branch split from\n * the default branch; an untracked file shows as all added. A renamed file is diffed with its old\n * path (`from`), as git pairs them, so it shows what changed in it rather than a whole new file.\n */\nexport async function gitDiff(cwd: string, file: string, scope: 'uncommitted' | 'base' = 'uncommitted', from?: string): Promise<string> {\n if (!(await repositoryOf(cwd))) return '';\n await diffPath(cwd, file);\n if (from) await diffPath(cwd, from);\n let diff = '';\n try {\n const branch = scope === 'base' ? (await git(cwd, ['symbolic-ref', '--quiet', '--short', 'HEAD'], 5000)).trim() : undefined;\n const against = scope === 'base' ? await splitPoint(cwd, branch) : 'HEAD';\n if (against) diff = await git(cwd, ['diff', '-M', against, '--', ...(from && from !== file ? [from] : []), file]);\n } catch {\n diff = '';\n }\n // Untracked (or no commits yet): all added. A tracked file with nothing to show has no diff.\n const committed = !diff && await git(cwd, ['rev-parse', '--verify', '-q', 'HEAD'], 5000).then(() => true, () => false);\n const tracked = committed && await git(cwd, ['ls-files', '-z', '--', file], 5000).then((out) => out.length > 0, () => false);\n if (!diff && !tracked) {\n // git diff --no-index exits with 1 when the files differ. `./`: a file named `-` would\n // 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\n/** At most this many paths are looked up at once (links in a reply), each this long at most. */\nexport const EXISTS_MAX = 50;\n\n/**\n * Which of `paths` are files in the session's folder: relative, with no `..`, a real path inside\n * the folder's, and a regular file (not a folder, a pipe or a device). For the links in a reply:\n * a path that is not there gets none. Nothing is read, nothing runs.\n */\nexport async function existingFiles(cwd: string, paths: readonly string[]): Promise<string[]> {\n const root = await realpath(cwd);\n const found = await Promise.all(paths.slice(0, EXISTS_MAX).map(async (relative) => {\n if (!relative || relative.length > 1024 || path.isAbsolute(relative)) return undefined;\n try {\n const real = await realpath(inside(cwd, relative));\n if (!within(root, real)) return undefined;\n return (await stat(real)).isFile() ? relative : undefined;\n } catch {\n return undefined;\n }\n }));\n return found.filter((p): p is string => Boolean(p));\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\n/** A file of the folder opened to be read whole (a download): its real path inside the folder, a regular file. */\nexport async function openProjectFile(cwd: string, relative: string): Promise<{ handle: Awaited<ReturnType<typeof openRegular>>; size: number }> {\n const handle = await openRegular(await insideReal(cwd, relative));\n try {\n return { handle, size: (await handle.stat()).size };\n } catch (error) {\n await handle.close();\n throw error;\n }\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 { spawn } from 'node:child_process';\nimport { readdir } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { bundledClaude, claudeBinary } from './claude-code.js';\nimport { openRegular } from './open.js';\nimport { limiter } from './transcripts.js';\nimport { inside } from './workspace.js';\n\n/**\n * Searching the text of a session's folder, for Files. With the ripgrep Claude Code carries\n * inside it, as Claude Code runs it itself for Grep: the Claude Code binary, by its absolute path,\n * started as `rg` with `--no-config` (no RIPGREP_CONFIG_PATH), an empty environment and nothing\n * from PATH. It reads files and runs nothing else: no preprocessor, no git, links not followed,\n * so it works in folders nobody trusted. Where that binary does not answer as ripgrep, a bounded\n * scan of the folder in Node does the same, more slowly.\n *\n * The query is a literal string (not a pattern), matched as smart case does it: case-insensitive\n * unless it has a capital letter.\n */\nexport type SearchResult = {\n engine: 'rg' | 'scan';\n files: Array<{ path: string; lines: Array<{ n: number; text: string }> }>;\n /** A limit was reached: there may be more. */\n truncated: boolean;\n};\n\nexport const SEARCH_LIMITS = { files: 200, lines: 500, perFile: 20, text: 300, ms: 8_000, output: 4 * 1024 * 1024, scanFiles: 20_000, scanBytes: 64 * 1024 * 1024, fileBytes: 1024 * 1024 };\n\n/**\n * Folders neither engine looks in, also where no ignore file says so (ripgrep reads those only in\n * a repository): what package managers fill. Hidden files and folders are skipped as well.\n */\nconst SKIP = ['node_modules', '__pycache__', 'venv'];\n\n/** A line as it is sent: at most 300 characters of it, around what was found when that is further in. */\nconst clipped = (text: string, query: string) => {\n const line = text.replace(/\\r?\\n$/, '');\n if (line.length <= SEARCH_LIMITS.text) return line;\n const caseless = query === query.toLowerCase();\n const at = (caseless ? line.toLowerCase() : line).indexOf(caseless ? query.toLowerCase() : query);\n const from = Math.max(0, Math.min(at - 100, line.length - SEARCH_LIMITS.text));\n return `${from > 0 ? '\u2026' : ''}${line.slice(from, from + SEARCH_LIMITS.text)}${from + SEARCH_LIMITS.text < line.length ? '\u2026' : ''}`;\n};\n\n/** Whether a binary answers as ripgrep when started as `rg`, asked once each. */\nconst answers = new Map<string, Promise<boolean>>();\nfunction answersAsRipgrep(binary: string): Promise<boolean> {\n let known = answers.get(binary);\n if (!known) {\n known = new Promise<boolean>((resolve) => {\n let out = '';\n const child = spawn(binary, ['--version'], { argv0: 'rg', env: {}, stdio: ['ignore', 'pipe', 'ignore'], timeout: 5_000 });\n child.stdout.on('data', (chunk: Buffer) => {\n out += chunk.toString('utf8');\n });\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0 && out.startsWith('ripgrep ')));\n });\n answers.set(binary, known);\n }\n return known;\n}\n\n/** The binary to search with: the Claude Code the SDK brings, else the one Pelican runs, if either is ripgrep inside. */\nasync function ripgrep(): Promise<string | undefined> {\n for (const binary of [...new Set([bundledClaude(), claudeBinary()])]) {\n if (binary && path.isAbsolute(binary) && await answersAsRipgrep(binary)) return binary;\n }\n return undefined;\n}\n\n/** A path as ripgrep prints it (`./src/a.ts`), relative to the folder, or undefined if it is not one. */\nfunction relativePath(printed: string, cwd: string): string | undefined {\n const file = printed.replace(/^\\.\\//, '');\n try {\n inside(cwd, file);\n return file && !path.isAbsolute(file) ? file : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction withRipgrep(binary: string, cwd: string, query: string): Promise<SearchResult> {\n return new Promise((resolve) => {\n const result: SearchResult = { engine: 'rg', files: [], truncated: false };\n const byPath = new Map<string, SearchResult['files'][number]>();\n let lines = 0;\n let bytes = 0;\n let carry = '';\n const args = [\n '--no-config', '--json', '--fixed-strings', '--smart-case', '--no-messages',\n '--max-count', String(SEARCH_LIMITS.perFile), '--max-filesize', '1M',\n ...SKIP.flatMap((name) => ['--glob', `!${name}`]),\n '-e', query, '--', '.',\n ];\n const child = spawn(binary, args, { argv0: 'rg', cwd, env: {}, stdio: ['ignore', 'pipe', 'ignore'] });\n const stop = (truncated: boolean) => {\n result.truncated ||= truncated;\n child.kill('SIGKILL');\n };\n const timer = setTimeout(() => stop(true), SEARCH_LIMITS.ms);\n const take = (line: string) => {\n if (!line.includes('\"type\":\"match\"')) return;\n let event: { type?: string; data?: { path?: { text?: unknown }; lines?: { text?: unknown }; line_number?: unknown } };\n try {\n event = JSON.parse(line) as typeof event;\n } catch {\n return;\n }\n const printed = event.data?.path?.text;\n const text = event.data?.lines?.text;\n const n = event.data?.line_number;\n // A name or a line that is not UTF-8 comes as bytes: left out.\n if (event.type !== 'match' || typeof printed !== 'string' || typeof text !== 'string' || typeof n !== 'number') return;\n const file = relativePath(printed, cwd);\n if (!file) return;\n let entry = byPath.get(file);\n if (!entry) {\n if (byPath.size >= SEARCH_LIMITS.files) return stop(true);\n entry = { path: file, lines: [] };\n byPath.set(file, entry);\n result.files.push(entry);\n }\n entry.lines.push({ n, text: clipped(text, query) });\n lines += 1;\n if (lines >= SEARCH_LIMITS.lines) stop(true);\n };\n child.stdout.on('data', (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > SEARCH_LIMITS.output) return stop(true);\n const text = carry + chunk.toString('utf8');\n const parts = text.split('\\n');\n carry = parts.pop() ?? '';\n for (const part of parts) {\n if (lines >= SEARCH_LIMITS.lines || result.truncated) break;\n take(part);\n }\n });\n const done = () => {\n clearTimeout(timer);\n resolve(result);\n };\n child.on('error', done);\n child.on('close', done);\n });\n}\n\n/** The same search without ripgrep: the folder walked (no hidden files, no links), within the same limits. */\nasync function withScan(cwd: string, query: string): Promise<SearchResult> {\n const result: SearchResult = { engine: 'scan', files: [], truncated: false };\n const deadline = Date.now() + SEARCH_LIMITS.ms;\n const caseless = query === query.toLowerCase();\n const needle = caseless ? query.toLowerCase() : query;\n let lines = 0;\n let seen = 0;\n let read = 0;\n const full = () => lines >= SEARCH_LIMITS.lines || result.files.length >= SEARCH_LIMITS.files;\n const visit = async (dir: string, depth: number): Promise<void> => {\n if (depth > 12 || full() || Date.now() > deadline) return;\n let entries;\n try {\n entries = await readdir(path.join(cwd, dir), { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const entry of entries) {\n if (full() || Date.now() > deadline || seen >= SEARCH_LIMITS.scanFiles || read >= SEARCH_LIMITS.scanBytes) {\n result.truncated = true;\n return;\n }\n if (entry.name.startsWith('.') || SKIP.includes(entry.name)) continue;\n const rel = dir ? `${dir}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n await visit(rel, depth + 1);\n continue;\n }\n if (!entry.isFile()) continue;\n seen += 1;\n const text = await readText(path.join(cwd, rel));\n if (text === undefined) continue;\n read += text.length;\n const found: Array<{ n: number; text: string }> = [];\n const all = text.split('\\n');\n for (let i = 0; i < all.length && found.length < SEARCH_LIMITS.perFile; i += 1) {\n const line = all[i]!;\n if ((caseless ? line.toLowerCase() : line).includes(needle)) found.push({ n: i + 1, text: clipped(line, query) });\n }\n if (found.length === 0) continue;\n const room = SEARCH_LIMITS.lines - lines;\n result.files.push({ path: rel, lines: found.slice(0, room) });\n lines += Math.min(found.length, room);\n }\n };\n await visit('', 0);\n if (full()) result.truncated = true;\n return result;\n}\n\n/** A file's text for the scan: regular files of up to 1 MB that are not binary. */\nasync function readText(file: string): Promise<string | undefined> {\n try {\n const handle = await openRegular(file);\n try {\n const { size } = await handle.stat();\n if (size > SEARCH_LIMITS.fileBytes) return undefined;\n const data = Buffer.alloc(size);\n await handle.read(data, 0, size, 0);\n return data.subarray(0, 8000).includes(0) ? undefined : data.toString('utf8');\n } finally {\n await handle.close();\n }\n } catch {\n return undefined;\n }\n}\n\n/** Two searches at a time at most: a burst of them waits its turn instead of loading the computer. */\nconst searching = limiter(2);\n\n/** The lines of the folder's files that hold `query`, by file. `engine: 'scan'` skips ripgrep (tests). */\nexport async function searchText(cwd: string, query: string, engine?: 'scan'): Promise<SearchResult> {\n return searching(async () => {\n const binary = engine === 'scan' ? undefined : await ripgrep();\n return binary ? withRipgrep(binary, cwd, query) : withScan(cwd, query);\n });\n}\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type Hunk, unifiedDiff } from '../shared/line-diff.js';\nimport type { ChatMessage, SessionChanges, TurnChanges, TurnFile } from '../shared/protocol.js';\nimport { readHistory } from './history.js';\nimport { openRegular } from './open.js';\n\n/**\n * What each turn of a session changed, as Claude Code's /diff shows it in its turn views: from\n * Claude's own file edits as the transcript records them (each Edit, MultiEdit and Write result\n * carries a structured patch, or a new file's text), not from git, so it works in any folder and\n * runs nothing. A change Claude made through a command shows only in git's views, as in the CLI;\n * so does a notebook's, which /diff's turns leave out too.\n *\n * Turns are cut and numbered as /diff cuts and numbers them: each row it counts as a prompt (a\n * typed one, a `/` or `!` command and their output, a background task's note, the summary a\n * compaction left) starts one, numbered by its place among them, and holds the edits that follow\n * it up to the next. So a prompt that changed nothing leaves a gap, and what Claude does in answer\n * to a `!` command is that command's turn. A turn's diff of a file is each of its edits' patches\n * in turn, and its counts their lines added up, as in /diff.\n *\n * The transcript is read the way history.ts reads it: incrementally, parsing only the rows that\n * matter here (edit results, checkpoints and prompts); an edit's patch is read again from its row\n * when a diff is asked for, so what is kept per edit is a few numbers.\n */\n\n/** One file one tool call changed. */\ntype FileEdit = { path: string; added: number; removed: number; line?: number; created?: boolean };\ntype EditRow = { at: number; bytes: number; toolUseId?: string; edits: FileEdit[] };\n\ntype Scan = {\n ino: number;\n offset: number;\n carry: Buffer;\n rows: Map<string, EditRow>;\n /** The prompts Claude Code kept the files for (file-history snapshots), by the prompt's id. */\n checkpoints: Set<string>;\n /** Rows copied from another session (a side chat's, a fork's), which ran there, not here. */\n copied: Set<string>;\n readAt: number;\n};\n\nconst CHUNK = 8 * 1024 * 1024;\nconst KEEP = 8;\nconst KEEP_UNREAD_MS = 10 * 60_000;\nconst scans = new Map<string, Scan>();\nconst locks = new Map<string, Promise<unknown>>();\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\nconst str = (value: unknown) => (typeof value === 'string' ? value : undefined);\n\n/** What one tool result says it did to one file. */\ntype Recorded = { file: string; hunks: Hunk[]; created: boolean };\n\n/**\n * A structured patch's hunks, as /diff reads them: each with its start lines and its lines, the\n * rest left out. The line counts git puts in a hunk's header are worked out where missing.\n */\nfunction hunksOf(value: unknown): Hunk[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((raw): Hunk[] => {\n if (!isRecord(raw) || typeof raw.oldStart !== 'number' || typeof raw.newStart !== 'number' || !Array.isArray(raw.lines)) return [];\n const lines = raw.lines.filter((l): l is string => typeof l === 'string');\n const count = (n: unknown, mark: string) => (typeof n === 'number' && Number.isSafeInteger(n) && n >= 0 ? n : lines.filter((l) => !l.startsWith(mark)).length);\n return [{ oldStart: raw.oldStart, oldLines: count(raw.oldLines, '+'), newStart: raw.newStart, newLines: count(raw.newLines, '-'), lines }];\n });\n}\n\n/**\n * The file edit a tool result records (`toolUseResult` on its row), as Claude Code's /diff reads\n * it: a file's path and a patch (Edit, MultiEdit, Write over a file), or for a new file with no\n * patch, its text, every piece of it between newlines an added line (`a\\n` is two, as /diff counts\n * it). Edits held for review (`staged`), a patch that changed nothing and anything else are no edit.\n */\nexport function recordedEdit(result: unknown): Recorded | undefined {\n if (!isRecord(result) || result.staged === true) return undefined;\n const file = str(result.filePath);\n if (!file) return undefined;\n const created = result.type === 'create';\n const hunks = hunksOf(result.structuredPatch);\n if (hunks.length > 0) return { file, hunks, created };\n if (!created || typeof result.content !== 'string') return undefined;\n const lines = result.content.split('\\n');\n return { file, hunks: [{ oldStart: 0, oldLines: 0, newStart: 1, newLines: lines.length, lines: lines.map((line) => `+${line}`) }], created };\n}\n\nfunction counts(hunks: readonly Hunk[]): { added: number; removed: number } {\n let added = 0;\n let removed = 0;\n for (const hunk of hunks) {\n for (const line of hunk.lines) {\n if (line.startsWith('+')) added += 1;\n else if (line.startsWith('-')) removed += 1;\n }\n }\n return { added, removed };\n}\n\n/** Where the first change of a patch is, in the file as it left it. */\nfunction firstLine(hunks: readonly Hunk[]): number | undefined {\n const hunk = hunks[0];\n if (!hunk) return undefined;\n let line = hunk.newStart;\n for (const text of hunk.lines) {\n if (text.startsWith('+') || text.startsWith('-')) return Math.max(1, line);\n if (text.startsWith(' ')) line += 1;\n }\n return Math.max(1, hunk.newStart);\n}\n\n/** What Claude Code writes into a user row that nobody typed: command output, `!` commands, notes. */\nconst NOT_TYPED = /^\\s*(?:<(?:bash-input|bash-stdout|bash-stderr|local-command-stdout|local-command-stderr|local-command-caveat|task-notification|system-reminder)>|\\[Request interrupted)/;\nconst isPrompt = (text: string) => Boolean(text.trim()) && !NOT_TYPED.test(text);\n\nfunction empty(ino: number): Scan {\n return { ino, offset: 0, carry: Buffer.alloc(0), rows: new Map(), checkpoints: new Set(), copied: new Set(), readAt: Date.now() };\n}\n\n/** The relative path of a file inside `cwd`, or the path as it is. */\nconst relative = (file: string, cwd: string | undefined) => (cwd && file.startsWith(`${cwd}${path.sep}`) ? file.slice(cwd.length + 1) : file);\n\nfunction addRow(scan: Scan, line: string, at: number, bytes: number, cwd: string | undefined, own: string): void {\n if (line.length < 2 || line.charCodeAt(0) !== 123) return;\n const snapshot = line.includes('\"file-history-snapshot\"');\n const result = line.includes('\"toolUseResult\"');\n // A prompt: a user row with no tool result in it (those carry \"tool_use_id\").\n const prompt = !result && line.includes('\"type\":\"user\"') && !line.includes('\"tool_use_id\"');\n if (!snapshot && !result && !prompt) return;\n let row: Record<string, unknown>;\n try {\n row = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return;\n }\n if (row.type === 'file-history-snapshot') {\n const id = str(row.messageId) ?? str(isRecord(row.snapshot) ? row.snapshot.messageId : undefined);\n if (id) scan.checkpoints.add(id);\n return;\n }\n const uuid = str(row.uuid);\n if (!uuid || row.isSidechain === true) return;\n // Copied as Claude Code's forkSession copies (it says from where), or as Claude Desktop's side\n // chats carry their session's rows (under its id).\n if ((row.forkedFrom !== undefined && row.forkedFrom !== null) || (typeof row.sessionId === 'string' && row.sessionId !== own)) scan.copied.add(uuid);\n const edit = result ? recordedEdit(row.toolUseResult) : undefined;\n if (!edit) return;\n const content = isRecord(row.message) && Array.isArray(row.message.content) ? row.message.content : [];\n const toolUseId = content.map((b) => (isRecord(b) ? str(b.tool_use_id) : undefined)).find(Boolean);\n const line1 = firstLine(edit.hunks);\n scan.rows.set(uuid, {\n at,\n bytes,\n ...(toolUseId ? { toolUseId } : {}),\n edits: [{ path: relative(edit.file, cwd), ...counts(edit.hunks), ...(line1 ? { line: line1 } : {}), ...(edit.created ? { created: true } : {}) }],\n });\n}\n\nasync function readNew(file: string, scan: Scan, size: number, cwd: string | undefined): Promise<void> {\n const own = path.basename(file, '.jsonl');\n const handle = await openRegular(file);\n try {\n while (scan.offset < size) {\n const buffer = Buffer.allocUnsafe(Math.min(CHUNK, size - scan.offset));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, scan.offset);\n if (bytesRead <= 0) break;\n const data = scan.carry.length > 0 ? Buffer.concat([scan.carry, buffer.subarray(0, bytesRead)]) : buffer.subarray(0, bytesRead);\n const start = scan.offset - scan.carry.length;\n const lastBreak = data.lastIndexOf(0x0a);\n scan.offset += bytesRead;\n if (lastBreak < 0) {\n scan.carry = Buffer.from(data);\n continue;\n }\n scan.carry = Buffer.from(data.subarray(lastBreak + 1));\n for (let from = 0; from <= lastBreak;) {\n const end = data.indexOf(0x0a, from);\n addRow(scan, data.toString('utf8', from, end), start + from, end - from, cwd, own);\n from = end + 1;\n }\n }\n } finally {\n await handle.close();\n }\n}\n\n/** The transcript scanned up to its end, one read of a file at a time. */\nasync function scanned(file: string, cwd: string | undefined): Promise<Scan> {\n const previous = locks.get(file) ?? Promise.resolve();\n const next = previous.catch(() => undefined).then(async () => {\n const info = await stat(file);\n let scan = scans.get(file);\n if (!scan || scan.ino !== info.ino || info.size < scan.offset) scan = empty(info.ino);\n scans.delete(file);\n scans.set(file, scan);\n scan.readAt = Date.now();\n if (info.size > scan.offset) await readNew(file, scan, info.size, cwd);\n for (const [other, kept] of scans) {\n if (scans.size <= KEEP && Date.now() - kept.readAt < KEEP_UNREAD_MS) break;\n if (other !== file) scans.delete(other);\n }\n return scan;\n });\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 * Whether Claude Code's /diff counts a message as a prompt, starting a turn there and numbering it\n * by it (its diff panel's own test): a user row with text in it and no tool result, not one Claude\n * Code added itself. A `!` command and its output, a `/` command and its output, a background\n * task's note and the summary a compaction left count; a picture sent without words does not.\n */\nfunction countsAsPrompt(message: ChatMessage): boolean {\n return message.role === 'user' && !message.meta && !message.steered && !message.parentToolUseId\n && !message.blocks.some((b) => b.type === 'tool_result') && message.blocks.some((b) => b.type === 'text' && b.text !== '');\n}\n\nconst words = (text: string) => text.replace(/\\s+/g, ' ').trim();\nconst tagged = (text: string, name: string) => new RegExp(`<${name}>([\\\\s\\\\S]*?)</${name}>`).exec(text)?.[1];\n\n/**\n * A turn's name, from the row that starts it, in the words the conversation shows for that row: a\n * prompt's words, a command as it was typed (`/review the theme`, `!npm test`), a background\n * task's note.\n */\nfunction nameOf(message: ChatMessage, text: string): string {\n if (message.compactSummary) return 'Context compacted';\n const command = tagged(text, 'command-name');\n if (command) return words(`${command} ${tagged(text, 'command-args') ?? ''}`);\n if (isPrompt(text)) {\n const typed = words(text.replace(/(?:^|\\n\\n)Attached files:\\n[\\s\\S]*$/, ''));\n if (typed) return typed;\n const files = [...text.matchAll(/^- .+ \\((.+)\\)$/gm)].map((m) => m[1]);\n return files.length > 0 ? files.join(', ') : 'Attached files';\n }\n const bash = tagged(text, 'bash-input');\n if (bash !== undefined) return `!${bash.trim()}`;\n if (/^\\s*<task-notification>/.test(text)) return words(tagged(text, 'summary') ?? '') || 'Background task update';\n if (/^\\s*\\[Request interrupted/.test(text)) return 'Interrupted';\n if (/^\\s*<(?:bash-stdout|bash-stderr|local-command-stdout|local-command-stderr)>/.test(text)) return 'Command output';\n return 'Claude Code';\n}\n\n/** What a row is to the turn it may start: a command whose output row comes next, or that output. */\nfunction partOf(text: string): 'bash' | 'bash-output' | 'command' | 'command-output' | undefined {\n if (/^\\s*<bash-input>/.test(text)) return 'bash';\n if (/^\\s*<(?:bash-stdout|bash-stderr)>/.test(text)) return 'bash-output';\n if (/<command-name>/.test(text) && !NOT_TYPED.test(text)) return 'command';\n if (/^\\s*<(?:local-command-stdout|local-command-stderr)>/.test(text)) return 'command-output';\n return undefined;\n}\n\ntype Turn = { uuid: string; n: number; text: string; at?: number; rows: Array<{ uuid: string; row: EditRow }>; awaits?: 'bash-output' | 'command-output' };\n\n/**\n * The conversation as it stands (its current branch), cut into turns where /diff cuts it: at each\n * row it counts as a prompt (countsAsPrompt), numbered by that row's place among them, each with\n * the edit rows up to the next. A command and its output are two such rows, and /diff gives what\n * Claude does in answer to the output the output's number; here that turn is the command's, named\n * and kept (for Rewind) by the row that holds the command. /diff sees only what followed the last\n * compaction and numbers from its summary; here, where the turns before it show too, the count\n * runs on through it. `ownOnly`: without the rows copied from another session (a side chat's).\n */\nfunction turnsOf(messages: readonly ChatMessage[], scan: Scan, ownOnly: boolean): Turn[] {\n const turns: Turn[] = [];\n let turn: Turn | undefined;\n let place = 0;\n for (const message of messages) {\n if (ownOnly && scan.copied.has(message.uuid)) continue;\n if (countsAsPrompt(message)) {\n place += 1;\n // As the conversation shows the row: without the notes Claude Code puts in it for Claude.\n const text = message.blocks.map((b) => (b.type === 'text' ? b.text : '')).join('\\n').replace(/<system-reminder>[\\s\\S]*?<\\/system-reminder>/g, '').trim();\n const part = partOf(text);\n if (turn && part && turn.awaits === part && turn.rows.length === 0) {\n // The output of the command just before: the turn Claude answers it in, the command's.\n turn.n = place;\n delete turn.awaits;\n continue;\n }\n turn = {\n uuid: message.uuid,\n n: place,\n text: nameOf(message, text),\n ...(message.timestamp ? { at: message.timestamp } : {}),\n rows: [],\n ...(part === 'bash' ? { awaits: 'bash-output' as const } : part === 'command' ? { awaits: 'command-output' as const } : {}),\n };\n turns.push(turn);\n continue;\n }\n const row = scan.rows.get(message.uuid);\n if (row && turn) turn.rows.push({ uuid: message.uuid, row });\n }\n return turns.filter((t) => t.rows.length > 0);\n}\n\n/** A turn's files, in the order Claude first edited them, each with its edits' lines added up, as /diff counts them. */\nfunction filesOf(turn: Turn): TurnFile[] {\n const byPath = new Map<string, FileEdit[]>();\n for (const { row } of turn.rows) {\n for (const edit of row.edits) byPath.set(edit.path, [...(byPath.get(edit.path) ?? []), edit]);\n }\n return [...byPath].map(([file, edits]) => {\n const first = edits[0]!;\n const added = edits.reduce((sum, e) => sum + e.added, 0);\n const removed = edits.reduce((sum, e) => sum + e.removed, 0);\n return { path: file, added, removed, ...(first.created ? { created: true } : {}), ...(first.line ? { line: first.line } : {}) };\n });\n}\n\nconst clip = (text: string, max: number) => (text.length > max ? `${text.slice(0, max - 1).trimEnd()}\u2026` : text);\n\n/**\n * What each turn of the session in `file` changed, oldest first. `cwd`: the session's folder, for\n * relative paths; `ownOnly`: a side chat's, which leaves out the turns it copied of its session.\n */\nexport async function sessionChanges(file: string, cwd: string | undefined, ownOnly = false): Promise<SessionChanges> {\n const scan = await scanned(file, cwd);\n const turns: TurnChanges[] = turnsOf(await readHistory(file), scan, ownOnly).map((turn) => ({\n uuid: turn.uuid,\n n: turn.n,\n text: clip(turn.text, 120),\n ...(turn.at ? { at: turn.at } : {}),\n files: filesOf(turn),\n checkpoint: scan.checkpoints.has(turn.uuid),\n }));\n const lines: Record<string, number> = {};\n for (const [uuid, row] of scan.rows) {\n const line = row.edits[0]?.line;\n if (row.toolUseId && line && !(ownOnly && scan.copied.has(uuid))) lines[row.toolUseId] = line;\n }\n return { turns, lines };\n}\n\n/** The edit a row recorded, read again from its place in the file. */\nasync function readEdit(file: string, row: EditRow): Promise<Recorded | undefined> {\n const handle = await openRegular(file);\n try {\n const buffer = Buffer.alloc(row.bytes);\n await handle.read(buffer, 0, row.bytes, row.at);\n const parsed = JSON.parse(buffer.toString('utf8')) as Record<string, unknown>;\n return recordedEdit(parsed.toolUseResult);\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n}\n\n/** Past this many edits of one file in one turn, only the first ones are shown. */\nconst MAX_EDITS_SHOWN = 50;\n\n/**\n * What one turn changed in one file, as Claude Code's /diff shows it: each edit's patch, in the\n * order Claude made them. Empty when the turn did not edit the file.\n */\nexport async function turnDiff(file: string, cwd: string | undefined, turnId: string, target: string, ownOnly = false): Promise<string> {\n const scan = await scanned(file, cwd);\n const turn = turnsOf(await readHistory(file), scan, ownOnly).find((t) => t.uuid === turnId);\n const rows = (turn?.rows ?? []).filter(({ row }) => row.edits.some((e) => e.path === target)).map(({ row }) => row);\n if (rows.length === 0) return '';\n const edits = await Promise.all(rows.slice(0, MAX_EDITS_SHOWN).map((row) => readEdit(file, row)));\n const diff = unifiedDiff(target, edits.flatMap((edit) => edit?.hunks ?? []));\n return rows.length > MAX_EDITS_SHOWN ? `${diff}\u2026 (${rows.length - MAX_EDITS_SHOWN} more edits of this file in this turn)\\n` : diff;\n}\n", "import { createHash, randomUUID } from 'node:crypto';\nimport type { Dirent } from 'node:fs';\nimport { mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport {\n type AppName, appOf, type LimitKind, limitKind, modelName, noTokens, type SessionUsage, type Tokens, tokenTotal,\n type UsageRange, type UsageSession, type UsageSummary,\n} from '../shared/usage.js';\nimport { config } from './config.js';\nimport { connect } from './feed.js';\nimport { folderKind } from './folders.js';\nimport { openRegular } from './open.js';\nimport { limiter } from './transcripts.js';\n\n/**\n * Usage and activity across every Claude Code session on this computer, whichever app ran it,\n * from the transcripts Claude Code writes (`~/.claude/projects`), as Claude Code's /usage and\n * /stats count them:\n * - Tokens by kind come from each API reply's `usage`. Claude Code writes a reply that has several\n * content blocks as several rows with the same usage, and copies conversations into side chats,\n * branches and forks: each reply counts once, for the transcript it first appeared in.\n * - A subagent's transcript (`<session>/subagents/\u2026/agent-*.jsonl`) adds to its session's tokens,\n * but is not a session of its own; neither are subagent rows in the main transcript.\n * - Days are UTC dates, as /stats counts them; hours of the day are this computer's.\n *\n * Each transcript is read once, then only what it gains (keyed by its size and mtime, checked by a\n * print of the bytes before where reading stopped), a few at a time, in chunks, so thousands of\n * sessions and gigabytes of transcripts never hold up the server. What was read is kept in\n * Pelican's state folder, one file per project folder, and read back after a restart.\n */\n\nconst DAY = 86_400_000;\nconst MINUTE = 60_000;\n/** Bumped when what a record holds changes: records of another version are read afresh. */\nexport const RECORD_VERSION = 1;\nconst CHUNK = 1024 * 1024;\n/** Rows past this size are a tool's output or a picture, except a reply (a long Write); a reply can be this big. */\nconst SMALL_ROW = 256 * 1024;\nconst LARGEST_REPLY = 32 * 1024 * 1024;\nconst HEAD = 1024;\nconst PRINT = 256;\n/** Each reply keeps six numbers: input, output, cache reads, cache writes, of those the 1-hour ones, and 1 for fast mode. */\nconst FIELDS = 6;\n/** Fast mode costs twice as much per token, on every model that has it. */\nconst FAST = 2;\n\nconst SESSION_FILE = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\.jsonl$/i;\nconst SESSION_DIR = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst AGENT_FILE = /^agent-[\\w.-]{1,160}\\.jsonl$/;\n\n/** What one transcript holds for usage. */\nexport type FileRecord = {\n v: number;\n file: string;\n /** The project folder it is filed under: Claude Code's name for the session's folder. */\n dir: string;\n /** The session its usage counts toward: its own, or for a subagent's transcript, its session's. */\n session: string;\n sub: boolean;\n ino: number;\n size: number;\n mtimeMs: number;\n /** When the file was made (0 where the file system does not say): an original is older than its copies. */\n born: number;\n /** Bytes read, to the end of the last whole line, and a print of the bytes just before: an append keeps them. */\n offset: number;\n print: string;\n cwd?: string;\n /** The first and last row of the conversation itself: not a subagent's, not one copied from another session. */\n first?: number;\n last?: number;\n /** UTC days with such rows. */\n days: number[];\n /** One entry per API reply: a hash of its id, its minute, its model and app (indexes), and FIELDS token counts. */\n keys: number[];\n minutes: number[];\n model: number[];\n app: number[];\n tokens: number[];\n models: string[];\n /** Claude Code's entrypoints: cli, claude-desktop, sdk-ts\u2026 */\n apps: string[];\n compactions: number[];\n limits: Array<[number, LimitKind]>;\n /**\n * What Claude Code's own estimates say a token costs on this computer, from its cost-state rows:\n * the total of the Claude process writing them now (one that starts from zero is a new process),\n * that process's figures per model, and the sums the earlier processes' last figures add to the\n * fit of each model's prices (see `fitPrices`).\n */\n costRun: number;\n runPoints: PricePoint[];\n priceSums: PriceSums[];\n};\n\n/** One model's figures in a cost-state row: its tokens priced like input, its cache reads, and the dollars for both. */\ntype PricePoint = [model: string, input: number, cacheRead: number, usd: number];\n/** Sums over many such figures, for a least-squares fit: AA, AB, BB, Ay, By, y, A, B (A input-like tokens, B cache reads, y dollars). */\ntype PriceSums = [model: string, ...sums: number[]];\n\nconst num = (value: unknown) => (typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.min(Math.round(value), 4_000_000_000) : 0);\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\nconst utcDay = (ms: number) => Math.floor(ms / DAY);\nexport const dayString = (day: number) => new Date(day * DAY).toISOString().slice(0, 10);\n\n/** A 53-bit hash (cyrb53): replies are told apart by it, and two of a million collide about never. */\nexport function hash53(text: string): number {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < text.length; i += 1) {\n const ch = text.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1 >>> 0);\n}\n\n/**\n * A reply's tokens as input tokens, by the shape of Anthropic's prices: output costs five times\n * input, a cache write 1.25 times (twice for the 1-hour cache). Cache reads are priced apart: a\n * tenth of input on older models, less on newer ones.\n */\nexport const inputLike = (input: number, output: number, cacheWrite: number, cacheWrite1h: number) =>\n input + 5 * output + 1.25 * Math.max(0, cacheWrite - cacheWrite1h) + 2 * cacheWrite1h;\n\n/** A model's prices per token, as Claude Code's estimates on this computer show them. */\nexport type Prices = { input: number; cacheRead: number };\n\n/**\n * Each model's price of an input token and of a cache read, fitted (least squares) to what Claude\n * Code estimated its sessions cost: its own list prices, or the organization's. With too little to\n * tell the two apart, cache reads cost a tenth of input.\n */\nexport function fitPrices(sums: Map<string, number[]>): Map<string, Prices> {\n const prices = new Map<string, Prices>();\n for (const [model, [aa = 0, ab = 0, bb = 0, ay = 0, by = 0, y = 0, a = 0, b = 0]] of sums) {\n let input = NaN;\n let cacheRead = NaN;\n const det = aa * bb - ab * ab;\n if (det > 1e-3 * aa * bb) {\n input = (ay * bb - by * ab) / det;\n cacheRead = (by * aa - ay * ab) / det;\n }\n if (!(input > 0) || !(cacheRead >= 0)) {\n const tokens = a + 0.1 * b;\n input = tokens > 0 ? y / tokens : NaN;\n cacheRead = 0.1 * input;\n }\n if (input > 0) prices.set(model, { input, cacheRead });\n }\n return prices;\n}\n\n/** What a reply cost at a model's prices. */\nconst priceOf = (prices: Prices, t: number[], at: number) =>\n (t[at + 5] ? FAST : 1) * (prices.input * inputLike(t[at]!, t[at + 1]!, t[at + 3]!, t[at + 4]!) + prices.cacheRead * t[at + 2]!);\n\n/**\n * Of a model's replies in a transcript so far: the share of cache writes that were 1-hour ones, and\n * the share of their worth in fast mode. Claude Code's own figures do not always say either.\n */\nfunction mixOf(record: FileRecord, model: string): { write1h: number; fast: number } {\n const m = record.models.indexOf(model);\n let writes = 0;\n let writes1h = 0;\n let worth = 0;\n let fast = 0;\n for (let j = 0; m >= 0 && j < record.keys.length; j += 1) {\n if (record.model[j] !== m) continue;\n const t = j * FIELDS;\n writes += record.tokens[t + 3]!;\n writes1h += record.tokens[t + 4]!;\n const w = inputLike(record.tokens[t]!, record.tokens[t + 1]!, record.tokens[t + 3]!, record.tokens[t + 4]!) + 0.1 * record.tokens[t + 2]!;\n worth += w;\n if (record.tokens[t + 5]) fast += w;\n }\n return { write1h: writes > 0 ? writes1h / writes : 0, fast: worth > 0 ? fast / worth : 0 };\n}\n\nfunction emptyRecord(file: string, found: Found, info: { ino: number; size: number; mtimeMs: number; birthtimeMs: number }): FileRecord {\n return {\n v: RECORD_VERSION, file, dir: found.dir, session: found.session, sub: found.sub,\n ino: info.ino, size: info.size, mtimeMs: info.mtimeMs, born: info.birthtimeMs || 0, offset: 0, print: '',\n days: [], keys: [], minutes: [], model: [], app: [], tokens: [], models: [], apps: [],\n compactions: [], limits: [], costRun: 0, runPoints: [], priceSums: [],\n };\n}\n\n/** What reading a record goes on with: its replies by hash, and its days, rebuilt from the record. */\ntype Reading = { replies: Map<number, number>; days: Set<number>; fileId: string };\n\nfunction reading(record: FileRecord): Reading {\n return {\n replies: new Map(record.keys.map((key, i) => [key, i])),\n days: new Set(record.days),\n fileId: path.basename(record.file, '.jsonl'),\n };\n}\n\nconst indexOf = (list: string[], value: string) => {\n const at = list.indexOf(value);\n if (at >= 0) return at;\n // A file with hundreds of models or apps is not one Claude Code wrote: the rest share the last slot.\n if (list.length >= 255) return 254;\n list.push(value);\n return list.length - 1;\n};\n\ntype Row = {\n type?: unknown; subtype?: unknown; timestamp?: unknown; isSidechain?: unknown; sessionId?: unknown; forkedFrom?: unknown;\n cwd?: unknown; entrypoint?: unknown; requestId?: unknown; uuid?: unknown; isApiErrorMessage?: unknown; error?: unknown;\n message?: { id?: unknown; model?: unknown; usage?: Record<string, unknown>; content?: unknown };\n totalCostUSD?: unknown; startTime?: unknown; totalDuration?: unknown; modelUsage?: unknown;\n};\n\nfunction textOf(content: unknown): string {\n if (typeof content === 'string') return content;\n if (!Array.isArray(content)) return '';\n return content.map((b: { type?: unknown; text?: unknown }) => (b?.type === 'text' && typeof b.text === 'string' ? b.text : '')).join('\\n');\n}\n\n/** Claude Code's cost-state row: the session's estimate so far, and per model what it priced. */\nfunction costRow(record: FileRecord, row: Row): void {\n const usd = typeof row.totalCostUSD === 'number' && Number.isFinite(row.totalCostUSD) && row.totalCostUSD >= 0 ? row.totalCostUSD : undefined;\n if (usd === undefined) return;\n // A Claude process that did not carry the total on started from zero: the last one's figures stay.\n if (usd + 1e-9 < record.costRun) for (const point of record.runPoints) addPoint(record.priceSums, point);\n record.costRun = usd;\n const points: PricePoint[] = [];\n const usage = row.modelUsage && typeof row.modelUsage === 'object' ? row.modelUsage as Record<string, Record<string, unknown>> : {};\n for (const [model, u] of Object.entries(usage)) {\n if (!u || typeof u !== 'object' || model.startsWith('<')) continue;\n // Web searches are priced per search, not per token.\n const cost = typeof u.costUSD === 'number' && Number.isFinite(u.costUSD) ? u.costUSD - 0.01 * num(u.webSearchRequests) : 0;\n const mix = mixOf(record, model);\n const writes = num(u.cacheCreationInputTokens);\n const writes1h = u.cacheCreationEphemeral1hInputTokens === undefined ? Math.round(writes * mix.write1h) : num(u.cacheCreationEphemeral1hInputTokens);\n const speed = 1 + (FAST - 1) * mix.fast;\n const input = inputLike(num(u.inputTokens), num(u.outputTokens), writes, writes1h) * speed;\n const reads = num(u.cacheReadInputTokens) * speed;\n if (cost > 0 && input + reads > 0) points.push([model, input, reads, cost]);\n }\n record.runPoints = points;\n}\n\nfunction addPoint(sums: PriceSums[], [model, a, b, y]: PricePoint): void {\n let known = sums.find((s) => s[0] === model);\n if (!known) {\n known = [model, 0, 0, 0, 0, 0, 0, 0, 0];\n sums.push(known);\n }\n const add = [a * a, a * b, b * b, a * y, b * y, y, a, b];\n for (let i = 0; i < add.length; i += 1) known[i + 1] = (known[i + 1] as number) + add[i]!;\n}\n\n/** Adds one row of the transcript. Rows that cannot matter are looked at only as far as it takes to tell. */\nfunction addLine(record: FileRecord, state: Reading, line: Buffer): void {\n if (line.length < 2 || line[0] !== 0x7b) return;\n const kind = kindOf(line.toString('latin1', 0, Math.min(HEAD, line.length)));\n // Titles, requests, snapshots, queue operations: rows of Claude Code's own, with \"type\" first.\n if (kind === 'skip') return;\n if (kind === 'cost') {\n const row = parse(line);\n if (row && (record.sub || row.sessionId === undefined || row.sessionId === state.fileId)) costRow(record, row);\n return;\n }\n // A tool's result sits between two replies: it has no usage and adds nothing to the times.\n if (kind === 'other' && (line.length > SMALL_ROW || line.includes('\"tool_use_id\"'))) return;\n const row = parse(line);\n if (!row) return;\n // Rows a side chat, branch or fork copied from another session: they ran there, not here.\n if (!record.sub && ((typeof row.sessionId === 'string' && row.sessionId !== state.fileId) || (row.forkedFrom !== undefined && row.forkedFrom !== null))) return;\n const time = typeof row.timestamp === 'string' ? Date.parse(row.timestamp) : NaN;\n const side = row.isSidechain === true;\n const own = !record.sub && !side && Number.isFinite(time);\n if (row.type !== 'user' && row.type !== 'assistant' && row.type !== 'system') return;\n if (!record.cwd && typeof row.cwd === 'string' && row.cwd) record.cwd = row.cwd;\n if (own) {\n record.first = Math.min(record.first ?? time, time);\n record.last = Math.max(record.last ?? time, time);\n state.days.add(utcDay(time));\n }\n if (row.type === 'system') {\n if (row.subtype === 'compact_boundary' && !side && Number.isFinite(time)) record.compactions.push(time);\n return;\n }\n if (row.type !== 'assistant' || !Number.isFinite(time)) return;\n const message = row.message;\n if (!message || typeof message !== 'object') return;\n if (message.model === '<synthetic>') {\n // Claude Code's note that a usage limit was reached, written in place of a reply.\n if (row.isApiErrorMessage === true || typeof row.error === 'string') {\n const kind = limitKind(textOf(message.content));\n if (kind) record.limits.push([time, kind]);\n }\n return;\n }\n const usage = message.usage;\n if (!usage || typeof usage !== 'object') return;\n const creation = usage.cache_creation && typeof usage.cache_creation === 'object' ? usage.cache_creation as Record<string, unknown> : undefined;\n const counts = [\n num(usage.input_tokens), num(usage.output_tokens), num(usage.cache_read_input_tokens), num(usage.cache_creation_input_tokens),\n num(creation?.ephemeral_1h_input_tokens), usage.speed === 'fast' ? 1 : 0,\n ];\n if (counts[0] === 0 && counts[1] === 0 && counts[2] === 0 && counts[3] === 0) return;\n const id = str(message.id) ?? str(row.uuid);\n if (!id) return;\n const key = hash53(`${id}\\u0000${str(row.requestId) ?? ''}`);\n const known = state.replies.get(key);\n if (known !== undefined) {\n // The same reply again (one row per content block): its usage only ever grows.\n for (let k = 0; k < FIELDS; k += 1) record.tokens[known * FIELDS + k] = Math.max(record.tokens[known * FIELDS + k]!, counts[k]!);\n return;\n }\n state.replies.set(key, record.keys.length);\n record.keys.push(key);\n record.minutes.push(Math.floor(time / MINUTE));\n record.model.push(indexOf(record.models, str(message.model) ?? 'unknown'));\n record.app.push(indexOf(record.apps, str(row.entrypoint) ?? ''));\n record.tokens.push(...counts);\n}\n\nfunction parse(line: Buffer): Row | undefined {\n try {\n const row = JSON.parse(line.toString('utf8')) as unknown;\n return row && typeof row === 'object' && !Array.isArray(row) ? row as Row : undefined;\n } catch {\n // Half written: read again with the rest of it.\n return undefined;\n }\n}\n\n/** A print of the bytes just before `offset`, which an append leaves as they are and a rewrite does not. */\nasync function printAt(handle: Awaited<ReturnType<typeof openRegular>>, offset: number): Promise<string> {\n if (offset <= 0) return '';\n const length = Math.min(PRINT, offset);\n const buffer = Buffer.alloc(length);\n const { bytesRead } = await handle.read(buffer, 0, length, offset - length);\n return createHash('sha256').update(buffer.subarray(0, bytesRead)).digest('base64url').slice(0, 22);\n}\n\n/**\n * What a row is, from its first kilobyte: Claude Code's cost (read), another of its own rows\n * (titles, requests, snapshots: passed over), a reply (read, however long), a tool's result (passed\n * over), or something else (read when it is short).\n */\ntype Kind = 'cost' | 'skip' | 'reply' | 'other';\n\nfunction kindOf(head: string): Kind {\n if (head.startsWith('{\"type\":\"')) return head.startsWith('{\"type\":\"cost-state\"') ? 'cost' : 'skip';\n if (head.includes('\"role\":\"assistant\"') || head.includes('\"type\":\"assistant\"')) return 'reply';\n return head.includes('\"tool_use_id\"') ? 'skip' : 'other';\n}\n\n/**\n * Reads the lines of `handle` from the record's offset to `size`, one chunk at a time, into one\n * buffer: a line is used up before the next read. A line that runs past a chunk is judged by its\n * head at once, so the long ones that do not matter (pictures, tools' output, request records) are\n * passed over without being copied.\n */\nasync function readLines(handle: Awaited<ReturnType<typeof openRegular>>, record: FileRecord, size: number, onLine: (line: Buffer) => void): Promise<void> {\n let position = record.offset;\n let pieces: Buffer[] = [];\n let pending = 0;\n let kind: Kind | undefined;\n let skipping = false;\n const buffer = Buffer.allocUnsafe(Math.min(CHUNK, Math.max(1, size - position)));\n while (position < size) {\n const length = Math.min(buffer.length, size - position);\n const { bytesRead } = await handle.read(buffer, 0, length, position);\n if (bytesRead <= 0) break;\n const data = buffer.subarray(0, bytesRead);\n let from = 0;\n for (;;) {\n const end = data.indexOf(0x0a, from);\n if (end < 0) {\n if (!skipping && from < data.length) {\n const rest = data.subarray(from);\n pending += rest.length;\n if (kind === undefined && pending >= HEAD) kind = kindOf((pieces.length > 0 ? Buffer.concat([...pieces, rest]) : rest).toString('latin1', 0, HEAD));\n if (kind === 'skip' || pending > (kind === 'reply' || kind === 'cost' ? LARGEST_REPLY : SMALL_ROW)) {\n skipping = true;\n pieces = [];\n } else {\n pieces.push(Buffer.from(rest));\n }\n }\n break;\n }\n if (!skipping) {\n const piece = data.subarray(from, end);\n onLine(pieces.length > 0 ? Buffer.concat([...pieces, piece]) : piece);\n }\n pieces = [];\n pending = 0;\n kind = undefined;\n skipping = false;\n from = end + 1;\n record.offset = position + from;\n }\n position += bytesRead;\n }\n}\n\ntype Found = { file: string; dir: string; session: string; sub: boolean };\n\n/**\n * Reads what a transcript gained since `old` was read, or all of it when it is new, was replaced\n * (another inode), got shorter, or changed before where reading stopped. Undefined when it cannot\n * be read (gone, not a regular file).\n */\nexport async function readRecord(found: Found, old?: FileRecord): Promise<FileRecord | undefined> {\n let handle: Awaited<ReturnType<typeof openRegular>>;\n try {\n handle = await openRegular(found.file);\n } catch {\n return undefined;\n }\n try {\n const info = await handle.stat();\n const unchanged = old && old.v === RECORD_VERSION && old.ino === info.ino && old.size === info.size && old.mtimeMs === info.mtimeMs;\n if (unchanged) return old;\n const appended = old && old.v === RECORD_VERSION && old.ino === info.ino && info.size >= old.offset && (await printAt(handle, old.offset)) === old.print;\n const record = appended && old ? old : emptyRecord(found.file, found, info);\n Object.assign(record, { ino: info.ino, size: info.size, mtimeMs: info.mtimeMs, born: info.birthtimeMs || record.born });\n const state = reading(record);\n await readLines(handle, record, info.size, (line) => addLine(record, state, line));\n record.days = [...state.days].sort((a, b) => a - b);\n record.print = await printAt(handle, record.offset);\n return record;\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n}\n\n// --- Finding every transcript -----------------------------------------------------------------\n\nconst listing = limiter(8);\nconst listingSubagents = limiter(16);\n\nasync function entries(dir: string): Promise<Dirent[]> {\n try {\n return await readdir(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n}\n\n/** A session's subagents, and those of its workflows, each in a folder of its own. */\nasync function subagentFiles(dir: string, project: string, session: string, found: Found[], depth = 0): Promise<void> {\n const list = await listingSubagents(() => entries(dir));\n for (const entry of list) {\n if (entry.isFile() && AGENT_FILE.test(entry.name)) found.push({ file: path.join(dir, entry.name), dir: project, session, sub: true });\n }\n if (depth > 0 || !list.some((e) => e.isDirectory() && e.name === 'workflows')) return;\n const runs = await listingSubagents(() => entries(path.join(dir, 'workflows')));\n await Promise.all(runs.filter((r) => r.isDirectory() && /^[\\w-][\\w.-]{0,159}$/.test(r.name))\n .map((r) => subagentFiles(path.join(dir, 'workflows', r.name), project, session, found, 1)));\n}\n\n/** Every transcript Claude Code keeps on this computer: each session's, and its subagents'. Links are not followed. */\nexport async function findTranscripts(): Promise<Found[]> {\n const root = path.join(config.claudeHome, 'projects');\n const found: Found[] = [];\n const projects = (await entries(root)).filter((d) => d.isDirectory());\n await Promise.all(projects.map(async (project) => {\n const dir = path.join(root, project.name);\n const list = await listing(() => entries(dir));\n for (const entry of list) {\n const id = entry.isFile() ? SESSION_FILE.exec(entry.name)?.[1] : undefined;\n if (id) found.push({ file: path.join(dir, entry.name), dir: project.name, session: id, sub: false });\n }\n await Promise.all(list.filter((e) => e.isDirectory() && SESSION_DIR.test(e.name))\n .map((e) => subagentFiles(path.join(dir, e.name, 'subagents'), project.name, e.name, found)));\n }));\n return found;\n}\n\n// --- What has been read, kept in the state folder ---------------------------------------------\n\nconst records = new Map<string, FileRecord>();\n/** Bumped whenever a record changes: what was worked out from them is worked out again. */\nlet version = 0;\nconst storeDir = () => path.join(config.stateDir, 'usage');\nconst shardOf = (dir: string) => path.join(storeDir(), 'files', `${createHash('sha256').update(dir).digest('hex').slice(0, 24)}.json`);\n\nfunction encode(values: number[], Kind: Float64ArrayConstructor | Uint32ArrayConstructor | Uint8ArrayConstructor): string {\n return Buffer.from(Kind.from(values).buffer).toString('base64');\n}\n\nfunction decode(text: unknown, Kind: Float64ArrayConstructor | Uint32ArrayConstructor | Uint8ArrayConstructor): number[] | undefined {\n if (typeof text !== 'string') return undefined;\n const bytes = Buffer.from(text, 'base64');\n if (bytes.length % Kind.BYTES_PER_ELEMENT !== 0) return undefined;\n // Copied, so the view starts where its type needs it to.\n const aligned = new Uint8Array(bytes.length);\n aligned.set(bytes);\n return Array.from(new Kind(aligned.buffer));\n}\n\nfunction serialize(record: FileRecord): Record<string, unknown> {\n return {\n ...record,\n keys: encode(record.keys, Float64Array),\n minutes: encode(record.minutes, Uint32Array),\n model: encode(record.model, Uint8Array),\n app: encode(record.app, Uint8Array),\n tokens: encode(record.tokens, Uint32Array),\n };\n}\n\nfunction deserialize(raw: Record<string, unknown>): FileRecord | undefined {\n if (raw.v !== RECORD_VERSION || typeof raw.file !== 'string' || typeof raw.dir !== 'string' || typeof raw.session !== 'string') return undefined;\n const keys = decode(raw.keys, Float64Array);\n const minutes = decode(raw.minutes, Uint32Array);\n const model = decode(raw.model, Uint8Array);\n const app = decode(raw.app, Uint8Array);\n const tokens = decode(raw.tokens, Uint32Array);\n const n = keys?.length ?? -1;\n if (!keys || minutes?.length !== n || model?.length !== n || app?.length !== n || tokens?.length !== n * FIELDS) return undefined;\n const numbers = (value: unknown) => (Array.isArray(value) && value.every((v) => typeof v === 'number') ? value as number[] : undefined);\n const strings = (value: unknown) => (Array.isArray(value) && value.every((v) => typeof v === 'string') ? value as string[] : undefined);\n const days = numbers(raw.days);\n const compactions = numbers(raw.compactions);\n const models = strings(raw.models);\n const apps = strings(raw.apps);\n if (!days || !compactions || !models || !apps || !Array.isArray(raw.limits) || !Array.isArray(raw.runPoints) || !Array.isArray(raw.priceSums)) return undefined;\n return {\n ...(raw as unknown as FileRecord), keys, minutes, model, app, tokens, days, compactions, models, apps,\n };\n}\n\nlet loaded: Promise<void> | undefined;\n\n/** Reads back what earlier runs of Pelican read; a file that cannot be read is read from the transcripts again. */\nfunction load(): Promise<void> {\n loaded ??= (async () => {\n const dir = path.join(storeDir(), 'files');\n const names = (await entries(dir)).filter((e) => e.isFile() && e.name.endsWith('.json')).map((e) => e.name);\n const reads = limiter(8);\n await Promise.all(names.map((name) => reads(async () => {\n try {\n const shard = JSON.parse(await readFile(path.join(dir, name), 'utf8')) as { records?: unknown };\n for (const raw of Array.isArray(shard.records) ? shard.records : []) {\n const record = raw && typeof raw === 'object' ? deserialize(raw as Record<string, unknown>) : undefined;\n if (record && !records.has(record.file)) records.set(record.file, record);\n }\n } catch {\n // Written by a Pelican that stopped half way, or not ours: read the transcripts again.\n }\n })));\n version += 1;\n })();\n return loaded;\n}\n\nconst dirty = new Set<string>();\nlet saveTimer: NodeJS.Timeout | undefined;\nlet saving: Promise<void> = Promise.resolve();\n\nfunction changed(record: FileRecord): void {\n version += 1;\n dirty.add(record.dir);\n saveTimer ??= setTimeout(() => {\n saveTimer = undefined;\n saving = saving.then(saveShards, saveShards);\n }, 5000);\n saveTimer.unref?.();\n}\n\nlet warned = false;\n/** Said once: a state folder that cannot be written to would otherwise say so every few seconds. */\nfunction warnOnce(error: unknown): void {\n if (warned) return;\n warned = true;\n console.warn('[pelican] could not keep usage figures in the state folder:', (error as Error).message);\n}\n\nasync function writeAtomically(file: string, text: string): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const temp = `${file}.${randomUUID()}.tmp`;\n await writeFile(temp, text, { mode: 0o600 });\n await rename(temp, file);\n}\n\nasync function saveShards(): Promise<void> {\n const dirs = [...dirty];\n dirty.clear();\n for (const dir of dirs) {\n const kept = [...records.values()].filter((r) => r.dir === dir);\n try {\n if (kept.length === 0) await rm(shardOf(dir), { force: true });\n else await writeAtomically(shardOf(dir), JSON.stringify({ v: RECORD_VERSION, dir, records: kept.map(serialize) }));\n } catch (error) {\n dirty.add(dir);\n warnOnce(error);\n }\n }\n}\n\n/** Writes what is not written yet, now (for tests, and before the server stops). */\nexport async function flushUsage(): Promise<void> {\n clearTimeout(saveTimer);\n saveTimer = undefined;\n saving = saving.then(saveShards, saveShards);\n await saving;\n await saveOwn();\n}\n\n// --- Reading everything, a little at a time -----------------------------------------------------\n\nconst progress = { files: 0, read: 0 };\nlet scanning: Promise<void> | undefined;\nlet scannedAt = 0;\nlet scannedOnce = false;\nconst statting = limiter(32);\nconst parsing = limiter(2);\nconst locks = new Map<string, Promise<FileRecord | undefined>>();\n\n/**\n * Reads a transcript into its record, one read per file at a time: a record grows in place, so\n * two reads of one file at once (the page's look at everything, a session menu) would add its new\n * lines twice.\n */\nfunction readLocked(found: Found): Promise<FileRecord | undefined> {\n const previous = locks.get(found.file) ?? Promise.resolve(undefined);\n const next = previous.catch(() => undefined).then(async () => {\n const old = records.get(found.file);\n const before = old ? `${old.size}:${old.mtimeMs}:${old.offset}` : '';\n const record = await readRecord(found, old);\n if (record && (record !== old || `${record.size}:${record.mtimeMs}:${record.offset}` !== before)) {\n records.set(found.file, record);\n changed(record);\n }\n return record;\n });\n locks.set(found.file, next);\n void next.finally(() => {\n if (locks.get(found.file) === next) locks.delete(found.file);\n }).catch(() => undefined);\n return next;\n}\n\nasync function scan(): Promise<void> {\n await load();\n const found = await findTranscripts();\n const present = new Set(found.map((f) => f.file));\n for (const [file, record] of records) {\n if (present.has(file)) continue;\n records.delete(file);\n changed(record);\n }\n progress.files = found.length;\n progress.read = 0;\n const stats = await Promise.all(found.map((f) => statting(async () => ({ f, info: await stat(f.file).catch(() => undefined) }))));\n const toRead: Array<{ f: Found; mtimeMs: number }> = [];\n for (const { f, info } of stats) {\n const old = records.get(f.file);\n if (!info?.isFile()) {\n if (old) {\n records.delete(f.file);\n changed(old);\n }\n progress.read += 1;\n } else if (old && old.v === RECORD_VERSION && old.ino === info.ino && old.size === info.size && old.mtimeMs === info.mtimeMs) {\n progress.read += 1;\n } else {\n toRead.push({ f, mtimeMs: info.mtimeMs });\n }\n }\n // The newest first: the last few days fill in before older months.\n toRead.sort((a, b) => b.mtimeMs - a.mtimeMs);\n await Promise.all(toRead.map(({ f }) => parsing(async () => {\n await readLocked(f);\n progress.read += 1;\n })));\n scannedOnce = true;\n}\n\n/** Starts a look at the transcripts when the last one is older than `maxAgeMs`; shared while it runs. */\nexport function refreshUsage(maxAgeMs = 15_000): Promise<void> {\n if (scanning) return scanning;\n if (scannedOnce && Date.now() - scannedAt < maxAgeMs) return Promise.resolve();\n scanning = scan().catch((error: Error) => console.warn('[pelican] reading usage:', error.message)).finally(() => {\n scanning = undefined;\n scannedAt = Date.now();\n });\n return scanning;\n}\n\n/** Ready once every transcript was read once; later looks only add what changed, quietly. */\nexport const usageProgress = () => ({ files: progress.files, read: Math.min(progress.read, progress.files), ready: scannedOnce });\n\n// --- What Pelican itself knows: the sessions it ran, and how long Claude waited for you there ---\n\ntype Own = { sessions: Record<string, number>; waits: Array<[string, number, number]> };\nconst ownFile = () => path.join(storeDir(), 'pelican.json');\nlet own: Promise<Own> | undefined;\nlet ownChanged = false;\nlet ownTimer: NodeJS.Timeout | undefined;\nconst MAX_WAITS = 5000;\n\nfunction ownRecord(): Promise<Own> {\n own ??= readFile(ownFile(), 'utf8').then((text) => {\n const raw = JSON.parse(text) as { sessions?: unknown; waits?: unknown };\n const sessions: Record<string, number> = {};\n if (raw.sessions && typeof raw.sessions === 'object') {\n for (const [id, at] of Object.entries(raw.sessions)) if (typeof at === 'number') sessions[id] = at;\n }\n const waits = Array.isArray(raw.waits)\n ? raw.waits.filter((w): w is [string, number, number] => Array.isArray(w) && typeof w[0] === 'string' && typeof w[1] === 'number' && typeof w[2] === 'number' && w[2] >= w[1])\n : [];\n return { sessions, waits };\n }).catch(() => ({ sessions: {}, waits: [] }));\n return own;\n}\n\nasync function saveOwn(): Promise<void> {\n if (!ownChanged || !own) return;\n ownChanged = false;\n try {\n await writeAtomically(ownFile(), JSON.stringify(await own));\n } catch (error) {\n ownChanged = true;\n warnOnce(error);\n }\n}\n\nfunction ownSoon(): void {\n ownChanged = true;\n ownVersion += 1;\n ownTimer ??= setTimeout(() => {\n ownTimer = undefined;\n void saveOwn();\n }, 2000);\n ownTimer.unref?.();\n}\n\nconst waitingSince = new Map<string, number>();\n\n/**\n * Pelican's runs say when their status changes (the session lists hear it too): a session that\n * says so is one Pelican runs, and the time it spends waiting for an approval, an answer or a\n * plan is time Claude waited for you.\n */\nexport function noteRunStatus(sessionId: string, status: string, now = Date.now()): void {\n void ownRecord().then((record) => {\n if (!(sessionId in record.sessions)) {\n record.sessions[sessionId] = now;\n ownSoon();\n }\n if (status === 'waiting') {\n if (!waitingSince.has(sessionId)) waitingSince.set(sessionId, now);\n return;\n }\n const since = waitingSince.get(sessionId);\n if (since === undefined) return;\n waitingSince.delete(sessionId);\n record.waits.push([sessionId, since, now]);\n if (record.waits.length > MAX_WAITS) record.waits.splice(0, record.waits.length - MAX_WAITS);\n ownSoon();\n });\n}\n\nconnect((event) => {\n if (event.type === 'status') noteRunStatus(event.sessionId, event.status);\n});\n\n// --- Claude Code's own stats (read only) --------------------------------------------------------\n\n/** `longest.at`: when that session started (ms), as Claude Code recorded it; the rest are UTC days. */\ntype StatsCache = { through: number; days: Map<number, { sessions: number; active: boolean }>; longest?: { id: string; ms: number; at: number }; first?: number };\n\n/**\n * Claude Code's `stats-cache.json`, which /stats keeps of every day it counted, also of sessions\n * whose transcripts are gone: per UTC day the sessions started and whether anything happened, the\n * longest session and the first session, through the last day it counted. Read only.\n */\nexport async function readStatsCache(): Promise<StatsCache | undefined> {\n let text: string;\n try {\n const handle = await openRegular(path.join(config.claudeHome, 'stats-cache.json'));\n try {\n if ((await handle.stat()).size > 16 * 1024 * 1024) return undefined;\n text = await handle.readFile('utf8');\n } finally {\n await handle.close();\n }\n } catch {\n return undefined;\n }\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(text) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n const date = (value: unknown) => (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value) && Number.isFinite(Date.parse(value)) ? utcDay(Date.parse(value.slice(0, 10))) : undefined);\n const through = date(raw.lastComputedDate);\n if (through === undefined || !Array.isArray(raw.dailyActivity)) return undefined;\n const days = new Map<number, { sessions: number; active: boolean }>();\n for (const entry of raw.dailyActivity as Array<Record<string, unknown>>) {\n const day = entry && typeof entry === 'object' ? date(entry.date) : undefined;\n if (day === undefined || day > through) continue;\n days.set(day, { sessions: num(entry.sessionCount), active: num(entry.messageCount) > 0 || num(entry.sessionCount) > 0 });\n }\n const longest = raw.longestSession as Record<string, unknown> | null | undefined;\n // Its time as it is, not cut to its day: the page says the day, in UTC as every other.\n const at = longest && typeof longest.timestamp === 'string' && date(longest.timestamp) !== undefined ? Date.parse(longest.timestamp) : undefined;\n const first = date(raw.firstSessionDate);\n return {\n through,\n days,\n ...(longest && typeof longest.sessionId === 'string' && at !== undefined && num(longest.duration) > 0\n ? { longest: { id: longest.sessionId, ms: num(longest.duration), at } } : {}),\n ...(first !== undefined ? { first } : {}),\n };\n}\n\n// --- Working it out -------------------------------------------------------------------------------\n\n/** Which replies each transcript owns: a reply found in several (a copy of a conversation) belongs to the oldest. */\ntype Ownership = { version: number; order: FileRecord[]; skip: Map<FileRecord, Uint8Array> };\nlet ownership: Ownership | undefined;\n\nconst age = (r: FileRecord) => r.born || (r.minutes[0] !== undefined ? r.minutes[0] * MINUTE : r.mtimeMs);\n\nfunction owners(): Ownership {\n if (ownership?.version === version) return ownership;\n const order = [...records.values()].sort((a, b) => age(a) - age(b) || (a.first ?? Infinity) - (b.first ?? Infinity) || (a.file < b.file ? -1 : 1));\n let total = 0;\n for (const r of order) total += r.keys.length;\n const all = new Float64Array(total);\n let i = 0;\n for (const r of order) for (const key of r.keys) all[i++] = key;\n all.sort();\n const shared = new Set<number>();\n for (let j = 1; j < all.length; j += 1) if (all[j] === all[j - 1]) shared.add(all[j]!);\n const claimed = new Set<number>();\n const skip = new Map<FileRecord, Uint8Array>();\n if (shared.size > 0) {\n for (const r of order) {\n let mask: Uint8Array | undefined;\n for (let j = 0; j < r.keys.length; j += 1) {\n const key = r.keys[j]!;\n if (!shared.has(key)) continue;\n if (claimed.has(key)) (mask ??= new Uint8Array(r.keys.length))[j] = 1;\n else claimed.add(key);\n }\n if (mask) skip.set(r, mask);\n }\n }\n ownership = { version, order, skip };\n return ownership;\n}\n\n/** Each model's prices, from every transcript's cost-state rows (see `fitPrices`). */\nfunction pricesFrom(list: Iterable<FileRecord>): Map<string, Prices> {\n const sums = new Map<string, number[]>();\n const into = (model: string, values: number[]) => {\n const sum = sums.get(model) ?? [0, 0, 0, 0, 0, 0, 0, 0];\n for (let i = 0; i < values.length; i += 1) sum[i] = sum[i]! + values[i]!;\n sums.set(model, sum);\n };\n for (const r of list) {\n for (const [model, ...values] of r.priceSums) into(model, values as number[]);\n for (const [model, a, b, y] of r.runPoints) into(model, [a * a, a * b, b * b, a * y, b * y, y, a, b]);\n }\n return fitPrices(sums);\n}\n\nconst add = (into: Tokens, t: number[], at: number) => {\n into.input += t[at]!;\n into.output += t[at + 1]!;\n into.cacheRead += t[at + 2]!;\n into.cacheWrite += t[at + 3]!;\n};\n\ntype SessionInfo = { title: string; project: string };\nexport type Titles = (ids: string[]) => Promise<Map<string, SessionInfo>>;\n\nconst projectName = (cwd: string) => path.basename(cwd) || cwd;\n\n/** Throwaway folders are one project each kind: the scratch folders, and the system's temp folders. */\nconst SCRATCH = 'scratch:';\nconst TEMP = 'temp:';\nconst projectOfFolder = (cwd: string) => {\n const kind = cwd.startsWith('/') ? folderKind(cwd) : 'project';\n return kind === 'scratch' ? SCRATCH : kind === 'temp' ? TEMP : cwd;\n};\n\n/** The first and last UTC day of a period that ends today. */\nexport function period(range: UsageRange, now: number, first: number | undefined): { from: number; to: number } {\n const to = utcDay(now);\n if (range === '7d') return { from: to - 6, to };\n if (range === '30d') return { from: to - 29, to };\n return { from: Math.min(first ?? to, to), to };\n}\n\n/** Consecutive days with activity: the run that ends today (none if today has none, as /stats says), and the longest. */\nexport function streaks(active: Set<number>, from: number, to: number): { current: number; longest: number } {\n let current = 0;\n for (let d = to; d >= from && active.has(d); d -= 1) current += 1;\n let longest = 0;\n let run = 0;\n for (let d = from; d <= to; d += 1) {\n run = active.has(d) ? run + 1 : 0;\n longest = Math.max(longest, run);\n }\n return { current, longest };\n}\n\n/**\n * Limits reached, each once: the sessions running when a limit is reached each say so, and a limit\n * reached again before it resets (5 hours, a week) is the same one.\n */\nexport function distinctLimits(hits: Array<[number, LimitKind]>): Array<{ kind: LimitKind; at: number }> {\n const span: Record<LimitKind, number> = { session: 5 * 60 * MINUTE, weekly: 7 * DAY, model: 7 * DAY };\n const out: Array<{ kind: LimitKind; at: number }> = [];\n const last = new Map<LimitKind, number>();\n for (const [at, kind] of [...hits].sort((a, b) => a[0] - b[0])) {\n const since = last.get(kind);\n if (since !== undefined && at - since < span[kind]) continue;\n last.set(kind, at);\n out.push({ kind, at });\n }\n return out;\n}\n\nexport type SummaryInput = { range: UsageRange; now: number; titles: Titles; statsCache?: StatsCache | undefined };\n\n/** Lets the server answer other requests between parts of a long piece of work. */\nconst breather = () => new Promise<void>((resolve) => setImmediate(resolve));\n\n/** Summaries worked out from records that have not changed since, for half a minute (titles can change). */\nconst summaries = new Map<string, { at: number; summary: UsageSummary }>();\nlet ownVersion = 0;\n\n/** Everything the page shows for a period, from what has been read so far. */\nexport async function summarize(input: SummaryInput): Promise<UsageSummary> {\n const key = `${version}:${ownVersion}:${input.range}:${utcDay(input.now)}:${input.statsCache?.through ?? '-'}`;\n const known = summaries.get(key);\n if (known && input.now - known.at < 30_000) return { ...known.summary, progress: usageProgress() };\n const summary = await workOut(input);\n if (summaries.size > 8) summaries.clear();\n summaries.set(key, { at: input.now, summary });\n return summary;\n}\n\nasync function workOut({ range, now, titles, statsCache: cache }: SummaryInput): Promise<UsageSummary> {\n const { order, skip } = owners();\n const mine = await ownRecord();\n // As /stats does, Claude Code's own record counts for everything; the last 7 or 30 days come from the transcripts.\n const statsCache = range === 'all' ? cache : undefined;\n const mainOf = new Map<string, FileRecord>();\n for (const r of order) if (!r.sub && (!mainOf.has(r.session) || (r.last ?? 0) > (mainOf.get(r.session)!.last ?? 0))) mainOf.set(r.session, r);\n let firstData: number | undefined;\n for (const r of order) {\n if (r.minutes[0] !== undefined) firstData = Math.min(firstData ?? Infinity, utcDay(r.minutes[0] * MINUTE));\n if (r.days[0] !== undefined) firstData = Math.min(firstData ?? Infinity, r.days[0]);\n }\n let firstKnown = firstData ?? Infinity;\n if (statsCache?.first !== undefined) firstKnown = Math.min(firstKnown, statsCache.first);\n for (const day of statsCache?.days.keys() ?? []) firstKnown = Math.min(firstKnown, day);\n const { from, to } = period(range, now, Number.isFinite(firstKnown) ? firstKnown : undefined);\n const fromMs = from * DAY;\n const toMs = (to + 1) * DAY;\n const prices = pricesFrom(order);\n\n const tokens = noTokens();\n const byDay = new Map<number, number>();\n const byModel = new Map<string, number>();\n const bySession = new Map<string, { tokens: number; at: number; apps: Map<AppName, number> }>();\n const byProject = new Map<string, { tokens: number; sessions: Set<string> }>();\n const byApp = new Map<AppName, { tokens: number; sessions: Set<string> }>();\n let usd = 0;\n const unpriced = new Set<string>();\n let firstTokens: number | undefined;\n\n let work = 0;\n for (const r of order) {\n // A home with a million replies takes a while to add up: other requests go on meanwhile.\n work += r.keys.length;\n if (work > 50_000) {\n work = 0;\n await breather();\n }\n const mask = skip.get(r);\n const pelican = r.session in mine.sessions;\n const cwd = projectOfFolder(mainOf.get(r.session)?.cwd ?? r.cwd ?? r.dir);\n for (let j = 0; j < r.keys.length; j += 1) {\n if (mask?.[j]) continue;\n const at = r.minutes[j]! * MINUTE;\n if (at < fromMs || at >= toMs) continue;\n const t = j * FIELDS;\n add(tokens, r.tokens, t);\n const total = r.tokens[t]! + r.tokens[t + 1]! + r.tokens[t + 2]! + r.tokens[t + 3]!;\n const day = utcDay(at);\n firstTokens = Math.min(firstTokens ?? day, day);\n byDay.set(day, (byDay.get(day) ?? 0) + total);\n const model = r.models[r.model[j]!] ?? 'unknown';\n byModel.set(model, (byModel.get(model) ?? 0) + total);\n const app = appOf(r.apps[r.app[j]!], pelican);\n const session = bySession.get(r.session) ?? { tokens: 0, at: 0, apps: new Map() };\n session.tokens += total;\n session.at = Math.max(session.at, at);\n session.apps.set(app, (session.apps.get(app) ?? 0) + total);\n bySession.set(r.session, session);\n const project = byProject.get(cwd) ?? { tokens: 0, sessions: new Set() };\n project.tokens += total;\n project.sessions.add(r.session);\n byProject.set(cwd, project);\n const used = byApp.get(app) ?? { tokens: 0, sessions: new Set() };\n used.tokens += total;\n used.sessions.add(r.session);\n byApp.set(app, used);\n const price = prices.get(model);\n if (price === undefined) unpriced.add(r.session);\n else usd += priceOf(price, r.tokens, t);\n }\n }\n\n // Activity, as /stats counts it: a session (not a subagent's) counts on the day it started, and\n // lasts from its first row to its last; a day is active when any session has a row on it. For the\n // days Claude Code's own record counted, its figures win over the transcripts.\n const counted = (day: number) => !statsCache || day > statsCache.through;\n const active = new Set<number>();\n let sessionCount = 0;\n let longest: { id: string; ms: number; at: number } | undefined;\n for (const [id, r] of mainOf) {\n for (const day of r.days) if (day >= from && day <= to && counted(day)) active.add(day);\n if (r.first === undefined || r.last === undefined) continue;\n const started = utcDay(r.first);\n if (started < from || started > to || !counted(started)) continue;\n sessionCount += 1;\n if (!longest || r.last - r.first > longest.ms) longest = { id, ms: r.last - r.first, at: r.first };\n }\n if (statsCache) {\n for (const [day, entry] of statsCache.days) {\n if (day < from || day > to) continue;\n sessionCount += entry.sessions;\n if (entry.active) active.add(day);\n }\n const theirs = statsCache.longest;\n if (theirs && (!longest || theirs.ms > longest.ms)) longest = theirs;\n }\n const { current, longest: longestStreak } = streaks(active, from, to);\n\n // Limits, compactions and waits in the period.\n const hits: Array<[number, LimitKind]> = [];\n const compactions = new Map<string, number>();\n for (const r of order) {\n for (const hit of r.limits) if (hit[0] >= fromMs && hit[0] < toMs) hits.push(hit);\n if (r.sub) continue;\n const times = r.compactions.filter((t) => t >= fromMs && t < toMs).length;\n if (times > 0) compactions.set(r.session, (compactions.get(r.session) ?? 0) + times);\n }\n const waits = mine.waits.filter(([, since]) => since >= fromMs && since < toMs);\n\n const sessionsShown = [...bySession].sort((a, b) => b[1].tokens - a[1].tokens).slice(0, 20);\n const compacted = [...compactions].filter(([, times]) => times >= 3).sort((a, b) => b[1] - a[1]).slice(0, 5);\n const named = await titles([...new Set([...sessionsShown.map(([id]) => id), ...compacted.map(([id]) => id), ...(longest ? [longest.id] : [])])]);\n const title = (id: string) => named.get(id)?.title ?? 'Untitled session';\n const projectOf = (id: string) => named.get(id)?.project || projectName(mainOf.get(id)?.cwd ?? '');\n\n // Two folders with the same name are told apart by their parent, as the new-session picker does.\n const names = new Map<string, number>();\n for (const cwd of byProject.keys()) names.set(projectName(cwd), (names.get(projectName(cwd)) ?? 0) + 1);\n const nameOf = (cwd: string) => (cwd === SCRATCH ? 'Scratch' : cwd === TEMP ? 'Temporary folders'\n : (names.get(projectName(cwd)) ?? 0) > 1 ? `${path.basename(path.dirname(cwd))}/${projectName(cwd)}` : projectName(cwd));\n\n // Everything: the chart starts where the transcripts do (Claude Code's own record has no tokens per kind).\n const chartFrom = range === 'all' && firstTokens !== undefined ? Math.max(from, firstTokens) : from;\n const long = to - chartFrom + 1 > 45;\n const points = new Map<number, number>();\n for (let d = chartFrom; d <= to; d += 1) {\n // Weeks start on Monday (day 0, 1 January 1970, was a Thursday).\n const key = long ? d - ((d + 3) % 7) : d;\n points.set(key, (points.get(key) ?? 0) + (byDay.get(d) ?? 0));\n }\n\n const summary: UsageSummary = {\n range,\n from: dayString(from),\n to: dayString(to),\n tokens,\n ...(range === 'all' && firstTokens !== undefined && firstTokens > from ? { tokensSince: dayString(firstTokens) } : {}),\n series: { unit: long ? 'week' : 'day', points: [...points].map(([day, value]) => ({ day: dayString(day), tokens: value })) },\n models: [...byModel].sort((a, b) => b[1] - a[1]).map(([model, value]) => ({ model, name: modelName(model), tokens: value })),\n projects: [...byProject].sort((a, b) => b[1].tokens - a[1].tokens).slice(0, 30)\n .map(([cwd, p]) => ({ cwd, name: nameOf(cwd), tokens: p.tokens, sessions: p.sessions.size })),\n apps: [...byApp].sort((a, b) => b[1].tokens - a[1].tokens).map(([app, a]) => ({ app, tokens: a.tokens, sessions: a.sessions.size })),\n sessions: sessionsShown.map(([id, s]): UsageSession => ({\n id, title: title(id), project: projectOf(id), app: [...s.apps].sort((a, b) => b[1] - a[1])[0]?.[0] ?? 'Other', tokens: s.tokens, at: s.at,\n })),\n activity: {\n sessions: sessionCount,\n activeDays: active.size,\n days: to - from + 1,\n currentStreak: current,\n longestStreak,\n // A session whose transcript is gone (Claude Code's own record) has no title, only its day.\n ...(longest && longest.ms > 0 ? { longest: { id: longest.id, ms: longest.ms, at: longest.at, ...(named.has(longest.id) ? { title: title(longest.id) } : {}) } } : {}),\n ...(range === 'all' && statsCache?.first !== undefined && firstData !== undefined && statsCache.first < firstData ? { since: dayString(statsCache.first) } : {}),\n },\n limits: distinctLimits(hits),\n compacted: compacted.map(([id, times]) => ({ id, title: title(id), times })),\n ...(waits.length > 0 ? {\n waits: {\n ms: waits.reduce((sum, [, since, until]) => sum + (until - since), 0),\n count: waits.length,\n longest: Math.max(...waits.map(([, since, until]) => until - since)),\n },\n } : {}),\n ...(prices.size > 0 && tokenTotal(tokens) > 0 ? { cost: { usd, without: unpriced.size } } : {}),\n progress: usageProgress(),\n };\n return summary;\n}\n\n/** One session's usage, from its own transcript and its subagents', read now if they changed. */\nexport async function sessionUsage(sessionId: string, files: Found[]): Promise<SessionUsage | undefined> {\n await load();\n const mine = (await Promise.all(files.map((f) => readLocked(f)))).filter((r): r is FileRecord => Boolean(r));\n if (mine.length === 0) return undefined;\n // Which of its replies were copied from another session is known once every transcript was read.\n const skip = scannedOnce ? owners().skip : new Map<FileRecord, Uint8Array>();\n const prices = pricesFrom(records.values());\n const tokens = noTokens();\n const byModel = new Map<string, number>();\n let usd = 0;\n let priced = true;\n let compactions = 0;\n for (const r of mine) {\n const mask = skip.get(r);\n for (let j = 0; j < r.keys.length; j += 1) {\n if (mask?.[j]) continue;\n const t = j * FIELDS;\n add(tokens, r.tokens, t);\n const model = r.models[r.model[j]!] ?? 'unknown';\n byModel.set(model, (byModel.get(model) ?? 0) + r.tokens[t]! + r.tokens[t + 1]! + r.tokens[t + 2]! + r.tokens[t + 3]!);\n const price = prices.get(model);\n if (price === undefined) priced = false;\n else usd += priceOf(price, r.tokens, t);\n }\n if (!r.sub) compactions += r.compactions.length;\n }\n const waits = (await ownRecord()).waits.filter(([id]) => id === sessionId);\n return {\n tokens,\n models: [...byModel].sort((a, b) => b[1] - a[1]).map(([model, value]) => ({ model, name: modelName(model), tokens: value })),\n compactions,\n ...(waits.length > 0 ? { waits: { ms: waits.reduce((sum, [, since, until]) => sum + (until - since), 0), count: waits.length } } : {}),\n ...(priced && prices.size > 0 && tokenTotal(tokens) > 0 ? { cost: { usd } } : {}),\n };\n}\n\n/** A session's transcripts: its own (the one the session list shows) and its subagents'. */\nexport async function sessionFiles(sessionId: string, main: string): Promise<Found[]> {\n if (!SESSION_DIR.test(sessionId)) return [];\n const dir = path.basename(path.dirname(main));\n const found: Found[] = [{ file: main, dir, session: sessionId, sub: false }];\n await subagentFiles(path.join(path.dirname(main), sessionId, 'subagents'), dir, sessionId, found);\n return found;\n}\n\n/** Forgets everything read (tests). */\nexport function resetUsage(): void {\n records.clear();\n loaded = undefined;\n own = undefined;\n ownChanged = false;\n summaries.clear();\n ownership = undefined;\n waitingSince.clear();\n scannedOnce = false;\n scannedAt = 0;\n progress.files = 0;\n progress.read = 0;\n dirty.clear();\n clearTimeout(saveTimer);\n saveTimer = undefined;\n clearTimeout(ownTimer);\n ownTimer = undefined;\n version += 1;\n}\n", "import { createHash } from 'node:crypto';\nimport { realpath, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { Block, ChatMessage, ToolResultBlock, ToolUseBlock, Workflow, WorkflowAgent, WorkflowAgentPage, WorkflowPhase, WorkflowStatus } from '../shared/protocol.js';\nimport { addPhase, agentTokens, launchOf, parseMeta, parseTaskNotice, RUN_ID, type TaskNotice, unframedPrompt, workflowOf } from '../shared/workflows.js';\nimport { readHistory } from './history.js';\nimport { liveProcesses } from './live.js';\nimport { openRegular } from './open.js';\nimport { loadMessages } from './sessions.js';\nimport { transcriptPath } from './transcripts.js';\n\n/**\n * Workflows as Claude Code leaves them on disk, beside a session's transcript, in the session's own\n * folder (`<project>/<session id>/`):\n * - `workflows/<run id>.json`: its record, written once the run ends (what the CLI's /workflows reads);\n * - `subagents/workflows/<run id>/journal.jsonl`: each agent started, and its result, as it goes;\n * - `subagents/workflows/<run id>/agent-<id>.jsonl` and `.meta.json`: each agent's own transcript;\n * - `workflows/scripts/<name>-<run id>.js`: the script it ran.\n * Only those names are read, each checked to be a regular file whose real path is inside that\n * folder, and within a size: nothing else on the computer can be reached through them.\n */\n\nconst SESSION = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n/** A tool call's id, as the transcript holds it (`toolu_\u2026`); only ever looked up there. */\nexport const CALL_ID = /^[\\w-]{1,128}$/;\n/** An agent's id, as Claude Code names its transcript `agent-<id>.jsonl`. */\nexport const AGENT_ID = /^[\\w-]{1,80}$/;\n\nconst RECORD_MAX = 8 * 1024 * 1024;\nconst META_FILE_MAX = 64 * 1024;\nconst SCRIPT_MAX = 256 * 1024;\nconst JOURNAL_MAX = 64 * 1024 * 1024;\nconst RESULT_MAX = 16 * 1024;\nconst PROMPT_MAX = 8 * 1024;\nconst SCRIPT_SHOWN_MAX = 64 * 1024;\n/** An agent that wrote this recently is at work. */\nconst ACTIVE_MS = 60_000;\n/**\n * Longer than Claude Code lets a workflow's agents go silent: it gives up on one after ten minutes\n * without progress (more with a tool at work) and starts it again, and the new one writes.\n */\nconst QUIET_MS = 20 * 60_000;\n/** Agents' transcripts read at once, at most, a little at a time: a run can have dozens of large ones. */\nconst READERS = 3;\nconst CHUNK = 1024 * 1024;\n\nconst str = (value: unknown) => (typeof value === 'string' && value ? value : undefined);\nconst num = (value: unknown) => (typeof value === 'number' && Number.isFinite(value) ? value : undefined);\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\nconst clip = (text: string, max: number) => (text.length > max ? `${text.slice(0, max)}\\n\u2026` : text);\nconst cut = (value: unknown, max: number) => (typeof value === 'string' && value ? (value.length > max ? `${value.slice(0, max - 1)}\u2026` : value) : undefined);\n\n/**\n * A long result cut where a line ends, saying how much was left out, as Claude Code cuts the one it\n * hands Claude: JSON cut there stays readable as JSON, line by line.\n */\nfunction clipLines(text: string, max: number): string {\n if (text.length <= max) return text;\n const at = text.lastIndexOf('\\n', max);\n const end = at > max / 2 ? at : max;\n return `${text.slice(0, end)}\\n... (truncated ${text.length - end} chars)`;\n}\n\n/** What a run or an agent returned, as text: a string as it is, a value as JSON, laid out. */\nfunction resultText(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return text ? clipLines(text, RESULT_MAX) : undefined;\n}\n\n/**\n * One read at a time per file, for the readers below that carry on from where the last one\n * stopped: two pages asking at once (a phone and a computer, a run and one of its agents) would\n * otherwise both read the same new bytes and both count them.\n */\nconst reading = new Map<string, Promise<unknown>>();\nfunction oneAtATime<T>(file: string, read: () => Promise<T>): Promise<T> {\n const previous = reading.get(file) ?? Promise.resolve();\n const next = previous.catch(() => undefined).then(read);\n reading.set(file, next);\n void next.finally(() => {\n if (reading.get(file) === next) reading.delete(file);\n }).catch(() => undefined);\n return next;\n}\n\n/** `fn` over `items`, `limit` at a time, the results in order. */\nasync function inTurn<T, R>(items: T[], limit: number, fn: (item: T, i: number) => Promise<R>): Promise<R[]> {\n const out = new Array<R>(items.length);\n let next = 0;\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, async () => {\n while (next < items.length) {\n const i = next;\n next += 1;\n out[i] = await fn(items[i]!, i);\n }\n }));\n return out;\n}\n\n// ---- Files inside the session's folder ---------------------------------------------------------\n\ntype Where = { dir: string; file: string };\n\n/** The session's own folder, next to its transcript: where Claude Code keeps its workflows. */\nasync function sessionDir(sessionId: string): Promise<Where | undefined> {\n if (!SESSION.test(sessionId)) return undefined;\n const file = await transcriptPath(sessionId);\n return file ? { file, dir: path.join(path.dirname(file), sessionId) } : undefined;\n}\n\n/** `file`'s real path, when that is inside the session's folder (links followed and checked). */\nasync function inside(dir: string, file: string): Promise<string | undefined> {\n try {\n const [root, real] = await Promise.all([realpath(dir), realpath(file)]);\n return real.startsWith(`${root}${path.sep}`) ? real : undefined;\n } catch {\n return undefined;\n }\n}\n\ntype Read = { text: string; mtimeMs: number; size: number };\n\n/** A regular file inside the session's folder, whole when it is no larger than `max`; else its first `max` bytes if `head`. */\nasync function readInside(dir: string, file: string, max: number, head = false): Promise<Read | undefined> {\n const real = await inside(dir, file);\n if (!real) return undefined;\n const handle = await openRegular(real).catch(() => undefined);\n if (!handle) return undefined;\n try {\n const info = await handle.stat();\n if (info.size > max && !head) return undefined;\n const buffer = Buffer.alloc(Math.min(info.size, max));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);\n return { text: buffer.toString('utf8', 0, bytesRead), mtimeMs: info.mtimeMs, size: info.size };\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n}\n\n/** Kept reads of small files that change seldom (records, meta files), by path, while unchanged. */\nconst kept = new Map<string, { mtimeMs: number; size: number; value: unknown }>();\n\nasync function cachedJson<T>(dir: string, file: string, max: number, shape: (value: unknown) => T | undefined): Promise<T | undefined> {\n const info = await stat(file).catch(() => undefined);\n if (!info?.isFile()) return undefined;\n const known = kept.get(file);\n if (known && known.mtimeMs === info.mtimeMs && known.size === info.size) return known.value as T | undefined;\n const read = await readInside(dir, file, max);\n let value: T | undefined;\n try {\n value = read ? shape(JSON.parse(read.text)) : undefined;\n } catch {\n value = undefined;\n }\n // A record being written is read again once it is whole.\n if (read) remember(kept, file, { mtimeMs: read.mtimeMs, size: read.size, value }, 256);\n return value;\n}\n\nfunction remember<K, V>(map: Map<K, V>, key: K, value: V, max: number): void {\n map.delete(key);\n map.set(key, value);\n while (map.size > max) map.delete(map.keys().next().value as K);\n}\n\n/** Each line of `data` that a newline ends, as text, cut on bytes: a character split across reads comes out whole. */\nfunction lines(data: Buffer, each: (line: string) => void): Buffer {\n const last = data.lastIndexOf(0x0a);\n if (last < 0) return Buffer.from(data);\n for (const line of data.toString('utf8', 0, last).split('\\n')) each(line);\n return Buffer.from(data.subarray(last + 1));\n}\n\n// ---- The run's record ------------------------------------------------------------------------\n\ntype RunRecord = {\n taskId?: string;\n name?: string;\n summary?: string;\n status: WorkflowStatus;\n startTime?: number;\n durationMs?: number;\n totalTokens?: number;\n totalToolCalls?: number;\n phases: WorkflowPhase[];\n items: unknown[];\n error?: string;\n result?: string;\n script?: string;\n};\n\nfunction recordOf(value: unknown): RunRecord | undefined {\n if (!isRecord(value)) return undefined;\n const status = value.status === 'completed' || value.status === 'failed' || value.status === 'killed' ? value.status : undefined;\n if (!status) return undefined;\n const phases = (Array.isArray(value.phases) ? value.phases : []).filter(isRecord).flatMap((p): WorkflowPhase[] => {\n const title = cut(p.title, 120);\n const detail = cut(p.detail, 400);\n return title ? [{ title, ...(detail ? { detail } : {}) }] : [];\n });\n const error = typeof value.error === 'string' ? value.error : isRecord(value.error) ? str(value.error.message) : undefined;\n return {\n ...(str(value.taskId) ? { taskId: str(value.taskId)! } : {}),\n ...(cut(value.workflowName, 200) ? { name: cut(value.workflowName, 200)! } : {}),\n ...(cut(value.summary, 2000) ? { summary: cut(value.summary, 2000)! } : {}),\n status,\n ...(num(value.startTime) !== undefined ? { startTime: num(value.startTime)! } : {}),\n ...(num(value.durationMs) !== undefined ? { durationMs: num(value.durationMs)! } : {}),\n ...(num(value.totalTokens) !== undefined ? { totalTokens: num(value.totalTokens)! } : {}),\n ...(num(value.totalToolCalls) !== undefined ? { totalToolCalls: num(value.totalToolCalls)! } : {}),\n phases,\n items: Array.isArray(value.workflowProgress) ? value.workflowProgress : [],\n ...(error ? { error: clip(error, 4000) } : {}),\n ...(resultText(value.result) ? { result: resultText(value.result)! } : {}),\n ...(str(value.script) ? { script: clip(str(value.script)!, SCRIPT_SHOWN_MAX) } : {}),\n };\n}\n\nconst recordFile = (dir: string, runId: string) => path.join(dir, 'workflows', `${runId}.json`);\n\n// ---- Progress items, as Claude Code reports them ---------------------------------------------\n\n/** A `workflow_agent` item, its long texts cut. */\nexport function agentItem(item: unknown): WorkflowAgent | undefined {\n if (!isRecord(item) || item.type !== 'workflow_agent') return undefined;\n const index = num(item.index);\n const state = item.state;\n if (index === undefined || (state !== 'start' && state !== 'progress' && state !== 'done' && state !== 'error')) return undefined;\n const out: WorkflowAgent = { index, label: cut(item.label, 200) ?? `Agent ${index}`, state };\n for (const key of ['phaseIndex', 'tokens', 'toolCalls', 'durationMs', 'queuedAt', 'startedAt', 'lastProgressAt', 'attempt'] as const) {\n const value = num(item[key]);\n if (value !== undefined) out[key] = value;\n }\n for (const key of ['phaseTitle', 'agentId', 'agentType', 'model', 'fallbackModel', 'lastToolName'] as const) {\n const value = cut(item[key], 120);\n if (value) out[key] = value;\n }\n const texts: Array<[keyof WorkflowAgent, number]> = [['error', 600], ['lastToolSummary', 160], ['resultPreview', 400], ['promptPreview', 400]];\n for (const [key, max] of texts) {\n const value = cut(item[key], max);\n if (value) (out as Record<string, unknown>)[key] = value;\n }\n if (item.isolation === 'worktree' || item.isolation === 'remote') out.isolation = item.isolation;\n if (item.lastAttemptReason === 'stalled' || item.lastAttemptReason === 'throttled' || item.lastAttemptReason === 'user-retry') out.lastAttemptReason = item.lastAttemptReason;\n for (const key of ['skipped', 'blocked', 'cached'] as const) if (item[key] === true) out[key] = true;\n return out;\n}\n\n/** Phases as the run lists them (`workflow_phase` items), after the script's own. */\nfunction withPhases(phases: WorkflowPhase[], items: unknown[]): WorkflowPhase[] {\n const out = [...phases];\n for (const item of items) {\n if (!isRecord(item) || item.type !== 'workflow_phase') continue;\n const title = cut(item.title, 120);\n if (title) addPhase(out, title);\n }\n return out;\n}\n\n// ---- The journal ------------------------------------------------------------------------------\n\n/** An agent as the journal tells it: started, done with a result, or failed; the latest line wins. */\ntype JournalAgent = { key: string; agentId?: string; label?: string; phase?: string; state: 'started' | 'done' | 'failed'; result?: string };\n\ntype Journal = { ino: number; offset: number; carry: Buffer; agents: Map<string, JournalAgent> };\n\nconst journals = new Map<string, Journal>();\n\n/** One journal line. A line cut short (Claude Code was stopped mid-write) or of another kind is passed over, as Claude Code does. */\nfunction journalLine(agents: Map<string, JournalAgent>, line: string): void {\n if (!line.trim()) return;\n let event: Record<string, unknown>;\n try {\n const parsed: unknown = JSON.parse(line);\n if (!isRecord(parsed)) return;\n event = parsed;\n } catch {\n return;\n }\n const key = str(event.key);\n if (!key || key.length > 200) return;\n const known = agents.get(key);\n const agentId = cut(event.agentId, 80) ?? known?.agentId;\n // The script names them: as long as it likes, in the journal; as long as the record has them, here.\n const label = (event.type === 'started' ? cut(event.label, 200) : undefined) ?? known?.label;\n const phase = (event.type === 'started' ? cut(event.phase, 120) : undefined) ?? known?.phase;\n const base = { key, ...(agentId ? { agentId } : {}), ...(label ? { label } : {}), ...(phase ? { phase } : {}) };\n if (event.type === 'started') {\n agents.set(key, { ...base, state: 'started' });\n } else if (event.type === 'result') {\n const result = resultText(event.result);\n agents.set(key, { ...base, state: 'done', ...(result ? { result } : {}) });\n } else if (event.type === 'failed') {\n agents.set(key, { ...base, state: 'failed' });\n }\n}\n\n/** The run's journal, read once and then only by what was added to it. */\nasync function readJournal(dir: string, runId: string): Promise<JournalAgent[] | undefined> {\n const file = path.join(dir, 'subagents', 'workflows', runId, 'journal.jsonl');\n const real = await inside(dir, file);\n if (!real) return undefined;\n return oneAtATime(real, async () => {\n const handle = await openRegular(real).catch(() => undefined);\n if (!handle) return undefined;\n try {\n const info = await handle.stat();\n let journal = journals.get(real);\n if (!journal || journal.ino !== info.ino || info.size < journal.offset) journal = { ino: info.ino, offset: 0, carry: Buffer.alloc(0), agents: new Map() };\n const end = Math.min(info.size, JOURNAL_MAX);\n while (journal.offset < end) {\n const buffer = Buffer.allocUnsafe(Math.min(4 * CHUNK, end - journal.offset));\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, journal.offset);\n if (bytesRead <= 0) break;\n const data = journal.carry.length > 0 ? Buffer.concat([journal.carry, buffer.subarray(0, bytesRead)]) : buffer.subarray(0, bytesRead);\n // The offset moves with the line it may leave unfinished: a read that fails part way carries on from there.\n const agents = journal.agents;\n journal.carry = lines(data, (line) => journalLine(agents, line));\n journal.offset += bytesRead;\n }\n remember(journals, real, journal, 64);\n // A last line without its newline yet counts if it is whole; it is read again with the rest.\n const agents = new Map(journal.agents);\n if (journal.carry.length > 0) journalLine(agents, journal.carry.toString('utf8'));\n return [...agents.values()];\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n });\n}\n\n// ---- Agents' own files ------------------------------------------------------------------------\n\ntype AgentMeta = { agentType?: string; label?: string; phase?: string; model?: string };\n\nfunction agentMetaOf(value: unknown): AgentMeta | undefined {\n if (!isRecord(value)) return undefined;\n const agentType = cut(value.agentType, 120);\n const label = cut(value.description, 200);\n const phase = cut(value.workflowPhase, 120);\n const model = cut(value.pickedEffortModel, 120);\n return { ...(agentType ? { agentType } : {}), ...(label ? { label } : {}), ...(phase ? { phase } : {}), ...(model ? { model } : {}) };\n}\n\n/**\n * What an agent's transcript says of it, without keeping it: when it started and last wrote, its\n * model, its tool calls, its last tool, and its context at its latest response (Claude Code's\n * \"tokens\"). Read once, then only by what was added, a little at a time.\n */\ntype AgentStats = {\n ino: number;\n offset: number;\n /** The start of a line not finished yet; of one too long to keep, its first bytes and its last. */\n carry: Buffer;\n long?: { head: Buffer; tail: Buffer };\n startedAt?: number;\n lastAt?: number;\n model?: string;\n tokens?: number;\n toolCalls: number;\n lastTool?: string;\n};\n\nconst stats = new Map<string, AgentStats>();\nconst ASSISTANT = /\"type\":\\s*\"assistant\"/;\nconst TIMESTAMP = /\"timestamp\":\\s*\"([^\"]{10,40})\"/;\n/** A row longer than this (a copy of an API request, a huge tool output) is only looked at for its time. */\nconst LINE_MAX = 2 * 1024 * 1024;\nconst TAIL = 4096;\nconst ROW = Buffer.from('{\"parentUuid\"');\n\nfunction noteTime(agent: AgentStats, text: string): void {\n const time = TIMESTAMP.exec(text)?.[1];\n const at = time ? Date.parse(time) : NaN;\n if (Number.isNaN(at)) return;\n agent.startedAt ??= at;\n agent.lastAt = at;\n}\n\nfunction statLine(agent: AgentStats, line: string): void {\n // Rows of the conversation only: copies of API requests repeat it, and are no part of it.\n if (!line.startsWith('{\"parentUuid\"')) return;\n noteTime(agent, line.length > TAIL ? line.slice(-TAIL) : line);\n if (!ASSISTANT.test(line)) return;\n let row: { type?: unknown; message?: { model?: unknown; content?: unknown; usage?: Record<string, unknown> } };\n try {\n row = JSON.parse(line) as typeof row;\n } catch {\n return;\n }\n if (row.type !== 'assistant') return;\n const model = str(row.message?.model);\n if (model && !model.startsWith('<')) agent.model = model;\n const usage = row.message?.usage;\n if (usage) {\n const total = ['input_tokens', 'cache_creation_input_tokens', 'cache_read_input_tokens', 'output_tokens'].reduce((sum, key) => sum + (num(usage[key]) ?? 0), 0);\n if (total > 0) agent.tokens = total;\n }\n if (Array.isArray(row.message?.content)) {\n for (const block of row.message.content) {\n if (isRecord(block) && block.type === 'tool_use') {\n agent.toolCalls += 1;\n if (str(block.name)) agent.lastTool = cut(block.name, 120);\n }\n }\n }\n}\n\n/** The end of a line: read it, or for one too long, only its time. */\nfunction endLine(agent: AgentStats, piece: Buffer): void {\n if (agent.long) {\n const { head } = agent.long;\n const tail = Buffer.concat([agent.long.tail, piece]).subarray(-TAIL);\n agent.long = undefined;\n if (head.subarray(0, ROW.length).equals(ROW)) noteTime(agent, tail.toString('utf8'));\n return;\n }\n const line = agent.carry.length > 0 ? Buffer.concat([agent.carry, piece]) : piece;\n agent.carry = Buffer.alloc(0);\n if (line.length > LINE_MAX) {\n if (line.subarray(0, ROW.length).equals(ROW)) noteTime(agent, line.subarray(-TAIL).toString('utf8'));\n return;\n }\n statLine(agent, line.toString('utf8'));\n}\n\n/** A line goes on past this read: kept, or of one too long, only its ends. */\nfunction carryOn(agent: AgentStats, piece: Buffer): void {\n if (agent.long) {\n agent.long.tail = Buffer.from(Buffer.concat([agent.long.tail, piece]).subarray(-TAIL));\n return;\n }\n agent.carry = Buffer.concat([agent.carry, piece]);\n if (agent.carry.length > LINE_MAX) {\n agent.long = { head: Buffer.from(agent.carry.subarray(0, ROW.length)), tail: Buffer.from(agent.carry.subarray(-TAIL)) };\n agent.carry = Buffer.alloc(0);\n }\n}\n\nfunction agentStats(real: string): Promise<AgentStats | undefined> {\n return oneAtATime(real, async () => {\n const handle = await openRegular(real).catch(() => undefined);\n if (!handle) return undefined;\n try {\n const info = await handle.stat();\n let agent = stats.get(real);\n if (!agent || agent.ino !== info.ino || info.size < agent.offset) agent = { ino: info.ino, offset: 0, carry: Buffer.alloc(0), toolCalls: 0 };\n const buffer = Buffer.allocUnsafe(Math.min(CHUNK, Math.max(1, info.size - agent.offset)));\n while (agent.offset < info.size) {\n const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, info.size - agent.offset), agent.offset);\n if (bytesRead <= 0) break;\n agent.offset += bytesRead;\n const chunk = buffer.subarray(0, bytesRead);\n for (let from = 0; ;) {\n const end = chunk.indexOf(0x0a, from);\n if (end < 0) {\n if (from < chunk.length) carryOn(agent, chunk.subarray(from));\n break;\n }\n endLine(agent, chunk.subarray(from, end));\n from = end + 1;\n }\n }\n remember(stats, real, agent, 512);\n return agent;\n } catch {\n return undefined;\n } finally {\n await handle.close();\n }\n });\n}\n\n/** An agent's figures over its files: its tool calls in all of them, its latest response's in the newest. */\ntype Seen = { startedAt?: number; lastAt?: number; model?: string; tokens?: number; toolCalls: number; lastTool?: string };\n\nfunction together(parts: AgentStats[]): Seen | undefined {\n if (parts.length === 0) return undefined;\n if (parts.length === 1) return parts[0];\n const newest = parts.reduce((a, b) => ((b.lastAt ?? 0) > (a.lastAt ?? 0) ? b : a));\n const times = (pick: (s: AgentStats) => number | undefined) => parts.map(pick).filter((t): t is number => t !== undefined);\n const started = times((s) => s.startedAt);\n const last = times((s) => s.lastAt);\n const model = newest.model ?? parts.find((s) => s.model)?.model;\n const tokens = newest.tokens ?? parts.find((s) => s.tokens)?.tokens;\n const lastTool = newest.lastTool ?? parts.find((s) => s.lastTool)?.lastTool;\n return {\n ...(started.length > 0 ? { startedAt: Math.min(...started) } : {}),\n ...(last.length > 0 ? { lastAt: Math.max(...last) } : {}),\n ...(model ? { model } : {}),\n ...(tokens ? { tokens } : {}),\n toolCalls: parts.reduce((sum, s) => sum + s.toolCalls, 0),\n ...(lastTool ? { lastTool } : {}),\n };\n}\n\n/**\n * An agent's transcript: in its run's folder, and (after an interrupt, Claude Code sometimes goes\n * on there) beside the session's other subagents, where the rest of it is: both, in that order.\n */\nasync function agentFiles(dir: string, runId: string, agentId: string): Promise<string[]> {\n if (!AGENT_ID.test(agentId)) return [];\n const found = await Promise.all([\n inside(dir, path.join(dir, 'subagents', 'workflows', runId, `agent-${agentId}.jsonl`)),\n inside(dir, path.join(dir, 'subagents', `agent-${agentId}.jsonl`)),\n ]);\n return [...new Set(found.filter((f): f is string => Boolean(f)))];\n}\n\n/**\n * The journal's agents, with what each one's own files say. For a call that resumed the run\n * (`since`: when it was made), only the agents at work since: the journal also holds those of the\n * attempts before it, which it did not run again.\n */\nasync function journalAgents(dir: string, runId: string, since?: number): Promise<WorkflowAgent[]> {\n const entries = (await readJournal(dir, runId)) ?? [];\n const agents = await inTurn(entries, READERS, async (entry): Promise<WorkflowAgent | undefined> => {\n const meta = entry.agentId\n ? await cachedJson(dir, path.join(dir, 'subagents', 'workflows', runId, `agent-${entry.agentId}.meta.json`), META_FILE_MAX, agentMetaOf)\n : undefined;\n const files = entry.agentId ? await agentFiles(dir, runId, entry.agentId) : [];\n const parts: AgentStats[] = [];\n for (const file of files) {\n const seen = await agentStats(file);\n if (seen) parts.push(seen);\n }\n const seen = together(parts);\n // An agent an earlier attempt ran, not run again by this call.\n if (since !== undefined && seen?.lastAt !== undefined && seen.lastAt < since) return undefined;\n const label = entry.label ?? meta?.label;\n const phase = entry.phase ?? meta?.phase;\n const model = cut(seen?.model, 120) ?? meta?.model;\n const done = entry.state === 'done';\n return {\n index: 0,\n label: label ?? '',\n state: done ? 'done' : entry.state === 'failed' ? 'error' : 'progress',\n ...(phase ? { phaseTitle: phase } : {}),\n ...(entry.agentId ? { agentId: entry.agentId } : {}),\n ...(meta?.agentType && meta.agentType !== 'workflow-subagent' ? { agentType: meta.agentType } : {}),\n ...(model ? { model } : {}),\n ...(seen?.tokens ? { tokens: seen.tokens } : {}),\n ...(seen && seen.toolCalls > 0 ? { toolCalls: seen.toolCalls } : {}),\n ...(seen?.lastTool ? { lastToolName: seen.lastTool } : {}),\n ...(seen?.startedAt !== undefined ? { startedAt: seen.startedAt } : {}),\n ...(seen?.lastAt !== undefined ? { lastProgressAt: seen.lastAt } : {}),\n ...(done && seen?.startedAt !== undefined && seen.lastAt !== undefined ? { durationMs: Math.max(0, seen.lastAt - seen.startedAt) } : {}),\n ...(done && entry.result ? { resultPreview: cut(entry.result.replace(/\\s+/g, ' ').trim(), 400)! } : {}),\n };\n });\n return agents.filter((a): a is WorkflowAgent => Boolean(a)).map((agent, i) => ({ ...agent, index: i + 1, label: agent.label || `Agent ${i + 1}` }));\n}\n\n// ---- The Workflow call, in the conversation -----------------------------------------------------\n\n/** A notice of a run's end, with when Claude Code wrote it. */\ntype Notice = TaskNotice & { at?: number };\n\n/** What the conversation says about its workflows: the calls, their results, how each ended. */\ntype Index = {\n calls: Map<string, ToolUseBlock>;\n /** When each call was made: an agent at work since is that call's. */\n madeAt: Map<string, number>;\n results: Map<string, { block: ToolResultBlock; at?: number }>;\n /** The end Claude Code wrote for each call, by its id; one from the Claude Code that ran it beats an orphan's. */\n notices: Map<string, Notice>;\n /** Tasks Claude stopped (TaskStop calls that ran). */\n stopped: Set<string>;\n /** The calls of each run, in order: a run resumed later has more than one. */\n runs: Map<string, string[]>;\n};\n\nconst indexes = new WeakMap<ChatMessage[], Index>();\n\nfunction indexOf(messages: ChatMessage[]): Index {\n const known = indexes.get(messages);\n if (known) return known;\n const index: Index = { calls: new Map(), madeAt: new Map(), results: new Map(), notices: new Map(), stopped: new Set(), runs: new Map() };\n const stops = new Map<string, string>();\n for (const message of messages) {\n for (const block of message.blocks) {\n if (block.type === 'tool_use') {\n if (block.name === 'Workflow') {\n index.calls.set(block.id, block);\n if (message.timestamp) index.madeAt.set(block.id, message.timestamp);\n } else if (block.name === 'TaskStop' && str(block.input.task_id ?? block.input.shell_id)) {\n stops.set(block.id, str(block.input.task_id ?? block.input.shell_id)!);\n }\n } else if (block.type === 'tool_result') {\n if (index.calls.has(block.tool_use_id)) {\n index.results.set(block.tool_use_id, { block, ...(message.timestamp ? { at: message.timestamp } : {}) });\n const runId = launchOf(block)?.runId;\n if (runId) index.runs.set(runId, [...(index.runs.get(runId) ?? []), block.tool_use_id]);\n } else if (stops.has(block.tool_use_id) && !block.is_error) {\n index.stopped.add(stops.get(block.tool_use_id)!);\n }\n } else if (block.type === 'text' && message.role === 'user' && block.text.trimStart().startsWith('<task-notification>')) {\n const notice = parseTaskNotice(block.text);\n if (!notice?.toolUseId) continue;\n const before = index.notices.get(notice.toolUseId);\n if (!before || before.orphan || !notice.orphan) index.notices.set(notice.toolUseId, { ...notice, ...(message.timestamp ? { at: message.timestamp } : {}) });\n }\n }\n }\n indexes.set(messages, index);\n return index;\n}\n\nconst ENDED: Record<NonNullable<TaskNotice['status']>, WorkflowStatus> = { completed: 'completed', failed: 'failed', killed: 'killed', stopped: 'killed' };\n\n/** The Workflow calls of a session, oldest first: what the site saves, and what the routes take. */\nexport async function workflowCalls(sessionId: string): Promise<Array<{ toolUseId: string; runId?: string; name?: string }>> {\n if (!(await sessionDir(sessionId))) return [];\n const index = indexOf(await loadMessages(sessionId));\n return [...index.calls.values()].map((call) => {\n const runId = launchOf(index.results.get(call.id)?.block)?.runId;\n const name = launchOf(index.results.get(call.id)?.block)?.name ?? workflowOf(call.input).name;\n return { toolUseId: call.id, ...(runId ? { runId } : {}), ...(name ? { name } : {}) };\n });\n}\n\ntype Found = { where: Where; call: ToolUseBlock; index: Index; runId?: string; taskId?: string };\n\nasync function findCall(sessionId: string, callId: string): Promise<Found | undefined> {\n if (!CALL_ID.test(callId)) return undefined;\n const where = await sessionDir(sessionId);\n if (!where) return undefined;\n const index = indexOf(await loadMessages(sessionId));\n const call = index.calls.get(callId);\n if (!call) return undefined;\n const launch = launchOf(index.results.get(callId)?.block);\n const runId = launch?.runId && RUN_ID.test(launch.runId) ? launch.runId : undefined;\n return { where, call, index, ...(runId ? { runId } : {}), ...(launch?.taskId ? { taskId: launch.taskId } : {}) };\n}\n\n/**\n * A script copy Claude Code kept in the session's scripts folder, by its file name: wherever the\n * path a call names, only that folder is read.\n */\nasync function scriptFile(dir: string, name: string | undefined): Promise<string | undefined> {\n const base = name?.split(/[\\\\/]/).pop();\n if (!base || !/^[\\w.-]{1,200}\\.js$/.test(base)) return undefined;\n return (await readInside(dir, path.join(dir, 'workflows', 'scripts', base), SCRIPT_MAX, true))?.text;\n}\n\n/** One Workflow call's run as a page shows it, and a tag that changes when it does. */\nexport type WorkflowAnswer = { workflow: Workflow; tag: string };\n\nconst tagOf = (value: unknown) => `\"${createHash('sha256').update(JSON.stringify(value)).digest('base64url').slice(0, 27)}\"`;\n\n/**\n * Whether a run nothing has said the end of is still at work. Its agents writing now say so.\n * Without word of its end, a Claude Code with the session open may be running it. A Claude Code\n * that found it in the session without a record of its end wrote an orphan's notice: then it runs\n * only while a Claude Code has the session open, and that alone is not enough, as the one that wrote\n * the notice has it open too: its agents went on after the notice (the Claude Code that started it,\n * still at it), or write now.\n */\nasync function stillRunning(sessionId: string, lastAt: number, orphan: Notice | undefined): Promise<boolean> {\n const quiet = Date.now() - lastAt;\n if (!orphan) return quiet < ACTIVE_MS || (await liveProcesses()).has(sessionId);\n const wentOn = quiet < ACTIVE_MS || (orphan.at !== undefined && lastAt > orphan.at && quiet < QUIET_MS);\n return wentOn && (await liveProcesses()).has(sessionId);\n}\n\n/**\n * A Workflow call's run: what this Pelican's Claude reports of it (`live`), else Claude Code's\n * record of it once it ended, else its journal and its agents' files. How it ended comes from what\n * Claude Code wrote into the conversation; without that, it runs while a Claude Code still has the\n * session open, and otherwise ended with it. A run another call resumed later shows there.\n */\nexport async function workflowView(sessionId: string, callId: string, live?: Workflow): Promise<WorkflowAnswer | undefined> {\n const found = await findCall(sessionId, callId);\n if (!found) return undefined;\n const { where, call, index, runId, taskId } = found;\n const own = workflowOf(call.input);\n const launch = launchOf(index.results.get(callId)?.block);\n const notice = index.notices.get(callId);\n const record = runId ? await cachedJson(where.dir, recordFile(where.dir, runId), RECORD_MAX, recordOf) : undefined;\n const ours = record && (!taskId || !record.taskId || record.taskId === taskId) ? record : undefined;\n // The call holds its script; one run from a file is read from the session's copy.\n const script = str(call.input.script) ? undefined\n : ours?.script ?? await scriptFile(where.dir, launch?.scriptFile) ?? await scriptFile(where.dir, str(call.input.scriptPath)) ?? record?.script;\n const meta = own.meta ?? (script ? parseMeta(script) : undefined);\n const base = {\n ...(runId ? { runId } : {}),\n ...(taskId ? { taskId } : {}),\n ...(launch?.name ?? meta?.name ?? own.name ? { name: launch?.name ?? meta?.name ?? own.name! } : {}),\n ...(meta?.description ?? launch?.summary ?? own.description ? { description: meta?.description ?? launch?.summary ?? own.description! } : {}),\n ...(script ? { script: clip(script, SCRIPT_SHOWN_MAX) } : {}),\n };\n const phases = meta?.phases ?? [];\n const startedAt = index.results.get(callId)?.at;\n let workflow: Workflow;\n // A later call resumed this run (the same run id): it is that call's to show. This one resumed\n // an earlier call's run: the journal goes back to that one's attempt.\n const calls = runId ? index.runs.get(runId) ?? [] : [];\n const position = calls.indexOf(callId);\n const resumedLater = position >= 0 && position < calls.length - 1;\n const resumed = position > 0;\n if (live) {\n workflow = { ...base, ...live, ...(live.phases.length > 0 ? {} : { phases }), source: 'live' };\n } else if (ours) {\n const agents = ours.items.map(agentItem).filter((a): a is WorkflowAgent => Boolean(a));\n workflow = {\n ...base,\n ...(ours.name ? { name: ours.name } : {}),\n ...(ours.summary && !base.description ? { description: ours.summary } : {}),\n status: ours.status,\n ...(ours.startTime ?? startedAt ? { startedAt: ours.startTime ?? startedAt! } : {}),\n ...(ours.durationMs !== undefined ? { durationMs: ours.durationMs } : {}),\n ...(ours.totalTokens !== undefined ? { totalTokens: ours.totalTokens } : {}),\n ...(ours.totalToolCalls !== undefined ? { totalToolCalls: ours.totalToolCalls } : {}),\n phases: withPhases(ours.phases.length > 0 ? ours.phases : phases, ours.items),\n agents,\n ...(ours.error ? { error: ours.error } : {}),\n ...(ours.result ? { result: ours.result } : {}),\n source: 'record',\n };\n } else {\n // Another call carries the run on: its card shows the run, this one how it ended here.\n const since = resumed ? index.madeAt.get(callId) ?? startedAt : undefined;\n const agents = runId && !resumedLater ? await journalAgents(where.dir, runId, since) : [];\n const lastAt = Math.max(0, ...agents.map((a) => a.lastProgressAt ?? 0));\n const ended = notice?.status && !notice.orphan ? ENDED[notice.status]\n : taskId && index.stopped.has(taskId) ? 'killed'\n : resumedLater ? 'killed'\n : await stillRunning(sessionId, lastAt, notice?.orphan ? notice : undefined) ? 'running' : 'stopped';\n const running = ended === 'running';\n const tokens = notice?.usage?.tokens ?? agentTokens(agents);\n const toolUses = notice?.usage?.toolUses ?? agents.reduce((sum, a) => sum + (a.toolCalls ?? 0), 0);\n const duration = notice?.usage?.durationMs ?? (!running && startedAt && lastAt > startedAt ? lastAt - startedAt : undefined);\n workflow = {\n ...base,\n status: ended,\n ...(startedAt ? { startedAt } : {}),\n ...(duration !== undefined ? { durationMs: duration } : {}),\n ...(tokens > 0 ? { totalTokens: tokens } : {}),\n ...(toolUses > 0 ? { totalToolCalls: toolUses } : {}),\n phases,\n agents,\n ...(notice?.error ? { error: notice.error } : {}),\n ...(notice?.result ? { result: clipLines(notice.result, RESULT_MAX) } : {}),\n source: 'journal',\n };\n }\n return { workflow, tag: tagOf(workflow) };\n}\n\n// ---- A workflow agent's own transcript --------------------------------------------------------\n\n/** How many of an agent's messages a page holds at most, and how many bytes of them. */\nconst PAGE_MAX = 300;\nconst PAGE_BYTES = 768 * 1024;\n/** One message, at most, on a page, in bytes: a call with a large value (a StructuredOutput of findings) is cut to this. */\nconst MESSAGE_MAX = 128 * 1024;\nconst PART_MAX = 8 * 1024;\n/** What a value comes to on a page, in bytes. */\nconst bytesOf = (value: unknown) => Buffer.byteLength(JSON.stringify(value) ?? '');\n\n/** A value as text no longer than `max`: a string cut, anything else as its JSON, cut. */\nfunction shortValue(value: unknown, max: number): unknown {\n if (typeof value === 'string') return value.length > max ? `${value.slice(0, max)}\\n\u2026` : value;\n if (value === null || typeof value !== 'object') return value;\n const text = JSON.stringify(value) ?? '';\n return text.length > max ? `${text.slice(0, max)}\\n\u2026` : value;\n}\n\n/** A block of a message too large for a page, each of its parts cut to a few kilobytes. */\nfunction shortBlock(block: Block): Block {\n switch (block.type) {\n case 'text':\n return block.text.length > PART_MAX ? { ...block, text: `${block.text.slice(0, PART_MAX)}\\n\u2026`, truncated: true } : block;\n case 'thinking':\n return block.thinking.length > PART_MAX / 4 ? { ...block, thinking: `${block.thinking.slice(0, PART_MAX / 4)}\\n\u2026` } : block;\n case 'tool_use':\n return { ...block, input: Object.fromEntries(Object.entries(block.input).map(([key, value]) => [key, shortValue(value, PART_MAX)])) };\n case 'tool_result': {\n if (typeof block.content === 'string') return block.content.length > PART_MAX ? { ...block, content: `${block.content.slice(0, PART_MAX)}\\n\u2026`, truncated: true } : block;\n const content = block.content.map((part) => (part.type === 'text' && part.text.length > PART_MAX ? { ...part, text: `${part.text.slice(0, PART_MAX)}\\n\u2026`, truncated: true } : part));\n return { ...block, content, ...(content.some((p) => p.type === 'text' && p.truncated) ? { truncated: true } : {}) };\n }\n default:\n return block;\n }\n}\n\nconst many = (n: number, unit: string) => `${n.toLocaleString('en-US')} more ${unit}${n === 1 ? '' : 's'}`;\n\n/**\n * A block, its parts cut already (shortBlock), made to fit `room` bytes: a call keeps as many of\n * its input's keys as fit and a result as many of its parts, each saying how many more were left\n * out; anything else that large is left out, saying so.\n */\nfunction fitBlock(block: Block, room: number): Block {\n if (bytesOf(block) <= room) return block;\n // The note's own room.\n let used = 96;\n if (block.type === 'tool_use') {\n const entries = Object.entries(block.input);\n const input: Record<string, unknown> = {};\n used += bytesOf({ ...block, input: {} });\n for (const [key, value] of entries) {\n const weight = bytesOf(key) + bytesOf(value) + 2;\n if (used + weight > room) break;\n input[key] = value;\n used += weight;\n }\n const left = entries.length - Object.keys(input).length;\n return { ...block, input: { ...input, '\u2026': `${many(left, 'key')} of its input left out` } };\n }\n if (block.type === 'tool_result' && Array.isArray(block.content)) {\n const content: Exclude<ToolResultBlock['content'], string> = [];\n used += bytesOf({ ...block, content: [] });\n for (const part of block.content) {\n const weight = bytesOf(part) + 1;\n if (used + weight > room) break;\n content.push(part);\n used += weight;\n }\n return { ...block, content: [...content, { type: 'text', text: `\u2026 (${many(block.content.length - content.length, 'part')} of this result left out)`, truncated: true }], truncated: true };\n }\n return { type: 'text', text: '\u2026 (a part too large to show left out)', truncated: true };\n}\n\n/**\n * A message as a page carries it, with its size in bytes: one too large has its parts cut, then\n * as many of them as fit, the first made to fit (fitBlock), whatever its shape, and a word on how\n * many more were left out.\n */\nconst sized = new WeakMap<ChatMessage, { message: ChatMessage; size: number }>();\nfunction onPage(message: ChatMessage): { message: ChatMessage; size: number } {\n const known = sized.get(message);\n if (known) return known;\n let shown = message;\n let size = bytesOf(message);\n if (size > MESSAGE_MAX) {\n const room = MESSAGE_MAX - bytesOf({ ...message, blocks: [] }) - 1024;\n const blocks: Block[] = [];\n let total = 0;\n const parts = message.blocks.map(shortBlock);\n for (const [i, part] of parts.entries()) {\n const block = blocks.length === 0 ? fitBlock(part, room) : part;\n const weight = bytesOf(block) + 1;\n if (total + weight > room && blocks.length > 0) {\n blocks.push({ type: 'text', text: `\u2026 (${many(parts.length - i, 'part')} of this message left out)`, truncated: true });\n break;\n }\n blocks.push(block);\n total += weight;\n }\n shown = { ...message, blocks };\n size = bytesOf(shown);\n }\n const out = { message: shown, size };\n sized.set(message, out);\n return out;\n}\n\n/** An agent's messages over its two files, the run folder's first: the second goes on where the first stopped. */\nconst joined = new WeakMap<ChatMessage[], { rest: ChatMessage[]; all: ChatMessage[] }>();\nfunction joinParts(parts: ChatMessage[][]): ChatMessage[] {\n const [first = [], rest = []] = parts;\n if (rest.length === 0) return first;\n if (first.length === 0) return rest;\n const known = joined.get(first);\n if (known?.rest === rest) return known.all;\n // The earlier one first, should the files be the other way round.\n const [a, b] = (rest[0]?.timestamp ?? Infinity) < (first[0]?.timestamp ?? Infinity) ? [rest, first] : [first, rest];\n const seen = new Set(a.map((m) => m.uuid));\n const all = [...a, ...b.filter((m) => !seen.has(m.uuid))];\n joined.set(first, { rest, all });\n return all;\n}\n\n/**\n * What the agent was asked, as Claude Code shows it: the last of the user messages its transcript\n * starts with (Claude Code relays the user's request in one, then the computed task), the one with\n * the computed task if any, without the harness's frame.\n */\nfunction promptOf(messages: ChatMessage[]): string | undefined {\n const leading: ChatMessage[] = [];\n for (const message of messages) {\n if (message.role !== 'user' || (message.meta && leading.length > 0)) break;\n if (!message.blocks.some((b) => b.type === 'text')) break;\n leading.push(message);\n }\n const text = (message: ChatMessage) => message.blocks.map((b) => (b.type === 'text' ? b.text : '')).join('\\n');\n const task = [...leading].reverse().find((m) => text(m).includes('The computed task text follows:\\n')) ?? leading.at(-1);\n return task ? unframedPrompt(text(task)) : undefined;\n}\n\n/**\n * A page of one workflow agent's own transcript: its last `limit` messages before message `before`\n * (default: the end), or with `after`, those from that message on (what a page that has the rest\n * asks for while the agent works); fewer when they come to more than a phone should load at once.\n * With its prompt, and what it returned, from the journal. Only agents of this call's run. Read\n * from that agent's own files only, whatever the run's size.\n */\nexport async function workflowAgentPage(\n sessionId: string, callId: string, agentId: string, { before, after, limit = 60 }: { before?: number; after?: number; limit?: number }, live?: Workflow,\n): Promise<(WorkflowAgentPage & { tag: string }) | undefined> {\n if (!AGENT_ID.test(agentId)) return undefined;\n const found = await findCall(sessionId, callId);\n if (!found?.runId) return undefined;\n const { where, runId, taskId } = found;\n const record = await cachedJson(where.dir, recordFile(where.dir, runId), RECORD_MAX, recordOf);\n const ours = record && (!taskId || !record.taskId || record.taskId === taskId) ? record : undefined;\n const fromRecord = (ours?.items ?? []).map(agentItem).find((a) => a?.agentId === agentId);\n const entry = ((await readJournal(where.dir, runId)) ?? []).find((e) => e.agentId === agentId);\n const agent = live?.agents.find((a) => a.agentId === agentId) ?? fromRecord;\n if (!agent && !entry) return undefined;\n const files = await agentFiles(where.dir, runId, agentId);\n const all = joinParts(await Promise.all(files.map((file) => readHistory(file, { sidechain: true }))));\n const wanted = Math.max(1, Math.min(limit, PAGE_MAX));\n let offset: number;\n let end: number;\n if (after !== undefined) {\n // From `after` on, as far as a page goes.\n offset = Math.min(after, all.length);\n end = offset;\n for (let bytes = 0; end < all.length && end - offset < wanted; end += 1) {\n const { size } = onPage(all[end]!);\n if (end > offset && bytes + size > PAGE_BYTES) break;\n bytes += size;\n }\n } else {\n end = Math.min(before ?? all.length, all.length);\n offset = end;\n for (let bytes = 0; offset > 0 && end - offset < wanted; offset -= 1) {\n const { size } = onPage(all[offset - 1]!);\n if (end - offset > 0 && bytes + size > PAGE_BYTES) break;\n bytes += size;\n }\n }\n const prompt = promptOf(all) ?? agent?.promptPreview ?? fromRecord?.promptPreview;\n const result = entry?.state === 'done' ? entry.result : undefined;\n const shown = result ?? agent?.resultPreview ?? fromRecord?.resultPreview;\n // Done by its run's word while the journal has it only started: its result follows there.\n const coming = !shown && agent?.state === 'done' && entry?.state === 'started';\n const page: WorkflowAgentPage = {\n messages: all.slice(offset, end).map((m) => onPage(m).message),\n total: all.length,\n offset,\n ...(prompt ? { prompt: clip(prompt, PROMPT_MAX) } : {}),\n ...(shown ? { result: shown } : {}),\n ...(coming ? { resultComing: true } : {}),\n };\n return { ...page, tag: tagOf(page) };\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 { Readable } from 'node:stream';\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 { USAGE_RANGES, type UsageRange } from '../shared/usage.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 { demoRunState, demoTaskOutput } from './demo.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, startSideChat } from './runner.js';\nimport { savedOutputPage } from './shell.js';\nimport { startShell, stopShell } from './shell-runs.js';\nimport { isSideChat } from './side-chat.js';\nimport { shownRun } from './stream.js';\nimport { usageLimits } from './usage.js';\nimport { EXISTS_MAX, existingFiles, gitDiff, gitStatus, listTree, openProjectFile, readProjectFile } from './workspace.js';\nimport { searchText } from './search.js';\nimport { sessionChanges, turnDiff } from './changes.js';\nimport { readStatsCache, refreshUsage, sessionFiles, sessionUsage, summarize } from './stats.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, launchFor, NeedsTrust, rememberChoice, type TrustChoice, trustQuestion } from './trust.js';\nimport { AGENT_ID, CALL_ID, workflowAgentPage, workflowCalls, workflowView } from './workflows.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) || c.req.path === '/api/file/raw');\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/**\n * A side question, as Claude Desktop asks one: the session so far is copied into a side chat whose\n * Claude only reads, and the question goes there (runner.ts, startSideChat). The session itself is\n * not touched, also while Claude works in it. Later questions go to the side chat as messages.\n */\napp.post('/api/sessions/:id/side', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const body = await c.req.json<{ question?: unknown; settings?: unknown; uuid?: unknown }>().catch(() => ({}) as Record<string, unknown>);\n if (typeof body.question !== 'string' || !body.question.trim() || body.question.length > 200_000) return c.json({ error: 'Ask a question' }, 400);\n if (!id || !(await sessionInfo(id))) return c.json({ error: 'No such session' }, 404);\n const uuid = uuidOf(body.uuid);\n const sessionId = await startSideChat(id, { text: body.question, settings: cleanSettings(body.settings), ...(uuid ? { uuid } : {}) });\n return c.json({ sessionId });\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/** Titles and folders of sessions, from the session list, for the usage page's lists. */\nasync function sessionTitles(ids: string[]): Promise<Map<string, { title: string; project: string }>> {\n const wanted = new Set(ids);\n const found = new Map<string, { title: string; project: string }>();\n if (wanted.size === 0) return found;\n for (const s of await listSummaries(runStatus)) if (wanted.has(s.id)) found.set(s.id, { title: s.title, project: s.project });\n return found;\n}\n\n/**\n * Usage and activity across every Claude Code session on this computer, whichever app ran it: what\n * has been read so far, and how far reading got. A small home is read before the first answer; a\n * large one fills in as the page asks again.\n */\napp.get('/api/usage/stats', async (c) => {\n const asked = c.req.query('range');\n const range: UsageRange = USAGE_RANGES.find((r) => r === asked) ?? '7d';\n let timer: NodeJS.Timeout | undefined;\n await Promise.race([refreshUsage(), new Promise<void>((resolve) => {\n timer = setTimeout(resolve, 1200);\n })]);\n clearTimeout(timer);\n const statsCache = range === 'all' ? await readStatsCache() : undefined;\n return c.json({ summary: await summarize({ range, now: Date.now(), titles: sessionTitles, statsCache }) });\n});\n\n/** One session's usage, for its menu: its transcript and its subagents', read now if they changed. */\napp.get('/api/sessions/:id/usage', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const file = id ? await transcriptPath(id) : undefined;\n if (!id || !file) return c.json({ usage: null });\n return c.json({ usage: (await sessionUsage(id, await sessionFiles(id, file))) ?? null });\n});\n\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\n/** What Changes compares with: the last commit, or (`scope=base`) where the branch split from the default one. */\nconst scopeOf = (c: Context) => (c.req.query('scope') === 'base' ? 'base' : 'uncommitted');\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, scopeOf(c)));\n});\n\n/** One file's diff; `from`, a renamed file's old path, so git pairs the two. */\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, scopeOf(c), c.req.query('from') || undefined) });\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\n/**\n * A file of the folder, downloaded: as an attachment that runs nothing where it opens (no\n * sniffing, the sandbox's policy), read as it is, up to 200 MB. Asked for by a plain link.\n */\napp.get('/api/file/raw', 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 const opened = await openProjectFile(cwd, file).catch(() => undefined);\n if (!opened) return c.json({ error: 'No such file' }, 404);\n if (opened.size > 200 * 1024 * 1024) {\n await opened.handle.close();\n return c.json({ error: 'That file is larger than 200 MB' }, 413);\n }\n const headers = {\n 'Content-Type': 'application/octet-stream',\n 'Content-Length': String(opened.size),\n 'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(path.basename(file))}`,\n 'Cache-Control': 'private, no-store',\n ...INERT,\n };\n // HEAD takes this route too and wants no body: a stream nobody reads would hold the file open.\n if (c.req.method === 'HEAD') {\n await opened.handle.close();\n return c.body(null, 200, headers);\n }\n return c.body(Readable.toWeb(opened.handle.createReadStream()) as ReadableStream, 200, headers);\n});\n\n/**\n * The lines of the folder's files that hold some text (Files' search): Claude Code's own\n * ripgrep, else a bounded scan (search.ts). Runs no git and nothing of the folder's.\n */\napp.get('/api/search', async (c) => {\n const cwd = await folderOf(c);\n const q = c.req.query('q') ?? '';\n if (!cwd) return c.json({ error: 'No such folder' }, 404);\n if (!q.trim() || q.length > 200) return c.json({ error: 'Search for some text, up to 200 characters' }, 400);\n return c.json(await searchText(cwd, q));\n});\n\n/**\n * Which of the paths named in the conversation are files in the folder (`p`, repeated, at most\n * 50): the links in a reply and in a step open only those. Stats files; runs nothing.\n */\napp.get('/api/exists', async (c) => {\n const cwd = await folderOf(c);\n if (!cwd) return c.json({ paths: [] });\n const asked = c.req.queries('p') ?? [];\n if (asked.length > EXISTS_MAX) return c.json({ error: `At most ${EXISTS_MAX} paths at a time` }, 400);\n return c.json({ paths: await existingFiles(cwd, asked) });\n});\n\n/**\n * What each turn of a session changed (T1, T2\u2026), from Claude Code's records of its edits: no git,\n * so in any folder. With `turn` and `path`, that turn's diff of that file. A side chat changes\n * nothing: the turns it copied of its session are that session's.\n */\napp.get('/api/sessions/:id/changes', async (c) => {\n const id = c.req.param('id');\n const file = await transcriptPath(id);\n if (!file) return c.json({ turns: [], lines: {} });\n const cwd = (await sessionInfo(id))?.cwd;\n const ownOnly = await isSideChat(id);\n const turn = c.req.query('turn');\n const target = c.req.query('path');\n if (turn !== undefined || target !== undefined) {\n if (!turn || !target || target.length > 4096) return c.json({ error: 'Which turn and file?' }, 400);\n return c.json({ diff: await turnDiff(file, cwd, turn, target, ownOnly) });\n }\n return c.json(await sessionChanges(file, cwd, ownOnly));\n});\n\n/**\n * A `!` command: it starts at once, its output goes to the session's pages as it comes, and once\n * done it goes into the conversation (shell-runs.ts). A folder nobody trusted is asked about\n * before anything runs, as for a message, since recording it starts Claude Code there; the\n * command runs as Claude Code would there, so in a folder kept to the user's settings only, git\n * runs none of the repository's programs.\n */\napp.post('/api/sessions/:id/shell', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json<{ command?: unknown; trust?: unknown }>().catch(() => ({}) as { command?: unknown; trust?: unknown });\n const command = typeof body.command === 'string' ? body.command.trim() : '';\n if (!command) return c.json({ error: 'No command' }, 400);\n const cwd = getRun(id)?.cwd ?? (await sessionInfo(id))?.cwd;\n if (!cwd || !(await isDirectory(cwd))) return c.json({ error: 'The session\u2019s folder is missing' }, 404);\n // A side chat reads; it runs nothing in the folder.\n if (await isSideChat(id)) return c.json({ error: 'A side chat runs no commands. Run it in the session itself.' }, 409);\n if (body.trust === 'trusted' || body.trust === 'user-only') await rememberChoice(cwd, body.trust);\n const launch = await launchFor(cwd);\n return c.json({ shell: startShell(id, cwd, command, launch.env) }, 202);\n});\n\n/**\n * An output Claude Code saved in a session's tool-results folder in place of one too long for the\n * conversation, as a long `!` command's record names it: read only, by its name alone, from that\n * session's own folder, a page at a time (`from`, in bytes), for Show all.\n */\napp.get('/api/sessions/:id/tool-results/:name', async (c) => {\n const page = await savedOutputPage(c.req.param('id'), c.req.param('name'), Number(c.req.query('from') ?? 0));\n return page ? c.json(page) : c.json({ error: 'That output is no longer saved' }, 404);\n});\n\napp.post('/api/sessions/:id/shell/:shell/stop', (c) => (stopShell(c.req.param('id'), c.req.param('shell'))\n ? c.json({ ok: true })\n : c.json({ error: 'That command is not running any more' }, 409)));\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 // The demo's command prints what it would have.\n const demo = config.demo ? demoTaskOutput(c.req.param('id'), c.req.param('task')) : undefined;\n if (demo) return c.json(demo);\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\n/** What this Pelican's Claude reports of a workflow it runs, by the Workflow call that started it. */\nconst liveWorkflow = (sessionId: string, call: string) => (config.demo ? demoRunState(sessionId)?.workflows?.[call] : getRun(sessionId)?.workflow(call));\n\n/** A session's Workflow calls, oldest first, with the runs they started. */\napp.get('/api/sessions/:id/workflows', async (c) => {\n const id = uuidOf(c.req.param('id'));\n return c.json({ workflows: id ? await workflowCalls(id) : [] });\n});\n\n/**\n * One Workflow call's run: its phases and agents and how it stands, as Claude Code reports it,\n * from this Pelican's Claude or from the run's own files (workflows.ts). A page asks again while it\n * runs; an answer it has already comes back short.\n */\napp.get('/api/sessions/:id/workflows/:call', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const call = c.req.param('call');\n if (!id || !CALL_ID.test(call)) return c.json({ error: 'No such workflow' }, 404);\n const answer = await workflowView(id, call, liveWorkflow(id, call));\n if (!answer) return c.json({ error: 'No such workflow' }, 404);\n if (unchanged(c, answer.tag)) return c.body(null, 304, { ETag: answer.tag, 'Cache-Control': KEPT_ASKING });\n return c.json({ workflow: answer.workflow }, 200, { ETag: answer.tag, 'Cache-Control': KEPT_ASKING });\n});\n\n/**\n * A page of a workflow agent's own transcript: the last messages by default, `before` for earlier\n * ones, `after` for those since (what a page asks while the agent works). An answer the page has\n * already comes back short, as for the run.\n */\napp.get('/api/sessions/:id/workflows/:call/agents/:agent', async (c) => {\n const id = uuidOf(c.req.param('id'));\n const call = c.req.param('call');\n const agent = c.req.param('agent');\n const position = (name: string) => {\n const value = c.req.query(name);\n if (value === undefined) return undefined;\n const n = Number(value);\n return Number.isSafeInteger(n) && n >= 0 ? n : NaN;\n };\n const before = position('before');\n const after = position('after');\n if (!id || !CALL_ID.test(call) || !AGENT_ID.test(agent) || Number.isNaN(before) || Number.isNaN(after) || (before !== undefined && after !== undefined)) {\n return c.json({ error: 'No such agent' }, 404);\n }\n const limit = Math.min(Math.max(Number(c.req.query('limit') ?? 60) || 60, 1), 300);\n const answer = await workflowAgentPage(id, call, agent, { ...(before !== undefined ? { before } : {}), ...(after !== undefined ? { after } : {}), limit }, liveWorkflow(id, call));\n if (!answer) return c.json({ error: 'No such agent' }, 404);\n const { tag, ...page } = answer;\n if (unchanged(c, tag)) return c.body(null, 304, { ETag: tag, 'Cache-Control': KEPT_ASKING });\n return c.json(page, 200, { ETag: tag, 'Cache-Control': KEPT_ASKING });\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 { askedBySystemd, LAUNCHD_EXIT_TIMEOUT_S, launchdExitTimeout, launchdJob, runCommand } from './service.js';\nimport { hurryShells, runningShells, shellsEvent, shutdownGrace, stopAllShells } from './shell-runs.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 send(shellsEvent(id));\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 // Claude's processes get half a second to close; `!` commands still running are asked to end,\n // given time to tidy up, inside what launchd allows when it started Pelican, then made to,\n // before Pelican exits: once it has, nothing would end them. Told again (a second Ctrl+C),\n // Pelican ends them at once.\n const context = { platform: process.platform, env: process.env, uid: process.getuid?.() ?? 0, run: runCommand };\n let exitTimeout = launchdJob(context) ? LAUNCHD_EXIT_TIMEOUT_S : undefined;\n void launchdExitTimeout(context).then((seconds) => {\n exitTimeout = seconds;\n }, () => undefined);\n let stopping = false;\n const shutdown = (signal: NodeJS.Signals) => {\n if (stopping) {\n hurryShells();\n return;\n }\n stopping = true;\n const waiting = runningShells();\n const grace = shutdownGrace(exitTimeout);\n if (waiting > 0) {\n const what = waiting === 1 ? 'a ! command' : `${waiting} ! commands`;\n console.log(`[pelican] Giving ${what} up to ${Math.round(grace / 100) / 10} seconds to end.${process.stdin.isTTY ? ` Ctrl+C again ends ${waiting === 1 ? 'it' : 'them'} now.` : ''}`);\n }\n const shells = stopAllShells(grace, { asked: askedBySystemd(signal) });\n closeAll();\n server.close();\n void Promise.all([shells, new Promise((resolve) => setTimeout(resolve, 500))]).finally(() => process.exit(0));\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": ["kept", "path", "info", "record", "os", "randomBytes", "readFileSync", "mkdir", "readFile", "writeFile", "path", "before", "text", "key", "file", "instance", "rest", "cookieHeader", "times", "code", "info", "text", "text", "lines", "init_qr", "existsSync", "os", "file", "app", "target", "serve", "cut", "shown", "path", "text", "lines", "instance", "init_qr", "execFile", "readFileSync", "mkdir", "rm", "writeFile", "os", "path", "kept", "file", "text", "strings", "result", "what", "loaded", "stdout", "pid", "real", "home", "execFile", "existsSync", "readFileSync", "stat", "path", "require", "file", "version", "text", "lines", "steps", "before", "k", "changed", "path", "mkdir", "writeFile", "path", "index", "lines", "before", "own", "index", "result", "MIN", "steps", "lines", "read", "file", "run", "execFile", "mkdir", "rm", "writeFile", "path", "file", "before", "git", "run", "MIN", "files", "lines", "own", "meta", "HOUR", "tool", "result", "text", "read", "text", "version", "text", "str", "file", "meta", "result", "text", "scriptFile", "failed", "same", "key", "text", "text", "files", "lines", "version", "note", "runs", "notice", "key", "result", "text", "cut", "kept", "randomUUID", "mkdir", "readFile", "rename", "writeFile", "path", "text", "file", "loaded", "before", "randomBytes", "realpathSync", "mkdir", "stat", "os", "path", "execFile", "readFile", "path", "promisify", "run", "alive", "entries", "waiting", "app", "text", "clipped", "key", "isRecord", "take", "scriptFile", "constants", "file", "stat", "path", "file", "str", "text", "notice", "lines", "seen", "read", "info", "image", "readdir", "stat", "path", "file", "waiting", "before", "text", "lines", "info", "key", "own", "read", "open", "rest", "path", "file", "text", "stat", "path", "info", "archived", "file", "times", "own", "recent", "sideChatOf", "stats", "changed", "before", "seen", "files", "summaries", "text", "info", "result", "blocks", "words", "note", "run", "target", "text", "files", "file", "stat", "waiting", "file", "info", "recent", "changed", "randomUUID", "mkdir", "readdir", "readFile", "realpath", "rm", "stat", "writeFile", "path", "file", "info", "target", "entries", "execFile", "mkdir", "readdir", "realpath", "rename", "stat", "writeFile", "os", "path", "file", "text", "head", "info", "readJson", "key", "home", "kept", "folder", "groups", "what", "target", "lines", "under", "files", "seen", "walk", "entries", "cut", "read", "json", "realpath", "os", "key", "info", "text", "cache", "asking", "read", "list", "limits", "add", "execFile", "realpathSync", "path", "promisify", "run", "readdir", "path", "cache", "TTL_MS", "files", "MAX_FILES", "walk", "entries", "file", "query", "cut", "mkdir", "readFile", "writeFile", "path", "file", "oneLine", "text", "cut", "index", "words", "width", "lines", "rest", "key", "shown", "before", "home", "tool", "list", "spawn", "randomBytes", "randomUUID", "read", "mkdir", "open", "realpath", "writeFile", "os", "path", "promisify", "resolveSettings", "running", "started", "result", "take", "text", "rest", "asking", "failed", "words", "answers", "head", "lines", "file", "SAVED_NAME", "limits", "count", "before", "target", "info", "init_usage", "randomUUID", "readFile", "query", "text", "file", "str", "lines", "key", "index", "tool", "run", "target", "info", "cwd", "started", "init_usage", "note", "rest", "changed", "progress", "meta", "before", "result", "version", "oneLine", "remember", "launched", "failed", "waiting", "randomUUID", "text", "entries", "record", "result", "run", "started", "running", "text", "before", "index", "textOf", "blocks", "readdir", "realpath", "stat", "path", "relative", "real", "files", "file", "entries", "head", "counts", "lines", "info", "data", "spawn", "readdir", "path", "file", "query", "result", "lines", "SKIP", "take", "text", "clipped", "seen", "read", "entries", "readText", "stat", "path", "isRecord", "lines", "count", "result", "file", "str", "created", "text", "empty", "scan", "own", "readNew", "CHUNK", "locks", "info", "kept", "KEEP", "KEEP_UNREAD_MS", "files", "edits", "clip", "target", "createHash", "randomUUID", "mkdir", "readdir", "readFile", "rename", "rm", "stat", "writeFile", "path", "text", "record", "file", "info", "reading", "key", "textOf", "num", "add", "addLine", "kindOf", "row", "own", "kind", "counts", "str", "head", "CHUNK", "rest", "unchanged", "list", "runs", "keys", "app", "strings", "load", "loaded", "kept", "locks", "before", "stats", "statting", "waits", "run", "DAY", "summarize", "cache", "bySession", "started", "times", "nameOf", "files", "main", "createHash", "realpath", "stat", "path", "text", "file", "read", "reading", "inside", "real", "head", "info", "key", "isRecord", "str", "num", "clip", "index", "result", "CHUNK", "agents", "times", "started", "entries", "meta", "files", "seen", "indexOf", "notice", "before", "own", "record", "running", "tagOf", "shown", "blocks", "rest", "init_workflows", "createHash", "readFile", "realpath", "stat", "path", "text", "file", "kept", "image", "run", "before", "key", "info", "isPrompt", "started", "real", "keys", "limits", "scopeOf", "liveWorkflow", "init_usage", "init_workflows", "succeeded", "newer", "result", "summarize", "target", "seen", "counts", "tag", "token", "waiting", "tell", "process", "info", "changed", "POLL_MS", "text", "SESSION_ID", "server", "info", "head", "pathOf", "subscriptions", "sweep", "waiting", "what", "spawn", "failed", "spawn", "mkdir", "rm", "writeFile", "path", "running", "path", "parse", "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", "count", "claudeLogin", "prepareDemo", "issueCode", "configWarnings", "startServer", "recordRunning", "shown", "open", "checkNewerClaude", "claudeCodeLine", "claudeSignIn", "newerClaudeLine", "newer", "code", "keepAwake", "anyRunBusy", "liveProcesses"]
7
7
  }