viepilot 2.23.0 → 2.45.2
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/CHANGELOG.md +288 -0
- package/README.md +6 -6
- package/bin/viepilot.cjs +140 -1
- package/bin/vp-tools.cjs +204 -0
- package/docs/brainstorm/session-2026-04-20.md +261 -0
- package/docs/brainstorm/session-2026-04-24.md +131 -0
- package/docs/brainstorm/session-2026-04-25.md +109 -0
- package/docs/skills-reference.md +22 -0
- package/docs/user/features/adapters.md +2 -2
- package/docs/user/features/scaffold-first.md +62 -0
- package/docs/user/features/skill-registry.md +125 -0
- package/lib/adapters/antigravity.cjs +5 -4
- package/lib/domain-packs/ai-product.json +33 -0
- package/lib/domain-packs/data-science.json +33 -0
- package/lib/domain-packs/devops.json +33 -0
- package/lib/domain-packs/mobile.json +33 -0
- package/lib/domain-packs/web-saas.json +33 -0
- package/lib/skill-installer.cjs +274 -0
- package/lib/skill-registry.cjs +212 -0
- package/lib/viepilot-calibrate.cjs +279 -0
- package/lib/viepilot-persona.cjs +446 -0
- package/lib/viepilot-update.cjs +113 -0
- package/package.json +1 -1
- package/skills/vp-audit/SKILL.md +67 -9
- package/skills/vp-auto/SKILL.md +54 -0
- package/skills/vp-brainstorm/SKILL.md +124 -2
- package/skills/vp-crystallize/SKILL.md +82 -0
- package/skills/vp-debug/SKILL.md +37 -0
- package/skills/vp-design/SKILL.md +219 -0
- package/skills/vp-docs/SKILL.md +37 -0
- package/skills/vp-evolve/SKILL.md +69 -6
- package/skills/vp-info/SKILL.md +37 -0
- package/skills/vp-pause/SKILL.md +37 -0
- package/skills/vp-persona/SKILL.md +207 -0
- package/skills/vp-proposal/SKILL.md +37 -0
- package/skills/vp-request/SKILL.md +62 -6
- package/skills/vp-resume/SKILL.md +37 -0
- package/skills/vp-rollback/SKILL.md +61 -1
- package/skills/vp-skills/SKILL.md +311 -0
- package/skills/vp-status/SKILL.md +37 -0
- package/skills/vp-task/SKILL.md +37 -0
- package/skills/vp-ui-components/SKILL.md +37 -0
- package/skills/vp-update/SKILL.md +37 -0
- package/templates/phase/TASK.md +7 -0
- package/templates/project/PROJECT-CONTEXT.md +76 -0
- package/workflows/audit.md +131 -0
- package/workflows/autonomous.md +199 -0
- package/workflows/brainstorm.md +1172 -9
- package/workflows/crystallize.md +639 -3
- package/workflows/design.md +601 -0
- package/workflows/evolve.md +9 -0
- package/workflows/rollback.md +79 -10
package/bin/vp-tools.cjs
CHANGED
|
@@ -1137,6 +1137,157 @@ ${colors.cyan}Examples:${colors.reset}
|
|
|
1137
1137
|
process.exit(1);
|
|
1138
1138
|
},
|
|
1139
1139
|
|
|
1140
|
+
/**
|
|
1141
|
+
* Output global skill registry as JSON (BUG-016 fix — shell-executable alternative to loadRegistry())
|
|
1142
|
+
*/
|
|
1143
|
+
'get-registry': (args) => {
|
|
1144
|
+
const { loadRegistry } = require('../lib/skill-registry.cjs');
|
|
1145
|
+
const registry = loadRegistry();
|
|
1146
|
+
if (!registry) {
|
|
1147
|
+
process.stdout.write('null\n');
|
|
1148
|
+
process.exit(0);
|
|
1149
|
+
}
|
|
1150
|
+
const idFilter = args[0] === '--id' ? args[1] : null;
|
|
1151
|
+
if (idFilter) {
|
|
1152
|
+
const skill = (registry.skills || []).find(s => s.id === idFilter) || null;
|
|
1153
|
+
process.stdout.write(JSON.stringify(skill) + '\n');
|
|
1154
|
+
} else {
|
|
1155
|
+
process.stdout.write(JSON.stringify(registry) + '\n');
|
|
1156
|
+
}
|
|
1157
|
+
process.exit(0);
|
|
1158
|
+
},
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* ENH-072: Check npm registry for newer ViePilot version (24h cached).
|
|
1162
|
+
* --silent exit 0 if up-to-date (no output); exit 1 + print latest if update available
|
|
1163
|
+
* --json print { installed, latest, has_update }; always exit 0
|
|
1164
|
+
* --force bypass 24h cache
|
|
1165
|
+
*/
|
|
1166
|
+
'check-update': (args) => {
|
|
1167
|
+
const silent = args.includes('--silent');
|
|
1168
|
+
const json = args.includes('--json');
|
|
1169
|
+
const force = args.includes('--force');
|
|
1170
|
+
const { checkLatestVersion } = require('../lib/viepilot-update.cjs');
|
|
1171
|
+
|
|
1172
|
+
checkLatestVersion({ force })
|
|
1173
|
+
.then(({ upToDate, installed, latest }) => {
|
|
1174
|
+
const has_update = !upToDate;
|
|
1175
|
+
if (json) {
|
|
1176
|
+
process.stdout.write(JSON.stringify({ installed, latest, has_update }) + '\n');
|
|
1177
|
+
process.exit(0);
|
|
1178
|
+
}
|
|
1179
|
+
if (silent) {
|
|
1180
|
+
if (has_update) {
|
|
1181
|
+
process.stdout.write(latest + '\n');
|
|
1182
|
+
process.exit(1);
|
|
1183
|
+
} else {
|
|
1184
|
+
process.exit(0);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
// default human-readable output
|
|
1188
|
+
if (has_update) {
|
|
1189
|
+
process.stdout.write(
|
|
1190
|
+
`\n┌──────────────────────────────────────────────────────────────────┐\n` +
|
|
1191
|
+
`│ ✨ ViePilot v${latest} available (installed: v${installed})`.padEnd(69) + '│\n' +
|
|
1192
|
+
`│ npm i -g viepilot && vp-tools install`.padEnd(69) + '│\n' +
|
|
1193
|
+
`└──────────────────────────────────────────────────────────────────┘\n`
|
|
1194
|
+
);
|
|
1195
|
+
process.exit(1);
|
|
1196
|
+
} else {
|
|
1197
|
+
process.stdout.write(`ViePilot ${installed} is up to date.\n`);
|
|
1198
|
+
process.exit(0);
|
|
1199
|
+
}
|
|
1200
|
+
})
|
|
1201
|
+
.catch(() => {
|
|
1202
|
+
process.exit(0);
|
|
1203
|
+
});
|
|
1204
|
+
},
|
|
1205
|
+
|
|
1206
|
+
/**
|
|
1207
|
+
* ENH-073: Manage cross-project personas.
|
|
1208
|
+
* persona get → print active persona JSON
|
|
1209
|
+
* persona infer [dir] → run inferPersona, print result, update context-map
|
|
1210
|
+
* persona list → list all ~/.viepilot/personas/*.json
|
|
1211
|
+
* persona set <name> → set active persona by name
|
|
1212
|
+
* persona auto-switch → auto-detect and switch for cwd (called at skill start)
|
|
1213
|
+
* persona context [dir] → print persona-context.md content
|
|
1214
|
+
*/
|
|
1215
|
+
'persona': (args) => {
|
|
1216
|
+
const {
|
|
1217
|
+
inferPersona, resolvePersona, generatePersonaContext,
|
|
1218
|
+
readActivePersona, writePersona, setActivePersona, listPersonas,
|
|
1219
|
+
updateContextMap, autoSwitch,
|
|
1220
|
+
} = require('../lib/viepilot-persona.cjs');
|
|
1221
|
+
|
|
1222
|
+
const op = args[0] || 'get';
|
|
1223
|
+
const dir = args[1] ? require('path').resolve(args[1]) : process.cwd();
|
|
1224
|
+
|
|
1225
|
+
if (op === 'get') {
|
|
1226
|
+
const persona = readActivePersona();
|
|
1227
|
+
if (!persona) { process.stdout.write('No active persona\n'); process.exit(0); }
|
|
1228
|
+
process.stdout.write(JSON.stringify(persona, null, 2) + '\n');
|
|
1229
|
+
process.exit(0);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
if (op === 'list') {
|
|
1233
|
+
const personas = listPersonas();
|
|
1234
|
+
if (!personas.length) { process.stdout.write('No personas saved\n'); process.exit(0); }
|
|
1235
|
+
for (const p of personas) {
|
|
1236
|
+
const marker = p.active ? '[active] ' : ' ';
|
|
1237
|
+
process.stdout.write(`${marker}${p.name} domain:${p.domain} confidence:${p.confidence}\n`);
|
|
1238
|
+
}
|
|
1239
|
+
process.exit(0);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
if (op === 'set') {
|
|
1243
|
+
const name = args[1];
|
|
1244
|
+
if (!name) { process.stderr.write('Usage: persona set <name>\n'); process.exit(1); }
|
|
1245
|
+
setActivePersona(name);
|
|
1246
|
+
process.stdout.write(`Active persona set to: ${name}\n`);
|
|
1247
|
+
process.exit(0);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
if (op === 'infer') {
|
|
1251
|
+
inferPersona(dir).then(persona => {
|
|
1252
|
+
writePersona(persona.name, persona);
|
|
1253
|
+
setActivePersona(persona.name);
|
|
1254
|
+
updateContextMap(dir, persona.name);
|
|
1255
|
+
process.stdout.write(JSON.stringify(persona, null, 2) + '\n');
|
|
1256
|
+
process.exit(0);
|
|
1257
|
+
}).catch(() => process.exit(0));
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
if (op === 'auto-switch') {
|
|
1262
|
+
autoSwitch(dir).then(() => process.exit(0)).catch(() => process.exit(0));
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
if (op === 'context') {
|
|
1267
|
+
(async () => {
|
|
1268
|
+
let persona = resolvePersona(dir);
|
|
1269
|
+
if (!persona) persona = await inferPersona(dir);
|
|
1270
|
+
process.stdout.write(generatePersonaContext(persona) + '\n');
|
|
1271
|
+
process.exit(0);
|
|
1272
|
+
})().catch(() => process.exit(0));
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
process.stderr.write(`Unknown persona op: ${op}\nUsage: persona get|infer|list|set|auto-switch|context\n`);
|
|
1277
|
+
process.exit(1);
|
|
1278
|
+
},
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Scan installed skills and rebuild ~/.viepilot/skill-registry.json (BUG-019)
|
|
1282
|
+
*/
|
|
1283
|
+
'scan-skills': (_args) => {
|
|
1284
|
+
const { scanSkills } = require('../lib/skill-registry.cjs');
|
|
1285
|
+
const result = scanSkills();
|
|
1286
|
+
const count = (result && result.skills) ? result.skills.length : 0;
|
|
1287
|
+
process.stdout.write(`✔ Scanned ${count} skill${count !== 1 ? 's' : ''} → ~/.viepilot/skill-registry.json\n`);
|
|
1288
|
+
process.exit(0);
|
|
1289
|
+
},
|
|
1290
|
+
|
|
1140
1291
|
/**
|
|
1141
1292
|
* Help
|
|
1142
1293
|
*/
|
|
@@ -1224,6 +1375,55 @@ ${colors.cyan}Examples:${colors.reset}
|
|
|
1224
1375
|
options: ['--json: Machine-readable JSON output'],
|
|
1225
1376
|
examples: ['vp-tools info', 'vp-tools info --json'],
|
|
1226
1377
|
},
|
|
1378
|
+
'get-registry': {
|
|
1379
|
+
usage: 'vp-tools get-registry [--id <skill-id>]',
|
|
1380
|
+
description: 'Output global skill registry as JSON (enables workflow shell integration)',
|
|
1381
|
+
options: ['--id <id>: Output only the matching skill object (null if not found)'],
|
|
1382
|
+
examples: [
|
|
1383
|
+
'vp-tools get-registry',
|
|
1384
|
+
'vp-tools get-registry --id frontend-design',
|
|
1385
|
+
],
|
|
1386
|
+
},
|
|
1387
|
+
'scan-skills': {
|
|
1388
|
+
usage: 'vp-tools scan-skills',
|
|
1389
|
+
description: 'Scan installed skills and rebuild ~/.viepilot/skill-registry.json',
|
|
1390
|
+
options: [],
|
|
1391
|
+
examples: ['vp-tools scan-skills'],
|
|
1392
|
+
},
|
|
1393
|
+
'check-update': {
|
|
1394
|
+
usage: 'vp-tools check-update [--silent] [--json] [--force]',
|
|
1395
|
+
description: 'Check for latest ViePilot version on npm registry (24h cached)',
|
|
1396
|
+
options: [
|
|
1397
|
+
'--silent Exit 0 if up-to-date (no output); exit 1 + print latest if update available',
|
|
1398
|
+
'--json Print { installed, latest, has_update }; always exit 0',
|
|
1399
|
+
'--force Bypass 24h cache and check now',
|
|
1400
|
+
],
|
|
1401
|
+
examples: [
|
|
1402
|
+
'vp-tools check-update --silent',
|
|
1403
|
+
'vp-tools check-update --json',
|
|
1404
|
+
'vp-tools check-update --force',
|
|
1405
|
+
],
|
|
1406
|
+
},
|
|
1407
|
+
'persona': {
|
|
1408
|
+
usage: 'vp-tools persona <op> [dir]',
|
|
1409
|
+
description: 'Manage cross-project personas (ENH-073)',
|
|
1410
|
+
options: [
|
|
1411
|
+
'get Show active persona JSON',
|
|
1412
|
+
'infer [dir] Infer persona from project files + git',
|
|
1413
|
+
'list List all saved personas',
|
|
1414
|
+
'set <name> Set active persona by name',
|
|
1415
|
+
'auto-switch Auto-detect and switch persona for current directory',
|
|
1416
|
+
'context [dir] Print persona-context.md content for current project',
|
|
1417
|
+
],
|
|
1418
|
+
examples: [
|
|
1419
|
+
'vp-tools persona get',
|
|
1420
|
+
'vp-tools persona infer .',
|
|
1421
|
+
'vp-tools persona list',
|
|
1422
|
+
'vp-tools persona set auto-web-saas',
|
|
1423
|
+
'vp-tools persona auto-switch',
|
|
1424
|
+
'vp-tools persona context',
|
|
1425
|
+
],
|
|
1426
|
+
},
|
|
1227
1427
|
update: {
|
|
1228
1428
|
usage: 'vp-tools update [--dry-run] [--yes] [--global]',
|
|
1229
1429
|
description: 'Update viepilot to npm latest (local dependency, global install, or explicit --global)',
|
|
@@ -1282,6 +1482,10 @@ ${colors.cyan}Commands:${colors.reset}
|
|
|
1282
1482
|
${colors.bold}hooks${colors.reset} scaffold|install [--adapter] scaffold: print snippet; install: write to settings.json
|
|
1283
1483
|
${colors.bold}config${colors.reset} <get|set|reset> Read/write language config (~/.viepilot/config.json)
|
|
1284
1484
|
${colors.bold}save-state${colors.reset} Save current state for precise resume
|
|
1485
|
+
${colors.bold}get-registry${colors.reset} [--id <id>] Output global skill registry as JSON
|
|
1486
|
+
${colors.bold}scan-skills${colors.reset} Scan installed skills → ~/.viepilot/skill-registry.json
|
|
1487
|
+
${colors.bold}check-update${colors.reset} [--silent] Check for latest ViePilot version on npm (24h cached)
|
|
1488
|
+
${colors.bold}persona${colors.reset} <op> Manage user personas (get|infer|list|set|auto-switch|context)
|
|
1285
1489
|
${colors.bold}help${colors.reset} [command] Show help (optionally for specific command)
|
|
1286
1490
|
|
|
1287
1491
|
${colors.cyan}Examples:${colors.reset}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# Brainstorm Session — 2026-04-20
|
|
2
|
+
|
|
3
|
+
## Topic
|
|
4
|
+
**ViePilot Skill Registry System** — Third-party skill installation + scan-skills command + workflow skill integration (brainstorm / crystallize / vp-auto gates)
|
|
5
|
+
|
|
6
|
+
## Status
|
|
7
|
+
In Progress
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Problem Statement
|
|
12
|
+
|
|
13
|
+
ViePilot hiện tại chỉ dùng built-in `vp-*` skills. Khi user muốn xây dựng UI-Direction phức tạp hơn (ví dụ dùng design system cụ thể, component library, hay frontend framework chuyên biệt), không có cơ chế nào để bổ sung context chuyên sâu từ external skills.
|
|
14
|
+
|
|
15
|
+
Vấn đề cụ thể:
|
|
16
|
+
1. Không có cách cài thêm skills từ bên thứ 3 (npm, GitHub, local)
|
|
17
|
+
2. ViePilot không biết skills nào đang có sẵn trên máy
|
|
18
|
+
3. Workflow (brainstorm / crystallize / vp-auto) không thể tận dụng skill context ngoài vp-* namespace
|
|
19
|
+
4. Quyết định "dùng skill nào" không có điểm lock — vp-auto phải hỏi lại hoặc đoán
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Proposed Solution: Skill Registry System
|
|
24
|
+
|
|
25
|
+
### Core Concept
|
|
26
|
+
|
|
27
|
+
Ba tầng hoạt động:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
[Install] vp-tools install-skill <source> → cài skill vào adapter dirs
|
|
31
|
+
[Discover] vp-tools scan-skills → quét + index toàn bộ skills
|
|
32
|
+
[Apply] brainstorm → crystallize → auto → dùng skills theo pipeline
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Tầng 1 — Installation (multi-channel)
|
|
36
|
+
|
|
37
|
+
`vp-tools install-skill <source>` hỗ trợ:
|
|
38
|
+
|
|
39
|
+
| Channel | Syntax | Example |
|
|
40
|
+
|---------|--------|---------|
|
|
41
|
+
| npm | `npm:package-name` hoặc bare name | `vp-tools install-skill @vp-skills/frontend-design` |
|
|
42
|
+
| GitHub | `github:org/repo` | `vp-tools install-skill github:myorg/vp-skill-tailwind` |
|
|
43
|
+
| Local | `./path` hoặc absolute path | `vp-tools install-skill ./my-skill` |
|
|
44
|
+
|
|
45
|
+
Sau khi install → tự động chạy `scan-skills` để cập nhật registry.
|
|
46
|
+
|
|
47
|
+
Commands bổ sung:
|
|
48
|
+
- `vp-tools uninstall-skill <id>` — xóa khỏi tất cả adapter dirs
|
|
49
|
+
- `vp-tools list-skills` — hiển thị skills đã cài + version + source
|
|
50
|
+
- `vp-tools update-skill <id>` — cập nhật từ source gốc
|
|
51
|
+
|
|
52
|
+
### Tầng 2 — Scanner & Registry
|
|
53
|
+
|
|
54
|
+
`vp-tools scan-skills` quét toàn bộ adapter dirs:
|
|
55
|
+
- `~/.claude/skills/` (Claude Code)
|
|
56
|
+
- `~/.cursor/skills/` (Cursor)
|
|
57
|
+
- `~/.codex/skills/` (Codex)
|
|
58
|
+
- `~/.antigravity/skills/` (Antigravity)
|
|
59
|
+
|
|
60
|
+
Output: `~/.viepilot/skill-registry.json`
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"version": "1.0",
|
|
65
|
+
"last_scan": "2026-04-20T10:30:00Z",
|
|
66
|
+
"scan_paths": ["~/.claude/skills/", "~/.cursor/skills/"],
|
|
67
|
+
"skills": [
|
|
68
|
+
{
|
|
69
|
+
"id": "frontend-design",
|
|
70
|
+
"name": "Frontend Design",
|
|
71
|
+
"source": "npm:@vp-skills/frontend-design",
|
|
72
|
+
"version": "1.2.0",
|
|
73
|
+
"description": "...",
|
|
74
|
+
"capabilities": ["ui-generation", "component-design", "responsive-layout"],
|
|
75
|
+
"tags": ["ui", "design", "frontend", "css", "html"],
|
|
76
|
+
"best_practices": ["Mobile-first", "Design tokens", "BEM naming"],
|
|
77
|
+
"adapters": ["claude-code", "cursor"],
|
|
78
|
+
"installed_paths": {
|
|
79
|
+
"claude-code": "~/.claude/skills/frontend-design/",
|
|
80
|
+
"cursor": "~/.cursor/skills/frontend-design/"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Tầng 3 — SKILL.md Extended Format
|
|
88
|
+
|
|
89
|
+
Third-party skills (và vp-* skills nếu muốn) thêm 3 sections mới vào SKILL.md:
|
|
90
|
+
|
|
91
|
+
```markdown
|
|
92
|
+
## Capabilities
|
|
93
|
+
- ui-generation
|
|
94
|
+
- component-design
|
|
95
|
+
- responsive-layout
|
|
96
|
+
|
|
97
|
+
## Tags
|
|
98
|
+
ui, design, frontend, css, html, tailwind
|
|
99
|
+
|
|
100
|
+
## Best Practices
|
|
101
|
+
- Use design tokens for consistency across components
|
|
102
|
+
- Mobile-first: design breakpoints from 320px up
|
|
103
|
+
- BEM naming convention for CSS classes
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Scanner đọc các sections này để index. Skills không có sections mới vẫn được scan (fallback: parse description + content tự động).
|
|
107
|
+
|
|
108
|
+
### Tầng 4 — Workflow Integration Pipeline
|
|
109
|
+
|
|
110
|
+
#### A. Brainstorm → Silent Skill Application (UI-Direction)
|
|
111
|
+
|
|
112
|
+
Khi brainstorm có UI signals (keywords: `component`, `design`, `layout`, `screen`, `UI`, v.v.):
|
|
113
|
+
- Load `~/.viepilot/skill-registry.json`
|
|
114
|
+
- Match skills có `capabilities` phù hợp (e.g., `ui-generation`, `component-design`)
|
|
115
|
+
- **Silent apply**: tự động include best practices từ matched skills vào HTML generation
|
|
116
|
+
- Record vào `notes.md`: `## skills_used` section
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
## skills_used
|
|
120
|
+
- id: frontend-design
|
|
121
|
+
version: 1.2.0
|
|
122
|
+
trigger: ui-generation signal
|
|
123
|
+
applied_at: brainstorm-session
|
|
124
|
+
best_practices_applied:
|
|
125
|
+
- Mobile-first
|
|
126
|
+
- Design tokens
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Không hỏi user — chạy ngầm như Background UI Extraction.
|
|
130
|
+
|
|
131
|
+
#### B. Crystallize → Skill Decision Lock Gate
|
|
132
|
+
|
|
133
|
+
Bước mới trong `vp-crystallize` (sau scope lock, trước generate SPEC):
|
|
134
|
+
|
|
135
|
+
1. Đọc `notes.md` → `## skills_used` của session đó
|
|
136
|
+
2. Hiển thị danh sách skills đã/sẽ được dùng
|
|
137
|
+
3. User confirm: required vs optional per phase/task
|
|
138
|
+
4. Ghi vào `PROJECT-CONTEXT.md`:
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
## Skills
|
|
142
|
+
|
|
143
|
+
| Skill | Source | Required | Phases | Rationale |
|
|
144
|
+
|-------|--------|----------|--------|-----------|
|
|
145
|
+
| frontend-design | npm:@vp-skills/frontend-design | required | 1, 2 | UI-Direction HTML generation — design token best practices |
|
|
146
|
+
| tailwind-guide | github:org/vp-tailwind | optional | 2 | Phase 2 styling layer |
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Lý do lock ở crystallize:** vp-auto là execution-only — nó đọc SPEC và chạy, không ra quyết định. Tất cả quyết định về "dùng skill nào" phải được lock trước khi vp-auto bắt đầu.
|
|
150
|
+
|
|
151
|
+
#### C. vp-auto → Silent Skill Execution
|
|
152
|
+
|
|
153
|
+
vp-auto đọc `## Skills` từ `PROJECT-CONTEXT.md`:
|
|
154
|
+
- Với mỗi task, kiểm tra skills `required` trong phases tương ứng
|
|
155
|
+
- Load best practices từ skill registry
|
|
156
|
+
- Include context vào execution prompt — **không hỏi lại user**
|
|
157
|
+
- Ghi vào task output: `skills_applied: [frontend-design@1.2.0]`
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Decisions
|
|
162
|
+
|
|
163
|
+
| Decision | Options Considered | Chosen | Rationale |
|
|
164
|
+
|----------|--------------------|--------|-----------|
|
|
165
|
+
| Skill source channels | npm-only / all channels | All channels (npm + github + local) | Flexibility cho cả published và WIP skills |
|
|
166
|
+
| Scanner scope | ViePilot-only dirs / all adapter dirs | All adapter dirs | Discover tất cả skills user đã cài qua bất kỳ tool nào |
|
|
167
|
+
| Gate model | Required block / heuristic prompt / silent / hybrid | Silent auto-apply + crystallize-time lock | vp-auto không hỏi lại; quyết định từ crystallize. Nhất quán với ui-direction guard |
|
|
168
|
+
| SKILL.md format | Giữ nguyên / extend / file riêng | Extend — thêm Capabilities/Tags/Best Practices | Backward compat; scanner vẫn parse skills cũ |
|
|
169
|
+
| Lock storage | SPEC.md per-task / PROJECT-CONTEXT.md ## Skills / file riêng | PROJECT-CONTEXT.md ## Skills | Tương tự ## Tech Stack — project-level; dễ đọc cho vp-auto |
|
|
170
|
+
| Phase 1 target | Scanner / Installer / Brainstorm integration | Scanner + registry first | Nền tảng cho mọi tính năng phía sau |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Open Questions
|
|
175
|
+
|
|
176
|
+
| ID | Question | Priority | Due |
|
|
177
|
+
|----|----------|----------|-----|
|
|
178
|
+
| Q1 | Có cần `vp-tools publish-skill` để user publish skill lên npm không? | low | next milestone |
|
|
179
|
+
| Q2 | Skill versioning: nếu skill update, best practices thay đổi — có cần re-crystallize không? | medium | Phase 4 design |
|
|
180
|
+
| Q3 | Skill conflict: 2 skills có cùng capability, workflow ưu tiên cái nào? | medium | Phase 3 design |
|
|
181
|
+
| Q4 | Có cần một "official ViePilot skills registry" (marketplace) hay chỉ dựa vào npm search? | low | future |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Phases
|
|
186
|
+
|
|
187
|
+
### Phase 1 — Skill Registry Foundation
|
|
188
|
+
**Goal**: `vp-tools scan-skills` + `~/.viepilot/skill-registry.json` + extended SKILL.md format spec
|
|
189
|
+
|
|
190
|
+
Tasks:
|
|
191
|
+
1. `lib/skill-registry.cjs` — scanner: traverse adapter dirs, parse SKILL.md (extended + legacy), build JSON
|
|
192
|
+
2. `bin/viepilot.cjs` — add `scan-skills` subcommand + `list-skills` display
|
|
193
|
+
3. `docs/user/features/skill-registry.md` — extended SKILL.md format spec + scanner docs
|
|
194
|
+
4. `tests/unit/vp-skill-registry.test.js` — 15+ contract tests (scan, parse, index, legacy compat)
|
|
195
|
+
|
|
196
|
+
Target version: **2.26.0**
|
|
197
|
+
|
|
198
|
+
### Phase 2 — Third-party Skill Installation
|
|
199
|
+
**Goal**: `vp-tools install-skill` (npm + github + local) + `uninstall-skill` + `update-skill`
|
|
200
|
+
|
|
201
|
+
Tasks:
|
|
202
|
+
1. `lib/skill-installer.cjs` — multi-channel installer (npm exec + git clone + fs copy)
|
|
203
|
+
2. `bin/viepilot.cjs` — add `install-skill`, `uninstall-skill`, `update-skill` subcommands
|
|
204
|
+
3. Post-install hook: auto-run `scan-skills`
|
|
205
|
+
4. `tests/unit/vp-skill-installer.test.js` — 12+ tests (each channel, auto-scan trigger)
|
|
206
|
+
|
|
207
|
+
Target version: **2.27.0**
|
|
208
|
+
|
|
209
|
+
### Phase 3 — Brainstorm Integration (UI-Direction silent apply)
|
|
210
|
+
**Goal**: brainstorm.md detects UI signals → loads registry → silently applies matched skill best practices → records `## skills_used` in notes.md
|
|
211
|
+
|
|
212
|
+
Tasks:
|
|
213
|
+
1. `workflows/brainstorm.md` — add skill registry load step + signal matching logic + silent apply rule
|
|
214
|
+
2. `skills/vp-brainstorm/SKILL.md` — document skill integration behavior
|
|
215
|
+
3. `tests/unit/brainstorm-skill-integration.test.js` — 10+ tests
|
|
216
|
+
|
|
217
|
+
Target version: **2.28.0**
|
|
218
|
+
|
|
219
|
+
### Phase 4 — Crystallize Skill Decision Gate
|
|
220
|
+
**Goal**: crystallize.md new step → skill confirmation gate → `## Skills` in PROJECT-CONTEXT.md
|
|
221
|
+
|
|
222
|
+
Tasks:
|
|
223
|
+
1. `workflows/crystallize.md` — add skill gate step (read notes.md skills_used → AUQ confirm → write PROJECT-CONTEXT.md)
|
|
224
|
+
2. `templates/project/PROJECT-CONTEXT.md` — add `## Skills` section template
|
|
225
|
+
3. `skills/vp-crystallize/SKILL.md` — document skill gate
|
|
226
|
+
4. `tests/unit/crystallize-skill-gate.test.js` — 10+ tests
|
|
227
|
+
|
|
228
|
+
Target version: **2.29.0**
|
|
229
|
+
|
|
230
|
+
### Phase 5 — vp-auto Silent Skill Execution
|
|
231
|
+
**Goal**: autonomous.md reads `## Skills` from PROJECT-CONTEXT.md → per-task silent context injection
|
|
232
|
+
|
|
233
|
+
Tasks:
|
|
234
|
+
1. `workflows/autonomous.md` — add skill context load step + per-task skill injection rule
|
|
235
|
+
2. `skills/vp-auto/SKILL.md` — document silent skill execution
|
|
236
|
+
3. `tests/unit/autonomous-skill-execution.test.js` — 8+ tests
|
|
237
|
+
|
|
238
|
+
Target version: **2.30.0**
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Background UI Extraction
|
|
243
|
+
|
|
244
|
+
Waiver — session topic is a framework feature (skill registry), not a consumer app UI. No UI Direction artifacts needed.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Project meta intake (FEAT-009)
|
|
249
|
+
|
|
250
|
+
Waiver — ViePilot framework repo; profile binding already exists.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Session Summary
|
|
255
|
+
|
|
256
|
+
- **Feature**: ViePilot Skill Registry System
|
|
257
|
+
- **Suggested ID**: FEAT-020
|
|
258
|
+
- **Scope**: 5 phases — registry/scanner → installer → brainstorm integration → crystallize gate → vp-auto execution
|
|
259
|
+
- **Key architectural decision**: Skills are **silent auto-apply** at brainstorm time; **locked at crystallize** time; **executed without re-asking** by vp-auto
|
|
260
|
+
- **Backward compat**: Existing SKILL.md files still work — scanner gracefully handles missing extended sections
|
|
261
|
+
- **First deliverable**: `vp-tools scan-skills` + `~/.viepilot/skill-registry.json` (Phase 1 → v2.26.0)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Brainstorm Session — 2026-04-24
|
|
2
|
+
|
|
3
|
+
## Session Info
|
|
4
|
+
- **Date**: 2026-04-24
|
|
5
|
+
- **Topic**: vp-persona — ViePilot Workflow Customization Skill
|
|
6
|
+
- **Status**: Completed
|
|
7
|
+
- **workflow_version**: 2.41.0
|
|
8
|
+
|
|
9
|
+
## Core Idea
|
|
10
|
+
|
|
11
|
+
A new skill `/vp-persona` that creates a **user-level, cross-project identity** for ViePilot.
|
|
12
|
+
Lets users customize ALL ViePilot workflows to fit their domain, profession, and interests —
|
|
13
|
+
without re-declaring context per project.
|
|
14
|
+
|
|
15
|
+
## Problem Statement
|
|
16
|
+
|
|
17
|
+
ViePilot is currently a general-purpose framework. Multi-domain professionals ("kiêm nhiệm")
|
|
18
|
+
working across Web SaaS, Embedded, Data Science, Mobile face:
|
|
19
|
+
- Brainstorm topics irrelevant to their domain
|
|
20
|
+
- Wrong phase templates
|
|
21
|
+
- No cross-project user identity
|
|
22
|
+
- Must re-declare stack/context for every project
|
|
23
|
+
|
|
24
|
+
## Key Design Decisions
|
|
25
|
+
|
|
26
|
+
### 1. Multi-Persona architecture (not single profile)
|
|
27
|
+
- `~/.viepilot/personas/` — named persona files
|
|
28
|
+
- `~/.viepilot/persona.json` — active persona pointer
|
|
29
|
+
- `~/.viepilot/context-map.json` — directory → persona bindings
|
|
30
|
+
|
|
31
|
+
### 2. Layered resolution (3 layers)
|
|
32
|
+
```
|
|
33
|
+
Priority: project > session > global
|
|
34
|
+
1. .viepilot/persona-override.json ← per-project explicit
|
|
35
|
+
2. context-map.json pattern match ← directory-based auto
|
|
36
|
+
3. ~/.viepilot/persona.json (active) ← global default
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 3. Switch + Merge both supported
|
|
40
|
+
- **Switch**: bind project dir to a named persona, change with 1 command
|
|
41
|
+
- **Merge**: create hybrid persona from multiple domains (e.g. IoT Full-stack = web-saas + embedded-iot)
|
|
42
|
+
- Analogy: git branch (switch) + git merge (merge)
|
|
43
|
+
|
|
44
|
+
### 4. Auto-detection from project files
|
|
45
|
+
| Signal file | Detected domain |
|
|
46
|
+
|------------|-----------------|
|
|
47
|
+
| `package.json` + `prisma/` | web-saas |
|
|
48
|
+
| `CMakeLists.txt` + `sdkconfig` | embedded |
|
|
49
|
+
| `requirements.txt` + `notebooks/` | data-science |
|
|
50
|
+
| `pubspec.yaml` / `*.xcodeproj` | mobile |
|
|
51
|
+
| `Dockerfile` + `terraform/` | devops |
|
|
52
|
+
| `pyproject.toml` + `langchain` | ai-product |
|
|
53
|
+
|
|
54
|
+
### 5. Persona schema
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"name": "Web SaaS Dev",
|
|
58
|
+
"domain": "web-saas",
|
|
59
|
+
"role": "full-stack",
|
|
60
|
+
"stacks": ["nextjs", "nestjs", "postgresql"],
|
|
61
|
+
"team_size": "solo",
|
|
62
|
+
"output_style": "lean",
|
|
63
|
+
"brainstorm": {
|
|
64
|
+
"topic_priority": ["auth", "user-data", "api", "admin"],
|
|
65
|
+
"topic_skip": ["embedded", "content-mgmt"]
|
|
66
|
+
},
|
|
67
|
+
"phase_template": "lean-startup",
|
|
68
|
+
"interests": ["ai-integration", "saas", "startup"]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 6. Domain Packs (5 built-in + community)
|
|
73
|
+
| Pack | Extra topics | Phase template | Extra architect pages |
|
|
74
|
+
|------|-------------|----------------|----------------------|
|
|
75
|
+
| `web-saas` | Billing, Multi-tenant, Onboarding | Auth→Core→Monetize→Scale | billing.html, tenant.html |
|
|
76
|
+
| `data-science` | Dataset mgmt, Model versioning, Drift monitoring | Data→EDA→Train→Serve→Monitor | ml-pipeline.html |
|
|
77
|
+
| `mobile` | Push, Offline sync, Store submit | Auth→Core→Offline→Submit | mobile-flow.html |
|
|
78
|
+
| `devops` | IaC, CI/CD, SLO, Incident | Infra→CI/CD→Observe→Runbooks | infra-topology.html |
|
|
79
|
+
| `ai-product` | LLM integration, RAG, Eval/feedback | Wrapper→Prompt→RAG→Eval→UX | llm-arch.html |
|
|
80
|
+
|
|
81
|
+
### 7. vp-persona commands
|
|
82
|
+
```
|
|
83
|
+
/vp-persona → Show active persona
|
|
84
|
+
/vp-persona --create web-saas → Create new persona (wizard)
|
|
85
|
+
/vp-persona --switch embedded → Switch active persona
|
|
86
|
+
/vp-persona --list → List all personas
|
|
87
|
+
/vp-persona --bind . web-saas → Bind current dir to persona
|
|
88
|
+
/vp-persona --auto → Enable auto-detect
|
|
89
|
+
/vp-persona --merge web embedded → Create hybrid persona
|
|
90
|
+
/vp-persona --export / --import → Backup/share personas
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 8. Workflow adaptations when persona active
|
|
94
|
+
- **vp-brainstorm**: topic order reordered by priority; skipped topics hidden; domain pack topics injected
|
|
95
|
+
- **vp-auto**: stack preflight uses persona stacks automatically; persona-context.md injected per task
|
|
96
|
+
- **vp-crystallize**: output_style "lean" → shorter docs; "enterprise" → full docs + compliance
|
|
97
|
+
- **vp-evolve**: new phase suggestions follow persona's phase_template
|
|
98
|
+
|
|
99
|
+
## Phases
|
|
100
|
+
|
|
101
|
+
### Phase 1 — Foundation
|
|
102
|
+
- `vp-persona` skill + wizard (5-question Q&A)
|
|
103
|
+
- `~/.viepilot/personas/` multi-file support
|
|
104
|
+
- `persona-context.md` injection into all skills
|
|
105
|
+
|
|
106
|
+
### Phase 2 — Multi-context
|
|
107
|
+
- `context-map.json` + directory binding (`--bind`)
|
|
108
|
+
- Auto-detection from project files
|
|
109
|
+
- Session-start smart prompt for multi-domain users
|
|
110
|
+
|
|
111
|
+
### Phase 3 — Domain Packs
|
|
112
|
+
- 5 built-in domain packs (web-saas, data-science, mobile, devops, ai-product)
|
|
113
|
+
- Domain pack schema + community extensibility (npm install viepilot-domain-*)
|
|
114
|
+
|
|
115
|
+
### Phase 4 — Merge + Advanced
|
|
116
|
+
- `/vp-persona --merge` hybrid personas
|
|
117
|
+
- Interest-based proactive hints in brainstorm
|
|
118
|
+
- Per-project `persona-override.json`
|
|
119
|
+
|
|
120
|
+
## Open Questions
|
|
121
|
+
- Should domain packs be separate npm packages or bundled?
|
|
122
|
+
- How to handle conflicts when merge produces duplicate topics?
|
|
123
|
+
- Should `persona-context.md` be injected as a system-prompt prefix or as a workflow step?
|
|
124
|
+
|
|
125
|
+
## Project meta intake (FEAT-009)
|
|
126
|
+
- Profile binding: skipped (this is ViePilot framework repo itself)
|
|
127
|
+
|
|
128
|
+
## Background extracted ideas
|
|
129
|
+
- Interest-based proactive suggestions (e.g. "ai-integration" interest → proactive LLM arch hints)
|
|
130
|
+
- Community domain pack registry (viepilot-domain-fintech, viepilot-domain-healthcare...)
|
|
131
|
+
- Persona export/import for team sharing (onboard new dev with same persona)
|