Imported from flyfishlxy/agent-flyfish (
frontend/AGENTS.md). Install upstream withnpx skills add flyfishlxy/agent-flyfish --skill frontend. Copyright stays with the author.
AGENTS.md
本文件定义本项目前端工程的 agent 协作规则、编码边界和验证要求。
技术栈
- 前端:Vite 8 + React 19 + TypeScript 6。
- 路由:React Router 7,集中在
src/router/。 - UI 组件库:shadcn/ui,
components.json配置为radix-nova、Tailwind v4、lucide 图标。 - 样式:Tailwind CSS v4,主题变量和 base 样式统一在
src/index.css。 - 包管理:npm,锁文件为
package-lock.json。 - 运行时版本:Node.js
22.15.0。 - 构建工具:Vite,React 插件为
@vitejs/plugin-react,Tailwind 插件为@tailwindcss/vite。 - 测试框架:Vitest;Lint 使用 ESLint 10 + typescript-eslint + react-hooks + react-refresh。
- 服务端状态:TanStack Query;用于接口数据缓存、加载态、错误态、重新拉取和 mutation 后失效刷新。
- 客户端状态:zustand;单页面局部交互优先使用 React state。
- 表单与校验:react-hook-form + zod。
- 请求:常规 HTTP 使用 axios;SSE / 流式接口使用
@microsoft/fetch-event-source。 - Markdown:react-markdown + remark-gfm。
- 表格:shadcn
Table优先;复杂数据表可使用@tanstack/react-table。 - 依赖策略:优先复用已安装依赖和 shadcn 组件,不新增第二套路由库、UI 组件库、CSS-in-JS 或全局状态库。
常用命令
- 切换运行时:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null - 安装依赖:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm ci - 启动开发服务:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm run dev - Lint:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm run lint - 测试:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm test - 构建:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm run build - 预览构建产物:
source ~/.nvm/nvm.sh && nvm use 22.15.0 >/dev/null && npm run preview - 检查受影响文件:
git status --short - 生产构建输出到后端
web/src/main/resources/static/的自动流程:待确认;当前vite.config.ts未配置build.outDir。
项目结构
src/App.tsx:应用壳、顶层 Provider、全局导航、路由挂载和Toaster。src/main.tsx:React 入口。src/index.css:Tailwind v4、shadcn 主题变量、字体和 base 样式。src/router/:只维护path -> Component路由运行时配置。src/pages/:路由页面,文件名使用 kebab-case,例如forms-page.tsx。src/components/ui/:shadcn 生成或维护的基础 UI 组件。src/components/shared/:跨页面或跨业务组件复用的业务组件。src/components/layouts/:页面级布局组件;不放具体页面业务数据。src/constants/:路由 path、导航项、展示配置、状态枚举和其他静态配置。src/store/:zustand store,按业务域拆分,示例为use-demo-store.ts。src/hooks/:通用 React hooks。src/lib/:公共工具函数和基础能力,优先复用@/lib/utils中的cn()。src/assets/:静态资源。public/:Vite public 静态资源。
编码规则
- 修改前先搜索现有实现,优先复用已有组件、API、表单校验、数据结构和样式。
- 不修改无关文件,不做顺手重构。
- 新增目录前先确认是否能归入
pages、router、components/layouts、components/shared、components/ui、store、constants、lib、hooks或assets。 src/App.tsx只承载应用壳、顶层 Provider、全局导航、路由声明和全局挂载点。- 新增页面时先创建
src/pages/<name>-page.tsx,导出具名组件,再在src/router/app-routes.ts注册。 - 路由配置只描述 path、Component 和必要的 loader/action/守卫/路由工厂;菜单、标题、侧边栏、面包屑和组件展示元数据放在
src/constants/、布局组件或页面局部常量。 - 页面组件负责场景组合;复杂可复用片段下沉到
src/components/shared/。 - 不要在组件内部定义复杂子组件;需要复用或结构复杂时提升到模块级。
- 派生状态优先在 render 阶段计算,不要用
useEffect同步可由 props/state 推导出的值。 - 常规请求走项目 axios/service/lib 层;不要在 UI 里绕过边界层散写请求和错误归一化。
- 不要吞掉请求错误;边界层返回明确错误状态,UI 层显式展示加载、空态、错误和禁用态。
- 服务端数据、列表缓存、详情刷新、mutation 后失效刷新交给 TanStack Query;不要复制到 zustand。
- store 只保存跨组件或跨页面共享状态;请求逻辑优先放 service/lib 层,store 只编排状态变化。
- 有业务语义的字符串、数字、状态值和路由 path 提取到
src/constants/,避免 magic strings 和 magic numbers 散落在 JSX 中。 - 日期处理优先选择一个库完成同一功能链路;不要在同一模块中混用 date-fns 和 dayjs。
- 外部输入、URL 参数、服务端返回数据进入业务逻辑前使用 zod 或显式函数校验。
- Markdown 内容来自外部输入时必须评估 XSS 和链接安全;不要默认信任 HTML。
- 抽取 helper 仅在 3 处以上重复、逻辑有独立边界,或本地既有模式明确要求时进行。
UI 规则
- 涉及可见 UI、交互、样式、布局或组件选择时,先读取
ui-design.md。 - 调整 shadcn/Tailwind 组件库颜色时,以
ui-design.md的 token 规则和ui-components.html的可渲染样例为准。 - 默认复用 shadcn 组件库原生结构、项目已有组件和当前页面样式约定。
- 不新增项目主题,不覆盖组件库基础样式,不创建自定义基础控件,除非
ui-design.md或用户明确要求。 - 优先复用
src/components/ui已有组件;不要手写与 shadcn 重复的 Button、Card、Dialog、Table、Form 控件。 - 新增 shadcn 组件时先确认组件不存在,再执行
npx shadcn@latest add <component>;执行前切换 Node22.15.0。 - 不要手动从远程复制 shadcn 源码;更新已有组件时优先使用 shadcn CLI 的 dry-run/diff 能力。
- 组件组合遵循 shadcn 结构:
Card使用CardHeader、CardTitle、CardDescription、CardContent、CardFooter;Dialog、AlertDialog必须包含标题。 - 表单布局优先使用
FieldGroup、Field、FieldLabel、FieldDescription。 - 图标优先使用
lucide-react;按钮内图标使用data-icon="inline-start"或data-icon="inline-end"。 - Tailwind 样式优先使用语义 token,例如
bg-background、text-muted-foreground、border-border。 - 布局间距使用
gap-*,不要使用space-x-*或space-y-*;宽高相等时使用size-*。 - 条件 className 使用
cn()。 - UI 改动必须手动打开受影响页面验证;验证前读取
test-env.md。
验证环境
- 私有测试域名、账号、密码和本机说明放在 ignored 的本地文件中,例如
AGENTS.local.md。 - 不提交账号、密码、个人路径、下载目录、临时文件、token、cookie、API key 或本机私有说明。
- worktree 中可能没有
AGENTS.local.md;如测试需要私密上下文,可到原项目目录或主工作区只读查找该文件。 - 不要求每个项目都有
AGENTS.local.md;只有测试确实需要账号、私有域名、权限或本机说明时才参考。 - UI 验证前读取
test-env.md,按其中的测试域名、登录流程、模块路径和自动化注意事项执行。 - 当前未发现
test-env.md,可靠 UI 验证流程待补充。 - 单元测试默认就近放置:测试文件与被测模块同目录,命名为
*.test.ts或*.test.tsx。 - 示例:
src/router/app-routes.ts对应src/router/app-routes.test.ts,src/store/use-demo-store.ts对应src/store/use-demo-store.test.ts。 - 不要把单元测试集中堆到
src/__tests__、根目录tests或src根目录;只有跨模块集成测试、E2E、fixtures、mock server、全局 setup 才使用集中测试目录。 - 如果未来新增集中测试目录,推荐使用
tests/integration/、tests/e2e/、tests/fixtures/或tests/setup/,并在相关配置中明确 include/exclude。 - 行为变化、路由变化、数据结构变化应优先补充 Vitest 回归测试。
- 修改 React、路由、样式或 shadcn 组件后,至少运行
npm test、npm run lint、npm run build。 - 前端页面有明显视觉或交互变化时,启动 Vite dev server 后用浏览器检查关键路由和交互。
npm run build出现 chunk size warning 不等于失败;如果新增大型依赖导致体积明显增长,需要说明原因并考虑动态导入。
Worktree 依赖
- Node.js 项目的 worktree 如果缺少
node_modules,优先复用原项目目录已有的兼容node_modules。 - 默认可以在 worktree 中创建指向原项目
node_modules的本地 symlink,除非本项目明确禁止。 - 不要因为 worktree 里缺少
node_modules/.bin/<tool>就直接判定无法验证;应先尝试或排除依赖复用。
Git 规则
- 不使用
git reset --hard或git checkout --覆盖用户改动。 - 提交只包含当前需求相关文件。
- 忽略无关 dirty files,除非它们阻塞当前任务。
openspec/changes/*/workflow-receipts.md仅作为本地流程记录,除非用户明确要求,否则不提交。- 提交前说明实际验证过的内容和未验证风险。
OpenSpec / Superpower 工作流
- 仅使用相关工具时才需要参考此段要求。
- 文档需使用中文。
- 如果验证受后端配置或环境限制,需要在
tasks.md中如实记录,不把部分验证写成已全部完成。
禁止事项
- 不要引入第二套路由库、UI 组件库、CSS-in-JS 方案或全局状态库,除非用户明确要求并说明取舍。
- 不要绕过 shadcn 组件体系手写相同功能的基础控件。
- 不要把 API key、token、密钥或私有地址写入源码。
- 不要为了“看起来成功”加入静默 fallback、吞错或 mock 成功路径。
- 不要批量重写
src/components/ui中的 shadcn 组件;确需更新时逐个组件评估并验证。