Communitygithub.com

Professor-Chen/cursor-byok

实现和审查 Cursor BYOK React/Tauri 桌面前端。适用于 apps/desktop 下涉及路由、页面布局、窗口 chrome、设置界面、滚动、虚拟化、图表、主题或前端组件架构的变更。

cursor-byok 是什么?

该技能指导开发者在 Cursor BYOK 项目的桌面前端(使用 React 和 Tauri)上进行构建和审查。它强制要求严格的架构边界,例如通过 `/__byok-api__/api` 进行所有前端管理通信,并禁止添加 IPC 业务 API。技能详细规定了页面布局规范(包括 Header/Footer/Content 的弹性布局、绝对定位的标题/操作区、固定菜单)、排版令牌使用、仅使用 VirtualPage/VirtualList 的虚拟化滚动,以及路由使用 HashRouter 和 ECharts 图表实现。此技能适用于 Claude Code、Cursor 或 Codex 等 AI 代理,指导它们在 `apps/desktop` 目录内进行一致的、符合架构的实现,并包含用于验证的构建和 lint 命令。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Professor-Chen/cursor-byok/tree/HEAD/.agents/skills/frontend

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Cursor BYOK 前端

在 apps/desktop 中已有的组件和主题系统基础上构建。保留 Tauri HTTP 边界;前端管理功能调用 /__byok-api__/api,绝不添加 IPC 业务 API。

