opencode-mobile 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { PushNotificationPlugin, default } from "./push-notifications";
2
2
  export * from "./src/tunnel";
3
- export { startProxy, stopProxy } from "./reverse-proxy";
3
+ export * from "./src/push";
4
+ export * from "./src/utils";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
+ // Single entry point for opencode-mobile plugin
1
2
  export { PushNotificationPlugin, default } from "./push-notifications";
2
3
  export * from "./src/tunnel";
3
- export { startProxy, stopProxy } from "./reverse-proxy";
4
+ export * from "./src/push";
5
+ export * from "./src/utils";
4
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACvE,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -2,6 +2,10 @@
2
2
  * Cloudflare tunnel provider implementation
3
3
  */
4
4
  import type { TunnelConfig, TunnelInfo } from "./types";
5
+ /**
6
+ * Find cloudflared binary in common locations
7
+ */
8
+ export declare function findCloudflared(): string | null;
5
9
  /**
6
10
  * Start a Cloudflare tunnel
7
11
  */
@@ -14,4 +18,8 @@ export declare function stopCloudflareTunnel(): Promise<void>;
14
18
  * Check if cloudflared is installed
15
19
  */
16
20
  export declare function isCloudflareInstalled(): Promise<boolean>;
21
+ /**
22
+ * Get the current Cloudflare tunnel URL
23
+ */
24
+ export declare function getCloudflareUrl(): string | null;
17
25
  //# sourceMappingURL=cloudflare.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKxD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA2CrF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAS9D"}
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKxD;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAa/C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA2DrF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD"}
@@ -4,47 +4,76 @@
4
4
  import { spawn } from "child_process";
5
5
  let cloudflareProcess = null;
6
6
  let cloudflareUrl = null;
7
+ /**
8
+ * Find cloudflared binary in common locations
9
+ */
10
+ export function findCloudflared() {
11
+ const paths = [
12
+ "/usr/local/bin/cloudflared",
13
+ "/usr/bin/cloudflared",
14
+ `${process.env.HOME}/.cloudflared/cloudflared`,
15
+ "/opt/homebrew/bin/cloudflared",
16
+ ];
17
+ for (const p of paths) {
18
+ try {
19
+ if (require("fs").existsSync(p))
20
+ return p;
21
+ }
22
+ catch { }
23
+ }
24
+ return null;
25
+ }
7
26
  /**
8
27
  * Start a Cloudflare tunnel
9
28
  */
