Peers live under Settings; Images is local-only. Registry is a top-level view with vault credentials, Hub search, and Registry API V2 catalog/tags/manifest/delete over the wire.
HTTPSAgent extends the patched Agent; mistaking path for socketPath made every registry digest check fail with ENOENT and broke image update indicators.
Registry HTTP now sets host/hostname, disables keep-alive, and times out cleanly; resolve container image tags/digests more reliably and surface check errors in the UI.
Compare local RepoDigests to remote registry manifest digests, show status in the containers table Updates column, and support force recheck with vault credentials for private registries.
Adds a dedicated blank create form (name, image, always pull, ports,
auto-remove, advanced settings) separate from template Deploy, reuses
deployContainer with pull-if-missing and publish-all-ports support.
Lifecycle RPCs now use a 120s operation timeout, remove cleans up
stats/terminal/log streams then SIGKILLs before force-remove, and the
UI awaits the request instead of a fragile 30s wait race.
Installer and operator docs now tell users to read SERVER_PUBLIC_KEY and
SERVER_SEED from /opt/peardock/.env, and how to connect as viewer, admin, or
via a pd1. invite without sharing the seed.
Force fresh capability auth after pairing, heal active grants stuck on the spent list, and fail closed when a grant is spent instead of falling back to bare viewer.
Stop silently dropping failed capabilities (which forced viewer), log handshake role/auth, and show each AutoPass invite with its linked capability on one Access card.
Force-wipe AutoPass invite packages on create/delete so spent capabilities cannot poison new invites, clear stale grants on the client, and let admins unrevoke or clear revoked peers from Access.
Default peers are read-only; admin requires seed proof and operators redeem AutoPass packages with signed grants. ACL UI and docs match the new trust model.
PM2 and similar tools emit VT100 color codes that browsers hide only
partially, leaving artifacts like [32m between table columns. Strip CSI/OSC
escapes when formatting log lines, and harden Docker multiplex demux on the
server so frames are not mis-parsed as text.
Show start, stop, kill, restart, pause, resume, recreate, duplicate/edit,
and remove in the container details header, enabled by runtime state, using
typed RPC for lifecycle operations.
Always show a containers action bar (start/stop/restart/pause/resume/kill/
recreate/remove/prune) driven by row selection via typed bulk RPC. Rebuild
the container Networking tab into a join/leave network manager with aliases
and optional static IPs, plus a clearer ports table.
Replace the broken fire-and-forget submit path with deployDockerContainer
(including replace prompts), suggest a free name-copy by default, correctly
map custom networks/mounts/ports from inspect, and load config via typed RPC.
When deploying a container whose name already exists, prompt to Replace
(stop and remove the old container) or Cancel. Server accepts replace:true
to perform the swap; clients pre-check names and retry on conflict races.
Expand server history samples with network/block rates and longer
retention, and rebuild the details Stats tab with live KPIs, 1m–30m
windows, auto-scale, pause, CSV export, and CPU/memory/net/disk charts.
Split overview into a stretching Identity/Runtime/Network band and a
content-height Ports/Mounts/Timeline strip with timeline, mount rows,
and clearer empty states so vertical space is used without sparse panels.
Make the overview tab body, card, and section grid grow with the details
shell so Identity/Runtime/Network and related panels use empty vertical
space instead of sitting in a short content-sized block.
Tighten container detail tabs into a fit-to-viewport layout with a richer
overview, debounced process filters, and a readable process table. Make
dashboard KPI cards navigate to resource views (with status filters that
reset on leave), and raise per-peer RPC limits so normal UI polling no
longer trips rate limiting.
Cause
navigateToView was running document.querySelectorAll('.nav-link') and clearing active on every nav link — including container detail tabs (Logs, Terminal, etc.).
That left the previous pane with .show.active while its tab button no longer had .active. Bootstrap’s Tab.show() then couldn’t find/hide the previous pane, so opening Overview (or another tab) stacked both.
Fix
1. Sidebar-only nav updates — only #sidebar .nav-link[data-view] get active-state changes; detail/swarm/settings tabs are left alone.
2. Explicit tab reset — activateContainerDetailsTab() forces a single visible pane when opening a container (defaults to Overview).
3. Safer click wiring — sidebar navigation listeners are scoped the same way so they don’t attach to tab buttons.
Result
• Overview → Logs → other container → Overview shows only Overview
• Same for any other tab when switching containers
• Manual tab clicks continue to show only that tab’s content