webtty 1.11.5 → 1.13.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/dist/cli/index.js +60 -31
- package/dist/cli/index.js.map +5 -4
- package/dist/client-browser.js +5 -4
- package/dist/client.css +4 -0
- package/dist/server/index.js +62 -33
- package/dist/server/index.js.map +5 -4
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,23 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import
|
|
4
|
+
import path5 from "node:path";
|
|
5
|
+
|
|
6
|
+
// src/version.ts
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
var cached;
|
|
11
|
+
function getVersion() {
|
|
12
|
+
if (cached)
|
|
13
|
+
return cached;
|
|
14
|
+
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
while (true) {
|
|
16
|
+
try {
|
|
17
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
18
|
+
if (pkg.name === "webtty" && pkg.version) {
|
|
19
|
+
cached = pkg.version;
|
|
20
|
+
return cached;
|
|
21
|
+
}
|
|
22
|
+
} catch {}
|
|
23
|
+
const parent = path.dirname(dir);
|
|
24
|
+
if (parent === dir)
|
|
25
|
+
return "unknown";
|
|
26
|
+
dir = parent;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
5
29
|
|
|
6
30
|
// src/cli/commands.ts
|
|
7
31
|
import * as childProcess2 from "node:child_process";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
32
|
+
import fs4 from "node:fs";
|
|
33
|
+
import path4 from "node:path";
|
|
10
34
|
|
|
11
35
|
// src/config.ts
|
|
12
|
-
import
|
|
36
|
+
import fs2 from "node:fs";
|
|
13
37
|
import os from "node:os";
|
|
14
|
-
import
|
|
38
|
+
import path2 from "node:path";
|
|
15
39
|
function configDir() {
|
|
16
|
-
const home = process.env.HOME &&
|
|
17
|
-
return
|
|
40
|
+
const home = process.env.HOME && path2.isAbsolute(process.env.HOME) ? process.env.HOME : os.homedir();
|
|
41
|
+
return path2.join(home, ".config", "webtty");
|
|
18
42
|
}
|
|
19
43
|
function getConfigPath() {
|
|
20
|
-
return
|
|
44
|
+
return path2.join(configDir(), "config.json");
|
|
21
45
|
}
|
|
22
46
|
var DEFAULT_THEME = {
|
|
23
47
|
background: "#000000",
|
|
@@ -97,7 +121,7 @@ function mergeKeyboardBindings(defaults, user) {
|
|
|
97
121
|
return merged;
|
|
98
122
|
}
|
|
99
123
|
function loadConfig() {
|
|
100
|
-
if (!
|
|
124
|
+
if (!fs2.existsSync(getConfigPath())) {
|
|
101
125
|
try {
|
|
102
126
|
initConfig();
|
|
103
127
|
} catch (err) {
|
|
@@ -107,7 +131,7 @@ function loadConfig() {
|
|
|
107
131
|
}
|
|
108
132
|
let raw;
|
|
109
133
|
try {
|
|
110
|
-
raw =
|
|
134
|
+
raw = fs2.readFileSync(getConfigPath(), "utf8");
|
|
111
135
|
} catch (err) {
|
|
112
136
|
throw new Error(`webtty: failed to read config at ${getConfigPath()}: ${err.message}`);
|
|
113
137
|
}
|
|
@@ -150,21 +174,21 @@ function loadConfig() {
|
|
|
150
174
|
};
|
|
151
175
|
}
|
|
152
176
|
function initConfig() {
|
|
153
|
-
|
|
177
|
+
fs2.mkdirSync(path2.dirname(getConfigPath()), { recursive: true });
|
|
154
178
|
const content = JSON.stringify({
|
|
155
179
|
port: DEFAULT_CONFIG.port,
|
|
156
180
|
host: DEFAULT_CONFIG.host
|
|
157
181
|
}, null, 2);
|
|
158
|
-
|
|
182
|
+
fs2.writeFileSync(getConfigPath(), content, "utf8");
|
|
159
183
|
}
|
|
160
184
|
|
|
161
185
|
// src/cli/http.ts
|
|
162
186
|
import * as childProcess from "node:child_process";
|
|
163
|
-
import
|
|
164
|
-
import
|
|
165
|
-
import { fileURLToPath } from "node:url";
|
|
166
|
-
var __filename2 =
|
|
167
|
-
var __dirname2 =
|
|
187
|
+
import fs3 from "node:fs";
|
|
188
|
+
import path3 from "node:path";
|
|
189
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
190
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
191
|
+
var __dirname2 = path3.dirname(__filename2);
|
|
168
192
|
function getPort() {
|
|
169
193
|
return loadConfig().port;
|
|
170
194
|
}
|
|
@@ -172,7 +196,7 @@ function getBaseUrl() {
|
|
|
172
196
|
return `http://127.0.0.1:${getPort()}`;
|
|
173
197
|
}
|
|
174
198
|
function logPath() {
|
|
175
|
-
return
|
|
199
|
+
return path3.join(configDir(), "server.log");
|
|
176
200
|
}
|
|
177
201
|
async function isServerRunning() {
|
|
178
202
|
try {
|
|
@@ -192,11 +216,11 @@ async function startServer(timeoutMs = 1e4, _spawn = childProcess.spawn) {
|
|
|
192
216
|
const runningFromSrc = __filename2.endsWith(".ts");
|
|
193
217
|
let serverEntry;
|
|
194
218
|
if (useNode) {
|
|
195
|
-
serverEntry = runningFromSrc ?
|
|
219
|
+
serverEntry = runningFromSrc ? path3.resolve(__dirname2, "../../dist/server/index.js") : path3.resolve(__dirname2, "../server/index.js");
|
|
196
220
|
} else {
|
|
197
|
-
serverEntry =
|
|
221
|
+
serverEntry = path3.resolve(__dirname2, runningFromSrc ? "../server/index.ts" : "../server/index.js");
|
|
198
222
|
}
|
|
199
|
-
if (!
|
|
223
|
+
if (!fs3.existsSync(serverEntry)) {
|
|
200
224
|
console.error(`webtty: server entry not found at ${serverEntry}`);
|
|
201
225
|
process.exit(1);
|
|
202
226
|
return;
|
|
@@ -206,8 +230,8 @@ async function startServer(timeoutMs = 1e4, _spawn = childProcess.spawn) {
|
|
|
206
230
|
let logFd;
|
|
207
231
|
if (config.logs) {
|
|
208
232
|
const log = logPath();
|
|
209
|
-
|
|
210
|
-
logFd =
|
|
233
|
+
fs3.mkdirSync(path3.dirname(log), { recursive: true });
|
|
234
|
+
logFd = fs3.openSync(log, "a");
|
|
211
235
|
stdio = ["ignore", logFd, logFd];
|
|
212
236
|
}
|
|
213
237
|
const child = _spawn(serverExec, [serverEntry], {
|
|
@@ -222,7 +246,7 @@ async function startServer(timeoutMs = 1e4, _spawn = childProcess.spawn) {
|
|
|
222
246
|
});
|
|
223
247
|
child.unref();
|
|
224
248
|
if (logFd !== undefined)
|
|
225
|
-
|
|
249
|
+
fs3.closeSync(logFd);
|
|
226
250
|
const deadline = Date.now() + timeoutMs;
|
|
227
251
|
while (Date.now() < deadline) {
|
|
228
252
|
if (await isServerRunning())
|
|
@@ -393,10 +417,10 @@ async function cmdStart() {
|
|
|
393
417
|
}
|
|
394
418
|
function cmdConfig() {
|
|
395
419
|
const dir = configDir();
|
|
396
|
-
const configPath =
|
|
397
|
-
|
|
398
|
-
if (!
|
|
399
|
-
|
|
420
|
+
const configPath = path4.join(dir, "config.json");
|
|
421
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
422
|
+
if (!fs4.existsSync(configPath)) {
|
|
423
|
+
fs4.writeFileSync(configPath, `{}
|
|
400
424
|
`, "utf8");
|
|
401
425
|
}
|
|
402
426
|
const editor = process.env.VISUAL ?? process.env.EDITOR ?? (process.platform === "win32" ? "notepad" : "vi");
|
|
@@ -611,7 +635,8 @@ function printHelp() {
|
|
|
611
635
|
row("start", "Start the webtty server"),
|
|
612
636
|
row("config", "Open the config file in $VISUAL, $EDITOR, or a default editor"),
|
|
613
637
|
row("key", "Capture a key combo and print its chars value for keyboardBindings"),
|
|
614
|
-
row("help", "Show this help message")
|
|
638
|
+
row("help", "Show this help message"),
|
|
639
|
+
row("-v, --version", "Print the webtty version")
|
|
615
640
|
].join(`
|
|
616
641
|
`));
|
|
617
642
|
}
|
|
@@ -619,7 +644,7 @@ var allArgs = process.argv.slice(2);
|
|
|
619
644
|
var dirFlagIdx = allArgs.indexOf("--dir");
|
|
620
645
|
var cliBaseDir;
|
|
621
646
|
if (dirFlagIdx !== -1) {
|
|
622
|
-
cliBaseDir =
|
|
647
|
+
cliBaseDir = path5.resolve(allArgs[dirFlagIdx + 1] ?? ".");
|
|
623
648
|
allArgs.splice(dirFlagIdx, 2);
|
|
624
649
|
}
|
|
625
650
|
var [cmd, ...rest] = allArgs;
|
|
@@ -663,6 +688,10 @@ if (!cmd) {
|
|
|
663
688
|
case "key":
|
|
664
689
|
cmdKey();
|
|
665
690
|
break;
|
|
691
|
+
case "-v":
|
|
692
|
+
case "--version":
|
|
693
|
+
console.log(getVersion());
|
|
694
|
+
break;
|
|
666
695
|
case "help":
|
|
667
696
|
case "--help":
|
|
668
697
|
case "-h":
|
|
@@ -675,4 +704,4 @@ Run \`webtty help\` for usage.`);
|
|
|
675
704
|
}
|
|
676
705
|
}
|
|
677
706
|
|
|
678
|
-
//# debugId=
|
|
707
|
+
//# debugId=693804F1ABA952F764756E2164756E21
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/cli/index.ts", "../src/cli/commands.ts", "../src/config.ts", "../src/cli/http.ts"],
|
|
3
|
+
"sources": ["../src/cli/index.ts", "../src/version.ts", "../src/cli/commands.ts", "../src/config.ts", "../src/cli/http.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import path from 'node:path';\nimport {\n cmdConfig,\n cmdGo,\n cmdKey,\n cmdList,\n cmdRemove,\n cmdRename,\n cmdRun,\n cmdStart,\n cmdStop,\n} from './commands';\n\nconst GO_ALIASES = new Set(['go', 'a', 'attach', 'open']);\n\nfunction printHelp(): void {\n const indent = ' ';\n const col = 18; // width of the widest term: \"mv <id> <new-id>\"\n const row = (term: string, desc: string) => `${indent}${term.padEnd(col)} ${desc}`;\n\n console.log(\n [\n 'Launch Terminal UI in the browser.',\n '',\n 'USAGE',\n row('webtty', 'Open main session in the browser'),\n row('webtty [command]', 'Execute a specific command'),\n '',\n 'COMMANDS',\n row('go [id]', 'Open a new or existing session in the browser'),\n row('ls [id]', 'List all sessions, or filter by id substring'),\n row('rm <id>', 'Destroy a session'),\n row('mv <id> <new-id>', 'Rename a session'),\n row('run <id> [cmd]', 'Start PTY (no browser) or run a command in a session'),\n row('stop', 'Stop the webtty server'),\n row('start', 'Start the webtty server'),\n row('config', 'Open the config file in $VISUAL, $EDITOR, or a default editor'),\n row('key', 'Capture a key combo and print its chars value for keyboardBindings'),\n row('help', 'Show this help message'),\n ].join('\\n'),\n );\n}\n\nconst allArgs = process.argv.slice(2);\nconst dirFlagIdx = allArgs.indexOf('--dir');\nlet cliBaseDir: string | undefined;\nif (dirFlagIdx !== -1) {\n cliBaseDir = path.resolve(allArgs[dirFlagIdx + 1] ?? '.');\n allArgs.splice(dirFlagIdx, 2);\n}\nconst [cmd, ...rest] = allArgs;\n\nif (!cmd) {\n await cmdGo('main', cliBaseDir);\n} else if (GO_ALIASES.has(cmd)) {\n await cmdGo(rest[0] ?? 'main', cliBaseDir);\n} else {\n switch (cmd) {\n case 'ls':\n case 'list':\n await cmdList(rest[0]);\n break;\n case 'rm':\n case 'remove':\n await cmdRemove(rest[0]);\n break;\n case 'mv':\n case 'move':\n case 'rename':\n await cmdRename(rest[0], rest[1]);\n break;\n case 'stop':\n await cmdStop();\n break;\n case 'start':\n await cmdStart();\n break;\n case 'config':\n cmdConfig();\n break;\n case 'run': {\n const [id, runCmd, ...runArgs] = rest;\n if (!id) {\n console.error('usage: webtty run <id> [cmd [args...]]');\n process.exit(1);\n }\n await cmdRun(id, runCmd, runArgs);\n break;\n }\n case 'key':\n cmdKey();\n break;\n case 'help':\n case '--help':\n case '-h':\n printHelp();\n break;\n default:\n console.error(`webtty: unknown command '${cmd}'\\nRun \\`webtty help\\` for usage.`);\n process.exit(1);\n }\n}\n",
|
|
5
|
+
"import path from 'node:path';\nimport { getVersion } from '../version';\nimport {\n cmdConfig,\n cmdGo,\n cmdKey,\n cmdList,\n cmdRemove,\n cmdRename,\n cmdRun,\n cmdStart,\n cmdStop,\n} from './commands';\n\nconst GO_ALIASES = new Set(['go', 'a', 'attach', 'open']);\n\nfunction printHelp(): void {\n const indent = ' ';\n const col = 18; // width of the widest term: \"mv <id> <new-id>\"\n const row = (term: string, desc: string) => `${indent}${term.padEnd(col)} ${desc}`;\n\n console.log(\n [\n 'Launch Terminal UI in the browser.',\n '',\n 'USAGE',\n row('webtty', 'Open main session in the browser'),\n row('webtty [command]', 'Execute a specific command'),\n '',\n 'COMMANDS',\n row('go [id]', 'Open a new or existing session in the browser'),\n row('ls [id]', 'List all sessions, or filter by id substring'),\n row('rm <id>', 'Destroy a session'),\n row('mv <id> <new-id>', 'Rename a session'),\n row('run <id> [cmd]', 'Start PTY (no browser) or run a command in a session'),\n row('stop', 'Stop the webtty server'),\n row('start', 'Start the webtty server'),\n row('config', 'Open the config file in $VISUAL, $EDITOR, or a default editor'),\n row('key', 'Capture a key combo and print its chars value for keyboardBindings'),\n row('help', 'Show this help message'),\n row('-v, --version', 'Print the webtty version'),\n ].join('\\n'),\n );\n}\n\nconst allArgs = process.argv.slice(2);\nconst dirFlagIdx = allArgs.indexOf('--dir');\nlet cliBaseDir: string | undefined;\nif (dirFlagIdx !== -1) {\n cliBaseDir = path.resolve(allArgs[dirFlagIdx + 1] ?? '.');\n allArgs.splice(dirFlagIdx, 2);\n}\nconst [cmd, ...rest] = allArgs;\n\nif (!cmd) {\n await cmdGo('main', cliBaseDir);\n} else if (GO_ALIASES.has(cmd)) {\n await cmdGo(rest[0] ?? 'main', cliBaseDir);\n} else {\n switch (cmd) {\n case 'ls':\n case 'list':\n await cmdList(rest[0]);\n break;\n case 'rm':\n case 'remove':\n await cmdRemove(rest[0]);\n break;\n case 'mv':\n case 'move':\n case 'rename':\n await cmdRename(rest[0], rest[1]);\n break;\n case 'stop':\n await cmdStop();\n break;\n case 'start':\n await cmdStart();\n break;\n case 'config':\n cmdConfig();\n break;\n case 'run': {\n const [id, runCmd, ...runArgs] = rest;\n if (!id) {\n console.error('usage: webtty run <id> [cmd [args...]]');\n process.exit(1);\n }\n await cmdRun(id, runCmd, runArgs);\n break;\n }\n case 'key':\n cmdKey();\n break;\n case '-v':\n case '--version':\n console.log(getVersion());\n break;\n case 'help':\n case '--help':\n case '-h':\n printHelp();\n break;\n default:\n console.error(`webtty: unknown command '${cmd}'\\nRun \\`webtty help\\` for usage.`);\n process.exit(1);\n }\n}\n",
|
|
6
|
+
"import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cached: string | undefined;\n\n/**\n * Returns the webtty version from the nearest `package.json` above this file.\n *\n * Read at runtime (not inlined at build time) because semantic-release bumps\n * `package.json` after `bun run build`. Walking up keeps it working from both\n * `src/` and the bundled `dist/cli` / `dist/server` entries.\n * Dev checkouts report `0.0.0-development`.\n */\nexport function getVersion(): string {\n if (cached) return cached;\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (true) {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === 'webtty' && pkg.version) {\n cached = pkg.version;\n return cached;\n }\n } catch {\n // no readable package.json at this level — keep walking up\n }\n const parent = path.dirname(dir);\n if (parent === dir) return 'unknown';\n dir = parent;\n }\n}\n",
|
|
6
7
|
"import * as childProcess from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { configDir, loadConfig } from '../config';\nimport { getBaseUrl, getPort, isServerRunning, openBrowser, startServer, stopServer } from './http';\n\n/**\n * Converts a bind host to a browser-navigable host.\n * - Bind-all addresses (`0.0.0.0`, `::`) become `localhost`.\n * - Bare IPv6 addresses are bracketed (`::1` → `[::1]`).\n * - All other values pass through unchanged.\n */\nexport function toBrowserHost(host: string): string {\n if (host === '0.0.0.0' || host === '::') return 'localhost';\n if (host.includes(':') && !host.startsWith('[')) return `[${host}]`;\n return host;\n}\n\n/**\n * Opens (or creates) session `id`, starts the server if needed, and opens the URL in the browser.\n *\n * @param id - The session ID to open (default: `'main'`).\n * @param baseDir - Working directory for the PTY shell (optional).\n */\nexport async function cmdGo(id = 'main', baseDir?: string): Promise<void> {\n if (!(await isServerRunning())) {\n await startServer();\n }\n\n let sessionId: string;\n const check = await fetch(`${getBaseUrl()}/api/sessions/${encodeURIComponent(id)}`);\n if (check.status === 200) {\n sessionId = id;\n } else {\n const res = await fetch(`${getBaseUrl()}/api/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id, ...(baseDir ? { baseDir } : {}) }),\n });\n if (!res.ok) {\n const body = (await res.json()) as { error?: string };\n console.error(`webtty: ${body.error ?? `failed to create session (${res.status})`}`);\n process.exit(1);\n }\n const session = (await res.json()) as { id: string };\n sessionId = session.id;\n }\n\n const url = `http://${toBrowserHost(loadConfig().host)}:${getPort()}/s/${sessionId}`;\n console.log(url);\n openBrowser(url);\n}\n\n/**\n * Lists all active sessions, optionally filtered by a substring of the session ID.\n *\n * @param filter - Optional substring to filter session IDs.\n */\nexport async function cmdList(filter?: string): Promise<void> {\n let res: Response;\n try {\n res = await fetch(`${getBaseUrl()}/api/sessions`);\n } catch {\n console.log('webtty is not running');\n process.exit(1);\n }\n const all = (await res.json()) as Array<{\n id: string;\n connected: boolean;\n createdAt: number;\n }>;\n const sessions = filter ? all.filter((s) => s.id.includes(filter)) : all;\n if (sessions.length === 0) {\n console.log('no sessions');\n return;\n }\n console.log('id\\t\\t\\tconnected\\tcreated');\n for (const s of sessions) {\n const created = new Date(s.createdAt).toLocaleString();\n console.log(`${s.id}\\t\\t\\t${s.connected}\\t\\t${created}`);\n }\n}\n\n/**\n * Removes session `id` and stops the server if no sessions remain.\n *\n * @param id - The session ID to remove.\n */\nexport async function cmdRemove(id?: string): Promise<void> {\n if (!id) {\n console.error('webtty: rm requires a session id');\n process.exit(1);\n }\n let res: Response;\n try {\n res = await fetch(`${getBaseUrl()}/api/sessions/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n } catch {\n console.log('webtty is not running');\n process.exit(1);\n }\n if (res.status === 204) {\n console.log(`removed ${id}`);\n if (res.headers.get('x-sessions-remaining') === '0') {\n await stopServer();\n console.log('no sessions remaining — webtty stopped');\n }\n } else if (res.status === 404) {\n console.error(`session ${id} not found`);\n process.exit(1);\n } else {\n console.error(`webtty rm failed (status: ${res.status})`);\n process.exit(1);\n }\n}\n\n/**\n * Renames session `id` to `newId`.\n *\n * @param id - The current session ID.\n * @param newId - The new session ID.\n */\nexport async function cmdRename(id?: string, newId?: string): Promise<void> {\n if (!id || !newId) {\n console.error('webtty: rename requires two arguments: [id] [new-id]');\n process.exit(1);\n }\n let res: Response;\n try {\n res = await fetch(`${getBaseUrl()}/api/sessions/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id: newId }),\n });\n } catch {\n console.log('webtty is not running');\n process.exit(1);\n }\n if (res.ok) {\n console.log(`renamed ${id} → ${newId}`);\n } else if (res.status === 404) {\n console.error(`session ${id} not found`);\n process.exit(1);\n } else {\n const body = (await res.json()) as { error?: string };\n console.error(`webtty: ${body.error ?? `rename failed (${res.status})`}`);\n process.exit(1);\n }\n}\n\n/** Stops the server if it is running. */\nexport async function cmdStop(): Promise<void> {\n if (!(await isServerRunning())) {\n console.log('webtty is not running');\n return;\n }\n const ok = await stopServer();\n if (ok) {\n console.log('webtty stopped');\n } else {\n console.error('webtty stop failed');\n process.exit(1);\n }\n}\n\n/** Starts the server if it is not already running. */\nexport async function cmdStart(): Promise<void> {\n if (await isServerRunning()) {\n console.log('webtty is already running');\n return;\n }\n await startServer();\n console.log('webtty started');\n}\n\n/** Opens `~/.config/webtty/config.json` in `$VISUAL` / `$EDITOR`, creating it if absent. */\nexport function cmdConfig(): void {\n const dir = configDir();\n const configPath = path.join(dir, 'config.json');\n fs.mkdirSync(dir, { recursive: true });\n if (!fs.existsSync(configPath)) {\n fs.writeFileSync(configPath, '{}\\n', 'utf8');\n }\n const editor =\n process.env.VISUAL ?? process.env.EDITOR ?? (process.platform === 'win32' ? 'notepad' : 'vi');\n childProcess.spawnSync(editor, [configPath], { stdio: 'inherit' });\n}\n\nexport function bytesToChars(buf: Buffer): string {\n let out = '';\n for (const b of buf) {\n if (b === 0x1b) out += '\\\\u001b';\n else if (b === 0x0d) out += '\\\\r';\n else if (b === 0x09) out += '\\\\t';\n else if (b === 0x0a) out += '\\\\n';\n else if (b === 0x22) out += '\\\\\"';\n else if (b === 0x5c) out += '\\\\\\\\';\n else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b);\n else out += `\\\\u${b.toString(16).padStart(4, '0')}`;\n }\n return `\"${out}\"`;\n}\n\nexport function bytesToDisplay(buf: Buffer): string {\n return Array.from(buf)\n .map((b) => {\n if (b === 0x1b) return 'ESC';\n if (b === 0x0d) return 'CR';\n if (b === 0x09) return 'TAB';\n if (b === 0x0a) return 'LF';\n if (b === 0x20) return 'SPC';\n if (b === 0x7f) return 'DEL';\n if (b > 0x20 && b < 0x7f) return String.fromCharCode(b);\n return `\\\\x${b.toString(16).padStart(2, '0')}`;\n })\n .join(' ');\n}\n\nexport async function cmdRun(id: string, cmd?: string, args: string[] = []): Promise<void> {\n if (!cmd) {\n // Warm-up mode: start server + session + PTY, no browser\n if (!(await isServerRunning())) {\n await startServer();\n }\n\n const check = await fetch(`${getBaseUrl()}/api/sessions/${encodeURIComponent(id)}`);\n if (check.status !== 200) {\n const res = await fetch(`${getBaseUrl()}/api/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id }),\n });\n if (!res.ok) {\n const body = (await res.json()) as { error?: string };\n console.error(`webtty: ${body.error ?? `failed to create session (${res.status})`}`);\n process.exit(1);\n }\n }\n\n const wsUrl = `ws://127.0.0.1:${getPort()}/ws/${encodeURIComponent(id)}/pty?cols=80&rows=24`;\n await new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(wsUrl);\n let opened = false;\n ws.onopen = () => {\n opened = true;\n ws.close(1000);\n resolve();\n };\n ws.onerror = () => reject(new Error('failed to connect to PTY'));\n ws.onclose = (evt) => {\n if (!opened) reject(new Error(`failed to start PTY (code ${(evt as CloseEvent).code})`));\n };\n }).catch((err: Error) => {\n console.error(`webtty: failed to start PTY: ${err.message}`);\n process.exit(1);\n });\n\n const url = `http://${toBrowserHost(loadConfig().host)}:${getPort()}/s/${id}`;\n console.log(url);\n return;\n }\n\n // Exec mode: headless command execution\n if (!(await isServerRunning())) {\n console.error('webtty: server is not running');\n process.exit(1);\n }\n\n let res: Response;\n try {\n res = await fetch(`${getBaseUrl()}/s/${encodeURIComponent(id)}/execute`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ cmd, args }),\n });\n } catch {\n console.error('webtty: server is not running');\n process.exit(1);\n }\n\n if (res.status === 404) {\n console.error(`webtty: session not found: ${id}`);\n process.exit(1);\n }\n if (res.status === 409) {\n console.error(`webtty: PTY not running for session: ${id}`);\n process.exit(1);\n }\n if (!res.ok || !res.body) {\n console.error(`webtty: run failed (${res.status})`);\n process.exit(1);\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buf = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n if (!line) continue;\n const msg = JSON.parse(line) as Record<string, unknown>;\n if (msg.stream === 'stdout') process.stdout.write(String(msg.data));\n else if (msg.stream === 'stderr') process.stderr.write(String(msg.data));\n else if ('exit' in msg) {\n if (msg.error) console.error(`webtty: ${msg.error}`);\n process.exit((msg.exit as number) ?? 1);\n }\n }\n }\n console.error('webtty: connection closed unexpectedly');\n process.exit(1);\n}\n\nexport function cmdKey(): void {\n if (!process.stdin.isTTY) {\n console.error('webtty key: requires an interactive terminal');\n process.exit(1);\n return;\n }\n\n const dim = '\\x1b[2m';\n const bold = '\\x1b[1m';\n const reset = '\\x1b[0m';\n\n const restoreTerminal = () => {\n try {\n process.stdin.setRawMode(false);\n } catch {}\n };\n process.once('exit', restoreTerminal);\n process.once('SIGINT', restoreTerminal);\n process.once('SIGTERM', restoreTerminal);\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n console.log('Press any key combo to see its chars value. q to quit.\\n');\n console.log(` ${dim}received${reset} → ${bold}chars${reset}`);\n console.log(` ${'─'.repeat(17)}`);\n\n let buf = Buffer.alloc(0);\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const flush = () => {\n if (buf.length === 0) return;\n const display = bytesToDisplay(buf).padEnd(8);\n console.log(` ${dim}${display}${reset} → ${bold}${bytesToChars(buf)}${reset}`);\n buf = Buffer.alloc(0);\n };\n\n process.stdin.on('data', (chunk: Buffer) => {\n if (chunk.length === 1 && chunk[0] === 0x71) {\n process.stdin.setRawMode(false);\n process.removeListener('exit', restoreTerminal);\n process.removeListener('SIGINT', restoreTerminal);\n process.removeListener('SIGTERM', restoreTerminal);\n console.log(` ${'─'.repeat(17)}\\n`);\n process.exit(0);\n }\n buf = Buffer.concat([buf, chunk]);\n if (timer) clearTimeout(timer);\n timer = setTimeout(flush, 50);\n });\n}\n",
|
|
7
8
|
"import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\n/** A single keyboard binding: intercepts `key`+`mods` and sends `chars` to the PTY. */\nexport interface KeyboardBinding {\n /** Key name matched case-insensitively against `KeyboardEvent.key` (e.g. `\"enter\"`, `\"arrowup\"`, `\"a\"`). */\n key: string;\n /** Modifier keys that must be active — and no others — for this binding to match. Accepted values: `\"shift\"`, `\"ctrl\"`, `\"alt\"`, `\"meta\"`. Order irrelevant. Unknown values are filtered out at config load time. */\n mods?: string[];\n /** Byte sequence sent verbatim to the PTY. Standard JSON escapes apply (`\\r`, `\\uXXXX`, etc.). */\n chars: string;\n}\n\n/** Terminal color palette. All keys are optional; omitted keys fall back to the Campbell defaults. */\nexport interface Theme {\n /** Terminal background. */\n background?: string;\n /** Default text color. */\n foreground?: string;\n /** Cursor color. */\n cursor?: string;\n /** Selection highlight. */\n selection?: string;\n /** ANSI 0. */\n black?: string;\n /** ANSI 1. */\n red?: string;\n /** ANSI 2. */\n green?: string;\n /** ANSI 3. */\n yellow?: string;\n /** ANSI 4. */\n blue?: string;\n /** ANSI 5. */\n purple?: string;\n /** ANSI 6. */\n cyan?: string;\n /** ANSI 7. */\n white?: string;\n /** ANSI 8. */\n brightBlack?: string;\n /** ANSI 9. */\n brightRed?: string;\n /** ANSI 10. */\n brightGreen?: string;\n /** ANSI 11. */\n brightYellow?: string;\n /** ANSI 12. */\n brightBlue?: string;\n /** ANSI 13. */\n brightPurple?: string;\n /** ANSI 14. */\n brightCyan?: string;\n /** ANSI 15. */\n brightWhite?: string;\n}\n\n/** Right-click behavior: `\"copyPaste\"` copies selection + clears it if selection exists, otherwise native menu; `\"default\"` always shows native context menu. */\nexport type RightClickBehavior = 'default' | 'copyPaste';\n\n/** Full webtty configuration. All keys are optional in the config file; missing keys fall back to {@link DEFAULT_CONFIG}. */\nexport interface Config {\n /** HTTP listen port; env `PORT` takes precedence. */\n port: number;\n /** Bind address; use `\"0.0.0.0\"` for remote access. */\n host: string;\n /** Shell for new sessions. */\n shell: string;\n /** `$TERM` env var passed to the shell. Fixed to `xterm-256color` — the PTY child talks to webtty, not to the parent terminal. */\n term: string;\n /** `$COLORTERM` env var passed to the shell. */\n colorTerm: string;\n /** PTY history buffer in bytes; used for server-side replay on reload/reconnect. */\n scrollback: number;\n /** Initial terminal width in columns. */\n cols: number;\n /** Initial terminal height in rows. */\n rows: number;\n /** Font size in px. */\n fontSize: number;\n /** CSS font-family stack. */\n fontFamily: string;\n /** Default cursor shape. Apps override at runtime via DECSCUSR — this is the startup default only. */\n cursorStyle: 'block' | 'bar' | 'underline';\n /** Default blink state. Apps override at runtime via DECSCUSR — this is the startup default only. */\n cursorStyleBlink: boolean;\n /** Auto-copy selection to clipboard on mouseup (kitty / Windows Terminal style). */\n copyOnSelect: boolean;\n /** `\"copyPaste\"` copies selection + clears it on right-click if selection exists; `\"default\"` always shows native context menu. */\n rightClickBehavior: RightClickBehavior;\n /** Mouse wheel scroll speed multiplier for apps with mouse tracking. `1` = one SGR per tick. Values `< 1` reduce rate; values `> 1` send multiple SGRs per tick. Must be `> 0`. */\n mouseScrollSpeed: number;\n /** Write server stdout/stderr to `~/.config/webtty/server.log`. Appends on each start. */\n logs: boolean;\n /** Terminal color palette. */\n theme: Theme;\n /** Custom key-to-sequence bindings. Merged with built-in defaults by `(key, mods)` identity. */\n keyboardBindings: KeyboardBinding[];\n /** Additional environment variables injected into PTY shells and execute commands. Merges over `process.env`; `TERM` and `COLORTERM` always take precedence for PTY spawns. */\n env: Record<string, string>;\n}\n\n/** Returns the webtty config directory: `~/.config/webtty`. */\nexport function configDir(): string {\n // os.homedir() is the authoritative home directory. process.env.HOME is used\n // as an override in tests (e.g. to isolate config state), but only when it is\n // an absolute path — guarding against accidental env pollution such as the\n // string \"undefined\" being assigned when HOME was originally unset on Windows.\n const home =\n process.env.HOME && path.isAbsolute(process.env.HOME) ? process.env.HOME : os.homedir();\n return path.join(home, '.config', 'webtty');\n}\n\nfunction getConfigPath(): string {\n return path.join(configDir(), 'config.json');\n}\n\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\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\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\nexport const DEFAULT_KEYBOARD_BINDINGS: KeyboardBinding[] = [];\n\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\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: '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 cursorStyle: 'bar',\n cursorStyleBlink: true,\n copyOnSelect: true,\n rightClickBehavior: 'default' as RightClickBehavior,\n mouseScrollSpeed: 1,\n logs: false,\n theme: DEFAULT_THEME,\n keyboardBindings: DEFAULT_KEYBOARD_BINDINGS,\n env: {},\n};\n\nfunction bindingKey(b: KeyboardBinding): string {\n const mods = [...(b.mods ?? [])].sort().join('+');\n return `${b.key.toLowerCase()}|${mods}`;\n}\n\nconst VALID_MODS = new Set(['shift', 'ctrl', 'alt', 'meta']);\n\nfunction isValidBinding(b: unknown): b is KeyboardBinding {\n if (!b || typeof b !== 'object') return false;\n const o = b as Record<string, unknown>;\n if (typeof o.key !== 'string' || typeof o.chars !== 'string') return false;\n if (o.mods !== undefined && !Array.isArray(o.mods)) return false;\n return true;\n}\n\nfunction normalizeBinding(b: KeyboardBinding): KeyboardBinding {\n return {\n ...b,\n key: b.key.toLowerCase(),\n mods: (b.mods ?? []).map((m) => m.toLowerCase()).filter((m) => VALID_MODS.has(m)),\n };\n}\n\n/**\n * Merges user-supplied bindings over a set of defaults by `(key, mods)` identity.\n * User entries replace matching defaults; unmatched user entries are appended.\n *\n * @param defaults - Default bindings to merge over.\n * @param user - User-supplied bindings that override defaults.\n * @returns Merged bindings with user entries replacing matching defaults and new user entries appended.\n */\n// NOTE: export for testing only\nexport function mergeKeyboardBindings(\n defaults: KeyboardBinding[],\n user: KeyboardBinding[],\n): KeyboardBinding[] {\n const deduped = [...new Map(user.map((b) => [bindingKey(b), b])).values()];\n const overrides = new Map(deduped.map((b) => [bindingKey(b), b]));\n const merged = defaults.map((d) => overrides.get(bindingKey(d)) ?? d);\n const defaultKeys = new Set(defaults.map(bindingKey));\n for (const b of deduped) {\n if (!defaultKeys.has(bindingKey(b))) merged.push(b);\n }\n return merged;\n}\n\n/**\n * Load config from `~/.config/webtty/config.json`, merged over `DEFAULT_CONFIG`.\n *\n * On first run (file absent), writes the default port/host stub and returns defaults.\n * Unknown keys and keys with wrong types are silently ignored.\n * Throws if the file exists but cannot be read or contains invalid JSON.\n *\n * @returns The resolved {@link Config}, with all missing keys filled from {@link DEFAULT_CONFIG}.\n */\nexport function loadConfig(): Config {\n if (!fs.existsSync(getConfigPath())) {\n try {\n initConfig();\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.cursorStyle === 'string' &&\n (p.cursorStyle === 'block' || p.cursorStyle === 'bar' || p.cursorStyle === 'underline') && {\n cursorStyle: p.cursorStyle,\n }),\n ...(typeof p.cursorStyleBlink === 'boolean' && { cursorStyleBlink: p.cursorStyleBlink }),\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.mouseScrollSpeed === 'number' &&\n p.mouseScrollSpeed > 0 && { mouseScrollSpeed: p.mouseScrollSpeed }),\n ...(typeof p.logs === 'boolean' && { logs: p.logs }),\n ...(p.theme && typeof p.theme === 'object' && { theme: { ...DEFAULT_THEME, ...p.theme } }),\n ...(Array.isArray(p.keyboardBindings) && {\n keyboardBindings: mergeKeyboardBindings(\n DEFAULT_KEYBOARD_BINDINGS,\n p.keyboardBindings.filter(isValidBinding).map(normalizeBinding),\n ),\n }),\n ...(p.env &&\n typeof p.env === 'object' &&\n !Array.isArray(p.env) && {\n env: Object.fromEntries(\n Object.entries(p.env as Record<string, unknown>).filter(\n ([k, v]) => typeof k === 'string' && typeof v === 'string',\n ) as [string, string][],\n ),\n }),\n };\n}\n\n/**\n * Write the initial config stub (`port` + `host` only) to `~/.config/webtty/config.json`.\n *\n * Only writes the two keys that are safe to persist as defaults; all other\n * keys are intentionally omitted so future webtty versions can add new fields\n * without the stub going stale.\n */\nexport function initConfig(): 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",
|
|
8
9
|
"import * as childProcess from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { configDir, loadConfig } from '../config';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/** Active server port, read from config on first call (env PORT is intentionally ignored). */\nexport function getPort(): number {\n return loadConfig().port;\n}\n\n/** Base URL for internal CLI↔server API calls (always 127.0.0.1, avoids IPv6 lookup). */\nexport function getBaseUrl(): string {\n return `http://127.0.0.1:${getPort()}`;\n}\n\n/** Returns the path to the server log file: `~/.config/webtty/server.log`. */\nexport function logPath(): string {\n return path.join(configDir(), 'server.log');\n}\n\n/** Returns `true` if the webtty server is reachable and responding to API requests. */\nexport async function isServerRunning(): Promise<boolean> {\n try {\n const res = await fetch(`${getBaseUrl()}/api/sessions`);\n if (!res.ok) return false;\n const body = await res.json();\n return Array.isArray(body);\n } catch {\n return false;\n }\n}\n\n/**\n * Spawns the server process detached, then polls until it is ready or `timeoutMs` expires.\n *\n * @param timeoutMs - Maximum time to wait for the server to start (default: 10000 ms).\n * @param _spawn - Spawn function override for testing (default: childProcess.spawn).\n * @throws Exits the process with code 1 if the server entry is not found or fails to start in time.\n */\nexport async function startServer(timeoutMs = 10000, _spawn = childProcess.spawn): Promise<void> {\n const isBun = typeof (globalThis as Record<string, unknown>).Bun !== 'undefined';\n\n // On Windows, Bun's net.Socket doesn't support the fd-based named-pipe\n // wrapping that node-pty's ConPTY backend requires, so node-pty fails under\n // Bun on Windows. bunx works because its #!/usr/bin/env node shim runs the\n // server with Node.js instead. Mirror that here explicitly.\n const useNode = process.platform === 'win32' && isBun;\n const serverExec = useNode ? 'node' : process.execPath;\n\n // Resolve the server entry. When useNode is true the executor is Node.js,\n // which cannot run .ts files, so we always need the compiled .js output.\n // The CLI may itself run from source (src/cli/) or from dist (dist/cli/);\n // adjust the relative path accordingly so we always land in the same dist/.\n const runningFromSrc = __filename.endsWith('.ts');\n let serverEntry: string;\n if (useNode) {\n serverEntry = runningFromSrc\n ? path.resolve(__dirname, '../../dist/server/index.js') // src/cli → dist/server\n : path.resolve(__dirname, '../server/index.js'); // dist/cli → dist/server\n } else {\n serverEntry = path.resolve(\n __dirname,\n runningFromSrc ? '../server/index.ts' : '../server/index.js',\n );\n }\n if (!fs.existsSync(serverEntry)) {\n console.error(`webtty: server entry not found at ${serverEntry}`);\n (process.exit as (code?: number) => void)(1);\n return;\n }\n\n const config = loadConfig();\n let stdio: childProcess.SpawnOptions['stdio'] = 'ignore';\n let logFd: number | undefined;\n if (config.logs) {\n const log = logPath();\n fs.mkdirSync(path.dirname(log), { recursive: true });\n logFd = fs.openSync(log, 'a');\n stdio = ['ignore', logFd, logFd];\n }\n\n const child = _spawn(serverExec, [serverEntry], {\n detached: true,\n stdio,\n env: { ...process.env, PORT: String(config.port) },\n });\n child.on('error', (err) => {\n const hint = useNode\n ? ' (Node.js must be on PATH when running webtty under Bun on Windows)'\n : '';\n console.error(`webtty: failed to start server: ${err.message}${hint}`);\n process.exit(1);\n });\n child.unref();\n if (logFd !== undefined) fs.closeSync(logFd);\n\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await isServerRunning()) return;\n await new Promise((r) => setTimeout(r, 100));\n }\n console.error('webtty: server did not start in time');\n process.exit(1);\n}\n\n/**\n * Sends `POST /api/server/stop`, then polls until the server is no longer reachable.\n *\n * @param baseUrl - The server base URL (default: getBaseUrl()).\n * @param timeoutMs - Maximum time to wait for the server to stop (default: 5000 ms).\n * @returns `true` if the server stopped successfully, `false` otherwise.\n */\nexport async function stopServer(\n baseUrl: string = getBaseUrl(),\n timeoutMs = 5000,\n): Promise<boolean> {\n try {\n const res = await fetch(`${baseUrl}/api/server/stop`, { method: 'POST' });\n if (!res.ok) return false;\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!(await isServerRunning())) return true;\n await new Promise((r) => setTimeout(r, 100));\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Opens `url` in the default system browser.\n * No-op in test environments or when `WEBTTY_NO_OPEN=1` is set.\n *\n * @param url - The URL to open.\n * @param _spawn - Spawn function override for testing (default: childProcess.spawn).\n */\nexport function openBrowser(url: string, _spawn = childProcess.spawn): void {\n if (process.env.WEBTTY_NO_OPEN === '1') return;\n if (process.env.NODE_ENV === 'test') return;\n if (process.platform === 'win32') {\n _spawn('cmd.exe', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' }).unref();\n } else {\n const cmd = process.platform === 'darwin' ? 'open' : 'xdg-open';\n _spawn(cmd, [url], { detached: true, stdio: 'ignore' }).unref();\n }\n}\n"
|
|
9
10
|
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "
|
|
11
|
+
"mappings": "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",
|
|
12
|
+
"debugId": "693804F1ABA952F764756E2164756E21",
|
|
12
13
|
"names": []
|
|
13
14
|
}
|
package/dist/client-browser.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import{FitAddon as W,init as z,Terminal as K}from"/dist/ghostty-web.js";var m=new RegExp("\x1B\\[(\\d*) q","g");function v(e,t){let s=e.options.cursorStyle,l=e.options.cursorBlink;m.lastIndex=0;let c=m.exec(t);while(c!==null){let o=c[1]===""?0:Number(c[1]);if(!Number.isNaN(o)&&o>=0&&o<=6)e.options.cursorStyle=o===0||o===1||o===2?"block":o===3||o===4?"underline":"bar",e.options.cursorBlink=o===0||o===1||o===3||o===5;c=m.exec(t)}if((e.options.cursorStyle!==s||e.options.cursorBlink!==l)&&e.renderer&&e.wasmTerm)e.renderer.render(e.wasmTerm,!0,e.viewportY)}function E(e,t){if(t&&e.startsWith("\x1B[<32;"))return"\x1B[<35;"+e.slice(6);return e}function k(e,t){return e.startsWith("\x1B[<32;")&&e===t}var x=window.location.pathname.split("/s/")[1]??"main",a=await fetch("/api/config").then((e)=>e.json());document.title=`${x} | webtty`;await z();var n=new K({cols:a.cols,rows:a.rows,cursorStyle:a.cursorStyle,cursorBlink:a.cursorStyleBlink,fontSize:a.fontSize,fontFamily:a.fontFamily,scrollback:Math.ceil(a.scrollback/80),theme:a.theme}),T=new W;n.loadAddon(T);var i=document.getElementById("terminal");if(a.theme?.background)i.style.background=a.theme.background;await n.open(i);function C(){i.style.padding="0",T.fit();let e=i.querySelector("canvas");if(!e)return;let t=Math.max(0,i.clientWidth-e.offsetWidth),s=Math.max(0,i.clientHeight-e.offsetHeight);i.style.paddingLeft=`${Math.floor(t/2)}px`,i.style.paddingRight=`${Math.ceil(t/2)}px`,i.style.paddingTop=`${Math.floor(s/2)}px`,i.style.paddingBottom=`${Math.ceil(s/2)}px`}var b=null;function w(){if(b!==null)return;b=window.requestAnimationFrame(()=>{b=null,C()})}w();new ResizeObserver(()=>w()).observe(i,{box:"border-box"});window.addEventListener("resize",w);document.fonts.ready.then(()=>n.renderer?.remeasureFont());document.addEventListener("visibilitychange",()=>{if(document.visibilityState!=="visible")return;if(n.renderer&&n.wasmTerm)n.renderer.render(n.wasmTerm,!0,n.viewportY)});function D(e){if(e.style.cursor==="text")e.style.cursor="default"}D(i);new MutationObserver((e)=>{for(let t of e)D(t.target)}).observe(i,{attributes:!0,attributeFilter:["style"],subtree:!0});var O=window.location.protocol==="https:"?"wss:":"ws:",r;function P(){let e=`${O}//${window.location.host}/ws/${x}/pty?cols=${n.cols}&rows=${n.rows}`;r=new WebSocket(e);let t="\x1B[2m",s="\x1B[1;33m",l="\x1B[3m",c="\x1B[0m",o=`${t}[${c} ${s}webtty${c} ${t}]${c}`,u=(d)=>`\r
|
|
2
|
-
${o}
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import{FitAddon as be,init as we,Terminal as ve}from"/dist/ghostty-web.js";var P=new RegExp("\x1B\\[(\\d*) q","g");function X(e,t){let i=e.options.cursorStyle,n=e.options.cursorBlink;P.lastIndex=0;let s=P.exec(t);while(s!==null){let r=s[1]===""?0:Number(s[1]);if(!Number.isNaN(r)&&r>=0&&r<=6)e.options.cursorStyle=r===0||r===1||r===2?"block":r===3||r===4?"underline":"bar",e.options.cursorBlink=r===0||r===1||r===3||r===5;s=P.exec(t)}if((e.options.cursorStyle!==i||e.options.cursorBlink!==n)&&e.renderer&&e.wasmTerm)e.renderer.render(e.wasmTerm,!0,e.viewportY)}var G=new RegExp("[\x1B\x18\x1A]","g");class S{maxBytes;state="text";parts=[];head="";size=0;overflow=!1;constructor(e=67108864){this.maxBytes=e}feed(e){let t=[],i="",n=0;while(n<e.length)if(this.state==="text"){let s=e.indexOf("\x1B",n);if(s<0){i+=e.slice(n);break}i+=e.slice(n,s),n=s+1,this.state="esc"}else if(this.state==="esc")if(e[n]==="_"){if(i)t.push({type:"text",text:i});i="",this.begin(),n++}else i+="\x1B",this.state="text";else if(this.state==="apc"){G.lastIndex=n;let s=G.exec(e),r=s?s.index:e.length;if(this.append(e.slice(n,r)),n=r,s)if(n++,s[0]==="\x1B")this.state="apc-esc";else this.reset()}else if(e[n]==="\\")t.push(this.overflow?{type:"apc",body:this.head,overflow:!0}:{type:"apc",body:this.parts.join("")}),this.reset(),n++;else this.reset(),this.state="esc";if(i)t.push({type:"text",text:i});return t}begin(){this.reset(),this.state="apc"}append(e){if(!e)return;if(this.head.length<4096)this.head+=e.slice(0,4096-this.head.length);if(this.overflow)return;if(this.size+=e.length,this.size>this.maxBytes){this.overflow=!0,this.parts=[];return}this.parts.push(e)}reset(){this.state="text",this.parts=[],this.head="",this.size=0,this.overflow=!1}}function V(e){if(e[0]!=="G")return null;let t=e.indexOf(";"),i=t<0?e.slice(1):e.slice(1,t),n=t<0?"":e.slice(t+1),s={};for(let r of i.split(",")){let a=r.indexOf("=");if(a>0)s[r.slice(0,a)]=r.slice(a+1)}return{keys:s,payload:n}}var x=67108864;class E{maxBytes;pending=null;discarding=null;constructor(e=x){this.maxBytes=e}reject(e){let t=this.pending?.keys??this.discarding??e.keys;if(this.pending=null,e.keys.m==="1")return this.discarding=t,null;return this.discarding=null,{keys:t,data:"",tooBig:!0}}push(e){let t=e.keys.m==="1";if(this.discarding){if(t)return null;let s=this.discarding;return this.discarding=null,{keys:s,data:"",tooBig:!0}}let i=(this.pending?.size??0)+e.payload.length;if(i>this.maxBytes){let s=this.pending?.keys??e.keys;if(this.pending=null,t)return this.discarding=s,null;return{keys:s,data:"",tooBig:!0}}if(!this.pending){if(!t)return{keys:e.keys,data:e.payload};return this.pending={keys:e.keys,parts:[e.payload],size:i},null}if(this.pending.parts.push(e.payload),this.pending.size=i,t)return null;let n={keys:this.pending.keys,data:this.pending.parts.join("")};return this.pending=null,n}}function u(e,t,i=0){let n=Number(e[t]);return e[t]!==void 0&&Number.isFinite(n)?n:i}function K(e,t,i){if(e.i===void 0&&e.I===void 0)return null;let n=u(e,"q");if(n===2||n===1&&!i)return null;let s=[`i=${t}`];if(e.I!==void 0)s.push(`I=${e.I}`);if(e.p!==void 0)s.push(`p=${e.p}`);let r=i?`${i.code}:${i.message}`:"OK";return`\x1B_G${s.join(",")};${r}\x1B\\`}var U=[137,80,78,71,13,10,26,10];function N(e){if(e.length<24)return null;for(let s=0;s<U.length;s++)if(e[s]!==U[s])return null;let t=(s)=>(e[s]<<24|e[s+1]<<16|e[s+2]<<8|e[s+3])>>>0;if(t(8)!==13)return null;if(t(12)!==1229472850)return null;let i=t(16),n=t(20);if(i===0||n===0||i>2147483647||n>2147483647)return null;return{width:i,height:n}}function j(e){if(e.length<32)return null;let t;try{t=atob(e.slice(0,32))}catch{return null}return N(Uint8Array.from(t,(i)=>i.charCodeAt(0)))}var le=new RegExp("\x1B\\[[23]J|\x1B\\[\\?(?:1049|1047|47)[hl]|\x1Bc");function he(e){return le.test(e)}var L=new RegExp("\x1B\\[(14|16|18)t","g");function ue(e){let t=[];L.lastIndex=0;for(let i=L.exec(e);i!==null;i=L.exec(e))t.push(Number(i[1]));return t}function I(e,t){return Math.max(1,Math.round(e*t))}function R(e,t){return e>0?I(e,t)/e:t}var de=new RegExp("\x1B(?:\\[[0-9;?]{0,16})?$");class T{carry="";scan(e){let t=this.carry+e,i=de.exec(t);return this.carry=i?i[0]:"",{clears:he(t),queries:ue(t)}}}function J(e,t){let i=Math.round(t.cols*t.cellWidth),n=Math.round(t.rows*t.cellHeight);if(e===14)return`\x1B[4;${n};${i}t`;if(e===16)return`\x1B[6;${Math.round(t.cellHeight)};${Math.round(t.cellWidth)}t`;return`\x1B[8;${t.rows};${t.cols}t`}function z(e,t,i,n){let s=u(e,"c"),r=u(e,"r"),{width:a,height:c}=t;if(s&&r)return{cols:s,rows:r};if(s)return{cols:s,rows:v(s*i*c/a,n)};if(r)return{cols:v(r*n*a/c,i),rows:r};return{cols:v(a,i),rows:v(c,n)}}function v(e,t){return Math.max(1,Math.ceil(e/t-0.000001))}var me={maxImages:256,maxImagePixels:33554432,maxTotalBytes:536870912,maxTransmissionBytes:x},fe=1073741824;class p extends Error{code;constructor(e,t){super(t);this.code=e}}function pe(e){let t=atob(e),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i}async function ge(e,t){let i=new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate")).getReader(),n=[],s=0;for(;;){let{done:c,value:o}=await i.read();if(c)break;if(s+=o.length,s>t)throw await i.cancel(),new p("EINVAL","decompressed data too large");n.push(o)}let r=new Uint8Array(s),a=0;for(let c of n)r.set(c,a),a+=c.length;return r}async function ye(e,t,i){let n=u(e,"f",32),s=u(e,"s"),r=u(e,"v"),a=n===24?3:4,c=pe(t);if(e.o==="z")c=await ge(c,n===100?x:s*r*a);if(n===100){let m=N(c);if(!m)throw new p("EINVAL","not a PNG");if(m.width*m.height>i)throw new p("EINVAL","image too large");return createImageBitmap(new Blob([c],{type:"image/png"}))}if(c.length<s*r*a)throw new p("ENODATA","not enough pixel data");let o=new Uint8ClampedArray(s*r*4);if(n===32)o.set(c.subarray(0,s*r*4));else for(let m=0,d=0;d<o.length;m+=3,d+=4)o[d]=c[m],o[d+1]=c[m+1],o[d+2]=c[m+2],o[d+3]=255;return createImageBitmap(new ImageData(o,s,r))}class O{term;container;send;splitter;assembler;scanner=new T;images=new Map;totalBytes=0;inFlightBytes=0;placements=new Map;anonymousId=0;generation=0;limits;overlay;dirty=!1;lastSignature="";constructor(e,t,i,n={}){this.term=e;this.container=t;this.send=i;this.limits={...me,...n},this.splitter=new S(this.limits.maxTransmissionBytes),this.assembler=new E(this.limits.maxTransmissionBytes),this.overlay=document.createElement("canvas"),this.overlay.dataset.kitty="",this.overlay.style.cssText="position:absolute;pointer-events:none;",t.appendChild(this.overlay),requestAnimationFrame(this.tick),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible")this.invalidate()})}invalidate(){this.dirty=!0,this.lastSignature=""}reset(){this.generation++,this.splitter=new S(this.limits.maxTransmissionBytes),this.assembler=new E(this.limits.maxTransmissionBytes),this.scanner=new T,this.dropImages(),this.clear()}feed(e){for(let t of this.splitter.feed(e))if(t.type==="text")this.writeText(t.text);else this.handleApc(t.body,t.overflow)}writeText(e){this.term.write(e);let{clears:t,queries:i}=this.scanner.scan(e);if(t)this.clear();for(let n of i)this.send(J(n,this.terminalSize()))}handleApc(e,t=!1){let i=V(e);if(!i)return;let n=t?this.assembler.reject(i):this.assembler.push(i);if(!n)return;let s=n.keys.a??"t";try{if(n.tooBig)throw new p("EINVAL","transmission too large");if(s==="q")this.query(n);else if(s==="t"||s==="T")this.transmit(n,s==="T");else if(s==="p"){let r=this.requireImage(n.keys);this.place(n.keys,r),this.reply(n.keys,r)}else if(s==="d")this.delete(n.keys)}catch(r){this.replyError(n.keys,r)}}imageIdOf(e){if(e.i!==void 0)return u(e,"i");if(e.I!==void 0)return fe+u(e,"I");return 0}requireImage(e){let t=this.imageIdOf(e);if(!this.images.has(t))throw new p("ENOENT","no such image");return t}assertSupported(e){let t=e.t??"d";if(t!=="d")throw new p("EINVAL",`unsupported transmission medium t=${t}`);let i=u(e,"f",32);if(i!==24&&i!==32&&i!==100)throw new p("EINVAL",`unsupported format f=${i}`)}query(e){this.assertSupported(e.keys),this.reply(e.keys,this.imageIdOf(e.keys))}assertWithinLimits(e,t){if(u(e,"f",32)!==100){let{width:i,height:n}=t;if(!Number.isInteger(i)||!Number.isInteger(n)||i<=0||n<=0)throw new p("EINVAL","raw image needs positive integer s and v")}if(t.width*t.height>this.limits.maxImagePixels)throw new p("EINVAL","image too large")}transmit(e,t){this.assertSupported(e.keys);let i=this.dimensions(e);if(this.assertWithinLimits(e.keys,i),t)this.assertCursorMovable(e.keys,i);let n=i.width&&i.height,s=e.data.length+(n?i.width*i.height:this.limits.maxImagePixels)*4;if(!this.enforceBudget(!1,s))throw new p("EINVAL","too many images being decoded");let r=this.imageIdOf(e.keys),a=r||--this.anonymousId,c=this.generation;this.removePlacements((d)=>d.imageId===a);let o=this.images.get(a)??{width:0,height:0,bytes:0,latest:0,applied:0};this.images.delete(a),this.images.set(a,o),o.width=i.width,o.height=i.height,this.evict();let m=++o.latest;if(t)this.place(e.keys,a);this.inFlightBytes+=s,ye(e.keys,e.data,this.limits.maxImagePixels).then((d)=>{if(this.inFlightBytes-=s,c!==this.generation){d.close();return}if(this.images.get(a)!==o){d.close(),this.replyError(e.keys,new p("EINVAL","image was removed before it finished decoding"));return}if(m<=o.applied){d.close(),this.reply(e.keys,r?a:0);return}if(o.bitmap?.close(),o.bitmap=d,o.applied=m,m===o.latest)o.width=d.width,o.height=d.height;let y=d.width*d.height*4;this.totalBytes+=y-o.bytes,o.bytes=y,this.enforceBudget(),this.dirty=!0,this.reply(e.keys,r?a:0)},(d)=>{if(this.inFlightBytes-=s,c!==this.generation)return;if(this.images.get(a)===o&&m===o.latest){if(this.removePlacements((y)=>y.imageId===a),!o.bitmap)this.dropImage(a)}this.replyError(e.keys,d)})}dimensions(e){if(u(e.keys,"f",32)!==100)return{width:u(e.keys,"s"),height:u(e.keys,"v")};if(e.keys.o==="z")return{width:0,height:0};let t=j(e.data);if(!t)throw new p("EINVAL","not a PNG");return t}assertCursorMovable(e,t){if(u(e,"C")===1||t.width&&t.height)return;throw new p("EINVAL","size of a compressed PNG is unknown until decoded: use C=1")}place(e,t){let i=this.images.get(t)??{width:0,height:0};this.assertCursorMovable(e,i);let n=this.term.buffer.active,s=this.cell(),r=this.scale(),a={imageId:t,placementId:u(e,"p"),absRow:this.scrollbackLength()+n.cursorY,col:n.cursorX,srcX:u(e,"x"),srcY:u(e,"y"),srcW:u(e,"w"),srcH:u(e,"h"),offX:u(e,"X"),offY:u(e,"Y"),scale:r};if(e.c!==void 0)a.cols=u(e,"c");if(e.r!==void 0)a.rows=u(e,"r");if(this.placements.set(`${t}:${a.placementId}`,a),this.dirty=!0,u(e,"C")===1)return;let c={width:(a.srcW||Math.max(1,i.width-a.srcX))/r.x,height:(a.srcH||Math.max(1,i.height-a.srcY))/r.y},o=z(e,c,s.width,s.height);this.term.write(`${`
|
|
2
|
+
`.repeat(o.rows-1)}\x1B[${a.col+o.cols+1}G`)}delete(e){let t=e.d??"a";if(t==="a"||t==="A"){if(this.removePlacements(()=>!0),t==="A")this.dropImages()}else if(t==="i"||t==="I"){let i=this.imageIdOf(e),n=e.p!==void 0?u(e,"p"):void 0;if(this.removePlacements((s)=>s.imageId===i&&(n===void 0||s.placementId===n)),t==="I")this.dropImage(i)}}removePlacements(e){for(let[t,i]of this.placements){if(!e(i))continue;this.placements.delete(t),this.dirty=!0}}dropImage(e){let t=this.images.get(e);if(!t)return;t.bitmap?.close(),this.totalBytes-=t.bytes,this.images.delete(e),this.removePlacements((i)=>i.imageId===e)}dropImages(){for(let e of[...this.images.keys()])this.dropImage(e)}clear(){this.placements.clear(),this.dirty=!0}evict(){while(this.images.size>this.limits.maxImages)this.dropImage(this.images.keys().next().value)}enforceBudget(e=!0,t=0){let i=()=>this.totalBytes+this.inFlightBytes+t<=this.limits.maxTotalBytes,n=[...this.images.keys()];if(e)n.pop();for(let s of n){if(i())return!0;this.dropImage(s)}return i()}reply(e,t){let i=K(e,t);if(i)this.send(i)}replyError(e,t){let i=t instanceof p?t.code:"EBADF",n=t instanceof Error?t.message:"decode failed",s=K(e,this.imageIdOf(e),{code:i,message:n});if(s)this.send(s)}scale(){let e=this.cell(),t=window.devicePixelRatio||1;return{x:R(e.width,t),y:R(e.height,t)}}cell(){let e=this.term.renderer?.getMetrics();return{width:e?.width??8,height:e?.height??16}}terminalSize(){let e=this.cell(),t=window.devicePixelRatio||1;return{cols:this.term.cols,rows:this.term.rows,cellWidth:I(e.width,t),cellHeight:I(e.height,t)}}scrollbackLength(){let e=this.term.wasmTerm;if(!e||e.isAlternateScreen())return 0;return e.getScrollbackLength()}terminalCanvas(){return this.container.querySelector("canvas:not([data-kitty])")}tick=()=>{if(requestAnimationFrame(this.tick),this.placements.size===0&&!this.overlay.width)return;let e=this.terminalCanvas();if(!e)return;let t=this.cell(),i=[this.scrollbackLength(),this.term.viewportY,t.width,t.height,e.offsetLeft,e.offsetTop,e.offsetWidth,e.offsetHeight,window.devicePixelRatio].join("|");if(!this.dirty&&i===this.lastSignature)return;this.dirty=!1,this.lastSignature=i,this.draw(e,t)};draw(e,t){let i=window.devicePixelRatio||1,{offsetWidth:n,offsetHeight:s}=e,r=this.overlay;if(r.width!==Math.round(n*i)||r.height!==Math.round(s*i))r.width=Math.round(n*i),r.height=Math.round(s*i);r.style.left=`${e.offsetLeft}px`,r.style.top=`${e.offsetTop}px`,r.style.width=`${n}px`,r.style.height=`${s}px`;let a=r.getContext("2d");if(!a)return;a.setTransform(i,0,0,i,0,0),a.clearRect(0,0,n,s);let c=this.scrollbackLength()-this.term.viewportY;for(let o of this.placements.values()){let m=this.images.get(o.imageId)?.bitmap;if(!m)continue;let{srcX:d,srcY:y}=o,C=o.srcW||m.width-d,A=o.srcH||m.height-y,w=o.cols!==void 0||o.rows!==void 0?z({c:String(o.cols??0),r:String(o.rows??0)},{width:C/o.scale.x,height:A/o.scale.y},t.width,t.height):null,Y=w?w.cols*t.width:C/o.scale.x,q=w?w.rows*t.height:A/o.scale.y,B=o.col*t.width+o.offX/o.scale.x,M=(o.absRow-c)*t.height+o.offY/o.scale.y;if(M+q<0||M>s||B+Y<0||B>n)continue;a.drawImage(m,d,y,C,A,B,M,Y,q)}}}function Q(e,t){if(t&&e.startsWith("\x1B[<32;"))return"\x1B[<35;"+e.slice(6);return e}function Z(e,t){return e.startsWith("\x1B[<32;")&&e===t}var ie=window.location.pathname.split("/s/")[1]??"main",g=await fetch("/api/config").then((e)=>e.json());document.title=`${ie} | webtty`;await we();var h=new ve({cols:g.cols,rows:g.rows,cursorStyle:g.cursorStyle,cursorBlink:g.cursorStyleBlink,fontSize:g.fontSize,fontFamily:g.fontFamily,scrollback:Math.ceil(g.scrollback/80),theme:g.theme}),ne=new be;h.loadAddon(ne);var f=document.getElementById("terminal");if(g.theme?.background)f.style.background=g.theme.background;await h.open(f);function se(){f.style.padding="0",ne.fit();let e=f.querySelector("canvas");if(!e)return;let t=Math.max(0,f.clientWidth-e.offsetWidth),i=Math.max(0,f.clientHeight-e.offsetHeight);f.style.paddingLeft=`${Math.floor(t/2)}px`,f.style.paddingRight=`${Math.ceil(t/2)}px`,f.style.paddingTop=`${Math.floor(i/2)}px`,f.style.paddingBottom=`${Math.ceil(i/2)}px`}var D=null;function _(){if(D!==null)return;D=window.requestAnimationFrame(()=>{D=null,se()})}_();new ResizeObserver(()=>_()).observe(f,{box:"border-box"});window.addEventListener("resize",_);document.fonts.ready.then(()=>h.renderer?.remeasureFont());document.addEventListener("visibilitychange",()=>{if(document.visibilityState!=="visible")return;if(h.renderer&&h.wasmTerm)h.renderer.render(h.wasmTerm,!0,h.viewportY)});function re(e){if(e.style.cursor==="text")e.style.cursor="default"}re(f);new MutationObserver((e)=>{for(let t of e)re(t.target)}).observe(f,{attributes:!0,attributeFilter:["style"],subtree:!0});var Se=window.location.protocol==="https:"?"wss:":"ws:",l,ee=new O(h,f,(e)=>{if(l&&l.readyState===WebSocket.OPEN)l.send(e)});function oe(){let e=`${Se}//${window.location.host}/ws/${ie}/pty?cols=${h.cols}&rows=${h.rows}`;l=new WebSocket(e);let t="\x1B[2m",i="\x1B[1;33m",n="\x1B[3m",s="\x1B[0m",r=`${t}[${s} ${i}webtty${s} ${t}]${s}`,a=(c)=>`\r
|
|
3
|
+
${r} ${t}${n}${c}${s}\r
|
|
4
|
+
`;l.onopen=()=>{ee.reset(),l.send(JSON.stringify({type:"resize",cols:h.cols,rows:h.rows}))},l.onmessage=(c)=>{X(h,c.data),ee.feed(c.data)},l.onclose=(c)=>{if(c.code===4001){h.write(a("Session removed.")),setTimeout(()=>window.close(),500);return}if(c.code===1001){h.write(a("Server stopped.")),setTimeout(()=>window.close(),500);return}h.write(a("Connection lost. Reconnecting in 2s...")),setTimeout(oe,2000)},l.onerror=()=>{h.write(a("WebSocket error."))}}oe();var k=0,te=0;h.attachCustomWheelEventHandler((e)=>{if(!h.hasMouseTracking())return!1;let t=h.renderer?.getMetrics();if(!t)return!1;let i=e.deltaY<0?-1:1;if(i!==te)k=0,te=i;k+=g.mouseScrollSpeed;let n=Math.trunc(k);if(n===0)return!0;k-=n;let s=e.target.getBoundingClientRect(),r=Math.max(1,Math.floor((e.clientX-s.left)/t.width)+1),a=Math.max(1,Math.floor((e.clientY-s.top)/t.height)+1),o=`\x1B[<${i<0?64:65};${r};${a}M`;if(l&&l.readyState===WebSocket.OPEN)for(let m=0;m<n;m++)l.send(o);return!0});function ae(e){let t=e.key.toLowerCase(),i=new Set([...e.shiftKey?["shift"]:[],...e.ctrlKey?["ctrl"]:[],...e.altKey?["alt"]:[],...e.metaKey?["meta"]:[]]);return g.keyboardBindings.find((n)=>{if(n.key.toLowerCase()!==t)return!1;let s=new Set((Array.isArray(n.mods)?n.mods:[]).map((r)=>r.toLowerCase()));if(s.size!==i.size)return!1;for(let r of s)if(!i.has(r))return!1;return!0})}f.addEventListener("keydown",(e)=>{let t=ae(e);if(!t)return;if(e.preventDefault(),e.stopPropagation(),t.chars&&l.readyState===WebSocket.OPEN)l.send(t.chars)},{capture:!0});var b=Math.min(32,Math.max(6,g.fontSize));window.addEventListener("keydown",(e)=>{if(!e.ctrlKey&&!e.metaKey)return;let t=e.code==="Equal"||e.code==="NumpadAdd",i=e.code==="Minus"&&!e.shiftKey||e.code==="NumpadSubtract",n=e.code==="Digit0"&&!e.shiftKey||e.code==="Numpad0";if(!t&&!i&&!n)return;if(e.preventDefault(),e.stopPropagation(),t)b=Math.min(32,b+1);else if(i)b=Math.max(6,b-1);else b=Math.min(32,Math.max(6,g.fontSize));h.options.fontSize=b,se()},{capture:!0});var W=!1,F="";f.addEventListener("mousemove",(e)=>{if(W=h.hasMouseTracking()&&e.buttons===0,W)F=""},{capture:!0});h.onData((e)=>{let t=Q(e,W);if(t!==e){if(l&&l.readyState===WebSocket.OPEN)l.send(t);return}if(Z(e,F))return;if(F=e.startsWith("\x1B[<32;")?e:"",l&&l.readyState===WebSocket.OPEN)l.send(e)});h.onResize(({cols:e,rows:t})=>{if(l&&l.readyState===WebSocket.OPEN)l.send(JSON.stringify({type:"resize",cols:e,rows:t}))});if(g.copyOnSelect)h.onSelectionChange(()=>{let e=h.getSelection();if(!e)return;navigator.clipboard.writeText(e).catch(()=>{})});if(g.rightClickBehavior==="copyPaste")f.addEventListener("contextmenu",(e)=>{let t=h.getSelection();if(!t)return;e.preventDefault(),navigator.clipboard.writeText(t).catch(()=>{}),h.clearSelection()});function H(){if(l&&l.readyState===WebSocket.OPEN)l.send("\x16")}function ce(e){if(!e){H();return}if(!e.includes(`
|
|
5
|
+
`)){if(l&&l.readyState===WebSocket.OPEN)l.send(e);return}if(!h.getMode(2004)){H();return}if(l&&l.readyState===WebSocket.OPEN)l.send(`\x1B[200~${e}\x1B[201~`)}f.addEventListener("keydown",(e)=>{if(!e.ctrlKey||e.metaKey||e.code!=="KeyV")return;if(ae(e))return;if(!navigator.clipboard?.readText)return;e.preventDefault(),e.stopImmediatePropagation(),navigator.clipboard.readText().then(ce,H)},{capture:!0});f.addEventListener("paste",(e)=>{let t=e.clipboardData;if(!t)return;e.preventDefault(),e.stopImmediatePropagation(),ce(t.getData("text/plain"))},{capture:!0});
|
package/dist/client.css
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -104,10 +104,10 @@ function spawn2(shell, cols, rows, term, colorTerm, cwd, env) {
|
|
|
104
104
|
var init_node = () => {};
|
|
105
105
|
|
|
106
106
|
// src/server/index.ts
|
|
107
|
-
import
|
|
107
|
+
import fs5 from "node:fs";
|
|
108
108
|
import http from "node:http";
|
|
109
|
-
import
|
|
110
|
-
import { fileURLToPath as
|
|
109
|
+
import path5 from "node:path";
|
|
110
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
111
111
|
|
|
112
112
|
// src/config.ts
|
|
113
113
|
import fs from "node:fs";
|
|
@@ -261,9 +261,33 @@ function initConfig() {
|
|
|
261
261
|
|
|
262
262
|
// src/server/routes.ts
|
|
263
263
|
import { spawn as spawn3 } from "node:child_process";
|
|
264
|
-
import
|
|
264
|
+
import fs4 from "node:fs";
|
|
265
265
|
import { homedir as homedir2 } from "node:os";
|
|
266
|
-
import
|
|
266
|
+
import path4 from "node:path";
|
|
267
|
+
|
|
268
|
+
// src/version.ts
|
|
269
|
+
import fs2 from "node:fs";
|
|
270
|
+
import path2 from "node:path";
|
|
271
|
+
import { fileURLToPath } from "node:url";
|
|
272
|
+
var cached;
|
|
273
|
+
function getVersion() {
|
|
274
|
+
if (cached)
|
|
275
|
+
return cached;
|
|
276
|
+
let dir = path2.dirname(fileURLToPath(import.meta.url));
|
|
277
|
+
while (true) {
|
|
278
|
+
try {
|
|
279
|
+
const pkg = JSON.parse(fs2.readFileSync(path2.join(dir, "package.json"), "utf8"));
|
|
280
|
+
if (pkg.name === "webtty" && pkg.version) {
|
|
281
|
+
cached = pkg.version;
|
|
282
|
+
return cached;
|
|
283
|
+
}
|
|
284
|
+
} catch {}
|
|
285
|
+
const parent = path2.dirname(dir);
|
|
286
|
+
if (parent === dir)
|
|
287
|
+
return "unknown";
|
|
288
|
+
dir = parent;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
267
291
|
|
|
268
292
|
// src/server/session.ts
|
|
269
293
|
import { homedir } from "node:os";
|
|
@@ -303,12 +327,12 @@ function sessionToJson(s) {
|
|
|
303
327
|
}
|
|
304
328
|
|
|
305
329
|
// src/server/static.ts
|
|
306
|
-
import
|
|
330
|
+
import fs3 from "node:fs";
|
|
307
331
|
import { createRequire } from "node:module";
|
|
308
|
-
import
|
|
309
|
-
import { fileURLToPath } from "node:url";
|
|
310
|
-
var __filename2 =
|
|
311
|
-
var __dirname2 =
|
|
332
|
+
import path3 from "node:path";
|
|
333
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
334
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
335
|
+
var __dirname2 = path3.dirname(__filename2);
|
|
312
336
|
var require2 = createRequire(import.meta.url);
|
|
313
337
|
var MIME_TYPES = {
|
|
314
338
|
".html": "text/html",
|
|
@@ -322,24 +346,24 @@ var MIME_TYPES = {
|
|
|
322
346
|
".ico": "image/x-icon"
|
|
323
347
|
};
|
|
324
348
|
function mimeType(filePath) {
|
|
325
|
-
const ext =
|
|
349
|
+
const ext = path3.extname(filePath);
|
|
326
350
|
return MIME_TYPES[ext] ?? "application/octet-stream";
|
|
327
351
|
}
|
|
328
352
|
function ghosttyWebRootFromMain(mainPath) {
|
|
329
353
|
return mainPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
330
354
|
}
|
|
331
355
|
function findGhosttyWeb() {
|
|
332
|
-
const bundledDist =
|
|
333
|
-
const bundledWasm =
|
|
334
|
-
if (
|
|
356
|
+
const bundledDist = path3.join(__dirname2, "..", "..", "dist");
|
|
357
|
+
const bundledWasm = path3.join(bundledDist, "ghostty-vt.wasm");
|
|
358
|
+
if (fs3.existsSync(path3.join(bundledDist, "ghostty-web.js")) && fs3.existsSync(bundledWasm)) {
|
|
335
359
|
return { distPath: bundledDist, wasmPath: bundledWasm };
|
|
336
360
|
}
|
|
337
361
|
try {
|
|
338
362
|
const ghosttyWebMain = require2.resolve("ghostty-web");
|
|
339
363
|
const ghosttyWebRoot = ghosttyWebRootFromMain(ghosttyWebMain);
|
|
340
|
-
const distPath =
|
|
341
|
-
const wasmPath =
|
|
342
|
-
if (
|
|
364
|
+
const distPath = path3.join(ghosttyWebRoot, "dist");
|
|
365
|
+
const wasmPath = path3.join(ghosttyWebRoot, "ghostty-vt.wasm");
|
|
366
|
+
if (fs3.existsSync(path3.join(distPath, "ghostty-web.js")) && fs3.existsSync(wasmPath)) {
|
|
343
367
|
return { distPath, wasmPath };
|
|
344
368
|
}
|
|
345
369
|
} catch {}
|
|
@@ -348,7 +372,7 @@ function findGhosttyWeb() {
|
|
|
348
372
|
}
|
|
349
373
|
function serveFile(filePath, res) {
|
|
350
374
|
const contentType = mimeType(filePath);
|
|
351
|
-
|
|
375
|
+
fs3.readFile(filePath, (err, data) => {
|
|
352
376
|
if (err) {
|
|
353
377
|
res.writeHead(404);
|
|
354
378
|
res.end("Not Found");
|
|
@@ -622,6 +646,11 @@ async function handleRequest(req, res, distPath, wasmPath, clientDistPath, onSto
|
|
|
622
646
|
onStop();
|
|
623
647
|
return;
|
|
624
648
|
}
|
|
649
|
+
if (req.method === "GET" && pathname === "/api/server/status") {
|
|
650
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
651
|
+
res.end(JSON.stringify({ version: getVersion() }));
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
625
654
|
if (req.method === "GET" && pathname === "/api/config") {
|
|
626
655
|
const config = loadConfig();
|
|
627
656
|
const clientConfig = {
|
|
@@ -671,17 +700,17 @@ async function handleRequest(req, res, distPath, wasmPath, clientDistPath, onSto
|
|
|
671
700
|
return;
|
|
672
701
|
}
|
|
673
702
|
const baseDir = body.baseDir ?? homedir2();
|
|
674
|
-
if (!
|
|
703
|
+
if (!path4.isAbsolute(baseDir)) {
|
|
675
704
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
676
705
|
res.end(JSON.stringify({ error: "baseDir must be an absolute path" }));
|
|
677
706
|
return;
|
|
678
707
|
}
|
|
679
|
-
if (!
|
|
708
|
+
if (!fs4.existsSync(baseDir)) {
|
|
680
709
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
681
710
|
res.end(JSON.stringify({ error: `baseDir does not exist: ${baseDir}` }));
|
|
682
711
|
return;
|
|
683
712
|
}
|
|
684
|
-
if (!
|
|
713
|
+
if (!fs4.statSync(baseDir).isDirectory()) {
|
|
685
714
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
686
715
|
res.end(JSON.stringify({ error: `baseDir is not a directory: ${baseDir}` }));
|
|
687
716
|
return;
|
|
@@ -787,7 +816,7 @@ async function handleRequest(req, res, distPath, wasmPath, clientDistPath, onSto
|
|
|
787
816
|
res.end("Not Found");
|
|
788
817
|
return;
|
|
789
818
|
}
|
|
790
|
-
const clientHtml =
|
|
819
|
+
const clientHtml = path4.resolve(clientDistPath, "client.html");
|
|
791
820
|
serveFile(clientHtml, res);
|
|
792
821
|
return;
|
|
793
822
|
}
|
|
@@ -971,16 +1000,16 @@ async function handleRequest(req, res, distPath, wasmPath, clientDistPath, onSto
|
|
|
971
1000
|
}
|
|
972
1001
|
if (pathname.startsWith("/dist/")) {
|
|
973
1002
|
const relativePath = pathname.slice(6);
|
|
974
|
-
const ownFile =
|
|
975
|
-
if (ownFile.startsWith(clientDistPath +
|
|
1003
|
+
const ownFile = path4.resolve(clientDistPath, relativePath);
|
|
1004
|
+
if (ownFile.startsWith(clientDistPath + path4.sep)) {
|
|
976
1005
|
const fs = await import("node:fs");
|
|
977
1006
|
if (fs.existsSync(ownFile)) {
|
|
978
1007
|
serveFile(ownFile, res);
|
|
979
1008
|
return;
|
|
980
1009
|
}
|
|
981
1010
|
}
|
|
982
|
-
const filePath =
|
|
983
|
-
if (!filePath.startsWith(
|
|
1011
|
+
const filePath = path4.resolve(distPath, relativePath);
|
|
1012
|
+
if (!filePath.startsWith(path4.resolve(distPath) + path4.sep) && filePath !== path4.resolve(distPath)) {
|
|
984
1013
|
res.writeHead(404);
|
|
985
1014
|
res.end("Not Found");
|
|
986
1015
|
return;
|
|
@@ -997,18 +1026,18 @@ async function handleRequest(req, res, distPath, wasmPath, clientDistPath, onSto
|
|
|
997
1026
|
}
|
|
998
1027
|
|
|
999
1028
|
// src/server/index.ts
|
|
1000
|
-
var __filename3 =
|
|
1001
|
-
var __dirname3 =
|
|
1029
|
+
var __filename3 = fileURLToPath3(import.meta.url);
|
|
1030
|
+
var __dirname3 = path5.dirname(__filename3);
|
|
1002
1031
|
var config = loadConfig();
|
|
1003
1032
|
var HTTP_PORT = Number(process.env.PORT) || config.port;
|
|
1004
1033
|
delete process.env.PORT;
|
|
1005
1034
|
var HTTP_HOST_DISPLAY = config.host;
|
|
1006
1035
|
var HTTP_HOST = config.host === "localhost" ? "127.0.0.1" : config.host;
|
|
1007
1036
|
var { distPath, wasmPath } = findGhosttyWeb();
|
|
1008
|
-
var projectRoot =
|
|
1009
|
-
var builtDistPath =
|
|
1010
|
-
var srcClientPath =
|
|
1011
|
-
var clientDistPath =
|
|
1037
|
+
var projectRoot = path5.resolve(__dirname3, "..", "..");
|
|
1038
|
+
var builtDistPath = path5.join(projectRoot, "dist");
|
|
1039
|
+
var srcClientPath = path5.join(projectRoot, "src", "client");
|
|
1040
|
+
var clientDistPath = fs5.existsSync(path5.join(builtDistPath, "client.html")) ? builtDistPath : srcClientPath;
|
|
1012
1041
|
function shutdown() {
|
|
1013
1042
|
closeAllSessions();
|
|
1014
1043
|
wss.close();
|
|
@@ -1046,4 +1075,4 @@ httpServer.listen(HTTP_PORT, HTTP_HOST, () => {
|
|
|
1046
1075
|
console.log(`listening on http://${HTTP_HOST_DISPLAY}:${HTTP_PORT}`);
|
|
1047
1076
|
});
|
|
1048
1077
|
|
|
1049
|
-
//# debugId=
|
|
1078
|
+
//# debugId=D3126F60C301FB1264756E2164756E21
|
package/dist/server/index.js.map
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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"],
|
|
3
|
+
"sources": ["../src/pty/bun.ts", "../src/pty/node.ts", "../src/server/index.ts", "../src/config.ts", "../src/server/routes.ts", "../src/version.ts", "../src/server/session.ts", "../src/server/static.ts", "../src/server/websocket.ts", "../src/pty/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { PtyProcess } from './types';\n\n/**\n * Spawns a PTY-backed shell using Bun's native `Bun.spawn` terminal API.\n *\n * @param shell - Shell executable path (e.g., `/bin/bash`).\n * @param cols - Terminal width in columns.\n * @param rows - Terminal height in rows.\n * @param term - `$TERM` environment variable (e.g., `xterm-256color`).\n * @param colorTerm - `$COLORTERM` environment variable (e.g., `truecolor`).\n * @param cwd - Working directory for the shell.\n * @returns A {@link PtyProcess} handle for reading/writing and managing the PTY.\n */\nexport function spawn(\n shell: string,\n cols: number,\n rows: number,\n term: string,\n colorTerm: string,\n cwd: string,\n env: Record<string, 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,\n env: { ...process.env, ...env, TERM: term, COLORTERM: colorTerm },\n });\n\n proc.exited.then((exitCode) => {\n onExitCb?.({ exitCode: exitCode ?? 0 });\n });\n\n return {\n pid: proc.pid,\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 nodePty from '@lydell/node-pty';\nimport type { PtyProcess } from './types';\n\n/**\n * Spawns a PTY-backed shell using the `@lydell/node-pty` native addon.\n *\n * @param shell - Shell executable path (e.g., `/bin/bash`).\n * @param cols - Terminal width in columns.\n * @param rows - Terminal height in rows.\n * @param term - `$TERM` environment variable (e.g., `xterm-256color`).\n * @param colorTerm - `$COLORTERM` environment variable (e.g., `truecolor`).\n * @param cwd - Working directory for the shell.\n * @returns A {@link PtyProcess} handle for reading/writing and managing the PTY.\n */\nexport function spawn(\n shell: string,\n cols: number,\n rows: number,\n term: string,\n colorTerm: string,\n cwd: string,\n env: Record<string, string>,\n): PtyProcess {\n // On Windows, cmd.exe may have an AutoRun registry key that launches shell\n // enhancers (e.g. clink). These take over the ConPTY pipe and cause\n // ERR_SOCKET_CLOSED on the first write. Pass /d to disable AutoRun.\n const shellArgs = process.platform === 'win32' && /cmd\\.exe$/i.test(shell) ? ['/d'] : [];\n\n const ptyProc = nodePty.spawn(shell, shellArgs, {\n name: term,\n cols,\n rows,\n cwd,\n env: { ...process.env, ...env, TERM: term, COLORTERM: colorTerm },\n });\n\n return {\n pid: ptyProc.pid,\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
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;\n// PORT is consumed for our own listen port above; clear it so it doesn't leak\n// into PTY shells and `/execute` invocations, which inherit process.env.\ndelete process.env.PORT;\n// 'localhost' resolves to ::1 (IPv6) on modern macOS/Node; bind to 127.0.0.1 instead\n// but keep 'localhost' as the display host so browser URLs use it as intended.\nconst HTTP_HOST_DISPLAY = config.host;\nconst HTTP_HOST = config.host === 'localhost' ? '127.0.0.1' : 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\nprocess.on('uncaughtException', (err) => {\n console.error('[webtty] uncaughtException:', err);\n});\nprocess.on('unhandledRejection', (reason) => {\n console.error('[webtty] unhandledRejection:', reason);\n});\n\nconst httpServer = http.createServer((req, res) => {\n handleRequest(req, res, distPath, wasmPath, clientDistPath, shutdown).catch((err) => {\n console.error('[webtty] unhandled route error:', err);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end('Internal Server Error');\n }\n });\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_DISPLAY}:${HTTP_PORT}`);\n});\n",
|
|
8
8
|
"import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\n/** A single keyboard binding: intercepts `key`+`mods` and sends `chars` to the PTY. */\nexport interface KeyboardBinding {\n /** Key name matched case-insensitively against `KeyboardEvent.key` (e.g. `\"enter\"`, `\"arrowup\"`, `\"a\"`). */\n key: string;\n /** Modifier keys that must be active — and no others — for this binding to match. Accepted values: `\"shift\"`, `\"ctrl\"`, `\"alt\"`, `\"meta\"`. Order irrelevant. Unknown values are filtered out at config load time. */\n mods?: string[];\n /** Byte sequence sent verbatim to the PTY. Standard JSON escapes apply (`\\r`, `\\uXXXX`, etc.). */\n chars: string;\n}\n\n/** Terminal color palette. All keys are optional; omitted keys fall back to the Campbell defaults. */\nexport interface Theme {\n /** Terminal background. */\n background?: string;\n /** Default text color. */\n foreground?: string;\n /** Cursor color. */\n cursor?: string;\n /** Selection highlight. */\n selection?: string;\n /** ANSI 0. */\n black?: string;\n /** ANSI 1. */\n red?: string;\n /** ANSI 2. */\n green?: string;\n /** ANSI 3. */\n yellow?: string;\n /** ANSI 4. */\n blue?: string;\n /** ANSI 5. */\n purple?: string;\n /** ANSI 6. */\n cyan?: string;\n /** ANSI 7. */\n white?: string;\n /** ANSI 8. */\n brightBlack?: string;\n /** ANSI 9. */\n brightRed?: string;\n /** ANSI 10. */\n brightGreen?: string;\n /** ANSI 11. */\n brightYellow?: string;\n /** ANSI 12. */\n brightBlue?: string;\n /** ANSI 13. */\n brightPurple?: string;\n /** ANSI 14. */\n brightCyan?: string;\n /** ANSI 15. */\n brightWhite?: string;\n}\n\n/** Right-click behavior: `\"copyPaste\"` copies selection + clears it if selection exists, otherwise native menu; `\"default\"` always shows native context menu. */\nexport type RightClickBehavior = 'default' | 'copyPaste';\n\n/** Full webtty configuration. All keys are optional in the config file; missing keys fall back to {@link DEFAULT_CONFIG}. */\nexport interface Config {\n /** HTTP listen port; env `PORT` takes precedence. */\n port: number;\n /** Bind address; use `\"0.0.0.0\"` for remote access. */\n host: string;\n /** Shell for new sessions. */\n shell: string;\n /** `$TERM` env var passed to the shell. Fixed to `xterm-256color` — the PTY child talks to webtty, not to the parent terminal. */\n term: string;\n /** `$COLORTERM` env var passed to the shell. */\n colorTerm: string;\n /** PTY history buffer in bytes; used for server-side replay on reload/reconnect. */\n scrollback: number;\n /** Initial terminal width in columns. */\n cols: number;\n /** Initial terminal height in rows. */\n rows: number;\n /** Font size in px. */\n fontSize: number;\n /** CSS font-family stack. */\n fontFamily: string;\n /** Default cursor shape. Apps override at runtime via DECSCUSR — this is the startup default only. */\n cursorStyle: 'block' | 'bar' | 'underline';\n /** Default blink state. Apps override at runtime via DECSCUSR — this is the startup default only. */\n cursorStyleBlink: boolean;\n /** Auto-copy selection to clipboard on mouseup (kitty / Windows Terminal style). */\n copyOnSelect: boolean;\n /** `\"copyPaste\"` copies selection + clears it on right-click if selection exists; `\"default\"` always shows native context menu. */\n rightClickBehavior: RightClickBehavior;\n /** Mouse wheel scroll speed multiplier for apps with mouse tracking. `1` = one SGR per tick. Values `< 1` reduce rate; values `> 1` send multiple SGRs per tick. Must be `> 0`. */\n mouseScrollSpeed: number;\n /** Write server stdout/stderr to `~/.config/webtty/server.log`. Appends on each start. */\n logs: boolean;\n /** Terminal color palette. */\n theme: Theme;\n /** Custom key-to-sequence bindings. Merged with built-in defaults by `(key, mods)` identity. */\n keyboardBindings: KeyboardBinding[];\n /** Additional environment variables injected into PTY shells and execute commands. Merges over `process.env`; `TERM` and `COLORTERM` always take precedence for PTY spawns. */\n env: Record<string, string>;\n}\n\n/** Returns the webtty config directory: `~/.config/webtty`. */\nexport function configDir(): string {\n // os.homedir() is the authoritative home directory. process.env.HOME is used\n // as an override in tests (e.g. to isolate config state), but only when it is\n // an absolute path — guarding against accidental env pollution such as the\n // string \"undefined\" being assigned when HOME was originally unset on Windows.\n const home =\n process.env.HOME && path.isAbsolute(process.env.HOME) ? process.env.HOME : os.homedir();\n return path.join(home, '.config', 'webtty');\n}\n\nfunction getConfigPath(): string {\n return path.join(configDir(), 'config.json');\n}\n\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\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\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\nexport const DEFAULT_KEYBOARD_BINDINGS: KeyboardBinding[] = [];\n\n// NOTE: export for testing only; users should use loadConfig() and initConfig() instead\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: '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 cursorStyle: 'bar',\n cursorStyleBlink: true,\n copyOnSelect: true,\n rightClickBehavior: 'default' as RightClickBehavior,\n mouseScrollSpeed: 1,\n logs: false,\n theme: DEFAULT_THEME,\n keyboardBindings: DEFAULT_KEYBOARD_BINDINGS,\n env: {},\n};\n\nfunction bindingKey(b: KeyboardBinding): string {\n const mods = [...(b.mods ?? [])].sort().join('+');\n return `${b.key.toLowerCase()}|${mods}`;\n}\n\nconst VALID_MODS = new Set(['shift', 'ctrl', 'alt', 'meta']);\n\nfunction isValidBinding(b: unknown): b is KeyboardBinding {\n if (!b || typeof b !== 'object') return false;\n const o = b as Record<string, unknown>;\n if (typeof o.key !== 'string' || typeof o.chars !== 'string') return false;\n if (o.mods !== undefined && !Array.isArray(o.mods)) return false;\n return true;\n}\n\nfunction normalizeBinding(b: KeyboardBinding): KeyboardBinding {\n return {\n ...b,\n key: b.key.toLowerCase(),\n mods: (b.mods ?? []).map((m) => m.toLowerCase()).filter((m) => VALID_MODS.has(m)),\n };\n}\n\n/**\n * Merges user-supplied bindings over a set of defaults by `(key, mods)` identity.\n * User entries replace matching defaults; unmatched user entries are appended.\n *\n * @param defaults - Default bindings to merge over.\n * @param user - User-supplied bindings that override defaults.\n * @returns Merged bindings with user entries replacing matching defaults and new user entries appended.\n */\n// NOTE: export for testing only\nexport function mergeKeyboardBindings(\n defaults: KeyboardBinding[],\n user: KeyboardBinding[],\n): KeyboardBinding[] {\n const deduped = [...new Map(user.map((b) => [bindingKey(b), b])).values()];\n const overrides = new Map(deduped.map((b) => [bindingKey(b), b]));\n const merged = defaults.map((d) => overrides.get(bindingKey(d)) ?? d);\n const defaultKeys = new Set(defaults.map(bindingKey));\n for (const b of deduped) {\n if (!defaultKeys.has(bindingKey(b))) merged.push(b);\n }\n return merged;\n}\n\n/**\n * Load config from `~/.config/webtty/config.json`, merged over `DEFAULT_CONFIG`.\n *\n * On first run (file absent), writes the default port/host stub and returns defaults.\n * Unknown keys and keys with wrong types are silently ignored.\n * Throws if the file exists but cannot be read or contains invalid JSON.\n *\n * @returns The resolved {@link Config}, with all missing keys filled from {@link DEFAULT_CONFIG}.\n */\nexport function loadConfig(): Config {\n if (!fs.existsSync(getConfigPath())) {\n try {\n initConfig();\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.cursorStyle === 'string' &&\n (p.cursorStyle === 'block' || p.cursorStyle === 'bar' || p.cursorStyle === 'underline') && {\n cursorStyle: p.cursorStyle,\n }),\n ...(typeof p.cursorStyleBlink === 'boolean' && { cursorStyleBlink: p.cursorStyleBlink }),\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.mouseScrollSpeed === 'number' &&\n p.mouseScrollSpeed > 0 && { mouseScrollSpeed: p.mouseScrollSpeed }),\n ...(typeof p.logs === 'boolean' && { logs: p.logs }),\n ...(p.theme && typeof p.theme === 'object' && { theme: { ...DEFAULT_THEME, ...p.theme } }),\n ...(Array.isArray(p.keyboardBindings) && {\n keyboardBindings: mergeKeyboardBindings(\n DEFAULT_KEYBOARD_BINDINGS,\n p.keyboardBindings.filter(isValidBinding).map(normalizeBinding),\n ),\n }),\n ...(p.env &&\n typeof p.env === 'object' &&\n !Array.isArray(p.env) && {\n env: Object.fromEntries(\n Object.entries(p.env as Record<string, unknown>).filter(\n ([k, v]) => typeof k === 'string' && typeof v === 'string',\n ) as [string, string][],\n ),\n }),\n };\n}\n\n/**\n * Write the initial config stub (`port` + `host` only) to `~/.config/webtty/config.json`.\n *\n * Only writes the two keys that are safe to persist as defaults; all other\n * keys are intentionally omitted so future webtty versions can add new fields\n * without the stub going stale.\n */\nexport function initConfig(): 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 { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport type http from 'node:http';\nimport { homedir } from 'node:os';\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 { broadcastToSubscribers, closeSession } from './websocket';\n\nconst MAX_BODY = 64 * 1024;\n\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n};\n\nfunction setCors(res: http.ServerResponse): void {\n for (const [k, v] of Object.entries(CORS_HEADERS)) res.setHeader(k, v);\n}\n\nfunction decodeId(raw: string): string | null {\n try {\n return decodeURIComponent(raw);\n } catch {\n return null;\n }\n}\n\n/**\n * Reads and JSON-parses the request body (max 64 KB).\n *\n * @param req - The incoming HTTP request.\n * @returns A promise resolving to the parsed JSON object, or an empty object if body is empty.\n * @throws {Error} with `status: 413` if body exceeds 64 KB.\n * @throws {Error} if the body contains invalid JSON.\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\n/**\n * Main HTTP request handler for the webtty server.\n * Dispatches all REST API routes and serves static client assets.\n *\n * @param req - The incoming HTTP request.\n * @param res - The HTTP response object.\n * @param distPath - Path to the server-side dist directory.\n * @param wasmPath - Path to the ghostty-vt.wasm file.\n * @param clientDistPath - Path to the client dist directory.\n * @param onStop - Callback invoked when `POST /api/server/stop` is received.\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 setCors(res);\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\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 // Whitelist client-safe keys — avoid exposing server-side config (shell, host, logs, etc.)\n const clientConfig = {\n cols: config.cols,\n rows: config.rows,\n fontSize: config.fontSize,\n fontFamily: config.fontFamily,\n cursorStyle: config.cursorStyle,\n cursorStyleBlink: config.cursorStyleBlink,\n scrollback: config.scrollback,\n theme: config.theme,\n copyOnSelect: config.copyOnSelect,\n rightClickBehavior: config.rightClickBehavior,\n mouseScrollSpeed: config.mouseScrollSpeed,\n keyboardBindings: config.keyboardBindings,\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; baseDir?: string };\n try {\n body = (await readJson(req)) as { id?: string; baseDir?: 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 baseDir = body.baseDir ?? homedir();\n if (!path.isAbsolute(baseDir)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'baseDir must be an absolute path' }));\n return;\n }\n if (!fs.existsSync(baseDir)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `baseDir does not exist: ${baseDir}` }));\n return;\n }\n if (!fs.statSync(baseDir).isDirectory()) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `baseDir is not a directory: ${baseDir}` }));\n return;\n }\n const session = createSession(id, baseDir);\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 const publishMatch = pathname.match(/^\\/s\\/([^/]+)\\/publish$/);\n if (req.method === 'POST' && publishMatch) {\n const id = decodeId(publishMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n if (!(req.headers['content-type'] ?? '').startsWith('application/json')) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n if (session.pty === null) {\n res.writeHead(409);\n res.end('PTY not running');\n return;\n }\n let buf = '';\n req.on('data', (chunk: Buffer) => {\n buf += chunk.toString('utf8');\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n if (buf.length > MAX_BODY) buf = '';\n for (const line of lines) {\n const trimmed = line.replace(/\\r$/, '');\n if (!trimmed) continue;\n try {\n JSON.parse(trimmed);\n broadcastToSubscribers(session, trimmed);\n } catch {\n // skip invalid JSON lines\n }\n }\n });\n req.on('end', () => {\n const trimmed = buf.replace(/\\r$/, '');\n if (trimmed) {\n try {\n JSON.parse(trimmed);\n broadcastToSubscribers(session, trimmed);\n } catch {\n // skip invalid JSON\n }\n }\n res.writeHead(204);\n res.end();\n });\n req.on('error', () => {\n res.writeHead(500);\n res.end();\n });\n return;\n }\n\n const executeMatch = pathname.match(/^\\/s\\/([^/]+)\\/execute$/);\n if (req.method === 'POST' && executeMatch) {\n const id = decodeId(executeMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n if (!(req.headers['content-type'] ?? '').startsWith('application/json')) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n if (session.pty === null) {\n res.writeHead(409);\n res.end('PTY not running');\n return;\n }\n let execBody: unknown;\n try {\n execBody = await readJson(req);\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 const { cmd, args, stdin } = execBody as { cmd?: unknown; args?: unknown; stdin?: unknown };\n if (typeof cmd !== 'string' || cmd.length === 0) {\n res.writeHead(400);\n res.end('invalid body');\n return;\n }\n if (!Array.isArray(args) || !args.every((a) => typeof a === 'string')) {\n res.writeHead(400);\n res.end('invalid body');\n return;\n }\n let child: ReturnType<typeof spawn>;\n try {\n const execConfig = loadConfig();\n child = spawn(cmd, args as string[], {\n env: { ...process.env, ...execConfig.env },\n cwd: session.baseDir,\n windowsHide: true,\n });\n } catch (err) {\n res.writeHead(500);\n res.end(`spawn error: ${String(err)}`);\n return;\n }\n res.writeHead(200, {\n 'Content-Type': 'application/x-ndjson',\n 'Cache-Control': 'no-cache',\n });\n let done = false;\n child.on('error', (err) => {\n if (done) return;\n done = true;\n const msg = err.message;\n const code = (err as NodeJS.ErrnoException).code;\n res.write(`${JSON.stringify({ stream: 'stderr', data: `${msg}\\n` })}\\n`);\n res.write(`${JSON.stringify({ exit: 1, error: msg, ...(code ? { code } : {}) })}\\n`);\n res.end();\n });\n if (typeof stdin === 'string') {\n child.stdin?.write(stdin);\n }\n child.stdin?.end();\n child.stdout?.on('data', (chunk: Buffer) => {\n res.write(`${JSON.stringify({ stream: 'stdout', data: chunk.toString() })}\\n`);\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n res.write(`${JSON.stringify({ stream: 'stderr', data: chunk.toString() })}\\n`);\n });\n child.on('close', (code: number | null) => {\n if (done) return;\n done = true;\n res.write(`${JSON.stringify({ exit: code ?? 1 })}\\n`);\n res.end();\n });\n req.on('close', () => {\n if (!done) child.kill();\n });\n return;\n }\n\n const pidMatch = pathname.match(/^\\/p\\/(\\d+)$/);\n if (req.method === 'GET' && pidMatch) {\n const pid = parseInt(pidMatch[1], 10);\n if (!Number.isFinite(pid) || pid <= 0) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n const session = [...sessionRegistry.values()].find((s) => s.pty?.pid === pid);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(302, { Location: `/s/${session.id}` });\n res.end();\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",
|
|
9
|
+
"import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport type http from 'node:http';\nimport { homedir } from 'node:os';\nimport path from 'node:path';\nimport { loadConfig } from '../config';\nimport { getVersion } from '../version';\nimport {\n createSession,\n generateId,\n isValidId,\n lastUsedId,\n sessionRegistry,\n sessionToJson,\n setLastUsedId,\n} from './session';\nimport { serveFile } from './static';\nimport { broadcastToSubscribers, closeSession } from './websocket';\n\nconst MAX_BODY = 64 * 1024;\n\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n};\n\nfunction setCors(res: http.ServerResponse): void {\n for (const [k, v] of Object.entries(CORS_HEADERS)) res.setHeader(k, v);\n}\n\nfunction decodeId(raw: string): string | null {\n try {\n return decodeURIComponent(raw);\n } catch {\n return null;\n }\n}\n\n/**\n * Reads and JSON-parses the request body (max 64 KB).\n *\n * @param req - The incoming HTTP request.\n * @returns A promise resolving to the parsed JSON object, or an empty object if body is empty.\n * @throws {Error} with `status: 413` if body exceeds 64 KB.\n * @throws {Error} if the body contains invalid JSON.\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\n/**\n * Main HTTP request handler for the webtty server.\n * Dispatches all REST API routes and serves static client assets.\n *\n * @param req - The incoming HTTP request.\n * @param res - The HTTP response object.\n * @param distPath - Path to the server-side dist directory.\n * @param wasmPath - Path to the ghostty-vt.wasm file.\n * @param clientDistPath - Path to the client dist directory.\n * @param onStop - Callback invoked when `POST /api/server/stop` is received.\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 setCors(res);\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\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/server/status') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ version: getVersion() }));\n return;\n }\n\n if (req.method === 'GET' && pathname === '/api/config') {\n const config = loadConfig();\n // Whitelist client-safe keys — avoid exposing server-side config (shell, host, logs, etc.)\n const clientConfig = {\n cols: config.cols,\n rows: config.rows,\n fontSize: config.fontSize,\n fontFamily: config.fontFamily,\n cursorStyle: config.cursorStyle,\n cursorStyleBlink: config.cursorStyleBlink,\n scrollback: config.scrollback,\n theme: config.theme,\n copyOnSelect: config.copyOnSelect,\n rightClickBehavior: config.rightClickBehavior,\n mouseScrollSpeed: config.mouseScrollSpeed,\n keyboardBindings: config.keyboardBindings,\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; baseDir?: string };\n try {\n body = (await readJson(req)) as { id?: string; baseDir?: 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 baseDir = body.baseDir ?? homedir();\n if (!path.isAbsolute(baseDir)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'baseDir must be an absolute path' }));\n return;\n }\n if (!fs.existsSync(baseDir)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `baseDir does not exist: ${baseDir}` }));\n return;\n }\n if (!fs.statSync(baseDir).isDirectory()) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `baseDir is not a directory: ${baseDir}` }));\n return;\n }\n const session = createSession(id, baseDir);\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 const publishMatch = pathname.match(/^\\/s\\/([^/]+)\\/publish$/);\n if (req.method === 'POST' && publishMatch) {\n const id = decodeId(publishMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n if (!(req.headers['content-type'] ?? '').startsWith('application/json')) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n if (session.pty === null) {\n res.writeHead(409);\n res.end('PTY not running');\n return;\n }\n let buf = '';\n req.on('data', (chunk: Buffer) => {\n buf += chunk.toString('utf8');\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n if (buf.length > MAX_BODY) buf = '';\n for (const line of lines) {\n const trimmed = line.replace(/\\r$/, '');\n if (!trimmed) continue;\n try {\n JSON.parse(trimmed);\n broadcastToSubscribers(session, trimmed);\n } catch {\n // skip invalid JSON lines\n }\n }\n });\n req.on('end', () => {\n const trimmed = buf.replace(/\\r$/, '');\n if (trimmed) {\n try {\n JSON.parse(trimmed);\n broadcastToSubscribers(session, trimmed);\n } catch {\n // skip invalid JSON\n }\n }\n res.writeHead(204);\n res.end();\n });\n req.on('error', () => {\n res.writeHead(500);\n res.end();\n });\n return;\n }\n\n const executeMatch = pathname.match(/^\\/s\\/([^/]+)\\/execute$/);\n if (req.method === 'POST' && executeMatch) {\n const id = decodeId(executeMatch[1]);\n if (!id) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n if (!(req.headers['content-type'] ?? '').startsWith('application/json')) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n const session = sessionRegistry.get(id);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n if (session.pty === null) {\n res.writeHead(409);\n res.end('PTY not running');\n return;\n }\n let execBody: unknown;\n try {\n execBody = await readJson(req);\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 const { cmd, args, stdin } = execBody as { cmd?: unknown; args?: unknown; stdin?: unknown };\n if (typeof cmd !== 'string' || cmd.length === 0) {\n res.writeHead(400);\n res.end('invalid body');\n return;\n }\n if (!Array.isArray(args) || !args.every((a) => typeof a === 'string')) {\n res.writeHead(400);\n res.end('invalid body');\n return;\n }\n let child: ReturnType<typeof spawn>;\n try {\n const execConfig = loadConfig();\n child = spawn(cmd, args as string[], {\n env: { ...process.env, ...execConfig.env },\n cwd: session.baseDir,\n windowsHide: true,\n });\n } catch (err) {\n res.writeHead(500);\n res.end(`spawn error: ${String(err)}`);\n return;\n }\n res.writeHead(200, {\n 'Content-Type': 'application/x-ndjson',\n 'Cache-Control': 'no-cache',\n });\n let done = false;\n child.on('error', (err) => {\n if (done) return;\n done = true;\n const msg = err.message;\n const code = (err as NodeJS.ErrnoException).code;\n res.write(`${JSON.stringify({ stream: 'stderr', data: `${msg}\\n` })}\\n`);\n res.write(`${JSON.stringify({ exit: 1, error: msg, ...(code ? { code } : {}) })}\\n`);\n res.end();\n });\n if (typeof stdin === 'string') {\n child.stdin?.write(stdin);\n }\n child.stdin?.end();\n child.stdout?.on('data', (chunk: Buffer) => {\n res.write(`${JSON.stringify({ stream: 'stdout', data: chunk.toString() })}\\n`);\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n res.write(`${JSON.stringify({ stream: 'stderr', data: chunk.toString() })}\\n`);\n });\n child.on('close', (code: number | null) => {\n if (done) return;\n done = true;\n res.write(`${JSON.stringify({ exit: code ?? 1 })}\\n`);\n res.end();\n });\n req.on('close', () => {\n if (!done) child.kill();\n });\n return;\n }\n\n const pidMatch = pathname.match(/^\\/p\\/(\\d+)$/);\n if (req.method === 'GET' && pidMatch) {\n const pid = parseInt(pidMatch[1], 10);\n if (!Number.isFinite(pid) || pid <= 0) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n const session = [...sessionRegistry.values()].find((s) => s.pty?.pid === pid);\n if (!session) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n res.writeHead(302, { Location: `/s/${session.id}` });\n res.end();\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 fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cached: string | undefined;\n\n/**\n * Returns the webtty version from the nearest `package.json` above this file.\n *\n * Read at runtime (not inlined at build time) because semantic-release bumps\n * `package.json` after `bun run build`. Walking up keeps it working from both\n * `src/` and the bundled `dist/cli` / `dist/server` entries.\n * Dev checkouts report `0.0.0-development`.\n */\nexport function getVersion(): string {\n if (cached) return cached;\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (true) {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === 'webtty' && pkg.version) {\n cached = pkg.version;\n return cached;\n }\n } catch {\n // no readable package.json at this level — keep walking up\n }\n const parent = path.dirname(dir);\n if (parent === dir) return 'unknown';\n dir = parent;\n }\n}\n",
|
|
10
11
|
"import { homedir } from 'node:os';\nimport type { WebSocket as WS } from 'ws';\nimport type { PtyProcess } from '../pty';\n\n/** A running (or recently created) terminal session. */\nexport interface Session {\n /** Unique session identifier. */\n id: string;\n /** Unix timestamp (ms) when the session was created. */\n createdAt: number;\n /** Working directory for the PTY shell. */\n baseDir: string;\n /** The underlying PTY process, or `null` if no shell has been spawned yet. */\n pty: PtyProcess | null;\n /** All currently connected WebSocket clients for this session. */\n clients: Set<WS>;\n /** All currently connected event subscribers for this session. */\n subscribers: Set<WS>;\n /** Accumulated PTY output retained for replay when a new client joins. */\n scrollback: string;\n}\n\n/** All active sessions, keyed by session ID. */\nexport const sessionRegistry = new Map<string, Session>();\n\n/** ID of the most recently opened session, used for `GET /` redirect. */\nexport let lastUsedId: string | null = null;\n\n/** Updates {@link lastUsedId}. */\nexport function setLastUsedId(id: string | null): void {\n lastUsedId = id;\n}\n\nconst ID_RE = /^[a-z0-9\\-_.]{1,64}$/;\n\n/**\n * Returns `true` if `id` is a valid session identifier (lowercase alphanumeric + `-_.`, max 64 chars).\n *\n * @param id - The session ID to validate.\n * @returns `true` if the ID matches the valid format, `false` otherwise.\n */\nexport function isValidId(id: string): boolean {\n return ID_RE.test(id);\n}\n\n/**\n * Generates a random 8-character hex session ID.\n *\n * @returns A random session ID.\n */\nexport function generateId(): string {\n return Math.floor(Math.random() * 0xffffffff)\n .toString(16)\n .padStart(8, '0');\n}\n\n/**\n * Creates a new session, registers it in {@link sessionRegistry}, and returns it.\n *\n * @param id - The session ID.\n * @param baseDir - Working directory for the PTY shell (default: `homedir()`).\n * @returns The newly created {@link Session}.\n */\nexport function createSession(id: string, baseDir = homedir()): Session {\n const session: Session = {\n id,\n createdAt: Date.now(),\n baseDir,\n pty: null,\n clients: new Set(),\n subscribers: new Set(),\n scrollback: '',\n };\n sessionRegistry.set(id, session);\n return session;\n}\n\n/**\n * Returns a plain JSON-safe representation of a session for API responses.\n *\n * @param s - The session to serialize.\n * @returns A JSON-safe object with session ID, creation timestamp, connection status, and PTY PID (or `null` if no PTY has been spawned yet).\n */\nexport function sessionToJson(s: Session) {\n return {\n id: s.id,\n createdAt: s.createdAt,\n baseDir: s.baseDir,\n connected: s.clients.size > 0,\n pid: s.pty?.pid ?? null,\n };\n}\n",
|
|
11
12
|
"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\n/** File extension → MIME type map used by {@link serveFile}. */\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\n/**\n * Returns the MIME type for `filePath` based on its extension, defaulting to `application/octet-stream`.\n *\n * @param filePath - The file path to determine the MIME type for.\n * @returns The MIME type string.\n */\nexport function mimeType(filePath: string): string {\n const ext = path.extname(filePath);\n return MIME_TYPES[ext] ?? 'application/octet-stream';\n}\n\n/**\n * Strips the `dist/…` suffix from a ghostty-web main entry path to get the package root.\n *\n * @param mainPath - The main entry path from ghostty-web package.\n * @returns The package root directory path.\n */\nexport function ghosttyWebRootFromMain(mainPath: string): string {\n return mainPath.replace(/[/\\\\]dist[/\\\\].*$/, '');\n}\n\n/**\n * Locates the ghostty-web package, preferring assets bundled in `dist/` (npm install)\n * over `node_modules/` (local dev). Exits the process if the package cannot be found.\n *\n * @returns An object with `distPath` (ghostty-web dist directory) and `wasmPath` (ghostty-vt.wasm file).\n * @throws Exits the process with code 1 if ghostty-web cannot be found.\n */\nexport function findGhosttyWeb(): { distPath: string; wasmPath: string } {\n // Prefer assets bundled into dist/ — present when installed via npx/npm.\n const bundledDist = path.join(__dirname, '..', '..', 'dist');\n const bundledWasm = path.join(bundledDist, 'ghostty-vt.wasm');\n if (fs.existsSync(path.join(bundledDist, 'ghostty-web.js')) && fs.existsSync(bundledWasm)) {\n return { distPath: bundledDist, wasmPath: bundledWasm };\n }\n\n // Fall back to node_modules — present during local development.\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\n/**\n * Reads `filePath` from disk and writes it to `res` with the correct Content-Type header.\n * Responds with 404 if the file cannot be read.\n *\n * @param filePath - The file path to serve.\n * @param res - The HTTP response object.\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
13
|
"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 PTY_NOT_RUNNING: 4002 as const, // app-level: PTY not running\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 for (const sub of session.subscribers) sub.close(code, reason);\n session.subscribers.clear();\n}\n\n/**\n * Closes all WebSocket clients for `session` with the SESSION_GONE close code.\n *\n * @param session - The session to close.\n */\nexport function closeSession(session: Session): void {\n closeClients(session, WS_CLOSE.SESSION_GONE, 'session deleted');\n}\n\n/** Closes all WebSocket clients across every active session with the SERVER_STOPPED close code. */\nexport function closeAllSessions(): void {\n for (const session of sessionRegistry.values()) {\n closeClients(session, WS_CLOSE.SERVER_STOPPED, 'server stopped');\n }\n}\n\n/**\n * Sends `line` to all open event subscribers of `session`.\n *\n * @param session - The session whose subscribers to notify.\n * @param line - The line to send.\n */\nexport function broadcastToSubscribers(session: Session, line: string): void {\n for (const sub of session.subscribers) {\n if (sub.readyState === sub.OPEN) sub.send(line);\n }\n}\n\nlet onLastSessionClosed: (() => void) | null = null;\n\n/**\n * Registers a callback invoked once the last session closes (e.g. to stop the HTTP server).\n *\n * @param handler - Callback to invoke when the last session closes.\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\nfunction handleSubscribe(ws: WS, id: string): void {\n const session = sessionRegistry.get(id);\n if (!session) {\n ws.close(WS_CLOSE.SESSION_GONE, 'session deleted');\n return;\n }\n if (session.pty === null) {\n ws.close(WS_CLOSE.PTY_NOT_RUNNING, 'PTY not running');\n return;\n }\n session.subscribers.add(ws);\n ws.on('close', () => {\n session.subscribers.delete(ws);\n });\n ws.on('error', () => {});\n}\n\n/**\n * Attaches a WebSocket server to `httpServer`, handling PTY I/O, session management,\n * scrollback replay, and terminal resize for all `/ws/:id/pty` connections,\n * and event subscriptions for `/ws/:id/events` connections.\n *\n * @param httpServer - The HTTP server to attach the WebSocket server to.\n * @returns The configured {@link WebSocketServer}.\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 (\n url.pathname.match(/^\\/ws\\/([^/]+)\\/pty$/) ||\n url.pathname.match(/^\\/ws\\/([^/]+)\\/events$/)\n ) {\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 ptyMatch = url.pathname.match(/^\\/ws\\/([^/]+)\\/pty$/);\n const eventsMatch = url.pathname.match(/^\\/ws\\/([^/]+)\\/events$/);\n const match = ptyMatch ?? eventsMatch;\n\n if (!match) {\n ws.close();\n return;\n }\n\n let id: string;\n try {\n id = decodeURIComponent(match[1]);\n } catch {\n ws.close(WS_CLOSE.BAD_REQUEST, 'Bad Request');\n return;\n }\n\n if (eventsMatch) {\n handleSubscribe(ws, id);\n return;\n }\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(\n cols,\n rows,\n config.shell,\n config.term,\n config.colorTerm,\n session.baseDir,\n config.env,\n );\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 for (const sub of session.subscribers) {\n if (sub.readyState === sub.OPEN) {\n sub.close(WS_CLOSE.SESSION_GONE, 'shell exited');\n }\n }\n session.subscribers.clear();\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
14
|
"export type { PtyProcess } from './types';\n\n// Bun.Terminal does not implement PTY on Windows (Bun.spawn({ terminal })\n// is a no-op there), so fall back to node-pty on that platform.\n// On all other platforms, prefer Bun.Terminal when running under Bun.\nconst isBun = !!process.versions.bun && process.platform !== 'win32';\nconsole.log(`pty: ${isBun ? 'Bun.Terminal' : 'node-pty'}`);\n\nconst { spawn: _spawn } = await (isBun ? import('./bun') : import('./node'));\n\nexport const spawn = _spawn;\n\n/**\n * Convenience wrapper: spawns a PTY using session-oriented parameters from config.\n *\n * @param cols - Terminal width in columns.\n * @param rows - Terminal height in rows.\n * @param shell - Shell executable path (e.g., `/bin/bash`).\n * @param term - `$TERM` environment variable (e.g., `xterm-256color`).\n * @param colorTerm - `$COLORTERM` environment variable (e.g., `truecolor`).\n * @param cwd - Working directory for the shell.\n * @returns A {@link PtyProcess} handle for reading/writing and managing the PTY.\n */\nexport function spawnForSession(\n cols: number,\n rows: number,\n shell: string,\n term: string,\n colorTerm: string,\n cwd: string,\n env: Record<string, string>,\n) {\n return _spawn(shell, cols, rows, term, colorTerm, cwd, env);\n}\n"
|
|
14
15
|
],
|
|
15
|
-
"mappings": "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",
|
|
16
|
-
"debugId": "
|
|
16
|
+
"mappings": "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",
|
|
17
|
+
"debugId": "D3126F60C301FB1264756E2164756E21",
|
|
17
18
|
"names": []
|
|
18
19
|
}
|