fe-harness 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 +55 -0
- package/agents/fe-codebase-mapper.md +945 -0
- package/agents/fe-design-scanner.md +47 -0
- package/agents/fe-executor.md +221 -0
- package/agents/fe-fix-loop.md +310 -0
- package/agents/fe-fixer.md +153 -0
- package/agents/fe-project-scanner.md +95 -0
- package/agents/fe-reviewer.md +141 -0
- package/agents/fe-verifier.md +231 -0
- package/agents/fe-wave-runner.md +477 -0
- package/bin/install.js +292 -0
- package/commands/fe/complete.md +35 -0
- package/commands/fe/execute.md +46 -0
- package/commands/fe/help.md +17 -0
- package/commands/fe/map-codebase.md +60 -0
- package/commands/fe/plan.md +36 -0
- package/commands/fe/status.md +39 -0
- package/fe-harness/bin/browser.cjs +271 -0
- package/fe-harness/bin/fe-tools.cjs +317 -0
- package/fe-harness/bin/lib/__tests__/browser.test.cjs +422 -0
- package/fe-harness/bin/lib/__tests__/config.test.cjs +93 -0
- package/fe-harness/bin/lib/__tests__/core.test.cjs +127 -0
- package/fe-harness/bin/lib/__tests__/scoring.test.cjs +130 -0
- package/fe-harness/bin/lib/__tests__/tasks.test.cjs +698 -0
- package/fe-harness/bin/lib/browser-core.cjs +365 -0
- package/fe-harness/bin/lib/config.cjs +34 -0
- package/fe-harness/bin/lib/core.cjs +135 -0
- package/fe-harness/bin/lib/logger.cjs +93 -0
- package/fe-harness/bin/lib/scoring.cjs +219 -0
- package/fe-harness/bin/lib/tasks.cjs +632 -0
- package/fe-harness/references/model-profiles.md +44 -0
- package/fe-harness/templates/config.jsonc +31 -0
- package/fe-harness/vendor/.gitkeep +0 -0
- package/fe-harness/vendor/puppeteer-core.cjs +445 -0
- package/fe-harness/workflows/complete.md +143 -0
- package/fe-harness/workflows/execute.md +227 -0
- package/fe-harness/workflows/help.md +89 -0
- package/fe-harness/workflows/map-codebase.md +331 -0
- package/fe-harness/workflows/plan.md +244 -0
- package/package.json +35 -0
- package/scripts/bundle-puppeteer.js +38 -0
package/bin/install.js
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
// ─── 配置 ────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
const CONFIG_DIR = '.claude';
|
|
10
|
+
const DIRS = {
|
|
11
|
+
commands: 'commands/fe',
|
|
12
|
+
agents: 'agents',
|
|
13
|
+
runtime: 'fe-harness',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// ─── 工具函数 ───────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
function logOk(msg) { console.log(` ✓ ${msg}`); }
|
|
19
|
+
function logErr(msg) { console.error(` ✗ ${msg}`); }
|
|
20
|
+
|
|
21
|
+
function ensureDir(dirPath) {
|
|
22
|
+
if (!fs.existsSync(dirPath)) {
|
|
23
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function copyDirRecursive(src, dest, pathReplace) {
|
|
28
|
+
ensureDir(dest);
|
|
29
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
30
|
+
let count = 0;
|
|
31
|
+
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
const srcPath = path.join(src, entry.name);
|
|
34
|
+
const destPath = path.join(dest, entry.name);
|
|
35
|
+
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
count += copyDirRecursive(srcPath, destPath, pathReplace);
|
|
38
|
+
} else {
|
|
39
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
40
|
+
|
|
41
|
+
// 替换 .md 文件中的路径引用
|
|
42
|
+
if (entry.name.endsWith('.md') && pathReplace) {
|
|
43
|
+
content = content.replace(/~\/\.claude\/fe-harness\//g, pathReplace);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fs.writeFileSync(destPath, content, 'utf8');
|
|
47
|
+
|
|
48
|
+
// 保留 .cjs 文件的可执行权限
|
|
49
|
+
if (entry.name.endsWith('.cjs')) {
|
|
50
|
+
fs.chmodSync(destPath, 0o755);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
count++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return count;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ─── 安装 ───────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
function install() {
|
|
63
|
+
const args = process.argv.slice(2);
|
|
64
|
+
const isLocal = args.includes('--local') || args.includes('-l');
|
|
65
|
+
const isHelp = args.includes('--help') || args.includes('-h');
|
|
66
|
+
const isUninstall = args.includes('--uninstall');
|
|
67
|
+
const isInit = args.includes('init');
|
|
68
|
+
|
|
69
|
+
if (isHelp) {
|
|
70
|
+
console.log(`
|
|
71
|
+
fe-harness — Figma 设计稿转代码工具(适用于 Claude Code)
|
|
72
|
+
|
|
73
|
+
用法:
|
|
74
|
+
npx fe-harness 全局安装到 ~/.claude/
|
|
75
|
+
npx fe-harness --local 本地安装到 ./.claude/
|
|
76
|
+
npx fe-harness init 在当前目录初始化项目配置
|
|
77
|
+
npx fe-harness --uninstall [--local] 卸载已安装的文件
|
|
78
|
+
|
|
79
|
+
安装后,可在 Claude Code 中使用以下命令:
|
|
80
|
+
/fe:plan 根据 Figma URL 创建任务计划
|
|
81
|
+
/fe:execute 使用子代理执行所有任务
|
|
82
|
+
/fe:complete 生成完成报告并归档
|
|
83
|
+
/fe:status 查看任务状态
|
|
84
|
+
/fe:help 显示帮助信息
|
|
85
|
+
`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (isInit) {
|
|
90
|
+
return initProject();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 确定源目录(此包的安装位置)
|
|
94
|
+
const pkgRoot = path.resolve(__dirname, '..');
|
|
95
|
+
|
|
96
|
+
// 确定目标目录
|
|
97
|
+
let targetDir;
|
|
98
|
+
if (isLocal) {
|
|
99
|
+
targetDir = path.join(process.cwd(), CONFIG_DIR);
|
|
100
|
+
} else {
|
|
101
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
102
|
+
targetDir = path.join(home, CONFIG_DIR);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 计算 .md 文件中引用的路径前缀
|
|
106
|
+
let pathPrefix;
|
|
107
|
+
if (isLocal) {
|
|
108
|
+
pathPrefix = path.resolve(targetDir, 'fe-harness') + '/';
|
|
109
|
+
} else {
|
|
110
|
+
pathPrefix = '~/.claude/fe-harness/';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (isUninstall) {
|
|
114
|
+
return uninstall(targetDir);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log(`\n ⚡ fe-harness 安装器\n`);
|
|
118
|
+
console.log(` 目标目录:${targetDir}`);
|
|
119
|
+
console.log(` 模式: ${isLocal ? '本地' : '全局'}\n`);
|
|
120
|
+
|
|
121
|
+
// 0. 清理旧版安装
|
|
122
|
+
const cleanDirs = [
|
|
123
|
+
path.join(targetDir, DIRS.commands),
|
|
124
|
+
path.join(targetDir, DIRS.runtime),
|
|
125
|
+
];
|
|
126
|
+
for (const dir of cleanDirs) {
|
|
127
|
+
if (fs.existsSync(dir)) {
|
|
128
|
+
fs.rmSync(dir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const agentCleanDir = path.join(targetDir, DIRS.agents);
|
|
132
|
+
if (fs.existsSync(agentCleanDir)) {
|
|
133
|
+
for (const f of fs.readdirSync(agentCleanDir).filter(f => f.startsWith('fe-'))) {
|
|
134
|
+
fs.unlinkSync(path.join(agentCleanDir, f));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
logOk('已清理旧版安装文件');
|
|
138
|
+
|
|
139
|
+
// 1. 复制命令文件
|
|
140
|
+
const cmdSrc = path.join(pkgRoot, 'commands', 'fe');
|
|
141
|
+
const cmdDest = path.join(targetDir, DIRS.commands);
|
|
142
|
+
if (fs.existsSync(cmdSrc)) {
|
|
143
|
+
const count = copyDirRecursive(cmdSrc, cmdDest, pathPrefix);
|
|
144
|
+
logOk(`${count} 个命令文件 → ${DIRS.commands}/`);
|
|
145
|
+
} else {
|
|
146
|
+
logErr(`命令源目录未找到:${cmdSrc}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 2. 复制代理文件
|
|
150
|
+
const agentSrc = path.join(pkgRoot, 'agents');
|
|
151
|
+
const agentDest = path.join(targetDir, DIRS.agents);
|
|
152
|
+
if (fs.existsSync(agentSrc)) {
|
|
153
|
+
const count = copyDirRecursive(agentSrc, agentDest, pathPrefix);
|
|
154
|
+
logOk(`${count} 个代理文件 → ${DIRS.agents}/`);
|
|
155
|
+
} else {
|
|
156
|
+
logErr(`代理源目录未找到:${agentSrc}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 3. 复制运行时文件 (fe-harness/)
|
|
160
|
+
const rtSrc = path.join(pkgRoot, 'fe-harness');
|
|
161
|
+
const rtDest = path.join(targetDir, DIRS.runtime);
|
|
162
|
+
if (fs.existsSync(rtSrc)) {
|
|
163
|
+
const count = copyDirRecursive(rtSrc, rtDest, pathPrefix);
|
|
164
|
+
logOk(`${count} 个运行时文件 → ${DIRS.runtime}/`);
|
|
165
|
+
} else {
|
|
166
|
+
logErr(`运行时源目录未找到:${rtSrc}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 4. 写入版本文件
|
|
170
|
+
let version = 'unknown';
|
|
171
|
+
try {
|
|
172
|
+
const srcPkg = JSON.parse(fs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf8'));
|
|
173
|
+
version = srcPkg.version;
|
|
174
|
+
} catch (_) {}
|
|
175
|
+
fs.writeFileSync(path.join(targetDir, DIRS.runtime, 'VERSION'), version, 'utf8');
|
|
176
|
+
|
|
177
|
+
console.log(`\n ✅ fe-harness v${version} 安装成功!\n`);
|
|
178
|
+
|
|
179
|
+
// 本地安装:将安装目录加入 .gitignore,避免提交大量文件
|
|
180
|
+
if (isLocal) {
|
|
181
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
182
|
+
const ignoreEntries = [
|
|
183
|
+
'.claude/fe-harness/',
|
|
184
|
+
'.claude/commands/fe/',
|
|
185
|
+
'.claude/agents/fe-*',
|
|
186
|
+
];
|
|
187
|
+
const ignoreBlock = '\n# fe-harness 安装文件(由 npx fe-harness --local 生成)\n'
|
|
188
|
+
+ ignoreEntries.join('\n') + '\n';
|
|
189
|
+
|
|
190
|
+
if (fs.existsSync(gitignorePath)) {
|
|
191
|
+
const existing = fs.readFileSync(gitignorePath, 'utf8');
|
|
192
|
+
if (!existing.includes('.claude/fe-harness/')) {
|
|
193
|
+
fs.appendFileSync(gitignorePath, ignoreBlock, 'utf8');
|
|
194
|
+
logOk('已将安装目录添加到 .gitignore');
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
fs.writeFileSync(gitignorePath, ignoreBlock.trimStart(), 'utf8');
|
|
198
|
+
logOk('已创建 .gitignore 并添加安装目录规则');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
initProject();
|
|
202
|
+
} else {
|
|
203
|
+
console.log(` 后续步骤:`);
|
|
204
|
+
console.log(` 1. 进入你的项目目录`);
|
|
205
|
+
console.log(` 2. 运行:npx fe-harness init`);
|
|
206
|
+
console.log(` 3. 编辑 .fe/config.jsonc 配置 devServer 等`);
|
|
207
|
+
console.log(` 4. 使用 /fe:plan 创建任务计划\n`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ─── 初始化(项目配置)────────────────────────────
|
|
212
|
+
|
|
213
|
+
function initProject() {
|
|
214
|
+
console.log(`\n ⚡ fe-harness 项目初始化\n`);
|
|
215
|
+
|
|
216
|
+
const pkgRoot = path.resolve(__dirname, '..');
|
|
217
|
+
const feDir = path.join(process.cwd(), '.fe');
|
|
218
|
+
|
|
219
|
+
// 1. 从模板创建 .fe/config.jsonc
|
|
220
|
+
const feConfigPath = path.join(feDir, 'config.jsonc');
|
|
221
|
+
if (!fs.existsSync(feConfigPath)) {
|
|
222
|
+
const templatePath = path.join(pkgRoot, 'fe-harness', 'templates', 'config.jsonc');
|
|
223
|
+
if (fs.existsSync(templatePath)) {
|
|
224
|
+
ensureDir(feDir);
|
|
225
|
+
fs.copyFileSync(templatePath, feConfigPath);
|
|
226
|
+
logOk('已创建 .fe/config.jsonc(默认配置)');
|
|
227
|
+
} else {
|
|
228
|
+
logErr('配置模板未找到,请确认 fe-harness 已正确安装');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
logOk('.fe/config.jsonc 已存在,跳过');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// 2. 创建 .fe-runtime/context/ 目录
|
|
236
|
+
const runtimeDir = path.join(process.cwd(), '.fe-runtime');
|
|
237
|
+
ensureDir(path.join(runtimeDir, 'context'));
|
|
238
|
+
|
|
239
|
+
// 3. 将 .fe-runtime/ 添加到 .gitignore
|
|
240
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
241
|
+
const feGitignoreContent = '\n# fe-harness 运行时产物(截图、分析文件、任务状态、临时结果)\n.fe-runtime/\n';
|
|
242
|
+
if (fs.existsSync(gitignorePath)) {
|
|
243
|
+
const existing = fs.readFileSync(gitignorePath, 'utf8');
|
|
244
|
+
if (!existing.includes('.fe-runtime')) {
|
|
245
|
+
fs.appendFileSync(gitignorePath, feGitignoreContent, 'utf8');
|
|
246
|
+
logOk('已将 .fe-runtime/ 添加到 .gitignore');
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
fs.writeFileSync(gitignorePath, feGitignoreContent.trimStart(), 'utf8');
|
|
250
|
+
logOk('已创建 .gitignore 并添加 .fe-runtime/ 规则');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log(`\n ✅ 项目初始化完成!\n`);
|
|
254
|
+
console.log(` 后续步骤:`);
|
|
255
|
+
console.log(` 1. 编辑 .fe/config.jsonc 配置 devServer 等`);
|
|
256
|
+
console.log(` 2. 使用 /fe:plan 创建任务计划`);
|
|
257
|
+
console.log(` 3. 使用 /fe:execute 开始执行\n`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ─── 卸载 ─────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
function uninstall(targetDir) {
|
|
263
|
+
console.log(`\n 🗑️ 正在从 ${targetDir} 卸载 fe-harness\n`);
|
|
264
|
+
|
|
265
|
+
const dirsToRemove = [
|
|
266
|
+
path.join(targetDir, DIRS.commands),
|
|
267
|
+
path.join(targetDir, DIRS.runtime),
|
|
268
|
+
];
|
|
269
|
+
|
|
270
|
+
// 删除 fe-* 代理文件(不删除整个 agents 目录)
|
|
271
|
+
const agentDir = path.join(targetDir, DIRS.agents);
|
|
272
|
+
if (fs.existsSync(agentDir)) {
|
|
273
|
+
const agents = fs.readdirSync(agentDir).filter(f => f.startsWith('fe-'));
|
|
274
|
+
for (const a of agents) {
|
|
275
|
+
fs.unlinkSync(path.join(agentDir, a));
|
|
276
|
+
logOk(`已删除代理:${a}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for (const dir of dirsToRemove) {
|
|
281
|
+
if (fs.existsSync(dir)) {
|
|
282
|
+
fs.rmSync(dir, { recursive: true });
|
|
283
|
+
logOk(`已删除:${path.relative(targetDir, dir)}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
console.log(`\n ✅ fe-harness 已卸载。\n`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// ─── 主入口 ──────────────────────────────────────────
|
|
291
|
+
|
|
292
|
+
install();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:complete
|
|
3
|
+
description: 完成所有任务后生成摘要报告、归档运行时产物并清理环境
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Bash
|
|
7
|
+
- Write
|
|
8
|
+
---
|
|
9
|
+
<objective>
|
|
10
|
+
在所有任务执行完毕后,汇总执行结果、生成完成报告、归档运行时产物并清理临时文件。
|
|
11
|
+
|
|
12
|
+
这是 fe-harness 工作流的最后一步:plan → execute → complete。
|
|
13
|
+
</objective>
|
|
14
|
+
|
|
15
|
+
<execution_context>
|
|
16
|
+
@~/.claude/fe-harness/workflows/complete.md
|
|
17
|
+
</execution_context>
|
|
18
|
+
|
|
19
|
+
<context>
|
|
20
|
+
$ARGUMENTS
|
|
21
|
+
</context>
|
|
22
|
+
|
|
23
|
+
<when_to_use>
|
|
24
|
+
- 当 `/fe:execute` 执行完毕后,使用此命令收尾
|
|
25
|
+
- 当想查看任务执行的最终摘要报告时
|
|
26
|
+
- 当需要归档本轮任务数据、为下一轮做准备时
|
|
27
|
+
|
|
28
|
+
不要在以下情况使用:
|
|
29
|
+
- 还有 pending 或 in_progress 的任务(会提示先完成执行)
|
|
30
|
+
- 还没有 tasks.json(会提示先运行 /fe:plan)
|
|
31
|
+
</when_to_use>
|
|
32
|
+
|
|
33
|
+
<process>
|
|
34
|
+
严格按照 @~/.claude/fe-harness/workflows/complete.md 中的流程执行。
|
|
35
|
+
</process>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:execute
|
|
3
|
+
description: 两级编排执行所有待处理任务(顶层 wave 调度 → wave-runner 内部闭环)
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Edit
|
|
8
|
+
- Bash
|
|
9
|
+
- Grep
|
|
10
|
+
- Glob
|
|
11
|
+
- Agent
|
|
12
|
+
- mcp__plugin_figma_figma__get_design_context
|
|
13
|
+
- mcp__plugin_figma_figma__get_screenshot
|
|
14
|
+
---
|
|
15
|
+
<objective>
|
|
16
|
+
两级编排架构。顶层编排器按 Wave 串行调度,每个 Wave 委托给 fe-wave-runner 子代理在独立上下文窗口中完成:
|
|
17
|
+
|
|
18
|
+
1. 并行调用 fe-executor(isolation=worktree)实现
|
|
19
|
+
2. 合并 worktree + backpressure 检查
|
|
20
|
+
3. 并行调用 fe-verifier/fe-reviewer 验证
|
|
21
|
+
4. 串行修复循环(fe-fixer → 重新验证)
|
|
22
|
+
5. 通过后 git commit,失败后传播到下游 Wave
|
|
23
|
+
|
|
24
|
+
顶层编排器只做 wave 级调度,上下文消耗 O(waves)。
|
|
25
|
+
</objective>
|
|
26
|
+
|
|
27
|
+
<execution_context>
|
|
28
|
+
@~/.claude/fe-harness/workflows/execute.md
|
|
29
|
+
</execution_context>
|
|
30
|
+
|
|
31
|
+
<process>
|
|
32
|
+
严格按照 @~/.claude/fe-harness/workflows/execute.md 中的编排流程执行。
|
|
33
|
+
|
|
34
|
+
关键要求:
|
|
35
|
+
1. 使用 Agent 工具调用 fe-wave-runner(每个 wave 一次调用)
|
|
36
|
+
2. fe-wave-runner 内部自行调用 fe-executor/fe-verifier/fe-reviewer/fe-fixer
|
|
37
|
+
3. 不使用 isolation="worktree" 调用 wave-runner(它需要主仓库 git 访问)
|
|
38
|
+
4. 不使用 run_in_background 调用 wave-runner(wave 间必须串行)
|
|
39
|
+
5. 每个 wave 开始前从 tasks waves 刷新状态
|
|
40
|
+
6. 读取 wave-result JSON 获取结果
|
|
41
|
+
|
|
42
|
+
上下文管理:
|
|
43
|
+
- 不复述 Agent 结果
|
|
44
|
+
- 每个 wave 只输出一行摘要
|
|
45
|
+
- 所有实现/验证/修复细节在 wave-runner 内部完成
|
|
46
|
+
</process>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:help
|
|
3
|
+
description: 显示 fe-harness 可用命令和使用指南
|
|
4
|
+
---
|
|
5
|
+
<objective>
|
|
6
|
+
显示完整的 fe-harness 命令参考。
|
|
7
|
+
|
|
8
|
+
只输出参考内容,不做项目分析、git 状态检查或其他额外操作。
|
|
9
|
+
</objective>
|
|
10
|
+
|
|
11
|
+
<execution_context>
|
|
12
|
+
@~/.claude/fe-harness/workflows/help.md
|
|
13
|
+
</execution_context>
|
|
14
|
+
|
|
15
|
+
<process>
|
|
16
|
+
直接输出 @~/.claude/fe-harness/workflows/help.md 中的帮助文档内容,不做修改或补充。
|
|
17
|
+
</process>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:map-codebase
|
|
3
|
+
description: 分析前端代码库,使用并行映射代理生成 .fe/codebase/ 下的结构化文档
|
|
4
|
+
argument-hint: "[可选: 聚焦区域, 如 'components' 或 'routing']"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
- Write
|
|
11
|
+
- Agent
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<objective>
|
|
15
|
+
使用并行 fe-codebase-mapper 代理分析现有前端代码库,生成结构化的前端代码库文档。
|
|
16
|
+
|
|
17
|
+
每个映射代理探索一个聚焦领域,并**直接写入文档**到 `.fe/codebase/`。编排器仅接收确认信息,保持上下文占用最小。
|
|
18
|
+
|
|
19
|
+
输出: .fe/codebase/ 目录,包含 7 个前端专属的结构化文档。
|
|
20
|
+
</objective>
|
|
21
|
+
|
|
22
|
+
<execution_context>
|
|
23
|
+
@~/.claude/fe-harness/workflows/map-codebase.md
|
|
24
|
+
</execution_context>
|
|
25
|
+
|
|
26
|
+
<context>
|
|
27
|
+
聚焦区域: $ARGUMENTS (可选 - 如果提供,告知代理聚焦特定子系统)
|
|
28
|
+
|
|
29
|
+
**如果已有配置则加载:**
|
|
30
|
+
检查 .fe/config.jsonc - 如果项目已初始化则加载上下文
|
|
31
|
+
|
|
32
|
+
**此命令可在以下时机运行:**
|
|
33
|
+
- /fe:plan 之前 (基于代码库理解生成更好的计划)
|
|
34
|
+
- 任何时候刷新代码库理解
|
|
35
|
+
</context>
|
|
36
|
+
|
|
37
|
+
<when_to_use>
|
|
38
|
+
**使用 map-codebase:**
|
|
39
|
+
- 已有前端项目,需要在规划前理解代码库
|
|
40
|
+
- 代码发生重大变更后刷新代码库映射
|
|
41
|
+
- 接手不熟悉的前端代码库
|
|
42
|
+
- 大型重构前理解当前状态
|
|
43
|
+
- 团队新成员快速了解项目
|
|
44
|
+
|
|
45
|
+
**跳过 map-codebase:**
|
|
46
|
+
- 全新项目,还没有代码
|
|
47
|
+
- 极简代码库 (<5 个文件)
|
|
48
|
+
</when_to_use>
|
|
49
|
+
|
|
50
|
+
<process>
|
|
51
|
+
严格按照 @~/.claude/fe-harness/workflows/map-codebase.md 中的编排流程执行。
|
|
52
|
+
</process>
|
|
53
|
+
|
|
54
|
+
<success_criteria>
|
|
55
|
+
- [ ] .fe/codebase/ 目录已创建
|
|
56
|
+
- [ ] 所有 7 个代码库文档由映射代理写入
|
|
57
|
+
- [ ] 文档遵循模板结构
|
|
58
|
+
- [ ] 并行代理无错误完成
|
|
59
|
+
- [ ] 用户知晓下一步操作
|
|
60
|
+
</success_criteria>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:plan
|
|
3
|
+
description: 解析功能列表和 Figma URL,智能分析后创建优化的任务列表
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Bash
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
- AskUserQuestion
|
|
11
|
+
- mcp__plugin_figma_figma__get_screenshot
|
|
12
|
+
- mcp__plugin_figma_figma__get_design_context
|
|
13
|
+
---
|
|
14
|
+
<objective>
|
|
15
|
+
解析用户提供的功能列表和 Figma 设计稿 URL,通过智能分析创建优化的任务计划。
|
|
16
|
+
|
|
17
|
+
输入格式示例:
|
|
18
|
+
```
|
|
19
|
+
功能1: 用户头像组件, figma设计稿: https://figma.com/design/xxx?node-id=1-2
|
|
20
|
+
功能2: 登录页面, figma设计稿: https://figma.com/design/xxx?node-id=3-4
|
|
21
|
+
功能3: 用户登录 API 对接
|
|
22
|
+
```
|
|
23
|
+
</objective>
|
|
24
|
+
|
|
25
|
+
<execution_context>
|
|
26
|
+
@~/.claude/fe-harness/workflows/plan.md
|
|
27
|
+
</execution_context>
|
|
28
|
+
|
|
29
|
+
<context>
|
|
30
|
+
$ARGUMENTS
|
|
31
|
+
</context>
|
|
32
|
+
|
|
33
|
+
<process>
|
|
34
|
+
按照 @~/.claude/fe-harness/workflows/plan.md 中的流程端到端执行任务规划。
|
|
35
|
+
使用 $ARGUMENTS 中的功能列表作为输入。
|
|
36
|
+
</process>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fe:status
|
|
3
|
+
description: 查看任务状态概览
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Bash
|
|
7
|
+
---
|
|
8
|
+
<objective>
|
|
9
|
+
显示当前任务的状态概览,包括任务总数、各状态分布、每个任务的详细信息。
|
|
10
|
+
</objective>
|
|
11
|
+
|
|
12
|
+
<process>
|
|
13
|
+
1. 调用状态工具获取概览:
|
|
14
|
+
```bash
|
|
15
|
+
node ~/.claude/fe-harness/bin/fe-tools.cjs tasks status
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. 将返回的 JSON 格式化为可读的表格输出:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
## Figma Implementation Status
|
|
22
|
+
|
|
23
|
+
| ID | 名称 | 类型 | 状态 | 重试次数 | 验证通过 |
|
|
24
|
+
|----|------|------|------|----------|----------|
|
|
25
|
+
| 1 | xxx | 设计 | done | 0 | ✓ |
|
|
26
|
+
| 2 | yyy | 逻辑 | pending | 0 | - |
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
### 统计
|
|
30
|
+
- 总计: N 个任务
|
|
31
|
+
- ✅ 完成: N
|
|
32
|
+
- ⏳ 进行中: N
|
|
33
|
+
- 📋 待处理: N
|
|
34
|
+
- ❌ 失败: N
|
|
35
|
+
- ⏭️ 跳过: N
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. 如果没有 tasks.json,提示用户先运行 `/fe:plan`。
|
|
39
|
+
</process>
|