offsite 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.mjs","names":["publish","IDLE_LIMIT","toItems","userText","record","contentText","toRequest","IDLE_LIMIT","toItems","toRequest","server","projects","publish","projects","setTimeout","todoStatuses","text","IDLE_LIMIT","executable","push","OUTPUT_LIMIT","server","open","send","spawn","projects","open","send","push"],"sources":["../../core/src/protocol.ts","../src/lib/hub.ts","../src/args.ts","../src/storage/storage.ts","../src/storage/config.ts","../src/lib/codex/app-server.ts","../src/lib/codex/accounts.ts","../src/lib/codex/items.ts","../src/lib/live.ts","../src/lib/codex/requests.ts","../src/lib/codex/run.ts","../src/lib/codex/sessions.ts","../src/storage/db.ts","../src/services/projects.ts","../src/services/sessions.ts","../src/lib/opencode/client.ts","../src/lib/opencode/items.ts","../src/lib/opencode/sessions.ts","../src/lib/opencode/run.ts","../src/services/accounts.ts","../src/lib/claude/content.ts","../src/lib/claude/claude.ts","../src/lib/claude/items.ts","../src/lib/claude/history.ts","../src/lib/claude/run.ts","../src/services/git.ts","../src/services/files.ts","../src/services/push.ts","../src/services/runs.ts","../../core/src/shell-check.ts","../src/services/terminal/shell-integration.ts","../src/services/terminal/process.ts","../src/services/terminal/alerts.ts","../src/services/terminal/terminal.ts","../src/api/socket.ts","../src/storage/token.ts","../src/main.ts"],"sourcesContent":["export const PROTOCOL = 2\n\nexport const HOSTED_APP = 'https://offsite.sayad.dev'\n\nexport type Provider = 'claude' | 'codex' | 'opencode'\n\nexport type RateLimit = {\n window: string\n utilization: number | null\n resetsAt: number | null\n rejected: boolean\n}\n\nexport type Session = {\n id: string\n provider: Provider\n title: string\n cwd: string\n branch: string | null\n updatedAt: number\n status: 'active' | 'pinned' | 'minimized' | 'inactive'\n}\n\nexport type Project = { path: string; name: string; logo: string | null }\n\nexport type ProjectPatch = { name?: string; logo?: string | null }\n\nexport type Directories = {\n path: string\n parent: string | null\n directories: { name: string; path: string }[]\n}\n\nexport type Snapshot = ConfigInfo & {\n protocol: number\n hostname: string\n projects: Project[]\n sessions: Session[]\n activity: Record<string, Activity>\n}\n\nexport type SessionPatch = {\n title?: string\n status?: 'active' | 'pinned' | 'minimized' | 'inactive'\n}\n\nexport type Context = {\n tokens: number\n window: number | null\n}\n\nexport type Account = {\n id: string\n provider: Provider\n name: string\n configDir: string\n email: string | null\n plan: string | null\n error: string | null\n limits: RateLimit[]\n linked: boolean\n valid: boolean\n}\n\nexport type Model = {\n value: string\n name: string\n description: string\n efforts: string[]\n}\n\nexport type Command = { name: string; description: string; hint: string }\n\nexport type Agent = { id: string; name: string; description: string }\n\nexport type Capabilities = {\n models: Model[]\n commands: Command[]\n agents: Agent[]\n}\n\nexport type ProviderSettings = {\n accountId: string | null\n model: string | null\n effort: string | null\n mode: string | null\n plan: boolean\n}\n\nexport type Settings = ProviderSettings & { provider: Provider }\n\nexport type Rewind = {\n sessionId: string\n cwd: string\n messageId: string\n settings: Settings\n code: boolean\n conversation: boolean\n dryRun: boolean\n}\n\nexport type RewindResult = {\n files: string[]\n insertions: number\n deletions: number\n} | null\n\nexport type GitStatus = {\n branch: string | null\n upstream: string | null\n ahead: number\n behind: number\n changed: number\n}\n\nexport type FilePreview =\n | { kind: 'text'; size: number; content: string }\n | { kind: 'image'; size: number; mediaType: string; data: string }\n | { kind: 'binary'; size: number }\n | { kind: 'large'; size: number; limit: number }\n\nexport type Platform = 'macos' | 'linux' | 'windows'\n\nexport type TerminalIdentity = 'offsite' | 'ghostty' | 'iterm2'\n\nexport type TerminalConfig = {\n shell: Record<Platform, string | null>\n behavior: { terminalIdentity: TerminalIdentity; shellIntegration: boolean }\n}\n\nexport type Config = {\n claudeBaseDir: string\n composer: { provider: Provider } & Record<Provider, ProviderSettings>\n commitModels: Record<Provider, string | null>\n terminal: TerminalConfig\n}\n\nexport type ConfigInfo = {\n config: Config\n defaults: Config\n platform: Platform\n version: string\n defaultShell: string\n}\n\nexport type TerminalTab = {\n id: number\n customName: string | null\n minimized: boolean\n}\n\nexport type TerminalProject = { tabs: TerminalTab[]; activeTab: number | null }\n\nexport type TerminalLayout = Record<string, TerminalProject>\n\nexport type TerminalRequest =\n | { type: 'attach' }\n | { type: 'detach' }\n | { type: 'createTab'; cwd: string }\n | { type: 'closeTab'; id: number }\n | { type: 'renameTab'; id: number; name: string }\n | { type: 'minimizeTab'; id: number }\n | { type: 'select'; cwd: string; tabId: number | null }\n | { type: 'resize'; id: number; cols: number; rows: number }\n\nexport type TerminalEvent =\n | { type: 'active'; layout: TerminalLayout; instance: string }\n | { type: 'layout'; layout: TerminalLayout }\n\nexport type Shell = { name: string; path: string }\n\nexport type BusyResult = { program: string | null } | { error: string }\n\nexport type TerminalPush = {\n title: string\n body: string\n cwd: string\n tabId: number\n}\n\nexport type Image = { mediaType: string; data: string }\n\nexport type Prompt = { text: string; images: Image[] }\n\nexport type Queued = { id: string; prompt: Prompt }\n\nexport type ItemStatus = 'running' | 'completed' | 'failed' | 'stopped'\n\nexport type ItemImage = { mediaType: string; data: string | null }\n\nexport type Question = {\n question: string\n header: string\n multiSelect: boolean\n options: { label: string; description: string }[]\n}\n\nexport type TodoStep = {\n text: string\n status: 'pending' | 'running' | 'completed'\n}\n\nexport type Background = {\n taskId: string | null\n outputPath: string | null\n events: string[]\n}\n\nexport type Item = {\n id: string\n parent: string | null\n time: number | null\n} & (\n | {\n kind: 'user'\n text: string\n images: ItemImage[]\n format: 'text' | 'command' | 'output'\n }\n | { kind: 'assistant'; text: string; message: string }\n | { kind: 'reasoning'; text: string }\n | {\n kind: 'command'\n command: string\n description: string\n output: string\n status: ItemStatus\n background: Background | null\n }\n | {\n kind: 'file_change'\n path: string\n diffs: { before: string; after: string }[]\n output: string\n status: ItemStatus\n }\n | {\n kind: 'web_search'\n query: string | null\n url: string | null\n results: { title: string; url: string }[]\n output: string\n status: ItemStatus\n }\n | { kind: 'skill'; skill: string; output: string; status: ItemStatus }\n | {\n kind: 'tool'\n name: string\n input: Record<string, unknown>\n output: string\n status: ItemStatus\n }\n | { kind: 'todo_list'; steps: TodoStep[] }\n | { kind: 'plan'; plan: string }\n | {\n kind: 'question'\n questions: Question[]\n answers: Record<string, string> | null\n status: ItemStatus\n }\n | {\n kind: 'subagent'\n agent: string\n description: string\n agentId: string | null\n status: ItemStatus\n }\n | {\n kind: 'agent_message'\n target: string | null\n summary: string\n status: ItemStatus\n }\n | { kind: 'compaction' }\n | { kind: 'notice'; text: string }\n | { kind: 'error'; text: string }\n)\n\nexport type PermissionRequest =\n | {\n id: string\n kind: 'approval'\n title: string\n canAlwaysAllow: boolean\n item: Item\n }\n | { id: string; kind: 'plan'; plan: string }\n | { id: string; kind: 'question'; questions: Question[] }\n\nexport type TaskStatus = 'running' | 'completed' | 'failed' | 'stopped'\n\nexport type Activity = {\n running: boolean\n waiting: boolean\n prompted: boolean\n tasks: Record<string, TaskStatus>\n}\n\nexport type Delivery = 'queue' | 'steer'\n\nexport type Decision = 'allow' | 'always' | 'deny'\n\nexport type PushSubscriptionInfo = {\n endpoint: string\n keys: { p256dh: string; auth: string }\n}\n\nexport type Methods = {\n ping: { params: void; result: null }\n sync: { params: void; result: Snapshot }\n 'config.get': { params: void; result: ConfigInfo }\n 'config.save': { params: Config; result: Config }\n 'projects.add': { params: { path: string }; result: Project }\n 'projects.update': {\n params: { path: string; patch: ProjectPatch }\n result: null\n }\n 'projects.remove': { params: { path: string }; result: null }\n 'directories.list': { params: { path: string }; result: Directories }\n 'sessions.update': {\n params: { id: string; patch: SessionPatch }\n result: null\n }\n 'sessions.remove': { params: { id: string }; result: null }\n 'sessions.open': { params: { sessionId: string; cwd: string }; result: null }\n 'sessions.earlier': {\n params: { sessionId: string; before: number }\n result: { items: Item[]; before: number | null }\n }\n 'sessions.image': {\n params: { sessionId: string; itemId: string; index: number }\n result: Image\n }\n 'sessions.agent': {\n params: { sessionId: string; cwd: string; agentId: string; parent: string }\n result: Item[]\n }\n 'sessions.send': {\n params: {\n sessionId: string | null\n cwd: string\n prompt: Prompt\n settings: Settings\n delivery: Delivery\n }\n result: null\n }\n 'sessions.unqueue': {\n params: { sessionId: string; id: string }\n result: null\n }\n 'sessions.steer': {\n params: { sessionId: string; id: string }\n result: null\n }\n 'sessions.interrupt': { params: { sessionId: string }; result: null }\n 'sessions.stopTask': {\n params: { sessionId: string; taskId: string }\n result: null\n }\n 'sessions.configure': {\n params: { sessionId: string; settings: Settings }\n result: null\n }\n 'sessions.respond': {\n params: {\n sessionId: string\n requestId: string\n decision: Decision\n answers: Record<string, string> | null\n }\n result: null\n }\n 'sessions.rewind': { params: Rewind; result: RewindResult }\n 'sessions.fork': {\n params: { sessionId: string; cwd: string; messageId: string }\n result: { sessionId: string }\n }\n 'accounts.list': { params: void; result: Account[] }\n 'accounts.add': {\n params: { provider: Provider; name: string; configDir: string }\n result: null\n }\n 'accounts.update': {\n params: { id: string; name: string; configDir: string }\n result: null\n }\n 'accounts.remove': { params: { id: string }; result: null }\n capabilities: {\n params: { accountId: string; cwd: string }\n result: Capabilities\n }\n 'files.list': { params: { cwd: string }; result: string[] }\n 'files.read': { params: { cwd: string; path: string }; result: FilePreview }\n 'files.upload': { params: { name: string; data: string }; result: string }\n 'tasks.output': {\n params: { sessionId: string; path: string }\n result: { text: string; truncated: boolean } | null\n }\n 'git.status': { params: { cwd: string }; result: GitStatus | null }\n 'git.diff': { params: { cwd: string }; result: string }\n 'git.commit': {\n params: { cwd: string; message: string }\n result: GitStatus | null\n }\n 'git.push': { params: { cwd: string }; result: GitStatus | null }\n 'git.pullRequest': { params: { cwd: string }; result: { url: string } }\n 'git.message': {\n params: { provider: Provider; accountId: string | null; cwd: string }\n result: { message: string }\n }\n 'push.key': { params: void; result: { publicKey: string } }\n 'push.subscribe': { params: PushSubscriptionInfo; result: null }\n 'push.unsubscribe': { params: { endpoint: string }; result: null }\n terminal: { params: TerminalRequest; result: null }\n 'terminal.shells': { params: void; result: Shell[] }\n 'terminal.busy': { params: { id: number }; result: BusyResult }\n 'terminal.paste': { params: { type: string; data: string }; result: string }\n}\n\nexport type Method = keyof Methods\n\nexport type Call = {\n [M in Method]: { id: number; method: M; params: Methods[M]['params'] }\n}[Method]\n\nexport type Reply =\n | { type: 'reply'; id: number; result: unknown }\n | { type: 'reply'; id: number; error: string }\n\nexport type ServerMessage =\n | ServerEvent\n | { type: 'terminal'; event: TerminalEvent }\n | Reply\n\nexport const FRAME_INPUT = 0\nexport const FRAME_REPLY = 1\nexport const FRAME_OUTPUT = 2\nexport const FRAME_REPLAY = 3\n\nexport function encodeFrame(kind: number, id: number, data: Uint8Array) {\n const frame = new Uint8Array(5 + data.length)\n frame[0] = kind\n new DataView(frame.buffer).setUint32(1, id)\n frame.set(data, 5)\n return frame\n}\n\nexport function decodeFrame(frame: Uint8Array) {\n if (frame.length < 5) throw new Error('terminal frame is too short')\n return {\n kind: frame[0],\n id: new DataView(\n frame.buffer,\n frame.byteOffset,\n frame.byteLength\n ).getUint32(1),\n data: frame.subarray(5),\n }\n}\n\nexport type ServerEvent =\n | { type: 'activity'; activity: Record<string, Activity> }\n | { type: 'limits'; accountId: string; limits: RateLimit[] }\n | { type: 'config'; config: Config }\n | { type: 'projects'; projects: Project[] }\n | { type: 'sessions'; sessions: Session[] }\n | { type: 'accounts'; accounts: Account[] }\n | { type: 'started'; sessionId: string; cwd: string }\n | {\n type: 'history'\n sessionId: string\n provider: Provider\n items: Item[]\n requests: PermissionRequest[]\n queue: Queued[]\n settings: Settings | null\n context: Context | null\n before: number | null\n partial: string\n }\n | { type: 'items'; sessionId: string; items: Item[] }\n | { type: 'delta'; sessionId: string; text: string }\n | { type: 'request'; sessionId: string; request: PermissionRequest }\n | { type: 'requestDone'; sessionId: string; requestId: string }\n | { type: 'queue'; sessionId: string; queue: Queued[] }\n | { type: 'settings'; sessionId: string; settings: Settings }\n | { type: 'context'; sessionId: string; context: Context | null }\n | { type: 'notification'; sessionId: string; message: string }\n","import type { ServerEvent, ServerMessage } from '@offsite/core/protocol'\nimport type { WebSocket } from 'ws'\n\nexport type Client = {\n socket: WebSocket\n heardAt: number\n opening: string | null\n sessionId: string | null\n send: (message: ServerMessage) => void\n}\n\nexport const clients = new Set<Client>()\n\nexport function publish(sessionId: string, event: ServerEvent) {\n for (const client of clients)\n if (client.sessionId === sessionId) client.send(event)\n}\n\nexport function broadcast(event: ServerEvent) {\n for (const client of clients) client.send(event)\n}\n","import os from 'node:os'\nimport path from 'node:path'\nimport { Command } from '@commander-js/extra-typings'\n\nlet command = 'web' as 'web' | 'serve' | 'pair' | 'unpair'\nlet name = null as string | null\n\nconst program = new Command('offsite')\n .description('Starts the server and the web app')\n .option('--host <host>', 'Address to listen on', '127.0.0.1')\n .option('--port <port>', 'Port to listen on', '47841')\n .option(\n '--dir <dir>',\n 'Folder for settings and accounts',\n path.join(os.homedir(), '.offsite')\n )\n .option('--no-auth', 'Accept connections without the pairing token')\n .option('--no-pair', \"Don't create a pairing token or print pairing links\")\n\nprogram\n .command('web', { isDefault: true })\n .description('Starts the server and the web app, same as offsite')\n\nprogram\n .command('serve')\n .description('Starts only the server, without the web app')\n .action(() => {\n command = 'serve'\n })\n\nprogram\n .command('pair')\n .description(\n 'Creates a pairing token for another browser and prints its links'\n )\n .option('--name <name>', 'Name to recognize this browser by')\n .action((options) => {\n command = 'pair'\n name = options.name ?? null\n })\n\nprogram\n .command('unpair')\n .description('Picks paired browsers to unpair')\n .action(() => {\n command = 'unpair'\n })\n\nprogram.parse()\n\nconst options = program.opts()\n\nexport const args = {\n ...options,\n dir: path.resolve(options.dir),\n command,\n name,\n}\n\nexport const serverDir = path.join(import.meta.dirname, '..')\n","import {\n mkdirSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport path from 'node:path'\nimport { consola } from 'consola'\nimport { args } from '../args.ts'\n\nexport const home = args.dir\n\nconst lockFile = path.join(home, 'server.pid')\n\nmkdirSync(home, { recursive: true })\n\nexport function lockHome() {\n lock()\n process.on('exit', () => unlinkSync(lockFile))\n}\n\nfunction lock() {\n try {\n writeFileSync(lockFile, `${process.pid}\\n`, { flag: 'wx' })\n return\n } catch (error) {\n if (!hasCode(error, 'EEXIST')) throw error\n }\n let content\n try {\n content = readFileSync(lockFile, 'utf8')\n } catch (error) {\n if (hasCode(error, 'ENOENT')) return lock()\n throw error\n }\n const pid = Number(content)\n if (!Number.isInteger(pid) || pid < 1)\n throw new Error(`invalid pid ${JSON.stringify(content)} in ${lockFile}`)\n if (pid !== process.pid && isRunning(pid)) {\n consola.error(`offsite is already running for ${home} (pid ${pid})`)\n process.exit(1)\n }\n unlinkSync(lockFile)\n lock()\n}\n\nfunction isRunning(pid: number) {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n if (hasCode(error, 'ESRCH')) return false\n if (hasCode(error, 'EPERM')) return true\n throw error\n }\n}\n\nfunction hasCode(error: unknown, code: string) {\n return error instanceof Error && 'code' in error && error.code === code\n}\n\nexport function readJson(name: string): unknown {\n try {\n return JSON.parse(readFileSync(path.join(home, name), 'utf8'))\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw error\n }\n}\n\nexport function writeJson(name: string, value: unknown) {\n const file = path.join(home, name)\n mkdirSync(home, { recursive: true })\n writeFileSync(`${file}.tmp`, `${JSON.stringify(value, null, 2)}\\n`, {\n mode: 0o600,\n })\n renameSync(`${file}.tmp`, file)\n}\n","import os from 'node:os'\nimport path from 'node:path'\nimport type { Config, ConfigInfo, Platform } from '@offsite/core/protocol'\nimport { broadcast } from '../lib/hub.ts'\nimport { home, readJson, writeJson } from './storage.ts'\n\nexport const version = '0.0.0'\n\nconst configFile = path.join(home, 'config.json')\n\nexport const defaults: Config = {\n claudeBaseDir: path.join(os.homedir(), '.claude'),\n composer: {\n provider: 'claude',\n claude: {\n accountId: null,\n model: 'haiku',\n effort: 'low',\n mode: 'bypassPermissions',\n plan: false,\n },\n codex: {\n accountId: null,\n model: null,\n effort: null,\n mode: 'auto',\n plan: false,\n },\n opencode: {\n accountId: 'opencode',\n model: null,\n effort: null,\n mode: null,\n plan: false,\n },\n },\n commitModels: { claude: 'haiku', codex: 'gpt-6-luna', opencode: null },\n terminal: {\n shell: { macos: null, linux: null, windows: null },\n behavior: { terminalIdentity: 'offsite', shellIntegration: true },\n },\n}\n\nconst retired = [\n 'theme',\n 'diff',\n 'terminal.font',\n 'terminal.cursor',\n 'terminal.padding',\n 'terminal.scrollback',\n 'terminal.boldIsBright',\n 'terminal.behavior.modernizeShiftEnter',\n 'terminal.behavior.pasteBrowserImages',\n 'terminal.behavior.captureShortcuts',\n 'terminal.behavior.bellFlash',\n 'terminal.behavior.bellSound',\n 'terminal.behavior.clickToMoveCursor',\n 'terminal.behavior.optionAsMeta',\n 'terminal.behavior.confirmCloseBusyTab',\n 'composer.accountId',\n 'composer.model',\n 'composer.effort',\n 'composer.permissionMode',\n]\n\nconst choices: Record<string, string[]> = {\n 'composer.provider': ['claude', 'codex', 'opencode'],\n 'composer.claude.effort': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'composer.claude.mode': [\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n 'plan',\n 'dontAsk',\n 'auto',\n ],\n 'composer.codex.mode': ['read-only', 'auto', 'full-access'],\n 'terminal.behavior.terminalIdentity': ['offsite', 'ghostty', 'iterm2'],\n}\nconst nullable = [\n 'composer.claude.accountId',\n 'composer.claude.model',\n 'composer.claude.effort',\n 'composer.claude.mode',\n 'composer.codex.accountId',\n 'composer.codex.model',\n 'composer.codex.effort',\n 'composer.codex.mode',\n 'composer.opencode.accountId',\n 'composer.opencode.model',\n 'composer.opencode.effort',\n 'composer.opencode.mode',\n 'commitModels.claude',\n 'commitModels.codex',\n 'commitModels.opencode',\n 'terminal.shell.macos',\n 'terminal.shell.linux',\n 'terminal.shell.windows',\n]\n\nexport function platform(): Platform {\n if (process.platform === 'darwin') return 'macos'\n if (process.platform === 'linux') return 'linux'\n if (process.platform === 'win32') return 'windows'\n throw new Error(`unsupported platform ${process.platform}`)\n}\n\nexport function defaultShell() {\n if (process.platform === 'win32') return process.env.COMSPEC ?? 'cmd.exe'\n return os.userInfo().shell ?? '/bin/sh'\n}\n\nexport function configInfo(): ConfigInfo {\n return {\n config: readConfig(),\n defaults,\n platform: platform(),\n version,\n defaultShell: defaultShell(),\n }\n}\n\nexport function readConfig() {\n let user: unknown\n try {\n user = readJson('config.json')\n } catch (error) {\n console.warn(`invalid ${configFile}, using the default config: ${error}`)\n return structuredClone(defaults)\n }\n if (user === null) return structuredClone(defaults)\n if (!isObject(user)) {\n console.warn(`${configFile} is not an object, using the default config`)\n return structuredClone(defaults)\n }\n let config: unknown = structuredClone(defaults)\n for (const [key, value] of Object.entries(user))\n config = merge(config, [key], value)\n return config as Config\n}\n\nexport function saveConfig(value: unknown) {\n const error = invalid(value, defaults, [])\n if (error !== null) throw new Error(error)\n writeJson('config.json', value)\n process.env.CLAUDE_CONFIG_DIR = (value as Config).claudeBaseDir\n broadcast({ type: 'config', config: value as Config })\n return value as Config\n}\n\nfunction merge(config: unknown, keys: string[], user: unknown): unknown {\n if (retired.includes(keys.join('.'))) return config\n const template = keys.reduce<unknown>(\n (value, key) => (isObject(value) ? value[key] : undefined),\n config\n )\n if (isObject(template) && isObject(user)) {\n let next = config\n for (const [key, value] of Object.entries(user))\n next = merge(next, [...keys, key], value)\n return next\n }\n const candidate = structuredClone(config) as Record<string, unknown>\n const parent = keys\n .slice(0, -1)\n .reduce((value, key) => value[key] as Record<string, unknown>, candidate)\n parent[keys[keys.length - 1]] = user\n const error = invalid(candidate, defaults, [])\n if (error === null) return candidate\n console.warn(\n `invalid ${keys.join('.')} in ${configFile}, using its default: ${error}`\n )\n return config\n}\n\nfunction invalid(\n value: unknown,\n template: unknown,\n keys: string[]\n): string | null {\n const name = keys.join('.')\n if (isObject(template)) {\n if (!isObject(value)) return `${name || 'config'} must be an object`\n for (const key of Object.keys(value))\n if (!(key in template))\n return `unknown setting ${[...keys, key].join('.')}`\n for (const key of Object.keys(template)) {\n if (!(key in value)) return `missing setting ${[...keys, key].join('.')}`\n const error = invalid(value[key], template[key], [...keys, key])\n if (error !== null) return error\n }\n return null\n }\n if (nullable.includes(name) && value === null) return null\n if (name === 'claudeBaseDir')\n return typeof value === 'string' && path.isAbsolute(value)\n ? null\n : 'claudeBaseDir must be an absolute path'\n if (name in choices) {\n if (choices[name].includes(value as string)) return null\n return `${name} must be one of ${choices[name].join(', ')}`\n }\n if (template === null) {\n if (typeof value === 'string') return null\n return `${name} must be text or null`\n }\n if (typeof value !== typeof template)\n return `${name} must be a ${typeof template}`\n return null\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { type ChildProcessByStdio, spawn } from 'node:child_process'\nimport { statSync } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport readline from 'node:readline'\nimport type { Readable, Writable } from 'node:stream'\nimport { version } from '../../storage/config.ts'\nimport { publishCodexLimits } from './accounts.ts'\nimport type { RateLimitSnapshot } from './types.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\n\nexport type Params = Record<string, unknown>\n\nexport type ThreadListener = {\n notify: (method: string, params: Params) => void\n request: (id: number | string, method: string, params: Params) => void\n exited: () => void\n}\n\ntype Incoming = {\n id?: number | string\n method?: string\n params?: Params\n result?: unknown\n error?: { message: string }\n}\n\nexport const codexBaseDir =\n process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex')\n\nconst servers = new Map<string, AppServer>()\n\nexport function appServer(home: string) {\n const existing = servers.get(home)\n if (existing !== undefined) return existing\n const server = new AppServer(home)\n servers.set(home, server)\n return server\n}\n\nexport function stopAppServers() {\n for (const server of servers.values()) server.stop()\n}\n\nexport function findCodex() {\n const name = process.platform === 'win32' ? 'codex.exe' : 'codex'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile())\n return candidate\n }\n return null\n}\n\nexport class AppServer {\n readonly home: string\n readonly threads = new Map<string, ThreadListener>()\n private readonly child: ChildProcessByStdio<Writable, Readable, null>\n private readonly waiting = new Map<\n number,\n { resolve: (result: unknown) => void; reject: (error: Error) => void }\n >()\n private readonly ready: Promise<void>\n private next = 0\n private idleTimer: NodeJS.Timeout | undefined\n private exited: Error | null = null\n\n constructor(home: string) {\n const executable = findCodex()\n if (executable === null)\n throw new Error('Codex is not installed or not on the PATH')\n this.home = home\n this.child = spawn(executable, ['app-server'], {\n env: { ...process.env, CODEX_HOME: home },\n stdio: ['pipe', 'pipe', 'ignore'],\n })\n readline\n .createInterface({ input: this.child.stdout })\n .on('line', (line) => this.receive(line))\n this.child.on('error', (error) => this.exit(error))\n this.child.on('exit', (code) =>\n this.exit(new Error(`Codex stopped (exit code ${code})`))\n )\n this.ready = this.call('initialize', {\n clientInfo: { name: 'offsite', title: 'Offsite', version },\n capabilities: { experimentalApi: true, requestAttestation: false },\n }).then(() => this.write({ method: 'initialized' }))\n this.armIdleTimer()\n }\n\n async request<T>(method: string, params: Params): Promise<T> {\n await this.ready\n this.armIdleTimer()\n return (await this.call(method, params)) as T\n }\n\n reply(id: number | string, result: unknown) {\n this.write({ id, result })\n }\n\n replyError(id: number | string, message: string) {\n this.write({ id, error: { code: -32000, message } })\n }\n\n stop() {\n clearTimeout(this.idleTimer)\n if (servers.get(this.home) === this) servers.delete(this.home)\n this.child.stdin.end()\n }\n\n private call(method: string, params: Params) {\n if (this.exited !== null) return Promise.reject(this.exited)\n this.next += 1\n const id = this.next\n const result = new Promise<unknown>((resolve, reject) =>\n this.waiting.set(id, { resolve, reject })\n )\n this.write({ id, method, params })\n return result\n }\n\n private write(message: Params) {\n if (this.exited !== null) return\n this.child.stdin.write(`${JSON.stringify(message)}\\n`)\n }\n\n private receive(line: string) {\n let message: Incoming\n try {\n message = JSON.parse(line) as Incoming\n } catch {\n console.warn(`ignoring a Codex line that is not JSON: ${line}`)\n return\n }\n if (message.method === undefined) {\n if (typeof message.id !== 'number') return\n const waiter = this.waiting.get(message.id)\n if (waiter === undefined) return\n this.waiting.delete(message.id)\n if (message.error !== undefined)\n waiter.reject(new Error(message.error.message))\n else waiter.resolve(message.result)\n return\n }\n const params = message.params ?? {}\n const listener =\n typeof params.threadId === 'string'\n ? this.threads.get(params.threadId)\n : undefined\n if (message.id !== undefined) {\n if (listener === undefined)\n this.replyError(message.id, `offsite does not handle ${message.method}`)\n else listener.request(message.id, message.method, params)\n return\n }\n if (message.method === 'account/rateLimits/updated') {\n publishCodexLimits(this.home, params.rateLimits as RateLimitSnapshot)\n return\n }\n listener?.notify(message.method, params)\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n this.idleTimer = setTimeout(() => {\n if (this.threads.size > 0) this.armIdleTimer()\n else this.stop()\n }, IDLE_LIMIT)\n }\n\n private exit(error: Error) {\n if (this.exited !== null) return\n this.exited = error\n clearTimeout(this.idleTimer)\n if (servers.get(this.home) === this) servers.delete(this.home)\n for (const waiter of this.waiting.values()) waiter.reject(error)\n this.waiting.clear()\n for (const listener of this.threads.values()) listener.exited()\n this.threads.clear()\n }\n}\n","import { readdirSync, realpathSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Account, Capabilities, RateLimit } from '@offsite/core/protocol'\nimport { type StoredAccount, storedAccounts } from '../../services/accounts.ts'\nimport { broadcast } from '../hub.ts'\nimport { type AppServer, appServer, codexBaseDir } from './app-server.ts'\nimport type { CodexModel, RateLimitSnapshot, Skill } from './types.ts'\n\nconst privateEntries = [\n 'auth.json',\n 'models_cache.json',\n 'log',\n 'memories',\n 'tmp',\n]\n\ntype CodexLogin =\n | { type: 'apiKey' }\n | { type: 'chatgpt'; email: string | null; planType: string }\n | { type: 'amazonBedrock' }\n\nconst windowNames = new Map([\n [300, 'five_hour'],\n [10080, 'seven_day'],\n])\n\nexport async function codexAccount(account: StoredAccount): Promise<Account> {\n const linked = isMirror(account.configDir)\n const base = { ...account, email: null, plan: null, limits: [], linked }\n try {\n const server = appServer(account.configDir)\n const result = await server.request<{ account: CodexLogin | null }>(\n 'account/read',\n {}\n )\n if (result.account === null)\n return {\n ...base,\n error: `Not logged in. Run CODEX_HOME=${account.configDir} codex login in a terminal`,\n valid: false,\n }\n switch (result.account.type) {\n case 'chatgpt':\n return {\n ...base,\n email: result.account.email,\n plan: result.account.planType,\n error: null,\n limits: await rateLimits(server),\n valid: linked,\n }\n case 'apiKey':\n return { ...base, plan: 'API key', error: null, valid: linked }\n case 'amazonBedrock':\n return { ...base, plan: 'Amazon Bedrock', error: null, valid: linked }\n }\n } catch (error) {\n return {\n ...base,\n error: error instanceof Error ? error.message : String(error),\n valid: false,\n }\n }\n}\n\nexport async function codexCapabilities(\n account: StoredAccount,\n cwd: string\n): Promise<Capabilities> {\n const server = appServer(account.configDir)\n const models: CodexModel[] = []\n let cursor: string | null = null\n do {\n const page: { data: CodexModel[]; nextCursor: string | null } =\n await server.request('model/list', { cursor })\n models.push(...page.data)\n cursor = page.nextCursor\n } while (cursor !== null)\n return {\n models: models\n .filter((model) => !model.hidden)\n .map((model) => ({\n value: model.model,\n name: model.displayName,\n description: model.description,\n efforts: model.supportedReasoningEfforts.map(\n (effort) => effort.reasoningEffort\n ),\n })),\n commands: [\n {\n name: 'compact',\n description: 'Summarize the conversation to free up context',\n hint: '',\n },\n ...(await skills(server, cwd)).map((skill) => ({\n name: skill.name,\n description: skill.description,\n hint: '',\n })),\n ],\n agents: [],\n }\n}\n\nexport async function skills(server: AppServer, cwd: string) {\n const result = await server.request<{\n data: { cwd: string; skills: (Skill & { enabled: boolean })[] }[]\n }>('skills/list', { cwds: [cwd] })\n return result.data.flatMap((entry) =>\n entry.skills.filter((skill) => skill.enabled)\n )\n}\n\nexport function publishCodexLimits(home: string, snapshot: RateLimitSnapshot) {\n for (const account of storedAccounts())\n if (account.provider === 'codex' && account.configDir === home)\n broadcast({\n type: 'limits',\n accountId: account.id,\n limits: toLimits(snapshot),\n })\n}\n\nasync function rateLimits(server: AppServer) {\n try {\n const result = await server.request<{ rateLimits: RateLimitSnapshot }>(\n 'account/rateLimits/read',\n {}\n )\n return toLimits(result.rateLimits)\n } catch (error) {\n console.warn(`could not read Codex usage limits: ${error}`)\n return []\n }\n}\n\nfunction toLimits(snapshot: RateLimitSnapshot): RateLimit[] {\n return [snapshot.primary, snapshot.secondary].flatMap((window) =>\n window === null\n ? []\n : [\n {\n window:\n (window.windowDurationMins === null\n ? undefined\n : windowNames.get(window.windowDurationMins)) ??\n `${window.windowDurationMins ?? 0}m`,\n utilization: window.usedPercent / 100,\n resetsAt: window.resetsAt,\n rejected: window.usedPercent >= 100,\n },\n ]\n )\n}\n\nfunction isMirror(dir: string) {\n try {\n if (realpathSync(dir) === realpathSync(codexBaseDir)) return true\n return readdirSync(codexBaseDir)\n .filter(\n (name) =>\n !privateEntries.includes(name) && !/-(wal|shm|journal)$/.test(name)\n )\n .every(\n (name) =>\n realpathSync(path.join(dir, name)) ===\n realpathSync(path.join(codexBaseDir, name))\n )\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n","import type { Item, ItemImage, ItemStatus } from '@offsite/core/protocol'\nimport type { Status, ThreadItem, Turn, UserInput } from './types.ts'\n\nconst statuses: Record<Status | 'interrupted', ItemStatus> = {\n inProgress: 'running',\n completed: 'completed',\n failed: 'failed',\n declined: 'stopped',\n interrupted: 'stopped',\n}\n\nexport function turnItems(turns: Turn[], parent: string | null) {\n return turns.flatMap((turn) => [\n ...turn.items.flatMap((item) =>\n toItems(\n turn.id,\n item,\n parent,\n turn.startedAt === null ? null : turn.startedAt * 1000\n )\n ),\n ...(turn.status === 'failed' && turn.error !== null\n ? [errorItem(`${turn.id}:error`, turn.error.message)]\n : []),\n ])\n}\n\nexport function itemId(turnId: string, id: string) {\n return `${turnId}:${id}`\n}\n\nexport function turnOf(itemId: string) {\n const index = itemId.indexOf(':')\n if (index < 0) throw new Error(`${itemId} is not a Codex item`)\n return itemId.slice(0, index)\n}\n\nexport function errorItem(id: string, text: string): Item {\n return { id, parent: null, time: Date.now(), kind: 'error', text }\n}\n\nexport function toItems(\n turnId: string,\n item: ThreadItem,\n parent: string | null,\n time: number | null\n): Item[] {\n const base = { id: itemId(turnId, item.id), parent, time }\n switch (item.type) {\n case 'userMessage':\n return [\n {\n ...base,\n kind: 'user',\n text: item.content\n .flatMap((input) => userText(input))\n .join('\\n')\n .trim(),\n images: item.content.flatMap((input) => userImages(input)),\n format: 'text',\n },\n ]\n case 'agentMessage':\n return item.text.trim() === ''\n ? []\n : [{ ...base, kind: 'assistant', text: item.text, message: base.id }]\n case 'reasoning': {\n const text = [...item.summary, ...item.content].join('\\n\\n').trim()\n return text === '' ? [] : [{ ...base, kind: 'reasoning', text }]\n }\n case 'plan':\n return [{ ...base, kind: 'plan', plan: item.text }]\n case 'commandExecution':\n return [\n {\n ...base,\n kind: 'command',\n command: item.command,\n description: '',\n output: item.aggregatedOutput ?? '',\n status: statuses[item.status],\n background: null,\n },\n ]\n case 'fileChange':\n return item.changes.map((change, index) => ({\n ...base,\n id: `${base.id}:${index}`,\n kind: 'file_change',\n path: change.path,\n diffs:\n change.kind.type === 'add'\n ? [{ before: '', after: change.diff }]\n : change.kind.type === 'delete'\n ? [{ before: change.diff, after: '' }]\n : hunks(change.diff),\n output: '',\n status: statuses[item.status],\n }))\n case 'mcpToolCall':\n return [\n {\n ...base,\n kind: 'tool',\n name: `${item.server}.${item.tool}`,\n input: record(item.arguments),\n output:\n item.error?.message ??\n (item.result === null ? '' : contentText(item.result.content)),\n status: statuses[item.status],\n },\n ]\n case 'dynamicToolCall':\n return [\n {\n ...base,\n kind: 'tool',\n name: item.tool,\n input: record(item.arguments),\n output: contentText(item.contentItems ?? []),\n status: statuses[item.status],\n },\n ]\n case 'collabAgentToolCall':\n if (item.tool === 'spawnAgent')\n return [\n {\n ...base,\n kind: 'subagent',\n agent: item.model ?? 'Agent',\n description: item.prompt ?? '',\n agentId: item.receiverThreadIds[0] ?? null,\n status: statuses[item.status],\n },\n ]\n return [\n {\n ...base,\n kind: 'agent_message',\n target: item.receiverThreadIds[0] ?? null,\n summary: item.prompt ?? item.tool,\n status: statuses[item.status],\n },\n ]\n case 'webSearch':\n return [\n {\n ...base,\n kind: 'web_search',\n query:\n item.action?.type === 'search'\n ? (item.action.query ?? item.query)\n : item.query === ''\n ? null\n : item.query,\n url:\n item.action?.type === 'openPage' ||\n item.action?.type === 'findInPage'\n ? item.action.url\n : null,\n results: [],\n output: '',\n status: 'completed',\n },\n ]\n case 'imageView':\n return [\n {\n ...base,\n kind: 'tool',\n name: 'view_image',\n input: { path: item.path },\n output: '',\n status: 'completed',\n },\n ]\n case 'contextCompaction':\n return [{ ...base, kind: 'compaction' }]\n case 'hookPrompt':\n case 'functionCallOutput':\n case 'subAgentActivity':\n case 'sleep':\n case 'imageGeneration':\n case 'enteredReviewMode':\n case 'exitedReviewMode':\n return []\n }\n}\n\nfunction userText(input: UserInput) {\n switch (input.type) {\n case 'text':\n return [input.text]\n case 'skill':\n case 'mention':\n return [`$${input.name}`]\n case 'image':\n case 'localImage':\n return []\n }\n}\n\nfunction userImages(input: UserInput): ItemImage[] {\n if (input.type !== 'image') return []\n const match = /^data:([^;,]+);base64,(.*)$/.exec(input.url)\n if (match === null) return []\n return [{ mediaType: match[1], data: match[2] }]\n}\n\nexport function hunks(diff: string) {\n const result: { before: string; after: string }[] = []\n let before: string[] = []\n let after: string[] = []\n let inside = false\n function flush() {\n if (inside)\n result.push({ before: before.join('\\n'), after: after.join('\\n') })\n before = []\n after = []\n }\n for (const line of diff.split('\\n')) {\n if (line.startsWith('@@')) {\n flush()\n inside = true\n continue\n }\n if (!inside || line === '' || line.startsWith('\\\\')) continue\n if (line.startsWith('-')) before.push(line.slice(1))\n else if (line.startsWith('+')) after.push(line.slice(1))\n else {\n before.push(line.slice(1))\n after.push(line.slice(1))\n }\n }\n flush()\n return result\n}\n\nfunction contentText(content: unknown[]) {\n return content\n .map((block) =>\n typeof block === 'object' &&\n block !== null &&\n 'text' in block &&\n typeof block.text === 'string'\n ? block.text\n : JSON.stringify(block)\n )\n .join('\\n')\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value === 'object' && value !== null && !Array.isArray(value))\n return value as Record<string, unknown>\n return { value }\n}\n","import type { Activity } from '@offsite/core/protocol'\nimport type { Run } from './claude/index.ts'\nimport type { CodexRun } from './codex/index.ts'\nimport { broadcast } from './hub.ts'\nimport type { OpenCodeRun } from './opencode/index.ts'\n\nexport const runs = new Map<string, Run | CodexRun | OpenCodeRun>()\n\nexport function activity() {\n const result: Record<string, Activity> = {}\n for (const run of runs.values())\n result[run.sessionId] = {\n running: run.running,\n waiting: run.pending.size > 0,\n prompted: run.prompted,\n tasks: run.tasks,\n }\n return result\n}\n\nexport function broadcastActivity() {\n broadcast({ type: 'activity', activity: activity() })\n}\n","import type { Item, PermissionRequest } from '@offsite/core/protocol'\nimport type { Params } from './app-server.ts'\nimport { itemId } from './items.ts'\nimport type { Question } from './types.ts'\n\nexport function toRequest(\n requestId: string,\n method: string,\n params: Params,\n items: Map<string, Item>\n): PermissionRequest | null {\n const turnId = params.turnId as string\n switch (method) {\n case 'item/commandExecution/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Run this command?',\n canAlwaysAllow: true,\n item: items.get(itemId(turnId, params.itemId as string)) ?? {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'command',\n command: (params.command as string | null) ?? '',\n description: '',\n output: '',\n status: 'running',\n background: null,\n },\n }\n case 'item/fileChange/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Apply these changes?',\n canAlwaysAllow: true,\n item: items.get(`${itemId(turnId, params.itemId as string)}:0`) ?? {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: 'apply_patch',\n input: {},\n output: '',\n status: 'running',\n },\n }\n case 'item/permissions/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Grant these permissions?',\n canAlwaysAllow: true,\n item: {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: 'permissions',\n input: params.permissions as Record<string, unknown>,\n output: '',\n status: 'running',\n },\n }\n case 'item/tool/requestUserInput':\n return {\n id: requestId,\n kind: 'question',\n questions: (params.questions as Question[]).map((question) => ({\n question: question.question,\n header: question.header,\n multiSelect: false,\n options: question.options ?? [],\n })),\n }\n default:\n return null\n }\n}\n\nexport function reply(\n method: string,\n params: Params,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n) {\n switch (method) {\n case 'item/commandExecution/requestApproval':\n case 'item/fileChange/requestApproval':\n return {\n decision: {\n allow: 'accept',\n always: 'acceptForSession',\n deny: 'decline',\n }[decision],\n }\n case 'item/permissions/requestApproval':\n return decision === 'deny'\n ? { permissions: {}, scope: 'turn' }\n : {\n permissions: params.permissions,\n scope: decision === 'always' ? 'session' : 'turn',\n }\n case 'item/tool/requestUserInput':\n return {\n answers: Object.fromEntries(\n (params.questions as Question[]).flatMap((question) => {\n const answer = answers?.[question.question]\n return decision === 'deny' || answer === undefined\n ? []\n : [[question.id, { answers: [answer] }]]\n })\n ),\n }\n }\n throw new Error(`offsite cannot answer ${method}`)\n}\n","import { randomUUID } from 'node:crypto'\nimport type {\n Context,\n Item,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport { storedAccount } from '../../services/accounts.ts'\nimport { publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport { skills } from './accounts.ts'\nimport {\n type AppServer,\n appServer,\n type Params,\n type ThreadListener,\n} from './app-server.ts'\nimport { errorItem, itemId, toItems } from './items.ts'\nimport { reply, toRequest } from './requests.ts'\nimport type { ThreadItem, ThreadStarted, Turn, UserInput } from './types.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\n\nconst presets = new Map([\n [\n 'read-only',\n {\n approvalPolicy: 'on-request',\n sandbox: 'read-only',\n sandboxPolicy: { type: 'readOnly', networkAccess: false },\n },\n ],\n [\n 'auto',\n {\n approvalPolicy: 'on-request',\n sandbox: 'workspace-write',\n sandboxPolicy: {\n type: 'workspaceWrite',\n writableRoots: [],\n networkAccess: false,\n excludeTmpdirEnvVar: false,\n excludeSlashTmp: false,\n },\n },\n ],\n [\n 'full-access',\n {\n approvalPolicy: 'never',\n sandbox: 'danger-full-access',\n sandboxPolicy: { type: 'dangerFullAccess' },\n },\n ],\n])\n\ntype Pending = {\n request: PermissionRequest\n id: number | string\n method: string\n params: Params\n}\n\nfunction codexServer(settings: Settings) {\n return appServer(storedAccount('codex', settings.accountId).configDir)\n}\n\nexport class CodexRun implements ThreadListener {\n readonly provider = 'codex'\n readonly sessionId: string\n readonly cwd: string\n readonly server: AppServer\n readonly pending = new Map<string, Pending>()\n readonly items = new Map<string, Item>()\n readonly closed: Promise<void>\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly model: string\n private readonly close: () => void\n private turnId: string | null = null\n private idleTimer: NodeJS.Timeout | undefined\n\n static async start(cwd: string, settings: Settings) {\n const server = codexServer(settings)\n const result = await server.request<ThreadStarted>('thread/start', {\n cwd,\n approvalsReviewer: 'user',\n ...(settings.model === null ? {} : { model: settings.model }),\n ...threadPreset(settings),\n })\n return new CodexRun(server, result.thread.id, cwd, result.model, settings)\n }\n\n static async resume(sessionId: string, cwd: string, settings: Settings) {\n const server = codexServer(settings)\n const result = await server.request<ThreadStarted>('thread/resume', {\n threadId: sessionId,\n approvalsReviewer: 'user',\n excludeTurns: true,\n ...(settings.model === null ? {} : { model: settings.model }),\n ...threadPreset(settings),\n })\n return new CodexRun(server, sessionId, cwd, result.model, settings)\n }\n\n private constructor(\n server: AppServer,\n sessionId: string,\n cwd: string,\n model: string,\n settings: Settings\n ) {\n this.server = server\n this.sessionId = sessionId\n this.cwd = cwd\n this.model = model\n this.settings = settings\n const closed = Promise.withResolvers<void>()\n this.closed = closed.promise\n this.close = closed.resolve\n server.threads.set(sessionId, this)\n runs.set(sessionId, this)\n this.armIdleTimer()\n }\n\n async submit(prompt: Prompt, delivery: 'queue' | 'steer') {\n if (!this.running) {\n await this.startTurn(prompt)\n return\n }\n switch (delivery) {\n case 'steer':\n if (this.turnId === null) throw new Error('Codex has no turn to steer')\n await this.server.request('turn/steer', {\n threadId: this.sessionId,\n input: await this.input(prompt),\n expectedTurnId: this.turnId,\n })\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer').catch((error: unknown) =>\n this.fail(error)\n )\n }\n\n configure(settings: Settings) {\n this.settings = { ...settings, accountId: this.settings.accountId }\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings: this.settings,\n })\n }\n\n async interrupt() {\n if (this.turnId === null) return\n await this.server.request('turn/interrupt', {\n threadId: this.sessionId,\n turnId: this.turnId,\n })\n }\n\n stopTask(): Promise<void> {\n throw new Error('Codex has no background tasks to stop')\n }\n\n respond(\n requestId: string,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n this.server.reply(\n pending.id,\n reply(pending.method, pending.params, decision, answers)\n )\n this.settle(requestId)\n }\n\n stop() {\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.server.threads.delete(this.sessionId)\n clearTimeout(this.idleTimer)\n this.server\n .request('thread/unsubscribe', { threadId: this.sessionId })\n .catch((error: unknown) =>\n console.warn(`could not unload Codex thread: ${error}`)\n )\n .finally(() => this.end())\n }\n\n exited() {\n this.put(errorItem(randomUUID(), 'Codex stopped'))\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.end()\n }\n\n notify(method: string, params: Params) {\n switch (method) {\n case 'turn/started': {\n const turn = params.turn as Turn\n this.turnId = turn.id\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n return\n }\n case 'turn/completed': {\n const turn = params.turn as Turn\n if (turn.status === 'failed' && turn.error !== null)\n this.put(errorItem(`${turn.id}:error`, turn.error.message))\n this.finishTurn()\n return\n }\n case 'item/started':\n case 'item/completed':\n for (const item of toItems(\n params.turnId as string,\n params.item as ThreadItem,\n null,\n Date.now()\n ))\n this.put(item)\n return\n case 'item/agentMessage/delta':\n this.partial += params.delta as string\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: params.delta as string,\n })\n return\n case 'item/commandExecution/outputDelta': {\n const item = this.items.get(\n itemId(params.turnId as string, params.itemId as string)\n )\n if (item?.kind === 'command')\n this.put({ ...item, output: item.output + (params.delta as string) })\n return\n }\n case 'turn/plan/updated': {\n const plan = params.plan as {\n step: string\n status: 'pending' | 'inProgress' | 'completed'\n }[]\n this.put({\n id: `${params.turnId as string}:plan`,\n parent: null,\n time: Date.now(),\n kind: 'todo_list',\n steps: plan.map((step) => ({\n text: step.step,\n status: step.status === 'inProgress' ? 'running' : step.status,\n })),\n })\n return\n }\n case 'thread/tokenUsage/updated': {\n const usage = params.tokenUsage as {\n last: { totalTokens: number }\n modelContextWindow: number | null\n }\n this.context = {\n tokens: usage.last.totalTokens,\n window: usage.modelContextWindow,\n }\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context: this.context,\n })\n return\n }\n case 'error': {\n const error = params.error as { message: string }\n if (params.willRetry !== true)\n this.put(errorItem(randomUUID(), error.message))\n return\n }\n case 'serverRequest/resolved':\n this.settle(String(params.requestId))\n }\n }\n\n request(id: number | string, method: string, params: Params) {\n if (method === 'mcpServer/elicitation/request') {\n this.server.reply(id, { action: 'decline', content: null, _meta: null })\n return\n }\n const request = toRequest(String(id), method, params, this.items)\n if (request === null) {\n this.server.replyError(id, `offsite does not handle ${method}`)\n return\n }\n this.pending.set(request.id, { request, id, method, params })\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request,\n })\n broadcastActivity()\n }\n\n private async startTurn(prompt: Prompt) {\n clearTimeout(this.idleTimer)\n this.running = true\n this.prompted = true\n broadcastActivity()\n try {\n if (prompt.text.trim() === '/compact' && prompt.images.length === 0) {\n await this.server.request('thread/compact/start', {\n threadId: this.sessionId,\n })\n return\n }\n const model = this.settings.model ?? this.model\n const preset = modePreset(this.settings.mode)\n const result = await this.server.request<{ turn: Turn }>('turn/start', {\n threadId: this.sessionId,\n input: await this.input(prompt),\n model,\n approvalsReviewer: 'user',\n summary: 'detailed',\n ...(this.settings.effort === null\n ? {}\n : { effort: this.settings.effort }),\n ...(preset === null\n ? {}\n : {\n approvalPolicy: preset.approvalPolicy,\n sandboxPolicy: preset.sandboxPolicy,\n }),\n collaborationMode: {\n mode: this.settings.plan ? 'plan' : 'default',\n settings: {\n model,\n reasoning_effort: this.settings.effort,\n developer_instructions: null,\n },\n },\n })\n this.turnId = result.turn.id\n } catch (error) {\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n throw error\n }\n }\n\n private async input(prompt: Prompt): Promise<UserInput[]> {\n const match = /^\\/(\\S+)\\s*([\\s\\S]*)$/.exec(prompt.text)\n const skill =\n match === null\n ? undefined\n : (await skills(this.server, this.cwd)).find(\n (item) => item.name === match[1]\n )\n const text = skill === undefined || match === null ? prompt.text : match[2]\n return [\n ...(skill === undefined\n ? []\n : [{ type: 'skill' as const, name: skill.name, path: skill.path }]),\n ...(text === ''\n ? []\n : [{ type: 'text' as const, text, text_elements: [] as [] }]),\n ...prompt.images.map((image) => ({\n type: 'image' as const,\n url: `data:${image.mediaType};base64,${image.data}`,\n })),\n ]\n }\n\n private finishTurn() {\n this.partial = ''\n this.turnId = null\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.startTurn(next.prompt).catch((error: unknown) => this.fail(error))\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private settle(requestId: string) {\n if (!this.pending.delete(requestId)) return\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private put(item: Item) {\n this.items.set(item.id, item)\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items: [item],\n })\n }\n\n private fail(error: unknown) {\n this.put(\n errorItem(\n randomUUID(),\n error instanceof Error ? error.message : String(error)\n )\n )\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private end() {\n clearTimeout(this.idleTimer)\n for (const requestId of [...this.pending.keys()]) this.settle(requestId)\n this.running = false\n broadcastActivity()\n this.close()\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction threadPreset(settings: Settings) {\n const preset = modePreset(settings.mode)\n if (preset === null) return {}\n return { approvalPolicy: preset.approvalPolicy, sandbox: preset.sandbox }\n}\n\nfunction modePreset(mode: string | null) {\n if (mode === null) return null\n const preset = presets.get(mode)\n if (preset === undefined) throw new Error(`Codex has no ${mode} mode`)\n return preset\n}\n","import { existsSync } from 'node:fs'\nimport type { Item, ServerEvent } from '@offsite/core/protocol'\nimport { storedAccount } from '../../services/accounts.ts'\nimport { runs } from '../live.ts'\nimport { appServer, codexBaseDir, findCodex } from './app-server.ts'\nimport { turnItems, turnOf } from './items.ts'\nimport type { Thread, ThreadItem, ThreadStarted, Turn } from './types.ts'\n\nfunction codexInstalled() {\n return findCodex() !== null && existsSync(codexBaseDir)\n}\n\nexport async function codexThreads(paths: string[]) {\n if (paths.length === 0 || !codexInstalled()) return []\n const server = appServer(codexBaseDir)\n const threads: Thread[] = []\n let cursor: string | null = null\n do {\n const page: { data: Thread[]; nextCursor: string | null } =\n await server.request('thread/list', {\n cwd: paths,\n cursor,\n limit: 100,\n sortKey: 'updated_at',\n sourceKinds: ['cli', 'vscode', 'appServer'],\n })\n threads.push(...page.data)\n cursor = page.nextCursor\n } while (cursor !== null)\n return threads\n}\n\nexport async function codexHistory(sessionId: string): Promise<ServerEvent> {\n const run = codexRun(sessionId)\n const thread = await readThread(sessionId)\n const items = turnItems(thread.turns, null)\n const ids = new Set(items.map((item) => item.id))\n return {\n type: 'history',\n sessionId,\n provider: 'codex',\n items: [\n ...items,\n ...[...(run?.items.values() ?? [])].filter((item) => !ids.has(item.id)),\n ],\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context: run?.context ?? null,\n before: null,\n partial: run?.partial ?? '',\n }\n}\n\nexport async function codexAgent(\n agentId: string,\n parent: string\n): Promise<Item[]> {\n return turnItems((await readThread(agentId)).turns, parent)\n}\n\nexport async function renameThread(sessionId: string, name: string) {\n await server(sessionId).request('thread/name/set', {\n threadId: sessionId,\n name,\n })\n}\n\nexport async function deleteThread(sessionId: string) {\n await server(sessionId).request('thread/delete', { threadId: sessionId })\n}\n\nexport async function forkThread(sessionId: string, messageId: string) {\n const result = await server(sessionId).request<ThreadStarted>('thread/fork', {\n threadId: sessionId,\n lastTurnId: turnOf(messageId),\n excludeTurns: true,\n })\n return { sessionId: result.thread.id }\n}\n\nexport async function revertThread(sessionId: string, messageId: string) {\n await server(sessionId).request('thread/revert', {\n threadId: sessionId,\n beforeTurnId: turnOf(messageId),\n })\n}\n\nexport async function codexCommitMessage(\n accountId: string | null,\n cwd: string,\n model: string,\n prompt: string\n) {\n const server = appServer(storedAccount('codex', accountId).configDir)\n const started = await server.request<ThreadStarted>('thread/start', {\n cwd,\n model,\n ephemeral: true,\n approvalPolicy: 'never',\n sandbox: 'read-only',\n developerInstructions: 'You write concise git commit messages.',\n })\n const threadId = started.thread.id\n const reply = Promise.withResolvers<string>()\n let text = ''\n server.threads.set(threadId, {\n notify: (method, params) => {\n if (method === 'item/completed') {\n const item = params.item as ThreadItem\n if (item.type === 'agentMessage') text = item.text\n }\n if (method !== 'turn/completed') return\n const turn = params.turn as Turn\n if (turn.status === 'completed') reply.resolve(text.trim())\n else reply.reject(new Error(turn.error?.message ?? 'Codex did not reply'))\n },\n request: (id, method) =>\n server.replyError(id, `offsite does not handle ${method}`),\n exited: () => reply.reject(new Error('Codex stopped')),\n })\n try {\n await server.request('turn/start', {\n threadId,\n input: [{ type: 'text', text: prompt, text_elements: [] }],\n model,\n })\n return { message: await reply.promise }\n } finally {\n server.threads.delete(threadId)\n await server.request('thread/unsubscribe', { threadId })\n }\n}\n\nfunction codexRun(sessionId: string) {\n const run = runs.get(sessionId)\n return run?.provider === 'codex' ? run : undefined\n}\n\nfunction server(sessionId: string) {\n return codexRun(sessionId)?.server ?? appServer(codexBaseDir)\n}\n\nasync function readThread(threadId: string) {\n const result = await server(threadId).request<{ thread: Thread }>(\n 'thread/read',\n { threadId, includeTurns: true }\n )\n return result.thread\n}\n","import path from 'node:path'\nimport { DatabaseSync } from 'node:sqlite'\nimport { home } from './storage.ts'\n\nexport const db = new DatabaseSync(path.join(home, 'offsite.db'))\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n logo TEXT\n )\n`)\n\ndb.exec('DROP TABLE IF EXISTS prompts')\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n interacted_at INTEGER,\n status TEXT NOT NULL CHECK (status IN ('active', 'pinned', 'minimized'))\n )\n`)\n","import { readdir, stat } from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport type { SQLOutputValue } from 'node:sqlite'\nimport type { Directories, Project, ProjectPatch } from '@offsite/core/protocol'\nimport { broadcast } from '../lib/hub.ts'\nimport { db } from '../storage/db.ts'\n\nconst LOGO_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/x-icon',\n 'image/vnd.microsoft.icon',\n]\nconst LOGO_LIMIT = 512 * 1024\n\nexport function projects() {\n return db\n .prepare('SELECT path, name, logo FROM projects')\n .all()\n .map(toProject)\n}\n\nexport async function addProject(input: string) {\n const folder = path.resolve(expandHome(input.trim()))\n if (!(await stat(folder)).isDirectory())\n throw new Error(`${folder} is not a folder`)\n db.prepare(\n 'INSERT OR IGNORE INTO projects (path, name, logo) VALUES (?, ?, NULL)'\n ).run(folder, path.basename(folder) || folder)\n publish()\n const project = projects().find((item) => item.path === folder)\n if (project === undefined) throw new Error(`Could not add ${folder}`)\n return project\n}\n\nexport function updateProject(folder: string, patch: ProjectPatch) {\n if (patch.name !== undefined) {\n const name = patch.name.trim()\n if (name === '') throw new Error('Project name cannot be empty')\n db.prepare('UPDATE projects SET name = ? WHERE path = ?').run(name, folder)\n }\n if (patch.logo !== undefined) {\n if (patch.logo !== null) checkLogo(patch.logo)\n db.prepare('UPDATE projects SET logo = ? WHERE path = ?').run(\n patch.logo,\n folder\n )\n }\n publish()\n return null\n}\n\nexport function removeProject(folder: string) {\n db.prepare('DELETE FROM projects WHERE path = ?').run(folder)\n publish()\n}\n\nexport async function directories(input: string): Promise<Directories> {\n const folder = path.resolve(expandHome(input.trim()))\n const entries = await readdir(folder, { withFileTypes: true })\n const parent = path.dirname(folder)\n return {\n path: folder,\n parent: parent === folder ? null : parent,\n directories: entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => ({\n name: entry.name,\n path: path.join(folder, entry.name),\n }))\n .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())),\n }\n}\n\nfunction publish() {\n broadcast({ type: 'projects', projects: projects() })\n}\n\nfunction toProject(row: Record<string, SQLOutputValue>): Project {\n if (\n typeof row.path !== 'string' ||\n typeof row.name !== 'string' ||\n (typeof row.logo !== 'string' && row.logo !== null)\n )\n throw new Error('The projects table has an unexpected row')\n return { path: row.path, name: row.name, logo: row.logo }\n}\n\nfunction checkLogo(logo: string) {\n const type = /^data:([^;,]+);base64,/.exec(logo)?.[1]\n if (type === undefined || !LOGO_TYPES.includes(type))\n throw new Error('Use a PNG, JPEG, GIF, WebP, SVG or ICO image')\n if (logo.length > LOGO_LIMIT)\n throw new Error('Use an image smaller than 384 KB')\n}\n\nfunction expandHome(input: string) {\n if (input === '~') return os.homedir()\n if (input.startsWith('~/')) return path.join(os.homedir(), input.slice(2))\n return input\n}\n","import { type FSWatcher, watch } from 'node:fs'\nimport path from 'node:path'\nimport {\n deleteSession,\n forkSession,\n getSessionMessages,\n listSessions,\n renameSession,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Provider, Session, SessionPatch } from '@offsite/core/protocol'\nimport {\n codexBaseDir,\n codexThreads,\n deleteThread,\n forkThread,\n renameThread,\n} from '../lib/codex/index.ts'\nimport { broadcast } from '../lib/hub.ts'\nimport { runs } from '../lib/live.ts'\nimport {\n forkOpenCode,\n openCodeSessions,\n removeOpenCode,\n renameOpenCode,\n} from '../lib/opencode/index.ts'\nimport { readConfig } from '../storage/config.ts'\nimport { db } from '../storage/db.ts'\nimport { projects } from './projects.ts'\n\nconst day = 24 * 60 * 60 * 1000\n\nconst providers = new Map<string, Provider>()\nlet watchers: FSWatcher[] = []\nlet timer: NodeJS.Timeout | undefined\n\nexport async function sessions(): Promise<Session[]> {\n const records = readRecords()\n const paths = projects().map((project) => project.path)\n const [claude, codex, opencode] = await Promise.all([\n Promise.all(\n paths.map(async (cwd) =>\n (\n await listSessions({\n dir: cwd,\n includeWorktrees: false,\n includeProgrammatic: false,\n })\n ).map((item) => ({\n id: item.sessionId,\n provider: 'claude' as const,\n title: item.summary,\n cwd,\n branch: item.gitBranch ?? null,\n updatedAt: item.lastModified,\n }))\n )\n ),\n codexThreads(paths).catch((error: unknown) => {\n console.warn(`could not list Codex threads: ${error}`)\n return []\n }),\n openCodeSessions(paths).catch((error: unknown) => {\n console.warn(`could not list OpenCode sessions: ${error}`)\n return []\n }),\n ])\n const found = [\n ...claude.flat(),\n ...codex.map((thread) => ({\n id: thread.id,\n provider: 'codex' as const,\n title: thread.name ?? thread.preview,\n cwd: thread.cwd,\n branch: thread.gitInfo?.branch ?? null,\n updatedAt: thread.updatedAt * 1000,\n })),\n ...opencode.map((session) => ({\n id: session.id,\n provider: 'opencode' as const,\n title: session.title ?? 'New session',\n cwd: session.location.directory,\n branch: null,\n updatedAt: session.time.updated,\n })),\n ]\n return found.map((item): Session => {\n providers.set(item.id, item.provider)\n const record = records.get(item.id)\n const updatedAt = record?.interactedAt ?? item.updatedAt\n return {\n ...item,\n updatedAt,\n status:\n record === undefined ||\n (record.status === 'active' && Date.now() - updatedAt > day)\n ? 'inactive'\n : record.status,\n }\n })\n}\n\nexport function providerOf(sessionId: string) {\n const provider = runs.get(sessionId)?.provider ?? providers.get(sessionId)\n if (provider === undefined)\n throw new Error('offsite does not know this session yet, reload the page')\n return provider\n}\n\nexport function recordInteraction(id: string) {\n db.prepare(\n \"INSERT INTO sessions (session_id, interacted_at, status) VALUES (?, ?, 'active') ON CONFLICT (session_id) DO UPDATE SET interacted_at = excluded.interacted_at, status = CASE status WHEN 'pinned' THEN 'pinned' WHEN 'minimized' THEN 'minimized' ELSE 'active' END\"\n ).run(id, Date.now())\n}\n\nexport async function publishSessions() {\n try {\n broadcast({ type: 'sessions', sessions: await sessions() })\n } catch (error) {\n console.warn(`could not list threads: ${error}`)\n }\n}\n\nexport function watchSessions() {\n for (const watcher of watchers) watcher.close()\n watchers = [\n path.join(readConfig().claudeBaseDir, 'projects'),\n path.join(codexBaseDir, 'sessions'),\n ].flatMap((dir) => {\n try {\n const watcher = watch(dir, { recursive: true }, refreshSessions)\n watcher.on('error', (error) =>\n console.warn(`stopped watching ${dir}: ${error}`)\n )\n return [watcher]\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n return []\n }\n })\n}\n\nexport function refreshSessions() {\n timer ??= setTimeout(() => {\n timer = undefined\n void publishSessions()\n }, 1000)\n}\n\nexport async function updateSession(id: string, patch: SessionPatch) {\n if (patch.title !== undefined)\n switch (providerOf(id)) {\n case 'claude':\n await renameSession(id, patch.title)\n break\n case 'codex':\n await renameThread(id, patch.title)\n break\n case 'opencode':\n await renameOpenCode(id, patch.title)\n }\n if (patch.status === 'inactive')\n db.prepare('DELETE FROM sessions WHERE session_id = ?').run(id)\n else if (patch.status !== undefined)\n db.prepare(\n 'INSERT INTO sessions (session_id, status) VALUES (?, ?) ON CONFLICT (session_id) DO UPDATE SET status = excluded.status'\n ).run(id, patch.status)\n}\n\nexport async function removeSession(id: string) {\n const provider = providerOf(id)\n const run = runs.get(id)\n if (run !== undefined) {\n run.stop()\n await run.closed\n }\n switch (provider) {\n case 'claude':\n await deleteSession(id)\n break\n case 'codex':\n await deleteThread(id)\n break\n case 'opencode':\n await removeOpenCode(id)\n }\n db.prepare('DELETE FROM sessions WHERE session_id = ?').run(id)\n}\n\nexport async function fork(sessionId: string, cwd: string, messageId: string) {\n const provider = providerOf(sessionId)\n const result = await forkWith(provider, sessionId, cwd, messageId)\n providers.set(result.sessionId, provider)\n recordInteraction(result.sessionId)\n return result\n}\n\nasync function forkWith(\n provider: Provider,\n sessionId: string,\n cwd: string,\n messageId: string\n) {\n if (provider === 'codex') return forkThread(sessionId, messageId)\n if (provider === 'opencode') return forkOpenCode(sessionId, messageId)\n const disk = await getSessionMessages(sessionId, { dir: cwd })\n const index = disk.findIndex((item) => item.uuid === messageId)\n if (index < 0) throw new Error('Cannot fork the session at that point')\n const result = await forkSession(sessionId, {\n dir: cwd,\n upToMessageId: messageId,\n })\n return { sessionId: result.sessionId }\n}\n\nfunction readRecords() {\n const records = new Map<\n string,\n { interactedAt: number | null; status: 'active' | 'pinned' | 'minimized' }\n >()\n for (const row of db\n .prepare('SELECT session_id, interacted_at, status FROM sessions')\n .all()) {\n if (\n typeof row.session_id !== 'string' ||\n (typeof row.interacted_at !== 'number' && row.interacted_at !== null) ||\n (row.status !== 'active' &&\n row.status !== 'pinned' &&\n row.status !== 'minimized')\n )\n throw new Error('The sessions table has an unexpected row')\n records.set(row.session_id, {\n interactedAt: row.interacted_at,\n status: row.status,\n })\n }\n return records\n}\n","import { statSync } from 'node:fs'\nimport path from 'node:path'\nimport { setTimeout } from 'node:timers/promises'\nimport { OpenCode, type OpenCodeClient, type V2Event } from '@opencode/client'\nimport { ensure, headers } from '@opencode/client/service'\nimport { refreshSessions } from '../../services/sessions.ts'\nimport { runs } from '../live.ts'\n\nconst listChanges = new Set([\n 'session.created',\n 'session.renamed',\n 'session.moved',\n 'session.forked',\n 'session.deleted',\n 'session.execution.succeeded',\n 'session.execution.failed',\n 'session.execution.interrupted',\n])\n\nlet connection: Promise<OpenCodeClient> | undefined\n\nexport function findOpenCode() {\n const name = process.platform === 'win32' ? 'opencode.exe' : 'opencode'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile())\n return candidate\n }\n return null\n}\n\nexport function openCode() {\n connection ??= connect()\n return connection\n}\n\nasync function connect() {\n try {\n const endpoint = await ensure()\n const client = OpenCode.make({\n baseUrl: endpoint.url,\n headers: headers(endpoint),\n })\n void listen(client)\n return client\n } catch (error) {\n connection = undefined\n throw error\n }\n}\n\nasync function listen(client: OpenCodeClient) {\n try {\n for await (const event of client.event.subscribe()) route(event)\n console.warn('the OpenCode event stream ended')\n } catch (error) {\n console.warn(`lost the OpenCode event stream: ${error}`)\n }\n connection = undefined\n if (openCodeRuns().length === 0) return\n await setTimeout(1000)\n try {\n const active = await (await openCode()).session.active()\n for (const run of openCodeRuns()) run.resync(run.sessionId in active)\n refreshSessions()\n } catch (error) {\n console.warn(`could not reconnect to OpenCode: ${error}`)\n for (const run of openCodeRuns()) run.exited()\n }\n}\n\nfunction route(event: V2Event) {\n if (listChanges.has(event.type)) refreshSessions()\n const sessionId = sessionOf(event)\n if (sessionId === null) return\n const run = runs.get(sessionId)\n if (run?.provider === 'opencode') run.receive(event)\n}\n\nfunction sessionOf(event: V2Event) {\n if (event.type === 'form.created') return event.data.form.sessionID\n const data: unknown = 'data' in event ? event.data : null\n if (\n typeof data === 'object' &&\n data !== null &&\n 'sessionID' in data &&\n typeof data.sessionID === 'string'\n )\n return data.sessionID\n return null\n}\n\nfunction openCodeRuns() {\n return [...runs.values()].flatMap((run) =>\n run.provider === 'opencode' ? [run] : []\n )\n}\n","import type {\n Item,\n ItemStatus,\n Question,\n TodoStep,\n} from '@offsite/core/protocol'\nimport type {\n FormField,\n FormInfo,\n SessionMessageAssistant,\n SessionMessageAssistantTool,\n SessionMessageInfo,\n ToolContent,\n} from '@opencode/client'\nimport { errorItem, hunks } from '../codex/index.ts'\n\ntype Base = { id: string; parent: string | null; time: number | null }\n\nconst toolStatuses: Record<\n SessionMessageAssistantTool['state']['status'],\n ItemStatus\n> = {\n streaming: 'running',\n running: 'running',\n completed: 'completed',\n error: 'failed',\n}\n\nconst todoStatuses: Record<string, TodoStep['status']> = {\n pending: 'pending',\n in_progress: 'running',\n completed: 'completed',\n cancelled: 'completed',\n}\n\nexport function messageItems(\n message: SessionMessageInfo,\n parent: string | null\n): Item[] {\n const base = { id: message.id, parent, time: message.time.created }\n switch (message.type) {\n case 'user':\n return [\n {\n ...base,\n kind: 'user',\n text: message.text,\n images: (message.files ?? [])\n .filter((file) => file.mime.startsWith('image/'))\n .map((file) => ({ mediaType: file.mime, data: file.data })),\n format: 'text',\n },\n ]\n case 'skill':\n return [\n {\n ...base,\n kind: 'skill',\n skill: message.name,\n output: '',\n status: 'completed',\n },\n ]\n case 'shell':\n return [\n {\n ...base,\n kind: 'command',\n command: message.command,\n description: '',\n output: message.output?.output ?? '',\n status:\n message.status === 'running'\n ? 'running'\n : message.status === 'exited'\n ? message.exit === 0\n ? 'completed'\n : 'failed'\n : 'stopped',\n background: null,\n },\n ]\n case 'assistant':\n return message.content.flatMap((part, index) =>\n partItems(message, part, index, parent)\n )\n case 'compaction':\n return message.status === 'failed'\n ? [{ ...errorItem(message.id, message.error.message), parent }]\n : [{ ...base, kind: 'compaction' }]\n case 'idle':\n return message.outcome === 'failed' && message.error !== undefined\n ? [{ ...errorItem(message.id, message.error.message), parent }]\n : []\n case 'agent-switched':\n case 'model-switched':\n case 'location-switched':\n case 'synthetic':\n case 'system':\n return []\n }\n}\n\nexport function formQuestions(form: FormInfo): Question[] {\n return form.fields.flatMap((field) =>\n field.type === 'external'\n ? []\n : [\n {\n question: questionText(field),\n header: field.title ?? '',\n multiSelect: field.type === 'multiselect',\n options: fieldOptions(field),\n },\n ]\n )\n}\n\nexport function formAnswer(form: FormInfo, answers: Record<string, string>) {\n return Object.fromEntries(\n form.fields.flatMap(\n (field): [string, string | number | boolean | string[]][] => {\n if (field.type === 'external') return []\n const answer = answers[questionText(field)]\n if (answer === undefined || answer === '') return []\n switch (field.type) {\n case 'string':\n return [[field.key, optionValue(field.options ?? [], answer)]]\n case 'multiselect':\n return [\n [\n field.key,\n answer\n .split(', ')\n .map((label) => optionValue(field.options, label)),\n ],\n ]\n case 'boolean':\n if (answer === 'Yes') return [[field.key, true]]\n if (answer === 'No') return [[field.key, false]]\n throw new Error(`${field.key} needs Yes or No`)\n case 'number':\n case 'integer':\n return [[field.key, Number(answer)]]\n }\n }\n )\n )\n}\n\nfunction partItems(\n message: SessionMessageAssistant,\n part: SessionMessageAssistant['content'][number],\n index: number,\n parent: string | null\n): Item[] {\n const base = {\n id: `${message.id}:${index}`,\n parent,\n time: message.time.created,\n }\n switch (part.type) {\n case 'text':\n return part.text.trim() === ''\n ? []\n : [{ ...base, kind: 'assistant', text: part.text, message: message.id }]\n case 'reasoning':\n return part.text.trim() === ''\n ? []\n : [{ ...base, kind: 'reasoning', text: part.text.trim() }]\n case 'tool':\n return toolItems(\n { id: `${message.id}:${part.id}`, parent, time: part.time.created },\n part\n )\n }\n}\n\nfunction toolItems(base: Base, tool: SessionMessageAssistantTool): Item[] {\n const state = tool.state\n const status = toolStatuses[state.status]\n const input: Record<string, unknown> =\n state.status === 'streaming' ? {} : state.input\n const metadata: Record<string, unknown> =\n state.status === 'streaming' ? {} : (state.metadata ?? {})\n const output =\n state.status === 'error'\n ? state.error.message\n : state.status === 'completed'\n ? contentText(state.content)\n : ''\n switch (tool.name) {\n case 'shell':\n return [\n {\n ...base,\n kind: 'command',\n command: text(input.command),\n description: text(input.description),\n output,\n status,\n background: null,\n },\n ]\n case 'edit':\n return [\n {\n ...base,\n kind: 'file_change',\n path: text(input.path ?? input.filePath),\n diffs: [\n { before: text(input.oldString), after: text(input.newString) },\n ],\n output,\n status,\n },\n ]\n case 'write':\n return [\n {\n ...base,\n kind: 'file_change',\n path: text(input.path ?? input.filePath),\n diffs: [{ before: '', after: text(input.content) }],\n output,\n status,\n },\n ]\n case 'patch':\n case 'apply_patch':\n if (!Array.isArray(metadata.files)) break\n return metadata.files.map((file: unknown, index) => ({\n ...base,\n id: `${base.id}:${index}`,\n kind: 'file_change',\n path: text(record(file).file),\n diffs: hunks(text(record(file).patch)),\n output,\n status,\n }))\n case 'todowrite':\n return [\n {\n ...base,\n kind: 'todo_list',\n steps: list(input.todos).map((todo) => ({\n text: text(record(todo).content),\n status: todoStatuses[text(record(todo).status)] ?? 'pending',\n })),\n },\n ]\n case 'subagent':\n case 'task':\n return [\n {\n ...base,\n kind: 'subagent',\n agent: text(input.agent ?? input.subagent_type) || 'Agent',\n description: text(input.description),\n agentId:\n typeof metadata.sessionID === 'string' ? metadata.sessionID : null,\n status,\n },\n ]\n case 'webfetch':\n case 'websearch':\n return [\n {\n ...base,\n kind: 'web_search',\n query: tool.name === 'websearch' ? text(input.query) : null,\n url: tool.name === 'webfetch' ? text(input.url) : null,\n results: [],\n output,\n status,\n },\n ]\n case 'question': {\n const questions = list(input.questions).map((item) => ({\n question: text(record(item).question),\n header: text(record(item).header),\n multiSelect: record(item).multiple === true,\n options: list(record(item).options).map((option) => ({\n label: text(record(option).label),\n description: text(record(option).description),\n })),\n }))\n const answers = metadata.answers\n return [\n {\n ...base,\n kind: 'question',\n questions,\n answers: Array.isArray(answers)\n ? Object.fromEntries(\n questions.map((question, index) => [\n question.question,\n list(answers[index]).map(text).join(', '),\n ])\n )\n : null,\n status,\n },\n ]\n }\n case 'skill':\n return [\n { ...base, kind: 'skill', skill: text(input.name), output, status },\n ]\n }\n return [{ ...base, kind: 'tool', name: tool.name, input, output, status }]\n}\n\nfunction questionText(field: Exclude<FormField, { type: 'external' }>) {\n return field.description ?? field.title ?? field.key\n}\n\nfunction fieldOptions(field: Exclude<FormField, { type: 'external' }>) {\n switch (field.type) {\n case 'string':\n case 'multiselect':\n return (field.options ?? []).map((option) => ({\n label: option.label,\n description: option.description ?? '',\n }))\n case 'boolean':\n return [\n { label: 'Yes', description: '' },\n { label: 'No', description: '' },\n ]\n case 'number':\n case 'integer':\n return []\n }\n}\n\nfunction optionValue(\n options: { value: string; label: string }[],\n label: string\n) {\n return options.find((option) => option.label === label)?.value ?? label\n}\n\nfunction contentText(content: ToolContent[]) {\n return content\n .map((block) => (block.type === 'text' ? block.text : block.uri))\n .join('\\n')\n}\n\nfunction text(value: unknown) {\n return typeof value === 'string' ? value : ''\n}\n\nfunction list(value: unknown): unknown[] {\n return Array.isArray(value) ? value : []\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n","import type {\n Account,\n Capabilities,\n Context,\n Item,\n Rewind,\n RewindResult,\n ServerEvent,\n} from '@offsite/core/protocol'\nimport type {\n OpenCodeClient,\n SessionInfo,\n SessionMessageInfo,\n} from '@opencode/client'\nimport { runs } from '../live.ts'\nimport { findOpenCode, openCode } from './client.ts'\nimport { messageItems } from './items.ts'\n\nconst PAGE = 100\nconst COMMIT_LIMIT = 2 * 60 * 1000\n\nconst temporary = new Set<string>()\n\nexport function openCodeAccount(): Account {\n return {\n id: 'opencode',\n provider: 'opencode',\n name: 'OpenCode',\n configDir: '',\n email: null,\n plan: null,\n error: null,\n limits: [],\n linked: true,\n valid: true,\n }\n}\n\nexport function openCodeInstalled() {\n return findOpenCode() !== null\n}\n\nexport async function openCodeCapabilities(cwd: string): Promise<Capabilities> {\n const client = await openCode()\n const location = { directory: cwd }\n const [models, commands, skills, agents] = await Promise.all([\n client.model.list({ location }),\n client.command.list({ location }),\n client.skill.list({ location }),\n client.agent.list({ location }),\n ])\n return {\n models: models.data\n .filter((model) => model.enabled)\n .map((model) => ({\n value: `${model.providerID}/${model.id}`,\n name: model.name,\n description: model.providerID,\n efforts: model.variants.map((variant) => variant.id),\n })),\n commands: [\n {\n name: 'compact',\n description: 'Summarize the conversation to free up context',\n hint: '',\n },\n ...commands.data.map((command) => ({\n name: command.name,\n description: command.description ?? '',\n hint: '',\n })),\n ...skills.data.map((skill) => ({\n name: skill.name,\n description: skill.description ?? '',\n hint: '',\n })),\n ],\n agents: agents.data\n .filter((agent) => agent.mode !== 'subagent' && !agent.hidden)\n .map((agent) => ({\n id: agent.id,\n name: agent.name,\n description: agent.description ?? '',\n })),\n }\n}\n\nexport async function openCodeSessions(paths: string[]) {\n if (paths.length === 0 || !openCodeInstalled()) return []\n const client = await openCode()\n const lists = await Promise.all(\n paths.map(async (directory) => {\n const found: SessionInfo[] = []\n let cursor: string | null = null\n do {\n const page = await client.session.list(\n cursor === null\n ? { directory, parentID: null, limit: PAGE }\n : { cursor }\n )\n found.push(...page.data)\n cursor = page.data.length === PAGE ? (page.cursor.next ?? null) : null\n } while (cursor !== null)\n return found\n })\n )\n return lists.flat().filter((session) => !temporary.has(session.id))\n}\n\nexport async function openCodeHistory(\n sessionId: string,\n cwd: string\n): Promise<ServerEvent> {\n const run = openCodeRun(sessionId)\n const client = await openCode()\n const messages = await allMessages(client, sessionId)\n return {\n type: 'history',\n sessionId,\n provider: 'opencode',\n items: messages.flatMap((message) => messageItems(message, null)),\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context: run?.context ?? (await contextOf(client, cwd, messages)),\n before: null,\n partial: run?.partial ?? '',\n }\n}\n\nexport async function openCodeAgent(\n agentId: string,\n parent: string\n): Promise<Item[]> {\n const messages = await allMessages(await openCode(), agentId)\n return messages.flatMap((message) => messageItems(message, parent))\n}\n\nexport async function renameOpenCode(sessionId: string, title: string) {\n await (await openCode()).session.update({ sessionID: sessionId, title })\n}\n\nexport async function removeOpenCode(sessionId: string) {\n await (await openCode()).session.remove({ sessionID: sessionId })\n}\n\nexport async function forkOpenCode(sessionId: string, messageId: string) {\n const client = await openCode()\n const messages = await allMessages(client, sessionId)\n const index = messages.findIndex((message) => message.id === messageId)\n if (index < 0) throw new Error('Cannot fork the session at that point')\n const next = messages.at(index + 1)\n const result = await client.session.fork({\n sessionID: sessionId,\n ...(next === undefined ? {} : { before: next.id }),\n })\n return { sessionId: result.id }\n}\n\nexport async function rewindOpenCode(request: Rewind): Promise<RewindResult> {\n if (request.code && !request.conversation && !request.dryRun)\n throw new Error('OpenCode restores files only with the conversation')\n const client = await openCode()\n const sessionID = request.sessionId\n const staged = await client.session.revert.stage({\n sessionID,\n messageID: request.messageId,\n files: request.code,\n })\n const files = staged.files ?? []\n const result = request.code\n ? {\n files: files.map((file) => file.file),\n insertions: files.reduce((sum, file) => sum + file.additions, 0),\n deletions: files.reduce((sum, file) => sum + file.deletions, 0),\n }\n : null\n if (request.dryRun) await client.session.revert.clear({ sessionID })\n else await client.session.revert.commit({ sessionID })\n return result\n}\n\nexport async function openCodeCommitMessage(\n cwd: string,\n model: string,\n prompt: string\n) {\n const client = await openCode()\n const session = await client.session.create({\n location: { directory: cwd },\n agent: 'plan',\n model: modelRef(model, null),\n })\n temporary.add(session.id)\n try {\n await client.session.prompt({ sessionID: session.id, text: prompt })\n await client.session.wait(\n { sessionID: session.id },\n { signal: AbortSignal.timeout(COMMIT_LIMIT) }\n )\n const messages = await allMessages(client, session.id)\n for (const message of messages.toReversed()) {\n if (message.type === 'idle' && message.outcome === 'failed')\n throw new Error(message.error?.message ?? 'OpenCode failed')\n if (message.type !== 'assistant') continue\n const text = message.content\n .flatMap((part) => (part.type === 'text' ? [part.text] : []))\n .join('')\n .trim()\n if (text !== '') return { message: text }\n }\n throw new Error('OpenCode did not reply')\n } finally {\n await client.session.remove({ sessionID: session.id })\n temporary.delete(session.id)\n }\n}\n\nexport async function contextOf(\n client: OpenCodeClient,\n cwd: string,\n messages: SessionMessageInfo[]\n): Promise<Context | null> {\n const last = messages.findLast(\n (message) => message.type === 'assistant' && message.tokens !== undefined\n )\n if (last?.type !== 'assistant' || last.tokens === undefined) return null\n const tokens = last.tokens\n const models = await client.model.list({ location: { directory: cwd } })\n const model = models.data.find(\n (item) =>\n item.providerID === last.model.providerID && item.id === last.model.id\n )\n return {\n tokens:\n tokens.input +\n tokens.output +\n tokens.reasoning +\n tokens.cache.read +\n tokens.cache.write,\n window: model?.limit.context ?? null,\n }\n}\n\nexport function modelRef(value: string, effort: string | null) {\n const index = value.indexOf('/')\n if (index < 0) throw new Error(`${value} is not an OpenCode model`)\n return {\n providerID: value.slice(0, index),\n id: value.slice(index + 1),\n ...(effort === null ? {} : { variant: effort }),\n }\n}\n\nasync function allMessages(client: OpenCodeClient, sessionId: string) {\n const messages: SessionMessageInfo[] = []\n let cursor: string | null = null\n do {\n const page = await client.message.list(\n cursor === null\n ? { sessionID: sessionId, limit: PAGE, order: 'asc' }\n : { sessionID: sessionId, cursor }\n )\n messages.push(...page.data)\n cursor = page.data.length === PAGE ? (page.cursor.next ?? null) : null\n } while (cursor !== null)\n return messages\n}\n\nfunction openCodeRun(sessionId: string) {\n const run = runs.get(sessionId)\n return run?.provider === 'opencode' ? run : undefined\n}\n","import { randomUUID } from 'node:crypto'\nimport type {\n Context,\n Decision,\n Delivery,\n Item,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport type {\n FormInfo,\n OpenCodeClient,\n PermissionReply,\n PermissionRequest as OpenCodePermission,\n SessionInfo,\n V2Event,\n} from '@opencode/client'\nimport { errorItem } from '../codex/index.ts'\nimport { publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport { openCode } from './client.ts'\nimport { formAnswer, formQuestions, messageItems } from './items.ts'\nimport { contextOf, modelRef } from './sessions.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\nconst RECENT = 30\n\nconst replies: Record<Decision, PermissionReply> = {\n allow: 'once',\n always: 'always',\n deny: 'reject',\n}\n\ntype Pending =\n | { kind: 'permission'; request: PermissionRequest }\n | { kind: 'form'; request: PermissionRequest; form: FormInfo }\n\nexport class OpenCodeRun {\n readonly provider = 'opencode'\n readonly sessionId: string\n readonly cwd: string\n readonly pending = new Map<string, Pending>()\n readonly items = new Map<string, Item>()\n readonly closed: Promise<void>\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly client: OpenCodeClient\n private readonly close: () => void\n private applied: Settings\n private loading = Promise.resolve()\n private refreshTimer: NodeJS.Timeout | undefined\n private idleTimer: NodeJS.Timeout | undefined\n\n static async start(cwd: string, settings: Settings) {\n const client = await openCode()\n const session = await client.session.create({\n location: { directory: cwd },\n ...(settings.mode === null ? {} : { agent: settings.mode }),\n ...(settings.model === null\n ? {}\n : { model: modelRef(settings.model, settings.effort) }),\n })\n return new OpenCodeRun(client, session.id, cwd, settings, settings)\n }\n\n static async resume(sessionId: string, cwd: string, settings: Settings) {\n const client = await openCode()\n const session = await client.session.get({ sessionID: sessionId })\n return new OpenCodeRun(\n client,\n sessionId,\n cwd,\n settings,\n sessionSettings(session, settings)\n )\n }\n\n private constructor(\n client: OpenCodeClient,\n sessionId: string,\n cwd: string,\n settings: Settings,\n applied: Settings\n ) {\n this.client = client\n this.sessionId = sessionId\n this.cwd = cwd\n this.settings = settings\n this.applied = applied\n const closed = Promise.withResolvers<void>()\n this.closed = closed.promise\n this.close = closed.resolve\n runs.set(sessionId, this)\n this.armIdleTimer()\n }\n\n async submit(prompt: Prompt, delivery: Delivery) {\n if (!this.running) {\n await this.startTurn(prompt)\n return\n }\n switch (delivery) {\n case 'steer':\n await this.client.session.prompt({\n sessionID: this.sessionId,\n text: prompt.text,\n files: files(prompt),\n delivery: 'steer',\n })\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer').catch((error: unknown) =>\n this.fail(error)\n )\n }\n\n configure(settings: Settings) {\n this.settings = { ...settings, accountId: this.settings.accountId }\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings: this.settings,\n })\n }\n\n async interrupt() {\n await this.client.session.interrupt({ sessionID: this.sessionId })\n }\n\n stopTask(): Promise<void> {\n throw new Error('OpenCode has no background tasks to stop')\n }\n\n async respond(\n requestId: string,\n decision: Decision,\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n const sessionID = this.sessionId\n if (pending.kind === 'permission')\n await this.client.permission.reply({\n sessionID,\n requestID: requestId,\n decision: replies[decision],\n })\n else if (decision === 'deny')\n await this.client.session.form.cancel({ sessionID, formID: requestId })\n else\n await this.client.session.form.reply({\n sessionID,\n formID: requestId,\n answer: formAnswer(pending.form, answers ?? {}),\n })\n this.settle(requestId)\n }\n\n stop() {\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.end()\n }\n\n exited() {\n this.put([errorItem(randomUUID(), 'Lost the connection to OpenCode')])\n this.stop()\n }\n\n resync(active: boolean) {\n this.refresh()\n if (this.running && !active) this.finishTurn()\n }\n\n receive(event: V2Event) {\n switch (event.type) {\n case 'session.reasoning.delta':\n case 'session.tool.input.delta':\n case 'session.compaction.delta':\n return\n case 'session.execution.started':\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n return\n case 'session.execution.succeeded':\n case 'session.execution.failed':\n case 'session.execution.interrupted':\n this.refresh()\n void this.loading.then(() => this.finishTurn())\n return\n case 'session.text.delta':\n this.partial += event.data.delta\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: event.data.delta,\n })\n return\n case 'permission.asked':\n this.refresh()\n void this.loading.then(() => this.ask(event.data))\n return\n case 'permission.replied':\n this.settle(event.data.requestID)\n return\n case 'form.created':\n this.addPending({\n kind: 'form',\n request: {\n id: event.data.form.id,\n kind: 'question',\n questions: formQuestions(event.data.form),\n },\n form: event.data.form,\n })\n return\n case 'form.replied':\n case 'form.cancelled':\n this.settle(event.data.id)\n return\n default:\n clearTimeout(this.refreshTimer)\n this.refreshTimer = setTimeout(() => this.refresh(), 100)\n }\n }\n\n private refresh() {\n clearTimeout(this.refreshTimer)\n this.loading = this.loading\n .then(() => this.load())\n .catch((error: unknown) =>\n console.warn(`could not load OpenCode messages: ${error}`)\n )\n }\n\n private async load() {\n const page = await this.client.message.list({\n sessionID: this.sessionId,\n limit: RECENT,\n order: 'desc',\n })\n const messages = page.data.toReversed()\n this.put(\n messages\n .flatMap((message) => messageItems(message, null))\n .filter(\n (item) =>\n JSON.stringify(this.items.get(item.id)) !== JSON.stringify(item)\n )\n )\n const context = await contextOf(this.client, this.cwd, messages)\n if (context === null || context.tokens === this.context?.tokens) return\n this.context = context\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context,\n })\n }\n\n private async startTurn(prompt: Prompt) {\n clearTimeout(this.idleTimer)\n this.running = true\n this.prompted = true\n broadcastActivity()\n try {\n await this.apply()\n await this.send(prompt)\n } catch (error) {\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n throw error\n }\n }\n\n private async send(prompt: Prompt) {\n const sessionID = this.sessionId\n const location = { directory: this.cwd }\n const match = /^\\/(\\S+)\\s*([\\s\\S]*)$/.exec(prompt.text)\n if (match !== null) {\n if (match[1] === 'compact' && prompt.images.length === 0) {\n await this.client.session.compact({ sessionID })\n return\n }\n const commands = await this.client.command.list({ location })\n if (commands.data.some((command) => command.name === match[1])) {\n await this.client.session.command({\n sessionID,\n name: match[1],\n text: match[2],\n files: files(prompt),\n })\n return\n }\n const skills = await this.client.skill.list({ location })\n const skill = skills.data.find((item) => item.name === match[1])\n if (skill !== undefined) {\n await this.client.session.prompt({\n sessionID,\n text: match[2],\n files: files(prompt),\n skills: [{ id: skill.id }],\n })\n return\n }\n }\n await this.client.session.prompt({\n sessionID,\n text: prompt.text,\n files: files(prompt),\n })\n }\n\n private async apply() {\n const settings = this.settings\n const model = settings.model ?? this.applied.model\n if (\n model !== null &&\n (model !== this.applied.model || settings.effort !== this.applied.effort)\n )\n await this.client.session.switchModel({\n sessionID: this.sessionId,\n model: modelRef(model, settings.effort),\n })\n if (settings.mode !== null && settings.mode !== this.applied.mode)\n await this.client.session.switchAgent({\n sessionID: this.sessionId,\n agent: settings.mode,\n })\n this.applied = {\n ...settings,\n model,\n mode: settings.mode ?? this.applied.mode,\n }\n }\n\n private ask(permission: OpenCodePermission) {\n const source = permission.source\n const item =\n source === undefined\n ? undefined\n : this.items.get(`${source.messageID}:${source.id}`)\n this.addPending({\n kind: 'permission',\n request: {\n id: permission.id,\n kind: 'approval',\n title:\n permission.message ??\n `Allow ${permission.action} ${permission.resources.join(', ')}?`,\n canAlwaysAllow: (permission.save ?? []).length > 0,\n item: item ?? {\n id: permission.id,\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: permission.action,\n input: { resources: permission.resources },\n output: '',\n status: 'running',\n },\n },\n })\n }\n\n private addPending(pending: Pending) {\n this.pending.set(pending.request.id, pending)\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request: pending.request,\n })\n broadcastActivity()\n }\n\n private finishTurn() {\n this.partial = ''\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.startTurn(next.prompt).catch((error: unknown) => this.fail(error))\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private settle(requestId: string) {\n if (!this.pending.delete(requestId)) return\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private put(items: Item[]) {\n if (items.length === 0) return\n for (const item of items) this.items.set(item.id, item)\n if (items.some((item) => item.kind === 'assistant')) this.partial = ''\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items,\n })\n }\n\n private fail(error: unknown) {\n this.put([\n errorItem(\n randomUUID(),\n error instanceof Error ? error.message : String(error)\n ),\n ])\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private end() {\n clearTimeout(this.idleTimer)\n clearTimeout(this.refreshTimer)\n for (const requestId of [...this.pending.keys()]) this.settle(requestId)\n this.running = false\n broadcastActivity()\n this.close()\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction sessionSettings(session: SessionInfo, settings: Settings): Settings {\n const variant = session.model?.variant\n return {\n ...settings,\n model:\n session.model === undefined\n ? null\n : `${session.model.providerID}/${session.model.id}`,\n effort: variant === undefined || variant === 'default' ? null : variant,\n mode: session.agent ?? null,\n }\n}\n\nfunction files(prompt: Prompt) {\n return prompt.images.map((image) => ({\n uri: `data:${image.mediaType};base64,${image.data}`,\n }))\n}\n","import { randomUUID } from 'node:crypto'\nimport os from 'node:os'\nimport path from 'node:path'\nimport type { Account, Capabilities, Provider } from '@offsite/core/protocol'\nimport {\n claudeAccount,\n claudeCapabilities,\n forgetClaude,\n} from '../lib/claude/index.ts'\nimport { codexAccount, codexCapabilities } from '../lib/codex/index.ts'\nimport { broadcast } from '../lib/hub.ts'\nimport {\n openCodeAccount,\n openCodeCapabilities,\n openCodeInstalled,\n} from '../lib/opencode/index.ts'\nimport { readJson, writeJson } from '../storage/storage.ts'\n\nexport type StoredAccount = {\n id: string\n provider: Provider\n name: string\n configDir: string\n}\n\nconst providerNames: Record<Provider, string> = {\n claude: 'Claude',\n codex: 'Codex',\n opencode: 'OpenCode',\n}\n\nexport function providerName(provider: Provider) {\n return providerNames[provider]\n}\n\nexport function storedAccounts(): StoredAccount[] {\n const items =\n (readJson('accounts.json') as\n | (Omit<StoredAccount, 'provider'> & { provider?: Provider })[]\n | null) ?? []\n return items.map((item) => ({ ...item, provider: item.provider ?? 'claude' }))\n}\n\nexport function storedAccount(provider: Provider, accountId: string | null) {\n if (accountId === null)\n throw new Error(\n `Add a ${providerName(provider)} account in Settings → Accounts`\n )\n const account = storedAccounts().find((item) => item.id === accountId)\n if (account === undefined) throw new Error('That account was removed')\n if (account.provider !== provider)\n throw new Error(`That account is not a ${providerName(provider)} account`)\n return account\n}\n\nexport async function accounts(): Promise<Account[]> {\n const stored = await Promise.all(\n storedAccounts().map((account) => {\n switch (account.provider) {\n case 'claude':\n return claudeAccount(account)\n case 'codex':\n return codexAccount(account)\n case 'opencode':\n throw new Error('OpenCode has no stored accounts')\n }\n })\n )\n return openCodeInstalled() ? [...stored, openCodeAccount()] : stored\n}\n\nexport async function publishAccounts() {\n try {\n broadcast({ type: 'accounts', accounts: await accounts() })\n } catch (error) {\n console.warn(`could not list accounts: ${error}`)\n }\n}\n\nexport function capabilities(\n accountId: string,\n cwd: string\n): Promise<Capabilities> {\n if (accountId === openCodeAccount().id) return openCodeCapabilities(cwd)\n const account = storedAccounts().find((item) => item.id === accountId)\n if (account === undefined) throw new Error('That account was removed')\n switch (account.provider) {\n case 'claude':\n return claudeCapabilities(account, cwd)\n case 'codex':\n return codexCapabilities(account, cwd)\n case 'opencode':\n throw new Error('OpenCode has no stored accounts')\n }\n}\n\nexport function addAccount(\n provider: Provider,\n name: string,\n configDir: string\n) {\n if (provider === 'opencode')\n throw new Error('OpenCode has no accounts. Connect providers in OpenCode')\n saveAccounts([\n ...storedAccounts(),\n { id: randomUUID(), provider, ...validAccount(name, configDir) },\n ])\n}\n\nexport function updateAccount(id: string, name: string, configDir: string) {\n const account = validAccount(name, configDir)\n saveAccounts(\n storedAccounts().map((item) =>\n item.id === id ? { ...item, ...account } : item\n )\n )\n forgetClaude(id)\n}\n\nexport function removeAccount(id: string) {\n saveAccounts(storedAccounts().filter((item) => item.id !== id))\n forgetClaude(id)\n}\n\nfunction validAccount(name: string, configDir: string) {\n if (name.trim() === '') throw new Error('Give the account a name')\n const dir = configDir.trim()\n if (dir === '~' || dir.startsWith('~/'))\n return {\n name: name.trim(),\n configDir: path.join(os.homedir(), dir.slice(1)),\n }\n if (path.isAbsolute(dir)) return { name: name.trim(), configDir: dir }\n throw new Error('Use an absolute config directory or one starting with ~/')\n}\n\nfunction saveAccounts(items: StoredAccount[]) {\n writeJson('accounts.json', items)\n}\n","export type Block =\n | { type: 'text'; text: string }\n | { type: 'thinking'; thinking: string }\n | { type: 'image'; mediaType: string; data: string | null }\n | {\n type: 'tool_use'\n id: string\n name: string\n input: Record<string, unknown>\n }\n | {\n type: 'tool_result'\n toolUseId: string\n content: Block[]\n isError: boolean\n answers: Record<string, string> | null\n }\n\nexport type Message =\n | {\n type: 'user' | 'assistant'\n uuid: string\n time: number | null\n content: Block[]\n parent: string | null\n }\n | {\n type: 'notice'\n uuid: string\n time: number | null\n text: string\n isError: boolean\n }\n | { type: 'compaction'; uuid: string; time: number | null }\n\nexport function toMessage(\n type: 'user' | 'assistant',\n item: {\n uuid: string\n message: unknown\n parent_tool_use_id: string | null\n tool_use_result?: unknown\n },\n time: number | null\n): Extract<Message, { type: 'user' | 'assistant' }> {\n return {\n type,\n uuid: item.uuid,\n time,\n content: isRecord(item.message)\n ? toBlocks(item.message.content, answersOf(item.tool_use_result))\n : [],\n parent: item.parent_tool_use_id,\n }\n}\n\nexport function contextTokens(message: unknown) {\n if (!isRecord(message) || !isRecord(message.usage)) return null\n const usage = message.usage\n return [\n usage.input_tokens,\n usage.cache_creation_input_tokens,\n usage.cache_read_input_tokens,\n usage.output_tokens,\n ].reduce<number>(\n (total, value) => total + (typeof value === 'number' ? value : 0),\n 0\n )\n}\n\nfunction answersOf(output: unknown) {\n if (!isRecord(output) || !isRecord(output.answers)) return null\n const answers: Record<string, string> = {}\n for (const [question, answer] of Object.entries(output.answers)) {\n if (typeof answer !== 'string') return null\n answers[question] = answer\n }\n return answers\n}\n\nfunction toBlocks(\n content: unknown,\n answers: Record<string, string> | null\n): Block[] {\n if (typeof content === 'string') return [{ type: 'text', text: content }]\n if (!Array.isArray(content)) return []\n return content.flatMap((block): Block[] => {\n if (!isRecord(block)) return []\n switch (block.type) {\n case 'text':\n return typeof block.text === 'string' &&\n !block.text.startsWith('<system-reminder>') &&\n !block.text.startsWith('<local-command-caveat>')\n ? [{ type: 'text', text: block.text }]\n : []\n case 'thinking':\n return typeof block.thinking === 'string' && block.thinking !== ''\n ? [{ type: 'thinking', thinking: block.thinking }]\n : []\n case 'image': {\n const source = block.source\n return isRecord(source) &&\n source.type === 'base64' &&\n typeof source.media_type === 'string' &&\n typeof source.data === 'string'\n ? [{ type: 'image', mediaType: source.media_type, data: source.data }]\n : []\n }\n case 'tool_use':\n return typeof block.id === 'string' &&\n typeof block.name === 'string' &&\n isRecord(block.input)\n ? [\n {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input,\n },\n ]\n : []\n case 'tool_result':\n return typeof block.tool_use_id === 'string'\n ? [\n {\n type: 'tool_result',\n toolUseId: block.tool_use_id,\n content: toBlocks(block.content, null).filter(\n (item) => item.type === 'text'\n ),\n isError: block.is_error === true,\n answers,\n },\n ]\n : []\n default:\n return []\n }\n })\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { realpathSync, statSync } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport {\n type EffortLevel,\n type Options,\n type PermissionMode,\n query,\n type SDKControlInitializeResponse,\n type SDKRateLimitInfo,\n type SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Account, Capabilities, RateLimit } from '@offsite/core/protocol'\nimport { type StoredAccount, storedAccount } from '../../services/accounts.ts'\nimport { readConfig } from '../../storage/config.ts'\nimport { broadcast } from '../hub.ts'\nimport { isRecord } from './content.ts'\n\nconst efforts: EffortLevel[] = ['low', 'medium', 'high', 'xhigh', 'max']\nconst modes: PermissionMode[] = [\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n 'plan',\n 'dontAsk',\n 'auto',\n]\nconst probes = new Map<string, Promise<SDKControlInitializeResponse>>()\nconst limits = new Map<string, Map<string, RateLimit>>()\nlet executable = ''\n\nexport function findClaude() {\n const name = process.platform === 'win32' ? 'claude.exe' : 'claude'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile()) {\n executable = candidate\n return candidate\n }\n }\n return null\n}\n\nexport function claudeEffort(value: string) {\n const effort = efforts.find((item) => item === value)\n if (effort === undefined) throw new Error(`Claude has no ${value} effort`)\n return effort\n}\n\nexport function claudeMode(value: string) {\n const mode = modes.find((item) => item === value)\n if (mode === undefined) throw new Error(`Claude has no ${value} mode`)\n return mode\n}\n\nexport function claudeOptions(accountId: string | null, cwd: string): Options {\n const account = storedAccount('claude', accountId)\n return {\n cwd,\n env: {\n ...process.env,\n CLAUDE_CODE_ENTRYPOINT: 'offsite',\n CLAUDE_CONFIG_DIR: account.configDir,\n },\n pathToClaudeCodeExecutable: executable,\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n hooks: {\n PostToolUse: [\n {\n matcher: 'PushNotification',\n hooks: [\n async (input) => {\n if (\n input.hook_event_name !== 'PostToolUse' ||\n typeof input.tool_input !== 'object' ||\n input.tool_input === null ||\n !('message' in input.tool_input) ||\n typeof input.tool_input.message !== 'string'\n )\n throw new Error('Unexpected PushNotification hook input')\n broadcast({\n type: 'notification',\n sessionId: input.session_id,\n message: input.tool_input.message,\n })\n return {\n hookSpecificOutput: {\n hookEventName: 'PostToolUse',\n updatedToolOutput: {\n message: input.tool_input.message,\n localSent: true,\n disabledReason: 'no_transport',\n },\n },\n }\n },\n ],\n },\n ],\n },\n }\n}\n\nexport async function claudeCapabilities(\n account: StoredAccount,\n cwd: string\n): Promise<Capabilities> {\n const result = await initialization(account.id, cwd)\n return {\n models: result.models.map((model) => ({\n value: model.value,\n name: model.displayName,\n description: model.description,\n efforts: model.supportedEffortLevels ?? [],\n })),\n commands: result.commands.map((command) => ({\n name: command.name,\n description: command.description,\n hint: command.argumentHint,\n })),\n agents: [],\n }\n}\n\nexport async function claudeAccount(account: StoredAccount): Promise<Account> {\n const linked = isLinked(account.configDir)\n try {\n const info = (await initialization(account.id, os.homedir())).account\n return {\n ...account,\n email: info.email ?? null,\n plan: info.subscriptionType ?? null,\n error: null,\n limits: accountLimits(account.id),\n linked,\n valid: linked,\n }\n } catch (error) {\n return {\n ...account,\n email: null,\n plan: null,\n error: error instanceof Error ? error.message : String(error),\n limits: accountLimits(account.id),\n linked,\n valid: linked,\n }\n }\n}\n\nexport function forgetClaude(accountId: string) {\n for (const key of probes.keys())\n if (key.startsWith(`${accountId}\\n`)) probes.delete(key)\n limits.delete(accountId)\n}\n\nexport function recordLimit(accountId: string, info: SDKRateLimitInfo) {\n const current = limits.get(accountId) ?? new Map<string, RateLimit>()\n const windows = (info as { unifiedWindows?: unknown }).unifiedWindows\n if (isRecord(windows))\n for (const [name, value] of Object.entries(windows))\n if (isRecord(value))\n current.set(name, {\n window: name,\n utilization:\n typeof value.utilization === 'number' ? value.utilization : null,\n resetsAt: typeof value.resetsAt === 'number' ? value.resetsAt : null,\n rejected: current.get(name)?.rejected ?? false,\n })\n if (info.rateLimitType !== undefined) {\n const existing = current.get(info.rateLimitType)\n current.set(info.rateLimitType, {\n window: info.rateLimitType,\n utilization: info.utilization ?? existing?.utilization ?? null,\n resetsAt: info.resetsAt ?? existing?.resetsAt ?? null,\n rejected: info.status === 'rejected',\n })\n }\n limits.set(accountId, current)\n return accountLimits(accountId)\n}\n\nfunction isLinked(configDir: string) {\n const base = readConfig().claudeBaseDir\n try {\n if (realpathSync(configDir) === realpathSync(base)) return true\n return (\n realpathSync(path.join(configDir, 'projects')) ===\n realpathSync(path.join(base, 'projects'))\n )\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n\nfunction accountLimits(accountId: string) {\n return [...(limits.get(accountId)?.values() ?? [])]\n}\n\nfunction initialization(accountId: string, cwd: string) {\n const key = `${accountId}\\n${cwd}`\n const existing = probes.get(key)\n if (existing !== undefined) return existing\n const probe = runProbe(accountId, cwd)\n probes.set(key, probe)\n probe.catch(() => probes.delete(key))\n return probe\n}\n\nasync function runProbe(accountId: string, cwd: string) {\n const closed = Promise.withResolvers<void>()\n const probe = query({\n prompt: idle(closed.promise),\n options: claudeOptions(accountId, cwd),\n })\n try {\n return await probe.initializationResult()\n } finally {\n closed.resolve()\n probe.close()\n }\n}\n\nasync function* idle(until: Promise<void>): AsyncGenerator<SDKUserMessage> {\n await until\n yield* []\n}\n","import type {\n Background,\n Item,\n ItemStatus,\n PermissionRequest,\n Question,\n TodoStep,\n} from '@offsite/core/protocol'\nimport { type Block, isRecord, type Message } from './content.ts'\n\ntype ToolUse = Extract<Block, { type: 'tool_use' }>\n\ntype ToolResult = Extract<Block, { type: 'tool_result' }>\n\nconst notifications = /<task-notification>([\\s\\S]*?)<\\/task-notification>/g\n\nconst taskStatuses = new Map<string, ItemStatus>([\n ['completed', 'completed'],\n ['failed', 'failed'],\n ['killed', 'stopped'],\n ['stopped', 'stopped'],\n])\n\nconst todoStatuses = new Map<string, TodoStep['status']>([\n ['pending', 'pending'],\n ['in_progress', 'running'],\n ['completed', 'completed'],\n])\n\nexport function toItems(messages: Message[]): Item[] {\n const items: Item[] = []\n const tools = new Map<string, number>()\n const owners = new Map<string, number>()\n const stops = new Map<string, string>()\n\n function change(index: number, patch: Partial<Item>) {\n items[index] = { ...items[index], ...patch } as Item\n }\n\n for (const message of messages) {\n const base = { parent: null, time: message.time }\n if (message.type === 'compaction') {\n items.push({ ...base, id: message.uuid, kind: 'compaction' })\n continue\n }\n if (message.type === 'notice') {\n items.push({\n ...base,\n id: message.uuid,\n kind: message.isError ? 'error' : 'notice',\n text: message.text,\n })\n continue\n }\n if (message.type === 'assistant') {\n message.content.forEach((block, index) => {\n const id = `${message.uuid}:${index}`\n const parent = message.parent\n switch (block.type) {\n case 'text':\n if (block.text.trim() !== '')\n items.push({\n id,\n parent,\n time: message.time,\n kind: 'assistant',\n text: block.text,\n message: message.uuid,\n })\n break\n case 'thinking':\n if (block.thinking.trim() !== '')\n items.push({\n id,\n parent,\n time: message.time,\n kind: 'reasoning',\n text: block.thinking,\n })\n break\n case 'tool_use': {\n if (block.name === 'SendMessage') {\n const owner = owners.get(text(block.input.to))\n if (owner !== undefined) change(owner, { status: 'running' })\n }\n if (block.name === 'TaskStop')\n stops.set(block.id, text(block.input.task_id))\n tools.set(block.id, items.length)\n items.push(\n toolItem(block, parent, message.time, (to) => {\n const owner = owners.get(to)\n return owner === undefined ? null : items[owner].id\n })\n )\n break\n }\n case 'image':\n case 'tool_result':\n break\n }\n })\n continue\n }\n const texts: { format: 'text' | 'command' | 'output'; text: string }[] = []\n const images = message.content.flatMap((block) =>\n block.type === 'image'\n ? [{ mediaType: block.mediaType, data: block.data }]\n : []\n )\n for (const block of message.content) {\n if (block.type === 'tool_result') {\n const index = tools.get(block.toolUseId)\n if (index === undefined) continue\n const result = applyResult(items[index], block)\n items[index] = result\n if (result.kind === 'subagent' && result.agentId !== null)\n owners.set(result.agentId, index)\n if (\n result.kind === 'command' &&\n result.background !== null &&\n result.background.taskId !== null\n )\n owners.set(result.background.taskId, index)\n const stopped = stops.get(block.toolUseId)\n const owner = stopped === undefined ? undefined : owners.get(stopped)\n if (owner !== undefined && !block.isError)\n change(owner, { status: 'stopped' })\n continue\n }\n if (block.type !== 'text') continue\n if (block.text.startsWith('<task-notification>')) {\n let count = 0\n for (const match of block.text.matchAll(notifications)) {\n const body = match[1]\n const status = taskStatuses.get(\n /<status>(\\w+)<\\/status>/.exec(body)?.[1] ?? ''\n )\n const event = /<event>([\\s\\S]*?)<\\/event>/.exec(body)?.[1]\n for (const id of body.matchAll(/<task-id>(\\w+)<\\/task-id>/g)) {\n const owner = owners.get(id[1])\n if (owner === undefined) continue\n if (status !== undefined) change(owner, { status })\n const task = items[owner]\n if (\n event !== undefined &&\n task.kind === 'command' &&\n task.background !== null\n )\n change(owner, {\n background: {\n ...task.background,\n events: [...task.background.events, event],\n },\n })\n }\n items.push({\n id: `${message.uuid}:${count}`,\n parent: message.parent,\n time: message.time,\n kind: 'notice',\n text:\n /<summary>([\\s\\S]*?)<\\/summary>/.exec(body)?.[1] ??\n 'Background task updated',\n })\n count += 1\n }\n continue\n }\n if (block.text.startsWith('[Request interrupted by user')) {\n items.push({\n id: message.uuid,\n parent: message.parent,\n time: message.time,\n kind: 'notice',\n text: 'Interrupted',\n })\n continue\n }\n texts.push(userText(block.text))\n }\n if (texts.length === 0 && images.length === 0) continue\n items.push({\n id: message.uuid,\n parent: message.parent,\n time: message.time,\n kind: 'user',\n text: texts.map((part) => part.text).join('\\n'),\n images,\n format: texts[0]?.format ?? 'text',\n })\n }\n return items\n}\n\nexport function toRequest(options: {\n id: string\n toolName: string\n input: Record<string, unknown>\n title: string | null\n canAlwaysAllow: boolean\n}): PermissionRequest {\n switch (options.toolName) {\n case 'AskUserQuestion':\n return {\n id: options.id,\n kind: 'question',\n questions: options.input.questions as Question[],\n }\n case 'ExitPlanMode':\n return { id: options.id, kind: 'plan', plan: text(options.input.plan) }\n default:\n return {\n id: options.id,\n kind: 'approval',\n title: options.title ?? `Allow ${options.toolName}?`,\n canAlwaysAllow: options.canAlwaysAllow,\n item: toolItem(\n {\n type: 'tool_use',\n id: options.id,\n name: options.toolName,\n input: options.input,\n },\n null,\n null,\n () => null\n ),\n }\n }\n}\n\nfunction toolItem(\n tool: ToolUse,\n parent: string | null,\n time: number | null,\n ownerOf: (id: string) => string | null\n): Item {\n const input = tool.input\n const base = { id: tool.id, parent, time }\n switch (tool.name) {\n case 'Bash':\n return {\n ...base,\n kind: 'command',\n command: text(input.command),\n description: text(input.description),\n output: '',\n status: 'running',\n background:\n input.run_in_background === true\n ? { taskId: null, outputPath: null, events: [] }\n : null,\n }\n case 'Monitor':\n return {\n ...base,\n kind: 'command',\n command:\n text(input.command) || (isRecord(input.ws) ? text(input.ws.url) : ''),\n description: text(input.description),\n output: '',\n status: 'running',\n background: { taskId: null, outputPath: null, events: [] },\n }\n case 'Edit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: [\n { before: text(input.old_string), after: text(input.new_string) },\n ],\n output: '',\n status: 'running',\n }\n case 'MultiEdit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: (\n input.edits as { old_string: string; new_string: string }[]\n ).map((edit) => ({ before: edit.old_string, after: edit.new_string })),\n output: '',\n status: 'running',\n }\n case 'Write':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: [{ before: '', after: text(input.content) }],\n output: '',\n status: 'running',\n }\n case 'NotebookEdit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.notebook_path),\n diffs: [],\n output: '',\n status: 'running',\n }\n case 'WebFetch':\n return {\n ...base,\n kind: 'web_search',\n query: null,\n url: text(input.url),\n results: [],\n output: '',\n status: 'running',\n }\n case 'WebSearch':\n return {\n ...base,\n kind: 'web_search',\n query: text(input.query),\n url: null,\n results: [],\n output: '',\n status: 'running',\n }\n case 'Skill':\n return {\n ...base,\n kind: 'skill',\n skill: text(input.skill),\n output: '',\n status: 'running',\n }\n case 'TodoWrite':\n return {\n ...base,\n kind: 'todo_list',\n steps: (input.todos as { content: string; status: string }[]).map(\n (todo) => ({\n text: todo.content,\n status: todoStatuses.get(todo.status) ?? 'pending',\n })\n ),\n }\n case 'ExitPlanMode':\n return { ...base, kind: 'plan', plan: text(input.plan) }\n case 'AskUserQuestion':\n return {\n ...base,\n kind: 'question',\n questions: input.questions as Question[],\n answers: null,\n status: 'running',\n }\n case 'Agent':\n case 'Task': {\n const agent = text(input.subagent_type)\n return {\n ...base,\n kind: 'subagent',\n agent: agent === '' ? 'general-purpose' : agent,\n description: text(input.description),\n agentId: null,\n status: 'running',\n }\n }\n case 'SendMessage': {\n const summary = text(input.summary)\n return {\n ...base,\n kind: 'agent_message',\n target: ownerOf(text(input.to)),\n summary: summary === '' ? text(input.message).split('\\n')[0] : summary,\n status: 'running',\n }\n }\n default:\n return {\n ...base,\n kind: 'tool',\n name: tool.name,\n input,\n output: '',\n status: 'running',\n }\n }\n}\n\nfunction applyResult(item: Item, result: ToolResult): Item {\n const output = result.content\n .flatMap((block) => (block.type === 'text' ? [block.text] : []))\n .join('\\n')\n const status = result.isError ? 'failed' : 'completed'\n switch (item.kind) {\n case 'command': {\n if (item.background === null) return { ...item, output, status }\n const shell =\n /^Command running in background with ID: (\\w+)\\. Output is being written to: (.+?\\.output)\\./.exec(\n output\n )\n const monitor = /^Monitor started \\(task (\\w+),/.exec(output)\n const background: Background =\n shell !== null\n ? { ...item.background, taskId: shell[1], outputPath: shell[2] }\n : monitor !== null\n ? { ...item.background, taskId: monitor[1] }\n : item.background\n return {\n ...item,\n output,\n background,\n status: background.taskId !== null ? 'running' : status,\n }\n }\n case 'subagent':\n return {\n ...item,\n agentId: /agentId: (\\w+)/.exec(output)?.[1] ?? null,\n status: output.startsWith('Async agent launched') ? 'running' : status,\n }\n case 'web_search':\n return {\n ...item,\n output,\n status,\n results: [\n ...output.matchAll(/\"title\":\"((?:[^\"\\\\]|\\\\.)*)\",\"url\":\"([^\"]+)\"/g),\n ].map((match) => ({ title: match[1], url: match[2] })),\n }\n case 'question':\n return { ...item, answers: result.answers, status }\n case 'file_change':\n case 'skill':\n case 'tool':\n case 'agent_message':\n return { ...item, output, status } as Item\n default:\n return item\n }\n}\n\nfunction userText(value: string): {\n format: 'text' | 'command' | 'output'\n text: string\n} {\n const command = /<command-name>(.*?)<\\/command-name>/s.exec(value)\n if (command !== null) {\n const args = /<command-args>(.*?)<\\/command-args>/s.exec(value)\n return {\n format: 'command',\n text: `${command[1]} ${args?.[1] ?? ''}`.trim(),\n }\n }\n const output =\n /^<local-command-(?:stdout|stderr)>(.*)<\\/local-command-(?:stdout|stderr)>$/s.exec(\n value.trim()\n )\n if (output !== null) return { format: 'output', text: output[1] }\n return { format: 'text', text: value }\n}\n\nfunction text(value: unknown) {\n return typeof value === 'string' ? value : ''\n}\n","import { readdir, readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport {\n getSessionMessages,\n getSubagentMessages,\n type SessionMessage,\n type SessionStoreEntry,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Item, ServerEvent } from '@offsite/core/protocol'\nimport { readConfig } from '../../storage/config.ts'\nimport { runs } from '../live.ts'\nimport { contextTokens, type Message, toMessage } from './content.ts'\nimport { toItems } from './items.ts'\n\nasync function sessionFile(sessionId: string) {\n const projectsDir = path.join(readConfig().claudeBaseDir, 'projects')\n for (const dir of await readdir(projectsDir)) {\n const file = path.join(projectsDir, dir, `${sessionId}.jsonl`)\n try {\n return { file, stats: await stat(file) }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue\n throw error\n }\n }\n return null\n}\n\nasync function readSession(sessionId: string, file: string) {\n const text = await readFile(file, 'utf8')\n const entries = text.split('\\n').flatMap((line): SessionStoreEntry[] => {\n const entry = parseLine(line)\n return entry !== null && typeof entry.type === 'string'\n ? [{ ...entry, type: entry.type }]\n : []\n })\n const pages: { before: number; disk: SessionMessage[] }[] = []\n const seen = new Set<string>()\n let before: number | null = entries.length\n while (before !== null) {\n const kept = entries.slice(0, before)\n const disk = await getSessionMessages(sessionId, {\n sessionStore: { append: () => Promise.resolve(), load: async () => kept },\n })\n pages.push({ before, disk: disk.filter((item) => !seen.has(item.uuid)) })\n for (const item of disk) seen.add(item.uuid)\n before = compactedBefore(entries, disk[0]?.uuid)\n }\n return { entries, pages }\n}\n\nlet cached: {\n file: string\n mtimeMs: number\n size: number\n session: ReturnType<typeof readSession>\n} | null = null\n\nasync function loadSession(sessionId: string) {\n const found = await sessionFile(sessionId)\n if (found === null) return null\n if (\n cached !== null &&\n cached.file === found.file &&\n cached.mtimeMs === found.stats.mtimeMs &&\n cached.size === found.stats.size\n )\n return cached.session\n const session = readSession(sessionId, found.file)\n cached = {\n file: found.file,\n mtimeMs: found.stats.mtimeMs,\n size: found.stats.size,\n session,\n }\n return session\n}\n\nfunction messageTimes(entries: SessionStoreEntry[]) {\n const times = new Map<string, number>()\n for (const entry of entries)\n if (typeof entry.uuid === 'string' && typeof entry.timestamp === 'string')\n times.set(entry.uuid, Date.parse(entry.timestamp))\n return times\n}\n\nfunction toolOutputs(entries: SessionStoreEntry[]) {\n const outputs = new Map<string, unknown>()\n for (const entry of entries)\n if (typeof entry.uuid === 'string' && entry.toolUseResult !== undefined)\n outputs.set(entry.uuid, entry.toolUseResult)\n return outputs\n}\n\nfunction compactedBefore(\n entries: SessionStoreEntry[],\n uuid: string | undefined\n) {\n if (uuid === undefined) return null\n const start = entries.findIndex((entry) => entry.uuid === uuid)\n const index = entries.findLastIndex(\n (entry, position) =>\n position < start &&\n entry.type === 'system' &&\n entry.subtype === 'compact_boundary'\n )\n return index < 0 ? null : index\n}\n\nfunction parseLine(line: string): Record<string, unknown> | null {\n try {\n return JSON.parse(line) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nfunction mainMessages(disk: SessionMessage[], entries: SessionStoreEntry[]) {\n const times = messageTimes(entries)\n const outputs = toolOutputs(entries)\n return disk.flatMap((item): Message[] => {\n if (item.type === 'system' || item.parent_tool_use_id !== null) return []\n const message = toMessage(\n item.type,\n { ...item, tool_use_result: outputs.get(item.uuid) },\n times.get(item.uuid) ?? null\n )\n return [\n {\n ...message,\n content: message.content.map((block) =>\n block.type === 'image' ? { ...block, data: null } : block\n ),\n },\n ]\n })\n}\n\nexport async function image(sessionId: string, uuid: string, index: number) {\n const session = await loadSession(sessionId)\n if (session === null) throw new Error(`session ${sessionId} not found`)\n const item = session.pages\n .flatMap((page) => page.disk)\n .find((candidate) => candidate.uuid === uuid)\n if (item === undefined) throw new Error(`message ${uuid} not found`)\n if (item.type === 'system' || item.parent_tool_use_id !== null)\n throw new Error(`message ${uuid} has no image ${index}`)\n const block = toMessage(item.type, item, null).content.filter(\n (candidate) => candidate.type === 'image'\n )[index]\n if (block === undefined || block.data === null)\n throw new Error(`message ${uuid} has no image ${index}`)\n return { mediaType: block.mediaType, data: block.data }\n}\n\nexport async function history(\n sessionId: string,\n cwd: string\n): Promise<ServerEvent> {\n const found = runs.get(sessionId)\n const run = found?.provider === 'claude' ? found : undefined\n const [disk, session] = await Promise.all([\n getSessionMessages(sessionId, { dir: cwd }),\n loadSession(sessionId),\n ])\n const entries = session === null ? [] : session.entries\n const resumeAt = run?.resumeAt ?? null\n const kept =\n resumeAt === null\n ? disk\n : disk.slice(0, disk.findIndex((item) => item.uuid === resumeAt) + 1)\n const messages = mainMessages(kept, entries)\n const seen = new Set(messages.map((item) => item.uuid))\n const last = kept.findLast(\n (item) => item.type === 'assistant' && item.parent_tool_use_id === null\n )\n const tokens = last === undefined ? null : contextTokens(last.message)\n return {\n type: 'history',\n sessionId,\n provider: 'claude',\n items: toItems([\n ...messages,\n ...(run?.messages.filter((item) => !seen.has(item.uuid)) ?? []),\n ]),\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context:\n run?.context ?? (tokens === null ? null : { tokens, window: null }),\n before: compactedBefore(entries, disk[0]?.uuid),\n partial: run?.partial ?? '',\n }\n}\n\nexport async function earlier(sessionId: string, before: number) {\n const session = await loadSession(sessionId)\n if (session === null) throw new Error(`session ${sessionId} not found`)\n const index = session.pages.findIndex((page) => page.before === before)\n if (index < 0) throw new Error(`no messages before entry ${before}`)\n const items = toItems([\n ...mainMessages(session.pages[index].disk, session.entries),\n { type: 'compaction', uuid: `compacted:${before}`, time: null },\n ])\n return { items, before: session.pages[index + 1]?.before ?? null }\n}\n\nexport async function agentMessages(\n sessionId: string,\n cwd: string,\n agentId: string,\n parent: string\n): Promise<Item[]> {\n if (!/^\\w+$/.test(agentId)) throw new Error(`invalid agent id ${agentId}`)\n const disk = await getSubagentMessages(sessionId, agentId, { dir: cwd })\n return toItems(\n disk.flatMap((item): Message[] =>\n item.type === 'system'\n ? []\n : [toMessage(item.type, { ...item, parent_tool_use_id: parent }, null)]\n )\n )\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n type PermissionResult,\n type PermissionUpdate,\n query,\n type Query,\n type SDKMessage,\n type SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type {\n Context,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport { broadcast, publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport {\n claudeEffort,\n claudeMode,\n claudeOptions,\n recordLimit,\n} from './claude.ts'\nimport { contextTokens, type Message, toMessage } from './content.ts'\nimport { toItems, toRequest } from './items.ts'\n\nconst IDLE_LIMIT = 10 * 60 * 1000\nconst imageTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp']\n\ntype Pending = {\n request: PermissionRequest\n input: Record<string, unknown>\n suggestions: PermissionUpdate[]\n resolve: (result: PermissionResult) => void\n}\n\ntype ImageType = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp'\n\nexport class Run {\n readonly provider = 'claude'\n readonly sessionId: string\n readonly messages: Message[] = []\n readonly pending = new Map<string, Pending>()\n private readonly published = new Map<string, string>()\n readonly query: Query\n readonly closed: Promise<void>\n readonly resumeAt: string | null\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n private model: string | null = null\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly inbox: SDKUserMessage[] = []\n private wake: (() => void) | null = null\n private idleTimer: NodeJS.Timeout | undefined\n private stopping = false\n\n constructor(options: {\n sessionId: string\n cwd: string\n resume: boolean\n resumeAt: string | null\n settings: Settings\n }) {\n this.sessionId = options.sessionId\n this.resumeAt = options.resumeAt\n this.settings = options.settings\n const settings = options.settings\n this.query = query({\n prompt: this.input(),\n options: {\n ...claudeOptions(settings.accountId, options.cwd),\n ...(options.resume\n ? { resume: options.sessionId }\n : { sessionId: options.sessionId }),\n ...(options.resumeAt === null\n ? {}\n : { resumeSessionAt: options.resumeAt }),\n enableFileCheckpointing: true,\n ...(settings.mode === null\n ? {}\n : { permissionMode: claudeMode(settings.mode) }),\n ...(settings.model === null ? {} : { model: settings.model }),\n ...(settings.effort === null\n ? {}\n : { effort: claudeEffort(settings.effort) }),\n allowDangerouslySkipPermissions: true,\n includePartialMessages: true,\n canUseTool: (toolName, input, context) =>\n this.ask({\n toolName,\n input,\n title: context.title ?? null,\n suggestions: context.suggestions ?? [],\n signal: context.signal,\n }),\n },\n })\n runs.set(this.sessionId, this)\n this.closed = this.read()\n }\n\n submit(prompt: Prompt, delivery: 'queue' | 'steer') {\n if (!this.running) {\n this.push(prompt, undefined)\n return\n }\n switch (delivery) {\n case 'steer':\n this.push(prompt, 'next')\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer')\n }\n\n async configure(settings: Settings) {\n if (settings.model !== this.settings.model)\n await this.query.setModel(settings.model ?? undefined)\n if (settings.effort !== this.settings.effort)\n await this.query.applyFlagSettings({\n effortLevel:\n settings.effort === null ? null : claudeEffort(settings.effort),\n })\n if (settings.mode !== null && settings.mode !== this.settings.mode)\n await this.query.setPermissionMode(claudeMode(settings.mode))\n this.updateSettings({\n ...settings,\n accountId: this.settings.accountId,\n mode: settings.mode ?? this.settings.mode,\n })\n }\n\n async interrupt() {\n await this.query.interrupt()\n }\n\n async stopTask(taskId: string) {\n await this.query.stopTask(taskId)\n }\n\n respond(\n requestId: string,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n const input = pending.input\n switch (decision) {\n case 'allow':\n this.settle(requestId, {\n behavior: 'allow',\n updatedInput: answers === null ? input : { ...input, answers },\n })\n return\n case 'always':\n this.settle(requestId, {\n behavior: 'allow',\n updatedInput: input,\n updatedPermissions: pending.suggestions,\n })\n return\n case 'deny':\n this.settle(requestId, {\n behavior: 'deny',\n message: 'The user rejected this action',\n interrupt: true,\n })\n }\n }\n\n stop() {\n this.stopping = true\n runs.delete(this.sessionId)\n this.query.close()\n }\n\n private push(prompt: Prompt, priority: 'next' | undefined) {\n clearTimeout(this.idleTimer)\n for (const image of prompt.images)\n if (!imageTypes.includes(image.mediaType))\n throw new Error(`${image.mediaType} images are not supported`)\n const uuid = randomUUID()\n this.inbox.push({\n type: 'user',\n message: {\n role: 'user',\n content: [\n ...prompt.images.map((image) => ({\n type: 'image' as const,\n source: {\n type: 'base64' as const,\n media_type: image.mediaType as ImageType,\n data: image.data,\n },\n })),\n ...(prompt.text === ''\n ? []\n : [{ type: 'text' as const, text: prompt.text }]),\n ],\n },\n parent_tool_use_id: null,\n uuid,\n ...(priority === undefined ? {} : { priority }),\n })\n this.wake?.()\n this.add({\n type: 'user',\n uuid,\n time: Date.now(),\n content: [\n ...prompt.images.map((image) => ({ type: 'image' as const, ...image })),\n ...(prompt.text === ''\n ? []\n : [{ type: 'text' as const, text: prompt.text }]),\n ],\n parent: null,\n })\n this.running = true\n this.prompted = true\n broadcastActivity()\n }\n\n private publishContext() {\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context: this.context,\n })\n }\n\n private async *input(): AsyncGenerator<SDKUserMessage> {\n while (true) {\n const next = this.inbox.shift()\n if (next !== undefined) {\n yield next\n continue\n }\n await new Promise<void>((resolve) => {\n this.wake = resolve\n })\n }\n }\n\n private async read() {\n try {\n for await (const message of this.query) this.receive(message)\n } catch (error) {\n if (!this.stopping)\n this.add(notice(error instanceof Error ? error.message : String(error)))\n }\n clearTimeout(this.idleTimer)\n for (const id of this.pending.keys())\n this.settle(id, { behavior: 'deny', message: 'Session ended' })\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.running = false\n broadcastActivity()\n }\n\n private receive(message: SDKMessage) {\n switch (message.type) {\n case 'assistant': {\n if (message.parent_tool_use_id === null) this.partial = ''\n this.add(toMessage('assistant', message, Date.now()))\n const tokens = contextTokens(message.message)\n if (message.parent_tool_use_id === null && tokens !== null) {\n this.model = message.message.model\n this.context = { tokens, window: this.context?.window ?? null }\n }\n if (message.error === 'rate_limit')\n this.add(\n notice(\n 'This account hit its usage limit. Pick another account below and send again.'\n )\n )\n return\n }\n case 'user':\n if (message.isSynthetic) return\n this.add(\n toMessage(\n 'user',\n { ...message, uuid: message.uuid ?? randomUUID() },\n Date.now()\n )\n )\n return\n case 'stream_event':\n if (\n message.parent_tool_use_id === null &&\n message.event.type === 'content_block_delta' &&\n message.event.delta.type === 'text_delta'\n ) {\n this.partial += message.event.delta.text\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: message.event.delta.text,\n })\n }\n return\n case 'rate_limit_event': {\n const accountId = this.settings.accountId\n if (accountId === null)\n throw new Error('Rate limit event for a run without an account')\n broadcast({\n type: 'limits',\n accountId,\n limits: recordLimit(accountId, message.rate_limit_info),\n })\n return\n }\n case 'result': {\n if (message.subtype !== 'success')\n this.add(notice(message.errors.join('\\n') || message.subtype))\n this.finishTurn()\n const usage =\n this.model === null ? undefined : message.modelUsage[this.model]\n if (this.context !== null && usage !== undefined)\n this.context = { ...this.context, window: usage.contextWindow }\n this.publishContext()\n return\n }\n case 'system':\n switch (message.subtype) {\n case 'init':\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n this.updateSettings({\n ...this.settings,\n mode: message.permissionMode,\n })\n return\n case 'background_tasks_changed': {\n const live = message.tasks.filter((task) => task.ambient !== true)\n this.backgroundTasks = live.length\n this.tasks = {\n ...Object.fromEntries(\n Object.entries(this.tasks).filter(\n ([, status]) => status !== 'running'\n )\n ),\n ...Object.fromEntries(\n live.map((task) => [task.task_id, 'running' as const])\n ),\n }\n broadcastActivity()\n this.armIdleTimer()\n return\n }\n case 'task_notification':\n if (message.ambient === true) return\n this.tasks = { ...this.tasks, [message.task_id]: message.status }\n broadcastActivity()\n return\n case 'status':\n if (message.permissionMode !== undefined)\n this.updateSettings({\n ...this.settings,\n mode: message.permissionMode,\n })\n return\n case 'compact_boundary': {\n const tokens = message.compact_metadata.post_tokens\n this.context =\n tokens === undefined\n ? null\n : { tokens, window: this.context?.window ?? null }\n this.publishContext()\n this.add({\n type: 'compaction',\n uuid: message.uuid,\n time: Date.now(),\n })\n return\n }\n case 'local_command_output':\n this.add({\n type: 'notice',\n uuid: message.uuid,\n time: Date.now(),\n text: message.content,\n isError: false,\n })\n }\n }\n }\n\n private finishTurn() {\n this.partial = ''\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.push(next.prompt, undefined)\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running || this.backgroundTasks > 0) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private ask(options: {\n toolName: string\n input: Record<string, unknown>\n title: string | null\n suggestions: PermissionUpdate[]\n signal: AbortSignal\n }) {\n const request = toRequest({\n id: randomUUID(),\n toolName: options.toolName,\n input: options.input,\n title: options.title,\n canAlwaysAllow: options.suggestions.length > 0,\n })\n return new Promise<PermissionResult>((resolve) => {\n this.pending.set(request.id, {\n request,\n input: options.input,\n suggestions: options.suggestions,\n resolve,\n })\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request,\n })\n broadcastActivity()\n options.signal.addEventListener('abort', () =>\n this.settle(request.id, { behavior: 'deny', message: 'Cancelled' })\n )\n })\n }\n\n private settle(requestId: string, result: PermissionResult) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n this.pending.delete(requestId)\n pending.resolve(result)\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private add(message: Message) {\n if (this.messages.some((item) => item.uuid === message.uuid)) return\n this.messages.push(message)\n const items = toItems(this.messages).filter((item) => {\n const json = JSON.stringify(item)\n if (this.published.get(item.id) === json) return false\n this.published.set(item.id, json)\n return true\n })\n if (items.length === 0) return\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items,\n })\n }\n\n private updateSettings(settings: Settings) {\n this.settings = settings\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings,\n })\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction notice(text: string): Message {\n return {\n type: 'notice',\n uuid: randomUUID(),\n time: Date.now(),\n text,\n isError: true,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { query } from '@anthropic-ai/claude-agent-sdk'\nimport type { GitStatus, Provider } from '@offsite/core/protocol'\nimport { claudeOptions } from '../lib/claude/index.ts'\nimport { codexCommitMessage } from '../lib/codex/index.ts'\nimport { openCodeCommitMessage } from '../lib/opencode/index.ts'\nimport { readConfig } from '../storage/config.ts'\nimport { providerName } from './accounts.ts'\n\nconst DIFF_LIMIT = 80_000\nconst UNTRACKED_LIMIT = 100\nconst NEW_FILE_LIMIT = 256 * 1024\nconst REPO_DEPTH = 3\n\nexport async function gitStatus(cwd: string): Promise<GitStatus | null> {\n let output\n try {\n output = await git(cwd, ['status', '--porcelain=v2', '--branch'])\n } catch {\n return null\n }\n const status: GitStatus = {\n branch: null,\n upstream: null,\n ahead: 0,\n behind: 0,\n changed: 0,\n }\n for (const line of output.stdout.split('\\n').filter(Boolean)) {\n const [marker, key, ...rest] = line.split(' ')\n if (marker !== '#') status.changed++\n else if (key === 'branch.head')\n status.branch = rest[0] === '(detached)' ? null : rest[0]\n else if (key === 'branch.upstream') status.upstream = rest[0]\n else if (key === 'branch.ab') {\n status.ahead = Number(rest[0])\n status.behind = -Number(rest[1])\n }\n }\n return status\n}\n\nexport async function commit(cwd: string, message: string) {\n if (message.trim() === '') throw new Error('Write a commit message first')\n await git(cwd, ['add', '--all'])\n await git(cwd, ['commit', '--message', message])\n return gitStatus(cwd)\n}\n\nexport async function push(cwd: string) {\n const status = await gitStatus(cwd)\n if (status === null) throw new Error(`${cwd} is not a git repository`)\n if (status.upstream === null)\n await git(cwd, ['push', '--set-upstream', 'origin', 'HEAD'])\n else await git(cwd, ['push'])\n return gitStatus(cwd)\n}\n\nexport async function createPullRequest(cwd: string) {\n const { stdout } = await promisify(execFile)(\n 'gh',\n ['pr', 'create', '--fill'],\n { cwd }\n )\n const url = stdout.trim().split('\\n').at(-1)\n if (url === undefined) throw new Error('gh did not return a pull request URL')\n return { url }\n}\n\nexport async function suggestCommitMessage(\n provider: Provider,\n accountId: string | null,\n cwd: string\n) {\n const diff = (await workingDiff(cwd)).slice(0, DIFF_LIMIT)\n if (diff === '') throw new Error('There is nothing to commit')\n const model = readConfig().commitModels[provider]\n if (model === null)\n throw new Error(\n `Choose a ${providerName(provider)} commit model in Settings → Accounts`\n )\n const prompt = `Write a git commit message for this diff. Reply with only the message: a short summary line, optionally followed by a blank line and a brief body.\\n\\n${diff}`\n if (provider === 'codex')\n return codexCommitMessage(accountId, cwd, model, prompt)\n if (provider === 'opencode') return openCodeCommitMessage(cwd, model, prompt)\n const conversation = query({\n prompt,\n options: {\n ...claudeOptions(accountId, cwd),\n systemPrompt: 'You write concise git commit messages.',\n tools: [],\n model,\n maxTurns: 1,\n persistSession: false,\n },\n })\n for await (const message of conversation) {\n if (message.type !== 'result') continue\n if (message.subtype !== 'success')\n throw new Error(message.errors.join('\\n'))\n if (message.is_error) throw new Error(message.result)\n return { message: message.result.trim() }\n }\n throw new Error('Claude did not reply')\n}\n\nasync function workingDiff(cwd: string) {\n if (!(await isRepo(cwd))) throw new Error(`${cwd} is not a git repository`)\n return repoDiff(cwd, '')\n}\n\nexport async function projectDiff(cwd: string) {\n if (await isRepo(cwd)) return repoDiff(cwd, '')\n const repos = childRepos(cwd, '', REPO_DEPTH)\n if (repos.length === 0)\n throw new Error(`${cwd} is not a git repository and has none inside it`)\n const diffs = await Promise.all(\n repos.map((repo) => repoDiff(path.join(cwd, repo), `${repo}/`))\n )\n return diffs.join('')\n}\n\nexport function git(cwd: string, args: string[]) {\n return promisify(execFile)('git', args, {\n cwd,\n maxBuffer: 64 * 1024 * 1024,\n })\n}\n\nasync function isRepo(cwd: string) {\n try {\n await git(cwd, ['rev-parse', '--is-inside-work-tree'])\n return true\n } catch {\n return false\n }\n}\n\nasync function repoDiff(repo: string, prefix: string) {\n const tracked = await git(repo, [\n 'diff',\n await diffBase(repo),\n '--no-color',\n '--no-ext-diff',\n `--src-prefix=a/${prefix}`,\n `--dst-prefix=b/${prefix}`,\n ])\n const untracked = await git(repo, [\n 'ls-files',\n '--others',\n '--exclude-standard',\n ])\n const added = untracked.stdout\n .split('\\n')\n .filter(Boolean)\n .slice(0, UNTRACKED_LIMIT)\n .map((file) => newFilePatch(repo, file, prefix))\n return [tracked.stdout, ...added].join('')\n}\n\nasync function diffBase(repo: string) {\n try {\n await git(repo, ['rev-parse', '--verify', '--quiet', 'HEAD'])\n return 'HEAD'\n } catch (error) {\n if (!(error instanceof Error && 'code' in error && error.code === 1))\n throw error\n }\n const empty = await git(repo, ['hash-object', '-t', 'tree', '/dev/null'])\n return empty.stdout.trim()\n}\n\nfunction childRepos(root: string, dir: string, depth: number): string[] {\n if (depth === 0) return []\n let entries\n try {\n entries = readdirSync(path.join(root, dir), { withFileTypes: true })\n } catch {\n return []\n }\n return entries\n .filter(\n (entry) =>\n entry.isDirectory() &&\n !entry.name.startsWith('.') &&\n entry.name !== 'node_modules'\n )\n .flatMap((entry) => {\n const relative = dir === '' ? entry.name : `${dir}/${entry.name}`\n return existsSync(path.join(root, relative, '.git'))\n ? [relative]\n : childRepos(root, relative, depth - 1)\n })\n}\n\nfunction newFilePatch(cwd: string, file: string, prefix: string) {\n const name = `${prefix}${file}`\n const header = `diff --git a/${name} b/${name}\\nnew file\\n--- /dev/null\\n+++ b/${name}\\n`\n const full = path.join(cwd, file)\n if (statSync(full).size > NEW_FILE_LIMIT)\n return `${header}Binary or large file\\n`\n const content = readFileSync(full, 'utf8')\n if (content.includes('\\0')) return `${header}Binary or large file\\n`\n const lines = content.split('\\n')\n if (lines.at(-1) === '') lines.pop()\n return `${header}@@ -0,0 +1,${lines.length} @@\\n${lines.map((line) => `+${line}\\n`).join('')}`\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { lstat, open } from 'node:fs/promises'\nimport path from 'node:path'\nimport type { FilePreview } from '@offsite/core/protocol'\nimport { home } from '../storage/storage.ts'\nimport { git } from './git.ts'\n\nconst FILE_LIMIT = 20_000\nconst OUTPUT_LIMIT = 256 * 1024\nconst READ_LIMIT = 1024 * 1024\nconst images = new Map([\n ['.png', 'image/png'],\n ['.jpg', 'image/jpeg'],\n ['.jpeg', 'image/jpeg'],\n ['.gif', 'image/gif'],\n ['.webp', 'image/webp'],\n ['.svg', 'image/svg+xml'],\n])\nconst skipped = new Set(['node_modules', '.git', 'dist', 'target', '.next'])\n\nexport async function listFiles(cwd: string) {\n try {\n const { stdout } = await git(cwd, [\n 'ls-files',\n '--cached',\n '--others',\n '--exclude-standard',\n ])\n return stdout.split('\\n').filter(Boolean).slice(0, FILE_LIMIT)\n } catch {\n return walk(cwd)\n }\n}\n\nexport function readProjectFile(cwd: string, file: string): FilePreview {\n const root = realpathSync(cwd)\n const full = realpathSync(path.resolve(root, file))\n const relative = path.relative(root, full)\n if (\n relative === '..' ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n )\n throw new Error(`${file} is outside the project`)\n const stats = statSync(full)\n if (!stats.isFile()) throw new Error(`${file} is not a file`)\n if (stats.size > READ_LIMIT)\n return { kind: 'large', size: stats.size, limit: READ_LIMIT }\n const data = readFileSync(full)\n const mediaType = images.get(path.extname(full).toLowerCase())\n if (mediaType !== undefined)\n return {\n kind: 'image',\n size: stats.size,\n mediaType,\n data: data.toString('base64'),\n }\n if (data.includes(0)) return { kind: 'binary', size: stats.size }\n return { kind: 'text', size: stats.size, content: data.toString('utf8') }\n}\n\nexport function saveUpload(name: string, data: Buffer) {\n const dir = path.join(home, 'uploads', randomUUID())\n mkdirSync(dir, { recursive: true })\n const file = path.join(dir, path.basename(name))\n writeFileSync(file, data)\n return file\n}\n\nexport async function taskOutput(sessionId: string, file: string) {\n const tasks = path.dirname(file)\n if (\n !/^[\\w-]+$/.test(sessionId) ||\n !path.isAbsolute(file) ||\n path.normalize(file) !== file ||\n !/^\\w+\\.output$/.test(path.basename(file)) ||\n path.basename(tasks) !== 'tasks' ||\n path.basename(path.dirname(tasks)) !== sessionId\n )\n throw new Error('Not a background task output file of this thread')\n let stats\n try {\n stats = await lstat(file)\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT')\n return null\n throw error\n }\n if (!stats.isFile())\n throw new Error('Background task output is not a regular file')\n const start = Math.max(0, stats.size - OUTPUT_LIMIT)\n const handle = await open(file, 'r')\n try {\n const buffer = Buffer.alloc(stats.size - start)\n const read = await handle.read(buffer, 0, buffer.length, start)\n return {\n text: buffer.subarray(0, read.bytesRead).toString('utf8'),\n truncated: start > 0,\n }\n } finally {\n await handle.close()\n }\n}\n\nfunction walk(root: string) {\n const files: string[] = []\n const pending = ['']\n while (pending.length > 0 && files.length < FILE_LIMIT) {\n const dir = pending.pop() ?? ''\n let entries\n try {\n entries = readdirSync(path.join(root, dir), { withFileTypes: true })\n } catch {\n continue\n }\n for (const entry of entries) {\n const relative = dir === '' ? entry.name : `${dir}/${entry.name}`\n if (entry.isDirectory() && !skipped.has(entry.name))\n pending.push(relative)\n if (entry.isFile()) files.push(relative)\n }\n }\n return files\n}\n","import { randomUUID } from 'node:crypto'\nimport { renameSync } from 'node:fs'\nimport path from 'node:path'\nimport type { PushSubscriptionInfo, TerminalPush } from '@offsite/core/protocol'\nimport webPush from 'web-push'\nimport { home, readJson, writeJson } from '../storage/storage.ts'\n\ntype Subscription = {\n endpoint: string\n keys: { p256dh: string; auth: string }\n server: string | null\n}\n\ntype Store = {\n publicKey: string\n privateKey: string\n subscriptions: Subscription[]\n}\n\nconst pushFile = path.join(home, 'push.json')\nconst TITLE_LIMIT = 100\nconst BODY_LIMIT = 500\nconst TIME_TO_LIVE = 15 * 60\nconst SEND_TIMEOUT = 10_000\nconst SUBJECT = 'https://github.com/NazmusSayad/offsite'\n\nlet server = ''\nlet active = false\n\nexport function startPush(address: string) {\n server = address\n try {\n const store = readJson('push.json') as Store | null\n if (store !== null) track(store)\n } catch (error) {\n console.warn(\n `push notifications are off until a browser turns them on again, could not read ${pushFile}: ${error}`\n )\n }\n}\n\nexport function pushActive() {\n return active\n}\n\nexport function pushKey() {\n return { publicKey: read().publicKey }\n}\n\nexport function subscribe(subscription: PushSubscriptionInfo) {\n const endpoint = new URL(subscription.endpoint)\n if (endpoint.protocol !== 'https:')\n throw new Error('the endpoint must be an https URL')\n update((store) => {\n store.subscriptions = store.subscriptions.filter(\n (existing) => existing.endpoint !== subscription.endpoint\n )\n store.subscriptions.push({\n endpoint: subscription.endpoint,\n keys: { p256dh: subscription.keys.p256dh, auth: subscription.keys.auth },\n server,\n })\n })\n console.log('a browser subscribed to push notifications')\n}\n\nexport function unsubscribe(endpoint: string) {\n update((store) => {\n store.subscriptions = store.subscriptions.filter(\n (existing) => existing.endpoint !== endpoint\n )\n })\n console.log('a browser unsubscribed from push notifications')\n}\n\nexport async function sendPush(message: TerminalPush) {\n let store: Store\n try {\n store = read()\n } catch (error) {\n console.error(`could not read push subscriptions: ${error}`)\n return\n }\n const subscriptions = store.subscriptions.filter(ours)\n if (subscriptions.length === 0) return\n const payload = JSON.stringify({\n ...message,\n title: [...message.title].slice(0, TITLE_LIMIT).join(''),\n body: [...message.body].slice(0, BODY_LIMIT).join(''),\n })\n const gone: string[] = []\n await Promise.all(\n subscriptions.map(async (subscription) => {\n try {\n await webPush.sendNotification(subscription, payload, {\n vapidDetails: {\n subject: SUBJECT,\n publicKey: store.publicKey,\n privateKey: store.privateKey,\n },\n TTL: TIME_TO_LIVE,\n urgency: 'high',\n timeout: SEND_TIMEOUT,\n })\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode\n if (status !== undefined && [401, 403, 404, 410].includes(status)) {\n console.log(\n `push subscription ${subscription.endpoint} is gone or was made for another key, removing it`\n )\n gone.push(subscription.endpoint)\n return\n }\n console.warn(\n `could not send a push to ${subscription.endpoint}: ${error}`\n )\n }\n })\n )\n if (gone.length === 0) return\n try {\n update((current) => {\n current.subscriptions = current.subscriptions.filter(\n (subscription) => !gone.includes(subscription.endpoint)\n )\n })\n } catch (error) {\n console.error(`could not remove gone push subscriptions: ${error}`)\n }\n}\n\nfunction ours(subscription: Subscription) {\n return subscription.server === server\n}\n\nfunction track(store: Store) {\n active = store.subscriptions.some(ours)\n}\n\nfunction load(): Store {\n let store: Store | null\n try {\n store = readJson('push.json') as Store | null\n } catch (error) {\n if (!(error instanceof SyntaxError)) throw error\n return replaceCorrupt(error)\n }\n if (store === null) return create()\n if (\n typeof store.publicKey !== 'string' ||\n typeof store.privateKey !== 'string' ||\n !Array.isArray(store.subscriptions)\n )\n return replaceCorrupt(new Error('it is missing its keys or subscriptions'))\n return store\n}\n\nfunction replaceCorrupt(error: Error) {\n const aside = `${pushFile}.corrupt-${randomUUID()}`\n renameSync(pushFile, aside)\n console.warn(\n `${pushFile} is corrupt, moved it to ${aside} and created a new one: ${error}`\n )\n return create()\n}\n\nfunction create(): Store {\n const keys = webPush.generateVAPIDKeys()\n const store = { ...keys, subscriptions: [] }\n save(store)\n return store\n}\n\nfunction save(store: Store) {\n writeJson('push.json', store)\n}\n\nfunction read() {\n const store = load()\n track(store)\n return store\n}\n\nfunction update(change: (store: Store) => void) {\n const store = load()\n change(store)\n save(store)\n track(store)\n}\n","import { randomUUID } from 'node:crypto'\nimport { statSync } from 'node:fs'\nimport { getSessionMessages } from '@anthropic-ai/claude-agent-sdk'\nimport type {\n Methods,\n Rewind,\n RewindResult,\n Settings,\n} from '@offsite/core/protocol'\nimport { history, Run } from '../lib/claude/index.ts'\nimport {\n stopAppServers,\n CodexRun,\n codexHistory,\n revertThread,\n} from '../lib/codex/index.ts'\nimport { type Client, publish } from '../lib/hub.ts'\nimport { runs } from '../lib/live.ts'\nimport {\n OpenCodeRun,\n openCodeHistory,\n rewindOpenCode,\n} from '../lib/opencode/index.ts'\nimport { providerName } from './accounts.ts'\nimport { providerOf, recordInteraction } from './sessions.ts'\n\nconst locks = new Map<string, Promise<void>>()\n\nexport function stopAll() {\n for (const run of runs.values()) run.stop()\n stopAppServers()\n}\n\nfunction sessionHistory(sessionId: string, cwd: string) {\n switch (providerOf(sessionId)) {\n case 'claude':\n return history(sessionId, cwd)\n case 'codex':\n return codexHistory(sessionId)\n case 'opencode':\n return openCodeHistory(sessionId, cwd)\n }\n}\n\nexport function rewind(request: Rewind): Promise<RewindResult> {\n return locked(request.sessionId, () => rewindNow(request))\n}\n\nasync function rewindNow(request: Rewind): Promise<RewindResult> {\n const sessionId = request.sessionId\n if (runs.get(sessionId)?.running === true)\n throw new Error('Stop Claude before rewinding')\n if ((runs.get(sessionId)?.backgroundTasks ?? 0) > 0)\n throw new Error('Wait for background tasks to finish before rewinding')\n const run = await runFor(sessionId, request.cwd, request.settings)\n if (run.provider === 'codex') {\n if (request.code) throw new Error('Codex cannot restore files')\n if (request.dryRun || !request.conversation) return null\n await revertThread(sessionId, request.messageId)\n run.items.clear()\n publish(sessionId, await codexHistory(sessionId))\n return null\n }\n if (run.provider === 'opencode') {\n const result = await rewindOpenCode(request)\n if (request.dryRun) return result\n run.items.clear()\n publish(sessionId, await openCodeHistory(sessionId, request.cwd))\n return result\n }\n let result: RewindResult = null\n if (request.code) {\n const files = await run.query.rewindFiles(request.messageId, {\n dryRun: request.dryRun,\n })\n if (!files.canRewind)\n throw new Error(files.error ?? 'The files cannot be restored')\n result = {\n files: files.filesChanged ?? [],\n insertions: files.insertions ?? 0,\n deletions: files.deletions ?? 0,\n }\n }\n if (request.dryRun || !request.conversation) return result\n const disk = await getSessionMessages(sessionId, { dir: request.cwd })\n const index = disk.findIndex((item) => item.uuid === request.messageId)\n if (index < 1) throw new Error('Cannot rewind the conversation to that point')\n run.stop()\n await run.closed\n new Run({\n sessionId,\n cwd: request.cwd,\n resume: true,\n resumeAt: disk[index - 1].uuid,\n settings: request.settings,\n })\n publish(sessionId, await history(sessionId, request.cwd))\n return result\n}\n\nexport async function open(client: Client, sessionId: string, cwd: string) {\n client.opening = sessionId\n const event = await sessionHistory(sessionId, cwd)\n if (client.opening !== sessionId) return\n client.sessionId = sessionId\n client.send(event)\n}\n\nexport async function send(\n client: Client,\n request: Methods['sessions.send']['params']\n) {\n if (!statSync(request.cwd, { throwIfNoEntry: false })?.isDirectory())\n throw new Error(`${request.cwd} is not a folder`)\n if (request.sessionId === null) {\n const run = await startRun(request.cwd, request.settings)\n const sessionId = run.sessionId\n client.opening = sessionId\n client.sessionId = sessionId\n client.send({ type: 'started', sessionId, cwd: request.cwd })\n await run.submit(request.prompt, request.delivery)\n recordInteraction(sessionId)\n return\n }\n const sessionId = request.sessionId\n await locked(sessionId, () => sendExisting(client, sessionId, request))\n}\n\nasync function sendExisting(\n client: Client,\n sessionId: string,\n request: Methods['sessions.send']['params']\n) {\n const provider = providerOf(sessionId)\n if (request.settings.provider !== provider)\n throw new Error(`This session belongs to ${providerName(provider)}`)\n const existing = runs.get(sessionId)\n if (\n existing?.provider === 'claude' &&\n !existing.running &&\n existing.backgroundTasks === 0 &&\n (await changedElsewhere(existing, request.cwd))\n ) {\n existing.stop()\n await existing.closed\n }\n const run = await runFor(sessionId, request.cwd, request.settings)\n if (run === existing) await run.configure(request.settings)\n else await open(client, sessionId, request.cwd)\n await run.submit(request.prompt, request.delivery)\n recordInteraction(sessionId)\n}\n\nasync function locked<T>(sessionId: string, task: () => Promise<T>) {\n const previous = locks.get(sessionId) ?? Promise.resolve()\n const result = previous.then(task)\n const done = result.then(\n () => undefined,\n () => undefined\n )\n locks.set(sessionId, done)\n await done\n if (locks.get(sessionId) === done) locks.delete(sessionId)\n return result\n}\n\nasync function runFor(sessionId: string, cwd: string, settings: Settings) {\n const run = runs.get(sessionId)\n if (run !== undefined && run.settings.accountId === settings.accountId)\n return run\n if (run !== undefined) {\n if (run.running)\n throw new Error('Wait for this turn to finish before switching accounts')\n if (run.backgroundTasks > 0)\n throw new Error(\n 'Wait for background tasks to finish before switching accounts'\n )\n run.stop()\n await run.closed\n }\n switch (settings.provider) {\n case 'claude':\n return new Run({ sessionId, cwd, resume: true, resumeAt: null, settings })\n case 'codex':\n return CodexRun.resume(sessionId, cwd, settings)\n case 'opencode':\n return OpenCodeRun.resume(sessionId, cwd, settings)\n }\n}\n\nasync function startRun(cwd: string, settings: Settings) {\n switch (settings.provider) {\n case 'claude':\n return new Run({\n sessionId: randomUUID(),\n cwd,\n resume: false,\n resumeAt: null,\n settings,\n })\n case 'codex':\n return CodexRun.start(cwd, settings)\n case 'opencode':\n return OpenCodeRun.start(cwd, settings)\n }\n}\n\nasync function changedElsewhere(run: Run, cwd: string) {\n if (run.messages.length === 0) return false\n const history = await getSessionMessages(run.sessionId, { dir: cwd })\n const last = history.at(-1)?.uuid\n return last !== undefined && !run.messages.some((item) => item.uuid === last)\n}\n","import type { Platform } from './protocol.ts'\n\nfunction zshOptionsSupported(options: string[]) {\n for (let position = 0; position < options.length; position++) {\n const word = options[position]\n if (!word.startsWith('-') && !word.startsWith('+')) return false\n const enable = word.startsWith('-')\n const flags = word.slice(1)\n if (flags === '' || flags === '-') return false\n if (flags.startsWith('-')) {\n if (!zshOptionAllowed(flags.slice(1), enable)) return false\n continue\n }\n for (let index = 0; index < flags.length; index++) {\n const letter = flags[index]\n if (letter === 'o') {\n let name = flags.slice(index + 1)\n if (name === '') {\n position++\n if (position === options.length) return false\n name = options[position]\n }\n if (!zshOptionAllowed(name, enable)) return false\n break\n }\n if (letter === 'b' || letter === 'c') return false\n if (enable && 'dfnprvx'.includes(letter)) return false\n if (!enable && letter === 'i') return false\n }\n }\n return true\n}\n\nfunction zshOptionAllowed(option: string, enable: boolean) {\n let name = option.toLowerCase().replace(/[-_]/g, '')\n let value = enable\n if (name.startsWith('no')) {\n name = name.slice(2)\n value = !enable\n }\n if (['rcs', 'globalrcs', 'interactive', 'exec'].includes(name)) return value\n if (\n ['privileged', 'restricted', 'sourcetrace', 'verbose', 'xtrace'].includes(\n name\n )\n )\n return !value\n return true\n}\n\nexport function shellIntegrationIssue(\n command: string | null,\n platform: Platform,\n defaultShell: string\n) {\n if (platform === 'windows') return 'Not available on Windows'\n if (command !== null && /[\\n\"'\\\\$`;&|<>()*?[\\]{}#!]/.test(command))\n return 'Not available for commands with shell syntax'\n const words =\n command === null\n ? [defaultShell]\n : command.split(/[ \\t]/).filter((word) => word !== '')\n if (words.length === 0) return 'Available for bash, zsh and fish'\n const path = words[0]\n const name = path.split('/').pop()\n const options = words.slice(1)\n if (name === 'bash') {\n if (platform === 'macos' && (path === '/bin/bash' || !path.includes('/')))\n return 'Needs a newer bash than the one macOS includes'\n if (options.every((option) => ['-l', '--login', '-i'].includes(option)))\n return null\n return 'Not available with these bash options'\n }\n if (name === 'zsh') {\n if (zshOptionsSupported(options)) return null\n return 'Not available with these zsh options'\n }\n if (name === 'fish') {\n const supported = options.every((option) => {\n if (option.startsWith('--')) {\n const name = option.slice(2).split('=')[0]\n return (\n name === '' ||\n !['command', 'no-config', 'no-execute'].some((long) =>\n long.startsWith(name)\n )\n )\n }\n return !(option.startsWith('-') && /[cNn]/.test(option))\n })\n if (supported) return null\n return 'Not available with these fish options'\n }\n return 'Available for bash, zsh and fish'\n}\n","import {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { shellIntegrationIssue } from '@offsite/core/shell-check'\nimport { serverDir } from '../../args.ts'\nimport { platform } from '../../storage/config.ts'\nimport { home } from '../../storage/storage.ts'\n\nconst scripts = path.join(\n serverDir,\n 'src',\n 'services',\n 'terminal',\n 'shell-integration'\n)\nconst folder = path.join(home, 'shell-integration')\n\nexport function prepare(\n env: Record<string, string>,\n command: string | null,\n shell: string\n) {\n if (shellIntegrationIssue(command, platform(), shell) !== null) return null\n const words =\n command === null\n ? [shell]\n : command.split(/[ \\t]/).filter((word) => word !== '')\n const program = command === null ? `'${shell}'` : words[0]\n const args = words.slice(1)\n const name = words[0].split('/').pop()\n let integration: string\n if (name === 'bash') {\n const userHome = process.env.HOME\n if (userHome === undefined || userHome === '') return null\n const script = path.join(folder, 'bash', 'offsite.bash')\n if (!writeScript(script, 'bash/offsite.bash')) return null\n env.ENV = script.replace(/[\\\\$`\"]/g, (character) => `\\\\${character}`)\n env.HISTFILE = path.join(userHome, '.bash_history')\n integration = ' --posix'\n } else if (name === 'zsh') {\n if (!zshGlobalsSupported()) return null\n if (\n ['.zshenv', '.zprofile', '.zshrc', '.zlogin'].every(\n (file) => !existsSync(path.join(os.homedir(), file))\n )\n )\n return null\n if (!writeScript(path.join(folder, 'zsh', '.zshenv'), 'zsh/.zshenv'))\n return null\n env.ZDOTDIR = path.join(folder, 'zsh')\n integration = ''\n } else if (name === 'fish') {\n const script = path.join(folder, 'fish', 'offsite.fish')\n if (!writeScript(script, 'fish/offsite.fish')) return null\n const source = `source '${script.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}'`\n integration = ` --init-command '${source.replaceAll(\"'\", \"'\\\\''\")}'`\n } else throw new Error(`shell integration does not support ${name}`)\n return [`${program}${integration}`, ...args].join(' ')\n}\n\nfunction zshGlobalsSupported() {\n for (const global of ['/etc/zshenv', '/etc/zsh/zshenv']) {\n let contents: string\n try {\n contents = readFileSync(global, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue\n console.warn(\n `could not read ${global}, zsh starts without shell integration: ${error}`\n )\n return false\n }\n for (const rawLine of contents.split('\\n')) {\n const line = rawLine.trimStart()\n if (line.startsWith('#')) continue\n const normalized = line.toLowerCase().replaceAll('_', '')\n if (\n [\n 'zdotdir',\n 'rcs',\n 'emulate',\n 'debug',\n 'xtrace',\n 'verbose',\n 'sourcetrace',\n ].some((word) => normalized.includes(word))\n )\n return false\n let setting = false\n for (const word of line.split(/[ \\t;&|]/)) {\n if (word === '') continue\n if (['set', 'setopt', 'unsetopt'].includes(word)) {\n setting = true\n continue\n }\n const flag = word.startsWith('-') || word.startsWith('+')\n if (setting && flag && /[fxv]/.test(word)) return false\n if (!flag) setting = false\n }\n }\n }\n return true\n}\n\nfunction writeScript(target: string, source: string) {\n try {\n const contents = readFileSync(path.join(scripts, source), 'utf8')\n const existing = lstatSync(target, { throwIfNoEntry: false })\n if (existing?.isFile() && readFileSync(target, 'utf8') === contents)\n return true\n mkdirSync(path.dirname(target), { recursive: true })\n rmSync(`${target}.tmp`, { force: true })\n writeFileSync(`${target}.tmp`, contents, { flag: 'wx' })\n renameSync(`${target}.tmp`, target)\n return true\n } catch (error) {\n console.warn(\n `could not write ${target}, the shell starts without shell integration: ${error}`\n )\n return false\n }\n}\n","import { execFile } from 'node:child_process'\nimport { readFileSync, realpathSync, statSync } from 'node:fs'\nimport { readFile, readlink } from 'node:fs/promises'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { spawn } from '@lydell/node-pty'\nimport {\n defaultShell,\n platform,\n readConfig,\n version,\n} from '../../storage/config.ts'\nimport { prepare } from './shell-integration.ts'\n\nconst run = promisify(execFile)\nconst iterm2Version = '3.6.8'\nconst ghosttyVersion = '1.3.1'\nconst shellNames =\n process.platform === 'win32'\n ? ['pwsh', 'powershell', 'cmd']\n : ['zsh', 'bash', 'fish', 'pwsh']\n\nexport function startShell(cwd: string) {\n const options = launch()\n const env: Record<string, string> = {}\n let file: string\n let args: string[]\n if (process.platform === 'win32') {\n Object.assign(env, process.env)\n file = options.command ?? defaultShell()\n args = []\n } else {\n for (const name of ['HOME', 'USER', 'LOGNAME', 'TMPDIR', 'SSH_AUTH_SOCK']) {\n const value = process.env[name]\n if (value !== undefined) env[name] = value\n }\n const shell = defaultShell()\n env.SHELL = shell\n env.LANG = 'en_US.UTF-8'\n if (process.env.PATH !== undefined) env.PATH = process.env.PATH\n const program =\n (options.shellIntegration\n ? prepare(env, options.command, shell)\n : null) ??\n options.command ??\n `'${shell}'`\n file = '/bin/bash'\n args = ['--noprofile', '--norc', '-c', `export -n PATH; exec -l ${program}`]\n }\n env.TERM = 'xterm-256color'\n env.COLORTERM = 'truecolor'\n Object.assign(env, options.environment)\n return spawn(file, args, {\n name: 'xterm-256color',\n cols: 80,\n rows: 24,\n cwd,\n env,\n encoding: null,\n })\n}\n\nexport async function currentDirectory(pid: number) {\n if (process.platform === 'linux') return readlink(`/proc/${pid}/cwd`)\n if (process.platform === 'darwin') {\n const { stdout } = await run('lsof', [\n '-a',\n '-d',\n 'cwd',\n '-p',\n String(pid),\n '-Fn',\n ])\n const line = stdout.split('\\n').find((item) => item.startsWith('n'))\n if (line === undefined) throw new Error(`lsof found no folder for ${pid}`)\n return line.slice(1)\n }\n throw new Error(\n 'reading the directory of another process is not supported on this platform'\n )\n}\n\nexport async function busyProgram(pid: number) {\n if (process.platform === 'win32') {\n const { stdout } = await run('powershell.exe', [\n '-NoProfile',\n '-Command',\n `Get-CimInstance Win32_Process -Filter \"ParentProcessId=${pid}\" | Select-Object -ExpandProperty Name`,\n ])\n const names = [\n ...new Set(\n stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line !== '')\n ),\n ]\n return names.length === 0 ? null : names.join(', ')\n }\n const group = await foregroundGroup(pid)\n if (group <= 0) throw new Error('its foreground process group is unknown')\n if (group === pid) return null\n try {\n return await programName(group)\n } catch (error) {\n console.warn(`could not read the name of process ${group}: ${error}`)\n return `process ${group}`\n }\n}\n\nasync function foregroundGroup(pid: number) {\n if (process.platform === 'linux') {\n const text = await readFile(`/proc/${pid}/stat`, 'utf8')\n return Number(text.slice(text.lastIndexOf(')') + 2).split(' ')[5])\n }\n const { stdout } = await run('ps', ['-o', 'tpgid=', '-p', String(pid)])\n return Number(stdout.trim())\n}\n\nasync function programName(pid: number) {\n if (process.platform === 'linux')\n return (await readFile(`/proc/${pid}/comm`, 'utf8')).trimEnd()\n const { stdout } = await run('ps', ['-o', 'comm=', '-p', String(pid)])\n return path.basename(stdout.trim())\n}\n\nfunction launch() {\n const config = readConfig().terminal\n const [program, terminal, programVersion] = {\n offsite: ['offsite', 'offsite', version],\n ghostty: ['ghostty', 'ghostty', ghosttyVersion],\n iterm2: ['iTerm.app', 'iTerm2', iterm2Version],\n }[config.behavior.terminalIdentity]\n return {\n command: config.shell[platform()],\n environment: {\n TERM_PROGRAM: program,\n TERM_PROGRAM_VERSION: programVersion,\n LC_TERMINAL: terminal,\n LC_TERMINAL_VERSION: programVersion,\n },\n shellIntegration: config.behavior.shellIntegration,\n }\n}\n\nexport function listShells() {\n const candidates = (process.env.PATH ?? '')\n .split(path.delimiter)\n .filter((directory) => directory !== '')\n .flatMap((directory) =>\n shellNames.map((name) => path.join(directory, executable(name)))\n )\n if (process.platform !== 'win32') {\n try {\n candidates.push(\n ...readFileSync('/etc/shells', 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.startsWith('/'))\n )\n } catch {}\n }\n const seen = new Set<string>()\n const shells: { name: string; path: string }[] = []\n for (const name of shellNames) {\n for (const candidate of candidates) {\n if (path.basename(candidate) !== executable(name)) continue\n if (!statSync(candidate, { throwIfNoEntry: false })?.isFile()) continue\n let target\n try {\n target = realpathSync(candidate)\n } catch {\n continue\n }\n if (seen.has(target)) continue\n seen.add(target)\n shells.push({ name, path: candidate })\n }\n }\n return shells\n}\n\nfunction executable(name: string) {\n return process.platform === 'win32' ? `${name}.exe` : name\n}\n","export const ALERT_DELAY = 500\n\nexport type Alert =\n | { type: 'bell' }\n | { type: 'notification'; title: string; body: string }\n\nconst BELL_GAP = 5000\nconst NOTIFICATION_GAP = 1000\nconst PAYLOAD_LIMIT = 1024\nconst ESC = 0x1b\nconst BEL = 0x07\nconst CAN = 0x18\nconst SUB = 0x1a\n\nexport class Scanner {\n title = ''\n private state:\n | 'ground'\n | 'escape'\n | 'osc'\n | 'oscEscape'\n | 'text'\n | 'textEscape' = 'ground'\n private payload: number[] = []\n\n scan(bytes: Uint8Array) {\n let alert: Alert | null = null\n let index = 0\n while (index < bytes.length) {\n if (this.state === 'ground') {\n let offset = index\n while (\n offset < bytes.length &&\n bytes[offset] !== ESC &&\n bytes[offset] !== BEL\n )\n offset++\n if (offset === bytes.length) break\n index = offset\n }\n const found = this.step(bytes[index])\n index++\n if (found === null) continue\n if (found.type === 'bell') alert ??= found\n else alert = found\n }\n return alert\n }\n\n private step(byte: number): Alert | null {\n if (byte === CAN || byte === SUB) {\n this.state = 'ground'\n return null\n }\n switch (this.state) {\n case 'ground':\n if (byte === ESC) this.state = 'escape'\n if (byte === BEL) return { type: 'bell' }\n return null\n case 'escape':\n if (byte === 0x5d) {\n this.payload = []\n this.state = 'osc'\n } else if ([0x50, 0x58, 0x5e, 0x5f].includes(byte)) this.state = 'text'\n else if (byte !== ESC) this.state = 'ground'\n if (byte === BEL) return { type: 'bell' }\n return null\n case 'osc':\n if (byte === BEL) {\n this.state = 'ground'\n return this.finish()\n }\n if (byte === ESC) this.state = 'oscEscape'\n else if (this.payload.length < PAYLOAD_LIMIT) this.payload.push(byte)\n return null\n case 'oscEscape':\n if (byte === 0x5c) {\n this.state = 'ground'\n return this.finish()\n }\n this.state = 'escape'\n return this.step(byte)\n case 'text':\n if (byte === ESC) this.state = 'textEscape'\n return null\n case 'textEscape':\n if (byte === 0x5c) {\n this.state = 'ground'\n return null\n }\n this.state = 'escape'\n return this.step(byte)\n }\n }\n\n private finish(): Alert | null {\n const text = Buffer.from(this.payload).toString('utf8')\n if (text.startsWith('0;') || text.startsWith('2;')) {\n this.title = text.slice(2)\n return null\n }\n if (text.startsWith('9;')) {\n const body = text.slice(2)\n const digits = /^\\d*/.exec(body)?.[0].length ?? 0\n if (digits > 0 && (body.length === digits || body[digits] === ';'))\n return null\n return { type: 'notification', title: '', body }\n }\n if (text.startsWith('777;notify;')) {\n const rest = text.slice('777;notify;'.length)\n const split = rest.indexOf(';')\n return split === -1\n ? { type: 'notification', title: rest, body: '' }\n : {\n type: 'notification',\n title: rest.slice(0, split),\n body: rest.slice(split + 1),\n }\n }\n return null\n }\n}\n\nexport class Alerts {\n private pushedAt: number | null = null\n private bellPending = false\n\n startBell() {\n if (this.bellPending || this.pushedRecently(BELL_GAP)) return false\n this.bellPending = true\n return true\n }\n\n finishBell() {\n if (!this.bellPending) return false\n this.bellPending = false\n this.pushedAt = Date.now()\n return true\n }\n\n startNotification() {\n this.bellPending = false\n if (this.pushedRecently(NOTIFICATION_GAP)) return false\n this.pushedAt = Date.now()\n return true\n }\n\n private pushedRecently(gap: number) {\n return this.pushedAt !== null && Date.now() - this.pushedAt < gap\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdirSync, statSync, writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport type { IPty } from '@lydell/node-pty'\nimport {\n type BusyResult,\n decodeFrame,\n encodeFrame,\n FRAME_INPUT,\n FRAME_OUTPUT,\n FRAME_REPLAY,\n FRAME_REPLY,\n type TerminalEvent,\n type TerminalLayout,\n type TerminalProject,\n type TerminalRequest,\n type TerminalTab,\n} from '@offsite/core/protocol'\nimport type { Client } from '../../lib/hub.ts'\nimport { home } from '../../storage/storage.ts'\nimport { pushActive, sendPush } from '../push.ts'\nimport { ALERT_DELAY, type Alert, Alerts, Scanner } from './alerts.ts'\nimport { busyProgram, currentDirectory, startShell } from './process.ts'\n\ntype Connection = {\n client: Client\n sizes: Map<number, { cols: number; rows: number }>\n}\n\ntype Terminal = {\n pty: IPty\n history: Buffer[]\n historySize: number\n owner: Connection | null\n alerts: Alerts\n scanner: Scanner\n}\n\nconst HISTORY_LIMIT = 2 * 1024 * 1024\nconst OUTPUT_LIMIT = 1024 * 1024\nconst STALL_LIMIT = 10_000\nconst SILENCE_LIMIT = 90_000\nconst KILL_DELAY = 3000\nconst pasteTypes: Record<string, string> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n}\n\nconst instance = `${Date.now()}-${randomUUID()}`\nconst projects = new Map<string, TerminalProject>()\nconst terminals = new Map<number, Terminal>()\nconst connections = new Map<Client, Connection>()\nconst paused = new Set<IPty>()\nlet nextTab = 0\nlet draining: NodeJS.Timeout | null = null\n\nexport async function terminalRequest(\n client: Client,\n message: TerminalRequest\n) {\n if (message.type === 'attach') {\n attach(client)\n return\n }\n if (message.type === 'detach') {\n detachTerminal(client)\n return\n }\n const connection = connections.get(client)\n if (connection === undefined) throw new Error('the terminal is not attached')\n await request(connection, message)\n}\n\nexport function terminalInput(client: Client, frame: Buffer) {\n const connection = connections.get(client)\n if (connection === undefined) {\n console.warn('terminal input from a browser that is not attached')\n return\n }\n input(connection, frame)\n}\n\nexport function detachTerminal(client: Client) {\n const connection = connections.get(client)\n if (connection === undefined) return\n connections.delete(client)\n for (const terminal of terminals.values())\n if (terminal.owner === connection) terminal.owner = null\n}\n\nexport async function busyTerminal(id: number): Promise<BusyResult> {\n const terminal = terminals.get(id)\n if (terminal === undefined) return { program: null }\n try {\n return { program: await busyProgram(terminal.pty.pid) }\n } catch (error) {\n console.warn(`could not tell if terminal ${id} is busy: ${error}`)\n return { error: String(error) }\n }\n}\n\nexport function savePastedImage(type: string, data: Buffer) {\n const extension = pasteTypes[type]\n if (extension === undefined)\n throw new Error('pasted image must be a PNG, JPEG, GIF or WebP image')\n const directory = path.join(home, 'paste')\n mkdirSync(directory, { recursive: true })\n const file = path.join(\n directory,\n `${Date.now()}-${randomUUID()}.${extension}`\n )\n writeFileSync(file, data)\n return file\n}\n\nfunction attach(client: Client) {\n detachTerminal(client)\n const connection: Connection = { client, sizes: new Map() }\n connections.set(client, connection)\n send(connection, {\n type: 'active',\n layout: layout(),\n instance,\n })\n for (const project of projects.values())\n for (const tab of project.tabs)\n forward(\n connection,\n tab.id,\n true,\n Buffer.concat(terminals.get(tab.id)?.history ?? [])\n )\n}\n\nasync function request(\n connection: Connection,\n message: Exclude<TerminalRequest, { type: 'attach' | 'detach' }>\n) {\n switch (message.type) {\n case 'resize': {\n const terminal = terminals.get(message.id)\n if (terminal === undefined) return\n connection.sizes.set(message.id, {\n cols: message.cols,\n rows: message.rows,\n })\n terminal.owner = connection\n terminal.pty.resize(message.cols, message.rows)\n return\n }\n case 'createTab':\n await createTab(message.cwd)\n break\n case 'closeTab':\n closeTab(message.id)\n break\n case 'renameTab': {\n const tab = findTab(message.id)\n if (tab === undefined) return\n tab.customName = message.name === '' ? null : message.name\n break\n }\n case 'minimizeTab': {\n const project = [...projects.values()].find((item) =>\n item.tabs.some((tab) => tab.id === message.id)\n )\n if (project === undefined) return\n if (!project.tabs.some((tab) => tab.id !== message.id && !tab.minimized))\n return\n const index = project.tabs.findIndex((tab) => tab.id === message.id)\n project.tabs[index].minimized = true\n if (project.activeTab === message.id) {\n const next = nearestVisible(project.tabs, index)\n project.activeTab = next === undefined ? null : project.tabs[next].id\n }\n break\n }\n case 'select': {\n const project = projects.get(message.cwd) ?? {\n tabs: [],\n activeTab: null,\n }\n projects.set(message.cwd, project)\n const tab = project.tabs.find((item) => item.id === message.tabId)\n if (tab !== undefined) {\n tab.minimized = false\n project.activeTab = tab.id\n }\n if (project.tabs.length === 0) await createTab(message.cwd)\n break\n }\n }\n publish()\n}\n\nfunction input(connection: Connection, bytes: Buffer) {\n let frame\n try {\n frame = decodeFrame(bytes)\n } catch (error) {\n console.warn(`ignoring terminal input: ${error}`)\n return\n }\n const terminal = terminals.get(frame.id)\n if (terminal === undefined) {\n console.warn(`input for terminal ${frame.id}, which does not exist`)\n return\n }\n if (frame.kind === FRAME_REPLY) {\n if (terminal.owner !== null && terminal.owner !== connection) return\n } else if (frame.kind === FRAME_INPUT) {\n const size = connection.sizes.get(frame.id)\n if (terminal.owner !== connection && size !== undefined) {\n terminal.owner = connection\n terminal.pty.resize(size.cols, size.rows)\n }\n } else {\n console.warn(`ignoring terminal input of unknown kind ${frame.kind}`)\n return\n }\n terminal.pty.write(Buffer.from(frame.data))\n}\n\nasync function createTab(cwd: string) {\n if (!statSync(cwd, { throwIfNoEntry: false })?.isDirectory()) {\n console.error(`${cwd} is not a folder, terminal not created`)\n return\n }\n const project = projects.get(cwd) ?? { tabs: [], activeTab: null }\n projects.set(cwd, project)\n const active =\n project.activeTab === null ? undefined : terminals.get(project.activeTab)\n let directory = cwd\n if (active !== undefined) {\n try {\n directory = await currentDirectory(active.pty.pid)\n } catch (error) {\n console.warn(\n `starting in the project folder, could not read the folder of the active terminal: ${error}`\n )\n }\n }\n nextTab += 1\n const id = nextTab\n let pty: IPty\n try {\n pty = startShell(directory)\n } catch (error) {\n console.error(`could not start terminal ${id}: ${error}`)\n return\n }\n const terminal: Terminal = {\n pty,\n history: [],\n historySize: 0,\n owner: null,\n alerts: new Alerts(),\n scanner: new Scanner(),\n }\n terminals.set(id, terminal)\n project.tabs.push({ id, customName: null, minimized: false })\n project.activeTab = id\n pty.onData((data) => output(id, terminal, data as unknown as Buffer))\n pty.onExit(() => {\n terminals.delete(id)\n paused.delete(pty)\n if (closeTab(id)) publish()\n })\n}\n\nfunction closeTab(id: number) {\n const project = [...projects.values()].find((item) =>\n item.tabs.some((tab) => tab.id === id)\n )\n if (project === undefined) return false\n const index = project.tabs.findIndex((tab) => tab.id === id)\n project.tabs.splice(index, 1)\n if (project.activeTab === id) {\n let next: number | undefined = nearestVisible(project.tabs, index)\n if (next === undefined && project.tabs.length > 0)\n next = Math.min(index, project.tabs.length - 1)\n if (next !== undefined) project.tabs[next].minimized = false\n project.activeTab = next === undefined ? null : project.tabs[next].id\n }\n const terminal = terminals.get(id)\n if (terminal === undefined) return true\n terminal.pty.kill()\n if (process.platform !== 'win32')\n setTimeout(() => {\n if (terminals.get(id) === terminal) terminal.pty.kill('SIGKILL')\n }, KILL_DELAY)\n return true\n}\n\nfunction output(id: number, terminal: Terminal, data: Buffer) {\n terminal.history.push(data)\n terminal.historySize += data.length\n while (terminal.historySize > HISTORY_LIMIT && terminal.history.length > 1) {\n terminal.historySize -= terminal.history[0].length\n terminal.history.shift()\n }\n for (const connection of connections.values())\n forward(connection, id, false, data)\n scan(id, terminal, data)\n if (\n [...connections.values()].some(\n (connection) => connection.client.socket.bufferedAmount > OUTPUT_LIMIT\n )\n ) {\n terminal.pty.pause()\n paused.add(terminal.pty)\n draining ??= drain()\n }\n}\n\nfunction drain() {\n const progress = new Map<Connection, { queued: number; at: number }>()\n return setInterval(() => {\n let full = false\n for (const connection of connections.values()) {\n const queued = connection.client.socket.bufferedAmount\n if (queued <= OUTPUT_LIMIT) continue\n const now = Date.now()\n const last = progress.get(connection) ?? { queued: Infinity, at: now }\n if (queued < last.queued) last.at = now\n last.queued = queued\n progress.set(connection, last)\n if (now - last.at > STALL_LIMIT) {\n console.warn('a browser is not reading fast enough, disconnecting it')\n connection.client.socket.terminate()\n continue\n }\n full = true\n }\n if (full) return\n if (draining !== null) clearInterval(draining)\n draining = null\n for (const pty of paused) pty.resume()\n paused.clear()\n }, 10)\n}\n\nfunction scan(id: number, terminal: Terminal, data: Buffer) {\n if (!pushActive()) {\n terminal.scanner = new Scanner()\n return\n }\n const alert = terminal.scanner.scan(data)\n if (alert === null || browserOpen()) return\n const started =\n alert.type === 'bell'\n ? terminal.alerts.startBell()\n : terminal.alerts.startNotification()\n if (!started) return\n const windowTitle = terminal.scanner.title\n setTimeout(() => push(id, alert, windowTitle), ALERT_DELAY)\n}\n\nfunction push(id: number, alert: Alert, windowTitle: string) {\n const terminal = terminals.get(id)\n if (terminal === undefined) return\n let title = ''\n let body: string\n if (alert.type === 'bell') {\n if (!terminal.alerts.finishBell()) return\n body = 'Bell'\n } else {\n title = alert.title\n body = alert.body\n }\n if (browserOpen()) return\n const entry = [...projects].find(([, project]) =>\n project.tabs.some((tab) => tab.id === id)\n )\n if (entry === undefined) return\n const tab = findTab(id)\n if (title === '') title = tab?.customName ?? (windowTitle || 'Terminal')\n void sendPush({ title, body, cwd: entry[0], tabId: id })\n}\n\nfunction browserOpen() {\n return [...connections.values()].some(\n (connection) => Date.now() - connection.client.heardAt < SILENCE_LIMIT\n )\n}\n\nfunction findTab(id: number): TerminalTab | undefined {\n for (const project of projects.values()) {\n const tab = project.tabs.find((item) => item.id === id)\n if (tab !== undefined) return tab\n }\n return undefined\n}\n\nfunction nearestVisible(tabs: TerminalTab[], index: number) {\n for (let position = index; position < tabs.length; position++)\n if (!tabs[position].minimized) return position\n for (\n let position = Math.min(index, tabs.length) - 1;\n position >= 0;\n position--\n )\n if (!tabs[position].minimized) return position\n return undefined\n}\n\nfunction layout(): TerminalLayout {\n return Object.fromEntries(projects)\n}\n\nfunction publish() {\n const event: TerminalEvent = { type: 'layout', layout: layout() }\n for (const connection of connections.values()) send(connection, event)\n}\n\nfunction forward(\n connection: Connection,\n id: number,\n replay: boolean,\n data: Buffer\n) {\n connection.client.socket.send(\n encodeFrame(replay ? FRAME_REPLAY : FRAME_OUTPUT, id, data)\n )\n}\n\nfunction send(connection: Connection, event: TerminalEvent) {\n connection.client.send({ type: 'terminal', event })\n}\n","import os from 'node:os'\nimport {\n type Call,\n type Method,\n type Methods,\n PROTOCOL,\n} from '@offsite/core/protocol'\nimport type { WebSocket } from 'ws'\nimport { agentMessages, earlier, image } from '../lib/claude/index.ts'\nimport { codexAgent } from '../lib/codex/index.ts'\nimport { type Client, clients } from '../lib/hub.ts'\nimport { activity, runs } from '../lib/live.ts'\nimport { openCodeAgent } from '../lib/opencode/index.ts'\nimport {\n accounts,\n addAccount,\n capabilities,\n publishAccounts,\n removeAccount,\n updateAccount,\n} from '../services/accounts.ts'\nimport {\n listFiles,\n readProjectFile,\n saveUpload,\n taskOutput,\n} from '../services/files.ts'\nimport {\n commit,\n createPullRequest,\n gitStatus,\n projectDiff,\n push,\n suggestCommitMessage,\n} from '../services/git.ts'\nimport {\n addProject,\n directories,\n projects,\n removeProject,\n updateProject,\n} from '../services/projects.ts'\nimport { pushKey, subscribe, unsubscribe } from '../services/push.ts'\nimport { open, rewind, send } from '../services/runs.ts'\nimport {\n fork,\n providerOf,\n publishSessions,\n recordInteraction,\n removeSession,\n sessions,\n updateSession,\n watchSessions,\n} from '../services/sessions.ts'\nimport { listShells } from '../services/terminal/process.ts'\nimport {\n busyTerminal,\n detachTerminal,\n savePastedImage,\n terminalInput,\n terminalRequest,\n} from '../services/terminal/terminal.ts'\nimport { configInfo, readConfig, saveConfig } from '../storage/config.ts'\n\ntype Handlers = {\n [M in Method]: (\n params: Methods[M]['params'],\n client: Client\n ) => Methods[M]['result'] | Promise<Methods[M]['result']>\n}\n\nconst handlers: Handlers = {\n ping: () => null,\n sync: async () => ({\n ...configInfo(),\n protocol: PROTOCOL,\n hostname: os.hostname(),\n projects: projects(),\n sessions: await sessions(),\n activity: activity(),\n }),\n 'config.get': () => configInfo(),\n 'config.save': (params) => {\n const before = readConfig().claudeBaseDir\n const saved = saveConfig(params)\n if (saved.claudeBaseDir === before) return saved\n watchSessions()\n void publishSessions()\n void publishAccounts()\n return saved\n },\n 'projects.add': async (params) => {\n const project = await addProject(params.path)\n void publishSessions()\n return project\n },\n 'projects.update': (params) => updateProject(params.path, params.patch),\n 'projects.remove': (params) => {\n removeProject(params.path)\n void publishSessions()\n return null\n },\n 'directories.list': (params) => directories(params.path),\n 'sessions.update': async (params) => {\n try {\n await updateSession(params.id, params.patch)\n } finally {\n void publishSessions()\n }\n return null\n },\n 'sessions.remove': async (params) => {\n try {\n await removeSession(params.id)\n } finally {\n void publishSessions()\n }\n return null\n },\n 'sessions.open': async (params, client) => {\n await open(client, params.sessionId, params.cwd)\n return null\n },\n 'sessions.earlier': (params) => earlier(params.sessionId, params.before),\n 'sessions.image': (params) =>\n image(params.sessionId, params.itemId, params.index),\n 'sessions.agent': (params) => {\n switch (providerOf(params.sessionId)) {\n case 'claude':\n return agentMessages(\n params.sessionId,\n params.cwd,\n params.agentId,\n params.parent\n )\n case 'codex':\n return codexAgent(params.agentId, params.parent)\n case 'opencode':\n return openCodeAgent(params.agentId, params.parent)\n }\n },\n 'sessions.send': async (params, client) => {\n await send(client, params)\n return null\n },\n 'sessions.unqueue': (params) => {\n runs.get(params.sessionId)?.unqueue(params.id)\n return null\n },\n 'sessions.steer': (params) => {\n runs.get(params.sessionId)?.steer(params.id)\n return null\n },\n 'sessions.interrupt': async (params) => {\n await runs.get(params.sessionId)?.interrupt()\n return null\n },\n 'sessions.stopTask': async (params) => {\n await runs.get(params.sessionId)?.stopTask(params.taskId)\n return null\n },\n 'sessions.configure': async (params) => {\n await runs.get(params.sessionId)?.configure(params.settings)\n return null\n },\n 'sessions.respond': async (params) => {\n const run = runs.get(params.sessionId)\n if (run === undefined) return null\n await run.respond(params.requestId, params.decision, params.answers)\n recordInteraction(params.sessionId)\n return null\n },\n 'sessions.rewind': (params) => rewind(params),\n 'sessions.fork': async (params) => {\n const result = await fork(params.sessionId, params.cwd, params.messageId)\n void publishSessions()\n return result\n },\n 'accounts.list': () => accounts(),\n 'accounts.add': (params) => {\n addAccount(params.provider, params.name, params.configDir)\n void publishAccounts()\n return null\n },\n 'accounts.update': (params) => {\n updateAccount(params.id, params.name, params.configDir)\n void publishAccounts()\n return null\n },\n 'accounts.remove': (params) => {\n removeAccount(params.id)\n void publishAccounts()\n return null\n },\n capabilities: (params) => capabilities(params.accountId, params.cwd),\n 'files.list': (params) => listFiles(params.cwd),\n 'files.read': (params) => readProjectFile(params.cwd, params.path),\n 'files.upload': (params) =>\n saveUpload(params.name, Buffer.from(params.data, 'base64')),\n 'tasks.output': (params) => taskOutput(params.sessionId, params.path),\n 'git.status': (params) => gitStatus(params.cwd),\n 'git.diff': (params) => projectDiff(params.cwd),\n 'git.commit': (params) => commit(params.cwd, params.message),\n 'git.push': (params) => push(params.cwd),\n 'git.pullRequest': (params) => createPullRequest(params.cwd),\n 'git.message': (params) =>\n suggestCommitMessage(params.provider, params.accountId, params.cwd),\n 'push.key': () => pushKey(),\n 'push.subscribe': (params) => {\n subscribe(params)\n return null\n },\n 'push.unsubscribe': (params) => {\n unsubscribe(params.endpoint)\n return null\n },\n terminal: async (params, client) => {\n await terminalRequest(client, params)\n return null\n },\n 'terminal.shells': () => listShells(),\n 'terminal.busy': (params) => busyTerminal(params.id),\n 'terminal.paste': (params) =>\n savePastedImage(params.type, Buffer.from(params.data, 'base64')),\n}\n\nexport function connectClient(socket: WebSocket) {\n const client: Client = {\n socket,\n heardAt: Date.now(),\n opening: null,\n sessionId: null,\n send: (message) => socket.send(JSON.stringify(message)),\n }\n clients.add(client)\n socket.on('message', (data, isBinary) => {\n client.heardAt = Date.now()\n if (isBinary) {\n terminalInput(client, data as Buffer)\n return\n }\n void answer(client, String(data))\n })\n socket.on('error', (error) =>\n console.warn(`a browser connection failed: ${error}`)\n )\n socket.on('close', () => {\n clients.delete(client)\n detachTerminal(client)\n })\n}\n\nasync function answer(client: Client, text: string) {\n let call: Call\n try {\n call = JSON.parse(text) as Call\n } catch (error) {\n console.warn(`ignoring a message that is not JSON: ${error}`)\n return\n }\n try {\n if (!Object.hasOwn(handlers, call.method))\n throw new Error(`unknown method ${call.method}`)\n const handler = handlers[call.method] as (\n params: unknown,\n client: Client\n ) => unknown\n const result = await handler(call.params, client)\n client.send({ type: 'reply', id: call.id, result })\n } catch (error) {\n client.send({\n type: 'reply',\n id: call.id,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto'\nimport { readJson, writeJson } from './storage.ts'\n\nexport type PairingToken = {\n token: string\n name: string | null\n createdAt: number\n}\n\nexport function readTokens() {\n const stored = readJson('tokens.json') as { tokens: PairingToken[] } | null\n return stored === null ? [] : stored.tokens\n}\n\nexport function addToken(name: string | null) {\n const token = randomBytes(32).toString('base64url')\n writeJson('tokens.json', {\n tokens: [...readTokens(), { token, name, createdAt: Date.now() }],\n })\n return token\n}\n\nexport function removeTokens(tokens: string[]) {\n writeJson('tokens.json', {\n tokens: readTokens().filter((item) => !tokens.includes(item.token)),\n })\n}\n\nexport function firstToken() {\n return readTokens().at(0)?.token ?? addToken(null)\n}\n\nexport function matchesToken(given: string | null) {\n if (given === null) return false\n const actual = Buffer.from(given)\n return readTokens().some((item) => {\n const expected = Buffer.from(item.token)\n return (\n expected.length === actual.length && timingSafeEqual(expected, actual)\n )\n })\n}\n\nexport function readUsage() {\n return (readJson('token-usage.json') ?? {}) as Record<string, number>\n}\n\nexport function recordUse(token: string) {\n writeJson('token-usage.json', { ...readUsage(), [token]: Date.now() })\n}\n","import { createReadStream, existsSync, statSync } from 'node:fs'\nimport { createServer, type ServerResponse } from 'node:http'\nimport path from 'node:path'\nimport { HOSTED_APP, PROTOCOL } from '@offsite/core/protocol'\nimport { consola } from 'consola'\nimport { type WebSocket, WebSocketServer } from 'ws'\nimport { connectClient } from './api/socket.ts'\nimport { args } from './args.ts'\nimport { findClaude } from './lib/claude/index.ts'\nimport { startPush } from './services/push.ts'\nimport { stopAll } from './services/runs.ts'\nimport { watchSessions } from './services/sessions.ts'\nimport { readConfig, version } from './storage/config.ts'\nimport { lockHome } from './storage/storage.ts'\nimport {\n addToken,\n firstToken,\n matchesToken,\n readTokens,\n readUsage,\n recordUse,\n removeTokens,\n} from './storage/token.ts'\n\nconst UNPAIR_CHECK = 5000\n\nconst contentTypes: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.json': 'application/json',\n '.webmanifest': 'application/manifest+json',\n '.woff2': 'font/woff2',\n}\n\nconst port = Number(args.port)\nif (!Number.isInteger(port) || port < 1 || port > 65535) {\n console.error(`invalid port ${args.port}`)\n process.exit(1)\n}\n\nconst address = `http://${args.host}:${port}`\n\nif (args.command === 'pair') {\n const links = pairingLinks(addToken(args.name))\n console.log('Open one of these links in the browser to pair:')\n console.log(` ${links.local}`)\n console.log(` ${links.hosted}`)\n process.exit(0)\n}\n\nif (args.command === 'unpair') {\n await unpair()\n process.exit(0)\n}\n\nlockHome()\n\nprocess.env.CLAUDE_CONFIG_DIR = readConfig().claudeBaseDir\nwatchSessions()\n\nif (findClaude() === null) {\n console.error('could not find claude on PATH; install Claude Code first')\n process.exit(1)\n}\n\nconst publicDir = path.join(import.meta.dirname, '..', '..', 'web', 'dist')\nconst token = args.auth && args.pair ? firstToken() : null\n\nconst server = createServer((request, response) => {\n const url = new URL(request.url ?? '/', 'http://localhost')\n if (url.pathname === '/version') {\n response.setHeader('access-control-allow-origin', '*')\n response.setHeader('content-type', 'application/json')\n response.end(\n JSON.stringify({\n version,\n protocol: PROTOCOL,\n authorized: authorized(url),\n })\n )\n return\n }\n if (args.command === 'serve') {\n response.statusCode = 404\n response.end(`offsite serve has no web app; open ${HOSTED_APP}`)\n return\n }\n serveFile(url.pathname, response)\n})\n\nconst sockets = new WebSocketServer({ noServer: true })\nconst paired = new Map<WebSocket, string>()\n\nserver.on('upgrade', (request, socket, head) => {\n const url = new URL(request.url ?? '/', 'http://localhost')\n const given = url.searchParams.get('token')\n if (\n url.pathname !== '/ws' ||\n url.searchParams.get('protocol') !== String(PROTOCOL) ||\n !authorized(url)\n ) {\n socket.destroy()\n return\n }\n sockets.handleUpgrade(request, socket, head, (client) => {\n connectClient(client)\n if (!args.auth || given === null) return\n paired.set(client, given)\n client.on('close', () => paired.delete(client))\n recordUse(given)\n })\n})\n\nif (args.auth)\n setInterval(() => {\n for (const [client, given] of paired)\n if (!matchesToken(given)) client.close()\n }, UNPAIR_CHECK)\n\nserver.listen(port, args.host, () => {\n startPush(`${args.host}:${port}`)\n if (args.pair) {\n const links = pairingLinks(token)\n if (args.command === 'web')\n console.log(`offsite is running at ${links.local}`)\n console.log(`Open it on ${HOSTED_APP}: ${links.hosted}`)\n } else {\n console.log(`offsite is running at ${address}`)\n console.log(`Open it on ${HOSTED_APP}`)\n }\n if (!args.auth)\n console.warn(\n 'auth is off; anyone who can reach this port can control this machine'\n )\n})\n\nprocess.on('SIGINT', stop)\nprocess.on('SIGTERM', stop)\n\nfunction stop() {\n stopAll()\n process.exit(0)\n}\n\nfunction authorized(url: URL) {\n return !args.auth || matchesToken(url.searchParams.get('token'))\n}\n\nasync function unpair() {\n const tokens = readTokens()\n if (tokens.length === 0) {\n console.log('No browsers are paired')\n return\n }\n if (!process.stdin.isTTY) {\n console.error('offsite unpair needs an interactive terminal')\n process.exit(1)\n }\n const usage = readUsage()\n const picked = (await consola.prompt('Which browsers should be unpaired?', {\n type: 'multiselect',\n required: false,\n cancel: 'null',\n options: tokens.map((item) => {\n const used = usage[item.token]\n return {\n value: item.token,\n label: [\n item.name ?? 'Unnamed',\n `${item.token.slice(0, 6)}…`,\n `paired ${new Date(item.createdAt).toLocaleString()}`,\n used === undefined\n ? 'never used'\n : `last used ${new Date(used).toLocaleString()}`,\n ].join(' · '),\n }\n }),\n })) as unknown as string[] | null\n if (picked === null || picked.length === 0) {\n console.log('Nothing unpaired')\n return\n }\n removeTokens(picked)\n console.log(\n `Unpaired ${picked.length} ${picked.length === 1 ? 'browser' : 'browsers'}; a running offsite disconnects them within seconds`\n )\n}\n\nfunction pairingLinks(token: string | null) {\n const hosted = new URLSearchParams({\n machine: address,\n ...(token !== null && { token }),\n })\n return {\n local:\n token === null\n ? address\n : `${address}/pair#${new URLSearchParams({ token })}`,\n hosted: `${HOSTED_APP}/pair#${hosted}`,\n }\n}\n\nfunction serveFile(pathname: string, response: ServerResponse) {\n const requested = path.join(publicDir, path.normalize(pathname))\n const file =\n requested.startsWith(publicDir + path.sep) &&\n statSync(requested, { throwIfNoEntry: false })?.isFile()\n ? requested\n : path.join(publicDir, 'index.html')\n if (!existsSync(file)) {\n response.statusCode = 404\n response.end('web app not built; run pnpm build')\n return\n }\n response.setHeader(\n 'content-type',\n contentTypes[path.extname(file)] ?? 'application/octet-stream'\n )\n createReadStream(file).pipe(response)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.mjs","names":["publish","IDLE_LIMIT","toItems","userText","record","contentText","toRequest","IDLE_LIMIT","toItems","toRequest","server","projects","publish","projects","setTimeout","todoStatuses","text","IDLE_LIMIT","executable","push","OUTPUT_LIMIT","server","open","send","spawn","projects","open","send","push"],"sources":["../../core/src/protocol.ts","../src/lib/hub.ts","../src/args.ts","../src/storage/storage.ts","../src/storage/config.ts","../src/lib/codex/app-server.ts","../src/lib/codex/accounts.ts","../src/lib/codex/items.ts","../src/lib/live.ts","../src/lib/codex/requests.ts","../src/lib/codex/run.ts","../src/lib/codex/sessions.ts","../src/storage/db.ts","../src/services/projects.ts","../src/services/sessions.ts","../src/lib/opencode/client.ts","../src/lib/opencode/items.ts","../src/lib/opencode/sessions.ts","../src/lib/opencode/run.ts","../src/services/accounts.ts","../src/lib/claude/content.ts","../src/lib/claude/claude.ts","../src/lib/claude/items.ts","../src/lib/claude/history.ts","../src/lib/claude/run.ts","../src/services/git.ts","../src/services/files.ts","../src/services/push.ts","../src/services/runs.ts","../../core/src/shell-check.ts","../src/services/terminal/shell-integration.ts","../src/services/terminal/process.ts","../src/services/terminal/alerts.ts","../src/services/terminal/terminal.ts","../src/api/socket.ts","../src/storage/token.ts","../src/main.ts"],"sourcesContent":["export const PROTOCOL = 2\n\nexport const HOSTED_APP = 'https://offsite.sayad.dev'\n\nexport type Provider = 'claude' | 'codex' | 'opencode'\n\nexport type RateLimit = {\n window: string\n utilization: number | null\n resetsAt: number | null\n rejected: boolean\n}\n\nexport type Session = {\n id: string\n provider: Provider\n title: string\n cwd: string\n branch: string | null\n updatedAt: number\n status: 'active' | 'pinned' | 'minimized' | 'inactive'\n}\n\nexport type Project = { path: string; name: string; logo: string | null }\n\nexport type ProjectPatch = { name?: string; logo?: string | null }\n\nexport type Directories = {\n path: string\n parent: string | null\n directories: { name: string; path: string }[]\n}\n\nexport type Snapshot = ConfigInfo & {\n protocol: number\n hostname: string\n projects: Project[]\n sessions: Session[]\n activity: Record<string, Activity>\n}\n\nexport type SessionPatch = {\n title?: string\n status?: 'active' | 'pinned' | 'minimized' | 'inactive'\n}\n\nexport type Context = {\n tokens: number\n window: number | null\n}\n\nexport type Account = {\n id: string\n provider: Provider\n name: string\n configDir: string\n email: string | null\n plan: string | null\n error: string | null\n limits: RateLimit[]\n linked: boolean\n valid: boolean\n}\n\nexport type Model = {\n value: string\n name: string\n description: string\n efforts: string[]\n}\n\nexport type Command = { name: string; description: string; hint: string }\n\nexport type Agent = { id: string; name: string; description: string }\n\nexport type Capabilities = {\n models: Model[]\n commands: Command[]\n agents: Agent[]\n}\n\nexport type ProviderSettings = {\n accountId: string | null\n model: string | null\n effort: string | null\n mode: string | null\n plan: boolean\n}\n\nexport type Settings = ProviderSettings & { provider: Provider }\n\nexport type Rewind = {\n sessionId: string\n cwd: string\n messageId: string\n settings: Settings\n code: boolean\n conversation: boolean\n dryRun: boolean\n}\n\nexport type RewindResult = {\n files: string[]\n insertions: number\n deletions: number\n} | null\n\nexport type GitStatus = {\n branch: string | null\n upstream: string | null\n ahead: number\n behind: number\n changed: number\n}\n\nexport type FilePreview =\n | { kind: 'text'; size: number; content: string }\n | { kind: 'image'; size: number; mediaType: string; data: string }\n | { kind: 'binary'; size: number }\n | { kind: 'large'; size: number; limit: number }\n\nexport type Platform = 'macos' | 'linux' | 'windows'\n\nexport type TerminalIdentity = 'offsite' | 'ghostty' | 'iterm2'\n\nexport type TerminalConfig = {\n shell: Record<Platform, string | null>\n behavior: { terminalIdentity: TerminalIdentity; shellIntegration: boolean }\n}\n\nexport type Config = {\n claudeBaseDir: string\n composer: { provider: Provider } & Record<Provider, ProviderSettings>\n commitModels: Record<Provider, string | null>\n terminal: TerminalConfig\n}\n\nexport type ConfigInfo = {\n config: Config\n defaults: Config\n platform: Platform\n version: string\n defaultShell: string\n}\n\nexport type TerminalTab = {\n id: number\n customName: string | null\n minimized: boolean\n}\n\nexport type TerminalProject = { tabs: TerminalTab[]; activeTab: number | null }\n\nexport type TerminalLayout = Record<string, TerminalProject>\n\nexport type TerminalRequest =\n | { type: 'attach' }\n | { type: 'detach' }\n | { type: 'createTab'; cwd: string }\n | { type: 'closeTab'; id: number }\n | { type: 'renameTab'; id: number; name: string }\n | { type: 'minimizeTab'; id: number }\n | { type: 'select'; cwd: string; tabId: number | null }\n | { type: 'resize'; id: number; cols: number; rows: number }\n\nexport type TerminalEvent =\n | { type: 'active'; layout: TerminalLayout; instance: string }\n | { type: 'layout'; layout: TerminalLayout }\n\nexport type Shell = { name: string; path: string }\n\nexport type BusyResult = { program: string | null } | { error: string }\n\nexport type TerminalPush = {\n title: string\n body: string\n cwd: string\n tabId: number\n}\n\nexport type Image = { mediaType: string; data: string }\n\nexport type Prompt = { text: string; images: Image[] }\n\nexport type Queued = { id: string; prompt: Prompt }\n\nexport type ItemStatus = 'running' | 'completed' | 'failed' | 'stopped'\n\nexport type ItemImage = { mediaType: string; data: string | null }\n\nexport type Question = {\n question: string\n header: string\n multiSelect: boolean\n options: { label: string; description: string }[]\n}\n\nexport type TodoStep = {\n text: string\n status: 'pending' | 'running' | 'completed'\n}\n\nexport type Background = {\n taskId: string | null\n outputPath: string | null\n events: string[]\n}\n\nexport type Item = {\n id: string\n parent: string | null\n time: number | null\n} & (\n | {\n kind: 'user'\n text: string\n images: ItemImage[]\n format: 'text' | 'command' | 'output'\n }\n | { kind: 'assistant'; text: string; message: string }\n | { kind: 'reasoning'; text: string }\n | {\n kind: 'command'\n command: string\n description: string\n output: string\n status: ItemStatus\n background: Background | null\n }\n | {\n kind: 'file_change'\n path: string\n diffs: { before: string; after: string }[]\n output: string\n status: ItemStatus\n }\n | {\n kind: 'web_search'\n query: string | null\n url: string | null\n results: { title: string; url: string }[]\n output: string\n status: ItemStatus\n }\n | { kind: 'skill'; skill: string; output: string; status: ItemStatus }\n | {\n kind: 'tool'\n name: string\n input: Record<string, unknown>\n output: string\n status: ItemStatus\n }\n | { kind: 'todo_list'; steps: TodoStep[] }\n | { kind: 'plan'; plan: string }\n | {\n kind: 'question'\n questions: Question[]\n answers: Record<string, string> | null\n status: ItemStatus\n }\n | {\n kind: 'subagent'\n agent: string\n description: string\n agentId: string | null\n status: ItemStatus\n }\n | {\n kind: 'agent_message'\n target: string | null\n summary: string\n status: ItemStatus\n }\n | { kind: 'compaction' }\n | { kind: 'notice'; text: string }\n | { kind: 'error'; text: string }\n)\n\nexport type PermissionRequest =\n | {\n id: string\n kind: 'approval'\n title: string\n canAlwaysAllow: boolean\n item: Item\n }\n | { id: string; kind: 'plan'; plan: string }\n | { id: string; kind: 'question'; questions: Question[] }\n\nexport type TaskStatus = 'running' | 'completed' | 'failed' | 'stopped'\n\nexport type Activity = {\n running: boolean\n waiting: boolean\n prompted: boolean\n tasks: Record<string, TaskStatus>\n}\n\nexport type Delivery = 'queue' | 'steer'\n\nexport type Decision = 'allow' | 'always' | 'deny'\n\nexport type PushSubscriptionInfo = {\n endpoint: string\n keys: { p256dh: string; auth: string }\n}\n\nexport type Methods = {\n ping: { params: void; result: null }\n sync: { params: void; result: Snapshot }\n 'config.get': { params: void; result: ConfigInfo }\n 'config.save': { params: Config; result: Config }\n 'projects.add': { params: { path: string }; result: Project }\n 'projects.update': {\n params: { path: string; patch: ProjectPatch }\n result: null\n }\n 'projects.remove': { params: { path: string }; result: null }\n 'directories.list': { params: { path: string }; result: Directories }\n 'sessions.update': {\n params: { id: string; patch: SessionPatch }\n result: null\n }\n 'sessions.remove': { params: { id: string }; result: null }\n 'sessions.open': { params: { sessionId: string; cwd: string }; result: null }\n 'sessions.earlier': {\n params: { sessionId: string; before: number }\n result: { items: Item[]; before: number | null }\n }\n 'sessions.image': {\n params: { sessionId: string; itemId: string; index: number }\n result: Image\n }\n 'sessions.agent': {\n params: { sessionId: string; cwd: string; agentId: string; parent: string }\n result: Item[]\n }\n 'sessions.send': {\n params: {\n sessionId: string | null\n cwd: string\n prompt: Prompt\n settings: Settings\n delivery: Delivery\n }\n result: null\n }\n 'sessions.unqueue': {\n params: { sessionId: string; id: string }\n result: null\n }\n 'sessions.steer': {\n params: { sessionId: string; id: string }\n result: null\n }\n 'sessions.interrupt': { params: { sessionId: string }; result: null }\n 'sessions.stopTask': {\n params: { sessionId: string; taskId: string }\n result: null\n }\n 'sessions.configure': {\n params: { sessionId: string; settings: Settings }\n result: null\n }\n 'sessions.respond': {\n params: {\n sessionId: string\n requestId: string\n decision: Decision\n answers: Record<string, string> | null\n }\n result: null\n }\n 'sessions.rewind': { params: Rewind; result: RewindResult }\n 'sessions.fork': {\n params: { sessionId: string; cwd: string; messageId: string }\n result: { sessionId: string }\n }\n 'accounts.list': { params: void; result: Account[] }\n 'accounts.add': {\n params: { provider: Provider; name: string; configDir: string }\n result: null\n }\n 'accounts.update': {\n params: { id: string; name: string; configDir: string }\n result: null\n }\n 'accounts.remove': { params: { id: string }; result: null }\n capabilities: {\n params: { accountId: string; cwd: string }\n result: Capabilities\n }\n 'files.list': { params: { cwd: string }; result: string[] }\n 'files.read': { params: { cwd: string; path: string }; result: FilePreview }\n 'files.upload': { params: { name: string; data: string }; result: string }\n 'tasks.output': {\n params: { sessionId: string; path: string }\n result: { text: string; truncated: boolean } | null\n }\n 'git.status': { params: { cwd: string }; result: GitStatus | null }\n 'git.diff': { params: { cwd: string }; result: string }\n 'git.commit': {\n params: { cwd: string; message: string }\n result: GitStatus | null\n }\n 'git.push': { params: { cwd: string }; result: GitStatus | null }\n 'git.pullRequest': { params: { cwd: string }; result: { url: string } }\n 'git.message': {\n params: { provider: Provider; accountId: string | null; cwd: string }\n result: { message: string }\n }\n 'push.key': { params: void; result: { publicKey: string } }\n 'push.subscribe': { params: PushSubscriptionInfo; result: null }\n 'push.unsubscribe': { params: { endpoint: string }; result: null }\n terminal: { params: TerminalRequest; result: null }\n 'terminal.shells': { params: void; result: Shell[] }\n 'terminal.busy': { params: { id: number }; result: BusyResult }\n 'terminal.paste': { params: { type: string; data: string }; result: string }\n}\n\nexport type Method = keyof Methods\n\nexport type Call = {\n [M in Method]: { id: number; method: M; params: Methods[M]['params'] }\n}[Method]\n\nexport type Reply =\n | { type: 'reply'; id: number; result: unknown }\n | { type: 'reply'; id: number; error: string }\n\nexport type ServerMessage =\n | ServerEvent\n | { type: 'terminal'; event: TerminalEvent }\n | Reply\n\nexport const FRAME_INPUT = 0\nexport const FRAME_REPLY = 1\nexport const FRAME_OUTPUT = 2\nexport const FRAME_REPLAY = 3\n\nexport function encodeFrame(kind: number, id: number, data: Uint8Array) {\n const frame = new Uint8Array(5 + data.length)\n frame[0] = kind\n new DataView(frame.buffer).setUint32(1, id)\n frame.set(data, 5)\n return frame\n}\n\nexport function decodeFrame(frame: Uint8Array) {\n if (frame.length < 5) throw new Error('terminal frame is too short')\n return {\n kind: frame[0],\n id: new DataView(\n frame.buffer,\n frame.byteOffset,\n frame.byteLength\n ).getUint32(1),\n data: frame.subarray(5),\n }\n}\n\nexport type ServerEvent =\n | { type: 'activity'; activity: Record<string, Activity> }\n | { type: 'limits'; accountId: string; limits: RateLimit[] }\n | { type: 'config'; config: Config }\n | { type: 'projects'; projects: Project[] }\n | { type: 'sessions'; sessions: Session[] }\n | { type: 'accounts'; accounts: Account[] }\n | { type: 'started'; sessionId: string; cwd: string }\n | {\n type: 'history'\n sessionId: string\n provider: Provider\n items: Item[]\n requests: PermissionRequest[]\n queue: Queued[]\n settings: Settings | null\n context: Context | null\n before: number | null\n partial: string\n }\n | { type: 'items'; sessionId: string; items: Item[] }\n | { type: 'delta'; sessionId: string; text: string }\n | { type: 'request'; sessionId: string; request: PermissionRequest }\n | { type: 'requestDone'; sessionId: string; requestId: string }\n | { type: 'queue'; sessionId: string; queue: Queued[] }\n | { type: 'settings'; sessionId: string; settings: Settings }\n | { type: 'context'; sessionId: string; context: Context | null }\n | { type: 'notification'; sessionId: string; message: string }\n","import type { ServerEvent, ServerMessage } from '@offsite/core/protocol'\nimport type { WebSocket } from 'ws'\n\nexport type Client = {\n socket: WebSocket\n heardAt: number\n opening: string | null\n sessionId: string | null\n send: (message: ServerMessage) => void\n}\n\nexport const clients = new Set<Client>()\n\nexport function publish(sessionId: string, event: ServerEvent) {\n for (const client of clients)\n if (client.sessionId === sessionId) client.send(event)\n}\n\nexport function broadcast(event: ServerEvent) {\n for (const client of clients) client.send(event)\n}\n","import os from 'node:os'\nimport path from 'node:path'\nimport { Command } from '@commander-js/extra-typings'\n\nlet command = 'web' as 'web' | 'serve' | 'pair' | 'unpair'\nlet name = null as string | null\n\nconst program = new Command('offsite')\n .description('Starts the server and the web app')\n .option('--host <host>', 'Address to listen on', '127.0.0.1')\n .option('--port <port>', 'Port to listen on', '47841')\n .option(\n '--dir <dir>',\n 'Folder for settings and accounts',\n path.join(os.homedir(), '.offsite')\n )\n .option('--no-auth', 'Accept connections without the pairing token')\n .option('--no-pair', \"Don't create a pairing token or print pairing links\")\n\nprogram\n .command('web', { isDefault: true })\n .description('Starts the server and the web app, same as offsite')\n\nprogram\n .command('serve')\n .description('Starts only the server, without the web app')\n .action(() => {\n command = 'serve'\n })\n\nprogram\n .command('pair')\n .description(\n 'Creates a pairing token for another browser and prints its links'\n )\n .option('--name <name>', 'Name to recognize this browser by')\n .action((options) => {\n command = 'pair'\n name = options.name ?? null\n })\n\nprogram\n .command('unpair')\n .description('Picks paired browsers to unpair')\n .action(() => {\n command = 'unpair'\n })\n\nprogram.parse()\n\nconst options = program.opts()\n\nexport const args = {\n ...options,\n dir: path.resolve(options.dir),\n command,\n name,\n}\n\nexport const serverDir = path.join(import.meta.dirname, '..')\n","import {\n mkdirSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { consola } from 'consola'\nimport { args } from '../args.ts'\n\nexport const home = args.dir\n\nconst lockFile = path.join(home, 'server.pid')\n\nmkdirSync(home, { recursive: true })\n\nexport function lockHome() {\n lock()\n process.on('exit', () => unlinkSync(lockFile))\n}\n\nfunction lock() {\n try {\n writeFileSync(lockFile, `${process.pid}\\n`, { flag: 'wx' })\n return\n } catch (error) {\n if (!hasCode(error, 'EEXIST')) throw error\n }\n let content\n let modified\n try {\n content = readFileSync(lockFile, 'utf8')\n modified = statSync(lockFile).mtimeMs\n } catch (error) {\n if (hasCode(error, 'ENOENT')) return lock()\n throw error\n }\n const pid = Number(content)\n const validPid = Number.isInteger(pid) && pid > 0\n const writtenThisBoot = modified > Date.now() - os.uptime() * 1000\n if (validPid && writtenThisBoot && pid !== process.pid && isRunning(pid)) {\n consola.error(`offsite is already running for ${home} (pid ${pid})`)\n process.exit(1)\n }\n unlinkSync(lockFile)\n lock()\n}\n\nfunction isRunning(pid: number) {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n if (hasCode(error, 'ESRCH')) return false\n if (hasCode(error, 'EPERM')) return true\n throw error\n }\n}\n\nfunction hasCode(error: unknown, code: string) {\n return error instanceof Error && 'code' in error && error.code === code\n}\n\nexport function readJson(name: string): unknown {\n try {\n return JSON.parse(readFileSync(path.join(home, name), 'utf8'))\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw error\n }\n}\n\nexport function writeJson(name: string, value: unknown) {\n const file = path.join(home, name)\n mkdirSync(home, { recursive: true })\n writeFileSync(`${file}.tmp`, `${JSON.stringify(value, null, 2)}\\n`, {\n mode: 0o600,\n })\n renameSync(`${file}.tmp`, file)\n}\n","import os from 'node:os'\nimport path from 'node:path'\nimport type { Config, ConfigInfo, Platform } from '@offsite/core/protocol'\nimport { broadcast } from '../lib/hub.ts'\nimport { home, readJson, writeJson } from './storage.ts'\n\nexport const version = '0.0.0'\n\nconst configFile = path.join(home, 'config.json')\n\nexport const defaults: Config = {\n claudeBaseDir: path.join(os.homedir(), '.claude'),\n composer: {\n provider: 'claude',\n claude: {\n accountId: null,\n model: 'haiku',\n effort: 'low',\n mode: 'bypassPermissions',\n plan: false,\n },\n codex: {\n accountId: null,\n model: null,\n effort: null,\n mode: 'auto',\n plan: false,\n },\n opencode: {\n accountId: 'opencode',\n model: null,\n effort: null,\n mode: null,\n plan: false,\n },\n },\n commitModels: { claude: 'haiku', codex: 'gpt-6-luna', opencode: null },\n terminal: {\n shell: { macos: null, linux: null, windows: null },\n behavior: { terminalIdentity: 'offsite', shellIntegration: true },\n },\n}\n\nconst retired = [\n 'theme',\n 'diff',\n 'terminal.font',\n 'terminal.cursor',\n 'terminal.padding',\n 'terminal.scrollback',\n 'terminal.boldIsBright',\n 'terminal.behavior.modernizeShiftEnter',\n 'terminal.behavior.pasteBrowserImages',\n 'terminal.behavior.captureShortcuts',\n 'terminal.behavior.bellFlash',\n 'terminal.behavior.bellSound',\n 'terminal.behavior.clickToMoveCursor',\n 'terminal.behavior.optionAsMeta',\n 'terminal.behavior.confirmCloseBusyTab',\n 'composer.accountId',\n 'composer.model',\n 'composer.effort',\n 'composer.permissionMode',\n]\n\nconst choices: Record<string, string[]> = {\n 'composer.provider': ['claude', 'codex', 'opencode'],\n 'composer.claude.effort': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'composer.claude.mode': [\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n 'plan',\n 'dontAsk',\n 'auto',\n ],\n 'composer.codex.mode': ['read-only', 'auto', 'full-access'],\n 'terminal.behavior.terminalIdentity': ['offsite', 'ghostty', 'iterm2'],\n}\nconst nullable = [\n 'composer.claude.accountId',\n 'composer.claude.model',\n 'composer.claude.effort',\n 'composer.claude.mode',\n 'composer.codex.accountId',\n 'composer.codex.model',\n 'composer.codex.effort',\n 'composer.codex.mode',\n 'composer.opencode.accountId',\n 'composer.opencode.model',\n 'composer.opencode.effort',\n 'composer.opencode.mode',\n 'commitModels.claude',\n 'commitModels.codex',\n 'commitModels.opencode',\n 'terminal.shell.macos',\n 'terminal.shell.linux',\n 'terminal.shell.windows',\n]\n\nexport function platform(): Platform {\n if (process.platform === 'darwin') return 'macos'\n if (process.platform === 'linux') return 'linux'\n if (process.platform === 'win32') return 'windows'\n throw new Error(`unsupported platform ${process.platform}`)\n}\n\nexport function defaultShell() {\n if (process.platform === 'win32') return process.env.COMSPEC ?? 'cmd.exe'\n return os.userInfo().shell ?? '/bin/sh'\n}\n\nexport function configInfo(): ConfigInfo {\n return {\n config: readConfig(),\n defaults,\n platform: platform(),\n version,\n defaultShell: defaultShell(),\n }\n}\n\nexport function readConfig() {\n let user: unknown\n try {\n user = readJson('config.json')\n } catch (error) {\n console.warn(`invalid ${configFile}, using the default config: ${error}`)\n return structuredClone(defaults)\n }\n if (user === null) return structuredClone(defaults)\n if (!isObject(user)) {\n console.warn(`${configFile} is not an object, using the default config`)\n return structuredClone(defaults)\n }\n let config: unknown = structuredClone(defaults)\n for (const [key, value] of Object.entries(user))\n config = merge(config, [key], value)\n return config as Config\n}\n\nexport function saveConfig(value: unknown) {\n const error = invalid(value, defaults, [])\n if (error !== null) throw new Error(error)\n writeJson('config.json', value)\n process.env.CLAUDE_CONFIG_DIR = (value as Config).claudeBaseDir\n broadcast({ type: 'config', config: value as Config })\n return value as Config\n}\n\nfunction merge(config: unknown, keys: string[], user: unknown): unknown {\n if (retired.includes(keys.join('.'))) return config\n const template = keys.reduce<unknown>(\n (value, key) => (isObject(value) ? value[key] : undefined),\n config\n )\n if (isObject(template) && isObject(user)) {\n let next = config\n for (const [key, value] of Object.entries(user))\n next = merge(next, [...keys, key], value)\n return next\n }\n const candidate = structuredClone(config) as Record<string, unknown>\n const parent = keys\n .slice(0, -1)\n .reduce((value, key) => value[key] as Record<string, unknown>, candidate)\n parent[keys[keys.length - 1]] = user\n const error = invalid(candidate, defaults, [])\n if (error === null) return candidate\n console.warn(\n `invalid ${keys.join('.')} in ${configFile}, using its default: ${error}`\n )\n return config\n}\n\nfunction invalid(\n value: unknown,\n template: unknown,\n keys: string[]\n): string | null {\n const name = keys.join('.')\n if (isObject(template)) {\n if (!isObject(value)) return `${name || 'config'} must be an object`\n for (const key of Object.keys(value))\n if (!(key in template))\n return `unknown setting ${[...keys, key].join('.')}`\n for (const key of Object.keys(template)) {\n if (!(key in value)) return `missing setting ${[...keys, key].join('.')}`\n const error = invalid(value[key], template[key], [...keys, key])\n if (error !== null) return error\n }\n return null\n }\n if (nullable.includes(name) && value === null) return null\n if (name === 'claudeBaseDir')\n return typeof value === 'string' && path.isAbsolute(value)\n ? null\n : 'claudeBaseDir must be an absolute path'\n if (name in choices) {\n if (choices[name].includes(value as string)) return null\n return `${name} must be one of ${choices[name].join(', ')}`\n }\n if (template === null) {\n if (typeof value === 'string') return null\n return `${name} must be text or null`\n }\n if (typeof value !== typeof template)\n return `${name} must be a ${typeof template}`\n return null\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { type ChildProcessByStdio, spawn } from 'node:child_process'\nimport { statSync } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport readline from 'node:readline'\nimport type { Readable, Writable } from 'node:stream'\nimport { version } from '../../storage/config.ts'\nimport { publishCodexLimits } from './accounts.ts'\nimport type { RateLimitSnapshot } from './types.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\n\nexport type Params = Record<string, unknown>\n\nexport type ThreadListener = {\n notify: (method: string, params: Params) => void\n request: (id: number | string, method: string, params: Params) => void\n exited: () => void\n}\n\ntype Incoming = {\n id?: number | string\n method?: string\n params?: Params\n result?: unknown\n error?: { message: string }\n}\n\nexport const codexBaseDir =\n process.env.CODEX_HOME ?? path.join(os.homedir(), '.codex')\n\nconst servers = new Map<string, AppServer>()\n\nexport function appServer(home: string) {\n const existing = servers.get(home)\n if (existing !== undefined) return existing\n const server = new AppServer(home)\n servers.set(home, server)\n return server\n}\n\nexport function stopAppServers() {\n for (const server of servers.values()) server.stop()\n}\n\nexport function findCodex() {\n const name = process.platform === 'win32' ? 'codex.exe' : 'codex'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile())\n return candidate\n }\n return null\n}\n\nexport class AppServer {\n readonly home: string\n readonly threads = new Map<string, ThreadListener>()\n private readonly child: ChildProcessByStdio<Writable, Readable, null>\n private readonly waiting = new Map<\n number,\n { resolve: (result: unknown) => void; reject: (error: Error) => void }\n >()\n private readonly ready: Promise<void>\n private next = 0\n private idleTimer: NodeJS.Timeout | undefined\n private exited: Error | null = null\n\n constructor(home: string) {\n const executable = findCodex()\n if (executable === null)\n throw new Error('Codex is not installed or not on the PATH')\n this.home = home\n this.child = spawn(executable, ['app-server'], {\n env: { ...process.env, CODEX_HOME: home },\n stdio: ['pipe', 'pipe', 'ignore'],\n })\n readline\n .createInterface({ input: this.child.stdout })\n .on('line', (line) => this.receive(line))\n this.child.on('error', (error) => this.exit(error))\n this.child.on('exit', (code) =>\n this.exit(new Error(`Codex stopped (exit code ${code})`))\n )\n this.ready = this.call('initialize', {\n clientInfo: { name: 'offsite', title: 'Offsite', version },\n capabilities: { experimentalApi: true, requestAttestation: false },\n }).then(() => this.write({ method: 'initialized' }))\n this.armIdleTimer()\n }\n\n async request<T>(method: string, params: Params): Promise<T> {\n await this.ready\n this.armIdleTimer()\n return (await this.call(method, params)) as T\n }\n\n reply(id: number | string, result: unknown) {\n this.write({ id, result })\n }\n\n replyError(id: number | string, message: string) {\n this.write({ id, error: { code: -32000, message } })\n }\n\n stop() {\n clearTimeout(this.idleTimer)\n if (servers.get(this.home) === this) servers.delete(this.home)\n this.child.stdin.end()\n }\n\n private call(method: string, params: Params) {\n if (this.exited !== null) return Promise.reject(this.exited)\n this.next += 1\n const id = this.next\n const result = new Promise<unknown>((resolve, reject) =>\n this.waiting.set(id, { resolve, reject })\n )\n this.write({ id, method, params })\n return result\n }\n\n private write(message: Params) {\n if (this.exited !== null) return\n this.child.stdin.write(`${JSON.stringify(message)}\\n`)\n }\n\n private receive(line: string) {\n let message: Incoming\n try {\n message = JSON.parse(line) as Incoming\n } catch {\n console.warn(`ignoring a Codex line that is not JSON: ${line}`)\n return\n }\n if (message.method === undefined) {\n if (typeof message.id !== 'number') return\n const waiter = this.waiting.get(message.id)\n if (waiter === undefined) return\n this.waiting.delete(message.id)\n if (message.error !== undefined)\n waiter.reject(new Error(message.error.message))\n else waiter.resolve(message.result)\n return\n }\n const params = message.params ?? {}\n const listener =\n typeof params.threadId === 'string'\n ? this.threads.get(params.threadId)\n : undefined\n if (message.id !== undefined) {\n if (listener === undefined)\n this.replyError(message.id, `offsite does not handle ${message.method}`)\n else listener.request(message.id, message.method, params)\n return\n }\n if (message.method === 'account/rateLimits/updated') {\n publishCodexLimits(this.home, params.rateLimits as RateLimitSnapshot)\n return\n }\n listener?.notify(message.method, params)\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n this.idleTimer = setTimeout(() => {\n if (this.threads.size > 0) this.armIdleTimer()\n else this.stop()\n }, IDLE_LIMIT)\n }\n\n private exit(error: Error) {\n if (this.exited !== null) return\n this.exited = error\n clearTimeout(this.idleTimer)\n if (servers.get(this.home) === this) servers.delete(this.home)\n for (const waiter of this.waiting.values()) waiter.reject(error)\n this.waiting.clear()\n for (const listener of this.threads.values()) listener.exited()\n this.threads.clear()\n }\n}\n","import { readdirSync, realpathSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Account, Capabilities, RateLimit } from '@offsite/core/protocol'\nimport { type StoredAccount, storedAccounts } from '../../services/accounts.ts'\nimport { broadcast } from '../hub.ts'\nimport { type AppServer, appServer, codexBaseDir } from './app-server.ts'\nimport type { CodexModel, RateLimitSnapshot, Skill } from './types.ts'\n\nconst privateEntries = [\n 'auth.json',\n 'models_cache.json',\n 'log',\n 'memories',\n 'tmp',\n]\n\ntype CodexLogin =\n | { type: 'apiKey' }\n | { type: 'chatgpt'; email: string | null; planType: string }\n | { type: 'amazonBedrock' }\n\nconst windowNames = new Map([\n [300, 'five_hour'],\n [10080, 'seven_day'],\n])\n\nexport async function codexAccount(account: StoredAccount): Promise<Account> {\n const linked = isMirror(account.configDir)\n const base = { ...account, email: null, plan: null, limits: [], linked }\n try {\n const server = appServer(account.configDir)\n const result = await server.request<{ account: CodexLogin | null }>(\n 'account/read',\n {}\n )\n if (result.account === null)\n return {\n ...base,\n error: `Not logged in. Run CODEX_HOME=${account.configDir} codex login in a terminal`,\n valid: false,\n }\n switch (result.account.type) {\n case 'chatgpt':\n return {\n ...base,\n email: result.account.email,\n plan: result.account.planType,\n error: null,\n limits: await rateLimits(server),\n valid: linked,\n }\n case 'apiKey':\n return { ...base, plan: 'API key', error: null, valid: linked }\n case 'amazonBedrock':\n return { ...base, plan: 'Amazon Bedrock', error: null, valid: linked }\n }\n } catch (error) {\n return {\n ...base,\n error: error instanceof Error ? error.message : String(error),\n valid: false,\n }\n }\n}\n\nexport async function codexCapabilities(\n account: StoredAccount,\n cwd: string\n): Promise<Capabilities> {\n const server = appServer(account.configDir)\n const models: CodexModel[] = []\n let cursor: string | null = null\n do {\n const page: { data: CodexModel[]; nextCursor: string | null } =\n await server.request('model/list', { cursor })\n models.push(...page.data)\n cursor = page.nextCursor\n } while (cursor !== null)\n return {\n models: models\n .filter((model) => !model.hidden)\n .map((model) => ({\n value: model.model,\n name: model.displayName,\n description: model.description,\n efforts: model.supportedReasoningEfforts.map(\n (effort) => effort.reasoningEffort\n ),\n })),\n commands: [\n {\n name: 'compact',\n description: 'Summarize the conversation to free up context',\n hint: '',\n },\n ...(await skills(server, cwd)).map((skill) => ({\n name: skill.name,\n description: skill.description,\n hint: '',\n })),\n ],\n agents: [],\n }\n}\n\nexport async function skills(server: AppServer, cwd: string) {\n const result = await server.request<{\n data: { cwd: string; skills: (Skill & { enabled: boolean })[] }[]\n }>('skills/list', { cwds: [cwd] })\n return result.data.flatMap((entry) =>\n entry.skills.filter((skill) => skill.enabled)\n )\n}\n\nexport function publishCodexLimits(home: string, snapshot: RateLimitSnapshot) {\n for (const account of storedAccounts())\n if (account.provider === 'codex' && account.configDir === home)\n broadcast({\n type: 'limits',\n accountId: account.id,\n limits: toLimits(snapshot),\n })\n}\n\nasync function rateLimits(server: AppServer) {\n try {\n const result = await server.request<{ rateLimits: RateLimitSnapshot }>(\n 'account/rateLimits/read',\n {}\n )\n return toLimits(result.rateLimits)\n } catch (error) {\n console.warn(`could not read Codex usage limits: ${error}`)\n return []\n }\n}\n\nfunction toLimits(snapshot: RateLimitSnapshot): RateLimit[] {\n return [snapshot.primary, snapshot.secondary].flatMap((window) =>\n window === null\n ? []\n : [\n {\n window:\n (window.windowDurationMins === null\n ? undefined\n : windowNames.get(window.windowDurationMins)) ??\n `${window.windowDurationMins ?? 0}m`,\n utilization: window.usedPercent / 100,\n resetsAt: window.resetsAt,\n rejected: window.usedPercent >= 100,\n },\n ]\n )\n}\n\nfunction isMirror(dir: string) {\n try {\n if (realpathSync(dir) === realpathSync(codexBaseDir)) return true\n return readdirSync(codexBaseDir)\n .filter(\n (name) =>\n !privateEntries.includes(name) && !/-(wal|shm|journal)$/.test(name)\n )\n .every(\n (name) =>\n realpathSync(path.join(dir, name)) ===\n realpathSync(path.join(codexBaseDir, name))\n )\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n","import type { Item, ItemImage, ItemStatus } from '@offsite/core/protocol'\nimport type { Status, ThreadItem, Turn, UserInput } from './types.ts'\n\nconst statuses: Record<Status | 'interrupted', ItemStatus> = {\n inProgress: 'running',\n completed: 'completed',\n failed: 'failed',\n declined: 'stopped',\n interrupted: 'stopped',\n}\n\nexport function turnItems(turns: Turn[], parent: string | null) {\n return turns.flatMap((turn) => [\n ...turn.items.flatMap((item) =>\n toItems(\n turn.id,\n item,\n parent,\n turn.startedAt === null ? null : turn.startedAt * 1000\n )\n ),\n ...(turn.status === 'failed' && turn.error !== null\n ? [errorItem(`${turn.id}:error`, turn.error.message)]\n : []),\n ])\n}\n\nexport function itemId(turnId: string, id: string) {\n return `${turnId}:${id}`\n}\n\nexport function turnOf(itemId: string) {\n const index = itemId.indexOf(':')\n if (index < 0) throw new Error(`${itemId} is not a Codex item`)\n return itemId.slice(0, index)\n}\n\nexport function errorItem(id: string, text: string): Item {\n return { id, parent: null, time: Date.now(), kind: 'error', text }\n}\n\nexport function toItems(\n turnId: string,\n item: ThreadItem,\n parent: string | null,\n time: number | null\n): Item[] {\n const base = { id: itemId(turnId, item.id), parent, time }\n switch (item.type) {\n case 'userMessage':\n return [\n {\n ...base,\n kind: 'user',\n text: item.content\n .flatMap((input) => userText(input))\n .join('\\n')\n .trim(),\n images: item.content.flatMap((input) => userImages(input)),\n format: 'text',\n },\n ]\n case 'agentMessage':\n return item.text.trim() === ''\n ? []\n : [{ ...base, kind: 'assistant', text: item.text, message: base.id }]\n case 'reasoning': {\n const text = [...item.summary, ...item.content].join('\\n\\n').trim()\n return text === '' ? [] : [{ ...base, kind: 'reasoning', text }]\n }\n case 'plan':\n return [{ ...base, kind: 'plan', plan: item.text }]\n case 'commandExecution':\n return [\n {\n ...base,\n kind: 'command',\n command: item.command,\n description: '',\n output: item.aggregatedOutput ?? '',\n status: statuses[item.status],\n background: null,\n },\n ]\n case 'fileChange':\n return item.changes.map((change, index) => ({\n ...base,\n id: `${base.id}:${index}`,\n kind: 'file_change',\n path: change.path,\n diffs:\n change.kind.type === 'add'\n ? [{ before: '', after: change.diff }]\n : change.kind.type === 'delete'\n ? [{ before: change.diff, after: '' }]\n : hunks(change.diff),\n output: '',\n status: statuses[item.status],\n }))\n case 'mcpToolCall':\n return [\n {\n ...base,\n kind: 'tool',\n name: `${item.server}.${item.tool}`,\n input: record(item.arguments),\n output:\n item.error?.message ??\n (item.result === null ? '' : contentText(item.result.content)),\n status: statuses[item.status],\n },\n ]\n case 'dynamicToolCall':\n return [\n {\n ...base,\n kind: 'tool',\n name: item.tool,\n input: record(item.arguments),\n output: contentText(item.contentItems ?? []),\n status: statuses[item.status],\n },\n ]\n case 'collabAgentToolCall':\n if (item.tool === 'spawnAgent')\n return [\n {\n ...base,\n kind: 'subagent',\n agent: item.model ?? 'Agent',\n description: item.prompt ?? '',\n agentId: item.receiverThreadIds[0] ?? null,\n status: statuses[item.status],\n },\n ]\n return [\n {\n ...base,\n kind: 'agent_message',\n target: item.receiverThreadIds[0] ?? null,\n summary: item.prompt ?? item.tool,\n status: statuses[item.status],\n },\n ]\n case 'webSearch':\n return [\n {\n ...base,\n kind: 'web_search',\n query:\n item.action?.type === 'search'\n ? (item.action.query ?? item.query)\n : item.query === ''\n ? null\n : item.query,\n url:\n item.action?.type === 'openPage' ||\n item.action?.type === 'findInPage'\n ? item.action.url\n : null,\n results: [],\n output: '',\n status: 'completed',\n },\n ]\n case 'imageView':\n return [\n {\n ...base,\n kind: 'tool',\n name: 'view_image',\n input: { path: item.path },\n output: '',\n status: 'completed',\n },\n ]\n case 'contextCompaction':\n return [{ ...base, kind: 'compaction' }]\n case 'hookPrompt':\n case 'functionCallOutput':\n case 'subAgentActivity':\n case 'sleep':\n case 'imageGeneration':\n case 'enteredReviewMode':\n case 'exitedReviewMode':\n return []\n }\n}\n\nfunction userText(input: UserInput) {\n switch (input.type) {\n case 'text':\n return [input.text]\n case 'skill':\n case 'mention':\n return [`$${input.name}`]\n case 'image':\n case 'localImage':\n return []\n }\n}\n\nfunction userImages(input: UserInput): ItemImage[] {\n if (input.type !== 'image') return []\n const match = /^data:([^;,]+);base64,(.*)$/.exec(input.url)\n if (match === null) return []\n return [{ mediaType: match[1], data: match[2] }]\n}\n\nexport function hunks(diff: string) {\n const result: { before: string; after: string }[] = []\n let before: string[] = []\n let after: string[] = []\n let inside = false\n function flush() {\n if (inside)\n result.push({ before: before.join('\\n'), after: after.join('\\n') })\n before = []\n after = []\n }\n for (const line of diff.split('\\n')) {\n if (line.startsWith('@@')) {\n flush()\n inside = true\n continue\n }\n if (!inside || line === '' || line.startsWith('\\\\')) continue\n if (line.startsWith('-')) before.push(line.slice(1))\n else if (line.startsWith('+')) after.push(line.slice(1))\n else {\n before.push(line.slice(1))\n after.push(line.slice(1))\n }\n }\n flush()\n return result\n}\n\nfunction contentText(content: unknown[]) {\n return content\n .map((block) =>\n typeof block === 'object' &&\n block !== null &&\n 'text' in block &&\n typeof block.text === 'string'\n ? block.text\n : JSON.stringify(block)\n )\n .join('\\n')\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value === 'object' && value !== null && !Array.isArray(value))\n return value as Record<string, unknown>\n return { value }\n}\n","import type { Activity } from '@offsite/core/protocol'\nimport type { Run } from './claude/index.ts'\nimport type { CodexRun } from './codex/index.ts'\nimport { broadcast } from './hub.ts'\nimport type { OpenCodeRun } from './opencode/index.ts'\n\nexport const runs = new Map<string, Run | CodexRun | OpenCodeRun>()\n\nexport function activity() {\n const result: Record<string, Activity> = {}\n for (const run of runs.values())\n result[run.sessionId] = {\n running: run.running,\n waiting: run.pending.size > 0,\n prompted: run.prompted,\n tasks: run.tasks,\n }\n return result\n}\n\nexport function broadcastActivity() {\n broadcast({ type: 'activity', activity: activity() })\n}\n","import type { Item, PermissionRequest } from '@offsite/core/protocol'\nimport type { Params } from './app-server.ts'\nimport { itemId } from './items.ts'\nimport type { Question } from './types.ts'\n\nexport function toRequest(\n requestId: string,\n method: string,\n params: Params,\n items: Map<string, Item>\n): PermissionRequest | null {\n const turnId = params.turnId as string\n switch (method) {\n case 'item/commandExecution/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Run this command?',\n canAlwaysAllow: true,\n item: items.get(itemId(turnId, params.itemId as string)) ?? {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'command',\n command: (params.command as string | null) ?? '',\n description: '',\n output: '',\n status: 'running',\n background: null,\n },\n }\n case 'item/fileChange/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Apply these changes?',\n canAlwaysAllow: true,\n item: items.get(`${itemId(turnId, params.itemId as string)}:0`) ?? {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: 'apply_patch',\n input: {},\n output: '',\n status: 'running',\n },\n }\n case 'item/permissions/requestApproval':\n return {\n id: requestId,\n kind: 'approval',\n title: (params.reason as string | null) ?? 'Grant these permissions?',\n canAlwaysAllow: true,\n item: {\n id: itemId(turnId, params.itemId as string),\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: 'permissions',\n input: params.permissions as Record<string, unknown>,\n output: '',\n status: 'running',\n },\n }\n case 'item/tool/requestUserInput':\n return {\n id: requestId,\n kind: 'question',\n questions: (params.questions as Question[]).map((question) => ({\n question: question.question,\n header: question.header,\n multiSelect: false,\n options: question.options ?? [],\n })),\n }\n default:\n return null\n }\n}\n\nexport function reply(\n method: string,\n params: Params,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n) {\n switch (method) {\n case 'item/commandExecution/requestApproval':\n case 'item/fileChange/requestApproval':\n return {\n decision: {\n allow: 'accept',\n always: 'acceptForSession',\n deny: 'decline',\n }[decision],\n }\n case 'item/permissions/requestApproval':\n return decision === 'deny'\n ? { permissions: {}, scope: 'turn' }\n : {\n permissions: params.permissions,\n scope: decision === 'always' ? 'session' : 'turn',\n }\n case 'item/tool/requestUserInput':\n return {\n answers: Object.fromEntries(\n (params.questions as Question[]).flatMap((question) => {\n const answer = answers?.[question.question]\n return decision === 'deny' || answer === undefined\n ? []\n : [[question.id, { answers: [answer] }]]\n })\n ),\n }\n }\n throw new Error(`offsite cannot answer ${method}`)\n}\n","import { randomUUID } from 'node:crypto'\nimport type {\n Context,\n Item,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport { storedAccount } from '../../services/accounts.ts'\nimport { publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport { skills } from './accounts.ts'\nimport {\n type AppServer,\n appServer,\n type Params,\n type ThreadListener,\n} from './app-server.ts'\nimport { errorItem, itemId, toItems } from './items.ts'\nimport { reply, toRequest } from './requests.ts'\nimport type { ThreadItem, ThreadStarted, Turn, UserInput } from './types.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\n\nconst presets = new Map([\n [\n 'read-only',\n {\n approvalPolicy: 'on-request',\n sandbox: 'read-only',\n sandboxPolicy: { type: 'readOnly', networkAccess: false },\n },\n ],\n [\n 'auto',\n {\n approvalPolicy: 'on-request',\n sandbox: 'workspace-write',\n sandboxPolicy: {\n type: 'workspaceWrite',\n writableRoots: [],\n networkAccess: false,\n excludeTmpdirEnvVar: false,\n excludeSlashTmp: false,\n },\n },\n ],\n [\n 'full-access',\n {\n approvalPolicy: 'never',\n sandbox: 'danger-full-access',\n sandboxPolicy: { type: 'dangerFullAccess' },\n },\n ],\n])\n\ntype Pending = {\n request: PermissionRequest\n id: number | string\n method: string\n params: Params\n}\n\nfunction codexServer(settings: Settings) {\n return appServer(storedAccount('codex', settings.accountId).configDir)\n}\n\nexport class CodexRun implements ThreadListener {\n readonly provider = 'codex'\n readonly sessionId: string\n readonly cwd: string\n readonly server: AppServer\n readonly pending = new Map<string, Pending>()\n readonly items = new Map<string, Item>()\n readonly closed: Promise<void>\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly model: string\n private readonly close: () => void\n private turnId: string | null = null\n private idleTimer: NodeJS.Timeout | undefined\n\n static async start(cwd: string, settings: Settings) {\n const server = codexServer(settings)\n const result = await server.request<ThreadStarted>('thread/start', {\n cwd,\n approvalsReviewer: 'user',\n ...(settings.model === null ? {} : { model: settings.model }),\n ...threadPreset(settings),\n })\n return new CodexRun(server, result.thread.id, cwd, result.model, settings)\n }\n\n static async resume(sessionId: string, cwd: string, settings: Settings) {\n const server = codexServer(settings)\n const result = await server.request<ThreadStarted>('thread/resume', {\n threadId: sessionId,\n approvalsReviewer: 'user',\n excludeTurns: true,\n ...(settings.model === null ? {} : { model: settings.model }),\n ...threadPreset(settings),\n })\n return new CodexRun(server, sessionId, cwd, result.model, settings)\n }\n\n private constructor(\n server: AppServer,\n sessionId: string,\n cwd: string,\n model: string,\n settings: Settings\n ) {\n this.server = server\n this.sessionId = sessionId\n this.cwd = cwd\n this.model = model\n this.settings = settings\n const closed = Promise.withResolvers<void>()\n this.closed = closed.promise\n this.close = closed.resolve\n server.threads.set(sessionId, this)\n runs.set(sessionId, this)\n this.armIdleTimer()\n }\n\n async submit(prompt: Prompt, delivery: 'queue' | 'steer') {\n if (!this.running) {\n await this.startTurn(prompt)\n return\n }\n switch (delivery) {\n case 'steer':\n if (this.turnId === null) throw new Error('Codex has no turn to steer')\n await this.server.request('turn/steer', {\n threadId: this.sessionId,\n input: await this.input(prompt),\n expectedTurnId: this.turnId,\n })\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer').catch((error: unknown) =>\n this.fail(error)\n )\n }\n\n configure(settings: Settings) {\n this.settings = { ...settings, accountId: this.settings.accountId }\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings: this.settings,\n })\n }\n\n async interrupt() {\n if (this.turnId === null) return\n await this.server.request('turn/interrupt', {\n threadId: this.sessionId,\n turnId: this.turnId,\n })\n }\n\n stopTask(): Promise<void> {\n throw new Error('Codex has no background tasks to stop')\n }\n\n respond(\n requestId: string,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n this.server.reply(\n pending.id,\n reply(pending.method, pending.params, decision, answers)\n )\n this.settle(requestId)\n }\n\n stop() {\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.server.threads.delete(this.sessionId)\n clearTimeout(this.idleTimer)\n this.server\n .request('thread/unsubscribe', { threadId: this.sessionId })\n .catch((error: unknown) =>\n console.warn(`could not unload Codex thread: ${error}`)\n )\n .finally(() => this.end())\n }\n\n exited() {\n this.put(errorItem(randomUUID(), 'Codex stopped'))\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.end()\n }\n\n notify(method: string, params: Params) {\n switch (method) {\n case 'turn/started': {\n const turn = params.turn as Turn\n this.turnId = turn.id\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n return\n }\n case 'turn/completed': {\n const turn = params.turn as Turn\n if (turn.status === 'failed' && turn.error !== null)\n this.put(errorItem(`${turn.id}:error`, turn.error.message))\n this.finishTurn()\n return\n }\n case 'item/started':\n case 'item/completed':\n for (const item of toItems(\n params.turnId as string,\n params.item as ThreadItem,\n null,\n Date.now()\n ))\n this.put(item)\n return\n case 'item/agentMessage/delta':\n this.partial += params.delta as string\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: params.delta as string,\n })\n return\n case 'item/commandExecution/outputDelta': {\n const item = this.items.get(\n itemId(params.turnId as string, params.itemId as string)\n )\n if (item?.kind === 'command')\n this.put({ ...item, output: item.output + (params.delta as string) })\n return\n }\n case 'turn/plan/updated': {\n const plan = params.plan as {\n step: string\n status: 'pending' | 'inProgress' | 'completed'\n }[]\n this.put({\n id: `${params.turnId as string}:plan`,\n parent: null,\n time: Date.now(),\n kind: 'todo_list',\n steps: plan.map((step) => ({\n text: step.step,\n status: step.status === 'inProgress' ? 'running' : step.status,\n })),\n })\n return\n }\n case 'thread/tokenUsage/updated': {\n const usage = params.tokenUsage as {\n last: { totalTokens: number }\n modelContextWindow: number | null\n }\n this.context = {\n tokens: usage.last.totalTokens,\n window: usage.modelContextWindow,\n }\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context: this.context,\n })\n return\n }\n case 'error': {\n const error = params.error as { message: string }\n if (params.willRetry !== true)\n this.put(errorItem(randomUUID(), error.message))\n return\n }\n case 'serverRequest/resolved':\n this.settle(String(params.requestId))\n }\n }\n\n request(id: number | string, method: string, params: Params) {\n if (method === 'mcpServer/elicitation/request') {\n this.server.reply(id, { action: 'decline', content: null, _meta: null })\n return\n }\n const request = toRequest(String(id), method, params, this.items)\n if (request === null) {\n this.server.replyError(id, `offsite does not handle ${method}`)\n return\n }\n this.pending.set(request.id, { request, id, method, params })\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request,\n })\n broadcastActivity()\n }\n\n private async startTurn(prompt: Prompt) {\n clearTimeout(this.idleTimer)\n this.running = true\n this.prompted = true\n broadcastActivity()\n try {\n if (prompt.text.trim() === '/compact' && prompt.images.length === 0) {\n await this.server.request('thread/compact/start', {\n threadId: this.sessionId,\n })\n return\n }\n const model = this.settings.model ?? this.model\n const preset = modePreset(this.settings.mode)\n const result = await this.server.request<{ turn: Turn }>('turn/start', {\n threadId: this.sessionId,\n input: await this.input(prompt),\n model,\n approvalsReviewer: 'user',\n summary: 'detailed',\n ...(this.settings.effort === null\n ? {}\n : { effort: this.settings.effort }),\n ...(preset === null\n ? {}\n : {\n approvalPolicy: preset.approvalPolicy,\n sandboxPolicy: preset.sandboxPolicy,\n }),\n collaborationMode: {\n mode: this.settings.plan ? 'plan' : 'default',\n settings: {\n model,\n reasoning_effort: this.settings.effort,\n developer_instructions: null,\n },\n },\n })\n this.turnId = result.turn.id\n } catch (error) {\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n throw error\n }\n }\n\n private async input(prompt: Prompt): Promise<UserInput[]> {\n const match = /^\\/(\\S+)\\s*([\\s\\S]*)$/.exec(prompt.text)\n const skill =\n match === null\n ? undefined\n : (await skills(this.server, this.cwd)).find(\n (item) => item.name === match[1]\n )\n const text = skill === undefined || match === null ? prompt.text : match[2]\n return [\n ...(skill === undefined\n ? []\n : [{ type: 'skill' as const, name: skill.name, path: skill.path }]),\n ...(text === ''\n ? []\n : [{ type: 'text' as const, text, text_elements: [] as [] }]),\n ...prompt.images.map((image) => ({\n type: 'image' as const,\n url: `data:${image.mediaType};base64,${image.data}`,\n })),\n ]\n }\n\n private finishTurn() {\n this.partial = ''\n this.turnId = null\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.startTurn(next.prompt).catch((error: unknown) => this.fail(error))\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private settle(requestId: string) {\n if (!this.pending.delete(requestId)) return\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private put(item: Item) {\n this.items.set(item.id, item)\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items: [item],\n })\n }\n\n private fail(error: unknown) {\n this.put(\n errorItem(\n randomUUID(),\n error instanceof Error ? error.message : String(error)\n )\n )\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private end() {\n clearTimeout(this.idleTimer)\n for (const requestId of [...this.pending.keys()]) this.settle(requestId)\n this.running = false\n broadcastActivity()\n this.close()\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction threadPreset(settings: Settings) {\n const preset = modePreset(settings.mode)\n if (preset === null) return {}\n return { approvalPolicy: preset.approvalPolicy, sandbox: preset.sandbox }\n}\n\nfunction modePreset(mode: string | null) {\n if (mode === null) return null\n const preset = presets.get(mode)\n if (preset === undefined) throw new Error(`Codex has no ${mode} mode`)\n return preset\n}\n","import { existsSync } from 'node:fs'\nimport type { Item, ServerEvent } from '@offsite/core/protocol'\nimport { storedAccount } from '../../services/accounts.ts'\nimport { runs } from '../live.ts'\nimport { appServer, codexBaseDir, findCodex } from './app-server.ts'\nimport { turnItems, turnOf } from './items.ts'\nimport type { Thread, ThreadItem, ThreadStarted, Turn } from './types.ts'\n\nfunction codexInstalled() {\n return findCodex() !== null && existsSync(codexBaseDir)\n}\n\nexport async function codexThreads(paths: string[]) {\n if (paths.length === 0 || !codexInstalled()) return []\n const server = appServer(codexBaseDir)\n const threads: Thread[] = []\n let cursor: string | null = null\n do {\n const page: { data: Thread[]; nextCursor: string | null } =\n await server.request('thread/list', {\n cwd: paths,\n cursor,\n limit: 100,\n sortKey: 'updated_at',\n sourceKinds: ['cli', 'vscode', 'appServer'],\n })\n threads.push(...page.data)\n cursor = page.nextCursor\n } while (cursor !== null)\n return threads\n}\n\nexport async function codexHistory(sessionId: string): Promise<ServerEvent> {\n const run = codexRun(sessionId)\n const thread = await readThread(sessionId)\n const items = turnItems(thread.turns, null)\n const ids = new Set(items.map((item) => item.id))\n return {\n type: 'history',\n sessionId,\n provider: 'codex',\n items: [\n ...items,\n ...[...(run?.items.values() ?? [])].filter((item) => !ids.has(item.id)),\n ],\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context: run?.context ?? null,\n before: null,\n partial: run?.partial ?? '',\n }\n}\n\nexport async function codexAgent(\n agentId: string,\n parent: string\n): Promise<Item[]> {\n return turnItems((await readThread(agentId)).turns, parent)\n}\n\nexport async function renameThread(sessionId: string, name: string) {\n await server(sessionId).request('thread/name/set', {\n threadId: sessionId,\n name,\n })\n}\n\nexport async function deleteThread(sessionId: string) {\n await server(sessionId).request('thread/delete', { threadId: sessionId })\n}\n\nexport async function forkThread(sessionId: string, messageId: string) {\n const result = await server(sessionId).request<ThreadStarted>('thread/fork', {\n threadId: sessionId,\n lastTurnId: turnOf(messageId),\n excludeTurns: true,\n })\n return { sessionId: result.thread.id }\n}\n\nexport async function revertThread(sessionId: string, messageId: string) {\n await server(sessionId).request('thread/revert', {\n threadId: sessionId,\n beforeTurnId: turnOf(messageId),\n })\n}\n\nexport async function codexCommitMessage(\n accountId: string | null,\n cwd: string,\n model: string,\n prompt: string\n) {\n const server = appServer(storedAccount('codex', accountId).configDir)\n const started = await server.request<ThreadStarted>('thread/start', {\n cwd,\n model,\n ephemeral: true,\n approvalPolicy: 'never',\n sandbox: 'read-only',\n developerInstructions: 'You write concise git commit messages.',\n })\n const threadId = started.thread.id\n const reply = Promise.withResolvers<string>()\n let text = ''\n server.threads.set(threadId, {\n notify: (method, params) => {\n if (method === 'item/completed') {\n const item = params.item as ThreadItem\n if (item.type === 'agentMessage') text = item.text\n }\n if (method !== 'turn/completed') return\n const turn = params.turn as Turn\n if (turn.status === 'completed') reply.resolve(text.trim())\n else reply.reject(new Error(turn.error?.message ?? 'Codex did not reply'))\n },\n request: (id, method) =>\n server.replyError(id, `offsite does not handle ${method}`),\n exited: () => reply.reject(new Error('Codex stopped')),\n })\n try {\n await server.request('turn/start', {\n threadId,\n input: [{ type: 'text', text: prompt, text_elements: [] }],\n model,\n })\n return { message: await reply.promise }\n } finally {\n server.threads.delete(threadId)\n await server.request('thread/unsubscribe', { threadId })\n }\n}\n\nfunction codexRun(sessionId: string) {\n const run = runs.get(sessionId)\n return run?.provider === 'codex' ? run : undefined\n}\n\nfunction server(sessionId: string) {\n return codexRun(sessionId)?.server ?? appServer(codexBaseDir)\n}\n\nasync function readThread(threadId: string) {\n const result = await server(threadId).request<{ thread: Thread }>(\n 'thread/read',\n { threadId, includeTurns: true }\n )\n return result.thread\n}\n","import path from 'node:path'\nimport { DatabaseSync } from 'node:sqlite'\nimport { home } from './storage.ts'\n\nexport const db = new DatabaseSync(path.join(home, 'offsite.db'))\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS projects (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n logo TEXT\n )\n`)\n\ndb.exec('DROP TABLE IF EXISTS prompts')\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n interacted_at INTEGER,\n status TEXT NOT NULL CHECK (status IN ('active', 'pinned', 'minimized'))\n )\n`)\n","import { readdir, stat } from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport type { SQLOutputValue } from 'node:sqlite'\nimport type { Directories, Project, ProjectPatch } from '@offsite/core/protocol'\nimport { broadcast } from '../lib/hub.ts'\nimport { db } from '../storage/db.ts'\n\nconst LOGO_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/x-icon',\n 'image/vnd.microsoft.icon',\n]\nconst LOGO_LIMIT = 512 * 1024\n\nexport function projects() {\n return db\n .prepare('SELECT path, name, logo FROM projects')\n .all()\n .map(toProject)\n}\n\nexport async function addProject(input: string) {\n const folder = path.resolve(expandHome(input.trim()))\n if (!(await stat(folder)).isDirectory())\n throw new Error(`${folder} is not a folder`)\n db.prepare(\n 'INSERT OR IGNORE INTO projects (path, name, logo) VALUES (?, ?, NULL)'\n ).run(folder, path.basename(folder) || folder)\n publish()\n const project = projects().find((item) => item.path === folder)\n if (project === undefined) throw new Error(`Could not add ${folder}`)\n return project\n}\n\nexport function updateProject(folder: string, patch: ProjectPatch) {\n if (patch.name !== undefined) {\n const name = patch.name.trim()\n if (name === '') throw new Error('Project name cannot be empty')\n db.prepare('UPDATE projects SET name = ? WHERE path = ?').run(name, folder)\n }\n if (patch.logo !== undefined) {\n if (patch.logo !== null) checkLogo(patch.logo)\n db.prepare('UPDATE projects SET logo = ? WHERE path = ?').run(\n patch.logo,\n folder\n )\n }\n publish()\n return null\n}\n\nexport function removeProject(folder: string) {\n db.prepare('DELETE FROM projects WHERE path = ?').run(folder)\n publish()\n}\n\nexport async function directories(input: string): Promise<Directories> {\n const folder = path.resolve(expandHome(input.trim()))\n const entries = await readdir(folder, { withFileTypes: true })\n const parent = path.dirname(folder)\n return {\n path: folder,\n parent: parent === folder ? null : parent,\n directories: entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => ({\n name: entry.name,\n path: path.join(folder, entry.name),\n }))\n .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())),\n }\n}\n\nfunction publish() {\n broadcast({ type: 'projects', projects: projects() })\n}\n\nfunction toProject(row: Record<string, SQLOutputValue>): Project {\n if (\n typeof row.path !== 'string' ||\n typeof row.name !== 'string' ||\n (typeof row.logo !== 'string' && row.logo !== null)\n )\n throw new Error('The projects table has an unexpected row')\n return { path: row.path, name: row.name, logo: row.logo }\n}\n\nfunction checkLogo(logo: string) {\n const type = /^data:([^;,]+);base64,/.exec(logo)?.[1]\n if (type === undefined || !LOGO_TYPES.includes(type))\n throw new Error('Use a PNG, JPEG, GIF, WebP, SVG or ICO image')\n if (logo.length > LOGO_LIMIT)\n throw new Error('Use an image smaller than 384 KB')\n}\n\nfunction expandHome(input: string) {\n if (input === '~') return os.homedir()\n if (input.startsWith('~/')) return path.join(os.homedir(), input.slice(2))\n return input\n}\n","import { type FSWatcher, watch } from 'node:fs'\nimport path from 'node:path'\nimport {\n deleteSession,\n forkSession,\n getSessionMessages,\n listSessions,\n renameSession,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Provider, Session, SessionPatch } from '@offsite/core/protocol'\nimport {\n codexBaseDir,\n codexThreads,\n deleteThread,\n forkThread,\n renameThread,\n} from '../lib/codex/index.ts'\nimport { broadcast } from '../lib/hub.ts'\nimport { runs } from '../lib/live.ts'\nimport {\n forkOpenCode,\n openCodeSessions,\n removeOpenCode,\n renameOpenCode,\n} from '../lib/opencode/index.ts'\nimport { readConfig } from '../storage/config.ts'\nimport { db } from '../storage/db.ts'\nimport { projects } from './projects.ts'\n\nconst day = 24 * 60 * 60 * 1000\n\nconst providers = new Map<string, Provider>()\nlet watchers: FSWatcher[] = []\nlet timer: NodeJS.Timeout | undefined\n\nexport async function sessions(): Promise<Session[]> {\n const records = readRecords()\n const paths = projects().map((project) => project.path)\n const [claude, codex, opencode] = await Promise.all([\n Promise.all(\n paths.map(async (cwd) =>\n (\n await listSessions({\n dir: cwd,\n includeWorktrees: false,\n includeProgrammatic: false,\n })\n ).map((item) => ({\n id: item.sessionId,\n provider: 'claude' as const,\n title: item.summary,\n cwd,\n branch: item.gitBranch ?? null,\n updatedAt: item.lastModified,\n }))\n )\n ),\n codexThreads(paths).catch((error: unknown) => {\n console.warn(`could not list Codex threads: ${error}`)\n return []\n }),\n openCodeSessions(paths).catch((error: unknown) => {\n console.warn(`could not list OpenCode sessions: ${error}`)\n return []\n }),\n ])\n const found = [\n ...claude.flat(),\n ...codex.map((thread) => ({\n id: thread.id,\n provider: 'codex' as const,\n title: thread.name ?? thread.preview,\n cwd: thread.cwd,\n branch: thread.gitInfo?.branch ?? null,\n updatedAt: thread.updatedAt * 1000,\n })),\n ...opencode.map((session) => ({\n id: session.id,\n provider: 'opencode' as const,\n title: session.title ?? 'New session',\n cwd: session.location.directory,\n branch: null,\n updatedAt: session.time.updated,\n })),\n ]\n return found.map((item): Session => {\n providers.set(item.id, item.provider)\n const record = records.get(item.id)\n const updatedAt = record?.interactedAt ?? item.updatedAt\n return {\n ...item,\n updatedAt,\n status:\n record === undefined ||\n (record.status === 'active' && Date.now() - updatedAt > day)\n ? 'inactive'\n : record.status,\n }\n })\n}\n\nexport function providerOf(sessionId: string) {\n const provider = runs.get(sessionId)?.provider ?? providers.get(sessionId)\n if (provider === undefined)\n throw new Error('offsite does not know this session yet, reload the page')\n return provider\n}\n\nexport function recordInteraction(id: string) {\n db.prepare(\n \"INSERT INTO sessions (session_id, interacted_at, status) VALUES (?, ?, 'active') ON CONFLICT (session_id) DO UPDATE SET interacted_at = excluded.interacted_at, status = CASE status WHEN 'pinned' THEN 'pinned' WHEN 'minimized' THEN 'minimized' ELSE 'active' END\"\n ).run(id, Date.now())\n}\n\nexport async function publishSessions() {\n try {\n broadcast({ type: 'sessions', sessions: await sessions() })\n } catch (error) {\n console.warn(`could not list threads: ${error}`)\n }\n}\n\nexport function watchSessions() {\n for (const watcher of watchers) watcher.close()\n watchers = [\n path.join(readConfig().claudeBaseDir, 'projects'),\n path.join(codexBaseDir, 'sessions'),\n ].flatMap((dir) => {\n try {\n const watcher = watch(dir, { recursive: true }, refreshSessions)\n watcher.on('error', (error) =>\n console.warn(`stopped watching ${dir}: ${error}`)\n )\n return [watcher]\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n return []\n }\n })\n}\n\nexport function refreshSessions() {\n timer ??= setTimeout(() => {\n timer = undefined\n void publishSessions()\n }, 1000)\n}\n\nexport async function updateSession(id: string, patch: SessionPatch) {\n if (patch.title !== undefined)\n switch (providerOf(id)) {\n case 'claude':\n await renameSession(id, patch.title)\n break\n case 'codex':\n await renameThread(id, patch.title)\n break\n case 'opencode':\n await renameOpenCode(id, patch.title)\n }\n if (patch.status === 'inactive')\n db.prepare('DELETE FROM sessions WHERE session_id = ?').run(id)\n else if (patch.status !== undefined)\n db.prepare(\n 'INSERT INTO sessions (session_id, status) VALUES (?, ?) ON CONFLICT (session_id) DO UPDATE SET status = excluded.status'\n ).run(id, patch.status)\n}\n\nexport async function removeSession(id: string) {\n const provider = providerOf(id)\n const run = runs.get(id)\n if (run !== undefined) {\n run.stop()\n await run.closed\n }\n switch (provider) {\n case 'claude':\n await deleteSession(id)\n break\n case 'codex':\n await deleteThread(id)\n break\n case 'opencode':\n await removeOpenCode(id)\n }\n db.prepare('DELETE FROM sessions WHERE session_id = ?').run(id)\n}\n\nexport async function fork(sessionId: string, cwd: string, messageId: string) {\n const provider = providerOf(sessionId)\n const result = await forkWith(provider, sessionId, cwd, messageId)\n providers.set(result.sessionId, provider)\n recordInteraction(result.sessionId)\n return result\n}\n\nasync function forkWith(\n provider: Provider,\n sessionId: string,\n cwd: string,\n messageId: string\n) {\n if (provider === 'codex') return forkThread(sessionId, messageId)\n if (provider === 'opencode') return forkOpenCode(sessionId, messageId)\n const disk = await getSessionMessages(sessionId, { dir: cwd })\n const index = disk.findIndex((item) => item.uuid === messageId)\n if (index < 0) throw new Error('Cannot fork the session at that point')\n const result = await forkSession(sessionId, {\n dir: cwd,\n upToMessageId: messageId,\n })\n return { sessionId: result.sessionId }\n}\n\nfunction readRecords() {\n const records = new Map<\n string,\n { interactedAt: number | null; status: 'active' | 'pinned' | 'minimized' }\n >()\n for (const row of db\n .prepare('SELECT session_id, interacted_at, status FROM sessions')\n .all()) {\n if (\n typeof row.session_id !== 'string' ||\n (typeof row.interacted_at !== 'number' && row.interacted_at !== null) ||\n (row.status !== 'active' &&\n row.status !== 'pinned' &&\n row.status !== 'minimized')\n )\n throw new Error('The sessions table has an unexpected row')\n records.set(row.session_id, {\n interactedAt: row.interacted_at,\n status: row.status,\n })\n }\n return records\n}\n","import { statSync } from 'node:fs'\nimport path from 'node:path'\nimport { setTimeout } from 'node:timers/promises'\nimport { OpenCode, type OpenCodeClient, type V2Event } from '@opencode/client'\nimport { ensure, headers } from '@opencode/client/service'\nimport { refreshSessions } from '../../services/sessions.ts'\nimport { runs } from '../live.ts'\n\nconst listChanges = new Set([\n 'session.created',\n 'session.renamed',\n 'session.moved',\n 'session.forked',\n 'session.deleted',\n 'session.execution.succeeded',\n 'session.execution.failed',\n 'session.execution.interrupted',\n])\n\nlet connection: Promise<OpenCodeClient> | undefined\n\nexport function findOpenCode() {\n const name = process.platform === 'win32' ? 'opencode.exe' : 'opencode'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile())\n return candidate\n }\n return null\n}\n\nexport function openCode() {\n connection ??= connect()\n return connection\n}\n\nasync function connect() {\n try {\n const endpoint = await ensure()\n const client = OpenCode.make({\n baseUrl: endpoint.url,\n headers: headers(endpoint),\n })\n void listen(client)\n return client\n } catch (error) {\n connection = undefined\n throw error\n }\n}\n\nasync function listen(client: OpenCodeClient) {\n try {\n for await (const event of client.event.subscribe()) route(event)\n console.warn('the OpenCode event stream ended')\n } catch (error) {\n console.warn(`lost the OpenCode event stream: ${error}`)\n }\n connection = undefined\n if (openCodeRuns().length === 0) return\n await setTimeout(1000)\n try {\n const active = await (await openCode()).session.active()\n for (const run of openCodeRuns()) run.resync(run.sessionId in active)\n refreshSessions()\n } catch (error) {\n console.warn(`could not reconnect to OpenCode: ${error}`)\n for (const run of openCodeRuns()) run.exited()\n }\n}\n\nfunction route(event: V2Event) {\n if (listChanges.has(event.type)) refreshSessions()\n const sessionId = sessionOf(event)\n if (sessionId === null) return\n const run = runs.get(sessionId)\n if (run?.provider === 'opencode') run.receive(event)\n}\n\nfunction sessionOf(event: V2Event) {\n if (event.type === 'form.created') return event.data.form.sessionID\n const data: unknown = 'data' in event ? event.data : null\n if (\n typeof data === 'object' &&\n data !== null &&\n 'sessionID' in data &&\n typeof data.sessionID === 'string'\n )\n return data.sessionID\n return null\n}\n\nfunction openCodeRuns() {\n return [...runs.values()].flatMap((run) =>\n run.provider === 'opencode' ? [run] : []\n )\n}\n","import type {\n Item,\n ItemStatus,\n Question,\n TodoStep,\n} from '@offsite/core/protocol'\nimport type {\n FormField,\n FormInfo,\n SessionMessageAssistant,\n SessionMessageAssistantTool,\n SessionMessageInfo,\n ToolContent,\n} from '@opencode/client'\nimport { errorItem, hunks } from '../codex/index.ts'\n\ntype Base = { id: string; parent: string | null; time: number | null }\n\nconst toolStatuses: Record<\n SessionMessageAssistantTool['state']['status'],\n ItemStatus\n> = {\n streaming: 'running',\n running: 'running',\n completed: 'completed',\n error: 'failed',\n}\n\nconst todoStatuses: Record<string, TodoStep['status']> = {\n pending: 'pending',\n in_progress: 'running',\n completed: 'completed',\n cancelled: 'completed',\n}\n\nexport function messageItems(\n message: SessionMessageInfo,\n parent: string | null\n): Item[] {\n const base = { id: message.id, parent, time: message.time.created }\n switch (message.type) {\n case 'user':\n return [\n {\n ...base,\n kind: 'user',\n text: message.text,\n images: (message.files ?? [])\n .filter((file) => file.mime.startsWith('image/'))\n .map((file) => ({ mediaType: file.mime, data: file.data })),\n format: 'text',\n },\n ]\n case 'skill':\n return [\n {\n ...base,\n kind: 'skill',\n skill: message.name,\n output: '',\n status: 'completed',\n },\n ]\n case 'shell':\n return [\n {\n ...base,\n kind: 'command',\n command: message.command,\n description: '',\n output: message.output?.output ?? '',\n status:\n message.status === 'running'\n ? 'running'\n : message.status === 'exited'\n ? message.exit === 0\n ? 'completed'\n : 'failed'\n : 'stopped',\n background: null,\n },\n ]\n case 'assistant':\n return message.content.flatMap((part, index) =>\n partItems(message, part, index, parent)\n )\n case 'compaction':\n return message.status === 'failed'\n ? [{ ...errorItem(message.id, message.error.message), parent }]\n : [{ ...base, kind: 'compaction' }]\n case 'idle':\n return message.outcome === 'failed' && message.error !== undefined\n ? [{ ...errorItem(message.id, message.error.message), parent }]\n : []\n case 'agent-switched':\n case 'model-switched':\n case 'location-switched':\n case 'synthetic':\n case 'system':\n return []\n }\n}\n\nexport function formQuestions(form: FormInfo): Question[] {\n return form.fields.flatMap((field) =>\n field.type === 'external'\n ? []\n : [\n {\n question: questionText(field),\n header: field.title ?? '',\n multiSelect: field.type === 'multiselect',\n options: fieldOptions(field),\n },\n ]\n )\n}\n\nexport function formAnswer(form: FormInfo, answers: Record<string, string>) {\n return Object.fromEntries(\n form.fields.flatMap(\n (field): [string, string | number | boolean | string[]][] => {\n if (field.type === 'external') return []\n const answer = answers[questionText(field)]\n if (answer === undefined || answer === '') return []\n switch (field.type) {\n case 'string':\n return [[field.key, optionValue(field.options ?? [], answer)]]\n case 'multiselect':\n return [\n [\n field.key,\n answer\n .split(', ')\n .map((label) => optionValue(field.options, label)),\n ],\n ]\n case 'boolean':\n if (answer === 'Yes') return [[field.key, true]]\n if (answer === 'No') return [[field.key, false]]\n throw new Error(`${field.key} needs Yes or No`)\n case 'number':\n case 'integer':\n return [[field.key, Number(answer)]]\n }\n }\n )\n )\n}\n\nfunction partItems(\n message: SessionMessageAssistant,\n part: SessionMessageAssistant['content'][number],\n index: number,\n parent: string | null\n): Item[] {\n const base = {\n id: `${message.id}:${index}`,\n parent,\n time: message.time.created,\n }\n switch (part.type) {\n case 'text':\n return part.text.trim() === ''\n ? []\n : [{ ...base, kind: 'assistant', text: part.text, message: message.id }]\n case 'reasoning':\n return part.text.trim() === ''\n ? []\n : [{ ...base, kind: 'reasoning', text: part.text.trim() }]\n case 'tool':\n return toolItems(\n { id: `${message.id}:${part.id}`, parent, time: part.time.created },\n part\n )\n }\n}\n\nfunction toolItems(base: Base, tool: SessionMessageAssistantTool): Item[] {\n const state = tool.state\n const status = toolStatuses[state.status]\n const input: Record<string, unknown> =\n state.status === 'streaming' ? {} : state.input\n const metadata: Record<string, unknown> =\n state.status === 'streaming' ? {} : (state.metadata ?? {})\n const output =\n state.status === 'error'\n ? state.error.message\n : state.status === 'completed'\n ? contentText(state.content)\n : ''\n switch (tool.name) {\n case 'shell':\n return [\n {\n ...base,\n kind: 'command',\n command: text(input.command),\n description: text(input.description),\n output,\n status,\n background: null,\n },\n ]\n case 'edit':\n return [\n {\n ...base,\n kind: 'file_change',\n path: text(input.path ?? input.filePath),\n diffs: [\n { before: text(input.oldString), after: text(input.newString) },\n ],\n output,\n status,\n },\n ]\n case 'write':\n return [\n {\n ...base,\n kind: 'file_change',\n path: text(input.path ?? input.filePath),\n diffs: [{ before: '', after: text(input.content) }],\n output,\n status,\n },\n ]\n case 'patch':\n case 'apply_patch':\n if (!Array.isArray(metadata.files)) break\n return metadata.files.map((file: unknown, index) => ({\n ...base,\n id: `${base.id}:${index}`,\n kind: 'file_change',\n path: text(record(file).file),\n diffs: hunks(text(record(file).patch)),\n output,\n status,\n }))\n case 'todowrite':\n return [\n {\n ...base,\n kind: 'todo_list',\n steps: list(input.todos).map((todo) => ({\n text: text(record(todo).content),\n status: todoStatuses[text(record(todo).status)] ?? 'pending',\n })),\n },\n ]\n case 'subagent':\n case 'task':\n return [\n {\n ...base,\n kind: 'subagent',\n agent: text(input.agent ?? input.subagent_type) || 'Agent',\n description: text(input.description),\n agentId:\n typeof metadata.sessionID === 'string' ? metadata.sessionID : null,\n status,\n },\n ]\n case 'webfetch':\n case 'websearch':\n return [\n {\n ...base,\n kind: 'web_search',\n query: tool.name === 'websearch' ? text(input.query) : null,\n url: tool.name === 'webfetch' ? text(input.url) : null,\n results: [],\n output,\n status,\n },\n ]\n case 'question': {\n const questions = list(input.questions).map((item) => ({\n question: text(record(item).question),\n header: text(record(item).header),\n multiSelect: record(item).multiple === true,\n options: list(record(item).options).map((option) => ({\n label: text(record(option).label),\n description: text(record(option).description),\n })),\n }))\n const answers = metadata.answers\n return [\n {\n ...base,\n kind: 'question',\n questions,\n answers: Array.isArray(answers)\n ? Object.fromEntries(\n questions.map((question, index) => [\n question.question,\n list(answers[index]).map(text).join(', '),\n ])\n )\n : null,\n status,\n },\n ]\n }\n case 'skill':\n return [\n { ...base, kind: 'skill', skill: text(input.name), output, status },\n ]\n }\n return [{ ...base, kind: 'tool', name: tool.name, input, output, status }]\n}\n\nfunction questionText(field: Exclude<FormField, { type: 'external' }>) {\n return field.description ?? field.title ?? field.key\n}\n\nfunction fieldOptions(field: Exclude<FormField, { type: 'external' }>) {\n switch (field.type) {\n case 'string':\n case 'multiselect':\n return (field.options ?? []).map((option) => ({\n label: option.label,\n description: option.description ?? '',\n }))\n case 'boolean':\n return [\n { label: 'Yes', description: '' },\n { label: 'No', description: '' },\n ]\n case 'number':\n case 'integer':\n return []\n }\n}\n\nfunction optionValue(\n options: { value: string; label: string }[],\n label: string\n) {\n return options.find((option) => option.label === label)?.value ?? label\n}\n\nfunction contentText(content: ToolContent[]) {\n return content\n .map((block) => (block.type === 'text' ? block.text : block.uri))\n .join('\\n')\n}\n\nfunction text(value: unknown) {\n return typeof value === 'string' ? value : ''\n}\n\nfunction list(value: unknown): unknown[] {\n return Array.isArray(value) ? value : []\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n","import type {\n Account,\n Capabilities,\n Context,\n Item,\n Rewind,\n RewindResult,\n ServerEvent,\n} from '@offsite/core/protocol'\nimport type {\n OpenCodeClient,\n SessionInfo,\n SessionMessageInfo,\n} from '@opencode/client'\nimport { runs } from '../live.ts'\nimport { findOpenCode, openCode } from './client.ts'\nimport { messageItems } from './items.ts'\n\nconst PAGE = 100\nconst COMMIT_LIMIT = 2 * 60 * 1000\n\nconst temporary = new Set<string>()\n\nexport function openCodeAccount(): Account {\n return {\n id: 'opencode',\n provider: 'opencode',\n name: 'OpenCode',\n configDir: '',\n email: null,\n plan: null,\n error: null,\n limits: [],\n linked: true,\n valid: true,\n }\n}\n\nexport function openCodeInstalled() {\n return findOpenCode() !== null\n}\n\nexport async function openCodeCapabilities(cwd: string): Promise<Capabilities> {\n const client = await openCode()\n const location = { directory: cwd }\n const [models, commands, skills, agents] = await Promise.all([\n client.model.list({ location }),\n client.command.list({ location }),\n client.skill.list({ location }),\n client.agent.list({ location }),\n ])\n return {\n models: models.data\n .filter((model) => model.enabled)\n .map((model) => ({\n value: `${model.providerID}/${model.id}`,\n name: model.name,\n description: model.providerID,\n efforts: model.variants.map((variant) => variant.id),\n })),\n commands: [\n {\n name: 'compact',\n description: 'Summarize the conversation to free up context',\n hint: '',\n },\n ...commands.data.map((command) => ({\n name: command.name,\n description: command.description ?? '',\n hint: '',\n })),\n ...skills.data.map((skill) => ({\n name: skill.name,\n description: skill.description ?? '',\n hint: '',\n })),\n ],\n agents: agents.data\n .filter((agent) => agent.mode !== 'subagent' && !agent.hidden)\n .map((agent) => ({\n id: agent.id,\n name: agent.name,\n description: agent.description ?? '',\n })),\n }\n}\n\nexport async function openCodeSessions(paths: string[]) {\n if (paths.length === 0 || !openCodeInstalled()) return []\n const client = await openCode()\n const lists = await Promise.all(\n paths.map(async (directory) => {\n const found: SessionInfo[] = []\n let cursor: string | null = null\n do {\n const page = await client.session.list(\n cursor === null\n ? { directory, parentID: null, limit: PAGE }\n : { cursor }\n )\n found.push(...page.data)\n cursor = page.data.length === PAGE ? (page.cursor.next ?? null) : null\n } while (cursor !== null)\n return found\n })\n )\n return lists.flat().filter((session) => !temporary.has(session.id))\n}\n\nexport async function openCodeHistory(\n sessionId: string,\n cwd: string\n): Promise<ServerEvent> {\n const run = openCodeRun(sessionId)\n const client = await openCode()\n const messages = await allMessages(client, sessionId)\n return {\n type: 'history',\n sessionId,\n provider: 'opencode',\n items: messages.flatMap((message) => messageItems(message, null)),\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context: run?.context ?? (await contextOf(client, cwd, messages)),\n before: null,\n partial: run?.partial ?? '',\n }\n}\n\nexport async function openCodeAgent(\n agentId: string,\n parent: string\n): Promise<Item[]> {\n const messages = await allMessages(await openCode(), agentId)\n return messages.flatMap((message) => messageItems(message, parent))\n}\n\nexport async function renameOpenCode(sessionId: string, title: string) {\n await (await openCode()).session.update({ sessionID: sessionId, title })\n}\n\nexport async function removeOpenCode(sessionId: string) {\n await (await openCode()).session.remove({ sessionID: sessionId })\n}\n\nexport async function forkOpenCode(sessionId: string, messageId: string) {\n const client = await openCode()\n const messages = await allMessages(client, sessionId)\n const index = messages.findIndex((message) => message.id === messageId)\n if (index < 0) throw new Error('Cannot fork the session at that point')\n const next = messages.at(index + 1)\n const result = await client.session.fork({\n sessionID: sessionId,\n ...(next === undefined ? {} : { before: next.id }),\n })\n return { sessionId: result.id }\n}\n\nexport async function rewindOpenCode(request: Rewind): Promise<RewindResult> {\n if (request.code && !request.conversation && !request.dryRun)\n throw new Error('OpenCode restores files only with the conversation')\n const client = await openCode()\n const sessionID = request.sessionId\n const staged = await client.session.revert.stage({\n sessionID,\n messageID: request.messageId,\n files: request.code,\n })\n const files = staged.files ?? []\n const result = request.code\n ? {\n files: files.map((file) => file.file),\n insertions: files.reduce((sum, file) => sum + file.additions, 0),\n deletions: files.reduce((sum, file) => sum + file.deletions, 0),\n }\n : null\n if (request.dryRun) await client.session.revert.clear({ sessionID })\n else await client.session.revert.commit({ sessionID })\n return result\n}\n\nexport async function openCodeCommitMessage(\n cwd: string,\n model: string,\n prompt: string\n) {\n const client = await openCode()\n const session = await client.session.create({\n location: { directory: cwd },\n agent: 'plan',\n model: modelRef(model, null),\n })\n temporary.add(session.id)\n try {\n await client.session.prompt({ sessionID: session.id, text: prompt })\n await client.session.wait(\n { sessionID: session.id },\n { signal: AbortSignal.timeout(COMMIT_LIMIT) }\n )\n const messages = await allMessages(client, session.id)\n for (const message of messages.toReversed()) {\n if (message.type === 'idle' && message.outcome === 'failed')\n throw new Error(message.error?.message ?? 'OpenCode failed')\n if (message.type !== 'assistant') continue\n const text = message.content\n .flatMap((part) => (part.type === 'text' ? [part.text] : []))\n .join('')\n .trim()\n if (text !== '') return { message: text }\n }\n throw new Error('OpenCode did not reply')\n } finally {\n await client.session.remove({ sessionID: session.id })\n temporary.delete(session.id)\n }\n}\n\nexport async function contextOf(\n client: OpenCodeClient,\n cwd: string,\n messages: SessionMessageInfo[]\n): Promise<Context | null> {\n const last = messages.findLast(\n (message) => message.type === 'assistant' && message.tokens !== undefined\n )\n if (last?.type !== 'assistant' || last.tokens === undefined) return null\n const tokens = last.tokens\n const models = await client.model.list({ location: { directory: cwd } })\n const model = models.data.find(\n (item) =>\n item.providerID === last.model.providerID && item.id === last.model.id\n )\n return {\n tokens:\n tokens.input +\n tokens.output +\n tokens.reasoning +\n tokens.cache.read +\n tokens.cache.write,\n window: model?.limit.context ?? null,\n }\n}\n\nexport function modelRef(value: string, effort: string | null) {\n const index = value.indexOf('/')\n if (index < 0) throw new Error(`${value} is not an OpenCode model`)\n return {\n providerID: value.slice(0, index),\n id: value.slice(index + 1),\n ...(effort === null ? {} : { variant: effort }),\n }\n}\n\nasync function allMessages(client: OpenCodeClient, sessionId: string) {\n const messages: SessionMessageInfo[] = []\n let cursor: string | null = null\n do {\n const page = await client.message.list(\n cursor === null\n ? { sessionID: sessionId, limit: PAGE, order: 'asc' }\n : { sessionID: sessionId, cursor }\n )\n messages.push(...page.data)\n cursor = page.data.length === PAGE ? (page.cursor.next ?? null) : null\n } while (cursor !== null)\n return messages\n}\n\nfunction openCodeRun(sessionId: string) {\n const run = runs.get(sessionId)\n return run?.provider === 'opencode' ? run : undefined\n}\n","import { randomUUID } from 'node:crypto'\nimport type {\n Context,\n Decision,\n Delivery,\n Item,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport type {\n FormInfo,\n OpenCodeClient,\n PermissionReply,\n PermissionRequest as OpenCodePermission,\n SessionInfo,\n V2Event,\n} from '@opencode/client'\nimport { errorItem } from '../codex/index.ts'\nimport { publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport { openCode } from './client.ts'\nimport { formAnswer, formQuestions, messageItems } from './items.ts'\nimport { contextOf, modelRef } from './sessions.ts'\n\nconst IDLE_LIMIT = 30 * 60 * 1000\nconst RECENT = 30\n\nconst replies: Record<Decision, PermissionReply> = {\n allow: 'once',\n always: 'always',\n deny: 'reject',\n}\n\ntype Pending =\n | { kind: 'permission'; request: PermissionRequest }\n | { kind: 'form'; request: PermissionRequest; form: FormInfo }\n\nexport class OpenCodeRun {\n readonly provider = 'opencode'\n readonly sessionId: string\n readonly cwd: string\n readonly pending = new Map<string, Pending>()\n readonly items = new Map<string, Item>()\n readonly closed: Promise<void>\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly client: OpenCodeClient\n private readonly close: () => void\n private applied: Settings\n private loading = Promise.resolve()\n private refreshTimer: NodeJS.Timeout | undefined\n private idleTimer: NodeJS.Timeout | undefined\n\n static async start(cwd: string, settings: Settings) {\n const client = await openCode()\n const session = await client.session.create({\n location: { directory: cwd },\n ...(settings.mode === null ? {} : { agent: settings.mode }),\n ...(settings.model === null\n ? {}\n : { model: modelRef(settings.model, settings.effort) }),\n })\n return new OpenCodeRun(client, session.id, cwd, settings, settings)\n }\n\n static async resume(sessionId: string, cwd: string, settings: Settings) {\n const client = await openCode()\n const session = await client.session.get({ sessionID: sessionId })\n return new OpenCodeRun(\n client,\n sessionId,\n cwd,\n settings,\n sessionSettings(session, settings)\n )\n }\n\n private constructor(\n client: OpenCodeClient,\n sessionId: string,\n cwd: string,\n settings: Settings,\n applied: Settings\n ) {\n this.client = client\n this.sessionId = sessionId\n this.cwd = cwd\n this.settings = settings\n this.applied = applied\n const closed = Promise.withResolvers<void>()\n this.closed = closed.promise\n this.close = closed.resolve\n runs.set(sessionId, this)\n this.armIdleTimer()\n }\n\n async submit(prompt: Prompt, delivery: Delivery) {\n if (!this.running) {\n await this.startTurn(prompt)\n return\n }\n switch (delivery) {\n case 'steer':\n await this.client.session.prompt({\n sessionID: this.sessionId,\n text: prompt.text,\n files: files(prompt),\n delivery: 'steer',\n })\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer').catch((error: unknown) =>\n this.fail(error)\n )\n }\n\n configure(settings: Settings) {\n this.settings = { ...settings, accountId: this.settings.accountId }\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings: this.settings,\n })\n }\n\n async interrupt() {\n await this.client.session.interrupt({ sessionID: this.sessionId })\n }\n\n stopTask(): Promise<void> {\n throw new Error('OpenCode has no background tasks to stop')\n }\n\n async respond(\n requestId: string,\n decision: Decision,\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n const sessionID = this.sessionId\n if (pending.kind === 'permission')\n await this.client.permission.reply({\n sessionID,\n requestID: requestId,\n decision: replies[decision],\n })\n else if (decision === 'deny')\n await this.client.session.form.cancel({ sessionID, formID: requestId })\n else\n await this.client.session.form.reply({\n sessionID,\n formID: requestId,\n answer: formAnswer(pending.form, answers ?? {}),\n })\n this.settle(requestId)\n }\n\n stop() {\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.end()\n }\n\n exited() {\n this.put([errorItem(randomUUID(), 'Lost the connection to OpenCode')])\n this.stop()\n }\n\n resync(active: boolean) {\n this.refresh()\n if (this.running && !active) this.finishTurn()\n }\n\n receive(event: V2Event) {\n switch (event.type) {\n case 'session.reasoning.delta':\n case 'session.tool.input.delta':\n case 'session.compaction.delta':\n return\n case 'session.execution.started':\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n return\n case 'session.execution.succeeded':\n case 'session.execution.failed':\n case 'session.execution.interrupted':\n this.refresh()\n void this.loading.then(() => this.finishTurn())\n return\n case 'session.text.delta':\n this.partial += event.data.delta\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: event.data.delta,\n })\n return\n case 'permission.asked':\n this.refresh()\n void this.loading.then(() => this.ask(event.data))\n return\n case 'permission.replied':\n this.settle(event.data.requestID)\n return\n case 'form.created':\n this.addPending({\n kind: 'form',\n request: {\n id: event.data.form.id,\n kind: 'question',\n questions: formQuestions(event.data.form),\n },\n form: event.data.form,\n })\n return\n case 'form.replied':\n case 'form.cancelled':\n this.settle(event.data.id)\n return\n default:\n clearTimeout(this.refreshTimer)\n this.refreshTimer = setTimeout(() => this.refresh(), 100)\n }\n }\n\n private refresh() {\n clearTimeout(this.refreshTimer)\n this.loading = this.loading\n .then(() => this.load())\n .catch((error: unknown) =>\n console.warn(`could not load OpenCode messages: ${error}`)\n )\n }\n\n private async load() {\n const page = await this.client.message.list({\n sessionID: this.sessionId,\n limit: RECENT,\n order: 'desc',\n })\n const messages = page.data.toReversed()\n this.put(\n messages\n .flatMap((message) => messageItems(message, null))\n .filter(\n (item) =>\n JSON.stringify(this.items.get(item.id)) !== JSON.stringify(item)\n )\n )\n const context = await contextOf(this.client, this.cwd, messages)\n if (context === null || context.tokens === this.context?.tokens) return\n this.context = context\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context,\n })\n }\n\n private async startTurn(prompt: Prompt) {\n clearTimeout(this.idleTimer)\n this.running = true\n this.prompted = true\n broadcastActivity()\n try {\n await this.apply()\n await this.send(prompt)\n } catch (error) {\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n throw error\n }\n }\n\n private async send(prompt: Prompt) {\n const sessionID = this.sessionId\n const location = { directory: this.cwd }\n const match = /^\\/(\\S+)\\s*([\\s\\S]*)$/.exec(prompt.text)\n if (match !== null) {\n if (match[1] === 'compact' && prompt.images.length === 0) {\n await this.client.session.compact({ sessionID })\n return\n }\n const commands = await this.client.command.list({ location })\n if (commands.data.some((command) => command.name === match[1])) {\n await this.client.session.command({\n sessionID,\n name: match[1],\n text: match[2],\n files: files(prompt),\n })\n return\n }\n const skills = await this.client.skill.list({ location })\n const skill = skills.data.find((item) => item.name === match[1])\n if (skill !== undefined) {\n await this.client.session.prompt({\n sessionID,\n text: match[2],\n files: files(prompt),\n skills: [{ id: skill.id }],\n })\n return\n }\n }\n await this.client.session.prompt({\n sessionID,\n text: prompt.text,\n files: files(prompt),\n })\n }\n\n private async apply() {\n const settings = this.settings\n const model = settings.model ?? this.applied.model\n if (\n model !== null &&\n (model !== this.applied.model || settings.effort !== this.applied.effort)\n )\n await this.client.session.switchModel({\n sessionID: this.sessionId,\n model: modelRef(model, settings.effort),\n })\n if (settings.mode !== null && settings.mode !== this.applied.mode)\n await this.client.session.switchAgent({\n sessionID: this.sessionId,\n agent: settings.mode,\n })\n this.applied = {\n ...settings,\n model,\n mode: settings.mode ?? this.applied.mode,\n }\n }\n\n private ask(permission: OpenCodePermission) {\n const source = permission.source\n const item =\n source === undefined\n ? undefined\n : this.items.get(`${source.messageID}:${source.id}`)\n this.addPending({\n kind: 'permission',\n request: {\n id: permission.id,\n kind: 'approval',\n title:\n permission.message ??\n `Allow ${permission.action} ${permission.resources.join(', ')}?`,\n canAlwaysAllow: (permission.save ?? []).length > 0,\n item: item ?? {\n id: permission.id,\n parent: null,\n time: Date.now(),\n kind: 'tool',\n name: permission.action,\n input: { resources: permission.resources },\n output: '',\n status: 'running',\n },\n },\n })\n }\n\n private addPending(pending: Pending) {\n this.pending.set(pending.request.id, pending)\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request: pending.request,\n })\n broadcastActivity()\n }\n\n private finishTurn() {\n this.partial = ''\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.startTurn(next.prompt).catch((error: unknown) => this.fail(error))\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private settle(requestId: string) {\n if (!this.pending.delete(requestId)) return\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private put(items: Item[]) {\n if (items.length === 0) return\n for (const item of items) this.items.set(item.id, item)\n if (items.some((item) => item.kind === 'assistant')) this.partial = ''\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items,\n })\n }\n\n private fail(error: unknown) {\n this.put([\n errorItem(\n randomUUID(),\n error instanceof Error ? error.message : String(error)\n ),\n ])\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private end() {\n clearTimeout(this.idleTimer)\n clearTimeout(this.refreshTimer)\n for (const requestId of [...this.pending.keys()]) this.settle(requestId)\n this.running = false\n broadcastActivity()\n this.close()\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction sessionSettings(session: SessionInfo, settings: Settings): Settings {\n const variant = session.model?.variant\n return {\n ...settings,\n model:\n session.model === undefined\n ? null\n : `${session.model.providerID}/${session.model.id}`,\n effort: variant === undefined || variant === 'default' ? null : variant,\n mode: session.agent ?? null,\n }\n}\n\nfunction files(prompt: Prompt) {\n return prompt.images.map((image) => ({\n uri: `data:${image.mediaType};base64,${image.data}`,\n }))\n}\n","import { randomUUID } from 'node:crypto'\nimport os from 'node:os'\nimport path from 'node:path'\nimport type { Account, Capabilities, Provider } from '@offsite/core/protocol'\nimport {\n claudeAccount,\n claudeCapabilities,\n forgetClaude,\n} from '../lib/claude/index.ts'\nimport { codexAccount, codexCapabilities } from '../lib/codex/index.ts'\nimport { broadcast } from '../lib/hub.ts'\nimport {\n openCodeAccount,\n openCodeCapabilities,\n openCodeInstalled,\n} from '../lib/opencode/index.ts'\nimport { readJson, writeJson } from '../storage/storage.ts'\n\nexport type StoredAccount = {\n id: string\n provider: Provider\n name: string\n configDir: string\n}\n\nconst providerNames: Record<Provider, string> = {\n claude: 'Claude',\n codex: 'Codex',\n opencode: 'OpenCode',\n}\n\nexport function providerName(provider: Provider) {\n return providerNames[provider]\n}\n\nexport function storedAccounts(): StoredAccount[] {\n const items =\n (readJson('accounts.json') as\n | (Omit<StoredAccount, 'provider'> & { provider?: Provider })[]\n | null) ?? []\n return items.map((item) => ({ ...item, provider: item.provider ?? 'claude' }))\n}\n\nexport function storedAccount(provider: Provider, accountId: string | null) {\n if (accountId === null)\n throw new Error(\n `Add a ${providerName(provider)} account in Settings → Accounts`\n )\n const account = storedAccounts().find((item) => item.id === accountId)\n if (account === undefined) throw new Error('That account was removed')\n if (account.provider !== provider)\n throw new Error(`That account is not a ${providerName(provider)} account`)\n return account\n}\n\nexport async function accounts(): Promise<Account[]> {\n const stored = await Promise.all(\n storedAccounts().map((account) => {\n switch (account.provider) {\n case 'claude':\n return claudeAccount(account)\n case 'codex':\n return codexAccount(account)\n case 'opencode':\n throw new Error('OpenCode has no stored accounts')\n }\n })\n )\n return openCodeInstalled() ? [...stored, openCodeAccount()] : stored\n}\n\nexport async function publishAccounts() {\n try {\n broadcast({ type: 'accounts', accounts: await accounts() })\n } catch (error) {\n console.warn(`could not list accounts: ${error}`)\n }\n}\n\nexport function capabilities(\n accountId: string,\n cwd: string\n): Promise<Capabilities> {\n if (accountId === openCodeAccount().id) return openCodeCapabilities(cwd)\n const account = storedAccounts().find((item) => item.id === accountId)\n if (account === undefined) throw new Error('That account was removed')\n switch (account.provider) {\n case 'claude':\n return claudeCapabilities(account, cwd)\n case 'codex':\n return codexCapabilities(account, cwd)\n case 'opencode':\n throw new Error('OpenCode has no stored accounts')\n }\n}\n\nexport function addAccount(\n provider: Provider,\n name: string,\n configDir: string\n) {\n if (provider === 'opencode')\n throw new Error('OpenCode has no accounts. Connect providers in OpenCode')\n saveAccounts([\n ...storedAccounts(),\n { id: randomUUID(), provider, ...validAccount(name, configDir) },\n ])\n}\n\nexport function updateAccount(id: string, name: string, configDir: string) {\n const account = validAccount(name, configDir)\n saveAccounts(\n storedAccounts().map((item) =>\n item.id === id ? { ...item, ...account } : item\n )\n )\n forgetClaude(id)\n}\n\nexport function removeAccount(id: string) {\n saveAccounts(storedAccounts().filter((item) => item.id !== id))\n forgetClaude(id)\n}\n\nfunction validAccount(name: string, configDir: string) {\n if (name.trim() === '') throw new Error('Give the account a name')\n const dir = configDir.trim()\n if (dir === '~' || dir.startsWith('~/'))\n return {\n name: name.trim(),\n configDir: path.join(os.homedir(), dir.slice(1)),\n }\n if (path.isAbsolute(dir)) return { name: name.trim(), configDir: dir }\n throw new Error('Use an absolute config directory or one starting with ~/')\n}\n\nfunction saveAccounts(items: StoredAccount[]) {\n writeJson('accounts.json', items)\n}\n","export type Block =\n | { type: 'text'; text: string }\n | { type: 'thinking'; thinking: string }\n | { type: 'image'; mediaType: string; data: string | null }\n | {\n type: 'tool_use'\n id: string\n name: string\n input: Record<string, unknown>\n }\n | {\n type: 'tool_result'\n toolUseId: string\n content: Block[]\n isError: boolean\n answers: Record<string, string> | null\n }\n\nexport type Message =\n | {\n type: 'user' | 'assistant'\n uuid: string\n time: number | null\n content: Block[]\n parent: string | null\n }\n | {\n type: 'notice'\n uuid: string\n time: number | null\n text: string\n isError: boolean\n }\n | { type: 'compaction'; uuid: string; time: number | null }\n\nexport function toMessage(\n type: 'user' | 'assistant',\n item: {\n uuid: string\n message: unknown\n parent_tool_use_id: string | null\n tool_use_result?: unknown\n },\n time: number | null\n): Extract<Message, { type: 'user' | 'assistant' }> {\n return {\n type,\n uuid: item.uuid,\n time,\n content: isRecord(item.message)\n ? toBlocks(item.message.content, answersOf(item.tool_use_result))\n : [],\n parent: item.parent_tool_use_id,\n }\n}\n\nexport function contextTokens(message: unknown) {\n if (!isRecord(message) || !isRecord(message.usage)) return null\n const usage = message.usage\n return [\n usage.input_tokens,\n usage.cache_creation_input_tokens,\n usage.cache_read_input_tokens,\n usage.output_tokens,\n ].reduce<number>(\n (total, value) => total + (typeof value === 'number' ? value : 0),\n 0\n )\n}\n\nfunction answersOf(output: unknown) {\n if (!isRecord(output) || !isRecord(output.answers)) return null\n const answers: Record<string, string> = {}\n for (const [question, answer] of Object.entries(output.answers)) {\n if (typeof answer !== 'string') return null\n answers[question] = answer\n }\n return answers\n}\n\nfunction toBlocks(\n content: unknown,\n answers: Record<string, string> | null\n): Block[] {\n if (typeof content === 'string') return [{ type: 'text', text: content }]\n if (!Array.isArray(content)) return []\n return content.flatMap((block): Block[] => {\n if (!isRecord(block)) return []\n switch (block.type) {\n case 'text':\n return typeof block.text === 'string' &&\n !block.text.startsWith('<system-reminder>') &&\n !block.text.startsWith('<local-command-caveat>')\n ? [{ type: 'text', text: block.text }]\n : []\n case 'thinking':\n return typeof block.thinking === 'string' && block.thinking !== ''\n ? [{ type: 'thinking', thinking: block.thinking }]\n : []\n case 'image': {\n const source = block.source\n return isRecord(source) &&\n source.type === 'base64' &&\n typeof source.media_type === 'string' &&\n typeof source.data === 'string'\n ? [{ type: 'image', mediaType: source.media_type, data: source.data }]\n : []\n }\n case 'tool_use':\n return typeof block.id === 'string' &&\n typeof block.name === 'string' &&\n isRecord(block.input)\n ? [\n {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input,\n },\n ]\n : []\n case 'tool_result':\n return typeof block.tool_use_id === 'string'\n ? [\n {\n type: 'tool_result',\n toolUseId: block.tool_use_id,\n content: toBlocks(block.content, null).filter(\n (item) => item.type === 'text'\n ),\n isError: block.is_error === true,\n answers,\n },\n ]\n : []\n default:\n return []\n }\n })\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { realpathSync, statSync } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport {\n type EffortLevel,\n type Options,\n type PermissionMode,\n query,\n type SDKControlInitializeResponse,\n type SDKRateLimitInfo,\n type SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Account, Capabilities, RateLimit } from '@offsite/core/protocol'\nimport { type StoredAccount, storedAccount } from '../../services/accounts.ts'\nimport { readConfig } from '../../storage/config.ts'\nimport { broadcast } from '../hub.ts'\nimport { isRecord } from './content.ts'\n\nconst efforts: EffortLevel[] = ['low', 'medium', 'high', 'xhigh', 'max']\nconst modes: PermissionMode[] = [\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n 'plan',\n 'dontAsk',\n 'auto',\n]\nconst probes = new Map<string, Promise<SDKControlInitializeResponse>>()\nconst limits = new Map<string, Map<string, RateLimit>>()\nlet executable = ''\n\nexport function findClaude() {\n const name = process.platform === 'win32' ? 'claude.exe' : 'claude'\n for (const dir of (process.env.PATH ?? '').split(path.delimiter)) {\n const candidate = path.join(dir, name)\n if (statSync(candidate, { throwIfNoEntry: false })?.isFile()) {\n executable = candidate\n return candidate\n }\n }\n return null\n}\n\nexport function claudeEffort(value: string) {\n const effort = efforts.find((item) => item === value)\n if (effort === undefined) throw new Error(`Claude has no ${value} effort`)\n return effort\n}\n\nexport function claudeMode(value: string) {\n const mode = modes.find((item) => item === value)\n if (mode === undefined) throw new Error(`Claude has no ${value} mode`)\n return mode\n}\n\nexport function claudeOptions(accountId: string | null, cwd: string): Options {\n const account = storedAccount('claude', accountId)\n return {\n cwd,\n env: {\n ...process.env,\n CLAUDE_CODE_ENTRYPOINT: 'offsite',\n CLAUDE_CONFIG_DIR: account.configDir,\n },\n pathToClaudeCodeExecutable: executable,\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n hooks: {\n PostToolUse: [\n {\n matcher: 'PushNotification',\n hooks: [\n async (input) => {\n if (\n input.hook_event_name !== 'PostToolUse' ||\n typeof input.tool_input !== 'object' ||\n input.tool_input === null ||\n !('message' in input.tool_input) ||\n typeof input.tool_input.message !== 'string'\n )\n throw new Error('Unexpected PushNotification hook input')\n broadcast({\n type: 'notification',\n sessionId: input.session_id,\n message: input.tool_input.message,\n })\n return {\n hookSpecificOutput: {\n hookEventName: 'PostToolUse',\n updatedToolOutput: {\n message: input.tool_input.message,\n localSent: true,\n disabledReason: 'no_transport',\n },\n },\n }\n },\n ],\n },\n ],\n },\n }\n}\n\nexport async function claudeCapabilities(\n account: StoredAccount,\n cwd: string\n): Promise<Capabilities> {\n const result = await initialization(account.id, cwd)\n return {\n models: result.models.map((model) => ({\n value: model.value,\n name: model.displayName,\n description: model.description,\n efforts: model.supportedEffortLevels ?? [],\n })),\n commands: result.commands.map((command) => ({\n name: command.name,\n description: command.description,\n hint: command.argumentHint,\n })),\n agents: [],\n }\n}\n\nexport async function claudeAccount(account: StoredAccount): Promise<Account> {\n const linked = isLinked(account.configDir)\n try {\n const info = (await initialization(account.id, os.homedir())).account\n return {\n ...account,\n email: info.email ?? null,\n plan: info.subscriptionType ?? null,\n error: null,\n limits: accountLimits(account.id),\n linked,\n valid: linked,\n }\n } catch (error) {\n return {\n ...account,\n email: null,\n plan: null,\n error: error instanceof Error ? error.message : String(error),\n limits: accountLimits(account.id),\n linked,\n valid: linked,\n }\n }\n}\n\nexport function forgetClaude(accountId: string) {\n for (const key of probes.keys())\n if (key.startsWith(`${accountId}\\n`)) probes.delete(key)\n limits.delete(accountId)\n}\n\nexport function recordLimit(accountId: string, info: SDKRateLimitInfo) {\n const current = limits.get(accountId) ?? new Map<string, RateLimit>()\n const windows = (info as { unifiedWindows?: unknown }).unifiedWindows\n if (isRecord(windows))\n for (const [name, value] of Object.entries(windows))\n if (isRecord(value))\n current.set(name, {\n window: name,\n utilization:\n typeof value.utilization === 'number' ? value.utilization : null,\n resetsAt: typeof value.resetsAt === 'number' ? value.resetsAt : null,\n rejected: current.get(name)?.rejected ?? false,\n })\n if (info.rateLimitType !== undefined) {\n const existing = current.get(info.rateLimitType)\n current.set(info.rateLimitType, {\n window: info.rateLimitType,\n utilization: info.utilization ?? existing?.utilization ?? null,\n resetsAt: info.resetsAt ?? existing?.resetsAt ?? null,\n rejected: info.status === 'rejected',\n })\n }\n limits.set(accountId, current)\n return accountLimits(accountId)\n}\n\nfunction isLinked(configDir: string) {\n const base = readConfig().claudeBaseDir\n try {\n if (realpathSync(configDir) === realpathSync(base)) return true\n return (\n realpathSync(path.join(configDir, 'projects')) ===\n realpathSync(path.join(base, 'projects'))\n )\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n\nfunction accountLimits(accountId: string) {\n return [...(limits.get(accountId)?.values() ?? [])]\n}\n\nfunction initialization(accountId: string, cwd: string) {\n const key = `${accountId}\\n${cwd}`\n const existing = probes.get(key)\n if (existing !== undefined) return existing\n const probe = runProbe(accountId, cwd)\n probes.set(key, probe)\n probe.catch(() => probes.delete(key))\n return probe\n}\n\nasync function runProbe(accountId: string, cwd: string) {\n const closed = Promise.withResolvers<void>()\n const probe = query({\n prompt: idle(closed.promise),\n options: claudeOptions(accountId, cwd),\n })\n try {\n return await probe.initializationResult()\n } finally {\n closed.resolve()\n probe.close()\n }\n}\n\nasync function* idle(until: Promise<void>): AsyncGenerator<SDKUserMessage> {\n await until\n yield* []\n}\n","import type {\n Background,\n Item,\n ItemStatus,\n PermissionRequest,\n Question,\n TodoStep,\n} from '@offsite/core/protocol'\nimport { type Block, isRecord, type Message } from './content.ts'\n\ntype ToolUse = Extract<Block, { type: 'tool_use' }>\n\ntype ToolResult = Extract<Block, { type: 'tool_result' }>\n\nconst notifications = /<task-notification>([\\s\\S]*?)<\\/task-notification>/g\n\nconst taskStatuses = new Map<string, ItemStatus>([\n ['completed', 'completed'],\n ['failed', 'failed'],\n ['killed', 'stopped'],\n ['stopped', 'stopped'],\n])\n\nconst todoStatuses = new Map<string, TodoStep['status']>([\n ['pending', 'pending'],\n ['in_progress', 'running'],\n ['completed', 'completed'],\n])\n\nexport function toItems(messages: Message[]): Item[] {\n const items: Item[] = []\n const tools = new Map<string, number>()\n const owners = new Map<string, number>()\n const stops = new Map<string, string>()\n\n function change(index: number, patch: Partial<Item>) {\n items[index] = { ...items[index], ...patch } as Item\n }\n\n for (const message of messages) {\n const base = { parent: null, time: message.time }\n if (message.type === 'compaction') {\n items.push({ ...base, id: message.uuid, kind: 'compaction' })\n continue\n }\n if (message.type === 'notice') {\n items.push({\n ...base,\n id: message.uuid,\n kind: message.isError ? 'error' : 'notice',\n text: message.text,\n })\n continue\n }\n if (message.type === 'assistant') {\n message.content.forEach((block, index) => {\n const id = `${message.uuid}:${index}`\n const parent = message.parent\n switch (block.type) {\n case 'text':\n if (block.text.trim() !== '')\n items.push({\n id,\n parent,\n time: message.time,\n kind: 'assistant',\n text: block.text,\n message: message.uuid,\n })\n break\n case 'thinking':\n if (block.thinking.trim() !== '')\n items.push({\n id,\n parent,\n time: message.time,\n kind: 'reasoning',\n text: block.thinking,\n })\n break\n case 'tool_use': {\n if (block.name === 'SendMessage') {\n const owner = owners.get(text(block.input.to))\n if (owner !== undefined) change(owner, { status: 'running' })\n }\n if (block.name === 'TaskStop')\n stops.set(block.id, text(block.input.task_id))\n tools.set(block.id, items.length)\n items.push(\n toolItem(block, parent, message.time, (to) => {\n const owner = owners.get(to)\n return owner === undefined ? null : items[owner].id\n })\n )\n break\n }\n case 'image':\n case 'tool_result':\n break\n }\n })\n continue\n }\n const texts: { format: 'text' | 'command' | 'output'; text: string }[] = []\n const images = message.content.flatMap((block) =>\n block.type === 'image'\n ? [{ mediaType: block.mediaType, data: block.data }]\n : []\n )\n for (const block of message.content) {\n if (block.type === 'tool_result') {\n const index = tools.get(block.toolUseId)\n if (index === undefined) continue\n const result = applyResult(items[index], block)\n items[index] = result\n if (result.kind === 'subagent' && result.agentId !== null)\n owners.set(result.agentId, index)\n if (\n result.kind === 'command' &&\n result.background !== null &&\n result.background.taskId !== null\n )\n owners.set(result.background.taskId, index)\n const stopped = stops.get(block.toolUseId)\n const owner = stopped === undefined ? undefined : owners.get(stopped)\n if (owner !== undefined && !block.isError)\n change(owner, { status: 'stopped' })\n continue\n }\n if (block.type !== 'text') continue\n if (block.text.startsWith('<task-notification>')) {\n let count = 0\n for (const match of block.text.matchAll(notifications)) {\n const body = match[1]\n const status = taskStatuses.get(\n /<status>(\\w+)<\\/status>/.exec(body)?.[1] ?? ''\n )\n const event = /<event>([\\s\\S]*?)<\\/event>/.exec(body)?.[1]\n for (const id of body.matchAll(/<task-id>(\\w+)<\\/task-id>/g)) {\n const owner = owners.get(id[1])\n if (owner === undefined) continue\n if (status !== undefined) change(owner, { status })\n const task = items[owner]\n if (\n event !== undefined &&\n task.kind === 'command' &&\n task.background !== null\n )\n change(owner, {\n background: {\n ...task.background,\n events: [...task.background.events, event],\n },\n })\n }\n items.push({\n id: `${message.uuid}:${count}`,\n parent: message.parent,\n time: message.time,\n kind: 'notice',\n text:\n /<summary>([\\s\\S]*?)<\\/summary>/.exec(body)?.[1] ??\n 'Background task updated',\n })\n count += 1\n }\n continue\n }\n if (block.text.startsWith('[Request interrupted by user')) {\n items.push({\n id: message.uuid,\n parent: message.parent,\n time: message.time,\n kind: 'notice',\n text: 'Interrupted',\n })\n continue\n }\n texts.push(userText(block.text))\n }\n if (texts.length === 0 && images.length === 0) continue\n items.push({\n id: message.uuid,\n parent: message.parent,\n time: message.time,\n kind: 'user',\n text: texts.map((part) => part.text).join('\\n'),\n images,\n format: texts[0]?.format ?? 'text',\n })\n }\n return items\n}\n\nexport function toRequest(options: {\n id: string\n toolName: string\n input: Record<string, unknown>\n title: string | null\n canAlwaysAllow: boolean\n}): PermissionRequest {\n switch (options.toolName) {\n case 'AskUserQuestion':\n return {\n id: options.id,\n kind: 'question',\n questions: options.input.questions as Question[],\n }\n case 'ExitPlanMode':\n return { id: options.id, kind: 'plan', plan: text(options.input.plan) }\n default:\n return {\n id: options.id,\n kind: 'approval',\n title: options.title ?? `Allow ${options.toolName}?`,\n canAlwaysAllow: options.canAlwaysAllow,\n item: toolItem(\n {\n type: 'tool_use',\n id: options.id,\n name: options.toolName,\n input: options.input,\n },\n null,\n null,\n () => null\n ),\n }\n }\n}\n\nfunction toolItem(\n tool: ToolUse,\n parent: string | null,\n time: number | null,\n ownerOf: (id: string) => string | null\n): Item {\n const input = tool.input\n const base = { id: tool.id, parent, time }\n switch (tool.name) {\n case 'Bash':\n return {\n ...base,\n kind: 'command',\n command: text(input.command),\n description: text(input.description),\n output: '',\n status: 'running',\n background:\n input.run_in_background === true\n ? { taskId: null, outputPath: null, events: [] }\n : null,\n }\n case 'Monitor':\n return {\n ...base,\n kind: 'command',\n command:\n text(input.command) || (isRecord(input.ws) ? text(input.ws.url) : ''),\n description: text(input.description),\n output: '',\n status: 'running',\n background: { taskId: null, outputPath: null, events: [] },\n }\n case 'Edit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: [\n { before: text(input.old_string), after: text(input.new_string) },\n ],\n output: '',\n status: 'running',\n }\n case 'MultiEdit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: (\n input.edits as { old_string: string; new_string: string }[]\n ).map((edit) => ({ before: edit.old_string, after: edit.new_string })),\n output: '',\n status: 'running',\n }\n case 'Write':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.file_path),\n diffs: [{ before: '', after: text(input.content) }],\n output: '',\n status: 'running',\n }\n case 'NotebookEdit':\n return {\n ...base,\n kind: 'file_change',\n path: text(input.notebook_path),\n diffs: [],\n output: '',\n status: 'running',\n }\n case 'WebFetch':\n return {\n ...base,\n kind: 'web_search',\n query: null,\n url: text(input.url),\n results: [],\n output: '',\n status: 'running',\n }\n case 'WebSearch':\n return {\n ...base,\n kind: 'web_search',\n query: text(input.query),\n url: null,\n results: [],\n output: '',\n status: 'running',\n }\n case 'Skill':\n return {\n ...base,\n kind: 'skill',\n skill: text(input.skill),\n output: '',\n status: 'running',\n }\n case 'TodoWrite':\n return {\n ...base,\n kind: 'todo_list',\n steps: (input.todos as { content: string; status: string }[]).map(\n (todo) => ({\n text: todo.content,\n status: todoStatuses.get(todo.status) ?? 'pending',\n })\n ),\n }\n case 'ExitPlanMode':\n return { ...base, kind: 'plan', plan: text(input.plan) }\n case 'AskUserQuestion':\n return {\n ...base,\n kind: 'question',\n questions: input.questions as Question[],\n answers: null,\n status: 'running',\n }\n case 'Agent':\n case 'Task': {\n const agent = text(input.subagent_type)\n return {\n ...base,\n kind: 'subagent',\n agent: agent === '' ? 'general-purpose' : agent,\n description: text(input.description),\n agentId: null,\n status: 'running',\n }\n }\n case 'SendMessage': {\n const summary = text(input.summary)\n return {\n ...base,\n kind: 'agent_message',\n target: ownerOf(text(input.to)),\n summary: summary === '' ? text(input.message).split('\\n')[0] : summary,\n status: 'running',\n }\n }\n default:\n return {\n ...base,\n kind: 'tool',\n name: tool.name,\n input,\n output: '',\n status: 'running',\n }\n }\n}\n\nfunction applyResult(item: Item, result: ToolResult): Item {\n const output = result.content\n .flatMap((block) => (block.type === 'text' ? [block.text] : []))\n .join('\\n')\n const status = result.isError ? 'failed' : 'completed'\n switch (item.kind) {\n case 'command': {\n if (item.background === null) return { ...item, output, status }\n const shell =\n /^Command running in background with ID: (\\w+)\\. Output is being written to: (.+?\\.output)\\./.exec(\n output\n )\n const monitor = /^Monitor started \\(task (\\w+),/.exec(output)\n const background: Background =\n shell !== null\n ? { ...item.background, taskId: shell[1], outputPath: shell[2] }\n : monitor !== null\n ? { ...item.background, taskId: monitor[1] }\n : item.background\n return {\n ...item,\n output,\n background,\n status: background.taskId !== null ? 'running' : status,\n }\n }\n case 'subagent':\n return {\n ...item,\n agentId: /agentId: (\\w+)/.exec(output)?.[1] ?? null,\n status: output.startsWith('Async agent launched') ? 'running' : status,\n }\n case 'web_search':\n return {\n ...item,\n output,\n status,\n results: [\n ...output.matchAll(/\"title\":\"((?:[^\"\\\\]|\\\\.)*)\",\"url\":\"([^\"]+)\"/g),\n ].map((match) => ({ title: match[1], url: match[2] })),\n }\n case 'question':\n return { ...item, answers: result.answers, status }\n case 'file_change':\n case 'skill':\n case 'tool':\n case 'agent_message':\n return { ...item, output, status } as Item\n default:\n return item\n }\n}\n\nfunction userText(value: string): {\n format: 'text' | 'command' | 'output'\n text: string\n} {\n const command = /<command-name>(.*?)<\\/command-name>/s.exec(value)\n if (command !== null) {\n const args = /<command-args>(.*?)<\\/command-args>/s.exec(value)\n return {\n format: 'command',\n text: `${command[1]} ${args?.[1] ?? ''}`.trim(),\n }\n }\n const output =\n /^<local-command-(?:stdout|stderr)>(.*)<\\/local-command-(?:stdout|stderr)>$/s.exec(\n value.trim()\n )\n if (output !== null) return { format: 'output', text: output[1] }\n return { format: 'text', text: value }\n}\n\nfunction text(value: unknown) {\n return typeof value === 'string' ? value : ''\n}\n","import { readdir, readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport {\n getSessionMessages,\n getSubagentMessages,\n type SessionMessage,\n type SessionStoreEntry,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Item, ServerEvent } from '@offsite/core/protocol'\nimport { readConfig } from '../../storage/config.ts'\nimport { runs } from '../live.ts'\nimport { contextTokens, type Message, toMessage } from './content.ts'\nimport { toItems } from './items.ts'\n\nasync function sessionFile(sessionId: string) {\n const projectsDir = path.join(readConfig().claudeBaseDir, 'projects')\n for (const dir of await readdir(projectsDir)) {\n const file = path.join(projectsDir, dir, `${sessionId}.jsonl`)\n try {\n return { file, stats: await stat(file) }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue\n throw error\n }\n }\n return null\n}\n\nasync function readSession(sessionId: string, file: string) {\n const text = await readFile(file, 'utf8')\n const entries = text.split('\\n').flatMap((line): SessionStoreEntry[] => {\n const entry = parseLine(line)\n return entry !== null && typeof entry.type === 'string'\n ? [{ ...entry, type: entry.type }]\n : []\n })\n const pages: { before: number; disk: SessionMessage[] }[] = []\n const seen = new Set<string>()\n let before: number | null = entries.length\n while (before !== null) {\n const kept = entries.slice(0, before)\n const disk = await getSessionMessages(sessionId, {\n sessionStore: { append: () => Promise.resolve(), load: async () => kept },\n })\n pages.push({ before, disk: disk.filter((item) => !seen.has(item.uuid)) })\n for (const item of disk) seen.add(item.uuid)\n before = compactedBefore(entries, disk[0]?.uuid)\n }\n return { entries, pages }\n}\n\nlet cached: {\n file: string\n mtimeMs: number\n size: number\n session: ReturnType<typeof readSession>\n} | null = null\n\nasync function loadSession(sessionId: string) {\n const found = await sessionFile(sessionId)\n if (found === null) return null\n if (\n cached !== null &&\n cached.file === found.file &&\n cached.mtimeMs === found.stats.mtimeMs &&\n cached.size === found.stats.size\n )\n return cached.session\n const session = readSession(sessionId, found.file)\n cached = {\n file: found.file,\n mtimeMs: found.stats.mtimeMs,\n size: found.stats.size,\n session,\n }\n return session\n}\n\nfunction messageTimes(entries: SessionStoreEntry[]) {\n const times = new Map<string, number>()\n for (const entry of entries)\n if (typeof entry.uuid === 'string' && typeof entry.timestamp === 'string')\n times.set(entry.uuid, Date.parse(entry.timestamp))\n return times\n}\n\nfunction toolOutputs(entries: SessionStoreEntry[]) {\n const outputs = new Map<string, unknown>()\n for (const entry of entries)\n if (typeof entry.uuid === 'string' && entry.toolUseResult !== undefined)\n outputs.set(entry.uuid, entry.toolUseResult)\n return outputs\n}\n\nfunction compactedBefore(\n entries: SessionStoreEntry[],\n uuid: string | undefined\n) {\n if (uuid === undefined) return null\n const start = entries.findIndex((entry) => entry.uuid === uuid)\n const index = entries.findLastIndex(\n (entry, position) =>\n position < start &&\n entry.type === 'system' &&\n entry.subtype === 'compact_boundary'\n )\n return index < 0 ? null : index\n}\n\nfunction parseLine(line: string): Record<string, unknown> | null {\n try {\n return JSON.parse(line) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nfunction mainMessages(disk: SessionMessage[], entries: SessionStoreEntry[]) {\n const times = messageTimes(entries)\n const outputs = toolOutputs(entries)\n return disk.flatMap((item): Message[] => {\n if (item.type === 'system' || item.parent_tool_use_id !== null) return []\n const message = toMessage(\n item.type,\n { ...item, tool_use_result: outputs.get(item.uuid) },\n times.get(item.uuid) ?? null\n )\n return [\n {\n ...message,\n content: message.content.map((block) =>\n block.type === 'image' ? { ...block, data: null } : block\n ),\n },\n ]\n })\n}\n\nexport async function image(sessionId: string, uuid: string, index: number) {\n const session = await loadSession(sessionId)\n if (session === null) throw new Error(`session ${sessionId} not found`)\n const item = session.pages\n .flatMap((page) => page.disk)\n .find((candidate) => candidate.uuid === uuid)\n if (item === undefined) throw new Error(`message ${uuid} not found`)\n if (item.type === 'system' || item.parent_tool_use_id !== null)\n throw new Error(`message ${uuid} has no image ${index}`)\n const block = toMessage(item.type, item, null).content.filter(\n (candidate) => candidate.type === 'image'\n )[index]\n if (block === undefined || block.data === null)\n throw new Error(`message ${uuid} has no image ${index}`)\n return { mediaType: block.mediaType, data: block.data }\n}\n\nexport async function history(\n sessionId: string,\n cwd: string\n): Promise<ServerEvent> {\n const found = runs.get(sessionId)\n const run = found?.provider === 'claude' ? found : undefined\n const [disk, session] = await Promise.all([\n getSessionMessages(sessionId, { dir: cwd }),\n loadSession(sessionId),\n ])\n const entries = session === null ? [] : session.entries\n const resumeAt = run?.resumeAt ?? null\n const kept =\n resumeAt === null\n ? disk\n : disk.slice(0, disk.findIndex((item) => item.uuid === resumeAt) + 1)\n const messages = mainMessages(kept, entries)\n const seen = new Set(messages.map((item) => item.uuid))\n const last = kept.findLast(\n (item) => item.type === 'assistant' && item.parent_tool_use_id === null\n )\n const tokens = last === undefined ? null : contextTokens(last.message)\n return {\n type: 'history',\n sessionId,\n provider: 'claude',\n items: toItems([\n ...messages,\n ...(run?.messages.filter((item) => !seen.has(item.uuid)) ?? []),\n ]),\n requests: [...(run?.pending.values() ?? [])].map((item) => item.request),\n queue: run?.queue ?? [],\n settings: run?.settings ?? null,\n context:\n run?.context ?? (tokens === null ? null : { tokens, window: null }),\n before: compactedBefore(entries, disk[0]?.uuid),\n partial: run?.partial ?? '',\n }\n}\n\nexport async function earlier(sessionId: string, before: number) {\n const session = await loadSession(sessionId)\n if (session === null) throw new Error(`session ${sessionId} not found`)\n const index = session.pages.findIndex((page) => page.before === before)\n if (index < 0) throw new Error(`no messages before entry ${before}`)\n const items = toItems([\n ...mainMessages(session.pages[index].disk, session.entries),\n { type: 'compaction', uuid: `compacted:${before}`, time: null },\n ])\n return { items, before: session.pages[index + 1]?.before ?? null }\n}\n\nexport async function agentMessages(\n sessionId: string,\n cwd: string,\n agentId: string,\n parent: string\n): Promise<Item[]> {\n if (!/^\\w+$/.test(agentId)) throw new Error(`invalid agent id ${agentId}`)\n const disk = await getSubagentMessages(sessionId, agentId, { dir: cwd })\n return toItems(\n disk.flatMap((item): Message[] =>\n item.type === 'system'\n ? []\n : [toMessage(item.type, { ...item, parent_tool_use_id: parent }, null)]\n )\n )\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n type PermissionResult,\n type PermissionUpdate,\n query,\n type Query,\n type SDKMessage,\n type SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type {\n Context,\n PermissionRequest,\n Prompt,\n Queued,\n Settings,\n TaskStatus,\n} from '@offsite/core/protocol'\nimport { broadcast, publish } from '../hub.ts'\nimport { broadcastActivity, runs } from '../live.ts'\nimport {\n claudeEffort,\n claudeMode,\n claudeOptions,\n recordLimit,\n} from './claude.ts'\nimport { contextTokens, type Message, toMessage } from './content.ts'\nimport { toItems, toRequest } from './items.ts'\n\nconst IDLE_LIMIT = 10 * 60 * 1000\nconst imageTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp']\n\ntype Pending = {\n request: PermissionRequest\n input: Record<string, unknown>\n suggestions: PermissionUpdate[]\n resolve: (result: PermissionResult) => void\n}\n\ntype ImageType = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp'\n\nexport class Run {\n readonly provider = 'claude'\n readonly sessionId: string\n readonly messages: Message[] = []\n readonly pending = new Map<string, Pending>()\n private readonly published = new Map<string, string>()\n readonly query: Query\n readonly closed: Promise<void>\n readonly resumeAt: string | null\n queue: Queued[] = []\n settings: Settings\n context: Context | null = null\n partial = ''\n private model: string | null = null\n running = false\n prompted = false\n backgroundTasks = 0\n tasks: Record<string, TaskStatus> = {}\n private readonly inbox: SDKUserMessage[] = []\n private wake: (() => void) | null = null\n private idleTimer: NodeJS.Timeout | undefined\n private stopping = false\n\n constructor(options: {\n sessionId: string\n cwd: string\n resume: boolean\n resumeAt: string | null\n settings: Settings\n }) {\n this.sessionId = options.sessionId\n this.resumeAt = options.resumeAt\n this.settings = options.settings\n const settings = options.settings\n this.query = query({\n prompt: this.input(),\n options: {\n ...claudeOptions(settings.accountId, options.cwd),\n ...(options.resume\n ? { resume: options.sessionId }\n : { sessionId: options.sessionId }),\n ...(options.resumeAt === null\n ? {}\n : { resumeSessionAt: options.resumeAt }),\n enableFileCheckpointing: true,\n ...(settings.mode === null\n ? {}\n : { permissionMode: claudeMode(settings.mode) }),\n ...(settings.model === null ? {} : { model: settings.model }),\n ...(settings.effort === null\n ? {}\n : { effort: claudeEffort(settings.effort) }),\n allowDangerouslySkipPermissions: true,\n includePartialMessages: true,\n canUseTool: (toolName, input, context) =>\n this.ask({\n toolName,\n input,\n title: context.title ?? null,\n suggestions: context.suggestions ?? [],\n signal: context.signal,\n }),\n },\n })\n runs.set(this.sessionId, this)\n this.closed = this.read()\n }\n\n submit(prompt: Prompt, delivery: 'queue' | 'steer') {\n if (!this.running) {\n this.push(prompt, undefined)\n return\n }\n switch (delivery) {\n case 'steer':\n this.push(prompt, 'next')\n return\n case 'queue':\n this.queue = [...this.queue, { id: randomUUID(), prompt }]\n this.publishQueue()\n }\n }\n\n unqueue(id: string) {\n this.queue = this.queue.filter((item) => item.id !== id)\n this.publishQueue()\n }\n\n steer(id: string) {\n const item = this.queue.find((queued) => queued.id === id)\n if (item === undefined) return\n this.unqueue(id)\n this.submit(item.prompt, 'steer')\n }\n\n async configure(settings: Settings) {\n if (settings.model !== this.settings.model)\n await this.query.setModel(settings.model ?? undefined)\n if (settings.effort !== this.settings.effort)\n await this.query.applyFlagSettings({\n effortLevel:\n settings.effort === null ? null : claudeEffort(settings.effort),\n })\n if (settings.mode !== null && settings.mode !== this.settings.mode)\n await this.query.setPermissionMode(claudeMode(settings.mode))\n this.updateSettings({\n ...settings,\n accountId: this.settings.accountId,\n mode: settings.mode ?? this.settings.mode,\n })\n }\n\n async interrupt() {\n await this.query.interrupt()\n }\n\n async stopTask(taskId: string) {\n await this.query.stopTask(taskId)\n }\n\n respond(\n requestId: string,\n decision: 'allow' | 'always' | 'deny',\n answers: Record<string, string> | null\n ) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n const input = pending.input\n switch (decision) {\n case 'allow':\n this.settle(requestId, {\n behavior: 'allow',\n updatedInput: answers === null ? input : { ...input, answers },\n })\n return\n case 'always':\n this.settle(requestId, {\n behavior: 'allow',\n updatedInput: input,\n updatedPermissions: pending.suggestions,\n })\n return\n case 'deny':\n this.settle(requestId, {\n behavior: 'deny',\n message: 'The user rejected this action',\n interrupt: true,\n })\n }\n }\n\n stop() {\n this.stopping = true\n runs.delete(this.sessionId)\n this.query.close()\n }\n\n private push(prompt: Prompt, priority: 'next' | undefined) {\n clearTimeout(this.idleTimer)\n for (const image of prompt.images)\n if (!imageTypes.includes(image.mediaType))\n throw new Error(`${image.mediaType} images are not supported`)\n const uuid = randomUUID()\n this.inbox.push({\n type: 'user',\n message: {\n role: 'user',\n content: [\n ...prompt.images.map((image) => ({\n type: 'image' as const,\n source: {\n type: 'base64' as const,\n media_type: image.mediaType as ImageType,\n data: image.data,\n },\n })),\n ...(prompt.text === ''\n ? []\n : [{ type: 'text' as const, text: prompt.text }]),\n ],\n },\n parent_tool_use_id: null,\n uuid,\n ...(priority === undefined ? {} : { priority }),\n })\n this.wake?.()\n this.add({\n type: 'user',\n uuid,\n time: Date.now(),\n content: [\n ...prompt.images.map((image) => ({ type: 'image' as const, ...image })),\n ...(prompt.text === ''\n ? []\n : [{ type: 'text' as const, text: prompt.text }]),\n ],\n parent: null,\n })\n this.running = true\n this.prompted = true\n broadcastActivity()\n }\n\n private publishContext() {\n publish(this.sessionId, {\n type: 'context',\n sessionId: this.sessionId,\n context: this.context,\n })\n }\n\n private async *input(): AsyncGenerator<SDKUserMessage> {\n while (true) {\n const next = this.inbox.shift()\n if (next !== undefined) {\n yield next\n continue\n }\n await new Promise<void>((resolve) => {\n this.wake = resolve\n })\n }\n }\n\n private async read() {\n try {\n for await (const message of this.query) this.receive(message)\n } catch (error) {\n if (!this.stopping)\n this.add(notice(error instanceof Error ? error.message : String(error)))\n }\n clearTimeout(this.idleTimer)\n for (const id of this.pending.keys())\n this.settle(id, { behavior: 'deny', message: 'Session ended' })\n if (runs.get(this.sessionId) === this) runs.delete(this.sessionId)\n this.running = false\n broadcastActivity()\n }\n\n private receive(message: SDKMessage) {\n switch (message.type) {\n case 'assistant': {\n if (message.parent_tool_use_id === null) this.partial = ''\n this.add(toMessage('assistant', message, Date.now()))\n const tokens = contextTokens(message.message)\n if (message.parent_tool_use_id === null && tokens !== null) {\n this.model = message.message.model\n this.context = { tokens, window: this.context?.window ?? null }\n }\n if (message.error === 'rate_limit')\n this.add(\n notice(\n 'This account hit its usage limit. Pick another account below and send again.'\n )\n )\n return\n }\n case 'user':\n if (message.isSynthetic) return\n this.add(\n toMessage(\n 'user',\n { ...message, uuid: message.uuid ?? randomUUID() },\n Date.now()\n )\n )\n return\n case 'stream_event':\n if (\n message.parent_tool_use_id === null &&\n message.event.type === 'content_block_delta' &&\n message.event.delta.type === 'text_delta'\n ) {\n this.partial += message.event.delta.text\n publish(this.sessionId, {\n type: 'delta',\n sessionId: this.sessionId,\n text: message.event.delta.text,\n })\n }\n return\n case 'rate_limit_event': {\n const accountId = this.settings.accountId\n if (accountId === null)\n throw new Error('Rate limit event for a run without an account')\n broadcast({\n type: 'limits',\n accountId,\n limits: recordLimit(accountId, message.rate_limit_info),\n })\n return\n }\n case 'result': {\n if (\n message.subtype !== 'success' &&\n message.terminal_reason !== 'aborted_streaming' &&\n message.terminal_reason !== 'aborted_tools'\n )\n this.add(\n notice(\n message.errors\n .filter((error) => !error.startsWith('[ede_diagnostic]'))\n .join('\\n') || message.subtype\n )\n )\n this.finishTurn()\n const usage =\n this.model === null ? undefined : message.modelUsage[this.model]\n if (this.context !== null && usage !== undefined)\n this.context = { ...this.context, window: usage.contextWindow }\n this.publishContext()\n return\n }\n case 'system':\n switch (message.subtype) {\n case 'init':\n clearTimeout(this.idleTimer)\n if (!this.running) this.prompted = false\n this.running = true\n broadcastActivity()\n this.updateSettings({\n ...this.settings,\n mode: message.permissionMode,\n })\n return\n case 'background_tasks_changed': {\n const live = message.tasks.filter((task) => task.ambient !== true)\n this.backgroundTasks = live.length\n this.tasks = {\n ...Object.fromEntries(\n Object.entries(this.tasks).filter(\n ([, status]) => status !== 'running'\n )\n ),\n ...Object.fromEntries(\n live.map((task) => [task.task_id, 'running' as const])\n ),\n }\n broadcastActivity()\n this.armIdleTimer()\n return\n }\n case 'task_notification':\n if (message.ambient === true) return\n this.tasks = { ...this.tasks, [message.task_id]: message.status }\n broadcastActivity()\n return\n case 'status':\n if (message.permissionMode !== undefined)\n this.updateSettings({\n ...this.settings,\n mode: message.permissionMode,\n })\n return\n case 'compact_boundary': {\n const tokens = message.compact_metadata.post_tokens\n this.context =\n tokens === undefined\n ? null\n : { tokens, window: this.context?.window ?? null }\n this.publishContext()\n this.add({\n type: 'compaction',\n uuid: message.uuid,\n time: Date.now(),\n })\n return\n }\n case 'local_command_output':\n this.add({\n type: 'notice',\n uuid: message.uuid,\n time: Date.now(),\n text: message.content,\n isError: false,\n })\n }\n }\n }\n\n private finishTurn() {\n this.partial = ''\n const [next, ...rest] = this.queue\n if (next !== undefined) {\n this.queue = rest\n this.publishQueue()\n this.push(next.prompt, undefined)\n return\n }\n this.running = false\n broadcastActivity()\n this.armIdleTimer()\n }\n\n private armIdleTimer() {\n clearTimeout(this.idleTimer)\n if (this.running || this.backgroundTasks > 0) return\n this.idleTimer = setTimeout(() => {\n if (!this.running && this.pending.size === 0) this.stop()\n }, IDLE_LIMIT)\n }\n\n private ask(options: {\n toolName: string\n input: Record<string, unknown>\n title: string | null\n suggestions: PermissionUpdate[]\n signal: AbortSignal\n }) {\n const request = toRequest({\n id: randomUUID(),\n toolName: options.toolName,\n input: options.input,\n title: options.title,\n canAlwaysAllow: options.suggestions.length > 0,\n })\n return new Promise<PermissionResult>((resolve) => {\n this.pending.set(request.id, {\n request,\n input: options.input,\n suggestions: options.suggestions,\n resolve,\n })\n publish(this.sessionId, {\n type: 'request',\n sessionId: this.sessionId,\n request,\n })\n broadcastActivity()\n options.signal.addEventListener('abort', () =>\n this.settle(request.id, { behavior: 'deny', message: 'Cancelled' })\n )\n })\n }\n\n private settle(requestId: string, result: PermissionResult) {\n const pending = this.pending.get(requestId)\n if (pending === undefined) return\n this.pending.delete(requestId)\n pending.resolve(result)\n publish(this.sessionId, {\n type: 'requestDone',\n sessionId: this.sessionId,\n requestId,\n })\n broadcastActivity()\n }\n\n private add(message: Message) {\n if (this.messages.some((item) => item.uuid === message.uuid)) return\n this.messages.push(message)\n const items = toItems(this.messages).filter((item) => {\n const json = JSON.stringify(item)\n if (this.published.get(item.id) === json) return false\n this.published.set(item.id, json)\n return true\n })\n if (items.length === 0) return\n publish(this.sessionId, {\n type: 'items',\n sessionId: this.sessionId,\n items,\n })\n }\n\n private updateSettings(settings: Settings) {\n this.settings = settings\n publish(this.sessionId, {\n type: 'settings',\n sessionId: this.sessionId,\n settings,\n })\n }\n\n private publishQueue() {\n publish(this.sessionId, {\n type: 'queue',\n sessionId: this.sessionId,\n queue: this.queue,\n })\n }\n}\n\nfunction notice(text: string): Message {\n return {\n type: 'notice',\n uuid: randomUUID(),\n time: Date.now(),\n text,\n isError: true,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { query } from '@anthropic-ai/claude-agent-sdk'\nimport type { GitStatus, Provider } from '@offsite/core/protocol'\nimport { claudeOptions } from '../lib/claude/index.ts'\nimport { codexCommitMessage } from '../lib/codex/index.ts'\nimport { openCodeCommitMessage } from '../lib/opencode/index.ts'\nimport { readConfig } from '../storage/config.ts'\nimport { providerName } from './accounts.ts'\n\nconst DIFF_LIMIT = 80_000\nconst UNTRACKED_LIMIT = 100\nconst NEW_FILE_LIMIT = 256 * 1024\nconst REPO_DEPTH = 3\n\nexport async function gitStatus(cwd: string): Promise<GitStatus | null> {\n let output\n try {\n output = await git(cwd, ['status', '--porcelain=v2', '--branch'])\n } catch {\n return null\n }\n const status: GitStatus = {\n branch: null,\n upstream: null,\n ahead: 0,\n behind: 0,\n changed: 0,\n }\n for (const line of output.stdout.split('\\n').filter(Boolean)) {\n const [marker, key, ...rest] = line.split(' ')\n if (marker !== '#') status.changed++\n else if (key === 'branch.head')\n status.branch = rest[0] === '(detached)' ? null : rest[0]\n else if (key === 'branch.upstream') status.upstream = rest[0]\n else if (key === 'branch.ab') {\n status.ahead = Number(rest[0])\n status.behind = -Number(rest[1])\n }\n }\n return status\n}\n\nexport async function commit(cwd: string, message: string) {\n if (message.trim() === '') throw new Error('Write a commit message first')\n await git(cwd, ['add', '--all'])\n await git(cwd, ['commit', '--message', message])\n return gitStatus(cwd)\n}\n\nexport async function push(cwd: string) {\n const status = await gitStatus(cwd)\n if (status === null) throw new Error(`${cwd} is not a git repository`)\n if (status.upstream === null)\n await git(cwd, ['push', '--set-upstream', 'origin', 'HEAD'])\n else await git(cwd, ['push'])\n return gitStatus(cwd)\n}\n\nexport async function createPullRequest(cwd: string) {\n const { stdout } = await promisify(execFile)(\n 'gh',\n ['pr', 'create', '--fill'],\n { cwd }\n )\n const url = stdout.trim().split('\\n').at(-1)\n if (url === undefined) throw new Error('gh did not return a pull request URL')\n return { url }\n}\n\nexport async function suggestCommitMessage(\n provider: Provider,\n accountId: string | null,\n cwd: string\n) {\n const diff = (await workingDiff(cwd)).slice(0, DIFF_LIMIT)\n if (diff === '') throw new Error('There is nothing to commit')\n const model = readConfig().commitModels[provider]\n if (model === null)\n throw new Error(\n `Choose a ${providerName(provider)} commit model in Settings → Accounts`\n )\n const prompt = `Write a git commit message for this diff. Reply with only the message: a short summary line, optionally followed by a blank line and a brief body.\\n\\n${diff}`\n if (provider === 'codex')\n return codexCommitMessage(accountId, cwd, model, prompt)\n if (provider === 'opencode') return openCodeCommitMessage(cwd, model, prompt)\n const conversation = query({\n prompt,\n options: {\n ...claudeOptions(accountId, cwd),\n systemPrompt: 'You write concise git commit messages.',\n tools: [],\n model,\n maxTurns: 1,\n persistSession: false,\n },\n })\n for await (const message of conversation) {\n if (message.type !== 'result') continue\n if (message.subtype !== 'success')\n throw new Error(message.errors.join('\\n'))\n if (message.is_error) throw new Error(message.result)\n return { message: message.result.trim() }\n }\n throw new Error('Claude did not reply')\n}\n\nasync function workingDiff(cwd: string) {\n if (!(await isRepo(cwd))) throw new Error(`${cwd} is not a git repository`)\n return repoDiff(cwd, '')\n}\n\nexport async function projectDiff(cwd: string) {\n if (await isRepo(cwd)) return repoDiff(cwd, '')\n const repos = childRepos(cwd, '', REPO_DEPTH)\n if (repos.length === 0)\n throw new Error(`${cwd} is not a git repository and has none inside it`)\n const diffs = await Promise.all(\n repos.map((repo) => repoDiff(path.join(cwd, repo), `${repo}/`))\n )\n return diffs.join('')\n}\n\nexport function git(cwd: string, args: string[]) {\n return promisify(execFile)('git', args, {\n cwd,\n maxBuffer: 64 * 1024 * 1024,\n })\n}\n\nasync function isRepo(cwd: string) {\n try {\n await git(cwd, ['rev-parse', '--is-inside-work-tree'])\n return true\n } catch {\n return false\n }\n}\n\nasync function repoDiff(repo: string, prefix: string) {\n const tracked = await git(repo, [\n 'diff',\n await diffBase(repo),\n '--no-color',\n '--no-ext-diff',\n `--src-prefix=a/${prefix}`,\n `--dst-prefix=b/${prefix}`,\n ])\n const untracked = await git(repo, [\n 'ls-files',\n '--others',\n '--exclude-standard',\n ])\n const added = untracked.stdout\n .split('\\n')\n .filter(Boolean)\n .slice(0, UNTRACKED_LIMIT)\n .map((file) => newFilePatch(repo, file, prefix))\n return [tracked.stdout, ...added].join('')\n}\n\nasync function diffBase(repo: string) {\n try {\n await git(repo, ['rev-parse', '--verify', '--quiet', 'HEAD'])\n return 'HEAD'\n } catch (error) {\n if (!(error instanceof Error && 'code' in error && error.code === 1))\n throw error\n }\n const empty = await git(repo, ['hash-object', '-t', 'tree', '/dev/null'])\n return empty.stdout.trim()\n}\n\nfunction childRepos(root: string, dir: string, depth: number): string[] {\n if (depth === 0) return []\n let entries\n try {\n entries = readdirSync(path.join(root, dir), { withFileTypes: true })\n } catch {\n return []\n }\n return entries\n .filter(\n (entry) =>\n entry.isDirectory() &&\n !entry.name.startsWith('.') &&\n entry.name !== 'node_modules'\n )\n .flatMap((entry) => {\n const relative = dir === '' ? entry.name : `${dir}/${entry.name}`\n return existsSync(path.join(root, relative, '.git'))\n ? [relative]\n : childRepos(root, relative, depth - 1)\n })\n}\n\nfunction newFilePatch(cwd: string, file: string, prefix: string) {\n const name = `${prefix}${file}`\n const header = `diff --git a/${name} b/${name}\\nnew file\\n--- /dev/null\\n+++ b/${name}\\n`\n const full = path.join(cwd, file)\n if (statSync(full).size > NEW_FILE_LIMIT)\n return `${header}Binary or large file\\n`\n const content = readFileSync(full, 'utf8')\n if (content.includes('\\0')) return `${header}Binary or large file\\n`\n const lines = content.split('\\n')\n if (lines.at(-1) === '') lines.pop()\n return `${header}@@ -0,0 +1,${lines.length} @@\\n${lines.map((line) => `+${line}\\n`).join('')}`\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { lstat, open } from 'node:fs/promises'\nimport path from 'node:path'\nimport type { FilePreview } from '@offsite/core/protocol'\nimport { home } from '../storage/storage.ts'\nimport { git } from './git.ts'\n\nconst FILE_LIMIT = 20_000\nconst OUTPUT_LIMIT = 256 * 1024\nconst READ_LIMIT = 1024 * 1024\nconst images = new Map([\n ['.png', 'image/png'],\n ['.jpg', 'image/jpeg'],\n ['.jpeg', 'image/jpeg'],\n ['.gif', 'image/gif'],\n ['.webp', 'image/webp'],\n ['.svg', 'image/svg+xml'],\n])\nconst skipped = new Set(['node_modules', '.git', 'dist', 'target', '.next'])\n\nexport async function listFiles(cwd: string) {\n try {\n const { stdout } = await git(cwd, [\n 'ls-files',\n '--cached',\n '--others',\n '--exclude-standard',\n ])\n return stdout.split('\\n').filter(Boolean).slice(0, FILE_LIMIT)\n } catch {\n return walk(cwd)\n }\n}\n\nexport function readProjectFile(cwd: string, file: string): FilePreview {\n const root = realpathSync(cwd)\n const full = realpathSync(path.resolve(root, file))\n const relative = path.relative(root, full)\n if (\n relative === '..' ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n )\n throw new Error(`${file} is outside the project`)\n const stats = statSync(full)\n if (!stats.isFile()) throw new Error(`${file} is not a file`)\n if (stats.size > READ_LIMIT)\n return { kind: 'large', size: stats.size, limit: READ_LIMIT }\n const data = readFileSync(full)\n const mediaType = images.get(path.extname(full).toLowerCase())\n if (mediaType !== undefined)\n return {\n kind: 'image',\n size: stats.size,\n mediaType,\n data: data.toString('base64'),\n }\n if (data.includes(0)) return { kind: 'binary', size: stats.size }\n return { kind: 'text', size: stats.size, content: data.toString('utf8') }\n}\n\nexport function saveUpload(name: string, data: Buffer) {\n const dir = path.join(home, 'uploads', randomUUID())\n mkdirSync(dir, { recursive: true })\n const file = path.join(dir, path.basename(name))\n writeFileSync(file, data)\n return file\n}\n\nexport async function taskOutput(sessionId: string, file: string) {\n const tasks = path.dirname(file)\n if (\n !/^[\\w-]+$/.test(sessionId) ||\n !path.isAbsolute(file) ||\n path.normalize(file) !== file ||\n !/^\\w+\\.output$/.test(path.basename(file)) ||\n path.basename(tasks) !== 'tasks' ||\n path.basename(path.dirname(tasks)) !== sessionId\n )\n throw new Error('Not a background task output file of this thread')\n let stats\n try {\n stats = await lstat(file)\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT')\n return null\n throw error\n }\n if (!stats.isFile())\n throw new Error('Background task output is not a regular file')\n const start = Math.max(0, stats.size - OUTPUT_LIMIT)\n const handle = await open(file, 'r')\n try {\n const buffer = Buffer.alloc(stats.size - start)\n const read = await handle.read(buffer, 0, buffer.length, start)\n return {\n text: buffer.subarray(0, read.bytesRead).toString('utf8'),\n truncated: start > 0,\n }\n } finally {\n await handle.close()\n }\n}\n\nfunction walk(root: string) {\n const files: string[] = []\n const pending = ['']\n while (pending.length > 0 && files.length < FILE_LIMIT) {\n const dir = pending.pop() ?? ''\n let entries\n try {\n entries = readdirSync(path.join(root, dir), { withFileTypes: true })\n } catch {\n continue\n }\n for (const entry of entries) {\n const relative = dir === '' ? entry.name : `${dir}/${entry.name}`\n if (entry.isDirectory() && !skipped.has(entry.name))\n pending.push(relative)\n if (entry.isFile()) files.push(relative)\n }\n }\n return files\n}\n","import { randomUUID } from 'node:crypto'\nimport { renameSync } from 'node:fs'\nimport path from 'node:path'\nimport type { PushSubscriptionInfo, TerminalPush } from '@offsite/core/protocol'\nimport webPush from 'web-push'\nimport { home, readJson, writeJson } from '../storage/storage.ts'\n\ntype Subscription = {\n endpoint: string\n keys: { p256dh: string; auth: string }\n server: string | null\n}\n\ntype Store = {\n publicKey: string\n privateKey: string\n subscriptions: Subscription[]\n}\n\nconst pushFile = path.join(home, 'push.json')\nconst TITLE_LIMIT = 100\nconst BODY_LIMIT = 500\nconst TIME_TO_LIVE = 15 * 60\nconst SEND_TIMEOUT = 10_000\nconst SUBJECT = 'https://github.com/NazmusSayad/offsite'\n\nlet server = ''\nlet active = false\n\nexport function startPush(address: string) {\n server = address\n try {\n const store = readJson('push.json') as Store | null\n if (store !== null) track(store)\n } catch (error) {\n console.warn(\n `push notifications are off until a browser turns them on again, could not read ${pushFile}: ${error}`\n )\n }\n}\n\nexport function pushActive() {\n return active\n}\n\nexport function pushKey() {\n return { publicKey: read().publicKey }\n}\n\nexport function subscribe(subscription: PushSubscriptionInfo) {\n const endpoint = new URL(subscription.endpoint)\n if (endpoint.protocol !== 'https:')\n throw new Error('the endpoint must be an https URL')\n update((store) => {\n store.subscriptions = store.subscriptions.filter(\n (existing) => existing.endpoint !== subscription.endpoint\n )\n store.subscriptions.push({\n endpoint: subscription.endpoint,\n keys: { p256dh: subscription.keys.p256dh, auth: subscription.keys.auth },\n server,\n })\n })\n console.log('a browser subscribed to push notifications')\n}\n\nexport function unsubscribe(endpoint: string) {\n update((store) => {\n store.subscriptions = store.subscriptions.filter(\n (existing) => existing.endpoint !== endpoint\n )\n })\n console.log('a browser unsubscribed from push notifications')\n}\n\nexport async function sendPush(message: TerminalPush) {\n let store: Store\n try {\n store = read()\n } catch (error) {\n console.error(`could not read push subscriptions: ${error}`)\n return\n }\n const subscriptions = store.subscriptions.filter(ours)\n if (subscriptions.length === 0) return\n const payload = JSON.stringify({\n ...message,\n title: [...message.title].slice(0, TITLE_LIMIT).join(''),\n body: [...message.body].slice(0, BODY_LIMIT).join(''),\n })\n const gone: string[] = []\n await Promise.all(\n subscriptions.map(async (subscription) => {\n try {\n await webPush.sendNotification(subscription, payload, {\n vapidDetails: {\n subject: SUBJECT,\n publicKey: store.publicKey,\n privateKey: store.privateKey,\n },\n TTL: TIME_TO_LIVE,\n urgency: 'high',\n timeout: SEND_TIMEOUT,\n })\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode\n if (status !== undefined && [401, 403, 404, 410].includes(status)) {\n console.log(\n `push subscription ${subscription.endpoint} is gone or was made for another key, removing it`\n )\n gone.push(subscription.endpoint)\n return\n }\n console.warn(\n `could not send a push to ${subscription.endpoint}: ${error}`\n )\n }\n })\n )\n if (gone.length === 0) return\n try {\n update((current) => {\n current.subscriptions = current.subscriptions.filter(\n (subscription) => !gone.includes(subscription.endpoint)\n )\n })\n } catch (error) {\n console.error(`could not remove gone push subscriptions: ${error}`)\n }\n}\n\nfunction ours(subscription: Subscription) {\n return subscription.server === server\n}\n\nfunction track(store: Store) {\n active = store.subscriptions.some(ours)\n}\n\nfunction load(): Store {\n let store: Store | null\n try {\n store = readJson('push.json') as Store | null\n } catch (error) {\n if (!(error instanceof SyntaxError)) throw error\n return replaceCorrupt(error)\n }\n if (store === null) return create()\n if (\n typeof store.publicKey !== 'string' ||\n typeof store.privateKey !== 'string' ||\n !Array.isArray(store.subscriptions)\n )\n return replaceCorrupt(new Error('it is missing its keys or subscriptions'))\n return store\n}\n\nfunction replaceCorrupt(error: Error) {\n const aside = `${pushFile}.corrupt-${randomUUID()}`\n renameSync(pushFile, aside)\n console.warn(\n `${pushFile} is corrupt, moved it to ${aside} and created a new one: ${error}`\n )\n return create()\n}\n\nfunction create(): Store {\n const keys = webPush.generateVAPIDKeys()\n const store = { ...keys, subscriptions: [] }\n save(store)\n return store\n}\n\nfunction save(store: Store) {\n writeJson('push.json', store)\n}\n\nfunction read() {\n const store = load()\n track(store)\n return store\n}\n\nfunction update(change: (store: Store) => void) {\n const store = load()\n change(store)\n save(store)\n track(store)\n}\n","import { randomUUID } from 'node:crypto'\nimport { statSync } from 'node:fs'\nimport { getSessionMessages } from '@anthropic-ai/claude-agent-sdk'\nimport type {\n Methods,\n Rewind,\n RewindResult,\n Settings,\n} from '@offsite/core/protocol'\nimport { history, Run } from '../lib/claude/index.ts'\nimport {\n stopAppServers,\n CodexRun,\n codexHistory,\n revertThread,\n} from '../lib/codex/index.ts'\nimport { type Client, publish } from '../lib/hub.ts'\nimport { runs } from '../lib/live.ts'\nimport {\n OpenCodeRun,\n openCodeHistory,\n rewindOpenCode,\n} from '../lib/opencode/index.ts'\nimport { providerName } from './accounts.ts'\nimport { providerOf, recordInteraction } from './sessions.ts'\n\nconst locks = new Map<string, Promise<void>>()\n\nexport function stopAll() {\n for (const run of runs.values()) run.stop()\n stopAppServers()\n}\n\nfunction sessionHistory(sessionId: string, cwd: string) {\n switch (providerOf(sessionId)) {\n case 'claude':\n return history(sessionId, cwd)\n case 'codex':\n return codexHistory(sessionId)\n case 'opencode':\n return openCodeHistory(sessionId, cwd)\n }\n}\n\nexport function rewind(request: Rewind): Promise<RewindResult> {\n return locked(request.sessionId, () => rewindNow(request))\n}\n\nasync function rewindNow(request: Rewind): Promise<RewindResult> {\n const sessionId = request.sessionId\n if (runs.get(sessionId)?.running === true)\n throw new Error('Stop Claude before rewinding')\n if ((runs.get(sessionId)?.backgroundTasks ?? 0) > 0)\n throw new Error('Wait for background tasks to finish before rewinding')\n const run = await runFor(sessionId, request.cwd, request.settings)\n if (run.provider === 'codex') {\n if (request.code) throw new Error('Codex cannot restore files')\n if (request.dryRun || !request.conversation) return null\n await revertThread(sessionId, request.messageId)\n run.items.clear()\n publish(sessionId, await codexHistory(sessionId))\n return null\n }\n if (run.provider === 'opencode') {\n const result = await rewindOpenCode(request)\n if (request.dryRun) return result\n run.items.clear()\n publish(sessionId, await openCodeHistory(sessionId, request.cwd))\n return result\n }\n let result: RewindResult = null\n if (request.code) {\n const files = await run.query.rewindFiles(request.messageId, {\n dryRun: request.dryRun,\n })\n if (!files.canRewind)\n throw new Error(files.error ?? 'The files cannot be restored')\n result = {\n files: files.filesChanged ?? [],\n insertions: files.insertions ?? 0,\n deletions: files.deletions ?? 0,\n }\n }\n if (request.dryRun || !request.conversation) return result\n const disk = await getSessionMessages(sessionId, { dir: request.cwd })\n const index = disk.findIndex((item) => item.uuid === request.messageId)\n if (index < 1) throw new Error('Cannot rewind the conversation to that point')\n run.stop()\n await run.closed\n new Run({\n sessionId,\n cwd: request.cwd,\n resume: true,\n resumeAt: disk[index - 1].uuid,\n settings: request.settings,\n })\n publish(sessionId, await history(sessionId, request.cwd))\n return result\n}\n\nexport async function open(client: Client, sessionId: string, cwd: string) {\n client.opening = sessionId\n const event = await sessionHistory(sessionId, cwd)\n if (client.opening !== sessionId) return\n client.sessionId = sessionId\n client.send(event)\n}\n\nexport async function send(\n client: Client,\n request: Methods['sessions.send']['params']\n) {\n if (!statSync(request.cwd, { throwIfNoEntry: false })?.isDirectory())\n throw new Error(`${request.cwd} is not a folder`)\n if (request.sessionId === null) {\n const run = await startRun(request.cwd, request.settings)\n const sessionId = run.sessionId\n client.opening = sessionId\n client.sessionId = sessionId\n client.send({ type: 'started', sessionId, cwd: request.cwd })\n await run.submit(request.prompt, request.delivery)\n recordInteraction(sessionId)\n return\n }\n const sessionId = request.sessionId\n await locked(sessionId, () => sendExisting(client, sessionId, request))\n}\n\nasync function sendExisting(\n client: Client,\n sessionId: string,\n request: Methods['sessions.send']['params']\n) {\n const provider = providerOf(sessionId)\n if (request.settings.provider !== provider)\n throw new Error(`This session belongs to ${providerName(provider)}`)\n const existing = runs.get(sessionId)\n if (\n existing?.provider === 'claude' &&\n !existing.running &&\n existing.backgroundTasks === 0 &&\n (await changedElsewhere(existing, request.cwd))\n ) {\n existing.stop()\n await existing.closed\n }\n const run = await runFor(sessionId, request.cwd, request.settings)\n if (run === existing) await run.configure(request.settings)\n else await open(client, sessionId, request.cwd)\n await run.submit(request.prompt, request.delivery)\n recordInteraction(sessionId)\n}\n\nasync function locked<T>(sessionId: string, task: () => Promise<T>) {\n const previous = locks.get(sessionId) ?? Promise.resolve()\n const result = previous.then(task)\n const done = result.then(\n () => undefined,\n () => undefined\n )\n locks.set(sessionId, done)\n await done\n if (locks.get(sessionId) === done) locks.delete(sessionId)\n return result\n}\n\nasync function runFor(sessionId: string, cwd: string, settings: Settings) {\n const run = runs.get(sessionId)\n if (run !== undefined && run.settings.accountId === settings.accountId)\n return run\n if (run !== undefined) {\n if (run.running)\n throw new Error('Wait for this turn to finish before switching accounts')\n if (run.backgroundTasks > 0)\n throw new Error(\n 'Wait for background tasks to finish before switching accounts'\n )\n run.stop()\n await run.closed\n }\n switch (settings.provider) {\n case 'claude':\n return new Run({ sessionId, cwd, resume: true, resumeAt: null, settings })\n case 'codex':\n return CodexRun.resume(sessionId, cwd, settings)\n case 'opencode':\n return OpenCodeRun.resume(sessionId, cwd, settings)\n }\n}\n\nasync function startRun(cwd: string, settings: Settings) {\n switch (settings.provider) {\n case 'claude':\n return new Run({\n sessionId: randomUUID(),\n cwd,\n resume: false,\n resumeAt: null,\n settings,\n })\n case 'codex':\n return CodexRun.start(cwd, settings)\n case 'opencode':\n return OpenCodeRun.start(cwd, settings)\n }\n}\n\nasync function changedElsewhere(run: Run, cwd: string) {\n if (run.messages.length === 0) return false\n const history = await getSessionMessages(run.sessionId, { dir: cwd })\n const last = history.at(-1)?.uuid\n return last !== undefined && !run.messages.some((item) => item.uuid === last)\n}\n","import type { Platform } from './protocol.ts'\n\nfunction zshOptionsSupported(options: string[]) {\n for (let position = 0; position < options.length; position++) {\n const word = options[position]\n if (!word.startsWith('-') && !word.startsWith('+')) return false\n const enable = word.startsWith('-')\n const flags = word.slice(1)\n if (flags === '' || flags === '-') return false\n if (flags.startsWith('-')) {\n if (!zshOptionAllowed(flags.slice(1), enable)) return false\n continue\n }\n for (let index = 0; index < flags.length; index++) {\n const letter = flags[index]\n if (letter === 'o') {\n let name = flags.slice(index + 1)\n if (name === '') {\n position++\n if (position === options.length) return false\n name = options[position]\n }\n if (!zshOptionAllowed(name, enable)) return false\n break\n }\n if (letter === 'b' || letter === 'c') return false\n if (enable && 'dfnprvx'.includes(letter)) return false\n if (!enable && letter === 'i') return false\n }\n }\n return true\n}\n\nfunction zshOptionAllowed(option: string, enable: boolean) {\n let name = option.toLowerCase().replace(/[-_]/g, '')\n let value = enable\n if (name.startsWith('no')) {\n name = name.slice(2)\n value = !enable\n }\n if (['rcs', 'globalrcs', 'interactive', 'exec'].includes(name)) return value\n if (\n ['privileged', 'restricted', 'sourcetrace', 'verbose', 'xtrace'].includes(\n name\n )\n )\n return !value\n return true\n}\n\nexport function shellIntegrationIssue(\n command: string | null,\n platform: Platform,\n defaultShell: string\n) {\n if (platform === 'windows') return 'Not available on Windows'\n if (command !== null && /[\\n\"'\\\\$`;&|<>()*?[\\]{}#!]/.test(command))\n return 'Not available for commands with shell syntax'\n const words =\n command === null\n ? [defaultShell]\n : command.split(/[ \\t]/).filter((word) => word !== '')\n if (words.length === 0) return 'Available for bash, zsh and fish'\n const path = words[0]\n const name = path.split('/').pop()\n const options = words.slice(1)\n if (name === 'bash') {\n if (platform === 'macos' && (path === '/bin/bash' || !path.includes('/')))\n return 'Needs a newer bash than the one macOS includes'\n if (options.every((option) => ['-l', '--login', '-i'].includes(option)))\n return null\n return 'Not available with these bash options'\n }\n if (name === 'zsh') {\n if (zshOptionsSupported(options)) return null\n return 'Not available with these zsh options'\n }\n if (name === 'fish') {\n const supported = options.every((option) => {\n if (option.startsWith('--')) {\n const name = option.slice(2).split('=')[0]\n return (\n name === '' ||\n !['command', 'no-config', 'no-execute'].some((long) =>\n long.startsWith(name)\n )\n )\n }\n return !(option.startsWith('-') && /[cNn]/.test(option))\n })\n if (supported) return null\n return 'Not available with these fish options'\n }\n return 'Available for bash, zsh and fish'\n}\n","import {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { shellIntegrationIssue } from '@offsite/core/shell-check'\nimport { serverDir } from '../../args.ts'\nimport { platform } from '../../storage/config.ts'\nimport { home } from '../../storage/storage.ts'\n\nconst scripts = path.join(\n serverDir,\n 'src',\n 'services',\n 'terminal',\n 'shell-integration'\n)\nconst folder = path.join(home, 'shell-integration')\n\nexport function prepare(\n env: Record<string, string>,\n command: string | null,\n shell: string\n) {\n if (shellIntegrationIssue(command, platform(), shell) !== null) return null\n const words =\n command === null\n ? [shell]\n : command.split(/[ \\t]/).filter((word) => word !== '')\n const program = command === null ? `'${shell}'` : words[0]\n const args = words.slice(1)\n const name = words[0].split('/').pop()\n let integration: string\n if (name === 'bash') {\n const userHome = process.env.HOME\n if (userHome === undefined || userHome === '') return null\n const script = path.join(folder, 'bash', 'offsite.bash')\n if (!writeScript(script, 'bash/offsite.bash')) return null\n env.ENV = script.replace(/[\\\\$`\"]/g, (character) => `\\\\${character}`)\n env.HISTFILE = path.join(userHome, '.bash_history')\n integration = ' --posix'\n } else if (name === 'zsh') {\n if (!zshGlobalsSupported()) return null\n if (\n ['.zshenv', '.zprofile', '.zshrc', '.zlogin'].every(\n (file) => !existsSync(path.join(os.homedir(), file))\n )\n )\n return null\n if (!writeScript(path.join(folder, 'zsh', '.zshenv'), 'zsh/.zshenv'))\n return null\n env.ZDOTDIR = path.join(folder, 'zsh')\n integration = ''\n } else if (name === 'fish') {\n const script = path.join(folder, 'fish', 'offsite.fish')\n if (!writeScript(script, 'fish/offsite.fish')) return null\n const source = `source '${script.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}'`\n integration = ` --init-command '${source.replaceAll(\"'\", \"'\\\\''\")}'`\n } else throw new Error(`shell integration does not support ${name}`)\n return [`${program}${integration}`, ...args].join(' ')\n}\n\nfunction zshGlobalsSupported() {\n for (const global of ['/etc/zshenv', '/etc/zsh/zshenv']) {\n let contents: string\n try {\n contents = readFileSync(global, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue\n console.warn(\n `could not read ${global}, zsh starts without shell integration: ${error}`\n )\n return false\n }\n for (const rawLine of contents.split('\\n')) {\n const line = rawLine.trimStart()\n if (line.startsWith('#')) continue\n const normalized = line.toLowerCase().replaceAll('_', '')\n if (\n [\n 'zdotdir',\n 'rcs',\n 'emulate',\n 'debug',\n 'xtrace',\n 'verbose',\n 'sourcetrace',\n ].some((word) => normalized.includes(word))\n )\n return false\n let setting = false\n for (const word of line.split(/[ \\t;&|]/)) {\n if (word === '') continue\n if (['set', 'setopt', 'unsetopt'].includes(word)) {\n setting = true\n continue\n }\n const flag = word.startsWith('-') || word.startsWith('+')\n if (setting && flag && /[fxv]/.test(word)) return false\n if (!flag) setting = false\n }\n }\n }\n return true\n}\n\nfunction writeScript(target: string, source: string) {\n try {\n const contents = readFileSync(path.join(scripts, source), 'utf8')\n const existing = lstatSync(target, { throwIfNoEntry: false })\n if (existing?.isFile() && readFileSync(target, 'utf8') === contents)\n return true\n mkdirSync(path.dirname(target), { recursive: true })\n rmSync(`${target}.tmp`, { force: true })\n writeFileSync(`${target}.tmp`, contents, { flag: 'wx' })\n renameSync(`${target}.tmp`, target)\n return true\n } catch (error) {\n console.warn(\n `could not write ${target}, the shell starts without shell integration: ${error}`\n )\n return false\n }\n}\n","import { execFile } from 'node:child_process'\nimport { readFileSync, realpathSync, statSync } from 'node:fs'\nimport { readFile, readlink } from 'node:fs/promises'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { spawn } from '@lydell/node-pty'\nimport {\n defaultShell,\n platform,\n readConfig,\n version,\n} from '../../storage/config.ts'\nimport { prepare } from './shell-integration.ts'\n\nconst run = promisify(execFile)\nconst iterm2Version = '3.6.8'\nconst ghosttyVersion = '1.3.1'\nconst shellNames =\n process.platform === 'win32'\n ? ['pwsh', 'powershell', 'cmd']\n : ['zsh', 'bash', 'fish', 'pwsh']\n\nexport function startShell(cwd: string) {\n const options = launch()\n const env: Record<string, string> = {}\n let file: string\n let args: string[]\n if (process.platform === 'win32') {\n Object.assign(env, process.env)\n file = options.command ?? defaultShell()\n args = []\n } else {\n for (const name of ['HOME', 'USER', 'LOGNAME', 'TMPDIR', 'SSH_AUTH_SOCK']) {\n const value = process.env[name]\n if (value !== undefined) env[name] = value\n }\n const shell = defaultShell()\n env.SHELL = shell\n env.LANG = 'en_US.UTF-8'\n if (process.env.PATH !== undefined) env.PATH = process.env.PATH\n const program =\n (options.shellIntegration\n ? prepare(env, options.command, shell)\n : null) ??\n options.command ??\n `'${shell}'`\n file = '/bin/bash'\n args = ['--noprofile', '--norc', '-c', `export -n PATH; exec -l ${program}`]\n }\n env.TERM = 'xterm-256color'\n env.COLORTERM = 'truecolor'\n Object.assign(env, options.environment)\n return spawn(file, args, {\n name: 'xterm-256color',\n cols: 80,\n rows: 24,\n cwd,\n env,\n encoding: null,\n })\n}\n\nexport async function currentDirectory(pid: number) {\n if (process.platform === 'linux') return readlink(`/proc/${pid}/cwd`)\n if (process.platform === 'darwin') {\n const { stdout } = await run('lsof', [\n '-a',\n '-d',\n 'cwd',\n '-p',\n String(pid),\n '-Fn',\n ])\n const line = stdout.split('\\n').find((item) => item.startsWith('n'))\n if (line === undefined) throw new Error(`lsof found no folder for ${pid}`)\n return line.slice(1)\n }\n throw new Error(\n 'reading the directory of another process is not supported on this platform'\n )\n}\n\nexport async function busyProgram(pid: number) {\n if (process.platform === 'win32') {\n const { stdout } = await run('powershell.exe', [\n '-NoProfile',\n '-Command',\n `Get-CimInstance Win32_Process -Filter \"ParentProcessId=${pid}\" | Select-Object -ExpandProperty Name`,\n ])\n const names = [\n ...new Set(\n stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line !== '')\n ),\n ]\n return names.length === 0 ? null : names.join(', ')\n }\n const group = await foregroundGroup(pid)\n if (group <= 0) throw new Error('its foreground process group is unknown')\n if (group === pid) return null\n try {\n return await programName(group)\n } catch (error) {\n console.warn(`could not read the name of process ${group}: ${error}`)\n return `process ${group}`\n }\n}\n\nasync function foregroundGroup(pid: number) {\n if (process.platform === 'linux') {\n const text = await readFile(`/proc/${pid}/stat`, 'utf8')\n return Number(text.slice(text.lastIndexOf(')') + 2).split(' ')[5])\n }\n const { stdout } = await run('ps', ['-o', 'tpgid=', '-p', String(pid)])\n return Number(stdout.trim())\n}\n\nasync function programName(pid: number) {\n if (process.platform === 'linux')\n return (await readFile(`/proc/${pid}/comm`, 'utf8')).trimEnd()\n const { stdout } = await run('ps', ['-o', 'comm=', '-p', String(pid)])\n return path.basename(stdout.trim())\n}\n\nfunction launch() {\n const config = readConfig().terminal\n const [program, terminal, programVersion] = {\n offsite: ['offsite', 'offsite', version],\n ghostty: ['ghostty', 'ghostty', ghosttyVersion],\n iterm2: ['iTerm.app', 'iTerm2', iterm2Version],\n }[config.behavior.terminalIdentity]\n return {\n command: config.shell[platform()],\n environment: {\n TERM_PROGRAM: program,\n TERM_PROGRAM_VERSION: programVersion,\n LC_TERMINAL: terminal,\n LC_TERMINAL_VERSION: programVersion,\n },\n shellIntegration: config.behavior.shellIntegration,\n }\n}\n\nexport function listShells() {\n const candidates = (process.env.PATH ?? '')\n .split(path.delimiter)\n .filter((directory) => directory !== '')\n .flatMap((directory) =>\n shellNames.map((name) => path.join(directory, executable(name)))\n )\n if (process.platform !== 'win32') {\n try {\n candidates.push(\n ...readFileSync('/etc/shells', 'utf8')\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.startsWith('/'))\n )\n } catch {}\n }\n const seen = new Set<string>()\n const shells: { name: string; path: string }[] = []\n for (const name of shellNames) {\n for (const candidate of candidates) {\n if (path.basename(candidate) !== executable(name)) continue\n if (!statSync(candidate, { throwIfNoEntry: false })?.isFile()) continue\n let target\n try {\n target = realpathSync(candidate)\n } catch {\n continue\n }\n if (seen.has(target)) continue\n seen.add(target)\n shells.push({ name, path: candidate })\n }\n }\n return shells\n}\n\nfunction executable(name: string) {\n return process.platform === 'win32' ? `${name}.exe` : name\n}\n","export const ALERT_DELAY = 500\n\nexport type Alert =\n | { type: 'bell' }\n | { type: 'notification'; title: string; body: string }\n\nconst BELL_GAP = 5000\nconst NOTIFICATION_GAP = 1000\nconst PAYLOAD_LIMIT = 1024\nconst ESC = 0x1b\nconst BEL = 0x07\nconst CAN = 0x18\nconst SUB = 0x1a\n\nexport class Scanner {\n title = ''\n private state:\n | 'ground'\n | 'escape'\n | 'osc'\n | 'oscEscape'\n | 'text'\n | 'textEscape' = 'ground'\n private payload: number[] = []\n\n scan(bytes: Uint8Array) {\n let alert: Alert | null = null\n let index = 0\n while (index < bytes.length) {\n if (this.state === 'ground') {\n let offset = index\n while (\n offset < bytes.length &&\n bytes[offset] !== ESC &&\n bytes[offset] !== BEL\n )\n offset++\n if (offset === bytes.length) break\n index = offset\n }\n const found = this.step(bytes[index])\n index++\n if (found === null) continue\n if (found.type === 'bell') alert ??= found\n else alert = found\n }\n return alert\n }\n\n private step(byte: number): Alert | null {\n if (byte === CAN || byte === SUB) {\n this.state = 'ground'\n return null\n }\n switch (this.state) {\n case 'ground':\n if (byte === ESC) this.state = 'escape'\n if (byte === BEL) return { type: 'bell' }\n return null\n case 'escape':\n if (byte === 0x5d) {\n this.payload = []\n this.state = 'osc'\n } else if ([0x50, 0x58, 0x5e, 0x5f].includes(byte)) this.state = 'text'\n else if (byte !== ESC) this.state = 'ground'\n if (byte === BEL) return { type: 'bell' }\n return null\n case 'osc':\n if (byte === BEL) {\n this.state = 'ground'\n return this.finish()\n }\n if (byte === ESC) this.state = 'oscEscape'\n else if (this.payload.length < PAYLOAD_LIMIT) this.payload.push(byte)\n return null\n case 'oscEscape':\n if (byte === 0x5c) {\n this.state = 'ground'\n return this.finish()\n }\n this.state = 'escape'\n return this.step(byte)\n case 'text':\n if (byte === ESC) this.state = 'textEscape'\n return null\n case 'textEscape':\n if (byte === 0x5c) {\n this.state = 'ground'\n return null\n }\n this.state = 'escape'\n return this.step(byte)\n }\n }\n\n private finish(): Alert | null {\n const text = Buffer.from(this.payload).toString('utf8')\n if (text.startsWith('0;') || text.startsWith('2;')) {\n this.title = text.slice(2)\n return null\n }\n if (text.startsWith('9;')) {\n const body = text.slice(2)\n const digits = /^\\d*/.exec(body)?.[0].length ?? 0\n if (digits > 0 && (body.length === digits || body[digits] === ';'))\n return null\n return { type: 'notification', title: '', body }\n }\n if (text.startsWith('777;notify;')) {\n const rest = text.slice('777;notify;'.length)\n const split = rest.indexOf(';')\n return split === -1\n ? { type: 'notification', title: rest, body: '' }\n : {\n type: 'notification',\n title: rest.slice(0, split),\n body: rest.slice(split + 1),\n }\n }\n return null\n }\n}\n\nexport class Alerts {\n private pushedAt: number | null = null\n private bellPending = false\n\n startBell() {\n if (this.bellPending || this.pushedRecently(BELL_GAP)) return false\n this.bellPending = true\n return true\n }\n\n finishBell() {\n if (!this.bellPending) return false\n this.bellPending = false\n this.pushedAt = Date.now()\n return true\n }\n\n startNotification() {\n this.bellPending = false\n if (this.pushedRecently(NOTIFICATION_GAP)) return false\n this.pushedAt = Date.now()\n return true\n }\n\n private pushedRecently(gap: number) {\n return this.pushedAt !== null && Date.now() - this.pushedAt < gap\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdirSync, statSync, writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport type { IPty } from '@lydell/node-pty'\nimport {\n type BusyResult,\n decodeFrame,\n encodeFrame,\n FRAME_INPUT,\n FRAME_OUTPUT,\n FRAME_REPLAY,\n FRAME_REPLY,\n type TerminalEvent,\n type TerminalLayout,\n type TerminalProject,\n type TerminalRequest,\n type TerminalTab,\n} from '@offsite/core/protocol'\nimport type { Client } from '../../lib/hub.ts'\nimport { home } from '../../storage/storage.ts'\nimport { pushActive, sendPush } from '../push.ts'\nimport { ALERT_DELAY, type Alert, Alerts, Scanner } from './alerts.ts'\nimport { busyProgram, currentDirectory, startShell } from './process.ts'\n\ntype Connection = {\n client: Client\n sizes: Map<number, { cols: number; rows: number }>\n}\n\ntype Terminal = {\n pty: IPty\n history: Buffer[]\n historySize: number\n owner: Connection | null\n alerts: Alerts\n scanner: Scanner\n}\n\nconst HISTORY_LIMIT = 2 * 1024 * 1024\nconst OUTPUT_LIMIT = 1024 * 1024\nconst STALL_LIMIT = 10_000\nconst SILENCE_LIMIT = 90_000\nconst KILL_DELAY = 3000\nconst pasteTypes: Record<string, string> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n}\n\nconst instance = `${Date.now()}-${randomUUID()}`\nconst projects = new Map<string, TerminalProject>()\nconst terminals = new Map<number, Terminal>()\nconst connections = new Map<Client, Connection>()\nconst paused = new Set<IPty>()\nlet nextTab = 0\nlet draining: NodeJS.Timeout | null = null\n\nexport async function terminalRequest(\n client: Client,\n message: TerminalRequest\n) {\n if (message.type === 'attach') {\n attach(client)\n return\n }\n if (message.type === 'detach') {\n detachTerminal(client)\n return\n }\n const connection = connections.get(client)\n if (connection === undefined) throw new Error('the terminal is not attached')\n await request(connection, message)\n}\n\nexport function terminalInput(client: Client, frame: Buffer) {\n const connection = connections.get(client)\n if (connection === undefined) {\n console.warn('terminal input from a browser that is not attached')\n return\n }\n input(connection, frame)\n}\n\nexport function detachTerminal(client: Client) {\n const connection = connections.get(client)\n if (connection === undefined) return\n connections.delete(client)\n for (const terminal of terminals.values())\n if (terminal.owner === connection) terminal.owner = null\n}\n\nexport async function busyTerminal(id: number): Promise<BusyResult> {\n const terminal = terminals.get(id)\n if (terminal === undefined) return { program: null }\n try {\n return { program: await busyProgram(terminal.pty.pid) }\n } catch (error) {\n console.warn(`could not tell if terminal ${id} is busy: ${error}`)\n return { error: String(error) }\n }\n}\n\nexport function savePastedImage(type: string, data: Buffer) {\n const extension = pasteTypes[type]\n if (extension === undefined)\n throw new Error('pasted image must be a PNG, JPEG, GIF or WebP image')\n const directory = path.join(home, 'paste')\n mkdirSync(directory, { recursive: true })\n const file = path.join(\n directory,\n `${Date.now()}-${randomUUID()}.${extension}`\n )\n writeFileSync(file, data)\n return file\n}\n\nfunction attach(client: Client) {\n detachTerminal(client)\n const connection: Connection = { client, sizes: new Map() }\n connections.set(client, connection)\n send(connection, {\n type: 'active',\n layout: layout(),\n instance,\n })\n for (const project of projects.values())\n for (const tab of project.tabs)\n forward(\n connection,\n tab.id,\n true,\n Buffer.concat(terminals.get(tab.id)?.history ?? [])\n )\n}\n\nasync function request(\n connection: Connection,\n message: Exclude<TerminalRequest, { type: 'attach' | 'detach' }>\n) {\n switch (message.type) {\n case 'resize': {\n const terminal = terminals.get(message.id)\n if (terminal === undefined) return\n connection.sizes.set(message.id, {\n cols: message.cols,\n rows: message.rows,\n })\n terminal.owner = connection\n terminal.pty.resize(message.cols, message.rows)\n return\n }\n case 'createTab':\n await createTab(message.cwd)\n break\n case 'closeTab':\n closeTab(message.id)\n break\n case 'renameTab': {\n const tab = findTab(message.id)\n if (tab === undefined) return\n tab.customName = message.name === '' ? null : message.name\n break\n }\n case 'minimizeTab': {\n const project = [...projects.values()].find((item) =>\n item.tabs.some((tab) => tab.id === message.id)\n )\n if (project === undefined) return\n if (!project.tabs.some((tab) => tab.id !== message.id && !tab.minimized))\n return\n const index = project.tabs.findIndex((tab) => tab.id === message.id)\n project.tabs[index].minimized = true\n if (project.activeTab === message.id) {\n const next = nearestVisible(project.tabs, index)\n project.activeTab = next === undefined ? null : project.tabs[next].id\n }\n break\n }\n case 'select': {\n const project = projects.get(message.cwd) ?? {\n tabs: [],\n activeTab: null,\n }\n projects.set(message.cwd, project)\n const tab = project.tabs.find((item) => item.id === message.tabId)\n if (tab !== undefined) {\n tab.minimized = false\n project.activeTab = tab.id\n }\n if (project.tabs.length === 0) await createTab(message.cwd)\n break\n }\n }\n publish()\n}\n\nfunction input(connection: Connection, bytes: Buffer) {\n let frame\n try {\n frame = decodeFrame(bytes)\n } catch (error) {\n console.warn(`ignoring terminal input: ${error}`)\n return\n }\n const terminal = terminals.get(frame.id)\n if (terminal === undefined) {\n console.warn(`input for terminal ${frame.id}, which does not exist`)\n return\n }\n if (frame.kind === FRAME_REPLY) {\n if (terminal.owner !== null && terminal.owner !== connection) return\n } else if (frame.kind === FRAME_INPUT) {\n const size = connection.sizes.get(frame.id)\n if (terminal.owner !== connection && size !== undefined) {\n terminal.owner = connection\n terminal.pty.resize(size.cols, size.rows)\n }\n } else {\n console.warn(`ignoring terminal input of unknown kind ${frame.kind}`)\n return\n }\n terminal.pty.write(Buffer.from(frame.data))\n}\n\nasync function createTab(cwd: string) {\n if (!statSync(cwd, { throwIfNoEntry: false })?.isDirectory()) {\n console.error(`${cwd} is not a folder, terminal not created`)\n return\n }\n const project = projects.get(cwd) ?? { tabs: [], activeTab: null }\n projects.set(cwd, project)\n const active =\n project.activeTab === null ? undefined : terminals.get(project.activeTab)\n let directory = cwd\n if (active !== undefined) {\n try {\n directory = await currentDirectory(active.pty.pid)\n } catch (error) {\n console.warn(\n `starting in the project folder, could not read the folder of the active terminal: ${error}`\n )\n }\n }\n nextTab += 1\n const id = nextTab\n let pty: IPty\n try {\n pty = startShell(directory)\n } catch (error) {\n console.error(`could not start terminal ${id}: ${error}`)\n return\n }\n const terminal: Terminal = {\n pty,\n history: [],\n historySize: 0,\n owner: null,\n alerts: new Alerts(),\n scanner: new Scanner(),\n }\n terminals.set(id, terminal)\n project.tabs.push({ id, customName: null, minimized: false })\n project.activeTab = id\n pty.onData((data) => output(id, terminal, data as unknown as Buffer))\n pty.onExit(() => {\n terminals.delete(id)\n paused.delete(pty)\n if (closeTab(id)) publish()\n })\n}\n\nfunction closeTab(id: number) {\n const project = [...projects.values()].find((item) =>\n item.tabs.some((tab) => tab.id === id)\n )\n if (project === undefined) return false\n const index = project.tabs.findIndex((tab) => tab.id === id)\n project.tabs.splice(index, 1)\n if (project.activeTab === id) {\n let next: number | undefined = nearestVisible(project.tabs, index)\n if (next === undefined && project.tabs.length > 0)\n next = Math.min(index, project.tabs.length - 1)\n if (next !== undefined) project.tabs[next].minimized = false\n project.activeTab = next === undefined ? null : project.tabs[next].id\n }\n const terminal = terminals.get(id)\n if (terminal === undefined) return true\n terminal.pty.kill()\n if (process.platform !== 'win32')\n setTimeout(() => {\n if (terminals.get(id) === terminal) terminal.pty.kill('SIGKILL')\n }, KILL_DELAY)\n return true\n}\n\nfunction output(id: number, terminal: Terminal, data: Buffer) {\n terminal.history.push(data)\n terminal.historySize += data.length\n while (terminal.historySize > HISTORY_LIMIT && terminal.history.length > 1) {\n terminal.historySize -= terminal.history[0].length\n terminal.history.shift()\n }\n for (const connection of connections.values())\n forward(connection, id, false, data)\n scan(id, terminal, data)\n if (\n [...connections.values()].some(\n (connection) => connection.client.socket.bufferedAmount > OUTPUT_LIMIT\n )\n ) {\n terminal.pty.pause()\n paused.add(terminal.pty)\n draining ??= drain()\n }\n}\n\nfunction drain() {\n const progress = new Map<Connection, { queued: number; at: number }>()\n return setInterval(() => {\n let full = false\n for (const connection of connections.values()) {\n const queued = connection.client.socket.bufferedAmount\n if (queued <= OUTPUT_LIMIT) continue\n const now = Date.now()\n const last = progress.get(connection) ?? { queued: Infinity, at: now }\n if (queued < last.queued) last.at = now\n last.queued = queued\n progress.set(connection, last)\n if (now - last.at > STALL_LIMIT) {\n console.warn('a browser is not reading fast enough, disconnecting it')\n connection.client.socket.terminate()\n continue\n }\n full = true\n }\n if (full) return\n if (draining !== null) clearInterval(draining)\n draining = null\n for (const pty of paused) pty.resume()\n paused.clear()\n }, 10)\n}\n\nfunction scan(id: number, terminal: Terminal, data: Buffer) {\n if (!pushActive()) {\n terminal.scanner = new Scanner()\n return\n }\n const alert = terminal.scanner.scan(data)\n if (alert === null || browserOpen()) return\n const started =\n alert.type === 'bell'\n ? terminal.alerts.startBell()\n : terminal.alerts.startNotification()\n if (!started) return\n const windowTitle = terminal.scanner.title\n setTimeout(() => push(id, alert, windowTitle), ALERT_DELAY)\n}\n\nfunction push(id: number, alert: Alert, windowTitle: string) {\n const terminal = terminals.get(id)\n if (terminal === undefined) return\n let title = ''\n let body: string\n if (alert.type === 'bell') {\n if (!terminal.alerts.finishBell()) return\n body = 'Bell'\n } else {\n title = alert.title\n body = alert.body\n }\n if (browserOpen()) return\n const entry = [...projects].find(([, project]) =>\n project.tabs.some((tab) => tab.id === id)\n )\n if (entry === undefined) return\n const tab = findTab(id)\n if (title === '') title = tab?.customName ?? (windowTitle || 'Terminal')\n void sendPush({ title, body, cwd: entry[0], tabId: id })\n}\n\nfunction browserOpen() {\n return [...connections.values()].some(\n (connection) => Date.now() - connection.client.heardAt < SILENCE_LIMIT\n )\n}\n\nfunction findTab(id: number): TerminalTab | undefined {\n for (const project of projects.values()) {\n const tab = project.tabs.find((item) => item.id === id)\n if (tab !== undefined) return tab\n }\n return undefined\n}\n\nfunction nearestVisible(tabs: TerminalTab[], index: number) {\n for (let position = index; position < tabs.length; position++)\n if (!tabs[position].minimized) return position\n for (\n let position = Math.min(index, tabs.length) - 1;\n position >= 0;\n position--\n )\n if (!tabs[position].minimized) return position\n return undefined\n}\n\nfunction layout(): TerminalLayout {\n return Object.fromEntries(projects)\n}\n\nfunction publish() {\n const event: TerminalEvent = { type: 'layout', layout: layout() }\n for (const connection of connections.values()) send(connection, event)\n}\n\nfunction forward(\n connection: Connection,\n id: number,\n replay: boolean,\n data: Buffer\n) {\n connection.client.socket.send(\n encodeFrame(replay ? FRAME_REPLAY : FRAME_OUTPUT, id, data)\n )\n}\n\nfunction send(connection: Connection, event: TerminalEvent) {\n connection.client.send({ type: 'terminal', event })\n}\n","import os from 'node:os'\nimport {\n type Call,\n type Method,\n type Methods,\n PROTOCOL,\n} from '@offsite/core/protocol'\nimport type { WebSocket } from 'ws'\nimport { agentMessages, earlier, image } from '../lib/claude/index.ts'\nimport { codexAgent } from '../lib/codex/index.ts'\nimport { type Client, clients } from '../lib/hub.ts'\nimport { activity, runs } from '../lib/live.ts'\nimport { openCodeAgent } from '../lib/opencode/index.ts'\nimport {\n accounts,\n addAccount,\n capabilities,\n publishAccounts,\n removeAccount,\n updateAccount,\n} from '../services/accounts.ts'\nimport {\n listFiles,\n readProjectFile,\n saveUpload,\n taskOutput,\n} from '../services/files.ts'\nimport {\n commit,\n createPullRequest,\n gitStatus,\n projectDiff,\n push,\n suggestCommitMessage,\n} from '../services/git.ts'\nimport {\n addProject,\n directories,\n projects,\n removeProject,\n updateProject,\n} from '../services/projects.ts'\nimport { pushKey, subscribe, unsubscribe } from '../services/push.ts'\nimport { open, rewind, send } from '../services/runs.ts'\nimport {\n fork,\n providerOf,\n publishSessions,\n recordInteraction,\n removeSession,\n sessions,\n updateSession,\n watchSessions,\n} from '../services/sessions.ts'\nimport { listShells } from '../services/terminal/process.ts'\nimport {\n busyTerminal,\n detachTerminal,\n savePastedImage,\n terminalInput,\n terminalRequest,\n} from '../services/terminal/terminal.ts'\nimport { configInfo, readConfig, saveConfig } from '../storage/config.ts'\n\ntype Handlers = {\n [M in Method]: (\n params: Methods[M]['params'],\n client: Client\n ) => Methods[M]['result'] | Promise<Methods[M]['result']>\n}\n\nconst handlers: Handlers = {\n ping: () => null,\n sync: async () => ({\n ...configInfo(),\n protocol: PROTOCOL,\n hostname: os.hostname(),\n projects: projects(),\n sessions: await sessions(),\n activity: activity(),\n }),\n 'config.get': () => configInfo(),\n 'config.save': (params) => {\n const before = readConfig().claudeBaseDir\n const saved = saveConfig(params)\n if (saved.claudeBaseDir === before) return saved\n watchSessions()\n void publishSessions()\n void publishAccounts()\n return saved\n },\n 'projects.add': async (params) => {\n const project = await addProject(params.path)\n void publishSessions()\n return project\n },\n 'projects.update': (params) => updateProject(params.path, params.patch),\n 'projects.remove': (params) => {\n removeProject(params.path)\n void publishSessions()\n return null\n },\n 'directories.list': (params) => directories(params.path),\n 'sessions.update': async (params) => {\n try {\n await updateSession(params.id, params.patch)\n } finally {\n void publishSessions()\n }\n return null\n },\n 'sessions.remove': async (params) => {\n try {\n await removeSession(params.id)\n } finally {\n void publishSessions()\n }\n return null\n },\n 'sessions.open': async (params, client) => {\n await open(client, params.sessionId, params.cwd)\n return null\n },\n 'sessions.earlier': (params) => earlier(params.sessionId, params.before),\n 'sessions.image': (params) =>\n image(params.sessionId, params.itemId, params.index),\n 'sessions.agent': (params) => {\n switch (providerOf(params.sessionId)) {\n case 'claude':\n return agentMessages(\n params.sessionId,\n params.cwd,\n params.agentId,\n params.parent\n )\n case 'codex':\n return codexAgent(params.agentId, params.parent)\n case 'opencode':\n return openCodeAgent(params.agentId, params.parent)\n }\n },\n 'sessions.send': async (params, client) => {\n await send(client, params)\n return null\n },\n 'sessions.unqueue': (params) => {\n runs.get(params.sessionId)?.unqueue(params.id)\n return null\n },\n 'sessions.steer': (params) => {\n runs.get(params.sessionId)?.steer(params.id)\n return null\n },\n 'sessions.interrupt': async (params) => {\n await runs.get(params.sessionId)?.interrupt()\n return null\n },\n 'sessions.stopTask': async (params) => {\n await runs.get(params.sessionId)?.stopTask(params.taskId)\n return null\n },\n 'sessions.configure': async (params) => {\n await runs.get(params.sessionId)?.configure(params.settings)\n return null\n },\n 'sessions.respond': async (params) => {\n const run = runs.get(params.sessionId)\n if (run === undefined) return null\n await run.respond(params.requestId, params.decision, params.answers)\n recordInteraction(params.sessionId)\n return null\n },\n 'sessions.rewind': (params) => rewind(params),\n 'sessions.fork': async (params) => {\n const result = await fork(params.sessionId, params.cwd, params.messageId)\n void publishSessions()\n return result\n },\n 'accounts.list': () => accounts(),\n 'accounts.add': (params) => {\n addAccount(params.provider, params.name, params.configDir)\n void publishAccounts()\n return null\n },\n 'accounts.update': (params) => {\n updateAccount(params.id, params.name, params.configDir)\n void publishAccounts()\n return null\n },\n 'accounts.remove': (params) => {\n removeAccount(params.id)\n void publishAccounts()\n return null\n },\n capabilities: (params) => capabilities(params.accountId, params.cwd),\n 'files.list': (params) => listFiles(params.cwd),\n 'files.read': (params) => readProjectFile(params.cwd, params.path),\n 'files.upload': (params) =>\n saveUpload(params.name, Buffer.from(params.data, 'base64')),\n 'tasks.output': (params) => taskOutput(params.sessionId, params.path),\n 'git.status': (params) => gitStatus(params.cwd),\n 'git.diff': (params) => projectDiff(params.cwd),\n 'git.commit': (params) => commit(params.cwd, params.message),\n 'git.push': (params) => push(params.cwd),\n 'git.pullRequest': (params) => createPullRequest(params.cwd),\n 'git.message': (params) =>\n suggestCommitMessage(params.provider, params.accountId, params.cwd),\n 'push.key': () => pushKey(),\n 'push.subscribe': (params) => {\n subscribe(params)\n return null\n },\n 'push.unsubscribe': (params) => {\n unsubscribe(params.endpoint)\n return null\n },\n terminal: async (params, client) => {\n await terminalRequest(client, params)\n return null\n },\n 'terminal.shells': () => listShells(),\n 'terminal.busy': (params) => busyTerminal(params.id),\n 'terminal.paste': (params) =>\n savePastedImage(params.type, Buffer.from(params.data, 'base64')),\n}\n\nexport function connectClient(socket: WebSocket) {\n const client: Client = {\n socket,\n heardAt: Date.now(),\n opening: null,\n sessionId: null,\n send: (message) => socket.send(JSON.stringify(message)),\n }\n clients.add(client)\n socket.on('message', (data, isBinary) => {\n client.heardAt = Date.now()\n if (isBinary) {\n terminalInput(client, data as Buffer)\n return\n }\n void answer(client, String(data))\n })\n socket.on('error', (error) =>\n console.warn(`a browser connection failed: ${error}`)\n )\n socket.on('close', () => {\n clients.delete(client)\n detachTerminal(client)\n })\n}\n\nasync function answer(client: Client, text: string) {\n let call: Call\n try {\n call = JSON.parse(text) as Call\n } catch (error) {\n console.warn(`ignoring a message that is not JSON: ${error}`)\n return\n }\n try {\n if (!Object.hasOwn(handlers, call.method))\n throw new Error(`unknown method ${call.method}`)\n const handler = handlers[call.method] as (\n params: unknown,\n client: Client\n ) => unknown\n const result = await handler(call.params, client)\n client.send({ type: 'reply', id: call.id, result })\n } catch (error) {\n client.send({\n type: 'reply',\n id: call.id,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto'\nimport { readJson, writeJson } from './storage.ts'\n\nexport type PairingToken = {\n token: string\n name: string | null\n createdAt: number\n}\n\nexport function readTokens() {\n const stored = readJson('tokens.json') as { tokens: PairingToken[] } | null\n return stored === null ? [] : stored.tokens\n}\n\nexport function addToken(name: string | null) {\n const token = randomBytes(32).toString('base64url')\n writeJson('tokens.json', {\n tokens: [...readTokens(), { token, name, createdAt: Date.now() }],\n })\n return token\n}\n\nexport function removeTokens(tokens: string[]) {\n writeJson('tokens.json', {\n tokens: readTokens().filter((item) => !tokens.includes(item.token)),\n })\n}\n\nexport function firstToken() {\n return readTokens().at(0)?.token ?? addToken(null)\n}\n\nexport function matchesToken(given: string | null) {\n if (given === null) return false\n const actual = Buffer.from(given)\n return readTokens().some((item) => {\n const expected = Buffer.from(item.token)\n return (\n expected.length === actual.length && timingSafeEqual(expected, actual)\n )\n })\n}\n\nexport function readUsage() {\n return (readJson('token-usage.json') ?? {}) as Record<string, number>\n}\n\nexport function recordUse(token: string) {\n writeJson('token-usage.json', { ...readUsage(), [token]: Date.now() })\n}\n","import { createReadStream, existsSync, statSync } from 'node:fs'\nimport { createServer, type ServerResponse } from 'node:http'\nimport path from 'node:path'\nimport { HOSTED_APP, PROTOCOL } from '@offsite/core/protocol'\nimport { consola } from 'consola'\nimport { type WebSocket, WebSocketServer } from 'ws'\nimport { connectClient } from './api/socket.ts'\nimport { args } from './args.ts'\nimport { findClaude } from './lib/claude/index.ts'\nimport { startPush } from './services/push.ts'\nimport { stopAll } from './services/runs.ts'\nimport { watchSessions } from './services/sessions.ts'\nimport { readConfig, version } from './storage/config.ts'\nimport { lockHome } from './storage/storage.ts'\nimport {\n addToken,\n firstToken,\n matchesToken,\n readTokens,\n readUsage,\n recordUse,\n removeTokens,\n} from './storage/token.ts'\n\nconst UNPAIR_CHECK = 5000\n\nconst contentTypes: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.ico': 'image/x-icon',\n '.json': 'application/json',\n '.webmanifest': 'application/manifest+json',\n '.woff2': 'font/woff2',\n}\n\nconst port = Number(args.port)\nif (!Number.isInteger(port) || port < 1 || port > 65535) {\n console.error(`invalid port ${args.port}`)\n process.exit(1)\n}\n\nconst address = `http://${args.host}:${port}`\n\nif (args.command === 'pair') {\n const links = pairingLinks(addToken(args.name))\n console.log('Open one of these links in the browser to pair:')\n console.log(` ${links.local}`)\n console.log(` ${links.hosted}`)\n process.exit(0)\n}\n\nif (args.command === 'unpair') {\n await unpair()\n process.exit(0)\n}\n\nlockHome()\n\nprocess.env.CLAUDE_CONFIG_DIR = readConfig().claudeBaseDir\nwatchSessions()\n\nif (findClaude() === null) {\n console.error('could not find claude on PATH; install Claude Code first')\n process.exit(1)\n}\n\nconst publicDir = path.join(import.meta.dirname, '..', '..', 'web', 'dist')\nconst token = args.auth && args.pair ? firstToken() : null\n\nconst server = createServer((request, response) => {\n const url = new URL(request.url ?? '/', 'http://localhost')\n if (url.pathname === '/version') {\n response.setHeader('access-control-allow-origin', '*')\n response.setHeader('content-type', 'application/json')\n response.end(\n JSON.stringify({\n version,\n protocol: PROTOCOL,\n authorized: authorized(url),\n })\n )\n return\n }\n if (args.command === 'serve') {\n response.statusCode = 404\n response.end(`offsite serve has no web app; open ${HOSTED_APP}`)\n return\n }\n serveFile(url.pathname, response)\n})\n\nconst sockets = new WebSocketServer({ noServer: true })\nconst paired = new Map<WebSocket, string>()\n\nserver.on('upgrade', (request, socket, head) => {\n const url = new URL(request.url ?? '/', 'http://localhost')\n const given = url.searchParams.get('token')\n if (\n url.pathname !== '/ws' ||\n url.searchParams.get('protocol') !== String(PROTOCOL) ||\n !authorized(url)\n ) {\n socket.destroy()\n return\n }\n sockets.handleUpgrade(request, socket, head, (client) => {\n connectClient(client)\n if (!args.auth || given === null) return\n paired.set(client, given)\n client.on('close', () => paired.delete(client))\n recordUse(given)\n })\n})\n\nif (args.auth)\n setInterval(() => {\n for (const [client, given] of paired)\n if (!matchesToken(given)) client.close()\n }, UNPAIR_CHECK)\n\nserver.listen(port, args.host, () => {\n startPush(`${args.host}:${port}`)\n if (args.pair) {\n const links = pairingLinks(token)\n if (args.command === 'web')\n console.log(`offsite is running at ${links.local}`)\n console.log(`Open it on ${HOSTED_APP}: ${links.hosted}`)\n } else {\n console.log(`offsite is running at ${address}`)\n console.log(`Open it on ${HOSTED_APP}`)\n }\n if (!args.auth)\n console.warn(\n 'auth is off; anyone who can reach this port can control this machine'\n )\n})\n\nprocess.on('SIGINT', stop)\nprocess.on('SIGTERM', stop)\n\nfunction stop() {\n stopAll()\n process.exit(0)\n}\n\nfunction authorized(url: URL) {\n return !args.auth || matchesToken(url.searchParams.get('token'))\n}\n\nasync function unpair() {\n const tokens = readTokens()\n if (tokens.length === 0) {\n console.log('No browsers are paired')\n return\n }\n if (!process.stdin.isTTY) {\n console.error('offsite unpair needs an interactive terminal')\n process.exit(1)\n }\n const usage = readUsage()\n const picked = (await consola.prompt('Which browsers should be unpaired?', {\n type: 'multiselect',\n required: false,\n cancel: 'null',\n options: tokens.map((item) => {\n const used = usage[item.token]\n return {\n value: item.token,\n label: [\n item.name ?? 'Unnamed',\n `${item.token.slice(0, 6)}…`,\n `paired ${new Date(item.createdAt).toLocaleString()}`,\n used === undefined\n ? 'never used'\n : `last used ${new Date(used).toLocaleString()}`,\n ].join(' · '),\n }\n }),\n })) as unknown as string[] | null\n if (picked === null || picked.length === 0) {\n console.log('Nothing unpaired')\n return\n }\n removeTokens(picked)\n console.log(\n `Unpaired ${picked.length} ${picked.length === 1 ? 'browser' : 'browsers'}; a running offsite disconnects them within seconds`\n )\n}\n\nfunction pairingLinks(token: string | null) {\n const hosted = new URLSearchParams({\n machine: address,\n ...(token !== null && { token }),\n })\n return {\n local:\n token === null\n ? address\n : `${address}/pair#${new URLSearchParams({ token })}`,\n hosted: `${HOSTED_APP}/pair#${hosted}`,\n }\n}\n\nfunction serveFile(pathname: string, response: ServerResponse) {\n const requested = path.join(publicDir, path.normalize(pathname))\n const file =\n requested.startsWith(publicDir + path.sep) &&\n statSync(requested, { throwIfNoEntry: false })?.isFile()\n ? requested\n : path.join(publicDir, 'index.html')\n if (!existsSync(file)) {\n response.statusCode = 404\n response.end('web app not built; run pnpm build')\n return\n }\n response.setHeader(\n 'content-type',\n contentTypes[path.extname(file)] ?? 'application/octet-stream'\n )\n createReadStream(file).pipe(response)\n}\n"],"mappings":"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"}
|