Skip to content

Launch hosted captun.sh tunnels#16

Merged
mmkal merged 13 commits into
mainfrom
hosted-captun-sh
May 26, 2026
Merged

Launch hosted captun.sh tunnels#16
mmkal merged 13 commits into
mainfrom
hosted-captun-sh

Conversation

@mmkal
Copy link
Copy Markdown
Contributor

@mmkal mmkal commented May 23, 2026

Summary

Adds the hosted captun.sh path so a first-time user can get a public tunnel without deploying anything first.

# with something listening on localhost:3000
npx captun 3000

The CLI now defaults to the hosted https://captun.sh gateway when there is no local config, generates a random tunnel name, and prints a public URL like:

https://abc123.captun.sh -> localhost:3000

No Cloudflare account, config file, token, or deploy wizard is needed for that first run. Users can still run npx captun deploy later if they want their own self-hosted gateway.

What Changed

  • defaults missing local config to the hosted https://captun.sh gateway
  • changes createCaptunTunnel to connect with { gateway, name, token, fetch } and wait for the gateway to return { url, token }
  • renames the low-level Cap'n Web accept APIs to acceptFetcherCapability and acceptFetcherCapabilityFromSocket
  • updates the CLI, deploy wizard, config file, smoke scripts, benchmarks, docs, and hosted browser demo to use gateway/token
  • keeps the self-hosted Cloudflare Tunnel Gateway readable in src/worker.ts, with the hosted captun.sh product surface isolated under src/hosted/
  • reserves product/control-plane tunnel names, serves www.captun.sh, and redirects the apex host to www
  • adds CONTEXT.md and ADR-0001 to keep the Fetcher Capability / Tunnel / Gateway language clear

#20 is superseded by this shape; hosted rate limiting and ownership controls are rebuilt in #22 on top of the gateway-owned protocol.

Library Example

import { createCaptunTunnel } from "captun";

const tunnel = await createCaptunTunnel({
  fetch: (request) => Response.json({ path: new URL(request.url).pathname }),
});

console.log(tunnel.url); // https://abc123.captun.sh

Self-hosted use now passes the gateway URL, not a tunnel URL template:

npx captun 3000 --gateway 'https://captun.youraccount.workers.dev' --token abc123

Structure

  • src/index.ts contains the client API and low-level Fetcher Capability helpers.
  • src/worker.ts is the deployable self-hosted Cloudflare Tunnel Gateway.
  • src/hosted/site.ts and src/hosted/worker.ts are the Iterate-operated hosted surface for captun.sh.
  • wrangler.jsonc is for self-hosted deployment; wrangler.hosted.jsonc is for the hosted service.

Verification

  • pnpm run check
  • pnpm test
  • pnpm run build
  • pnpm exec vitest run test/worker.test.ts test/e2e.test.ts examples/weather-reporter/e2e.test.ts
  • CAPTUN_PUBLIC_E2E=1 pnpm exec vitest run test/public-hosted.test.ts
  • deployed captun-public to Iterate prd with captun.sh/* and *.captun.sh/*

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 24, 2026

Open in StackBlitz

npx https://pkg.pr.new/captun@16

commit: 1a924a7

Comment thread src/cli/bin.ts
Comment thread src/worker.ts
Comment thread src/worker.ts
Comment thread src/worker.ts
Comment thread src/hosted/worker.ts
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 4 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ead1f28. Configure here.

Comment thread src/hosted/site.ts
Comment thread scripts/smoke/step-6-tunnel-remote.sh
@mmkal mmkal merged commit b752670 into main May 26, 2026
1 check passed
mmkal added a commit that referenced this pull request May 26, 2026
## Summary

Fast-follow for #16 review comments.

- lets hosted apex `captun-connect` requests reach the tunnel gateway
before the apex-to-www redirect runs
- adds a hosted Worker regression test that an apex WebSocket connect
gets a 101 upgrade
- updates the remote smoke script to pick the standalone public tunnel
URL line instead of the last URL in the CLI log, which can be the local
target

## Verification

- `pnpm exec vitest run test/hosted-worker.test.ts`
- `pnpm run check`
- `pnpm test`
- `pnpm run build`

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small routing guard and test/smoke-script tweaks; no auth, data, or
broad architectural changes.
> 
> **Overview**
> **Apex tunnel connects** on `captun.sh` now bypass the hosted site
handler (including the apex→www redirect) when `captun-connect=1` is
present, so WebSocket upgrades hit the tunnel gateway first. A hosted
Worker test asserts that behavior returns **101**.
> 
> The **remote smoke** script infers the public tunnel URL from log
lines that are standalone `http(s)://…` URLs (trimmed), instead of
grabbing the last URL anywhere in the log—which could be the local
target.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9742d22. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant