A terminal you live in.

A fullscreen TUI that pairs a real, interactive shell with an AI agent chat. The agent sees your terminal, investigates in a hidden shell, and can type into your visible pane on request.

latest v0.1.7curl -fsSL https://sensus.sh/install | bash

detach any time: shells and agent turns keep running · kill switch: sensus kill

one pane is the terminal, the other is the agent chat

│ │  + new tab? commands
tabs
+ new tab
? commands
terminal ●
ops@homelab:~$ sudo tail -f /var/log/auth.log
sshd[812]: Failed password for root from 203.0.113.7
sshd[812]: Failed password for invalid user admin
sshd[812]: Failed password for root from 203.0.113.7
sshd[812]: Failed password for invalid user oracle
sshd[812]: Failed password for root from 203.0.113.7
sshd[812]: Failed password for invalid user postgres
sshd[812]: error: maximum authentication attempts exceeded
sshd[812]: Failed password for root from 203.0.113.7
sshd[812]: Failed password for invalid user ubuntu
sshd[812]: Failed password for root from 203.0.113.7
^C
ops@homelab:~$
ops@homelab:~$ docker compose logs -f web
web | Error: connect ECONNREFUSED 172.18.0.4:5432
web | at TCPConnectWrap.afterConnect
web exited with code 1
web | Error: connect ECONNREFUSED 172.18.0.4:5432
web | at TCPConnectWrap.afterConnect
web exited with code 1
web | Error: connect ECONNREFUSED 172.18.0.4:5432
web | at TCPConnectWrap.afterConnect
web exited with code 1
^C
ops@homelab:~$
ops@homelab:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 98G 91G 2.4G 98% /
kernel: EXT4-fs warning (sda2): Directory index full!
dockerd[901]: register layer: no space left on device
postgres[1204]: PANIC: could not write pg_wal
kernel: EXT4-fs warning (sda2): Directory index full!
dockerd[901]: register layer: no space left on device
postgres[1204]: FATAL: could not write pg_wal
kernel: EXT4-fs warning (sda2): Directory index full!
dockerd[901]: register layer: no space left on device
ops@homelab:~$
chat
❯ you⧉ copy  ↺ revert
ssh keeps getting hammered
▸ shell_background
sudo fail2ban-client status sshd
sudo sshd -T | grep -i permitrootlogin
● done
✱ copilot⧉ copy
fail2ban shows 47 failures from 203.0.113.7 in the last minute, root included. sshd still allows password auth and root logins, so the next run can get in.
▸ shell_background
sudo tee /etc/ssh/sshd_config.d/hardening.conf <<'EOF'
PermitRootLogin prohibit-password
PasswordAuthentication no
EOF
○ awaiting approval
[y accept]
[n reject]
❯ you⧉ copy  ↺ revert
web keeps restarting
▸ shell_background
docker compose ps web
cat .env
● done
✱ copilot⧉ copy
.env still points web at 172.18.0.4, but db now answers on the compose network as db. web has restarted 34 times and never gets past startup.
▸ shell_background
sed -i 's/^DB_HOST=.*/DB_HOST=db/' .env
docker compose up -d --force-recreate web
docker compose ps web
docker logs --tail 1 web
○ awaiting approval
[y accept]
[n reject]
❯ you⧉ copy  ↺ revert
no space left on device
▸ shell_background
sudo du -sh /var/lib/docker /var/log
docker system df
● done
✱ copilot⧉ copy
Docker is 41G of the 91G used: build cache and dangling images. The journal is 3.2G more. Nothing running needs the cache, so it can go without a restart.
▸ shell_background
sudo docker system prune -af
sudo journalctl --vacuum-size=500M
df -h /
du -sh /var/lib/docker /var/log
○ awaiting approval
[y accept]
[n reject]
agent:copilot ⇄
input
ask the agent… (Enter sends · Shift+Enter newline)
tab 1/3: sshd· cwd: /home/ops· ollama@deepseek-v4.1-flash· 24k/1M· ✱ agent:copilot· confirm
tab 2/3: logs· cwd: /home/ops/app· ollama@deepseek-v4.1-flash· 31k/1M· ✱ agent:copilot· confirm
tab 3/3: disk· cwd: /home/ops· ollama@deepseek-v4.1-flash· 18k/1M· ✱ agent:copilot· confirm

A real shell, not a simulation.

The terminal pane is one real PTY per tab, rendered by an embedded VT (Ghostty).vim, htop, colors, mouse, and scrollback behave like a real terminal, because it is one.

  • one PTY per tab, per-tab sessions
  • full-color VT, mouse passthrough
  • scrollback, resize, works over SSH
1:vim2:htop3:zsh
1import { createSignal } from "solid-js"
2import { theme } from "./theme"
3
4export function StatusBar() {
5 const [tab] = createSignal(0)
6 return <text fg="{theme.accent}">{tab()}</text>
7}
~
~
-- INSERT --7,1  All
host homelabcwd /home/opsshell bashrecent: sudo fail2ban-client status sshd
chat
❯ you⧉ copy  ↺ revert
harden ssh on homelab
✱ copilot⧉ copy
Two gated changes: the drop-in and a reload. Both run with sudo, in order.
▸ plan · 2 approvals
❯ ✓ [1/2] shell_background  sudo tee /etc/ssh/sshd_config.d/hardening.conf
sudo tee /etc/ssh/sshd_config.d/hardening.conf <<'EOF'
PermitRootLogin prohibit-password
PasswordAuthentication no
EOF
✓ [2/2] shell_background  sudo systemctl reload sshd
[A approve all]
[N deny all]
[↵ confirm]
[esc cancel]
▸ shell_session  systemctl status sshd
● done

The agent lives beside you.

One tab = one shell = one chat session. The agent sees the cwd, shell, and recent output, including git status when there is one. It investigates in a hidden shell, and shell_sessiontypes into your visible pane on request, special keys included.

It keeps notes between sessions: environment memory, a host map of this machine, and a journal of what it did. Plain markdown under ~/.config/sensus/, alongside your own AGENTS.md instructions.

  • every action asks first · allow rules skip the card
  • pane typing is free · nothing runs until you confirm
  • plan cards: approve all / deny all / confirm
  • sudo steps: masked password prompt, cached for the session
  • /yolo flips to full-auto when you want it

Nothing to clean up.

Sensus runs as a child of your shell, never exec'd. Exit (or detach withCtrl+A d) and you are back at a plain prompt: the shells and the agent's work keep running in the local daemon, re-attachable on the next boot. Closing a tab never kills its shell; type exit in the pane to end one. When you want a clean slate,sensus kill is the kill switch: one command stops every local daemon and the shells they own.

❯ sensus# the TUI opens; shells run in the local daemon
…
❯ Ctrl+A d# detach: back to this prompt, nothing killed
❯ sensus# reattach: tabs, shells, and sessions are still there
❯ sensus kill# kill switch: stop every local daemon and its shells

Your model, your endpoint.

Sensus speaks to any configured endpoint through the Vercel AI SDK: a hosted API, a model on your homelab box, or a gateway. sensus init walks you through the setup.

config, memory, and sessions live in ~/.config/sensus/

openai-compatible
/chat/completionsdefault
openai
Responses API
anthropic
Messages API
google
Gemini

Install sensus.

One line. The release binary is checksum-verified.

curl -fsSL https://sensus.sh/install | bash

Linux or macOS · x86_64/aarch64 · works over SSH

System-wide install — /usr/local/bin, uses sudo when needed

curl -fsSL https://sensus.sh/install | bash -s -- -g

All install options · build from source