Files

13 KiB
Raw Permalink Blame History

AGENTS.md

本文档用于约束本项目中的 AI / 自动化开发行为。开发时优先遵循本文件,其次遵循用户当前消息。

基本原则

  • 先读现有代码,再动手修改,优先沿用项目已有结构和写法。
  • 写代码保持最少行数,能简单实现就不要引入复杂抽象。
  • 标准格式、协议、解析、压缩、加密、日期等通用能力优先使用成熟稳定的库,不要手写底层实现,除非用户明确要求或项目已有实现必须沿用。
  • 不要为了“兼容更多场景”写大量分支,只实现当前明确需要的功能。
  • 项目尚未上线,不需要兼容旧数据;本地存储结构调整时直接按新设计修改,不写旧字段兼容或数据迁移兜底,除非用户明确要求。
  • 每次写完代码,不需要检查语法,不需要执行构建,用户会自己做。
  • 不要改无关文件,不要顺手重构。
  • 如果工作区已有用户改动,不要回滚,不要覆盖;只在必要范围内追加修改。

反复提醒沉淀

  • 如果开发过程中总是遇到某个问题,或者用户反复提醒同一个注意事项,需要把该注意事项补充到本文件。
  • 补充时写成明确、可执行的规则,避免只写模糊描述。
  • 新规则应放到最相关的章节;找不到合适章节时放到“项目注意事项”。