桌面 HTTP 通信

  • 将 Rust 管理服务器视为桌面 UI 的单一 HTTP 源。主 WebView 和浏览器打开的详情页面必须使用 http://127.0.0.1:<dynamic-port>/__byok-api__/;不要从 tauri://localhost 加载主 UI,也不要暴露第二个前端源。
  • 使每个前端管理请求相对于 /__byok-api__/api。不要发现、注入、持久化或传递 apiOrigin,也不要从固定端口构建管理 URL。
  • 保留 /__byok-api__/ 命名空间专用于此边界:
    • /__byok-api__/api/* 由 Rust 管理 API 本地处理。
    • 其他 /__byok-api__/* 路径是前端文档、资源、模块和开发资源。
  • 在生产环境中,通过 Rust 服务器提供由 Tauri 的 frontendDist 嵌入的前端。重用 Tauri 的资源解析器,而不是打包或复制第二套前端资源。
  • 在开发环境中,让 Rust 服务器将非 API 的 /__byok-api__/* 请求反向代理到 Vite。保留请求路径和查询字符串。不要配置 Vite 将管理 API 请求代理回 Rust。
  • 将 Vite 的基本路径配置为 /__byok-api__/,以便生成的资源、模块导入和开发客户端 URL 保持在保留的命名空间下。
  • 将开发 Vite 服务器绑定到与 Rust 代理目标兼容的显式环回地址;不要依赖 localhost 解析到相同的 IP 系列。
  • 使用其正常的环回 HTTP URL 和哈希路由打开外部详情页面。由于页面和 API 同源,不要添加 Tauri URL 变通方法、API 源查询参数或依赖 CORS 的浏览器流。
  • 仅将 Tauri 命令用于原生桌面功能,例如打开终端、托盘集成或操作系统操作。不要为 HTTP 业务 API 创建 IPC 镜像。

组件边界

  • 将 Provider、Model、Call、Usage 和持久化设置状态保持在展示组件之外。
  • 让组件接收业务快照并分发操作。允许本地 React 状态用于瞬态 UI 行为,例如焦点、打开状态、拖动状态和输入草稿。
  • 将页面、布局、图表、表单和可重用控件拆分为专注的组件。不要将整个功能集收集在 App.tsx 中。
  • 保持 App.tsx 作为路由组合根。

页面布局

  • 使用 components/layout/PageLayout.tsx 构建每个全高页面;不要手动编写带有网格行的页面外壳。
  • 将页面级命令和控件(例如创建、导入、导出、筛选、排序和视图选项)放在通过 PageActions 共享的页面操作区域中。仅将针对一个具体列表项的操作(例如编辑和删除)保留在该项的行内。不要在页面内容内添加重复的操作栏或面板标题控件。
  • 绝不要在数据表格或平面数据列表上方渲染标题区域。使用页面标题提供上下文,将列标签保留在表头中,将页面级控件放在 PageActions 中,并将表格包装在无标题的 Card 中。在分组的父子视图中标识父数据的分层标签不是表格标题。
  • 保持主滚动视口全高且 position: relative;将页面标题和操作区域绝对定位在其上方。
  • 使用滚动内容的 padding-top 保留绝对标题/操作区域,绝不能通过缩短或偏移滚动视口本身来实现。
  • 保持菜单 Card 固定,并使用内容区域的 margin-left 保留它;不要将 Header、菜单和内容放在流式网格中。
  • 不要使用子节或节内边距来创建外部间距。使用兄弟元素之间的 flex/grid 间距以及容器边界处的边距或固定偏移量;滚动内容顶部内边距仅为其绝对定位的标题/操作叠加层保留。
  • 使用具有以下不变量的垂直弹性布局:
    • Header:flex: 0 0 auto。
    • Footer:flex: 0 0 auto。
    • Content:flex: 1 1 auto、min-height: 0 和 overflow: hidden。
  • 保持 Header 和 Footer 在滚动视口之外。它们绝不能随内容增长或收缩。
  • 仅对可能进入原生圆角的边缘 chrome 应用 macOS、Windows 和 Linux 窗口角安全区变量。
  • 保持 macOS 交通灯空间和顶部固定拖拽条无交互控件。
  • 避免使用装饰性品牌文本和说明性文字,除非它们能帮助用户执行操作或解释状态。

排版

  • 以 SCSS 编写组件样式,并从 src/styles/_typography.scss 获取每个 font-size;绝不要在 SCSS、React 样式或图表选项中硬编码字号。
  • 对普通 UI 文本和普通标题(包括标题栏、面板、卡片和节标题)使用 base。不要仅仅因为元素是 h1 或 h2 就增大字号。
  • 仅对辅助信息使用 xs。保留 lg 用于显式 oversized 显示标题;不要将其用于常规标题。
  • 更改标度后审计所有排版令牌的用法,而不仅仅是原始数字字号。

滚动和虚拟化

  • 对垂直滚动页面内容使用 components/layout/VirtualPage.tsx。
  • 对可增长的数据集合和菜单使用 components/virtual/VirtualList.tsx。
  • 将 ScrollArea 视为由虚拟滚动实现拥有的低级原语。不要在页面或布局中直接导入 ScrollArea。
  • 使用全局的 scroll-shadow-top 和 scroll-shadow-bottom 蒙版实现滚动边缘阴影。当滚动内容嵌入保留绝对叠加层时,从与其 padding-top 相同的 CSS 变量获取顶部阴影距离。
  • 将非列表页面建模为一系列可测量的顶级虚拟节。
  • 不要使用文档滚动、原生页面 overflow: auto 或嵌套的垂直滚动容器。
  • 确保虚拟视口的每个 flex/grid 祖先都具有 min-height: 0,并且视口具有明确的有界高度。

路由和页面

  • 使用 HashRouter 以实现 Tauri 兼容性。
  • 保持 / 作为统计仪表板,并通过共享的 AppLayout 中的持久菜单暴露每个主页面。
  • 对主页面使用顶级路由:/、/providers、/models、/calls 和 /settings。
  • 不要创建单独的 Home 和 Settings 外壳,也不要添加 Home 切换控件。
  • 保持路由内容独立于窗口 Header 和 Footer。

图表

  • 通过 components/charts/EChart.tsx 使用 ECharts。
  • 仅注册所需的 ECharts Core 图表、组件和渲染器。
  • 保持图表组件声明式:接受领域数据并构建选项,而不获取或持久化数据。
  • 让 ResizeObserver 根据其布局容器调整图表大小,并在卸载时销毁实例。

验证

从 apps/desktop 运行:

npm run check
npm run tauri:build -- --debug --no-bundle

验证 Header 和 Footer 保持固定,只有虚拟内容视口滚动,设置导航在最小窗口尺寸下仍然可访问,并且 macOS 控件保持在圆角和交通灯非安全区域之外。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能