tunli 0.1.0 → 0.3.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/CHANGELOG.md +30 -0
  2. package/README.md +39 -0
  3. package/dist/cli-app/Dashboard.d.ts.map +1 -1
  4. package/dist/cli-app/Dashboard.js +103 -11
  5. package/dist/cli-app/Dashboard.js.map +1 -1
  6. package/dist/client.js +6 -0
  7. package/dist/client.js.map +1 -1
  8. package/dist/commands/CommandConnect/CommandConnect.d.ts +4 -0
  9. package/dist/commands/CommandConnect/CommandConnect.d.ts.map +1 -0
  10. package/dist/commands/CommandConnect/CommandConnect.js +51 -0
  11. package/dist/commands/CommandConnect/CommandConnect.js.map +1 -0
  12. package/dist/commands/CommandHTTP/CommandHttp.d.ts.map +1 -1
  13. package/dist/commands/CommandHTTP/CommandHttp.js +20 -1
  14. package/dist/commands/CommandHTTP/CommandHttp.js.map +1 -1
  15. package/dist/commands/CommandIdentity/CommandIdentity.d.ts +4 -0
  16. package/dist/commands/CommandIdentity/CommandIdentity.d.ts.map +1 -0
  17. package/dist/commands/CommandIdentity/CommandIdentity.js +18 -0
  18. package/dist/commands/CommandIdentity/CommandIdentity.js.map +1 -0
  19. package/dist/commands/CommandRegister/CommandRegister.d.ts.map +1 -1
  20. package/dist/commands/CommandRegister/CommandRegister.js +7 -0
  21. package/dist/commands/CommandRegister/CommandRegister.js.map +1 -1
  22. package/dist/commands/CommandShare/CommandShare.d.ts +4 -0
  23. package/dist/commands/CommandShare/CommandShare.d.ts.map +1 -0
  24. package/dist/commands/CommandShare/CommandShare.js +55 -0
  25. package/dist/commands/CommandShare/CommandShare.js.map +1 -0
  26. package/dist/identity/identity.d.ts +11 -0
  27. package/dist/identity/identity.d.ts.map +1 -0
  28. package/dist/identity/identity.js +39 -0
  29. package/dist/identity/identity.js.map +1 -0
  30. package/dist/lib/defs.d.ts +2 -0
  31. package/dist/lib/defs.d.ts.map +1 -1
  32. package/dist/lib/defs.js +2 -0
  33. package/dist/lib/defs.js.map +1 -1
  34. package/dist/share/ShareClient.d.ts +35 -0
  35. package/dist/share/ShareClient.d.ts.map +1 -0
  36. package/dist/share/ShareClient.js +83 -0
  37. package/dist/share/ShareClient.js.map +1 -0
  38. package/dist/share/ShareHost.d.ts +40 -0
  39. package/dist/share/ShareHost.d.ts.map +1 -0
  40. package/dist/share/ShareHost.js +83 -0
  41. package/dist/share/ShareHost.js.map +1 -0
  42. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.0] - 2026-03-24
4
+
5
+ ### Share / Connect (private peer-to-peer tunnels)
6
+ - `tunli share <port>` — share a local port privately; outputs a public key for the other party
7
+ - `tunli connect <pubkey>` — connect to a remote share, opens a local TCP port (random or `--port`)
8
+ - Connecting client's public key shown on host side at connect/disconnect
9
+ - `docs/share-relay-spec.md` — relay server implementation spec (Socket.IO `/share` namespace)
10
+
11
+ ### Identity
12
+ - Ed25519 keypair generated once at `tunli register` time, stored in `~/.tunli/identity.key` (private, mode 0600) and `~/.tunli/identity.pub`
13
+ - Public key encoded as `tunli1<base64url>` — recognisable, copy-paste-safe
14
+ - Short fingerprint (8-char hex) for display
15
+ - `tunli identity` — show public key and fingerprint
16
+ - Foundation for private peer-to-peer tunnels (`tunli share` / `tunli connect`)
17
+
18
+ ### `tunli http` foreground mode
19
+ - `--foreground` — run the tunnel in the CLI process without a background daemon; exits when the process is killed
20
+ - `--dashboard` — foreground mode with the live TUI dashboard attached
21
+ - `--logs` — foreground mode with live log output to stdout
22
+
23
+ ## [0.2.0] - 2026-03-24
24
+
25
+ ### Dashboard
26
+ - Request runtime per log entry, color-coded (green <100ms, yellow <500ms, red ≥500ms)
27
+ - Path and status columns dynamically sized to longest entry
28
+ - Pause access log with Ctrl+P — new entries are buffered and flushed on resume
29
+ - Keyboard navigation through log entries (↑↓), Enter opens detail view, Esc exits
30
+ - Detail modal: request/response headers, status, duration, timestamp
31
+ - `dev:dashboard` script for UI development with simulated fake data (`npm run dev:dashboard`)
32
+
3
33
  ## [0.1.0] - 2026-03-23
4
34
 
5
35
  Initial release after full rewrite.
package/README.md CHANGED
@@ -34,6 +34,7 @@ Requires Node.js >= 22.
34
34
  - Profiles & environments
35
35
  - Self-hosted relay servers
36
36
  - CIDR allow/deny access control
37
+ - Private peer-to-peer tunnels (`tunli share` / `tunli connect`) — no public URL, access by key only
37
38
 
38
39
  ## Quick Start
39
40
 
@@ -66,6 +67,14 @@ tunli http 3000 --save myapp # save as a named profile for later reuse
66
67
 
67
68
  Use `--save <name>` to persist the configuration as a profile. You can then start it again with `tunli use <profile>` or `tunli @<profile>`.
68
69
 
70
+ **Foreground mode** — run the tunnel directly in the CLI process without a background daemon:
71
+
72
+ ```bash
73
+ tunli http 3000 --foreground # silent, exits when the process is killed
74
+ tunli http 3000 --dashboard # with live TUI dashboard
75
+ tunli http 3000 --logs # with live log output to stdout
76
+ ```
77
+
69
78
  ### `tunli use <profile>`
70
79
 
71
80
  Start a tunnel using a saved profile. Profiles are created via `tunli http --save` or managed with `tunli profile`.
@@ -182,6 +191,36 @@ tunli profile use staging # set staging as the default profile
182
191
  tunli profile delete staging # remove a profile
