echo
Echo
A TUI for field-testing Ethernet communications on the factory floor, built on Phosphor.
Techs work from named presets rather than retyping IP addresses. Select a preset, apply its interface config in one keystroke, ping the device, or open its web UI — all without leaving the terminal.
Designed for the ClockWork uConsole.
Home screen
┌─ ECHO v{version} ──────────────────────────────── #{hostname} · eth0 ┐
├─ PRESETS ────────────────────┬─ INTERFACE STATUS ─────────────────┤
│ ▶ Cube20 – Line 3 Panel A │ CURRENT │
│ Cube20 – Line 3 Panel B │ IP 192.168.1.100 │
│ Switch – Cabinet 7 │ Mask 255.255.255.0 │
│ Murr Profibus Gateway │ Mode Static │
│ Cube67 – Assembly Line 1 │ Link ● Up │
│ ─ 5 of 8 ─ │ │
│ │ PRESET WANTS │
│ │ IP 192.168.2.50 ← mismatch │
│ │ Mask 255.255.255.0 │
│ │ Target 192.168.2.1:80 │
│ │ │
│ │ ⚠ IP mismatch — press [a] to apply │
│ │ │
│ │ PING STATUS │
│ │ 192.168.2.50 — not tested [p] │
├─ RECENT ACTIVITY ───────────────────────────────────────────────── │
│ 14:32 ✓ Applied 192.168.2.50/24 to eth0 │
│ 13:58 ✓ Ping 192.168.2.1 — 4ms avg, 0% loss │
│ 13:55 → Set eth0 to DHCP │
├─────────────────────────────────────────────────────────────────── │
│ [a] Apply IP [p] Ping [b] Browser │ [n] New [e] Edit [d] Del │ [D] DHCP [q] Quit │
└──────────────────────────────────────────────────────────────────── ┘
The mismatch indicator updates live as the interface state changes — no manual refresh needed.
Requirements
- Crystal 1.20.3 (see toolchain note below)
ping(standard on most Linux systems)xdg-openfor browser launch (xdg-utilspackage)ipfromiproute2for interface configuration
Applying a static IP or requesting a DHCP lease requires either running Echo as root or adding a sudoers rule for the specific commands:
# /etc/sudoers.d/echo
your_username ALL=(ALL) NOPASSWD: /usr/sbin/ip, /usr/sbin/dhclient
Installation
git clone https://gitlab.com/quiet-corner-linux/echo
cd echo
shards install
shards build --release
# Copy bin/echo to somewhere on your PATH
cp bin/echo ~/.local/bin/
Usage
echo # Launch
Key bindings
| Key | Action |
|---|---|
j / ↓ |
Next preset |
k / ↑ |
Previous preset |
a |
Apply preset's IP config to the interface |
p |
Full ping test (opens PingResultsScreen) |
b |
Open device web UI in browser |
n |
New preset |
e |
Edit selected preset |
d |
Delete selected preset (confirm required) |
D |
Set interface to DHCP (confirm required) |
q |
Quit |
Presets
Presets are stored at ~/.config/echo/presets.json. Each preset captures:
- Title — a human-readable name, e.g.
Cube20 – Line 3 Panel A - Interface — the NIC to configure, e.g.
eth0 - Local IP / Subnet Mask — the static config to apply
- Remote IP / Port / Scheme — the device to test against
Toolchain note
Echo is pinned to Crystal 1.20.3 because ameba 1.6.4 (the linter) calls Crystal::Lexer#next_string_array_token which was removed in Crystal 1.21. Once ameba ships a compatible release this pin will be removed. If you see Ameba compile errors, confirm your local Crystal version with crystal --version.
Development
just check # format + lint + specs
just ci # full CI run
just run # build and run
Echo is also Phosphor's Phase 28 "build a real app" stress test. Friction encountered while building Echo feeds back into Phosphor's issue tracker — see CLAUDE.md for how to file it.
echo
- 0
- 0
- 0
- 0
- 2
- 4 days ago
- August 1, 2026
MIT License
Wed, 19 Aug 2026 18:10:56 GMT