从零到一跑通 Pi Web:Pi 编程智能体 Web 界面实战指南
从零到一跑通 Pi Web:Pi 编程智能体 Web 界面实战指南
【免费下载链接】pi-webWeb UI for the pi coding agent项目地址: https://gitcode.com/GitHub_Trending/pi/pi-web
Pi Web 是 pi 编程智能体的官方本地浏览器界面(Web UI),与 pi 共用本机配置和会话文件,让你在浏览器里查找、继续历史对话,管理模型与 Provider,浏览项目文件。本文覆盖安装启动、启动参数与环境变量配置速查,以及密码认证、主机白名单、文件访问边界背后的安全加固原理,读完即可直接部署。
给 pi 智能体一个浏览器:Pi Web 的定位
pi 智能体原本是终端工具:会话以 JSONL 形式落在~/.pi/agent/sessions/<编码后的工作目录>/<时间戳>_<uuid>.jsonl,配置散落在~/.pi/agent/models.json等文件里。Pi Web 不另起炉灶,它是一层架在同一份数据之上的薄 Next.js 壳:浏览器通过只读 API 解析会话文件,发消息时在 Node 进程内创建AgentSession,再用 SSE 收流式输出。
这个定位带来两点直接价值:
- 零割裂:终端里聊到一半的对话,浏览器里接着聊;模型配置改一处,两个界面都看得见。
- 数据始终在磁盘上:浏览会话不创建运行时,纯解析
.jsonl,Pi Web 不是会反锁你数据的第三套存储。
3 分钟跑起来:Pi Web 安装与首次启动
环境要求:Node.js 22.19.0 或更高(package.json 的engines字段有约束),先node --version确认。
npx 一次性运行
npx @agegr/pi-web@latest终端出现Ready后会自动打开浏览器;没自动打开就手动访问http://127.0.0.1:30141。默认只监听回环地址127.0.0.1,不会暴露到局域网。尚未配置 Provider 时,打开Models面板登录或添加 API Key 即可。
全局安装、更新与卸载
npm install -g @agegr/pi-web@latest pi-web全局安装后多出一组子命令:pi-web version打印版本、pi-web status列出运行中的服务、pi-web stop [--port N]停服、pi-web update更新(先stop再执行)。卸载:npm uninstall -g @agegr/pi-web。
从源码启动开发服务器
git clone https://gitcode.com/GitHub_Trending/pi/pi-web cd pi-web npm install npm run dev开发服务器同样运行在 http://127.0.0.1:30141。日常检查三连:npm test(单元测试)、node_modules/.bin/tsc --noEmit(类型检查)、npm run lint(ESLint)。⚠️ 开发期间不要运行next build或npm run build,它们写入.next/会直接干扰开发服务器;构建只属于发布流程。
能力地图:浏览器里都能干什么
- 会话工作区:按项目查找、继续、重命名、导出、删除对话,运行状态、上下文占用、花费、压缩信息实时可见 → lib/session-reader.ts
- 两种分支:新会话产生独立
.jsonl文件;"从此处编辑"在同一文件内分支(多个条目共享parentId),语义在 hooks/useAgentSession.ts 中明确区分,切勿混淆 - 项目文件工具:浏览与上传文件、查看 Git Diff,预览源码、Markdown、图片、音频、PDF、DOCX,文件变化自动刷新 → app/api/files/
- Git worktree:侧边栏切换 checkout,同一仓库不同 worktree 的会话归组展示 → lib/worktree.ts,详见 docs/worktrees.zh-CN.md
- 网页配置:Provider 登录与 API Key、模型管理、模型测试、插件包、技能,无需离开页面 → app/api/models-config/
- 三语界面:英文、简体中文、繁体中文,首次打开跟随浏览器语言,顶部栏可切换 → docs/i18n.md
启动配置速查表:参数优先级与环境变量
规则先说清:命令行参数优先于同名环境变量;端口必须是 0~65535 的整数,否则启动直接报错;传入未知参数会报错并以退出码 1 结束。
| 参数 / 环境变量 | 作用 | 默认值 | 备注 |
|---|---|---|---|
--help/-h | 打印启动选项并退出 | — | 退出码 0,不启动服务 |
--port <端口>/-p,或PORT | 服务端口 | 30141 | 必须为 0~65535 整数 |
--hostname <主机>/-H,或PI_WEB_HOSTNAME | 监听主机名 | 127.0.0.1 | 非回环会触发安全警告 |
--no-open,或PI_WEB_NO_OPEN=1 | 不自动打开浏览器 | 自动打开 | 环境变量接受1/true/yes/on |
PI_WEB_APP_NAME | PWA manifest 的名称 | Pi Web | 启动前设置,重启生效 |
PI_WEB_PASSWORD | 启用浏览器密码登录 | 不启用 | API 客户端可用用户名pi的 Basic Auth |
PI_WEB_ALLOWED_HOSTS | 额外允许的主机名 | 未设置 | 逗号分隔,精确匹配 |
PI_WEB_SKIP_VERSION_CHECK | 关闭更新检查 | 开启 | 设为1 |
PI_WEB_IDLE_TIMEOUT_MS | 会话空闲超时(毫秒) | 600000 | 0表示禁用 |
PI_WEB_SHUTDOWN_DEADLINE_MS | 关闭时等待扩展(毫秒) | 5000 | |
HTTP_PROXY/HTTPS_PROXY/NO_PROXY | 模型与 API 请求走代理 | 系统默认 | 仅服务端请求读取 |
场景示例:
# 局域网访问:8080 端口、监听 0.0.0.0、不自动开浏览器 pi-web -p 8080 -H 0.0.0.0 --no-open # 服务端模型/API 请求经本地代理转发 HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 NO_PROXY=localhost,127.0.0.1 \ npx @agegr/pi-web@latest$env:HTTP_PROXY = "http://127.0.0.1:7890" $env:HTTPS_PROXY = "http://127.0.0.1:7890" $env:NO_PROXY = "localhost,127.0.0.1" npx @agegr/pi-web@latest安全加固:密码认证、主机白名单与文件访问边界
⚠️ 监听非回环地址,等于把一个可执行高权限操作的智能体暴露出去。切勿通过明文 HTTP 把 Pi Web 挂到互联网上——密码认证只验证身份,不加密连接。
认证链路由 proxy.ts 中间件统一接管(matcher 为/、/login、/api/:path*):
- 未设
PI_WEB_PASSWORD时,/login直接重定向回/,其余请求放行(Host 检查仍会执行); - 启用密码后,未认证的浏览器页面重定向到
/login;未认证的 API 请求返回401并携带WWW-Authenticate: Basic realm="Pi Web"头,API 客户端按 Basic Auth 接入即可; - 登录成功后签发
pi_web_sessionCookie(HMAC-SHA256 签名,有效期 30 天),后续请求凭它通过校验。
密码校验细节在 lib/web-auth.ts:Basic Auth 用户名固定为pi,密码经 SHA-256 摘要后用timingSafeEqual比较,消除时序侧信道。lib/auth-throttle.ts 的限流器让登录表单与 API 共享失败计数,连续失败返回429,封禁期内即使密码正确也会被拒——否则"答对即解封"本身会泄漏信息。
主机白名单与 CSRF 在 lib/request-security.ts:API 请求的 Host 只信任localhost(含*.localhost)、IP 字面量,或操作者显式配置的主机名。IP 字面量天然抗 DNS rebinding——浏览器会在 Host 头中保留字面地址。Origin/Fetch Metadata 检查直接拒绝cross-site的浏览器跨站请求,并给"反向代理改写 Origin 但仍是同源"的场景留了兼容通路。
文件访问边界是独立的允许列表:lib/file-access.ts 收集所有会话的 cwd、解析出的项目根目录以及显式添加的根(带 5 秒 TTL 缓存),路径判定统一收敛到 lib/path-security.ts 的isPathWithinRoots()。文件浏览器因此不是通用文件浏览器:没在 Pi Web 里选过的工作目录,就是读不到。
可信局域网部署的推荐命令:
PI_WEB_PASSWORD='足够长的随机密码' pi-web --hostname 0.0.0.0入口脚本 bin/pi-web.js 检测到非回环监听且未启用密码时,会打印 "without authentication" 警告;即使已设密码,也会提示 HTTP 不保护传输中的密码。走反向代理时务必让它提供 HTTPS,并把外部主机名精确加入PI_WEB_ALLOWED_HOSTS——白名单不改监听地址,只做匹配。
源码导读:目录结构与关键模块
app/ Next.js 界面与 API 路由 components/ React 界面组件 hooks/ 客户端状态与交互 lib/ 会话、智能体、模型、文件、Git、安全逻辑 public/ 静态资源与 PWA 文件 bin/ npm CLI 入口及启动参数解析 docs/ 面向用户与贡献者的专题文档 demo/ 静态演示站关键模块:
- bin/pi-web.js — Node 版本检查、参数解析、拉起
next start子进程、输出Ready后打开浏览器(Windows 用cmd /c start、macOS 用open、Linux 用xdg-open),启动前还会轮换包内预置的 preview 密钥 - bin/pi-web-options.js — 参数与环境变量解析、端口校验、
--help文本 - lib/rpc-manager.ts —
startRpcSession()在进程内创建AgentSession,维护注册表与生命周期 - lib/session-reader.ts — 直读
.jsonl会话文件,纯只读,浏览不产生运行时 - lib/agent-client.ts — 面向
/api/agent命令的类型化 fetch 封装 - proxy.ts + lib/web-auth.ts + lib/request-security.ts — 认证入口、会话令牌、Host 白名单、跨站检查
- lib/file-access.ts + lib/path-security.ts —
/api/files的允许根安全边界 - lib/worktree.ts — 把 linked worktree 解析回主仓库根,供侧边栏归组
一次发消息的流转:POST /api/agent/[id]→startRpcSession()创建AgentSession→session.prompt();浏览器从GET /api/agent/[id]/events的 SSE 流实时消费事件。而浏览会话只走GET /api/sessions(列目录)与GET /api/sessions/[id](经 SDK 的SessionManager工具解析.jsonl),全程不碰运行时。
避坑清单:部署时最容易踩的六个坑
- 坑:跑过
next build后npm run dev报错→ 构建产物污染了.next/开发图 → 开发期不构建;已污染就清掉.next再重启。 - 坑:两个
next dev进程互相打架、端口占用→ 它们争用同一个.next/dev/lock→ 先lsof -nP -iTCP:30141 -sTCP:LISTEN确认已有健康进程并复用,切勿换个端口开第二个。 - 坑:浏览器里看不到历史会话→ Pi Web 跑在容器或远程主机上,读的是另一台机器的本地路径 → 让 Pi Web 与 pi 运行在同一文件系统环境;换 agent 目录用
PI_CODING_AGENT_DIR。 - 坑:挂上反向代理后 API 返回 403 Untrusted request→ 代理传的外部主机名不在信任列表 → 把它精确加入
PI_WEB_ALLOWED_HOSTS(逗号分隔,不支持通配符)。 - 坑:API 客户端反复收到 429→ 认证限流器累计了连续失败,封禁期内正确密码也拒绝 → 用用户名
pi的 Basic Auth 正常重试即可,不要做循环爆破。 - 坑:文件浏览器"读不到"某个目录→ 这是 allow-list 设计的边界,不是权限 bug → 在 Pi Web 中把该目录选为工作目录,或让它成为已识别的项目根/会话根。
许可证
Pi Web 采用 MIT 许可证,文本见 LICENSE。完整的架构说明与文件地图在 AGENTS.md;要参与开发,先读 docs/CONTRIBUTING.zh-CN.md 确认改动范围,贡献者文档还有 docs/i18n.md(国际化)与 docs/release.md(发布流程)。
【免费下载链接】pi-webWeb UI for the pi coding agent项目地址: https://gitcode.com/GitHub_Trending/pi/pi-web
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考