Skip to content

feat(skill): Add Claude Agent Skills generation support#998

Merged
yamadashy merged 30 commits intomainfrom
feat/agent-skills
Dec 11, 2025
Merged

feat(skill): Add Claude Agent Skills generation support#998
yamadashy merged 30 commits intomainfrom
feat/agent-skills

Conversation

@yamadashy
Copy link
Owner

Summary

This PR adds a new --generate-skill option 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

  • Skill Generation: New --generate-skill CLI option that creates a structured skill package
  • Skill Location Selection: Interactive prompt to choose between project skills (.claude/skills/) and personal skills (~/.claude/skills/)
  • Auto-naming: Automatically generates skill names as repomix-reference-<folder-name>
  • Multi-file Output Structure:
    • SKILL.md - Entry point with usage guide
    • references/summary.md - Purpose, format, and statistics
    • references/project-structure.md - Directory tree with line counts
    • references/files.md - All file contents
    • references/tech-stack.md - Languages, frameworks, dependencies (if detected)
  • Tech Stack Detection: Detects languages, frameworks, dependencies, runtime versions (.node-version, .tool-versions), and configuration files
  • Line Counts: Directory structure includes line counts for each file
  • MCP Tool Support: New generate_skill MCP tool for programmatic skill generation

Changes

  • Added new CLI option --generate-skill / -s
  • Added skill output generation in src/core/output/skill/
  • Added tech stack detection with dependency analysis
  • Added interactive skill location selection
  • Updated MCP tools with improved descriptions
  • Added comprehensive test coverage

Checklist

  • Run npm run test
  • Run npm run lint

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

This 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