183
192
  ```
184
193
 
194
+ ### `tunli identity`
195
+
196
+ Show your tunli identity (public key and fingerprint). The keypair is generated automatically on first `tunli register`.
197
+
198
+ ```bash
199
+ tunli identity
200
+ ```
201
+
202
+ ### `tunli share <port> [host]`
203
+
204
+ Share a local port privately via a peer-to-peer tunnel. No public URL is created — only someone with your public key can connect.
205
+
206
+ ```bash
207
+ tunli share 8080
208
+ # → Your public key: tunli1abc...
209
+ # → Share this: tunli connect tunli1abc...
210
+ ```
211
+
212
+ ### `tunli connect <pubkey>`
213
+
214
+ Connect to a remote share by the host's public key. Opens a local TCP port that proxies to the remote service.
215
+
216
+ ```bash
217
+ tunli connect tunli1abc...
218
+ # → Connected. Service available at localhost:52416
219
+ # → For SSH: ssh -p 52416 user@localhost
220
+
221
+ tunli connect tunli1abc... --port 2222 # fixed local port
222
+ ```
223
+
185
224
  ### `tunli update`
186
225
 
187
226
  Download and apply the latest binary release.
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../src/cli-app/Dashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAiN7D,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,EAAE,iBAAiB,eAAe,SAYpF,CAAA"}
1
+ {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../src/cli-app/Dashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAC,eAAe,EAAW,MAAM,0BAA0B,CAAA;AAgWvE,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,EAAE,iBAAiB,eAAe,SAYpF,CAAA"}
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { render, Box, Text, useInput, useApp, useStdout } from 'ink';
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { Box, render, Text, useApp, useInput, useStdout } from 'ink';
4
4
  import chalk from 'chalk';
5
5
  import QRCode from 'qrcode';
6
6
  import { readPackageJson } from '#package-json/packageJson';
7
7
  import { setCursorVisibility } from '#utils/cliFunctions';
8
8
  import { getAvailableUpdate, performUpdate } from '#cli-app/versionCheck';
9
9
  import { CHECK_FOR_UPDATES } from "#lib/defs";
10
+ const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
10
11
  const SPINNER_CHARS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
11
12
  const Spinner = ({ spinning }) => {
12
13
  const [index, setIndex] = useState(0);
@@ -27,6 +28,20 @@ const QRModal = ({ text, onClose }) => {
27
28
  });
28
29
  return (_jsx(Box, { width: "100%", height: stdout.rows, flexDirection: "column", alignItems: "center", justifyContent: "center", children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [_jsx(Text, { dimColor: true, children: "Press q or Escape to close" }), _jsx(Text, { children: text })] }) }));
29
30
  };
31
+ const DetailModal = ({ entry, onClose }) => {
32
+ const { stdout } = useStdout();
33
+ useInput((input, key) => {
34
+ if (key.escape || input === 'q')
35
+ onClose();
36
+ });
37
+ const reqHeaders = Object.entries(entry.req.headers);
38
+ const resHeaders = Object.entries(entry.res.headers);
39
+ return (_jsx(Box, { width: "100%", height: stdout.rows, flexDirection: "column", alignItems: "center", justifyContent: "center", children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: Math.min(stdout.columns - 4, 100), children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Text, { bold: true, children: [entry.method, " ", entry.path] }), _jsx(Text, { dimColor: true, children: "q / Esc to close" })] }), _jsxs(Box, { marginTop: 1, gap: 4, children: [_jsx(Text, { children: entry.status }), entry.runtime ? _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Duration " }), _jsx(Text, { children: entry.runtime })] }) : null, _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Time " }), _jsx(Text, { children: new Date(entry.id).toLocaleTimeString() })] })] }), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: "Request Headers" }), _jsx(Text, { children: '─'.repeat(40) }), reqHeaders.length === 0
40
+ ? _jsx(Text, { dimColor: true, children: "\u2014" })
41
+ : reqHeaders.map(([k, v]) => (_jsxs(Box, { children: [_jsx(Box, { minWidth: 30, children: _jsx(Text, { color: "cyan", children: k }) }), _jsx(Text, { children: String(v) })] }, k))), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: "Response Headers" }), _jsx(Text, { children: '─'.repeat(40) }), resHeaders.length === 0
42
+ ? _jsx(Text, { dimColor: true, children: "\u2014" })
43
+ : resHeaders.map(([k, v]) => (_jsxs(Box, { children: [_jsx(Box, { minWidth: 30, children: _jsx(Text, { color: "cyan", children: k }) }), _jsx(Text, { children: String(v) })] }, k)))] }) }));
44
+ };
30
45
  const DashboardApp = ({ config, appEventEmitter }) => {
31
46
  const { exit } = useApp();
32
47
  const { stdout } = useStdout();
@@ -42,6 +57,13 @@ const DashboardApp = ({ config, appEventEmitter }) => {
42
57
  const [accessLog, setAccessLog] = useState([]);
43
58
  const [qrText, setQrText] = useState(null);
44
59
  const [latency, setLatency] = useState(null);
60
+ const [paused, setPaused] = useState(false);
61
+ const [cursorIndex, setCursorIndex] = useState(null);
62
+ const [detailEntry, setDetailEntry] = useState(null);
63
+ const runtimeStack = useRef(new Map());
64
+ const pendingLog = useRef([]);
65
+ const accessLogRef = useRef([]);
66
+ const pausedRef = useRef(false);
45
67
  const forwardingUrl = `${config.proxy.proxyURL} -> http://${config.target.host}:${config.target.port}/`;
46
68
  useEffect(() => {
47
69
  if (!CHECK_FOR_UPDATES)
@@ -68,8 +90,15 @@ const DashboardApp = ({ config, appEventEmitter }) => {
68
90
  .on('connect_error', (e) => {
69
91
  setSpinning(true);
70
92
  setConnectionStatus(`${chalk.bold(chalk.red('error'))} - ${e.message}`);
93
+ })
94
+ .on('request', (req) => {
95
+ runtimeStack.current.set(req.requestId, Date.now());
71
96
  })
72
97
  .on('response', (req, res) => {
98
+ const now = Date.now();
99
+ const startTime = runtimeStack.current.get(req.requestId);
100
+ runtimeStack.current.delete(req.requestId);
101
+ const runtimeMs = startTime !== undefined ? now - startTime : undefined;
73
102
  let rspMsg = `${res.statusCode} ${res.statusMessage}`;
74
103
  if (res.statusCode >= 500)
75
104
  rspMsg = chalk.red(rspMsg);
@@ -78,13 +107,25 @@ const DashboardApp = ({ config, appEventEmitter }) => {
78
107
  else
79
108
  rspMsg = chalk.green(rspMsg);
80
109
  rspMsg = chalk.bold(rspMsg);
110
+ let runtime;
111
+ if (runtimeMs !== undefined) {
112
+ const label = `${runtimeMs}ms`;
113
+ runtime = runtimeMs < 100 ? chalk.green(label)
114
+ : runtimeMs < 500 ? chalk.yellow(label)
115
+ : chalk.red(label);
116
+ }
117
+ const entry = { method: req.method, path: req.path, status: rspMsg, runtime, id: now, req, res };
81
118
  setRequestCount(c => c + 1);
82
- setAccessLog(log => [...log, {
83
- method: req.method,
84
- path: req.path,
85
- status: rspMsg,
86
- id: Date.now()
87
- }].slice(-30));
119
+ if (pausedRef.current) {
120
+ pendingLog.current.push(entry);
121
+ }
122
+ else {
123
+ setAccessLog(log => {
124
+ const next = [...log, entry].slice(-30);
125
+ accessLogRef.current = next;
126
+ return next;
127
+ });
128
+ }
88
129
  })
89
130
  .on('client-blocked', (ip) => {
90
131
  setBlockedCount(c => c + 1);
@@ -93,13 +134,14 @@ const DashboardApp = ({ config, appEventEmitter }) => {
93
134
  .on('latency', (ms) => setLatency(ms))
94
135
  .on('request-count', (count) => setRequestCount(count));
95
136
  }, []);
96
- // Ctrl+C always active (even when QR modal is open)
137
+ // Ctrl+C always active
97
138
  useInput((input, key) => {
98
139
  if (key.ctrl && input === 'c') {
99
140
  exit();
100
141
  process.exit(0);
101
142
  }
102
143
  });
144
+ // Main key handler — inactive when any modal is open
103
145
  useInput((input, key) => {
104
146
  if (key.ctrl && input === 'r') {
105
147
  setAvailableUpdate(chalk.yellow('Restarting...'));
@@ -111,6 +153,20 @@ const DashboardApp = ({ config, appEventEmitter }) => {
111
153
  setQrText(url);
112
154
  });
113
155
  }
156
+ if (key.ctrl && input === 'p') {
157
+ const next = !pausedRef.current;
158
+ pausedRef.current = next;
159
+ setPaused(next);
160
+ if (!next) {
161
+ // unpause: flush buffered entries
162
+ setAccessLog(log => {
163
+ const flushed = [...log, ...pendingLog.current].slice(-30);
164
+ accessLogRef.current = flushed;
165
+ pendingLog.current = [];
166
+ return flushed;
167
+ });
168
+ }
169
+ }
114
170
  if (key.ctrl && input === 'u' && latestVersion && !updatingPackage && packageJson) {
115
171
  setUpdatingPackage(true);
116
172
  setAvailableUpdate(chalk.yellow('Updating...'));
@@ -128,13 +184,49 @@ const DashboardApp = ({ config, appEventEmitter }) => {
128
184
  }
129
185
  });
130
186
  }
131
- }, { isActive: qrText === null });
187
+ // cursor navigation
188
+ if (key.upArrow) {
189
+ setCursorIndex(i => {
190
+ if (i === null)
191
+ return 0;
192
+ return Math.max(0, i - 1);
193
+ });
194
+ }
195
+ if (key.downArrow) {
196
+ setCursorIndex(i => {
197
+ const max = accessLogRef.current.length - 1;
198
+ if (i === null)
199
+ return 0;
200
+ return Math.min(max, i + 1);
201
+ });
202
+ }
203
+ if (key.escape) {
204
+ setCursorIndex(null);
205
+ }
206
+ if (key.return && cursorIndex !== null) {
207
+ const displayed = [...accessLogRef.current].reverse();
208
+ const entry = displayed[cursorIndex];
209
+ if (entry)
210
+ setDetailEntry(entry);
211
+ }
212
+ }, { isActive: qrText === null && detailEntry === null });
132
213
  const allowedCidr = config.allowedCidr.length ? config.allowedCidr : null;
