Imported from youtal/tiny-fly (
AGENTS.md). Install upstream withnpx skills add youtal/tiny-fly. Copyright stays with the author.
tiny-fly 项目开发规范
本文档是 tiny-fly 仓库的强制开发规范,适用于开发人员和自动化开发代理。所有功能、修复、重构、测试、配置和文档变更均需遵守本文。规范中的“必须”“禁止”和 P0 条款都是合并门禁,不是建议。
1. 规范效力与优先级
- 本文件适用于整个仓库。
- 子目录可以通过更具体的
AGENTS.md增加局部规则,但只能补充或收紧本文,不能降低要求。 - 用户对当前任务提出的新要求可以增加约束。若用户要求与本文冲突,必须在执行前说明冲突并取得用户决定,禁止静默采用更宽松的规则。
- tiny-fly 仅进行单机操作。未经明确需求、设计和批准,禁止引入远程网络服务、云端存储、遥测、后台上传或任何生产数据外传能力。
- 未经用户同意不得增加依赖。确需新增时,必须说明必要性、可替代方案、单机范围影响、维护风险和许可证影响。
2. 任务开始前
开始任何任务前必须:
- 检查当前目录、分支、工作树和 Git 状态。
- 识别用户已有的未提交改动;不得覆盖、回滚或混入本次提交。
- 阅读与任务有关的设计规格、实施计划、源代码、测试和更具体的目录规范。
- 明确任务是只读分析、缺陷诊断、功能实现、重构还是文档变更。
- 识别受影响的公开 API、领域规则、文件格式、数据兼容性和错误契约。
- 明确本次目标、不做事项和可验证的完成标准。
只读分析可以在 main 上进行。任何写入仓库的功能、修复、重构或成组文档变更,都必须使用独立功能分支和独立工作树。
3. 设计与实施计划
- 新功能、行为变更和非平凡重构必须先形成设计并取得用户确认。
- 多步骤任务必须在编码前形成可执行实施计划。
- 设计必须说明范围、职责边界、数据流、错误处理、测试策略和明确不做的事项。
- 实施计划必须拆成可独立验证的小任务,写明目标文件、接口、验证命令和预期结果。
- 未经确认的设计禁止提前实现。
- 实施过程中发现设计矛盾、关键歧义或范围扩张时,必须暂停并重新确认,禁止自行扩大授权。
4. Git 工作树与分支
- 写入型任务从最新且可验证的
main创建独立工作树和功能分支。 - 项目内工作树统一放在
.worktrees/;创建前必须用git check-ignore确认该目录已被忽略。 - 一个工作树只负责一个清晰目标,禁止混入无关修改。
- 创建工作树后先安装锁定依赖并运行基线测试。基线失败时必须报告,不得未经用户决定继续实现。
- 禁止未经授权使用
git reset --hard、强制签出覆盖文件或其他破坏性命令。 - 提交前检查 staged diff,确保不包含用户改动、缓存、构建产物、可视化会话或临时文件。
- 只有完成验证和评审后才能合并回
main。 - 合并后在
main上再次验证;确认提交已进入main后,才能移除工作树并删除已合并分支。
5. 架构与模块边界
代码必须保持以下职责边界:
utils:保存与生产计划业务无关、可以独立复用的本地文件和 XLSX 基础能力。- 边界适配层:读取文件、工作簿和用户输入,完成严格校验并转换为可信领域输入。
- 生产计划领域层:实现项目、工序、日历、排程、约束、拟合和冲突等业务模型与策略。
- 状态管理层:保存应用状态,组织用例,协调领域结果、持久化和界面反馈。
- Vue 展示层:渲染视图模型、采集输入、发送事件和组合可复用组件。
强制边界:
- 领域层禁止依赖 Vue、Pinia、DOM、浏览器文件 API 或具体组件。
utils禁止反向依赖生产计划领域类型。- 外部数据必须先在边界层校验,禁止把未知数据直接断言成领域模型。
- 模块通过明确类型和公开入口通信,禁止跨目录引用其他模块的内部实现文件。
- 相同业务规则只能存在一个权威实现,禁止复制到组件、状态仓库和工具函数中。
- 纯业务计算优先使用无副作用函数或职责明确的领域服务,以便独立测试和替换实现。
6. P0:Vue 组件与业务逻辑分离
本节所有规则均为 P0。发现任意违规必须阻止合并,即使单元测试、类型检查、Lint 和构建已经通过。
6.1 禁止上帝组件
Vue 组件必须只有清晰、可描述的界面职责。出现以下信号时必须拆分组件或抽取 TypeScript 模块:
- 同时承担文件读取、业务校验、排程计算、状态持久化和大块界面渲染;
- 包含大量与渲染无关的业务条件分支、循环、匹配、聚合或约束求解;
- 修改一条业务规则会迫使改动大量无关模板或交互代码;
- props、emits 和局部状态不断增加,是因为组件混合了多个职责;
- 组件无法脱离完整页面进行独立测试;
- 文件中的数据转换、策略选择或错误判定可以脱离 Vue 独立运行。
不得用单一行数机械判断上帝组件。职责数量、耦合程度、变更原因和可测试性是主要判断依据。
6.2 主动抽取可复用组件
- 对重复出现、具有稳定独立职责或值得独立测试的界面单元,必须主动抽取可复用 Vue 组件。
- 抽取后的组件必须具有清晰的 props、emits、slots 和状态所有权。
- 通用展示组件禁止依赖生产计划领域对象;领域组件应接收经过定义的视图模型。
- 禁止为了形式上的“组件化”拆出只包装一行模板、没有复用或职责隔离价值的组件。
- 评审时必须主动寻找复用机会,而不是只检查当前页面能否运行。
6.3 Vue 组件允许承担的职责
- 模板渲染与局部样式;
- 用户输入采集;
- 事件发送;
- 调用状态层或用例入口;
- 展示已计算完成的视图模型;
- 组合较小的可复用组件。
6.4 Vue 组件禁止承担的职责
以下逻辑禁止在 .vue 文件中实现:
- 生产计划排程策略;
deviation、缓冲、拟合和资源冲突算法;- 复杂 XLSX 转换与业务校验;
- 复杂日期和生产日历计算;
- 多步骤业务状态机;
- 可以独立单元测试的复杂计算、排序、匹配或聚合逻辑。
这些逻辑必须放在职责明确的专用 TypeScript 文件中,通过纯函数、领域服务或用例接口供 Vue 调用。
6.5 组合式函数不是业务逻辑容器
组合式函数只用于复用 Vue 响应式状态、生命周期和界面行为。禁止把业务策略移入 composables 后声称已经实现分层。能够脱离 Vue 运行的逻辑必须位于普通 TypeScript 领域模块。
7. TypeScript 规范
- 保持 TypeScript 严格类型,公开 API 必须声明明确的输入、输出和错误契约。
- 禁止使用无说明的
any。 - 禁止使用非空断言或类型强制转换掩盖未经验证的数据。
- 确需在已证明安全的边界使用断言时,必须在就地注释中写明证明条件。
- 优先使用能够表达完整业务状态的联合类型、只读类型和结构化结果。
- 日期、数量、偏差、索引和标识符必须通过类型或命名明确单位与语义。
- 禁止用
undefined、空字符串和特殊数字混合表达多个未建模状态。 - 导出的类型和函数名称必须稳定、清晰,并通过模块公开入口暴露。
8. 注释规范
注释必须足够详细,使长期维护者无需反向猜测业务意图。
必须为以下内容添加中文注释:
- 每个源文件的职责、依赖方向和明确不负责的内容;
- 所有公开类型、接口、常量、函数和类;
- 领域字段的业务含义、单位、符号方向和合法范围;
- 关键算法的阶段、选择原因、不变量和边界条件;
- 错误路径、兼容处理和容易被误删的防御性逻辑;
- 看似可以简化、实际受到业务约束限制的实现;
- 测试夹具中不直观的数据关系和测试目的。
注释必须解释“为什么”和“受什么约束”,禁止只把代码逐字翻译成中文。禁止使用含糊占位表达代替规则,也禁止保留与实现不一致的历史注释。修改代码时必须同步更新注释;失真的注释按缺陷处理。
9. 业务错误与警告卡片
9.1 领域层结构化问题
领域层和用例层使用框架无关的 BusinessIssue 或等价结构返回业务错误与警告。禁止在领域代码中直接调用 Vue 组件或通知 API。
结构化问题至少包含:
- 严重级别;
- 稳定的问题代码;
- 用户可理解的标题和说明;
- 项目、工序、日期或字段等业务上下文;
- 对当前操作的影响;
- 可执行的修正建议;
- 必要时用于诊断的追踪标识。
9.2 集中式 Vue 卡片
- 状态层或专用通知通道统一接收业务问题。
- Vue 必须使用统一卡片模板展示级别、标题、上下文、原因、影响和建议操作。
- 错误与警告都必须由用户点击确认后关闭,禁止自动消失导致用户遗漏。
- 同一操作产生多个问题时优先聚合到一张卡片,并提供明细查看能力。
- 未捕获异常必须转换为通用错误卡片,同时保留追踪标识。
- 禁止仅使用
console.log、console.warn或console.error向用户反馈业务问题。 - 开发环境可以附加 console 诊断,但 console 永远不能成为唯一反馈渠道。
10. 测试驱动开发
功能和缺陷修复必须执行以下循环:
- 先编写表达目标行为的测试。
- 运行测试,确认它因为目标行为尚未实现而失败。
- 编写使测试通过的最小实现。
- 在测试保护下重构。
- 运行针对性测试和完整验证集。
测试分工:
- 领域算法优先使用快速、确定性的纯单元测试。
- 边界适配必须覆盖有效输入、无效输入、聚合错误和原子失败。
- Vue 测试聚焦渲染、用户事件、告警卡片和与状态层的契约,不在组件测试中复制领域算法测试。
- 缺陷修复必须加入能够复现原问题的回归测试。
- 禁止通过删除断言、降低校验强度、跳过用例或只测试实现细节让测试变绿。
11. 验证门禁
代码变更合并前必须使用当前代码依次运行:
npm run test:unit -- --run
npm run type-check
npm run lint
npm run build
- 必须读取每个命令的退出码、失败数量和关键输出,禁止依据历史结果推断。
npm run lint会自动修复文件;运行后必须重新检查差异,确认没有无关修改。- 与文件格式或算法有关的变更必须先运行针对性测试,再运行完整测试集。
- 纯文档变更可以不运行代码构建,但必须执行占位符扫描、内容一致性检查和
git diff --check。 - 未取得新鲜验证证据,禁止宣称任务完成、问题修复、测试通过或构建成功。
12. 文档同步
- 业务规则、公开 API、文件格式、错误代码、开发命令或目录结构发生变化时,必须同步更新相关文档。
- 文档必须明确区分已实现能力、当前目标和后续版本。
- 规格文档定义行为,实施计划定义执行步骤,二者不能互相替代。
- 文档禁止保留未解释的占位内容或模糊规则。
- 示例必须与当前字段、类型、命令和业务规则一致。
13. Git 提交、评审、合并与清理
- 提交必须小而聚焦,每个提交表达一个可说明、可评审的目标。
- 提交前必须检查 staged diff,确保只包含本次工作。
- 重大功能、业务规则、公共 API 和 P0 架构相关变更必须在合并前接受代码评审。
- 评审必须检查需求符合性、模块分层、上帝组件、复用机会、测试、注释、告警路径和兼容性。
- 评审意见必须经过技术验证,不得机械接受,也不得无证据拒绝。
- 完成最终验证后才能合并回
main。 - 合并后必须在
main上执行与风险相称的验证并检查 Git 状态。 - 只有确认功能分支提交已进入
main后,才能清理工作树和删除分支。
14. 交付说明
最终交付至少说明:
- 已完成的结果;
- 关键文件和公开入口;
- 实际运行的验证命令和结果;
- 尚未实现、明确推迟或仍需用户决定的内容;
- 关联规格、实施计划和提交。
禁止使用“应该可以”“看起来正常”等推测替代验证证据。
15. 执行检查清单
开始前
- 已检查分支、工作区和用户已有改动。
- 已阅读相关规范、代码和测试。
- 已确认设计与实施计划门禁。
- 写入任务已创建独立工作树和分支。
- 基线测试已通过,或已获得用户对既有失败的处理决定。
提交前
- P0 Vue 组件规则无违规。
- 业务策略和复杂逻辑位于专用 TypeScript 模块。
- 已识别并抽取有价值的可复用组件。
- 功能或修复测试经历了失败到通过。
- 严格类型、详细注释和错误契约已同步。
- 每个业务错误和警告都有 Vue 卡片反馈路径。
- 相关业务与开发文档已同步。
- staged diff 只包含本次目标。
合并前
- 当前代码已通过完整验证门禁。
- 代码评审问题已处理并验证。
- 不存在上帝组件、重复业务策略或 console-only 业务反馈。
- 合并目标、提交范围和版本信息正确。
- 已安排合并后验证、工作树清理和分支删除。