@vibelet/cli 0.1.38 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/bin/cloudflared-quick-tunnel.mjs +11 -0
- package/bin/cloudflared-resolver.mjs +171 -0
- package/bin/vibelet-runtime-policy.mjs +36 -0
- package/bin/vibelet.cjs +12 -0
- package/bin/vibelet.mjs +1062 -0
- package/dist/index.cjs +126 -0
- package/package.json +24 -22
- package/app.json +0 -5
- package/dist/advertised-hosts.d.ts +0 -34
- package/dist/advertised-hosts.d.ts.map +0 -1
- package/dist/advertised-hosts.js +0 -176
- package/dist/advertised-hosts.js.map +0 -1
- package/dist/advertised-hosts.test.d.ts +0 -2
- package/dist/advertised-hosts.test.d.ts.map +0 -1
- package/dist/advertised-hosts.test.js +0 -96
- package/dist/advertised-hosts.test.js.map +0 -1
- package/dist/audit.d.ts +0 -30
- package/dist/audit.d.ts.map +0 -1
- package/dist/audit.js +0 -73
- package/dist/audit.js.map +0 -1
- package/dist/audit.test.d.ts +0 -2
- package/dist/audit.test.d.ts.map +0 -1
- package/dist/audit.test.js +0 -33
- package/dist/audit.test.js.map +0 -1
- package/dist/auth.d.ts +0 -6
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -27
- package/dist/auth.js.map +0 -1
- package/dist/claude-hooks.d.ts +0 -58
- package/dist/claude-hooks.d.ts.map +0 -1
- package/dist/claude-hooks.js +0 -129
- package/dist/claude-hooks.js.map +0 -1
- package/dist/cli-version.d.ts +0 -3
- package/dist/cli-version.d.ts.map +0 -1
- package/dist/cli-version.js +0 -35
- package/dist/cli-version.js.map +0 -1
- package/dist/cli-version.test.d.ts +0 -2
- package/dist/cli-version.test.d.ts.map +0 -1
- package/dist/cli-version.test.js +0 -38
- package/dist/cli-version.test.js.map +0 -1
- package/dist/config.d.ts +0 -30
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -327
- package/dist/config.js.map +0 -1
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -184
- package/dist/config.test.js.map +0 -1
- package/dist/dev-auth.test.d.ts +0 -2
- package/dist/dev-auth.test.d.ts.map +0 -1
- package/dist/dev-auth.test.js +0 -154
- package/dist/dev-auth.test.js.map +0 -1
- package/dist/dev-script.test.d.ts +0 -2
- package/dist/dev-script.test.d.ts.map +0 -1
- package/dist/dev-script.test.js +0 -412
- package/dist/dev-script.test.js.map +0 -1
- package/dist/drivers/claude.d.ts +0 -34
- package/dist/drivers/claude.d.ts.map +0 -1
- package/dist/drivers/claude.js +0 -413
- package/dist/drivers/claude.js.map +0 -1
- package/dist/drivers/claude.test.d.ts +0 -2
- package/dist/drivers/claude.test.d.ts.map +0 -1
- package/dist/drivers/claude.test.js +0 -951
- package/dist/drivers/claude.test.js.map +0 -1
- package/dist/drivers/codex.d.ts +0 -38
- package/dist/drivers/codex.d.ts.map +0 -1
- package/dist/drivers/codex.js +0 -771
- package/dist/drivers/codex.js.map +0 -1
- package/dist/drivers/codex.test.d.ts +0 -2
- package/dist/drivers/codex.test.d.ts.map +0 -1
- package/dist/drivers/codex.test.js +0 -939
- package/dist/drivers/codex.test.js.map +0 -1
- package/dist/drivers/types.d.ts +0 -14
- package/dist/drivers/types.d.ts.map +0 -1
- package/dist/drivers/types.js +0 -2
- package/dist/drivers/types.js.map +0 -1
- package/dist/e2e.test.d.ts +0 -2
- package/dist/e2e.test.d.ts.map +0 -1
- package/dist/e2e.test.js +0 -111
- package/dist/e2e.test.js.map +0 -1
- package/dist/identity.d.ts +0 -10
- package/dist/identity.d.ts.map +0 -1
- package/dist/identity.js +0 -66
- package/dist/identity.js.map +0 -1
- package/dist/identity.test.d.ts +0 -2
- package/dist/identity.test.d.ts.map +0 -1
- package/dist/identity.test.js +0 -25
- package/dist/identity.test.js.map +0 -1
- package/dist/index-entry.test.d.ts +0 -2
- package/dist/index-entry.test.d.ts.map +0 -1
- package/dist/index-entry.test.js +0 -272
- package/dist/index-entry.test.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -707
- package/dist/index.js.map +0 -1
- package/dist/logger.d.ts +0 -31
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -75
- package/dist/logger.js.map +0 -1
- package/dist/metrics.d.ts +0 -52
- package/dist/metrics.d.ts.map +0 -1
- package/dist/metrics.js +0 -89
- package/dist/metrics.js.map +0 -1
- package/dist/pairing-store.d.ts +0 -29
- package/dist/pairing-store.d.ts.map +0 -1
- package/dist/pairing-store.js +0 -131
- package/dist/pairing-store.js.map +0 -1
- package/dist/pairing-store.test.d.ts +0 -2
- package/dist/pairing-store.test.d.ts.map +0 -1
- package/dist/pairing-store.test.js +0 -47
- package/dist/pairing-store.test.js.map +0 -1
- package/dist/paths.d.ts +0 -16
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js +0 -18
- package/dist/paths.js.map +0 -1
- package/dist/perf-compare.d.ts +0 -13
- package/dist/perf-compare.d.ts.map +0 -1
- package/dist/perf-compare.js +0 -125
- package/dist/perf-compare.js.map +0 -1
- package/dist/port-conflict.d.ts +0 -9
- package/dist/port-conflict.d.ts.map +0 -1
- package/dist/port-conflict.js +0 -33
- package/dist/port-conflict.js.map +0 -1
- package/dist/port-conflict.test.d.ts +0 -2
- package/dist/port-conflict.test.d.ts.map +0 -1
- package/dist/port-conflict.test.js +0 -38
- package/dist/port-conflict.test.js.map +0 -1
- package/dist/process-scanner.d.ts +0 -43
- package/dist/process-scanner.d.ts.map +0 -1
- package/dist/process-scanner.js +0 -453
- package/dist/process-scanner.js.map +0 -1
- package/dist/process-scanner.perf.test.d.ts +0 -2
- package/dist/process-scanner.perf.test.d.ts.map +0 -1
- package/dist/process-scanner.perf.test.js +0 -186
- package/dist/process-scanner.perf.test.js.map +0 -1
- package/dist/process-scanner.test.d.ts +0 -2
- package/dist/process-scanner.test.d.ts.map +0 -1
- package/dist/process-scanner.test.js +0 -399
- package/dist/process-scanner.test.js.map +0 -1
- package/dist/push-protocol.d.ts +0 -15
- package/dist/push-protocol.d.ts.map +0 -1
- package/dist/push-protocol.js +0 -23
- package/dist/push-protocol.js.map +0 -1
- package/dist/push-protocol.test.d.ts +0 -2
- package/dist/push-protocol.test.d.ts.map +0 -1
- package/dist/push-protocol.test.js +0 -57
- package/dist/push-protocol.test.js.map +0 -1
- package/dist/push-store.d.ts +0 -22
- package/dist/push-store.d.ts.map +0 -1
- package/dist/push-store.js +0 -103
- package/dist/push-store.js.map +0 -1
- package/dist/push-store.test.d.ts +0 -2
- package/dist/push-store.test.d.ts.map +0 -1
- package/dist/push-store.test.js +0 -79
- package/dist/push-store.test.js.map +0 -1
- package/dist/push.d.ts +0 -65
- package/dist/push.d.ts.map +0 -1
- package/dist/push.js +0 -202
- package/dist/push.js.map +0 -1
- package/dist/push.test.d.ts +0 -2
- package/dist/push.test.d.ts.map +0 -1
- package/dist/push.test.js +0 -199
- package/dist/push.test.js.map +0 -1
- package/dist/safe-stdio.d.ts +0 -3
- package/dist/safe-stdio.d.ts.map +0 -1
- package/dist/safe-stdio.js +0 -46
- package/dist/safe-stdio.js.map +0 -1
- package/dist/scanner.d.ts +0 -30
- package/dist/scanner.d.ts.map +0 -1
- package/dist/scanner.js +0 -859
- package/dist/scanner.js.map +0 -1
- package/dist/scanner.perf.test.d.ts +0 -2
- package/dist/scanner.perf.test.d.ts.map +0 -1
- package/dist/scanner.perf.test.js +0 -320
- package/dist/scanner.perf.test.js.map +0 -1
- package/dist/scanner.test.d.ts +0 -2
- package/dist/scanner.test.d.ts.map +0 -1
- package/dist/scanner.test.js +0 -948
- package/dist/scanner.test.js.map +0 -1
- package/dist/session-inventory.d.ts +0 -63
- package/dist/session-inventory.d.ts.map +0 -1
- package/dist/session-inventory.js +0 -525
- package/dist/session-inventory.js.map +0 -1
- package/dist/session-inventory.perf.test.d.ts +0 -2
- package/dist/session-inventory.perf.test.d.ts.map +0 -1
- package/dist/session-inventory.perf.test.js +0 -220
- package/dist/session-inventory.perf.test.js.map +0 -1
- package/dist/session-inventory.test.d.ts +0 -2
- package/dist/session-inventory.test.d.ts.map +0 -1
- package/dist/session-inventory.test.js +0 -712
- package/dist/session-inventory.test.js.map +0 -1
- package/dist/session-manager.d.ts +0 -75
- package/dist/session-manager.d.ts.map +0 -1
- package/dist/session-manager.js +0 -1515
- package/dist/session-manager.js.map +0 -1
- package/dist/session-manager.test.d.ts +0 -2
- package/dist/session-manager.test.d.ts.map +0 -1
- package/dist/session-manager.test.js +0 -2861
- package/dist/session-manager.test.js.map +0 -1
- package/dist/session-store.d.ts +0 -42
- package/dist/session-store.d.ts.map +0 -1
- package/dist/session-store.js +0 -163
- package/dist/session-store.js.map +0 -1
- package/dist/session-store.test.d.ts +0 -2
- package/dist/session-store.test.d.ts.map +0 -1
- package/dist/session-store.test.js +0 -236
- package/dist/session-store.test.js.map +0 -1
- package/dist/session-title.d.ts +0 -6
- package/dist/session-title.d.ts.map +0 -1
- package/dist/session-title.js +0 -105
- package/dist/session-title.js.map +0 -1
- package/dist/session-title.perf.test.d.ts +0 -2
- package/dist/session-title.perf.test.d.ts.map +0 -1
- package/dist/session-title.perf.test.js +0 -99
- package/dist/session-title.perf.test.js.map +0 -1
- package/dist/session-title.test.d.ts +0 -2
- package/dist/session-title.test.d.ts.map +0 -1
- package/dist/session-title.test.js +0 -199
- package/dist/session-title.test.js.map +0 -1
- package/dist/shutdown-endpoint.test.d.ts +0 -2
- package/dist/shutdown-endpoint.test.d.ts.map +0 -1
- package/dist/shutdown-endpoint.test.js +0 -93
- package/dist/shutdown-endpoint.test.js.map +0 -1
- package/dist/storage-housekeeping.d.ts +0 -28
- package/dist/storage-housekeeping.d.ts.map +0 -1
- package/dist/storage-housekeeping.js +0 -76
- package/dist/storage-housekeeping.js.map +0 -1
- package/dist/storage-housekeeping.test.d.ts +0 -2
- package/dist/storage-housekeeping.test.d.ts.map +0 -1
- package/dist/storage-housekeeping.test.js +0 -65
- package/dist/storage-housekeeping.test.js.map +0 -1
- package/dist/test-daemon-harness.d.ts +0 -31
- package/dist/test-daemon-harness.d.ts.map +0 -1
- package/dist/test-daemon-harness.js +0 -337
- package/dist/test-daemon-harness.js.map +0 -1
- package/dist/token-auth.test.d.ts +0 -2
- package/dist/token-auth.test.d.ts.map +0 -1
- package/dist/token-auth.test.js +0 -52
- package/dist/token-auth.test.js.map +0 -1
- package/dist/utils.d.ts +0 -4
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -40
- package/dist/utils.js.map +0 -1
- package/dist/utils.test.d.ts +0 -2
- package/dist/utils.test.d.ts.map +0 -1
- package/dist/utils.test.js +0 -54
- package/dist/utils.test.js.map +0 -1
- package/dist/ws-data.d.ts +0 -4
- package/dist/ws-data.d.ts.map +0 -1
- package/dist/ws-data.js +0 -20
- package/dist/ws-data.js.map +0 -1
- package/dist/ws-data.test.d.ts +0 -2
- package/dist/ws-data.test.d.ts.map +0 -1
- package/dist/ws-data.test.js +0 -17
- package/dist/ws-data.test.js.map +0 -1
- package/perf-reporter.mjs +0 -138
- package/scripts/build-release.mjs +0 -41
- package/scripts/dev.mjs +0 -537
- package/src/advertised-hosts.test.ts +0 -125
- package/src/advertised-hosts.ts +0 -225
- package/src/audit.test.ts +0 -38
- package/src/audit.ts +0 -117
- package/src/auth.ts +0 -31
- package/src/claude-hooks.ts +0 -195
- package/src/cli-version.test.ts +0 -36
- package/src/cli-version.ts +0 -46
- package/src/config.test.ts +0 -254
- package/src/config.ts +0 -324
- package/src/dev-auth.test.ts +0 -183
- package/src/dev-script.test.ts +0 -511
- package/src/drivers/claude.test.ts +0 -1186
- package/src/drivers/claude.ts +0 -443
- package/src/drivers/codex.test.ts +0 -1096
- package/src/drivers/codex.ts +0 -879
- package/src/drivers/types.ts +0 -15
- package/src/e2e.test.ts +0 -139
- package/src/identity.test.ts +0 -26
- package/src/identity.ts +0 -82
- package/src/index-entry.test.ts +0 -336
- package/src/index.ts +0 -781
- package/src/logger.ts +0 -112
- package/src/metrics.ts +0 -117
- package/src/pairing-store.test.ts +0 -53
- package/src/pairing-store.ts +0 -154
- package/src/paths.ts +0 -19
- package/src/perf-compare.ts +0 -164
- package/src/port-conflict.test.ts +0 -45
- package/src/port-conflict.ts +0 -44
- package/src/process-scanner.perf.test.ts +0 -222
- package/src/process-scanner.test.ts +0 -575
- package/src/process-scanner.ts +0 -514
- package/src/push-protocol.test.ts +0 -74
- package/src/push-protocol.ts +0 -36
- package/src/push-store.test.ts +0 -89
- package/src/push-store.ts +0 -126
- package/src/push.test.ts +0 -234
- package/src/push.ts +0 -318
- package/src/safe-stdio.ts +0 -51
- package/src/scanner.perf.test.ts +0 -359
- package/src/scanner.test.ts +0 -1045
- package/src/scanner.ts +0 -924
- package/src/session-inventory.perf.test.ts +0 -250
- package/src/session-inventory.test.ts +0 -1002
- package/src/session-inventory.ts +0 -721
- package/src/session-manager.test.ts +0 -3430
- package/src/session-manager.ts +0 -1775
- package/src/session-store.test.ts +0 -276
- package/src/session-store.ts +0 -202
- package/src/session-title.perf.test.ts +0 -118
- package/src/session-title.test.ts +0 -286
- package/src/session-title.ts +0 -108
- package/src/shutdown-endpoint.test.ts +0 -95
- package/src/storage-housekeeping.test.ts +0 -78
- package/src/storage-housekeeping.ts +0 -111
- package/src/test-daemon-harness.ts +0 -410
- package/src/token-auth.test.ts +0 -67
- package/src/utils.test.ts +0 -65
- package/src/utils.ts +0 -47
- package/src/ws-data.test.ts +0 -20
- package/src/ws-data.ts +0 -26
- package/tsconfig.json +0 -12
package/src/dev-script.test.ts
DELETED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { spawn, type ChildProcess } from 'node:child_process';
|
|
3
|
-
import { once } from 'node:events';
|
|
4
|
-
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
5
|
-
import { createServer, Socket } from 'node:net';
|
|
6
|
-
import { tmpdir } from 'node:os';
|
|
7
|
-
import path from 'node:path';
|
|
8
|
-
import test from 'node:test';
|
|
9
|
-
import { fileURLToPath } from 'node:url';
|
|
10
|
-
|
|
11
|
-
const srcDir = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const daemonDir = path.resolve(srcDir, '..');
|
|
13
|
-
const devScriptPath = path.resolve(daemonDir, 'scripts/dev.mjs');
|
|
14
|
-
|
|
15
|
-
function delay(ms: number): Promise<void> {
|
|
16
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function getFreePort(): Promise<number> {
|
|
20
|
-
const server = createServer();
|
|
21
|
-
server.listen(0, '127.0.0.1');
|
|
22
|
-
await once(server, 'listening');
|
|
23
|
-
const address = server.address();
|
|
24
|
-
assert.ok(address && typeof address === 'object');
|
|
25
|
-
const { port } = address;
|
|
26
|
-
await new Promise<void>((resolve, reject) => {
|
|
27
|
-
server.close((error) => (error ? reject(error) : resolve()));
|
|
28
|
-
});
|
|
29
|
-
return port;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function isPortListening(port: number): Promise<boolean> {
|
|
33
|
-
return new Promise((resolve) => {
|
|
34
|
-
const socket = new Socket();
|
|
35
|
-
|
|
36
|
-
const finish = (result: boolean) => {
|
|
37
|
-
socket.removeAllListeners();
|
|
38
|
-
socket.destroy();
|
|
39
|
-
resolve(result);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
socket.setTimeout(200);
|
|
43
|
-
socket.once('connect', () => finish(true));
|
|
44
|
-
socket.once('timeout', () => finish(false));
|
|
45
|
-
socket.once('error', () => finish(false));
|
|
46
|
-
socket.connect(port, '127.0.0.1');
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function waitForPortState(
|
|
51
|
-
port: number,
|
|
52
|
-
expectedListening: boolean,
|
|
53
|
-
timeoutMs: number,
|
|
54
|
-
getOutput: () => string,
|
|
55
|
-
): Promise<void> {
|
|
56
|
-
const deadline = Date.now() + timeoutMs;
|
|
57
|
-
|
|
58
|
-
while (Date.now() < deadline) {
|
|
59
|
-
if ((await isPortListening(port)) === expectedListening) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
await delay(100);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Timed out waiting for port ${port} to become ${expectedListening ? 'open' : 'closed'}.\n${getOutput()}`,
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function waitForExit(
|
|
71
|
-
child: ChildProcess,
|
|
72
|
-
timeoutMs: number,
|
|
73
|
-
getOutput: () => string,
|
|
74
|
-
): Promise<{ code: number | null; signal: NodeJS.Signals | null }> {
|
|
75
|
-
if (child.exitCode !== null || child.signalCode !== null) {
|
|
76
|
-
return { code: child.exitCode, signal: child.signalCode };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return new Promise((resolve, reject) => {
|
|
80
|
-
const timer = setTimeout(() => {
|
|
81
|
-
reject(new Error(`Timed out waiting for dev wrapper to exit.\n${getOutput()}`));
|
|
82
|
-
}, timeoutMs);
|
|
83
|
-
|
|
84
|
-
child.once('exit', (code, signal) => {
|
|
85
|
-
clearTimeout(timer);
|
|
86
|
-
resolve({ code, signal });
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function appendOutput(output: string, chunk: string | Buffer): string {
|
|
92
|
-
const next = `${output}${chunk.toString()}`;
|
|
93
|
-
return next.length > 12000 ? next.slice(-12000) : next;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function createDevEnv(homeDir: string, port: number, extraEnv: Record<string, string> = {}) {
|
|
97
|
-
return {
|
|
98
|
-
...process.env,
|
|
99
|
-
HOME: homeDir,
|
|
100
|
-
VIBELET_RELAY_URL: '',
|
|
101
|
-
VIBELET_CANONICAL_HOST: '',
|
|
102
|
-
VIBELET_FALLBACK_HOSTS: '',
|
|
103
|
-
VIBE_PORT: String(port),
|
|
104
|
-
VIBE_TOKEN: 'test-token',
|
|
105
|
-
CLAUDE_PATH: process.execPath,
|
|
106
|
-
CODEX_PATH: process.execPath,
|
|
107
|
-
...extraEnv,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function writeExecutableScript(filePath: string, contents: string) {
|
|
112
|
-
writeFileSync(filePath, contents, 'utf8');
|
|
113
|
-
chmodSync(filePath, 0o755);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function writeCloudflaredDependency(packageDir: string, cliContents: string) {
|
|
117
|
-
mkdirSync(path.join(packageDir, 'lib'), { recursive: true });
|
|
118
|
-
writeFileSync(path.join(packageDir, 'package.json'), JSON.stringify({
|
|
119
|
-
name: 'cloudflared',
|
|
120
|
-
bin: {
|
|
121
|
-
cloudflared: 'lib/cloudflared.js',
|
|
122
|
-
},
|
|
123
|
-
}), 'utf8');
|
|
124
|
-
writeFileSync(path.join(packageDir, 'lib', 'cloudflared.js'), cliContents, 'utf8');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async function cleanupChild(child: ChildProcess, port: number): Promise<void> {
|
|
128
|
-
if (child.exitCode === null && child.signalCode === null) {
|
|
129
|
-
child.kill('SIGTERM');
|
|
130
|
-
try {
|
|
131
|
-
await waitForExit(child, 5000, () => '');
|
|
132
|
-
} catch {}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (await isPortListening(port)) {
|
|
136
|
-
await new Promise<void>((resolve) => {
|
|
137
|
-
const killer = spawn('/bin/zsh', ['-lc', `lsof -tiTCP:${port} -sTCP:LISTEN | xargs -r kill -9`], {
|
|
138
|
-
stdio: 'ignore',
|
|
139
|
-
});
|
|
140
|
-
killer.once('exit', () => resolve());
|
|
141
|
-
killer.once('error', () => resolve());
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async function runShutdownSignalTest(
|
|
147
|
-
t: test.TestContext,
|
|
148
|
-
signal: NodeJS.Signals,
|
|
149
|
-
extraEnv: Record<string, string> = {},
|
|
150
|
-
): Promise<void> {
|
|
151
|
-
const port = await getFreePort();
|
|
152
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
153
|
-
let output = '';
|
|
154
|
-
|
|
155
|
-
const child = spawn(process.execPath, [devScriptPath, '--local'], {
|
|
156
|
-
cwd: daemonDir,
|
|
157
|
-
env: createDevEnv(homeDir, port, extraEnv),
|
|
158
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
child.stdout?.on('data', (chunk) => {
|
|
162
|
-
output = appendOutput(output, chunk);
|
|
163
|
-
});
|
|
164
|
-
child.stderr?.on('data', (chunk) => {
|
|
165
|
-
output = appendOutput(output, chunk);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
t.after(async () => {
|
|
169
|
-
await cleanupChild(child, port);
|
|
170
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
174
|
-
child.kill(signal);
|
|
175
|
-
|
|
176
|
-
const exit = await waitForExit(child, 10000, () => output);
|
|
177
|
-
assert.ok(exit.code !== null || exit.signal !== null);
|
|
178
|
-
|
|
179
|
-
await waitForPortState(port, false, 5000, () => output);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
test('dev wrapper tears down tsx watch and releases the port on SIGHUP', { timeout: 30000 }, async (t) => {
|
|
183
|
-
await runShutdownSignalTest(t, 'SIGHUP');
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test('dev wrapper tears down tsx watch and releases the port on SIGINT', { timeout: 30000 }, async (t) => {
|
|
187
|
-
await runShutdownSignalTest(t, 'SIGINT');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
test(
|
|
191
|
-
'dev wrapper tears down tsx watch without detached child mode',
|
|
192
|
-
{ timeout: 30000 },
|
|
193
|
-
async (t) => {
|
|
194
|
-
await runShutdownSignalTest(t, 'SIGINT', { VIBE_DEV_DETACHED: '0' });
|
|
195
|
-
},
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
test('dev wrapper restart stops the previous wrapper before rebinding the port', { timeout: 45000 }, async (t) => {
|
|
199
|
-
const port = await getFreePort();
|
|
200
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
201
|
-
let firstOutput = '';
|
|
202
|
-
let restartOutput = '';
|
|
203
|
-
|
|
204
|
-
const firstChild = spawn(process.execPath, [devScriptPath, '--local'], {
|
|
205
|
-
cwd: daemonDir,
|
|
206
|
-
env: createDevEnv(homeDir, port),
|
|
207
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
firstChild.stdout?.on('data', (chunk) => {
|
|
211
|
-
firstOutput = appendOutput(firstOutput, chunk);
|
|
212
|
-
});
|
|
213
|
-
firstChild.stderr?.on('data', (chunk) => {
|
|
214
|
-
firstOutput = appendOutput(firstOutput, chunk);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
let restartChild: ChildProcess | null = null;
|
|
218
|
-
|
|
219
|
-
t.after(async () => {
|
|
220
|
-
if (restartChild) {
|
|
221
|
-
await cleanupChild(restartChild, port);
|
|
222
|
-
}
|
|
223
|
-
await cleanupChild(firstChild, port);
|
|
224
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
await waitForPortState(port, true, 15000, () => firstOutput);
|
|
228
|
-
|
|
229
|
-
restartChild = spawn(process.execPath, [devScriptPath, 'restart', '--local'], {
|
|
230
|
-
cwd: daemonDir,
|
|
231
|
-
env: createDevEnv(homeDir, port),
|
|
232
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
restartChild.stdout?.on('data', (chunk) => {
|
|
236
|
-
restartOutput = appendOutput(restartOutput, chunk);
|
|
237
|
-
});
|
|
238
|
-
restartChild.stderr?.on('data', (chunk) => {
|
|
239
|
-
restartOutput = appendOutput(restartOutput, chunk);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const combinedOutput = () => `${firstOutput}\n--- restart ---\n${restartOutput}`;
|
|
243
|
-
|
|
244
|
-
const firstExit = await waitForExit(firstChild, 10000, combinedOutput);
|
|
245
|
-
assert.ok(firstExit.code !== null || firstExit.signal !== null);
|
|
246
|
-
|
|
247
|
-
await waitForPortState(port, true, 15000, combinedOutput);
|
|
248
|
-
assert.doesNotMatch(restartOutput, /EADDRINUSE/);
|
|
249
|
-
assert.match(restartOutput, /\[dev\] Stopping previous dev wrapper/);
|
|
250
|
-
|
|
251
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
252
|
-
assert.equal(response.status, 200);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
test('dev wrapper rejects unknown positional commands', { timeout: 10000 }, async (t) => {
|
|
256
|
-
const port = await getFreePort();
|
|
257
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
258
|
-
let output = '';
|
|
259
|
-
|
|
260
|
-
const child = spawn(process.execPath, [devScriptPath, 'bogus', '--local'], {
|
|
261
|
-
cwd: daemonDir,
|
|
262
|
-
env: createDevEnv(homeDir, port),
|
|
263
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
child.stdout?.on('data', (chunk) => {
|
|
267
|
-
output = appendOutput(output, chunk);
|
|
268
|
-
});
|
|
269
|
-
child.stderr?.on('data', (chunk) => {
|
|
270
|
-
output = appendOutput(output, chunk);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
t.after(async () => {
|
|
274
|
-
await cleanupChild(child, port);
|
|
275
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
const exit = await waitForExit(child, 5000, () => output);
|
|
279
|
-
assert.notEqual(exit.code, 0);
|
|
280
|
-
assert.match(output, /\[dev\] Unknown command: bogus/);
|
|
281
|
-
assert.equal(await isPortListening(port), false);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
test('dev wrapper forwards --relay to the watched daemon env', { timeout: 30000 }, async (t) => {
|
|
285
|
-
const port = await getFreePort();
|
|
286
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
287
|
-
let output = '';
|
|
288
|
-
|
|
289
|
-
const child = spawn(process.execPath, [devScriptPath, '--relay=https://relay.example.com:443'], {
|
|
290
|
-
cwd: daemonDir,
|
|
291
|
-
env: createDevEnv(homeDir, port),
|
|
292
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
child.stdout?.on('data', (chunk) => {
|
|
296
|
-
output = appendOutput(output, chunk);
|
|
297
|
-
});
|
|
298
|
-
child.stderr?.on('data', (chunk) => {
|
|
299
|
-
output = appendOutput(output, chunk);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
t.after(async () => {
|
|
303
|
-
await cleanupChild(child, port);
|
|
304
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
308
|
-
|
|
309
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
310
|
-
assert.equal(response.status, 200);
|
|
311
|
-
const health = await response.json() as { relayUrl?: string; canonicalHost?: string };
|
|
312
|
-
assert.equal(health.relayUrl, 'https://relay.example.com:443');
|
|
313
|
-
assert.equal(health.canonicalHost, 'relay.example.com');
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test('dev wrapper falls back to npm_config_relay when npm run swallows the flag', { timeout: 30000 }, async (t) => {
|
|
317
|
-
const port = await getFreePort();
|
|
318
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
319
|
-
let output = '';
|
|
320
|
-
|
|
321
|
-
const child = spawn(process.execPath, [devScriptPath], {
|
|
322
|
-
cwd: daemonDir,
|
|
323
|
-
env: createDevEnv(homeDir, port, {
|
|
324
|
-
npm_config_relay: 'https://relay-from-npm.example.com:443',
|
|
325
|
-
}),
|
|
326
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
child.stdout?.on('data', (chunk) => {
|
|
330
|
-
output = appendOutput(output, chunk);
|
|
331
|
-
});
|
|
332
|
-
child.stderr?.on('data', (chunk) => {
|
|
333
|
-
output = appendOutput(output, chunk);
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
t.after(async () => {
|
|
337
|
-
await cleanupChild(child, port);
|
|
338
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
342
|
-
|
|
343
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
344
|
-
assert.equal(response.status, 200);
|
|
345
|
-
const health = await response.json() as { relayUrl?: string; canonicalHost?: string };
|
|
346
|
-
assert.equal(health.relayUrl, 'https://relay-from-npm.example.com:443');
|
|
347
|
-
assert.equal(health.canonicalHost, 'relay-from-npm.example.com');
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
test('dev wrapper reuses an existing tunnel and forwards its relay URL by default', { timeout: 30000 }, async (t) => {
|
|
351
|
-
const port = await getFreePort();
|
|
352
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
353
|
-
const vibeletDir = path.join(homeDir, '.vibelet');
|
|
354
|
-
mkdirSync(vibeletDir, { recursive: true });
|
|
355
|
-
writeFileSync(path.join(vibeletDir, 'tunnel.json'), JSON.stringify({
|
|
356
|
-
pid: process.pid,
|
|
357
|
-
url: 'https://relay-from-tunnel.example.com:443',
|
|
358
|
-
}) + '\n', 'utf8');
|
|
359
|
-
let output = '';
|
|
360
|
-
|
|
361
|
-
const child = spawn(process.execPath, [devScriptPath], {
|
|
362
|
-
cwd: daemonDir,
|
|
363
|
-
env: createDevEnv(homeDir, port),
|
|
364
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
child.stdout?.on('data', (chunk) => {
|
|
368
|
-
output = appendOutput(output, chunk);
|
|
369
|
-
});
|
|
370
|
-
child.stderr?.on('data', (chunk) => {
|
|
371
|
-
output = appendOutput(output, chunk);
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
t.after(async () => {
|
|
375
|
-
await cleanupChild(child, port);
|
|
376
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
380
|
-
assert.match(output, /\[dev\] Reusing tunnel: https:\/\/relay-from-tunnel\.example\.com:443/);
|
|
381
|
-
|
|
382
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
383
|
-
assert.equal(response.status, 200);
|
|
384
|
-
const health = await response.json() as { relayUrl?: string; canonicalHost?: string };
|
|
385
|
-
assert.equal(health.relayUrl, 'https://relay-from-tunnel.example.com:443');
|
|
386
|
-
assert.equal(health.canonicalHost, 'relay-from-tunnel.example.com');
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
test('dev wrapper starts the tunnel through the bundled cloudflared dependency when cloudflared is not installed', { timeout: 30000 }, async (t) => {
|
|
390
|
-
const port = await getFreePort();
|
|
391
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
392
|
-
const fakeBinDir = mkdtempSync(path.join(tmpdir(), 'vibelet-cloudflared-bin-'));
|
|
393
|
-
const fakePackageDir = mkdtempSync(path.join(tmpdir(), 'vibelet-cloudflared-package-'));
|
|
394
|
-
const tunnelUrl = 'https://bundled-dependency.trycloudflare.com';
|
|
395
|
-
let output = '';
|
|
396
|
-
|
|
397
|
-
writeCloudflaredDependency(fakePackageDir, `
|
|
398
|
-
console.log('2026-04-07T14:00:01Z INF Requesting new quick Tunnel on trycloudflare.com...');
|
|
399
|
-
console.log('2026-04-07T14:00:01Z INF Your quick Tunnel has been created! Visit it at:');
|
|
400
|
-
console.log(${JSON.stringify(tunnelUrl)});
|
|
401
|
-
`);
|
|
402
|
-
|
|
403
|
-
const child = spawn(process.execPath, [devScriptPath], {
|
|
404
|
-
cwd: daemonDir,
|
|
405
|
-
env: createDevEnv(homeDir, port, {
|
|
406
|
-
PATH: fakeBinDir,
|
|
407
|
-
VIBELET_CLOUDFLARED_PACKAGE_JSON: path.join(fakePackageDir, 'package.json'),
|
|
408
|
-
}),
|
|
409
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
child.stdout?.on('data', (chunk) => {
|
|
413
|
-
output = appendOutput(output, chunk);
|
|
414
|
-
});
|
|
415
|
-
child.stderr?.on('data', (chunk) => {
|
|
416
|
-
output = appendOutput(output, chunk);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
t.after(async () => {
|
|
420
|
-
await cleanupChild(child, port);
|
|
421
|
-
rmSync(fakeBinDir, { recursive: true, force: true });
|
|
422
|
-
rmSync(fakePackageDir, { recursive: true, force: true });
|
|
423
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
427
|
-
|
|
428
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
429
|
-
assert.equal(response.status, 200);
|
|
430
|
-
const health = await response.json() as { relayUrl?: string; canonicalHost?: string };
|
|
431
|
-
assert.equal(health.relayUrl, tunnelUrl);
|
|
432
|
-
assert.equal(health.canonicalHost, 'bundled-dependency.trycloudflare.com');
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
test('dev wrapper includes bundled dependency stderr when tunnel bootstrap fails', { timeout: 15000 }, async (t) => {
|
|
436
|
-
const port = await getFreePort();
|
|
437
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
438
|
-
const fakeBinDir = mkdtempSync(path.join(tmpdir(), 'vibelet-cloudflared-bin-'));
|
|
439
|
-
const fakePackageDir = mkdtempSync(path.join(tmpdir(), 'vibelet-cloudflared-package-'));
|
|
440
|
-
let output = '';
|
|
441
|
-
|
|
442
|
-
writeCloudflaredDependency(fakePackageDir, `
|
|
443
|
-
console.error('dependency bootstrap failed');
|
|
444
|
-
process.exit(42);
|
|
445
|
-
`);
|
|
446
|
-
|
|
447
|
-
const child = spawn(process.execPath, [devScriptPath], {
|
|
448
|
-
cwd: daemonDir,
|
|
449
|
-
env: createDevEnv(homeDir, port, {
|
|
450
|
-
PATH: fakeBinDir,
|
|
451
|
-
VIBELET_CLOUDFLARED_PACKAGE_JSON: path.join(fakePackageDir, 'package.json'),
|
|
452
|
-
}),
|
|
453
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
child.stdout?.on('data', (chunk) => {
|
|
457
|
-
output = appendOutput(output, chunk);
|
|
458
|
-
});
|
|
459
|
-
child.stderr?.on('data', (chunk) => {
|
|
460
|
-
output = appendOutput(output, chunk);
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
t.after(async () => {
|
|
464
|
-
await cleanupChild(child, port);
|
|
465
|
-
rmSync(fakeBinDir, { recursive: true, force: true });
|
|
466
|
-
rmSync(fakePackageDir, { recursive: true, force: true });
|
|
467
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
const exit = await waitForExit(child, 10000, () => output);
|
|
471
|
-
assert.notEqual(exit.code, 0);
|
|
472
|
-
assert.equal(await isPortListening(port), false);
|
|
473
|
-
assert.match(output, /\[dev\] Tunnel failed: cloudflared exited before producing a tunnel URL via bundled cloudflared dependency/);
|
|
474
|
-
assert.match(output, /dependency bootstrap failed/);
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
test('dev wrapper ignores the saved relay config when --local is provided', { timeout: 30000 }, async (t) => {
|
|
478
|
-
const port = await getFreePort();
|
|
479
|
-
const homeDir = mkdtempSync(path.join(tmpdir(), 'vibelet-dev-test-'));
|
|
480
|
-
const vibeletDir = path.join(homeDir, '.vibelet');
|
|
481
|
-
mkdirSync(vibeletDir, { recursive: true });
|
|
482
|
-
writeFileSync(path.join(vibeletDir, 'relay.json'), JSON.stringify({
|
|
483
|
-
relayUrl: 'https://relay-from-config.example.com:443',
|
|
484
|
-
}) + '\n', 'utf8');
|
|
485
|
-
let output = '';
|
|
486
|
-
|
|
487
|
-
const child = spawn(process.execPath, [devScriptPath, '--local'], {
|
|
488
|
-
cwd: daemonDir,
|
|
489
|
-
env: createDevEnv(homeDir, port),
|
|
490
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
child.stdout?.on('data', (chunk) => {
|
|
494
|
-
output = appendOutput(output, chunk);
|
|
495
|
-
});
|
|
496
|
-
child.stderr?.on('data', (chunk) => {
|
|
497
|
-
output = appendOutput(output, chunk);
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
t.after(async () => {
|
|
501
|
-
await cleanupChild(child, port);
|
|
502
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
await waitForPortState(port, true, 15000, () => output);
|
|
506
|
-
|
|
507
|
-
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
|
508
|
-
assert.equal(response.status, 200);
|
|
509
|
-
const health = await response.json() as { relayUrl?: string; canonicalHost?: string };
|
|
510
|
-
assert.equal(health.relayUrl, undefined);
|
|
511
|
-
});
|