omp packages

pios-webui0.37.0

Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, systemd/launchd deployable

mrytsr Published 1 month ago MIT ~181 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pios

English | 简体中文

npm 版本 Node.js 许可证

一个精致的 pi 浏览器界面:流式对话、查看工具调用、管理文件, 在一个工作台里完成开发任务。

pi 编码智能体 的 Web 聊天界面 —— 智能体通过 pi SDK 在服务端进程内运行, 事件经 WebSocket 流式推送到浏览器。支持思考块与工具调用、附件与图片问答、内置终端、 模型管理,以及设置面板(自定义系统提示词、技能/插件开关、设置预设一键应用)等功能。 需要 Node.js ≥ 22.19 及配置好的 pi 环境。

作者的其他项目

正在使用 DSH 构建工具?

dsh-ui-tools 是作者的配套项目, 用于在 DSH 生态中构建和扩展 UI 工具。

功能特性

对话

  • WebSocket 流式聊天 —— pi SDK 在服务端进程内运行,事件以快照(60ms 节流)推送,浏览器按快照渲染。
  • 思考块、工具调用卡片、bash 输出,实时显示状态(执行中 → 已结束 · 等模型 · 耗时)。
  • 补充(steer) —— 回复流式中可排队发送跟进消息,当前回合工具结算后立即注入(对应 pi CLI 的 Enter 打断语义)。
  • 斜杠命令 —— 输入 / 弹出命令选择器(内置 / 扩展 / 模板 / 技能);内置 /new /model /compact /cwd /thinking /resume,另有 /help(命令清单)与 /copy(复制上一条回复)。
  • 每项目多对话并发 —— 每个对话独立 agent runtime,切走后仍在后台运行;「运行的对话」列表显示流式进度,可随时切回。
  • 编辑重问 —— 把任意历史问题 fork 成新分支重新提问,原对话不受影响。
  • 超过 30 条的消息自动折叠为摘要行(惰性渲染,点击展开)。
  • 问题导航 —— 右侧浮动导航条 + 每个问题顶部的序号标签,一键跳转。

文件、图片与附件

  • 三种附件模式:inline(≤12KB 内联)、reference(仅路径引用)、lines(选中行),超限自动降级。
  • 粘贴 / 拖拽 / 上传图片 —— 浏览器端自动缩放,模型支持识图时作为图片内容发送(不支持时提示警告)。
  • 视觉桥 —— 当前模型不支持识图时,把图片交给自动发现的视觉模型转写成文字证据(按批次缓存,可在设置里指定模型/开关)。
  • 免工作区路径附加任意文件 —— 存入全局上传目录,小文件内联,其余以绝对路径引用。
  • 文件预览 —— 行号、点选/拖拽/Shift 选区(可添加到对话为 lines 附件)、GBK 回退解码、二进制十六进制视图、媒体 HTTP 预览(支持 Range)、下载按钮。
  • 实时文件树 —— 服务端对当前列出目录 fs.watch,改动即静默重列;超大目录显示截断提示。

终端与 Git

  • 内置终端(xterm.js + node-pty),每客户端独立 PTY 管理;Windows 自动选择 Git Bash(busybox 兜底)。
  • 源代码管理(Git)面板 —— 经隐藏查询终端展示 status / branch / diff / 未跟踪文件;提交、切换分支、推送、拉取复用可见终端并自动切换到终端视图。

模型与设置

  • 模型管理 —— UI 里编辑 models.json、按 provider 设置 API key(密钥/headers 永不下发浏览器)。
  • 主题切换 —— 顶栏选择主题;每个主题是完整独立的样式表(默认深色 + 内置亮色)。如何添加自定义主题或向仓库贡献主题,见 主题。
  • 思考强度(thinking level)按模型切换(只显示该模型实际支持的档位)。
  • 首次配置引导(PiSetupModal)。
  • 设置面板 —— 系统提示词(追加或整体替换)、技能/插件一键开关(即时生效)、设置预设保存/应用/删除、视觉桥模型与开关。

目标(Goal)模式

  • GoalBar 目标栏 —— 设置目标 + 审查模型 + 最大轮数 + 锁定开关。
  • 目标调研向导(「AI 提炼」)—— 通过引导式问卷把原始需求收敛成明确目标。
  • 自动审查循环 —— 每轮结束后用独立审查会话核对「目标 + 最终文本 + git diff HEAD」;不达标就把审查意见作为 steer 注入重改,直到通过或达到轮数上限。

后台任务

  • 后台任务面板 —— 通过端口快照检测 agent 启动的服务(端口/pid/名称),可单独停止或全部关闭。
  • 工具看门狗 —— 单个工具调用超过 20 分钟自动中断会话。
  • 只停止 bash 命令 —— 中止运行中的 bash 工具而不打断对话。

