webtty 0.0.0-development → 1.0.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.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # wtty
1
+ # webtty
2
2
 
3
3
  A web TTY for running CLI/TUI applications in a browser tab, across platforms.
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ if (command === "start") {
14
14
  const isTs = __filename2.endsWith(".ts");
15
15
  const serverEntry = path.resolve(__dirname2, isTs ? "server.ts" : "server.js");
16
16
  if (!fs.existsSync(serverEntry)) {
17
- console.error(`wtty: server entry not found at ${serverEntry}`);
17
+ console.error(`webtty: server entry not found at ${serverEntry}`);
18
18
  process.exit(1);
19
19
  }
20
20
  const child = spawn(process.execPath, [serverEntry], {
@@ -23,22 +23,22 @@ if (command === "start") {
23
23
  env: { ...process.env, PORT: String(PORT) }
24
24
  });
25
25
  child.unref();
26
- console.log("wtty started");
26
+ console.log("webtty started");
27
27
  } else if (command === "stop") {
28
28
  try {
29
29
  const res = await fetch(`${BASE_URL}/api/server/stop`, { method: "POST" });
30
30
  if (res.ok) {
31
- console.log("wtty stopped");
31
+ console.log("webtty stopped");
32
32
  } else {
33
- console.error(`wtty stop failed (status: ${res.status})`);
33
+ console.error(`webtty stop failed (status: ${res.status})`);
34
34
  process.exit(1);
35
35
  }
36
36
  } catch {
37
- console.log("wtty is not running");
37
+ console.log("webtty is not running");
38
38
  }
39
39
  } else {
40
- console.error("Usage: wtty start | wtty stop");
40
+ console.error("Usage: webtty start | webtty stop");
41
41
  process.exit(1);
42
42
  }
43
43
 
44
- //# debugId=1DF946E2C6FEAE1864756E2164756E21
44
+ //# debugId=E82F6BB29AC8C5B764756E2164756E21
package/dist/cli.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/cli.ts"],
4
4
  "sourcesContent": [
5
- "import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst PORT = Number(process.env.PORT) || 2346;\nconst BASE_URL = `http://127.0.0.1:${PORT}`;\n\nconst command = process.argv[2];\n\nif (command === 'start') {\n const isTs = __filename.endsWith('.ts');\n const serverEntry = path.resolve(__dirname, isTs ? 'server.ts' : 'server.js');\n if (!fs.existsSync(serverEntry)) {\n console.error(`wtty: server entry not found at ${serverEntry}`);\n process.exit(1);\n }\n const child = spawn(process.execPath, [serverEntry], {\n detached: true,\n stdio: 'ignore',\n env: { ...process.env, PORT: String(PORT) },\n });\n child.unref();\n console.log('wtty started');\n} else if (command === 'stop') {\n try {\n const res = await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' });\n if (res.ok) {\n console.log('wtty stopped');\n } else {\n console.error(`wtty stop failed (status: ${res.status})`);\n process.exit(1);\n }\n } catch {\n console.log('wtty is not running');\n }\n} else {\n console.error('Usage: wtty start | wtty stop');\n process.exit(1);\n}\n"
5
+ "import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst PORT = Number(process.env.PORT) || 2346;\nconst BASE_URL = `http://127.0.0.1:${PORT}`;\n\nconst command = process.argv[2];\n\nif (command === 'start') {\n const isTs = __filename.endsWith('.ts');\n const serverEntry = path.resolve(__dirname, isTs ? 'server.ts' : 'server.js');\n if (!fs.existsSync(serverEntry)) {\n console.error(`webtty: server entry not found at ${serverEntry}`);\n process.exit(1);\n }\n const child = spawn(process.execPath, [serverEntry], {\n detached: true,\n stdio: 'ignore',\n env: { ...process.env, PORT: String(PORT) },\n });\n child.unref();\n console.log('webtty started');\n} else if (command === 'stop') {\n try {\n const res = await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' });\n if (res.ok) {\n console.log('webtty stopped');\n } else {\n console.error(`webtty stop failed (status: ${res.status})`);\n process.exit(1);\n }\n } catch {\n console.log('webtty is not running');\n }\n} else {\n console.error('Usage: webtty start | webtty stop');\n process.exit(1);\n}\n"
6
6
  ],
7
- "mappings": ";;;AAAA;AACA;AACA;AACA;AAEA,IAAM,cAAa,cAAc,YAAY,GAAG;AAChD,IAAM,aAAY,KAAK,QAAQ,WAAU;AAEzC,IAAM,OAAO,OAAO,QAAQ,IAAI,IAAI,KAAK;AACzC,IAAM,WAAW,oBAAoB;AAErC,IAAM,UAAU,QAAQ,KAAK;AAE7B,IAAI,YAAY,SAAS;AAAA,EACvB,MAAM,OAAO,YAAW,SAAS,KAAK;AAAA,EACtC,MAAM,cAAc,KAAK,QAAQ,YAAW,OAAO,cAAc,WAAW;AAAA,EAC5E,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;AAAA,IAC/B,QAAQ,MAAM,mCAAmC,aAAa;AAAA,IAC9D,QAAQ,KAAK,CAAC;AAAA,EAChB;AAAA,EACA,MAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,WAAW,GAAG;AAAA,IACnD,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK,KAAK,QAAQ,KAAK,MAAM,OAAO,IAAI,EAAE;AAAA,EAC5C,CAAC;AAAA,EACD,MAAM,MAAM;AAAA,EACZ,QAAQ,IAAI,cAAc;AAC5B,EAAO,SAAI,YAAY,QAAQ;AAAA,EAC7B,IAAI;AAAA,IACF,MAAM,MAAM,MAAM,MAAM,GAAG,4BAA4B,EAAE,QAAQ,OAAO,CAAC;AAAA,IACzE,IAAI,IAAI,IAAI;AAAA,MACV,QAAQ,IAAI,cAAc;AAAA,IAC5B,EAAO;AAAA,MACL,QAAQ,MAAM,6BAA6B,IAAI,SAAS;AAAA,MACxD,QAAQ,KAAK,CAAC;AAAA;AAAA,IAEhB,MAAM;AAAA,IACN,QAAQ,IAAI,qBAAqB;AAAA;AAErC,EAAO;AAAA,EACL,QAAQ,MAAM,+BAA+B;AAAA,EAC7C,QAAQ,KAAK,CAAC;AAAA;",
8
- "debugId": "1DF946E2C6FEAE1864756E2164756E21",
7
+ "mappings": ";;;AAAA;AACA;AACA;AACA;AAEA,IAAM,cAAa,cAAc,YAAY,GAAG;AAChD,IAAM,aAAY,KAAK,QAAQ,WAAU;AAEzC,IAAM,OAAO,OAAO,QAAQ,IAAI,IAAI,KAAK;AACzC,IAAM,WAAW,oBAAoB;AAErC,IAAM,UAAU,QAAQ,KAAK;AAE7B,IAAI,YAAY,SAAS;AAAA,EACvB,MAAM,OAAO,YAAW,SAAS,KAAK;AAAA,EACtC,MAAM,cAAc,KAAK,QAAQ,YAAW,OAAO,cAAc,WAAW;AAAA,EAC5E,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG;AAAA,IAC/B,QAAQ,MAAM,qCAAqC,aAAa;AAAA,IAChE,QAAQ,KAAK,CAAC;AAAA,EAChB;AAAA,EACA,MAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,WAAW,GAAG;AAAA,IACnD,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK,KAAK,QAAQ,KAAK,MAAM,OAAO,IAAI,EAAE;AAAA,EAC5C,CAAC;AAAA,EACD,MAAM,MAAM;AAAA,EACZ,QAAQ,IAAI,gBAAgB;AAC9B,EAAO,SAAI,YAAY,QAAQ;AAAA,EAC7B,IAAI;AAAA,IACF,MAAM,MAAM,MAAM,MAAM,GAAG,4BAA4B,EAAE,QAAQ,OAAO,CAAC;AAAA,IACzE,IAAI,IAAI,IAAI;AAAA,MACV,QAAQ,IAAI,gBAAgB;AAAA,IAC9B,EAAO;AAAA,MACL,QAAQ,MAAM,+BAA+B,IAAI,SAAS;AAAA,MAC1D,QAAQ,KAAK,CAAC;AAAA;AAAA,IAEhB,MAAM;AAAA,IACN,QAAQ,IAAI,uBAAuB;AAAA;AAEvC,EAAO;AAAA,EACL,QAAQ,MAAM,mCAAmC;AAAA,EACjD,QAAQ,KAAK,CAAC;AAAA;",
8
+ "debugId": "E82F6BB29AC8C5B764756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/server.js CHANGED
@@ -152,7 +152,7 @@ var HTML_TEMPLATE = `<!doctype html>
152
152
  <head>
153
153
  <meta charset="UTF-8" />
154
154
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
155
- <title>wtty</title>
155
+ <title>webtty</title>
156
156
  <style>
157
157
  * { margin: 0; padding: 0; box-sizing: border-box; }
158
158
 
@@ -215,7 +215,7 @@ var HTML_TEMPLATE = `<!doctype html>
215
215
  ws = new WebSocket(wsUrl);
216
216
 
217
217
  ws.onopen = () => {
218
- console.log('[wtty] connected');
218
+ console.log('[webtty] connected');
219
219
  };
220
220
 
221
221
  ws.onmessage = (event) => {
@@ -223,13 +223,13 @@ var HTML_TEMPLATE = `<!doctype html>
223
223
  };
224
224
 
225
225
  ws.onclose = () => {
226
- console.log('[wtty] disconnected, reconnecting in 2s...');
226
+ console.log('[webtty] disconnected, reconnecting in 2s...');
227
227
  term.write('\\r\\n\\x1b[31mConnection closed. Reconnecting in 2s...\\x1b[0m\\r\\n');
228
228
  setTimeout(connect, 2000);
229
229
  };
230
230
 
231
231
  ws.onerror = () => {
232
- console.error('[wtty] websocket error');
232
+ console.error('[webtty] websocket error');
233
233
  };
234
234
  }
235
235
 
@@ -351,7 +351,7 @@ wss.on("connection", (ws, req) => {
351
351
  const R = "\x1B[0m";
352
352
  ws.send(`${C}╔══════════════════════════════════════════════════════════════╗${R}\r
353
353
  `);
354
- ws.send(`${C}║${R} ${G}Welcome to wtty!${R} ${C}║${R}\r
354
+ ws.send(`${C}║${R} ${G}Welcome to webtty!${R} ${C}║${R}\r
355
355
  `);
356
356
  ws.send(`${C}║${R} ${C}║${R}\r
357
357
  `);
@@ -378,4 +378,4 @@ httpServer.listen(HTTP_PORT, "127.0.0.1", () => {
378
378
  console.log(`listening on http://127.0.0.1:${HTTP_PORT}`);
379
379
  });
380
380
 
381
- //# debugId=76EEF695BF016C4664756E2164756E21
381
+ //# debugId=52E880A19E25196264756E2164756E21
@@ -4,11 +4,11 @@
4
4
  "sourcesContent": [
5
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
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 fs from 'node:fs';\nimport http from 'node:http';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { WebSocket as WS } from 'ws';\nimport { WebSocketServer } from 'ws';\nimport { type PtyProcess, spawn as spawnPty } from './pty';\nimport { ghosttyWebRootFromMain, mimeType } from './utils';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst HTTP_PORT = Number(process.env.PORT) || 2346;\n\nconst require = createRequire(import.meta.url);\n\nfunction 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\nconst { distPath, wasmPath } = findGhosttyWeb();\n\nconst HTML_TEMPLATE = `<!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>wtty</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 protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = protocol + '//' + window.location.host + '/ws?cols=' + term.cols + '&rows=' + term.rows;\n let ws;\n\n function connect() {\n ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n console.log('[wtty] connected');\n };\n\n ws.onmessage = (event) => {\n term.write(event.data);\n };\n\n ws.onclose = () => {\n console.log('[wtty] 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('[wtty] 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\nconst httpServer = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\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 for (const [ws, session] of sessions.entries()) {\n session.pty.kill();\n ws.close();\n }\n wss.close();\n httpServer.close(() => process.exit(0));\n return;\n }\n\n if (pathname === '/' || pathname === '/index.html') {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(HTML_TEMPLATE);\n return;\n }\n\n if (pathname.startsWith('/dist/')) {\n serveFile(path.join(distPath, pathname.slice(6)), 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\nfunction 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\nconst sessions = new Map<WS, { pty: PtyProcess }>();\n\nfunction createPtySession(cols: number, rows: number): PtyProcess {\n const shell =\n process.platform === 'win32'\n ? (process.env.COMSPEC ?? 'cmd.exe')\n : (process.env.SHELL ?? '/bin/bash');\n return spawnPty(shell, cols, rows);\n}\n\nconst wss = new WebSocketServer({ noServer: true });\n\nhttpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n if (url.pathname === '/ws') {\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n } else {\n socket.destroy();\n }\n});\n\nwss.on('connection', (ws: WS, req: http.IncomingMessage) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const cols = Number.parseInt(url.searchParams.get('cols') ?? '80', 10);\n const rows = Number.parseInt(url.searchParams.get('rows') ?? '24', 10);\n\n const ptyProcess = createPtySession(cols, rows);\n sessions.set(ws, { pty: ptyProcess });\n\n ptyProcess.onData((data: string) => {\n if (ws.readyState === ws.OPEN) ws.send(data, { binary: false });\n });\n\n ptyProcess.onExit(({ exitCode }) => {\n if (ws.readyState === ws.OPEN) {\n ws.send(`\\r\\n\\x1b[33mShell exited (code: ${exitCode})\\x1b[0m\\r\\n`);\n ws.close();\n }\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 ptyProcess.resize(msg.cols, msg.rows);\n return;\n }\n } catch {\n // fall through\n }\n }\n ptyProcess.write(message);\n });\n\n ws.on('close', () => {\n sessions.get(ws)?.pty.kill();\n sessions.delete(ws);\n });\n\n ws.on('error', () => {});\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 ws.send(`${C}╔══════════════════════════════════════════════════════════════╗${R}\\r\\n`);\n ws.send(\n `${C}║${R} ${G}Welcome to wtty!${R} ${C}║${R}\\r\\n`,\n );\n ws.send(`${C}║${R} ${C}║${R}\\r\\n`);\n ws.send(`${C}║${R} You have a real shell session with full PTY support. ${C}║${R}\\r\\n`);\n ws.send(\n `${C}║${R} Try: ${Y}ls${R}, ${Y}cd${R}, ${Y}top${R}, ${Y}vim${R}, or any command! ${C}║${R}\\r\\n`,\n );\n ws.send(`${C}╚══════════════════════════════════════════════════════════════╝${R}\\r\\n\\r\\n`);\n});\n\nprocess.on('SIGINT', () => {\n console.log('\\n\\nShutting down...');\n for (const [ws, session] of sessions.entries()) {\n session.pty.kill();\n ws.close();\n }\n wss.close();\n process.exit(0);\n});\n\nhttpServer.listen(HTTP_PORT, '127.0.0.1', () => {\n console.log(`listening on http://127.0.0.1:${HTTP_PORT}`);\n});\n",
7
+ "import fs from 'node:fs';\nimport http from 'node:http';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { WebSocket as WS } from 'ws';\nimport { WebSocketServer } from 'ws';\nimport { type PtyProcess, spawn as spawnPty } from './pty';\nimport { ghosttyWebRootFromMain, mimeType } from './utils';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst HTTP_PORT = Number(process.env.PORT) || 2346;\n\nconst require = createRequire(import.meta.url);\n\nfunction 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\nconst { distPath, wasmPath } = findGhosttyWeb();\n\nconst HTML_TEMPLATE = `<!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</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 protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = protocol + '//' + window.location.host + '/ws?cols=' + term.cols + '&rows=' + term.rows;\n let ws;\n\n function connect() {\n ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n console.log('[webtty] connected');\n };\n\n ws.onmessage = (event) => {\n term.write(event.data);\n };\n\n ws.onclose = () => {\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\nconst httpServer = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\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 for (const [ws, session] of sessions.entries()) {\n session.pty.kill();\n ws.close();\n }\n wss.close();\n httpServer.close(() => process.exit(0));\n return;\n }\n\n if (pathname === '/' || pathname === '/index.html') {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(HTML_TEMPLATE);\n return;\n }\n\n if (pathname.startsWith('/dist/')) {\n serveFile(path.join(distPath, pathname.slice(6)), 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\nfunction 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\nconst sessions = new Map<WS, { pty: PtyProcess }>();\n\nfunction createPtySession(cols: number, rows: number): PtyProcess {\n const shell =\n process.platform === 'win32'\n ? (process.env.COMSPEC ?? 'cmd.exe')\n : (process.env.SHELL ?? '/bin/bash');\n return spawnPty(shell, cols, rows);\n}\n\nconst wss = new WebSocketServer({ noServer: true });\n\nhttpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n if (url.pathname === '/ws') {\n wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));\n } else {\n socket.destroy();\n }\n});\n\nwss.on('connection', (ws: WS, req: http.IncomingMessage) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const cols = Number.parseInt(url.searchParams.get('cols') ?? '80', 10);\n const rows = Number.parseInt(url.searchParams.get('rows') ?? '24', 10);\n\n const ptyProcess = createPtySession(cols, rows);\n sessions.set(ws, { pty: ptyProcess });\n\n ptyProcess.onData((data: string) => {\n if (ws.readyState === ws.OPEN) ws.send(data, { binary: false });\n });\n\n ptyProcess.onExit(({ exitCode }) => {\n if (ws.readyState === ws.OPEN) {\n ws.send(`\\r\\n\\x1b[33mShell exited (code: ${exitCode})\\x1b[0m\\r\\n`);\n ws.close();\n }\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 ptyProcess.resize(msg.cols, msg.rows);\n return;\n }\n } catch {\n // fall through\n }\n }\n ptyProcess.write(message);\n });\n\n ws.on('close', () => {\n sessions.get(ws)?.pty.kill();\n sessions.delete(ws);\n });\n\n ws.on('error', () => {});\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 ws.send(`${C}╔══════════════════════════════════════════════════════════════╗${R}\\r\\n`);\n ws.send(\n `${C}║${R} ${G}Welcome to webtty!${R} ${C}║${R}\\r\\n`,\n );\n ws.send(`${C}║${R} ${C}║${R}\\r\\n`);\n ws.send(`${C}║${R} You have a real shell session with full PTY support. ${C}║${R}\\r\\n`);\n ws.send(\n `${C}║${R} Try: ${Y}ls${R}, ${Y}cd${R}, ${Y}top${R}, ${Y}vim${R}, or any command! ${C}║${R}\\r\\n`,\n );\n ws.send(`${C}╚══════════════════════════════════════════════════════════════╝${R}\\r\\n\\r\\n`);\n});\n\nprocess.on('SIGINT', () => {\n console.log('\\n\\nShutting down...');\n for (const [ws, session] of sessions.entries()) {\n session.pty.kill();\n ws.close();\n }\n wss.close();\n process.exit(0);\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
8
  "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",
9
9
  "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"
10
10
  ],
11
- "mappings": "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",
12
- "debugId": "76EEF695BF016C4664756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "52E880A19E25196264756E2164756E21",
13
13
  "names": []
14
14
  }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "webtty",
3
- "version": "0.0.0-development",
3
+ "version": "1.0.0",
4
4
  "description": "Web TTY for running CLI/TUI applications in a browser tab, across platforms",
5
5
  "bin": {
6
- "webtty": "./dist/cli.js"
6
+ "webtty": "dist/cli.js",
7
+ "wtty": "dist/cli.js"
7
8
  },
8
9
  "files": [
9
10
  "dist"