133
214
  const deniedCidr = config.deniedCidr.length ? config.deniedCidr : null;
134
215
  if (qrText !== null) {
135
216
  return _jsx(QRModal, { text: qrText, onClose: () => setQrText(null) });
136
217
  }
137
- return (_jsxs(Box, { flexDirection: "column", height: stdout.rows, children: [_jsxs(Box, { width: "100%", justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { children: "tunli " }), _jsx(Spinner, { spinning: spinning })] }), _jsx(Text, { children: "(Ctrl+C to quit)" })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(InfoRow, { label: "Tunnel", value: connectionStatus }), packageJson ? _jsx(InfoRow, { label: "Version", value: packageJson.version }) : null, availableUpdate ? _jsx(InfoRow, { label: chalk.yellow('Update'), value: availableUpdate }) : null, _jsx(InfoRow, { label: "Profile", value: config.profileName }), _jsx(InfoRow, { label: "Config", value: config.filepath }), _jsx(InfoRow, { label: "QR-Code", value: "Ctrl-Q" }), (allowedCidr ?? deniedCidr) ? _jsx(Text, { children: " " }) : null, allowedCidr ? _jsx(InfoRow, { label: "Allowed", value: allowedCidr.join(', ') }) : null, deniedCidr ? _jsx(InfoRow, { label: "Denied", value: deniedCidr.join(', ') }) : null, (allowedCidr ?? deniedCidr) ? (_jsx(InfoRow, { label: "Blocked", value: `${blockedCount}${lastBlockedIp ? ` (${lastBlockedIp})` : ''}` })) : null, _jsx(Text, { children: " " }), _jsx(InfoRow, { label: "Latency", value: latency !== null ? `${latency}ms` : '—' }), _jsx(InfoRow, { label: "Forwarding", value: forwardingUrl }), _jsx(InfoRow, { label: "Connections", value: String(requestCount) })] }), _jsx(Text, { children: " " }), _jsx(Text, { children: " " }), _jsx(Text, { children: "HTTP Requests" }), _jsx(Text, { children: '─'.repeat(stdout.columns) }), _jsx(Box, { flexDirection: "column", children: [...accessLog].reverse().map(entry => (_jsxs(Box, { children: [_jsx(Box, { minWidth: 8, children: _jsx(Text, { children: entry.method }) }), _jsx(Box, { minWidth: 30, children: _jsx(Text, { children: entry.path }) }), _jsx(Text, { children: entry.status })] }, entry.id))) })] }));
218
+ if (detailEntry !== null) {
219
+ return _jsx(DetailModal, { entry: detailEntry, onClose: () => setDetailEntry(null) });
220
+ }
221
+ const displayedLog = [...accessLog].reverse();
222
+ const pathColWidth = Math.max(40, ...accessLog.map(e => e.path.length + 3));
223
+ const statusColWidth = Math.max(20, ...accessLog.map(e => stripAnsi(e.status).length + 3));
224
+ return (_jsxs(Box, { flexDirection: "column", height: stdout.rows, children: [_jsxs(Box, { width: "100%", justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { children: "tunli " }), _jsx(Spinner, { spinning: spinning })] }), _jsx(Text, { children: "(Ctrl+C to quit)" })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(InfoRow, { label: "Tunnel", value: connectionStatus }), packageJson ? _jsx(InfoRow, { label: "Version", value: packageJson.version }) : null, availableUpdate ? _jsx(InfoRow, { label: chalk.yellow('Update'), value: availableUpdate }) : null, _jsx(InfoRow, { label: "Profile", value: config.profileName }), _jsx(InfoRow, { label: "Config", value: config.filepath }), _jsx(InfoRow, { label: "QR-Code", value: "Ctrl-Q" }), (allowedCidr ?? deniedCidr) ? _jsx(Text, { children: " " }) : null, allowedCidr ? _jsx(InfoRow, { label: "Allowed", value: allowedCidr.join(', ') }) : null, deniedCidr ? _jsx(InfoRow, { label: "Denied", value: deniedCidr.join(', ') }) : null, (allowedCidr ?? deniedCidr) ? (_jsx(InfoRow, { label: "Blocked", value: `${blockedCount}${lastBlockedIp ? ` (${lastBlockedIp})` : ''}` })) : null, _jsx(Text, { children: " " }), _jsx(InfoRow, { label: "Latency", value: latency !== null ? `${latency}ms` : '—' }), _jsx(InfoRow, { label: "Forwarding", value: forwardingUrl }), _jsx(InfoRow, { label: "Connections", value: String(requestCount) })] }), _jsx(Text, { children: " " }), _jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Text, { children: ["HTTP Requests", cursorIndex !== null ? chalk.dim(' ↑↓ navigate · Enter detail · Esc exit') : chalk.dim(' ↑↓ navigate · Ctrl+P pause')] }), paused ? _jsxs(Text, { children: [chalk.yellow('PAUSED'), " ", pendingLog.current.length > 0 ? chalk.dim(`+${pendingLog.current.length}`) : ''] }) : null] }), _jsx(Text, { children: '─'.repeat(stdout.columns) }), _jsx(Box, { flexDirection: "column", children: displayedLog.map((entry, i) => {
225
+ const selected = cursorIndex === i;
226
+ const dim = cursorIndex !== null && !selected;
227
+ const prefix = selected ? '›' : ' ';
228
+ return (_jsxs(Box, { children: [_jsx(Box, { minWidth: 2, children: _jsx(Text, { color: "cyan", children: prefix }) }), _jsx(Box, { minWidth: 8, children: _jsx(Text, { dimColor: dim, children: entry.method }) }), _jsx(Box, { minWidth: pathColWidth, children: _jsx(Text, { dimColor: dim, children: entry.path }) }), _jsx(Box, { minWidth: statusColWidth, children: _jsx(Text, { dimColor: dim, children: entry.status }) }), entry.runtime ? _jsx(Text, { dimColor: dim, children: entry.runtime }) : null] }, entry.id));
229
+ }) })] }));
138
230
  };
