FWS – 可通过 pip 安装的嵌入式进程监护器,支持 PTY/管道/dtach 后端

2作者: mrsurge大约 19 小时前
我发布了 *Framework Shells* (`fws`):一个独立的 Python 包,用于编排长时间运行的后台进程(“shell”),支持 *PTY*、*管道* 和 *dtach* 后端。<p>这适用于那些不想搭建完整 supervisor 堆栈(或没有堆栈)的环境:快速的多服务原型、开发环境、受限的用户空间等。<p>### 它的作用<p>* 使用以下方式生成/管理 shell:<p><pre><code> * **PTY**: 交互式终端会话(调整大小、输入、流) * **管道**: stdin/stdout/stderr 流(适用于守护进程/LSP) * **dtach**: 可附着/分离的持久会话(在管理器重启后仍然存在)</code></pre> * *运行时隔离*(主要功能):shell 通过 `~/.cache/framework_shells/runtimes/<repo_fingerprint>/<runtime_id>/...` 进行命名空间管理,因此同一仓库的两个克隆可以并发运行,而不会出现交叉采用或交叉控制的情况。 * *控制界面*:CLI + 可选的 FastAPI/WS UI,用于列出、查看日志和生命周期操作。 * 可选的 *钩子*,用于主机集成(外部注册表/遥测)。<p>### CLI 快速入门<p>```bash # 列出 shell fws list<p># 运行一次性 shell(无规范) fws run --backend pty --label demo -- bash -l -i<p># 应用 YAML shellspec(推荐) fws up shells.yaml<p># 终止 shell fws down<p># 附着到 dtach 后端 shell fws attach <shell_id><p># 显示已管理的 shell + procfs 后代 fws tree --depth 4 ```<p>### Shellspec 示例<p>```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}"] ```<p>### 隔离 + 安全模型(默认简单)<p>* `FRAMEWORK_SHELLS_SECRET` 派生 `runtime_id`(命名空间)和 API 令牌。 * 如果设置了 secret,则修改 API 端点需要:<p><pre><code> * `Authorization: Bearer <token>` (或 `X-Framework-Key`)。</code></pre> * 如果未设置 secret,则禁用身份验证(开发模式)。<p>硬限制:如果两个运行时共享相同的 OS 用户/UID,OS 仍然可能允许相互发出信号。保证是:*通过库的控制平面*,不会出现交叉计数/采用/控制。<p>### 实际应用<p>我将其用作完整开发环境的基础,其中“应用程序是 shell”(终端、IDE + LSP、代理/MCP、aria2 RPC、文件浏览器、llama.cpp 运行器等)。仓库:<p>```text https://github.com/mrsurge/termux-extensions-2 ```<p>### 我想要的反馈<p>* secret/fingerprint/运行时隔离的契约感觉对吗? * 默认 API/CLI 中是否有明显的陷阱? * 与 systemd/supervisord/tmux/dtach 相比:您会在哪里使用它?<p>github.com/mrsurge/framework-shells<p>pip install "framework-shells @ git+https://github.com/mrsurge/framework-shells@main"<p>```bash fws --help ```
查看原文
I’m releasing *Framework Shells* (`fws`): a standalone Python package for orchestrating long-running background processes (“shells”) with *PTY*, *pipes*, and *dtach* backends.<p>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.<p>### What it does<p>* Spawn&#x2F;manage shells with:<p><pre><code> * **PTY**: interactive terminal sessions (resize, input, stream) * **Pipes**: stdin&#x2F;stdout&#x2F;stderr streams (good for daemons&#x2F;LSPs) * **dtach**: persistent sessions you can attach&#x2F;detach to (survives manager restarts)</code></pre> * *Runtime isolation* (the big feature): shells are namespaced by `~&#x2F;.cache&#x2F;framework_shells&#x2F;runtimes&#x2F;&lt;repo_fingerprint&gt;&#x2F;&lt;runtime_id&gt;&#x2F;...` so two clones of the same repo can run concurrently without cross-adoption or cross-control. * *Control surfaces*: CLI + optional FastAPI&#x2F;WS UI for listing, logs, and lifecycle actions. * Optional *hooks* for host integration (external registries&#x2F;telemetry).<p>### CLI quickstart<p>```bash # list shells fws list<p># run a one-off shell (no spec) fws run --backend pty --label demo -- bash -l -i<p># apply a YAML shellspec (recommended) fws up shells.yaml<p># terminate shells fws down<p># attach to a dtach-backed shell fws attach &lt;shell_id&gt;<p># show managed shells + procfs descendants fws tree --depth 4 ```<p>### Shellspec example<p>```yaml version: &quot;1&quot; shells: worker: backend: proc cwd: ${ctx:PROJECT_ROOT} subgroups: [&quot;worker&quot;, &quot;project:${ctx:APP_ID}&quot;] command: [&quot;python&quot;, &quot;-m&quot;, &quot;your_module.worker&quot;, &quot;--port&quot;, &quot;${free_port}&quot;] ```<p>### Isolation + security model (simple by default)<p>* `FRAMEWORK_SHELLS_SECRET` derives the `runtime_id` (namespace) and API tokens. * If the secret is set, mutating API endpoints require:<p><pre><code> * `Authorization: Bearer &lt;token&gt;` (or `X-Framework-Key`).</code></pre> * If the secret is unset, auth is disabled (dev mode).<p>Hard limit: if two runtimes share the same OS user&#x2F;UID, the OS may still allow signaling each other’s processes. The guarantee is: no cross-count&#x2F;adopt&#x2F;control *through the library’s control plane*.<p>### Real-world usage<p>I use this as the substrate of a full dev environment where “apps are shells” (terminals, IDE + LSP, agent&#x2F;MCP, aria2 RPC, file explorer, llama.cpp runner, etc.). Repo:<p>```text https:&#x2F;&#x2F;github.com&#x2F;mrsurge&#x2F;termux-extensions-2 ```<p>### Feedback I want<p>* Does the secret&#x2F;fingerprint&#x2F;runtime isolation contract feel right? * Any obvious foot-guns in the default API&#x2F;CLI? * Expectations vs systemd&#x2F;supervisord&#x2F;tmux&#x2F;dtach: where would you use this?<p>github.com&#x2F;mrsurge&#x2F;framework-shells<p>pip install &quot;framework-shells @ git+https:&#x2F;&#x2F;github.com&#x2F;mrsurge&#x2F;framework-shells@main&quot;<p>```bash fws --help ```