webtty 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,18 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/pty/bun.ts", "../src/pty/node.ts", "../src/server/index.ts", "../src/server/routes.ts", "../src/server/client.ts", "../src/server/session.ts", "../src/server/static.ts", "../src/utils.ts", "../src/server/websocket.ts", "../src/pty/index.ts"],
3
+ "sources": ["../src/pty/bun.ts", "../src/pty/node.ts", "../src/server/index.ts", "../src/config.ts", "../src/server/routes.ts", "../src/server/session.ts", "../src/server/static.ts", "../src/server/websocket.ts", "../src/pty/index.ts"],
4
4
  "sourcesContent": [
5
- "import { homedir } from 'node:os';\nimport type { PtyProcess } from './types';\n\nexport function spawn(shell: string, cols: number, rows: number): PtyProcess {\n let onDataCb: ((data: string) => void) | undefined;\n let onExitCb: ((e: { exitCode: number }) => void) | undefined;\n\n const proc = Bun.spawn([shell], {\n terminal: {\n cols,\n rows,\n data(_term: unknown, data: Uint8Array) {\n onDataCb?.(Buffer.from(data).toString('utf8'));\n },\n },\n cwd: homedir(),\n env: { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor' },\n });\n\n proc.exited.then((exitCode) => {\n onExitCb?.({ exitCode: exitCode ?? 0 });\n });\n\n return {\n onData(cb) {\n onDataCb = cb;\n },\n onExit(cb) {\n onExitCb = cb;\n },\n write(data) {\n proc.terminal?.write(data);\n },\n resize(cols, rows) {\n proc.terminal?.resize(cols, rows);\n },\n kill() {\n proc.kill();\n },\n };\n}\n",
6
- "import { homedir } from 'node:os';\nimport nodePty from '@lydell/node-pty';\nimport type { PtyProcess } from './types';\n\nexport function spawn(shell: string, cols: number, rows: number): PtyProcess {\n const ptyProc = nodePty.spawn(shell, [], {\n name: 'xterm-256color',\n cols,\n rows,\n cwd: homedir(),\n env: { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor' },\n });\n\n return {\n onData(cb) {\n ptyProc.onData(cb);\n },\n onExit(cb) {\n ptyProc.onExit(cb);\n },\n write(data) {\n ptyProc.write(data);\n },\n resize(cols, rows) {\n ptyProc.resize(cols, rows);\n },\n kill() {\n ptyProc.kill();\n },\n };\n}\n",
7
- "import http from 'node:http';\nimport { handleRequest } from './routes';\nimport { sessionRegistry } from './session';\nimport { findGhosttyWeb } from './static';\nimport { createWebSocketServer } from './websocket';\n\nconst HTTP_PORT = Number(process.env.PORT) || 2346;\n\nconst { distPath, wasmPath } = findGhosttyWeb();\n\nconst httpServer = http.createServer((req, res) => {\n handleRequest(req, res, distPath, wasmPath, () => {\n for (const session of sessionRegistry.values()) {\n session.pty?.kill();\n for (const client of session.clients) client.close(1001, 'server stopped');\n }\n wss.close();\n httpServer.close(() => process.exit(0));\n });\n});\n\nconst wss = createWebSocketServer(httpServer);\n\nprocess.on('SIGINT', () => {\n console.log('\\n\\nShutting down...');\n for (const session of sessionRegistry.values()) {\n session.pty?.kill();\n for (const client of session.clients) client.close(1001, 'server stopped');\n }\n wss.close();\n const exit = () => process.exit(0);\n const shutdownTimeout = setTimeout(exit, 1000);\n httpServer.close(() => {\n clearTimeout(shutdownTimeout);\n exit();\n });\n});\n\nhttpServer.listen(HTTP_PORT, '127.0.0.1', () => {\n console.log(`listening on http://127.0.0.1:${HTTP_PORT}`);\n});\n",
8
- "import type http from 'node:http';\nimport path from 'node:path';\nimport { render } from './client';\nimport {\n createSession,\n generateId,\n isValidId,\n lastUsedId,\n sessionRegistry,\n sessionToJson,\n setLastUsedId,\n} from './session';\nimport { serveFile } from './static';\n\nconst MAX_BODY = 64 * 1024;\n\nfunction decodeId(raw: string): string | null {\n try {\n return decodeURIComponent(raw);\n } catch {\n return null;\n }\n}\n\nexport function readJson(req: http.IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n if (body.length > MAX_BODY) {\n req.destroy();\n reject(Object.assign(new Error('payload too large'), { status: 413 }));\n }\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch {\n reject(new Error('invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n}\n\nexport async function handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n distPath: string,\n wasmPath: string,\n onStop: () => void,\n): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n const pathname = url.pathname;\n\n if (req.method === 'POST' && pathname === '/api/server/stop') {\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end('stopping');\n onStop();\n return;\n }\n\n if (pathname === '/api/sessions') {\n if (req.method === 'GET') {\n const list = [...sessionRegistry.values()].map(sessionToJson);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(list));\n return;\n }\n\n if (req.method === 'POST') {\n let body: { id?: string };\n try {\n body = (await readJson(req)) as { id?: string };\n } catch (err) {\n const status = (err as { status?: number }).status === 413 ? 413 : 400;\n res.writeHead(status);\n res.end(status === 413 ? 'Payload Too Large' : 'invalid JSON');\n return;\n }\n\n const id = body.id ?? generateId();\n if (!isValidId(id)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `invalid id: ${id}` }));\n return;\n }\n if (sessionRegistry.has(id)) {\n res.writeHead(409, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `session already exists: ${id}` }));\n return;\n }\n const session = createSession(id);\n res.writeHead(201, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n }\n\n const sessionMatch = pathname.match(/^\\/api\\/sessions\\/([^/]+)$/);\n if (sessionMatch) {\n const id = decodeId(sessionMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n\n if (req.method === 'GET') {\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n\n if (req.method === 'PATCH') {\n let body: { id?: string };\n try {\n body = (await readJson(req)) as { id?: string };\n } catch (err) {\n const status = (err as { status?: number }).status === 413 ? 413 : 400;\n res.writeHead(status);\n res.end(status === 413 ? 'Payload Too Large' : 'invalid JSON');\n return;\n }\n\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const newId = body.id;\n if (!newId) {\n res.writeHead(400);\n res.end('missing id');\n return;\n }\n if (!isValidId(newId)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `invalid id: ${newId}` }));\n return;\n }\n if (sessionRegistry.has(newId)) {\n res.writeHead(409, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `session already exists: ${newId}` }));\n return;\n }\n sessionRegistry.delete(id);\n session.id = newId;\n sessionRegistry.set(newId, session);\n if (lastUsedId === id) setLastUsedId(newId);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n\n if (req.method === 'DELETE') {\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n sessionRegistry.delete(id);\n if (lastUsedId === id) setLastUsedId(null);\n for (const client of session.clients) client.close(4001, 'session deleted');\n session.pty?.kill();\n res.writeHead(204);\n res.end();\n return;\n }\n }\n\n if (req.method === 'GET' && (pathname === '/' || pathname === '/index.html')) {\n let targetId = lastUsedId ?? null;\n if (!targetId || !sessionRegistry.has(targetId)) {\n if (!sessionRegistry.has('main')) createSession('main');\n targetId = 'main';\n }\n res.writeHead(302, { Location: `/s/${targetId}` });\n res.end();\n return;\n }\n\n const clientMatch = pathname.match(/^\\/s\\/([^/]+)$/);\n if (req.method === 'GET' && clientMatch) {\n const id = decodeId(clientMatch[1]);\n if (!id || !isValidId(id) || !sessionRegistry.has(id)) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(render(id));\n return;\n }\n\n if (pathname.startsWith('/dist/')) {\n const filePath = path.resolve(distPath, pathname.slice(6));\n if (\n !filePath.startsWith(path.resolve(distPath) + path.sep) &&\n filePath !== path.resolve(distPath)\n ) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n serveFile(filePath, res);\n return;\n }\n\n if (pathname === '/ghostty-vt.wasm') {\n serveFile(wasmPath, res);\n return;\n }\n\n res.writeHead(404);\n res.end('Not Found');\n}\n",
9
- "export function render(sessionId: string): string {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>webtty ${sessionId}</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n html, body, #terminal { width: 100%; height: 100%; overflow: hidden; background: #282A36; }\n\n #terminal canvas { display: block; }\n </style>\n </head>\n <body>\n <div id=\"terminal\"></div>\n\n <script type=\"module\">\n import { init, Terminal, FitAddon } from '/dist/ghostty-web.js';\n\n await init();\n const term = new Terminal({\n cols: 80,\n rows: 24,\n cursorBlink: true,\n fontSize: 14,\n fontFamily: \"'FiraMono Nerd Font', Menlo, Monaco, 'Courier New', monospace\",\n scrollback: 10000,\n theme: {\n background: '#282A36',\n foreground: '#F8F8F2',\n cursor: '#F8F8F2',\n selection: '#44475A',\n black: '#21222C',\n red: '#FF5555',\n green: '#50FA7B',\n yellow: '#F1FA8C',\n blue: '#BD93F9',\n purple: '#FF79C6',\n cyan: '#8BE9FD',\n white: '#F8F8F2',\n brightBlack: '#6272A4',\n brightRed: '#FF6E6E',\n brightGreen: '#69FF94',\n brightYellow: '#FFFFA5',\n brightBlue: '#D6ACFF',\n brightPurple: '#FF92DF',\n brightCyan: '#A4FFFF',\n brightWhite: '#FFFFFF',\n },\n });\n\n const fitAddon = new FitAddon();\n term.loadAddon(fitAddon);\n\n const container = document.getElementById('terminal');\n await term.open(container);\n fitAddon.fit();\n fitAddon.observeResize();\n\n const sessionId = ${JSON.stringify(sessionId)};\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n let ws;\n\n function connect() {\n const wsUrl = protocol + '//' + window.location.host + '/ws/' + sessionId + '?cols=' + term.cols + '&rows=' + term.rows;\n ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n console.log('[webtty] connected to session ' + sessionId);\n ws.send(JSON.stringify({ type: 'resize', cols: term.cols, rows: term.rows }));\n };\n\n ws.onmessage = (event) => {\n term.write(event.data);\n };\n\n ws.onclose = (event) => {\n if (event.code === 4001) {\n term.write('\\\\r\\\\n\\\\x1b[31mSession removed.\\\\x1b[0m\\\\r\\\\n');\n setTimeout(() => window.close(), 500);\n return;\n }\n if (event.code === 1001) {\n term.write('\\\\r\\\\n\\\\x1b[33mServer stopped.\\\\x1b[0m\\\\r\\\\n');\n setTimeout(() => window.close(), 500);\n return;\n }\n console.log('[webtty] disconnected, reconnecting in 2s...');\n term.write('\\\\r\\\\n\\\\x1b[31mConnection closed. Reconnecting in 2s...\\\\x1b[0m\\\\r\\\\n');\n setTimeout(connect, 2000);\n };\n\n ws.onerror = () => {\n console.error('[webtty] websocket error');\n };\n }\n\n connect();\n\n term.onData((data) => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data);\n }\n });\n\n term.onResize(({ cols, rows }) => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: 'resize', cols, rows }));\n }\n });\n\n window.addEventListener('resize', () => {\n fitAddon.fit();\n });\n </script>\n </body>\n</html>`;\n}\n",
10
- "import type { WebSocket as WS } from 'ws';\nimport type { PtyProcess } from '../pty';\n\nexport const SCROLLBACK_MAX = 256 * 1024;\n\nexport interface Session {\n id: string;\n createdAt: number;\n pty: PtyProcess | null;\n clients: Set<WS>;\n scrollback: string;\n}\n\nexport const sessionRegistry = new Map<string, Session>();\nexport let lastUsedId: string | null = null;\n\nexport function setLastUsedId(id: string | null): void {\n lastUsedId = id;\n}\n\nconst ID_RE = /^[a-z0-9\\-_.]{1,64}$/;\n\nexport function isValidId(id: string): boolean {\n return ID_RE.test(id);\n}\n\nexport function generateId(): string {\n return Math.floor(Math.random() * 0xffffffff)\n .toString(16)\n .padStart(8, '0');\n}\n\nexport function createSession(id: string): Session {\n const session: Session = {\n id,\n createdAt: Date.now(),\n pty: null,\n clients: new Set(),\n scrollback: '',\n };\n sessionRegistry.set(id, session);\n return session;\n}\n\nexport function sessionToJson(s: Session) {\n return { id: s.id, createdAt: s.createdAt, connected: s.clients.size > 0 };\n}\n",
11
- "import fs from 'node:fs';\nimport type http from 'node:http';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ghosttyWebRootFromMain, mimeType } from '../utils';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst require = createRequire(import.meta.url);\n\nexport function findGhosttyWeb(): { distPath: string; wasmPath: string } {\n try {\n const ghosttyWebMain = require.resolve('ghostty-web') as string;\n const ghosttyWebRoot = ghosttyWebRootFromMain(ghosttyWebMain);\n const distPath = path.join(ghosttyWebRoot, 'dist');\n const wasmPath = path.join(ghosttyWebRoot, 'ghostty-vt.wasm');\n if (fs.existsSync(path.join(distPath, 'ghostty-web.js')) && fs.existsSync(wasmPath)) {\n return { distPath, wasmPath };\n }\n } catch {\n // fall through\n }\n console.error('Error: Could not find ghostty-web package.');\n process.exit(1);\n}\n\nexport function serveFile(filePath: string, res: http.ServerResponse): void {\n const contentType = mimeType(filePath);\n fs.readFile(filePath, (err, data) => {\n if (err) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(data);\n });\n}\n",
12
- "import path from 'node:path';\n\nexport const MIME_TYPES: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.mjs': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.wasm': 'application/wasm',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n};\n\nexport function mimeType(filePath: string): string {\n const ext = path.extname(filePath);\n return MIME_TYPES[ext] ?? 'application/octet-stream';\n}\n\nexport function ghosttyWebRootFromMain(mainPath: string): string {\n return mainPath.replace(/[/\\\\]dist[/\\\\].*$/, '');\n}\n",
13
- "import type http from 'node:http';\nimport type { WebSocket as WS } from 'ws';\nimport { WebSocketServer } from 'ws';\nimport { spawnForSession } from '../pty';\nimport { SCROLLBACK_MAX, sessionRegistry, setLastUsedId } from './session';\n\nexport function createWebSocketServer(httpServer: http.Server): WebSocketServer {\n const wss = new WebSocketServer({ noServer: true });\n\n httpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n if (url.pathname.match(/^\\/ws\\/([^/]+)$/)) {\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws: WS, req: http.IncomingMessage) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n const wsMatch = url.pathname.match(/^\\/ws\\/([^/]+)$/);\n if (!wsMatch) {\n ws.close();\n return;\n }\n\n let id: string;\n try {\n id = decodeURIComponent(wsMatch[1]);\n } catch {\n ws.close(1008, 'Bad Request');\n return;\n }\n const cols = Math.max(\n 1,\n Math.min(1000, Number.parseInt(url.searchParams.get('cols') ?? '80', 10) || 80),\n );\n const rows = Math.max(\n 1,\n Math.min(500, Number.parseInt(url.searchParams.get('rows') ?? '24', 10) || 24),\n );\n\n if (!sessionRegistry.has(id)) {\n ws.close(4001, 'session deleted');\n return;\n }\n\n const session = sessionRegistry.get(id);\n if (!session) {\n ws.close(4001, 'session deleted');\n return;\n }\n session.clients.add(ws);\n setLastUsedId(id);\n\n if (!session.pty) {\n session.pty = spawnForSession(cols, rows);\n\n session.pty.onData((data: string) => {\n session.scrollback = (session.scrollback + data).slice(-SCROLLBACK_MAX);\n for (const client of session.clients) {\n if (client.readyState === client.OPEN) {\n client.send(data, { binary: false });\n }\n }\n });\n\n session.pty.onExit(() => {\n sessionRegistry.delete(session.id);\n for (const client of session.clients) {\n if (client.readyState === client.OPEN) {\n client.close(4001, 'shell exited');\n }\n }\n session.pty = null;\n });\n\n const C = '\\x1b[1;36m';\n const G = '\\x1b[1;32m';\n const Y = '\\x1b[1;33m';\n const R = '\\x1b[0m';\n const banner = [\n `${C}╔══════════════════════════════════════════════════════════════╗${R}\\r\\n`,\n `${C}║${R} ${G}Welcome to webtty!${R} ${C}║${R}\\r\\n`,\n `${C}║${R} ${C}║${R}\\r\\n`,\n `${C}║${R} You have a real shell session with full PTY support. ${C}║${R}\\r\\n`,\n `${C}║${R} Try: ${Y}ls${R}, ${Y}cd${R}, ${Y}top${R}, ${Y}vim${R}, or any command! ${C}║${R}\\r\\n`,\n `${C}╚══════════════════════════════════════════════════════════════╝${R}\\r\\n\\r\\n`,\n ].join('');\n ws.send(banner);\n session.scrollback = banner;\n session.pty.write('\\n');\n } else {\n if (session.scrollback) {\n ws.send(session.scrollback, { binary: false });\n }\n session.pty.resize(cols, rows);\n }\n\n ws.on('message', (data: Buffer) => {\n const message = data.toString('utf8');\n if (message.startsWith('{')) {\n try {\n const msg = JSON.parse(message) as { type: string; cols: number; rows: number };\n if (msg.type === 'resize') {\n const c = Math.max(1, Math.min(1000, Math.trunc(msg.cols) || 80));\n const r = Math.max(1, Math.min(500, Math.trunc(msg.rows) || 24));\n session.pty?.resize(c, r);\n return;\n }\n } catch {\n // fall through\n }\n }\n session.pty?.write(message);\n });\n\n ws.on('close', () => {\n session.clients.delete(ws);\n });\n\n ws.on('error', () => {});\n });\n\n return wss;\n}\n",
14
- "export type { PtyProcess } from './types';\n\nconst isBun = !!process.versions.bun;\nconsole.log(`pty: ${isBun ? 'Bun.Terminal' : 'node-pty'}`);\n\nconst { spawn: _spawn } = await (isBun ? import('./bun') : import('./node'));\n\nexport const spawn = _spawn;\n\nexport function spawnForSession(cols: number, rows: number) {\n const shell =\n process.platform === 'win32'\n ? (process.env.COMSPEC ?? 'cmd.exe')\n : (process.env.SHELL ?? '/bin/bash');\n return _spawn(shell, cols, rows);\n}\n"
5
+ "import { homedir } from 'node:os';\nimport type { PtyProcess } from './types';\n\nexport function spawn(\n shell: string,\n cols: number,\n rows: number,\n term: string,\n colorTerm: string,\n): PtyProcess {\n let onDataCb: ((data: string) => void) | undefined;\n let onExitCb: ((e: { exitCode: number }) => void) | undefined;\n\n const proc = Bun.spawn([shell], {\n terminal: {\n cols,\n rows,\n data(_term: unknown, data: Uint8Array) {\n onDataCb?.(Buffer.from(data).toString('utf8'));\n },\n },\n cwd: homedir(),\n env: { ...process.env, TERM: term, COLORTERM: colorTerm },\n });\n\n proc.exited.then((exitCode) => {\n onExitCb?.({ exitCode: exitCode ?? 0 });\n });\n\n return {\n onData(cb) {\n onDataCb = cb;\n },\n onExit(cb) {\n onExitCb = cb;\n },\n write(data) {\n proc.terminal?.write(data);\n },\n resize(cols, rows) {\n proc.terminal?.resize(cols, rows);\n },\n kill() {\n proc.kill();\n },\n };\n}\n",
6
+ "import { homedir } from 'node:os';\nimport nodePty from '@lydell/node-pty';\nimport type { PtyProcess } from './types';\n\nexport function spawn(\n shell: string,\n cols: number,\n rows: number,\n term: string,\n colorTerm: string,\n): PtyProcess {\n const ptyProc = nodePty.spawn(shell, [], {\n name: term,\n cols,\n rows,\n cwd: homedir(),\n env: { ...process.env, TERM: term, COLORTERM: colorTerm },\n });\n\n return {\n onData(cb) {\n ptyProc.onData(cb);\n },\n onExit(cb) {\n ptyProc.onExit(cb);\n },\n write(data) {\n ptyProc.write(data);\n },\n resize(cols, rows) {\n ptyProc.resize(cols, rows);\n },\n kill() {\n ptyProc.kill();\n },\n };\n}\n",
7
+ "import fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { loadConfig } from '../config';\nimport { handleRequest } from './routes';\nimport { findGhosttyWeb } from './static';\nimport { closeAllSessions, createWebSocketServer, setLastSessionClosedHandler } from './websocket';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst config = loadConfig();\nconst HTTP_PORT = Number(process.env.PORT) || config.port;\nconst HTTP_HOST = config.host;\n\nconst { distPath, wasmPath } = findGhosttyWeb();\nconst projectRoot = path.resolve(__dirname, '..', '..');\nconst builtDistPath = path.join(projectRoot, 'dist');\nconst srcClientPath = path.join(projectRoot, 'src', 'client');\nconst clientDistPath = fs.existsSync(path.join(builtDistPath, 'client.html'))\n ? builtDistPath\n : srcClientPath;\n\nfunction shutdown() {\n closeAllSessions();\n wss.close();\n const exit = () => process.exit(0);\n const shutdownTimeout = setTimeout(exit, 1000);\n httpServer.close(() => {\n clearTimeout(shutdownTimeout);\n exit();\n });\n}\n\nconst httpServer = http.createServer((req, res) => {\n handleRequest(req, res, distPath, wasmPath, clientDistPath, shutdown);\n});\n\nconst wss = createWebSocketServer(httpServer);\nsetLastSessionClosedHandler(shutdown);\n\nprocess.on('SIGINT', () => {\n console.log('\\n\\nShutting down...');\n shutdown();\n});\n\nhttpServer.listen(HTTP_PORT, HTTP_HOST, () => {\n console.log(`listening on http://${HTTP_HOST}:${HTTP_PORT}`);\n});\n",
8
+ "import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport interface Theme {\n background?: string;\n foreground?: string;\n cursor?: string;\n selection?: string;\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n purple?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightPurple?: string;\n brightCyan?: string;\n brightWhite?: string;\n}\n\nexport type RightClickBehavior = 'default' | 'copyPaste';\n\nexport interface Config {\n port: number;\n host: string;\n shell: string;\n term: string;\n colorTerm: string;\n scrollback: number;\n cols: number;\n rows: number;\n fontSize: number;\n fontFamily: string;\n cursorBlink: boolean;\n copyOnSelect: boolean;\n rightClickBehavior: RightClickBehavior;\n logs: boolean;\n theme: Theme;\n}\n\nexport function configDir(): string {\n return path.join(process.env.HOME ?? os.homedir(), '.config', 'webtty');\n}\n\nfunction getConfigPath(): string {\n return path.join(configDir(), 'config.json');\n}\n\nexport const DEFAULT_THEME: Theme = {\n background: '#000000',\n foreground: '#CCCCCC',\n cursor: '#FFFFFF',\n selection: '#FFFFFF',\n black: '#0C0C0C',\n red: '#C50F1F',\n green: '#13A10E',\n yellow: '#C19C00',\n blue: '#0037DA',\n purple: '#881798',\n cyan: '#3A96DD',\n white: '#CCCCCC',\n brightBlack: '#767676',\n brightRed: '#E74856',\n brightGreen: '#16C60C',\n brightYellow: '#F9F1A5',\n brightBlue: '#3B78FF',\n brightPurple: '#B4009E',\n brightCyan: '#61D6D6',\n brightWhite: '#F2F2F2',\n};\n\nexport const DEFAULT_CONFIG: Config = {\n port: 2346,\n host: '127.0.0.1',\n shell:\n process.platform === 'win32'\n ? (process.env.COMSPEC ?? 'cmd.exe')\n : (process.env.SHELL ?? '/bin/bash'),\n term: process.env.TERM ?? 'xterm-256color',\n colorTerm: 'truecolor',\n scrollback: 256 * 1024,\n cols: 80,\n rows: 24,\n fontSize: 13,\n fontFamily: \"Menlo, Consolas, 'DejaVu Sans Mono', monospace\",\n cursorBlink: true,\n copyOnSelect: true,\n rightClickBehavior: 'default' as RightClickBehavior,\n logs: false,\n theme: DEFAULT_THEME,\n};\n\nexport function loadConfig(): Config {\n if (!fs.existsSync(getConfigPath())) {\n try {\n saveConfig(DEFAULT_CONFIG);\n } catch (err) {\n console.warn(\n `webtty: failed to write default config to ${getConfigPath()}: ${(err as Error).message}`,\n );\n return { ...DEFAULT_CONFIG };\n }\n }\n\n let raw: string;\n try {\n raw = fs.readFileSync(getConfigPath(), 'utf8');\n } catch (err) {\n throw new Error(\n `webtty: failed to read config at ${getConfigPath()}: ${(err as Error).message}`,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(`webtty: invalid JSON in config file ${getConfigPath()}`);\n }\n\n const p = parsed as Partial<Config>;\n return {\n ...DEFAULT_CONFIG,\n ...(typeof p.port === 'number' && { port: p.port }),\n ...(typeof p.host === 'string' && { host: p.host }),\n ...(typeof p.shell === 'string' && { shell: p.shell }),\n ...(typeof p.term === 'string' && { term: p.term }),\n ...(typeof p.colorTerm === 'string' && { colorTerm: p.colorTerm }),\n ...(typeof p.scrollback === 'number' && { scrollback: p.scrollback }),\n ...(typeof p.cols === 'number' && { cols: p.cols }),\n ...(typeof p.rows === 'number' && { rows: p.rows }),\n ...(typeof p.fontSize === 'number' && { fontSize: p.fontSize }),\n ...(typeof p.fontFamily === 'string' && { fontFamily: p.fontFamily }),\n ...(typeof p.cursorBlink === 'boolean' && { cursorBlink: p.cursorBlink }),\n ...(typeof p.copyOnSelect === 'boolean' && { copyOnSelect: p.copyOnSelect }),\n ...(typeof p.rightClickBehavior === 'string' && {\n rightClickBehavior: (p.rightClickBehavior === 'copyPaste'\n ? 'copyPaste'\n : 'default') as RightClickBehavior,\n }),\n ...(typeof p.logs === 'boolean' && { logs: p.logs }),\n ...(p.theme && typeof p.theme === 'object' && { theme: { ...DEFAULT_THEME, ...p.theme } }),\n };\n}\n\nexport function saveConfig(_config: Config): void {\n fs.mkdirSync(path.dirname(getConfigPath()), { recursive: true });\n const content = JSON.stringify(\n {\n port: DEFAULT_CONFIG.port,\n host: DEFAULT_CONFIG.host,\n },\n null,\n 2,\n );\n fs.writeFileSync(getConfigPath(), content, 'utf8');\n}\n",
9
+ "import type http from 'node:http';\nimport path from 'node:path';\nimport { loadConfig } from '../config';\nimport {\n createSession,\n generateId,\n isValidId,\n lastUsedId,\n sessionRegistry,\n sessionToJson,\n setLastUsedId,\n} from './session';\nimport { serveFile } from './static';\nimport { closeSession } from './websocket';\n\nconst MAX_BODY = 64 * 1024;\n\nfunction decodeId(raw: string): string | null {\n try {\n return decodeURIComponent(raw);\n } catch {\n return null;\n }\n}\n\nexport function readJson(req: http.IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n if (body.length > MAX_BODY) {\n req.destroy();\n reject(Object.assign(new Error('payload too large'), { status: 413 }));\n }\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch {\n reject(new Error('invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n}\n\nexport async function handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n distPath: string,\n wasmPath: string,\n clientDistPath: string,\n onStop: () => void,\n): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n const pathname = url.pathname;\n\n if (req.method === 'POST' && pathname === '/api/server/stop') {\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end('stopping');\n onStop();\n return;\n }\n\n if (req.method === 'GET' && pathname === '/api/config') {\n const config = loadConfig();\n const clientConfig = {\n cols: config.cols,\n rows: config.rows,\n fontSize: config.fontSize,\n fontFamily: config.fontFamily,\n cursorBlink: config.cursorBlink,\n scrollback: config.scrollback,\n theme: config.theme,\n copyOnSelect: config.copyOnSelect,\n rightClickBehavior: config.rightClickBehavior,\n };\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(clientConfig));\n return;\n }\n\n if (pathname === '/api/sessions') {\n if (req.method === 'GET') {\n const list = [...sessionRegistry.values()].map(sessionToJson);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(list));\n return;\n }\n\n if (req.method === 'POST') {\n let body: { id?: string };\n try {\n body = (await readJson(req)) as { id?: string };\n } catch (err) {\n const status = (err as { status?: number }).status === 413 ? 413 : 400;\n res.writeHead(status);\n res.end(status === 413 ? 'Payload Too Large' : 'invalid JSON');\n return;\n }\n\n const id = body.id ?? generateId();\n if (!isValidId(id)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `invalid id: ${id}` }));\n return;\n }\n if (sessionRegistry.has(id)) {\n res.writeHead(409, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `session already exists: ${id}` }));\n return;\n }\n const session = createSession(id);\n res.writeHead(201, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n }\n\n const sessionMatch = pathname.match(/^\\/api\\/sessions\\/([^/]+)$/);\n if (sessionMatch) {\n const id = decodeId(sessionMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n\n if (req.method === 'GET') {\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n\n if (req.method === 'PATCH') {\n let body: { id?: string };\n try {\n body = (await readJson(req)) as { id?: string };\n } catch (err) {\n const status = (err as { status?: number }).status === 413 ? 413 : 400;\n res.writeHead(status);\n res.end(status === 413 ? 'Payload Too Large' : 'invalid JSON');\n return;\n }\n\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const newId = body.id;\n if (!newId) {\n res.writeHead(400);\n res.end('missing id');\n return;\n }\n if (!isValidId(newId)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `invalid id: ${newId}` }));\n return;\n }\n if (sessionRegistry.has(newId)) {\n res.writeHead(409, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `session already exists: ${newId}` }));\n return;\n }\n sessionRegistry.delete(id);\n session.id = newId;\n sessionRegistry.set(newId, session);\n if (lastUsedId === id) setLastUsedId(newId);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessionToJson(session)));\n return;\n }\n\n if (req.method === 'DELETE') {\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n sessionRegistry.delete(id);\n if (lastUsedId === id) setLastUsedId(null);\n closeSession(session);\n res.writeHead(204, { 'X-Sessions-Remaining': String(sessionRegistry.size) });\n res.end();\n return;\n }\n }\n\n if (req.method === 'GET' && (pathname === '/' || pathname === '/index.html')) {\n let targetId = lastUsedId ?? null;\n if (!targetId || !sessionRegistry.has(targetId)) {\n if (!sessionRegistry.has('main')) createSession('main');\n targetId = 'main';\n }\n res.writeHead(302, { Location: `/s/${targetId}` });\n res.end();\n return;\n }\n\n const clientMatch = pathname.match(/^\\/s\\/([^/]+)$/);\n if (req.method === 'GET' && clientMatch) {\n const id = decodeId(clientMatch[1]);\n if (!id || !isValidId(id) || !sessionRegistry.has(id)) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n const clientHtml = path.resolve(clientDistPath, 'client.html');\n serveFile(clientHtml, res);\n return;\n }\n\n if (pathname.startsWith('/dist/')) {\n const relativePath = pathname.slice(6);\n const ownFile = path.resolve(clientDistPath, relativePath);\n if (ownFile.startsWith(clientDistPath + path.sep)) {\n const fs = await import('node:fs');\n if (fs.existsSync(ownFile)) {\n serveFile(ownFile, res);\n return;\n }\n }\n const filePath = path.resolve(distPath, relativePath);\n if (\n !filePath.startsWith(path.resolve(distPath) + path.sep) &&\n filePath !== path.resolve(distPath)\n ) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n serveFile(filePath, res);\n return;\n }\n\n if (pathname === '/ghostty-vt.wasm') {\n serveFile(wasmPath, res);\n return;\n }\n\n res.writeHead(404);\n res.end('Not Found');\n}\n",
10
+ "import type { WebSocket as WS } from 'ws';\nimport type { PtyProcess } from '../pty';\n\nexport interface Session {\n id: string;\n createdAt: number;\n pty: PtyProcess | null;\n clients: Set<WS>;\n scrollback: string;\n}\n\nexport const sessionRegistry = new Map<string, Session>();\nexport let lastUsedId: string | null = null;\n\nexport function setLastUsedId(id: string | null): void {\n lastUsedId = id;\n}\n\nconst ID_RE = /^[a-z0-9\\-_.]{1,64}$/;\n\nexport function isValidId(id: string): boolean {\n return ID_RE.test(id);\n}\n\nexport function generateId(): string {\n return Math.floor(Math.random() * 0xffffffff)\n .toString(16)\n .padStart(8, '0');\n}\n\nexport function createSession(id: string): Session {\n const session: Session = {\n id,\n createdAt: Date.now(),\n pty: null,\n clients: new Set(),\n scrollback: '',\n };\n sessionRegistry.set(id, session);\n return session;\n}\n\nexport function sessionToJson(s: Session) {\n return { id: s.id, createdAt: s.createdAt, connected: s.clients.size > 0 };\n}\n",
11
+ "import fs from 'node:fs';\nimport type http from 'node:http';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst require = createRequire(import.meta.url);\n\nexport const MIME_TYPES: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.mjs': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.wasm': 'application/wasm',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n};\n\nexport function mimeType(filePath: string): string {\n const ext = path.extname(filePath);\n return MIME_TYPES[ext] ?? 'application/octet-stream';\n}\n\nexport function ghosttyWebRootFromMain(mainPath: string): string {\n return mainPath.replace(/[/\\\\]dist[/\\\\].*$/, '');\n}\n\nexport function findGhosttyWeb(): { distPath: string; wasmPath: string } {\n try {\n const ghosttyWebMain = require.resolve('ghostty-web') as string;\n const ghosttyWebRoot = ghosttyWebRootFromMain(ghosttyWebMain);\n const distPath = path.join(ghosttyWebRoot, 'dist');\n const wasmPath = path.join(ghosttyWebRoot, 'ghostty-vt.wasm');\n if (fs.existsSync(path.join(distPath, 'ghostty-web.js')) && fs.existsSync(wasmPath)) {\n return { distPath, wasmPath };\n }\n } catch {\n // fall through\n }\n console.error('Error: Could not find ghostty-web package.');\n process.exit(1);\n}\n\nexport function serveFile(filePath: string, res: http.ServerResponse): void {\n const contentType = mimeType(filePath);\n fs.readFile(filePath, (err, data) => {\n if (err) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(data);\n });\n}\n",
12
+ "import type http from 'node:http';\nimport type { WebSocket as WS } from 'ws';\nimport { WebSocketServer } from 'ws';\nimport { loadConfig } from '../config';\nimport { spawnForSession } from '../pty';\nimport type { Session } from './session';\nimport { sessionRegistry, setLastUsedId } from './session';\n\nconst WS_CLOSE = {\n SERVER_STOPPED: 1001 as const, // RFC 6455: server going away\n BAD_REQUEST: 1008 as const, // RFC 6455: policy violation / bad data\n SESSION_GONE: 4001 as const, // app-level: session deleted or shell exited\n} as const;\n\nfunction closeClients(session: Session, code: number, reason: string): void {\n session.pty?.kill();\n for (const client of session.clients) client.close(code, reason);\n}\n\nexport function closeSession(session: Session): void {\n closeClients(session, WS_CLOSE.SESSION_GONE, 'session deleted');\n}\n\nexport function closeAllSessions(): void {\n for (const session of sessionRegistry.values()) {\n closeClients(session, WS_CLOSE.SERVER_STOPPED, 'server stopped');\n }\n}\n\nlet onLastSessionClosed: (() => void) | null = null;\n\nexport function setLastSessionClosedHandler(handler: () => void): void {\n onLastSessionClosed = handler;\n}\n\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst ITALIC = '\\x1b[3m';\nconst YELLOW = '\\x1b[1;33m';\nconst CYAN = '\\x1b[1;36m';\n\nconst isBun = process.execPath.includes('bun');\nconst PKG_RUNNER = isBun ? 'bunx' : 'npx';\n\nfunction sessionBanner(): string {\n const W = 48;\n const pipe = (content: string) => `${CYAN}║${RESET}${content}${CYAN}║${RESET}`;\n const blank = pipe(' '.repeat(W));\n\n const titleVis = ' [ webtty ] Terminal UI in the browser';\n const titleStr = ` ${DIM}[${RESET} ${BOLD}${YELLOW}webtty${RESET} ${DIM}] Terminal UI in the browser${RESET}`;\n const titleLine = pipe(titleStr + ' '.repeat(W - titleVis.length));\n\n const cmd = `${PKG_RUNNER} webtty help`;\n const helpVis = ` Run \\`${cmd}\\` for more information.`;\n const helpStr = ` ${DIM}Run \\`${RESET}${ITALIC}${cmd}${RESET}${DIM}\\` for more information.${RESET}`;\n const helpLine = pipe(helpStr + ' '.repeat(W - helpVis.length));\n\n return [\n `${CYAN}╔${'═'.repeat(W)}╗${RESET}`,\n '\\r\\n',\n blank,\n '\\r\\n',\n titleLine,\n '\\r\\n',\n blank,\n '\\r\\n',\n helpLine,\n '\\r\\n',\n blank,\n '\\r\\n',\n `${CYAN}╚${'═'.repeat(W)}╝${RESET}`,\n '\\r\\n',\n '\\r\\n',\n ].join('');\n}\n\nexport function createWebSocketServer(httpServer: http.Server): WebSocketServer {\n const wss = new WebSocketServer({ noServer: true });\n\n httpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n if (url.pathname.match(/^\\/ws\\/([^/]+)$/)) {\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws: WS, req: http.IncomingMessage) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);\n const wsMatch = url.pathname.match(/^\\/ws\\/([^/]+)$/);\n if (!wsMatch) {\n ws.close();\n return;\n }\n\n let id: string;\n try {\n id = decodeURIComponent(wsMatch[1]);\n } catch {\n ws.close(WS_CLOSE.BAD_REQUEST, 'Bad Request');\n return;\n }\n const cols = Math.max(\n 1,\n Math.min(1000, Number.parseInt(url.searchParams.get('cols') ?? '80', 10) || 80),\n );\n const rows = Math.max(\n 1,\n Math.min(500, Number.parseInt(url.searchParams.get('rows') ?? '24', 10) || 24),\n );\n\n if (!sessionRegistry.has(id)) {\n ws.close(WS_CLOSE.SESSION_GONE, 'session deleted');\n return;\n }\n\n const session = sessionRegistry.get(id);\n if (!session) {\n ws.close(WS_CLOSE.SESSION_GONE, 'session deleted');\n return;\n }\n session.clients.add(ws);\n setLastUsedId(id);\n\n if (!session.pty) {\n const config = loadConfig();\n session.pty = spawnForSession(cols, rows, config.shell, config.term, config.colorTerm);\n\n session.pty.onData((data: string) => {\n session.scrollback = (session.scrollback + data).slice(-config.scrollback);\n for (const client of session.clients) {\n if (client.readyState === client.OPEN) {\n client.send(data, { binary: false });\n }\n }\n });\n\n session.pty.onExit(() => {\n sessionRegistry.delete(session.id);\n for (const client of session.clients) {\n if (client.readyState === client.OPEN) {\n client.close(WS_CLOSE.SESSION_GONE, 'shell exited');\n }\n }\n session.pty = null;\n if (sessionRegistry.size === 0) onLastSessionClosed?.();\n });\n\n const banner = sessionBanner();\n ws.send(banner);\n session.scrollback = banner;\n session.pty.write('\\n');\n } else {\n if (session.scrollback) {\n ws.send(session.scrollback, { binary: false });\n }\n session.pty.resize(cols, rows);\n }\n\n ws.on('message', (data: Buffer) => {\n const message = data.toString('utf8');\n if (message.startsWith('{')) {\n try {\n const msg = JSON.parse(message) as { type: string; cols: number; rows: number };\n if (msg.type === 'resize') {\n const c = Math.max(1, Math.min(1000, Math.trunc(msg.cols) || 80));\n const r = Math.max(1, Math.min(500, Math.trunc(msg.rows) || 24));\n session.pty?.resize(c, r);\n return;\n }\n } catch {\n // fall through\n }\n }\n session.pty?.write(message);\n });\n\n ws.on('close', () => {\n session.clients.delete(ws);\n });\n\n ws.on('error', () => {});\n });\n\n return wss;\n}\n",
13
+ "export type { PtyProcess } from './types';\n\nconst isBun = !!process.versions.bun;\nconsole.log(`pty: ${isBun ? 'Bun.Terminal' : 'node-pty'}`);\n\nconst { spawn: _spawn } = await (isBun ? import('./bun') : import('./node'));\n\nexport const spawn = _spawn;\n\nexport function spawnForSession(\n cols: number,\n rows: number,\n shell: string,\n term: string,\n colorTerm: string,\n) {\n return _spawn(shell, cols, rows, term, colorTerm);\n}\n"
15
14
  ],
16
- "mappings": "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",
17
- "debugId": "243D0B6704BD6DB364756E2164756E21",
15
+ "mappings": "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",
16
+ "debugId": "D4A6F10E2C8CA53E64756E2164756E21",
18
17
  "names": []
19
18
  }
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "webtty",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "description": "Web TTY for running CLI/TUI applications in a browser tab, across platforms",
5
5
  "bin": {
6
- "webtty": "dist/cli/index.js",
7
- "wtty": "dist/cli/index.js"
6
+ "webtty": "dist/cli/index.js"
8
7
  },
9
8
  "files": [
10
9
  "dist"