A lightweight PTY daemon with a Unix socket API for remote shell access
Project description
dmn
A lightweight PTY daemon. Spawns a shell in a pseudo-terminal and exposes it over a Unix socket, allowing multiple clients to send commands, attach interactively, or watch the output read-only.
Quick start
Install via pip/uv:
[!IMPORTANT] The package name is
dmn-ptynotdmn. I do not maintain that project!
pip install dmn-pty
# or uv
uv tool install dmn-pty
# Start the daemon (default session)
dmn
# attach to it
dmn-attach
# Or with a named session and custom shell
dmn --session work --shell /bin/bash
Or from the repo's root:
# Start the daemon (default session)
uv run -m dmn
# attach to it
uv run -m dmn.attach
# Or with a named session and custom shell
uv run -m dmn --session work --shell /bin/bash
Clients
scripts/client.py — command execution
Send one-off commands to the running shell (starts a REPL):
python scripts/client.py -s work
> echo hi # gets sent to the daemonized session
web/bridge.py — web terminal
A WebSocket bridge that serves a browser-based terminal using ghostty-web
cd web && npm install
uv run --script web/bridge.py --session work
# Open http://127.0.0.1:9001 in a browser
The web UI has session switching, connect/disconnect controls, and a read-only mode. The bridge also supports --force-readonly for sharing a terminal view without allowing input.
How it works
dmn uses a hand-rolled event loop built on a selector. A single-threaded loop manages the PTY, stdin/stdout, a Unix server socket, and all connected clients.
Protocol
Clients connect to a Unix socket ($XDG_RUNTIME_DIR/dmn-{session}.sock) and send newline-delimited JSON:
EXEC — send input to the shell:
{"type": "EXEC", "payload": {"command": "ls -la\n"}}
ATTACH — switch to raw bidirectional mode:
{"type": "ATTACH"}
After the {"ok": true}\n response, the connection is raw: bytes from the client go to the PTY, bytes from the PTY go to the client.
WATCH — read-only attach (output only, input discarded):
{"type": "WATCH"}
Resize (in ATTACH mode)
Terminal size changes are sent in-band as a 6-byte escape sequence:
\x00 R cols_hi cols_lo rows_hi rows_lo
Requirements
- Python 3.14+
- Node/npm (for the web client's ghostty-web dependency)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dmn_pty-1.0.0.tar.gz.
File metadata
- Download URL: dmn_pty-1.0.0.tar.gz
- Upload date:
- Size: 58.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87031c71be131d2be0498b7763772bd98a473604597f270f3e65beafb24635f6
|
|
| MD5 |
c5268187ea4cb4f670a9c45096e2668d
|
|
| BLAKE2b-256 |
39a9fa7a5138848b2850c99e3b08b8d8d5cee0b9e0fb95b9842bcc5d5638f6da
|
File details
Details for the file dmn_pty-1.0.0-py3-none-any.whl.
File metadata
- Download URL: dmn_pty-1.0.0-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9388ae161ae5a7273bc0f83b6a1b4ac2c6ab076e0ccf9ab6d7be63482cd0dd0a
|
|
| MD5 |
406d02eb0953063c9d8b47d2928af9b5
|
|
| BLAKE2b-256 |
7ec56c426fb36c412e7b75805e81d03a341a88a46f7715b1a19e434b8d160ddc
|