coderaft 0.0.23 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -243,6 +243,14 @@ interface CodeServerHandle {
243
243
  | `--force-disable-user-env` | Force disable user shell env resolution |
244
244
  | `--force-user-env` | Force user shell env resolution |
245
245
 
246
+ ### Other
247
+
248
+ | Option | Description |
249
+ | ------------ | ------------------------------------------------------ |
250
+ | `--no-fork` | Run server in the main process (no subprocess) |
251
+ | `--no-tui` | Disable interactive terminal UI (alt screen with logs) |
252
+ | `-o, --open` | Open in browser on startup |
253
+
246
254
  ### Debugging
247
255
 
248
256
  | Option | Description |
package/code.mjs CHANGED
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
6
6
  // Auto-updated by scripts/pack.ts
7
- const codeArchiveHash = "4578b0a8f19e8531";
7
+ const codeArchiveHash = "096c26773369f84b";
8
8
 
9
9
  const archivePath = fileURLToPath(new URL("./code.tar.zst", import.meta.url));
10
10
 
package/code.tar.zst CHANGED
Binary file
@@ -0,0 +1,217 @@
1
+ const cliOptions = {
2
+ port: {
3
+ type: "string",
4
+ short: "p"
5
+ },
6
+ host: {
7
+ type: "string",
8
+ short: "H"
9
+ },
10
+ "base-url": { type: "string" },
11
+ "server-base-path": { type: "string" },
12
+ "socket-path": { type: "string" },
13
+ "print-startup-performance": { type: "boolean" },
14
+ token: {
15
+ type: "string",
16
+ short: "t"
17
+ },
18
+ "connection-token": { type: "string" },
19
+ "connection-token-file": { type: "string" },
20
+ "without-connection-token": { type: "boolean" },
21
+ auth: { type: "string" },
22
+ "github-auth": { type: "string" },
23
+ "default-folder": { type: "string" },
24
+ "default-workspace": { type: "string" },
25
+ locale: { type: "string" },
26
+ "server-data-dir": { type: "string" },
27
+ "user-data-dir": { type: "string" },
28
+ "extensions-dir": { type: "string" },
29
+ "extensions-download-dir": { type: "string" },
30
+ "builtin-extensions-dir": { type: "string" },
31
+ "agent-plugins-dir": { type: "string" },
32
+ log: {
33
+ type: "string",
34
+ multiple: true
35
+ },
36
+ "logs-path": { type: "string" },
37
+ "disable-websocket-compression": { type: "boolean" },
38
+ "use-host-proxy": { type: "boolean" },
39
+ "disable-file-downloads": { type: "boolean" },
40
+ "disable-file-uploads": { type: "boolean" },
41
+ "file-watcher-polling": { type: "string" },
42
+ "telemetry-level": { type: "string" },
43
+ "disable-telemetry": { type: "boolean" },
44
+ "disable-update-check": { type: "boolean" },
45
+ "disable-experiments": { type: "boolean" },
46
+ "enable-sync": { type: "boolean" },
47
+ "disable-extensions": { type: "boolean" },
48
+ "disable-extension": {
49
+ type: "string",
50
+ multiple: true
51
+ },
52
+ "enable-proposed-api": {
53
+ type: "string",
54
+ multiple: true
55
+ },
56
+ "disable-workspace-trust": { type: "boolean" },
57
+ "disable-getting-started-override": { type: "boolean" },
58
+ "enable-remote-auto-shutdown": { type: "boolean" },
59
+ "remote-auto-shutdown-without-delay": { type: "boolean" },
60
+ "without-browser-env-var": { type: "boolean" },
61
+ "reconnection-grace-time": { type: "string" },
62
+ "agent-host-path": { type: "string" },
63
+ "agent-host-port": { type: "string" },
64
+ "inspect-ptyhost": { type: "string" },
65
+ "inspect-brk-ptyhost": { type: "string" },
66
+ "inspect-agenthost": { type: "string" },
67
+ "inspect-brk-agenthost": { type: "string" },
68
+ "enable-smoke-test-driver": { type: "boolean" },
69
+ "crash-reporter-directory": { type: "string" },
70
+ "crash-reporter-id": { type: "string" },
71
+ "force-disable-user-env": { type: "boolean" },
72
+ "force-user-env": { type: "boolean" },
73
+ "no-fork": { type: "boolean" },
74
+ "no-tui": { type: "boolean" },
75
+ open: {
76
+ type: "boolean",
77
+ short: "o"
78
+ },
79
+ help: {
80
+ type: "boolean",
81
+ short: "h"
82
+ }
83
+ };
84
+ const vsKeys = [
85
+ "server-base-path",
86
+ "print-startup-performance",
87
+ "connection-token-file",
88
+ "without-connection-token",
89
+ "auth",
90
+ "github-auth",
91
+ "default-workspace",
92
+ "locale",
93
+ "server-data-dir",
94
+ "user-data-dir",
95
+ "extensions-dir",
96
+ "extensions-download-dir",
97
+ "builtin-extensions-dir",
98
+ "agent-plugins-dir",
99
+ "log",
100
+ "file-watcher-polling",
101
+ "disable-websocket-compression",
102
+ "use-host-proxy",
103
+ "disable-file-downloads",
104
+ "disable-file-uploads",
105
+ "telemetry-level",
106
+ "disable-telemetry",
107
+ "disable-update-check",
108
+ "disable-experiments",
109
+ "enable-sync",
110
+ "disable-extensions",
111
+ "disable-extension",
112
+ "enable-proposed-api",
113
+ "disable-workspace-trust",
114
+ "disable-getting-started-override",
115
+ "enable-remote-auto-shutdown",
116
+ "remote-auto-shutdown-without-delay",
117
+ "without-browser-env-var",
118
+ "reconnection-grace-time",
119
+ "agent-host-path",
120
+ "agent-host-port",
121
+ "inspect-ptyhost",
122
+ "inspect-brk-ptyhost",
123
+ "inspect-agenthost",
124
+ "inspect-brk-agenthost",
125
+ "enable-smoke-test-driver",
126
+ "crash-reporter-directory",
127
+ "crash-reporter-id",
128
+ "force-disable-user-env",
129
+ "force-user-env"
130
+ ];
131
+ const helpText = `
132
+ Usage: coderaft [options]
133
+
134
+ Server:
135
+ -p, --port <port> Port to listen on (default: $PORT or 6063)
136
+ -H, --host <host> Host/interface to bind
137
+ --base-url <path> Base URL the server is mounted under (default: /)
138
+ --socket-path <path> Path to a socket file to listen on
139
+ --print-startup-performance Print startup timing to stdout
140
+
141
+ Auth:
142
+ -t, --token <token> Connection token for auth (shorthand)
143
+ --connection-token <token> Connection token for auth (auto-generated)
144
+ --connection-token-file <path> Path to file containing connection token
145
+ --without-connection-token Disable connection token auth
146
+ --auth <type> Auth type
147
+ --github-auth <token> GitHub auth token
148
+
149
+ Defaults:
150
+ --default-folder <path> Default workspace folder
151
+ --default-workspace <path> Default workspace file
152
+ --locale <locale> The locale to use (e.g. en-US)
153
+
154
+ Data:
155
+ --server-data-dir <path> Server data directory
156
+ --user-data-dir <path> User data directory
157
+ --extensions-dir <path> Extensions directory
158
+ --extensions-download-dir <path> Extensions download directory
159
+ --builtin-extensions-dir <path> Built-in extensions directory
160
+ --agent-plugins-dir <path> Agent plugins directory
161
+
162
+ Logging:
163
+ --log <level> Log level (off, critical, error, warn, info, debug, trace)
164
+ --logs-path <path> Logs output directory
165
+
166
+ Network:
167
+ --disable-websocket-compression Disable WebSocket compression
168
+ --use-host-proxy Enable host proxy
169
+
170
+ Files:
171
+ --disable-file-downloads Disable file downloads
172
+ --disable-file-uploads Disable file uploads
173
+ --file-watcher-polling <ms> File watcher polling interval
174
+
175
+ Telemetry:
176
+ --telemetry-level <level> Telemetry level (off, crash, error, all)
177
+ --disable-telemetry Disable telemetry
178
+ --disable-update-check Disable update check
179
+ --disable-experiments Disable experiments
180
+
181
+ Features:
182
+ --enable-sync Enable settings sync
183
+ --disable-extensions Disable all installed extensions
184
+ --disable-extension <ext-id> Disable specific extension (repeatable)
185
+ --enable-proposed-api <ext-id> Enable proposed API for extension (repeatable)
186
+ --disable-workspace-trust Disable workspace trust
187
+ --disable-getting-started-override Disable getting started override
188
+
189
+ Remote:
190
+ --enable-remote-auto-shutdown Enable remote auto shutdown
191
+ --remote-auto-shutdown-without-delay Auto shutdown without delay
192
+ --without-browser-env-var Disable browser env var
193
+ --reconnection-grace-time <sec> Reconnection grace time (default: 10800)
194
+
195
+ Agent Host:
196
+ --agent-host-path <path> Agent host WebSocket socket path
197
+ --agent-host-port <port> Agent host WebSocket port
198
+
199
+ Shell:
200
+ --force-disable-user-env Force disable user shell env resolution
201
+ --force-user-env Force user shell env resolution
202
+
203
+ Debugging:
204
+ --inspect-ptyhost <port> Inspect pty host
205
+ --inspect-brk-ptyhost <port> Inspect pty host (break on start)
206
+ --inspect-agenthost <port> Inspect agent host
207
+ --inspect-brk-agenthost <port> Inspect agent host (break on start)
208
+ --enable-smoke-test-driver Enable smoke test driver
209
+ --crash-reporter-directory <dir> Crash reporter directory
210
+ --crash-reporter-id <id> Crash reporter ID
211
+
212
+ --no-fork Run server in the main process (no subprocess)
213
+ --no-tui Disable interactive terminal UI
214
+ -o, --open Open in browser on startup
215
+ -h, --help Show this help message
216
+ `;
217
+ export { cliOptions, helpText, vsKeys };
@@ -1,3 +1,13 @@
1
1
  import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
2
12
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
- export { __require as t };
13
+ export { __require as n, __exportAll as t };
@@ -1,4 +1,4 @@
1
- import { t as __require } from "./rolldown-runtime.mjs";
1
+ import { n as __require, t as __exportAll } from "./rolldown-runtime.mjs";
2
2
  import { t as createProxyServer } from "./libs/httpxy.mjs";
3
3
  import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import { createReadStream, readFileSync, readdirSync, unlinkSync } from "node:fs";
@@ -123,6 +123,10 @@ async function serveStatic(res, root, relPath) {
123
123
  return false;
124
124
  }
125
125
  }
126
+ var server_exports = /* @__PURE__ */ __exportAll({
127
+ createCodeServer: () => createCodeServer,
128
+ startCodeServer: () => startCodeServer
129
+ });
126
130
  const _os = process.getBuiltinModule?.("os") ?? __require("node:os");
127
131
  const MANIFEST_BODY = JSON.stringify({
128
132
  name: "coderaft",
@@ -405,4 +409,4 @@ function sendJson(res, status, body) {
405
409
  });
406
410
  res.end(payload);
407
411
  }
408
- export { startCodeServer as n, createCodeServer as t };
412
+ export { server_exports as n, startCodeServer as r, createCodeServer as t };
package/dist/cli.mjs CHANGED
@@ -1,260 +1,331 @@
1
1
  #!/usr/bin/env node
2
- import { n as startCodeServer } from "./_chunks/server.mjs";
3
- import { parseArgs } from "node:util";
4
- const { values, positionals } = parseArgs({
5
- allowPositionals: true,
6
- options: {
7
- port: {
8
- type: "string",
9
- short: "p"
10
- },
11
- host: {
12
- type: "string",
13
- short: "H"
14
- },
15
- "base-url": { type: "string" },
16
- "server-base-path": { type: "string" },
17
- "socket-path": { type: "string" },
18
- "print-startup-performance": { type: "boolean" },
19
- token: {
20
- type: "string",
21
- short: "t"
22
- },
23
- "connection-token": { type: "string" },
24
- "connection-token-file": { type: "string" },
25
- "without-connection-token": { type: "boolean" },
26
- auth: { type: "string" },
27
- "github-auth": { type: "string" },
28
- "default-folder": { type: "string" },
29
- "default-workspace": { type: "string" },
30
- locale: { type: "string" },
31
- "server-data-dir": { type: "string" },
32
- "user-data-dir": { type: "string" },
33
- "extensions-dir": { type: "string" },
34
- "extensions-download-dir": { type: "string" },
35
- "builtin-extensions-dir": { type: "string" },
36
- "agent-plugins-dir": { type: "string" },
37
- log: {
38
- type: "string",
39
- multiple: true
40
- },
41
- "logs-path": { type: "string" },
42
- "disable-websocket-compression": { type: "boolean" },
43
- "use-host-proxy": { type: "boolean" },
44
- "disable-file-downloads": { type: "boolean" },
45
- "disable-file-uploads": { type: "boolean" },
46
- "file-watcher-polling": { type: "string" },
47
- "telemetry-level": { type: "string" },
48
- "disable-telemetry": { type: "boolean" },
49
- "disable-update-check": { type: "boolean" },
50
- "disable-experiments": { type: "boolean" },
51
- "enable-sync": { type: "boolean" },
52
- "disable-extensions": { type: "boolean" },
53
- "disable-extension": {
54
- type: "string",
55
- multiple: true
56
- },
57
- "enable-proposed-api": {
58
- type: "string",
59
- multiple: true
2
+ import { exec, fork } from "node:child_process";
3
+ const BANNER_PLAIN = `
4
+ ▄█████ ▄▄▄ ▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄
5
+ ██ ██▀██ ██▀██ ██▄▄ ██▄█▄ ██▀██ ██▄▄ ██
6
+ ▀█████ ▀███▀ ████▀ ██▄▄▄ ██ ██ ██▀██ ██ ██
7
+ `;
8
+ function gradientBanner(text) {
9
+ const colors = [
10
+ [
11
+ 0,
12
+ 210,
13
+ 255
14
+ ],
15
+ [
16
+ 0,
17
+ 150,
18
+ 255
19
+ ],
20
+ [
21
+ 120,
22
+ 80,
23
+ 255
24
+ ],
25
+ [
26
+ 200,
27
+ 50,
28
+ 255
29
+ ]
30
+ ];
31
+ return text.split("\n").map((line) => {
32
+ if (line.trim().length === 0) return line;
33
+ let result = "";
34
+ for (let i = 0; i < line.length; i++) {
35
+ const segment = (line.length > 1 ? i / (line.length - 1) : 0) * (colors.length - 1);
36
+ const idx = Math.min(Math.floor(segment), colors.length - 2);
37
+ const local = segment - idx;
38
+ const c0 = colors[idx];
39
+ const c1 = colors[idx + 1];
40
+ const r = Math.round(c0[0] + (c1[0] - c0[0]) * local);
41
+ const g = Math.round(c0[1] + (c1[1] - c0[1]) * local);
42
+ const b = Math.round(c0[2] + (c1[2] - c0[2]) * local);
43
+ result += `\x1b[38;2;${r};${g};${b}m${line[i]}`;
44
+ }
45
+ return result + "\x1B[0m";
46
+ }).join("\n");
47
+ }
48
+ const BANNER = gradientBanner(BANNER_PLAIN);
49
+ const BANNER_LINES = BANNER.split("\n").length;
50
+ function createTUI(HEADER_LINES, opts) {
51
+ const c = {
52
+ cyan: "\x1B[36m",
53
+ bold: "\x1B[1m",
54
+ dim: "\x1B[2m",
55
+ reset: "\x1B[0m",
56
+ yellow: "\x1B[33m",
57
+ red: "\x1B[31m"
58
+ };
59
+ const logBuffer = [];
60
+ const maxBuffer = 5e3;
61
+ let scrollOffset = 0;
62
+ let url = "";
63
+ let rendering = false;
64
+ let stats = { rss: 0 };
65
+ let startedAt = 0;
66
+ const origStdoutWrite = process.stdout.write.bind(process.stdout);
67
+ const write = (s) => origStdoutWrite(s);
68
+ const origConsoleLog = console.log;
69
+ const origConsoleError = console.error;
70
+ const origConsoleWarn = console.warn;
71
+ write("\x1B[?1049h\x1B[2J\x1B[H\x1B[?25l");
72
+ let destroyed = false;
73
+ const destroy = () => {
74
+ if (destroyed) return;
75
+ destroyed = true;
76
+ process.stdout.write = origStdoutWrite;
77
+ console.log = origConsoleLog;
78
+ console.error = origConsoleError;
79
+ console.warn = origConsoleWarn;
80
+ if (process.stdin.isTTY) process.stdin.setRawMode(false);
81
+ write("\x1B[?25h\x1B[?1049l");
82
+ const lines = [BANNER, ""];
83
+ if (url) {
84
+ let status = ` ${c.bold}\x1b[31m●${c.reset} ${c.cyan}${url}${c.reset}`;
85
+ const rss = stats.rss || 0;
86
+ if (rss > 0) status += ` ${c.dim}▪ mem ${(rss / 1024 / 1024).toFixed(0)} MB${c.reset}`;
87
+ if (startedAt) status += ` ${c.dim}▴ up ${formatUptime(Date.now() - startedAt)}${c.reset}`;
88
+ lines.push(status);
89
+ }
90
+ if (lines.length > 0) write(`\n${lines.join("\n")}\n\n`);
91
+ };
92
+ const addLines = (text) => {
93
+ const lines = text.split("\n");
94
+ const added = lines.length;
95
+ for (const line of lines) logBuffer.push(line);
96
+ while (logBuffer.length > maxBuffer) logBuffer.shift();
97
+ if (scrollOffset > 0) {
98
+ const logRows = (process.stdout.rows || 24) - HEADER_LINES;
99
+ const maxOffset = Math.max(0, logBuffer.length - logRows);
100
+ scrollOffset = Math.min(maxOffset, scrollOffset + added);
101
+ }
102
+ scheduleRender();
103
+ };
104
+ const format = (...args) => args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
105
+ console.log = (...args) => addLines(format(...args));
106
+ console.error = (...args) => addLines(format(...args));
107
+ console.warn = (...args) => addLines(`${c.yellow}${format(...args)}${c.reset}`);
108
+ process.stdout.write = ((chunk, ...rest) => {
109
+ const str = typeof chunk === "string" ? chunk : chunk.toString();
110
+ if (rendering) return origStdoutWrite(chunk, ...rest);
111
+ addLines(str.replace(/\n$/, ""));
112
+ return true;
113
+ });
114
+ let renderTimer;
115
+ function scheduleRender() {
116
+ if (renderTimer) return;
117
+ renderTimer = setTimeout(() => {
118
+ renderTimer = void 0;
119
+ render();
120
+ }, 16);
121
+ }
122
+ function render() {
123
+ rendering = true;
124
+ const rows = process.stdout.rows || 24;
125
+ const cols = process.stdout.columns || 80;
126
+ const logRows = rows - HEADER_LINES;
127
+ if (logRows <= 0) {
128
+ rendering = false;
129
+ return;
130
+ }
131
+ const end = logBuffer.length - scrollOffset;
132
+ const start = Math.max(0, end - logRows);
133
+ const visible = logBuffer.slice(start, end);
134
+ let out = "\x1B[H";
135
+ const mem = `${((stats.rss || process.memoryUsage.rss()) / 1024 / 1024).toFixed(0)} MB`;
136
+ const sep = c.dim + "─".repeat(cols) + c.reset;
137
+ for (const line of BANNER.split("\n")) out += `\x1b[2K${line}\n`;
138
+ out += `\x1b[2K\n`;
139
+ if (url) {
140
+ let status = ` ${c.bold}\x1b[32m●${c.reset} ${c.cyan}${url}${c.reset}`;
141
+ status += ` ${c.dim}▪ mem ${mem}${c.reset}`;
142
+ if (startedAt) status += ` ${c.dim}▴ up ${formatUptime(Date.now() - startedAt)}${c.reset}`;
143
+ if (scrollOffset > 0) status += ` ${c.yellow}↑ ${scrollOffset}${c.reset}`;
144
+ out += `\x1b[2K${status}\n`;
145
+ if (opts?.onOpen) out += `\x1b[2K ${c.dim}press ${c.reset}${c.bold}enter${c.reset}${c.dim} to open ${c.reset}${c.bold}q${c.reset}${c.dim} to quit${c.reset}\n`;
146
+ } else out += `\x1b[2K ${c.dim}○ Starting...${c.reset}\n`;
147
+ out += `\x1b[2K${sep}\n`;
148
+ for (let i = 0; i < logRows; i++) out += `\x1b[2K${visible[i] ?? ""}\n`;
149
+ write(out);
150
+ rendering = false;
151
+ }
152
+ if (process.stdin.isTTY) {
153
+ process.stdin.setRawMode(true);
154
+ process.stdin.resume();
155
+ process.stdin.on("data", (data) => {
156
+ const key = data.toString();
157
+ const logRows = (process.stdout.rows || 24) - HEADER_LINES;
158
+ const maxOffset = Math.max(0, logBuffer.length - logRows);
159
+ if (key === "\x1B[A" || key === "k") {
160
+ scrollOffset = Math.min(maxOffset, scrollOffset + 1);
161
+ render();
162
+ } else if (key === "\x1B[B" || key === "j") {
163
+ scrollOffset = Math.max(0, scrollOffset - 1);
164
+ render();
165
+ } else if (key === "\x1B[5~") {
166
+ scrollOffset = Math.min(maxOffset, scrollOffset + logRows);
167
+ render();
168
+ } else if (key === "\x1B[6~") {
169
+ scrollOffset = Math.max(0, scrollOffset - logRows);
170
+ render();
171
+ } else if (key === "g") {
172
+ scrollOffset = maxOffset;
173
+ render();
174
+ } else if (key === "G") {
175
+ scrollOffset = 0;
176
+ render();
177
+ } else if (key === "\r" && url && opts?.onOpen) opts.onOpen();
178
+ else if (key === "q" || key === "") process.kill(process.pid, "SIGINT");
179
+ });
180
+ }
181
+ process.stdout.on("resize", () => render());
182
+ render();
183
+ let refreshInterval;
184
+ return {
185
+ setURL(u) {
186
+ url = u;
187
+ startedAt = Date.now();
188
+ render();
189
+ refreshInterval = setInterval(() => scheduleRender(), 2e3);
190
+ refreshInterval.unref();
60
191
  },
61
- "disable-workspace-trust": { type: "boolean" },
62
- "disable-getting-started-override": { type: "boolean" },
63
- "enable-remote-auto-shutdown": { type: "boolean" },
64
- "remote-auto-shutdown-without-delay": { type: "boolean" },
65
- "without-browser-env-var": { type: "boolean" },
66
- "reconnection-grace-time": { type: "string" },
67
- "agent-host-path": { type: "string" },
68
- "agent-host-port": { type: "string" },
69
- "inspect-ptyhost": { type: "string" },
70
- "inspect-brk-ptyhost": { type: "string" },
71
- "inspect-agenthost": { type: "string" },
72
- "inspect-brk-agenthost": { type: "string" },
73
- "enable-smoke-test-driver": { type: "boolean" },
74
- "crash-reporter-directory": { type: "string" },
75
- "crash-reporter-id": { type: "string" },
76
- "force-disable-user-env": { type: "boolean" },
77
- "force-user-env": { type: "boolean" },
78
- open: {
79
- type: "boolean",
80
- short: "o"
192
+ setStats(s) {
193
+ stats = s;
81
194
  },
82
- help: {
83
- type: "boolean",
84
- short: "h"
195
+ destroy() {
196
+ if (refreshInterval) clearInterval(refreshInterval);
197
+ destroy();
198
+ }
199
+ };
200
+ }
201
+ function formatUptime(ms) {
202
+ const s = Math.floor(ms / 1e3);
203
+ if (s < 60) return `${s}s`;
204
+ const m = Math.floor(s / 60);
205
+ if (m < 60) return `${m}m ${s % 60}s`;
206
+ return `${Math.floor(m / 60)}h ${m % 60}m`;
207
+ }
208
+ if (process.argv.includes("--worker")) startWorker();
209
+ else startMain();
210
+ function startWorker() {
211
+ process.on("message", async (msg) => {
212
+ if (msg.type === "start") {
213
+ const { startCodeServer } = await import("./_chunks/server.mjs").then((n) => n.n);
214
+ const handle = await startCodeServer(msg.opts);
215
+ process.send({
216
+ type: "ready",
217
+ url: handle.url,
218
+ connectionToken: handle.connectionToken,
219
+ port: handle.port,
220
+ socketPath: handle.socketPath
221
+ });
222
+ }
223
+ });
224
+ }
225
+ async function startMain() {
226
+ const { parseArgs } = await import("node:util");
227
+ const { cliOptions, vsKeys, helpText } = await import("./_chunks/_args.mjs");
228
+ const { values, positionals } = parseArgs({
229
+ allowPositionals: true,
230
+ options: cliOptions,
231
+ strict: true
232
+ });
233
+ if (values.help) {
234
+ console.log(helpText);
235
+ process.exit(0);
236
+ }
237
+ const vscode = {};
238
+ for (const key of vsKeys) if (values[key] !== void 0) vscode[key] = values[key];
239
+ if (values["logs-path"]) vscode.logsPath = values["logs-path"];
240
+ const dir = positionals[0];
241
+ if (dir) vscode["disable-workspace-trust"] = true;
242
+ const opts = {
243
+ port: values.port ? Number(values.port) : void 0,
244
+ host: values.host,
245
+ socketPath: values["socket-path"],
246
+ baseURL: values["base-url"] ?? values["server-base-path"],
247
+ defaultFolder: dir || values["default-folder"],
248
+ connectionToken: values["connection-token"] ?? values.token,
249
+ vscode
250
+ };
251
+ const interactive = process.stdout.isTTY && !values["no-tui"];
252
+ const HEADER_LINES = BANNER_LINES + 4;
253
+ let tui;
254
+ let serverURL = "";
255
+ if (interactive) tui = createTUI(HEADER_LINES, { onOpen: () => {
256
+ if (serverURL) openBrowser(serverURL);
257
+ } });
258
+ process.on("exit", () => tui?.destroy());
259
+ if (values["no-fork"]) {
260
+ const { startCodeServer } = await import("./_chunks/server.mjs").then((n) => n.n);
261
+ let handle;
262
+ let shuttingDown = false;
263
+ const shutdown = () => {
264
+ tui?.destroy();
265
+ if (shuttingDown) process.exit(0);
266
+ shuttingDown = true;
267
+ setTimeout(() => process.exit(0), 3e3).unref();
268
+ if (handle) handle.close().finally(() => process.exit(0));
269
+ else process.exit(0);
270
+ };
271
+ process.on("SIGINT", shutdown);
272
+ process.on("SIGTERM", shutdown);
273
+ handle = await startCodeServer(opts);
274
+ onReady(handle.url);
275
+ } else {
276
+ const child = fork(process.argv[1], ["--worker"], {
277
+ stdio: [
278
+ "ignore",
279
+ "pipe",
280
+ "pipe",
281
+ "ipc"
282
+ ],
283
+ env: {
284
+ ...process.env,
285
+ FORCE_COLOR: "1"
286
+ }
287
+ });
288
+ child.stdout.on("data", (chunk) => process.stdout.write(chunk));
289
+ child.stderr.on("data", (chunk) => console.error(chunk.toString()));
290
+ let shuttingDown = false;
291
+ const shutdown = () => {
292
+ tui?.destroy();
293
+ if (shuttingDown) process.exit(0);
294
+ shuttingDown = true;
295
+ child.kill("SIGTERM");
296
+ setTimeout(() => process.exit(0), 5e3).unref();
297
+ };
298
+ process.on("SIGINT", shutdown);
299
+ process.on("SIGTERM", shutdown);
300
+ child.on("exit", (code) => {
301
+ process.exit(code ?? 1);
302
+ });
303
+ child.send({
304
+ type: "start",
305
+ opts
306
+ });
307
+ child.on("message", (msg) => {
308
+ if (msg.type === "ready") onReady(msg.url);
309
+ });
310
+ }
311
+ function onReady(url) {
312
+ serverURL = url;
313
+ if (values.open) openBrowser(url);
314
+ if (tui) {
315
+ tui.setURL(url);
316
+ return;
85
317
  }
86
- },
87
- strict: true
88
- });
89
- if (values.help) {
90
- console.log(`
91
- Usage: coderaft [options]
92
-
93
- Server:
94
- -p, --port <port> Port to listen on (default: $PORT or 6063)
95
- -H, --host <host> Host/interface to bind
96
- --base-url <path> Base URL the server is mounted under (default: /)
97
- --socket-path <path> Path to a socket file to listen on
98
- --print-startup-performance Print startup timing to stdout
99
-
100
- Auth:
101
- -t, --token <token> Connection token for auth (shorthand)
102
- --connection-token <token> Connection token for auth (auto-generated)
103
- --connection-token-file <path> Path to file containing connection token
104
- --without-connection-token Disable connection token auth
105
- --auth <type> Auth type
106
- --github-auth <token> GitHub auth token
107
-
108
- Defaults:
109
- --default-folder <path> Default workspace folder
110
- --default-workspace <path> Default workspace file
111
- --locale <locale> The locale to use (e.g. en-US)
112
-
113
- Data:
114
- --server-data-dir <path> Server data directory
115
- --user-data-dir <path> User data directory
116
- --extensions-dir <path> Extensions directory
117
- --extensions-download-dir <path> Extensions download directory
118
- --builtin-extensions-dir <path> Built-in extensions directory
119
- --agent-plugins-dir <path> Agent plugins directory
120
-
121
- Logging:
122
- --log <level> Log level (off, critical, error, warn, info, debug, trace)
123
- --logs-path <path> Logs output directory
124
-
125
- Network:
126
- --disable-websocket-compression Disable WebSocket compression
127
- --use-host-proxy Enable host proxy
128
-
129
- Files:
130
- --disable-file-downloads Disable file downloads
131
- --disable-file-uploads Disable file uploads
132
- --file-watcher-polling <ms> File watcher polling interval
133
-
134
- Telemetry:
135
- --telemetry-level <level> Telemetry level (off, crash, error, all)
136
- --disable-telemetry Disable telemetry
137
- --disable-update-check Disable update check
138
- --disable-experiments Disable experiments
139
-
140
- Features:
141
- --enable-sync Enable settings sync
142
- --disable-extensions Disable all installed extensions
143
- --disable-extension <ext-id> Disable specific extension (repeatable)
144
- --enable-proposed-api <ext-id> Enable proposed API for extension (repeatable)
145
- --disable-workspace-trust Disable workspace trust
146
- --disable-getting-started-override Disable getting started override
147
-
148
- Remote:
149
- --enable-remote-auto-shutdown Enable remote auto shutdown
150
- --remote-auto-shutdown-without-delay Auto shutdown without delay
151
- --without-browser-env-var Disable browser env var
152
- --reconnection-grace-time <sec> Reconnection grace time (default: 10800)
153
-
154
- Agent Host:
155
- --agent-host-path <path> Agent host WebSocket socket path
156
- --agent-host-port <port> Agent host WebSocket port
157
-
158
- Shell:
159
- --force-disable-user-env Force disable user shell env resolution
160
- --force-user-env Force user shell env resolution
161
-
162
- Debugging:
163
- --inspect-ptyhost <port> Inspect pty host
164
- --inspect-brk-ptyhost <port> Inspect pty host (break on start)
165
- --inspect-agenthost <port> Inspect agent host
166
- --inspect-brk-agenthost <port> Inspect agent host (break on start)
167
- --enable-smoke-test-driver Enable smoke test driver
168
- --crash-reporter-directory <dir> Crash reporter directory
169
- --crash-reporter-id <id> Crash reporter ID
170
-
171
- -o, --open Open in browser on startup
172
- -h, --help Show this help message
173
- `);
174
- process.exit(0);
318
+ const c = {
319
+ cyan: "\x1B[36m",
320
+ bold: "\x1B[1m",
321
+ dim: "\x1B[2m",
322
+ reset: "\x1B[0m"
323
+ };
324
+ const mem = `${(process.memoryUsage.rss() / 1024 / 1024).toFixed(0)} MB`;
325
+ console.log(`\n${BANNER}\n\n ${c.bold}${c.cyan}➜${c.reset} ${c.bold}Ready${c.reset} ${c.dim}at${c.reset} ${c.cyan}${url}${c.reset}\n ${c.bold}${c.cyan}➜${c.reset} ${c.bold}Memory${c.reset} ${c.dim}${mem}${c.reset}\n`);
326
+ }
175
327
  }
176
- const vscode = {};
177
- for (const key of [
178
- "server-base-path",
179
- "print-startup-performance",
180
- "connection-token-file",
181
- "without-connection-token",
182
- "auth",
183
- "github-auth",
184
- "default-workspace",
185
- "locale",
186
- "server-data-dir",
187
- "user-data-dir",
188
- "extensions-dir",
189
- "extensions-download-dir",
190
- "builtin-extensions-dir",
191
- "agent-plugins-dir",
192
- "log",
193
- "file-watcher-polling",
194
- "disable-websocket-compression",
195
- "use-host-proxy",
196
- "disable-file-downloads",
197
- "disable-file-uploads",
198
- "telemetry-level",
199
- "disable-telemetry",
200
- "disable-update-check",
201
- "disable-experiments",
202
- "enable-sync",
203
- "disable-extensions",
204
- "disable-extension",
205
- "enable-proposed-api",
206
- "disable-workspace-trust",
207
- "disable-getting-started-override",
208
- "enable-remote-auto-shutdown",
209
- "remote-auto-shutdown-without-delay",
210
- "without-browser-env-var",
211
- "reconnection-grace-time",
212
- "agent-host-path",
213
- "agent-host-port",
214
- "inspect-ptyhost",
215
- "inspect-brk-ptyhost",
216
- "inspect-agenthost",
217
- "inspect-brk-agenthost",
218
- "enable-smoke-test-driver",
219
- "crash-reporter-directory",
220
- "crash-reporter-id",
221
- "force-disable-user-env",
222
- "force-user-env"
223
- ]) if (values[key] !== void 0) vscode[key] = values[key];
224
- if (values["logs-path"]) vscode.logsPath = values["logs-path"];
225
- const dir = positionals[0];
226
- if (dir) vscode["disable-workspace-trust"] = true;
227
- let handle;
228
- let shuttingDown = false;
229
- const shutdown = () => {
230
- if (shuttingDown) process.exit(0);
231
- shuttingDown = true;
232
- setTimeout(() => process.exit(0), 3e3).unref();
233
- if (handle) handle.close().finally(() => process.exit(0));
234
- else process.exit(0);
235
- };
236
- process.on("SIGINT", shutdown);
237
- process.on("SIGTERM", shutdown);
238
- handle = await startCodeServer({
239
- port: values.port ? Number(values.port) : void 0,
240
- host: values.host,
241
- socketPath: values["socket-path"],
242
- baseURL: values["base-url"] ?? values["server-base-path"],
243
- defaultFolder: dir || values["default-folder"],
244
- connectionToken: values["connection-token"] ?? values.token,
245
- vscode
246
- });
247
- const c = {
248
- cyan: "\x1B[36m",
249
- bold: "\x1B[1m",
250
- dim: "\x1B[2m",
251
- reset: "\x1B[0m"
252
- };
253
- const mem = `${(process.memoryUsage.rss() / 1024 / 1024).toFixed(0)} MB`;
254
- console.log(`\n ${c.bold}${c.cyan}➜${c.reset} ${c.bold}Ready${c.reset} ${c.dim}at${c.reset} ${c.cyan}${handle.url}${c.reset}\n ${c.bold}${c.cyan}➜${c.reset} ${c.bold}Memory${c.reset} ${c.dim}${mem}${c.reset}\n`);
255
- if (values.open) {
256
- const { exec } = await import("node:child_process");
257
- const url = handle.url;
328
+ function openBrowser(url) {
258
329
  const platform = process.platform;
259
330
  if (platform === "darwin") exec(`open -na "Google Chrome" --args --app="${url}" || open -na "Chromium" --args --app="${url}" || open "${url}"`);
260
331
  else if (platform === "win32") exec(`start chrome --app="${url}" || start msedge --app="${url}" || start "" "${url}"`);
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as startCodeServer, t as createCodeServer } from "./_chunks/server.mjs";
1
+ import { r as startCodeServer, t as createCodeServer } from "./_chunks/server.mjs";
2
2
  export { createCodeServer, startCodeServer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coderaft",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "repository": "pithings/coderaft",
5
5
  "bin": {
6
6
  "coderaft": "./dist/cli.mjs"
@@ -1 +0,0 @@
1
- export { };