@mockuser/cli 0.0.1

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.
@@ -0,0 +1,2 @@
1
+ export declare function saveApiKey(apiKey: string): void;
2
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,QAGxC"}
@@ -0,0 +1,6 @@
1
+ import { saveConfig } from '../config.js';
2
+ export function saveApiKey(apiKey) {
3
+ saveConfig({ apiKey });
4
+ console.log('API key saved. You can now run: mockuser tunnel');
5
+ }
6
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACtB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;AAChE,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function generate(options: {
2
+ port: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAqDA,wBAAsB,QAAQ,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,iBAgEvD"}
@@ -0,0 +1,104 @@
1
+ import { execSync, execFileSync } from 'child_process';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import WebSocket from 'ws';
5
+ import { requireConfig, BACKEND_WS_URL } from '../config.js';
6
+ const PROJECT_ROOT = process.env.INIT_CWD ?? process.cwd();
7
+ function getGitDiff() {
8
+ try {
9
+ return execSync('git diff HEAD', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], cwd: PROJECT_ROOT });
10
+ }
11
+ catch {
12
+ return '';
13
+ }
14
+ }
15
+ function getGitStatus() {
16
+ try {
17
+ return execSync('git status --short', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], cwd: PROJECT_ROOT });
18
+ }
19
+ catch {
20
+ return '';
21
+ }
22
+ }
23
+ function executeTool(tool, params) {
24
+ if (tool === 'list_dir') {
25
+ const target = path.resolve(PROJECT_ROOT, params.path ?? '.');
26
+ return fs.readdirSync(target, { withFileTypes: true }).map((e) => ({
27
+ name: e.name,
28
+ type: e.isDirectory() ? 'dir' : 'file',
29
+ }));
30
+ }
31
+ if (tool === 'read_file') {
32
+ const target = path.resolve(PROJECT_ROOT, params.path);
33
+ return fs.readFileSync(target, 'utf8');
34
+ }
35
+ if (tool === 'search_files') {
36
+ const searchPath = path.resolve(PROJECT_ROOT, params.path ?? '.');
37
+ try {
38
+ const output = execFileSync('grep', ['-r', '--fixed-strings', '-l', params.query, searchPath], {
39
+ encoding: 'utf8',
40
+ stdio: ['pipe', 'pipe', 'pipe'],
41
+ });
42
+ return output.split('\n').filter(Boolean);
43
+ }
44
+ catch {
45
+ return [];
46
+ }
47
+ }
48
+ throw new Error(`Unknown tool: ${tool}`);
49
+ }
50
+ export async function generate(options) {
51
+ const port = parseInt(options.port, 10);
52
+ if (isNaN(port)) {
53
+ console.error('Invalid port number');
54
+ process.exit(1);
55
+ }
56
+ const cfg = requireConfig();
57
+ const cwd = process.env.INIT_CWD ?? process.cwd();
58
+ const diff = getGitDiff();
59
+ const gitStatus = getGitStatus();
60
+ console.log(`Connecting to backend...`);
61
+ const ws = new WebSocket(`${BACKEND_WS_URL}/ws/generate?apiKey=${cfg.apiKey}`);
62
+ process.on('SIGINT', () => {
63
+ ws.send(JSON.stringify({ type: 'cancel' }));
64
+ ws.close();
65
+ process.exit(1);
66
+ });
67
+ ws.on('open', () => {
68
+ ws.send(JSON.stringify({ type: 'init', port, diff, gitStatus, cwd }));
69
+ });
70
+ ws.on('message', (raw) => {
71
+ const msg = JSON.parse(raw.toString());
72
+ switch (msg.type) {
73
+ case 'status':
74
+ console.log(msg.message);
75
+ break;
76
+ case 'tool_call':
77
+ try {
78
+ const result = executeTool(msg.tool, msg.params);
79
+ ws.send(JSON.stringify({ type: 'tool_result', id: msg.id, result }));
80
+ }
81
+ catch (err) {
82
+ ws.send(JSON.stringify({ type: 'tool_result', id: msg.id, result: { error: String(err) } }));
83
+ }
84
+ break;
85
+ case 'done':
86
+ console.log(`\nDone! Generation ID: ${msg.generationId}`);
87
+ process.exit(0);
88
+ case 'error':
89
+ console.error(`\nError: ${msg.message}`);
90
+ process.exit(1);
91
+ }
92
+ });
93
+ ws.on('error', (err) => {
94
+ console.error(`Connection error: ${err.message}`);
95
+ process.exit(1);
96
+ });
97
+ ws.on('close', (code, reason) => {
98
+ if (code !== 1000 && code !== undefined) {
99
+ console.error(`Disconnected (${code}: ${reason.toString()})`);
100
+ process.exit(1);
101
+ }
102
+ });
103
+ }
104
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,SAAS,MAAM,IAAI,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAS5D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;AAE1D,SAAS,UAAU;IACjB,IAAI,CAAC;QAAC,OAAO,QAAQ,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,CAAA;IAAC,CAAC;AACxI,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC;QAAC,OAAO,QAAQ,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,CAAA;IAAC,CAAC;AAC7I,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,MAA8B;IAC/D,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,CAAA;QAC7D,OAAO,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;SACvC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACtD,OAAO,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,CAAA;QACjE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE;gBAC7F,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAChC,CAAC,CAAA;YACF,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAyB;IACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACvC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,EAAE,CAAA;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACjD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAA;IACzB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAEhC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;IAEvC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,cAAc,uBAAuB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAE9E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;QAC3C,EAAE,CAAC,KAAK,EAAE,CAAA;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACjB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;QACvB,MAAM,GAAG,GAAkB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;QAErD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACxB,MAAK;YAEP,KAAK,WAAW;gBACd,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;oBAChD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;gBACtE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;gBAC9F,CAAC;gBACD,MAAK;YAEP,KAAK,MAAM;gBACT,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,CAAC,YAAY,EAAE,CAAC,CAAA;gBACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAEjB,KAAK,OAAO;gBACV,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;gBACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function openTunnel(options: {
2
+ port: string;
3
+ }): Promise<void>;
4
+ export declare function listTunnels(): Promise<void>;
5
+ export declare function closeTunnel(id: string): Promise<void>;
6
+ export declare function stopAllTunnels(): Promise<void>;
7
+ export declare function restartTunnel(id: string): Promise<void>;
8
+ //# sourceMappingURL=tunnel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"AAmJA,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,iBAoCzD;AAED,wBAAsB,WAAW,kBAoBhC;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,iBAS3C;AAED,wBAAsB,cAAc,kBAmBnC;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,iBAkB7C"}
@@ -0,0 +1,247 @@
1
+ import https from 'https';
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
5
+ import { execSync, spawn } from 'child_process';
6
+ import { TunnelAllocateResponseSchema, TunnelListResponseSchema } from '@shared/types';
7
+ import { requireConfig, BACKEND_URL } from '../config.js';
8
+ const AGENT_VERSION = '0.61.1';
9
+ const MOCKUSER_DIR = path.join(os.homedir(), '.mockuser');
10
+ const MOCKUSER_BIN_DIR = path.join(MOCKUSER_DIR, 'bin');
11
+ const PID_DIR = path.join(MOCKUSER_DIR, 'pids');
12
+ function getPlatformTarget() {
13
+ const { platform, arch } = process;
14
+ const map = {
15
+ darwin: { arm64: 'darwin_arm64', x64: 'darwin_amd64' },
16
+ linux: { arm64: 'linux_arm64', x64: 'linux_amd64' },
17
+ win32: { x64: 'windows_amd64' },
18
+ };
19
+ const target = map[platform]?.[arch];
20
+ if (!target)
21
+ throw new Error(`Unsupported platform: ${platform}/${arch}`);
22
+ return target;
23
+ }
24
+ function getAgentBinPath() {
25
+ return path.join(MOCKUSER_BIN_DIR, process.platform === 'win32' ? 'frpc.exe' : 'frpc');
26
+ }
27
+ function downloadFile(url, dest) {
28
+ return new Promise((resolve, reject) => {
29
+ const file = fs.createWriteStream(dest);
30
+ https.get(url, (res) => {
31
+ if (res.statusCode === 301 || res.statusCode === 302) {
32
+ file.close();
33
+ fs.unlinkSync(dest);
34
+ return downloadFile(res.headers.location, dest).then(resolve).catch(reject);
35
+ }
36
+ if (res.statusCode !== 200) {
37
+ file.close();
38
+ reject(new Error(`Download failed: HTTP ${res.statusCode}`));
39
+ return;
40
+ }
41
+ res.pipe(file);
42
+ file.on('finish', () => file.close(() => resolve()));
43
+ file.on('error', reject);
44
+ }).on('error', reject);
45
+ });
46
+ }
47
+ async function ensureAgent() {
48
+ const agentBin = getAgentBinPath();
49
+ if (fs.existsSync(agentBin))
50
+ return agentBin;
51
+ const target = getPlatformTarget();
52
+ const tarName = `frp_${AGENT_VERSION}_${target}.tar.gz`;
53
+ const downloadUrl = `https://github.com/fatedier/frp/releases/download/v${AGENT_VERSION}/${tarName}`;
54
+ const tmpTar = path.join(os.tmpdir(), tarName);
55
+ const tmpExtractDir = path.join(os.tmpdir(), `frp_${AGENT_VERSION}_${target}`);
56
+ console.log('Setting up tunnel agent...');
57
+ await downloadFile(downloadUrl, tmpTar);
58
+ fs.mkdirSync(tmpExtractDir, { recursive: true });
59
+ execSync(`tar -xzf "${tmpTar}" -C "${tmpExtractDir}" --strip-components=1`);
60
+ fs.unlinkSync(tmpTar);
61
+ fs.mkdirSync(MOCKUSER_BIN_DIR, { recursive: true });
62
+ const extractedBin = path.join(tmpExtractDir, process.platform === 'win32' ? 'frpc.exe' : 'frpc');
63
+ fs.copyFileSync(extractedBin, agentBin);
64
+ fs.rmSync(tmpExtractDir, { recursive: true, force: true });
65
+ if (process.platform !== 'win32')
66
+ fs.chmodSync(agentBin, 0o755);
67
+ return agentBin;
68
+ }
69
+ function writePid(tunnelId, pid) {
70
+ fs.mkdirSync(PID_DIR, { recursive: true });
71
+ fs.writeFileSync(path.join(PID_DIR, `${tunnelId}.pid`), String(pid));
72
+ }
73
+ function readPid(tunnelId) {
74
+ try {
75
+ return parseInt(fs.readFileSync(path.join(PID_DIR, `${tunnelId}.pid`), 'utf8'), 10);
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ function deletePid(tunnelId) {
82
+ try {
83
+ fs.unlinkSync(path.join(PID_DIR, `${tunnelId}.pid`));
84
+ }
85
+ catch { }
86
+ }
87
+ function isProcessAlive(pid) {
88
+ try {
89
+ process.kill(pid, 0);
90
+ return true;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ async function api(method, route, apiKey, body) {
97
+ let res;
98
+ try {
99
+ res = await fetch(`${BACKEND_URL}/api${route}`, {
100
+ method,
101
+ headers: {
102
+ 'Content-Type': 'application/json',
103
+ 'x-api-key': apiKey,
104
+ },
105
+ body: body ? JSON.stringify(body) : undefined,
106
+ });
107
+ }
108
+ catch {
109
+ console.error('Cannot reach Mockuser. Check your connection and try again.');
110
+ process.exit(1);
111
+ }
112
+ if (!res.ok) {
113
+ const text = await res.text();
114
+ throw new Error(`Request failed (${res.status}): ${text}`);
115
+ }
116
+ return res.json();
117
+ }
118
+ function spawnAgentDaemon(agentBin, configPath, tunnelId) {
119
+ const child = spawn(agentBin, ['-c', configPath], {
120
+ detached: true,
121
+ stdio: 'ignore',
122
+ });
123
+ child.unref();
124
+ writePid(tunnelId, child.pid);
125
+ return child.pid;
126
+ }
127
+ function buildAgentConfig(cfg) {
128
+ return [
129
+ `serverAddr = "${cfg.frpServer}"`,
130
+ `serverPort = ${cfg.frpPort}`,
131
+ '',
132
+ `auth.method = "token"`,
133
+ `auth.token = "${cfg.token}"`,
134
+ '',
135
+ `[[proxies]]`,
136
+ `name = "${cfg.id}"`,
137
+ `type = "http"`,
138
+ `localPort = ${cfg.localPort}`,
139
+ `customDomains = ["${cfg.subdomain}"]`,
140
+ `hostHeaderRewrite = "localhost:${cfg.localPort}"`,
141
+ `requestHeaders.set.Origin = "http://localhost:${cfg.localPort}"`,
142
+ ].join('\n');
143
+ }
144
+ export async function openTunnel(options) {
145
+ const { apiKey } = requireConfig();
146
+ const localPort = parseInt(options.port, 10);
147
+ const existing = await api('GET', '/tunnels', apiKey);
148
+ const { tunnels } = TunnelListResponseSchema.parse(existing);
149
+ const active = tunnels.find((t) => t.localPort === localPort);
150
+ if (active) {
151
+ const pid = readPid(active.id);
152
+ if (pid && isProcessAlive(pid)) {
153
+ console.log(`Tunnel already running for port ${localPort}: https://${active.subdomain} (pid ${pid})`);
154
+ return;
155
+ }
156
+ console.log(`Reconnecting existing tunnel for port ${localPort}...`);
157
+ const raw = await api('POST', `/tunnels/${active.id}/restart`, apiKey);
158
+ const cfg = TunnelAllocateResponseSchema.parse(raw);
159
+ const agentBin = await ensureAgent();
160
+ const configPath = path.join(os.tmpdir(), `mockuser-${cfg.id}.toml`);
161
+ fs.writeFileSync(configPath, buildAgentConfig(cfg));
162
+ const pid2 = spawnAgentDaemon(agentBin, configPath, cfg.id);
163
+ console.log(`Tunnel reconnected: https://${cfg.subdomain} (pid ${pid2})`);
164
+ return;
165
+ }
166
+ console.log(`Allocating tunnel on port ${localPort}...`);
167
+ const raw = await api('POST', '/tunnels', apiKey, { localPort });
168
+ const cfg = TunnelAllocateResponseSchema.parse(raw);
169
+ console.log(`Tunnel allocated: https://${cfg.subdomain}`);
170
+ const agentBin = await ensureAgent();
171
+ const configPath = path.join(os.tmpdir(), `mockuser-${cfg.id}.toml`);
172
+ fs.writeFileSync(configPath, buildAgentConfig(cfg));
173
+ const pid = spawnAgentDaemon(agentBin, configPath, cfg.id);
174
+ console.log(`Tunnel live: https://${cfg.subdomain} → localhost:${localPort} (pid ${pid})`);
175
+ console.log(`Manage: mockuser tunnel list | close ${cfg.id.slice(0, 8)} | restart ${cfg.id.slice(0, 8)}`);
176
+ }
177
+ export async function listTunnels() {
178
+ const { apiKey } = requireConfig();
179
+ const raw = await api('GET', '/tunnels', apiKey);
180
+ const { tunnels } = TunnelListResponseSchema.parse(raw);
181
+ if (tunnels.length === 0) {
182
+ console.log('No active tunnels.');
183
+ return;
184
+ }
185
+ console.log('\nID \tSubdomain\t\t\t\tPort\tStatus\t\tCreated');
186
+ console.log('─'.repeat(90));
187
+ for (const t of tunnels) {
188
+ const pid = readPid(t.id);
189
+ const alive = pid ? isProcessAlive(pid) : false;
190
+ const liveStatus = alive ? t.status : `${t.status} (agent not running)`;
191
+ const age = formatAge(new Date(t.createdAt));
192
+ console.log(`${t.id.slice(0, 8)}\t${t.subdomain.padEnd(36)}\t${t.localPort}\t${liveStatus.padEnd(16)}\t${age}`);
193
+ }
194
+ console.log();
195
+ }
196
+ export async function closeTunnel(id) {
197
+ const { apiKey } = requireConfig();
198
+ const pid = readPid(id);
199
+ if (pid && isProcessAlive(pid))
200
+ process.kill(pid, 'SIGTERM');
201
+ deletePid(id);
202
+ await api('DELETE', `/tunnels/${id}`, apiKey);
203
+ console.log(`Tunnel ${id.slice(0, 8)} closed.`);
204
+ }
205
+ export async function stopAllTunnels() {
206
+ const { apiKey } = requireConfig();
207
+ const raw = await api('GET', '/tunnels', apiKey);
208
+ const { tunnels } = TunnelListResponseSchema.parse(raw);
209
+ if (tunnels.length === 0) {
210
+ console.log('No active tunnels.');
211
+ return;
212
+ }
213
+ for (const t of tunnels) {
214
+ const pid = readPid(t.id);
215
+ if (pid && isProcessAlive(pid))
216
+ process.kill(pid, 'SIGTERM');
217
+ deletePid(t.id);
218
+ await api('DELETE', `/tunnels/${t.id}`, apiKey);
219
+ console.log(`Closed ${t.id.slice(0, 8)} (${t.subdomain})`);
220
+ }
221
+ console.log(`Stopped ${tunnels.length} tunnel(s).`);
222
+ }
223
+ export async function restartTunnel(id) {
224
+ const { apiKey } = requireConfig();
225
+ const oldPid = readPid(id);
226
+ if (oldPid && isProcessAlive(oldPid))
227
+ process.kill(oldPid, 'SIGTERM');
228
+ deletePid(id);
229
+ console.log('Restarting tunnel...');
230
+ const raw = await api('POST', `/tunnels/${id}/restart`, apiKey);
231
+ const cfg = TunnelAllocateResponseSchema.parse(raw);
232
+ const agentBin = await ensureAgent();
233
+ const configPath = path.join(os.tmpdir(), `mockuser-${cfg.id}.toml`);
234
+ fs.writeFileSync(configPath, buildAgentConfig(cfg));
235
+ const newPid = spawnAgentDaemon(agentBin, configPath, cfg.id);
236
+ console.log(`Tunnel restarted: https://${cfg.subdomain} (pid ${newPid})`);
237
+ console.log(`Manage: mockuser tunnel list | close ${cfg.id.slice(0, 8)} | restart ${cfg.id.slice(0, 8)}`);
238
+ }
239
+ function formatAge(date) {
240
+ const secs = Math.floor((Date.now() - date.getTime()) / 1000);
241
+ if (secs < 60)
242
+ return `${secs}s ago`;
243
+ if (secs < 3600)
244
+ return `${Math.floor(secs / 60)}m ago`;
245
+ return `${Math.floor(secs / 3600)}h ago`;
246
+ }
247
+ //# sourceMappingURL=tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAEzD,MAAM,aAAa,GAAG,QAAQ,CAAA;AAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAA;AACzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;AACvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;AAE/C,SAAS,iBAAiB;IACxB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;IAClC,MAAM,GAAG,GAA2C;QAClD,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE;QACtD,KAAK,EAAG,EAAE,KAAK,EAAE,aAAa,EAAG,GAAG,EAAE,aAAa,EAAG;QACtD,KAAK,EAAG,EAAE,GAAG,EAAI,eAAe,EAAsB;KACvD,CAAA;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAA;IACzE,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AACxF,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,IAAY;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;QACvC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YACrB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACrD,IAAI,CAAC,KAAK,EAAE,CAAA;gBACZ,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;gBACnB,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,QAAS,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAC9E,CAAC;YACD,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,EAAE,CAAA;gBACZ,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;gBAC5D,OAAM;YACR,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACd,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YACpD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACxB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAA;IAClC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAE5C,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,OAAO,GAAG,OAAO,aAAa,IAAI,MAAM,SAAS,CAAA;IACvD,MAAM,WAAW,GAAG,sDAAsD,aAAa,IAAI,OAAO,EAAE,CAAA;IACpG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,aAAa,IAAI,MAAM,EAAE,CAAC,CAAA;IAE9E,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;IACzC,MAAM,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAEvC,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,QAAQ,CAAC,aAAa,MAAM,SAAS,aAAa,wBAAwB,CAAC,CAAA;IAC3E,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAErB,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IACjG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;IACvC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAE1D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC/D,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB,EAAE,GAAW;IAC7C,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AACtE,CAAC;AAED,SAAS,OAAO,CAAC,QAAgB;IAC/B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,IAAI,CAAC;QAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAA;IAAC,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc,EAAE,IAAc;IAC9E,IAAI,GAAa,CAAA;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,OAAO,KAAK,EAAE,EAAE;YAC9C,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,MAAM;aACpB;YACD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAA;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,QAAgB;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE;QAChD,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAA;IACF,KAAK,CAAC,KAAK,EAAE,CAAA;IACb,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAI,CAAC,CAAA;IAC9B,OAAO,KAAK,CAAC,GAAI,CAAA;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,GAA4G;IACpI,OAAO;QACL,iBAAiB,GAAG,CAAC,SAAS,GAAG;QACjC,gBAAgB,GAAG,CAAC,OAAO,EAAE;QAC7B,EAAE;QACF,uBAAuB;QACvB,iBAAiB,GAAG,CAAC,KAAK,GAAG;QAC7B,EAAE;QACF,aAAa;QACb,WAAW,GAAG,CAAC,EAAE,GAAG;QACpB,eAAe;QACf,eAAe,GAAG,CAAC,SAAS,EAAE;QAC9B,qBAAqB,GAAG,CAAC,SAAS,IAAI;QACtC,kCAAkC,GAAG,CAAC,SAAS,GAAG;QAClD,iDAAiD,GAAG,CAAC,SAAS,GAAG;KAClE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAyB;IACxD,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IACrD,MAAM,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IAC7D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC9B,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,mCAAmC,SAAS,aAAa,MAAM,CAAC,SAAS,SAAS,GAAG,GAAG,CAAC,CAAA;YACrG,OAAM;QACR,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,yCAAyC,SAAS,KAAK,CAAC,CAAA;QACpE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,YAAY,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;QACtE,MAAM,GAAG,GAAG,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,YAAY,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;QACpE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA;QACnD,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3D,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,CAAC,SAAS,SAAS,IAAI,GAAG,CAAC,CAAA;QACzE,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,SAAS,KAAK,CAAC,CAAA;IACxD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;IAChE,MAAM,GAAG,GAAG,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,CAAC,SAAS,EAAE,CAAC,CAAA;IAEzD,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,YAAY,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IACpE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA;IAEnD,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAC1D,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,SAAS,gBAAgB,SAAS,SAAS,GAAG,GAAG,CAAC,CAAA;IAC1F,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;AAC3G,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;IACpE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAC/C,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,sBAAsB,CAAA;QACvE,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;IACjH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAElC,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,CAAA;IACvB,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IAC5D,SAAS,CAAC,EAAE,CAAC,CAAA;IAEb,MAAM,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;IAC7C,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACzB,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC5D,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACf,MAAM,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;QAC/C,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAA;IAC5D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,CAAC,MAAM,aAAa,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAU;IAC5C,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAElC,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAAA;IAC1B,IAAI,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrE,SAAS,CAAC,EAAE,CAAC,CAAA;IAEb,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAC/D,MAAM,GAAG,GAAG,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEnD,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,YAAY,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IACpE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA;IAEnD,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7D,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,CAAC,SAAS,SAAS,MAAM,GAAG,CAAC,CAAA;IACzE,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;AAC3G,CAAC;AAED,SAAS,SAAS,CAAC,IAAU;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;IAC7D,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,OAAO,CAAA;IACpC,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAA;IACvD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,11 @@
1
+ interface CliConfig {
2
+ apiKey: string;
3
+ }
4
+ export declare function getConfig(): CliConfig | null;
5
+ export declare function saveConfig(cfg: CliConfig): void;
6
+ export declare function requireConfig(): CliConfig;
7
+ export declare function generateApiKey(): string;
8
+ export declare const BACKEND_URL: string;
9
+ export declare const BACKEND_WS_URL: string;
10
+ export {};
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,UAAU,SAAS;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,SAAS,IAAI,SAAS,GAAG,IAAI,CAO5C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAG/C;AAED,wBAAgB,aAAa,IAAI,SAAS,CAOzC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,eAAO,MAAM,WAAW,QAAgE,CAAA;AACxF,eAAO,MAAM,cAAc,QAAqC,CAAA"}
package/dist/config.js ADDED
@@ -0,0 +1,33 @@
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import crypto from 'crypto';
5
+ const CONFIG_DIR = path.join(os.homedir(), '.mockuser');
6
+ const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
7
+ export function getConfig() {
8
+ try {
9
+ const raw = fs.readFileSync(CONFIG_PATH, 'utf8');
10
+ return JSON.parse(raw);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ export function saveConfig(cfg) {
17
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
18
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
19
+ }
20
+ export function requireConfig() {
21
+ const cfg = getConfig();
22
+ if (!cfg) {
23
+ console.error('Not authenticated. Run: mockuser auth <apiKey>');
24
+ process.exit(1);
25
+ }
26
+ return cfg;
27
+ }
28
+ export function generateApiKey() {
29
+ return crypto.randomUUID();
30
+ }
31
+ export const BACKEND_URL = process.env.MOCKUSER_BACKEND_URL ?? 'https://api.mockuser.ai';
32
+ export const BACKEND_WS_URL = BACKEND_URL.replace(/^http/, 'ws');
33
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,MAAM,MAAM,QAAQ,CAAA;AAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAA;AACvD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;AAMxD,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAc;IACvC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7C,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAA;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,MAAM,CAAC,UAAU,EAAE,CAAA;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,yBAAyB,CAAA;AACxF,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { saveApiKey } from './commands/auth.js';
4
+ import { generate } from './commands/generate.js';
5
+ import { openTunnel, listTunnels, closeTunnel, restartTunnel, stopAllTunnels } from './commands/tunnel.js';
6
+ const program = new Command();
7
+ program
8
+ .name('mockuser')
9
+ .description('Mockuser CLI')
10
+ .version('0.0.1');
11
+ program
12
+ .command('auth <apiKey>')
13
+ .description('Save your API key')
14
+ .action(saveApiKey);
15
+ const tunnelCmd = program
16
+ .command('tunnel')
17
+ .description('Manage tunnels');
18
+ tunnelCmd
19
+ .command('open', { isDefault: true })
20
+ .description('Open a new tunnel')
21
+ .requiredOption('-p, --port <port>', 'local port to tunnel')
22
+ .action(openTunnel);
23
+ tunnelCmd
24
+ .command('list')
25
+ .description('List active tunnels')
26
+ .action(listTunnels);
27
+ tunnelCmd
28
+ .command('close <id>')
29
+ .description('Close a tunnel by ID')
30
+ .action(closeTunnel);
31
+ tunnelCmd
32
+ .command('restart <id>')
33
+ .description('Restart a tunnel by ID')
34
+ .action(restartTunnel);
35
+ tunnelCmd
36
+ .command('stop-all')
37
+ .description('Stop and close all active tunnels')
38
+ .action(stopAllTunnels);
39
+ program
40
+ .command('generate')
41
+ .description('Generate and run tests for uncommitted code')
42
+ .requiredOption('-p, --port <port>', 'local port of the tunneled UI')
43
+ .action(generate);
44
+ program.parse();
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1G,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,cAAc,CAAC;KAC3B,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,mBAAmB,CAAC;KAChC,MAAM,CAAC,UAAU,CAAC,CAAA;AAErB,MAAM,SAAS,GAAG,OAAO;KACtB,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,gBAAgB,CAAC,CAAA;AAEhC,SAAS;KACN,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACpC,WAAW,CAAC,mBAAmB,CAAC;KAChC,cAAc,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;KAC3D,MAAM,CAAC,UAAU,CAAC,CAAA;AAErB,SAAS;KACN,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,WAAW,CAAC,CAAA;AAEtB,SAAS;KACN,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,WAAW,CAAC,CAAA;AAEtB,SAAS;KACN,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,aAAa,CAAC,CAAA;AAExB,SAAS;KACN,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,cAAc,CAAC,CAAA;AAEzB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,cAAc,CAAC,mBAAmB,EAAE,+BAA+B,CAAC;KACpE,MAAM,CAAC,QAAQ,CAAC,CAAA;AAEnB,OAAO,CAAC,KAAK,EAAE,CAAA"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@mockuser/cli",
3
+ "version": "0.0.1",
4
+ "description": "CLI for Mockuser — tunnel and test your local apps",
5
+ "type": "module",
6
+ "bin": {
7
+ "mockuser": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18"
14
+ },
15
+ "keywords": [
16
+ "mockuser",
17
+ "tunnel",
18
+ "testing",
19
+ "cli"
20
+ ],
21
+ "license": "MIT",
22
+ "homepage": "https://mockuser.ai",
23
+ "scripts": {
24
+ "dev": "tsx --tsconfig tsconfig.dev.json src/index.ts",
25
+ "build": "tsc",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "dependencies": {
29
+ "@types/ws": "^8.18.1",
30
+ "commander": "^14.0.3",
31
+ "ws": "^8.20.1",
32
+ "zod": "^4.4.3"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.0.0",
36
+ "tsx": "^4.22.3",
37
+ "typescript": "^6.0.3"
38
+ }
39
+ }