diff --git a/src/__tests__/skills.test.ts b/src/__tests__/skills.test.ts index dceb482..4c21df1 100644 --- a/src/__tests__/skills.test.ts +++ b/src/__tests__/skills.test.ts @@ -654,6 +654,30 @@ scope: 'user', const content = await fse.readFile(contribPath, 'utf-8'); expect(content).toBe('testuser\n'); }); + + it('should NOT copy .git directory when skill source is a git repo', async () => { + const localSkillDir = path.join(homeDir, '.claude/skills', 'git-skill'); + await fse.ensureDir(localSkillDir); + await fse.writeFile(path.join(localSkillDir, 'SKILL.md'), '# Git Skill\nContent here'); + await fse.writeFile(path.join(localSkillDir, 'helper.py'), 'print("hello")'); + // Simulate a .git directory (as if skill was cloned from a git repo) + await fse.ensureDir(path.join(localSkillDir, '.git', 'objects')); + await fse.writeFile(path.join(localSkillDir, '.git', 'HEAD'), 'ref: refs/heads/main'); + + const item = { + name: 'git-skill', + type: 'skills' as const, + sourcePath: localSkillDir, + relativePath: 'skills/git-skill', + }; + + await handler.pushItem(item, teamConfig, localConfig); + + const destDir = path.join(localConfig.repo.localPath, 'skills', 'git-skill'); + expect(await fse.pathExists(path.join(destDir, 'SKILL.md'))).toBe(true); + expect(await fse.pathExists(path.join(destDir, 'helper.py'))).toBe(true); + expect(await fse.pathExists(path.join(destDir, '.git'))).toBe(false); + }); }); describe('SkillsHandler.readContributors', () => { diff --git a/src/utils/fs.ts b/src/utils/fs.ts index 6243f08..ff44fac 100644 --- a/src/utils/fs.ts +++ b/src/utils/fs.ts @@ -8,6 +8,7 @@ const IGNORED_NAMES = new Set([ '.pyc', '.DS_Store', 'node_modules', + '.git', ]); function isIgnored(name: string): boolean {