mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-30 22:13:28 +08:00
fix: namespace claude managed install paths
This commit is contained in:
committed by
Affaan Mustafa
parent
08d6c82989
commit
e381c8d8a8
@@ -79,9 +79,11 @@ function writeManifestSourceFixture(root) {
|
||||
kind: 'fixture',
|
||||
description: 'Fixture module',
|
||||
paths: [
|
||||
'rules',
|
||||
'src',
|
||||
'standalone.txt',
|
||||
'missing.txt',
|
||||
'skills/demo',
|
||||
path.join('runtime', 'ecc', 'install-state.json'),
|
||||
'.claude-plugin',
|
||||
],
|
||||
@@ -107,6 +109,8 @@ function writeManifestSourceFixture(root) {
|
||||
writeFile(root, path.join('src', 'node_modules', 'ignored.js'), 'console.log("ignored");\n');
|
||||
writeFile(root, path.join('src', '.git', 'ignored.js'), 'console.log("ignored");\n');
|
||||
writeFile(root, path.join('src', 'nested', 'ecc-install-state.json'), '{}\n');
|
||||
writeFile(root, path.join('rules', 'common', 'coding-style.md'), '# Common\n');
|
||||
writeFile(root, path.join('skills', 'demo', 'SKILL.md'), '# Demo\n');
|
||||
writeFile(root, 'standalone.txt', 'standalone\n');
|
||||
writeFile(root, path.join('runtime', 'ecc', 'install-state.json'), '{}\n');
|
||||
writeJson(root, path.join('.claude-plugin', 'plugin.json'), { name: 'fixture' });
|
||||
@@ -194,6 +198,35 @@ function runTests() {
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('plans Claude legacy rules under the default ECC-managed rules directory', () => {
|
||||
const sourceRoot = createTempDir('install-executor-source-');
|
||||
const homeDir = createTempDir('install-executor-home-');
|
||||
const projectRoot = createTempDir('install-executor-project-');
|
||||
try {
|
||||
writeLegacySourceFixture(sourceRoot);
|
||||
writeFile(homeDir, path.join('.claude', 'rules', 'common', 'coding-style.md'), '# User custom rule\n');
|
||||
|
||||
const plan = createLegacyInstallPlan({
|
||||
sourceRoot,
|
||||
homeDir,
|
||||
projectRoot,
|
||||
target: 'claude',
|
||||
languages: ['typescript'],
|
||||
});
|
||||
|
||||
const managedRulesDir = path.join(homeDir, '.claude', 'rules', 'ecc');
|
||||
assert.strictEqual(plan.installRoot, managedRulesDir);
|
||||
assert.ok(operationFor(plan, path.join('.claude', 'rules', 'ecc', 'common', 'coding-style.md')));
|
||||
assert.ok(operationFor(plan, path.join('.claude', 'rules', 'ecc', 'typescript', 'testing.md')));
|
||||
assert.ok(!operationFor(plan, path.join('.claude', 'rules', 'common', 'coding-style.md')));
|
||||
assert.ok(!plan.warnings.some(warning => warning.includes('files may be overwritten')));
|
||||
} finally {
|
||||
cleanup(sourceRoot);
|
||||
cleanup(homeDir);
|
||||
cleanup(projectRoot);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('plans Cursor legacy assets and JSON merge payloads', () => {
|
||||
const sourceRoot = createTempDir('install-executor-source-');
|
||||
const projectRoot = createTempDir('install-executor-project-');
|
||||
@@ -307,6 +340,8 @@ function runTests() {
|
||||
));
|
||||
assert.ok(normalizedSources.includes('src/app.js'));
|
||||
assert.ok(normalizedSources.includes('src/nested/feature.js'));
|
||||
assert.ok(normalizedSources.includes('rules/common/coding-style.md'));
|
||||
assert.ok(normalizedSources.includes('skills/demo/SKILL.md'));
|
||||
assert.ok(normalizedSources.includes('standalone.txt'));
|
||||
assert.ok(normalizedSources.includes('.claude-plugin/plugin.json'));
|
||||
assert.ok(!normalizedSources.includes('missing.txt'));
|
||||
@@ -318,6 +353,14 @@ function runTests() {
|
||||
operation.sourceRelativePath === path.join('.claude-plugin', 'plugin.json')
|
||||
&& operation.destinationPath === path.join(homeDir, '.claude', 'plugin.json')
|
||||
)));
|
||||
assert.ok(plan.operations.some(operation => (
|
||||
operation.sourceRelativePath === path.join('rules', 'common', 'coding-style.md')
|
||||
&& operation.destinationPath === path.join(homeDir, '.claude', 'rules', 'ecc', 'common', 'coding-style.md')
|
||||
)));
|
||||
assert.ok(plan.operations.some(operation => (
|
||||
operation.sourceRelativePath === path.join('skills', 'demo', 'SKILL.md')
|
||||
&& operation.destinationPath === path.join(homeDir, '.claude', 'skills', 'ecc', 'demo', 'SKILL.md')
|
||||
)));
|
||||
assert.deepStrictEqual(plan.warnings, ['fixture warning']);
|
||||
assert.strictEqual(plan.statePreview.request.profile, 'minimal');
|
||||
assert.deepStrictEqual(plan.statePreview.request.includeComponents, ['capability:fixture']);
|
||||
@@ -369,6 +412,8 @@ function runTests() {
|
||||
const applied = applyInstallPlan(plan);
|
||||
|
||||
assert.strictEqual(applied.applied, true);
|
||||
assert.ok(fs.existsSync(path.join(homeDir, '.claude', 'rules', 'ecc', 'common', 'coding-style.md')));
|
||||
assert.ok(fs.existsSync(path.join(homeDir, '.claude', 'skills', 'ecc', 'demo', 'SKILL.md')));
|
||||
assert.ok(fs.existsSync(path.join(homeDir, '.claude', 'src', 'app.js')));
|
||||
assert.ok(fs.existsSync(path.join(homeDir, '.claude', 'standalone.txt')));
|
||||
assert.ok(fs.existsSync(path.join(homeDir, '.claude', 'plugin.json')));
|
||||
|
||||
@@ -65,6 +65,42 @@ function runTests() {
|
||||
assert.strictEqual(statePath, path.join(homeDir, '.claude', 'ecc', 'install-state.json'));
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('plans claude rules and skills under ECC-managed subdirectories', () => {
|
||||
const repoRoot = path.join(__dirname, '..', '..');
|
||||
const homeDir = '/Users/example';
|
||||
|
||||
const plan = planInstallTargetScaffold({
|
||||
target: 'claude',
|
||||
repoRoot,
|
||||
homeDir,
|
||||
modules: [
|
||||
{
|
||||
id: 'rules-core',
|
||||
paths: ['rules'],
|
||||
},
|
||||
{
|
||||
id: 'workflow-quality',
|
||||
paths: ['skills/tdd-workflow'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.ok(
|
||||
plan.operations.some(operation => (
|
||||
normalizedRelativePath(operation.sourceRelativePath) === 'rules'
|
||||
&& operation.destinationPath === path.join(homeDir, '.claude', 'rules', 'ecc')
|
||||
)),
|
||||
'Should install bundled Claude rules under rules/ecc'
|
||||
);
|
||||
assert.ok(
|
||||
plan.operations.some(operation => (
|
||||
normalizedRelativePath(operation.sourceRelativePath) === 'skills/tdd-workflow'
|
||||
&& operation.destinationPath === path.join(homeDir, '.claude', 'skills', 'ecc', 'tdd-workflow')
|
||||
)),
|
||||
'Should install bundled Claude skills under skills/ecc'
|
||||
);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('plans scaffold operations and flattens native target roots', () => {
|
||||
const repoRoot = path.join(__dirname, '..', '..');
|
||||
const projectRoot = '/workspace/app';
|
||||
|
||||
@@ -576,10 +576,10 @@ function runTests() {
|
||||
|
||||
const claudeRoot = path.join(homeDir, '.claude');
|
||||
// Security skill should be installed (from --with)
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'security-review', 'SKILL.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'security-review', 'SKILL.md')),
|
||||
'Should install security-review skill from --with');
|
||||
// Core profile modules should be installed
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'common', 'coding-style.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'ecc', 'common', 'coding-style.md')),
|
||||
'Should install core rules');
|
||||
|
||||
// Install state should record include/exclude
|
||||
@@ -615,12 +615,12 @@ function runTests() {
|
||||
|
||||
const claudeRoot = path.join(homeDir, '.claude');
|
||||
// Orchestration skills should NOT be installed (from --without)
|
||||
assert.ok(!fs.existsSync(path.join(claudeRoot, 'skills', 'dmux-workflows', 'SKILL.md')),
|
||||
assert.ok(!fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'dmux-workflows', 'SKILL.md')),
|
||||
'Should not install orchestration skills');
|
||||
// Developer profile base modules should be installed
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'common', 'coding-style.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'ecc', 'common', 'coding-style.md')),
|
||||
'Should install core rules');
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'tdd-workflow', 'SKILL.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'tdd-workflow', 'SKILL.md')),
|
||||
'Should install workflow skills');
|
||||
|
||||
const statePath = path.join(claudeRoot, 'ecc', 'install-state.json');
|
||||
@@ -653,10 +653,10 @@ function runTests() {
|
||||
|
||||
const claudeRoot = path.join(homeDir, '.claude');
|
||||
// framework-language skill (from lang:typescript) should be installed
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'coding-standards', 'SKILL.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'coding-standards', 'SKILL.md')),
|
||||
'Should install framework-language skills');
|
||||
// Its dependencies should be installed
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'common', 'coding-style.md')),
|
||||
assert.ok(fs.existsSync(path.join(claudeRoot, 'rules', 'ecc', 'common', 'coding-style.md')),
|
||||
'Should install dependency rules-core');
|
||||
|
||||
const statePath = path.join(claudeRoot, 'ecc', 'install-state.json');
|
||||
|
||||
Reference in New Issue
Block a user