viepilot 1.9.5 → 1.9.8

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 CHANGED
@@ -19,6 +19,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
19
19
 
20
20
  - None yet.
21
21
 
22
+ ## [1.9.8] - 2026-04-02
23
+
24
+ ### Fixed
25
+
26
+ - **BUG-005**: `claude-code` install target không mirror `workflows/`, `bin/`, `templates/` sang `~/.claude/viepilot/` dẫn đến tất cả skills bị broken trên máy không có Cursor. Fix: `buildInstallPlan` nay tạo `claudeViepilotDir = ~/.claude/viepilot/`, mirror toàn bộ artifacts, và thêm bước `rewrite_paths_in_dir` để replace `.cursor/viepilot` → `.claude/viepilot` trong SKILL.md files. Cursor targets không bị ảnh hưởng. (+6 tests, 314 total pass)
27
+
28
+ ## [1.9.7] - 2026-04-02
29
+
30
+ ### Fixed
31
+
32
+ - **ENH-024**: Fix chuỗi truyền tải ui-direction bị đứt qua crystallize → vp-auto:
33
+ - `crystallize.md` Step 1A: đổi trigger thành hard check mandatory khi `.viepilot/ui-direction/` exists (không còn soft heuristic "if indicates").
34
+ - `crystallize.md` Step 10: thêm "UI Direction context injection" — inject `context_required` trỏ vào `notes.md` + `style.css` + `pages/*.html` vào task files cho UI tasks.
35
+ - `autonomous.md` Step 3a: thêm "UI Direction safety check" — warn + auto-load latest session nếu UI task thiếu ui-direction trong context_required.
36
+ - `templates/project/AI-GUIDE.md`: thêm 2 rows ui-direction vào Quick Lookup table + footnote hướng dẫn resolve `{session}`.
37
+
38
+ ## [1.9.6] - 2026-04-02
39
+
40
+ ### Fixed
41
+
42
+ - **ENH-023**: `workflows/autonomous.md` Step 3 Handle Result PASS — thêm `Update ROADMAP.md: sync phase progress % và task count nếu phase status/progress thay đổi` vào danh sách update sau `CHANGELOG.md`. Trước đây ROADMAP.md chỉ được sync tại phase-complete (Step 5a), bỏ sót task-level progress.
43
+
22
44
  ## [1.9.5] - 2026-04-02
23
45
 
24
46
  ### Added
@@ -94,6 +94,7 @@ function buildInstallPlan(packageRoot, envSource = process.env, opts = {}) {
94
94
  const installTargets = Array.isArray(opts.installTargets) ? opts.installTargets : [];
95
95
  const installClaudeSkills = installTargets.includes('claude-code');
96
96
  const claudeSkillsDir = installClaudeSkills ? path.join(home, '.claude', 'skills') : null;
97
+ const claudeViepilotDir = installClaudeSkills ? path.join(home, '.claude', 'viepilot') : null;
97
98
 
98
99
  let wantPathShim = opts.wantPathShim;
99
100
  if (wantPathShim === undefined) {
@@ -152,6 +153,55 @@ function buildInstallPlan(packageRoot, envSource = process.env, opts = {}) {
152
153
  steps.push({ kind: 'copy_dir', from: src, to: dest });
153
154
  }
154
155
  }
156
+
157
+ // BUG-005: mirror workflows/templates/bin/lib to ~/.claude/viepilot/
158
+ if (claudeViepilotDir) {
159
+ for (const sub of [
160
+ 'workflows',
161
+ path.join('templates', 'project'),
162
+ path.join('templates', 'phase'),
163
+ 'bin',
164
+ 'lib',
165
+ ]) {
166
+ steps.push({ kind: 'mkdir', path: path.join(claudeViepilotDir, sub) });
167
+ }
168
+
169
+ for (const ent of listDirEntries(root, 'workflows')) {
170
+ const src = path.join(root, 'workflows', ent.name);
171
+ const dest = path.join(claudeViepilotDir, 'workflows', ent.name);
172
+ steps.push(ent.isDirectory() ? { kind: 'copy_dir', from: src, to: dest } : { kind: 'copy_file', from: src, to: dest });
173
+ }
174
+
175
+ for (const ent of listDirEntries(root, path.join('templates', 'project'))) {
176
+ const src = path.join(root, 'templates', 'project', ent.name);
177
+ const dest = path.join(claudeViepilotDir, 'templates', 'project', ent.name);
178
+ steps.push(ent.isDirectory() ? { kind: 'copy_dir', from: src, to: dest } : { kind: 'copy_file', from: src, to: dest });
179
+ }
180
+
181
+ for (const ent of listDirEntries(root, path.join('templates', 'phase'))) {
182
+ const src = path.join(root, 'templates', 'phase', ent.name);
183
+ const dest = path.join(claudeViepilotDir, 'templates', 'phase', ent.name);
184
+ steps.push(ent.isDirectory() ? { kind: 'copy_dir', from: src, to: dest } : { kind: 'copy_file', from: src, to: dest });
185
+ }
186
+
187
+ for (const f of ['vp-tools.cjs', 'viepilot.cjs']) {
188
+ steps.push({ kind: 'copy_file', from: path.join(root, 'bin', f), to: path.join(claudeViepilotDir, 'bin', f) });
189
+ }
190
+ steps.push({
191
+ kind: 'copy_file',
192
+ from: path.join(root, 'lib', 'cli-shared.cjs'),
193
+ to: path.join(claudeViepilotDir, 'lib', 'cli-shared.cjs'),
194
+ });
195
+
196
+ // Rewrite execution_context paths in mirrored skill files
197
+ steps.push({
198
+ kind: 'rewrite_paths_in_dir',
199
+ dir: claudeSkillsDir,
200
+ glob: '**/*.md',
201
+ from: '.cursor/viepilot',
202
+ to: '.claude/viepilot',
203
+ });
204
+ }
155
205
  }
