ai-spec-dev 0.1.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.claude/settings.local.json +18 -0
  2. package/README.md +1215 -146
  3. package/RELEASE_LOG.md +1489 -0
  4. package/cli/index.ts +1981 -0
  5. package/cli/welcome.ts +151 -0
  6. package/core/code-generator.ts +757 -0
  7. package/core/combined-generator.ts +63 -0
  8. package/core/constitution-consolidator.ts +141 -0
  9. package/core/constitution-generator.ts +89 -0
  10. package/core/context-loader.ts +453 -0
  11. package/core/contract-bridge.ts +217 -0
  12. package/core/dsl-extractor.ts +337 -0
  13. package/core/dsl-types.ts +166 -0
  14. package/core/dsl-validator.ts +450 -0
  15. package/core/error-feedback.ts +354 -0
  16. package/core/frontend-context-loader.ts +602 -0
  17. package/core/global-constitution.ts +88 -0
  18. package/core/key-store.ts +49 -0
  19. package/core/knowledge-memory.ts +171 -0
  20. package/core/mock-server-generator.ts +571 -0
  21. package/core/openapi-exporter.ts +361 -0
  22. package/core/requirement-decomposer.ts +198 -0
  23. package/core/reviewer.ts +259 -0
  24. package/core/spec-assessor.ts +99 -0
  25. package/core/spec-generator.ts +428 -0
  26. package/core/spec-refiner.ts +89 -0
  27. package/core/spec-updater.ts +227 -0
  28. package/core/spec-versioning.ts +213 -0
  29. package/core/task-generator.ts +174 -0
  30. package/core/test-generator.ts +273 -0
  31. package/core/workspace-loader.ts +256 -0
  32. package/dist/cli/index.js +6717 -672
  33. package/dist/cli/index.js.map +1 -1
  34. package/dist/cli/index.mjs +6717 -670
  35. package/dist/cli/index.mjs.map +1 -1
  36. package/dist/index.d.mts +147 -27
  37. package/dist/index.d.ts +147 -27
  38. package/dist/index.js +2337 -286
  39. package/dist/index.js.map +1 -1
  40. package/dist/index.mjs +2329 -285
  41. package/dist/index.mjs.map +1 -1
  42. package/git/worktree.ts +109 -0
  43. package/index.ts +9 -0
  44. package/package.json +4 -28
  45. package/prompts/codegen.prompt.ts +259 -0
  46. package/prompts/consolidate.prompt.ts +73 -0
  47. package/prompts/constitution.prompt.ts +63 -0
  48. package/prompts/decompose.prompt.ts +168 -0
  49. package/prompts/dsl.prompt.ts +203 -0
  50. package/prompts/frontend-spec.prompt.ts +191 -0
  51. package/prompts/global-constitution.prompt.ts +61 -0
  52. package/prompts/spec-assess.prompt.ts +53 -0
  53. package/prompts/spec.prompt.ts +102 -0
  54. package/prompts/tasks.prompt.ts +35 -0
  55. package/prompts/testgen.prompt.ts +84 -0
  56. package/prompts/update.prompt.ts +131 -0
  57. package/purpose.docx +0 -0
  58. package/purpose.md +444 -0
  59. package/tsconfig.json +14 -0
  60. package/tsup.config.ts +10 -0
