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.
Files changed (52) hide show
  1. package/CHANGELOG.md +288 -0
  2. package/README.md +6 -6
  3. package/bin/viepilot.cjs +140 -1
  4. package/bin/vp-tools.cjs +204 -0
  5. package/docs/brainstorm/session-2026-04-20.md +261 -0
  6. package/docs/brainstorm/session-2026-04-24.md +131 -0
  7. package/docs/brainstorm/session-2026-04-25.md +109 -0
  8. package/docs/skills-reference.md +22 -0
  9. package/docs/user/features/adapters.md +2 -2
  10. package/docs/user/features/scaffold-first.md +62 -0
  11. package/docs/user/features/skill-registry.md +125 -0
  12. package/lib/adapters/antigravity.cjs +5 -4
  13. package/lib/domain-packs/ai-product.json +33 -0
  14. package/lib/domain-packs/data-science.json +33 -0
  15. package/lib/domain-packs/devops.json +33 -0
  16. package/lib/domain-packs/mobile.json +33 -0
  17. package/lib/domain-packs/web-saas.json +33 -0
  18. package/lib/skill-installer.cjs +274 -0
  19. package/lib/skill-registry.cjs +212 -0
  20. package/lib/viepilot-calibrate.cjs +279 -0
  21. package/lib/viepilot-persona.cjs +446 -0
  22. package/lib/viepilot-update.cjs +113 -0
  23. package/package.json +1 -1
  24. package/skills/vp-audit/SKILL.md +67 -9
  25. package/skills/vp-auto/SKILL.md +54 -0
  26. package/skills/vp-brainstorm/SKILL.md +124 -2
  27. package/skills/vp-crystallize/SKILL.md +82 -0
  28. package/skills/vp-debug/SKILL.md +37 -0
  29. package/skills/vp-design/SKILL.md +219 -0
  30. package/skills/vp-docs/SKILL.md +37 -0
  31. package/skills/vp-evolve/SKILL.md +69 -6
  32. package/skills/vp-info/SKILL.md +37 -0
  33. package/skills/vp-pause/SKILL.md +37 -0
  34. package/skills/vp-persona/SKILL.md +207 -0
  35. package/skills/vp-proposal/SKILL.md +37 -0
  36. package/skills/vp-request/SKILL.md +62 -6
  37. package/skills/vp-resume/SKILL.md +37 -0
  38. package/skills/vp-rollback/SKILL.md +61 -1
  39. package/skills/vp-skills/SKILL.md +311 -0
  40. package/skills/vp-status/SKILL.md +37 -0
  41. package/skills/vp-task/SKILL.md +37 -0
  42. package/skills/vp-ui-components/SKILL.md +37 -0
  43. package/skills/vp-update/SKILL.md +37 -0
  44. package/templates/phase/TASK.md +7 -0
  45. package/templates/project/PROJECT-CONTEXT.md +76 -0
  46. package/workflows/audit.md +131 -0
  47. package/workflows/autonomous.md +199 -0
  48. package/workflows/brainstorm.md +1172 -9
  49. package/workflows/crystallize.md +639 -3
  50. package/workflows/design.md +601 -0
  51. package/workflows/evolve.md +9 -0
  52. 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)