From 454508cbe236e0f359a72ba48033cd8083e239a1 Mon Sep 17 00:00:00 2001 From: Yasuhisa Yoshida Date: Thu, 31 Jul 2025 07:47:27 +0900 Subject: [PATCH] feat: exclude documentation files from command installation Add functionality to automatically exclude README.md and CLAUDE.md files from being installed as slash commands when using 'cccsc add user/repo'. Changes: - Add shouldExcludeFile function to filter documentation files - Integrate exclusion logic into findMarkdownFiles - Support case-insensitive matching - Add comprehensive test coverage - Simplify file name normalization (remove hyphen/underscore conversion) This prevents documentation files from cluttering the slash command autocomplete list, improving user experience. --- src/utils/github.js | 31 ++++++++++++++++++++++++++++++- tests/utils/github-simple.test.js | 21 ++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/utils/github.js b/src/utils/github.js index 396d923..11bc312 100644 --- a/src/utils/github.js +++ b/src/utils/github.js @@ -1,6 +1,28 @@ import axios from 'axios'; import { logWarning } from './errors.js'; +// Default documentation files to exclude from command installation +const DEFAULT_EXCLUDED_FILES = [ + 'readme', + 'claude' +]; + +/** + * Check if a markdown file should be excluded from command installation + * @param {string} fileName - File name without extension + * @returns {boolean} True if file should be excluded + */ +export function shouldExcludeFile(fileName) { + // Handle invalid inputs + if (typeof fileName !== 'string' || !fileName) { + return false; + } + + // Simple case-insensitive check + const normalizedName = fileName.toLowerCase(); + return DEFAULT_EXCLUDED_FILES.includes(normalizedName); +} + export function parseRepositoryPath(repoPath) { const parts = repoPath.split('/'); @@ -74,10 +96,17 @@ export async function findMarkdownFiles(user, repo, basePath = '', branch = 'mai for (const item of contents) { if (item.type === 'file' && item.name.endsWith('.md')) { + const fileName = item.name.replace('.md', ''); + + // Skip documentation files + if (shouldExcludeFile(fileName)) { + continue; + } + const relativePath = basePath ? `${basePath}/${item.name}` : item.name; files.push({ path: relativePath, - name: item.name.replace('.md', ''), + name: fileName, fullPath: item.path }); } else if (item.type === 'dir') { diff --git a/tests/utils/github-simple.test.js b/tests/utils/github-simple.test.js index c6d886b..ceda41d 100644 --- a/tests/utils/github-simple.test.js +++ b/tests/utils/github-simple.test.js @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { parseRepositoryPath } from '../../src/utils/github.js'; +import { parseRepositoryPath, shouldExcludeFile } from '../../src/utils/github.js'; describe('GitHub Utils - Simple Tests', () => { describe('parseRepositoryPath', () => { @@ -35,4 +35,23 @@ describe('GitHub Utils - Simple Tests', () => { expect(() => parseRepositoryPath('')).toThrow('Invalid repository path format. Expected user/repo or user/repo/command'); }); }); + + describe('shouldExcludeFile', () => { + test('should exclude README and CLAUDE files', () => { + expect(shouldExcludeFile('README')).toBe(true); + expect(shouldExcludeFile('readme')).toBe(true); + expect(shouldExcludeFile('CLAUDE')).toBe(true); + expect(shouldExcludeFile('claude')).toBe(true); + }); + + test('should not exclude command files', () => { + expect(shouldExcludeFile('NOT_TO_INCLUDE_FILE')).toBe(false); + }); + + test('should handle invalid input', () => { + expect(shouldExcludeFile('')).toBe(false); + expect(shouldExcludeFile(null)).toBe(false); + expect(shouldExcludeFile(undefined)).toBe(false); + }); + }); }); \ No newline at end of file