viepilot 1.9.7 → 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 +6 -0
- package/lib/viepilot-install.cjs +80 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,12 @@ 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
|
+
|
|
22
28
|
## [1.9.7] - 2026-04-02
|
|
23
29
|
|
|
24
30
|
### Fixed
|
package/lib/viepilot-install.cjs
CHANGED
|
@@ -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
|
}
|