FWS – pip-installable embedded process supervisor with PTY/pipe/dtach back ends

I’m releasing *Framework Shells* (`fws`): a standalone Python package for orchestrating long-running background processes (“shells”) with *PTY*, *pipes*, and *dtach* backends.

This is meant for environments where you don’t want to stand up a full supervisor stack (or don’t have one): quick multi-service prototypes, dev environments, constrained userlands, etc.

### What it does

* Spawn/manage shells with:

  * **PTY**: interactive terminal sessions (resize, input, stream)
  * **Pipes**: stdin/stdout/stderr streams (good for daemons/LSPs)
  * **dtach**: persistent sessions you can attach/detach to (survives manager restarts)
* *Runtime isolation* (the big feature): shells are namespaced by `~/.cache/framework_shells/runtimes/<repo_fingerprint>/<runtime_id>/...` so two clones of the same repo can run concurrently without cross-adoption or cross-control. * *Control surfaces*: CLI + optional FastAPI/WS UI for listing, logs, and lifecycle actions. * Optional *hooks* for host integration (external registries/telemetry).

### CLI quickstart

```bash # list shells fws list

# run a one-off shell (no spec) fws run --backend pty --label demo -- bash -l -i

# apply a YAML shellspec (recommended) fws up shells.yaml

# terminate shells fws down

# attach to a dtach-backed shell fws attach <shell_id>

# show managed shells + procfs descendants fws tree --depth 4 ```

### Shellspec example

```yaml version: "1" shells: worker: backend: proc cwd: ${ctx:PROJECT_ROOT} subgroups: ["worker", "project:${ctx:APP_ID}"] command: ["python", "-m", "your_module.worker", "--port", "${free_port}"] ```

### Isolation + security model (simple by default)

* `FRAMEWORK_SHELLS_SECRET` derives the `runtime_id` (namespace) and API tokens. * If the secret is set, mutating API endpoints require:

  * `Authorization: Bearer <token>` (or `X-Framework-Key`).
* If the secret is unset, auth is disabled (dev mode).

Hard limit: if two runtimes share the same OS user/UID, the OS may still allow signaling each other’s processes. The guarantee is: no cross-count/adopt/control *through the library’s control plane*.

### Real-world usage

I use this as the substrate of a full dev environment where “apps are shells” (terminals, IDE + LSP, agent/MCP, aria2 RPC, file explorer, llama.cpp runner, etc.). Repo:

```text https://github.com/mrsurge/termux-extensions-2 ```

### Feedback I want

* Does the secret/fingerprint/runtime isolation contract feel right? * Any obvious foot-guns in the default API/CLI? * Expectations vs systemd/supervisord/tmux/dtach: where would you use this?

github.com/mrsurge/framework-shells

pip install "framework-shells @ git+https://github.com/mrsurge/framework-shells@main"

```bash fws --help ```

8 points | by mrsurge 3 days ago

2 comments

  • talideon 2 minutes ago
    First up, you shouldn't just paste a random lump of Markdown into the submission form. Write some actual prose. It makes your submission look sloppy.

    Secondly, what does this give me that either systemd or Supervisor (where systemd isn't available) don't already give me?

  • teraflop 1 hour ago
    > Expectations vs systemd/supervisord/tmux/dtach: where would you use this?

    Sorry to be blunt, but I feel like this is a big unanswered question that you should be addressing. Why would I use your tool over the other well-known alternatives? I read through your overview and I don't see an answer.

    You say that this is intended "for environments where you don’t want to stand up a full supervisor stack (or don’t have one)". And you compare it to systemd. But what Linux developer doesn't already have systemd installed?

    Or to use a different comparison, what advantage does "fws run" have over "podman run"? Podman already supports PTYs that can be attached/detached, allows isolating different processes, and has an HTTP API.

    It seems like you intend this for situations where you want a multi-pane text-base UI that resembles an IDE. But personally, I prefer to do this sort of thing by composing existing tools that provide that functionality (namely tmux/screen and Docker/Podman) rather than using a single integrated tool that tries to replace both.