Skip to content

table: web dev servers show their URL, clickable in a terminal, without a request sent - #30

Merged
pyjeebz merged 2 commits into
mainfrom
feat/url-column
Nov 3, 2026
Merged

pyjeebz merged 2 commits into
mainfrom
feat/url-column

Conversation

@pyjeebz

@pyjeebz pyjeebz commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Closes #23, with a changed design (below). Follow-up for what it leaves out: #29.

The most useful fact about a dev server is where to open it. The table now shows it:

PORT   PROCESS      PROJECT   UPTIME   URL
3458   Next.js      ports     2s       http://localhost:3458
9239   Next.js      ports     2s
8791   python3.13   shop      3s
  • The URL column is last, and appears only when some row has a URL. A machine running only databases looks exactly as before.
  • Clickable (an OSC 8 link) in a terminal that renders links. Plain text when piped or with NO_COLOR. On Windows, links appear only in Windows Terminal or a terminal that sets TERM_PROGRAM (like VS Code's), because the legacy console prints the escape codes raw.
  • --json gains url. It's additive and omitted when empty.

The design change: no request is ever sent

#23 asked to probe every listener with an HTTP request. I didn't, because the listing has to stay side-effect free:

  • a HEAD makes a Next.js dev server compile a page;
  • a database port never answers, so it stalls until the request times out;
  • --watch would repeat all of that every second.

Instead the URL comes from framework detection. There's a curated list of dev servers that serve plain HTTP unless told otherwise: Next.js, Vite, Astro, Remix, Nuxt, SvelteKit, Storybook, Angular, NestJS, FastAPI, Django, Flask, Rails, Laravel, Phoenix, Spring Boot, Gin and their kin.

One URL per app, on its own port

A framework label belongs to the process, and one process can hold several ports, so:

  • A --port/-p on the command line names the app port, and only that port gets the URL. A process that names a port it doesn't hold gets none. Next.js runs as two processes: the next dev -p 3458 parent holds only its debugger port, and its server child holds the app port.
  • Otherwise, the lowest port that isn't a known side port gets it. Side ports are Node --inspect 9229–9230, JDWP 5005, debugpy 5678 and LiveReload 35729.
  • HTTPS chosen on the command line gets no http:// URL. That covers --ssl, --ssl-keyfile, --cert, --certfile, --experimental-https and similar. HTTPS set in a config file can't be seen; the docs say so.

How it was verified

Gate, locally with CI's versions: unit ✓, build ✓, Windows build ✓, integration ✓ (uncached), installers ✓, gofmt ✓, vet ✓, lint ✓ (v2.13.2). Site: npm run lint ✓, npm run build ✓.

Live, against a real next dev (the site in web/) plus a python -m http.server:

  • Piped: the Next.js row has the URL; the python row has none, and no trailing spaces.
  • --json: "url" appears on the Next.js row only.
  • In a terminal: an OSC 8 link. With NO_COLOR: plain text.
  • The dev server's own log shows 0 requests from ports. curl of the URL returns 200.
  • NODE_OPTIONS=--inspect next dev -p 3458: only 3458 has a URL. The parent's inspector (9239) and the child's (9240) have none. My first version gave the parent's inspector a URL, and this live run is what caught it.

New tests:

  • TestLocalURL: binds, IPv6 including zone ids, nginx not guessed, Windows rows, dropped frameworks.
  • TestTableURLColumn: the column only when present, last, no trailing spaces, links only when enabled.
  • TestFillURLs: the inspector, -p/--port, the parent/child Next.js case, JDWP, HTTPS flags, two apps.

Every README, docs and --help table containing a web server was re-rendered exactly as the binary prints it. The commands page documents the URL column and the url field. The landing page's styled tables are left for the Phase 4 site refresh.

Risk

Tier: risky (internal/inspect/output.go, --json).
Public surface: a new table column, and a new url JSON field (additive).
Rollback: revert the squash commit.

A fresh-context review blocked the first commit. On the Windows legacy console, the default ports would print raw escape codes. That's fixed, and so are its should-fixes:

Notes for the release

The table shows http://localhost:<port> for known web dev servers (Next.js, Vite, FastAPI, Rails…), clickable in a terminal. --json rows gain url.


Generated by Claude Code

@pyjeebz
pyjeebz merged commit 9b91feb into main Nov 3, 2026
5 checks passed
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.

table: a URL column for listeners that answer HTTP, clickable in the terminal

2 participants