@privateclaw/privateclaw-relay 0.1.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.
Files changed (42) hide show
  1. package/.env.example +13 -0
  2. package/README.md +86 -0
  3. package/dist/cli-error.d.ts +3 -0
  4. package/dist/cli-error.js +7 -0
  5. package/dist/cli-error.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +14 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/config.d.ts +13 -0
  10. package/dist/config.js +36 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/frame-cache.d.ts +77 -0
  13. package/dist/frame-cache.js +127 -0
  14. package/dist/frame-cache.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.js +5 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/push-notifier.d.ts +36 -0
  19. package/dist/push-notifier.js +198 -0
  20. package/dist/push-notifier.js.map +1 -0
  21. package/dist/push-registration-store.d.ts +39 -0
  22. package/dist/push-registration-store.js +98 -0
  23. package/dist/push-registration-store.js.map +1 -0
  24. package/dist/relay-cli.d.ts +28 -0
  25. package/dist/relay-cli.js +256 -0
  26. package/dist/relay-cli.js.map +1 -0
  27. package/dist/relay-cluster.d.ts +144 -0
  28. package/dist/relay-cluster.js +436 -0
  29. package/dist/relay-cluster.js.map +1 -0
  30. package/dist/relay-server.d.ts +25 -0
  31. package/dist/relay-server.js +1090 -0
  32. package/dist/relay-server.js.map +1 -0
  33. package/dist/session-store.d.ts +40 -0
  34. package/dist/session-store.js +159 -0
  35. package/dist/session-store.js.map +1 -0
  36. package/dist/tunnel-installer.d.ts +36 -0
  37. package/dist/tunnel-installer.js +402 -0
  38. package/dist/tunnel-installer.js.map +1 -0
  39. package/dist/tunnel.d.ts +35 -0
  40. package/dist/tunnel.js +334 -0
  41. package/dist/tunnel.js.map +1 -0
  42. package/package.json +45 -0