前端规范

  • 前端使用 Vite、React、React Router、TypeScript、TDesign、Tailwind、Zustand。
  • 编写 TDesign 相关代码时,优先结合项目当前锁定版本、共享 packages/ui Provider 和既有适配层写法;不要重新引入 Ant Design 或其他普通控件库。
  • 外部服务请求统一放在 web/src/services/api/,由浏览器前端直连,不假设存在项目后端。
  • 全局或跨页面状态优先放在 web/src/stores/。
  • 已经放在全局 store 或全局 hook 中的状态/动作,组件需要时直接使用对应 store/hook,不要为了“纯组件”层层透传 props;避免一个组件传递过多参数。
  • 全局组件、全局常量、全局配置等全局性质的内容不要作为 props 或参数层层传递;哪里需要就在哪里直接从对应全局入口获取。
  • 多个页面重复出现的 UI 副作用动作,例如复制文本并提示、下载并提示、统一确认弹窗,优先抽成 web/src/hooks/ 下的全局 hook;不要放进 store,除非它确实是需要共享/订阅的状态。
  • 路由页面放在 web/src/pages/,页面布局放在 web/src/layouts/,路由配置放在 web/src/router.tsx。
  • 画布页面放在 web/src/pages/canvas/,画布组件放在 web/src/components/canvas/,画布状态放在 web/src/stores/canvas/,画布工具函数放在 web/src/lib/canvas/。
  • 页面按目录组织,例如 web/src/pages/image/index.tsx;页面里只有一个主业务组件时直接写在对应页面入口中,不要单独拆 Manager 组件再传一堆 props。
  • 不要新增只做简单转发的组件,例如只 return <X>{children}</X> 或只换个名字透传 props;直接在使用处使用真实组件或把逻辑写进当前文件。
  • 页面私有 hook 放在对应页面目录下,例如 admin/assets/use-admin-assets.ts;只有多个页面真实复用的 hook 才放到外层 hooks/。
  • 管理后台页面私有组件放到各自页面目录的 components/ 下,例如 admin/assets/components/、admin/prompts/components/;不要为了单页面使用放到 admin/components/ 共享目录。
  • 前后台主题、背景、卡片阴影、表格配色等统一在 web/src/lib/tdesign-theme.ts、AppProviders 或必要的全局 CSS 作用域中配置;页面私有组件不要自己写 dark ? ... 主题分支。
  • TDesign 的 Dropdown、Menu、Select、Cascader、TreeSelect 等弹层背景、悬停态和选中态颜色统一通过 web/src/lib/tdesign-theme.ts 的主题变量与组件 Token 配置;不要在业务组件内为单个弹层覆盖颜色。
  • 组件优先使用函数组件和现有 hooks,不新增大型状态管理方案。
  • 前后台通用 UI 图标统一使用项目内本地化的 Lineicons 子集;只收录实际使用的图标,禁止引入 CDN、WebFont、完整图标目录或其他业务图标库。品牌标识、模型标识、媒体内容和画布连线等具有独立语义的视觉资产不按通用 UI 图标替换。
  • 用户端业务下拉不得使用浏览器原生 <select>;统一使用项目自有的主题化 GUI 下拉组件,必须保留键盘选择、当前选中态、禁用/空状态、点击外部关闭、Escape 关闭和移动端可用性。需要搜索或多选的复杂场景也必须使用带主题的 GUI 组件。
  • 用户端主导航、用户菜单和侧栏账户操作必须显式设置 justify-content: flex-start 与 text-align: left;仅设置文字对齐不能覆盖通用按钮的居中布局。
  • 管理后台的菜单、页头、登录和业务操作图标统一使用 admin/src/components/LineIcons.jsx 中本地化的 Lineicons 子集;禁止重新引入 CDN、WebFont、全量图标目录或 tdesign-icons-react 业务引用。菜单、页头和主要业务操作图标默认 24px,并同步保留至少 40px 的稳定点击区域。
  • 管理台全屏登录路由必须直接挂载登录主体,不得继承后台 Layout/Content 壳层或新增移动端卡片容器;手机端沿用桌面左侧内容轨道,仅按视口缩放,不另起一套布局。
  • 页面文案保持中文。
  • 管理后台的业务字段必须经过中文映射后再展示;对象、数组和余额等结构化数据使用字段化组件呈现,禁止直接把原始 JSON 输出到页面。用户列表的 id 在表头为 ID 时按当前列表顺序显示为从 1 开始的纯数字;模型、套餐、渠道等其他资源标识保留其真实语义,不得擅自改成连续编号。
  • 渠道模型映射必须明确区分平台显示模型 ID 与供应商请求模型 ID;显示 ID 用于匹配公开模型产品,请求 ID 只用于发送给上游,不能在管理台或服务端把两者合并成一个字段。
  • 渠道请求地址表单必须给出完整 URL 示例(如 https://example.com、https://example.com/v1);API Key 只校验去除首尾空白后非空,不得设置固定最小长度,编辑留空表示沿用原凭证。
  • 渠道模型列表只能由用户点击按钮主动拉取,新增或编辑保存不得隐式发起上游请求;动态模型映射行必须使用创建时稳定的 React key,不得使用正在编辑的输入值作为 key,避免输入过程中组件重建而丢失焦点。
  • 渠道模型列表与模型映射必须独立:拉取结果只能作为候选模型供用户勾选并添加到渠道模型列表,禁止自动创建映射;模型映射是可选的,仅用于平台显示模型 ID 与供应商请求模型 ID 不同时的转换。
  • 管理后台使用受控字段时,不得用无 name 的 TDesign FormItem 直接包裹控件,避免其内部状态覆盖外部 value;要么完整使用 Form 作为唯一数据源,要么使用普通布局容器保持单一状态源。
  • 管理后台所有新增、编辑、确认和提示弹窗都必须支持取消、右上角关闭、遮罩关闭和 ESC 关闭;异步操作成功后自动关闭,失败时保留表单并显示中文错误,不得依赖刷新页面清除弹窗。
  • 用户金币调整必须提供独立的增加、扣减图标入口;弹窗只让管理员填写正整数数量和原因,并显示当前可用金币与审批后预计余额,禁止要求管理员用正负号表达方向。
  • 管理后台对外部供应商的探活或模型拉取必须显示独立加载状态、实际请求路径和请求是否已发起;失败原因要用中文区分地址解析、网络连接、HTTP 权限/状态和返回内容问题,不得只显示笼统的“探测未通过”。
  • 不要在组件里堆太多无关逻辑;复杂逻辑优先抽成同目录工具函数或小组件。
  • 样式优先由组件自己管理;组件私有样式优先使用 Tailwind className 或少量内联 style,不要为单个组件新增大量全局 CSS。
  • 全局 CSS 只放基础变量、全局重置、跨页面通用样式和少量第三方组件必要覆盖;不要在 globals.css 堆页面私有样式。
  • 代码尽量短小直接,少拆不必要组件,少做多层 props 传递,避免为了抽象堆出更多代码。
  • 前端业务数据需要浏览器本地持久化时,默认使用 localforage;localStorage 只用于极小的简单配置,不要用来保存业务列表、生成记录、图片、base64 或大 JSON。

画布 UI 规范

  • 做 canvas 前端 UI 时必须遵循当前画布主题。
  • 优先使用 canvasThemes、useThemeStore、共享 TDesignProvider 或 TDesign 主题变量。
  • 不要硬编码黑白、stone、slate 等颜色导致浅色/深色主题不一致。
  • 新增画布按钮、弹窗、浮层时,尽量复用已有工具栏、节点面板、Modal 的视觉风格。
  • 画布顶部工具栏和状态信息优先采用极简扁平风格:无边框、无阴影、无胶囊背景,融入整体背景,弱化按钮感,仅保留轻微 hover 反馈,保持简洁现代、低视觉重量。
  • 左侧画布面板等列表里的节点/元素缩略图容器,非图片类型(文本、配置、视频、音频等)不要使用 theme.node.fill(#e7e5df/#292524)这类灰色背景,图标直接无背景展示,尽量不要给多余底色,保持干净。
  • 画布内的操作按钮(如面板里的「添加」「导出」「选择」等)默认用扁平无底色样式:透明背景、仅 hover:bg-black/5 dark:hover:bg-white/10 轻微反馈,靠图标+文字表达,不要用 theme.toolbar.activeBg(#e7e5df/#3a3631)或 theme.node.fill 之类的灰色作为按钮填充底色。灰色 activeBg 只允许用于「选中态」等需要表达状态的高亮,不要当普通装饰底色。
  • 图片节点尺寸逻辑要尊重原始比例,除非功能明确要求自由变形。
  • 批量生成、多图展示、助手面板等画布交互要尽量简洁,不要占用过多画布空间。

文档规范

  • README 保持简洁,只放项目介绍、核心功能、快速开始和文档入口。
  • docs/index.md 放给 AI 使用的文档索引,不要再放到 docs/content/docs/ 内容目录里。
  • 详细功能介绍写到 docs/content/docs/overview/features.mdx。
  • 后续待办写到 docs/content/docs/progress/todo.mdx。
  • 已实现但还需要用户测试确认的事项写到 docs/content/docs/progress/pending-test.mdx。
  • docs/content/docs/progress/pending-test.mdx 用来记录这个版本实际做了哪些可测试变更;CHANGELOG.md 的 Unreleased 只保留对这些变更的版本级归纳,避免逐条照搬实现细节。
  • 每次重大改动(新增/调整/删除功能、接口或工具,影响用户可感知行为)完成后,都要在 CHANGELOG.md 的 Unreleased 追加一条记录,按 [新增] / [调整] / [修复] / [优化] 前缀分类,用一句中文归纳;纯内部重构、格式化、无用户可感知影响的小改动可不记。
  • 每次 todo 事项完成后,先从 docs/content/docs/progress/todo.mdx 移到 docs/content/docs/progress/pending-test.mdx,不要直接写进正式功能说明;用户确认测试通过后再更新 docs/content/docs/overview/features.mdx。
  • 每次任务完成前,都要根据实际变更检查并更新 docs/content/docs/progress/todo.mdx 和 docs/content/docs/progress/pending-test.mdx;如果功能或待办没有变化,也要确认无需修改。
  • 文档不要写过期日期;除非用户明确要求记录具体时间。

发版本流程

  • 发版本时,先把 CHANGELOG.md 的 Unreleased 变更整理成新的版本记录,并保留空的 Unreleased 标题。
  • 按当前版本号提升一个版本,更新根目录 VERSION。
  • 将当前未提交的代码全部提交到 Git。
  • 提交完成后,给当前提交打最新版本号对应的 tag,例如 v0.0.5。
  • 发版本流程中不要执行编译、测试或构建,除非用户明确要求。

项目注意事项

  • 当前画布项目和“我的素材”主要保存在浏览器本地,不要在文档中误写成已支持云同步。
  • 当前 AI API Key 存在浏览器本地,并由前端直接请求 OpenAI 兼容接口;涉及安全说明时要写清楚。
  • Docker 静态资源路径目前仍是待办项,文档中不要过度承诺生产部署已经完全验证。
  • Agent 对话消息必须同时按 threadId、turnId 和 itemId 归属;实时事件只用于补充未物化的 turn,历史快照成为权威后不得重复合并同一条消息。
  • Agent 通信协议版本与消息存储版本必须独立管理;消息存储格式升级时必须先备份再迁移,遇到未知版本、损坏清单或冲突备份时拒绝覆盖原文件,不得按记录数量或文件大小静默裁剪历史元数据。
  • 本地启动或浏览器验收时不要关闭用户已经打开的浏览器窗口或标签页;需要自动化验证时使用独立测试页面,避免打断用户当前页面和对话状态。
  • 开发环境不得自动创建展示用 mock 渠道;需要渠道数据时由用户显式新增,自动化测试专用 fixture 不受此限制。