openzoo 0.18.9 → 0.18.10

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/lib/proxy.js CHANGED
@@ -285,6 +285,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
285
285
  // origin, not off whether the URL exists yet, so there is no startup window
286
286
  // where public traffic slips through ungated.
287
287
  let tunnelGate = null;
288
+ let tunnelError = null;
288
289
 
289
290
  const server = http.createServer(async (req, res) => {
290
291
  // MCP on the SAME port as the proxy. One `npx openzoo` gives a harness
@@ -746,6 +747,10 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
746
747
  log(` (key REQUIRED on the public URL — it spends this wallet; ${Number.isFinite(cap) ? `capped at $${cap.toFixed(2)}/session` : 'NO session cap — OPENZOO_TUNNEL_MAX_USD adds one'},`);
747
748
  log(' OPENZOO_NO_TUNNEL=1 for localhost-only)');
748
749
  } catch (err) {
750
+ // Record it: a caller polling for publicUrl (openzoo cursor) would
751
+ // otherwise spin the full timeout on a tunnel that already died, with
752
+ // silent:true swallowing this very message.
753
+ tunnelError = err.message;
749
754
  log(`public URL unavailable (${err.message}) — localhost still works; OPENZOO_NO_TUNNEL=1 hides this line`);
750
755
  }
751
756
  })();
@@ -760,5 +765,6 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
760
765
  spent: () => sessionSpent,
761
766
  get publicUrl() { return tunnelGate?.publicUrl ?? null; },
762
767
  get tunnelToken() { return tunnelGate?.token ?? null; },
768
+ get tunnelError() { return tunnelError; },
763
769
  };
764
770
  }
package/lib/setup.js CHANGED
@@ -156,13 +156,20 @@ export async function setupEditor(which, target) {
156
156
  // routinely takes 30-45s; a 10s wait meant the tunnel line simply never
157
157
  // printed and the user never learned the public URL existed.
158
158
  process.stdout.write('waiting for tunnel');
159
+ let tunnelErr = null;
159
160
  for (let i = 0; i < 120 && !publicUrl; i++) {
160
161
  await new Promise((r) => setTimeout(r, 500));
161
162
  publicUrl = started?.publicUrl ?? null;
162
163
  tunnelKey = started?.tunnelToken ?? null;
164
+ // Bail the moment it FAILS. Polling to the full timeout on a dead tunnel
165
+ // just looks like a hang — and silent:true hides the proxy's own error.
166
+ tunnelErr = started?.tunnelError ?? null;
167
+ if (tunnelErr) break;
163
168
  if (i % 4 === 3) process.stdout.write('.');
164
169
  }
165
- process.stdout.write(publicUrl ? ' ok\n' : ' (not up yet — it will print in this terminal when ready)\n');
170
+ if (publicUrl) process.stdout.write(' ok\n');
171
+ else if (tunnelErr) process.stdout.write(` failed: ${tunnelErr}\n (localhost still works; OPENZOO_NO_TUNNEL=1 skips this)\n`);
172
+ else process.stdout.write(' timed out — carrying on; it will print here if it comes up later\n');
166
173
  } else {
167
174
  console.log(`proxy already running on ${base}`);
168
175
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.18.9",
3
+ "version": "0.18.10",
4
4
  "description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
5
5
  "license": "MIT",
6
6
  "type": "module",