# ompDesktop **Repository Path**: argustang/omp-desktop ## Basic Information - **Project Name**: ompDesktop - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-19 - **Last Updated**: 2026-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OMP Desktop [oh-my-pi](https://github.com/can1357/oh-my-pi)(`omp`)编码代理的桌面客户端(v1.9.0)。 **技术栈**:Tauri v2(Rust)+ MyUI 统一设计架构(Vue 3 + TypeScript + Element Plus + Pinia)+ xterm.js + ECharts。 整体架构参考 myShell(Tauri 桌面工作台 + PTY 终端),信息架构与交互参考 ZCode Desktop(任务列表、流式对话、工具卡片、设置中心、Agent 能力管理)。 ## 页面与功能 | 路由 | 页面 | 功能 | | --- | --- | --- | | `/workbench` | 会话工作台 | ZCode 式任务制会话 + 底部内嵌终端 | | `/settings` | 设置中心 | 左侧分组菜单(通用设置 / Agent 配置 / 统计与关于)+ Agent 能力管理 + OMP 原生配置 + 应用偏好 | ### 会话工作台(WorkbenchShell + workbench/index.vue) - **侧栏任务列表**:扫描 `~/.omp/agent/sessions` 的真实会话,按工作区(cwd)分组、当前工作区置顶,相对时间标注(X 分钟/小时/天前);排序可在「按项目 / 按时间」间切换——按项目保持分组并支持按住手柄拖动调整项目顺序(顺序持久化),按时间把全部会话打平、按最近执行从新到旧排列并标出所属项目;会话右侧红点表示上次执行失败(悬停给出原因,保留 1 天);顶部工具区依次为用量统计 / 回收站 / 设置 / 收起侧栏;新建任务(Ctrl+N)、全局搜索(Ctrl+K 搜索弹窗:操作 + 历史任务,键盘导航)。 - **欢迎态**:按时段问候语、工作区 chip、快捷提示词栏(QuickPromptBar,内置常用提示词 + LLM 改写优化)、快速入口(终端 / Agent 管理 / 用量统计 / 历史)。 - **会话视图**:流式转录(文本/思考块/Markdown)、**编辑器式代码块**(标题栏给出语言色点/语言名/行数与体积,可复制与切换自动换行,代码区左侧带吸附行号槽;超 24 行 / 4000 字节默认收起)、工具调用卡片(运行中/完成/失败 + 参数输出折叠)、extension_ui_request 宿主应答对话框(select/confirm/input 等)、tok/s 与**上下文容量面板**(点击状态条进度条展开:窗口已用/分段占用条/分类明细 消息·系统工具·MCP 工具·技能·系统提示词·其他 /平均缓存命中率/本会话累计 token 与工具调用数)、模型与思考等级即时切换(会话级覆盖,不回写全局默认)、**对话模式四档**(计划 / 变更前确认 / 自动编辑 / 完全访问:模式指令拼进消息正文、只随模式变化整组下发一次并静默生效,气泡展示时自动剥离指令前缀)、**智能计划**(设置开关:按任务复杂度自动决定要不要先出实施计划,计划以待确认卡片挂出、一键确认后执行)、追问/插话排队、极速模式(仅当前模型具备服务层级时才展示开关)、上下文压缩、历史消息分页加载、**历史问题面板**(右下角时钟按钮,新→旧列出全部提问:当前路径上的问题点箭头跳回消息流对应位置;任意一行点分支按钮即从该点开新分支,问题回填输入栏供改写重发,原路径完整保留,含非当前分支的历史提问——`get_tree` 不可用时自动退回「仅当前路径可跳转」)、**斜杠命令**(会话输入栏与欢迎态输入框均支持:输入 `/` 弹出补全,命令名/别名/参数提示/子命令,Tab·Enter 接受、Esc 关闭;清单以 omp 上报为准,未上报时回落内置核心命令;本地命令的 `command_output` 原样落成等宽输出块,与 omp 终端输出一致)。 - **项目与会话入口**(会话窗口左上角):项目选择行首项为「新建项目」——打开原生文件夹选择框设定项目根目录并登记切换;其余项为当前/历史项目,切换即进入该项目的欢迎态(不自动恢复历史会话)。该行最右为「新建会话」图标:在当前项目直接新建会话,默认名「新会话 + 时间戳」,用户发出首条消息后自动改名为消息开头 10 个字(同步写回 omp 会话文件,侧栏按会话 id 显示名称覆盖)。 - **顶部栏工具**(项目行右侧):「打开方式」下拉(资源管理器 / VS Code)与终端按钮——终端按钮在底部打开内嵌面板(侧栏底部不再有终端入口),详见下方「底部终端面板」。 - **会话启动参数**:工作区 cwd、默认模型(`--model`)、思考等级(`--thinking`)、恢复会话(`--resume`)、记忆工具禁用(Rust 侧映射为 `--tools` 白名单排除 memory_edit/recall/reflect/retain)、输出语言(`--append-system-prompt` 静默注入,全程按所选语言回复,对新会话生效)。 - **会话规则**(状态条与欢迎页各一个图标入口,角标为本会话挂载条数):面板按项目维护可复用的条目,勾选即挂载到当前会话——同一项目开多个会话各持一份勾选,即可并行开发不同功能而互不串味。两类条目:**会话记忆**(自由文本,只做指引)与**路径护栏**(结构化的可写路径)。两者都在会话启动时经 `--append-system-prompt` 静默注入,不进入消息流、会话树与历史问题面板。路径护栏另经 `--extension` 挂一个应用内嵌的 omp 扩展真拦越界写入:拦截时由模型转述「请在对话中回复『允许修改 <路径>』」,用户说完重试即放行一次。**覆盖 `write`/`edit`/`ast_edit` 等带路径的工具,bash 拦不住**(输入只有一条命令串)——提高门槛,不是沙箱。条目与挂载关系存应用本地,不写入项目目录;会话态改动需「重开会话」生效(对话历史由 `--resume` 保留)。 ### 会话运行态与任务面板 - **任务面板 HUD**(会话右上角,默认展开):三个可折叠区块 —— 进程(omp 计划任务:阶段/任务状态、完成度 `已完成/总数`、「执行中 n」)、终端(bash 调用累计耗时、后台标记与逐条命令)、智能体(`task` 工具调起的子智能体:类型徽标、运行状态、已运行时长,点击展开运行详情)。**进程摘要与面板标题同行冻结**,内容区独立滚动;会话空闲时残留的 `in_progress` 不再计入「执行中」而是标为已中断。 面板内容**跟随当前问题**:每个问题一份计划任务 / 终端记录 / 子智能体,新问题发出即重置(并过滤 omp `get_state` 返回的上一问题残留清单),计划任务随 todo 工具收尾实时刷新。 进程区块的阶段名与任务名由 AI 写出(多为英文),会按 i18n 术语表 `omp.todoGlossary` 在渲染前映射为当前语言,悬停保留模型原文;终端命令与子智能体标签属技术标识符,不参与翻译。 - **侧栏会话状态**:左侧小点表示后台进程存活(绿=运行中,灰=未运行,悬停确认,运行态画空心环以便与右侧实心点区分);右侧小点表示最近一次运行结果(绿=运行中 / 黄=已完成 / 红=失败),未运行的会话不展示右侧点。**待确认**:会话卡在等用户应答(路径护栏授权、OAuth 登录等)时,行内加指针图标 + 整行琥珀底色 + 左侧竖条——这类会话此前与普通空闲会话外观完全一致,用户无从得知它在等人点。后台任务在途不单开状态(不要求用户做任何动作),只并入「运行中」。状态点为静态色(无动效)——任意无限动画都会让 WebView2 持续出帧,动效让位于资源占用。 - **停止会话**:会话右键菜单「停止会话」结束后台 omp 子进程释放内存(会话记录保留,再点即恢复);归档会话、归档全部会话、归档项目时会一并结束相关进程;项目右键另有「批量归档会话」(选择态勾选整批归档);会话全部归档后项目保留在侧栏(空态提示 + 回收站入口),何时归档项目由用户显式决定。 - **上下文治理**:状态条进度条给出占用率与告警,达到阈值提供一键压缩;「压缩上下文 / 交接摘要」直接走 RPC 并回报 `token 前后对比` 或失败原因,执行后补拉用量让占用条即时回落;切换到窗口更小的模型导致上下文越界时会**主动压缩**(否则该会话无法继续对话);空闲自动压缩按「空闲时长 + 占用阈值」双条件触发(设置里可配,默认关闭);另可开启**会话超时自动退出**(空闲超时自动结束进程释放内存,记录保留)。 - **错误码自动重试**:模型请求以错误收尾时按错误码决定是否重发该回合,默认重试 429,可自行增删错误码(100–599),次数与间隔可调;另支持「不重试的拦截关键字」——失败报文命中关键字或 `/正则/` 时直接按失败结束不再白等(典型如额度耗尽);重试过程在会话流写入系统提示,用户打断或发新消息即停止(设置 → Agent 配置,默认关闭)。 ### 输入区:待提交队列 / 图片 / 斜杠命令 - **待提交队列**:上一个回合还在流式输出时回车不再丢消息 —— 消息进入队列面板(`omp-queue` store,按任务隔离),等回合结束按顺序自动发送;每项支持上移/下移/删除、在「追问 / 插话」之间切换、以及「立即执行」。 - **追问(followUp)**:当前回合结束后作为新一轮处理,可连续排多条; - **插话(steer)**:会话仍在跑时立即注入当前回合,可打断剩余工具调用; - **立即执行**:流式中走 omp `abort_and_prompt`(打断并马上发送),空闲则直接发送;`Ctrl+Enter` 等效。 - omp 自身队列(用 steer/followUp 直发时)会以「OMP 侧队列 n 条」显示在队列面板底部。 - **图片**:`Ctrl+V` 直接粘贴剪贴板图片(或点图片按钮多选),长边压到 1600px 后转 base64,随 RPC `prompt` / `steer` / `follow_up` 的 `images` 字段下发(原生多模态,不拼进正文文本)。 - **斜杠命令补全**:以 omp 上报为准(实测本机 127 条:内置 41 / 技能 82 / 扩展 / 项目命令),菜单按来源分组(内置 → 技能 → MCP 提示词 → 扩展 → 自定义 → 项目文件),最多展示 120 条并显示未截断的命中总数;**二级子命令提示**:输入 `/mcp `、`/memory `、`/session `、`/fast ` 后直接展开该命令的子命令清单(参数签名 + 中文用法),继续输入按前缀过滤、键入自由参数自动收起。技能通过 `/skill:` 调用,MCP 提示词命令来源为 `mcp_prompt`,MCP 服务器管理用 `/mcp`;中文输入法下首字符输入「、」会自动纠正为「/」。 - **快捷键**:控制条的键盘按钮弹出清单(Enter 发送 / Shift+Enter 换行 / Ctrl+Enter 立即执行 / Ctrl+V 粘贴图片 / `/` 命令补全 / Ctrl+K 全局搜索 / Ctrl+N 新建任务);omp TUI 专属快捷键可在会话里发送 `/hotkeys` 查看。 ### 底部终端面板 终端不再是独立页面:右侧栏(工作台)顶部栏的终端按钮在**底部**打开内嵌面板(portable-pty 真 PTY + xterm.js 渲染),cwd 默认当前项目路径、切换项目自动重建会话,上沿可拖拽调整高度;shell/字体/字号/回滚行数在设置中配置。 同一顶部栏还有「打开方式」下拉,把当前项目交给外部程序: | 选项 | 行为 | | --- | --- | | 资源管理器 | 系统文件管理器打开该项目(Windows `explorer` / macOS `open` / Linux `xdg-open`) | | VS Code | `code <项目目录>`,以当前项目作为工作区打开(并把当前项目对齐为工作区;需 `code` 命令在 PATH 上) | ### 设置中心(左侧分组菜单,MySettingsPanel) **排版**:设置为中心铺满整屏(进入时隐藏工作台侧栏),左侧为分组菜单(组标题 + 条目:通用设置 / Agent 配置 / 统计与关于),右侧顶部为当前页标题、正文限宽居中;支持 `?section=` 深链直达。 | 分组 | 内容 | | --- | --- | | 基础 | 工作区管理(最近 8 个)、**新建会话默认**(默认对话模式 / 默认模型 / 默认思考等级 / 智能计划开关 / 会话输出语言)、**日志保留时长**(1/3/7/14/30/90 天,默认 7 天;落盘 `app_data/logging.json`,改完立即巡检清理,不必重启)、记忆工具禁用开关、**开机自启动**(登录后自动启动;启动项由应用自管,写入带引号的标准命令并在升级/搬迁后自动修正)、桌面悬浮球、**桌宠**(petdex 社区像素桌宠:宠物选择/宠物库浏览,随会话状态换动作)。OMP 版本与更新不在此处展示——统一由左下角更新卡片管理 | | 外观 | 深浅主题、背景模式、界面 / 弹窗不透明度(浮层族独立调实心度,弹层文字不被背后内容糊住)、语言(中/英) | | 模型 | **供应商 + 多模型**:自定义供应商(落盘 `~/.omp/agent/models.yml`:线协议/接口地址/API Key/模型列表)与 omp 内置供应商**同一列表统一管理**(按住手柄拖动排序、内置可本地移除与恢复);「导入配置」从 ClaudeCode / OpenCode / ZCode / OMP / Qoder / WorkBuddy 识别供应商(自动探测默认位置或手动选文件,OMP 仅支持选文件),自定义区「快捷引入」保留 13 家预设一键带出连接配置与预置模型;「获取模型列表」从 `GET {baseUrl}/models` 读回真实清单并**勾选导入**(已导入的不再重复出现),并自动匹配真实上下文长度 / 最大输出 / 图片与推理能力(取自 OpenRouter 目录,未收录的按默认值并在对话框中明示);模型列表的操作列(修改 / 删除)固定在右侧,修改为全字段弹窗(id / 名称 / 上下文 / 最大输出 / 能力 / 设为默认);上下文长度取不到时按 200k 计;内置供应商可「转为自定义」后自由增删改模型;**「会话可用模型」**(写 omp 的 `enabledModels` 白名单)按供应商分组勾选——整家启用或逐模型勾选,收窄会话内模型选择器(同名内置目录并入的模型不再挤满选择器;只对新会话生效,设置页目录不受限);目录快照本地缓存(30 分钟 TTL),进面板即渲染 | | 提示词 | 提示词管理:默认「全部」列出所有提示词(内置 + 自定义,带业务类型徽标),**内置也可修改文案与启停**;选中全局或某个业务类型时只列该范围自己的提示词;行内操作(删除)固定在最右一列。业务类型可增 / 改名 / 删——**名称可改、编码自动生成且只读**(项目引用与排序登记都按编码走),删除后引用它的项目在下次启动会话时提示重选;选中具体范围可「修改排序」(拖拽维护会话内展示顺序,列表含全局可用部分,停用项也可排);新建任务界面只展示全局提示词 | | **OMP 配置** | `~/.omp/agent/config.yml` 可视化编辑:模型角色 / 界面 / 行为 / 搜索 Provider + 原始 YAML(见下) | | **子智能体** | 能力条目页(见下) | | **MCP 服务器** | 能力条目页(见下) | | **技能** | 能力条目页(见下) | | **斜杠命令** | 能力条目页(见下) | | **钩子** | 能力条目页(见下) | | **工具** | 能力条目页(见下) | | **插件** | 已安装管理 + 插件市场(见下) | | 使用统计 | 快捷日期范围(近 1/7/30/90 天、全部)与自定义区间;版面自左向右依次为概览(主指标 + 次级指标)、时间范围与 Token 构成(输入/输出/缓存读写 + 缓存命中率/费用)、Token 活动热力图(日/周/累计)、每日趋势按模型分线、分模型/分供应商占比环图、分项目用量明细表。配额查询不在此页——在「模型」分组的模型管理面板里,按**供应商卡片**单独开启(原挂在供应商列表底部的「Coding Plan 配额」卡片已移除) | | 关于 | 应用/OMP/框架版本(含**应用内自动更新**:检查/下载/静默安装并重启) | ### Agent 能力条目页(设计核心) 四类能力不再是抽象开关,而是**本机 omp 的真实配置清单**,所有操作直接落盘 omp 原生配置、由 omp 下次会话原生生效: | 能力 | 清单来源 | 逐项禁用写入 | 支持操作 | | --- | --- | --- | --- | | 子智能体 | 项目 `.omp/agents/*.md` > 用户 `~/.omp/agent/agents/*.md` > omp 内置 5 项(scout/reviewer/security-reviewer/task/sonic) | config.yml `task.disabledAgents` | 搜索、来源筛选(全部/项目/用户/内置)、新建、编辑、删除(内置项仅禁用) | | MCP 服务器 | 项目 `.omp/mcp.json` + 用户 `~/.omp/agent/mcp.json` | mcp.json 每服务器 `enabled: false` | 搜索、新建(stdio 命令/参数/环境变量 或 http URL)、删除、真实探活(Rust 起子进程发 MCP `initialize` 握手,绿/红状态点 + serverInfo 回显) | | 技能 | `.omp/skills/`、`~/.omp/agent/skills/`、`managed-skills/`、`~/.agent[s]/skills/`(SKILL.md frontmatter) | config.yml `skills.ignoredSkills` | 搜索、新建(生成 SKILL.md)、删除(仅用户/managed 层) | | 插件 | `~/.omp/plugins`(`omp plugin list --json`) | `omp plugin enable/disable`(omp-plugins.lock.json) | 搜索、市场浏览(分类 / 关键字筛选)、安装(npm 包名 / `github:user/repo` / 本地路径 / `name@marketplace`)、卸载、单个或全部升级、市场源增删与刷新、插件体检(doctor) | | 斜杠命令 | `/commands/*.md` | config.yml `disabledExtensions`(`slash-command:`) | 搜索、来源筛选(用户/项目)、新建(description / argumentHint / 正文)、删除、启停 | | 钩子 | `/hooks/{pre,post}/.` | config.yml `disabledExtensions`(`hook:::<文件名>`) | 搜索、来源筛选、新建(pre/post + 目标工具 + 脚本)、删除、启停 | | 工具 | `/tools/*`(含 `/index.ts` 子目录) | config.yml `disabledExtensions`(`tool:`) | 搜索、来源筛选、新建(JSON / Markdown / TS 脚本)、删除、启停 | 子智能体 `.md` 写入格式与 `omp agents unpack` 的序列化契约一致(frontmatter:name/description/tools/model/thinkingLevel + 正文系统提示词)。 ### OMP 配置面板(config.yml 同步修改) 设置中心「OMP 配置」把 `~/.omp/agent/config.yml`(omp 全局设置)的常用项做成表单,**保存即写回该文件**,omp 下次会话生效: | 分组 | 键 | 说明 | | --- | --- | --- | | 模型角色 | `modelRoles.*` / `modelRoleStorage` | 9 个内置角色(default/smol/slow/vision/plan/commit/tiny/task/advisor)各绑一个模型 selector(`provider/model[:thinking]`,候选来自 `omp models --json`);角色写入位置可选全局或项目 | | 界面 | `theme.dark` / `theme.light` / `symbolPreset` | 主题名与图标预设(unicode / nerd / ascii) | | 行为 | `memory.backend` / `tools.approvalMode` / `startup.quiet` / `startup.showSplash` | 记忆后端(off/local/hindsight/mnemopi)、工具审批(always-ask/write/yolo)、启动装饰开关 | | Web 搜索 | `providers.webSearchOrder` / `providers.webSearchExclude` | 搜索 Provider 优先级与排除项(24 个来源可选) | | 高级 | 整份 YAML | 直接编辑配置文件(保存前校验可解析且根节点为映射),兜底 hooks / tui / statusLine / 各工具开关等未入表单的键 | 写回策略(`omp_config.rs`):读整份 YAML → 只改表单覆盖的键 → 全量写回,**其余键原样保留**;表单留空的字段会从配置中移除该键。因为是重序列化,注释与原有排版可能丢失,需保注释时用 YAML 编辑器维护。 面板同时展示项目级配置路径(`<工作区>/.omp/config.yml`:omp 只读合并、桌面端不写入),并提供「打开配置目录 / 用 VS Code 打开 / 在终端查看全部设置项(`omp config list`)」。 ## 目录结构 ``` src/ api/omp/ # 桥接层:bridge(Tauri invoke/事件订阅)/ commands(类型化命令)/ mock(浏览器预览模拟)/ types(RPC 与域类型) services/omp/ # rpc-client(命令-响应关联、超时、会话生命周期)/ transcript(帧→视图模型纯函数,可单测)/ prompt-optimizer stores/modules/ # omp-settings(工作区/默认模型/终端偏好/记忆开关,localStorage 持久化)/ omp-tasks(任务列表 30s 缓存)/ omp-terminal(底部终端面板开关与待执行命令) layouts/ # WorkbenchShell(侧栏 + Ctrl+N/K 快捷键 + 搜索弹窗挂载) views/workbench/ # 会话工作台 + TranscriptPane / ComposerBar / MessageMarkdown / MarkdownCodeBlock / ToolCard / UiRequestDialog / QuickPromptBar # TerminalDock(底部内嵌终端面板)/ TerminalView(xterm + PTY)/ ProjectMenu / VsCodeIcon views/settings/ # 设置中心(分组):OmpConfigPanel(config.yml) / OmpEnvPanel(安装与更新) / ModelsPanel # SubagentsPanel / McpPanel / SkillsPanel / CommandsPanel / HooksPanel / ToolsPanel # PluginsPanel(插件 + 市场) / ResourceListPanel(命令·钩子·工具共用列表) / UsagePanel config/ompPrompts.ts # 快捷提示词内置清单 config/ompInstall.ts # omp 安装/更新渠道命令(脚本/Homebrew/Bun/npm/Nix/mise) config/ompSubcommands.ts # 斜杠命令二级子命令清单(如 /mcp,随 omp 升级同步维护) composables/useOmpHealth.ts # omp 安装/更新健康检查单例(启动检测 + 左下角更新卡片共用) services/omp/omp-version.ts # 最新版本查询(npm registry → GitHub 回落)与版本比较 src-tauri/src/ agent.rs # omp RPC 子进程管理(stdin/stdout NDJSON 桥、omp-frame 事件、taskkill 退出清理) capabilities.rs # 能力清单发现与 CRUD(子智能体/MCP/技能/斜杠命令/钩子/工具)+ MCP initialize 探活 plugins.rs # omp 插件与市场(omp plugin CLI:list/doctor 走 --json,市场目录直读) pty.rs # portable-pty 本地终端(base64 输出转发、resize、kill) sessions.rs # 扫描 ~/.omp/agent/sessions(256B 标题槽 + session 头解析,按 mtime 排序) usage.rs # 用量统计聚合(assistant 消息 usage → 按日/按模型/连续天数) info.rs # omp 版本 / 配置目录 / config.yml 读取 omp_env.rs # omp 安装检测(定位/版本/渠道)+ 后台静默更新(渠道白名单命令) omp_config.rs # omp 全局设置读写(config.yml 结构化 patch + 整份 YAML 覆盖) apps.rs # 用外部程序打开项目目录(资源管理器 / Finder / xdg-open;VS Code) ``` ### OMP 安装与更新检查 桌面端在启动时体检本机 omp(`where`/`which` 定位 + `omp --version` 解析版本号 + 按安装路径推断渠道),结果统一由**左下角更新卡片**管理(不出右上角通知、设置页不再展示版本明细): | 检查结果 | 处理方式 | | --- | --- | | 未安装 | 启动弹窗提示,确认后打开 omp.sh 查看安装方式 | | 有更新 | 左下角更新卡片:标题「发现新版本」+「立即更新」按钮(`update_omp` 后台静默执行该渠道的更新命令,隐藏窗口、捕获输出、5 分钟超时,完成后自动重新检测)+「忽略」(仅本会话) | | 已是最新 | 无提示 | 最新版本取自 npm registry(`@oh-my-pi/pi-coding-agent`),失败时回落 GitHub releases;渠道按安装路径自动识别(Windows 不提供 Homebrew/Nix),如需手动指定可在启动检测失败时于卡片内选择。 ## 常用命令与工程门禁 ```bash pnpm version:check # 只读比较 Cargo.toml / package.json / tauri.conf.json pnpm version:sync # 以 Cargo.toml 为来源,同步 package.json / tauri.conf.json pnpm test:typecheck # 强制类型检查应用、Vitest 配置与工程门禁测试 pnpm test # Vitest 前端测试 + Node 工程脚本测试 pnpm test:rust # Rust 单元/集成测试(发布门禁需显式执行) pnpm check # 版本检查 + 前端构建 + 完整类型检查 + 全部前端/脚本测试 + bundle 预算 pnpm tauri:build:release # 发布构建:须先通过 pnpm check 与 pnpm test:rust,仅生成 NSIS ``` `tsconfig.test.json` 严格检查 `vitest.config.ts` 与工程门禁契约测试 `tests/engineering-gates.test.ts`;既有业务测试大量使用有意精简的 mock/fixture,仍由 `pnpm test:frontend` 做全量运行时验证,不通过 `any` 或 `@ts-nocheck` 掩盖其类型边界。这样新增门禁本身始终受 TypeScript 约束,同时不让历史测试夹具决定日常门禁能否落地。 `pnpm check` 有意不直接合并 `cargo test`:冷编译耗时显著,适合日常前端门禁;发布流程必须在构建安装器前显式运行 `pnpm test:rust`。运行时契约以 `package.json` 为准:Node `^22.12.0 || ^24.0.0 || >=26.0.0`,包管理器 `pnpm@12.5.1`。 发布时推荐显式传入刚生成的安装器: ```bash node scripts/publish-gitee-release.mjs "" "" "" ``` 旧调用可省略安装器路径,但目录中必须只有一个文件名精确包含目标版本的 `*-setup.exe`;脚本不再按 mtime 猜测。联网前还会校验 `dist/version.json` 的 `semver`、`buildId`、`buildTime`,并要求安装器生成时间不早于该构建元数据。 ```bash pnpm dev # 浏览器开发预览(mock 层:模拟 RPC/PTY/能力清单) pnpm tauri:dev # Tauri 桌面开发(接入本机 omp,需 Rust 工具链) pnpm tauri:build # 独立打包:重新构建前端,仅生成 NSIS node scripts/make-icon.cjs # 重新生成 src-tauri/icons/icon.ico ``` ## OMP RPC 集成约定(实测协议,v18.x) - 启动:`omp --mode rpc --cwd <工作区> [--model] [--resume] [--thinking] [--tools …]`,NDJSON over stdio。 - 命令帧 `{ id, type, …payload }` 走 stdin;stdout 事件帧 + 响应帧 `{ type:'response', id, success, data }`(**注意:实测为 success/data,非文档的 ok/payload**,桥接层做了双兼容)。 - 消息事件(message_start/update/end)**无消息 id**,增量在 `assistantMessageEvent` 字段(text_delta/thinking_delta/toolcall_*,附 partial 累积全文);transcript.ts 按角色定位 + content 权威重建归并。 - 启动期 omp 会主动发 method 型 `extension_ui_request`(setWidget/setStatus 等),宿主需静默回 `extension_ui_response { id, confirmed: true }`。 - 会话用量走 `get_session_stats`(`data.tokens` = 累计 input/output/reasoning/cacheRead/cacheWrite/total,附 `contextUsage`,与 `/session` 同源);上下文**分类**无 RPC 接口,客户端按 `get_state` 的 `systemPrompt`(`` 区块单独计量)与 `dumpTools`(`mcp__` 前缀归 MCP 工具)估算,消息列取「上下文已用 - 其余五类」的差额,保证六项合计等于已用。 - 会话文件:`~/.omp/agent/sessions/<工作区编码目录>/<时间戳>_.jsonl`,行 1 为 256 字节标题槽,行 2 为 session 头。 ## 桌面端 E2E 验证方法 ```bash # Windows:带 CDP 调试端口启动 set WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9225 pnpm tauri:dev # 另开终端,Node 22+ 原生 WebSocket 直连 webview 做断言/截图 # (本项目各能力页均有 44 项 CDP 断言:清单渲染、落盘契约、探活握手、对话框流) ``` ## 竞品参考:ZCode Desktop 的本地缓存机制(逆向记录) > 只记录**可观测产物位置与机制结论**,未提取/复制其源码;实现方式按结论在本项目自行编写。 **产物位置(本机)** | 类别 | 路径 | | --- | --- | | 安装目录(Electron,3.12.3) | `E:\Program Files\zcode-assistant\`(`ZCode.exe` 222MB,asar 内嵌) | | 本地数据库(主缓存层,10MB SQLite) | `C:\Users\argus\AppData\Roaming\com.zcode-assistant.app\zcode-assistant.db` | | 账号快照(启动时直读,约 20KB/个) | `C:\Users\argus\AppData\Roaming\com.zcode-assistant.app\accounts\*.snap.json` | | Electron 会话数据(Chromium 层) | `C:\Users\argus\AppData\Roaming\ZCode\session\`、`%LOCALAPPDATA%\com.zcode-assistant.app\EBWebView\` | | 更新器 | `%LOCALAPPDATA%\@zcodedesktop-updater` | **库表(从库文件页内 SQL 文本读出)**:`kv`、`project_names`、`accounts`、`provider_meta`、`provider_aliases`、`quota_templates`、`usage_records`、`autoswitch_rules`、`autoswitch_logs`;`kv` 中存在 `usage_sync_state` 之类的同步状态键。 **机制结论** 1. **派生数据落本地库**:项目名映射(`project_names`)、通用键值缓存(`kv`)、用量记录各自成表,UI 读库而非每次重算/重扫。 2. **快照文件做启动直出**:`accounts/*.snap.json` 保存账号级轻量快照,启动先渲染快照再异步校正。 3. **增量同步而非全量重算**:`kv.usage_sync_state` 这类"上次同步位点"键说明其刷新是带位点的增量。 **本项目的对应实现(自行编写)**:`src-tauri/src/sessions.rs` 增加会话索引缓存 (`~/.omp/agent/.ompdesktop/sessions-index.json`,与会话数据同盘)。`list_sessions(refresh=false)` 直读缓存供首屏渲染; `refresh=true` 时按 `mtime + size` 命中缓存、只解析变更文件后回写;`delete_sessions` 同步清理缓存。 前端 `stores/modules/omp-tasks.ts` 采用两段式加载:先缓存直出,再后台增量刷新覆盖式更新 (`refreshing` 不遮罩已有列表)。 本机实测(12 个会话文件,CDP 直调命令计时): | 路径 | 耗时 | | --- | --- | | 缓存命中 `refresh=false` | 5–10 ms | | 增量扫描 `refresh=true` | 50 ms(冷启动首帧含启动期开销,一次性) | ## 开发约定摘要 - MyUI 门禁 `pnpm check` 必须全绿;入口 gzip 预算见 `scripts/check-bundle.mjs`(当前 110KB,历次放宽原因均注释在脚本内)。 - 重依赖(xterm/markdown-it/highlight.js/ECharts)按路由懒加载守预算;设置页四个能力面板随 `/settings` 路由 chunk 拆分。 - i18n 文案中 `@` 必须写成 `{'@'}` 字面量(vue-i18n 链接语法冲突);toast 用位置参数签名 `toast(message, { type })`。 - 组件 defineOptions name 与路由 name 一致(keepAlive);文件 kebab-case;禁用 `as any`。 ## 依赖前置 - Rust(stable-msvc)与 WebView2 —— `pnpm tauri:dev` 需要; - 本机已安装 `omp`(PATH 可寻址,Windows 下经 `cmd /C omp` 启动);未安装时桌面端会提示安装命令并可在终端一键执行。