tunli 0.2.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 (39) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +39 -0
  3. package/dist/client.js +6 -0
  4. package/dist/client.js.map +1 -1
  5. package/dist/commands/CommandConnect/CommandConnect.d.ts +4 -0
  6. package/dist/commands/CommandConnect/CommandConnect.d.ts.map +1 -0
  7. package/dist/commands/CommandConnect/CommandConnect.js +51 -0
  8. package/dist/commands/CommandConnect/CommandConnect.js.map +1 -0
  9. package/dist/commands/CommandHTTP/CommandHttp.d.ts.map +1 -1
  10. package/dist/commands/CommandHTTP/CommandHttp.js +20 -1
  11. package/dist/commands/CommandHTTP/CommandHttp.js.map +1 -1
  12. package/dist/commands/CommandIdentity/CommandIdentity.d.ts +4 -0
  13. package/dist/commands/CommandIdentity/CommandIdentity.d.ts.map +1 -0
  14. package/dist/commands/CommandIdentity/CommandIdentity.js +18 -0
  15. package/dist/commands/CommandIdentity/CommandIdentity.js.map +1 -0
  16. package/dist/commands/CommandRegister/CommandRegister.d.ts.map +1 -1
  17. package/dist/commands/CommandRegister/CommandRegister.js +7 -0
  18. package/dist/commands/CommandRegister/CommandRegister.js.map +1 -1
  19. package/dist/commands/CommandShare/CommandShare.d.ts +4 -0
  20. package/dist/commands/CommandShare/CommandShare.d.ts.map +1 -0
  21. package/dist/commands/CommandShare/CommandShare.js +55 -0
  22. package/dist/commands/CommandShare/CommandShare.js.map +1 -0
  23. package/dist/identity/identity.d.ts +11 -0
  24. package/dist/identity/identity.d.ts.map +1 -0
  25. package/dist/identity/identity.js +39 -0
  26. package/dist/identity/identity.js.map +1 -0
  27. package/dist/lib/defs.d.ts +2 -0
  28. package/dist/lib/defs.d.ts.map +1 -1
  29. package/dist/lib/defs.js +2 -0
  30. package/dist/lib/defs.js.map +1 -1
  31. package/dist/share/ShareClient.d.ts +35 -0
  32. package/dist/share/ShareClient.d.ts.map +1 -0
  33. package/dist/share/ShareClient.js +83 -0
  34. package/dist/share/ShareClient.js.map +1 -0
  35. package/dist/share/ShareHost.d.ts +40 -0
  36. package/dist/share/ShareHost.d.ts.map +1 -0
  37. package/dist/share/ShareHost.js +83 -0
  38. package/dist/share/ShareHost.js.map +1 -0
  39. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
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
+
3
23
  ## [0.2.0] - 2026-03-24
4
24
 
5
25
  ### Dashboard
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.
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":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,MAAM,EAAoB,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAC,2BAA2B,EAAE,sBAAsB,EAAE,qBAAqB,EAAC,MAAM,WAAW,CAAC;AACrG,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,yBAAyB,EAAC,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAC,qBAAqB,EAAC,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAC,oBAAoB,EAAC,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,sBAAsB,EAAC,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,oBAAoB,EAAC,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,qBAAqB,EAAC,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAC,kBAAkB,EAAC,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAC,oBAAoB,EAAC,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAE1D,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,YAAY,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC,CAAA;AACvG,MAAM,SAAS,GAAG,2BAA2B,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,YAAY,CAAC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzJ,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;AACrC,MAAM,GAAG,GAAY;IACnB,MAAM,EAAE;QACN,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,SAAS;QAChB,iBAAiB,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,qBAAqB,CAAC;KAClE;IACD,IAAI,CAAC,IAAa;QAChB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACzB,CAAC;IACD,SAAS,EAAE,IAAI,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/C,MAAM,EAAE;QACN,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB;CACF,CAAA;AAED,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,oBAAoB,CAAC;KACjC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9C,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;AACtE,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACvD,wDAAwD;AACxD,uDAAuD;AACvD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3D,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACtD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACxD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACtD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACvD,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACpD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AAEtD,OAAO,CAAC,MAAM,CAAC,CAAC,EAAC,OAAO,EAAc,EAAE,EAAE;IACxC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;QACjD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACb,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAA;QAC3F,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACb,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -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.2.0",
4
+ "version": "0.3.0",
5
5
  "main": "bin/tunli",
6
6
  "bin": {
7
7
  "tunli": "bin/tunli"