10
29
  export async function startCloudflareTunnel(config) {
30
+ const cloudflaredPath = findCloudflared();
31
+ if (!cloudflaredPath)
32
+ throw new Error("cloudflared not found. Install from https://github.com/cloudflare/cloudflared");
11
33
  return new Promise((resolve, reject) => {
12
- try {
13
- const cloudflared = spawn("cloudflared", [
14
- "tunnel",
15
- "--url",
16
- `http://127.0.0.1:${config.port}`,
17
- ]);
18
- cloudflareProcess = cloudflared;
19
- let output = "";
20
- cloudflared.stdout.on("data", (data) => {
21
- output += data.toString();
22
- const match = output.match(/https:\/\/[^\s]+\\.trycloudflare\\.com/);
23
- if (match) {
24
- cloudflareUrl = match[0];
25
- resolve({
26
- url: cloudflareUrl,
27
- tunnelId: "cloudflare",
28
- port: config.port,
29
- provider: "cloudflare",
30
- });
31
- }
32
- });
33
- cloudflared.stderr.on("data", (data) => {
34
- console.error("[Tunnel] Cloudflare stderr:", data.toString());
35
- });
36
- cloudflared.on("error", (err) => {
37
- reject(new Error(`Cloudflare tunnel failed: ${err.message}`));
38
- });
39
- cloudflared.on("close", (code) => {
40
- if (code !== 0 && !cloudflareUrl) {
41
- reject(new Error(`Cloudflare tunnel exited with code ${code}`));
42
- }
43
- });
44
- }
45
- catch (error) {
46
- reject(new Error(`Cloudflare tunnel failed: ${error.message}`));
47
- }
34
+ const timeout = setTimeout(() => reject(new Error("Timeout waiting for cloudflared URL (60s)")), 60000);
35
+ cloudflareProcess = spawn(cloudflaredPath, [
36
+ "tunnel",
37
+ "--url",
38
+ `http://127.0.0.1:${config.port}`,
39
+ ], { stdio: ["ignore", "pipe", "pipe"] });
40
+ const onData = (data) => {
41
+ const line = data.toString().trim();
42
+ const urlMatch = line.match(/https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
43
+ if (urlMatch) {
44
+ const url = urlMatch[0];
45
+ console.log("[Cloudflared] URL:", url);
46
+ clearTimeout(timeout);
47
+ cloudflareUrl = url;
48
+ resolve({
49
+ url: cloudflareUrl,
50
+ tunnelId: cloudflareUrl.split("://")[1].split(".")[0],
51
+ port: config.port,
52
+ provider: "cloudflare",
53
+ });
54
+ }
55
+ else if (line.includes("ERR") || line.includes("error")) {
56
+ console.log("[Cloudflared]", line);
57
+ }
58
+ };
59
+ cloudflareProcess.stdout?.on("data", onData);
60
+ cloudflareProcess.stderr?.on("data", onData);
61
+ cloudflareProcess.on("error", (err) => {
62
+ clearTimeout(timeout);
63
+ reject(err);
64
+ });
65
+ cloudflareProcess.on("exit", (code) => {
66
+ // If no URL was captured, treat as failure even on clean exit
67
+ if (!cloudflareUrl) {
68
+ clearTimeout(timeout);
69
+ reject(new Error("cloudflared exited without providing a tunnel URL"));
70
+ return;
71
+ }
72
+ if (code !== 0 && code !== null) {
73
+ clearTimeout(timeout);
74
+ reject(new Error(`cloudflared exited with code ${code}`));
75
+ }
76
+ });
48
77
  });
49
78
  }
50
79
  /**
@@ -52,23 +81,21 @@ export async function startCloudflareTunnel(config) {
52
81
  */
53
82
  export async function stopCloudflareTunnel() {
54
83
  if (cloudflareProcess) {
55
- cloudflareProcess.kill();
84
+ cloudflareProcess.kill("SIGTERM");
56
85
  cloudflareProcess = null;
57
- cloudflareUrl = null;
58
86
  }
87
+ cloudflareUrl = null;
59
88
  }
60
89
  /**
61
90
  * Check if cloudflared is installed
62
91
  */
63
92
  export async function isCloudflareInstalled() {
64
- try {
65
- const { promisify } = await import("util");
66
- const execAsync = promisify((await import("child_process")).exec);
67
- await execAsync("which cloudflared");
68
- return true;
69
- }
70
- catch {
71
- return false;
72
- }
93
+ return findCloudflared() !== null;
94
+ }
95
+ /**
96
+ * Get the current Cloudflare tunnel URL
97
+ */
98
+ export function getCloudflareUrl() {
99
+ return cloudflareUrl;
73
100
  }
74
101
  //# sourceMappingURL=cloudflare.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,IAAI,iBAAiB,GAAQ,IAAI,CAAC;AAClC,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAoB;IAC9D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,EAAE;gBACvC,QAAQ;gBACR,OAAO;gBACP,oBAAoB,MAAM,CAAC,IAAI,EAAE;aAClC,CAAC,CAAC;YAEH,iBAAiB,GAAG,WAAW,CAAC;YAEhC,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7C,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBACrE,IAAI,KAAK,EAAE,CAAC;oBACV,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,OAAO,CAAC;wBACN,GAAG,EAAE,aAAa;wBAClB,QAAQ,EAAE,YAAY;wBACtB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,QAAQ,EAAE,YAAY;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7C,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBACrC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YAEH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE;gBACvC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,iBAAiB,EAAE,CAAC;QACtB,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACzB,iBAAiB,GAAG,IAAI,CAAC;QACzB,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/tunnel/cloudflare.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * Tunnel manager - unified interface for all tunnel providers
3
3
  */
4
4
  import type { TunnelConfig, TunnelInfo, TunnelDetails } from "./types";
5
+ import { diagnoseNgrok, ensureNgrokReady } from "./ngrok";
5
6
  /**
6
7
  * Start a tunnel with the specified provider
7
8
  */
@@ -15,7 +16,7 @@ export declare function stopTunnel(): Promise<void>;
15
16
  */
16
17
  export declare function displayQR(tunnelInfo: TunnelInfo): Promise<void>;
17
18
  /**
18
- * Get current tunnel details
19
+ * Get current tunnel details with login status
19
20
  */
20
21
  export declare function getTunnelDetails(): TunnelDetails;
21
22
  /**
@@ -26,4 +27,9 @@ export declare function getTunnelInfo(): TunnelInfo | null;
26
27
  * Get current server URL from tunnel
27
28
  */
28
29
  export declare function getServerUrl(): string;
30
+ /**
31
+ * Graceful shutdown
32
+ */
33
+ export declare function gracefulShutdown(): Promise<void>;
34
+ export { diagnoseNgrok, ensureNgrokReady };
29
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAQvE;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAoC3E;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBhD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBrE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAiBhD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAKjD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAGL,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAejB;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAoC3E;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBhD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBrE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAoEhD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAKjD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD;AAYD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,22 +1,23 @@
1
1
  /**
2
2
  * Tunnel manager - unified interface for all tunnel providers
3
3
  */
4
- import { startNgrokTunnel, stopNgrokTunnel } from "./ngrok";
5
- import { startLocaltunnel, stopLocaltunnel } from "./localtunnel";
6
- import { startCloudflareTunnel, stopCloudflareTunnel } from "./cloudflare";
7
- import { displayQRCode } from "../../tunnel-manager";
4
+ import * as fs from "fs";
5
+ import { startNgrokTunnel, stopNgrokTunnel, diagnoseNgrok, ensureNgrokReady } from "./ngrok";
6
+ import { startLocaltunnel, stopLocaltunnel, getLocaltunnelUrl } from "./localtunnel";
7
+ import { startCloudflareTunnel, stopCloudflareTunnel, getCloudflareUrl } from "./cloudflare";
8
+ import { displayQRCode } from "./qrcode";
8
9
  let currentTunnel = null;
9
10
  /**
10
11
  * Start a tunnel with the specified provider
11
12
  */
12
13
  export async function startTunnel(config) {
13
14
  // Validate that we have a proper TunnelConfig object
14
- if (!config || typeof config !== 'object') {
15
+ if (!config || typeof config !== "object") {
15
16
  console.log("[Tunnel] startTunnel called with invalid config type:", typeof config);
16
17
  throw new Error("Invalid tunnel config: config must be an object");
17
18
  }
18
19
  // Check if this looks like the OpenCode client context (has 'client' property)
19
- if ('client' in config) {
20
+ if ("client" in config) {
20
21
  console.log("[Tunnel] startTunnel called with OpenCode client context instead of TunnelConfig");
21
22
  console.log("[Tunnel] This indicates a plugin initialization issue");
22
23
  throw new Error("Invalid tunnel config: received OpenCode client context");
@@ -66,43 +67,90 @@ export async function stopTunnel() {
66
67
  */
67
68
  export async function displayQR(tunnelInfo) {
68
69
  // Validate that we have a proper TunnelInfo object, not the OpenCode client context
69
- if (!tunnelInfo || typeof tunnelInfo !== 'object') {
70
+ if (!tunnelInfo || typeof tunnelInfo !== "object") {
70
71
  console.log("[Tunnel] displayQR called with invalid tunnelInfo type:", typeof tunnelInfo);
71
72
  return;
72
73
  }
73
74
  // Check if this looks like the OpenCode client context (has 'client' property)
74
- if ('client' in tunnelInfo) {
75
+ if ("client" in tunnelInfo) {
75
76
  console.log("[Tunnel] displayQR called with OpenCode client context instead of TunnelInfo");
76
77
  console.log("[Tunnel] This indicates a plugin initialization issue");
77
78
  return;
78
79
  }
79
80
  if (!tunnelInfo?.url) {
80
81
  console.log("[Tunnel] displayQR called with invalid tunnelInfo:", JSON.stringify(tunnelInfo).substring(0, 200));
81
- console.log("[Tunnel] Stack:", new Error().stack?.split('\n').slice(2, 6).join('\n'));
82
+ console.log("[Tunnel] Stack:", new Error().stack?.split("\n").slice(2, 6).join("\n"));
82
83
  return;
83
84
  }
84
85
  await displayQRCode(tunnelInfo.url);
85
86
  }
86
87
  /**
87
- * Get current tunnel details
88
+ * Get current tunnel details with login status
88
89
  */
89
90
  export function getTunnelDetails() {
90
- if (!currentTunnel?.url) {
91
- return {
92
- type: "none",
93
- url: null,
94
- loginStatus: "unknown",
95
- loginId: null,
96
- configPath: null,
97
- };
98
- }
99
- return {
100
- type: currentTunnel.provider,
101
- url: currentTunnel.url,
91
+ const details = {
92
+ type: "none",
93
+ url: null,
102
94
  loginStatus: "unknown",
103
95
  loginId: null,
104
96
  configPath: null,
105
97
  };
98
+ // Determine tunnel type and URL
99
+ if (currentTunnel) {
100
+ details.type = currentTunnel.provider;
101
+ details.url = currentTunnel.url;
102
+ }
103
+ else if (getLocaltunnelUrl()) {
104
+ details.type = "localtunnel";
105
+ details.url = getLocaltunnelUrl();
106
+ }
107
+ else if (getCloudflareUrl()) {
108
+ details.type = "cloudflare";
109
+ details.url = getCloudflareUrl();
110
+ }
111
+ // Get config path for ngrok
112
+ const configPaths = [
113
+ `${process.env.HOME}/Library/Application Support/ngrok/ngrok.yml`,
114
+ `${process.env.HOME}/.config/ngrok/ngrok.yml`,
115
+ "/etc/ngrok/ngrok.yml",
116
+ ];
117
+ for (const p of configPaths) {
118
+ try {
119
+ if (fs.existsSync(p)) {
120
+ details.configPath = p;
121
+ break;
122
+ }
123
+ }
124
+ catch { }
125
+ }
126
+ // Check ngrok config for login status
127
+ if (details.configPath && details.type === "ngrok") {
128
+ try {
129
+ const configContent = fs.readFileSync(details.configPath, "utf-8");
130
+ // Check for authtoken (indicates logged in)
131
+ if (configContent.includes("authtoken:")) {
132
+ details.loginStatus = "authenticated";
133
+ // Try to extract account info from config comments
134
+ const accountMatch = configContent.match(/account:\s*(.+)/);
135
+ if (accountMatch) {
136
+ details.loginId = accountMatch[1].trim();
137
+ }
138
+ }
139
+ else {
140
+ details.loginStatus = "free";
141
+ }
142
+ }
143
+ catch { }
144
+ }
145
+ // Localtunnel is always free/anonymous
146
+ if (details.type === "localtunnel") {
147
+ details.loginStatus = "anonymous";
148
+ }
149
+ // Cloudflare might have config info
150
+ if (details.type === "cloudflare") {
151
+ details.loginStatus = "unknown";
152
+ }
153
+ return details;
106
154
  }
107
155
  /**
108
156
  * Get current tunnel info
@@ -122,4 +170,22 @@ export function getServerUrl() {
122
170
  }
123
171
  return currentTunnel.url;
124
172
  }
173
+ /**
174
+ * Graceful shutdown
175
+ */
176
+ export async function gracefulShutdown() {
177
+ console.log("\n[Tunnel] Graceful shutdown...");
178
+ await stopTunnel();
179
+ console.log("[Tunnel] Shutdown complete");
180
+ }
181
+ // Handle process signals for graceful shutdown
182
+ const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
183
+ signals.forEach((signal) => {
184
+ process.on(signal, async () => {
185
+ await gracefulShutdown();
186
+ process.exit(0);
187
+ });
188
+ });
189
+ // Re-export ngrok utilities
190
+ export { diagnoseNgrok, ensureNgrokReady };
125
191
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tunnel/index.ts"],"names":[],"mappings":"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"}
@@ -10,4 +10,8 @@ export declare function startLocaltunnel(config: TunnelConfig): Promise<TunnelIn
10
10
  * Stop the localtunnel
11
11
  */
12
12
  export declare function stopLocaltunnel(): Promise<void>;
13
+ /**
14
+ * Get the current localtunnel URL
15
+ */
16
+ export declare function getLocaltunnelUrl(): string | null;
13
17
  //# sourceMappingURL=localtunnel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localtunnel.d.ts","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIxD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAchF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD"}
1
+ {"version":3,"file":"localtunnel.d.ts","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIxD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD"}
@@ -7,25 +7,42 @@ let localtunnelInstance = null;
7
7
  * Start a localtunnel
8
8
  */
9
9
  export async function startLocaltunnel(config) {
10
- const tunnel = await localtunnel({
11
- port: config.port,
12
- subdomain: config.subdomain,
10
+ return new Promise((resolve, reject) => {
11
+ const timeout = setTimeout(() => reject(new Error("Timeout waiting for localtunnel URL (30s)")), 30000);
12
+ localtunnel({ port: config.port, subdomain: config.subdomain }, (err, tunnel) => {
13
+ if (err) {
14
+ clearTimeout(timeout);
15
+ reject(new Error(`Localtunnel failed: ${err.message}`));
16
+ return;
17
+ }
18
+ clearTimeout(timeout);
19
+ localtunnelInstance = tunnel;
20
+ console.log("[Tunnel] URL:", tunnel.url);
21
+ tunnel.on("close", () => {
22
+ localtunnelInstance = null;
23
+ });
24
+ resolve({
25
+ url: tunnel.url,
26
+ tunnelId: tunnel.url.split("://")[1].split(".")[0],
27
+ port: config.port,
28
+ provider: "localtunnel",
29
+ });
30
+ });
13
31
  });
14
- localtunnelInstance = tunnel;
15
- return {
16
- url: tunnel.url,
17
- tunnelId: tunnel.name,
18
- port: config.port,
19
- provider: "localtunnel",
20
- };
21
32
  }
22
33
  /**
23
34
  * Stop the localtunnel
24
35
  */
25
36
  export async function stopLocaltunnel() {
26
37
  if (localtunnelInstance) {
27
- await localtunnelInstance.close();
38
+ localtunnelInstance.close();
28
39
  localtunnelInstance = null;
29
40
  }
30
41
  }
42
+ /**
43
+ * Get the current localtunnel URL
44
+ */
45
+ export function getLocaltunnelUrl() {
46
+ return localtunnelInstance?.url || null;
47
+ }
31
48
  //# sourceMappingURL=localtunnel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"localtunnel.js","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,WAAW,MAAM,aAAa,CAAC;AAGtC,IAAI,mBAAmB,GAAQ,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IACzD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,mBAAmB,GAAG,MAAM,CAAC;IAE7B,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,GAAa;QACzB,QAAQ,EAAE,MAAM,CAAC,IAAc;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,aAAa;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,mBAAmB,EAAE,CAAC;QACxB,MAAM,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAClC,mBAAmB,GAAG,IAAI,CAAC;IAC7B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"localtunnel.js","sourceRoot":"","sources":["../../../src/tunnel/localtunnel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,WAAW,MAAM,aAAa,CAAC;AAGtC,IAAI,mBAAmB,GAAQ,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC,EACpE,KAAK,CACN,CAAC;QAEF,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,GAAQ,EAAE,MAAW,EAAE,EAAE;YACxF,IAAI,GAAG,EAAE,CAAC;gBACR,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACxD,OAAO;YACT,CAAC;YAED,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,mBAAmB,GAAG,MAAM,CAAC;YAE7B,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAEzC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,mBAAmB,GAAG,IAAI,CAAC;YAC7B,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC;gBACN,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,aAAa;aACxB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,mBAAmB,EAAE,CAAC;QACxB,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,mBAAmB,GAAG,IAAI,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,mBAAmB,EAAE,GAAG,IAAI,IAAI,CAAC;AAC1C,CAAC"}
@@ -7,13 +7,24 @@ import type { TunnelConfig, TunnelInfo, NgrokDiagnostics } from "./types";
7
7
  */
8
8
  export declare function diagnoseNgrok(): Promise<NgrokDiagnostics>;
9
9
  /**
10
- * Start an ngrok tunnel
10
+ * Ensure ngrok is ready for use (diagnose + interactive setup if needed)
11
+ */
12
+ export declare function ensureNgrokReady(): Promise<{
13
+ ready: boolean;
14
+ authtoken: string | null;
15
+ }>;
16
+ /**
17
+ * Start an ngrok tunnel with multi-strategy fallback
11
18
  */
12
19
  export declare function startNgrokTunnel(config: TunnelConfig): Promise<TunnelInfo>;
13
20
  /**
14
21
  * Stop the ngrok tunnel
15
22
  */
16
23
  export declare function stopNgrokTunnel(): Promise<void>;
24
+ /**
25
+ * Stop ngrok (legacy name for compatibility)
26
+ */
27
+ export declare function stopNgrok(): Promise<void>;
17
28
  /**
18
29
  * Check if ngrok is installed
19
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ngrok.d.ts","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI1E;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAyC/D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAgBhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD"}
1
+ {"version":3,"file":"ngrok.d.ts","sourceRoot":"","sources":["../../../src/tunnel/ngrok.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI1E;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CA+F/D;AAoED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAyB9F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CA4OhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD"}