feat(skill-creator): Add path reference validation

- Add find_path_references() to scan SKILL.md for bundled resource paths
- Add validate_path_references() to verify referenced files exist
- Smart filtering for example/documentation contexts
- Update SKILL.md Step 6 with validation details
- Bump version to 1.2.0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
daymade
2025-12-01 20:33:15 +08:00
parent adc4072f02
commit 31a535b409
3 changed files with 124 additions and 12 deletions

View File

@@ -5,17 +5,17 @@
"email": "daymadev89@gmail.com"
},
"metadata": {
"description": "Professional Claude Code skills for GitHub operations, document conversion, diagram generation, statusline customization, Teams communication, repomix utilities, skill creation, CLI demo generation, LLM icon access, Cloudflare troubleshooting, UI design system extraction, professional presentation creation, YouTube video downloading, secure repomix packaging, ASR transcription correction, video comparison quality analysis, comprehensive QA testing infrastructure, and prompt optimization with EARS methodology",
"version": "1.11.0",
"description": "Professional Claude Code skills for GitHub operations, document conversion, diagram generation, statusline customization, Teams communication, repomix utilities, skill creation, CLI demo generation, LLM icon access, Cloudflare troubleshooting, UI design system extraction, professional presentation creation, YouTube video downloading, secure repomix packaging, ASR transcription correction, video comparison quality analysis, comprehensive QA testing infrastructure, prompt optimization with EARS methodology, session history recovery, and documentation cleanup",
"version": "1.13.0",
"homepage": "https://github.com/daymade/claude-code-skills"
},
"plugins": [
{
"name": "skill-creator",
"description": "Essential meta-skill for creating effective Claude Code skills with initialization scripts, validation, packaging, and privacy best practices",
"description": "Essential meta-skill for creating effective Claude Code skills with initialization scripts, validation, packaging, marketplace registration, and privacy best practices",
"source": "./",
"strict": false,
"version": "1.0.0",
"version": "1.2.0",
"category": "developer-tools",
"keywords": ["skill-creation", "claude-code", "development", "tooling", "workflow", "meta-skill", "essential"],
"skills": ["./skill-creator"]
@@ -189,6 +189,26 @@
"category": "productivity",
"keywords": ["prompt-engineering", "ears", "requirements", "specifications", "optimization", "domain-theory", "prompt-enhancement", "ai-prompting"],
"skills": ["./prompt-optimizer"]
},
{
"name": "claude-code-history-files-finder",
"description": "Find and recover content from Claude Code session history files. Use when searching for deleted files, tracking changes across sessions, analyzing conversation history, or recovering code/documents from previous Claude interactions. Triggers include mentions of session history, recover deleted, find in history, previous conversation, or .claude/projects",
"source": "./",
"strict": false,
"version": "1.0.0",
"category": "developer-tools",
"keywords": ["session-history", "recovery", "deleted-files", "conversation-history", "file-tracking", "claude-code", "history-analysis"],
"skills": ["./claude-code-history-files-finder"]
},
{
"name": "docs-cleaner",
"description": "Consolidates redundant documentation while preserving all valuable content. Use when cleaning up documentation bloat, merging redundant docs, reducing documentation sprawl, or consolidating multiple files covering the same topic",
"source": "./",
"strict": false,
"version": "1.0.0",
"category": "productivity",
"keywords": ["documentation", "cleanup", "consolidation", "redundancy", "merge", "docs"],
"skills": ["./docs-cleaner"]
}
]
}

View File