@@ -0,0 +1,402 @@
1
+ import { spawn } from "node:child_process";
2
+ import { once } from "node:events";
3
+ import { createInterface } from "node:readline/promises";
4
+ import { stdin, stdout } from "node:process";
5
+ import { RelayCliUserError } from "./cli-error.js";
6
+ import { isUnavailableTunnelBinaryError, } from "./tunnel.js";
7
+ const TAILSCALE_INSTALL_DOCS_URL = "https://tailscale.com/docs/install";
8
+ const CLOUDFLARE_INSTALL_DOCS_URL = "https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/";
9
+ const PACKAGE_MANAGER_PROBES = new Map([
10
+ ["brew", ["--version"]],
11
+ ["curl", ["--version"]],
12
+ ["dnf", ["--version"]],
13
+ ["pacman", ["--version"]],
14
+ ["apt-get", ["--version"]],
15
+ ["sh", ["-c", "exit 0"]],
16
+ ["sudo", ["--version"]],
17
+ ["systemctl", ["--version"]],
18
+ ["winget", ["--version"]],
19
+ ["yum", ["--version"]],
20
+ ]);
21
+ function createStep(title, command, args, display) {
22
+ return {
23
+ title,
24
+ command,
25
+ args,
26
+ display,
27
+ };
28
+ }
29
+ function createShellStep(title, script, display) {
30
+ return createStep(title, "sh", ["-c", script], display);
31
+ }
32
+ function createStepWithOptionalSudo(useSudo, title, command, args, display) {
33
+ if (!useSudo) {
34
+ return createStep(title, command, args, display);
35
+ }
36
+ return createStep(title, "sudo", [command, ...args], `sudo ${display}`);
37
+ }
38
+ function supportsAutomaticInstall(plan) {
39
+ return plan.installStep != null;
40
+ }
41
+ function isInteractiveTerminal() {
42
+ return Boolean(process.stdin.isTTY &&
43
+ process.stdout.isTTY &&
44
+ !process.stdin.destroyed &&
45
+ !process.stdout.destroyed);
46
+ }
47
+ async function commandExists(command) {
48
+ const args = PACKAGE_MANAGER_PROBES.get(command) ?? ["--version"];
49
+ const child = spawn(command, args, {
50
+ stdio: "ignore",
51
+ });
52
+ const childError = once(child, "error").then(([error]) => {
53
+ throw error;
54
+ });
55
+ const childClose = once(child, "close");
56
+ try {
57
+ await Promise.race([childError, childClose]);
58
+ return true;
59
+ }
60
+ catch (error) {
61
+ return !isUnavailableTunnelBinaryError(error);
62
+ }
63
+ }
64
+ async function detectAvailableCommands(commands) {
65
+ const entries = await Promise.all(commands.map(async (command) => [command, await commandExists(command)]));
66
+ return new Set(entries.filter(([, present]) => present).map(([command]) => command));
67
+ }
68
+ export function resolveRelayTunnelDependencyPlan(provider, options = {}) {
69
+ const platform = options.platform ?? process.platform;
70
+ const availableCommands = new Set(options.availableCommands ?? []);
71
+ const isRoot = options.isRoot ??
72
+ (typeof process.getuid === "function" ? process.getuid() === 0 : false);
73
+ const canSudo = isRoot || availableCommands.has("sudo");
74
+ const useSudo = !isRoot && availableCommands.has("sudo");
75
+ if (provider === "tailscale") {
76
+ const docsUrl = TAILSCALE_INSTALL_DOCS_URL;
77
+ if (platform === "darwin") {
78
+ const installStep = availableCommands.has("brew")
79
+ ? createStep("Install Tailscale with Homebrew", "brew", ["install", "tailscale"], "brew install tailscale")
80
+ : undefined;
81
+ const configureSteps = [
82
+ createStepWithOptionalSudo(useSudo, "Start the local Tailscale daemon", "brew", ["services", "start", "tailscale"], "brew services start tailscale"),
83
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
84
+ ];
85
+ return {
86
+ provider,
87
+ binary: "tailscale",
88
+ displayName: "Tailscale CLI",
89
+ docsUrl,
90
+ ...(installStep ? { installStep } : {}),
91
+ configureSteps,
92
+ manualSteps: [
93
+ createStep("Install Tailscale with Homebrew", "brew", ["install", "tailscale"], "brew install tailscale"),
94
+ createStepWithOptionalSudo(useSudo, "Start the local Tailscale daemon", "brew", ["services", "start", "tailscale"], "brew services start tailscale"),
95
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
96
+ ],
97
+ notes: [
98
+ "Tailscale Funnel also requires Funnel to be enabled for your tailnet.",
99
+ ],
100
+ };
101
+ }
102
+ if (platform === "win32") {
103
+ const installStep = availableCommands.has("winget")
104
+ ? createStep("Install Tailscale with winget", "winget", ["install", "--id", "Tailscale.Tailscale", "-e"], "winget install --id Tailscale.Tailscale -e")
105
+ : undefined;
106
+ return {
107
+ provider,
108
+ binary: "tailscale",
109
+ displayName: "Tailscale CLI",
110
+ docsUrl,
111
+ ...(installStep ? { installStep } : {}),
112
+ configureSteps: [
113
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
114
+ ],
115
+ manualSteps: [
116
+ createStep("Install Tailscale with winget", "winget", ["install", "--id", "Tailscale.Tailscale", "-e"], "winget install --id Tailscale.Tailscale -e"),
117
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
118
+ ],
119
+ notes: [
120
+ "Tailscale Funnel also requires Funnel to be enabled for your tailnet.",
121
+ ],
122
+ };
123
+ }
124
+ const installStep = availableCommands.has("curl") && availableCommands.has("sh")
125
+ ? createShellStep("Install Tailscale with the official installer", "curl -fsSL https://tailscale.com/install.sh | sh", "curl -fsSL https://tailscale.com/install.sh | sh")
126
+ : undefined;
127
+ return {
128
+ provider,
129
+ binary: "tailscale",
130
+ displayName: "Tailscale CLI",
131
+ docsUrl,
132
+ ...(installStep ? { installStep } : {}),
133
+ configureSteps: [
134
+ ...(availableCommands.has("systemctl") && canSudo
135
+ ? [
136
+ createStepWithOptionalSudo(useSudo, "Start the local tailscaled service", "systemctl", ["enable", "--now", "tailscaled"], "systemctl enable --now tailscaled"),
137
+ ]
138
+ : []),
139
+ ...(canSudo
140
+ ? [
141
+ createStepWithOptionalSudo(useSudo, "Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
142
+ ]
143
+ : [
144
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
145
+ ]),
146
+ ],
147
+ manualSteps: [
148
+ createShellStep("Install Tailscale with the official installer", "curl -fsSL https://tailscale.com/install.sh | sh", "curl -fsSL https://tailscale.com/install.sh | sh"),
149
+ ...(availableCommands.has("systemctl") && canSudo
150
+ ? [
151
+ createStepWithOptionalSudo(useSudo, "Start the local tailscaled service", "systemctl", ["enable", "--now", "tailscaled"], "systemctl enable --now tailscaled"),
152
+ ]
153
+ : []),
154
+ ...(canSudo
155
+ ? [
156
+ createStepWithOptionalSudo(useSudo, "Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
157
+ ]
158
+ : [
159
+ createStep("Connect this device to your tailnet", "tailscale", ["up"], "tailscale up"),
160
+ ]),
161
+ ],
162
+ notes: [
163
+ "Tailscale Funnel also requires Funnel to be enabled for your tailnet.",
164
+ ],
165
+ };
166
+ }
167
+ const docsUrl = CLOUDFLARE_INSTALL_DOCS_URL;
168
+ if (platform === "darwin") {
169
+ const installStep = availableCommands.has("brew")
170
+ ? createStep("Install cloudflared with Homebrew", "brew", ["install", "cloudflared"], "brew install cloudflared")
171
+ : undefined;
172
+ return {
173
+ provider,
174
+ binary: "cloudflared",
175
+ displayName: "cloudflared",
176
+ docsUrl,
177
+ ...(installStep ? { installStep } : {}),
178
+ configureSteps: [],
179
+ manualSteps: [
180
+ createStep("Install cloudflared with Homebrew", "brew", ["install", "cloudflared"], "brew install cloudflared"),
181
+ ],
182
+ notes: [],
183
+ };
184
+ }
185
+ if (platform === "win32") {
186
+ const installStep = availableCommands.has("winget")
187
+ ? createStep("Install cloudflared with winget", "winget", ["install", "--id", "Cloudflare.cloudflared", "-e"], "winget install --id Cloudflare.cloudflared -e")
188
+ : undefined;
189
+ return {
190
+ provider,
191
+ binary: "cloudflared",
192
+ displayName: "cloudflared",
193
+ docsUrl,
194
+ ...(installStep ? { installStep } : {}),
195
+ configureSteps: [],
196
+ manualSteps: [
197
+ createStep("Install cloudflared with winget", "winget", ["install", "--id", "Cloudflare.cloudflared", "-e"], "winget install --id Cloudflare.cloudflared -e"),
198
+ ],
199
+ notes: [],
200
+ };
201
+ }
202
+ if (availableCommands.has("brew")) {
203
+ return {
204
+ provider,
205
+ binary: "cloudflared",
206
+ displayName: "cloudflared",
207
+ docsUrl,
208
+ installStep: createStep("Install cloudflared with Homebrew", "brew", ["install", "cloudflared"], "brew install cloudflared"),
209
+ configureSteps: [],
210
+ manualSteps: [
211
+ createStep("Install cloudflared with Homebrew", "brew", ["install", "cloudflared"], "brew install cloudflared"),
212
+ ],
213
+ notes: [],
214
+ };
215
+ }
216
+ if (availableCommands.has("pacman") && canSudo) {
217
+ const installStep = createStepWithOptionalSudo(useSudo, "Install cloudflared with pacman", "pacman", ["-Syu", "--needed", "cloudflared"], "pacman -Syu --needed cloudflared");
218
+ return {
219
+ provider,
220
+ binary: "cloudflared",
221
+ displayName: "cloudflared",
222
+ docsUrl,
223
+ installStep,
224
+ configureSteps: [],
225
+ manualSteps: [installStep],
226
+ notes: [],
227
+ };
228
+ }
229
+ if (availableCommands.has("apt-get") && availableCommands.has("curl") && canSudo) {
230
+ const sudoPrefix = useSudo ? "sudo " : "";
231
+ const installDisplay = [
232
+ `${sudoPrefix}mkdir -p --mode=0755 /usr/share/keyrings`,
233
+ `curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | ${sudoPrefix}tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null`,
234
+ `. /etc/os-release && codename="${"${VERSION_CODENAME:-${UBUNTU_CODENAME:-}}"}"`,
235
+ `echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $codename main" | ${sudoPrefix}tee /etc/apt/sources.list.d/cloudflared.list >/dev/null`,
236
+ `${sudoPrefix}apt-get update`,
237
+ `${sudoPrefix}apt-get install -y cloudflared`,
238
+ ].join(" && ");
239
+ const installStep = createShellStep("Install cloudflared from Cloudflare's apt repository", [
240
+ "set -e",
241
+ `${sudoPrefix}mkdir -p --mode=0755 /usr/share/keyrings`,
242
+ `curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | ${sudoPrefix}tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null`,
243
+ ". /etc/os-release",
244
+ 'codename="${VERSION_CODENAME:-${UBUNTU_CODENAME:-}}"',
245
+ 'if [ -z "$codename" ]; then echo "Could not determine the Linux codename for cloudflared." >&2; exit 1; fi',
246
+ `echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared ${"$"}codename main" | ${sudoPrefix}tee /etc/apt/sources.list.d/cloudflared.list >/dev/null`,
247
+ `${sudoPrefix}apt-get update`,
248
+ `${sudoPrefix}apt-get install -y cloudflared`,
249
+ ].join(" && "), installDisplay);
250
+ return {
251
+ provider,
252
+ binary: "cloudflared",
253
+ displayName: "cloudflared",
254
+ docsUrl,
255
+ installStep,
256
+ configureSteps: [],
257
+ manualSteps: [installStep],
258
+ notes: [],
259
+ };
260
+ }
261
+ if ((availableCommands.has("dnf") || availableCommands.has("yum")) &&
262
+ availableCommands.has("curl") &&
263
+ canSudo) {
264
+ const manager = availableCommands.has("dnf") ? "dnf" : "yum";
265
+ const sudoPrefix = useSudo ? "sudo " : "";
266
+ const installStep = createShellStep(`Install cloudflared with ${manager}`, [
267
+ "set -e",
268
+ `curl -fsSL https://pkg.cloudflare.com/cloudflared-ascii.repo | ${sudoPrefix}tee /etc/yum.repos.d/cloudflared.repo >/dev/null`,
269
+ `${sudoPrefix}${manager} install -y cloudflared`,
270
+ ].join(" && "), [
271
+ `curl -fsSL https://pkg.cloudflare.com/cloudflared-ascii.repo | ${sudoPrefix}tee /etc/yum.repos.d/cloudflared.repo >/dev/null`,
272
+ `${sudoPrefix}${manager} install -y cloudflared`,
273
+ ].join(" && "));
274
+ return {
275
+ provider,
276
+ binary: "cloudflared",
277
+ displayName: "cloudflared",
278
+ docsUrl,
279
+ installStep,
280
+ configureSteps: [],
281
+ manualSteps: [installStep],
282
+ notes: [],
283
+ };
284
+ }
285
+ return {
286
+ provider,
287
+ binary: "cloudflared",
288
+ displayName: "cloudflared",
289
+ docsUrl,
290
+ configureSteps: [],
291
+ manualSteps: [],
292
+ notes: [],
293
+ };
294
+ }
295
+ export function renderRelayTunnelDependencyGuidance(plan) {
296
+ const lines = [
297
+ `[privateclaw-relay] ${plan.displayName} (\`${plan.binary}\`) is required for \`--public ${plan.provider}\` but was not found in PATH or is not executable.`,
298
+ ...(supportsAutomaticInstall(plan)
299
+ ? [
300
+ `[privateclaw-relay] Suggested install command: ${plan.installStep.display}`,
301
+ ]
302
+ : []),
303
+ ...(!supportsAutomaticInstall(plan) && plan.manualSteps.length > 0
304
+ ? [
305
+ "[privateclaw-relay] Suggested install/setup commands:",
306
+ ...plan.manualSteps.map((step) => `[privateclaw-relay] ${step.display}`),
307
+ ]
308
+ : []),
309
+ ...plan.notes.map((note) => `[privateclaw-relay] ${note}`),
310
+ ...(plan.configureSteps.length > 0
311
+ ? [
312
+ "[privateclaw-relay] Recommended follow-up commands:",
313
+ ...plan.configureSteps.map((step) => `[privateclaw-relay] ${step.display}`),
314
+ ]
315
+ : []),
316
+ `[privateclaw-relay] Docs: ${plan.docsUrl}`,
317
+ ];
318
+ return lines.join("\n");
319
+ }
320
+ async function promptForConfirmation(question) {
321
+ const rl = createInterface({
322
+ input: stdin,
323
+ output: stdout,
324
+ });
325
+ try {
326
+ const answer = await rl.question(`${question} [Y/n] `);
327
+ const normalized = answer.trim().toLowerCase();
328
+ return normalized === "" || normalized === "y" || normalized === "yes";
329
+ }
330
+ finally {
331
+ rl.close();
332
+ }
333
+ }
334
+ async function runRelayTunnelDependencyStep(step) {
335
+ const child = spawn(step.command, step.args, {
336
+ stdio: "inherit",
337
+ });
338
+ const childError = once(child, "error").then(([error]) => {
339
+ throw error;
340
+ });
341
+ const childClose = once(child, "close").then(([code, signal]) => ({
342
+ code,
343
+ signal,
344
+ }));
345
+ try {
346
+ const { code, signal } = await Promise.race([childError, childClose]);
347
+ if (code !== 0) {
348
+ throw new Error(`Command \`${step.display}\` exited with ${code == null ? `signal ${signal ?? "unknown"}` : `code ${code}`}.`);
349
+ }
350
+ }
351
+ catch (error) {
352
+ if (error.code === "ENOENT") {
353
+ throw new Error(`Could not run \`${step.display}\` because \`${step.command}\` is unavailable.`);
354
+ }
355
+ throw error;
356
+ }
357
+ }
358
+ export async function buildRelayTunnelDependencyPlanForCurrentSystem(provider) {
359
+ const availableCommands = await detectAvailableCommands(Array.from(PACKAGE_MANAGER_PROBES.keys()));
360
+ return resolveRelayTunnelDependencyPlan(provider, {
361
+ availableCommands,
362
+ });
363
+ }
364
+ export async function ensureRelayTunnelDependencyAvailable(options) {
365
+ const resolvePlan = options.resolvePlan ??
366
+ ((provider) => buildRelayTunnelDependencyPlanForCurrentSystem(provider));
367
+ const plan = await resolvePlan(options.provider);
368
+ const guidance = renderRelayTunnelDependencyGuidance(plan);
369
+ for (const line of guidance.split("\n")) {
370
+ options.onLog?.(line);
371
+ }
372
+ const interactive = options.isInteractive ?? isInteractiveTerminal();
373
+ if (!interactive) {
374
+ throw new RelayCliUserError(`${options.missingDependency.message}\n${guidance}\n[privateclaw-relay] Re-run in an interactive terminal to let the CLI install it for you automatically when supported.`);
375
+ }
376
+ if (!supportsAutomaticInstall(plan)) {
377
+ throw new RelayCliUserError(`${options.missingDependency.message}\n${guidance}\n[privateclaw-relay] Automatic installation is not available for this platform/package-manager combination yet.`);
378
+ }
379
+ const promptToContinue = options.promptToContinue ?? promptForConfirmation;
380
+ const runStep = options.runStep ?? runRelayTunnelDependencyStep;
381
+ const installStep = plan.installStep;
382
+ const installNow = await promptToContinue(`Install ${plan.displayName} now with \`${installStep.display}\`?`);
383
+ if (!installNow) {
384
+ throw new RelayCliUserError(`${options.missingDependency.message}\n${guidance}\n[privateclaw-relay] Installation was declined, so the public tunnel could not be started.`);
385
+ }
386
+ options.onLog?.(`[privateclaw-relay] Running: ${installStep.display}`);
387
+ await runStep(installStep);
388
+ options.onLog?.(`[privateclaw-relay] ${plan.displayName} installation completed.`);
389
+ if (plan.configureSteps.length === 0) {
390
+ return;
391
+ }
392
+ const configureNow = await promptToContinue(`Run the recommended ${plan.provider} setup commands now so the tunnel can be retried automatically?`);
393
+ if (!configureNow) {
394
+ options.onLog?.("[privateclaw-relay] Skipping the optional setup commands for now.");
395
+ return;
396
+ }
397
+ for (const step of plan.configureSteps) {
398
+ options.onLog?.(`[privateclaw-relay] Running: ${step.display}`);
399
+ await runStep(step);
400
+ }
401
+ }
402
+ //# sourceMappingURL=tunnel-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-installer.js","sourceRoot":"","sources":["../src/tunnel-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { spawn } from "node:child_process";
2
+ export type RelayTunnelProvider = "tailscale" | "cloudflare";
3
+ export interface RelayTunnelCommandPlan {
4
+ command: string;
5
+ args: string[];
6
+ }
7
+ export interface RelayTunnelHandle {
8
+ kind: RelayTunnelProvider;
9
+ publicUrl?: string;
10
+ notes: string[];
11
+ close(): Promise<void>;
12
+ }
13
+ export declare class MissingRelayTunnelBinaryError extends Error {
14
+ readonly command: string;
15
+ readonly hint: string;
16
+ constructor(command: string, hint: string);
17
+ }
18
+ interface OpenRelayTunnelOptions {
19
+ provider: RelayTunnelProvider;
20
+ localPort: number;
21
+ localUrl: string;
22
+ onLog?: (line: string) => void;
23
+ spawnCommand?: typeof spawn;
24
+ }
25
+ export declare function isUnavailableTunnelBinaryError(error: unknown): error is NodeJS.ErrnoException;
26
+ export declare function isRelayTunnelProvider(value: string): value is RelayTunnelProvider;
27
+ export declare function extractRelayTunnelPublicUrl(output: string): string | undefined;
28
+ export declare function extractCloudflareQuickTunnelPublicUrl(output: string): string | undefined;
29
+ export declare function buildRelayTunnelCommand(params: {
30
+ provider: RelayTunnelProvider;
31
+ localPort: number;
32
+ localUrl: string;
33
+ }): RelayTunnelCommandPlan;
34
+ export declare function openRelayTunnel(params: OpenRelayTunnelOptions): Promise<RelayTunnelHandle>;
35
+ export {};