在接入 Trellis 后,第一件重要的事情不是立刻让 AI 写功能,而是初始化项目的 spec。这次 00-bootstrap-guidelines 任务的目标,就是把 Visionary 项目的真实代码约定沉淀到 .trellis/spec/ 中,让后续所有 Trellis 驱动的 AI 开发、检查、重构都能基于项目事实工作,而不是基于通用模板猜测。
一、为什么要初始化 Spec
Trellis 的核心思想是:AI 写代码前必须先理解项目约定。
如果没有初始化 spec,后续的 AI agent 只能依赖通用经验。例如它可能会误以为项目使用 React Query、oRPC、nuqs、Radix UI、better-auth、Tailwind-only styling,或者误以为项目采用 monorepo modules/ 目录结构。
但 Visionary 实际不是这样。这个项目当前真实使用的是 Next.js App Router、React 18、TypeScript、Redux Toolkit、Ant Design、SCSS modules、apiClient 封装 fetch、src/shared/api/ 维护共享 DTO,以及 src/app/、src/components/、src/hooks/、src/store/ 的组织方式。
如果不初始化 spec,AI 很容易写出“看起来合理但不属于这个项目”的代码。
初始化 spec 的价值包括:
- 让 AI 遵守项目真实目录结构。
- 让 AI 使用现有状态管理和 API 调用方式。
- 避免引入项目没有采用的技术栈。
- 把当前代码里的技术债和禁用模式写清楚。
- 让后续
trellis-implement和trellis-check有稳定上下文。
一句话总结:spec 是给未来 AI agent 看的项目开发手册。
二、这次是如何初始化 Spec 的
这次任务没有直接凭空写规范,而是按 Trellis bootstrap 的要求,从真实项目中提取约定。
1. 先确认任务状态
首先读取了:
.trellis/tasks/00-bootstrap-guidelines/prd.md.trellis/tasks/00-bootstrap-guidelines/task.json
确认任务目标是补全 .trellis/spec/frontend/,并且任务状态已经是 in_progress。
2. 查找已有约定文档
随后检查了项目里的约定文件,例如 AGENTS.md、可能存在的 CLAUDE.md、.cursorrules、CONTRIBUTING.md、.editorconfig 等。
最终发现当前项目只有 AGENTS.md,其中主要是 Trellis 通用说明,没有具体前端开发约定。
所以这次 spec 不能从已有文档导入,只能从真实代码中分析。
3. 扫描真实代码模式
重点阅读了这些文件:
package.jsontsconfig.jsonnext.config.tseslint.config.mjssrc/app/layout.tsxsrc/app/page.tsxsrc/app/HomeClient.tsxsrc/components/ArticleItem/index.tsxsrc/components/ArticleItem/index.module.scsssrc/components/MdEditorV2/index.tsxsrc/hooks/articles/useArticles.tssrc/hooks/users/useUsers.tssrc/store/index.tssrc/store/provider.tsxsrc/store/features/userSlice.tssrc/shared/api/article.tssrc/shared/api/response.tssrc/clientApi/index.ts
这些文件覆盖了页面结构、组件模式、hooks、Redux、API 类型、请求封装、样式、质量检查等关键方面。
4. 替换通用模板为项目真实规范
原来的 .trellis/spec/frontend/ 里有一些通用 Next.js 模板内容,但很多不符合 Visionary。
所以这次做了项目化改写,更新或新增了这些文件:
.trellis/spec/frontend/index.md.trellis/spec/frontend/directory-structure.md.trellis/spec/frontend/component-guidelines.md.trellis/spec/frontend/hook-guidelines.md.trellis/spec/frontend/state-management.md.trellis/spec/frontend/type-safety.md.trellis/spec/frontend/quality-guidelines.md
写入的核心内容包括:
- 项目是单仓库 Next.js App Router 项目。
- 前端代码主要在
src/下。 - 页面放在
src/app/**/page.tsx。 - 交互逻辑放入 Client Component。
- 复用组件放在
src/components/。 - hooks 按领域放在
src/hooks/。 - 全局状态使用 Redux Toolkit。
- API DTO 放在
src/shared/api/。 - 客户端请求使用
apiClient。 - 样式主要使用 colocated
index.module.scss。 - Ant Design 是当前主要 UI 组件库。
- 旧代码里的
@ts-expect-error、console.log、构建忽略类型错误是技术债,不是新代码应复制的模式。
5. 完成检查和归档
完成 spec 后,运行了质量检查:
rtk lint
结果是 0 errors,3 warnings;warnings 来自既有 Trellis 脚本,和本次变更无关。
然后将 bootstrap 任务 checklist 标记完成,并归档任务:
python3 ./.trellis/scripts/task.py archive 00-bootstrap-guidelines --no-commit
最后提交:
docs: bootstrap frontend trellis guidelines
提交为:
8c632c0 docs: bootstrap frontend trellis guidelines
三、后续 Trellis 流程会如何使用这些 Spec
初始化后的 spec 不只是文档,它会参与后续 Trellis 工作流。
1. 开发前读取 Spec
当后续进入开发任务时,Trellis 会要求先加载相关规范。
例如前端任务会读取 .trellis/spec/frontend/index.md,以及 index 中指向的具体 guideline 文件。
这样 AI 在写代码前就知道:
- 应该使用
apiClient,不是 React Query。 - 应该使用 Redux Toolkit,不能随手引入新状态库。
- 应该优先参考
src/app/HomeClient.tsx、src/components/ArticleItem/、src/hooks/articles/useArticles.ts等真实模式。 - 应该避免新增
@ts-expect-error、console.log。
2. trellis-implement 会按 Spec 写代码
后续执行实现任务时,trellis-implement agent 会拿到任务 PRD、design、implement,以及相关 spec。
它会根据这些规范决定:
- 文件应该放在哪里。
- 新组件应该怎么命名。
- hook 应该怎么返回数据。
- API 类型应该从哪里 import。
- 状态应该放 Redux 还是组件本地。
- 样式应该用 SCSS module 还是沿用现有模式。
这能显著降低“AI 写出项目外风格代码”的概率。
3. trellis-check 会按 Spec 检查代码
开发完成后,trellis-check 会基于同一批 spec 做质量检查。
它会检查:
- 是否违反目录结构。
- 是否绕过了共享 DTO。
- 是否引入了未采用的技术方案。
- 是否新增了 debug log。
- 是否错误使用全局状态。
- 是否没有处理 loading/error 状态。
- 是否和现有组件、hook、store 模式不一致。
所以 spec 既是开发标准,也是 review 标准。
4. Spec 会成为跨会话记忆
Trellis 的一个重要价值是跨会话持续记忆。
普通 AI 对话结束后,很多项目约定会丢失。但写入 .trellis/spec/ 后,这些约定会留在仓库里。
未来不管是谁开启新的 AI session,只要走 Trellis 流程,都会重新加载这些规范。
四、后续如何更新 Spec
Spec 不是一次性文件。它应该随着项目演进持续更新。
需要更新 spec 的典型场景包括:
1. 引入新技术栈
例如未来真的引入 React Query、Zustand、SWR、shadcn/ui,就应该更新对应 spec,而不是让 AI 从旧规则里推断。
2. 改变目录结构
例如从当前 src/components/、src/hooks/ 迁移到 feature-based structure,就需要更新 directory-structure.md、component-guidelines.md、hook-guidelines.md。
3. 形成新的代码模式
如果某个功能开发中沉淀出稳定模式,例如新的图片上传 hook、新的分页列表组件、新的权限控制方式,就应该写入 spec。
4. 修复重复 bug 后
如果某类 bug 反复出现,比如 API response 没有判断 res.ok、Client Component 忘记加 "use client"、Redux 状态和本地状态重复、移动端样式遗漏,修复后应该把经验更新到对应 spec,避免下一次再犯。
5. 发现旧 spec 不符合现实
如果 spec 写的是理想规范,但代码现实不是这样,就应该改成现实规范。Trellis bootstrap 的原则是:document reality, not ideals。
五、推荐的 Spec 更新方式
后续更新 spec 时,可以按这个流程:
- 先完成当前任务或 bug 修复。
- 判断是否产生了可复用经验。
- 如果有,加载
trellis-update-spec。 - 找到对应 spec 文件。
- 写入明确、可执行、带真实路径的规则。
- 避免写抽象口号。
- 提交时把 spec 更新和代码变更一起说明。
好的 spec 应该像这样:
Use `ApiResponse<T>` from `src/shared/api/response.ts` for internal API calls.
Always check `res.ok` before reading `res.data`.
Example:
`src/hooks/articles/useArticles.ts`
不好的 spec 是这样:
Write clean code and handle errors properly.
前者能指导 agent 行动,后者只是口号。
总结
这次 spec 初始化的本质,是把 Visionary 项目的真实开发方式写入 Trellis 的长期记忆。
初始化后,Trellis 不再只是“帮你写代码的工具”,而是变成一个有项目上下文的开发流程系统:
- 规划阶段:任务 PRD 明确做什么。
- 执行阶段:implement agent 按 spec 写代码。
- 检查阶段:check agent 按 spec 审查代码。
- 收尾阶段:如果发现新规则,再更新 spec。
- 下一次任务:继续复用这些项目知识。
这就是初始化 spec 的意义:让 AI 从一次性助手,变成持续理解项目的工程协作者。