@@ -194,6 +194,8 @@ To begin implementation, start with the reusable resources identified above: `sc
Also, delete any example files and directories not needed for the skill. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.
**When updating an existing skill**: Scan all existing reference files to check if they need corresponding updates. New features often require updates to architecture, workflow, or other existing documentation to maintain consistency.
#### Reference File Naming
Filenames must be self-explanatory without reading contents.
@@ -276,13 +278,41 @@ The packaging script will:
- YAML frontmatter format and required fields
- Skill naming conventions and directory structure
- Description completeness and quality
- File organization and resource references
- **Path reference integrity** - all `scripts/`, `references/`, and `assets/` paths mentioned in SKILL.md must exist
2. **Package** the skill if validation passes, creating a zip file named after the skill (e.g., `my-skill.zip`) that includes all files and maintains the proper directory structure for distribution.
**Common validation failure:** If SKILL.md references `scripts/my_script.py` but the file doesn't exist, validation will fail with "Missing referenced files: scripts/my_script.py". Ensure all bundled resources exist before packaging.
If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again.
### Step 7: Iterate
### Step 7: Update Marketplace
After packaging, update the marketplace registry to include the new or updated skill.
**For new skills**, add an entry to `.claude-plugin/marketplace.json`:
```json
{
"name": "skill-name",
"description": "Copy from SKILL.md frontmatter description",
"source": "./",
"strict": false,
"version": "1.0.0",
"category": "developer-tools",
"keywords": ["relevant", "keywords"],
"skills": ["./skill-name"]
}
```
**For updated skills**, bump the version in `plugins[].version` following semver:
- Patch (1.0.x): Bug fixes, typo corrections
- Minor (1.x.0): New features, additional references
- Major (x.0.0): Breaking changes, restructured workflows
**Also update** `metadata.version` and `metadata.description` if the overall plugin collection changed significantly.
### Step 8: Iterate
After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.

View File

@@ -8,33 +8,90 @@ import os
import re
from pathlib import Path
def find_path_references(content: str) -> list[str]:
"""
Extract path references from SKILL.md content.
Looks for patterns like scripts/xxx, references/xxx, assets/xxx
Filters out:
- Placeholder paths (xxx, example, etc.)
- Paths in example contexts (lines containing "Example:", "e.g.", etc.)
- Generic documentation examples
"""
# Pattern to match bundled resource paths (scripts/, references/, assets/)
pattern = r'(?:scripts|references|assets)/[\w./-]+'
# Find all matches with their line context
unique_paths = set()
for line in content.split('\n'):
# Skip lines that are clearly examples or documentation
line_lower = line.lower()
if any(x in line_lower for x in [
'example:', 'examples:', 'e.g.', 'for example',
'- **example', '- example:', 'such as',
'pattern:', 'usage:', '', '',
'- **allowed', '- **best practice', 'would be helpful',
'like `scripts/', 'like `references/', 'like `assets/',
]):
continue
# Find paths in this line
matches = re.findall(pattern, line)
for path in matches:
# Skip obvious placeholders
if any(x in path.lower() for x in ['example', 'xxx', '<', '>', 'my-', 'my_']):
continue
unique_paths.add(path)
return list(unique_paths)
def validate_path_references(skill_path: Path, content: str) -> tuple[bool, list[str]]:
"""
Verify all path references in SKILL.md actually exist.
Returns:
(all_exist, missing_paths)
"""
referenced_paths = find_path_references(content)
missing = []
for ref_path in referenced_paths:
full_path = skill_path / ref_path
if not full_path.exists():
missing.append(ref_path)
return len(missing) == 0, missing
def validate_skill(skill_path):
"""Basic validation of a skill"""
skill_path = Path(skill_path)
# Check SKILL.md exists
skill_md = skill_path / 'SKILL.md'
if not skill_md.exists():
return False, "SKILL.md not found"
# Read and validate frontmatter
content = skill_md.read_text()
if not content.startswith('---'):
return False, "No YAML frontmatter found"
# Extract frontmatter
match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if not match:
return False, "Invalid frontmatter format"
frontmatter = match.group(1)
# Check required fields
if 'name:' not in frontmatter:
return False, "Missing 'name' in frontmatter"
if 'description:' not in frontmatter:
return False, "Missing 'description' in frontmatter"
# Extract name for validation
name_match = re.search(r'name:\s*(.+)', frontmatter)
if name_match:
@@ -53,6 +110,11 @@ def validate_skill(skill_path):
if '<' in description or '>' in description:
return False, "Description cannot contain angle brackets (< or >)"
# Validate path references exist
paths_valid, missing_paths = validate_path_references(skill_path, content)
if not paths_valid:
return False, f"Missing referenced files: {', '.join(missing_paths)}"
return True, "Skill is valid!"
if __name__ == "__main__":