pi-web-console
把 Pi CLI(pi.dev)的全部能力通过 Web UI 暴露出来 —— 后端为每个会话孵化 pi --mode rpc 子进程做 JSONL 双向桥接,Web 前端经 WebSocket 与之对话,原生复用 Pi 全部能力。
Package details
Install pi-web-console from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-web-console- Package
pi-web-console- Version
1.0.0- Published
- Aug 18, 2026
- Downloads
- 150/mo · 150/wk
- Author
- applesun
- License
- MIT
- Types
- extension
- Size
- 316.2 KB
- Dependencies
- 3 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Pi Web Console
把 Pi(一个极简、可扩展的终端编码 Agent)的全部能力通过 Web UI 暴露出来。架构与 Pi 官方集成规范一致:后端为每个会话孵化一个 pi --mode rpc 子进程,在 stdin/stdout 上做 JSONL 双向桥接,Web 前端经 WebSocket 与后端对话,从而原生复用 Pi 的全部能力,而不是重造一个 Agent。
Pi 官方明确 RPC 模式(
--mode rpc,stdin/stdout JSONL)是"把 Pi 嵌入 IDE / 外部 UI"的首选机制。本项目即是该机制在 Web 端的完整实现。
特性
- 原生复用 Pi 全部能力:
prompt / steer / follow_up / abort / bash / set_model / set_thinking_level / compact / fork / clone / switch_session / export_html / get_tree / get_session_stats …全部 RPC 命令均可用。 - 流式渲染:文本增量(
text_delta)、思考过程(thinking_delta)、工具调用(tool_execution_*)实时呈现,支持 Markdown。 - 扩展 UI 子协议:正确处理
select / confirm / input / editor(弹窗回填extension_ui_response)以及notify / setStatus / setWidget / setTitle。 - 会话管理:新建 / 销毁 / 切换到磁盘上的历史会话(与 CLI 共享
~/.pi/agent/sessions),树形分支、分叉、克隆、导出 HTML。 - 模型与思考等级:
get_available_models/get_available_thinking_levels驱动下拉框,set_model/set_thinking_level即时切换。 - 用量统计:Token 用量、成本、上下文占用(
get_session_stats)。 - 一次性模式:
pi --mode json(print/JSON 事件流)做快速提问,不占用会话。 - 无密钥演示:内置
test/mock-pi.js模拟 pi 子进程,可端到端跑通整个链路。
架构
┌────────────┐ WebSocket (JSON) ┌──────────────────────────────┐
│ 浏览器前端 │ ◄────────────────────► │ Node 后端 (express + ws) │
│ index.html │ │ ┌────────────────────────┐ │
│ app.js │ │ │ SessionManager │ │
└────────────┘ │ │ ┌──────────────────┐ │ │
│ │ │ PiRpcSession #1 │ │ │
REST (健康检查 / 会话列表) │ │ │ spawn pi │ │ │
┌────────────┐ │ │ │ --mode rpc │ │ │
│ GET /api/* │ ◄────────────────────┤ │ └────────┬─────────┘ │ │
└────────────┘ │ └────────────┼───────────┘ │
└───────────────┼─────────────┘
stdin 命令 / stdout 事件+响应
│
┌────────────▼─────────────┐
│ pi --mode rpc │
│ (JSONL over stdio) │
└──────────────────────────┘
- 一个会话 = 一个
pi --mode rpc子进程。会话生命周期与子进程绑定,父进程退出即自然终止。 - 后端只做透明转发 + 请求/响应 id 关联,不解析、不改造 Agent 语义——前端直接发 Pi RPC 命令对象。
- 严格 JSONL 帧解析:仅以
\n切分记录、剥离尾部\r,不使用会把U+2028/2029当换行的通用行读取器(如 Nodereadline)。
WebSocket 协议(后端 ↔ 前端)
客户端 → 服务端
| type | 字段 | 说明 |
|---|---|---|
session.create |
payload: { cwd?, name?, env? } |
创建会话(spawn pi) |
session.destroy |
runtimeId |
销毁会话(kill 子进程) |
session.list |
— | 列出活跃 + 磁盘会话 |
session.deleteDisk |
sessionFile |
删除磁盘上的历史会话文件(.jsonl,路径受限 + 活跃占用保护) |
command |
runtimeId, command, clientId? |
转发 Pi RPC 命令 |
ui.response |
runtimeId, response |
回填 extension_ui_response |
oneshot |
payload: { prompt, cwd?, model?, provider? } |
pi --mode json 一次性调用 |
服务端 → 客户端
| type | 字段 | 说明 |
|---|---|---|
hello |
pi |
pi 可用性 / 版本 |
session.created / session.destroyed / session.exited / session.list |
— | 会话生命周期与列表 |
session.diskDeleted |
sessionFile, removed |
磁盘历史会话已删除(全端广播刷新) |
command.ack |
id, clientId |
命令已写出的实际 id |
response |
runtimeId, response |
Pi 命令应答 |
event |
runtimeId, event |
Pi Agent 事件流(原始透传) |
ui.request |
runtimeId, request |
扩展 UI 请求 |
stderr |
runtimeId, text |
pi 子进程 stderr |
oneshot.event / oneshot.done |
— | 一次性调用事件流 |
快速开始
前置:Node ≥ 18,且已安装 Pi(npm install -g --ignore-scripts @earendil-works/pi-coding-agent 或 curl -fsSL https://pi.dev/install.sh | sh)。
cd pi-web-console
npm install
npm start
打开 http://127.0.0.1:4120 即可。点「+ 新会话」,输入消息回车发送;运行中回车即 Steer,或用 Follow-up / 中止 按钮。
无 API 密钥演示(mock pi)
npm run demo
此时后端用 node test/mock-pi.js 模拟 pi 子进程,可完整体验聊天、工具卡、统计、树、分叉等交互,无需任何模型密钥。
作为 Pi 插件安装(pi install)
本项目内置了一个真正的 Pi Extension(extensions/web-console.ts),通过标准的包管理方式分发,无需单独 git clone:
pi install npm:pi-web-console # 安装到 ~/.pi/agent/
# 或项目内安装(团队共享,随 pi 启动自动安装缺失包):
pi install -l npm:pi-web-console
安装后在任意 pi 会话中输入:
/web-console
即会以子进程方式拉起 server/index.js(默认 http://127.0.0.1:4120),并尝试自动打开浏览器;工作目录、会话自动继承当前 pi 会话的 cwd。
/web-console 8080— 指定端口启动/web-console stop— 停止- 会话退出 /
/reload时会自动清理子进程
配置(.env)
复制 .env.example 为 .env,按需修改。关键项:
| 变量 | 默认 | 说明 |
|---|---|---|
HOST / PORT |
127.0.0.1 / 4120 |
监听地址/端口。默认仅本机 |
PI_BIN |
pi |
pi 可执行文件,可带参数(如 node test/mock-pi.js) |
PI_SESSION_DIR |
~/.pi/agent/sessions |
会话目录(默认与 CLI 共享) |
DEFAULT_CWD |
启动目录 | 新会话默认工作目录 |
ALLOWED_CWDS |
空 | 白名单工作目录(安全) |
PI_APPROVE |
false |
是否 --approve 信任项目本地文件 |
PI_EXTRA_ARGS |
空 | 透传给 pi 的额外参数(逗号分隔) |
AUTH_TOKEN |
空 | 设置后 REST/WS 需携带 token |
MAX_SESSIONS |
20 |
最大同时会话数 |
安全须知(重要)
⚠️ 本应用让浏览器驱动 pi,而 pi 可在机器上执行 bash 等工具。默认只绑定 127.0.0.1。不要在没有鉴权与可信网络的前提下暴露到公网。
- 保持
HOST=127.0.0.1;确需远程访问时务必设置AUTH_TOKEN并走 HTTPS 反向代理。 - 用
ALLOWED_CWDS把会话限制在指定项目目录。 - 需要权限门禁/沙箱时,可结合 Pi 扩展(permission-gate、sandbox、protected-paths)或把 pi 跑进容器(见 Pi 官方 Containerization 文档)。
项目结构
pi-web-console/
├── server/
│ ├── index.js # HTTP + WebSocket 服务入口、REST、鉴权
│ ├── config.js # 环境配置
│ ├── jsonl.js # 严格 JSONL 读取器(仅 \n 切分)
│ ├── pi-rpc-session.js # PiRpcSession:spawn pi --mode rpc 并桥接
│ ├── session-manager.js # 会话管理 + 磁盘会话枚举
│ ├── one-shot.js # pi --mode json 一次性调用
│ └── check-pi.js # pi 可用性探测
├── public/
│ ├── index.html
│ ├── css/style.css
│ └── js/ (app.js, ws.js, markdown.js)
└── test/
├── mock-pi.js # 模拟 pi(无密钥演示/测试)
└── smoke.mjs # 后端桥接冒烟测试
测试
npm run smoke # 用 mock pi 验证 JSONL 桥接(事件流 + 响应关联)
参考
- Pi 官网 · RPC 模式文档 · JSON 事件流
- Pi 源码(earendil-works/pi)
- 真实世界集成参考:OpenClaw