Commit Graph
4 Commits
Author SHA1 Message Date
UltradesuandClaude Opus 4.8 de56258eb1 Tray: copy a network secret via ipc; use text buttons, not missing glyphs
Two fixes.

Secret copy: a new local control request returns a configured network's secret
in its tsn1 text form, so the tray's "Copy secret" button can put it on the
clipboard. The agent reads it from local state (same source as the CLI's
`network secret show`); it crosses only the owner/group socket and is wrapped in
a RedactedText type whose Debug prints "<redacted>", so it can never land in a
log. In the GUI the worker fetches it and hands it to the UI thread (which owns
the clipboard) through a one-shot slot kept out of the status snapshot, so it is
copied once and never stored in the cloned snapshot. Control protocol bumped
16 -> 17.

Icons: the button glyphs (⧉ ⟳ ✎ ✔ ✕) are not in egui's bundled fonts and showed
as tofu squares, so they are now plain text: copy / refresh / random / edit /
save / cancel. No icon font to embed.

Checks: fmt, clippy --workspace --all-targets -D warnings, and the tsunagi lib,
tsunagi-cli and wg-quic local_control tests pass on macOS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 15:48:32 +01:00
UltradesuandClaude Opus 4.8 8f5ce21ce9 Tray: devices window, bytes/packets toggle, copy & edit affordances
Replaces the in-tile collapsing peer list with a "Show devices" button that
opens a separate, normal-sized window per network, and fills in the rest of the
feedback.

Main window:
- A global show: pkts/bytes toggle; all rates and sparklines follow it.
- Sparklines now reserve their space always (fixed height, "no data yet"
  placeholder) so the layout no longer jumps when data arrives, and each one
  overlays its peak (top-left) and current value (bottom-right) with units.
- Device id has a copy button; the hostname is editable in place (✎ → edit →
  ✔/Enter sends SetHostname); network name, range and address copy on click.
- The Leave button is a neutral red. Per-tile "Show devices" opens the detail.

Devices window (a separate egui viewport per network):
- Network summary: id (copy), active/broadcast, range, this device's address,
  candidates, relay fwd/via/recv, dial/handshake failures.
- A larger network traffic sparkline.
- Connected peers in a table: hostname when known (else short key), protocol,
  address, handshake age formatted (s/m/h/d), tx/rx packets, tx/rx bytes, and
  current rate with an inline sparkline. Names and addresses copy on click.
- Offline members listed below with address and failed-dial count.

Agent: a SetHostname command (over the existing ipc) backs the in-place rename.
Traffic sampler now tracks both packet and byte rates; the toggle selects which.

Deferred: a "copy secret" button on the tile — the secret is deliberately not
exported to the GUI (secrets never leave the agent), so it needs a small local
secret-export ipc, which is the next step.

Builds and is clippy-clean (-D warnings) on macOS; the UI has not been run in
this headless session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 15:37:08 +01:00
UltradesuandClaude Opus 4.8 d1de61ba29 Tray UI: start hidden, fixed window, grid layout, traffic + peers
Reworks the tray window per feedback and fills it in.

- Starts hidden in the tray (no window on launch); the window opens from the
  menu. On macOS the app now uses the Accessory activation policy, so it lives
  in the menu bar with no Dock icon (via a winit event-loop hook, pinned to
  eframe's winit). Fixed, non-resizable 360x600 window; the layout targets it.
- Tidied layout: top bar (title + refresh), a bottom panel with the join form
  and the action banner, and a scrolling list of network tiles between them.
  Labels and values sit on two-column grids so they align; the join name and
  secret inputs are the same fixed width.
- A ⟳ button beside the secret generates a fresh random secret
  (NetworkSecret::generate), for creating a network.
- Each network tile shows id, range, this device's address, peers
  (connected/known), the active and broadcast switches, a Leave button, and a
  collapsing "peers (N)" section with a formatted per-peer table (short key,
  address, handshake age, tx/rx packets, rate).
- Traffic: a new sampler turns the agent's cumulative packet counters into a
  packets-per-second rate per network and per peer, from the deltas between
  snapshots (the snapshot now carries a generation and timestamp so each
  refresh is sampled once). The network tile shows the current rate and a small
  hand-drawn sparkline of recent rates (no extra dependency).

Note: rates are packets/s — the report has no byte counters yet; bytes would
need an agent change. Builds and is clippy-clean (-D warnings) on macOS; the UI
has not been run in this headless session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 15:08:29 +01:00
UltradesuandClaude Opus 4.8 19509dc833 Add the tsunagi-tray GUI (egui) — first increment
A native, lightweight tray application to manage a running agent — no web
engine. It is a thin client over the agent's local control socket, reusing
tsunagi::ipc and the report types directly; it owns its own runtime, logger and
event loop, like the CLI.

This first increment:
- tray icon with an Open/Quit menu (tray-icon); menu events are read on a
  background thread so Open works even while the window is hidden;
- a small window that hides to the tray on close and reopens from the menu;
- a background tokio worker that polls status every 2s and runs commands off the
  UI thread, writing a snapshot the UI renders from and repainting egui;
- UI: device header, a per-network card (name, id, range, this device's
  address, peers connected/known, a Leave button, and the per-network active
  and broadcast switches), a join form (name + secret), and a transient
  action/error banner; an "agent unreachable" state that names the socket.

Socket resolution: TSUNAGI_CONTROL_SOCKET if set, else the platform default
(/var/run/tsunagi/agent.sock on macOS) — the same socket the group-access agent
serves.

Scope/notes: macOS first (Linux and Windows follow). Not yet done — macOS
accessory activation policy (so there is no dock icon), light/dark tray icons
from assets (the icon is drawn in code for now), and packaging/autostart. Builds
and is clippy-clean (-D warnings) on macOS; the UI itself has not been run in
this headless session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-02 14:48:52 +01:00