Web viewer and desktop app
Mjolnir’s daemon starts a personal authenticated web viewer by default. It is a control surface over the same workspaces and sessions as the terminal, not a copy of the repository or a separate session server.
Open the viewer
Section titled “Open the viewer”Ask the daemon for the current address and six-digit login code:
mj daemon statusOpen the reported URL, enter the code, and Mjolnir exchanges it for a signed HTTP-only session cookie. The viewer exposes the workspaces attached to this daemon, live and resumable sessions, the conversation and prompt composer, target capacity, profile quota, and the new-session flow.
On a workstation, the dashboard arranges sessions in columns and conversations use a wider reading area with the composer kept in view. On phones, sessions remain in a single column with touch controls.
Create and Resume stay above the Sessions list, including when a workspace has no live sessions or the list is filtered. Opening a conversation does not move those controls away from the list.
The viewer can:
- create a session by choosing its profile, target, project or bundle, and reviewing the resolved launch;
- open a live conversation, send prompts, and run the slash commands the session actually supports;
- queue prompts while an agent is busy, Interrupt turn without releasing the environment, and cancel shell work;
- suspend a session, resume it from its checkpoint, and browse all suspended resume candidates, including records previously archived by a provider;
- Destroy session… from a live session menu or retained-session detail, with a separate confirmation; older linked-worktree sessions also offer an option to delete their managed branch;
- search the SessionWiki index, list archived sessions, read one’s briefing, and restore it into a new session, matching the terminal’s Archived tab (see Search and restore archived sessions); the Resume search box searches that index and nothing else, so it lists the sessions the index returned in the order it ranked them, and it is closed and reads Indexing… until the first index build finishes;
- prepare and confirm a move to another compatible target or profile while keeping the same logical session;
- refresh target capacity and profile quota; and
- keep a per-browser draft for the active conversation.
Use Earlier messages above the conversation to read stored history, then Load earlier page to continue backward. Each page replaces the previous page. Close or Escape returns to the live conversation with your draft preserved, including while a history request is still loading.
During creation, Where to run includes resource sizing. On the final Review screen, Attached directories lets you add, edit, or remove host directories and choose their container paths and read-only, copy-on-write, or read-write access. Source directories must exist on the selected target’s host.
For an existing container session, ⋯ → Restart agent restarts inside the same container and preserves its filesystem. ⋯ → Upgrade container and restart… shows the current and target image and asks for explicit acknowledgment of possible writable-layer loss. Workspace and cache mounts are retained. Busy workers finish accepted work first; the pending upgrade survives daemon replacement and may be cancelled before replacement starts. Saved Container settings… apply when a new environment is explicitly created; Restart and image upgrade retain the existing mounts and limits.
Use the terminal for native-session import, Discard changes since checkpoint, and configuration or secret editing. Explicit Destroy session is available with confirmation.
Move confirmation
Section titled “Move confirmation”Move is a two-step, authenticated flow. The viewer first asks the daemon for a read-only preparation that resolves the profile, target, compatibility, active state, and queued commands. Only the confirmation submits the fingerprinted preparation and interruption acknowledgement. The browser cannot implement a move by composing Suspend and Resume, and a stale destination is rejected before the source is interrupted.
The confirmation explains what will be rebuilt. A move that keeps the same target, attached directories, and resource allocation replaces only the harness and profile and keeps the environment and workspace; a move that changes the target rebuilds a fresh environment from the checkpoint. It warns before interrupting an active turn, lists queued prompts and configuration changes, and defaults to discarding that queue. Selecting Run queued work admits the original commands only after the destination is ready. The daemon keeps moving after a browser tab closes; the session row reports its current phase and recovery guidance on reconnect.
Resource sizing is inherited and attached directories remain fixed to the workspace. The confirmation has an explicit Clear inherited resource sizing checkbox for returning to destination defaults. If a move fails or is cancelled after retaining its checkpoint, the dashboard offers Retry move with the recorded destination and Resume with previous settings using the source profile and target. Partial queue admission is pinned to its original destination and queue choice so a retry cannot replay accepted commands on a new target.
The browser’s Back button returns from a conversation to its workspace. A temporary network loss does not move session ownership into the browser: the daemon and target keep working, and the viewer reconnects to their current state.
Recover a port conflict
Section titled “Recover a port conflict”Press prefix+u in the terminal to open Web viewer. If its port is occupied, the dialog shows the address and offers Use another port, Retry, and Inspect port. Startup status updates automatically while the dialog is open.
Use another port reserves an available port and shows the new URL and login code. It keeps the same HTTPS hostname and certificate when HTTPS is configured. The port applies until the daemon restarts; saved configuration is unchanged.
Inspect port shows the listening process and its PID. On Linux, an identified Mjolnir daemon owned by your account can be stopped with Stop server… and a separate Stop and retry confirmation. Other clients using that daemon will disconnect. Mjolnir verifies the process identity again before requesting a graceful stop and does not escalate to a force kill. The current daemon and unrelated applications cannot be stopped through this dialog. On other platforms, stop the identified application yourself or use another port.
Open the native desktop shell
Section titled “Open the native desktop shell”mj appmj app launches the separate mj-desktop executable and opens the same
viewer in a native window. The main mj binary stays headless. On Linux, the
desktop executable uses the system WebKitGTK runtime; install the distribution
package that provides WebKitGTK 4.1 when the app cannot start. Headless
installations do not need the desktop package or its native libraries.
Local access by default
Section titled “Local access by default”Without an explicit TLS configuration or a usable Tailscale node, the viewer
serves plain HTTP only on 127.0.0.1:3765. This makes it reachable solely from
the controller machine.
The historical configuration section is named [phone]:
[phone]enabled = truebind = "127.0.0.1:3765"tailscale_detect = trueSet enabled = false to turn the viewer off. A non-loopback bind is rejected
unless both tls_cert and tls_key are configured.
Reach it through Tailscale
Section titled “Reach it through Tailscale”When the local Tailscale node has MagicDNS and HTTPS Certificates enabled,
Mjolnir requests the node’s trusted ts.net certificate in the background and
serves HTTPS on all interfaces at the same port. The first certificate can take
about 30 seconds. Mjolnir renews it daily without restarting the daemon.
If detection cannot obtain a trusted certificate, mj daemon status keeps the
viewer on loopback and explains why. After changing the tailnet setting, run:
mj daemon restartTo manage certificates yourself, explicit paths take precedence over automatic detection:
[phone]enabled = truebind = "0.0.0.0:3765"tailscale_detect = falsetls_cert = "/path/to/fullchain.pem"tls_key = "/path/to/private-key.pem"Security boundary
Section titled “Security boundary”The viewer is designed for one operator, not as a multi-user team service. Treat its login code, cookies, TLS private key, and any copied transcript as secrets. The repository and harness processes remain on their configured targets, but an authenticated viewer can send prompts and lifecycle commands with your authority.
See Security boundaries for the full trust model, Configuration reference for every field, and Troubleshooting when the viewer remains loopback-only or the desktop shell cannot open.
Suspend session… confirms saving a recovery copy and releasing the environment, warning about the current turn and about sub-agents still at work, which suspending stops. Accepted work remains visible until it completes or reports a failure. Destroy session… permanently removes the session record, environment, and recovery archive after indexing the conversation in SessionWiki. The archived conversation can seed a new session, but cannot recover deleted workspace files. Closing a browser pane or tab leaves sessions running.