Cohort / File(s) Summary
CLI Configuration
src/cli/cliRun.ts, src/cli/types.ts
Added --skill-generate [name] CLI option and corresponding skillGenerate, skillName, skillDir fields to CliOptions interface.
CLI Actions & Workflows
src/cli/actions/defaultAction.ts, src/cli/actions/remoteAction.ts, src/cli/actions/workers/defaultActionWorker.ts
Integrated skill generation flow into default and remote actions, adding skill name resolution, location prompts, skill-specific output handling, and passing skillName/skillDir through worker-driven packing.
CLI Prompts
src/cli/prompts/skillPrompts.ts
New module providing interactive prompts for skill location selection (personal/project) with directory existence and overwrite handling.
CLI Reporting
src/cli/cliReport.ts
Extended reporting to display skill directory output when skill generation is active, with relative path resolution and conditional output path logic.
Configuration
src/config/configLoad.ts, src/config/configSchema.ts
Added conditional merge of skillGenerate option into merged config and extended CLI schema to accept skillGenerate union type.
Core Packing & Orchestration
src/core/packager.ts
Added PackOptions interface and early-exit path in pack workflow to invoke skill generation when config.skillGenerate is defined and options.skillDir is provided.
Skill Generation Modules (New)
src/core/skill/packSkill.ts, src/core/skill/skillUtils.ts, src/core/skill/skillSectionGenerators.ts, src/core/skill/skillStatistics.ts, src/core/skill/skillStyle.ts, src/core/skill/skillTechStack.ts, src/core/skill/writeSkillOutput.ts
New skill generation framework: packSkill orchestrates end-to-end workflow; skillUtils handles naming/validation; skillSectionGenerators/Statistics/Style produce markdown sections; skillTechStack detects project dependencies; writeSkillOutput persists output to filesystem.
Core Output Utilities
src/core/output/outputGenerate.ts, src/core/output/outputGeneratorTypes.ts, src/core/output/outputStyleUtils.ts, src/core/file/fileTreeGenerate.ts
Extended RenderContext with fileLineCounts; added language-from-extension mapping; introduced tree generation with line counts for skill reference display.
MCP Tools
src/mcp/tools/generateSkillTool.ts, src/mcp/mcpServer.ts
Registered new generate_skill MCP tool for non-interactive skill generation from MCP clients.
Tests
tests/cli/actions/defaultAction.test.ts, tests/cli/actions/defaultAction.tokenCountTree.test.ts, tests/cli/actions/workers/defaultActionWorker.test.ts, tests/cli/cliReport.test.ts, tests/cli/prompts/skillPrompts.test.ts, tests/core/output/outputStyles/markdownStyle.test.ts, tests/core/skill/*.test.ts, tests/mcp/tools/generateSkillTool.test.ts, tests/testing/testUtils.ts
Comprehensive test coverage for new skill generation features, updated pack/report call signatures, and tech stack detection across multiple ecosystems.
Configuration & Misc
.gitignore, typos.toml
Added repomix reference artifact exclusions and Stylus extension mapping.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

  • skillTechStack.ts: Dense parsing logic across 11+ dependency formats and version managers with framework detection; requires careful validation of ecosystem-specific patterns and precedent.
  • packSkill.ts: Orchestration logic threading multiple dependencies, conditional tech stack detection, and metrics calculation; coordinate flow with multiple sub-modules.
  • Integration points: Verify proper threading of skillName/skillDir through CLI actions → workers → packager → packSkill, ensuring options are not inadvertently dropped or misrouted.
  • skillPrompts.ts: Interactive prompt flow with dependency injection for testability; validate cancellation handling and directory existence checks.
  • Reporter integration: Ensure reportResults/reportSummary signature changes don't break existing non-skill codepaths and that skill output paths are displayed correctly.

Possibly related PRs

Suggested labels

enhancement

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(skill): Add Claude Agent Skills generation support' directly summarizes the main feature added—generating Claude Agent Skills from codebases.
Description check ✅ Passed The PR description covers key features, changes, file structure, and includes the required checklist with both items marked complete. It provides comprehensive context for the skill generation capability.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 8, 2025

Deploying repomix with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7e5a431
Status: ✅  Deploy successful!
Preview URL: https://6c1fc8e6.repomix.pages.dev
Branch Preview URL: https://feat-agent-skills.repomix.pages.dev

View logs

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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

  • Claude Agent Skills Generation: Introduces a new --generate-skill CLI option to create structured Claude Agent Skills packages from a codebase. These packages are designed to provide AI agents with pre-packaged code references for better understanding and interaction with projects.
  • Structured Skill Output: Generated skills include a SKILL.md entry point, and a references/ directory containing summary.md (purpose, format, statistics), project-structure.md (directory tree with line counts), files.md (all file contents), and tech-stack.md (languages, frameworks, dependencies, runtime versions, config files, if detected).
  • Interactive Skill Location and Naming: Users are prompted to choose between saving skills as 'Personal Skills' (~/.claude/skills/) or 'Project Skills' (.claude/skills/). Skill names are automatically generated as repomix-reference-<folder-name> but can also be specified manually.
  • Enhanced Codebase Analysis: The skill generation process includes advanced tech stack detection, line counting for each file in the directory structure, and integration with the Model Context Protocol (MCP) via a new generate_skill tool for programmatic skill creation.
  • CLI and Configuration Updates: New CLI options and configuration schema updates support the skill generation feature, including validation to prevent conflicts with --stdout and --copy options.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 84.84848% with 215 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.50%. Comparing base (50580c2) to head (7e5a431).
⚠️ Report is 31 commits behind head on main.

Files with missing lines Patch % Lines
src/core/skill/skillTechStack.ts 73.94% 124 Missing ⚠️
src/cli/actions/remoteAction.ts 32.55% 29 Missing ⚠️
src/core/packager.ts 18.18% 18 Missing ⚠️
src/core/skill/skillUtils.ts 75.40% 15 Missing ⚠️
src/core/skill/writeSkillOutput.ts 63.88% 13 Missing ⚠️
src/cli/cliReport.ts 66.66% 8 Missing ⚠️
src/cli/actions/defaultAction.ts 74.07% 7 Missing ⚠️
src/core/output/outputGenerate.ts 93.33% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@claude

This comment was marked as outdated.

gemini-code-assist[bot]

This comment was marked as outdated.

@claude

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.
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.
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.
@yamadashy yamadashy marked this pull request as ready for review December 11, 2025 14:41
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/cli/actions/remoteAction.ts (1)

117-124: Consider the clipboard behavior with skill generation.

When skillGenerate is enabled, the clipboard functionality (if enabled via copyToClipboard) will copy the wrong content. The existing copyToClipboardIfEnabled function likely operates on the standard output file, not the skill package. Consider either:

  1. Disabling clipboard copy when skill generation is active
  2. 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 counts

Adding fileLineCounts to RenderContext is a good fit for the new line-count–aware skill outputs. If you want to mirror the immutability style of processedFiles, you could type this as Readonly<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 options

The new config.skillGenerate handling is coherent:

  • Correctly rejects incompatible combinations with --stdout and --copy.
  • Resolves cliOptions.skillName once (respecting precomputed values from other flows) and only prompts for a location when skillDir is missing.
  • Ensures reportResults can show the skill directory via cliOptions.skillDir.

One small refinement: reportResults only needs skillDir, but you pass the full CliOptions object. 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 branches

These tests nicely cover the directory layout and writes for SKILL.md, summary.md, project-structure.md, and files.md, plus the return value.

To lock in behavior further, consider adding:

  • A case where output.references.techStack is present to assert tech-stack.md is written.
  • A case where deps.writeFile or deps.mkdir throws EPERM/EACCES to verify the specialized RepomixError message, 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 assertions

The tests exercise both calculateStatistics and generateStatisticsSection very well. One minor concern is the reliance on specific toLocaleString output ('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 template

The SKILL.md Handlebars template and SkillRenderContext shape look good, and the conditionals around hasTechStack are straightforward.

Since the template is static, you could avoid recompiling it on every generateSkillMd call 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 returning never type for testability.

The onCancelOperation function calls process.exit(0), which works correctly for CLI but makes unit testing difficult since it terminates the process. The injectable deps pattern is already used for other dependencies, but process.exit isn't mockable here.

Consider adding process.exit to 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 how detectTechStack handles 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 for options.skillName precedence.

Based on the implementation in packSkill.ts (lines 203-205), options.skillName takes 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 rootDirs is empty, rootDirs[0] will be undefined, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 50580c2 and f8f476f.

📒 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 createRenderContext and adding fileLineCounts to 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 cwd allows tests to override the working directory
  • Conditionally spreading skillGenerate maintains proper typing for CLI-only properties

Also 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:

  • .sass files now map to sass (not scss) - these are distinct Sass syntaxes
  • .c files now map to c (not cpp) - these are different languages

The 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 reportResults signature, which now accepts a fourth parameter (ReportOptions) to support the new skill generation workflow. Using expect.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: MCP generate_skill tool wiring looks correct

Importing and registering registerGenerateSkillTool plus mentioning generate_skill explicitly in MCP_SERVER_INSTRUCTIONS keeps the MCP capabilities and documentation in sync; registration order is consistent with existing tools.

src/config/configLoad.ts (1)

233-235: Conditional merge of skillGenerate from CLI is appropriate

Limiting skillGenerate to cliConfig and only adding it when not undefined avoids surprising defaults and keeps config-file usage unchanged while enabling the new skill-generation flow.

src/cli/cliRun.ts (1)

171-176: --skill-generate option is cleanly integrated

The new “Skill Generation (Experimental)” group and --skill-generate [name] flag are consistent with existing CLI patterns and align with the downstream CliOptions.skillGenerate handling.

tests/cli/actions/defaultAction.test.ts (1)

308-392: Skill generation CLI tests cover key config and validation paths

The added tests for buildCliConfig (string vs boolean skillGenerate) and the error cases with --stdout / --copy exercise 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: Forwarding skillName/skillDir into pack is correctly implemented

Deriving packOptions from cliOptions and passing it as the last argument to pack in both stdin and directory branches aligns with the updated pack signature and ensures skill-generation options are honored consistently.

tests/cli/prompts/skillPrompts.test.ts (1)

1-132: Skill prompt tests are thorough and well-isolated

The createMockDeps helper plus process.exit spying give solid coverage of getSkillBaseDir and promptSkillLocation, 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 on CliOptions align with CLI and internal usage

Defining skillGenerate as string | boolean and adding internal skillName/skillDir fields matches the new --skill-generate flag 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 usage

The new skillGenerate: z.union([z.string(), z.boolean()]).optional() aligns with CliOptions.skillGenerate and the way config.skillGenerate is consumed in defaultAction. No issues from a schema / merge perspective.

tests/cli/cliReport.test.ts (1)

52-52: reportSummary invocation updates look correct

All reportSummary calls 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 contract

The function correctly:

  • Creates <skillDir>/references with recursive: true.
  • Writes SKILL.md, summary.md, project-structure.md, files.md, and tech-stack.md only 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 isCancel checks 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.access to 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 !== undefined and options.skillDir before delegating to packSkill. 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 directoryStructureEnabled and uses generateTreeStringWithLineCounts to include line counts in the directory tree output.

tests/core/skill/packSkill.test.ts (3)

19-54: LGTM!

Good test structure for generateSkillReferences covering 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 packSkill throws a descriptive error when skillDir is missing, which is an important validation.


285-327: LGTM on skill name resolution tests.

The tests correctly verify the precedence logic:

  • When config.skillGenerate is a string, it uses that value and doesn't call generateDefaultSkillName
  • When config.skillGenerate is a boolean, it calls generateDefaultSkillName to derive the name

Also 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 from git@github.com:user/repo.git by 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
@claude
Copy link
Contributor

claude bot commented Dec 11, 2025

Code Review for PR #998: Claude Agent Skills Generation Support

I'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

  1. Excellent Architecture: The feature is well-modularized with clear separation of concerns between CLI, skill generation logic, and output writing.

  2. Comprehensive Test Coverage: The PR includes extensive tests (373 lines in packSkill.test.ts, 330 in skillTechStack.test.ts, etc.) covering various scenarios including edge cases and error conditions.

  3. Security Conscious: Good path traversal protection in validateSkillName() with explicit checks for path separators, null bytes, and dot-only names.

  4. User-Friendly Interface: The interactive prompt system using @clack/prompts provides a good UX with clear options for personal vs project skills.

  5. Tech Stack Detection: The comprehensive tech stack detection across 11+ package ecosystems (npm, pip, go.mod, Cargo.toml, etc.) is impressive and well-implemented.

🔍 Potential Issues & Suggestions

1. Error Handling in Skill Prompts

The 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 Codebases

The 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 Check

Location: 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 Length

While 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

  1. Language Detection Map: The 100+ language mappings in outputStyleUtils.ts could benefit from being a frozen object or Map for better performance.

  2. File Line Counting: Consider caching line counts if the same files are processed multiple times.

  3. Dependency Parsing: For large package.json files with many dependencies, consider streaming JSON parsing for better memory efficiency.

📋 Premortem Analysis

Potential Failure Scenarios:

  1. Disk Space Issues: Writing skill output could fail on low disk space. Consider checking available space before writing.

  2. Network Filesystems: The skill generation might behave unexpectedly on network-mounted filesystems with different permission models.

  3. Concurrent Skill Generation: Multiple processes generating the same skill simultaneously could cause conflicts.

  4. Large Monorepos: The tech stack detection might become slow or memory-intensive for very large monorepos with thousands of dependencies.

Mitigation Strategies:

  • Add disk space checks before writing
  • Implement file locking for concurrent access
  • Add memory usage monitoring for large operations
  • Consider chunked processing for very large dependency lists

✅ Code Quality

  • Consistent Error Handling: RepomixError is used consistently throughout
  • Good TypeScript Practices: Proper typing, interfaces, and type guards
  • Clean Code Structure: Well-organized with single responsibility principle
  • Dependency Injection: Good use of deps parameter for testability

🔒 Security Review

  • ✅ Path traversal protection implemented
  • ✅ Input validation for skill names
  • ✅ Proper error messages without exposing sensitive paths
  • ✅ Safe file operations with proper permissions handling

📝 Minor Suggestions

  1. Consider adding a --dry-run option to preview what would be generated
  2. Add progress indicators for large codebase processing
  3. Consider adding skill metadata versioning for future compatibility
  4. Add telemetry/analytics (with user consent) to understand skill usage patterns

Verdict

This 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)
@claude
Copy link
Contributor

claude bot commented Dec 11, 2025

Code Review: Claude Agent Skills Generation Support

This 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

  1. Clean Architecture: The skill generation is cleanly separated into its own module with clear responsibilities across multiple files (packSkill.ts, skillTechStack.ts, skillSectionGenerators.ts, etc.)

  2. Comprehensive Test Coverage: Good test coverage for all new modules including edge cases and multiple dependency formats

  3. Interactive UX: Thoughtful prompts for skill location selection with proper overwrite confirmation

  4. Tech Stack Detection: Impressive coverage across 11+ ecosystems (Node.js, Python, Go, Rust, PHP, Ruby, Java/Kotlin) with framework detection

  5. MCP Integration: Properly integrated MCP tool for programmatic skill generation with good schema validation

🔧 Potential Issues & Suggestions

1. Performance Optimization for Large Codebases

The 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 improvement

Process 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 Generation

The skill generation process creates multiple files. If it fails partway, it could leave incomplete output in the .claude/skills directory.

Suggested improvement

Consider 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 Protection

The MCP tool validates absolute paths but could benefit from additional security checks to prevent symlink-based path traversal.

Suggested improvement

In 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 Files

The skill generation loads all file contents into memory. For very large codebases, this could cause memory issues.

Suggested improvement

Consider adding a size limit check in packSkill.ts and warn users to use the --compress option for large codebases (e.g., >500MB total).

📋 Premortem Analysis

Potential Failure Scenarios:

  1. Concurrent Skill Generation: If multiple processes try to generate the same skill simultaneously

    • Mitigation: Add file locking or unique temporary directories with atomic rename
  2. Network File Systems: Skills generated on network drives might fail or be slow

    • Mitigation: Add timeout handling and better error messages for I/O operations
  3. CI/CD Integration: Skill generation in CI pipelines might fail due to permission issues

    • Mitigation: Document required permissions and consider adding --dry-run option
  4. Version Control Conflicts: Team members generating different versions of the same skill

    • Mitigation: Add timestamp or content hash to skill metadata for versioning

🎯 Minor Improvements

  1. Skill Naming: Consider validating against reserved skill names that might conflict with Claude's built-in skills

  2. Progress Indication: For large codebases, tech stack detection could benefit from progress callbacks

  3. Caching: Tech stack detection results could be cached based on file hashes to speed up repeated generations

  4. Documentation: Consider adding JSDoc comments to public APIs in the skill module for better IDE support

✨ Overall Assessment

This 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. 🎉

@yamadashy yamadashy merged commit fc6b1ed into main Dec 11, 2025
95 of 96 checks passed
@yamadashy yamadashy deleted the feat/agent-skills branch December 11, 2025 15:12
yamadashy pushed a commit that referenced this pull request Dec 12, 2025
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
yamadashy pushed a commit that referenced this pull request Dec 12, 2025
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant