@pennyfarthing/core 9.3.0 β 10.0.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/dist/cli/commands/cyclist.d.ts +1 -1
- package/dist/cli/commands/cyclist.d.ts.map +1 -1
- package/dist/cli/commands/cyclist.js +15 -25
- package/dist/cli/commands/cyclist.js.map +1 -1
- package/dist/cli/commands/cyclist.test.js +12 -8
- package/dist/cli/commands/cyclist.test.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +149 -15
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/e2e-fresh-install.test.d.ts +19 -0
- package/dist/cli/commands/e2e-fresh-install.test.d.ts.map +1 -0
- package/dist/cli/commands/e2e-fresh-install.test.js +395 -0
- package/dist/cli/commands/e2e-fresh-install.test.js.map +1 -0
- package/dist/cli/commands/e2e-upgrade.test.d.ts +22 -0
- package/dist/cli/commands/e2e-upgrade.test.d.ts.map +1 -0
- package/dist/cli/commands/e2e-upgrade.test.js +562 -0
- package/dist/cli/commands/e2e-upgrade.test.js.map +1 -0
- package/dist/cli/commands/init-consolidation.test.d.ts +17 -0
- package/dist/cli/commands/init-consolidation.test.d.ts.map +1 -0
- package/dist/cli/commands/init-consolidation.test.js +217 -0
- package/dist/cli/commands/init-consolidation.test.js.map +1 -0
- package/dist/cli/commands/init.js +18 -15
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/persona-config-consolidation.test.d.ts +18 -0
- package/dist/cli/commands/persona-config-consolidation.test.d.ts.map +1 -0
- package/dist/cli/commands/persona-config-consolidation.test.js +230 -0
- package/dist/cli/commands/persona-config-consolidation.test.js.map +1 -0
- package/dist/cli/commands/theme.js +2 -2
- package/dist/cli/commands/theme.js.map +1 -1
- package/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/dist/cli/commands/uninstall.js +2 -1
- package/dist/cli/commands/uninstall.js.map +1 -1
- package/dist/cli/commands/update-consolidation.test.d.ts +19 -0
- package/dist/cli/commands/update-consolidation.test.d.ts.map +1 -0
- package/dist/cli/commands/update-consolidation.test.js +572 -0
- package/dist/cli/commands/update-consolidation.test.js.map +1 -0
- package/dist/cli/commands/update.d.ts +25 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +128 -11
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/utils/manifest.d.ts +3 -3
- package/dist/cli/utils/manifest.d.ts.map +1 -1
- package/dist/cli/utils/manifest.js +21 -12
- package/dist/cli/utils/manifest.js.map +1 -1
- package/dist/cli/utils/settings-consolidation.test.d.ts +13 -0
- package/dist/cli/utils/settings-consolidation.test.d.ts.map +1 -0
- package/dist/cli/utils/settings-consolidation.test.js +227 -0
- package/dist/cli/utils/settings-consolidation.test.js.map +1 -0
- package/dist/cli/utils/settings.d.ts +11 -0
- package/dist/cli/utils/settings.d.ts.map +1 -1
- package/dist/cli/utils/settings.js +59 -6
- package/dist/cli/utils/settings.js.map +1 -1
- package/dist/cli/utils/themes.d.ts +3 -3
- package/dist/cli/utils/themes.d.ts.map +1 -1
- package/dist/cli/utils/themes.js +14 -12
- package/dist/cli/utils/themes.js.map +1 -1
- package/dist/cli/utils/themes.test.d.ts +2 -2
- package/dist/cli/utils/themes.test.js +29 -13
- package/dist/cli/utils/themes.test.js.map +1 -1
- package/dist/workflow/complete-step-integration.test.d.ts +13 -0
- package/dist/workflow/complete-step-integration.test.d.ts.map +1 -0
- package/dist/workflow/complete-step-integration.test.js +163 -0
- package/dist/workflow/complete-step-integration.test.js.map +1 -0
- package/dist/workflow/handoff.test.js +2 -2
- package/dist/workflow/handoff.test.js.map +1 -1
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +6 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/workflow-stepped-schema.test.js +1 -1
- package/dist/workflow/workflow-stepped-schema.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E test for MSSCI-14374: Existing repo upgrade
|
|
3
|
+
*
|
|
4
|
+
* This test sets up an old-style installation with files in legacy .claude/
|
|
5
|
+
* locations, runs `pennyfarthing update` to migrate, and validates that:
|
|
6
|
+
* - Files are migrated to .pennyfarthing/
|
|
7
|
+
* - Symlinks exist for Claude Code compatibility
|
|
8
|
+
* - Doctor passes after migration
|
|
9
|
+
* - Temp directory is cleaned up
|
|
10
|
+
*
|
|
11
|
+
* Acceptance Criteria:
|
|
12
|
+
* AC1: Test creates a temp directory with old-style install layout (.claude/ based)
|
|
13
|
+
* AC2: Test runs `pennyfarthing update` against the old layout
|
|
14
|
+
* AC3: Test validates files migrated to .pennyfarthing/
|
|
15
|
+
* AC4: Test validates symlinks exist for Claude Code compatibility
|
|
16
|
+
* AC5: Test runs doctor and confirms it passes
|
|
17
|
+
* AC6: Test cleans up temp directory afterward
|
|
18
|
+
*
|
|
19
|
+
* Run with: cd packages/core && npm run build && npm test
|
|
20
|
+
*/
|
|
21
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
22
|
+
import assert from 'node:assert';
|
|
23
|
+
import { existsSync, mkdirSync, rmSync, readFileSync, lstatSync, readdirSync, symlinkSync, writeFileSync, chmodSync, } from 'fs';
|
|
24
|
+
import { join, resolve, dirname } from 'path';
|
|
25
|
+
import { tmpdir } from 'os';
|
|
26
|
+
import { execSync, spawnSync } from 'child_process';
|
|
27
|
+
import { fileURLToPath } from 'url';
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = dirname(__filename);
|
|
30
|
+
// Path to the CLI binary (compiled JS)
|
|
31
|
+
const CLI_BIN = resolve(__dirname, '../../../bin/pennyfarthing.js');
|
|
32
|
+
// Path to the real pennyfarthing-dist (for creating fake node_modules)
|
|
33
|
+
// From dist/cli/commands/ β packages/core/dist/cli/commands/ β 5 levels up to repo root
|
|
34
|
+
const REAL_PENNYFARTHING_DIST = resolve(__dirname, '../../../../../pennyfarthing-dist');
|
|
35
|
+
// βββ Helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
36
|
+
function createTestDir() {
|
|
37
|
+
const dir = join(tmpdir(), `pf-e2e-upgrade-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
38
|
+
mkdirSync(dir, { recursive: true });
|
|
39
|
+
return dir;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a fake node_modules tree that symlinks to the real pennyfarthing-dist.
|
|
43
|
+
* This simulates what `npm install pennyfarthing` would produce.
|
|
44
|
+
*/
|
|
45
|
+
function setupNodeModules(testDir) {
|
|
46
|
+
const targetDir = join(testDir, 'node_modules/@pennyfarthing/core');
|
|
47
|
+
mkdirSync(targetDir, { recursive: true });
|
|
48
|
+
// Symlink to the real pennyfarthing-dist so update can find templates, commands, etc.
|
|
49
|
+
symlinkSync(REAL_PENNYFARTHING_DIST, join(targetDir, 'pennyfarthing-dist'));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Initialize a git repo in the test directory so hooks can be installed.
|
|
53
|
+
*/
|
|
54
|
+
function initGitRepo(testDir) {
|
|
55
|
+
execSync('git init', { cwd: testDir, stdio: 'pipe' });
|
|
56
|
+
writeFileSync(join(testDir, '.gitkeep'), '');
|
|
57
|
+
execSync('git add .gitkeep && git commit -m "init"', {
|
|
58
|
+
cwd: testDir,
|
|
59
|
+
stdio: 'pipe',
|
|
60
|
+
env: {
|
|
61
|
+
...process.env,
|
|
62
|
+
GIT_AUTHOR_NAME: 'Test',
|
|
63
|
+
GIT_AUTHOR_EMAIL: 'test@test.com',
|
|
64
|
+
GIT_COMMITTER_NAME: 'Test',
|
|
65
|
+
GIT_COMMITTER_EMAIL: 'test@test.com',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run the pennyfarthing CLI in the test directory.
|
|
71
|
+
*/
|
|
72
|
+
function runCLI(testDir, args) {
|
|
73
|
+
const result = spawnSync('node', [CLI_BIN, ...args], {
|
|
74
|
+
cwd: testDir,
|
|
75
|
+
stdio: 'pipe',
|
|
76
|
+
timeout: 30000,
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
NODE_PATH: '',
|
|
80
|
+
FORCE_COLOR: '0',
|
|
81
|
+
NO_COLOR: '1',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
stdout: result.stdout?.toString() || '',
|
|
86
|
+
stderr: result.stderr?.toString() || '',
|
|
87
|
+
status: result.status,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Extract JSON array from doctor --json output.
|
|
92
|
+
* Doctor outputs header text before the JSON array.
|
|
93
|
+
*/
|
|
94
|
+
function extractDoctorJson(stdout) {
|
|
95
|
+
const jsonStart = stdout.indexOf('[');
|
|
96
|
+
if (jsonStart === -1) {
|
|
97
|
+
throw new Error(`No JSON array found in doctor output: ${stdout.slice(0, 200)}`);
|
|
98
|
+
}
|
|
99
|
+
return JSON.parse(stdout.slice(jsonStart));
|
|
100
|
+
}
|
|
101
|
+
// βββ Constants for verification βββββββββββββββββββββββββββββββββββ
|
|
102
|
+
const CORE_AGENTS = [
|
|
103
|
+
'dev', 'tea', 'sm', 'reviewer', 'architect',
|
|
104
|
+
'pm', 'tech-writer', 'ux-designer', 'devops', 'orchestrator'
|
|
105
|
+
];
|
|
106
|
+
const DIRECTORY_SYMLINKS = [
|
|
107
|
+
{ name: 'agents', link: '.pennyfarthing/agents' },
|
|
108
|
+
{ name: 'guides', link: '.pennyfarthing/guides' },
|
|
109
|
+
{ name: 'output-styles', link: '.pennyfarthing/output-styles' },
|
|
110
|
+
{ name: 'personas', link: '.pennyfarthing/personas' },
|
|
111
|
+
{ name: 'scripts', link: '.pennyfarthing/scripts' },
|
|
112
|
+
{ name: 'workflows', link: '.pennyfarthing/workflows' },
|
|
113
|
+
];
|
|
114
|
+
// Legacy template files that should migrate from .claude/ to .pennyfarthing/
|
|
115
|
+
const LEGACY_TEMPLATE_MIGRATIONS = [
|
|
116
|
+
{ oldPath: '.claude/project/docs/agent-scopes.yaml', newPath: '.pennyfarthing/project/docs/agent-scopes.yaml' },
|
|
117
|
+
{ oldPath: '.claude/project/hooks/setup-env.sh', newPath: '.pennyfarthing/project/hooks/setup-env.sh' },
|
|
118
|
+
{ oldPath: '.claude/project/pennyfarthing-settings.yaml', newPath: '.pennyfarthing/project/pennyfarthing-settings.yaml' },
|
|
119
|
+
{ oldPath: '.claude/preferences.yaml', newPath: '.pennyfarthing/preferences.yaml' },
|
|
120
|
+
{ oldPath: '.claude/persona-config.yaml', newPath: '.pennyfarthing/persona-config.yaml' },
|
|
121
|
+
];
|
|
122
|
+
// βββ Legacy Layout Setup ββββββββββββββββββββββββββββββββββββββββββ
|
|
123
|
+
/**
|
|
124
|
+
* Create an old-style Pennyfarthing installation layout.
|
|
125
|
+
* This simulates what a pre-consolidation install looked like:
|
|
126
|
+
* - Manifest at .claude/manifest.json (legacy location)
|
|
127
|
+
* - Symlinks at .claude/{agents,guides,personas,scripts} (legacy)
|
|
128
|
+
* - Template files at .claude/ locations (legacy)
|
|
129
|
+
* - Sidecars at sprint/sidecars/ (legacy)
|
|
130
|
+
* - settings.local.json as a real file in .claude/ (not symlinked)
|
|
131
|
+
*/
|
|
132
|
+
function createLegacyLayout(testDir) {
|
|
133
|
+
const distPath = join(testDir, 'node_modules/@pennyfarthing/core/pennyfarthing-dist');
|
|
134
|
+
// Create required directories
|
|
135
|
+
mkdirSync(join(testDir, '.claude/project/docs'), { recursive: true });
|
|
136
|
+
mkdirSync(join(testDir, '.claude/project/hooks'), { recursive: true });
|
|
137
|
+
mkdirSync(join(testDir, '.claude/project/commands'), { recursive: true });
|
|
138
|
+
mkdirSync(join(testDir, '.claude/project/skills'), { recursive: true });
|
|
139
|
+
mkdirSync(join(testDir, '.pennyfarthing'), { recursive: true });
|
|
140
|
+
mkdirSync(join(testDir, 'sprint'), { recursive: true });
|
|
141
|
+
mkdirSync(join(testDir, '.session'), { recursive: true });
|
|
142
|
+
// 1. Legacy manifest at .claude/manifest.json
|
|
143
|
+
const manifest = {
|
|
144
|
+
version: '9.0.0', // Old version to trigger update
|
|
145
|
+
installedAt: '2025-12-01T00:00:00.000Z',
|
|
146
|
+
updatedAt: '2025-12-01T00:00:00.000Z',
|
|
147
|
+
projectName: 'test-upgrade',
|
|
148
|
+
installationType: 'symlink',
|
|
149
|
+
nodeModulesPath: 'node_modules/@pennyfarthing/core/pennyfarthing-dist',
|
|
150
|
+
managedPaths: [
|
|
151
|
+
'.claude/commands',
|
|
152
|
+
'.claude/skills',
|
|
153
|
+
'.claude/agents', // Old-style paths
|
|
154
|
+
'.claude/guides',
|
|
155
|
+
'.claude/personas',
|
|
156
|
+
'.claude/scripts',
|
|
157
|
+
],
|
|
158
|
+
fileHashes: {},
|
|
159
|
+
};
|
|
160
|
+
writeFileSync(join(testDir, '.claude/manifest.json'), JSON.stringify(manifest, null, 2));
|
|
161
|
+
// 2. Legacy symlinks at .claude/{agents,guides,personas,scripts}
|
|
162
|
+
// These pointed to node_modules in the old layout
|
|
163
|
+
const legacySymlinkDirs = ['agents', 'guides', 'personas', 'scripts'];
|
|
164
|
+
for (const name of legacySymlinkDirs) {
|
|
165
|
+
const sourcePath = join(distPath, name);
|
|
166
|
+
const linkPath = join(testDir, '.claude', name);
|
|
167
|
+
if (existsSync(sourcePath)) {
|
|
168
|
+
symlinkSync(sourcePath, linkPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// 3. Legacy template files at .claude/ locations
|
|
172
|
+
writeFileSync(join(testDir, '.claude/preferences.yaml'), '# User preferences\ntheme: blade-runner\n');
|
|
173
|
+
writeFileSync(join(testDir, '.claude/persona-config.yaml'), '# Persona config\nactive_theme: blade-runner\n');
|
|
174
|
+
writeFileSync(join(testDir, '.claude/project/docs/agent-scopes.yaml'), '# Agent scopes\nscopes: {}\n');
|
|
175
|
+
writeFileSync(join(testDir, '.claude/project/pennyfarthing-settings.yaml'), '# Settings\nrepos: []\n');
|
|
176
|
+
const setupEnvPath = join(testDir, '.claude/project/hooks/setup-env.sh');
|
|
177
|
+
writeFileSync(setupEnvPath, '#!/bin/bash\n# Setup env\n');
|
|
178
|
+
chmodSync(setupEnvPath, 0o755);
|
|
179
|
+
// 4. shared-context.md (user-owned, should stay at .claude/)
|
|
180
|
+
writeFileSync(join(testDir, '.claude/project/docs/shared-context.md'), '# My Project\nUser-written project description\n');
|
|
181
|
+
// 5. Legacy sidecars at sprint/sidecars/
|
|
182
|
+
for (const agent of CORE_AGENTS) {
|
|
183
|
+
const sidecarDir = join(testDir, `sprint/sidecars/${agent}`);
|
|
184
|
+
mkdirSync(sidecarDir, { recursive: true });
|
|
185
|
+
writeFileSync(join(sidecarDir, 'patterns.md'), `# ${agent} patterns\nLegacy content\n`);
|
|
186
|
+
writeFileSync(join(sidecarDir, 'gotchas.md'), `# ${agent} gotchas\nLegacy content\n`);
|
|
187
|
+
writeFileSync(join(sidecarDir, 'decisions.md'), `# ${agent} decisions\nLegacy content\n`);
|
|
188
|
+
}
|
|
189
|
+
// 6. settings.local.json as a real file (not symlinked) in .claude/
|
|
190
|
+
const settings = {
|
|
191
|
+
permissions: {
|
|
192
|
+
allow: ['Read', 'Grep', 'Glob'],
|
|
193
|
+
},
|
|
194
|
+
hooks: {
|
|
195
|
+
SessionStart: [
|
|
196
|
+
{ hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/hooks/session-start.sh' }] }
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
writeFileSync(join(testDir, '.claude/settings.local.json'), JSON.stringify(settings, null, 2));
|
|
201
|
+
// 7. Copy commands and skills as real directories (like init did)
|
|
202
|
+
// We use the real pennyfarthing-dist as source
|
|
203
|
+
const commandsSrc = join(distPath, 'commands');
|
|
204
|
+
const skillsSrc = join(distPath, 'skills');
|
|
205
|
+
const commandsDest = join(testDir, '.claude/commands');
|
|
206
|
+
const skillsDest = join(testDir, '.claude/skills');
|
|
207
|
+
mkdirSync(commandsDest, { recursive: true });
|
|
208
|
+
mkdirSync(skillsDest, { recursive: true });
|
|
209
|
+
// Copy a few command files
|
|
210
|
+
if (existsSync(commandsSrc)) {
|
|
211
|
+
for (const file of readdirSync(commandsSrc)) {
|
|
212
|
+
const src = join(commandsSrc, file);
|
|
213
|
+
const dest = join(commandsDest, file);
|
|
214
|
+
writeFileSync(dest, readFileSync(src));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Copy skill directories
|
|
218
|
+
if (existsSync(skillsSrc)) {
|
|
219
|
+
for (const entry of readdirSync(skillsSrc)) {
|
|
220
|
+
const srcDir = join(skillsSrc, entry);
|
|
221
|
+
const destDir = join(skillsDest, entry);
|
|
222
|
+
if (lstatSync(srcDir).isDirectory()) {
|
|
223
|
+
mkdirSync(destDir, { recursive: true });
|
|
224
|
+
for (const file of readdirSync(srcDir)) {
|
|
225
|
+
const fileSrc = join(srcDir, file);
|
|
226
|
+
if (!lstatSync(fileSrc).isDirectory()) {
|
|
227
|
+
writeFileSync(join(destDir, file), readFileSync(fileSrc));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// 8. Git hooks (these were in .git/hooks/ in old layout too)
|
|
234
|
+
const hooksDir = join(testDir, '.git/hooks');
|
|
235
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
236
|
+
for (const hook of ['pre-commit', 'pre-push', 'post-merge']) {
|
|
237
|
+
const hookPath = join(hooksDir, hook);
|
|
238
|
+
writeFileSync(hookPath, '#!/bin/bash\n# pennyfarthing hook\nexit 0\n');
|
|
239
|
+
chmodSync(hookPath, 0o755);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// βββ Test Suites ββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
243
|
+
describe('MSSCI-14374: E2E existing repo upgrade', () => {
|
|
244
|
+
let testDir;
|
|
245
|
+
beforeEach(() => {
|
|
246
|
+
testDir = createTestDir();
|
|
247
|
+
setupNodeModules(testDir);
|
|
248
|
+
initGitRepo(testDir);
|
|
249
|
+
createLegacyLayout(testDir);
|
|
250
|
+
});
|
|
251
|
+
afterEach(() => {
|
|
252
|
+
// AC6: Cleans up the temp repo afterward
|
|
253
|
+
if (existsSync(testDir)) {
|
|
254
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
// βββ AC1: Create old-style install layout βββββββββββββββββββββ
|
|
258
|
+
describe('AC1: Test creates a temp directory with old-style install layout', () => {
|
|
259
|
+
it('should have a valid git repo with node_modules', () => {
|
|
260
|
+
assert.ok(existsSync(join(testDir, '.git')), 'Test dir should be a git repo');
|
|
261
|
+
const distPath = join(testDir, 'node_modules/@pennyfarthing/core/pennyfarthing-dist');
|
|
262
|
+
assert.ok(existsSync(distPath), 'node_modules should contain pennyfarthing-dist');
|
|
263
|
+
});
|
|
264
|
+
it('should have legacy manifest at .claude/manifest.json', () => {
|
|
265
|
+
const manifestPath = join(testDir, '.claude/manifest.json');
|
|
266
|
+
assert.ok(existsSync(manifestPath), 'Legacy manifest should exist at .claude/');
|
|
267
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
268
|
+
assert.strictEqual(manifest.installationType, 'symlink', 'Should be symlink type');
|
|
269
|
+
assert.strictEqual(manifest.version, '9.0.0', 'Should have old version');
|
|
270
|
+
});
|
|
271
|
+
it('should have legacy symlinks at .claude/{agents,guides,personas,scripts}', () => {
|
|
272
|
+
const legacyDirs = ['agents', 'guides', 'personas', 'scripts'];
|
|
273
|
+
for (const name of legacyDirs) {
|
|
274
|
+
const legacyPath = join(testDir, '.claude', name);
|
|
275
|
+
assert.ok(existsSync(legacyPath), `Legacy .claude/${name} should exist`);
|
|
276
|
+
assert.ok(lstatSync(legacyPath).isSymbolicLink(), `.claude/${name} should be a symlink in the legacy layout`);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
it('should have legacy template files at .claude/ locations', () => {
|
|
280
|
+
for (const { oldPath } of LEGACY_TEMPLATE_MIGRATIONS) {
|
|
281
|
+
assert.ok(existsSync(join(testDir, oldPath)), `Legacy template ${oldPath} should exist`);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
it('should have legacy sidecars at sprint/sidecars/', () => {
|
|
285
|
+
for (const agent of CORE_AGENTS) {
|
|
286
|
+
const sidecarDir = join(testDir, `sprint/sidecars/${agent}`);
|
|
287
|
+
assert.ok(existsSync(sidecarDir), `Legacy sidecar for ${agent} should exist`);
|
|
288
|
+
assert.ok(existsSync(join(sidecarDir, 'patterns.md')), `Legacy patterns.md for ${agent} should exist`);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
it('should have settings.local.json as a real file (not symlink)', () => {
|
|
292
|
+
const settingsPath = join(testDir, '.claude/settings.local.json');
|
|
293
|
+
assert.ok(existsSync(settingsPath), 'settings.local.json should exist');
|
|
294
|
+
assert.ok(!lstatSync(settingsPath).isSymbolicLink(), 'settings.local.json should be a real file in legacy layout');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
// βββ AC2: Run pennyfarthing update ββββββββββββββββββββββββββββ
|
|
298
|
+
describe('AC2: Test runs pennyfarthing update against the old layout', () => {
|
|
299
|
+
it('should complete update without error', () => {
|
|
300
|
+
const result = runCLI(testDir, ['update']);
|
|
301
|
+
assert.strictEqual(result.status, 0, `Update should exit 0, got ${result.status}.\nStdout: ${result.stdout}\nStderr: ${result.stderr}`);
|
|
302
|
+
});
|
|
303
|
+
it('should report migration activity in output', () => {
|
|
304
|
+
const result = runCLI(testDir, ['update']);
|
|
305
|
+
assert.strictEqual(result.status, 0, 'Update should succeed');
|
|
306
|
+
// Update should mention migration activity
|
|
307
|
+
const output = result.stdout + result.stderr;
|
|
308
|
+
assert.ok(output.includes('Migrated') || output.includes('Updated') || output.includes('Update'), 'Output should indicate migration/update activity');
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
// βββ AC3: Validate files migrated to .pennyfarthing/ ββββββββββ
|
|
312
|
+
describe('AC3: Test validates files migrated to .pennyfarthing/', () => {
|
|
313
|
+
it('should migrate manifest from .claude/ to .pennyfarthing/', () => {
|
|
314
|
+
runCLI(testDir, ['update']);
|
|
315
|
+
// Manifest should now be at .pennyfarthing/
|
|
316
|
+
const newManifestPath = join(testDir, '.pennyfarthing/manifest.json');
|
|
317
|
+
assert.ok(existsSync(newManifestPath), 'Manifest should exist at .pennyfarthing/');
|
|
318
|
+
const manifest = JSON.parse(readFileSync(newManifestPath, 'utf8'));
|
|
319
|
+
assert.strictEqual(manifest.installationType, 'symlink', 'Manifest should remain symlink type');
|
|
320
|
+
assert.ok(manifest.version, 'Manifest should have a version');
|
|
321
|
+
});
|
|
322
|
+
it('should remove legacy manifest from .claude/', () => {
|
|
323
|
+
runCLI(testDir, ['update']);
|
|
324
|
+
assert.ok(!existsSync(join(testDir, '.claude/manifest.json')), 'Legacy manifest should be removed from .claude/');
|
|
325
|
+
});
|
|
326
|
+
it('should migrate template files to .pennyfarthing/', () => {
|
|
327
|
+
runCLI(testDir, ['update']);
|
|
328
|
+
for (const { oldPath, newPath } of LEGACY_TEMPLATE_MIGRATIONS) {
|
|
329
|
+
assert.ok(existsSync(join(testDir, newPath)), `Template should be migrated to ${newPath}`);
|
|
330
|
+
assert.ok(!existsSync(join(testDir, oldPath)), `Legacy template ${oldPath} should be removed after migration`);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
it('should preserve user content in migrated template files', () => {
|
|
334
|
+
runCLI(testDir, ['update']);
|
|
335
|
+
// preferences.yaml should retain user content
|
|
336
|
+
const prefsPath = join(testDir, '.pennyfarthing/preferences.yaml');
|
|
337
|
+
const content = readFileSync(prefsPath, 'utf8');
|
|
338
|
+
assert.ok(content.includes('theme: blade-runner'), 'Migrated preferences should preserve user content');
|
|
339
|
+
});
|
|
340
|
+
it('should migrate sidecars from sprint/sidecars/ to .pennyfarthing/sidecars/', () => {
|
|
341
|
+
runCLI(testDir, ['update']);
|
|
342
|
+
for (const agent of CORE_AGENTS) {
|
|
343
|
+
const newSidecarDir = join(testDir, `.pennyfarthing/sidecars/${agent}`);
|
|
344
|
+
assert.ok(existsSync(newSidecarDir), `Sidecar for ${agent} should exist at .pennyfarthing/sidecars/`);
|
|
345
|
+
// Verify files were migrated
|
|
346
|
+
for (const file of ['patterns.md', 'gotchas.md', 'decisions.md']) {
|
|
347
|
+
assert.ok(existsSync(join(newSidecarDir, file)), `${file} for ${agent} should exist at new location`);
|
|
348
|
+
}
|
|
349
|
+
// Verify content was preserved
|
|
350
|
+
const content = readFileSync(join(newSidecarDir, 'patterns.md'), 'utf8');
|
|
351
|
+
assert.ok(content.includes('Legacy content'), `Sidecar content for ${agent} should be preserved`);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
it('should remove legacy sprint/sidecars/ directory after migration', () => {
|
|
355
|
+
runCLI(testDir, ['update']);
|
|
356
|
+
assert.ok(!existsSync(join(testDir, 'sprint/sidecars')), 'Legacy sprint/sidecars/ should be removed after migration');
|
|
357
|
+
});
|
|
358
|
+
it('should remove legacy .claude/{agents,guides,personas,scripts} symlinks', () => {
|
|
359
|
+
runCLI(testDir, ['update']);
|
|
360
|
+
const legacyDirs = ['agents', 'guides', 'personas', 'scripts'];
|
|
361
|
+
for (const name of legacyDirs) {
|
|
362
|
+
assert.ok(!existsSync(join(testDir, '.claude', name)), `Legacy .claude/${name} should be removed after update`);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
it('should NOT move shared-context.md (user-owned, stays in .claude/)', () => {
|
|
366
|
+
runCLI(testDir, ['update']);
|
|
367
|
+
assert.ok(existsSync(join(testDir, '.claude/project/docs/shared-context.md')), 'shared-context.md should remain at .claude/project/docs/');
|
|
368
|
+
const content = readFileSync(join(testDir, '.claude/project/docs/shared-context.md'), 'utf8');
|
|
369
|
+
assert.ok(content.includes('User-written project description'), 'shared-context.md content should be preserved');
|
|
370
|
+
});
|
|
371
|
+
it('should migrate settings.local.json to .pennyfarthing/', () => {
|
|
372
|
+
runCLI(testDir, ['update']);
|
|
373
|
+
const pennyfarthingSettings = join(testDir, '.pennyfarthing/settings.local.json');
|
|
374
|
+
assert.ok(existsSync(pennyfarthingSettings), 'settings.local.json should exist at .pennyfarthing/');
|
|
375
|
+
// Verify settings have been merged (should include required hooks)
|
|
376
|
+
const settings = JSON.parse(readFileSync(pennyfarthingSettings, 'utf8'));
|
|
377
|
+
assert.ok(settings.hooks, 'Migrated settings should have hooks');
|
|
378
|
+
assert.ok(settings.hooks.SessionStart, 'Should have SessionStart hooks');
|
|
379
|
+
});
|
|
380
|
+
it('should update managedPaths to use .pennyfarthing/ paths', () => {
|
|
381
|
+
runCLI(testDir, ['update']);
|
|
382
|
+
const manifestPath = join(testDir, '.pennyfarthing/manifest.json');
|
|
383
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
384
|
+
// Should have new .pennyfarthing/ paths
|
|
385
|
+
assert.ok(manifest.managedPaths.some((p) => p.startsWith('.pennyfarthing/')), 'managedPaths should include .pennyfarthing/ paths');
|
|
386
|
+
// Should still include .claude/commands and .claude/skills
|
|
387
|
+
assert.ok(manifest.managedPaths.includes('.claude/commands'), 'managedPaths should still include .claude/commands');
|
|
388
|
+
assert.ok(manifest.managedPaths.includes('.claude/skills'), 'managedPaths should still include .claude/skills');
|
|
389
|
+
// Should NOT include old .claude/agents etc.
|
|
390
|
+
assert.ok(!manifest.managedPaths.includes('.claude/agents'), 'managedPaths should NOT include legacy .claude/agents');
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
// βββ AC4: Validate symlinks for Claude Code compatibility βββββ
|
|
394
|
+
describe('AC4: Test validates symlinks exist for Claude Code compatibility', () => {
|
|
395
|
+
it('should create .pennyfarthing/ symlinks to node_modules', () => {
|
|
396
|
+
runCLI(testDir, ['update']);
|
|
397
|
+
for (const { name, link } of DIRECTORY_SYMLINKS) {
|
|
398
|
+
const linkPath = join(testDir, link);
|
|
399
|
+
assert.ok(existsSync(linkPath), `Symlink ${link} should exist after update`);
|
|
400
|
+
assert.ok(lstatSync(linkPath).isSymbolicLink(), `${link} should be a symlink (not a copy)`);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
it('should maintain .claude/commands as real directory', () => {
|
|
404
|
+
runCLI(testDir, ['update']);
|
|
405
|
+
const commandsDir = join(testDir, '.claude/commands');
|
|
406
|
+
assert.ok(existsSync(commandsDir), '.claude/commands should exist');
|
|
407
|
+
assert.ok(!lstatSync(commandsDir).isSymbolicLink(), '.claude/commands should be a real directory (for Claude Code discovery)');
|
|
408
|
+
const files = readdirSync(commandsDir);
|
|
409
|
+
assert.ok(files.length > 0, '.claude/commands should contain files');
|
|
410
|
+
assert.ok(files.some(f => f.endsWith('.md')), '.claude/commands should contain .md command files');
|
|
411
|
+
});
|
|
412
|
+
it('should maintain .claude/skills as real directory', () => {
|
|
413
|
+
runCLI(testDir, ['update']);
|
|
414
|
+
const skillsDir = join(testDir, '.claude/skills');
|
|
415
|
+
assert.ok(existsSync(skillsDir), '.claude/skills should exist');
|
|
416
|
+
assert.ok(!lstatSync(skillsDir).isSymbolicLink(), '.claude/skills should be a real directory (for Claude Code discovery)');
|
|
417
|
+
const entries = readdirSync(skillsDir);
|
|
418
|
+
assert.ok(entries.length > 0, '.claude/skills should contain skill directories');
|
|
419
|
+
});
|
|
420
|
+
it('should create settings.local.json symlink at .claude/', () => {
|
|
421
|
+
runCLI(testDir, ['update']);
|
|
422
|
+
const claudeSettings = join(testDir, '.claude/settings.local.json');
|
|
423
|
+
assert.ok(existsSync(claudeSettings), '.claude/settings.local.json should exist');
|
|
424
|
+
assert.ok(lstatSync(claudeSettings).isSymbolicLink(), '.claude/settings.local.json should be a symlink (pointing to .pennyfarthing/)');
|
|
425
|
+
// Verify the symlink target resolves correctly
|
|
426
|
+
const settings = JSON.parse(readFileSync(claudeSettings, 'utf8'));
|
|
427
|
+
assert.ok(settings.hooks, 'settings.local.json via symlink should have hooks');
|
|
428
|
+
});
|
|
429
|
+
it('should keep .claude/ directory structure intact for Claude Code', () => {
|
|
430
|
+
runCLI(testDir, ['update']);
|
|
431
|
+
// These paths must exist for Claude Code to discover commands/skills
|
|
432
|
+
assert.ok(existsSync(join(testDir, '.claude')), '.claude/ should exist');
|
|
433
|
+
assert.ok(existsSync(join(testDir, '.claude/commands')), '.claude/commands/ should exist');
|
|
434
|
+
assert.ok(existsSync(join(testDir, '.claude/skills')), '.claude/skills/ should exist');
|
|
435
|
+
assert.ok(existsSync(join(testDir, '.claude/settings.local.json')), '.claude/settings.local.json should exist');
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
// βββ AC5: Run doctor and confirm it passes ββββββββββββββββββββ
|
|
439
|
+
describe('AC5: Test runs doctor and confirms it passes', () => {
|
|
440
|
+
it('should pass doctor check with no failures after update', () => {
|
|
441
|
+
const updateResult = runCLI(testDir, ['update']);
|
|
442
|
+
assert.strictEqual(updateResult.status, 0, 'Update should succeed first');
|
|
443
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
444
|
+
assert.strictEqual(doctorResult.status, 0, `Doctor should exit 0.\nStdout: ${doctorResult.stdout}\nStderr: ${doctorResult.stderr}`);
|
|
445
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
446
|
+
const failures = results.filter((r) => r.status === 'fail');
|
|
447
|
+
assert.strictEqual(failures.length, 0, `Doctor should have 0 failures after upgrade, got ${failures.length}: ${JSON.stringify(failures, null, 2)}`);
|
|
448
|
+
});
|
|
449
|
+
it('doctor should show manifest as passing', () => {
|
|
450
|
+
runCLI(testDir, ['update']);
|
|
451
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
452
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
453
|
+
const manifestCheck = results.find((r) => r.name === 'manifest/exists');
|
|
454
|
+
assert.ok(manifestCheck, 'Doctor should check manifest');
|
|
455
|
+
assert.strictEqual(manifestCheck.status, 'pass', 'Manifest check should pass after upgrade');
|
|
456
|
+
});
|
|
457
|
+
it('doctor should show all directory symlinks as passing', () => {
|
|
458
|
+
runCLI(testDir, ['update']);
|
|
459
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
460
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
461
|
+
const directorySymlinkNames = ['agents', 'guides', 'output-styles', 'personas', 'scripts', 'workflows'];
|
|
462
|
+
for (const name of directorySymlinkNames) {
|
|
463
|
+
const check = results.find((r) => r.name === `symlink/${name}`);
|
|
464
|
+
assert.ok(check, `Doctor should check symlink/${name}`);
|
|
465
|
+
assert.strictEqual(check.status, 'pass', `symlink/${name} should pass after upgrade, got ${check.status}: ${check.detail}`);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
it('doctor should show settings.local.json as passing', () => {
|
|
469
|
+
runCLI(testDir, ['update']);
|
|
470
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
471
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
472
|
+
const settingsCheck = results.find((r) => r.name === 'settings.local.json');
|
|
473
|
+
assert.ok(settingsCheck, 'Doctor should check settings.local.json');
|
|
474
|
+
assert.strictEqual(settingsCheck.status, 'pass', 'Settings check should pass after upgrade');
|
|
475
|
+
});
|
|
476
|
+
it('doctor should show session-start hook as passing', () => {
|
|
477
|
+
runCLI(testDir, ['update']);
|
|
478
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
479
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
480
|
+
const hookCheck = results.find((r) => r.name === 'settings/session-start-hook');
|
|
481
|
+
assert.ok(hookCheck, 'Doctor should check session-start hook');
|
|
482
|
+
assert.strictEqual(hookCheck.status, 'pass', 'Session-start hook should pass after upgrade');
|
|
483
|
+
});
|
|
484
|
+
it('doctor should detect no legacy files after migration', () => {
|
|
485
|
+
runCLI(testDir, ['update']);
|
|
486
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
487
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
488
|
+
// If doctor has a legacy file check, it should pass
|
|
489
|
+
const legacyChecks = results.filter((r) => r.name.startsWith('legacy/'));
|
|
490
|
+
for (const check of legacyChecks) {
|
|
491
|
+
assert.notStrictEqual(check.status, 'fail', `Legacy check ${check.name} should not fail after migration`);
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
// βββ AC6: Cleanup verification ββββββββββββββββββββββββββββββββ
|
|
496
|
+
describe('AC6: Cleans up the temp repo afterward', () => {
|
|
497
|
+
it('test cleanup in afterEach removes the temp directory', () => {
|
|
498
|
+
assert.ok(existsSync(testDir), 'Test dir should exist during test');
|
|
499
|
+
// afterEach will clean up
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
// βββ Idempotency βββββββββββββββββββββββββββββββββββββββββββββ
|
|
503
|
+
describe('Idempotency: Running update twice should not break things', () => {
|
|
504
|
+
it('should succeed when update is run twice', () => {
|
|
505
|
+
const result1 = runCLI(testDir, ['update']);
|
|
506
|
+
assert.strictEqual(result1.status, 0, 'First update should succeed');
|
|
507
|
+
const result2 = runCLI(testDir, ['update']);
|
|
508
|
+
assert.strictEqual(result2.status, 0, 'Second update should succeed');
|
|
509
|
+
// Doctor should still pass after double-update
|
|
510
|
+
const doctorResult = runCLI(testDir, ['doctor', '--json']);
|
|
511
|
+
assert.strictEqual(doctorResult.status, 0, 'Doctor should pass after double update');
|
|
512
|
+
const results = extractDoctorJson(doctorResult.stdout);
|
|
513
|
+
const failures = results.filter((r) => r.status === 'fail');
|
|
514
|
+
assert.strictEqual(failures.length, 0, 'No doctor failures after double update');
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
// βββ Edge cases βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
518
|
+
describe('Edge cases', () => {
|
|
519
|
+
it('should handle missing legacy files gracefully', () => {
|
|
520
|
+
// Remove some legacy files to test partial migration
|
|
521
|
+
rmSync(join(testDir, '.claude/preferences.yaml'), { force: true });
|
|
522
|
+
rmSync(join(testDir, '.claude/persona-config.yaml'), { force: true });
|
|
523
|
+
const result = runCLI(testDir, ['update']);
|
|
524
|
+
assert.strictEqual(result.status, 0, `Update should succeed even with missing legacy files.\nStdout: ${result.stdout}\nStderr: ${result.stderr}`);
|
|
525
|
+
});
|
|
526
|
+
it('should handle already-migrated sidecars (no duplicate)', () => {
|
|
527
|
+
// Pre-create a sidecar at the new location with different content
|
|
528
|
+
const newSidecarDir = join(testDir, '.pennyfarthing/sidecars/dev');
|
|
529
|
+
mkdirSync(newSidecarDir, { recursive: true });
|
|
530
|
+
writeFileSync(join(newSidecarDir, 'patterns.md'), '# Already at new location\n');
|
|
531
|
+
const result = runCLI(testDir, ['update']);
|
|
532
|
+
assert.strictEqual(result.status, 0, 'Update should succeed');
|
|
533
|
+
// Existing new-location content should NOT be overwritten
|
|
534
|
+
const content = readFileSync(join(newSidecarDir, 'patterns.md'), 'utf8');
|
|
535
|
+
assert.ok(content.includes('Already at new location'), 'Pre-existing sidecar content should not be overwritten');
|
|
536
|
+
});
|
|
537
|
+
it('should fail without node_modules', () => {
|
|
538
|
+
// Create a legacy layout without node_modules
|
|
539
|
+
const bareDir = createTestDir();
|
|
540
|
+
initGitRepo(bareDir);
|
|
541
|
+
mkdirSync(join(bareDir, '.claude'), { recursive: true });
|
|
542
|
+
mkdirSync(join(bareDir, '.pennyfarthing'), { recursive: true });
|
|
543
|
+
writeFileSync(join(bareDir, '.pennyfarthing/manifest.json'), JSON.stringify({
|
|
544
|
+
version: '9.0.0',
|
|
545
|
+
installationType: 'symlink',
|
|
546
|
+
projectName: 'test',
|
|
547
|
+
installedAt: new Date().toISOString(),
|
|
548
|
+
updatedAt: new Date().toISOString(),
|
|
549
|
+
managedPaths: [],
|
|
550
|
+
fileHashes: {},
|
|
551
|
+
}));
|
|
552
|
+
try {
|
|
553
|
+
const result = runCLI(bareDir, ['update']);
|
|
554
|
+
assert.notStrictEqual(result.status, 0, 'Update should fail without node_modules');
|
|
555
|
+
}
|
|
556
|
+
finally {
|
|
557
|
+
rmSync(bareDir, { recursive: true, force: true });
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
//# sourceMappingURL=e2e-upgrade.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e-upgrade.test.js","sourceRoot":"","sources":["../../../src/cli/commands/e2e-upgrade.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for MSSCI-14370: Update init command for bootstrapping install
|
|
3
|
+
*
|
|
4
|
+
* These tests verify that the init command creates the consolidated .pennyfarthing/
|
|
5
|
+
* layout established by epic-85 stories 1.2-1.5.
|
|
6
|
+
*
|
|
7
|
+
* Key changes tested:
|
|
8
|
+
* - Manifest at .pennyfarthing/manifest.json (not .claude/)
|
|
9
|
+
* - Template files placed under .pennyfarthing/ (not .claude/)
|
|
10
|
+
* - managedPaths in manifest reflect new layout
|
|
11
|
+
* - Backward compatibility with legacy .claude/ manifest
|
|
12
|
+
* - Directory structure includes .pennyfarthing/project/* dirs
|
|
13
|
+
*
|
|
14
|
+
* Run with: cd packages/core && npm run build && npm test
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=init-consolidation.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-consolidation.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init-consolidation.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|