Skip to content

feat: resolve discovered server IPs to hostnames, dedup and shorten labels - #29

Merged
matt-gribben merged 7 commits into
Hypabolic:mainfrom
hwacookie:feat/hostname-resolution-v2
Aug 17, 2026
Merged

feat: resolve discovered server IPs to hostnames, dedup and shorten labels#29
matt-gribben merged 7 commits into
Hypabolic:mainfrom
hwacookie:feat/hostname-resolution-v2

Conversation

@hwacookie

@hwacookie hwacookie commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #21

Resolves discovered server IPs to hostnames and dedups servers that resolve to the same host (e.g. multiple NICs on one machine appearing as separate entries).

Changes

  • src/discovery/dns.tsresolveHostname()/resolveUrlHostname() (reverse DNS with caching), shortHostname() (strips shared domain suffix for compact labels), getLocalDomain() (cascades os.hostname() → env vars → /etc/resolv.conf)
  • src/discovery/engine.tsdiscoverLocalhost()/discoverLan() resolve hostnames and dedup by hostname+port after the existing origin-based dedup; clearCache() at the start of each scan
  • src/ui/onboarding.tshostPortOf() uses shortHostname() so same-domain LAN servers show as devbox:8080 instead of devbox.fritz.box:8080

Follow-up on rebase

Rebased onto main after #28 and #30. Maintainer polish:

  • Wire clearCache() into each discover entry point
  • Strip the full shared domain suffix (keep subdomain labels)
  • Align docs/hostname-dedup.md with actual behavior (no unimplemented co-location preference)
  • Correct changelog dates to 2026

Testing

All 624 tests pass, tsc --noEmit clean.

Hauke Walden and others added 7 commits August 17, 2026 12:40
- Implements reverse DNS resolution for discovered servers
- IPs are resolved to hostnames (e.g., 192.168.1.42 → workstation.local)
- Deduplicates servers by hostname+port to collapse multiple network interfaces
- Same machine on multiple IPs now appears once with resolved hostname
- Graceful fallback: unresolved IPs stay as-is
- Caching to avoid redundant DNS lookups within a scan

Fixes Hypabolic#19 (multiple IPs of same machine appearing as separate entries)
Root cause: resolveUrlHostname() and dedupByHostname() reconstructed the
URL using new URL().pathname, which defaults to '/' even when the
original URL had no path. This turned 'http://192.168.1.42:8080' into
'http://hostname:8080/', and downstream code that does `${baseUrl}/v1`
produced a double slash (//v1), causing 404s from llama.cpp and other
backends.

Fix: replace only the hostname substring in the original URL string,
preserving whatever path/trailing-slash state existed before.

Also fixes TS strict-mode noUncheckedIndexedAccess errors introduced
in the dedup helper.
- Add shortHostname() helper in dns.ts — strips everything after the first dot
  (macpro16.fritz.box → macpro16), skips IPs and localhost
- Add shortLabel() helper in engine.ts — builds 'Kind (shortHost:port)'
- All labels now use short hostnames, saving horizontal space in UI
- baseUrl keeps the full hostname for correct DNS resolution

Tests:
- dns.test.ts: 18 tests (added shortHostname)
- hostname-dedup.test.ts: 8 tests (added short label test)
- workstation.local, devbox.local instead of macpro16.fritz.box, dagobert.fritz.box
- local-host.local instead of myMac.fritz.box
- Tests fully isolated — no dependency on actual machine hostname or domain
…olved hostname

- getLocalDomain() cascades: os.hostname() → env vars → /etc/resolv.conf
- shortHostname() strips domain suffix for same-LAN hostnames
- hostPortOf() now uses shortHostname() for compact /crossbar labels
- dedupByHostname() collapses IPs resolving to the same hostname
- 27 unit tests for the fallback chain, shortening, and crash resistance
Call clearCache at the start of discoverLocalhost/discoverLan, strip the full
shared domain suffix (not only the first label), and drop the unimplemented
co-location claims from the dedup docs. Also correct changelog dates to 2026.

Co-authored-by: Cursor <cursoragent@cursor.com>
@matt-gribben
matt-gribben force-pushed the feat/hostname-resolution-v2 branch from e59f0bb to 929b48a Compare August 17, 2026 02:45

@matt-gribben matt-gribben left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved after rebase onto main (#28 + #30) and a small maintainer polish pass:

  • clearCache() now runs at the start of each discover call (was imported but unused)
  • shortHostname strips the full shared suffix
  • Docs match implementation (loopback vs LAN hostname stay separate keys)
  • Changelog dates corrected to 2026

CI pending; will merge when green.

@matt-gribben
matt-gribben merged commit 4c615c1 into Hypabolic:main Aug 17, 2026
2 checks passed
matt-gribben added a commit that referenced this pull request Aug 17, 2026
Bump for work landed since v0.7.0:
- hostname resolution, LAN dedup, and shortened labels (#29, #21)
- animated /crossbar scan progress with ESC abort (#30, #23)
- fix removing no-auth servers without error (#28, #27)

Publish by triggering the Release workflow with tag v0.8.0 (or pushing the
tag); release.yml verifies the tag matches package.json.

Co-authored-by: Cursor <cursoragent@cursor.com>
matt-gribben added a commit that referenced this pull request Aug 17, 2026
git-cliff listed per-commit noise and wiped the fleshed-out v0.7.0 notes.
Summarize the three landed PRs (#29/#30/#28) and restore the oMLX entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
matt-gribben added a commit that referenced this pull request Aug 17, 2026
feat: resolve discovered server IPs to hostnames, dedup and shorten labels
matt-gribben added a commit that referenced this pull request Aug 17, 2026
Bump for work landed since v0.7.0:
- hostname resolution, LAN dedup, and shortened labels (#29, #21)
- animated /crossbar scan progress with ESC abort (#30, #23)
- fix removing no-auth servers without error (#28, #27)

Publish by triggering the Release workflow with tag v0.8.0 (or pushing the
tag); release.yml verifies the tag matches package.json.
matt-gribben added a commit that referenced this pull request Aug 17, 2026
git-cliff listed per-commit noise and wiped the fleshed-out v0.7.0 notes.
Summarize the three landed PRs (#29/#30/#28) and restore the oMLX entry.
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.

feat: use hostnames instead of IPs

2 participants