139
231
  export const initDashboard = (config, appEventEmitter) => {
140
232
  process.stdout.write('\x1b[?1049h'); // enter alternate screen buffer
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../src/cli-app/Dashboard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAE,SAAS,EAAC,MAAM,OAAO,CAAA;AACzC,OAAO,EAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,MAAM,KAAK,CAAA;AAClE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,MAAM,MAAM,QAAQ,CAAA;AAG3B,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAC,mBAAmB,EAAC,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAA;AACvE,OAAO,EAAC,iBAAiB,EAAC,MAAM,WAAW,CAAC;AAS5C,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAEjF,MAAM,OAAO,GAAG,CAAC,EAAC,QAAQ,EAAsB,EAAE,EAAE;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,OAAM;QACrB,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAA;QAChF,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;IAChC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,OAAO,KAAC,IAAI,cAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAQ,CAAA;AACtE,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,EAAC,KAAK,EAAE,KAAK,EAAiC,EAAE,EAAE,CAAC,CAClE,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,QAAQ,EAAE,EAAE,YAAE,KAAC,IAAI,cAAE,KAAK,GAAQ,GAAM,EAC7C,KAAC,IAAI,cAAE,KAAK,GAAQ,IAChB,CACP,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,EAAC,IAAI,EAAE,OAAO,EAAsC,EAAE,EAAE;IACvE,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAE5B,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,EAAE,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,OAAO,CACL,KAAC,GAAG,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAC,cAAc,EAAC,QAAQ,YACvG,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,OAAO,EAAE,CAAC,aAC3E,KAAC,IAAI,IAAC,QAAQ,iDAAkC,EAChD,KAAC,IAAI,cAAE,IAAI,GAAQ,IACf,GACF,CACP,CAAA;AACH,CAAC,CAAA;AAOD,MAAM,YAAY,GAAG,CAAC,EAAC,MAAM,EAAE,eAAe,EAAoB,EAAE,EAAE;IACpE,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,EAAE,CAAA;IACvB,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAC5B,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IAErC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9C,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;IACjF,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC1D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IACvE,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACtD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAa,EAAE,CAAC,CAAA;IAC1D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAE3D,MAAM,aAAa,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,cAAc,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAA;IAEvG,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,iBAAiB;YAAE,OAAM;QAC9B,IAAI,CAAC,WAAW;YAAE,OAAM;QACxB,KAAK,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAC1D,IAAI,OAAO,EAAE,CAAC;gBACZ,gBAAgB,CAAC,OAAO,CAAC,CAAA;gBACzB,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,6BAA6B,OAAO,qBAAqB,CAAC,CAAC,CAAA;YAC7F,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,eAAe;aACZ,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAClB,WAAW,CAAC,KAAK,CAAC,CAAA;YAClB,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACxD,CAAC,CAAC;aACD,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACrB,WAAW,CAAC,IAAI,CAAC,CAAA;YACjB,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACvD,CAAC,CAAC;aACD,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE;YACzB,WAAW,CAAC,IAAI,CAAC,CAAA;YACjB,mBAAmB,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACzE,CAAC,CAAC;aACD,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3B,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,aAAa,EAAE,CAAA;YACrD,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG;gBAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;iBAChD,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG;gBAAE,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;;gBAC5D,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACjC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC3B,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC3B,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE;oBAC3B,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,MAAM;oBACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;iBACf,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAChB,CAAC,CAAC;aACD,EAAE,CAAC,gBAAgB,EAAE,CAAC,EAAE,EAAE,EAAE;YAC3B,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC3B,gBAAgB,CAAC,EAAE,CAAC,CAAA;QACtB,CAAC,CAAC;aACD,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;aACrC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3D,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,oDAAoD;IACpD,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAC9B,IAAI,EAAE,CAAA;YACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAC9B,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAA;YACjD,OAAO,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,CAAA;QAC3B,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAC9B,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,UAAU,EAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACtE,IAAI,CAAC,GAAG;oBAAE,SAAS,CAAC,GAAG,CAAC,CAAA;YAC1B,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,aAAa,IAAI,CAAC,eAAe,IAAI,WAAW,EAAE,CAAC;YAClF,kBAAkB,CAAC,IAAI,CAAC,CAAA;YACxB,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAA;YAC/C,KAAK,aAAa,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;oBAChD,OAAM;gBACR,CAAC;gBACD,kBAAkB,CAAC,KAAK,CAAC,CAAA;gBACzB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChC,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAA;gBAC3F,CAAC;qBAAM,CAAC;oBACN,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;gBAClE,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,EAAE,EAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EAAC,CAAC,CAAA;IAE/B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAA;IACzE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA;IAEtE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,KAAC,OAAO,IAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAI,CAAA;IAClE,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,MAAM,EAAE,MAAM,CAAC,IAAI,aAC7C,MAAC,GAAG,IAAC,KAAK,EAAC,MAAM,EAAC,cAAc,EAAC,eAAe,aAC9C,MAAC,GAAG,eACF,KAAC,IAAI,yBAAc,EACnB,KAAC,OAAO,IAAC,QAAQ,EAAE,QAAQ,GAAI,IAC3B,EACN,KAAC,IAAI,mCAAwB,IACzB,EACN,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,KAAC,OAAO,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,gBAAgB,GAAI,EAClD,WAAW,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,WAAW,CAAC,OAAO,GAAI,CAAC,CAAC,CAAC,IAAI,EAC5E,eAAe,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,eAAe,GAAI,CAAC,CAAC,CAAC,IAAI,EAC5F,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,MAAM,CAAC,WAAW,GAAI,EACtD,KAAC,OAAO,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,GAAI,EAClD,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAC,QAAQ,GAAG,EACzC,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,KAAC,IAAI,oBAAS,CAAC,CAAC,CAAC,IAAI,EACnD,WAAW,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC,CAAC,IAAI,EAC/E,UAAU,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC,CAAC,IAAI,EAC5E,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAC7B,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,GAAG,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAI,CACnG,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,IAAI,oBAAS,EACd,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,GAAI,EAC3E,KAAC,OAAO,IAAC,KAAK,EAAC,YAAY,EAAC,KAAK,EAAE,aAAa,GAAI,EACpD,KAAC,OAAO,IAAC,KAAK,EAAC,aAAa,EAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,GAAI,IACxD,EACN,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,gCAAqB,EAC1B,KAAC,IAAI,cAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAQ,EACzC,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CACrC,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,YAAE,KAAC,IAAI,cAAE,KAAK,CAAC,MAAM,GAAQ,GAAM,EACnD,KAAC,GAAG,IAAC,QAAQ,EAAE,EAAE,YAAE,KAAC,IAAI,cAAE,KAAK,CAAC,IAAI,GAAQ,GAAM,EAClD,KAAC,IAAI,cAAE,KAAK,CAAC,MAAM,GAAQ,KAHnB,KAAK,CAAC,EAAE,CAIZ,CACP,CAAC,GACE,IACF,CACP,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAqB,EAAE,eAAgC,EAAE,EAAE;IACvF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA,CAAC,gCAAgC;IACpE,mBAAmB,CAAC,KAAK,CAAC,CAAA;IAE1B,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA,CAAC,gCAAgC;QACpE,mBAAmB,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAEnC,MAAM,CAAC,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,GAAI,EAAE,EAAC,WAAW,EAAE,KAAK,EAAC,CAAC,CAAA;AAClG,CAAC,CAAA"}
1
+ {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../src/cli-app/Dashboard.tsx"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -19,6 +19,9 @@ import { createCommandLogs } from "#commands/CommandLogs/CommandLogs";
19
19
  import { createCommandStop } from "#commands/CommandStop/CommandStop";
20
20
  import { createCommandRestart } from "#commands/CommandRestart/CommandRestart";
21
21
  import { createCommandUpdate } from "#commands/CommandUpdate/CommandUpdate";
22
+ import { createCommandIdentity } from "#commands/CommandIdentity/CommandIdentity";
23
+ import { createCommandShare } from "#commands/CommandShare/CommandShare";
24
+ import { createCommandConnect } from "#commands/CommandConnect/CommandConnect";
22
25
  import { ApiClient } from "#api-client/ApiClient";
23
26
  import { readPackageJson } from "#package-json/packageJson";
24
27
  const globalConf = new ParsedGlobalConfig(readJsonFile(GLOBAL_CONFIG_FILEPATH), GLOBAL_CONFIG_FILEPATH);
@@ -61,6 +64,9 @@ program.addCommand(createCommandLogs(ctx, program));
61
64
  program.addCommand(createCommandStop(ctx, program));
62
65
  program.addCommand(createCommandRestart(ctx, program));
63
66
  program.addCommand(createCommandUpdate(ctx, program));
67
+ program.addCommand(createCommandIdentity(ctx, program));
68
+ program.addCommand(createCommandShare(ctx, program));
69
+ program.addCommand(createCommandConnect(ctx, program));
64
70
  program.action(({ options }) => {
65
71
  if (options.version) {
66
72
  ctx.logger.info(`tunli: ${packageJson?.version}`);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from '#commander/index';
2
+ import type { Context } from '#types/types';
3
+ export declare const createCommandConnect: (ctx: Context, _program: Command) => Command;
4
+ //# sourceMappingURL=CommandConnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandConnect.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandConnect/CommandConnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAS,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAKzC,eAAO,MAAM,oBAAoB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA+DnE,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { Argument, Command, Option } from '#commander/index';
2
+ import { ensureIdentity } from '#identity/identity';
3
+ import { createShareClient } from '#share/ShareClient';
4
+ import { DEFAULT_SERVER_NAME } from '#lib/defs';
5
+ export const createCommandConnect = (ctx, _program) => {
6
+ const cmd = new Command('connect')
7
+ .description('Connect to a remote share by public key')
8
+ .addArgument(new Argument('pubkey', 'Public key of the share host (tunli1...)').required())
9
+ .addOption(new Option('port', 'Local port to listen on (default: random)').argument('port').parse(Number));
10
+ cmd.action(async ({ args, options }) => {
11
+ const targetPublicKey = args.pubkey;
12
+ const localPort = options.port ?? 0;
13
+ if (!targetPublicKey.startsWith('tunli1')) {
14
+ ctx.logger.error('Invalid public key. Expected format: tunli1...');
15
+ return ctx.exit(1);
16
+ }
17
+ const serverName = ctx.config.global.activeServer ?? DEFAULT_SERVER_NAME;
18
+ const serverConf = ctx.config.global.server(serverName);
19
+ if (!serverConf.exists() || !serverConf.authToken || !serverConf.url) {
20
+ ctx.logger.error('Not registered. Run `tunli register` first.');
21
+ return ctx.exit(1);
22
+ }
23
+ const serverConfig = { url: serverConf.url, authToken: serverConf.authToken };
24
+ const apiClient = ctx.apiClient.withServer(serverConfig);
25
+ const connectInfoResult = await apiClient.connectInfo();
26
+ if (connectInfoResult.error) {
27
+ ctx.logger.error(`Failed to reach relay: ${connectInfoResult.error.message}`);
28
+ return ctx.exit(1);
29
+ }
30
+ const { socketUrl, capturePath } = connectInfoResult.data;
31
+ const identity = ensureIdentity();
32
+ ctx.logger.info(`Connecting to share ${targetPublicKey}...`);
33
+ const client = createShareClient(serverConfig, socketUrl, capturePath, identity, targetPublicKey, localPort, (event) => {
34
+ if (event.type === 'connected') {
35
+ ctx.logger.info(`Connected. Service available at localhost:${event.localPort}`);
36
+ ctx.logger.info(`For SSH: ssh -p ${event.localPort} user@localhost`);
37
+ }
38
+ else if (event.type === 'error') {
39
+ ctx.logger.error(`Connection failed: ${event.message}`);
40
+ process.exit(1);
41
+ }
42
+ else if (event.type === 'disconnected') {
43
+ ctx.logger.info('Share host disconnected.');
44
+ }
45
+ });
46
+ process.on('SIGINT', () => { client.disconnect(); process.exit(0); });
47
+ process.on('SIGTERM', () => { client.disconnect(); process.exit(0); });
48
+ });
49
+ return cmd;
50
+ };
51
+ //# sourceMappingURL=CommandConnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandConnect.js","sourceRoot":"","sources":["../../../src/commands/CommandConnect/CommandConnect.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommandHttp.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAQ1C,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA+ChE,CAAA"}
1
+ {"version":3,"file":"CommandHttp.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAY1C,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA6DhE,CAAA"}
@@ -1,9 +1,13 @@
1
- import { Argument, Command } from "#commander/index";
1
+ import { Argument, Command, Option } from "#commander/index";
2
2
  import { checkPort } from "#utils/checkFunctions";
3
3
  import { resolveConfig } from "#commands/CommandConfig/utils/resolveConfig";
4
4
  import { addSharedOptions } from "#commands/CommandConfig/utils/sharedOptions";
5
5
  import { validateProfileConfig } from "#config/validations/validateProfileConfig";
6
6
  import { DaemonClient } from "#daemon/DaemonClient";
7
+ import { AppEventEmitter } from "#cli-app/AppEventEmitter";
8
+ import { createProxy } from "#proxy/Proxy";
9
+ import { initDashboard } from "#cli-app/Dashboard";
10
+ import { initLiveLog } from "#cli-app/LiveLog";
7
11
  export const createCommandHttp = (ctx, _program) => {
8
12
  const cmd = new Command('http')
9
13
  .description('Start a tunnel to a local HTTP service')
@@ -11,6 +15,9 @@ export const createCommandHttp = (ctx, _program) => {
11
15
  addSharedOptions(cmd, 'save');
12
16
  cmd.addArgument(new Argument('port', 'Local port to forward (e.g. 3000)').required().parse(checkPort));
13
17
  cmd.addArgument(new Argument('host', 'Local host to forward to (default: localhost)'));
18
+ cmd.addOption(new Option('foreground', 'Run tunnel in the foreground (no daemon)'));
19
+ cmd.addOption(new Option('dashboard', 'Show live dashboard (implies --foreground)'));
20
+ cmd.addOption(new Option('logs', 'Show live log output (implies --foreground)'));
14
21
  cmd.action(async ({ args, options }) => {
15
22
  const port = args.port;
16
23
  const host = args.host ?? 'localhost';
@@ -24,6 +31,18 @@ export const createCommandHttp = (ctx, _program) => {
24
31
  const validated = await validateProfileConfig(ctx, config);
25
32
  if (opts.save)
26
33
  config.save();
34
+ if (opts.foreground || opts.dashboard || opts.logs) {
35
+ const appEmitter = new AppEventEmitter();
36
+ const proxy = await createProxy(validated, appEmitter);
37
+ process.once('exit', () => proxy.disconnect());
38
+ process.on('SIGINT', () => process.exit(0));
39
+ process.on('SIGTERM', () => process.exit(0));
40
+ if (opts.dashboard)
41
+ initDashboard(validated, appEmitter);
42
+ else if (opts.logs)
43
+ initLiveLog(validated, appEmitter);
44
+ return;
45
+ }
27
46
  await DaemonClient.ensureRunning();
28
47
  const client = new DaemonClient();
29
48
  const result = await client.send({
@@ -1 +1 @@
1
- {"version":3,"file":"CommandHttp.js","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommandHttp.js","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from '#commander/index';
2
+ import type { Context } from '#types/types';
3
+ export declare const createCommandIdentity: (ctx: Context, _program: Command) => Command;
4
+ //# sourceMappingURL=CommandIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandIdentity.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandIdentity/CommandIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAmB,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAIzC,eAAO,MAAM,qBAAqB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YAepE,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { Command } from '#commander/index';
2
+ import { ensureIdentity, encodePublicKey, fingerprint } from '#identity/identity';
3
+ import { IDENTITY_KEY_PATH, IDENTITY_PUB_PATH } from '#lib/defs';
4
+ export const createCommandIdentity = (ctx, _program) => {
5
+ const cmd = new Command('identity')
6
+ .description('Show your tunli identity (public key and fingerprint)');
7
+ cmd.action((_) => {
8
+ const identity = ensureIdentity();
9
+ const pubKey = encodePublicKey(identity.publicKeyRaw);
10
+ const fp = fingerprint(identity.publicKeyRaw);
11
+ ctx.logger.info(`Public key: ${pubKey}`);
12
+ ctx.logger.info(`Fingerprint: ${fp}`);
13
+ ctx.logger.info(`Key file: ${IDENTITY_KEY_PATH}`);
14
+ ctx.logger.info(`Pub file: ${IDENTITY_PUB_PATH}`);
15
+ });
16
+ return cmd;
17
+ };
18
+ //# sourceMappingURL=CommandIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandIdentity.js","sourceRoot":"","sources":["../../../src/commands/CommandIdentity/CommandIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAmB,MAAM,kBAAkB,CAAA;AAE1D,OAAO,EAAC,cAAc,EAAE,eAAe,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,WAAW,CAAA;AAE9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAY,EAAE,QAAiB,EAAE,EAAE;IACvE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,uDAAuD,CAAC,CAAA;IAEvE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAc,EAAE,EAAE;QAC5B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QACrD,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAA;QACzC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;QACrC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,iBAAiB,EAAE,CAAC,CAAA;QACpD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,iBAAiB,EAAE,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommandRegister.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAG1C,eAAO,MAAM,qBAAqB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YAsDpE,CAAA"}
1
+ {"version":3,"file":"CommandRegister.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAI1C,eAAO,MAAM,qBAAqB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA6DpE,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { Command, Option } from "#commander/index";
2
2
  import { DEFAULT_API_SERVER_URL, DEFAULT_SERVER_NAME } from "#lib/defs";
3
+ import { encodePublicKey, ensureIdentity, fingerprint, loadIdentity } from "#identity/identity";
3
4
  export const createCommandRegister = (ctx, _program) => {
4
5
  const cmd = new Command('register')
5
6
  .description('Register a new account and store the auth token')
@@ -33,6 +34,12 @@ export const createCommandRegister = (ctx, _program) => {
33
34
  .setAuthToken(data)
34
35
  .save();
35
36
  ctx.logger.info(`Registration successful. Relay: ${opt.relay} (${serverName})`);
37
+ const isNew = loadIdentity() === null;
38
+ const identity = ensureIdentity();
39
+ if (isNew) {
40
+ ctx.logger.info(`Identity key generated: ${encodePublicKey(identity.publicKeyRaw)}`);
41
+ ctx.logger.info(`Fingerprint: ${fingerprint(identity.publicKeyRaw)}`);
42
+ }
36
43
  });
37
44
  cmd.extendUsage();
38
45
  cmd.addExample('register', 'Register a new account against tunli.app');
@@ -1 +1 @@
1
- {"version":3,"file":"CommandRegister.js","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,MAAM,EAAmB,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAC,sBAAsB,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAY,EAAE,QAAiB,EAAE,EAAE;IAQvE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,iDAAiD,CAAC;SAC9D,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,yDAAyD,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACpG,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,2EAA2E,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;SAC3J,SAAS,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,gFAAgF,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAEjK,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAC,OAAO,EAAc,EAAE,EAAE;QAC1C,MAAM,GAAG,GAAG,OAAkB,CAAA;QAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,IAAI,CAAA;QAChC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,mBAAmB,CAAA;QACpF,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAEvD,IAAI,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;YACnE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAED,MAAM,EAAC,IAAI,EAAE,KAAK,EAAC,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE7D,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,KAAK,EAAE,CAAC;gBACV,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;YAClE,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,UAAU,CAAA;QAC7C,CAAC;QAED,UAAU;aACP,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;aACjB,YAAY,CAAC,IAAI,CAAC;aAClB,IAAI,EAAE,CAAA;QAET,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,GAAG,CAAC,KAAK,KAAK,UAAU,GAAG,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,WAAW,EAAE,CAAA;IACjB,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,0CAA0C,CAAC,CAAA;IACtE,GAAG,CAAC,UAAU,CAAC,0DAA0D,EAAE,6CAA6C,CAAC,CAAA;IACzH,GAAG,CAAC,UAAU,CAAC,kBAAkB,EAAE,gDAAgD,CAAC,CAAA;IAEpF,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
1
+ {"version":3,"file":"CommandRegister.js","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from '#commander/index';
2
+ import type { Context } from '#types/types';
3
+ export declare const createCommandShare: (ctx: Context, _program: Command) => Command;
4
+ //# sourceMappingURL=CommandShare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandShare.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandShare/CommandShare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAKzC,eAAO,MAAM,kBAAkB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YAgEjE,CAAA"}
@@ -0,0 +1,55 @@
1
+ import { Argument, Command } from '#commander/index';
2
+ import { ensureIdentity, encodePublicKey, fingerprint } from '#identity/identity';
3
+ import { createShareHost } from '#share/ShareHost';
4
+ import { DEFAULT_SERVER_NAME } from '#lib/defs';
5
+ export const createCommandShare = (ctx, _program) => {
6
+ const cmd = new Command('share')
7
+ .description('Share a local port via a private peer-to-peer tunnel')
8
+ .addArgument(new Argument('port', 'Local port to share').required().parse(Number))
9
+ .addArgument(new Argument('host', 'Local host to share (default: localhost)'));
10
+ cmd.action(async ({ args }) => {
11
+ const port = args.port;
12
+ const host = args.host ?? 'localhost';
13
+ const serverName = ctx.config.global.activeServer ?? DEFAULT_SERVER_NAME;
14
+ const serverConf = ctx.config.global.server(serverName);
15
+ if (!serverConf.exists() || !serverConf.authToken || !serverConf.url) {
16
+ ctx.logger.error('Not registered. Run `tunli register` first.');
17
+ return ctx.exit(1);
18
+ }
19
+ const serverConfig = { url: serverConf.url, authToken: serverConf.authToken };
20
+ const apiClient = ctx.apiClient.withServer(serverConfig);
21
+ const connectInfoResult = await apiClient.connectInfo();
22
+ if (connectInfoResult.error) {
23
+ ctx.logger.error(`Failed to reach relay: ${connectInfoResult.error.message}`);
24
+ return ctx.exit(1);
25
+ }
26
+ const { socketUrl, capturePath } = connectInfoResult.data;
27
+ const identity = ensureIdentity();
28
+ const pubKey = encodePublicKey(identity.publicKeyRaw);
29
+ const fp = fingerprint(identity.publicKeyRaw);
30
+ ctx.logger.info(`Sharing ${host}:${port}`);
31
+ ctx.logger.info(`Your public key: ${pubKey}`);
32
+ ctx.logger.info(`Fingerprint: ${fp}`);
33
+ ctx.logger.info(`Share this with the other party:`);
34
+ ctx.logger.info(` tunli connect ${pubKey}`);
35
+ ctx.logger.info(`Waiting for connections... (Ctrl+C to stop)`);
36
+ const host_ = createShareHost(serverConfig, socketUrl, capturePath, identity, host, port, (event) => {
37
+ if (event.type === 'registered') {
38
+ ctx.logger.info('Registered with relay.');
39
+ }
40
+ else if (event.type === 'client-connected') {
41
+ ctx.logger.info(`Client connected: ${event.publicKey}`);
42
+ }
43
+ else if (event.type === 'client-disconnected') {
44
+ ctx.logger.info(`Client disconnected: ${event.publicKey}`);
45
+ }
46
+ else if (event.type === 'error') {
47
+ ctx.logger.error(`Share error: ${event.message}`);
48
+ }
49
+ });
50
+ process.on('SIGINT', () => { host_.disconnect(); process.exit(0); });
51
+ process.on('SIGTERM', () => { host_.disconnect(); process.exit(0); });
52
+ });
53
+ return cmd;
54
+ };
55
+ //# sourceMappingURL=CommandShare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandShare.js","sourceRoot":"","sources":["../../../src/commands/CommandShare/CommandShare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type Identity = {
2
+ privateKeyPem: string;
3
+ publicKeyRaw: Buffer;
4
+ };
5
+ export declare const encodePublicKey: (publicKeyRaw: Buffer) => string;
6
+ export declare const decodePublicKey: (encoded: string) => Buffer;
7
+ export declare const fingerprint: (publicKeyRaw: Buffer) => string;
8
+ export declare const saveIdentity: (identity: Identity) => void;
9
+ export declare const loadIdentity: () => Identity | null;
10
+ export declare const ensureIdentity: () => Identity;
11
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity/identity.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,GAAG;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,MACJ,CAAA;AAEnD,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAGjD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,cAAc,MAAM,KAAG,MACkB,CAAA;AAUrE,eAAO,MAAM,YAAY,GAAI,UAAU,QAAQ,KAAG,IAIjD,CAAA;AAED,eAAO,MAAM,YAAY,QAAO,QAAQ,GAAG,IAK1C,CAAA;AAED,eAAO,MAAM,cAAc,QAAO,QAMjC,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { createHash, generateKeyPairSync } from 'node:crypto';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { GLOBAL_CONFIG_DIR, IDENTITY_KEY_PATH, IDENTITY_PUB_PATH } from '#lib/defs';
4
+ const TUNLI_PREFIX = 'tunli1';
5
+ export const encodePublicKey = (publicKeyRaw) => TUNLI_PREFIX + publicKeyRaw.toString('base64url');
6
+ export const decodePublicKey = (encoded) => {
7
+ if (!encoded.startsWith(TUNLI_PREFIX))
8
+ throw new Error('Invalid tunli public key');
9
+ return Buffer.from(encoded.slice(TUNLI_PREFIX.length), 'base64url');
10
+ };
11
+ export const fingerprint = (publicKeyRaw) => createHash('sha256').update(publicKeyRaw).digest('hex').slice(0, 8);
12
+ const generate = () => {
13
+ const { privateKey, publicKey } = generateKeyPairSync('ed25519');
14
+ const privateKeyPem = privateKey.export({ type: 'pkcs8', format: 'pem' });
15
+ // SPKI DER for Ed25519: 12-byte header + 32-byte raw key
16
+ const publicKeyRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(-32);
17
+ return { privateKeyPem, publicKeyRaw };
18
+ };
19
+ export const saveIdentity = (identity) => {
20
+ mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
21
+ writeFileSync(IDENTITY_KEY_PATH, identity.privateKeyPem, { encoding: 'utf-8', mode: 0o600 });
22
+ writeFileSync(IDENTITY_PUB_PATH, encodePublicKey(identity.publicKeyRaw), { encoding: 'utf-8' });
23
+ };
24
+ export const loadIdentity = () => {
25
+ if (!existsSync(IDENTITY_KEY_PATH) || !existsSync(IDENTITY_PUB_PATH))
26
+ return null;
27
+ const privateKeyPem = readFileSync(IDENTITY_KEY_PATH, 'utf-8');
28
+ const publicKeyRaw = decodePublicKey(readFileSync(IDENTITY_PUB_PATH, 'utf-8').trim());
29
+ return { privateKeyPem, publicKeyRaw };
30
+ };
31
+ export const ensureIdentity = () => {
32
+ const existing = loadIdentity();
33
+ if (existing)
34
+ return existing;
35
+ const identity = generate();
36
+ saveIdentity(identity);
37
+ return identity;
38
+ };
39
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity/identity.ts"],"names":[],"mappings":"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"}
@@ -15,4 +15,6 @@ export declare const TUNLI_BIN_DIR: string;
15
15
  export declare const TUNLI_BIN_PATH: string;
16
16
  export declare const TUNLI_BIN_NEW_PATH: string;
17
17
  export declare const RESTART_DUMP_FILEPATH: string;
18
+ export declare const IDENTITY_KEY_PATH: string;
19
+ export declare const IDENTITY_PUB_PATH: string;
18
20
  //# sourceMappingURL=defs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC,eAAO,MAAM,sBAAsB,0BAA0B,CAAA;AAE7D,eAAO,MAAM,yBAAyB,qEAAqE,CAAA;AAE3G,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,eAAO,MAAM,sBAAsB,QAA4C,CAAA;AAE/E,eAAO,MAAM,qBAAqB,QAAyD,CAAA;AAE3F,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAA;AAE7C,eAAO,MAAM,yBAAyB,UAalC,CAAC;AAEL,eAAO,MAAM,2BAA2B,oBAA2D,CAAA;AAEnG,eAAO,MAAM,kBAAkB,QAA4C,CAAA;AAE3E,eAAO,MAAM,aAAa,QAAoC,CAAA;AAC9D,eAAO,MAAM,cAAc,QAAuC,CAAA;AAClE,eAAO,MAAM,kBAAkB,QAA8C,CAAA;AAC7E,eAAO,MAAM,qBAAqB,QAA0C,CAAA"}
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC,eAAO,MAAM,sBAAsB,0BAA0B,CAAA;AAE7D,eAAO,MAAM,yBAAyB,qEAAqE,CAAA;AAE3G,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,eAAO,MAAM,sBAAsB,QAA4C,CAAA;AAE/E,eAAO,MAAM,qBAAqB,QAAyD,CAAA;AAE3F,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAA;AAE7C,eAAO,MAAM,yBAAyB,UAalC,CAAC;AAEL,eAAO,MAAM,2BAA2B,oBAA2D,CAAA;AAEnG,eAAO,MAAM,kBAAkB,QAA4C,CAAA;AAE3E,eAAO,MAAM,aAAa,QAAoC,CAAA;AAC9D,eAAO,MAAM,cAAc,QAAuC,CAAA;AAClE,eAAO,MAAM,kBAAkB,QAA8C,CAAA;AAC7E,eAAO,MAAM,qBAAqB,QAA0C,CAAA;AAE5E,eAAO,MAAM,iBAAiB,QAA6C,CAAA;AAC3E,eAAO,MAAM,iBAAiB,QAA6C,CAAA"}
package/dist/lib/defs.js CHANGED
@@ -30,4 +30,6 @@ export const TUNLI_BIN_DIR = resolve(GLOBAL_CONFIG_DIR, 'bin');
30
30
  export const TUNLI_BIN_PATH = resolve(TUNLI_BIN_DIR, 'tunli-main');
31
31
  export const TUNLI_BIN_NEW_PATH = resolve(TUNLI_BIN_DIR, 'tunli-main.update');
32
32
  export const RESTART_DUMP_FILEPATH = resolve(GLOBAL_CONFIG_DIR, 'dump.json');
33
+ export const IDENTITY_KEY_PATH = resolve(GLOBAL_CONFIG_DIR, 'identity.key');
34
+ export const IDENTITY_PUB_PATH = resolve(GLOBAL_CONFIG_DIR, 'identity.pub');
33
35
  //# sourceMappingURL=defs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defs.js","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAC,MAAM,MAAM,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAE7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,kEAAkE,CAAA;AAE3G,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAEvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAE7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE;IAC7C,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,GAAG,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACjG,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAK;QACvC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,CAAA;IACvE,CAAC,QAAQ,mBAAmB,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,mBAAmB,CAAC,MAAM,EAAC;IAE/E,OAAO,YAAY,CAAA;AACrB,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AAEnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA"}
1
+ {"version":3,"file":"defs.js","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAC,MAAM,MAAM,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAE7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,kEAAkE,CAAA;AAE3G,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAEvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAE7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE;IAC7C,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,GAAG,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACjG,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAK;QACvC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,CAAA;IACvE,CAAC,QAAQ,mBAAmB,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,mBAAmB,CAAC,MAAM,EAAC;IAE/E,OAAO,YAAY,CAAA;AACrB,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AAEnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;AAE5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Share client (Bob side) — Bob runs `tunli connect <pubkey>`.
3
+ *
4
+ * Connects to the relay's `/share` Socket.IO namespace and requests
5
+ * a connection to Alice's share by her public key. Once the relay
6
+ * confirms the session, a local TCP server is started on `localPort`
7
+ * (0 = OS-assigned). Any TCP client connecting to that port (e.g. an
8
+ * SSH client) gets its data piped through the relay to Alice's machine.
9
+ *
10
+ * Required relay events (server → client):
11
+ * share-connected {sessionId} — relay confirmed the session
12
+ * share-error {message} — connection refused / not found
13
+ * share-data {sessionId, data} — data from Alice
14
+ * share-end {sessionId} — Alice disconnected
15
+ *
16
+ * Required relay events (client → server):
17
+ * share-connect {targetPublicKey, publicKey} — request connection to Alice; publicKey is Bob's own key so Alice can identify the caller
18
+ * share-data {sessionId, data}
19
+ * share-end {sessionId}
20
+ */
21
+ import type { ServerConfig } from '#types/types';
22
+ import type { Identity } from '#identity/identity';
23
+ export type ShareClientEvent = {
24
+ type: 'connected';
25
+ localPort: number;
26
+ } | {
27
+ type: 'error';
28
+ message: string;
29
+ } | {
30
+ type: 'disconnected';
31
+ };
32
+ export declare const createShareClient: (serverConfig: ServerConfig, socketUrl: string, socketPath: string, identity: Identity, targetPublicKey: string, localPort: number, onEvent: (event: ShareClientEvent) => void) => {
33
+ disconnect: () => void;
34
+ };
35
+ //# sourceMappingURL=ShareClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareClient.d.ts","sourceRoot":"","sources":["../../src/share/ShareClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAGhD,MAAM,MAAM,gBAAgB,GACxB;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GACtC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAChC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAC,CAAA;AAE1B,eAAO,MAAM,iBAAiB,GAC5B,cAAc,YAAY,EAC1B,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,UAAU,QAAQ,EAClB,iBAAiB,MAAM,EACvB,WAAW,MAAM,EACjB,SAAS,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,KACzC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAA;CAoEzB,CAAA"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Share client (Bob side) — Bob runs `tunli connect <pubkey>`.
3
+ *
4
+ * Connects to the relay's `/share` Socket.IO namespace and requests
5
+ * a connection to Alice's share by her public key. Once the relay
6
+ * confirms the session, a local TCP server is started on `localPort`
7
+ * (0 = OS-assigned). Any TCP client connecting to that port (e.g. an
8
+ * SSH client) gets its data piped through the relay to Alice's machine.
9
+ *
10
+ * Required relay events (server → client):
11
+ * share-connected {sessionId} — relay confirmed the session
12
+ * share-error {message} — connection refused / not found
13
+ * share-data {sessionId, data} — data from Alice
14
+ * share-end {sessionId} — Alice disconnected
15
+ *
16
+ * Required relay events (client → server):
17
+ * share-connect {targetPublicKey, publicKey} — request connection to Alice; publicKey is Bob's own key so Alice can identify the caller
18
+ * share-data {sessionId, data}
19
+ * share-end {sessionId}
20
+ */
21
+ import net from 'node:net';
22
+ import { io } from 'socket.io-client';
23
+ import { encodePublicKey } from '#identity/identity';
24
+ export const createShareClient = (serverConfig, socketUrl, socketPath, identity, targetPublicKey, localPort, onEvent) => {
25
+ const shareUrl = socketUrl.replace(/\/$/, '') + '/share';
26
+ const socket = io(shareUrl, {
27
+ path: socketPath,
28
+ auth: { token: serverConfig.authToken },
29
+ });
30
+ // One session per local TCP client connection.
31
+ // Currently the relay creates one session per `share-connect`, so we
32
+ // only track the single active one. Multi-client support can be added
33
+ // on both sides later.
34
+ let sessionId = null;
35
+ let activeTcpClient = null;
36
+ const server = net.createServer();
37
+ socket.on('connect', () => {
38
+ socket.emit('share-connect', { targetPublicKey, publicKey: encodePublicKey(identity.publicKeyRaw) });
39
+ });
40
+ socket.on('share-connected', ({ sessionId: sid }) => {
41
+ sessionId = sid;
42
+ if (server.listening)
43
+ return;
44
+ server.listen(localPort, '127.0.0.1', () => {
45
+ const addr = server.address();
46
+ onEvent({ type: 'connected', localPort: addr.port });
47
+ });
48
+ server.on('connection', (client) => {
49
+ activeTcpClient = client;
50
+ // Notify Alice that a local TCP client has connected — she should now
51
+ // open the TCP connection to her local service.
52
+ socket.emit('share-session-start', { sessionId });
53
+ client.on('data', (chunk) => {
54
+ if (sessionId)
55
+ socket.emit('share-data', { sessionId, data: chunk });
56
+ });
57
+ const closeClient = () => {
58
+ if (sessionId)
59
+ socket.emit('share-end', { sessionId });
60
+ activeTcpClient = null;
61
+ };
62
+ client.on('end', closeClient);
63
+ client.on('error', closeClient);
64
+ });
65
+ });
66
+ socket.on('share-error', ({ message }) => onEvent({ type: 'error', message }));
67
+ socket.on('share-data', ({ data }) => {
68
+ activeTcpClient?.write(Buffer.from(data));
69
+ });
70
+ socket.on('share-end', () => {
71
+ activeTcpClient?.end();
72
+ activeTcpClient = null;
73
+ onEvent({ type: 'disconnected' });
74
+ });
75
+ return {
76
+ disconnect: () => {
77
+ activeTcpClient?.destroy();
78
+ server.close();
79
+ socket.disconnect();
80
+ },
81
+ };
82
+ };
83
+ //# sourceMappingURL=ShareClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareClient.js","sourceRoot":"","sources":["../../src/share/ShareClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Share host (server side) — Alice runs `tunli share <port>`.
3
+ *
4
+ * Connects to the relay's `/share` Socket.IO namespace and registers
5
+ * with her public key. The relay bridges incoming client connections
6
+ * to this socket. For each session, a TCP connection is opened to the
7
+ * local target (host:port) and data is piped in both directions.
8
+ *
9
+ * Required relay events (server → client):
10
+ * share-registered — registration confirmed
11
+ * share-error {message} — registration or session error
12
+ * share-client {sessionId} — a client has connected
13
+ * share-data {sessionId, data: Buffer} — data from a client
14
+ * share-end {sessionId} — client disconnected
15
+ *
16
+ * Required relay events (client → server):
17
+ * share-register {publicKey} — register as share host
18
+ * share-data {sessionId, data: Buffer}
19
+ * share-end {sessionId}
20
+ */
21
+ import type { ServerConfig } from '#types/types';
22
+ import { type Identity } from '#identity/identity';
23
+ export type ShareHostEvent = {
24
+ type: 'registered';
25
+ } | {
26
+ type: 'client-connected';
27
+ sessionId: string;
28
+ publicKey: string;
29
+ } | {
30
+ type: 'client-disconnected';
31
+ sessionId: string;
32
+ publicKey: string;
33
+ } | {
34
+ type: 'error';
35
+ message: string;
36
+ };
37
+ export declare const createShareHost: (serverConfig: ServerConfig, socketUrl: string, socketPath: string, identity: Identity, targetHost: string, targetPort: number, onEvent: (event: ShareHostEvent) => void) => {
38
+ disconnect: () => void;
39
+ };
40
+ //# sourceMappingURL=ShareHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareHost.d.ts","sourceRoot":"","sources":["../../src/share/ShareHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAkB,KAAK,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAEjE,MAAM,MAAM,cAAc,GACtB;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC,GACpB;IAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GAChE;IAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GACnE;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAA;AAEpC,eAAO,MAAM,eAAe,GAC1B,cAAc,YAAY,EAC1B,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,UAAU,QAAQ,EAClB,YAAY,MAAM,EAClB,YAAY,MAAM,EAClB,SAAS,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,KACvC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAA;CAoEzB,CAAA"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Share host (server side) — Alice runs `tunli share <port>`.
3
+ *
4
+ * Connects to the relay's `/share` Socket.IO namespace and registers
5
+ * with her public key. The relay bridges incoming client connections
6
+ * to this socket. For each session, a TCP connection is opened to the
7
+ * local target (host:port) and data is piped in both directions.
8
+ *
9
+ * Required relay events (server → client):
10
+ * share-registered — registration confirmed
11
+ * share-error {message} — registration or session error
12
+ * share-client {sessionId} — a client has connected
13
+ * share-data {sessionId, data: Buffer} — data from a client
14
+ * share-end {sessionId} — client disconnected
15
+ *
16
+ * Required relay events (client → server):
17
+ * share-register {publicKey} — register as share host
18
+ * share-data {sessionId, data: Buffer}
19
+ * share-end {sessionId}
20
+ */
21
+ import net from 'node:net';
22
+ import { io } from 'socket.io-client';
23
+ import { encodePublicKey } from '#identity/identity';
24
+ export const createShareHost = (serverConfig, socketUrl, socketPath, identity, targetHost, targetPort, onEvent) => {
25
+ const shareUrl = socketUrl.replace(/\/$/, '') + '/share';
26
+ const socket = io(shareUrl, {
27
+ path: socketPath,
28
+ auth: { token: serverConfig.authToken },
29
+ });
30
+ const sessions = new Map();
31
+ const sessionKeys = new Map(); // sessionId → publicKey
32
+ socket.on('connect', () => {
33
+ socket.emit('share-register', { publicKey: encodePublicKey(identity.publicKeyRaw) });
34
+ });
35
+ socket.on('share-registered', () => onEvent({ type: 'registered' }));
36
+ socket.on('share-error', ({ message }) => onEvent({ type: 'error', message }));
37
+ socket.on('share-client', ({ sessionId, publicKey }) => {
38
+ // Bob registered — just remember the key, TCP opens on share-session-start
39
+ sessionKeys.set(sessionId, publicKey);
40
+ onEvent({ type: 'client-connected', sessionId, publicKey });
41
+ });
42
+ socket.on('share-session-start', ({ sessionId }) => {
43
+ const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
44
+ const tcp = net.connect(targetPort, targetHost);
45
+ sessions.set(sessionId, tcp);
46
+ tcp.on('data', (chunk) => socket.emit('share-data', { sessionId, data: chunk }));
47
+ const closeSession = () => {
48
+ if (!sessions.has(sessionId))
49
+ return;
50
+ sessions.delete(sessionId);
51
+ sessionKeys.delete(sessionId);
52
+ socket.emit('share-end', { sessionId });
53
+ onEvent({ type: 'client-disconnected', sessionId, publicKey });
54
+ };
55
+ tcp.on('end', closeSession);
56
+ tcp.on('error', (e) => {
57
+ onEvent({ type: 'error', message: `Could not connect to ${targetHost}:${targetPort} — ${e.message}` });
58
+ closeSession();
59
+ });
60
+ });
61
+ socket.on('share-data', ({ sessionId, data }) => {
62
+ sessions.get(sessionId)?.write(Buffer.from(data));
63
+ });
64
+ socket.on('share-end', ({ sessionId }) => {
65
+ const tcp = sessions.get(sessionId);
66
+ if (!tcp)
67
+ return;
68
+ const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
69
+ sessions.delete(sessionId);
70
+ sessionKeys.delete(sessionId);
71
+ tcp.end();
72
+ onEvent({ type: 'client-disconnected', sessionId, publicKey });
73
+ });
74
+ return {
75
+ disconnect: () => {
76
+ for (const tcp of sessions.values())
77
+ tcp.destroy();
78
+ sessions.clear();
79
+ socket.disconnect();
80
+ },
81
+ };
82
+ };
83
+ //# sourceMappingURL=ShareHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareHost.js","sourceRoot":"","sources":["../../src/share/ShareHost.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tunli",
3
3
  "description": "Developer-first HTTP tunneling CLI with daemon-based tunnel management, profiles, and self-hosted server support.",
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "main": "bin/tunli",
6
6
  "bin": {
7
7
  "tunli": "bin/tunli"
@@ -13,7 +13,8 @@
13
13
  "build:main": "npm run clean && tsc && scripts/build-main.sh",
14
14
  "build:launcher": "npm run clean && tsc && scripts/build-launcher.sh",
15
15
  "clean": "rm -rf dist",
16
- "test": "npm run build && node --test",
16
+ "dev:dashboard": "tsx --tsconfig tsconfig.json dev/dashboard-dev.ts",
17
+ "test": "npm run build && node --test test/**",
17
18
  "test:coverage": "npm run build && node --test --experimental-test-coverage --test-coverage-exclude='test/**'",
18
19
  "test:coverage:c8": "npm run build && npx c8 node --test",
19
20
  "test:coverage:lcov": "npm run build && npx c8 --src src node --enable-source-maps --test"