feat(skill): Add Claude Agent Skills generation support#998
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThis PR introduces Claude Agent Skills generation support to repomix, enabling users to generate skill output in SKILL.md format with project references and metadata. It adds CLI options, interactive prompts, skill orchestration logic, tech stack detection, and new core modules to handle skill packaging and output alongside standard repomix functionality. Changes
Sequence DiagramsequenceDiagram
participant User
participant CLI as CLI Interface
participant Prompt as Skill Prompts
participant Packager as Packager
participant SkillGen as Skill Generator
participant FileSystem as File System
User->>CLI: Run with --skill-generate [name]
CLI->>CLI: Validate skillGenerate option
CLI->>Prompt: Request skill location (personal/project)
Prompt->>User: Display location selector
User->>Prompt: Choose location
Prompt->>FileSystem: Check if skill dir exists
alt Directory exists
Prompt->>User: Confirm overwrite?
User->>Prompt: Confirm or cancel
end
Prompt->>CLI: Return skillDir & location
CLI->>Packager: pack() with skillDir in PackOptions
Packager->>SkillGen: packSkill(params) when skillGenerate is defined
SkillGen->>SkillGen: Generate skill references & metadata
SkillGen->>SkillGen: Detect tech stack
SkillGen->>SkillGen: Generate SKILL.md & sections
SkillGen->>FileSystem: Write SKILL.md & references
FileSystem->>FileSystem: Create references/ directory
SkillGen->>Packager: Return PackResult
Packager->>CLI: Return early (skip standard output)
CLI->>CLI: Report skill generation complete
CLI->>User: Display skillDir path
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–60 minutes
Possibly related PRs
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying repomix with
|
| Latest commit: |
7e5a431
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6c1fc8e6.repomix.pages.dev |
| Branch Preview URL: | https://feat-agent-skills.repomix.pages.dev |
Summary of ChangesHello @yamadashy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the tool's capabilities by introducing the ability to generate Claude Agent Skills. This feature streamlines the process of creating AI-ready representations of codebases, providing a standardized and comprehensive format for AI agents to consume. It focuses on delivering rich context, including project structure, file contents, and technological insights, to enhance AI's understanding and interaction with software projects. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #998 +/- ##
==========================================
- Coverage 90.38% 89.50% -0.88%
==========================================
Files 110 120 +10
Lines 7890 9192 +1302
Branches 1528 1662 +134
==========================================
+ Hits 7131 8227 +1096
- Misses 759 965 +206 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Implement Claude Agent Skills format output support for Repomix. This feature was requested in issue #952 to enable seamless integration with Claude Code's skill system. New CLI option: repomix --generate-skill <name> Output structure: .claude/skills/<name>/ ├── SKILL.md # Entry point with YAML frontmatter └── references/ └── codebase.md # Packed codebase in Markdown format Features: - Skill name auto-converts to kebab-case (max 64 chars) - SKILL.md includes usage guidance for reading the codebase - Incompatible with --stdout and --copy options - MCP tool `generate_skill` for programmatic access New files: - src/core/output/skillUtils.ts - src/core/output/outputStyles/skillStyle.ts - src/core/packager/writeSkillOutput.ts - src/mcp/tools/generateSkillTool.ts Closes #952
Improve the Claude Agent Skills generation feature: - Rename CLI option from --generate-skill to --skill-generate [name] - Make skill name optional with auto-generation (repomix-reference-<folder>) - Split skill output into multiple reference files: - summary.md: Purpose, format description, and notes - structure.md: Directory tree view - files.md: Complete file contents - git-diffs.md: Uncommitted changes (optional) - git-logs.md: Recent commit history (optional) - Move skill-related code to src/core/output/skill/ folder - Extract shared language mapping to outputStyleUtils.ts - Add 100+ language mappings for syntax highlighting
Refactor and improve the skill generation feature based on code review: - Split generateSkillOutput into generateSkillReferences and generateSkillMdFromReferences to avoid double generation - Add try-catch error handling to writeSkillOutput with proper permission error messages - Add unit tests for skillSectionGenerators (12 tests) - Add validation tests for --skill-generate flag combinations - Update createMockConfig to support skillGenerate and remoteUrl
Add @clack/prompts-based selection for skill output location: - Personal Skills (~/.claude/skills/) - default, available across all projects - Project Skills (.claude/skills/) - shared with team via git Features: - Interactive prompt to choose skill location - Overwrite confirmation when skill directory already exists - Works with both local and remote repositories
When Personal Skills location is selected, the summary was showing a relative path (.claude/skills/) instead of the actual path (~/.claude/skills/). Now passes the computed skillDir to reportResults.
When the skill directory is under the current working directory, show a relative path (e.g., .claude/skills/my-skill) instead of an absolute path for better readability.
Apply the same relative/absolute path display logic to regular repomix output, not just skill output. Shows relative path when the output file is under the current working directory.
Change message structure to show the question first, then the path on a separate line with dimmed styling for better readability.
Extract the relative/absolute path display logic into a reusable getDisplayPath function and use it in both cliReport.ts and skillPrompts.ts for consistent path display.
Display the number of lines next to each file in the directory
structure section of skill output. This helps when using grep
to find specific files by line count.
Example:
src/
index.ts (42 lines)
utils.ts (128 lines)
- Mention line counts in directory structure for easier file identification - Explain that files use `## File: <file-path>` format for direct grep searches
Skill output is designed for referencing external codebases (e.g., GitHub repositories) as persistent skills. Git diffs (uncommitted changes) and git logs (commit history) are not meaningful in this context since: - Remote repositories have no uncommitted changes - Commit history is less relevant for reference skills This simplifies the skill output to include only: - SKILL.md - references/summary.md - references/structure.md - references/files.md
Restructure SKILL.md to be more practical and scannable: - Add reference files table with descriptions - Include Quick Reference section with concrete examples - Show exact grep patterns for finding files - Display file format examples for understanding structure - Move statistics inline with header for brevity
Add Overview, Common Use Cases, and Tips sections to make the template more actionable and instantly understandable. Remove redundant File Format section (delegated to summary.md). Changes: - Add Overview section explaining when to use this skill - Add Common Use Cases with concrete scenarios (understand feature, debug, find usages) - Add Tips section for effective usage - Remove File Format section to reduce redundancy
…tput Add new features to improve skill output for understanding codebases: - Add tech-stack.md: Auto-detect languages, frameworks, and dependencies from package.json, requirements.txt, go.mod, Cargo.toml, etc. - Add file statistics section to SKILL.md with language breakdown and largest files list - Rename structure.md to project-structure.md for clarity - Add total lines count to SKILL.md header
Remove remoteUrl from config schema and pass pre-computed skillName through CLI options instead. This provides cleaner separation between configuration and runtime data. - Add generateDefaultSkillNameFromUrl() for remote repository names - Update generateDefaultSkillName() to only handle local directories - Pass skillName through DefaultActionTask to packager
Move skill prompt utilities to a dedicated prompts directory for better organization, consistent with the reporters directory pattern.
- Show all dependencies without truncation (removed 20/10 limits) - Add runtime version detection (.node-version, .nvmrc, .tool-versions, etc.) - Add configuration files section to tech-stack.md - Move statistics section from SKILL.md to summary.md - Update summary.md to use multi-file format language - Increase largest files display from 5 to 10 - Improve generate_skill MCP tool description with skill types and paths
Remove generateGitDiffsSection and generateGitLogsSection functions and their tests as they are no longer used in the skill generation flow. These became dead code after removing git diffs/logs from skill output.
634ab13 to
19887e2
Compare
Instead of creating separate variables and passing them through the task, directly update cliOptions.skillName and cliOptions.skillDir. This simplifies the code flow and removes redundant fields from DefaultActionTask interface.
19887e2 to
54a1391
Compare
Reorganize skill generation code for better domain separation: - Move files from core/output/skill/ to core/skill/ (5 files) - Move writeSkillOutput.ts from core/packager/ to core/skill/ - Create packSkill.ts to encapsulate skill generation logic - Simplify packager.ts by delegating skill generation to packSkill() - Add re-exports in outputGenerate.ts for backward compatibility This change improves code organization by: - Separating skill domain from output domain - Reducing packager.ts complexity - Centralizing all skill-related code in one location
Skill feature is new in this branch, so backward compatibility re-exports are not needed. Also fix writeSkillOutput.ts to import SkillOutputResult from packSkill.ts directly.
- Remove redundant second calculateMetrics call in packSkill.ts (skillMetrics already contains the same result) - Fix MCP generateSkillTool to pre-compute skillDir explicitly to avoid interactive prompts in non-interactive MCP context
- Add validation in validateSkillName to reject path separators (/, \), null bytes, and dot-only names (., .., ...) - Add absolute path validation in MCP generateSkillTool - Add directory existence check before skill generation in MCP tool - Add existing skill directory check to prevent silent overwrites - Add security tests for path traversal prevention
Add comprehensive tests for: - packSkill.ts: generateSkillReferences, generateSkillMdFromReferences, packSkill - skillPrompts.ts: getSkillBaseDir, promptSkillLocation - generateSkillTool.ts: MCP tool registration, input validation, error handling
The 'styl' is a valid file extension for Stylus CSS preprocessor.
The typos spell checker expects the config file to be named _typos.toml (with underscore) not .typos.toml (with dot).
Move styl exception from _typos.toml to the existing typos.toml file. The 'styl' word is the file extension for Stylus CSS preprocessor.
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
src/cli/actions/remoteAction.ts (1)
117-124: Consider the clipboard behavior with skill generation.When
skillGenerateis enabled, the clipboard functionality (if enabled viacopyToClipboard) will copy the wrong content. The existingcopyToClipboardIfEnabledfunction likely operates on the standard output file, not the skill package. Consider either:
- Disabling clipboard copy when skill generation is active
- Updating clipboard logic to copy the SKILL.md content
This aligns with a previous review comment about this same concern.
🧹 Nitpick comments (13)
src/core/output/outputGeneratorTypes.ts (1)
26-26: RenderContext now exposes per-file line countsAdding
fileLineCountstoRenderContextis a good fit for the new line-count–aware skill outputs. If you want to mirror the immutability style ofprocessedFiles, you could type this asReadonly<Record<string, number>>, but it’s not required for correctness.src/cli/actions/defaultAction.ts (1)
55-79: Skill generation wiring looks solid; consider narrowing report optionsThe new
config.skillGeneratehandling is coherent:
- Correctly rejects incompatible combinations with
--stdoutand--copy.- Resolves
cliOptions.skillNameonce (respecting precomputed values from other flows) and only prompts for a location whenskillDiris missing.- Ensures
reportResultscan show the skill directory viacliOptions.skillDir.One small refinement:
reportResultsonly needsskillDir, but you pass the fullCliOptionsobject. For clarity and to decouple reporting from CLI concerns, consider passing a narrower{ skillDir: cliOptions.skillDir }object instead.Also applies to: 122-123, 319-322
tests/core/skill/writeSkillOutput.test.ts (1)
5-51: Happy path is well covered; consider tests for tech-stack and error branchesThese tests nicely cover the directory layout and writes for
SKILL.md,summary.md,project-structure.md, andfiles.md, plus the return value.To lock in behavior further, consider adding:
- A case where
output.references.techStackis present to asserttech-stack.mdis written.- A case where
deps.writeFileordeps.mkdirthrowsEPERM/EACCESto verify the specializedRepomixErrormessage, and one generic error to cover the fallback branch.This would fully exercise
writeSkillOutput’s branching.Also applies to: 53-76
tests/core/skill/skillStatistics.test.ts (1)
65-77: Solid coverage; watch for locale-sensitivity in number formatting assertionsThe tests exercise both
calculateStatisticsandgenerateStatisticsSectionvery well. One minor concern is the reliance on specifictoLocaleStringoutput ('10,000','5,000'): if the Node runtime locale isn’t US-style, those expectations could fail even though the code is correct.Consider either:
- Explicitly formatting with a fixed locale in the implementation (e.g.,
toLocaleString('en-US')) to guarantee the comma style, or- Relaxing the tests (e.g., regex that only checks for digit grouping) so they’re robust across locales.
Also applies to: 117-177
src/core/skill/skillStyle.ts (1)
3-11: Template and rendering are clear; consider caching the compiled templateThe SKILL.md Handlebars template and
SkillRenderContextshape look good, and the conditionals aroundhasTechStackare straightforward.Since the template is static, you could avoid recompiling it on every
generateSkillMdcall by compiling once at module load:const skillTemplate = getSkillTemplate(); const compiledSkillTemplate = Handlebars.compile(skillTemplate); export const generateSkillMd = (context: SkillRenderContext): string => { return `${compiledSkillTemplate(context).trim()}\n`; };This keeps behavior identical while shaving a bit of overhead.
Also applies to: 18-108
src/cli/prompts/skillPrompts.ts (1)
15-18: Consider returningnevertype for testability.The
onCancelOperationfunction callsprocess.exit(0), which works correctly for CLI but makes unit testing difficult since it terminates the process. The injectabledepspattern is already used for other dependencies, butprocess.exitisn't mockable here.Consider adding
process.exitto the injectable deps to improve testability:export const promptSkillLocation = async ( skillName: string, cwd: string, deps = { select: prompts.select, confirm: prompts.confirm, isCancel: prompts.isCancel, access: fs.access, + exit: (code: number) => process.exit(code), }, ): Promise<SkillPromptResult> => { + const onCancelOperation = () => { + prompts.cancel('Skill generation cancelled.'); + deps.exit(0); + };tests/core/skill/skillTechStack.test.ts (1)
7-32: Consider adding a test for malformed JSON handling.The tests cover valid JSON in
package.json, but there's no test for howdetectTechStackhandles malformed JSON content. This could help ensure robust error handling.test('should handle malformed package.json gracefully', () => { const files: ProcessedFile[] = [ { path: 'package.json', content: '{ invalid json' }, ]; // Depending on implementation, this should either return null // or handle the error gracefully expect(() => detectTechStack(files)).not.toThrow(); });src/core/skill/skillSectionGenerators.ts (2)
79-84: Global Handlebars helper registration may cause subtle issues.The helper registration uses a global check and mutates
Handlebars.helpers. While the guard condition prevents duplicate registration, this pattern can cause issues in concurrent test environments or if the helper needs different behavior in different contexts.Consider registering the helper once at module load time or using a local Handlebars instance:
+// Register helper once at module load +if (!Handlebars.helpers.getFileExtension) { + Handlebars.registerHelper('getFileExtension', (filePath: string) => { + return getLanguageFromFilePath(filePath); + }); +} + export const generateFilesSection = (context: RenderContext): string => { if (!context.filesEnabled) { return ''; } - // Register the helper if not already registered - if (!Handlebars.helpers.getFileExtension) { - Handlebars.registerHelper('getFileExtension', (filePath: string) => { - return getLanguageFromFilePath(filePath); - }); - } - const template = Handlebars.compile(`# Files
10-45: Consider pre-compiling Handlebars templates for performance.Each function compiles its Handlebars template on every invocation. For frequently called functions, this adds unnecessary overhead.
Pre-compile templates at module load:
const summaryTemplate = Handlebars.compile(`{{{generationHeader}}} # Summary ...`); export const generateSummarySection = (context: RenderContext, statisticsSection?: string): string => { return summaryTemplate({ ...context, statisticsSection }).trim(); };Also applies to: 51-68, 74-98
tests/core/skill/packSkill.test.ts (1)
239-283: Consider adding a test foroptions.skillNameprecedence.Based on the implementation in
packSkill.ts(lines 203-205),options.skillNametakes highest precedence. Adding a test to verify this would strengthen coverage.test('should use options.skillName over config.skillGenerate', async () => { const mockConfig = createMockConfig({ skillGenerate: 'config-skill-name' }); const mockFiles = createMockProcessedFiles(); const params: PackSkillParams = { rootDirs: ['/test/project'], config: mockConfig, options: { skillName: 'options-skill-name', skillDir: '/test/.claude/skills/options-skill-name' }, // ... other params }; // Assert that the skill is generated with 'options-skill-name', not 'config-skill-name' });src/core/skill/skillUtils.ts (1)
50-59: Verify handling of empty rootDirs array.If
rootDirsis empty,rootDirs[0]will beundefined, defaulting to'.', which then resolves to the current directory name. While this fallback behavior is reasonable, it may not be immediately obvious to callers. Consider documenting this behavior or adding explicit validation.src/core/skill/skillTechStack.ts (1)
492-498: Simplify root-level file detection logic.The current logic for determining if a file is at the root level is complex and difficult to understand. The nested conditions with split operations and depth checks make the intent unclear.
Consider simplifying to make the intent explicit:
for (const file of processedFiles) { - // Only check root-level files (no directory separator in path) - const fileName = file.path.split('/').pop() || file.path; - if (file.path !== fileName && !file.path.startsWith('./')) { - // Skip files in subdirectories - const dirDepth = file.path.split('/').length - 1; - if (dirDepth > 0) continue; - } + // Only check root-level files (no directory separator in path) + const normalizedPath = file.path.startsWith('./') ? file.path.slice(2) : file.path; + const isRootLevel = !normalizedPath.includes('/'); + if (!isRootLevel) continue; + + const fileName = normalizedPath;This makes it clear that files at the root level are those without any
/in their normalized path.src/core/skill/packSkill.ts (1)
203-205: Consider extracting skill name resolution logic.The nested ternary operation with type checking makes this logic hard to read and understand at a glance.
Extract to a helper function for clarity:
const resolveSkillName = ( options: PackOptions, config: RepomixConfigMerged, rootDirs: string[], generateDefault: typeof generateDefaultSkillName ): string => { if (options.skillName) { return options.skillName; } if (typeof config.skillGenerate === 'string') { return config.skillGenerate; } return generateDefault(rootDirs); }; // Usage: const skillName = resolveSkillName(options, config, rootDirs, deps.generateDefaultSkillName);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (41)
.gitignore(1 hunks)src/cli/actions/defaultAction.ts(5 hunks)src/cli/actions/remoteAction.ts(3 hunks)src/cli/actions/workers/defaultActionWorker.ts(2 hunks)src/cli/cliReport.ts(3 hunks)src/cli/cliRun.ts(1 hunks)src/cli/prompts/skillPrompts.ts(1 hunks)src/cli/types.ts(1 hunks)src/config/configLoad.ts(1 hunks)src/config/configSchema.ts(1 hunks)src/core/file/fileTreeGenerate.ts(1 hunks)src/core/output/outputGenerate.ts(2 hunks)src/core/output/outputGeneratorTypes.ts(1 hunks)src/core/output/outputStyleUtils.ts(1 hunks)src/core/output/outputStyles/markdownStyle.ts(2 hunks)src/core/packager.ts(3 hunks)src/core/skill/packSkill.ts(1 hunks)src/core/skill/skillSectionGenerators.ts(1 hunks)src/core/skill/skillStatistics.ts(1 hunks)src/core/skill/skillStyle.ts(1 hunks)src/core/skill/skillTechStack.ts(1 hunks)src/core/skill/skillUtils.ts(1 hunks)src/core/skill/writeSkillOutput.ts(1 hunks)src/mcp/mcpServer.ts(3 hunks)src/mcp/tools/generateSkillTool.ts(1 hunks)tests/cli/actions/defaultAction.test.ts(1 hunks)tests/cli/actions/defaultAction.tokenCountTree.test.ts(4 hunks)tests/cli/actions/workers/defaultActionWorker.test.ts(7 hunks)tests/cli/cliReport.test.ts(6 hunks)tests/cli/prompts/skillPrompts.test.ts(1 hunks)tests/core/output/outputStyles/markdownStyle.test.ts(2 hunks)tests/core/skill/packSkill.test.ts(1 hunks)tests/core/skill/skillSectionGenerators.test.ts(1 hunks)tests/core/skill/skillStatistics.test.ts(1 hunks)tests/core/skill/skillStyle.test.ts(1 hunks)tests/core/skill/skillTechStack.test.ts(1 hunks)tests/core/skill/skillUtils.test.ts(1 hunks)tests/core/skill/writeSkillOutput.test.ts(1 hunks)tests/mcp/tools/generateSkillTool.test.ts(1 hunks)tests/testing/testUtils.ts(2 hunks)typos.toml(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-18T15:12:57.179Z
Learnt from: CR
Repo: yamadashy/repomix PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T15:12:57.179Z
Learning: .agents/rules/base.md
Applied to files:
.gitignore
🧬 Code graph analysis (19)
src/core/output/outputStyles/markdownStyle.ts (1)
src/core/output/outputStyleUtils.ts (1)
getLanguageFromFilePath(220-223)
tests/core/skill/writeSkillOutput.test.ts (1)
src/core/skill/writeSkillOutput.ts (1)
writeSkillOutput(17-58)
src/mcp/tools/generateSkillTool.ts (5)
src/mcp/tools/mcpToolRuntime.ts (3)
buildMcpToolErrorResponse(234-248)buildMcpToolSuccessResponse(215-227)convertErrorToJson(166-208)src/core/skill/skillUtils.ts (1)
generateDefaultSkillName(111-116)src/cli/prompts/skillPrompts.ts (1)
getSkillBaseDir(23-28)src/cli/types.ts (1)
CliOptions(4-67)src/cli/cliRun.ts (1)
runCli(219-270)
src/core/skill/writeSkillOutput.ts (2)
src/core/skill/packSkill.ts (1)
SkillOutputResult(52-55)src/shared/errorHandle.ts (1)
RepomixError(6-11)
src/mcp/mcpServer.ts (1)
src/mcp/tools/generateSkillTool.ts (1)
registerGenerateSkillTool(48-145)
tests/cli/cliReport.test.ts (1)
src/cli/cliReport.ts (1)
reportSummary(65-124)
src/cli/actions/workers/defaultActionWorker.ts (1)
src/core/packager.ts (1)
pack(55-179)
src/cli/actions/defaultAction.ts (3)
src/shared/errorHandle.ts (1)
RepomixError(6-11)src/core/skill/skillUtils.ts (1)
generateDefaultSkillName(111-116)src/cli/prompts/skillPrompts.ts (1)
promptSkillLocation(33-91)
tests/core/skill/skillStyle.test.ts (1)
src/core/skill/skillStyle.ts (2)
getSkillTemplate(18-99)generateSkillMd(104-108)
tests/core/skill/skillStatistics.test.ts (1)
src/core/skill/skillStatistics.ts (2)
calculateStatistics(113-158)generateStatisticsSection(163-196)
src/cli/cliReport.ts (2)
src/core/packager.ts (1)
PackResult(19-33)src/config/configSchema.ts (1)
RepomixConfigMerged(158-158)
tests/core/skill/packSkill.test.ts (2)
tests/testing/testUtils.ts (1)
createMockConfig(15-47)src/core/skill/packSkill.ts (5)
generateSkillReferences(69-139)SkillReferencesResult(38-47)generateSkillMdFromReferences(145-163)PackSkillParams(165-179)packSkill(185-248)
src/core/packager.ts (4)
src/index.ts (2)
pack(4-4)RepomixProgressCallback(40-40)src/config/configSchema.ts (1)
RepomixConfigMerged(158-158)website/server/src/utils/logger.ts (1)
logMemoryUsage(64-72)src/shared/memoryUtils.ts (1)
logMemoryUsage(46-51)
tests/core/skill/skillTechStack.test.ts (1)
src/core/skill/skillTechStack.ts (2)
detectTechStack(479-545)generateTechStackMd(550-624)
src/core/skill/packSkill.ts (12)
src/config/configSchema.ts (1)
RepomixConfigMerged(158-158)src/core/git/gitDiffHandle.ts (1)
GitDiffResult(7-10)src/core/git/gitLogHandle.ts (1)
GitLogResult(21-24)src/core/skill/skillUtils.ts (3)
validateSkillName(26-44)generateProjectName(50-59)generateSkillDescription(65-69)src/core/output/outputGenerate.ts (1)
createRenderContext(42-69)src/core/skill/skillStatistics.ts (2)
calculateStatistics(113-158)generateStatisticsSection(163-196)src/core/skill/skillTechStack.ts (2)
detectTechStack(479-545)generateTechStackMd(550-624)src/core/skill/skillSectionGenerators.ts (3)
generateSummarySection(10-45)generateStructureSection(51-68)generateFilesSection(74-98)src/core/skill/skillStyle.ts (1)
generateSkillMd(104-108)src/core/packager.ts (2)
PackOptions(50-53)PackResult(19-33)src/index.ts (1)
RepomixProgressCallback(40-40)src/shared/memoryUtils.ts (1)
withMemoryLogging(71-87)
src/cli/prompts/skillPrompts.ts (1)
src/cli/cliReport.ts (1)
getDisplayPath(13-15)
tests/core/skill/skillSectionGenerators.test.ts (2)
src/core/output/outputGeneratorTypes.ts (1)
RenderContext(16-38)src/core/skill/skillSectionGenerators.ts (3)
generateSummarySection(10-45)generateStructureSection(51-68)generateFilesSection(74-98)
src/core/output/outputGenerate.ts (1)
src/core/output/outputGeneratorTypes.ts (2)
OutputGeneratorContext(6-14)RenderContext(16-38)
tests/core/skill/skillUtils.test.ts (1)
src/core/skill/skillUtils.ts (4)
toKebabCase(11-19)validateSkillName(26-44)generateProjectName(50-59)generateSkillDescription(65-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (29)
src/core/output/outputGenerate.ts (1)
42-42: LGTM!Exporting
createRenderContextand addingfileLineCountsto the render context enables the skill generation workflow to leverage existing rendering infrastructure. The integration is clean and maintains backward compatibility.Also applies to: 56-56
.gitignore (1)
47-48: LGTM!The ignore pattern correctly excludes auto-generated skill reference directories that match the naming convention
repomix-reference-<folder-name>as described in the PR objectives.typos.toml (1)
15-17: LGTM!The addition of "styl" to the extend-words configuration correctly prevents the typo checker from flagging the Stylus CSS preprocessor file extension, which aligns with the new language mappings introduced in this PR.
tests/testing/testUtils.ts (1)
17-17: LGTM!The changes properly support testing the new skill generation feature:
- Using nullish coalescing for
cwdallows tests to override the working directory- Conditionally spreading
skillGeneratemaintains proper typing for CLI-only propertiesAlso applies to: 44-45
src/core/output/outputStyleUtils.ts (2)
1-211: LGTM!The extension-to-language mapping is comprehensive and well-organized, covering a wide range of programming languages, frameworks, data formats, and tooling. The categorization by comments (JavaScript/TypeScript, Web frameworks, etc.) enhances maintainability.
220-223: LGTM!The implementation correctly handles edge cases:
- Files without extensions return an empty string
- Dotfiles (e.g.,
.gitignore) gracefully fall through to empty string- Case-insensitive matching via
toLowerCase()- Unknown extensions default to empty string
The function is concise and defensive with the optional chaining operator.
tests/core/output/outputStyles/markdownStyle.test.ts (1)
146-146: LGTM!These test updates correctly fix the language mappings:
.sassfiles now map tosass(notscss) - these are distinct Sass syntaxes.cfiles now map toc(notcpp) - these are different languagesThe corrections align with the accurate language mappings introduced in
outputStyleUtils.ts.Also applies to: 161-161
tests/cli/actions/defaultAction.tokenCountTree.test.ts (1)
112-112: LGTM!The test expectations correctly reflect the updated
reportResultssignature, which now accepts a fourth parameter (ReportOptions) to support the new skill generation workflow. Usingexpect.any(Object)provides appropriate flexibility for these test cases.Also applies to: 129-129, 160-160, 191-191
src/mcp/mcpServer.ts (1)
9-47: MCPgenerate_skilltool wiring looks correctImporting and registering
registerGenerateSkillToolplus mentioninggenerate_skillexplicitly inMCP_SERVER_INSTRUCTIONSkeeps the MCP capabilities and documentation in sync; registration order is consistent with existing tools.src/config/configLoad.ts (1)
233-235: Conditional merge ofskillGeneratefrom CLI is appropriateLimiting
skillGeneratetocliConfigand only adding it when notundefinedavoids surprising defaults and keeps config-file usage unchanged while enabling the new skill-generation flow.src/cli/cliRun.ts (1)
171-176:--skill-generateoption is cleanly integratedThe new “Skill Generation (Experimental)” group and
--skill-generate [name]flag are consistent with existing CLI patterns and align with the downstreamCliOptions.skillGeneratehandling.tests/cli/actions/defaultAction.test.ts (1)
308-392: Skill generation CLI tests cover key config and validation pathsThe added tests for
buildCliConfig(string vs booleanskillGenerate) and the error cases with--stdout/--copyexercise the critical branches of the new skill-generation flow and should guard against regressions in option compatibility.src/cli/actions/workers/defaultActionWorker.ts (1)
58-90: ForwardingskillName/skillDirintopackis correctly implementedDeriving
packOptionsfromcliOptionsand passing it as the last argument topackin both stdin and directory branches aligns with the updatedpacksignature and ensures skill-generation options are honored consistently.tests/cli/prompts/skillPrompts.test.ts (1)
1-132: Skill prompt tests are thorough and well-isolatedThe
createMockDepshelper plusprocess.exitspying give solid coverage ofgetSkillBaseDirandpromptSkillLocation, including overwrite and cancel flows, without leaking real exits or filesystem access into the tests.src/cli/types.ts (1)
58-62: Skill-related fields onCliOptionsalign with CLI and internal usageDefining
skillGenerateasstring | booleanand adding internalskillName/skillDirfields matches the new--skill-generateflag behavior and the worker/packager wiring for skill generation, while keeping these options clearly scoped in one place.src/config/configSchema.ts (1)
133-143: Skill generation flag schema matches CLI usageThe new
skillGenerate: z.union([z.string(), z.boolean()]).optional()aligns withCliOptions.skillGenerateand the wayconfig.skillGenerateis consumed indefaultAction. No issues from a schema / merge perspective.tests/cli/cliReport.test.ts (1)
52-52: reportSummary invocation updates look correctAll
reportSummarycalls now pass the project path as the first parameter, matching the new(cwd, packResult, config, options?)signature while keeping the existing assertions intact.Also applies to: 79-79, 107-107, 134-134, 162-162, 188-188
src/core/skill/writeSkillOutput.ts (1)
17-57: writeSkillOutput implementation matches the intended contractThe function correctly:
- Creates
<skillDir>/referenceswithrecursive: true.- Writes
SKILL.md,summary.md,project-structure.md,files.md, andtech-stack.mdonly when present.- Wraps filesystem errors in
RepomixError, with special handling for EPERM/EACCES.This aligns with the documented structure and the associated tests.
src/cli/actions/remoteAction.ts (1)
211-243: LGTM! Robust skill output copying with good error handling.The function properly handles the skill directory copy with appropriate early returns, recursive copying, and clear error messages for permission issues.
src/cli/prompts/skillPrompts.ts (2)
61-63: LGTM!The cancel handling after
isCancelchecks is correctly placed. The flow properly exits early when the user cancels either the location selection or the overwrite confirmation prompt.Also applies to: 82-84
67-74: LGTM!Using
fs.accessto check directory existence with a try-catch is the correct pattern. This avoids TOCTOU issues since the actual directory creation happens later in the workflow.tests/core/skill/skillTechStack.test.ts (1)
1-330: Comprehensive test coverage for tech stack detection.The test suite thoroughly covers detection across multiple ecosystems (Node.js, Python, Go, Rust), version manager files, and configuration files. Good coverage of edge cases including subdirectory filtering and empty sections.
src/core/packager.ts (2)
50-53: LGTM!Clean interface definition for skill generation options. The optional fields allow flexible usage.
128-149: LGTM on the skill generation branch.The conditional check correctly requires both
config.skillGenerate !== undefinedandoptions.skillDirbefore delegating topackSkill. This ensures skill generation only occurs when explicitly requested with a valid output directory. The early return cleanly separates skill generation from normal output flow.src/core/skill/skillSectionGenerators.ts (1)
51-68: LGTM!The structure section correctly guards with
directoryStructureEnabledand usesgenerateTreeStringWithLineCountsto include line counts in the directory tree output.tests/core/skill/packSkill.test.ts (3)
19-54: LGTM!Good test structure for
generateSkillReferencescovering the happy path with valid data. The mock dependencies are properly injected and assertions verify key output fields.
197-237: Good error handling test for missing skillDir.This correctly verifies that
packSkillthrows a descriptive error whenskillDiris missing, which is an important validation.
285-327: LGTM on skill name resolution tests.The tests correctly verify the precedence logic:
- When
config.skillGenerateis a string, it uses that value and doesn't callgenerateDefaultSkillName- When
config.skillGenerateis a boolean, it callsgenerateDefaultSkillNameto derive the nameAlso applies to: 329-371
src/core/skill/skillUtils.ts (1)
78-95: The function correctly handles all URL formats, including SSH format. The regex pattern/\/([^/]+)$/successfully extracts the repository name fromgit@github.com:user/repo.gitby matching the final path segment after the colon. No changes needed.
- Replace process.exit() with OperationCancelledError in skillPrompts.ts - Centralize Handlebars helper registration in outputStyleUtils.ts - Add path normalization validation in generateSkillTool.ts - Set idempotentHint to true for generate_skill MCP tool - Add skillGenerate config merge tests in configLoad.test.ts - Add path normalization test in generateSkillTool.test.ts
Code Review for PR #998: Claude Agent Skills Generation SupportI've completed a thorough review of this PR that adds Claude Agent Skills generation support to Repomix. Overall, this is a well-structured and comprehensive feature implementation with excellent test coverage. Here's my detailed feedback: 🎯 Strengths
🔍 Potential Issues & Suggestions1. Error Handling in Skill PromptsThe use of OperationCancelledError instead of process.exit() is good, but ensure all callers properly handle this exception to avoid unhandled promise rejections. Location: src/cli/prompts/skillPrompts.ts:18-19 Consider adding a try-catch block in the calling code to gracefully handle cancellations. 2. Performance Consideration for Large CodebasesThe tech stack detection iterates through all processed files. For large codebases, consider implementing early exit once all dependency files are found. Location: src/core/skill/skillTechStack.ts:564-604 3. Potential Race Condition in Skill Directory CheckLocation: src/mcp/tools/generateSkillTool.ts:108-115 There's a TOCTOU (Time-of-Check-Time-of-Use) issue where the directory could be created between the check and actual write. Consider using atomic operations or file locking. 4. Missing Validation for Skill Name LengthWhile validateSkillName truncates to 64 chars, the MCP tool description mentions this limit but doesn't validate user input before normalization. Consider adding a warning if the provided name will be truncated. 🚀 Performance Optimizations
📋 Premortem AnalysisPotential Failure Scenarios:
Mitigation Strategies:
✅ Code Quality
🔒 Security Review
📝 Minor Suggestions
VerdictThis is a high-quality implementation that's ready for merge after addressing the minor issues mentioned above. The feature is well-thought-out, properly tested, and follows the project's coding standards. Great work on the comprehensive tech stack detection and the clean separation between CLI interaction and core logic! The skill generation feature will be a valuable addition for Claude Code users working with external codebases. 🤖 Generated with Claude Code |
- Fix line count logic for edge cases (empty files return 0, trailing newlines don't add extra line count) - Move skillDir validation earlier in packSkill.ts for fail-fast behavior - Normalize user-provided skillName in generateSkillTool.ts using validateSkillName() for consistent kebab-case format - Update generateSkillTool description to reflect project-only behavior (removed misleading personal skill documentation)
Code Review: Claude Agent Skills Generation SupportThis is a well-structured implementation of Claude Agent Skills generation. The feature adds significant value by enabling automated skill package creation for Claude Code. Here's my comprehensive review: ✅ Strengths
🔧 Potential Issues & Suggestions1. Performance Optimization for Large CodebasesThe tech stack detection in skillTechStack.ts:251-257 iterates through all files sequentially. For large codebases, this could be slow. Consider parallel processing or early termination once all dependency files are found. Suggested improvementProcess dependency files in parallel instead of sequentially to improve performance on large codebases. Also consider implementing early termination if all expected dependency files have been found. 2. Error Recovery in Skill GenerationThe skill generation process creates multiple files. If it fails partway, it could leave incomplete output in the .claude/skills directory. Suggested improvementConsider implementing a transaction-like rollback mechanism in writeSkillOutput.ts that tracks created directories/files and removes them on failure to ensure atomicity. 3. Security: Path Traversal ProtectionThe MCP tool validates absolute paths but could benefit from additional security checks to prevent symlink-based path traversal. Suggested improvementIn generateSkillTool.ts after line 92, add validation using fs.realpath to ensure the resolved path doesn't escape the intended directory through symlinks. 4. Memory Usage with Large FilesThe skill generation loads all file contents into memory. For very large codebases, this could cause memory issues. Suggested improvementConsider adding a size limit check in packSkill.ts and warn users to use the --compress option for large codebases (e.g., >500MB total). 📋 Premortem AnalysisPotential Failure Scenarios:
🎯 Minor Improvements
✨ Overall AssessmentThis is a high-quality implementation that follows the codebase conventions well. The feature is well-tested and thoughtfully designed. With the suggested improvements for error handling and performance optimization, this will be a robust addition to repomix. The code quality is excellent, with good separation of concerns and comprehensive test coverage. The interactive prompts provide a good user experience, and the tech stack detection is particularly impressive in its breadth. Great work on this feature! The Claude Agent Skills generation will be very useful for developers working with Claude Code. 🎉 |
Add documentation for the --skill-generate feature introduced in PR #998: - Add --skill-generate option to Command Line Options section - Add dedicated Skill Generation section with usage examples - Document generated structure (SKILL.md and references/) - Include auto-generated skill names and integration examples
Add documentation for the --skill-generate feature introduced in PR #998: - Add --skill-generate option to Command Line Options section - Add dedicated Skill Generation section with usage examples - Document generated structure (SKILL.md and references/) - Include auto-generated skill names and integration examples
Summary
This PR adds a new
--generate-skilloption to generate Claude Agent Skills from a codebase. Skills are pre-packaged code references that Claude Code can use to understand and work with specific projects.Key Features
--generate-skillCLI option that creates a structured skill package.claude/skills/) and personal skills (~/.claude/skills/)repomix-reference-<folder-name>SKILL.md- Entry point with usage guidereferences/summary.md- Purpose, format, and statisticsreferences/project-structure.md- Directory tree with line countsreferences/files.md- All file contentsreferences/tech-stack.md- Languages, frameworks, dependencies (if detected)generate_skillMCP tool for programmatic skill generationChanges
--generate-skill/-ssrc/core/output/skill/Checklist
npm run testnpm run lint