const path = require('path'); const { createInstallTargetAdapter, createRemappedOperation, isForeignPlatformPath, normalizeRelativePath, planClaudeHooksOperations, } = require('./helpers'); const CLAUDE_ECC_NAMESPACE = 'ecc'; const CLAUDE_PROJECT_COMMONJS_PACKAGE = 'manifests/install-assets/claude-project-scripts-package.json'; function getClaudeManagedDestinationPath(adapter, sourceRelativePath, input) { const normalizedSourcePath = normalizeRelativePath(sourceRelativePath); const targetRoot = adapter.resolveRoot(input); if (normalizedSourcePath === 'rules') { return path.join(targetRoot, 'rules', CLAUDE_ECC_NAMESPACE); } if (normalizedSourcePath.startsWith('rules/')) { return path.join( targetRoot, 'rules', CLAUDE_ECC_NAMESPACE, normalizedSourcePath.slice('rules/'.length) ); } if (normalizedSourcePath === 'skills') { return path.join(targetRoot, 'skills'); } if (normalizedSourcePath.startsWith('skills/')) { return path.join( targetRoot, 'skills', normalizedSourcePath.slice('skills/'.length) ); } if (normalizedSourcePath === 'docs' || normalizedSourcePath.startsWith('docs/')) { return path.join(targetRoot, normalizedSourcePath); } return null; } module.exports = createInstallTargetAdapter({ id: 'claude-project', target: 'claude-project', kind: 'project', rootSegments: ['.claude'], installStatePathSegments: ['ecc', 'install-state.json'], nativeRootRelativePath: '.claude-plugin', planOperations(input, adapter) { const modules = Array.isArray(input.modules) ? input.modules : (input.module ? [input.module] : []); const planningInput = { repoRoot: input.repoRoot, projectRoot: input.projectRoot, homeDir: input.homeDir, }; return modules.flatMap(module => { const paths = Array.isArray(module.paths) ? module.paths : []; const operations = paths .filter(p => !isForeignPlatformPath(p, 'claude')) .flatMap(sourceRelativePath => { if ( module.id === 'hooks-runtime' && normalizeRelativePath(sourceRelativePath) === 'hooks' ) { return planClaudeHooksOperations(adapter, module, planningInput); } const managedDestinationPath = getClaudeManagedDestinationPath( adapter, sourceRelativePath, planningInput ); if (managedDestinationPath) { return [createRemappedOperation( adapter, module.id, sourceRelativePath, managedDestinationPath, { strategy: 'preserve-relative-path' } )]; } return [adapter.createScaffoldOperation(module.id, sourceRelativePath, planningInput)]; }); if (module.id !== 'hooks-runtime') { return operations; } return [ ...['hooks', 'lib'].map(directory => createRemappedOperation( adapter, module.id, CLAUDE_PROJECT_COMMONJS_PACKAGE, path.join(adapter.resolveRoot(planningInput), 'scripts', directory, 'package.json'), { strategy: 'preserve-relative-path' } )), ...operations, ]; }); }, });