package/purpose.md ADDED
@@ -0,0 +1,444 @@
1
+ # ai-spec 设计思考文档
2
+
3
+ > 痛点 · 架构创新 · 边界处理 · DSL 的意义 · 当前局限 · 未来方向
4
+ >
5
+ > 当前版本:v0.14.x · 最后更新:2026-03-24
6
+
7
+ ---
8
+
9
+ ## 目录
10
+
11
+ 1. [这个工具在解决什么问题](#1-这个工具在解决什么问题)
12
+ 2. [核心架构设计](#2-核心架构设计)
13
+ 3. [DSL 层的意义](#3-dsl-层的意义)
14
+ 4. [完整功能矩阵](#4-完整功能矩阵)
15
+ 5. [边界情况与兜底机制](#5-边界情况与兜底机制)
16
+ 6. [适合哪些项目](#6-适合哪些项目)
17
+ 7. [当前局限](#7-当前局限)
18
+ 8. [未来优化方向](#8-未来优化方向)
19
+
20
+ ---
21
+
22
+ ## 1. 这个工具在解决什么问题
23
+
24
+ 在 AI 代码生成工具已经泛滥的今天,ai-spec 试图回答的问题不是「AI 能不能写代码」,而是「AI 写出的代码能不能直接用在一个真实运行的、有历史包袱的工程项目里」。这两件事之间有一道非常现实的鸿沟。
25
+
26
+ ### 1.1 现有 AI 编码工具的根本局限
27
+
28
+ 几乎所有 AI 代码生成工具都面临同样的结构性困境:
29
+
30
+ | 局限 | 描述 |
31
+ |------|------|
32
+ | **没有项目记忆** | AI 不知道这个项目的错误码体系是什么,不知道认证中间件挂在哪里,不知道 i18n 文件只有一个不能新建。每次对话都是从零开始,生成的代码像是一个从来没看过这个项目的新人写的 |
33
+ | **缺乏结构化中间层** | 从一段自然语言描述直接跳到代码,中间没有任何可审查、可版本化的契约。需求理解有偏差,你在代码里才会发现——代价极高 |
34
+ | **生成粒度太粗** | 一次性让 AI 生成一个完整功能的所有文件,任何一个文件出错都可能导致整体失败。没有断点续传,失败就要从头来 |
35
+ | **生成即结束** | 代码生成完成后工具就退出了。有没有通过测试?有没有 lint 错误?架构是否符合规范?只能靠人去回答 |
36
+ | **经验不断流失** | 这次代码审查发现了一个安全漏洞,下次 AI 还会犯同样的错误。团队积累的工程经验无法系统性地约束 AI 的行为 |
37
+ | **跨 task 一致性缺失** | 多个文件由多次独立 AI 调用生成,各 task 之间不共享上下文。Task B 生成的路由文件会对 Task A 刚生成的 API 函数名产生幻觉——即使函数就在同一个 PR 里 |
38
+
39
+ ### 1.2 ai-spec 的应对策略
40
+
41
+ ai-spec 对每个痛点都有对应的架构设计,不是功能堆砌,而是一套完整的解决思路:
42
+
43
+ | 痛点 | ai-spec 的解法 | 核心机制 |
44
+ |------|---------------|---------|
45
+ | 没有项目记忆 | 项目宪法系统 | `.ai-spec-constitution.md` 自动注入所有 prompt,§9 随审查持续进化 |
46
+ | 缺乏结构化中间层 | Spec + DSL 双层契约 | Markdown Spec 供人审查,JSON DSL 供机器消费 |
47
+ | 生成粒度太粗 | Task 分层 + 断点续传 | data→infra→service→api→test 层级,逐 task 生成 + `--resume` |
48
+ | 生成后无质量验证 | 错误反馈闭环 | 自动运行 test/lint → AI 修复 → 验证,最多 2 轮 |
49
+ | 经验不断流失 | 知识记忆机制 | 审查 issue 自动写入宪法 §9,下次运行即生效;`init --consolidate` 定期精简 |
50
+ | 跨 task 一致性 | Generated File Cache | 已生成的 API/store 文件内容缓存,后续 task 可见真实导出名 |
51
+
52
+ **核心定位**:ai-spec 不是代码补全工具,而是一个「AI 辅助工程流程编排器」。它的目标是让工程师用最少的时间获得一个符合项目规范、通过基本质检、可直接进入 Review 的代码分支。
53
+
54
+ ---
55
+
56
+ ## 2. 核心架构设计
57
+
58
+ ### 2.1 项目宪法:可进化的项目记忆
59
+
60
+ 绝大多数 AI 工具的「上下文注入」是静态的——你手动写一段 prompt,每次带进去。ai-spec 的宪法系统不同,它是一个会随项目迭代自动更新的活文档。
61
+
62
+ **宪法的生命周期:**
63
+
64
+ ```
65
+ ① ai-spec init
66
+ └─ AI 扫描 routes / schema / middleware / package.json
67
+ → 生成 §1-§8(架构 / 命名 / API / 数据层 / 错误处理 / 禁区 / 测试 / 共享文件清单)
68
+
69
+ ② ai-spec create / review(日常运行)
70
+ └─ 宪法全文注入 Spec 生成 prompt 的最高优先级位置
71
+ → AI 输出天然符合项目规范和架构约束
72
+ → 审查完成后,issue 自动追加到 §9
73
+
74
+ ③ §9 累积到 8 条后,自动提示运行 ai-spec init --consolidate
75
+ └─ LIFT:通用规则融入 §1-§8
76
+ KEEP:近期特定条目,保留 ≤5 条
77
+ DROP:重复或已过时的条目删除
78
+ → 宪法总长度收敛,保持高信噪比
79
+ ```
80
+
81
+ **两级宪法(v0.9+)**:支持全局宪法(`~/.ai-spec-global-constitution.md`)和项目宪法。生成时先注入全局宪法,再注入项目宪法,项目宪法优先级更高。适合维护多个服务的团队统一约定跨项目规范。
82
+
83
+ **核心设计思想**:不试图在一次 init 时就写出完美规范(这不可能),而是通过实际运行中发现的真实问题来持续完善约束。项目跑得越久,宪法越准确,AI 输出越可靠。
84
+
85
+ ---
86
+
87
+ ### 2.2 双层契约:Spec + DSL
88
+
89
+ 在需求和代码之间插入两层中间产物,是 ai-spec 区别于其他工具最关键的架构决策之一:
90
+
91
+ | 层 | 产物 | 服务对象 | 核心价值 |
92
+ |----|------|---------|---------|
93
+ | Spec 层 | `feature-xxx-v1.md` | 人(工程师) | 自然语言,供审查、对齐、留档,可版本化比较 |
94
+ | DSL 层 | `feature-xxx-v1.dsl.json` | 机器(AI / 工具) | 结构化契约,消除歧义,驱动代码生成和测试生成 |
95
+
96
+ - **没有 Spec 层直接生成代码**:AI 理解可能偏差,你在代码里才发现——代价高
97
+ - **没有 DSL 层只用 Spec 生成代码**:Markdown 是非结构化的,AI 需要反复从中解析信息——容易产生幻觉
98
+ - **两层并存**:人看 Spec 做决策,AI 读 DSL 做生成,职责分离
99
+
100
+ DSL 同时作为多个下游模块的共享契约:代码生成、测试骨架生成、错误修复 prompt、OpenAPI 导出、Mock Server 生成,全部以同一份 DSL 为准。
101
+
102
+ ---
103
+
104
+ ### 2.3 Approval Gate:人在正确位置介入
105
+
106
+ 全自动流水线的最大风险不是「AI 写错了代码」,而是「AI 理解错了需求,写了很多正确但没用的代码」。
107
+
108
+ Approval Gate 设计在「Spec 润色完成 + DSL 提取完成」之后、「代码生成开始」之前:
109
+
110
+ - 此时你已经看到了完整的 Spec(人类可读),知道 AI 打算做什么
111
+ - 此时你还没有花任何代码生成的时间和 token
112
+ - 如果你 Abort,Spec 不会写入磁盘——没有任何残留
113
+ - 如果你 Proceed,后续所有步骤都有明确的 Spec 作为依据
114
+
115
+ **设计原则**:「人工确认」不应该发生在流程的末尾(代价已经发生了),也不应该发生在流程的开始(AI 的理解你还看不到)。应该发生在「信息刚好足够决策,代价还没有开始」的那个节点。
116
+
117
+ ---
118
+
119
+ ### 2.4 Task 分层:依赖感知的生成顺序
120
+
121
+ 代码生成的顺序不是随意的。ai-spec 要求 AI 按 **data → infra → service → api → test** 的层级顺序生成:
122
+
123
+ - Service 层调用 Prisma 模型 → 模型必须先存在
124
+ - API 层调用 Service → Service 必须先存在
125
+ - 测试引用真实的实现 → 实现必须先存在
126
+
127
+ 乱序生成时,AI 会假设依赖存在并生成引用,结果所有文件都互相依赖但没有一个完整——这是 AI 代码生成最常见的「幻觉依赖」问题。层级顺序从根本上消除了这类问题。
128
+
129
+ 每个 task 完成后立即写入 `status: done` 到 `tasks.json`,`--resume` 标志让流水线跳过已完成 task,中断恢复精确到 task 粒度。
130
+
131
+ **同层并行执行**:同一层内的多个 task(如 3 个 service)通过 `Promise.all` 并发执行,可将多 task 功能的生成时间从线性缩短到接近单 task 耗时。跨层依赖(service 依赖 data)严格串行保障;同层 task 共享本层开始前的 `generatedFileCache` 快照,层全部完成后统一写入缓存供下一层使用。共享配置文件(如 `routes/index.ts`)从并行 filePlan 中剥离,改为层完成后统一 batch update,避免并发覆写冲突。
132
+
133
+ ---
134
+
135
+ ### 2.5 错误反馈闭环
136
+
137
+ 传统代码生成模型是「生成 → 结束」。ai-spec 引入了「生成 → 验证 → 修复 → 再验证」的循环:
138
+
139
+ ```
140
+ 代码生成完成
141
+
142
+
143
+ 运行 npm test / npm run lint
144
+
145
+ ├─ 全部通过 ──→ 继续
146
+
147
+ └─ 有错误
148
+
149
+
150
+ 解析错误输出(最后 80 行,过滤噪音)
151
+ 按文件分组,逐文件提交 AI 修复
152
+ (prompt 携带:错误描述 + DSL 上下文 + 当前文件内容)
153
+
154
+
155
+ 写回文件 → 重新运行测试
156
+
157
+ ├─ 通过 ──→ 继续
158
+ └─ 还有错误(cycle 2)──→ 再修复一轮
159
+
160
+ └─ 仍有错误 ──→ 黄色警告 + 继续(不中断)
161
+ ```
162
+
163
+ **关键设计点**:修复 prompt 中携带了 DSL 上下文,AI 修复时知道这个文件应该满足什么接口契约,避免了「把错误藏起来」式的修复。
164
+
165
+ ---
166
+
167
+ ### 2.6 前端深度感知(Frontend Context)
168
+
169
+ 前端项目有特殊的高幻觉风险区:HTTP client 导入路径、分页参数命名、路由模块注册方式、状态管理层与 API 层的职责划分。ai-spec 通过 `frontend-context-loader` 从项目现有代码中自动提取这些 ground-truth 信息并注入 prompt:
170
+
171
+ | 提取项 | 注入方式 | 解决的问题 |
172
+ |--------|---------|-----------|
173
+ | `httpClientImport` | "COPY THIS EXACTLY" | 防止 AI 用 `axios` 替换 `import http from '@/utils/http'` |
174
+ | `paginationExample` | "COPY THIS EXACTLY for all paginated list APIs" | 防止 `pageIndex`/`pageSize` vs `page`/`size` 混用;防止 POST body 变 GET query |
175
+ | `layoutImport` | "COPY THIS EXACTLY in every new route module" | 防止路由模块使用错误的 Layout 路径 |
176
+ | `routeModuleExample` | 完整文件作为模板 | 路由模块文件结构、命名、meta 字段保持一致 |
177
+ | `storePatterns` | "stores call API layer, NOT HTTP directly" | 防止 store 直接发起 HTTP 请求 |
178
+ | `reusableComponents` | 枚举列表 | 防止重造已有组件 |
179
+ | `pageExamples` | 完整页面代码示例 | 让 AI 学习 UI 库组件的真实用法 |
180
+
181
+ 扫描覆盖范围:`src/api/`、`src/apis/`、`src/services/`、`src/router/`、`src/routes/`、`src/store/`、`src/stores/`、`src/components/`、`src/views/`、`src/pages/`。
182
+
183
+ ---
184
+
185
+ ### 2.7 跨 Task 一致性(Generated File Cache)
186
+
187
+ 多文件功能由多次独立 AI 调用完成。Task B 的 AI 实例无法感知 Task A 刚写了什么——这是跨 task 函数名幻觉的根本原因(`getTaskList` 被猜成 `getTasks`)。
188
+
189
+ **解决方案**:`generatedFileCache` — 每个 task 完成后,将写入的 `src/api*` / `src/service*` / `src/store*` / `src/composable*` 文件读回并缓存到内存 Map;后续每个 task 的 prompt 中追加 `=== Files Already Generated in This Run ===` 区段,内容为缓存文件的实际代码。
190
+
191
+ 系统提示中有对应的强制规则(Rule 17):该区段中的导出函数名是权威来源,NEVER 重命名或猜测替代名。
192
+
193
+ **路由模块注册**:当 task 新建路由模块文件时,`routes/index.ts` 被注入为 shared config file,purpose 字段精确指定需要 import 的模块名(而非通用描述),配合 Rule 16 强制要求 AI 同时更新 index 文件。
194
+
195
+ ---
196
+
197
+ ### 2.8 多语言后端支持
198
+
199
+ `ContextLoader` 自动识别项目技术栈,选择对应的代码生成 prompt:
200
+
201
+ | 语言 / 框架 | 识别方式 | Codegen Prompt 关键约束 |
202
+ |------------|---------|------------------------|
203
+ | Node.js / TypeScript | `package.json` | 路由注册、Prisma schema、中间件挂载 |
204
+ | PHP / Lumen / Laravel | `composer.json` | `import http` 封装、Eloquent、`routes/api.php` 注册 |
205
+ | Java / Spring Boot | `pom.xml` / `build.gradle` | Controller → Service → Repository 分层、Lombok、构造器注入 |
206
+ | Go | `go.mod` | 命名错误返回、`defer` 清理、context 传播 |
207
+ | Python / FastAPI | `requirements.txt` / `pyproject.toml` | Pydantic 模型、`APIRouter` 注册、type annotations |
208
+ | Rust / Axum | `Cargo.toml` | `Result<T,E>`、no `unwrap()` in production、tokio async |
209
+
210
+ ---
211
+
212
+ ## 3. DSL 层的意义
213
+
214
+ DSL 是整个系统中设计投入最大的模块,也是最容易被误解为「多此一举」的部分。
215
+
216
+ ### 3.1 消除「规格到代码」之间的歧义
217
+
218
+ 考虑这样一段 Spec 描述:
219
+
220
+ > POST /api/v1/auth/login — 接受 email 和 password,登录成功返回 JWT token,邮箱格式错误返回 400,密码错误返回 401
221
+
222
+ 对人类来说这足够清楚。但对 AI 代码生成来说,这段文字里有几十个「待解释的细节」:400 错误的 code 字段是什么?JWT payload 要包含哪些字段?这个接口需要认证中间件吗?
223
+
224
+ 每一个不确定的细节,AI 都会自己「填空」——填出来的答案未必和你的项目一致。DSL 强制把这些细节显式化:
225
+
226
+ ```json
227
+ {
228
+ "endpoints": [{
229
+ "method": "POST",
230
+ "path": "/api/v1/auth/login",
231
+ "auth": false,
232
+ "request": { "body": { "email": "string (email format)", "password": "string" } },
233
+ "successStatus": 200,
234
+ "successDescription": "返回 JWT token,payload 包含 userId 和 role",
235
+ "errors": [
236
+ { "status": 400, "code": "INVALID_EMAIL", "description": "邮箱格式不合法" },
237
+ { "status": 401, "code": "INVALID_CREDENTIALS", "description": "密码错误" }
238
+ ]
239
+ }]
240
+ }
241
+ ```
242
+
243
+ DSL 提取完成后,这些细节就是确定的。后续所有下游模块以 DSL 为准,而不是每次重新解析 Spec。
244
+
245
+ ### 3.2 多下游模块的共享契约
246
+
247
+ DSL 的价值不只是给 codegen 用:
248
+
249
+ | 消费方 | 如何使用 DSL | 如果没有 DSL |
250
+ |--------|------------|-------------|
251
+ | 代码生成(api 模式) | 端点签名 + 模型字段注入 prompt,减少 AI 猜测 | AI 从 Spec 文本反复解析,每次可能得到不同结论 |
252
+ | 测试骨架生成 | 按端点生成对应的 test case,按模型生成 CRUD 测试 | 只能生成通用骨架,无法对应具体接口 |
253
+ | 错误反馈修复 | 修复 prompt 中注入端点契约,避免「把错误藏起来」 | AI 修复时不知道接口规范,可能改坏其他逻辑 |
254
+ | OpenAPI 导出 | DSL → OpenAPI 3.1.0 YAML/JSON | 需要手动维护两份文档 |
255
+ | Mock Server | DSL → Express mock handler | mock 和实现不保证结构一致 |
256
+
257
+ ### 3.3 抗幻觉设计
258
+
259
+ DSL 提取本身是高幻觉风险操作。ai-spec 做了几个针对性设计:
260
+
261
+ - **9 条 CRITICAL RULES**:明确告诉 AI「只提取明确写出的内容,不推断不补全」
262
+ - **空数组是正确答案**:没有 models 时输出 `[]`,不要强行推断出模型
263
+ - **字段类型限制**:FieldMap 的值必须是字符串描述,不能是嵌套对象(嵌套是幻觉的温床)
264
+ - **硬性上界**:models ≤ 50,fields/model ≤ 100——超出说明 AI 在臆造内容
265
+ - **精确错误 retry**:第 2 次 retry 携带具体的字段路径错误,让 AI 定向修复而不是重新生成
266
+
267
+ ---
268
+
269
+ ## 4. 完整功能矩阵
270
+
271
+ 截至 v0.14.x,ai-spec 的完整能力覆盖:
272
+
273
+ | 阶段 | 命令 | 核心能力 |
274
+ |------|------|---------|
275
+ | **初始化** | `ai-spec init` | 扫描项目 → 生成宪法 §1-§8(`--global` 生成全局宪法,`--consolidate` 整合 §9) |
276
+ | **新功能** | `ai-spec create` | 宪法 → context → Spec+Tasks → **Spec质量评估** → Approval Gate → DSL → Worktree → 逐 task codegen(同层并行 + 跨 task 缓存)→ **TDD测试(`--tdd`)** → test → error feedback → **2-pass review** |
277
+ | **变更迭代** | `ai-spec update` | 最小化更新 Spec → 定向更新 DSL(delta 对比)→ 识别受影响文件 → 可选重新生成 |
278
+ | **接口导出** | `ai-spec export` | DSL → OpenAPI 3.1.0 YAML/JSON,纯 TypeScript 实现,零外部依赖 |
279
+ | **前后端联调** | `ai-spec mock` | DSL → Express Mock Server + Proxy 配置 + MSW Handlers |
280
+ | **代码审查** | `ai-spec review` | git diff + Spec → AI 架构审查 → issue 写入宪法 §9 |
281
+ | **多 Repo 工作区** | workspace 模式 | 一句需求 → AI 拆分职责+UX 决策 → [后端流水线 → DSL 契约] → [前端流水线(注入后端契约)] |
282
+
283
+ **单 Repo 流水线总图:**
284
+ ```
285
+ 需求描述
286
+ → 项目宪法 + 多语言 Context 感知
287
+ → Spec + Tasks(合并生成)
288
+ → 交互式润色(Diff 预览)
289
+ → Approval Gate
290
+ → DSL 提取 + 校验(抗幻觉)
291
+ → Git Worktree 隔离
292
+ → 逐 task 代码生成(依赖层级 + 跨 task 缓存)
293
+ → 错误反馈闭环(自动修复 ≤2 轮)
294
+ → 测试骨架生成
295
+ → AI 代码审查
296
+ → 经验写入宪法 §9
297
+ ```
298
+
299
+ ---
300
+
301
+ ## 5. 边界情况与兜底机制
302
+
303
+ 一个工具在 demo 场景下好用不难。难的是在各种「不对劲」的情况下不崩溃、不丢数据、给出有用的提示。
304
+
305
+ ### 5.1 DSL 提取失败
306
+
307
+ ```
308
+ attempt 1: 提取失败(JSON 解析错 / 校验不通过)
309
+ └─ 展示具体字段路径错误(如: endpoints[1].auth 不是 boolean)
310
+
311
+ attempt 2: 携带错误信息重试
312
+ ├─ 通过 → 继续正常流程
313
+ └─ 仍失败
314
+ ├─ --auto 模式: 静默跳过 DSL,后续 codegen 使用 Spec+Tasks 兜底
315
+ └─ 交互模式: 询问用户 → ⏭ Skip(降级运行)或 ❌ Abort(Spec 不写磁盘)
316
+ ```
317
+
318
+ ### 5.2 项目宪法失败
319
+
320
+ - `create` 触发自动 init 但失败时:警告 + 继续,不阻断流程
321
+ - 宪法失败通常意味着项目结构不符合预期——此时没有宪法比有错误的宪法更安全
322
+ - 用户可随时手动运行 `ai-spec init --force` 重新生成
323
+
324
+ ### 5.3 Tasks 解析失败
325
+
326
+ Spec + Tasks 在同一次 AI 调用中生成。Tasks 部分解析失败时:
327
+ - Spec 已经生成成功,不会丢失
328
+ - 自动降级到独立的 Task 生成调用(第二次 AI 调用)
329
+ - 两次都失败时:警告,代码生成使用 fallback 文件规划模式
330
+
331
+ ### 5.4 代码生成中途中断
332
+
333
+ - 每个 task 完成后立即写入 `status: done` 到 `tasks.json`
334
+ - `--resume` 标志让流水线跳过所有已标记为 done 的 task
335
+ - 中断点精确到 task 粒度,不需要重跑整个功能
336
+
337
+ 注意:`--resume` 依赖 `tasks.json` 的存在。`--skip-tasks` 运行时没有 resume 能力。
338
+
339
+ ### 5.5 错误反馈循环的边界处理
340
+
341
+ | 场景 | 处理方式 |
342
+ |------|---------|
343
+ | 项目无 test 命令也无 lint 命令 | 跳过整个 error feedback 步骤,打印提示 |
344
+ | 测试命令超时(>60s) | `execSync` timeout 触发,视为失败,进入修复流程 |
345
+ | 修复后测试仍失败(cycle 2 结束) | 黄色警告提示,继续后续步骤(不硬停) |
346
+ | 修复的文件不存在 | 跳过该文件,记录 `fixed: false`,继续其他文件 |
347
+ | AI 修复调用失败 | 记录失败,继续其他错误文件,不中断整个修复循环 |
348
+ | 错误输出过长 | 只取最后 80 行,过滤 `node_modules` / npm timing 噪音,上限 20 条错误 |
349
+
350
+ ### 5.6 Git Worktree 边界
351
+
352
+ - 当前目录不是 git 仓库:跳过 worktree 创建,直接在原目录工作
353
+ - feature 分支已存在:直接复用,不报错
354
+ - `--skip-worktree`:完全跳过,所有文件生成在当前目录
355
+
356
+ ### 5.7 Approval Gate 的 Abort 行为
357
+
358
+ 选择 Abort 时,Spec 内容**不会**写入磁盘(`specs/` 目录下不会出现新文件)。这是刻意设计——避免在用户明确拒绝的情况下留下「半成品」文件污染 `specs/` 目录。
359
+
360
+ ### 5.8 API Key 处理
361
+
362
+ CLI Key(`-k`)> 环境变量 > 交互式输入——三级回退,不会因为 key 不在环境变量里就崩溃。
363
+
364
+ ---
365
+
366
+ ## 6. 适合哪些项目
367
+
368
+ ai-spec 不是通用工具。它在特定类型的项目上效果非常好,在另一些场景下收益有限。
369
+
370
+ ### 6.1 最适合的场景
371
+
372
+ | 场景 | 为什么适合 |
373
+ |------|-----------|
374
+ | 有成熟架构规范的团队项目 | 项目宪法约束发挥最大价值,AI 输出与现有代码一致性高 |
375
+ | Node.js / TypeScript + Prisma 后端 | Context loader 对这类项目的扫描最精准(路由、schema、middleware) |
376
+ | Java Spring Boot 后端 | `pom.xml` / `build.gradle` 自动解析依赖,Controller→Service→Repository 分层规则完善 |
377
+ | Vue / React 前端(有规范的 API 封装层) | 分页 pattern、HTTP client import、路由注册方式全部从代码中自动提取 |
378
+ | 功能边界清晰的 CRUD 型功能 | DSL 可以完整提取端点和模型,代码生成和测试生成准确率高 |
379
+ | 需要快速出 PR 草稿的场景 | `create` 产出的代码分支可以直接作为 PR 基础,节省大量初始化工作 |
380
+ | 多人协作、需要留下需求文档的项目 | 版本化 Spec 文件是天然的需求文档,和代码一起存入 git |
381
+
382
+ ### 6.2 效果有限的场景
383
+
384
+ | 场景 | 原因 |
385
+ |------|------|
386
+ | 全新项目(无任何代码) | 宪法生成时无足够上下文,Context 为空,AI 输出质量下降。建议先写好基础骨架再使用 |
387
+ | 纯算法 / 数据处理类代码 | 没有路由、没有模型,DSL 无法提取有意义的结构,测试骨架也无法对应 |
388
+ | 一次性脚本 / 工具类代码 | 流水线成本高于收益,直接用 AI 助手更快 |
389
+ | 前端项目(无规范 API 封装层) | `httpClientImport` 提取失败,分页 pattern 无法找到参照,AI 会回退到通用默认值 |
390
+
391
+ ### 6.3 最佳组合推荐
392
+
393
+ - **Spec 生成**:Gemini 2.5 Pro(理解力强,成本合理)或 Claude Opus 4.6(用于复杂功能)
394
+ - **代码生成**:Qwen3-235B 或 GLM-5(性价比高,中文 codebase 表现好)
395
+ - **代码审查**:和 Spec 生成用同一个模型(保持上下文一致性)
396
+
397
+ 配合 RTK(Rust Token Killer)+ `--auto` 模式,claude-code 模式下可节省 60-90% token。适合 CI 环境或需要频繁运行 `create` 的场景。
398
+
399
+ ---
400
+
401
+ ## 7. 当前局限
402
+
403
+ 客观列出当前版本已知的不足,避免对工具产生不切实际的期望。
404
+
405
+ ### 7.1 前端 Context 提取依赖项目规范度
406
+
407
+ `frontend-context-loader` 的提取逻辑基于约定俗成的目录结构(`src/apis/`、`src/stores/` 等)和代码特征(interface 字段名、import 路径模式)。对于不遵循常规结构的前端项目,提取可能失败,AI 会回退到通用默认值,输出一致性下降。
408
+
409
+ ### 7.3 DSL 的有效范围
410
+
411
+ DSL 设计主要针对 REST API 场景(HTTP 端点 + 数据模型)。对于以下场景,DSL 无法有效提取结构:
412
+ - 纯 UI 功能(没有新接口,只有前端交互逻辑)
413
+ - 事件驱动 / 消息队列场景
414
+ - WebSocket 实时通信
415
+
416
+ 这些场景会降级为「Spec + Tasks 模式」,代码生成质量取决于 Spec 的详细程度。
417
+
418
+ ### 7.4 宪法长度限制
419
+
420
+ 代码中存在 `constitution.slice(0, 2000)` 的硬截断。随着宪法增长,末尾内容(通常是 §9 最新教训)会被截断。`init --consolidate` 是缓解手段,但不能完全消除这个限制。
421
+
422
+ ### 7.5 错误修复能力有上限
423
+
424
+ 错误反馈循环最多运行 2 次,每次修复以文件为粒度。对于复杂的跨文件依赖错误(A 文件的 export 类型变了,B、C、D 都引用了它),当前的修复逻辑可能只修复了第一个文件,后续文件的错误留到下一 cycle,效率较低。
425
+
426
+ ---
427
+
428
+ ## 8. 未来优化方向
429
+
430
+ 按优先级从高到低排列(已实现的功能不在此列)。
431
+
432
+ ### 8.1 中优先级:多 Repo 工作区合同同步(ai-spec sync)
433
+
434
+ 当后端 DSL 变更时,前端的 TypeScript 接口定义、mock 文件需要联动更新。目前需要手动重跑前端流水线。`ai-spec sync` 的设计思路:监听后端 DSL 变更 → 自动重新生成前端契约层文件。
435
+
436
+ ### 8.2 低优先级:CI/CD 集成
437
+
438
+ - GitHub Actions workflow 模板:push → `ai-spec create --auto --fast` → PR 自动创建
439
+ - PR 自动附上对应的 Spec 和审查报告
440
+ - `spec review` 作为 PR check:新 PR 如果没有对应 spec,自动标记 warning
441
+
442
+ ---
443
+
444
+ *ai-spec v0.16.x · Design Rationale Document · 2026-03-24*
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "module": "commonjs",
5
+ "lib": ["es2022"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true
12
+ },
13
+ "include": ["core/**/*", "cli/**/*", "prompts/**/*", "index.ts"]
14
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["cli/index.ts", "index.ts"],
5
+ format: ["cjs", "esm"],
6
+ dts: true,
7
+ splitting: false,
8
+ sourcemap: true,
9
+ clean: true,
10
+ });