create-vela-workflow 1.0.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.
- package/README.md +136 -0
- package/bin/cli.js +188 -0
- package/docs/ai-workflow-tutorial.md +462 -0
- package/docs/official-site-tutorial.md +391 -0
- package/package.json +34 -0
- package/templates/.github/HARNESS-ENGINEERING-GUIDE.md +407 -0
- package/templates/.github/agents/vela-knowledge.agent.md +45 -0
- package/templates/.github/agents/vela-s1-prd.agent.md +69 -0
- package/templates/.github/agents/vela-s2-tech.agent.md +66 -0
- package/templates/.github/agents/vela-s3-coding.agent.md +301 -0
- package/templates/.github/agents/vela-workflow.agent.md +110 -0
- package/templates/.github/copilot-instructions.md +64 -0
- package/templates/.github/prompts/vela-apis.prompt.md +98 -0
- package/templates/.github/prompts/vela-best-practices.prompt.md +93 -0
- package/templates/.github/prompts/vela-components.prompt.md +118 -0
- package/templates/.github/prompts/vela-dev-guide.prompt.md +622 -0
- package/templates/.github/rules/project-init.md +45 -0
- package/templates/.github/rules/vela-coding-convention.md +324 -0
- package/templates/.github/rules/vela-css.md +217 -0
- package/templates/.github/rules/vela-design-driven.md +306 -0
- package/templates/.github/rules/vela-figma-mcp.md +198 -0
- package/templates/.github/rules/vela-format.md +119 -0
- package/templates/.github/rules/vela-layout.md +67 -0
- package/templates/.github/rules/vela-platform.md +46 -0
- package/templates/.github/rules/vela-quality.md +109 -0
- package/templates/.kiro/hooks/figma-design-check.kiro.hook +14 -0
- package/templates/.kiro/hooks/post-coding-validation.kiro.hook +13 -0
- package/templates/.kiro/hooks/validate-ux-files.kiro.hook +16 -0
- package/templates/.kiro/settings/mcp.json +7 -0
- package/templates/.kiro/skills/vela-js-app/SKILL.md +1072 -0
- package/templates/.kiro/steering/workflow-conventions.md +110 -0
- package/templates/.workflow/resource-paths.json +62 -0
- package/templates/.workflow/scripts/.gitkeep +0 -0
- package/templates/.workflow/scripts/checkpoint_manager.js +284 -0
- package/templates/.workflow/scripts/context_loader.js +841 -0
- package/templates/.workflow/scripts/figma_export.js +346 -0
- package/templates/.workflow/scripts/session_manager.js +438 -0
- package/templates/.workflow/stages/.gitkeep +0 -0
- package/templates/.workflow/stages/commands.md +171 -0
- package/templates/.workflow/stages/s1_prd.md +286 -0
- package/templates/.workflow/stages/s2_tech_design.md +302 -0
- package/templates/.workflow/stages/s3_coding.md +699 -0
- package/templates/.workflow/stages/s4_simulator.md +259 -0
- package/templates/.workflow/workflow-config.json +46 -0
- package/templates/.workflow/workflow_starter.md +912 -0
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
# S3: 功能研发
|
|
2
|
+
|
|
3
|
+
**⚠️ 重要:仅对 S3 功能研发阶段执行。**
|
|
4
|
+
|
|
5
|
+
S3 阶段的目标是根据已审核通过的 PRD 文档和技术方案,结合 Vela 快应用知识库中的开发范式、API 接口文档、组件规范和代码示例,在项目工程目录中直接编写可运行的 Vela 快应用代码。
|
|
6
|
+
|
|
7
|
+
> ⚠️ **关键区别**:S3 阶段的代码产出物直接写入项目工程目录(`session.inputs.project_path`),而非 Session 目录。这确保代码可以直接在项目中编译运行。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 阶段概要
|
|
12
|
+
|
|
13
|
+
| 属性 | 值 |
|
|
14
|
+
|------|-----|
|
|
15
|
+
| 阶段 ID | S3 |
|
|
16
|
+
| 阶段名称 | 功能研发 |
|
|
17
|
+
| Agent | `agents/coding_agent.prompt.md` |
|
|
18
|
+
| 知识库 | `vela/dev-paradigm`、`vela/api-reference`、`vela/components`、`vela/examples`、`vela/best-practices` |
|
|
19
|
+
| 前置条件 | S1 已完成且 S2 已完成 |
|
|
20
|
+
| 工作目录 | `session.inputs.project_path`(项目工程目录,由 S2 阶段收集) |
|
|
21
|
+
| 产出物 | 项目工程目录中的代码文件 |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 执行步骤
|
|
26
|
+
|
|
27
|
+
### Step 1: 前置校验
|
|
28
|
+
|
|
29
|
+
校验前置阶段、项目工程路径,并加载前置产出物。
|
|
30
|
+
|
|
31
|
+
**1.1 检查 S1、S2 完成状态**
|
|
32
|
+
|
|
33
|
+
读取 `session.json`,根据 `workflow_mode` 判断前置条件:
|
|
34
|
+
|
|
35
|
+
| 工作流模式 | 前置条件 |
|
|
36
|
+
|-----------|---------|
|
|
37
|
+
| `full`(完整模式) | S1 和 S2 均为 `completed`,任一未完成则阻止执行 |
|
|
38
|
+
| `quick`(快速模式) | 无前置条件,S1 和 S2 状态为 `skipped`,直接执行 S3 |
|
|
39
|
+
|
|
40
|
+
**1.2 加载前置产出物**
|
|
41
|
+
|
|
42
|
+
- **完整模式**:确认 `01-prd.md` 和 `02-tech-design.md` 均存在于 Session 目录中
|
|
43
|
+
- **快速模式**:跳过此步骤,S3 将直接基于用户需求描述 + Figma 设计稿 + 知识库生成代码
|
|
44
|
+
|
|
45
|
+
**1.3 校验项目工程路径**
|
|
46
|
+
|
|
47
|
+
S3 阶段必须有一个有效的项目工程路径作为代码写入目标。
|
|
48
|
+
|
|
49
|
+
| 情况 | 处理方式 |
|
|
50
|
+
|------|---------|
|
|
51
|
+
| `project_path` 不为 `null` 且路径存在 | ✅ 使用该路径 |
|
|
52
|
+
| `project_path` 为 `null` 或 `.` | ✅ 使用当前工作区根目录 `.` |
|
|
53
|
+
| 路径不存在 | ⚠️ 自动创建目录后使用 |
|
|
54
|
+
|
|
55
|
+
> 项目工程路径默认为 `.`(当前工作区根目录),S3 脚手架会在该路径下创建以项目名命名的子目录。
|
|
56
|
+
|
|
57
|
+
**1.4 更新 Session 状态**
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
updateStageStatus(sessionId, 'S3', 'in_progress')
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Step 2: 项目工程初始化检测
|
|
66
|
+
|
|
67
|
+
检测项目工程目录状态,判断是全新项目还是已有项目。
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
📂 正在检测项目工程状态...
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**2.1 检测项目目录状态**
|
|
74
|
+
|
|
75
|
+
| 条件 | 判定 | 处理方式 |
|
|
76
|
+
|------|------|---------|
|
|
77
|
+
| 目录不存在或为空 | 🆕 全新项目 | 执行 Step 2.2 基于知识库模板初始化 |
|
|
78
|
+
| 目录存在但无 `src/manifest.json` | 🆕 全新项目 | 执行 Step 2.2 基于知识库模板初始化 |
|
|
79
|
+
| 目录存在且有 `src/manifest.json` | ✏️ 已有项目 | 跳过初始化,进入 Step 3 |
|
|
80
|
+
|
|
81
|
+
**2.2 全新项目工程初始化(使用 create-aiot 脚手架)**
|
|
82
|
+
|
|
83
|
+
> ⚠️ **强制规则**:全新项目必须使用 `npx create-aiot ux --name <项目名>` 命令创建项目模板。**禁止**手动拼凑 package.json、manifest.json 等配置文件。
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
🔧 检测到全新项目,正在使用 create-aiot 脚手架初始化...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
执行步骤:
|
|
90
|
+
|
|
91
|
+
1. **自动生成项目名**:根据需求名称生成 kebab-case 格式的项目名
|
|
92
|
+
- 示例:需求"手环汽车App" → 项目名 `band-car-app`
|
|
93
|
+
- 示例:需求"应用商店" → 项目名 `app-store`
|
|
94
|
+
- 规则:中文转英文、全小写、空格/特殊字符替换为 `-`
|
|
95
|
+
|
|
96
|
+
2. **在项目工程路径下执行脚手架命令**:
|
|
97
|
+
```bash
|
|
98
|
+
cd ${projectPath} && npx create-aiot ux --name ${projectName}
|
|
99
|
+
```
|
|
100
|
+
- 该命令会在 `${projectPath}/${projectName}/` 下生成完整的项目模板(含 package.json、src/manifest.json、src/app.ux 等)
|
|
101
|
+
- 若 `projectPath` 为 `.`(当前目录),则项目生成在 `./${projectName}/`
|
|
102
|
+
|
|
103
|
+
3. **更新 project_path**:脚手架生成的项目在子目录中,需要更新 session 中的 `project_path`
|
|
104
|
+
```javascript
|
|
105
|
+
session.inputs.project_path = `${projectPath}/${projectName}`
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
4. **校验初始化结果**:
|
|
109
|
+
- 检查 `${projectPath}/${projectName}/src/manifest.json` 是否存在
|
|
110
|
+
- 检查 `${projectPath}/${projectName}/package.json` 是否存在
|
|
111
|
+
|
|
112
|
+
| 情况 | 处理方式 |
|
|
113
|
+
|------|---------|
|
|
114
|
+
| 初始化成功 | ✅ 继续 Step 3 |
|
|
115
|
+
| `npx` 命令不存在 | ⚠️ 提示安装 Node.js,提供 [r] 重试 / [s] 跳过 选项 |
|
|
116
|
+
| `create-aiot` 包下载失败 | ⚠️ 提示检查网络,提供 [r] 重试 / [s] 跳过 选项 |
|
|
117
|
+
| 其他错误 | ⚠️ 输出错误信息,提供 [r] 重试 / [s] 跳过 选项 |
|
|
118
|
+
|
|
119
|
+
> 用户选择 `[s]` 跳过时,回退到手动创建目录结构并从知识库模板复制配置文件的方式。
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
✅ 工程初始化完成(create-aiot 脚手架)
|
|
123
|
+
📂 项目目录: ${projectPath}/${projectName}
|
|
124
|
+
📄 package.json: 已生成
|
|
125
|
+
📄 manifest.json: 已生成
|
|
126
|
+
📄 app.ux: 已生成
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**2.2.5 脚手架产物补全**
|
|
130
|
+
|
|
131
|
+
> ⚠️ `npx create-aiot` 生成的项目模板可能缺少必要的依赖声明和配置文件,必须在此步骤补全。
|
|
132
|
+
|
|
133
|
+
1. **补全 package.json 依赖**:读取脚手架生成的 `package.json`,若 `devDependencies` 为空或缺少核心依赖,则参考知识库模板(`knowledge/examples/multi_screen_todolist/package.json`)补全:
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"devDependencies": {
|
|
137
|
+
"aiot-toolkit": "^2.0.5"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
同时确保 `scripts` 中包含以下命令(若缺失则补充):
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"scripts": {
|
|
145
|
+
"start": "aiot server --watch --open-nuttx",
|
|
146
|
+
"build": "aiot build",
|
|
147
|
+
"release": "aiot release",
|
|
148
|
+
"watch": "aiot watch --open-nuttx"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
保留脚手架已生成的 `name`、`version` 等字段不变,仅合并缺失项。
|
|
153
|
+
|
|
154
|
+
2. **生成 README.md**(若不存在):
|
|
155
|
+
```markdown
|
|
156
|
+
# ${projectName}
|
|
157
|
+
|
|
158
|
+
基于 Vela 快应用框架开发的 ${requirementName} 应用。
|
|
159
|
+
|
|
160
|
+
## 开发
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npm install
|
|
164
|
+
npm run start
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 构建
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm run build
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 目标平台
|
|
174
|
+
|
|
175
|
+
- VelaOS 智能手表(${screenWidth}×${screenHeight} ${screenShape})
|
|
176
|
+
```
|
|
177
|
+
其中 `${requirementName}` 取自 `session.requirement_name`,屏幕规格取自 `session.inputs.screen_spec`。
|
|
178
|
+
|
|
179
|
+
3. **生成 .gitignore**(若不存在):
|
|
180
|
+
```
|
|
181
|
+
node_modules/
|
|
182
|
+
build/
|
|
183
|
+
dist/
|
|
184
|
+
.DS_Store
|
|
185
|
+
*.log
|
|
186
|
+
.env
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
4. **生成 .eslintrc.json**(若不存在):
|
|
190
|
+
> ⚠️ 不生成 .eslintrc.json,项目不强制使用 eslint。
|
|
191
|
+
|
|
192
|
+
补全完成后输出:
|
|
193
|
+
```
|
|
194
|
+
🔧 脚手架产物补全完成
|
|
195
|
+
📦 package.json: 依赖已补全(aiot-toolkit)
|
|
196
|
+
📄 README.md: 已生成
|
|
197
|
+
📄 .gitignore: 已生成
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**2.3 已有项目扫描**
|
|
201
|
+
|
|
202
|
+
若为已有项目,简要输出项目现状:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
✏️ 检测到已有项目工程
|
|
206
|
+
📂 项目目录: {projectPath}
|
|
207
|
+
📑 已有页面: {page_count} 个
|
|
208
|
+
🧩 已有组件: {component_count} 个
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**2.4 询问是否使用 UnoCSS(仅全新项目)**
|
|
212
|
+
|
|
213
|
+
> 全新项目初始化完成后,询问用户是否启用 UnoCSS 原子化样式。
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
🎨 是否启用 UnoCSS 原子化样式?
|
|
217
|
+
[y] 启用 — 使用 unocss-preset-vela 插件,支持 Tailwind 风格的原子类(如 flex, w-full, text-white 等)
|
|
218
|
+
[n] 不启用 — 使用传统 CSS 手写样式(默认)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- 用户选择 `y`:执行以下配置步骤
|
|
222
|
+
- 用户选择 `n` 或直接回车:跳过,使用传统 CSS
|
|
223
|
+
|
|
224
|
+
**启用 UnoCSS 的配置步骤**:
|
|
225
|
+
|
|
226
|
+
1. **安装依赖**:
|
|
227
|
+
```bash
|
|
228
|
+
cd ${projectPath} && npm install -D unocss unocss-preset-vela
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
2. **创建 `unocss.config.js`**:
|
|
232
|
+
```javascript
|
|
233
|
+
import { defineConfig } from 'unocss'
|
|
234
|
+
import { presetVela } from 'unocss-preset-vela'
|
|
235
|
+
|
|
236
|
+
export default defineConfig({
|
|
237
|
+
presets: [
|
|
238
|
+
presetVela()
|
|
239
|
+
]
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
3. **在 `package.json` 的 `scripts` 中添加 uno 命令**:
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"scripts": {
|
|
247
|
+
"uno": "unocss 'src/**/*.ux' --out-file=src/common/style/unocss-vela.css --watch"
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
4. **创建样式输出目录**:
|
|
253
|
+
```bash
|
|
254
|
+
mkdir -p ${projectPath}/src/common/style
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
5. **在 `app.ux` 中引入生成的 CSS**:
|
|
258
|
+
```html
|
|
259
|
+
<style src="./common/style/unocss-vela.css"></style>
|
|
260
|
+
```
|
|
261
|
+
> ⚠️ 快应用引入外部 CSS 必须使用 `<style src="./path"></style>` 标签方式。**禁止**使用 `@import './path';` 或 `@import url('./path');`
|
|
262
|
+
|
|
263
|
+
6. **记录到 session**:`session.inputs.use_unocss = true`
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
✅ UnoCSS 已启用
|
|
267
|
+
📦 已安装: unocss, unocss-preset-vela
|
|
268
|
+
📄 unocss.config.js 已创建
|
|
269
|
+
📝 app.ux 已引入
|
|
270
|
+
💡 开发时运行 npm run uno 生成原子类 CSS
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> 启用 UnoCSS 后,后续代码生成阶段可以在 `.ux` 文件的模板中直接使用原子类(如 `class="flex items-center w-full text-white"`),无需手写 CSS。
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
### Step 3: 上下文加载
|
|
278
|
+
|
|
279
|
+
加载 S3 阶段所需的全部知识库、前置产出和 Agent 提示词。
|
|
280
|
+
|
|
281
|
+
**3.1 调用上下文加载器**
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
const context = loadStageContext('S3', session)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
| 资源类型 | 加载内容 |
|
|
288
|
+
|---------|---------|
|
|
289
|
+
| SKILL.md | Vela 快应用完整开发指南(项目结构、manifest、组件、API、最佳实践) |
|
|
290
|
+
| 代码示例 | `vela/examples`(完整项目模板参考) |
|
|
291
|
+
| 前置产出 | 完整模式:`01-prd.md` + `02-tech-design.md`;快速模式:无(使用 `session.requirement_description` 作为需求输入) |
|
|
292
|
+
| Figma 数据 | `session_dir/figma-exports/`(若有) |
|
|
293
|
+
| 项目工程现状 | `scanProjectStructure()` 扫描结果 |
|
|
294
|
+
|
|
295
|
+
> **知识加载策略**:优先加载 SKILL.md 全文。当需要某个组件/API 的完整属性列表时,使用 `webFetch` 访问 SKILL.md 中标注的官网链接按需获取。S3 阶段额外加载 `vela/examples` 知识库提供完整项目模板参考。
|
|
296
|
+
|
|
297
|
+
**3.2 注入上下文到 Agent 提示词**
|
|
298
|
+
|
|
299
|
+
```javascript
|
|
300
|
+
const agentPrompt = readFile('agents/coding_agent.prompt.md')
|
|
301
|
+
const injectedPrompt = injectContext(agentPrompt, context)
|
|
302
|
+
// 替换: {session.requirement_name}, {knowledge_content}, {previous_outputs}
|
|
303
|
+
// 替换: {figma_data}, {project_analysis}, {project_path}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
### Step 3.5: 快速模式轻量技术规划(仅 quick 模式执行)
|
|
309
|
+
|
|
310
|
+
> ⚠️ 仅当 `session.workflow_mode === "quick"` 时执行此步骤。完整模式跳过。
|
|
311
|
+
|
|
312
|
+
快速模式跳过了 S1/S2,直接进入编码。为避免代码结构混乱,Agent 必须先输出一个轻量技术规划供用户确认,再开始生成代码。
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
📋 快速模式 — 轻量技术规划
|
|
316
|
+
🤖 正在分析需求并规划项目结构...
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**3.5.1 Agent 输出轻量规划**
|
|
320
|
+
|
|
321
|
+
Agent 根据需求描述、Figma 设计稿和知识库,输出以下规划内容:
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
📋 轻量技术规划:
|
|
325
|
+
📄 页面列表:
|
|
326
|
+
- {page_1}: {description}
|
|
327
|
+
- {page_2}: {description}
|
|
328
|
+
🧩 自定义组件:
|
|
329
|
+
- {component_1}: {description}(若无则标注"无")
|
|
330
|
+
🔗 路由配置:
|
|
331
|
+
- 入口页面: {entry_page}
|
|
332
|
+
- 导航关系: {page_1} → {page_2} → ...
|
|
333
|
+
📡 系统 API:
|
|
334
|
+
- {api_1}: {usage}
|
|
335
|
+
- {api_2}: {usage}
|
|
336
|
+
📂 项目目录结构:
|
|
337
|
+
src/
|
|
338
|
+
├── manifest.json
|
|
339
|
+
├── app.ux
|
|
340
|
+
├── pages/
|
|
341
|
+
│ ├── {Page1}/index.ux
|
|
342
|
+
│ └── {Page2}/index.ux
|
|
343
|
+
└── common/images/
|
|
344
|
+
|
|
345
|
+
❓ 请确认规划:
|
|
346
|
+
[y] 确认 — 按此规划生成代码
|
|
347
|
+
[e] 修改 — 提供调整意见
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
- 用户输入 `y` → 按规划进入 Step 4 生成代码
|
|
351
|
+
- 用户输入 `e` → 接收修改意见,重新输出规划(支持多轮)
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
### Step 4: Figma 图片资源导出(代码生成前必须完成)
|
|
356
|
+
|
|
357
|
+
> ⚠️ **强制执行**:此步骤必须在代码生成(Step 5)之前完成。若 `session.inputs.figma_urls` 非空,**禁止跳过此步骤直接生成代码**。
|
|
358
|
+
|
|
359
|
+
```
|
|
360
|
+
🎨 正在从 Figma 设计稿导出图片资源...
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**4.1 检查是否需要导出**
|
|
364
|
+
|
|
365
|
+
| 条件 | 处理方式 |
|
|
366
|
+
|------|---------|
|
|
367
|
+
| `session.inputs.figma_urls` 非空且 Figma 数据已获取 | ✅ **必须执行**图片导出,然后进入 Step 5 |
|
|
368
|
+
| `session.inputs.figma_urls` 为空 | ⏭️ 跳过此步骤,直接进入 Step 5 |
|
|
369
|
+
|
|
370
|
+
**4.2 识别图片节点**
|
|
371
|
+
|
|
372
|
+
从已获取的 Figma 设计稿数据(session 目录下的 `figma-exports/design.json`)中识别所有包含图片资源的节点:
|
|
373
|
+
- 带有 `imageRef` 的 RECTANGLE 填充(应用图标、banner 图、背景图等)
|
|
374
|
+
- INSTANCE 类型的图标组件(如 app 图标、功能图标、箭头图标)
|
|
375
|
+
- 带有图片填充的 ELLIPSE 节点(圆形图标)
|
|
376
|
+
- 其他包含 `type: "IMAGE"` 填充的节点
|
|
377
|
+
- VECTOR/BOOLEAN_OPERATION 类型的图标节点(如返回箭头、功能图标)
|
|
378
|
+
|
|
379
|
+
**4.3 使用 Figma MCP 导出图片**
|
|
380
|
+
|
|
381
|
+
调用 `mcp_figma_export_image` 导出识别到的图片节点:
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
// 导出图片节点为 PNG,scale=2 保证清晰度
|
|
385
|
+
mcp_figma_export_image({
|
|
386
|
+
file_key: fileKey,
|
|
387
|
+
node_ids: nodeIds, // 逗号分隔的节点 ID 列表
|
|
388
|
+
format: 'png',
|
|
389
|
+
scale: 2
|
|
390
|
+
})
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**4.4 下载图片到项目目录**
|
|
394
|
+
|
|
395
|
+
将导出的图片 URL 下载到项目的 `src/common/images/` 目录:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
mkdir -p ${projectPath}/src/common/images/
|
|
399
|
+
curl -sL "{image_url}" -o "${projectPath}/src/common/images/{image_name}.png"
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
图片命名规则(根据 Figma 节点名称和语义):
|
|
403
|
+
- 应用图标 → `icon_{appname}.png`
|
|
404
|
+
- 功能图标 → `icon_{function}.png`(如 `icon_back.png`、`icon_lock.png`)
|
|
405
|
+
- 背景图 → `bg_{scene}.png`(如 `bg_parked.png`、`bg_charging.png`)
|
|
406
|
+
- Banner/卡片 → `banner_{name}.png`
|
|
407
|
+
|
|
408
|
+
**4.5 输出导出结果**
|
|
409
|
+
|
|
410
|
+
```
|
|
411
|
+
✅ Figma 图片资源导出完成
|
|
412
|
+
📂 保存目录: {projectPath}/src/common/images/
|
|
413
|
+
🖼️ 导出图片: {count} 张
|
|
414
|
+
- {image_1_name}.png ({size})
|
|
415
|
+
- {image_2_name}.png ({size})
|
|
416
|
+
...
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
> ⚠️ **导出完成后才能进入 Step 5 代码生成**。代码中引用的图片路径必须与此步骤导出的文件名一致。
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
### Step 5: Agent 执行(代码生成)
|
|
423
|
+
|
|
424
|
+
> ⚠️ **前置条件**:若 Figma 数据可用,Step 4 的图片导出必须已完成。代码中**必须引用 Step 4 导出的真实图片路径**,**禁止使用占位符路径**。
|
|
425
|
+
|
|
426
|
+
在项目工程目录中编写 Vela 快应用代码。
|
|
427
|
+
|
|
428
|
+
```
|
|
429
|
+
🤖 正在执行编码 Agent...
|
|
430
|
+
📂 工作目录: {project_path}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**5.1 执行 Coding Agent**
|
|
434
|
+
|
|
435
|
+
Agent 必须:
|
|
436
|
+
|
|
437
|
+
- **直接在项目工程目录中创建/修改文件**,路径基于 `session.inputs.project_path`
|
|
438
|
+
- 严格按照技术方案(完整模式)或轻量技术规划(快速模式)组织代码
|
|
439
|
+
- 若为已有项目增量开发,仅修改/新增标注的文件,不破坏已有代码
|
|
440
|
+
- **代码中引用的所有图片路径必须指向 `src/common/images/` 下 Step 4 导出的真实文件**
|
|
441
|
+
|
|
442
|
+
**5.2 代码写入路径规则**
|
|
443
|
+
|
|
444
|
+
```javascript
|
|
445
|
+
const projectPath = session.inputs.project_path
|
|
446
|
+
|
|
447
|
+
// ✅ 正确:写入项目工程目录
|
|
448
|
+
saveFile(`${projectPath}/src/manifest.json`, manifestContent)
|
|
449
|
+
saveFile(`${projectPath}/src/app.ux`, appContent)
|
|
450
|
+
saveFile(`${projectPath}/src/pages/Index/index.ux`, pageContent)
|
|
451
|
+
saveFile(`${projectPath}/src/components/MyComp/index.ux`, compContent)
|
|
452
|
+
|
|
453
|
+
// ❌ 错误:禁止写入 Session 目录
|
|
454
|
+
// saveFile(`${session_dir}/03-code/...`, content)
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
**5.3 VelaOS 兼容性要求**
|
|
458
|
+
|
|
459
|
+
- 使用 Vela 快应用支持的 JS 语法特性
|
|
460
|
+
- 使用内置组件和 API,不引入不兼容的第三方库
|
|
461
|
+
- 样式使用 CSS 子集(Flexbox 布局为主)
|
|
462
|
+
- 模板使用 Vela 快应用模板语法
|
|
463
|
+
|
|
464
|
+
**5.4 API 调用规范**
|
|
465
|
+
|
|
466
|
+
必须从知识库中查找 API 签名、参数和示例,确保调用语法符合规范。
|
|
467
|
+
|
|
468
|
+
**5.5 代码结构遵循技术方案**
|
|
469
|
+
|
|
470
|
+
严格按照 `02-tech-design.md` 中定义的文件目录结构组织。
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
### Step 6: 安装项目依赖
|
|
475
|
+
|
|
476
|
+
代码文件写入完成后,自动在项目工程目录中执行 `npm install` 安装依赖。
|
|
477
|
+
|
|
478
|
+
```
|
|
479
|
+
📦 正在安装项目依赖...
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**5.1 执行 npm install**
|
|
483
|
+
|
|
484
|
+
在项目工程目录下执行:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
cd ${projectPath} && npm install
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
| 情况 | 处理方式 |
|
|
491
|
+
|------|---------|
|
|
492
|
+
| 安装成功 | ✅ 继续 Step 6 |
|
|
493
|
+
| 安装失败 | ⚠️ 输出错误信息,提供 [r] 重试 / [s] 跳过 选项 |
|
|
494
|
+
|
|
495
|
+
安装成功后输出:
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
✅ 依赖安装完成
|
|
499
|
+
📦 已安装 {package_count} 个包
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
安装失败时输出:
|
|
503
|
+
|
|
504
|
+
```
|
|
505
|
+
⚠️ 依赖安装失败: {error_message}
|
|
506
|
+
|
|
507
|
+
❓ 请选择:
|
|
508
|
+
[r] 重试安装
|
|
509
|
+
[s] 跳过(后续手动执行 npm install)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
### Step 7: 产出物记录
|
|
515
|
+
|
|
516
|
+
代码已直接写入项目工程目录,此步骤记录产出信息到 Session。
|
|
517
|
+
|
|
518
|
+
**5.1 记录产出物路径**
|
|
519
|
+
|
|
520
|
+
```javascript
|
|
521
|
+
updateStageStatus(sessionId, 'S3', 'pending_review', session.inputs.project_path)
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
**5.2 生成变更文件清单**
|
|
525
|
+
|
|
526
|
+
记录本次创建或修改的所有文件列表,保存到 Session 目录供审核参考:
|
|
527
|
+
|
|
528
|
+
```javascript
|
|
529
|
+
saveFile(`${session_dir}/03-code-manifest.json`, JSON.stringify({
|
|
530
|
+
project_path: projectPath,
|
|
531
|
+
created_files: [...],
|
|
532
|
+
modified_files: [...],
|
|
533
|
+
timestamp: new Date().toISOString()
|
|
534
|
+
}, null, 2))
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
```
|
|
538
|
+
✅ 代码文件已写入项目工程目录
|
|
539
|
+
📂 项目目录: {project_path}
|
|
540
|
+
📝 新建文件: {created_count} 个
|
|
541
|
+
✏️ 修改文件: {modified_count} 个
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
### Step 7.5: 自动质量校验
|
|
547
|
+
|
|
548
|
+
代码写入完成后,在进入人工审核前,自动执行以下静态校验:
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
🔍 正在执行自动质量校验...
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
**5.5.1 路由一致性校验**
|
|
555
|
+
|
|
556
|
+
检查 `manifest.json` 中 `router.pages` 声明的每个页面路径,对应的页面文件是否存在:
|
|
557
|
+
|
|
558
|
+
```javascript
|
|
559
|
+
const manifest = JSON.parse(readFile(`${projectPath}/src/manifest.json`))
|
|
560
|
+
const pages = Object.keys(manifest.router.pages)
|
|
561
|
+
const missingPages = []
|
|
562
|
+
for (const route of pages) {
|
|
563
|
+
const pagePath = `${projectPath}/src/${route}`
|
|
564
|
+
if (!fs.existsSync(pagePath)) {
|
|
565
|
+
missingPages.push(route)
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
**5.5.2 图片资源引用校验**
|
|
571
|
+
|
|
572
|
+
扫描所有 `.ux` 文件中引用的图片路径(`/common/images/xxx.png`),检查对应文件是否存在于项目目录中。
|
|
573
|
+
|
|
574
|
+
**5.5.3 API 声明一致性校验**
|
|
575
|
+
|
|
576
|
+
扫描所有 `.ux` 文件中的 `import xxx from '@system.xxx'` 语句,检查对应的 API 是否已在 `manifest.json` 的 `features` 中声明。
|
|
577
|
+
|
|
578
|
+
**5.5.4 校验结果输出**
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
🔍 自动质量校验结果:
|
|
582
|
+
✅ 路由一致性: {pass_count}/{total_count} 页面通过
|
|
583
|
+
✅ 图片资源引用: {pass_count}/{total_count} 引用有效
|
|
584
|
+
✅ API 声明一致性: {pass_count}/{total_count} API 已声明
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
若存在校验失败项:
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
⚠️ 自动质量校验发现问题:
|
|
591
|
+
❌ 路由一致性: 以下页面在 manifest.json 中声明但文件不存在:
|
|
592
|
+
- {missing_route_1}
|
|
593
|
+
- {missing_route_2}
|
|
594
|
+
❌ 图片资源引用: 以下图片被引用但文件不存在:
|
|
595
|
+
- {missing_image_1}
|
|
596
|
+
❌ API 声明一致性: 以下 API 被 import 但未在 features 中声明:
|
|
597
|
+
- {missing_api_1}
|
|
598
|
+
|
|
599
|
+
🔧 正在自动修复可修复的问题...
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
对于 API 声明缺失,自动将缺失的 API 添加到 `manifest.json` 的 `features` 数组中。
|
|
603
|
+
对于路由和图片问题,记录到校验报告中供人工审核时参考。
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
### Step 8: Checkpoint 交互
|
|
608
|
+
|
|
609
|
+
> ⚠️ **关键规则:必须阻塞等待用户输入**。代码写入完成后,展示摘要和操作选项,然后**停止一切后续操作**。
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
📋 代码生成摘要:
|
|
613
|
+
• 需求名称: {requirement_name}
|
|
614
|
+
• 项目目录: {project_path}
|
|
615
|
+
• 项目类型: {全新项目/已有项目增量开发}
|
|
616
|
+
• 总文件数: {file_count} 个
|
|
617
|
+
• 页面数: {page_count} 个
|
|
618
|
+
• 自定义组件数: {component_count} 个
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
```
|
|
622
|
+
❓ 请选择操作:
|
|
623
|
+
[y] 确认 — 标记 S3 完成,工作流结束
|
|
624
|
+
[e] 编辑 — 提供修改意见,迭代修改代码
|
|
625
|
+
[n] 放弃 — 回滚代码变更,重新生成
|
|
626
|
+
|
|
627
|
+
⏳ 等待您的输入...
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
> 严格按照 `.workflow/stages/commands.md` 中定义的逻辑处理用户命令。
|
|
631
|
+
|
|
632
|
+
| 命令 | 处理逻辑 |
|
|
633
|
+
|------|---------|
|
|
634
|
+
| `y` | `updateStageStatus(sessionId, 'S3', 'completed', project_path)`,工作流完成 |
|
|
635
|
+
| `e` | 接收修改意见,在项目工程目录中迭代修改(支持多轮) |
|
|
636
|
+
| `n` | `updateStageStatus(sessionId, 'S3', 'in_progress')`,返回 Step 1 |
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## 产出物规范
|
|
641
|
+
|
|
642
|
+
| 属性 | 值 |
|
|
643
|
+
|------|-----|
|
|
644
|
+
| 写入位置 | `session.inputs.project_path`(项目工程目录) |
|
|
645
|
+
| 变更清单 | `.ai-workspace/sessions/{session_id}/03-code-manifest.json` |
|
|
646
|
+
| 格式 | UX / JS / CSS / JSON |
|
|
647
|
+
|
|
648
|
+
### 目录结构
|
|
649
|
+
|
|
650
|
+
代码直接写入项目工程目录,典型结构如下:
|
|
651
|
+
|
|
652
|
+
```
|
|
653
|
+
{project_path}/
|
|
654
|
+
├── package.json
|
|
655
|
+
├── src/
|
|
656
|
+
│ ├── manifest.json
|
|
657
|
+
│ ├── app.ux
|
|
658
|
+
│ ├── pages/
|
|
659
|
+
│ │ └── {PageName}/
|
|
660
|
+
│ │ └── index.ux
|
|
661
|
+
│ ├── components/
|
|
662
|
+
│ │ └── {ComponentName}/
|
|
663
|
+
│ │ └── index.ux
|
|
664
|
+
│ ├── utils/
|
|
665
|
+
│ │ └── *.js
|
|
666
|
+
│ └── common/
|
|
667
|
+
│ ├── images/
|
|
668
|
+
│ │ ├── logo.png # 应用 Logo(从 Figma 导出或用户上传)
|
|
669
|
+
│ │ ├── icon_{appname}.png # 从 Figma 导出的应用图标
|
|
670
|
+
│ │ ├── icon_{function}.png # 从 Figma 导出的功能图标
|
|
671
|
+
│ │ └── banner_{name}.png # 从 Figma 导出的 Banner 图
|
|
672
|
+
│ └── styles/
|
|
673
|
+
│ └── global.css
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
## 使用的脚本函数
|
|
679
|
+
|
|
680
|
+
| 函数 | 来源 | 用途 |
|
|
681
|
+
|------|------|------|
|
|
682
|
+
| `loadStageContext('S3', session)` | `context_loader.js` | 加载全部知识库和前置产出 |
|
|
683
|
+
| `injectContext(agentPrompt, context)` | `context_loader.js` | 替换 Agent 提示词占位符 |
|
|
684
|
+
| `scanProjectStructure(session)` | `context_loader.js` | 扫描项目工程目录现状 |
|
|
685
|
+
| `updateStageStatus(sessionId, stageId, status, outputPath)` | `session_manager.js` | 更新阶段状态 |
|
|
686
|
+
| `resumeSession(sessionId)` | `session_manager.js` | 恢复 Session |
|
|
687
|
+
| `extractImageNodes(figmaData, fileKey)` | `figma_export.js` | 从 Figma 节点树中提取图片节点 |
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
## 文件引用
|
|
692
|
+
|
|
693
|
+
| 文件 | 用途 |
|
|
694
|
+
|------|------|
|
|
695
|
+
| `agents/coding_agent.prompt.md` | 编码 Agent 提示词模板 |
|
|
696
|
+
| `.workflow/resource-paths.json` | 知识库路径映射 |
|
|
697
|
+
| `.workflow/stages/commands.md` | 快捷命令处理逻辑 |
|
|
698
|
+
| `.workflow/scripts/context_loader.js` | 上下文加载器 |
|
|
699
|
+
| `.workflow/scripts/session_manager.js` | Session 管理器 |
|