codexapp 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist-cli/index.js CHANGED
@@ -1553,6 +1553,7 @@ async function startServer(options) {
1553
1553
  "",
1554
1554
  "Codex Web Local is running!",
1555
1555
  ` Version: ${version}`,
1556
+ " GitHub: https://github.com/friuns2/codexui",
1556
1557
  "",
1557
1558
  ` Local: http://localhost:${String(port)}`
1558
1559
  ];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/server/httpServer.ts","../src/server/codexAppServerBridge.ts","../src/server/authMiddleware.ts","../src/server/password.ts"],"sourcesContent":["import { createServer } from 'node:http'\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { spawn, spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname } from 'node:path'\nimport { Command } from 'commander'\nimport { createServer as createApp } from '../server/httpServer.js'\nimport { generatePassword } from '../server/password.js'\n\nconst program = new Command().name('codexui').description('Web interface for Codex app-server')\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nasync function readCliVersion(): Promise<string> {\n try {\n const packageJsonPath = join(__dirname, '..', 'package.json')\n const raw = await readFile(packageJsonPath, 'utf8')\n const parsed = JSON.parse(raw) as { version?: unknown }\n return typeof parsed.version === 'string' ? parsed.version : 'unknown'\n } catch {\n return 'unknown'\n }\n}\n\nfunction isTermuxRuntime(): boolean {\n return Boolean(process.env.TERMUX_VERSION || process.env.PREFIX?.includes('/com.termux/'))\n}\n\nfunction canRun(command: string, args: string[] = []): boolean {\n const result = spawnSync(command, args, { stdio: 'ignore' })\n return result.status === 0\n}\n\nfunction runOrFail(command: string, args: string[], label: string): void {\n const result = spawnSync(command, args, { stdio: 'inherit' })\n if (result.status !== 0) {\n throw new Error(`${label} failed with exit code ${String(result.status ?? -1)}`)\n }\n}\n\nfunction runWithStatus(command: string, args: string[]): number {\n const result = spawnSync(command, args, { stdio: 'inherit' })\n return result.status ?? -1\n}\n\nfunction getUserNpmPrefix(): string {\n return join(homedir(), '.npm-global')\n}\n\nfunction resolveCodexCommand(): string | null {\n if (canRun('codex', ['--version'])) {\n return 'codex'\n }\n\n const userCandidate = join(getUserNpmPrefix(), 'bin', 'codex')\n if (existsSync(userCandidate) && canRun(userCandidate, ['--version'])) {\n return userCandidate\n }\n\n const prefix = process.env.PREFIX?.trim()\n if (!prefix) {\n return null\n }\n const candidate = join(prefix, 'bin', 'codex')\n if (existsSync(candidate) && canRun(candidate, ['--version'])) {\n return candidate\n }\n return null\n}\n\nfunction hasCodexAuth(): boolean {\n const codexHome = process.env.CODEX_HOME?.trim() || join(homedir(), '.codex')\n return existsSync(join(codexHome, 'auth.json'))\n}\n\nfunction ensureCodexInstalled(): string | null {\n let codexCommand = resolveCodexCommand()\n if (!codexCommand) {\n const installWithFallback = (pkg: string, label: string): void => {\n const status = runWithStatus('npm', ['install', '-g', pkg])\n if (status === 0) {\n return\n }\n if (isTermuxRuntime()) {\n throw new Error(`${label} failed with exit code ${String(status)}`)\n }\n const userPrefix = getUserNpmPrefix()\n console.log(`\\nGlobal npm install requires elevated permissions. Retrying with --prefix ${userPrefix}...\\n`)\n runOrFail('npm', ['install', '-g', '--prefix', userPrefix, pkg], `${label} (user prefix)`)\n process.env.PATH = `${join(userPrefix, 'bin')}:${process.env.PATH ?? ''}`\n }\n\n if (isTermuxRuntime()) {\n console.log('\\nCodex CLI not found. Installing Termux-compatible Codex CLI from npm...\\n')\n installWithFallback('@mmmbuto/codex-cli-termux', 'Codex CLI install')\n codexCommand = resolveCodexCommand()\n if (!codexCommand) {\n console.log('\\nTermux npm package did not expose `codex`. Installing official CLI fallback...\\n')\n installWithFallback('@openai/codex', 'Codex CLI fallback install')\n }\n } else {\n console.log('\\nCodex CLI not found. Installing official Codex CLI from npm...\\n')\n installWithFallback('@openai/codex', 'Codex CLI install')\n }\n\n codexCommand = resolveCodexCommand()\n if (!codexCommand && !isTermuxRuntime()) {\n // Non-Termux path should resolve after official package install.\n throw new Error('Official Codex CLI install completed but binary is still not available in PATH')\n }\n if (!codexCommand && isTermuxRuntime()) {\n codexCommand = resolveCodexCommand()\n }\n if (!codexCommand) {\n throw new Error('Codex CLI install completed but binary is still not available in PATH')\n }\n console.log('\\nCodex CLI installed.\\n')\n }\n return codexCommand\n}\n\nfunction resolvePassword(input: string | boolean): string | undefined {\n if (input === false) {\n return undefined\n }\n if (typeof input === 'string') {\n return input\n }\n return generatePassword()\n}\n\nfunction printTermuxKeepAlive(lines: string[]): void {\n if (!isTermuxRuntime()) {\n return\n }\n lines.push('')\n lines.push(' Android/Termux keep-alive:')\n lines.push(' 1) Keep this Termux session open (do not swipe it away).')\n lines.push(' 2) Disable battery optimization for Termux in Android settings.')\n lines.push(' 3) Optional: run `termux-wake-lock` in another shell.')\n}\n\nfunction openBrowser(url: string): void {\n const command = process.platform === 'darwin'\n ? { cmd: 'open', args: [url] }\n : process.platform === 'win32'\n ? { cmd: 'cmd', args: ['/c', 'start', '', url] }\n : { cmd: 'xdg-open', args: [url] }\n\n const child = spawn(command.cmd, command.args, { detached: true, stdio: 'ignore' })\n child.on('error', () => {})\n child.unref()\n}\n\nfunction listenWithFallback(server: ReturnType<typeof createServer>, startPort: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const attempt = (port: number) => {\n const onError = (error: NodeJS.ErrnoException) => {\n server.off('listening', onListening)\n if (error.code === 'EADDRINUSE' || error.code === 'EACCES') {\n attempt(port + 1)\n return\n }\n reject(error)\n }\n const onListening = () => {\n server.off('error', onError)\n resolve(port)\n }\n\n server.once('error', onError)\n server.once('listening', onListening)\n server.listen(port)\n }\n\n attempt(startPort)\n })\n}\n\nasync function startServer(options: { port: string; password: string | boolean }) {\n const version = await readCliVersion()\n const codexCommand = ensureCodexInstalled() ?? resolveCodexCommand()\n if (!hasCodexAuth() && codexCommand) {\n console.log('\\nCodex is not logged in. Starting `codex login`...\\n')\n runOrFail(codexCommand, ['login'], 'Codex login')\n }\n const requestedPort = parseInt(options.port, 10)\n const password = resolvePassword(options.password)\n const { app, dispose } = createApp({ password })\n const server = createServer(app)\n const port = await listenWithFallback(server, requestedPort)\n const lines = [\n '',\n 'Codex Web Local is running!',\n ` Version: ${version}`,\n '',\n ` Local: http://localhost:${String(port)}`,\n ]\n\n if (port !== requestedPort) {\n lines.push(` Requested port ${String(requestedPort)} was unavailable; using ${String(port)}.`)\n }\n\n if (password) {\n lines.push(` Password: ${password}`)\n }\n\n printTermuxKeepAlive(lines)\n lines.push('')\n console.log(lines.join('\\n'))\n openBrowser(`http://localhost:${String(port)}`)\n\n function shutdown() {\n console.log('\\nShutting down...')\n server.close(() => {\n dispose()\n process.exit(0)\n })\n // Force exit after timeout\n setTimeout(() => {\n dispose()\n process.exit(1)\n }, 5000).unref()\n }\n\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n}\n\nasync function runLogin() {\n const codexCommand = ensureCodexInstalled() ?? 'codex'\n console.log('\\nStarting `codex login`...\\n')\n runOrFail(codexCommand, ['login'], 'Codex login')\n}\n\nprogram\n .option('-p, --port <port>', 'port to listen on', '5999')\n .option('--password <pass>', 'set a specific password')\n .option('--no-password', 'disable password protection')\n .action(async (opts: { port: string; password: string | boolean }) => {\n await startServer(opts)\n })\n\nprogram.command('login').description('Install/check Codex CLI and run `codex login`').action(runLogin)\n\nprogram.command('help').description('Show codexui command help').action(() => {\n program.outputHelp()\n})\n\nprogram.parseAsync(process.argv).catch((error) => {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`\\nFailed to run codexui: ${message}`)\n process.exit(1)\n})\n","import { fileURLToPath } from 'node:url'\nimport { dirname, extname, isAbsolute, join } from 'node:path'\nimport express, { type Express } from 'express'\nimport { createCodexBridgeMiddleware } from './codexAppServerBridge.js'\nimport { createAuthMiddleware } from './authMiddleware.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst distDir = join(__dirname, '..', 'dist')\n\nexport type ServerOptions = {\n password?: string\n}\n\nexport type ServerInstance = {\n app: Express\n dispose: () => void\n}\n\nconst IMAGE_CONTENT_TYPES: Record<string, string> = {\n '.avif': 'image/avif',\n '.bmp': 'image/bmp',\n '.gif': 'image/gif',\n '.jpeg': 'image/jpeg',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n}\n\nfunction normalizeLocalImagePath(rawPath: string): string {\n const trimmed = rawPath.trim()\n if (!trimmed) return ''\n if (trimmed.startsWith('file://')) {\n try {\n return decodeURIComponent(trimmed.replace(/^file:\\/\\//u, ''))\n } catch {\n return trimmed.replace(/^file:\\/\\//u, '')\n }\n }\n return trimmed\n}\n\nexport function createServer(options: ServerOptions = {}): ServerInstance {\n const app = express()\n const bridge = createCodexBridgeMiddleware()\n\n // 1. Auth middleware (if password is set)\n if (options.password) {\n app.use(createAuthMiddleware(options.password))\n }\n\n // 2. Bridge middleware for /codex-api/*\n app.use(bridge)\n\n // 3. Serve local images referenced in markdown (desktop parity for absolute image paths)\n app.get('/codex-local-image', (req, res) => {\n const rawPath = typeof req.query.path === 'string' ? req.query.path : ''\n const localPath = normalizeLocalImagePath(rawPath)\n if (!localPath || !isAbsolute(localPath)) {\n res.status(400).json({ error: 'Expected absolute local file path.' })\n return\n }\n\n const contentType = IMAGE_CONTENT_TYPES[extname(localPath).toLowerCase()]\n if (!contentType) {\n res.status(415).json({ error: 'Unsupported image type.' })\n return\n }\n\n res.type(contentType)\n res.setHeader('Cache-Control', 'private, max-age=300')\n res.sendFile(localPath, { dotfiles: 'allow' }, (error) => {\n if (!error) return\n if (!res.headersSent) res.status(404).json({ error: 'Image file not found.' })\n })\n })\n\n // 4. Static files from Vue build\n app.use(express.static(distDir))\n\n // 5. SPA fallback\n app.use((_req, res) => {\n res.sendFile(join(distDir, 'index.html'))\n })\n\n return {\n app,\n dispose: () => bridge.dispose(),\n }\n}\n","import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'\nimport { mkdtemp, readFile, readdir, rm, mkdir, stat } from 'node:fs/promises'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { request as httpsRequest } from 'node:https'\nimport { homedir } from 'node:os'\nimport { tmpdir } from 'node:os'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport { writeFile } from 'node:fs/promises'\n\ntype JsonRpcCall = {\n jsonrpc: '2.0'\n id: number\n method: string\n params?: unknown\n}\n\ntype JsonRpcResponse = {\n id?: number\n result?: unknown\n error?: {\n code: number\n message: string\n }\n method?: string\n params?: unknown\n}\n\ntype RpcProxyRequest = {\n method: string\n params?: unknown\n}\n\ntype ServerRequestReply = {\n result?: unknown\n error?: {\n code: number\n message: string\n }\n}\n\ntype WorkspaceRootsState = {\n order: string[]\n labels: Record<string, string>\n active: string[]\n}\n\ntype PendingServerRequest = {\n id: number\n method: string\n params: unknown\n receivedAtIso: string\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null\n}\n\nfunction getErrorMessage(payload: unknown, fallback: string): string {\n if (payload instanceof Error && payload.message.trim().length > 0) {\n return payload.message\n }\n\n const record = asRecord(payload)\n if (!record) return fallback\n\n const error = record.error\n if (typeof error === 'string' && error.length > 0) return error\n\n const nestedError = asRecord(error)\n if (nestedError && typeof nestedError.message === 'string' && nestedError.message.length > 0) {\n return nestedError.message\n }\n\n return fallback\n}\n\nfunction setJson(res: ServerResponse, statusCode: number, payload: unknown): void {\n res.statusCode = statusCode\n res.setHeader('Content-Type', 'application/json; charset=utf-8')\n res.end(JSON.stringify(payload))\n}\n\nfunction scoreFileCandidate(path: string, query: string): number {\n if (!query) return 0\n const lowerPath = path.toLowerCase()\n const lowerQuery = query.toLowerCase()\n const baseName = lowerPath.slice(lowerPath.lastIndexOf('/') + 1)\n if (baseName === lowerQuery) return 0\n if (baseName.startsWith(lowerQuery)) return 1\n if (baseName.includes(lowerQuery)) return 2\n if (lowerPath.includes(`/${lowerQuery}`)) return 3\n if (lowerPath.includes(lowerQuery)) return 4\n return 10\n}\n\nasync function listFilesWithRipgrep(cwd: string): Promise<string[]> {\n return await new Promise<string[]>((resolve, reject) => {\n const proc = spawn('rg', ['--files', '--hidden', '-g', '!.git', '-g', '!node_modules'], {\n cwd,\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n proc.stdout.on('data', (chunk: Buffer) => { stdout += chunk.toString() })\n proc.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString() })\n proc.on('error', reject)\n proc.on('close', (code) => {\n if (code === 0) {\n const rows = stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n resolve(rows)\n return\n }\n const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\\n')\n reject(new Error(details || 'rg --files failed'))\n })\n })\n}\n\nfunction getCodexHomeDir(): string {\n const codexHome = process.env.CODEX_HOME?.trim()\n return codexHome && codexHome.length > 0 ? codexHome : join(homedir(), '.codex')\n}\n\nfunction getSkillsInstallDir(): string {\n return join(getCodexHomeDir(), 'skills')\n}\n\nasync function runCommand(command: string, args: string[], options: { cwd?: string } = {}): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: options.cwd,\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n proc.stdout.on('data', (chunk: Buffer) => { stdout += chunk.toString() })\n proc.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString() })\n proc.on('error', reject)\n proc.on('close', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\\n')\n const suffix = details.length > 0 ? `: ${details}` : ''\n reject(new Error(`Command failed (${command} ${args.join(' ')})${suffix}`))\n })\n })\n}\n\nasync function detectUserSkillsDir(appServer: AppServerProcess): Promise<string> {\n try {\n const result = (await appServer.rpc('skills/list', {})) as {\n data?: Array<{ skills?: Array<{ scope?: string; path?: string }> }>\n }\n for (const entry of result.data ?? []) {\n for (const skill of entry.skills ?? []) {\n if (skill.scope !== 'user' || !skill.path) continue\n const parts = skill.path.split('/').filter(Boolean)\n if (parts.length < 2) continue\n return `/${parts.slice(0, -2).join('/')}`\n }\n }\n } catch {}\n return getSkillsInstallDir()\n}\n\nasync function ensureInstalledSkillIsValid(appServer: AppServerProcess, skillPath: string): Promise<void> {\n const result = (await appServer.rpc('skills/list', { forceReload: true })) as {\n data?: Array<{ errors?: Array<{ path?: string; message?: string }> }>\n }\n const normalized = skillPath.endsWith('/SKILL.md') ? skillPath : `${skillPath}/SKILL.md`\n for (const entry of result.data ?? []) {\n for (const error of entry.errors ?? []) {\n if (error.path === normalized) {\n throw new Error(error.message || 'Installed skill is invalid')\n }\n }\n }\n}\n\ntype SkillHubEntry = {\n name: string\n owner: string\n description: string\n displayName: string\n publishedAt: number\n avatarUrl: string\n url: string\n installed: boolean\n path?: string\n enabled?: boolean\n}\n\ntype SkillsTreeEntry = {\n name: string\n owner: string\n url: string\n}\n\ntype SkillsTreeCache = {\n entries: SkillsTreeEntry[]\n fetchedAt: number\n}\n\ntype MetaJson = {\n displayName?: string\n owner?: string\n slug?: string\n latest?: { publishedAt?: number }\n}\n\nconst TREE_CACHE_TTL_MS = 5 * 60 * 1000\nlet skillsTreeCache: SkillsTreeCache | null = null\nconst metaCache = new Map<string, { description: string; displayName: string; publishedAt: number }>()\n\nasync function getGhToken(): Promise<string | null> {\n try {\n const proc = spawn('gh', ['auth', 'token'], { stdio: ['ignore', 'pipe', 'ignore'] })\n let out = ''\n proc.stdout.on('data', (d: Buffer) => { out += d.toString() })\n return new Promise((resolve) => {\n proc.on('close', (code) => resolve(code === 0 ? out.trim() : null))\n proc.on('error', () => resolve(null))\n })\n } catch { return null }\n}\n\nasync function ghFetch(url: string): Promise<Response> {\n const token = await getGhToken()\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'codex-web-local',\n }\n if (token) headers.Authorization = `Bearer ${token}`\n return fetch(url, { headers })\n}\n\nasync function fetchSkillsTree(): Promise<SkillsTreeEntry[]> {\n if (skillsTreeCache && Date.now() - skillsTreeCache.fetchedAt < TREE_CACHE_TTL_MS) {\n return skillsTreeCache.entries\n }\n\n const resp = await ghFetch('https://api.github.com/repos/openclaw/skills/git/trees/main?recursive=1')\n if (!resp.ok) throw new Error(`GitHub tree API returned ${resp.status}`)\n const data = (await resp.json()) as { tree?: Array<{ path: string; type: string }> }\n\n const metaPattern = /^skills\\/([^/]+)\\/([^/]+)\\/_meta\\.json$/\n const seen = new Set<string>()\n const entries: SkillsTreeEntry[] = []\n\n for (const node of data.tree ?? []) {\n const match = metaPattern.exec(node.path)\n if (!match) continue\n const [, owner, skillName] = match\n const key = `${owner}/${skillName}`\n if (seen.has(key)) continue\n seen.add(key)\n entries.push({\n name: skillName,\n owner,\n url: `https://github.com/openclaw/skills/tree/main/skills/${owner}/${skillName}`,\n })\n }\n\n skillsTreeCache = { entries, fetchedAt: Date.now() }\n return entries\n}\n\nasync function fetchMetaBatch(entries: SkillsTreeEntry[]): Promise<void> {\n const toFetch = entries.filter((e) => !metaCache.has(`${e.owner}/${e.name}`))\n if (toFetch.length === 0) return\n\n const batch = toFetch.slice(0, 50)\n const results = await Promise.allSettled(\n batch.map(async (e) => {\n const rawUrl = `https://raw.githubusercontent.com/openclaw/skills/main/skills/${e.owner}/${e.name}/_meta.json`\n const resp = await fetch(rawUrl)\n if (!resp.ok) return\n const meta = (await resp.json()) as MetaJson\n metaCache.set(`${e.owner}/${e.name}`, {\n displayName: typeof meta.displayName === 'string' ? meta.displayName : '',\n description: typeof meta.displayName === 'string' ? meta.displayName : '',\n publishedAt: meta.latest?.publishedAt ?? 0,\n })\n }),\n )\n void results\n}\n\nfunction buildHubEntry(e: SkillsTreeEntry): SkillHubEntry {\n const cached = metaCache.get(`${e.owner}/${e.name}`)\n return {\n name: e.name,\n owner: e.owner,\n description: cached?.description ?? '',\n displayName: cached?.displayName ?? '',\n publishedAt: cached?.publishedAt ?? 0,\n avatarUrl: `https://github.com/${e.owner}.png?size=40`,\n url: e.url,\n installed: false,\n }\n}\n\ntype InstalledSkillInfo = { name: string; path: string; enabled: boolean }\n\nasync function scanInstalledSkillsFromDisk(): Promise<Map<string, InstalledSkillInfo>> {\n const map = new Map<string, InstalledSkillInfo>()\n const skillsDir = getSkillsInstallDir()\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true })\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith('.')) continue\n const skillMd = join(skillsDir, entry.name, 'SKILL.md')\n try {\n await stat(skillMd)\n map.set(entry.name, { name: entry.name, path: skillMd, enabled: true })\n } catch {}\n }\n } catch {}\n return map\n}\n\nasync function searchSkillsHub(\n allEntries: SkillsTreeEntry[],\n query: string,\n limit: number,\n sort: string,\n installedMap: Map<string, InstalledSkillInfo>,\n): Promise<SkillHubEntry[]> {\n const q = query.toLowerCase().trim()\n let filtered = q\n ? allEntries.filter((s) => {\n if (s.name.toLowerCase().includes(q) || s.owner.toLowerCase().includes(q)) return true\n const cached = metaCache.get(`${s.owner}/${s.name}`)\n if (cached?.displayName?.toLowerCase().includes(q)) return true\n return false\n })\n : allEntries\n\n const page = filtered.slice(0, Math.min(limit * 2, 200))\n await fetchMetaBatch(page)\n\n let results = page.map(buildHubEntry)\n\n if (sort === 'date') {\n results.sort((a, b) => b.publishedAt - a.publishedAt)\n } else if (q) {\n results.sort((a, b) => {\n const aExact = a.name.toLowerCase() === q ? 1 : 0\n const bExact = b.name.toLowerCase() === q ? 1 : 0\n if (aExact !== bExact) return bExact - aExact\n return b.publishedAt - a.publishedAt\n })\n }\n\n return results.slice(0, limit).map((s) => {\n const local = installedMap.get(s.name)\n return local\n ? { ...s, installed: true, path: local.path, enabled: local.enabled }\n : s\n })\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n const normalized: string[] = []\n for (const item of value) {\n if (typeof item === 'string' && item.length > 0 && !normalized.includes(item)) {\n normalized.push(item)\n }\n }\n return normalized\n}\n\nfunction normalizeStringRecord(value: unknown): Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n const next: Record<string, string> = {}\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof key === 'string' && key.length > 0 && typeof item === 'string') {\n next[key] = item\n }\n }\n return next\n}\n\nfunction getCodexAuthPath(): string {\n return join(getCodexHomeDir(), 'auth.json')\n}\n\ntype CodexAuth = {\n tokens?: {\n access_token?: string\n account_id?: string\n }\n}\n\nasync function readCodexAuth(): Promise<{ accessToken: string; accountId?: string } | null> {\n try {\n const raw = await readFile(getCodexAuthPath(), 'utf8')\n const auth = JSON.parse(raw) as CodexAuth\n const token = auth.tokens?.access_token\n if (!token) return null\n return { accessToken: token, accountId: auth.tokens?.account_id ?? undefined }\n } catch {\n return null\n }\n}\n\nfunction getCodexGlobalStatePath(): string {\n return join(getCodexHomeDir(), '.codex-global-state.json')\n}\n\ntype ThreadTitleCache = { titles: Record<string, string>; order: string[] }\nconst MAX_THREAD_TITLES = 500\n\nfunction normalizeThreadTitleCache(value: unknown): ThreadTitleCache {\n const record = asRecord(value)\n if (!record) return { titles: {}, order: [] }\n const rawTitles = asRecord(record.titles)\n const titles: Record<string, string> = {}\n if (rawTitles) {\n for (const [k, v] of Object.entries(rawTitles)) {\n if (typeof v === 'string' && v.length > 0) titles[k] = v\n }\n }\n const order = normalizeStringArray(record.order)\n return { titles, order }\n}\n\nfunction updateThreadTitleCache(cache: ThreadTitleCache, id: string, title: string): ThreadTitleCache {\n const titles = { ...cache.titles, [id]: title }\n const order = [id, ...cache.order.filter((o) => o !== id)]\n while (order.length > MAX_THREAD_TITLES) {\n const removed = order.pop()\n if (removed) delete titles[removed]\n }\n return { titles, order }\n}\n\nfunction removeFromThreadTitleCache(cache: ThreadTitleCache, id: string): ThreadTitleCache {\n const { [id]: _, ...titles } = cache.titles\n return { titles, order: cache.order.filter((o) => o !== id) }\n}\n\nasync function readThreadTitleCache(): Promise<ThreadTitleCache> {\n const statePath = getCodexGlobalStatePath()\n try {\n const raw = await readFile(statePath, 'utf8')\n const payload = asRecord(JSON.parse(raw)) ?? {}\n return normalizeThreadTitleCache(payload['thread-titles'])\n } catch {\n return { titles: {}, order: [] }\n }\n}\n\nasync function writeThreadTitleCache(cache: ThreadTitleCache): Promise<void> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n try {\n const raw = await readFile(statePath, 'utf8')\n payload = asRecord(JSON.parse(raw)) ?? {}\n } catch {\n payload = {}\n }\n payload['thread-titles'] = cache\n await writeFile(statePath, JSON.stringify(payload), 'utf8')\n}\n\nasync function readWorkspaceRootsState(): Promise<WorkspaceRootsState> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n\n try {\n const raw = await readFile(statePath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n payload = asRecord(parsed) ?? {}\n } catch {\n payload = {}\n }\n\n return {\n order: normalizeStringArray(payload['electron-saved-workspace-roots']),\n labels: normalizeStringRecord(payload['electron-workspace-root-labels']),\n active: normalizeStringArray(payload['active-workspace-roots']),\n }\n}\n\nasync function writeWorkspaceRootsState(nextState: WorkspaceRootsState): Promise<void> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n try {\n const raw = await readFile(statePath, 'utf8')\n payload = asRecord(JSON.parse(raw)) ?? {}\n } catch {\n payload = {}\n }\n\n payload['electron-saved-workspace-roots'] = normalizeStringArray(nextState.order)\n payload['electron-workspace-root-labels'] = normalizeStringRecord(nextState.labels)\n payload['active-workspace-roots'] = normalizeStringArray(nextState.active)\n\n await writeFile(statePath, JSON.stringify(payload), 'utf8')\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const raw = await readRawBody(req)\n if (raw.length === 0) return null\n const text = raw.toString('utf8').trim()\n if (text.length === 0) return null\n return JSON.parse(text) as unknown\n}\n\nasync function readRawBody(req: IncomingMessage): Promise<Buffer> {\n const chunks: Uint8Array[] = []\n for await (const chunk of req) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nfunction bufferIndexOf(buf: Buffer, needle: Buffer, start = 0): number {\n for (let i = start; i <= buf.length - needle.length; i++) {\n let match = true\n for (let j = 0; j < needle.length; j++) {\n if (buf[i + j] !== needle[j]) { match = false; break }\n }\n if (match) return i\n }\n return -1\n}\n\nfunction handleFileUpload(req: IncomingMessage, res: ServerResponse): void {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', async () => {\n try {\n const body = Buffer.concat(chunks)\n const contentType = req.headers['content-type'] ?? ''\n const boundaryMatch = contentType.match(/boundary=(.+)/i)\n if (!boundaryMatch) { setJson(res, 400, { error: 'Missing multipart boundary' }); return }\n const boundary = boundaryMatch[1]\n const boundaryBuf = Buffer.from(`--${boundary}`)\n const parts: Buffer[] = []\n let searchStart = 0\n while (searchStart < body.length) {\n const idx = body.indexOf(boundaryBuf, searchStart)\n if (idx < 0) break\n if (searchStart > 0) parts.push(body.subarray(searchStart, idx))\n searchStart = idx + boundaryBuf.length\n if (body[searchStart] === 0x0d && body[searchStart + 1] === 0x0a) searchStart += 2\n }\n let fileName = 'uploaded-file'\n let fileData: Buffer | null = null\n const headerSep = Buffer.from('\\r\\n\\r\\n')\n for (const part of parts) {\n const headerEnd = bufferIndexOf(part, headerSep)\n if (headerEnd < 0) continue\n const headers = part.subarray(0, headerEnd).toString('utf8')\n const fnMatch = headers.match(/filename=\"([^\"]+)\"/i)\n if (!fnMatch) continue\n fileName = fnMatch[1].replace(/[/\\\\]/g, '_')\n let end = part.length\n if (end >= 2 && part[end - 2] === 0x0d && part[end - 1] === 0x0a) end -= 2\n fileData = part.subarray(headerEnd + 4, end)\n break\n }\n if (!fileData) { setJson(res, 400, { error: 'No file in request' }); return }\n const uploadDir = join(tmpdir(), 'codex-web-uploads')\n await mkdir(uploadDir, { recursive: true })\n const destDir = await mkdtemp(join(uploadDir, 'f-'))\n const destPath = join(destDir, fileName)\n await writeFile(destPath, fileData)\n setJson(res, 200, { path: destPath })\n } catch (err) {\n setJson(res, 500, { error: getErrorMessage(err, 'Upload failed') })\n }\n })\n req.on('error', (err) => {\n setJson(res, 500, { error: getErrorMessage(err, 'Upload stream error') })\n })\n}\n\nasync function proxyTranscribe(\n body: Buffer,\n contentType: string,\n authToken: string,\n accountId?: string,\n): Promise<{ status: number; body: string }> {\n const headers: Record<string, string | number> = {\n 'Content-Type': contentType,\n 'Content-Length': body.length,\n Authorization: `Bearer ${authToken}`,\n originator: 'Codex Desktop',\n 'User-Agent': `Codex Desktop/0.1.0 (${process.platform}; ${process.arch})`,\n }\n\n if (accountId) {\n headers['ChatGPT-Account-Id'] = accountId\n }\n\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n 'https://chatgpt.com/backend-api/transcribe',\n { method: 'POST', headers },\n (res) => {\n const chunks: Buffer[] = []\n res.on('data', (c: Buffer) => chunks.push(c))\n res.on('end', () => resolve({ status: res.statusCode ?? 500, body: Buffer.concat(chunks).toString('utf8') }))\n res.on('error', reject)\n },\n )\n req.on('error', reject)\n req.write(body)\n req.end()\n })\n}\n\nclass AppServerProcess {\n private process: ChildProcessWithoutNullStreams | null = null\n private initialized = false\n private initializePromise: Promise<void> | null = null\n private readBuffer = ''\n private nextId = 1\n private stopping = false\n private readonly pending = new Map<number, { resolve: (value: unknown) => void; reject: (reason?: unknown) => void }>()\n private readonly notificationListeners = new Set<(value: { method: string; params: unknown }) => void>()\n private readonly pendingServerRequests = new Map<number, PendingServerRequest>()\n private readonly appServerArgs = [\n 'app-server',\n '-c',\n 'approval_policy=\"never\"',\n '-c',\n 'sandbox_mode=\"danger-full-access\"',\n ]\n\n private start(): void {\n if (this.process) return\n\n this.stopping = false\n const proc = spawn('codex', this.appServerArgs, { stdio: ['pipe', 'pipe', 'pipe'] })\n this.process = proc\n\n proc.stdout.setEncoding('utf8')\n proc.stdout.on('data', (chunk: string) => {\n this.readBuffer += chunk\n\n let lineEnd = this.readBuffer.indexOf('\\n')\n while (lineEnd !== -1) {\n const line = this.readBuffer.slice(0, lineEnd).trim()\n this.readBuffer = this.readBuffer.slice(lineEnd + 1)\n\n if (line.length > 0) {\n this.handleLine(line)\n }\n\n lineEnd = this.readBuffer.indexOf('\\n')\n }\n })\n\n proc.stderr.setEncoding('utf8')\n proc.stderr.on('data', () => {\n // Keep stderr silent in dev middleware; JSON-RPC errors are forwarded via responses.\n })\n\n proc.on('exit', () => {\n const failure = new Error(this.stopping ? 'codex app-server stopped' : 'codex app-server exited unexpectedly')\n for (const request of this.pending.values()) {\n request.reject(failure)\n }\n\n this.pending.clear()\n this.pendingServerRequests.clear()\n this.process = null\n this.initialized = false\n this.initializePromise = null\n this.readBuffer = ''\n })\n }\n\n private sendLine(payload: Record<string, unknown>): void {\n if (!this.process) {\n throw new Error('codex app-server is not running')\n }\n\n this.process.stdin.write(`${JSON.stringify(payload)}\\n`)\n }\n\n private handleLine(line: string): void {\n let message: JsonRpcResponse\n try {\n message = JSON.parse(line) as JsonRpcResponse\n } catch {\n return\n }\n\n if (typeof message.id === 'number' && this.pending.has(message.id)) {\n const pendingRequest = this.pending.get(message.id)\n this.pending.delete(message.id)\n\n if (!pendingRequest) return\n\n if (message.error) {\n pendingRequest.reject(new Error(message.error.message))\n } else {\n pendingRequest.resolve(message.result)\n }\n return\n }\n\n if (typeof message.method === 'string' && typeof message.id !== 'number') {\n this.emitNotification({\n method: message.method,\n params: message.params ?? null,\n })\n return\n }\n\n // Handle server-initiated JSON-RPC requests (approvals, dynamic tool calls, etc.).\n if (typeof message.id === 'number' && typeof message.method === 'string') {\n this.handleServerRequest(message.id, message.method, message.params ?? null)\n }\n }\n\n private emitNotification(notification: { method: string; params: unknown }): void {\n for (const listener of this.notificationListeners) {\n listener(notification)\n }\n }\n\n private sendServerRequestReply(requestId: number, reply: ServerRequestReply): void {\n if (reply.error) {\n this.sendLine({\n jsonrpc: '2.0',\n id: requestId,\n error: reply.error,\n })\n return\n }\n\n this.sendLine({\n jsonrpc: '2.0',\n id: requestId,\n result: reply.result ?? {},\n })\n }\n\n private resolvePendingServerRequest(requestId: number, reply: ServerRequestReply): void {\n const pendingRequest = this.pendingServerRequests.get(requestId)\n if (!pendingRequest) {\n throw new Error(`No pending server request found for id ${String(requestId)}`)\n }\n this.pendingServerRequests.delete(requestId)\n\n this.sendServerRequestReply(requestId, reply)\n const requestParams = asRecord(pendingRequest.params)\n const threadId =\n typeof requestParams?.threadId === 'string' && requestParams.threadId.length > 0\n ? requestParams.threadId\n : ''\n this.emitNotification({\n method: 'server/request/resolved',\n params: {\n id: requestId,\n method: pendingRequest.method,\n threadId,\n mode: 'manual',\n resolvedAtIso: new Date().toISOString(),\n },\n })\n }\n\n private handleServerRequest(requestId: number, method: string, params: unknown): void {\n const pendingRequest: PendingServerRequest = {\n id: requestId,\n method,\n params,\n receivedAtIso: new Date().toISOString(),\n }\n this.pendingServerRequests.set(requestId, pendingRequest)\n\n this.emitNotification({\n method: 'server/request',\n params: pendingRequest,\n })\n }\n\n private async call(method: string, params: unknown): Promise<unknown> {\n this.start()\n const id = this.nextId++\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject })\n\n this.sendLine({\n jsonrpc: '2.0',\n id,\n method,\n params,\n } satisfies JsonRpcCall)\n })\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return\n if (this.initializePromise) {\n await this.initializePromise\n return\n }\n\n this.initializePromise = this.call('initialize', {\n clientInfo: {\n name: 'codex-web-local',\n version: '0.1.0',\n },\n }).then(() => {\n this.initialized = true\n }).finally(() => {\n this.initializePromise = null\n })\n\n await this.initializePromise\n }\n\n async rpc(method: string, params: unknown): Promise<unknown> {\n await this.ensureInitialized()\n return this.call(method, params)\n }\n\n onNotification(listener: (value: { method: string; params: unknown }) => void): () => void {\n this.notificationListeners.add(listener)\n return () => {\n this.notificationListeners.delete(listener)\n }\n }\n\n async respondToServerRequest(payload: unknown): Promise<void> {\n await this.ensureInitialized()\n\n const body = asRecord(payload)\n if (!body) {\n throw new Error('Invalid response payload: expected object')\n }\n\n const id = body.id\n if (typeof id !== 'number' || !Number.isInteger(id)) {\n throw new Error('Invalid response payload: \"id\" must be an integer')\n }\n\n const rawError = asRecord(body.error)\n if (rawError) {\n const message = typeof rawError.message === 'string' && rawError.message.trim().length > 0\n ? rawError.message.trim()\n : 'Server request rejected by client'\n const code = typeof rawError.code === 'number' && Number.isFinite(rawError.code)\n ? Math.trunc(rawError.code)\n : -32000\n this.resolvePendingServerRequest(id, { error: { code, message } })\n return\n }\n\n if (!('result' in body)) {\n throw new Error('Invalid response payload: expected \"result\" or \"error\"')\n }\n\n this.resolvePendingServerRequest(id, { result: body.result })\n }\n\n listPendingServerRequests(): PendingServerRequest[] {\n return Array.from(this.pendingServerRequests.values())\n }\n\n dispose(): void {\n if (!this.process) return\n\n const proc = this.process\n this.stopping = true\n this.process = null\n this.initialized = false\n this.initializePromise = null\n this.readBuffer = ''\n\n const failure = new Error('codex app-server stopped')\n for (const request of this.pending.values()) {\n request.reject(failure)\n }\n this.pending.clear()\n this.pendingServerRequests.clear()\n\n try {\n proc.stdin.end()\n } catch {\n // ignore close errors on shutdown\n }\n\n try {\n proc.kill('SIGTERM')\n } catch {\n // ignore kill errors on shutdown\n }\n\n const forceKillTimer = setTimeout(() => {\n if (!proc.killed) {\n try {\n proc.kill('SIGKILL')\n } catch {\n // ignore kill errors on shutdown\n }\n }\n }, 1500)\n forceKillTimer.unref()\n }\n}\n\nclass MethodCatalog {\n private methodCache: string[] | null = null\n private notificationCache: string[] | null = null\n\n private async runGenerateSchemaCommand(outDir: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const process = spawn('codex', ['app-server', 'generate-json-schema', '--out', outDir], {\n stdio: ['ignore', 'ignore', 'pipe'],\n })\n\n let stderr = ''\n\n process.stderr.setEncoding('utf8')\n process.stderr.on('data', (chunk: string) => {\n stderr += chunk\n })\n\n process.on('error', reject)\n process.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(stderr.trim() || `generate-json-schema exited with code ${String(code)}`))\n })\n })\n }\n\n private extractMethodsFromClientRequest(payload: unknown): string[] {\n const root = asRecord(payload)\n const oneOf = Array.isArray(root?.oneOf) ? root.oneOf : []\n const methods = new Set<string>()\n\n for (const entry of oneOf) {\n const row = asRecord(entry)\n const properties = asRecord(row?.properties)\n const methodDef = asRecord(properties?.method)\n const methodEnum = Array.isArray(methodDef?.enum) ? methodDef.enum : []\n\n for (const item of methodEnum) {\n if (typeof item === 'string' && item.length > 0) {\n methods.add(item)\n }\n }\n }\n\n return Array.from(methods).sort((a, b) => a.localeCompare(b))\n }\n\n private extractMethodsFromServerNotification(payload: unknown): string[] {\n const root = asRecord(payload)\n const oneOf = Array.isArray(root?.oneOf) ? root.oneOf : []\n const methods = new Set<string>()\n\n for (const entry of oneOf) {\n const row = asRecord(entry)\n const properties = asRecord(row?.properties)\n const methodDef = asRecord(properties?.method)\n const methodEnum = Array.isArray(methodDef?.enum) ? methodDef.enum : []\n\n for (const item of methodEnum) {\n if (typeof item === 'string' && item.length > 0) {\n methods.add(item)\n }\n }\n }\n\n return Array.from(methods).sort((a, b) => a.localeCompare(b))\n }\n\n async listMethods(): Promise<string[]> {\n if (this.methodCache) {\n return this.methodCache\n }\n\n const outDir = await mkdtemp(join(tmpdir(), 'codex-web-local-schema-'))\n await this.runGenerateSchemaCommand(outDir)\n\n const clientRequestPath = join(outDir, 'ClientRequest.json')\n const raw = await readFile(clientRequestPath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n const methods = this.extractMethodsFromClientRequest(parsed)\n\n this.methodCache = methods\n return methods\n }\n\n async listNotificationMethods(): Promise<string[]> {\n if (this.notificationCache) {\n return this.notificationCache\n }\n\n const outDir = await mkdtemp(join(tmpdir(), 'codex-web-local-schema-'))\n await this.runGenerateSchemaCommand(outDir)\n\n const serverNotificationPath = join(outDir, 'ServerNotification.json')\n const raw = await readFile(serverNotificationPath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n const methods = this.extractMethodsFromServerNotification(parsed)\n\n this.notificationCache = methods\n return methods\n }\n}\n\ntype CodexBridgeMiddleware = ((req: IncomingMessage, res: ServerResponse, next: () => void) => Promise<void>) & {\n dispose: () => void\n}\n\ntype SharedBridgeState = {\n appServer: AppServerProcess\n methodCatalog: MethodCatalog\n}\n\nconst SHARED_BRIDGE_KEY = '__codexRemoteSharedBridge__'\n\nfunction getSharedBridgeState(): SharedBridgeState {\n const globalScope = globalThis as typeof globalThis & {\n [SHARED_BRIDGE_KEY]?: SharedBridgeState\n }\n\n const existing = globalScope[SHARED_BRIDGE_KEY]\n if (existing) return existing\n\n const created: SharedBridgeState = {\n appServer: new AppServerProcess(),\n methodCatalog: new MethodCatalog(),\n }\n globalScope[SHARED_BRIDGE_KEY] = created\n return created\n}\n\nexport function createCodexBridgeMiddleware(): CodexBridgeMiddleware {\n const { appServer, methodCatalog } = getSharedBridgeState()\n\n const middleware = async (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n try {\n if (!req.url) {\n next()\n return\n }\n\n const url = new URL(req.url, 'http://localhost')\n\n if (req.method === 'POST' && url.pathname === '/codex-api/upload-file') {\n handleFileUpload(req, res)\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/rpc') {\n const payload = await readJsonBody(req)\n const body = asRecord(payload) as RpcProxyRequest | null\n\n if (!body || typeof body.method !== 'string' || body.method.length === 0) {\n setJson(res, 400, { error: 'Invalid body: expected { method, params? }' })\n return\n }\n\n const result = await appServer.rpc(body.method, body.params ?? null)\n setJson(res, 200, { result })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/transcribe') {\n const auth = await readCodexAuth()\n if (!auth) {\n setJson(res, 401, { error: 'No auth token available for transcription' })\n return\n }\n\n const rawBody = await readRawBody(req)\n const incomingCt = req.headers['content-type'] ?? 'application/octet-stream'\n const upstream = await proxyTranscribe(rawBody, incomingCt, auth.accessToken, auth.accountId)\n\n res.statusCode = upstream.status\n res.setHeader('Content-Type', 'application/json; charset=utf-8')\n res.end(upstream.body)\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/server-requests/respond') {\n const payload = await readJsonBody(req)\n await appServer.respondToServerRequest(payload)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/server-requests/pending') {\n setJson(res, 200, { data: appServer.listPendingServerRequests() })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/meta/methods') {\n const methods = await methodCatalog.listMethods()\n setJson(res, 200, { data: methods })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/meta/notifications') {\n const methods = await methodCatalog.listNotificationMethods()\n setJson(res, 200, { data: methods })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/workspace-roots-state') {\n const state = await readWorkspaceRootsState()\n setJson(res, 200, { data: state })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/home-directory') {\n setJson(res, 200, { data: { path: homedir() } })\n return\n }\n\n if (req.method === 'PUT' && url.pathname === '/codex-api/workspace-roots-state') {\n const payload = await readJsonBody(req)\n const record = asRecord(payload)\n if (!record) {\n setJson(res, 400, { error: 'Invalid body: expected object' })\n return\n }\n const nextState: WorkspaceRootsState = {\n order: normalizeStringArray(record.order),\n labels: normalizeStringRecord(record.labels),\n active: normalizeStringArray(record.active),\n }\n await writeWorkspaceRootsState(nextState)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/project-root') {\n const payload = asRecord(await readJsonBody(req))\n const rawPath = typeof payload?.path === 'string' ? payload.path.trim() : ''\n const createIfMissing = payload?.createIfMissing === true\n const label = typeof payload?.label === 'string' ? payload.label : ''\n if (!rawPath) {\n setJson(res, 400, { error: 'Missing path' })\n return\n }\n\n const normalizedPath = isAbsolute(rawPath) ? rawPath : resolve(rawPath)\n let pathExists = true\n try {\n const info = await stat(normalizedPath)\n if (!info.isDirectory()) {\n setJson(res, 400, { error: 'Path exists but is not a directory' })\n return\n }\n } catch {\n pathExists = false\n }\n\n if (!pathExists && createIfMissing) {\n await mkdir(normalizedPath, { recursive: true })\n } else if (!pathExists) {\n setJson(res, 404, { error: 'Directory does not exist' })\n return\n }\n\n const existingState = await readWorkspaceRootsState()\n const nextOrder = [normalizedPath, ...existingState.order.filter((item) => item !== normalizedPath)]\n const nextActive = [normalizedPath, ...existingState.active.filter((item) => item !== normalizedPath)]\n const nextLabels = { ...existingState.labels }\n if (label.trim().length > 0) {\n nextLabels[normalizedPath] = label.trim()\n }\n await writeWorkspaceRootsState({\n order: nextOrder,\n labels: nextLabels,\n active: nextActive,\n })\n setJson(res, 200, { data: { path: normalizedPath } })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/project-root-suggestion') {\n const basePath = url.searchParams.get('basePath')?.trim() ?? ''\n if (!basePath) {\n setJson(res, 400, { error: 'Missing basePath' })\n return\n }\n const normalizedBasePath = isAbsolute(basePath) ? basePath : resolve(basePath)\n try {\n const baseInfo = await stat(normalizedBasePath)\n if (!baseInfo.isDirectory()) {\n setJson(res, 400, { error: 'basePath is not a directory' })\n return\n }\n } catch {\n setJson(res, 404, { error: 'basePath does not exist' })\n return\n }\n\n let index = 1\n while (index < 100000) {\n const candidateName = `New Project (${String(index)})`\n const candidatePath = join(normalizedBasePath, candidateName)\n try {\n await stat(candidatePath)\n index += 1\n continue\n } catch {\n setJson(res, 200, { data: { name: candidateName, path: candidatePath } })\n return\n }\n }\n\n setJson(res, 500, { error: 'Failed to compute project name suggestion' })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/composer-file-search') {\n const payload = asRecord(await readJsonBody(req))\n const rawCwd = typeof payload?.cwd === 'string' ? payload.cwd.trim() : ''\n const query = typeof payload?.query === 'string' ? payload.query.trim() : ''\n const limitRaw = typeof payload?.limit === 'number' ? payload.limit : 20\n const limit = Math.max(1, Math.min(100, Math.floor(limitRaw)))\n if (!rawCwd) {\n setJson(res, 400, { error: 'Missing cwd' })\n return\n }\n const cwd = isAbsolute(rawCwd) ? rawCwd : resolve(rawCwd)\n try {\n const info = await stat(cwd)\n if (!info.isDirectory()) {\n setJson(res, 400, { error: 'cwd is not a directory' })\n return\n }\n } catch {\n setJson(res, 404, { error: 'cwd does not exist' })\n return\n }\n\n try {\n const files = await listFilesWithRipgrep(cwd)\n const scored = files\n .map((path) => ({ path, score: scoreFileCandidate(path, query) }))\n .filter((row) => query.length === 0 || row.score < 10)\n .sort((a, b) => (a.score - b.score) || a.path.localeCompare(b.path))\n .slice(0, limit)\n .map((row) => ({ path: row.path }))\n setJson(res, 200, { data: scored })\n } catch (error) {\n setJson(res, 500, { error: getErrorMessage(error, 'Failed to search files') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/thread-titles') {\n const cache = await readThreadTitleCache()\n setJson(res, 200, { data: cache })\n return\n }\n\n if (req.method === 'PUT' && url.pathname === '/codex-api/thread-titles') {\n const payload = asRecord(await readJsonBody(req))\n const id = typeof payload?.id === 'string' ? payload.id : ''\n const title = typeof payload?.title === 'string' ? payload.title : ''\n if (!id) {\n setJson(res, 400, { error: 'Missing id' })\n return\n }\n const cache = await readThreadTitleCache()\n const next = title ? updateThreadTitleCache(cache, id, title) : removeFromThreadTitleCache(cache, id)\n await writeThreadTitleCache(next)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/skills-hub') {\n try {\n const q = url.searchParams.get('q') || ''\n const limit = Math.min(Math.max(parseInt(url.searchParams.get('limit') || '50', 10) || 50, 1), 200)\n const sort = url.searchParams.get('sort') || 'date'\n const allEntries = await fetchSkillsTree()\n\n const installedMap = await scanInstalledSkillsFromDisk()\n try {\n const result = (await appServer.rpc('skills/list', {})) as { data?: Array<{ skills?: Array<{ name?: string; path?: string; enabled?: boolean }> }> }\n for (const entry of result.data ?? []) {\n for (const skill of entry.skills ?? []) {\n if (skill.name) {\n installedMap.set(skill.name, { name: skill.name, path: skill.path ?? '', enabled: skill.enabled !== false })\n }\n }\n }\n } catch {}\n\n const installedHubEntries = allEntries.filter((e) => installedMap.has(e.name))\n await fetchMetaBatch(installedHubEntries)\n\n const installed: SkillHubEntry[] = []\n for (const [, info] of installedMap) {\n const hubEntry = allEntries.find((e) => e.name === info.name)\n const base = hubEntry ? buildHubEntry(hubEntry) : {\n name: info.name, owner: 'local', description: '', displayName: '',\n publishedAt: 0, avatarUrl: '', url: '', installed: false,\n }\n installed.push({ ...base, installed: true, path: info.path, enabled: info.enabled })\n }\n\n const results = await searchSkillsHub(allEntries, q, limit, sort, installedMap)\n setJson(res, 200, { data: results, installed, total: allEntries.length })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to fetch skills hub') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/skills-hub/readme') {\n try {\n const owner = url.searchParams.get('owner') || ''\n const name = url.searchParams.get('name') || ''\n if (!owner || !name) {\n setJson(res, 400, { error: 'Missing owner or name' })\n return\n }\n const rawUrl = `https://raw.githubusercontent.com/openclaw/skills/main/skills/${owner}/${name}/SKILL.md`\n const resp = await fetch(rawUrl)\n if (!resp.ok) throw new Error(`Failed to fetch SKILL.md: ${resp.status}`)\n const content = await resp.text()\n setJson(res, 200, { content })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to fetch SKILL.md') })\n }\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/skills-hub/install') {\n try {\n const payload = asRecord(await readJsonBody(req))\n const owner = typeof payload?.owner === 'string' ? payload.owner : ''\n const name = typeof payload?.name === 'string' ? payload.name : ''\n if (!owner || !name) {\n setJson(res, 400, { error: 'Missing owner or name' })\n return\n }\n const installerScript = '/Users/igor/.cursor/skills/.system/skill-installer/scripts/install-skill-from-github.py'\n const installDest = await detectUserSkillsDir(appServer)\n const skillPathInRepo = `skills/${owner}/${name}`\n await runCommand('python3', [\n installerScript,\n '--repo', 'openclaw/skills',\n '--path', skillPathInRepo,\n '--dest', installDest,\n '--method', 'git',\n ])\n const skillDir = join(installDest, name)\n await ensureInstalledSkillIsValid(appServer, skillDir)\n setJson(res, 200, { ok: true, path: skillDir })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to install skill') })\n }\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/skills-hub/uninstall') {\n try {\n const payload = asRecord(await readJsonBody(req))\n const name = typeof payload?.name === 'string' ? payload.name : ''\n const path = typeof payload?.path === 'string' ? payload.path : ''\n const target = path || (name ? join(getSkillsInstallDir(), name) : '')\n if (!target) {\n setJson(res, 400, { error: 'Missing name or path' })\n return\n }\n await rm(target, { recursive: true, force: true })\n try { await appServer.rpc('skills/list', { forceReload: true }) } catch {}\n setJson(res, 200, { ok: true, deletedPath: target })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to uninstall skill') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/events') {\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8')\n res.setHeader('Cache-Control', 'no-cache, no-transform')\n res.setHeader('Connection', 'keep-alive')\n res.setHeader('X-Accel-Buffering', 'no')\n\n const unsubscribe = appServer.onNotification((notification) => {\n if (res.writableEnded || res.destroyed) return\n const payload = {\n ...notification,\n atIso: new Date().toISOString(),\n }\n res.write(`data: ${JSON.stringify(payload)}\\n\\n`)\n })\n\n res.write(`event: ready\\ndata: ${JSON.stringify({ ok: true })}\\n\\n`)\n const keepAlive = setInterval(() => {\n res.write(': ping\\n\\n')\n }, 15000)\n\n const close = () => {\n clearInterval(keepAlive)\n unsubscribe()\n if (!res.writableEnded) {\n res.end()\n }\n }\n\n req.on('close', close)\n req.on('aborted', close)\n return\n }\n\n next()\n } catch (error) {\n const message = getErrorMessage(error, 'Unknown bridge error')\n setJson(res, 502, { error: message })\n }\n }\n\n middleware.dispose = () => {\n appServer.dispose()\n }\n\n return middleware\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto'\nimport type { RequestHandler, Request, Response, NextFunction } from 'express'\n\nconst TOKEN_COOKIE = 'codex_web_local_token'\n\nfunction isLocalhostRequest(req: Request): boolean {\n const remote = req.socket.remoteAddress ?? ''\n if (remote === '127.0.0.1' || remote === '::1' || remote === '::ffff:127.0.0.1') {\n return true\n }\n\n const host = (req.headers.host ?? '').toLowerCase()\n return host.startsWith('localhost:') || host === 'localhost' || host.startsWith('127.0.0.1:')\n}\n\nfunction constantTimeCompare(a: string, b: string): boolean {\n const bufA = Buffer.from(a)\n const bufB = Buffer.from(b)\n if (bufA.length !== bufB.length) return false\n return timingSafeEqual(bufA, bufB)\n}\n\nfunction parseCookies(header: string | undefined): Record<string, string> {\n const cookies: Record<string, string> = {}\n if (!header) return cookies\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=')\n if (idx === -1) continue\n const key = pair.slice(0, idx).trim()\n const value = pair.slice(idx + 1).trim()\n cookies[key] = value\n }\n return cookies\n}\n\nconst LOGIN_PAGE_HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Codex Web Local &mdash; Login</title>\n<style>\n*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}\nbody{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;background:#0a0a0a;color:#e5e5e5;display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}\n.card{background:#171717;border:1px solid #262626;border-radius:12px;padding:2rem;width:100%;max-width:380px}\nh1{font-size:1.25rem;font-weight:600;margin-bottom:1.5rem;text-align:center;color:#fafafa}\nlabel{display:block;font-size:.875rem;color:#a3a3a3;margin-bottom:.5rem}\ninput{width:100%;padding:.625rem .75rem;background:#0a0a0a;border:1px solid #404040;border-radius:8px;color:#fafafa;font-size:1rem;outline:none;transition:border-color .15s}\ninput:focus{border-color:#3b82f6}\nbutton{width:100%;padding:.625rem;margin-top:1rem;background:#3b82f6;color:#fff;border:none;border-radius:8px;font-size:.9375rem;font-weight:500;cursor:pointer;transition:background .15s}\nbutton:hover{background:#2563eb}\n.error{color:#ef4444;font-size:.8125rem;margin-top:.75rem;text-align:center;display:none}\n</style>\n</head>\n<body>\n<div class=\"card\">\n<h1>Codex Web Local</h1>\n<form id=\"f\">\n<label for=\"pw\">Password</label>\n<input id=\"pw\" name=\"password\" type=\"password\" autocomplete=\"current-password\" autofocus required>\n<button type=\"submit\">Sign in</button>\n<p class=\"error\" id=\"err\">Incorrect password</p>\n</form>\n</div>\n<script>\nconst form=document.getElementById('f');\nconst errEl=document.getElementById('err');\nform.addEventListener('submit',async e=>{\n e.preventDefault();\n errEl.style.display='none';\n const res=await fetch('/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:document.getElementById('pw').value})});\n if(res.ok){window.location.reload()}else{errEl.style.display='block';document.getElementById('pw').value='';document.getElementById('pw').focus()}\n});\n</script>\n</body>\n</html>`\n\nexport function createAuthMiddleware(password: string): RequestHandler {\n const validTokens = new Set<string>()\n\n return (req: Request, res: Response, next: NextFunction): void => {\n if (isLocalhostRequest(req)) {\n next()\n return\n }\n\n // Handle login POST\n if (req.method === 'POST' && req.path === '/auth/login') {\n let body = ''\n req.setEncoding('utf8')\n req.on('data', (chunk: string) => { body += chunk })\n req.on('end', () => {\n try {\n const parsed = JSON.parse(body) as { password?: string }\n const provided = typeof parsed.password === 'string' ? parsed.password : ''\n\n if (!constantTimeCompare(provided, password)) {\n res.status(401).json({ error: 'Invalid password' })\n return\n }\n\n const token = randomBytes(32).toString('hex')\n validTokens.add(token)\n\n res.setHeader('Set-Cookie', `${TOKEN_COOKIE}=${token}; Path=/; HttpOnly; SameSite=Strict`)\n res.json({ ok: true })\n } catch {\n res.status(400).json({ error: 'Invalid request body' })\n }\n })\n return\n }\n\n // Check for valid token cookie\n const cookies = parseCookies(req.headers.cookie)\n const token = cookies[TOKEN_COOKIE]\n\n if (token && validTokens.has(token)) {\n next()\n return\n }\n\n // No valid session — serve login page\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.status(200).send(LOGIN_PAGE_HTML)\n }\n}\n","import { randomInt } from 'node:crypto'\n\nconst CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789'\n\nfunction randomGroup(length: number): string {\n let result = ''\n for (let i = 0; i < length; i++) {\n result += CHARS[randomInt(CHARS.length)]\n }\n return result\n}\n\nexport function generatePassword(): string {\n return `${randomGroup(3)}-${randomGroup(3)}-${randomGroup(3)}`\n}\n"],"mappings":"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","names":["createServer","readFile","homedir","join","spawn","fileURLToPath","dirname","isAbsolute","join","resolve","process","next","token","join","isAbsolute","__dirname","dirname","fileURLToPath","join","readFile","homedir","spawn","resolve","createServer"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/server/httpServer.ts","../src/server/codexAppServerBridge.ts","../src/server/authMiddleware.ts","../src/server/password.ts"],"sourcesContent":["import { createServer } from 'node:http'\nimport { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { spawn, spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname } from 'node:path'\nimport { Command } from 'commander'\nimport { createServer as createApp } from '../server/httpServer.js'\nimport { generatePassword } from '../server/password.js'\n\nconst program = new Command().name('codexui').description('Web interface for Codex app-server')\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nasync function readCliVersion(): Promise<string> {\n try {\n const packageJsonPath = join(__dirname, '..', 'package.json')\n const raw = await readFile(packageJsonPath, 'utf8')\n const parsed = JSON.parse(raw) as { version?: unknown }\n return typeof parsed.version === 'string' ? parsed.version : 'unknown'\n } catch {\n return 'unknown'\n }\n}\n\nfunction isTermuxRuntime(): boolean {\n return Boolean(process.env.TERMUX_VERSION || process.env.PREFIX?.includes('/com.termux/'))\n}\n\nfunction canRun(command: string, args: string[] = []): boolean {\n const result = spawnSync(command, args, { stdio: 'ignore' })\n return result.status === 0\n}\n\nfunction runOrFail(command: string, args: string[], label: string): void {\n const result = spawnSync(command, args, { stdio: 'inherit' })\n if (result.status !== 0) {\n throw new Error(`${label} failed with exit code ${String(result.status ?? -1)}`)\n }\n}\n\nfunction runWithStatus(command: string, args: string[]): number {\n const result = spawnSync(command, args, { stdio: 'inherit' })\n return result.status ?? -1\n}\n\nfunction getUserNpmPrefix(): string {\n return join(homedir(), '.npm-global')\n}\n\nfunction resolveCodexCommand(): string | null {\n if (canRun('codex', ['--version'])) {\n return 'codex'\n }\n\n const userCandidate = join(getUserNpmPrefix(), 'bin', 'codex')\n if (existsSync(userCandidate) && canRun(userCandidate, ['--version'])) {\n return userCandidate\n }\n\n const prefix = process.env.PREFIX?.trim()\n if (!prefix) {\n return null\n }\n const candidate = join(prefix, 'bin', 'codex')\n if (existsSync(candidate) && canRun(candidate, ['--version'])) {\n return candidate\n }\n return null\n}\n\nfunction hasCodexAuth(): boolean {\n const codexHome = process.env.CODEX_HOME?.trim() || join(homedir(), '.codex')\n return existsSync(join(codexHome, 'auth.json'))\n}\n\nfunction ensureCodexInstalled(): string | null {\n let codexCommand = resolveCodexCommand()\n if (!codexCommand) {\n const installWithFallback = (pkg: string, label: string): void => {\n const status = runWithStatus('npm', ['install', '-g', pkg])\n if (status === 0) {\n return\n }\n if (isTermuxRuntime()) {\n throw new Error(`${label} failed with exit code ${String(status)}`)\n }\n const userPrefix = getUserNpmPrefix()\n console.log(`\\nGlobal npm install requires elevated permissions. Retrying with --prefix ${userPrefix}...\\n`)\n runOrFail('npm', ['install', '-g', '--prefix', userPrefix, pkg], `${label} (user prefix)`)\n process.env.PATH = `${join(userPrefix, 'bin')}:${process.env.PATH ?? ''}`\n }\n\n if (isTermuxRuntime()) {\n console.log('\\nCodex CLI not found. Installing Termux-compatible Codex CLI from npm...\\n')\n installWithFallback('@mmmbuto/codex-cli-termux', 'Codex CLI install')\n codexCommand = resolveCodexCommand()\n if (!codexCommand) {\n console.log('\\nTermux npm package did not expose `codex`. Installing official CLI fallback...\\n')\n installWithFallback('@openai/codex', 'Codex CLI fallback install')\n }\n } else {\n console.log('\\nCodex CLI not found. Installing official Codex CLI from npm...\\n')\n installWithFallback('@openai/codex', 'Codex CLI install')\n }\n\n codexCommand = resolveCodexCommand()\n if (!codexCommand && !isTermuxRuntime()) {\n // Non-Termux path should resolve after official package install.\n throw new Error('Official Codex CLI install completed but binary is still not available in PATH')\n }\n if (!codexCommand && isTermuxRuntime()) {\n codexCommand = resolveCodexCommand()\n }\n if (!codexCommand) {\n throw new Error('Codex CLI install completed but binary is still not available in PATH')\n }\n console.log('\\nCodex CLI installed.\\n')\n }\n return codexCommand\n}\n\nfunction resolvePassword(input: string | boolean): string | undefined {\n if (input === false) {\n return undefined\n }\n if (typeof input === 'string') {\n return input\n }\n return generatePassword()\n}\n\nfunction printTermuxKeepAlive(lines: string[]): void {\n if (!isTermuxRuntime()) {\n return\n }\n lines.push('')\n lines.push(' Android/Termux keep-alive:')\n lines.push(' 1) Keep this Termux session open (do not swipe it away).')\n lines.push(' 2) Disable battery optimization for Termux in Android settings.')\n lines.push(' 3) Optional: run `termux-wake-lock` in another shell.')\n}\n\nfunction openBrowser(url: string): void {\n const command = process.platform === 'darwin'\n ? { cmd: 'open', args: [url] }\n : process.platform === 'win32'\n ? { cmd: 'cmd', args: ['/c', 'start', '', url] }\n : { cmd: 'xdg-open', args: [url] }\n\n const child = spawn(command.cmd, command.args, { detached: true, stdio: 'ignore' })\n child.on('error', () => {})\n child.unref()\n}\n\nfunction listenWithFallback(server: ReturnType<typeof createServer>, startPort: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const attempt = (port: number) => {\n const onError = (error: NodeJS.ErrnoException) => {\n server.off('listening', onListening)\n if (error.code === 'EADDRINUSE' || error.code === 'EACCES') {\n attempt(port + 1)\n return\n }\n reject(error)\n }\n const onListening = () => {\n server.off('error', onError)\n resolve(port)\n }\n\n server.once('error', onError)\n server.once('listening', onListening)\n server.listen(port)\n }\n\n attempt(startPort)\n })\n}\n\nasync function startServer(options: { port: string; password: string | boolean }) {\n const version = await readCliVersion()\n const codexCommand = ensureCodexInstalled() ?? resolveCodexCommand()\n if (!hasCodexAuth() && codexCommand) {\n console.log('\\nCodex is not logged in. Starting `codex login`...\\n')\n runOrFail(codexCommand, ['login'], 'Codex login')\n }\n const requestedPort = parseInt(options.port, 10)\n const password = resolvePassword(options.password)\n const { app, dispose } = createApp({ password })\n const server = createServer(app)\n const port = await listenWithFallback(server, requestedPort)\n const lines = [\n '',\n 'Codex Web Local is running!',\n ` Version: ${version}`,\n ' GitHub: https://github.com/friuns2/codexui',\n '',\n ` Local: http://localhost:${String(port)}`,\n ]\n\n if (port !== requestedPort) {\n lines.push(` Requested port ${String(requestedPort)} was unavailable; using ${String(port)}.`)\n }\n\n if (password) {\n lines.push(` Password: ${password}`)\n }\n\n printTermuxKeepAlive(lines)\n lines.push('')\n console.log(lines.join('\\n'))\n openBrowser(`http://localhost:${String(port)}`)\n\n function shutdown() {\n console.log('\\nShutting down...')\n server.close(() => {\n dispose()\n process.exit(0)\n })\n // Force exit after timeout\n setTimeout(() => {\n dispose()\n process.exit(1)\n }, 5000).unref()\n }\n\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n}\n\nasync function runLogin() {\n const codexCommand = ensureCodexInstalled() ?? 'codex'\n console.log('\\nStarting `codex login`...\\n')\n runOrFail(codexCommand, ['login'], 'Codex login')\n}\n\nprogram\n .option('-p, --port <port>', 'port to listen on', '5999')\n .option('--password <pass>', 'set a specific password')\n .option('--no-password', 'disable password protection')\n .action(async (opts: { port: string; password: string | boolean }) => {\n await startServer(opts)\n })\n\nprogram.command('login').description('Install/check Codex CLI and run `codex login`').action(runLogin)\n\nprogram.command('help').description('Show codexui command help').action(() => {\n program.outputHelp()\n})\n\nprogram.parseAsync(process.argv).catch((error) => {\n const message = error instanceof Error ? error.message : String(error)\n console.error(`\\nFailed to run codexui: ${message}`)\n process.exit(1)\n})\n","import { fileURLToPath } from 'node:url'\nimport { dirname, extname, isAbsolute, join } from 'node:path'\nimport express, { type Express } from 'express'\nimport { createCodexBridgeMiddleware } from './codexAppServerBridge.js'\nimport { createAuthMiddleware } from './authMiddleware.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst distDir = join(__dirname, '..', 'dist')\n\nexport type ServerOptions = {\n password?: string\n}\n\nexport type ServerInstance = {\n app: Express\n dispose: () => void\n}\n\nconst IMAGE_CONTENT_TYPES: Record<string, string> = {\n '.avif': 'image/avif',\n '.bmp': 'image/bmp',\n '.gif': 'image/gif',\n '.jpeg': 'image/jpeg',\n '.jpg': 'image/jpeg',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n}\n\nfunction normalizeLocalImagePath(rawPath: string): string {\n const trimmed = rawPath.trim()\n if (!trimmed) return ''\n if (trimmed.startsWith('file://')) {\n try {\n return decodeURIComponent(trimmed.replace(/^file:\\/\\//u, ''))\n } catch {\n return trimmed.replace(/^file:\\/\\//u, '')\n }\n }\n return trimmed\n}\n\nexport function createServer(options: ServerOptions = {}): ServerInstance {\n const app = express()\n const bridge = createCodexBridgeMiddleware()\n\n // 1. Auth middleware (if password is set)\n if (options.password) {\n app.use(createAuthMiddleware(options.password))\n }\n\n // 2. Bridge middleware for /codex-api/*\n app.use(bridge)\n\n // 3. Serve local images referenced in markdown (desktop parity for absolute image paths)\n app.get('/codex-local-image', (req, res) => {\n const rawPath = typeof req.query.path === 'string' ? req.query.path : ''\n const localPath = normalizeLocalImagePath(rawPath)\n if (!localPath || !isAbsolute(localPath)) {\n res.status(400).json({ error: 'Expected absolute local file path.' })\n return\n }\n\n const contentType = IMAGE_CONTENT_TYPES[extname(localPath).toLowerCase()]\n if (!contentType) {\n res.status(415).json({ error: 'Unsupported image type.' })\n return\n }\n\n res.type(contentType)\n res.setHeader('Cache-Control', 'private, max-age=300')\n res.sendFile(localPath, { dotfiles: 'allow' }, (error) => {\n if (!error) return\n if (!res.headersSent) res.status(404).json({ error: 'Image file not found.' })\n })\n })\n\n // 4. Static files from Vue build\n app.use(express.static(distDir))\n\n // 5. SPA fallback\n app.use((_req, res) => {\n res.sendFile(join(distDir, 'index.html'))\n })\n\n return {\n app,\n dispose: () => bridge.dispose(),\n }\n}\n","import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'\nimport { mkdtemp, readFile, readdir, rm, mkdir, stat } from 'node:fs/promises'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { request as httpsRequest } from 'node:https'\nimport { homedir } from 'node:os'\nimport { tmpdir } from 'node:os'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport { writeFile } from 'node:fs/promises'\n\ntype JsonRpcCall = {\n jsonrpc: '2.0'\n id: number\n method: string\n params?: unknown\n}\n\ntype JsonRpcResponse = {\n id?: number\n result?: unknown\n error?: {\n code: number\n message: string\n }\n method?: string\n params?: unknown\n}\n\ntype RpcProxyRequest = {\n method: string\n params?: unknown\n}\n\ntype ServerRequestReply = {\n result?: unknown\n error?: {\n code: number\n message: string\n }\n}\n\ntype WorkspaceRootsState = {\n order: string[]\n labels: Record<string, string>\n active: string[]\n}\n\ntype PendingServerRequest = {\n id: number\n method: string\n params: unknown\n receivedAtIso: string\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null\n}\n\nfunction getErrorMessage(payload: unknown, fallback: string): string {\n if (payload instanceof Error && payload.message.trim().length > 0) {\n return payload.message\n }\n\n const record = asRecord(payload)\n if (!record) return fallback\n\n const error = record.error\n if (typeof error === 'string' && error.length > 0) return error\n\n const nestedError = asRecord(error)\n if (nestedError && typeof nestedError.message === 'string' && nestedError.message.length > 0) {\n return nestedError.message\n }\n\n return fallback\n}\n\nfunction setJson(res: ServerResponse, statusCode: number, payload: unknown): void {\n res.statusCode = statusCode\n res.setHeader('Content-Type', 'application/json; charset=utf-8')\n res.end(JSON.stringify(payload))\n}\n\nfunction scoreFileCandidate(path: string, query: string): number {\n if (!query) return 0\n const lowerPath = path.toLowerCase()\n const lowerQuery = query.toLowerCase()\n const baseName = lowerPath.slice(lowerPath.lastIndexOf('/') + 1)\n if (baseName === lowerQuery) return 0\n if (baseName.startsWith(lowerQuery)) return 1\n if (baseName.includes(lowerQuery)) return 2\n if (lowerPath.includes(`/${lowerQuery}`)) return 3\n if (lowerPath.includes(lowerQuery)) return 4\n return 10\n}\n\nasync function listFilesWithRipgrep(cwd: string): Promise<string[]> {\n return await new Promise<string[]>((resolve, reject) => {\n const proc = spawn('rg', ['--files', '--hidden', '-g', '!.git', '-g', '!node_modules'], {\n cwd,\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n proc.stdout.on('data', (chunk: Buffer) => { stdout += chunk.toString() })\n proc.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString() })\n proc.on('error', reject)\n proc.on('close', (code) => {\n if (code === 0) {\n const rows = stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n resolve(rows)\n return\n }\n const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\\n')\n reject(new Error(details || 'rg --files failed'))\n })\n })\n}\n\nfunction getCodexHomeDir(): string {\n const codexHome = process.env.CODEX_HOME?.trim()\n return codexHome && codexHome.length > 0 ? codexHome : join(homedir(), '.codex')\n}\n\nfunction getSkillsInstallDir(): string {\n return join(getCodexHomeDir(), 'skills')\n}\n\nasync function runCommand(command: string, args: string[], options: { cwd?: string } = {}): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: options.cwd,\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n proc.stdout.on('data', (chunk: Buffer) => { stdout += chunk.toString() })\n proc.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString() })\n proc.on('error', reject)\n proc.on('close', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\\n')\n const suffix = details.length > 0 ? `: ${details}` : ''\n reject(new Error(`Command failed (${command} ${args.join(' ')})${suffix}`))\n })\n })\n}\n\nasync function detectUserSkillsDir(appServer: AppServerProcess): Promise<string> {\n try {\n const result = (await appServer.rpc('skills/list', {})) as {\n data?: Array<{ skills?: Array<{ scope?: string; path?: string }> }>\n }\n for (const entry of result.data ?? []) {\n for (const skill of entry.skills ?? []) {\n if (skill.scope !== 'user' || !skill.path) continue\n const parts = skill.path.split('/').filter(Boolean)\n if (parts.length < 2) continue\n return `/${parts.slice(0, -2).join('/')}`\n }\n }\n } catch {}\n return getSkillsInstallDir()\n}\n\nasync function ensureInstalledSkillIsValid(appServer: AppServerProcess, skillPath: string): Promise<void> {\n const result = (await appServer.rpc('skills/list', { forceReload: true })) as {\n data?: Array<{ errors?: Array<{ path?: string; message?: string }> }>\n }\n const normalized = skillPath.endsWith('/SKILL.md') ? skillPath : `${skillPath}/SKILL.md`\n for (const entry of result.data ?? []) {\n for (const error of entry.errors ?? []) {\n if (error.path === normalized) {\n throw new Error(error.message || 'Installed skill is invalid')\n }\n }\n }\n}\n\ntype SkillHubEntry = {\n name: string\n owner: string\n description: string\n displayName: string\n publishedAt: number\n avatarUrl: string\n url: string\n installed: boolean\n path?: string\n enabled?: boolean\n}\n\ntype SkillsTreeEntry = {\n name: string\n owner: string\n url: string\n}\n\ntype SkillsTreeCache = {\n entries: SkillsTreeEntry[]\n fetchedAt: number\n}\n\ntype MetaJson = {\n displayName?: string\n owner?: string\n slug?: string\n latest?: { publishedAt?: number }\n}\n\nconst TREE_CACHE_TTL_MS = 5 * 60 * 1000\nlet skillsTreeCache: SkillsTreeCache | null = null\nconst metaCache = new Map<string, { description: string; displayName: string; publishedAt: number }>()\n\nasync function getGhToken(): Promise<string | null> {\n try {\n const proc = spawn('gh', ['auth', 'token'], { stdio: ['ignore', 'pipe', 'ignore'] })\n let out = ''\n proc.stdout.on('data', (d: Buffer) => { out += d.toString() })\n return new Promise((resolve) => {\n proc.on('close', (code) => resolve(code === 0 ? out.trim() : null))\n proc.on('error', () => resolve(null))\n })\n } catch { return null }\n}\n\nasync function ghFetch(url: string): Promise<Response> {\n const token = await getGhToken()\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'codex-web-local',\n }\n if (token) headers.Authorization = `Bearer ${token}`\n return fetch(url, { headers })\n}\n\nasync function fetchSkillsTree(): Promise<SkillsTreeEntry[]> {\n if (skillsTreeCache && Date.now() - skillsTreeCache.fetchedAt < TREE_CACHE_TTL_MS) {\n return skillsTreeCache.entries\n }\n\n const resp = await ghFetch('https://api.github.com/repos/openclaw/skills/git/trees/main?recursive=1')\n if (!resp.ok) throw new Error(`GitHub tree API returned ${resp.status}`)\n const data = (await resp.json()) as { tree?: Array<{ path: string; type: string }> }\n\n const metaPattern = /^skills\\/([^/]+)\\/([^/]+)\\/_meta\\.json$/\n const seen = new Set<string>()\n const entries: SkillsTreeEntry[] = []\n\n for (const node of data.tree ?? []) {\n const match = metaPattern.exec(node.path)\n if (!match) continue\n const [, owner, skillName] = match\n const key = `${owner}/${skillName}`\n if (seen.has(key)) continue\n seen.add(key)\n entries.push({\n name: skillName,\n owner,\n url: `https://github.com/openclaw/skills/tree/main/skills/${owner}/${skillName}`,\n })\n }\n\n skillsTreeCache = { entries, fetchedAt: Date.now() }\n return entries\n}\n\nasync function fetchMetaBatch(entries: SkillsTreeEntry[]): Promise<void> {\n const toFetch = entries.filter((e) => !metaCache.has(`${e.owner}/${e.name}`))\n if (toFetch.length === 0) return\n\n const batch = toFetch.slice(0, 50)\n const results = await Promise.allSettled(\n batch.map(async (e) => {\n const rawUrl = `https://raw.githubusercontent.com/openclaw/skills/main/skills/${e.owner}/${e.name}/_meta.json`\n const resp = await fetch(rawUrl)\n if (!resp.ok) return\n const meta = (await resp.json()) as MetaJson\n metaCache.set(`${e.owner}/${e.name}`, {\n displayName: typeof meta.displayName === 'string' ? meta.displayName : '',\n description: typeof meta.displayName === 'string' ? meta.displayName : '',\n publishedAt: meta.latest?.publishedAt ?? 0,\n })\n }),\n )\n void results\n}\n\nfunction buildHubEntry(e: SkillsTreeEntry): SkillHubEntry {\n const cached = metaCache.get(`${e.owner}/${e.name}`)\n return {\n name: e.name,\n owner: e.owner,\n description: cached?.description ?? '',\n displayName: cached?.displayName ?? '',\n publishedAt: cached?.publishedAt ?? 0,\n avatarUrl: `https://github.com/${e.owner}.png?size=40`,\n url: e.url,\n installed: false,\n }\n}\n\ntype InstalledSkillInfo = { name: string; path: string; enabled: boolean }\n\nasync function scanInstalledSkillsFromDisk(): Promise<Map<string, InstalledSkillInfo>> {\n const map = new Map<string, InstalledSkillInfo>()\n const skillsDir = getSkillsInstallDir()\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true })\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith('.')) continue\n const skillMd = join(skillsDir, entry.name, 'SKILL.md')\n try {\n await stat(skillMd)\n map.set(entry.name, { name: entry.name, path: skillMd, enabled: true })\n } catch {}\n }\n } catch {}\n return map\n}\n\nasync function searchSkillsHub(\n allEntries: SkillsTreeEntry[],\n query: string,\n limit: number,\n sort: string,\n installedMap: Map<string, InstalledSkillInfo>,\n): Promise<SkillHubEntry[]> {\n const q = query.toLowerCase().trim()\n let filtered = q\n ? allEntries.filter((s) => {\n if (s.name.toLowerCase().includes(q) || s.owner.toLowerCase().includes(q)) return true\n const cached = metaCache.get(`${s.owner}/${s.name}`)\n if (cached?.displayName?.toLowerCase().includes(q)) return true\n return false\n })\n : allEntries\n\n const page = filtered.slice(0, Math.min(limit * 2, 200))\n await fetchMetaBatch(page)\n\n let results = page.map(buildHubEntry)\n\n if (sort === 'date') {\n results.sort((a, b) => b.publishedAt - a.publishedAt)\n } else if (q) {\n results.sort((a, b) => {\n const aExact = a.name.toLowerCase() === q ? 1 : 0\n const bExact = b.name.toLowerCase() === q ? 1 : 0\n if (aExact !== bExact) return bExact - aExact\n return b.publishedAt - a.publishedAt\n })\n }\n\n return results.slice(0, limit).map((s) => {\n const local = installedMap.get(s.name)\n return local\n ? { ...s, installed: true, path: local.path, enabled: local.enabled }\n : s\n })\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n const normalized: string[] = []\n for (const item of value) {\n if (typeof item === 'string' && item.length > 0 && !normalized.includes(item)) {\n normalized.push(item)\n }\n }\n return normalized\n}\n\nfunction normalizeStringRecord(value: unknown): Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n const next: Record<string, string> = {}\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof key === 'string' && key.length > 0 && typeof item === 'string') {\n next[key] = item\n }\n }\n return next\n}\n\nfunction getCodexAuthPath(): string {\n return join(getCodexHomeDir(), 'auth.json')\n}\n\ntype CodexAuth = {\n tokens?: {\n access_token?: string\n account_id?: string\n }\n}\n\nasync function readCodexAuth(): Promise<{ accessToken: string; accountId?: string } | null> {\n try {\n const raw = await readFile(getCodexAuthPath(), 'utf8')\n const auth = JSON.parse(raw) as CodexAuth\n const token = auth.tokens?.access_token\n if (!token) return null\n return { accessToken: token, accountId: auth.tokens?.account_id ?? undefined }\n } catch {\n return null\n }\n}\n\nfunction getCodexGlobalStatePath(): string {\n return join(getCodexHomeDir(), '.codex-global-state.json')\n}\n\ntype ThreadTitleCache = { titles: Record<string, string>; order: string[] }\nconst MAX_THREAD_TITLES = 500\n\nfunction normalizeThreadTitleCache(value: unknown): ThreadTitleCache {\n const record = asRecord(value)\n if (!record) return { titles: {}, order: [] }\n const rawTitles = asRecord(record.titles)\n const titles: Record<string, string> = {}\n if (rawTitles) {\n for (const [k, v] of Object.entries(rawTitles)) {\n if (typeof v === 'string' && v.length > 0) titles[k] = v\n }\n }\n const order = normalizeStringArray(record.order)\n return { titles, order }\n}\n\nfunction updateThreadTitleCache(cache: ThreadTitleCache, id: string, title: string): ThreadTitleCache {\n const titles = { ...cache.titles, [id]: title }\n const order = [id, ...cache.order.filter((o) => o !== id)]\n while (order.length > MAX_THREAD_TITLES) {\n const removed = order.pop()\n if (removed) delete titles[removed]\n }\n return { titles, order }\n}\n\nfunction removeFromThreadTitleCache(cache: ThreadTitleCache, id: string): ThreadTitleCache {\n const { [id]: _, ...titles } = cache.titles\n return { titles, order: cache.order.filter((o) => o !== id) }\n}\n\nasync function readThreadTitleCache(): Promise<ThreadTitleCache> {\n const statePath = getCodexGlobalStatePath()\n try {\n const raw = await readFile(statePath, 'utf8')\n const payload = asRecord(JSON.parse(raw)) ?? {}\n return normalizeThreadTitleCache(payload['thread-titles'])\n } catch {\n return { titles: {}, order: [] }\n }\n}\n\nasync function writeThreadTitleCache(cache: ThreadTitleCache): Promise<void> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n try {\n const raw = await readFile(statePath, 'utf8')\n payload = asRecord(JSON.parse(raw)) ?? {}\n } catch {\n payload = {}\n }\n payload['thread-titles'] = cache\n await writeFile(statePath, JSON.stringify(payload), 'utf8')\n}\n\nasync function readWorkspaceRootsState(): Promise<WorkspaceRootsState> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n\n try {\n const raw = await readFile(statePath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n payload = asRecord(parsed) ?? {}\n } catch {\n payload = {}\n }\n\n return {\n order: normalizeStringArray(payload['electron-saved-workspace-roots']),\n labels: normalizeStringRecord(payload['electron-workspace-root-labels']),\n active: normalizeStringArray(payload['active-workspace-roots']),\n }\n}\n\nasync function writeWorkspaceRootsState(nextState: WorkspaceRootsState): Promise<void> {\n const statePath = getCodexGlobalStatePath()\n let payload: Record<string, unknown> = {}\n try {\n const raw = await readFile(statePath, 'utf8')\n payload = asRecord(JSON.parse(raw)) ?? {}\n } catch {\n payload = {}\n }\n\n payload['electron-saved-workspace-roots'] = normalizeStringArray(nextState.order)\n payload['electron-workspace-root-labels'] = normalizeStringRecord(nextState.labels)\n payload['active-workspace-roots'] = normalizeStringArray(nextState.active)\n\n await writeFile(statePath, JSON.stringify(payload), 'utf8')\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const raw = await readRawBody(req)\n if (raw.length === 0) return null\n const text = raw.toString('utf8').trim()\n if (text.length === 0) return null\n return JSON.parse(text) as unknown\n}\n\nasync function readRawBody(req: IncomingMessage): Promise<Buffer> {\n const chunks: Uint8Array[] = []\n for await (const chunk of req) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nfunction bufferIndexOf(buf: Buffer, needle: Buffer, start = 0): number {\n for (let i = start; i <= buf.length - needle.length; i++) {\n let match = true\n for (let j = 0; j < needle.length; j++) {\n if (buf[i + j] !== needle[j]) { match = false; break }\n }\n if (match) return i\n }\n return -1\n}\n\nfunction handleFileUpload(req: IncomingMessage, res: ServerResponse): void {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', async () => {\n try {\n const body = Buffer.concat(chunks)\n const contentType = req.headers['content-type'] ?? ''\n const boundaryMatch = contentType.match(/boundary=(.+)/i)\n if (!boundaryMatch) { setJson(res, 400, { error: 'Missing multipart boundary' }); return }\n const boundary = boundaryMatch[1]\n const boundaryBuf = Buffer.from(`--${boundary}`)\n const parts: Buffer[] = []\n let searchStart = 0\n while (searchStart < body.length) {\n const idx = body.indexOf(boundaryBuf, searchStart)\n if (idx < 0) break\n if (searchStart > 0) parts.push(body.subarray(searchStart, idx))\n searchStart = idx + boundaryBuf.length\n if (body[searchStart] === 0x0d && body[searchStart + 1] === 0x0a) searchStart += 2\n }\n let fileName = 'uploaded-file'\n let fileData: Buffer | null = null\n const headerSep = Buffer.from('\\r\\n\\r\\n')\n for (const part of parts) {\n const headerEnd = bufferIndexOf(part, headerSep)\n if (headerEnd < 0) continue\n const headers = part.subarray(0, headerEnd).toString('utf8')\n const fnMatch = headers.match(/filename=\"([^\"]+)\"/i)\n if (!fnMatch) continue\n fileName = fnMatch[1].replace(/[/\\\\]/g, '_')\n let end = part.length\n if (end >= 2 && part[end - 2] === 0x0d && part[end - 1] === 0x0a) end -= 2\n fileData = part.subarray(headerEnd + 4, end)\n break\n }\n if (!fileData) { setJson(res, 400, { error: 'No file in request' }); return }\n const uploadDir = join(tmpdir(), 'codex-web-uploads')\n await mkdir(uploadDir, { recursive: true })\n const destDir = await mkdtemp(join(uploadDir, 'f-'))\n const destPath = join(destDir, fileName)\n await writeFile(destPath, fileData)\n setJson(res, 200, { path: destPath })\n } catch (err) {\n setJson(res, 500, { error: getErrorMessage(err, 'Upload failed') })\n }\n })\n req.on('error', (err) => {\n setJson(res, 500, { error: getErrorMessage(err, 'Upload stream error') })\n })\n}\n\nasync function proxyTranscribe(\n body: Buffer,\n contentType: string,\n authToken: string,\n accountId?: string,\n): Promise<{ status: number; body: string }> {\n const headers: Record<string, string | number> = {\n 'Content-Type': contentType,\n 'Content-Length': body.length,\n Authorization: `Bearer ${authToken}`,\n originator: 'Codex Desktop',\n 'User-Agent': `Codex Desktop/0.1.0 (${process.platform}; ${process.arch})`,\n }\n\n if (accountId) {\n headers['ChatGPT-Account-Id'] = accountId\n }\n\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n 'https://chatgpt.com/backend-api/transcribe',\n { method: 'POST', headers },\n (res) => {\n const chunks: Buffer[] = []\n res.on('data', (c: Buffer) => chunks.push(c))\n res.on('end', () => resolve({ status: res.statusCode ?? 500, body: Buffer.concat(chunks).toString('utf8') }))\n res.on('error', reject)\n },\n )\n req.on('error', reject)\n req.write(body)\n req.end()\n })\n}\n\nclass AppServerProcess {\n private process: ChildProcessWithoutNullStreams | null = null\n private initialized = false\n private initializePromise: Promise<void> | null = null\n private readBuffer = ''\n private nextId = 1\n private stopping = false\n private readonly pending = new Map<number, { resolve: (value: unknown) => void; reject: (reason?: unknown) => void }>()\n private readonly notificationListeners = new Set<(value: { method: string; params: unknown }) => void>()\n private readonly pendingServerRequests = new Map<number, PendingServerRequest>()\n private readonly appServerArgs = [\n 'app-server',\n '-c',\n 'approval_policy=\"never\"',\n '-c',\n 'sandbox_mode=\"danger-full-access\"',\n ]\n\n private start(): void {\n if (this.process) return\n\n this.stopping = false\n const proc = spawn('codex', this.appServerArgs, { stdio: ['pipe', 'pipe', 'pipe'] })\n this.process = proc\n\n proc.stdout.setEncoding('utf8')\n proc.stdout.on('data', (chunk: string) => {\n this.readBuffer += chunk\n\n let lineEnd = this.readBuffer.indexOf('\\n')\n while (lineEnd !== -1) {\n const line = this.readBuffer.slice(0, lineEnd).trim()\n this.readBuffer = this.readBuffer.slice(lineEnd + 1)\n\n if (line.length > 0) {\n this.handleLine(line)\n }\n\n lineEnd = this.readBuffer.indexOf('\\n')\n }\n })\n\n proc.stderr.setEncoding('utf8')\n proc.stderr.on('data', () => {\n // Keep stderr silent in dev middleware; JSON-RPC errors are forwarded via responses.\n })\n\n proc.on('exit', () => {\n const failure = new Error(this.stopping ? 'codex app-server stopped' : 'codex app-server exited unexpectedly')\n for (const request of this.pending.values()) {\n request.reject(failure)\n }\n\n this.pending.clear()\n this.pendingServerRequests.clear()\n this.process = null\n this.initialized = false\n this.initializePromise = null\n this.readBuffer = ''\n })\n }\n\n private sendLine(payload: Record<string, unknown>): void {\n if (!this.process) {\n throw new Error('codex app-server is not running')\n }\n\n this.process.stdin.write(`${JSON.stringify(payload)}\\n`)\n }\n\n private handleLine(line: string): void {\n let message: JsonRpcResponse\n try {\n message = JSON.parse(line) as JsonRpcResponse\n } catch {\n return\n }\n\n if (typeof message.id === 'number' && this.pending.has(message.id)) {\n const pendingRequest = this.pending.get(message.id)\n this.pending.delete(message.id)\n\n if (!pendingRequest) return\n\n if (message.error) {\n pendingRequest.reject(new Error(message.error.message))\n } else {\n pendingRequest.resolve(message.result)\n }\n return\n }\n\n if (typeof message.method === 'string' && typeof message.id !== 'number') {\n this.emitNotification({\n method: message.method,\n params: message.params ?? null,\n })\n return\n }\n\n // Handle server-initiated JSON-RPC requests (approvals, dynamic tool calls, etc.).\n if (typeof message.id === 'number' && typeof message.method === 'string') {\n this.handleServerRequest(message.id, message.method, message.params ?? null)\n }\n }\n\n private emitNotification(notification: { method: string; params: unknown }): void {\n for (const listener of this.notificationListeners) {\n listener(notification)\n }\n }\n\n private sendServerRequestReply(requestId: number, reply: ServerRequestReply): void {\n if (reply.error) {\n this.sendLine({\n jsonrpc: '2.0',\n id: requestId,\n error: reply.error,\n })\n return\n }\n\n this.sendLine({\n jsonrpc: '2.0',\n id: requestId,\n result: reply.result ?? {},\n })\n }\n\n private resolvePendingServerRequest(requestId: number, reply: ServerRequestReply): void {\n const pendingRequest = this.pendingServerRequests.get(requestId)\n if (!pendingRequest) {\n throw new Error(`No pending server request found for id ${String(requestId)}`)\n }\n this.pendingServerRequests.delete(requestId)\n\n this.sendServerRequestReply(requestId, reply)\n const requestParams = asRecord(pendingRequest.params)\n const threadId =\n typeof requestParams?.threadId === 'string' && requestParams.threadId.length > 0\n ? requestParams.threadId\n : ''\n this.emitNotification({\n method: 'server/request/resolved',\n params: {\n id: requestId,\n method: pendingRequest.method,\n threadId,\n mode: 'manual',\n resolvedAtIso: new Date().toISOString(),\n },\n })\n }\n\n private handleServerRequest(requestId: number, method: string, params: unknown): void {\n const pendingRequest: PendingServerRequest = {\n id: requestId,\n method,\n params,\n receivedAtIso: new Date().toISOString(),\n }\n this.pendingServerRequests.set(requestId, pendingRequest)\n\n this.emitNotification({\n method: 'server/request',\n params: pendingRequest,\n })\n }\n\n private async call(method: string, params: unknown): Promise<unknown> {\n this.start()\n const id = this.nextId++\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject })\n\n this.sendLine({\n jsonrpc: '2.0',\n id,\n method,\n params,\n } satisfies JsonRpcCall)\n })\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return\n if (this.initializePromise) {\n await this.initializePromise\n return\n }\n\n this.initializePromise = this.call('initialize', {\n clientInfo: {\n name: 'codex-web-local',\n version: '0.1.0',\n },\n }).then(() => {\n this.initialized = true\n }).finally(() => {\n this.initializePromise = null\n })\n\n await this.initializePromise\n }\n\n async rpc(method: string, params: unknown): Promise<unknown> {\n await this.ensureInitialized()\n return this.call(method, params)\n }\n\n onNotification(listener: (value: { method: string; params: unknown }) => void): () => void {\n this.notificationListeners.add(listener)\n return () => {\n this.notificationListeners.delete(listener)\n }\n }\n\n async respondToServerRequest(payload: unknown): Promise<void> {\n await this.ensureInitialized()\n\n const body = asRecord(payload)\n if (!body) {\n throw new Error('Invalid response payload: expected object')\n }\n\n const id = body.id\n if (typeof id !== 'number' || !Number.isInteger(id)) {\n throw new Error('Invalid response payload: \"id\" must be an integer')\n }\n\n const rawError = asRecord(body.error)\n if (rawError) {\n const message = typeof rawError.message === 'string' && rawError.message.trim().length > 0\n ? rawError.message.trim()\n : 'Server request rejected by client'\n const code = typeof rawError.code === 'number' && Number.isFinite(rawError.code)\n ? Math.trunc(rawError.code)\n : -32000\n this.resolvePendingServerRequest(id, { error: { code, message } })\n return\n }\n\n if (!('result' in body)) {\n throw new Error('Invalid response payload: expected \"result\" or \"error\"')\n }\n\n this.resolvePendingServerRequest(id, { result: body.result })\n }\n\n listPendingServerRequests(): PendingServerRequest[] {\n return Array.from(this.pendingServerRequests.values())\n }\n\n dispose(): void {\n if (!this.process) return\n\n const proc = this.process\n this.stopping = true\n this.process = null\n this.initialized = false\n this.initializePromise = null\n this.readBuffer = ''\n\n const failure = new Error('codex app-server stopped')\n for (const request of this.pending.values()) {\n request.reject(failure)\n }\n this.pending.clear()\n this.pendingServerRequests.clear()\n\n try {\n proc.stdin.end()\n } catch {\n // ignore close errors on shutdown\n }\n\n try {\n proc.kill('SIGTERM')\n } catch {\n // ignore kill errors on shutdown\n }\n\n const forceKillTimer = setTimeout(() => {\n if (!proc.killed) {\n try {\n proc.kill('SIGKILL')\n } catch {\n // ignore kill errors on shutdown\n }\n }\n }, 1500)\n forceKillTimer.unref()\n }\n}\n\nclass MethodCatalog {\n private methodCache: string[] | null = null\n private notificationCache: string[] | null = null\n\n private async runGenerateSchemaCommand(outDir: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const process = spawn('codex', ['app-server', 'generate-json-schema', '--out', outDir], {\n stdio: ['ignore', 'ignore', 'pipe'],\n })\n\n let stderr = ''\n\n process.stderr.setEncoding('utf8')\n process.stderr.on('data', (chunk: string) => {\n stderr += chunk\n })\n\n process.on('error', reject)\n process.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(stderr.trim() || `generate-json-schema exited with code ${String(code)}`))\n })\n })\n }\n\n private extractMethodsFromClientRequest(payload: unknown): string[] {\n const root = asRecord(payload)\n const oneOf = Array.isArray(root?.oneOf) ? root.oneOf : []\n const methods = new Set<string>()\n\n for (const entry of oneOf) {\n const row = asRecord(entry)\n const properties = asRecord(row?.properties)\n const methodDef = asRecord(properties?.method)\n const methodEnum = Array.isArray(methodDef?.enum) ? methodDef.enum : []\n\n for (const item of methodEnum) {\n if (typeof item === 'string' && item.length > 0) {\n methods.add(item)\n }\n }\n }\n\n return Array.from(methods).sort((a, b) => a.localeCompare(b))\n }\n\n private extractMethodsFromServerNotification(payload: unknown): string[] {\n const root = asRecord(payload)\n const oneOf = Array.isArray(root?.oneOf) ? root.oneOf : []\n const methods = new Set<string>()\n\n for (const entry of oneOf) {\n const row = asRecord(entry)\n const properties = asRecord(row?.properties)\n const methodDef = asRecord(properties?.method)\n const methodEnum = Array.isArray(methodDef?.enum) ? methodDef.enum : []\n\n for (const item of methodEnum) {\n if (typeof item === 'string' && item.length > 0) {\n methods.add(item)\n }\n }\n }\n\n return Array.from(methods).sort((a, b) => a.localeCompare(b))\n }\n\n async listMethods(): Promise<string[]> {\n if (this.methodCache) {\n return this.methodCache\n }\n\n const outDir = await mkdtemp(join(tmpdir(), 'codex-web-local-schema-'))\n await this.runGenerateSchemaCommand(outDir)\n\n const clientRequestPath = join(outDir, 'ClientRequest.json')\n const raw = await readFile(clientRequestPath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n const methods = this.extractMethodsFromClientRequest(parsed)\n\n this.methodCache = methods\n return methods\n }\n\n async listNotificationMethods(): Promise<string[]> {\n if (this.notificationCache) {\n return this.notificationCache\n }\n\n const outDir = await mkdtemp(join(tmpdir(), 'codex-web-local-schema-'))\n await this.runGenerateSchemaCommand(outDir)\n\n const serverNotificationPath = join(outDir, 'ServerNotification.json')\n const raw = await readFile(serverNotificationPath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n const methods = this.extractMethodsFromServerNotification(parsed)\n\n this.notificationCache = methods\n return methods\n }\n}\n\ntype CodexBridgeMiddleware = ((req: IncomingMessage, res: ServerResponse, next: () => void) => Promise<void>) & {\n dispose: () => void\n}\n\ntype SharedBridgeState = {\n appServer: AppServerProcess\n methodCatalog: MethodCatalog\n}\n\nconst SHARED_BRIDGE_KEY = '__codexRemoteSharedBridge__'\n\nfunction getSharedBridgeState(): SharedBridgeState {\n const globalScope = globalThis as typeof globalThis & {\n [SHARED_BRIDGE_KEY]?: SharedBridgeState\n }\n\n const existing = globalScope[SHARED_BRIDGE_KEY]\n if (existing) return existing\n\n const created: SharedBridgeState = {\n appServer: new AppServerProcess(),\n methodCatalog: new MethodCatalog(),\n }\n globalScope[SHARED_BRIDGE_KEY] = created\n return created\n}\n\nexport function createCodexBridgeMiddleware(): CodexBridgeMiddleware {\n const { appServer, methodCatalog } = getSharedBridgeState()\n\n const middleware = async (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n try {\n if (!req.url) {\n next()\n return\n }\n\n const url = new URL(req.url, 'http://localhost')\n\n if (req.method === 'POST' && url.pathname === '/codex-api/upload-file') {\n handleFileUpload(req, res)\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/rpc') {\n const payload = await readJsonBody(req)\n const body = asRecord(payload) as RpcProxyRequest | null\n\n if (!body || typeof body.method !== 'string' || body.method.length === 0) {\n setJson(res, 400, { error: 'Invalid body: expected { method, params? }' })\n return\n }\n\n const result = await appServer.rpc(body.method, body.params ?? null)\n setJson(res, 200, { result })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/transcribe') {\n const auth = await readCodexAuth()\n if (!auth) {\n setJson(res, 401, { error: 'No auth token available for transcription' })\n return\n }\n\n const rawBody = await readRawBody(req)\n const incomingCt = req.headers['content-type'] ?? 'application/octet-stream'\n const upstream = await proxyTranscribe(rawBody, incomingCt, auth.accessToken, auth.accountId)\n\n res.statusCode = upstream.status\n res.setHeader('Content-Type', 'application/json; charset=utf-8')\n res.end(upstream.body)\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/server-requests/respond') {\n const payload = await readJsonBody(req)\n await appServer.respondToServerRequest(payload)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/server-requests/pending') {\n setJson(res, 200, { data: appServer.listPendingServerRequests() })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/meta/methods') {\n const methods = await methodCatalog.listMethods()\n setJson(res, 200, { data: methods })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/meta/notifications') {\n const methods = await methodCatalog.listNotificationMethods()\n setJson(res, 200, { data: methods })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/workspace-roots-state') {\n const state = await readWorkspaceRootsState()\n setJson(res, 200, { data: state })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/home-directory') {\n setJson(res, 200, { data: { path: homedir() } })\n return\n }\n\n if (req.method === 'PUT' && url.pathname === '/codex-api/workspace-roots-state') {\n const payload = await readJsonBody(req)\n const record = asRecord(payload)\n if (!record) {\n setJson(res, 400, { error: 'Invalid body: expected object' })\n return\n }\n const nextState: WorkspaceRootsState = {\n order: normalizeStringArray(record.order),\n labels: normalizeStringRecord(record.labels),\n active: normalizeStringArray(record.active),\n }\n await writeWorkspaceRootsState(nextState)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/project-root') {\n const payload = asRecord(await readJsonBody(req))\n const rawPath = typeof payload?.path === 'string' ? payload.path.trim() : ''\n const createIfMissing = payload?.createIfMissing === true\n const label = typeof payload?.label === 'string' ? payload.label : ''\n if (!rawPath) {\n setJson(res, 400, { error: 'Missing path' })\n return\n }\n\n const normalizedPath = isAbsolute(rawPath) ? rawPath : resolve(rawPath)\n let pathExists = true\n try {\n const info = await stat(normalizedPath)\n if (!info.isDirectory()) {\n setJson(res, 400, { error: 'Path exists but is not a directory' })\n return\n }\n } catch {\n pathExists = false\n }\n\n if (!pathExists && createIfMissing) {\n await mkdir(normalizedPath, { recursive: true })\n } else if (!pathExists) {\n setJson(res, 404, { error: 'Directory does not exist' })\n return\n }\n\n const existingState = await readWorkspaceRootsState()\n const nextOrder = [normalizedPath, ...existingState.order.filter((item) => item !== normalizedPath)]\n const nextActive = [normalizedPath, ...existingState.active.filter((item) => item !== normalizedPath)]\n const nextLabels = { ...existingState.labels }\n if (label.trim().length > 0) {\n nextLabels[normalizedPath] = label.trim()\n }\n await writeWorkspaceRootsState({\n order: nextOrder,\n labels: nextLabels,\n active: nextActive,\n })\n setJson(res, 200, { data: { path: normalizedPath } })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/project-root-suggestion') {\n const basePath = url.searchParams.get('basePath')?.trim() ?? ''\n if (!basePath) {\n setJson(res, 400, { error: 'Missing basePath' })\n return\n }\n const normalizedBasePath = isAbsolute(basePath) ? basePath : resolve(basePath)\n try {\n const baseInfo = await stat(normalizedBasePath)\n if (!baseInfo.isDirectory()) {\n setJson(res, 400, { error: 'basePath is not a directory' })\n return\n }\n } catch {\n setJson(res, 404, { error: 'basePath does not exist' })\n return\n }\n\n let index = 1\n while (index < 100000) {\n const candidateName = `New Project (${String(index)})`\n const candidatePath = join(normalizedBasePath, candidateName)\n try {\n await stat(candidatePath)\n index += 1\n continue\n } catch {\n setJson(res, 200, { data: { name: candidateName, path: candidatePath } })\n return\n }\n }\n\n setJson(res, 500, { error: 'Failed to compute project name suggestion' })\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/composer-file-search') {\n const payload = asRecord(await readJsonBody(req))\n const rawCwd = typeof payload?.cwd === 'string' ? payload.cwd.trim() : ''\n const query = typeof payload?.query === 'string' ? payload.query.trim() : ''\n const limitRaw = typeof payload?.limit === 'number' ? payload.limit : 20\n const limit = Math.max(1, Math.min(100, Math.floor(limitRaw)))\n if (!rawCwd) {\n setJson(res, 400, { error: 'Missing cwd' })\n return\n }\n const cwd = isAbsolute(rawCwd) ? rawCwd : resolve(rawCwd)\n try {\n const info = await stat(cwd)\n if (!info.isDirectory()) {\n setJson(res, 400, { error: 'cwd is not a directory' })\n return\n }\n } catch {\n setJson(res, 404, { error: 'cwd does not exist' })\n return\n }\n\n try {\n const files = await listFilesWithRipgrep(cwd)\n const scored = files\n .map((path) => ({ path, score: scoreFileCandidate(path, query) }))\n .filter((row) => query.length === 0 || row.score < 10)\n .sort((a, b) => (a.score - b.score) || a.path.localeCompare(b.path))\n .slice(0, limit)\n .map((row) => ({ path: row.path }))\n setJson(res, 200, { data: scored })\n } catch (error) {\n setJson(res, 500, { error: getErrorMessage(error, 'Failed to search files') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/thread-titles') {\n const cache = await readThreadTitleCache()\n setJson(res, 200, { data: cache })\n return\n }\n\n if (req.method === 'PUT' && url.pathname === '/codex-api/thread-titles') {\n const payload = asRecord(await readJsonBody(req))\n const id = typeof payload?.id === 'string' ? payload.id : ''\n const title = typeof payload?.title === 'string' ? payload.title : ''\n if (!id) {\n setJson(res, 400, { error: 'Missing id' })\n return\n }\n const cache = await readThreadTitleCache()\n const next = title ? updateThreadTitleCache(cache, id, title) : removeFromThreadTitleCache(cache, id)\n await writeThreadTitleCache(next)\n setJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/skills-hub') {\n try {\n const q = url.searchParams.get('q') || ''\n const limit = Math.min(Math.max(parseInt(url.searchParams.get('limit') || '50', 10) || 50, 1), 200)\n const sort = url.searchParams.get('sort') || 'date'\n const allEntries = await fetchSkillsTree()\n\n const installedMap = await scanInstalledSkillsFromDisk()\n try {\n const result = (await appServer.rpc('skills/list', {})) as { data?: Array<{ skills?: Array<{ name?: string; path?: string; enabled?: boolean }> }> }\n for (const entry of result.data ?? []) {\n for (const skill of entry.skills ?? []) {\n if (skill.name) {\n installedMap.set(skill.name, { name: skill.name, path: skill.path ?? '', enabled: skill.enabled !== false })\n }\n }\n }\n } catch {}\n\n const installedHubEntries = allEntries.filter((e) => installedMap.has(e.name))\n await fetchMetaBatch(installedHubEntries)\n\n const installed: SkillHubEntry[] = []\n for (const [, info] of installedMap) {\n const hubEntry = allEntries.find((e) => e.name === info.name)\n const base = hubEntry ? buildHubEntry(hubEntry) : {\n name: info.name, owner: 'local', description: '', displayName: '',\n publishedAt: 0, avatarUrl: '', url: '', installed: false,\n }\n installed.push({ ...base, installed: true, path: info.path, enabled: info.enabled })\n }\n\n const results = await searchSkillsHub(allEntries, q, limit, sort, installedMap)\n setJson(res, 200, { data: results, installed, total: allEntries.length })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to fetch skills hub') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/skills-hub/readme') {\n try {\n const owner = url.searchParams.get('owner') || ''\n const name = url.searchParams.get('name') || ''\n if (!owner || !name) {\n setJson(res, 400, { error: 'Missing owner or name' })\n return\n }\n const rawUrl = `https://raw.githubusercontent.com/openclaw/skills/main/skills/${owner}/${name}/SKILL.md`\n const resp = await fetch(rawUrl)\n if (!resp.ok) throw new Error(`Failed to fetch SKILL.md: ${resp.status}`)\n const content = await resp.text()\n setJson(res, 200, { content })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to fetch SKILL.md') })\n }\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/skills-hub/install') {\n try {\n const payload = asRecord(await readJsonBody(req))\n const owner = typeof payload?.owner === 'string' ? payload.owner : ''\n const name = typeof payload?.name === 'string' ? payload.name : ''\n if (!owner || !name) {\n setJson(res, 400, { error: 'Missing owner or name' })\n return\n }\n const installerScript = '/Users/igor/.cursor/skills/.system/skill-installer/scripts/install-skill-from-github.py'\n const installDest = await detectUserSkillsDir(appServer)\n const skillPathInRepo = `skills/${owner}/${name}`\n await runCommand('python3', [\n installerScript,\n '--repo', 'openclaw/skills',\n '--path', skillPathInRepo,\n '--dest', installDest,\n '--method', 'git',\n ])\n const skillDir = join(installDest, name)\n await ensureInstalledSkillIsValid(appServer, skillDir)\n setJson(res, 200, { ok: true, path: skillDir })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to install skill') })\n }\n return\n }\n\n if (req.method === 'POST' && url.pathname === '/codex-api/skills-hub/uninstall') {\n try {\n const payload = asRecord(await readJsonBody(req))\n const name = typeof payload?.name === 'string' ? payload.name : ''\n const path = typeof payload?.path === 'string' ? payload.path : ''\n const target = path || (name ? join(getSkillsInstallDir(), name) : '')\n if (!target) {\n setJson(res, 400, { error: 'Missing name or path' })\n return\n }\n await rm(target, { recursive: true, force: true })\n try { await appServer.rpc('skills/list', { forceReload: true }) } catch {}\n setJson(res, 200, { ok: true, deletedPath: target })\n } catch (error) {\n setJson(res, 502, { error: getErrorMessage(error, 'Failed to uninstall skill') })\n }\n return\n }\n\n if (req.method === 'GET' && url.pathname === '/codex-api/events') {\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8')\n res.setHeader('Cache-Control', 'no-cache, no-transform')\n res.setHeader('Connection', 'keep-alive')\n res.setHeader('X-Accel-Buffering', 'no')\n\n const unsubscribe = appServer.onNotification((notification) => {\n if (res.writableEnded || res.destroyed) return\n const payload = {\n ...notification,\n atIso: new Date().toISOString(),\n }\n res.write(`data: ${JSON.stringify(payload)}\\n\\n`)\n })\n\n res.write(`event: ready\\ndata: ${JSON.stringify({ ok: true })}\\n\\n`)\n const keepAlive = setInterval(() => {\n res.write(': ping\\n\\n')\n }, 15000)\n\n const close = () => {\n clearInterval(keepAlive)\n unsubscribe()\n if (!res.writableEnded) {\n res.end()\n }\n }\n\n req.on('close', close)\n req.on('aborted', close)\n return\n }\n\n next()\n } catch (error) {\n const message = getErrorMessage(error, 'Unknown bridge error')\n setJson(res, 502, { error: message })\n }\n }\n\n middleware.dispose = () => {\n appServer.dispose()\n }\n\n return middleware\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto'\nimport type { RequestHandler, Request, Response, NextFunction } from 'express'\n\nconst TOKEN_COOKIE = 'codex_web_local_token'\n\nfunction isLocalhostRequest(req: Request): boolean {\n const remote = req.socket.remoteAddress ?? ''\n if (remote === '127.0.0.1' || remote === '::1' || remote === '::ffff:127.0.0.1') {\n return true\n }\n\n const host = (req.headers.host ?? '').toLowerCase()\n return host.startsWith('localhost:') || host === 'localhost' || host.startsWith('127.0.0.1:')\n}\n\nfunction constantTimeCompare(a: string, b: string): boolean {\n const bufA = Buffer.from(a)\n const bufB = Buffer.from(b)\n if (bufA.length !== bufB.length) return false\n return timingSafeEqual(bufA, bufB)\n}\n\nfunction parseCookies(header: string | undefined): Record<string, string> {\n const cookies: Record<string, string> = {}\n if (!header) return cookies\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=')\n if (idx === -1) continue\n const key = pair.slice(0, idx).trim()\n const value = pair.slice(idx + 1).trim()\n cookies[key] = value\n }\n return cookies\n}\n\nconst LOGIN_PAGE_HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Codex Web Local &mdash; Login</title>\n<style>\n*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}\nbody{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;background:#0a0a0a;color:#e5e5e5;display:flex;align-items:center;justify-content:center;min-height:100vh;padding:1rem}\n.card{background:#171717;border:1px solid #262626;border-radius:12px;padding:2rem;width:100%;max-width:380px}\nh1{font-size:1.25rem;font-weight:600;margin-bottom:1.5rem;text-align:center;color:#fafafa}\nlabel{display:block;font-size:.875rem;color:#a3a3a3;margin-bottom:.5rem}\ninput{width:100%;padding:.625rem .75rem;background:#0a0a0a;border:1px solid #404040;border-radius:8px;color:#fafafa;font-size:1rem;outline:none;transition:border-color .15s}\ninput:focus{border-color:#3b82f6}\nbutton{width:100%;padding:.625rem;margin-top:1rem;background:#3b82f6;color:#fff;border:none;border-radius:8px;font-size:.9375rem;font-weight:500;cursor:pointer;transition:background .15s}\nbutton:hover{background:#2563eb}\n.error{color:#ef4444;font-size:.8125rem;margin-top:.75rem;text-align:center;display:none}\n</style>\n</head>\n<body>\n<div class=\"card\">\n<h1>Codex Web Local</h1>\n<form id=\"f\">\n<label for=\"pw\">Password</label>\n<input id=\"pw\" name=\"password\" type=\"password\" autocomplete=\"current-password\" autofocus required>\n<button type=\"submit\">Sign in</button>\n<p class=\"error\" id=\"err\">Incorrect password</p>\n</form>\n</div>\n<script>\nconst form=document.getElementById('f');\nconst errEl=document.getElementById('err');\nform.addEventListener('submit',async e=>{\n e.preventDefault();\n errEl.style.display='none';\n const res=await fetch('/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:document.getElementById('pw').value})});\n if(res.ok){window.location.reload()}else{errEl.style.display='block';document.getElementById('pw').value='';document.getElementById('pw').focus()}\n});\n</script>\n</body>\n</html>`\n\nexport function createAuthMiddleware(password: string): RequestHandler {\n const validTokens = new Set<string>()\n\n return (req: Request, res: Response, next: NextFunction): void => {\n if (isLocalhostRequest(req)) {\n next()\n return\n }\n\n // Handle login POST\n if (req.method === 'POST' && req.path === '/auth/login') {\n let body = ''\n req.setEncoding('utf8')\n req.on('data', (chunk: string) => { body += chunk })\n req.on('end', () => {\n try {\n const parsed = JSON.parse(body) as { password?: string }\n const provided = typeof parsed.password === 'string' ? parsed.password : ''\n\n if (!constantTimeCompare(provided, password)) {\n res.status(401).json({ error: 'Invalid password' })\n return\n }\n\n const token = randomBytes(32).toString('hex')\n validTokens.add(token)\n\n res.setHeader('Set-Cookie', `${TOKEN_COOKIE}=${token}; Path=/; HttpOnly; SameSite=Strict`)\n res.json({ ok: true })\n } catch {\n res.status(400).json({ error: 'Invalid request body' })\n }\n })\n return\n }\n\n // Check for valid token cookie\n const cookies = parseCookies(req.headers.cookie)\n const token = cookies[TOKEN_COOKIE]\n\n if (token && validTokens.has(token)) {\n next()\n return\n }\n\n // No valid session — serve login page\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.status(200).send(LOGIN_PAGE_HTML)\n }\n}\n","import { randomInt } from 'node:crypto'\n\nconst CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789'\n\nfunction randomGroup(length: number): string {\n let result = ''\n for (let i = 0; i < length; i++) {\n result += CHARS[randomInt(CHARS.length)]\n }\n return result\n}\n\nexport function generatePassword(): string {\n return `${randomGroup(3)}-${randomGroup(3)}-${randomGroup(3)}`\n}\n"],"mappings":"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","names":["createServer","readFile","homedir","join","spawn","fileURLToPath","dirname","isAbsolute","join","resolve","process","next","token","join","isAbsolute","__dirname","dirname","fileURLToPath","join","readFile","homedir","spawn","resolve","createServer"]}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "codexapp",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "A lightweight web interface for Codex that runs on top of the Codex app-server, allowing remote access from any browser",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Pavel Voronin, Igor Levochkin",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/friuns/codexui.git"
10
+ "url": "git+https://github.com/friuns2/codexui.git"
11
11
  },
12
- "homepage": "https://github.com/friuns/codexui#readme",
12
+ "homepage": "https://github.com/friuns2/codexui#readme",
13
13
  "bugs": {
14
- "url": "https://github.com/friuns/codexui/issues"
14
+ "url": "https://github.com/friuns2/codexui/issues"
15
15
  },
16
16
  "keywords": [
17
17
  "codex",