156
206
 
157
207
  for (const ent of listDirEntries(root, 'workflows')) {
@@ -245,6 +295,7 @@ function buildInstallPlan(packageRoot, envSource = process.env, opts = {}) {
245
295
  paths: {
246
296
  cursorSkillsDir,
247
297
  claudeSkillsDir,
298
+ claudeViepilotDir,
248
299
  viepilotDir,
249
300
  viepilotUserDataDir,
250
301
  viepilotProfilesDir,
@@ -268,6 +319,9 @@ function formatPlanLines(plan) {
268
319
  if (plan.paths.claudeSkillsDir) {
269
320
  lines.push(` skills (Claude Code): ${plan.paths.claudeSkillsDir}`);
270
321
  }
322
+ if (plan.paths.claudeViepilotDir) {
323
+ lines.push(` viepilot (Claude Code): ${plan.paths.claudeViepilotDir}`);
324
+ }
271
325
  lines.push(` viepilot: ${plan.paths.viepilotDir}`);
272
326
  if (plan.paths.viepilotUserDataDir) {
273
327
  lines.push(` userData (~/.viepilot): ${plan.paths.viepilotUserDataDir}`);
@@ -302,6 +356,9 @@ function formatPlanLines(plan) {
302
356
  lines.push(`${n}. path shim: ${s.links.map((l) => `${l.path} -> ${l.target}`).join('; ')}`);
303
357
  if (s.note) lines.push(` (${s.note})`);
304
358
  break;
359
+ case 'rewrite_paths_in_dir':
360
+ lines.push(`${n}. rewrite_paths_in_dir ${s.dir}: "${s.from}" → "${s.to}" in ${s.glob}`);
361
+ break;
305
362
  default:
306
363
  lines.push(`${n}. ${JSON.stringify(s)}`);
307
364
  }
@@ -465,6 +522,29 @@ function applyInstallPlan(plan, options = {}) {
465
522
  }
466
523
  }
467
524
  break;
525
+ case 'rewrite_paths_in_dir': {
526
+ if (dryRun) {
527
+ logs.push(`[dry-run] rewrite_paths_in_dir ${step.dir}: "${step.from}" → "${step.to}" in ${step.glob}`);
528
+ break;
529
+ }
530
+ const rewriteDir = (dir) => {
531
+ if (!fs.existsSync(dir)) return;
532
+ for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
533
+ const fullPath = path.join(dir, ent.name);
534
+ if (ent.isDirectory()) {
535
+ rewriteDir(fullPath);
536
+ } else if (ent.isFile() && ent.name.endsWith('.md')) {
537
+ const content = fs.readFileSync(fullPath, 'utf8');
538
+ if (content.includes(step.from)) {
539
+ fs.writeFileSync(fullPath, content.split(step.from).join(step.to), 'utf8');
540
+ logs.push(`rewrite: ${fullPath}`);
541
+ }
542
+ }
543
+ }
544
+ };
545
+ rewriteDir(step.dir);
546
+ break;
547
+ }
468
548
  default:
469
549
  logs.push(`unknown step kind: ${JSON.stringify(step)}`);
470
550
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viepilot",
3
- "version": "1.9.5",
3
+ "version": "1.9.8",
4
4
  "description": "**Autonomous Vibe Coding Framework / Bộ khung phát triển tự động có kiểm soát**",
5
5
  "main": "index.js",
6
6
  "bin": {