内容
# OMP Studio
> **状态: 活跃开发中** — OMP Studio 是早期、pre-1.0 软件,正在进行大量迭代。预计会有快速的变化、粗糙的边缘和突破性的变化:UI、内部 API 和磁盘/设置格式 **尚未稳定**。
适用于 [Oh My Pi (`omp`)](https://github.com/can1357/oh-my-pi) 编码代理程序的时尚桌面控制台 — 直观的代理聊天、仪表板和浏览 `omp` 所知的一切,全部在一个原生窗口中。
OMP Studio 将 `omp` 命令行程序封装在 Electron 桌面应用程序中。它通过 `omp --mode rpc` 协议驱动实际的代理交互,读取本地 `~/.omp/agent` 状态,并通过 `gh` CLI 显示 GitHub 上下文 — 这样您就可以在无需终端的情况下运行、检查和管理代理工作。
## 功能
- **仪表板** — 一个聚合最近的会话、模型和提供者计数、配置的 MCP 服务器、可用技能、捆绑代理和当前 GitHub 仓库的单个面板。
- **实时代理聊天** — 通过 `omp` RPC 协议进行完整的代理交互,具有流式助手文本、思考块、实时工具调用渲染、转向和后续跟进,每个会话都由自己的 `omp` 子进程支持。
- **工作区** — 具有侧边栏切换器、添加工作区对话框和固定功能的第一类项目工作区。选择工作区将新的聊天指向其目录;实时会话保留自己的工作目录。
- **子代理深入分析** — 展开会话的子代理工作流树,并在检查器中打开任何节点以跟进其实时进度、工具调用和转录。
- **会话浏览器** — 浏览和重放过去的会话转录,直接从磁盘 `omp` 会话日志中读取。
- **技能和命令** — 发现项目、用户和捆绑技能,浏览活动会话的可用斜杠命令(固定收藏夹,将它们放入聊天中),并查看 TUI 独有命令的参考。
- **MCP 服务器** — 检查为您的用户和项目配置的模型上下文协议服务器。
- **捆绑代理** — 探索与 `omp` 捆绑的任务代理,包括它们的模型和 spawn 关系。
- **模型/提供者** — 查看模型目录和已验证的提供者。
- **GitHub** — 查看当前仓库、问题和拉取请求,以及您的拥有仓库。
- **Linear** — 连接 Linear API 密钥(存储在 OS 密钥链中,绝不存储在设置中)以浏览您的团队、项目和问题;密钥和所有 HTTP 操作均在主进程中进行。
- **终端** — 一个可选的嵌入式终端,通过 `node-pty` 在活动工作区中运行一个真正的 shell(默认为关闭状态)。
- **浏览器** — 一个可选的嵌入式 Web 浏览器,在单独的沙盒视图中渲染,与特权应用程序窗口隔离(默认为关闭状态)。
- **可拖动布局** — 可调整大小的侧边栏和聊天面板,具有可重新排序、可折叠和可隐藏的轨道面板和导航项,在启动之间持久化。
## 要求
- **Node.js >= 20**
- **`omp`** 已安装并经过身份验证(OMP Studio 驱动的程序)。通过 `omp --version` 验证。
- **`gh`** (GitHub CLI)已安装并经过身份验证,以使用 GitHub 功能。通过 `gh auth status` 验证。
- **macOS、Linux 或 Windows.**
OMP Studio 探测常见的安装位置以查找 `omp` 和 `gh`(Homebrew、 `~/.bun/bin`、`~/.local/bin`),因此即使作为具有最小 `PATH` 的打包应用程序启动,它也能够正常工作。设置 `OMP_BINARY` 环境变量以覆盖 `omp` 二进制位置。
## 快速入门
```sh
npm install
npm run dev
```
`npm run dev` 在开发模式下启动应用程序,具有热重载渲染器和主进程,通过 electron-vite。
## 构建
```sh
# 类型检查 Node 和 Web TypeScript 项目
npm run typecheck
# 将 main、preload 和 renderer 打包到 out/
npm run build
# 将可安装的安装程序构建到 release/(dmg / AppImage / nsis)
npm run dist
```
`npm run dist:mac` 仅针对 macOS。 可安装的打包使用 electron-builder 并下载平台 Electron 二进制文件,因此它在本地或发布工作流中运行,而不是在 CI 中。
## 版本发布
版本发布从 `main` 分支发布,由 CI 发布。流程是一个命令加上一个标签推送:
```sh
# 1. 增加版本号 + 将 CHANGELOG 的 [Unreleased] 部分标记为日期发布部分,然后提交并在本地创建 vX.Y.Z 标签。
npm run release -- 0.1.0 # 显式版本号(用于第一个发布)
npm run release -- patch # 或增加 patch/minor/major
npm run release -- patch --dry-run # 预览版本号 + 发布说明
# 2. 推送分支和标签。推送标签会触发发布工作流。
git push && git push origin v0.1.0
```
在 `v*` 标签上, `.github/workflows/release.yml`:
1. 验证 `package.json` 的版本号与标签匹配(否则失败),
2. 在 macOS/Linux/Windows 上构建和启动烟雾测试应用程序,
3. 使用 electron-builder 打包安装程序(`.dmg` / `.AppImage` / `.exe`),
4. 为标签创建一个 **GitHub 发布**,其注释是匹配的 `CHANGELOG.md` 部分(`npm run release:notes -- <version>` 打印它们)。
macOS 代码签名/记名是故意延迟的(它需要 Apple 帐户凭证),因此 macOS 构建目前是未签名的。
## 测试
```sh
# RPC 桥接集成测试(仅握手;实时模型交互需要 RPC_LIVE=1)
npm run test:rpc
# 针对构建应用程序的 Electron 端到端烟雾测试(启动/渲染/导航)
npm run build && npm run test:e2e
```
`npm run test:e2e` 使用 Playwright 的 `_electron` API 从 `out/main/index.js` 启动捆绑应用程序,因此必须先构建应用程序。烟雾测试套件(`e2e/smoke.spec.ts`)**非实时且密封**:它从不启动聊天,并且启动应用程序时将 `omp`/`gh` 指向一个不存在的二进制文件,将代理状态目录指向一个空的临时目录,因此数据服务会进入其优雅降级路径,并且不会生成任何 `omp`/`gh` 子进程。结果无论 `omp`/`gh` 是否安装都相同。它断言窗口标题、侧边栏导航、仪表板,并且每个浏览视图(会话、技能、MCP、代理、GitHub、设置)导航时不会渲染崩溃。
Electron 甚至对于烟雾启动也需要显示服务器,因此在无头 Linux CI 上,使用 xvfb 包装命令:
```sh
xvfb-run -a npm run test:e2e
```
实时、有偿的端到端场景(实际聊天回合,D1 批准批准/拒绝和输入/选择往返,D3 重启/恢复,D2 两个会话并发)位于 `e2e/live.spec.ts`,并在 `STUDIO_E2E_LIVE=1` 后台运行(镜像 `RPC_LIVE=1`)。它们**默认跳过** — `npm run test:e2e` 和 CI 从不生成付费回合。与烟雾测试不同,它们针对已安装的 `omp`(无密封 `OMP_BINARY`/`GH_BINARY` 覆盖),在临时 `--user-data-dir` 中隔离工作室设置,在一个临时项目目录中运行每个聊天,并保持提示很小。在具有已配置的 `omp` 的情况下本地运行它们:
```sh
npm run build && STUDIO_E2E_LIVE=1 npm run test:e2e
```
## 架构
OMP Studio 遵循标准的 Electron 三进程拆分。渲染器从不直接触摸 Node 或 Electron;它调用一个类型化的 `window.omp` 桥接,该桥接由预加载脚本公开,然后转发给主进程中的 `ipcMain` 处理程序。主进程拥有 `omp` RPC 子进程和所有数据服务。
```mermaid
flowchart LR
subgraph Renderer["渲染器 (React)"]
UI["视图和组件"]
API["window.omp (OmpApi)"]
end
subgraph Preload["预加载"]
Bridge["contextBridge -> ipcRenderer"]
end
subgraph Main["主进程"]
IPC["ipcMain 处理程序"]
Data["数据服务"]
RPC["RPC 会话桥接"]
end
subgraph External["外部"]
OMP["omp --mode rpc"]
State["~/.omp/agent 状态"]
GH["gh CLI"]
end
UI --> API
API --> Bridge
Bridge -->|invoke / on| IPC
IPC --> Data
IPC --> RPC
RPC <-->|JSONL stdio| OMP
Data --> State
Data --> GH
RPC -->|evt:rpc / evt:lifecycle| Bridge
```
有关完整的进程模型、RPC 协议桥接、数据源、共享类型合约、IPC 通道映射和安全说明,请参阅 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
## 项目布局
```text
omp-studio/
├─ src/
│ ├─ main/ Electron 主进程
│ │ ├─ index.ts 应用程序启动、窗口、IPC 注册
│ │ ├─ paths.ts 二进制文件 + omp 状态路径解析
│ │ ├─ omp/ RPC 会话桥接 + 注册表
│ │ ├─ services/ 只读数据服务(会话、mcp、...)
│ │ └─ ipc/ chat.ts + data.ts ipcMain 处理程序
│ ├─ preload/
│ │ └─ index.ts 公开类型化的 window.omp 桥接
│ ├─ renderer/
│ │ ├─ index.html
│ │ └─ src/ React 应用程序(视图、组件、存储、库)
│ └─ shared/ 冻结的跨进程合约
│ ├─ ipc.ts 通道映射(CH)+ OmpApi 接口
│ ├─ rpc.ts omp RPC 协议 + 消息类型
│ └─ domain.ts 应用程序级域类型
├─ docs/ARCHITECTURE.md
├─ electron.vite.config.ts
└─ package.json
```
## 聊天工作原理(RPC)
每个聊天都由其自己的 `omp --mode rpc --cwd <dir>` 子进程支持,由主进程中的会话注册表启动和跟踪。桥接器将换行分隔的 JSON 命令(`prompt`、`steer`、`follow_up`、`abort`、`get_state`,...)写入子进程的 stdin,并从 stdout 读取 JSONL 帧。第一个帧是 `{"type":"ready"}`;后续帧是命令响应(回声命令 `id`)或非请求的事件帧(`message_update`、`tool_execution_*`、`agent_end` 等)。
`prompt` 立即确认;回合稍后使用 `agent_end` 帧完成。桥接器通过 `evt:rpc` 频道将每个帧转发给渲染器,并通过 `evt:lifecycle` 报告会话生命周期变化,因此聊天视图在输出到达时渲染流式输出。桥接器还自动响应 `extension_ui_request` 帧,因此 `omp` 永远不会阻塞等待桌面应用程序未呈现的 UI。当渲染器处理会话时,桥接器关闭 stdin,`omp` 进程干净地退出。
## 贡献
欢迎贡献。在打开拉取请求之前:
1. 运行 `npm run typecheck` 并确保它通过。
2. 运行 `npm run build` 以确认应用程序已构建。
3. 运行 `npm run test:rpc` 进行 RPC 桥接测试。
4. 运行 `npm run build && npm run test:e2e` 进行 Electron 烟雾测试套件。
保持更改集中,遵循现有的 TypeScript 和组件约定,并更新 [CHANGELOG.md](CHANGELOG.md) 中的 `## [Unreleased]`。问题和拉取请求模板位于 `.github/` 下。
## 许可证
[MIT](LICENSE) © 2026 Dylan McCavitt.
连接信息
猜你喜欢
暂无推荐服务器