@vima_tech/flywheel 1.0.0 → 1.1.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/bin/flywheel.js +211 -33
- package/package.json +8 -1
- package/scripts/available.json +10 -0
- package/scripts/flywheel-install.sh +21 -1
- package/.claude/commands/flywheel.md +0 -42
- package/.claude/commands/skill.md +0 -36
- package/.claude/settings.local.json +0 -13
- package/.distill-needed/.gitkeep +0 -0
- package/CLAUDE.md +0 -178
- package/agents.md +0 -59
- package/docs/Flywheel_Poster.html +0 -1059
- package/docs/Flywheel_Poster.png +0 -0
- package/episodic-logs/.gitkeep +0 -0
- package/install.sh +0 -194
- package/memory/industry/.gitkeep +0 -0
- package/projects/.gitkeep +0 -0
- package/skills/req-mining/artifacts.md +0 -185
- package/skills/req-mining/domain.md +0 -243
- package/skills/req-mining/feedback-questions.sh +0 -9
- package/skills/req-mining/industry/erp.md +0 -108
- package/skills/req-mining/industry/retail.md +0 -24
- package/skills/req-mining/memory/failure-patterns.md +0 -84
- package/skills/req-mining/skill.yaml +0 -41
package/bin/flywheel.js
CHANGED
|
@@ -1,39 +1,200 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
* Flywheel CLI
|
|
4
|
-
* Global entry point for @renmengkai/flywheel npm package
|
|
5
|
-
*/
|
|
6
|
-
const { spawn } = require('child_process');
|
|
2
|
+
const { spawn, execSync } = require('child_process');
|
|
7
3
|
const path = require('path');
|
|
8
4
|
const fs = require('fs');
|
|
5
|
+
const readline = require('readline');
|
|
9
6
|
|
|
10
|
-
const REPO_DIR = process.env.FLYWHEEL_DIR ||
|
|
7
|
+
const REPO_DIR = process.env.FLYWHEEL_DIR || path.dirname(path.dirname(__dirname));
|
|
8
|
+
const NPM_PKG = '@vima_tech/flywheel';
|
|
11
9
|
|
|
12
10
|
function resolveScript(name) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
return scripts[name];
|
|
11
|
+
return path.join(__dirname, '../scripts/' + name + '.sh');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function resolveKernelFile(name) {
|
|
15
|
+
return path.join(__dirname, '../' + name);
|
|
20
16
|
}
|
|
21
17
|
|
|
22
18
|
function runScript(scriptPath, args) {
|
|
23
19
|
return new Promise((resolve, reject) => {
|
|
24
20
|
const child = spawn('bash', [scriptPath, ...args], {
|
|
25
|
-
cwd:
|
|
21
|
+
cwd: process.cwd(),
|
|
26
22
|
stdio: 'inherit',
|
|
27
|
-
env: { ...process.env, FLYWHEEL_DIR:
|
|
23
|
+
env: { ...process.env, FLYWHEEL_DIR: process.cwd() },
|
|
28
24
|
});
|
|
29
25
|
child.on('exit', (code) => {
|
|
30
26
|
if (code === 0) resolve(0);
|
|
31
|
-
else reject(new Error(
|
|
27
|
+
else reject(new Error('exit code ' + code));
|
|
32
28
|
});
|
|
33
29
|
});
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
|
|
32
|
+
function downloadFile(url, destPath) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const file = fs.createWriteStream(destPath);
|
|
35
|
+
spawn('curl', ['-fsSL', url, '-o', destPath], { stdio: 'ignore' })
|
|
36
|
+
.on('exit', (code) => {
|
|
37
|
+
if (code === 0) resolve(0);
|
|
38
|
+
else reject(new Error('curl failed'));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function initKernel(dir, skill) {
|
|
44
|
+
const kernelFiles = [
|
|
45
|
+
'CLAUDE.md', '.gitignore',
|
|
46
|
+
'.claude/commands/flywheel.md', '.claude/commands/skill.md',
|
|
47
|
+
'scripts/auto-distill.sh', 'scripts/feedback-hook.sh',
|
|
48
|
+
'scripts/bridge-to-coder.sh', 'scripts/flywheel-install.sh',
|
|
49
|
+
'templates/state.json',
|
|
50
|
+
'skills/_kernel/distillation.md',
|
|
51
|
+
'skills/_template/skill.yaml', 'skills/_template/domain.md',
|
|
52
|
+
'skills/_template/feedback-questions.sh',
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const optionalFiles = [
|
|
56
|
+
'skills/_template/artifacts.md',
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const baseUrl = 'https://raw.githubusercontent.com/renmengkai/flywheel/main';
|
|
60
|
+
const skillFiles = skill ? [
|
|
61
|
+
'skills/' + skill + '/skill.yaml',
|
|
62
|
+
'skills/' + skill + '/domain.md',
|
|
63
|
+
'skills/' + skill + '/feedback-questions.sh',
|
|
64
|
+
] : [];
|
|
65
|
+
|
|
66
|
+
for (const f of kernelFiles) {
|
|
67
|
+
const dest = path.join(dir, f);
|
|
68
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
69
|
+
const srcPath = resolveKernelFile(f);
|
|
70
|
+
if (fs.existsSync(srcPath)) {
|
|
71
|
+
fs.copyFileSync(srcPath, dest);
|
|
72
|
+
} else {
|
|
73
|
+
await downloadFile(baseUrl + '/' + f, dest);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (const f of optionalFiles) {
|
|
78
|
+
const dest = path.join(dir, f);
|
|
79
|
+
const srcPath = resolveKernelFile(f);
|
|
80
|
+
if (fs.existsSync(srcPath)) fs.copyFileSync(srcPath, dest);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (skill) {
|
|
84
|
+
for (const f of skillFiles) {
|
|
85
|
+
const dest = path.join(dir, f);
|
|
86
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
87
|
+
const srcPath = resolveKernelFile(f);
|
|
88
|
+
if (fs.existsSync(srcPath)) {
|
|
89
|
+
fs.copyFileSync(srcPath, dest);
|
|
90
|
+
} else {
|
|
91
|
+
await downloadFile(baseUrl + '/' + f, dest);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fs.mkdirSync(path.join(dir, '.distill-needed'), { recursive: true });
|
|
97
|
+
fs.mkdirSync(path.join(dir, 'episodic-logs'), { recursive: true });
|
|
98
|
+
fs.mkdirSync(path.join(dir, 'projects'), { recursive: true });
|
|
99
|
+
fs.mkdirSync(path.join(dir, 'memory'), { recursive: true });
|
|
100
|
+
fs.writeFileSync(path.join(dir, '.distill-needed/.gitkeep'), '');
|
|
101
|
+
fs.writeFileSync(path.join(dir, 'episodic-logs/.gitkeep'), '');
|
|
102
|
+
fs.writeFileSync(path.join(dir, 'projects/.gitkeep'), '');
|
|
103
|
+
fs.writeFileSync(path.join(dir, 'memory/.gitkeep'), '');
|
|
104
|
+
|
|
105
|
+
if (!fs.existsSync(path.join(dir, '.gitignore'))) {
|
|
106
|
+
fs.writeFileSync(path.join(dir, '.gitignore'), `# flywheel-managed\nprojects/*/\nepisodic-logs/\n.distill-needed/*\n!.distill-needed/.gitkeep\nmemory/.gitkeep\n*.log\n`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
execSync('chmod +x ' + path.join(dir, 'scripts/*.sh'), { stdio: 'ignore', shell: true });
|
|
111
|
+
} catch (e) {}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function cmdNew(args) {
|
|
115
|
+
if (args.length < 1) {
|
|
116
|
+
console.error('用法: flywheel new <project-name> [--agent claude|opencode] [--skill req-mining]');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const projectName = args[0];
|
|
121
|
+
const dirName = projectName;
|
|
122
|
+
const targetDir = path.join(process.cwd(), dirName);
|
|
123
|
+
|
|
124
|
+
if (fs.existsSync(targetDir)) {
|
|
125
|
+
console.error('❌ 目录已存在: ' + targetDir);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let agent = 'claude';
|
|
130
|
+
let skill = 'req-mining';
|
|
131
|
+
|
|
132
|
+
for (let i = 1; i < args.length; i++) {
|
|
133
|
+
if (args[i] === '--agent' && args[i + 1]) {
|
|
134
|
+
agent = args[i + 1];
|
|
135
|
+
i++;
|
|
136
|
+
} else if (args[i] === '--skill' && args[i + 1]) {
|
|
137
|
+
skill = args[i + 1];
|
|
138
|
+
i++;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log('');
|
|
143
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
144
|
+
console.log(' Flywheel 初始化');
|
|
145
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
146
|
+
console.log(' 项目: ' + projectName);
|
|
147
|
+
console.log(' 目录: ' + targetDir);
|
|
148
|
+
console.log(' Agent: ' + agent);
|
|
149
|
+
console.log(' Skill: ' + skill);
|
|
150
|
+
console.log('');
|
|
151
|
+
|
|
152
|
+
console.log('📦 初始化内核文件...');
|
|
153
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
154
|
+
await initKernel(targetDir, skill);
|
|
155
|
+
console.log(' ✓ 内核安装完成');
|
|
156
|
+
|
|
157
|
+
console.log('');
|
|
158
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
159
|
+
console.log(' ✅ 项目创建完成!');
|
|
160
|
+
console.log('');
|
|
161
|
+
console.log(' 进入目录并启动 ' + agent + ':');
|
|
162
|
+
console.log(' cd ' + dirName + ' && flywheel start');
|
|
163
|
+
console.log('');
|
|
164
|
+
console.log(' 或手动启动:cd ' + dirName + ' && claude');
|
|
165
|
+
console.log(' 然后输入 /sfw 开始飞轮工作');
|
|
166
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function cmdStart() {
|
|
170
|
+
const agent = detectAgent();
|
|
171
|
+
if (!agent) {
|
|
172
|
+
console.error('❌ 未检测到 Claude Code 或 OpenCode');
|
|
173
|
+
console.error('请先安装 Claude Code 或 OpenCode');
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
console.log('🚀 启动 ' + agent + '...');
|
|
178
|
+
spawn(agent, [], {
|
|
179
|
+
cwd: process.cwd(),
|
|
180
|
+
stdio: 'inherit',
|
|
181
|
+
shell: true,
|
|
182
|
+
env: { ...process.env, FLYWHEEL_DIR: process.cwd() },
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function detectAgent() {
|
|
187
|
+
const agents = ['claude', 'claude-code', 'opencode', 'codex'];
|
|
188
|
+
for (const a of agents) {
|
|
189
|
+
try {
|
|
190
|
+
execSync('which ' + a, { stdio: 'ignore' });
|
|
191
|
+
return a;
|
|
192
|
+
} catch (e) {}
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const [, , command, ...args] = process.argv;
|
|
37
198
|
|
|
38
199
|
if (!command) {
|
|
39
200
|
console.log(`
|
|
@@ -42,22 +203,29 @@ Flywheel CLI — 自成长 AI Agent 飞轮框架
|
|
|
42
203
|
用法: flywheel <command> [args]
|
|
43
204
|
|
|
44
205
|
可用命令:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
206
|
+
new <name> 创建新项目
|
|
207
|
+
start 启动 Claude Code 或 OpenCode
|
|
208
|
+
version 显示版本号
|
|
209
|
+
update 更新 flywheel 到最新版本
|
|
210
|
+
install <skill> 安装 skill 包
|
|
211
|
+
list 列出已安装的 skill
|
|
212
|
+
update [skill] 更新 skill 包
|
|
213
|
+
distill [project] 手动触发蒸馏
|
|
214
|
+
help 显示帮助
|
|
50
215
|
|
|
51
216
|
示例:
|
|
217
|
+
flywheel new my-project
|
|
218
|
+
cd my-project && flywheel start
|
|
52
219
|
flywheel install req-mining
|
|
53
|
-
flywheel list
|
|
54
|
-
flywheel update
|
|
55
|
-
flywheel distill proj_20260515_01
|
|
56
220
|
`);
|
|
57
221
|
process.exit(0);
|
|
58
222
|
}
|
|
59
223
|
|
|
60
224
|
switch (command) {
|
|
225
|
+
case '--version':
|
|
226
|
+
case 'version':
|
|
227
|
+
console.log('@vima_tech/flywheel v1.1.0');
|
|
228
|
+
break;
|
|
61
229
|
case 'help':
|
|
62
230
|
console.log(`
|
|
63
231
|
Flywheel CLI — 自成长 AI Agent 飞轮框架
|
|
@@ -65,16 +233,19 @@ Flywheel CLI — 自成长 AI Agent 飞轮框架
|
|
|
65
233
|
用法: flywheel <command> [args]
|
|
66
234
|
|
|
67
235
|
可用命令:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
236
|
+
new <name> 创建新项目
|
|
237
|
+
start 启动 Claude Code 或 OpenCode
|
|
238
|
+
version 显示版本号
|
|
239
|
+
update 更新 flywheel 到最新版本
|
|
240
|
+
install <skill> 安装 skill 包
|
|
241
|
+
list 列出已安装的 skill
|
|
242
|
+
update [skill] 更新 skill 包
|
|
243
|
+
distill [project] 手动触发蒸馏
|
|
72
244
|
|
|
73
245
|
示例:
|
|
246
|
+
flywheel new my-project --agent claude --skill req-mining
|
|
247
|
+
cd my-project && flywheel start
|
|
74
248
|
flywheel install req-mining
|
|
75
|
-
flywheel list
|
|
76
|
-
flywheel update
|
|
77
|
-
flywheel distill proj_20260515_01
|
|
78
249
|
`);
|
|
79
250
|
break;
|
|
80
251
|
case 'install':
|
|
@@ -89,7 +260,14 @@ Flywheel CLI — 自成长 AI Agent 飞轮框架
|
|
|
89
260
|
case 'distill':
|
|
90
261
|
runScript(resolveScript('auto-distill'), args).catch((e) => process.exit(1));
|
|
91
262
|
break;
|
|
263
|
+
case 'update':
|
|
264
|
+
spawn('npm', ['install', '-g', '@vima_tech/flywheel'], {
|
|
265
|
+
cwd: process.cwd(),
|
|
266
|
+
stdio: 'inherit',
|
|
267
|
+
}).on('exit', (code) => process.exit(code));
|
|
268
|
+
break;
|
|
92
269
|
default:
|
|
93
|
-
console.error(
|
|
270
|
+
console.error('未知命令: ' + command);
|
|
271
|
+
console.error('运行 flywheel help 查看用法');
|
|
94
272
|
process.exit(1);
|
|
95
273
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vima_tech/flywheel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "自成长 AI Agent 飞轮框架 — 让任何需要积累迭代的 AI 工作流都能自我进化",
|
|
5
5
|
"main": "bin/flywheel.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"flywheel": "./bin/flywheel.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"scripts/",
|
|
12
|
+
"templates/",
|
|
13
|
+
"skills/_kernel/",
|
|
14
|
+
"skills/_template/"
|
|
15
|
+
],
|
|
9
16
|
"scripts": {
|
|
10
17
|
"postinstall": "chmod +x bin/flywheel.js"
|
|
11
18
|
},
|
|
@@ -37,7 +37,27 @@ cmd_list() {
|
|
|
37
37
|
done
|
|
38
38
|
$found || echo " (未安装任何 skill)"
|
|
39
39
|
echo ""
|
|
40
|
-
echo "安装新 skill
|
|
40
|
+
echo "安装新 skill:flywheel install <skill-name>"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# ── available ─────────────────────────────────────────────────
|
|
44
|
+
cmd_available() {
|
|
45
|
+
echo "━━━ 可安装 Skill 包 ━━━"
|
|
46
|
+
local available_file="$SCRIPT_DIR/available.json"
|
|
47
|
+
if [ -f "$available_file" ]; then
|
|
48
|
+
python3 - << 'PYEOF'
|
|
49
|
+
import json, sys
|
|
50
|
+
with open(sys.argv[1]) as f:
|
|
51
|
+
data = json.load(f)
|
|
52
|
+
for s in data.get('skills', []):
|
|
53
|
+
print(f" - {s['name']} v{s['version']} - {s['description']}")
|
|
54
|
+
PYEOF
|
|
55
|
+
"$available_file"
|
|
56
|
+
else
|
|
57
|
+
echo " (无可用 skill,请检查网络后重试)"
|
|
58
|
+
fi
|
|
59
|
+
echo ""
|
|
60
|
+
echo "安装 skill:flywheel install <skill-name>"
|
|
41
61
|
}
|
|
42
62
|
|
|
43
63
|
# ── add ────────────────────────────────────────────────────────
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# 启动自飞轮需求挖掘
|
|
2
|
-
|
|
3
|
-
执行以下步骤,激活飞轮模式:
|
|
4
|
-
|
|
5
|
-
## Step 0:检查待蒸馏标记
|
|
6
|
-
|
|
7
|
-
读取 `.distill-needed/` 目录。如果存在标记文件:
|
|
8
|
-
- 列出所有待蒸馏项目
|
|
9
|
-
- 询问用户是否现在处理,还是先处理新文档
|
|
10
|
-
- 若用户选择现在蒸馏:读取 `skills/core/distillation.md`,对每个标记项目执行蒸馏协议(展示预览,单次 y/n 确认),完成后删除标记文件
|
|
11
|
-
|
|
12
|
-
## Step 1:加载运行时上下文
|
|
13
|
-
|
|
14
|
-
按顺序读取:
|
|
15
|
-
1. `memory/patterns/failure-patterns.md`(常驻知识,必须)
|
|
16
|
-
2. `skills/core/auto-req.md`(Ring 1 分析协议)
|
|
17
|
-
|
|
18
|
-
## Step 2:显示飞轮状态
|
|
19
|
-
|
|
20
|
-
输出当前状态摘要:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
━━━ Req-Miner 自飞轮 | 就绪 ━━━
|
|
24
|
-
|
|
25
|
-
待蒸馏项目:{N} 个
|
|
26
|
-
活跃项目:
|
|
27
|
-
• {project_id} — 阶段:{状态} | 假设:{N}项
|
|
28
|
-
|
|
29
|
-
提供文档材料开始 Ring 1 分析:
|
|
30
|
-
• 直接粘贴文本
|
|
31
|
-
• 输入文件路径(如 /path/to/doc.pdf)
|
|
32
|
-
• 输入 URL
|
|
33
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Step 3:等待用户输入材料
|
|
37
|
-
|
|
38
|
-
用户提供材料后,执行 `skills/core/auto-req.md` 的五维度扫描流程。
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
**别名:** 用户输入 `sfw`、`start flywheel`、`开始飞轮`、`开启飞轮` 时,等同于运行本命令。
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Skill 包管理
|
|
2
|
-
|
|
3
|
-
管理当前项目中安装的 Flywheel skill 包。
|
|
4
|
-
|
|
5
|
-
## 用法
|
|
6
|
-
|
|
7
|
-
用户输入以下命令时,通过 Bash 工具执行对应操作:
|
|
8
|
-
|
|
9
|
-
### `/skill list` 或 `skill list`
|
|
10
|
-
```bash
|
|
11
|
-
./scripts/flywheel-install.sh list
|
|
12
|
-
```
|
|
13
|
-
列出所有已安装的 skill 包、版本号和描述。
|
|
14
|
-
|
|
15
|
-
### `/skill add <skill-name>` 或 `skill add <name>`
|
|
16
|
-
```bash
|
|
17
|
-
./scripts/flywheel-install.sh add <skill-name>
|
|
18
|
-
```
|
|
19
|
-
从官方注册表安装新 skill 包。
|
|
20
|
-
|
|
21
|
-
### `/skill update` 或 `skill update`
|
|
22
|
-
```bash
|
|
23
|
-
./scripts/flywheel-install.sh update
|
|
24
|
-
```
|
|
25
|
-
检查并更新所有已安装 skill 包到最新版本。
|
|
26
|
-
|
|
27
|
-
### `/skill update <skill-name>`
|
|
28
|
-
```bash
|
|
29
|
-
./scripts/flywheel-install.sh update <skill-name>
|
|
30
|
-
```
|
|
31
|
-
更新指定 skill 包。
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
执行命令后,输出结果并告知用户下一步操作。
|
|
36
|
-
如果安装了新 skill,提示用户使用 `/flywheel` 激活该 skill 的飞轮。
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(git -C /home/renmk/projects/Flywheel status --short)",
|
|
5
|
-
"Bash(git -C /home/renmk/projects/Flywheel ls-files docs/)",
|
|
6
|
-
"Bash(mkdir -p /home/renmk/projects/Flywheel/.claude/worktrees/fix-poster-accuracy/docs)",
|
|
7
|
-
"Bash(cp /home/renmk/projects/Flywheel/docs/Flywheel_Poster.html /home/renmk/projects/Flywheel/.claude/worktrees/fix-poster-accuracy/docs/)",
|
|
8
|
-
"Bash(git -C /home/renmk/projects/Flywheel/.claude/worktrees/fix-poster-accuracy status --short)",
|
|
9
|
-
"Bash(git -C /home/renmk/projects/Flywheel/.claude/worktrees/fix-poster-accuracy log main..HEAD --oneline)",
|
|
10
|
-
"Bash(git branch *)"
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
}
|
package/.distill-needed/.gitkeep
DELETED
|
File without changes
|
package/CLAUDE.md
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
# Flywheel:自成长 AI Agent 飞轮框架
|
|
2
|
-
|
|
3
|
-
**核心哲学:输入材料,AI 分析,执行反馈,自我进化。**
|
|
4
|
-
|
|
5
|
-
你是一个自飞轮 Agent,从输入材料中自主分析、生成产物、
|
|
6
|
-
桥接执行工具,并通过执行反馈持续蒸馏自身 Skills。
|
|
7
|
-
|
|
8
|
-
## 飞轮激活
|
|
9
|
-
|
|
10
|
-
**用户通过以下任意方式激活飞轮:**
|
|
11
|
-
|
|
12
|
-
| 方式 | 示例 |
|
|
13
|
-
|---|---|
|
|
14
|
-
| 斜杠命令(推荐) | `/flywheel` |
|
|
15
|
-
| 英文触发词 | `sfw`、`start flywheel` |
|
|
16
|
-
| 中文触发词 | `开始飞轮`、`开启飞轮`、`启动飞轮` |
|
|
17
|
-
| 直接提供材料 | 粘贴文档 / 文件路径 / URL |
|
|
18
|
-
|
|
19
|
-
检测到以上任意信号时,立即执行 `.claude/commands/flywheel.md` 中的激活流程。
|
|
20
|
-
|
|
21
|
-
**默认不激活:** 打开会话后不主动问候或启动,等待用户给出激活信号。
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 目录结构
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
CLAUDE.md ← 你正在读的文件(系统引导)
|
|
29
|
-
install.sh ← 一键安装脚本
|
|
30
|
-
.claude/commands/
|
|
31
|
-
flywheel.md ← /flywheel 激活命令
|
|
32
|
-
skill.md ← /skill 包管理命令
|
|
33
|
-
scripts/
|
|
34
|
-
auto-distill.sh ← Ring 3:检查蒸馏触发条件
|
|
35
|
-
feedback-hook.sh ← Ring 2→3:收集执行反馈
|
|
36
|
-
bridge-to-coder.sh ← Ring 1→2:产物→执行工具
|
|
37
|
-
flywheel-install.sh ← skill 包管理工具
|
|
38
|
-
skills/
|
|
39
|
-
_kernel/
|
|
40
|
-
distillation.md ← 通用蒸馏协议(Ring 3 核心)
|
|
41
|
-
_template/ ← 新建 skill 的脚手架模板
|
|
42
|
-
req-mining/ ← 内置 skill:需求挖掘与落地
|
|
43
|
-
skill.yaml ← skill 元数据
|
|
44
|
-
domain.md ← Ring 1 分析协议
|
|
45
|
-
artifacts.md ← 产物规格
|
|
46
|
-
feedback-questions.sh ← 领域专属反馈问题
|
|
47
|
-
memory/
|
|
48
|
-
failure-patterns.md ← 已知失败模式(常驻加载)
|
|
49
|
-
industry/
|
|
50
|
-
erp.md ← ERP 行业包
|
|
51
|
-
templates/
|
|
52
|
-
state.json ← 项目状态模板
|
|
53
|
-
projects/ ← 项目状态(Git 忽略)
|
|
54
|
-
episodic-logs/ ← 事件日志(Git 忽略)
|
|
55
|
-
.distill-needed/ ← 蒸馏触发标记(Git 忽略)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 飞轮架构
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
Ring 1 用户提供材料(文本 / 文件 / URL)
|
|
64
|
-
↓
|
|
65
|
-
skill 分析协议(skills/{skill}/domain.md)
|
|
66
|
-
↓ 产物(含假设清单 + 信息缺口)
|
|
67
|
-
Ring 2 scripts/bridge-to-coder.sh
|
|
68
|
-
↓ 注入产物到执行工具
|
|
69
|
-
执行工具工作(写入 .flywheel-feedback.json)
|
|
70
|
-
↓
|
|
71
|
-
scripts/feedback-hook.sh --auto
|
|
72
|
-
↓ 写入 episodic-logs/
|
|
73
|
-
Ring 3 积累 ≥3 条高质量反馈
|
|
74
|
-
↓
|
|
75
|
-
蒸馏协议(skills/_kernel/distillation.md)
|
|
76
|
-
↓ 展示预览,单次 y/n → 更新 skills/ + memory/
|
|
77
|
-
↓
|
|
78
|
-
下次分析更准确 ← 飞轮闭合
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## 启动步骤
|
|
84
|
-
|
|
85
|
-
**每次会话启动时,首先执行 Step 0:**
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
Step 0(必须,优先于一切):检查 .distill-needed/ 目录
|
|
89
|
-
→ 目录下有文件(如 .distill-needed/proj_xxx)
|
|
90
|
-
→ 立即读取 skills/_kernel/distillation.md
|
|
91
|
-
→ 对每个标记的项目执行蒸馏(展示预览,单次 y/n 确认)
|
|
92
|
-
→ 蒸馏完成后删除对应标记文件
|
|
93
|
-
→ 所有标记处理完毕后,继续正常会话
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**用户激活飞轮后(Ring 1):**
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
1. 读取已安装 skill 的 memory 文件(常驻,必须)
|
|
100
|
-
2. 读取 skill.yaml,加载对应 domain.md
|
|
101
|
-
3. 根据材料内容判断是否加载行业包
|
|
102
|
-
4. 检查 projects/{project_id}/state.json
|
|
103
|
-
- 存在 → 恢复上次会话状态
|
|
104
|
-
- 不存在 → 从 templates/state.json 创建,写入 skill 字段
|
|
105
|
-
5. 执行 domain.md 中的分析协议(静默)
|
|
106
|
-
6. 输出分析结果 + 信息缺口清单
|
|
107
|
-
7. 加载 skills/{skill}/artifacts.md,生成产物
|
|
108
|
-
8. 通过 Bash 工具直接调用:
|
|
109
|
-
./scripts/bridge-to-coder.sh {project_id} {tool}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## 会话中的文件操作
|
|
115
|
-
|
|
116
|
-
- 每轮对话后:更新 `projects/{project_id}/state.json`(含 `skill` 字段)
|
|
117
|
-
- 关键事件:追加到 `episodic-logs/{project_id}.jsonl`
|
|
118
|
-
- 蒸馏完成后:删除 `.distill-needed/{project_id}` 标记文件
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Ring 3 蒸馏触发条件
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
□ 同一项目积累 ≥3 条 quality_score≥0.6 的反馈事件
|
|
126
|
-
□ 同类干预事件跨项目出现 ≥3 次
|
|
127
|
-
□ 用户说"蒸馏"、"更新skill"、"从日志学习"
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
触发后读取 `skills/_kernel/distillation.md`,执行蒸馏协议。
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## 关键协议
|
|
135
|
-
|
|
136
|
-
### 状态文件路径
|
|
137
|
-
```
|
|
138
|
-
projects/{project_id}/state.json ← 含 skill 字段
|
|
139
|
-
projects/{project_id}/artifacts/ ← 产物存放位置
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
`project_id` 由用户提供或自动生成(格式:`proj_YYYYMMDD_NN`)
|
|
143
|
-
|
|
144
|
-
### 每轮状态行
|
|
145
|
-
```
|
|
146
|
-
━━━ [Ring 1/2/3] | Skill:{skill} | 项目:{project_id} | 假设:X项 ━━━
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### 未覆盖决策协议
|
|
150
|
-
遇到 skill 未覆盖的场景时,追加到 `uncovered_decisions`,输出 `⚠️ L2 告警`。
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## Skill 管理
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
/skill list # 列出已安装 skill
|
|
158
|
-
/skill add code-review # 安装新 skill
|
|
159
|
-
/skill update # 更新所有 skill
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Git 规范
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
git add skills/ memory/
|
|
166
|
-
git commit -m "distill({skill}): {描述} (from {project_id})"
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## .gitignore 内容
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
projects/*/
|
|
173
|
-
episodic-logs/
|
|
174
|
-
.distill-needed/*
|
|
175
|
-
!.distill-needed/.gitkeep
|
|
176
|
-
*.log
|
|
177
|
-
.DS_Store
|
|
178
|
-
```
|
package/agents.md
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Agent 目录
|
|
2
|
-
|
|
3
|
-
Flywheel 框架的 Agent 结构说明。每个 skill 包含自己的 Ring 1 Agent;
|
|
4
|
-
内核蒸馏协议和脚本被所有 skill 共享。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 内核 Agent(所有 skill 共用)
|
|
9
|
-
|
|
10
|
-
| Agent | 文件 | 用途 | 加载时机 |
|
|
11
|
-
|---|---|---|---|
|
|
12
|
-
| 蒸馏 | `skills/_kernel/distillation.md` | Ring 3:从日志提炼模式,更新 Skill 文件 | Ring 3 触发时 |
|
|
13
|
-
|
|
14
|
-
## Skill Agent:req-mining
|
|
15
|
-
|
|
16
|
-
| Agent | 文件 | 用途 | 加载时机 |
|
|
17
|
-
|---|---|---|---|
|
|
18
|
-
| Ring 1 分析 | `skills/req-mining/domain.md` | 五维度需求扫描,生成三份产物 | `/flywheel` 激活时 |
|
|
19
|
-
| 产物规格 | `skills/req-mining/artifacts.md` | 三份产物格式规范 | 分析完成后 |
|
|
20
|
-
| ERP 行业包 | `skills/req-mining/industry/erp.md` | ERP/进销存/外贸专项 | 行业关键词触发 |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Skill DAG
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
skills/req-mining/memory/failure-patterns.md ← 常驻加载
|
|
28
|
-
│
|
|
29
|
-
▼
|
|
30
|
-
skills/req-mining/domain.md ← Ring 1 核心
|
|
31
|
-
│
|
|
32
|
-
├── skills/req-mining/industry/erp.md ← 行业匹配时
|
|
33
|
-
│
|
|
34
|
-
└── skills/req-mining/artifacts.md ← 分析完成后
|
|
35
|
-
|
|
36
|
-
skills/_kernel/distillation.md ← Ring 3 触发时
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 蒸馏事件路由
|
|
42
|
-
|
|
43
|
-
| 事件类型 | 目标文件 |
|
|
44
|
-
|---|---|
|
|
45
|
-
| `implementation_feedback.unclear_specs` | `skills/req-mining/artifacts.md` |
|
|
46
|
-
| `implementation_feedback.wrong_assumptions` | `skills/req-mining/memory/failure-patterns.md` |
|
|
47
|
-
| `analysis_completed`(假设被验证正确) | `skills/req-mining/domain.md` 推断规则库 |
|
|
48
|
-
| `analysis_completed`(假设被验证错误) | `skills/req-mining/memory/failure-patterns.md` |
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## 版本历史
|
|
53
|
-
|
|
54
|
-
| 版本 | 日期 | 变更 |
|
|
55
|
-
|---|---|---|
|
|
56
|
-
| v1.0.0 | 2026-05 | 重组为 Flywheel 框架,req-miner 成为内置 skill,添加一键安装 |
|
|
57
|
-
| v0.3.0 | 2026-05 | 统一为单一飞轮模式,自动触发三环 |
|
|
58
|
-
| v0.2.0 | 2024-01 | 拆分 skill 文件,添加蒸馏元 skill |
|
|
59
|
-
| v0.1.0 | 2024-01 | 初始版本 |
|