limbo-ai 1.18.1 → 1.18.3

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 (2) hide show
  1. package/cli.js +39 -5
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -1028,7 +1028,7 @@ function installCloudflared() {
1028
1028
  }
1029
1029
  }
1030
1030
 
1031
- function createSetupTunnel(port, tunnelDomain) {
1031
+ async function createSetupTunnel(port, tunnelDomain) {
1032
1032
  if (!hasCloudflared() && !installCloudflared()) return null;
1033
1033
  if (!hasCloudflared()) return null;
1034
1034
 
@@ -1081,16 +1081,50 @@ function createSetupTunnel(port, tunnelDomain) {
1081
1081
  });
1082
1082
  tunnelProc.unref();
1083
1083
 
1084
+ // Wait for tunnel URL to appear in logs
1085
+ let tunnelUrl = null;
1084
1086
  for (let i = 0; i < 15; i++) {
1085
1087
  sleep(1000);
1086
1088
  try {
1087
1089
  const logs = fs.readFileSync(logFile, 'utf8');
1088
1090
  const match = logs.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);
1089
- if (match) return { type: 'quick', url: match[0], pid: tunnelProc.pid, logFile };
1091
+ if (match) { tunnelUrl = match[0]; break; }
1090
1092
  } catch {}
1091
1093
  }
1092
- warn('Could not start cloudflare tunnel.');
1093
- return null;
1094
+ if (!tunnelUrl) {
1095
+ warn('Could not start cloudflare tunnel.');
1096
+ return null;
1097
+ }
1098
+
1099
+ // Warmup: wait for DNS to propagate AND tunnel to respond before returning.
1100
+ // Chrome uses its own DoH resolver and won't see the URL until DNS is globally propagated.
1101
+ // We check DNS resolution (not just HTTP reachability) to ensure browsers can reach it.
1102
+ log('Waiting for tunnel to be reachable...');
1103
+ const https = require('https');
1104
+ const dns = require('dns').promises;
1105
+ const tunnelHost = tunnelUrl.replace('https://', '');
1106
+ let reachable = false;
1107
+ for (let i = 0; i < 30; i++) {
1108
+ try {
1109
+ // First verify DNS resolves (catches DoH propagation issues)
1110
+ await dns.lookup(tunnelHost);
1111
+ // Then verify HTTP responds
1112
+ const ok = await new Promise((resolve) => {
1113
+ const req = https.get(tunnelUrl, { timeout: 5000 }, (res) => {
1114
+ res.resume();
1115
+ resolve(res.statusCode < 500);
1116
+ });
1117
+ req.on('error', () => resolve(false));
1118
+ req.on('timeout', () => { req.destroy(); resolve(false); });
1119
+ });
1120
+ if (ok) { reachable = true; break; }
1121
+ } catch {}
1122
+ sleep(2000);
1123
+ }
1124
+ if (!reachable) {
1125
+ warn('Tunnel created but DNS has not fully propagated. The URL may take a moment to work.');
1126
+ }
1127
+ return { type: 'quick', url: tunnelUrl, pid: tunnelProc.pid, logFile };
1094
1128
  } catch {
1095
1129
  return null;
1096
1130
  }
@@ -1720,7 +1754,7 @@ async function cmdStart() {
1720
1754
  let tunnel = null;
1721
1755
  if (isServerEnvironment()) {
1722
1756
  log('Server environment detected — creating secure tunnel...');
1723
- tunnel = createSetupTunnel(PORT, flagTunnelDomain);
1757
+ tunnel = await createSetupTunnel(PORT, flagTunnelDomain);
1724
1758
  }
1725
1759
  printWizardUrl(wizardUrl, tunnel);
1726
1760
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "limbo-ai",
3
- "version": "1.18.1",
3
+ "version": "1.18.3",
4
4
  "description": "Your personal AI memory agent — install and manage Limbo via npx",
5
5
  "type": "commonjs",
6
6
  "bin": {