Everything a serious terminal needs, and the parts no
terminal has: sessions that outlive the window, machines without
screens, agents with a permission gate. Eight chapters, one product.
A real terminal first.
Native Rust, rendered on the GPU, with JetBrains Mono in the box.
Tabs, splits nested any way you like, themes and profiles that sync
without an account. The budgets are enforced in CI: a build that
exceeds them does not ship.
thinkingthe webhook retry has no backoff, the queue hammers the endpoint…
The failing test wants exponential backoff on the payment webhook. I added three jittered attempts in webhook.ts and kept the idempotency key across retries.
// webhook.ts: retry with backoff, same idempotency keyfor (let n = 0; n < 3; n++) {
if (await deliver(evt, key)) break;
await sleep(backoff(n));
}
edit src/payments/webhook.ts+41 −6
npm test --workspaces149 passed149 passed · 0 failed · 12.4s
needs your permissiongit commit -m "payments: retry the webhook with backoff"DeclineAllowalso asked on pixel 8
git commit -m "payments: retry the webhook with backoff"done
git commit -m "payments: retry the webhook with backoff"declined · nothing ran
message the agent…
manual
aurorassh connectionsesc
ssh connections
Saved hosts, sealed on this device. Shared vaults are wrapped to each member's own key.
Search hostsNew vaultAdd host
synced 5 connections · 0 new from the cloud
personal1 host · private
nova-labnova@nova-lab:22···
nova labs3 hosts · shared with 2membersdelete
relay eu-centraldeploy@relay.novalabs.dev:22···
k8s-prodops@k8s.novalabs.dev:22···
staging-boxdeploy@staging.novalabs.dev:22···
grafanadeploy@grafana.novalabs.dev:22···
Hosts in ~/.ssh/config are not imported automatically.Import them
continuity
nova-deskattached now
pixel 8viewed 2m ago
webtermuna.com/s/9f3aopen ↗
share
Copy share linkScan with phone
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
aurora · ~/dev/aurorakey→glyph 6.2 ms87 MBe2e
unlock
Enter the passphrase you chose when you first turned
on sync. It is the same on every device: Termuna never receives it.
Unlock
fig 01 · cold start< 300 msLaunch to a usable prompt, measured on every build.
fig 03 · keystroke< 20 msKey press to glyph on screen.
fig 04 · installer< 30 MBNo browser runtime in the download.
Tabs and nested splits
The layout is a first-class object, which is exactly what syncs,
restores, and resurrects.
Search that works
Scrollback search is indexed: forty thousand lines is a query,
not a hang.
Profiles and themes
Colour schemes paint the terminal grid, never the chrome. Any
font, ligatures optional.
Hotkeys, your way
Every action is remappable, chords included, and quake mode
drops down on a global key.
Tell me when it is done
Arm a pane and Termuna tells you when the prompt comes back,
when it goes quiet for 30 seconds, or when it rings. The watch
runs in the daemon, so it works over SSH with nothing installed
on the far end.
Calm by design
Nothing interrupts typing. No popups in the input path, and no
AI completing your thoughts uninvited. A product rule, not a
setting.
ctrl+athenssplit right
ctrl+shift+fsearch 40k lines of scrollback
f12quake, over any app
Sessions live in the daemon, not the window.
A small daemon owns your shells and the session tree; the window is
a viewer. Close the GUI, crash it, update it - the shells never
notice. Reboot the machine and the whole layout, tabs, splits and
working directories, resurrects into fresh shells with one click.
thinkingthe webhook retry has no backoff, the queue hammers the endpoint…
The failing test wants exponential backoff on the payment webhook. I added three jittered attempts in webhook.ts and kept the idempotency key across retries.
// webhook.ts: retry with backoff, same idempotency keyfor (let n = 0; n < 3; n++) {
if (await deliver(evt, key)) break;
await sleep(backoff(n));
}
edit src/payments/webhook.ts+41 −6
npm test --workspaces149 passed149 passed · 0 failed · 12.4s
needs your permissiongit commit -m "payments: retry the webhook with backoff"DeclineAllowalso asked on pixel 8
git commit -m "payments: retry the webhook with backoff"done
git commit -m "payments: retry the webhook with backoff"declined · nothing ran
message the agent…
manual
aurorassh connectionsesc
ssh connections
Saved hosts, sealed on this device. Shared vaults are wrapped to each member's own key.
Search hostsNew vaultAdd host
synced 5 connections · 0 new from the cloud
personal1 host · private
nova-labnova@nova-lab:22···
nova labs3 hosts · shared with 2membersdelete
relay eu-centraldeploy@relay.novalabs.dev:22···
k8s-prodops@k8s.novalabs.dev:22···
staging-boxdeploy@staging.novalabs.dev:22···
grafanadeploy@grafana.novalabs.dev:22···
Hosts in ~/.ssh/config are not imported automatically.Import them
continuity
nova-deskattached now
pixel 8viewed 2m ago
webtermuna.com/s/9f3aopen ↗
share
Copy share linkScan with phone
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
aurora · ~/dev/aurorakey→glyph 6.2 ms87 MBe2e
unlock
Enter the passphrase you chose when you first turned
on sync. It is the same on every device: Termuna never receives it.
Unlock
Detach and reattach
Scrollback replays when a viewer returns. A session without a
window is dormant, not gone.
One window, three densities
Below 720px the chrome folds away to a quake drop-down; wide
windows pin the sessions drawer and continuity panel as real
columns.
Every machine, one drawer
Live and idle sessions from every machine you are signed in on.
Another machine's session names arrive sealed until your
passphrase opens them.
ctrl+k
Every action, session, and ssh host from one palette: "ssh
prod" finds the prod box.
Ctrl+R across machines
Every command you ran, on every machine, read off the terminal
echo with nothing installed on the far end. Sealed per record,
synced every five minutes, and Enter inserts it at the prompt
without running it.
Put the daemon on a box with no screen.
termuna-daemon is the same engine
without a window - a 10 MB binary for servers and lab machines.
Sign it in once and the machine becomes addressable: it shows up as
online in every client, and your phone can open the first session on
it while you are on the couch. The daemon dials out to the
relay, so the box needs no open port, no jump host, and no bastion -
it can sit behind NAT or inside a VPN and still answer
(how that works).
Login and status from the shell; a systemd user unit keeps the
daemon up across reboots.
Online means answered
A machine holds its own connection to the relay, so "online" is
the machine answering - not a guess from old sessions.
Custody stays yours
The machine publishes a key wrapped to your account vault.
Commanding it costs your passphrase, and the server never can.
First session from anywhere
List the machine and start a shell on it from the desktop, the
web dashboard, or the phone.
Continuity you can watch.
Turn on sync and the session mirrors to Termuna Cloud as it happens,
sealed with XChaCha20-Poly1305 before it leaves your machine. The
continuity panel names every device attached right now; a share link
or a QR code puts the session on another screen in seconds.
thinkingthe webhook retry has no backoff, the queue hammers the endpoint…
The failing test wants exponential backoff on the payment webhook. I added three jittered attempts in webhook.ts and kept the idempotency key across retries.
// webhook.ts: retry with backoff, same idempotency keyfor (let n = 0; n < 3; n++) {
if (await deliver(evt, key)) break;
await sleep(backoff(n));
}
edit src/payments/webhook.ts+41 −6
npm test --workspaces149 passed149 passed · 0 failed · 12.4s
needs your permissiongit commit -m "payments: retry the webhook with backoff"DeclineAllowalso asked on pixel 8
git commit -m "payments: retry the webhook with backoff"done
git commit -m "payments: retry the webhook with backoff"declined · nothing ran
message the agent…
manual
aurorassh connectionsesc
ssh connections
Saved hosts, sealed on this device. Shared vaults are wrapped to each member's own key.
Search hostsNew vaultAdd host
synced 5 connections · 0 new from the cloud
personal1 host · private
nova-labnova@nova-lab:22···
nova labs3 hosts · shared with 2membersdelete
relay eu-centraldeploy@relay.novalabs.dev:22···
k8s-prodops@k8s.novalabs.dev:22···
staging-boxdeploy@staging.novalabs.dev:22···
grafanadeploy@grafana.novalabs.dev:22···
Hosts in ~/.ssh/config are not imported automatically.Import them
continuity
nova-deskattached now
pixel 8viewed 2m ago
webtermuna.com/s/9f3aopen ↗
share
Copy share linkScan with phone
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
aurora · ~/dev/aurorakey→glyph 6.2 ms87 MBe2e
unlock
Enter the passphrase you chose when you first turned
on sync. It is the same on every device: Termuna never receives it.
Unlock
The web viewer
Anyone with the link watches and types at
termuna.com/s/<id> - into the
real shell, still running on your machine.
Scan with phone
The QR under Share attaches your phone without typing
anything.
History survives reboots
Scrollback stays in the cloud; the desktop resurrects the
layout into fresh shells.
The relay is blind
It stores ciphertext it cannot read. Session keys are generated
on your devices and never leave them unwrapped.
A recovery kit, not a reset
Termuna never receives your passphrase, so it cannot reset it.
The kit is how a forgotten passphrase never means lost
history.
Told, not watched
A pane that rings its bell or blocks on a question pushes a
notification to your browser. The text is generic: the relay
cannot read the session, so it cannot quote it.
Agents are sessions with a permission gate.
Claude Code runs as a managed process, not text typed into a shell.
When the agent wants to run a command it stops on that exact tool
call, and stays stopped until a human answers - at the desk or from
the phone. A remote client can never grant blanket permission.
thinkingthe webhook retry has no backoff, the queue hammers the endpoint…
The failing test wants exponential backoff on the payment webhook. I added three jittered attempts in webhook.ts and kept the idempotency key across retries.
// webhook.ts: retry with backoff, same idempotency keyfor (let n = 0; n < 3; n++) {
if (await deliver(evt, key)) break;
await sleep(backoff(n));
}
edit src/payments/webhook.ts+41 −6
npm test --workspaces149 passed149 passed · 0 failed · 12.4s
needs your permissiongit commit -m "payments: retry the webhook with backoff"DeclineAllowalso asked on pixel 8
git commit -m "payments: retry the webhook with backoff"done
git commit -m "payments: retry the webhook with backoff"declined · nothing ran
message the agent…
manual
aurorassh connectionsesc
ssh connections
Saved hosts, sealed on this device. Shared vaults are wrapped to each member's own key.
Search hostsNew vaultAdd host
synced 5 connections · 0 new from the cloud
personal1 host · private
nova-labnova@nova-lab:22···
nova labs3 hosts · shared with 2membersdelete
relay eu-centraldeploy@relay.novalabs.dev:22···
k8s-prodops@k8s.novalabs.dev:22···
staging-boxdeploy@staging.novalabs.dev:22···
grafanadeploy@grafana.novalabs.dev:22···
Hosts in ~/.ssh/config are not imported automatically.Import them
continuity
nova-deskattached now
pixel 8viewed 2m ago
webtermuna.com/s/9f3aopen ↗
share
Copy share linkScan with phone
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
aurora · ~/dev/aurorakey→glyph 6.2 ms87 MBe2e
unlock
Enter the passphrase you chose when you first turned
on sync. It is the same on every device: Termuna never receives it.
Unlock
The same ask also stands on your phone;
whoever answers first wins.
Attention, everywhere
The drawer and your phone go amber the moment an agent blocks,
with a push notification if you are away.
Conversations resume
A managed session resumes by the provider's own session id -
pick it back up days later.
Every provider
Claude Code runs fully structured; Codex, Gemini, Cursor, and
OpenCode launch into their own shells.
MCP servers
Tools your agents can call, written into each provider's own
config file from one screen.
SSH hosts live in encrypted vaults.
Termuna speaks SSH natively through a pure-Rust stack, with no
external client to install. Hosts are organized into vaults: personal
vaults sync across your computers, and a vault shared with your team
is wrapped to each member's own key. The server stores hosts it
cannot read.
thinkingthe webhook retry has no backoff, the queue hammers the endpoint…
The failing test wants exponential backoff on the payment webhook. I added three jittered attempts in webhook.ts and kept the idempotency key across retries.
// webhook.ts: retry with backoff, same idempotency keyfor (let n = 0; n < 3; n++) {
if (await deliver(evt, key)) break;
await sleep(backoff(n));
}
edit src/payments/webhook.ts+41 −6
npm test --workspaces149 passed149 passed · 0 failed · 12.4s
needs your permissiongit commit -m "payments: retry the webhook with backoff"DeclineAllowalso asked on pixel 8
git commit -m "payments: retry the webhook with backoff"done
git commit -m "payments: retry the webhook with backoff"declined · nothing ran
message the agent…
manual
aurorassh connectionsesc
ssh connections
Saved hosts, sealed on this device. Shared vaults are wrapped to each member's own key.
Search hostsNew vaultAdd host
synced 5 connections · 0 new from the cloud
personal1 host · private
nova-labnova@nova-lab:22···
nova labs3 hosts · shared with 2membersdelete
relay eu-centraldeploy@relay.novalabs.dev:22···
k8s-prodops@k8s.novalabs.dev:22···
staging-boxdeploy@staging.novalabs.dev:22···
grafanadeploy@grafana.novalabs.dev:22···
Hosts in ~/.ssh/config are not imported automatically.Import them
continuity
nova-deskattached now
pixel 8viewed 2m ago
webtermuna.com/s/9f3aopen ↗
share
Copy share linkScan with phone
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
aurora · ~/dev/aurorakey→glyph 6.2 ms87 MBe2e
unlock
Enter the passphrase you chose when you first turned
on sync. It is the same on every device: Termuna never receives it.
Unlock
Jump hosts and forwards
Bastion chains, and local, remote and SOCKS forwards on the
same profile.
Files beside the session
An SFTP browser on the desktop, and the same directory in a
files pane beside the live terminal in the web dashboard and on
the phone: browse, upload, download, every name and byte sealed
through the relay.
Your keys, your rules
Trust on first use, ssh-agent authentication, and import
straight from ~/.ssh/config.
Drop a file on the pane
It lands in that shell's own directory over the shell's own
bytes, past jump hosts, containers and tmux where SFTP cannot
follow. Needs trz on the far
side, and tsz path there sends
one back.
Shared, precisely
A vault you only read: connect and clone, never edit. Remove a
member and they stop receiving changes.
Sealed end to end
Keys, passwords and passphrases are sealed on your device with
the same encryption as sessions.
Commands you keep retyping
Snippets are items in the same vault: save one from a
selection, insert it from ctrl+k,
the dashboard or the phone. It types itself at the prompt and
never runs on its own.
A client in your pocket.
Same sessions, same rows, same encryption: the desktop's drawer
given the whole hand. An open session flips between terminal and
files, so the directory its shells run in is a tap away and a
download keeps moving while you flip back. The native apps are in the
works; the web dashboard already does all of this from any phone.
add retry with backoff to the payment webhook, then run the tests
Added exponential backoff to webhook.ts: three attempts, jittered, idempotency key preserved. Running the suite next.
Edit src/payments/webhook.ts · +41 −6
checkout-flow wants to run
$ npm test -- payments
AllowAlwaysDeny
Message checkout-flow…ask edits
23:41●●● ⏻
aurora
nova@nova-desk:~/dev/aurora$
continuity
this phoneattached now
nova-deskhost · desktop
webtermuna.com/s/9f3aopen ↗
share
Copy share link
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
A real terminal by thumb: the keys the soft keyboard
forgot, output streaming live from your machine, and your saved
snippets in a strip above the soft keys, typed at the prompt with
one tap.
add retry with backoff to the payment webhook, then run the tests
Added exponential backoff to webhook.ts: three attempts, jittered, idempotency key preserved. Running the suite next.
Edit src/payments/webhook.ts · +41 −6
checkout-flow wants to run
$ npm test -- payments
AllowAlwaysDeny
Message checkout-flow…ask edits
23:41●●● ⏻
aurora
nova@nova-desk:~/dev/aurora$
continuity
this phoneattached now
nova-deskhost · desktop
webtermuna.com/s/9f3aopen ↗
share
Copy share link
Anyone with the link sees this session. The relay never can.
session
3 tabs · 7 panes18k lines scrollbackstarted 4h ago · synced 2s ago
End-to-end encryptedxchacha20-poly1305
Hand the session off: the phone attaches, the desktop
stays the host, the relay stays blind.
Native on every desk.
One codebase, real binaries. Linux, Windows, and macOS all ship
today, macOS in early access for Apple silicon. Continuous integration
builds and tests all three, and the performance budgets hold on
each.