Skip to content

feat(skill): Improve skill generation for remote repositories#1001

Merged
yamadashy merged 5 commits intomainfrom
fix/skill-generate-project-name
Dec 12, 2025
Merged

feat(skill): Improve skill generation for remote repositories#1001
yamadashy merged 5 commits intomainfrom
fix/skill-generate-project-name

Conversation

@yamadashy
Copy link
Owner

Summary

This PR improves the --skill-generate feature when used with --remote:

  1. Fix project name generation: Previously, the project name was incorrectly derived from the temp directory name (e.g., "Repomix HPkbgH"). Now it correctly uses the repository name from the URL (e.g., "Vite" for https://github.com/vitejs/vite).

  2. Add source URL to SKILL.md: For remote repositories, the SKILL.md footer now includes the source URL:

    • Remote: This skill was generated by [Repomix](...) from [https://github.com/vitejs/vite](...)
    • Local: This skill was generated by [Repomix](...) (no URL to avoid exposing personal paths)
  3. Fix .claude/ directory copy conflict: When the remote repository has its own .claude/ directory (with commands, agents, etc.), only .claude/skills/ is now copied to prevent conflicts.

Changes

  • Add generateProjectNameFromUrl() function to extract and format project name from URLs
  • Add skillSourceUrl option to pass source URL through the pipeline
  • Update SKILL.md template with conditional source URL rendering
  • Fix copySkillOutputToCurrentDirectory to copy only .claude/skills/

Checklist

  • Run npm run test
  • Run npm run lint

- Fix project name generation to use repository name from URL instead of
  temp directory name (e.g., "Vite" instead of "Repomix HPkbgH")
- Add source URL to SKILL.md footer for remote repositories only
  (local repos don't include URL to avoid exposing personal paths)
- Copy only .claude/skills/ directory to prevent conflicts with
  repository's own .claude config (commands, agents, etc.)

Example SKILL.md footer:
- Remote: "This skill was generated by Repomix from [https://github.com/...]"
- Local: "This skill was generated by Repomix"
@cloudflare-workers-and-pages
Copy link

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

Deploying repomix with  Cloudflare Pages  Cloudflare Pages

Latest commit: 670e839
Status: ✅  Deploy successful!
Preview URL: https://6dc6c2ae.repomix.pages.dev
Branch Preview URL: https://fix-skill-generate-project-n.repomix.pages.dev

View logs

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 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 extends the skill generation pipeline to compute project names from repository URLs and thread source URL metadata through the skill packaging stack. It restricts .claude directory copying to only the .claude/skills subdirectory and updates skill documentation templates to include source attribution.

Changes

Cohort / File(s) Change Summary
CLI Layer
src/cli/actions/remoteAction.ts, src/cli/actions/workers/defaultActionWorker.ts, src/cli/types.ts
Added import of generateProjectNameFromUrl; computed skillProjectName from repo URL; extended CliOptions and options passed to defaultAction to include skillProjectName and skillSourceUrl; restricted .claude copy scope to .claude/skills only; updated existence checks and error messages accordingly
Core Skill Metadata
src/core/packager.ts, src/core/skill/packSkill.ts, src/core/skill/skillUtils.ts
Extended PackOptions with optional skillProjectName and skillSourceUrl fields; added sourceUrl field to SkillReferencesResult; implemented generateProjectNameFromUrl utility; threaded new parameters through generateSkillReferences
Skill Rendering
src/core/skill/skillStyle.ts
Added optional sourceUrl field to SkillRenderContext; repositioned summary.md reference in SKILL.md template; added footer attribution block with conditional source URL link and Repomix citation
Test Coverage
tests/core/skill/packSkill.test.ts, tests/core/skill/skillUtils.test.ts
Added tests validating skillProjectName override behavior; added tests verifying conditional sourceUrl inclusion in Skill MD; added tests for generateProjectNameFromUrl across various URL formats
Configuration Schema
website/client/src/public/schemas/1.10.0/schema.json
New JSON Schema file defining Repomix configuration structure with properties for input, output (including nested git settings), include/ignore patterns, security, and token count options

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • generateProjectNameFromUrl utility: Verify URL parsing and name conversion (kebab/snake-case to Title Case) handles edge cases and aligns with naming conventions
  • Copy behavior restriction: Confirm change from full .claude to .claude/skills-only copying doesn't affect existing workflows or break permission checks
  • skillStyle template changes: Review markdown rendering of new attribution footer and repositioned summary.md link for correctness and formatting

Possibly related PRs

  • PR #998: Implements the skill generation pipeline foundation that this PR builds upon by adding metadata threading through the same modules
  • PR #335: Modifies remoteAction.ts with repository URL parsing and metadata handling logic
  • PR #583: Updates runRemoteAction in remoteAction.ts with related git command changes

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 pull request title accurately summarizes the main focus: improving skill generation specifically for remote repositories by addressing project naming, source URL attribution, and directory copying issues.
Description check ✅ Passed The pull request description follows the template structure with a comprehensive summary section explaining the three main improvements, detailed changes, and a completed checklist matching repository requirements.

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.

@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 enhances the --skill-generate feature when used with remote repositories. It addresses issues related to how project names are derived, ensures proper attribution by including the source URL in the generated skill documentation, and prevents unintended overwrites of existing .claude configurations by selectively copying only the necessary skill-related files.

Highlights

  • Improved Project Name Generation: The project name for generated skills from remote repositories now correctly uses the repository name from the URL (e.g., 'Vite' for https://github.com/vitejs/vite) instead of the temporary directory name.
  • Source URL in SKILL.md: For skills generated from remote repositories, the SKILL.md footer now includes a link to the original source URL, providing better attribution and context.
  • Resolved .claude/ Directory Copy Conflict: The skill generation process now only copies the .claude/skills/ directory from the remote repository, preventing conflicts with existing .claude/ configurations (commands, agents, etc.) in the target directory.
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.

@claude
Copy link
Contributor

claude bot commented Dec 12, 2025

PR Review: Improve skill generation for remote repositories

This is a well-structured PR that addresses important usability improvements for skill generation from remote repositories. The implementation is clean and the test coverage is comprehensive.

✅ Strengths

  1. Clear problem solving: The PR addresses three specific issues with skill generation for remote repositories, each with a targeted solution.

  2. Good architectural decisions:

    • Threading the source URL and project name through the pipeline without breaking existing interfaces
    • Selective copying of only .claude/skills/ to avoid conflicts
  3. Comprehensive test coverage: The new functionality is well-tested with edge cases covered.

  4. Security-conscious: The implementation properly handles path separators and potential security issues in skill names.

🎯 Code Quality Observations

Minor suggestions for consideration
  1. Error handling for malformed URLs: While generateProjectNameFromUrl works well for standard cases, consider what happens if extractRepoName fails to match and returns the full URL. The Title Case conversion would still work, but the result might be unexpected.

  2. Documentation opportunity: Consider adding JSDoc comments to the new skillProjectName and skillSourceUrl options in the interfaces to clarify their purpose and when they are populated.

  3. Consistency in error messages: The error message in copySkillOutputToCurrentDirectory mentions "Permission denied" but the actual error could be other things (disk full, etc.). Consider including the actual error message.

🔍 Premortem Analysis

Potential edge cases to consider

Risk 1: URL parsing edge cases

  • Non-standard Git URLs might not parse correctly (e.g., custom Git servers, SSH URLs with ports)
  • Mitigation: The current implementation gracefully falls back to using the full URL if parsing fails

Risk 2: Concurrent skill generation

  • If multiple skill generation processes run simultaneously in the same directory, the .claude/skills/ copy could have race conditions
  • Mitigation: The current implementation overwrites, which is reasonable for this use case

Risk 3: Large repository handling

  • For very large repositories, the skill generation might hit memory or token limits
  • Mitigation: This is handled by existing limits in the broader Repomix architecture

✅ Overall Assessment

This PR is ready to merge. The implementation is solid, addresses real user pain points, and maintains backward compatibility. The code is clean, well-tested, and follows the project conventions. The selective copying of only .claude/skills/ is a particularly thoughtful solution that prevents unintended side effects.

Great work on this improvement! 🚀

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the ability to capture and utilize a skillProjectName and skillSourceUrl when generating skills, particularly for remote repositories. The changes involve propagating these new parameters through the CLI actions, worker, and packager components, and updating the skill generation logic to use them. A new utility function, generateProjectNameFromUrl, was added to derive a human-readable project name from a repository URL. The SKILL.md template was updated to display this project name in the skill description and include an optional source URL link in the footer. Additionally, the skill output copying mechanism was refined to only copy the .claude/skills directory to prevent conflicts. Review comments suggest improving the SKILL.md source URL link text by using the projectName instead of the full URL, and refactoring the Title Case conversion logic into a shared helper function to reduce code duplication.

Add unit tests for the copySkillOutputToCurrentDirectory function:
- Copy .claude/skills directory when it exists
- Skip copy when directory does not exist
- Handle EPERM and EACCES permission errors
- Handle generic errors
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/core/skill/skillUtils.test.ts (1)

3-8: Fix the “kebab-case” test case + add a couple of high-value URL edge cases.

  • Line 99-101: the test claims kebab-case but uses repomix (not kebab-case). Use something like my-project-name to actually exercise the conversion.
  • Consider adding coverage for trailing slash + ssh form (git@github.com:org/repo.git) since extractRepoName docs mention it.

Example patch:

-    test('should handle kebab-case repo names', () => {
-      expect(generateProjectNameFromUrl('https://github.com/yamadashy/repomix')).toBe('Repomix');
-    });
+    test('should handle kebab-case repo names', () => {
+      expect(generateProjectNameFromUrl('https://github.com/user/my-project-name')).toBe('My Project Name');
+    });
+
+    test('should handle trailing slash', () => {
+      expect(generateProjectNameFromUrl('https://github.com/vitejs/vite/')).toBe('Vite');
+    });
+
+    test('should handle ssh URL', () => {
+      expect(generateProjectNameFromUrl('git@github.com:yamadashy/repomix.git')).toBe('Repomix');
+    });

Also applies to: 94-115

src/core/skill/skillStyle.ts (1)

3-12: Avoid {{{sourceUrl}}} in markdown link to prevent markdown injection; validate + render safely.
Right now sourceUrl is inserted unescaped into both the link label and URL. A malicious value could break the markdown structure of SKILL.md. Prefer:

  1. Validate sourceUrl upstream (e.g., new URL(...), allow only http:/https:), and
  2. Render with a safer markdown form like an autolink: from <{{sourceUrl}}> (still after validation).

Template-only tweak (assuming upstream validation):

-This skill was generated by [Repomix](https://github.com/yamadashy/repomix){{#if sourceUrl}} from [{{{sourceUrl}}}]({{{sourceUrl}}}){{/if}}
+This skill was generated by [Repomix](https://github.com/yamadashy/repomix){{#if sourceUrl}} from <{{sourceUrl}}>{{/if}}

Also applies to: 99-103

🧹 Nitpick comments (3)
website/client/src/public/schemas/1.10.0/schema.json (1)

2-3: Tighten numeric fields (integer/min) + consider $id/https for schema URL.
Several “count/length/size” fields are currently "number" with no constraints, so configs like -1, 1.5, etc. would validate. Suggest making these "integer" with "minimum": 0 (e.g., input.maxFileSize, output.topFilesLength, output.git.sortByChangesMaxCommits, output.git.includeLogsCount). Also consider adding a root-level "$id" and using an https $schema URL for best practice.

Example (illustrative) patch:

-  "$schema": "http://json-schema.org/draft-07/schema#",
+  "$schema": "https://json-schema.org/draft-07/schema#",
+  "$id": "https://repomix.dev/schemas/1.10.0/schema.json",
...
-        "maxFileSize": { "type": "number" }
+        "maxFileSize": { "type": "integer", "minimum": 0 }
...
-        "topFilesLength": { "type": "number" }
+        "topFilesLength": { "type": "integer", "minimum": 0 }
...
-            "sortByChangesMaxCommits": { "type": "number" }
+            "sortByChangesMaxCommits": { "type": "integer", "minimum": 0 }
-            "includeLogsCount": { "type": "number" }
+            "includeLogsCount": { "type": "integer", "minimum": 0 }

Also applies to: 11-13, 59-61, 96-99, 105-107, 153-155

src/cli/actions/workers/defaultActionWorker.ts (1)

58-60: Good propagation of skillProjectName / skillSourceUrl into packOptions.
Optional nit: consider omitting undefined keys to keep logs/debug output cleaner (esp. if options are ever serialized).

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

236-279: Source URL inclusion/omission tests match the conditional rendering intent.
Optional: assert the full rendered link form (not just the label) once the SKILL.md footer format is finalized (especially if you adopt autolink <...> for safety).

📜 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 38f31e9 and 90ffa5b.

📒 Files selected for processing (10)
  • src/cli/actions/remoteAction.ts (3 hunks)
  • src/cli/actions/workers/defaultActionWorker.ts (1 hunks)
  • src/cli/types.ts (1 hunks)
  • src/core/packager.ts (1 hunks)
  • src/core/skill/packSkill.ts (6 hunks)
  • src/core/skill/skillStyle.ts (3 hunks)
  • src/core/skill/skillUtils.ts (1 hunks)
  • tests/core/skill/packSkill.test.ts (5 hunks)
  • tests/core/skill/skillUtils.test.ts (2 hunks)
  • website/client/src/public/schemas/1.10.0/schema.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
tests/core/skill/packSkill.test.ts (1)
src/core/skill/packSkill.ts (3)
  • generateSkillReferences (70-143)
  • SkillReferencesResult (38-48)
  • generateSkillMdFromReferences (149-168)
tests/core/skill/skillUtils.test.ts (1)
src/core/skill/skillUtils.ts (1)
  • generateProjectNameFromUrl (75-83)
src/core/skill/packSkill.ts (1)
src/core/skill/skillUtils.ts (1)
  • generateProjectName (50-59)
src/cli/actions/remoteAction.ts (1)
src/core/skill/skillUtils.ts (2)
  • generateDefaultSkillNameFromUrl (115-119)
  • generateProjectNameFromUrl (75-83)
⏰ 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 (13)
src/core/packager.ts (1)

50-55: PackOptions extension looks consistent with the new skill metadata flow.
No concerns with adding skillProjectName?: string and skillSourceUrl?: string here.

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

36-47: Coverage for skillProjectName override looks solid.
The temp-dir example is a good regression guard for the remote flow.

Also applies to: 73-84, 89-119

src/cli/types.ts (1)

58-64: Types look fine; verify these fields aren’t user-settable in a way that leaks local paths.
The comments say “internal / remote only”; worth double-checking there’s no CLI flag or config option that could populate skillSourceUrl on local runs (or accept a file://... URL).

#!/bin/bash
set -euo pipefail

# Check if these options are exposed as CLI flags or config-mapped fields.
rg -n --hidden -S "skillProjectName|skillSourceUrl" -C2
src/cli/actions/remoteAction.ts (4)

10-10: LGTM!

The import of generateProjectNameFromUrl is correct and necessary for the new project name generation feature.


97-105: LGTM!

The project name generation logic is well-placed within the skill generation block and properly extracts a user-friendly project name from the repository URL. The comment clearly explains the purpose.


113-116: LGTM!

The conditional assignment of skillSourceUrl correctly ensures that the repository URL is only propagated when skill generation is active. The spreading of options properly passes the new fields through the pipeline.


216-250: Excellent improvement to prevent conflicts.

The refinement to copy only .claude/skills/ instead of the entire .claude/ directory is well-reasoned and properly implemented. All path references, checks, and error messages have been consistently updated to reflect the narrower scope. The comments clearly explain the rationale for preventing conflicts with a repository's own .claude configuration.

src/core/skill/packSkill.ts (6)

47-47: LGTM!

The sourceUrl field is properly typed as optional and follows the interface's conventions.


78-79: LGTM!

The optional parameters are properly typed and positioned, maintaining backward compatibility while enabling the new metadata propagation feature.


88-89: LGTM!

The fallback logic is correct and well-commented. Using the nullish coalescing operator properly handles the case where skillProjectName is provided (from URL for remote repos) versus generated (from directory for local repos).


141-141: LGTM!

The sourceUrl is properly propagated through the skill references result.


161-161: LGTM!

The sourceUrl is correctly passed from the references result to the skill MD generation function, completing the propagation pipeline.


220-234: LGTM!

The function call properly passes the new skillProjectName and skillSourceUrl parameters from options, maintaining the correct argument order and properly structured dependency injection.

@claude
Copy link
Contributor

claude bot commented Dec 12, 2025

Code Review: feat(skill): Improve skill generation for remote repositories

✅ Overall Assessment

This PR successfully addresses three key issues with skill generation from remote repositories. The implementation is clean, well-tested, and maintains backward compatibility. The changes significantly improve the user experience when generating skills from remote sources.

🎯 Key Improvements

  1. Project Name Generation: Correctly extracts repository names from URLs and converts them to human-readable Title Case format
  2. Source Attribution: Adds transparent source URL tracking in SKILL.md for remote repositories
  3. Selective Directory Copying: Prevents conflicts by copying only .claude/skills/ rather than the entire .claude/ directory

💡 Suggestions for Consideration

1. Improve link text in SKILL.md footer

In skillStyle.ts:103, consider using the project name for the source URL link text instead of showing the full URL:

// Current:
This skill was generated by [Repomix](...) from [{{{sourceUrl}}}]({{{sourceUrl}}})

// Suggested:
This skill was generated by [Repomix](...) from [{{{projectName}}}]({{{sourceUrl}}})

This would display as "from Vite" instead of the full URL twice, improving readability.

2. Extract Title Case conversion to shared utility

The Title Case conversion logic is duplicated in both generateProjectName and generateProjectNameFromUrl. Consider extracting it to a shared helper:

// skillUtils.ts:54-57 and :79-82
const toTitleCase = (text: string): string => {
  return text
    .replace(/[-_]/g, ' ')
    .replace(/\b\w/g, (char) => char.toUpperCase())
    .trim();
};

export const generateProjectName = (rootDirs: string[]): string => {
  const primaryDir = rootDirs[0] || '.';
  const dirName = path.basename(path.resolve(primaryDir));
  return toTitleCase(dirName);
};

export const generateProjectNameFromUrl = (remoteUrl: string): string => {
  const repoName = extractRepoName(remoteUrl);
  return toTitleCase(repoName);
};

🔍 Premortem Analysis

Potential risks and mitigations

Risk 1: Non-standard Git URLs

  • URLs from enterprise Git servers or SSH URLs with custom ports might not parse correctly
  • Current mitigation: extractRepoName gracefully handles various formats and returns the full URL if parsing fails

Risk 2: Directory permission issues

  • The .claude/skills/ directory copy might fail due to filesystem permissions
  • Current mitigation: Clear error messages guide users to try different directories

Risk 3: Large repository token limits

  • Skills from very large repositories might exceed Claude's context limits
  • Current mitigation: Existing Repomix architecture handles token counting and limits

✅ Test Coverage

Excellent test coverage including:

  • URL parsing edge cases
  • Project name generation variations
  • Source URL inclusion/exclusion in SKILL.md
  • Directory copy error handling

🚀 Ready to Merge

The implementation is solid and addresses real user needs. The selective copying of .claude/skills/ is particularly thoughtful, preventing unintended overwrites of existing Claude configurations.

Great work on this improvement! The code quality is excellent and follows the project's conventions well.

@codecov
Copy link

codecov bot commented Dec 12, 2025

Codecov Report

❌ Patch coverage is 95.65217% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.83%. Comparing base (38f31e9) to head (670e839).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
src/core/skill/skillUtils.ts 94.28% 2 Missing ⚠️
src/cli/actions/remoteAction.ts 91.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1001      +/-   ##
==========================================
+ Coverage   89.50%   89.83%   +0.32%     
==========================================
  Files         120      120              
  Lines        9192     9234      +42     
  Branches     1662     1683      +21     
==========================================
+ Hits         8227     8295      +68     
+ Misses        965      939      -26     

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

- Fix extractRepoName to handle trailing slashes, query strings, and
  fragments in URLs (e.g., https://github.com/user/repo/ now works)
- Extract toTitleCase helper function to reduce code duplication
- Use projectName instead of sourceUrl for link text in SKILL.md footer
  (displays as "from [Vite](https://...)" instead of full URL twice)
- Add tests for URL edge cases (trailing slash, query, fragment)
@claude
Copy link
Contributor

claude bot commented Dec 12, 2025

PR Review: feat(skill): Improve skill generation for remote repositories

I've completed a thorough review of this PR. The implementation thoughtfully addresses issues with remote repository skill generation, particularly around project name derivation, source URL attribution, and selective directory copying.

Strengths

  • Clear problem resolution with targeted solutions
  • Good architectural decisions (metadata threading, selective .claude/skills copying)
  • Comprehensive test coverage including edge cases
  • Security-conscious implementation

Code Quality Suggestions

  1. Consider using project name instead of full URL in the SKILL.md template link text (line 102 in skillStyle.ts)
  2. Include actual error message in the error handler (line 241 in remoteAction.ts)
  3. Fix the kebab-case test to actually test kebab-case conversion (line 99 in skillUtils.test.ts)

Premortem Analysis

The implementation handles potential edge cases well:

  • Non-standard Git URLs gracefully fall back to 'unknown'
  • Concurrent skill generation uses reasonable overwrite behavior
  • Consider adding URL validation for additional security

Overall Assessment

This PR is ready to merge. The implementation successfully resolves the identified issues while maintaining backward compatibility. The selective copying approach is particularly thoughtful.

Great work on this enhancement!

Replace regex patterns that could cause polynomial time complexity
with safe string methods:
- /[?#].*$/ → indexOf + slice
- /\/+$/ → iterative trimTrailingSlashes helper

This addresses GitHub Advanced Security warnings about potential
ReDoS attacks with maliciously crafted URLs containing many
repetitions of '#' or '/'.
@claude
Copy link
Contributor

claude bot commented Dec 12, 2025

Code Review Summary

I've reviewed PR #1001 comprehensively, and this is a well-implemented enhancement to the skill generation feature for remote repositories. The changes effectively address the three main issues outlined in the PR description.

Strengths

  1. Clean Architecture: The implementation threads the new parameters (skillProjectName and skillSourceUrl) through the pipeline without breaking existing interfaces
  2. Security-Conscious: The ReDoS vulnerability fix using string methods instead of regex patterns is excellent
  3. Comprehensive Test Coverage: Good coverage for edge cases including trailing slashes, query strings, and fragments
  4. Thoughtful Design: The selective copying of only .claude/skills/ prevents conflicts with existing configurations

🔍 Code Quality Observations

Minor improvements to consider
  1. Template Safety (src/core/skill/skillStyle.ts:102)

    • The sourceUrl is rendered unescaped using {{{sourceUrl}}} in both the link text and URL
    • Consider using the projectName for the link text instead: from [{{{projectName}}}]({{{sourceUrl}}})
    • This would avoid displaying the URL twice and provide cleaner output
  2. Test Case Accuracy (tests/core/skill/skillUtils.test.ts:99-101)

    • The test claims "kebab-case" but uses repomix (not actually kebab-case)
    • Consider using my-project-name to properly test the kebab-case conversion
  3. Code Duplication (src/core/skill/skillUtils.ts)

    • The toTitleCase helper is well-extracted, reducing duplication between generateProjectName and generateProjectNameFromUrl
    • Good refactoring!

🎯 Premortem Analysis

Potential edge cases and mitigations

Risk 1: Non-standard Git URLs

  • SSH URLs with non-standard ports or custom Git servers might not parse correctly
  • Current Mitigation: Falls back gracefully to "unknown" if parsing fails ✅

Risk 2: Malformed URLs in skillSourceUrl

  • No explicit URL validation could allow invalid URLs
  • Suggested Mitigation: Consider validating URLs upstream with new URL() and allowing only http/https protocols

Risk 3: Concurrent skill generation

  • Multiple processes could have race conditions when copying to .claude/skills/
  • Current Mitigation: Copy operation overwrites, which is acceptable for this use case ✅

Overall Assessment

This PR is ready to merge. The implementation is solid, maintains backward compatibility, and follows project conventions. The selective directory copying and improved project name generation significantly enhance the user experience when working with remote repositories.

Particularly commendable:

  • The ReDoS vulnerability fix shows security awareness
  • The comprehensive test suite covers important edge cases
  • The decision to copy only .claude/skills/ is a thoughtful solution that prevents unintended side effects

Great work on this improvement! 🚀

@yamadashy yamadashy merged commit f482ec3 into main Dec 12, 2025
55 of 56 checks passed
@yamadashy yamadashy deleted the fix/skill-generate-project-name branch December 12, 2025 13:22
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