安全与运维

  • 默认只绑 loopback;局域网 / 容器需显式 PI_WEB_HOST=0.0.0.0。
  • WebSocket Origin/Host 同权威校验 —— 跨源页面直接拒绝(403);反代场景用 PI_WEB_ALLOW_ORIGINS 白名单。
  • 本地控制 socket 提供 server status|quiesce|unquiesce(排空模式:拒绝新工作、存量跑完)。
  • 凭据不下发浏览器 —— provider headers(可能含 Authorization/API key)永不发送到前端。
  • 声音提醒、中英文界面、最近项目列表(点击即切换工作目录)。

部署与更新

  • 前台运行 / 全局 npm 安装 / macOS launchd / Linux systemd / Windows 计划任务 / 桌面快捷方式(server shortcut)。
  • 界面内自更新 —— 对比 npm registry 版本,安装后自动重启服务。

界面截图

设置面板

内置终端

对话界面

Git 源代码管理面板

安装

npm i -g pios            # 全局安装(推荐)
npx pios                 # 或免安装直接跑(拉取最新版,启动在 :8787)
npm i -g .                    # 或安装本地 checkout

npm ≥ 12? npm 12+ 默认阻止依赖安装脚本(会看到 npm warn install-scripts … blocked 警告)。 node-pty 是原生模块,需要放行其脚本(其余两个包只是 no-op/纯提示,一并放行可消除警告):

npm i -g --allow-scripts=node-pty,@google/genai,protobufjs pios@latest

启动

pios                                           # 前台,http://localhost:8787
PORT=9000 PI_WEB_CWD=/path/to/project pios     # 自定义端口 / 工作目录

停止

  • 前台:在运行它的终端里按 Ctrl+C。
  • 作为服务:pios server stop(停止实例;开机自启保留,直到 server uninstall)。

更新

npm i -g pios@latest     # 升级到最新发布版本
pios server restart      # 重启服务使新版本生效(前台运行则手动重启)

卸载

npm uninstall -g pios

卸载不会删除你的聊天记录 —— 会话数据存放在 <cwd>/.pi-web(或 PI_WEB_DATA_DIR), 卸载/升级后依然保留。

作为系统服务(开机自启)

pios server install --port 9000 --cwd /path/to/project   # 安装 + 启动
pios server status                     # 运行中?开机自启?
pios server restart                    # 重启(应用配置/版本变更)
pios server stop                       # 停止(开机自启保留)
pios server start                      # 再次启动
pios server uninstall                  # 彻底移除服务
pios server shortcut                   # 桌面一键启动图标
pios server quiesce                    # 排空:拒绝新的对话/消息,存量运行继续跑完
pios server unquiesce                  # 解除排空,恢复接收新工作

server status 还会经本地控制 socket 显示实时状态(版本、PID、排空状态、 浏览器连接数、运行中对话数)——quiesce/unquiesce 也走同一个 socket。

  • macOS → launchd 代理(无需 sudo),日志 /tmp/pios.log / .err
  • Linux → systemd unit(systemctl enable --now),日志 journalctl -u pios -f
  • Windows → 计划任务(登录自启,隐藏 PowerShell 窗口,无黑窗)

选项:--port(默认 8787)、--cwd(工作目录)、--data-dir(会话目录)、 --name(自定义服务名)。重复执行 server install 并传入新选项即可重新生成配置 并重启服务 —— 这就是修改已装服务端口/工作目录的方式。

主题

每个主题是一份完整独立的样式表 —— 一份自包含的 CSS 文件(不做 CSS 变量抽取、不需要引入基础文件)。切换主题就是整文件替换,因此任何主题都能在所有版本上工作。

仓库内唯一内置主题是 themes/white.css,随 npm 包分发。主题选择器在设置面板(⚙ → 外观 → 主题),当前选择按浏览器存在 localStorage。

使用主题

在顶栏直接选择即可 —— 内置主题和用户主题合并显示在同一个菜单里;同名 id 时用户主题优先。

本地添加主题(无需 GitHub)

把任意 CSS 文件丢进数据目录的 themes 文件夹就会自动出现在主题菜单里 —— 不用重启、不用重新构建:

  1. 找到数据目录(默认 ~/.pi-web,可用 PI_WEB_DATA_DIR 覆盖)。
  2. 创建 <dataDir>/themes/ 并放入你的样式表,例如 ~/.pi-web/themes/my-theme.css。
  3. 刷新页面,在顶栏选择它。文件名(去掉 .css) 就是菜单里显示的主题 id。
~/.pi-web/
└── themes/
    └── my-theme.css          # 菜单里显示为 "my-theme"

最容易的写法:复制 themes/white.css,改 :root 颜色和必要的硬编码值即可 —— 文件必须自包含。注意:

  • 终端跟随主题 —— 在你的 :root 里设置 --term-* 变量(终端 ANSI 配色 + --term-bg),xterm 画布和它的内边距容器都会自动适配(默认值见 themes/white.css)。
  • 代码高亮色(打包自带 highlight.js 的 github-dark.css)必须在你的主题文件里覆盖,否则代码会看不清 —— 参照 themes/white.css 末尾的 .hljs 覆盖写法。
  • 主题 id 必须匹配 ^[A-Za-z0-9_-]+$(不能有点和斜杠 —— 服务端有路径穿越防护)。

向仓库贡献主题(GitHub)

想让你的主题随包分发给所有人?在 github.com/xing-shuyin/pios 开一个 Pull Request:

  1. Fork 并 clone 仓库。
  2. 创建 themes/<id>.css —— 一份自包含的样式表。以 themes/white.css 为模板。
  3. 本地验证:运行 npm run dev,用设置面板主题选择器确认你的主题能被列出、渲染正确(对话卡片、代码块、工具调用卡片、Git/终端面板)。
  4. 提交(git add themes/<id>.css)并开 PR。themes/ 已在 npm 包 files 白名单里,合并发布后 npm i -g pios 即可把你的主题带给所有人。

合并主题的规则:必须是单一自包含 CSS 文件、是完整独立主题、不要 import 基础文件、保持 xterm 区域可读、覆盖 .hljs 语法高亮色以保证代码可读。

安全

  • 默认只绑 loopback —— 服务器只监听 127.0.0.1,不暴露到网络;需要局域网访问或 需要远程访问时显式配置监听地址或使用 nginx 反代。
  • WebSocket Origin 校验 —— 浏览器页面连 /ws 时其 Origin 的 hostname 和端口 必须与请求 Host 一致,跨源页面直接 403;无 Origin 的非浏览器客户端不受影响。 反向代理场景可用 PI_WEB_ALLOW_ORIGINS=http://你的域名:端口 放行。
  • Quiesce 排空 —— server quiesce 后拒绝新的 prompt/编辑重问/会话恢复,存量运行 跑完为止(升级/备份前用);server unquiesce 恢复。
  • 凭据不下发浏览器 —— provider 的 headers(可能含 Authorization / API key) 永不发给浏览器;模型管理 UI 编辑其他字段,服务端自动保留 headers。

反向代理(nginx)

pios 默认只绑 loopback,同机 nginx 反代是官方支持的远程访问方式(无需 PI_WEB_HOST=0.0.0.0):

# pios 在 127.0.0.1:8787,对外暴露为 https://your-host/pi/
server {
    listen 443 ssl;
    server_name your-host;
    # ssl_certificate ... / ssl_certificate_key ...

    # 应用入口(剥掉 /pi/ 前缀)
    location /pi/ {
        proxy_pass http://127.0.0.1:8787/;
        proxy_http_version 1.1;
        # 必须用 $http_host(保留端口)—— 服务端的 Origin 校验比较完整权威
        # (hostname + 端口),$host 会丢掉端口导致 403
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket —— 必须原样转发 Host,否则升级被 403(页面能开,
    # 但对话/终端一直重连)
    location /ws {
        proxy_pass http://127.0.0.1:8787;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    # 构建产物的绝对路径资源/API(根路径,不带 /pi/)
    location /assets/  { proxy_pass http://127.0.0.1:8787; }
    location = /favicon.svg           { proxy_pass http://127.0.0.1:8787; }
    location = /favicon-streaming.svg { proxy_pass http://127.0.0.1:8787; }
    location = /api/file   { proxy_pass http://127.0.0.1:8787; }
    location = /api/health { proxy_pass http://127.0.0.1:8787; }
}

要点:

  • Host 必须用 $http_host(保留端口),/pi/ 和 /ws 都要 —— Origin 校验比较 hostname 和端口。proxy_set_header Host $host 或不设置(默认上游地址 127.0.0.1:8787)都会 403。
  • 同源自动通过:只要浏览器 Origin 与转发后的 Host 一致(普通反代天然如此), 就无需 PI_WEB_ALLOW_ORIGINS;仅当浏览器 Origin 与后端看到的 Host 不同 (如 TLS 终止代理改了端口)才需要设置。
  • 不要开 proxy_protocol(除非确实要真实客户端 IP):它会让 nginx 拒绝所有 不带 PROXY 头的连接,局域网直连和 frp 以外的客户端全挂。用 frp 时同样去掉 transport.proxyProtocolVersion(除非 nginx 也 listen proxy_protocol)。
  • 局域网免代理访问:直接设 PI_WEB_HOST=0.0.0.0(加防火墙规则), 或把上面的 server 块放到 80/443 端口。

带 frp 内网穿透的完整可运行示例:deploy/nginx-pios.conf。

License

MIT