-
Notifications
You must be signed in to change notification settings - Fork 0
Getting started
Three ways in. They end at the same place — a URL with a token in it — and none of them needs
sudo.
curl -fsSL https://raw.githubusercontent.com/andreaderuvo/argus/master/install.sh | bash
argus --allow-writeEverything it does, all of it:
~/.local/share/argus |
the code, downloaded as a tarball — no git needed |
~/.local/share/argus/venv |
a virtual environment with the five runtime dependencies |
~/.local/bin/argus |
a three-line launcher |
What it does not do: touch anything outside your home, use sudo, install a system
package, add a repository, or start anything in the background unless you ask. There is
nothing to consent to, which is why it does not ask — a curl | bash that cannot prompt (its
standard input is the script) and asks anyway is theatre.
-
Run the same line again to update. The code is replaced, the virtual environment
refreshed, and
~/.config/argus— your token, your devices, your journal — is not touched. -
… | bash -s -- --servicealso writes a systemd user service and starts it. It stops when you log out unless lingering is on:sudo loginctl enable-linger $USER. -
… | bash -s -- uninstalltakes the code and the launcher away and leaves your configuration, because a token you may still have on three phones is not the uninstaller's to throw away. -
--dirputs it somewhere else,--branchfollows a different branch.
It is checked on every change, on Linux and macOS, by installing into an empty home, starting it, listing a real tmux session through the API, updating in place, and uninstalling.
For Windows-through-WSL, or for anyone who would rather not install Python:
git clone https://github.com/andreaderuvo/argus && cd argus
ARGUS_UID=$(id -u) ARGUS_GID=$(id -g) docker compose up -d
docker compose logs # the URL with the token is in hereThose two variables are not called UID and GID for a reason worth one sentence: bash makes
UID readonly, so UID=$(id -u) docker compose up fails with "readonly variable" — which
is what this page said to type until CI pointed at it.
This container is a way to get the runtime, not a sandbox. Argus's whole job is to attach
to the tmux sessions and read the files of the machine it runs on, so it has to be handed that
machine, and docker-compose.yml spells out each thing it needs and why:
pid: host |
the lookups that say which agent is in a pane, and what folder it is really in, read /proc. Without this every session lists and none of them says anything about itself. |
| the same uid as you | or the tmux socket will not talk, and the files it reads are root's |
$HOME at the same path |
a pane reports /home/you/project; mounted at /work that is a path Argus cannot find |
/tmp/tmux-<uid> |
how a tmux client reaches a tmux server. This is what makes it your sessions rather than an empty server in a container. |
One caveat before it bites: tmux's client and server speak a versioned protocol. The image
ships Debian's tmux, and a host running a much older or newer one can be refused — mount your
own binary over the image's (- /usr/bin/tmux:/usr/bin/tmux:ro) or install natively, which
cannot have the problem at all.
ARGUS_PORT=8100 docker compose up -d when 8090 is taken, which it will be if you already run
one natively.
git clone https://github.com/andreaderuvo/argus && cd argus
pip install -r requirements.txt
python3 -m app.main --allow-write # prints a URL with a token in itOpen the URL it prints. On first run it writes ~/.config/argus/config.yaml with a fresh
64-character token; that file is the only credential and is never in the repository.
--qr prints a QR code to photograph with a phone. Settings → Open on another device
shows the same code from inside the app.
The thing you look at runs in a browser, so that side is any operating system with one. The server side is a different question, and the honest answer is short: tmux is a Unix program and there is no native Windows build of it.
| Linux | natively, or in the container |
| macOS | natively — brew install tmux python@3.13. No systemd, so the service flag says so and stops rather than pretending |
| Windows | inside WSL, which is a Linux machine: the one-line installer works there unchanged. Not in Windows itself, and not because of Argus |
| A phone, a tablet, anything | as the browser, which is the whole point |
Linux and macOS are checked on every change; WSL is Linux and is not separately tested.
argus --help is the authority — it is on the machine and cannot be out of date, and a test
fails if a flag ever ships without its sentence. The same list, to read here:
--version |
what is installed, without starting anything |
-c, --config PATH |
somewhere other than ~/.config/argus/config.yaml
|
-l, --listen HOST:PORT |
override listen for this run — usually because a port is taken |
-r, --root PATH |
override roots; repeat it for several |
--socket NAME |
drive a specific tmux server: a socket name (-L), or a path if it contains / (-S). Use a throwaway one when testing — a crashing tmux server takes every session on its socket with it |
--allow-write |
permit mkdir, rename, move, copy, delete and upload through the API. Off by default: a read-only viewer is a safe thing to leave listening |
--allow-proxy |
permit reverse-proxying one loopback port at a time, and only after you open it. Off by default: a service on 127.0.0.1 is there on purpose |
--mounts |
add every real filesystem on the machine to the browsable roots |
--print-url |
print the URL with the token and exit |
--qr |
print a QR code of the URL for every address this machine answers on, and exit |
-
Python 3.11+ — the PTY bridge uses
os.login_tty - tmux — any recent version
- Optional: pandoc (Word documents), pdftotext from poppler (searching PDFs). Without them those files still open, they are just plainer.
No build step, no database, no bundler: the frontend is plain ES modules and the dependencies are vendored.
Everything is a config key and a command-line flag with the same name.
| Key | Default | What it does |
|---|---|---|
listen |
127.0.0.1:8080 |
address and port |
token |
generated | the only credential |
roots |
~ |
the only paths that can be read at all |
allow_write |
false |
rename, move, delete, upload, save |
allow_proxy |
false |
reverse-proxy a loopback port |
include_mounts |
false |
add every mount point to the roots |
launchers |
Claude Code, Codex, Gemini, a shell | what Start something here may start: a name and a shell line each. Yours replaces the shipped list — see Starting an agent |
agents |
none | keys for the agents running here: a name and a token each, able to do five things and nothing else |
launches_a_minute |
12 | the brake on starting things — a fan-out is a dozen in seconds, a runaway loop is hundreds |
relay_a_minute |
30 | the same, for sentences pushed into other sessions |
ask_outside |
true | whether the System screen may offer to ask a stranger what this machine's public address is. Nothing happens without a press; false removes the button |
tmux_socket |
tmux's default | which tmux server to drive |
resize_policy |
adapt |
adapt, preserve, auto — who sets the window size |
max_preview_bytes |
2 MiB | past this a text file arrives as its tail |
viewers |
none | per-kind overrides of the cap above (PDF, mesh, spreadsheet, document, image), and telling the server an extension is really something else — see Documents |
max_upload_bytes |
2 GiB | per-file upload cap, 0 for none |
drop_keep_days |
0 | delete drops older than this many days, swept at startup and once a day. 0 keeps them for ever. Also --drop-keep-days N, and Keep dropped files for in Settings |
drop_dir |
argus-drops |
where a file dropped on a session lands. Relative means inside the first root, which is what keeps the default inside the jail on a machine serving /data rather than a home directory. An absolute path is taken as written and must sit inside roots. Empty and a session takes no drops |
ntfy |
none | optional notifications when the browser is closed: server, an unguessable topic, optional token and the events to send. See Notifications |
[Unit]
Description=Argus
After=network-online.target
[Service]
ExecStart=/usr/bin/python3 -m app.main
WorkingDirectory=/path/to/argus
Restart=alwaysSave as ~/.config/systemd/user/argus.service, then:
systemctl --user enable --now argus
sudo loginctl enable-linger $USER # or it stops at your last logoutThe GitHub mark in the top bar opens this wiki, the repository and the landing page. The documentation is meant to be one tap from wherever you are, rather than something to go and look for.