Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:42:40 +08:00
commit 2446a70ab4
9 changed files with 1970 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "skill-customizer",
"description": "Fork and iteratively customize existing skills based on your preferences and workflows. Perfect for personalizing skills to match your output format preferences, company standards, or domain-specific requirements.",
"version": "0.0.0-2025.11.28",
"author": {
"name": "Meta-Skills Collection",
"email": "onlrrr@gmail.com"
},
"skills": [
"./skills/skill-customizer"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# skill-customizer
Fork and iteratively customize existing skills based on your preferences and workflows. Perfect for personalizing skills to match your output format preferences, company standards, or domain-specific requirements.

64
plugin.lock.json Normal file
View File

@@ -0,0 +1,64 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:nemori-ai/skills:skill-customizer",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "a56833dfa3836fb320d760f6cf6034c1418c0095",
"treeHash": "1414b4f2c863589edd46c7fe025ea08c1c9fba810213bd8f626cbd90e30e6b36",
"generatedAt": "2025-11-28T10:27:18.470037Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "skill-customizer",
"description": "Fork and iteratively customize existing skills based on your preferences and workflows. Perfect for personalizing skills to match your output format preferences, company standards, or domain-specific requirements."
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "2173727a289ffbeb3d819a878fc24942799964a10194a91e0f850f90f495215a"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "1768323e1b63ba34e6ea7fba266d2f022f14f1e786c391572f7b7c8696d745ba"
},
{
"path": "skills/skill-customizer/SKILL.md",
"sha256": "fca92e98bb9ebac15fd9b9e51c8562a37aefda45609ec1c6e886a33b5cc159ee"
},
{
"path": "skills/skill-customizer/references/customization_patterns.md",
"sha256": "e3acd7cba083792e43f4b16036f5bc7ad09920212b7e9e439854872bcee8cde2"
},
{
"path": "skills/skill-customizer/scripts/fork_skill.py",
"sha256": "30fdaecfec6e1b1bf03a97239ec0ce2b4b68f7e0b12e0b272b1dca39fd4ce936"
},
{
"path": "skills/skill-customizer/scripts/quick_validate.py",
"sha256": "d99c187cb1186da912a5a859f8ac2916f6f2ad7e1cd3e5df7e2342760185892d"
},
{
"path": "skills/skill-customizer/scripts/track_feedback.py",
"sha256": "dfce811ce26f0bec13f3b327ae55ceb1096ea9d55f8746226166719847ea94e1"
},
{
"path": "skills/skill-customizer/scripts/finalize_skill.py",
"sha256": "4a7b44433af48799bbb3fe7bde6df2b4537d4b32c118c0a6acede4b5b4111c69"
}
],
"dirSha256": "1414b4f2c863589edd46c7fe025ea08c1c9fba810213bd8f626cbd90e30e6b36"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,289 @@
---
name: skill-customizer
description: Customize existing skills through iterative improvement based on user feedback and preferences. Use when users want to personalize a skill to match their specific workflow, output preferences, domain requirements, or company standards by forking and iteratively refining an existing skill.
---
# Skill Customizer
Enable users to transform existing skills into personalized versions that perfectly match their unique needs through forking, testing, gathering feedback, and iterative improvement.
## When to Use This Skill
Use skill-customizer when:
- User finds an existing skill useful but wants specific modifications
- User has personal preferences about output format, verbosity, or style
- User needs to adapt a skill to company-specific requirements or workflows
- User wants to add domain-specific knowledge to an existing skill
- User discovers gaps after trying a skill on real tasks
**Do NOT use when:**
- User wants to create a completely new skill from scratch (use skill-creator instead)
- User only needs a one-time modification without creating a reusable skill
- The customization is so extensive that starting fresh would be simpler
## Proactive Suggestion Trigger
**When to proactively suggest using skill-customizer:**
When a user is actively using a skill and has provided modification requests, preferences, or guidance during the session, watch for satisfaction signals such as:
- User expresses satisfaction with the customized behavior ("That's perfect!", "Exactly what I needed", "Much better")
- User has given multiple consistent preferences or modifications
- User has requested specific output format changes or workflow adjustments
- The session shows iterative refinement that stabilized to user's preference
**In these scenarios, proactively offer:**
"I notice you've been refining how [skill-name] works to match your preferences. Would you like to save these customizations as your own personalized version of this skill? I can help you create a customized skill that automatically applies these preferences in future sessions."
This transforms one-time adjustments into reusable, persistent customizations that improve the user's long-term workflow.
## Customization Workflow
Follow this iterative process to customize a skill effectively:
### Phase 1: Fork the Base Skill
**Identify the base skill**
Ask the user:
- Which skill to customize?
- Where is the skill located?
- What name for the customized version?
**Create the fork**
Run from the skill-customizer directory:
```bash
cd skill-customizer
python3 scripts/fork_skill.py <source-skill-path> <new-skill-name> --path <output-directory>
```
Or from parent directory with full path:
```bash
python3 skill-customizer/scripts/fork_skill.py <source-skill-path> <new-skill-name> --path <output-directory>
```
This creates:
- Complete copy of the original skill
- Updated metadata with customization tracking
- CUSTOMIZATION_LOG.md for documenting changes
**Understand the base skill**
Review the forked skill:
- SKILL.md content and structure
- Scripts in `scripts/` directory
- Reference documents in `references/` directory
- Assets in `assets/` directory
### Phase 2: Test and Gather Feedback
**Use the skill on real tasks**
Have the user try the forked skill to identify:
- What works well as-is
- What doesn't match expectations
- Specific pain points or inefficiencies
- Missing features or capabilities
**Collect structured feedback**
Use the feedback tracking script:
```bash
python3 scripts/track_feedback.py <skill-directory>
```
Or collect through conversation:
1. "What task were you trying to accomplish?"
2. "What aspects worked well?"
3. "What didn't match your expectations?"
4. "What are your specific preferences?"
5. "What improvements would help most?"
This creates/updates FEEDBACK.md with timestamped entries.
### Phase 3: Plan and Apply Improvements
**Analyze feedback and plan changes**
Categorize modifications by target:
**SKILL.md modifications:**
- Change default behavior or workflows
- Adjust output format preferences
- Update examples with user-specific scenarios
- Add user's domain context
- Modify tone or verbosity
**Script modifications:**
- Adjust default parameters
- Add preprocessing or postprocessing steps
- Customize output formatting
- Add validation logic specific to user's needs
**Reference additions:**
- Add company guidelines or policies
- Include domain-specific schemas
- Document user's preferred workflows
**Asset additions:**
- Add company templates
- Include brand assets
- Add domain-specific boilerplate
**Apply targeted modifications**
For each modification:
1. Edit the relevant file
2. Test the change on the same task that revealed the gap
3. Document in CUSTOMIZATION_LOG.md with version, what changed, why, and how to verify
### Phase 4: Iterate Until Satisfied
**Test the improved version**
After applying changes:
1. Run the skill on the same task again
2. Compare results with previous version
3. Verify the changes addressed the feedback
**Gather new feedback**
Ask the user:
- "Does this better match your expectations?"
- "Are there any new issues or additional preferences?"
- "What else would you like to adjust?"
**Repeat or finalize**
If more improvements needed: return to Phase 3
If satisfied: proceed to Phase 5
### Phase 5: Packaging the Skill
Once the skill is ready, package it into a distributable zip file. The packaging process automatically validates the skill first to ensure it meets all requirements.
```bash
python3 scripts/finalize_skill.py <skill-directory>
```
Optional output directory specification:
```bash
python3 scripts/finalize_skill.py <skill-directory> ./dist
```
The packaging script will:
1. **Validate** the skill automatically, checking:
- YAML frontmatter format and required fields
- Skill naming conventions and directory structure
- Description completeness and quality
2. **Package** the skill if validation passes, creating a timestamped zip file: `{skill-name}-{YYYYMMDD-HHMMSS}.zip`
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.
## Best Practices
**Iterative Improvement**
- Make small, focused changes rather than large overhauls
- Test each change before moving to the next
- Document each iteration in CUSTOMIZATION_LOG.md
- Keep feedback organized and prioritized
**Maintain Skill Quality**
- Follow the same quality standards as the original skill
- Use imperative/infinitive form in SKILL.md (not second person)
- Keep SKILL.md concise; move details to `references/`
- Ensure scripts are well-documented and reusable
**Preserve Original Structure**
- Keep the same directory organization as the base skill
- Maintain compatibility with skill tooling
- Don't break existing functionality unless intentionally removing it
**Document Customizations**
- Always update CUSTOMIZATION_LOG.md with each change
- Include rationale for changes (why, not just what)
- Provide testing steps to verify improvements
- Track version numbers for major iterations
**Balance Specificity and Reusability**
- Don't over-customize to a single task
- Keep the skill useful for related tasks
- Consider whether changes should be configurable vs. hardcoded
## Resources
### scripts/fork_skill.py
Creates a customized copy of an existing skill with updated metadata and customization tracking.
**Usage:**
```bash
scripts/fork_skill.py <source-skill-path> <new-skill-name> --path <output-directory>
```
**What it does:**
- Copies entire skill directory structure
- Updates SKILL.md frontmatter with new name
- Adds customization metadata (source skill, date)
- Creates CUSTOMIZATION_LOG.md for tracking changes
### scripts/track_feedback.py
Interactively collects and organizes user feedback for systematic improvement.
**Usage:**
```bash
scripts/track_feedback.py <skill-directory>
```
**What it does:**
- Prompts for structured feedback (task, preferences, improvements)
- Creates/updates FEEDBACK.md with timestamped entries
- Analyzes feedback patterns across multiple entries
- Helps prioritize customization efforts
### scripts/finalize_skill.py
Validates and packages a customized skill with timestamp for distribution.
**Usage:**
```bash
scripts/finalize_skill.py <skill-directory> [output-directory]
```
**What it does:**
- Validates skill structure and frontmatter automatically
- Creates timestamped zip file: `{skill-name}-{YYYYMMDD-HHMMSS}.zip`
The timestamp allows tracking different versions and iterations of the customized skill.
### scripts/quick_validate.py
Standalone validation script for checking skill structure without packaging.
**Usage:**
```bash
scripts/quick_validate.py <skill-directory>
```
**What it does:**
- Checks YAML frontmatter format
- Validates required fields (name, description)
- Verifies naming conventions
Use this during development to validate changes before packaging.
### references/customization_patterns.md
Comprehensive guide to common customization patterns, detailed examples, and best practices.
Load this reference when:
- Facing complex customization decisions
- Unsure how to implement a specific type of change
- Looking for examples of successful customizations
- Planning extensive modifications
Includes:
- Detailed modification examples with before/after code
- Troubleshooting common customization challenges
- Advanced techniques for skill enhancement
- Patterns for maintaining customized skills over time

View File

@@ -0,0 +1,908 @@
# Customization Patterns Reference
This comprehensive guide provides detailed examples, patterns, and best practices for customizing skills effectively.
## Table of Contents
1. [Modification Patterns by Type](#modification-patterns-by-type)
2. [Before/After Examples](#beforeafter-examples)
3. [Common Challenges and Solutions](#common-challenges-and-solutions)
4. [Advanced Techniques](#advanced-techniques)
5. [Maintenance Best Practices](#maintenance-best-practices)
---
## Modification Patterns by Type
### Pattern 1: Output Format Customization
**Use case:** User prefers a different output format than the skill's default
**Common scenarios:**
- JSON → Markdown conversion
- Adding/removing metadata fields
- Changing table formats
- Customizing citations or references
**Implementation approach:**
1. **Simple format preference** (Markdown vs JSON):
- Modify SKILL.md to specify new default format
- Update examples to show new format
- If script-based, add format parameter to scripts
2. **Complex formatting requirements** (company style guide):
- Create `scripts/custom_formatter.py` with formatting functions
- Add `references/format_guide.md` with detailed specifications
- Update SKILL.md to reference custom formatter
- Provide examples of correctly formatted output
**Example modification:**
```markdown
# Before (in SKILL.md):
## Output Format
Return results as JSON with the following structure:
{
"title": "...",
"content": "..."
}
# After (customized for Markdown preference):
## Output Format
Return results as Markdown with the following structure:
# [Title]
[Content]
Source: [Document name, page X]
```
### Pattern 2: Workflow Simplification
**Use case:** User only uses a subset of the skill's features
**Common scenarios:**
- Removing unused sections from decision trees
- Focusing on a single primary workflow
- Eliminating optional features
- Streamlining for repetitive tasks
**Implementation approach:**
1. **Identify core workflow:**
- Review user's actual usage patterns
- Determine which features are never used
- Identify the 80/20 of user's needs
2. **Restructure SKILL.md:**
- Move primary workflow to the top
- Simplify or remove unused sections
- Update decision trees to reflect focused use case
- Consolidate related operations
3. **Update examples:**
- Replace generic examples with user-specific scenarios
- Focus on most common tasks
- Remove examples for unused features
**Example modification:**
```markdown
# Before: Generic PDF skill with many capabilities
## Capabilities
1. Extract text
2. Extract tables
3. Extract images
4. Merge PDFs
5. Split PDFs
6. Rotate pages
7. Add watermarks
8. Fill forms
# After: Streamlined for table extraction use case
## Primary Workflow: Table Extraction
Extract tables from PDF documents and output as CSV.
### Quick Start
[Focused table extraction workflow]
### Advanced Options
- Multi-page table handling
- Custom column mapping
- Header detection
(Other capabilities removed or moved to appendix)
```
### Pattern 3: Domain Context Addition
**Use case:** User works in a specialized domain requiring specific knowledge
**Common scenarios:**
- Adding industry terminology
- Including domain-specific schemas
- Incorporating regulatory requirements
- Adding company-specific processes
**Implementation approach:**
1. **Create domain reference files:**
- `references/domain_glossary.md` - Terminology and definitions
- `references/domain_schemas.md` - Data structures and standards
- `references/domain_workflows.md` - Industry-specific processes
2. **Update SKILL.md:**
- Add domain context to overview
- Reference domain files in relevant sections
- Include domain-specific examples
- Adjust language for domain audience
3. **Add domain assets:**
- Templates specific to the domain
- Sample documents from the domain
- Domain-specific boilerplate
**Example modification:**
```markdown
# Before: Generic document processing
## Overview
Process documents to extract and analyze content.
# After: Healthcare-specific document processing
## Overview
Process healthcare documents (clinical notes, lab reports, discharge summaries)
according to HL7 and HIPAA standards. Extract structured medical information
while maintaining compliance with healthcare regulations.
## Domain Context
Load `references/medical_terminology.md` for standardized medical terms and codes.
Load `references/hipaa_compliance.md` for data handling requirements.
## Workflows
[Updated with healthcare-specific examples and terminology]
```
### Pattern 4: Parameter Default Adjustment
**Use case:** User consistently uses different parameters than skill defaults
**Common scenarios:**
- Changing verbosity levels
- Adjusting processing thresholds
- Modifying timeout or retry settings
- Updating file format preferences
**Implementation approach:**
1. **In SKILL.md:**
- Update default values in workflow descriptions
- Modify examples to use new defaults
- Document when non-default values might be appropriate
2. **In scripts:**
- Change default parameter values in function signatures
- Update configuration constants
- Maintain backward compatibility if needed
**Example modification:**
```python
# Before: scripts/extractor.py
def extract_text(pdf_path, verbosity='verbose'):
"""Extract text with verbose output by default"""
if verbosity == 'verbose':
# Include metadata, page numbers, formatting
pass
else:
# Concise output
pass
# After: Customized for concise preference
def extract_text(pdf_path, verbosity='concise'):
"""Extract text with concise output by default (customized)"""
if verbosity == 'concise':
# Clean text only
pass
else:
# Include additional details
pass
```
### Pattern 5: Tool Integration
**Use case:** User wants to integrate with specific tools or services
**Common scenarios:**
- Adding API integrations
- Connecting to company databases
- Integrating with project management tools
- Automating with company workflows
**Implementation approach:**
1. **Create integration scripts:**
- `scripts/api_connector.py` - Handle API authentication and calls
- `scripts/data_transformer.py` - Convert between formats
2. **Add integration documentation:**
- `references/api_setup.md` - Configuration instructions
- `references/authentication.md` - Credential management
3. **Update SKILL.md:**
- Add integration setup steps
- Document new workflows enabled by integration
- Provide troubleshooting guidance
**Example modification:**
```markdown
# Added to SKILL.md:
## Notion Integration
This customized version integrates with Notion to automatically save processed
documents to your Notion workspace.
### Setup
1. Generate Notion API token (see references/notion_setup.md)
2. Set NOTION_TOKEN environment variable
3. Configure target database ID
### Workflow
After processing a document:
1. Extract content using standard workflow
2. Format for Notion (using scripts/notion_formatter.py)
3. Upload to specified Notion database
4. Return Notion page URL
### Scripts
- scripts/notion_connector.py - Handle Notion API calls
- scripts/notion_formatter.py - Convert to Notion blocks
```
---
## Before/After Examples
### Example 1: PDF Skill → My PDF Tables
**Original use case:** General PDF processing
**Customized use case:** Quick table extraction for financial reports
#### Before: Generic PDF skill excerpt
```markdown
## Capabilities
### Extract Text
Use pypdf or pdfplumber to extract text content...
### Extract Tables
Use pdfplumber to extract tables...
[Detailed multi-option workflow]
### Merge PDFs
Combine multiple PDF files...
### Split PDFs
Separate PDF into individual pages...
```
#### After: Streamlined for table extraction
```markdown
## Primary Workflow: Financial Report Table Extraction
Extract tables from financial PDF reports and output as CSV files with
proper numeric formatting.
### Quick Workflow
1. Load PDF using pdfplumber
2. Detect tables on each page
3. Extract with financial number formatting preserved
4. Output as CSV with headers
5. Include source page reference
### Default Settings (Customized)
- Output format: CSV (not JSON)
- Number format: Preserve commas and decimal points
- Headers: Auto-detect from first row
- Multiple tables: Separate files with page suffix
### Example
Input: quarterly_report.pdf
Output: quarterly_report_p3_table1.csv, quarterly_report_p3_table2.csv
[Detailed table extraction code with financial formatting]
---
Note: Other PDF capabilities (merge, split, etc.) removed for focus.
Refer to base 'pdf' skill if needed.
```
### Example 2: Internal Comms → Company X Communications
**Original use case:** General internal communications
**Customized use case:** Company X-specific communication standards
#### Before: Generic internal comms
```markdown
## Writing Status Updates
Write clear status updates for internal teams.
### Structure
- Summary
- Progress
- Blockers
- Next steps
### Tone
Professional and clear.
```
#### After: Company X customized
```markdown
## Writing Status Updates (Company X Standard)
Follow Company X communication guidelines (references/company_style_guide.md).
### Structure (Company X Template)
1. **TL;DR** - One-sentence summary
2. **Highlights** - 3-5 bullet points (emoji required per style guide)
3. **Metrics** - Include OKR alignment
4. **Blockers** - Use RAG status (Red/Amber/Green)
5. **Next Steps** - Include owner and due date
6. **Links** - Notion doc, Jira tickets, Slack thread
### Tone
Match Company X voice:
- Casual but professional
- Use "we" not "I"
- Default to transparent/public sharing
- Include memes/GIFs when appropriate
### Template
Use assets/company_x_status_template.md as starting point.
### Example Output
[Shows Company X-specific format with emojis, RAG status, etc.]
```
### Example 3: Canvas Design → Medical Infographic Designer
**Original use case:** General visual design
**Customized use case:** Medical education infographics
#### Before: Generic design instructions
```markdown
## Design Principles
- Use color theory for visual hierarchy
- Balance composition
- Choose appropriate typography
- Create clear focal points
```
#### After: Medical infographic specific
```markdown
## Medical Infographic Design Principles
Follow medical education best practices and accessibility standards.
### Color Requirements
- Use colorblind-safe palette (references/medical_colors.md)
- Avoid red/green for critical distinctions
- High contrast ratios (WCAG AAA)
- Use color + pattern for differentiation
### Typography
- Sans-serif for body (Arial, Helvetica)
- Minimum 14pt for body text (readability for all ages)
- Medical terms in bold on first use
- Include pronunciation guides for complex terms
### Medical Content Standards
- Cite sources (AMA format)
- Include disclaimer for educational use
- Use anatomically correct illustrations from assets/medical_images/
- Follow HIPAA guidelines for any patient data
### Layout
- Clear information hierarchy (diagnosis → symptoms → treatment)
- Use flowcharts for decision trees
- Include legend for all symbols
- Mobile-friendly formatting (many clinicians use tablets)
### Assets
- assets/anatomical_illustrations/ - Approved medical illustrations
- assets/medical_icons/ - Standard medical symbol set
- assets/citation_template.txt - AMA citation format
```
---
## Common Challenges and Solutions
### Challenge 1: Balancing Customization vs. Reusability
**Problem:** Over-customizing for a single task makes the skill too narrow
**Solutions:**
1. **Parameterize instead of hardcode:**
- Use configuration files for user-specific values
- Make customizations optional/togglable
- Provide defaults but allow overrides
2. **Document the scope:**
- Clearly state what the customized skill is for
- List related use cases it still supports
- Note when to use base skill vs. customized version
3. **Version thoughtfully:**
- Keep base fork for general use
- Create specialized forks for very specific needs
- Document fork relationships
**Example:**
```markdown
# In SKILL.md metadata:
metadata:
customized-from: pdf
customization-scope: Financial report table extraction
also-works-for: Quarterly reports, balance sheets, income statements
not-suitable-for: Image extraction, form filling, general PDFs
```
### Challenge 2: Keeping Customizations Maintainable
**Problem:** Hard to remember what was changed and why after time passes
**Solutions:**
1. **Comprehensive CUSTOMIZATION_LOG.md:**
- Document every change with rationale
- Include "why" not just "what"
- Note testing procedures
2. **Inline comments in modified scripts:**
```python
# CUSTOMIZED: Changed default from 'verbose' to 'concise'
# Reason: User preference for minimal output (see CUSTOMIZATION_LOG v1.1)
def process(verbosity='concise'):
pass
```
3. **Version number in SKILL.md:**
```yaml
metadata:
customization-version: 2.3
last-updated: 2025-10-21
```
### Challenge 3: Merging Updates from Base Skill
**Problem:** Base skill gets updates/improvements that you want in customized version
**Solutions:**
1. **Track base skill version:**
```yaml
metadata:
customized-from: pdf
base-skill-version: 1.0
last-sync-date: 2025-10-21
```
2. **Manual merge process:**
- Review base skill changelog
- Identify relevant updates
- Apply updates manually to customized version
- Test thoroughly
- Update metadata
3. **Minimize deep modifications:**
- Prefer additions over modifications when possible
- Use wrapper scripts instead of editing base scripts
- Keep modifications isolated and documented
### Challenge 4: Multiple Users with Different Preferences
**Problem:** Team wants shared skill but members have different preferences
**Solutions:**
1. **Configuration-driven approach:**
- Create `config.yaml` for user preferences
- Each user maintains their own config
- Skill reads config at runtime
```python
# scripts/config.py
import yaml
def load_user_config():
config_path = Path.home() / '.skill-config' / 'pdf-config.yaml'
if config_path.exists():
return yaml.safe_load(config_path.read_text())
return default_config()
```
2. **Profile-based customization:**
- Create named profiles (analyst, researcher, designer)
- User selects profile at runtime
- Skill applies profile-specific settings
3. **Fork per user or team:**
- Maintain individual forks for strongly divergent needs
- Share common base scripts as library
- Document fork relationships
### Challenge 5: Testing Customized Skills
**Problem:** Ensuring customizations work as intended without breaking functionality
**Solutions:**
1. **Maintain test cases:**
- Document specific test scenarios in CUSTOMIZATION_LOG.md
- Keep sample input files in `tests/` directory
- Define expected outputs for each customization
2. **Before/after comparison:**
- Run same task on base skill and customized skill
- Compare outputs
- Verify customizations took effect
- Check for unintended side effects
3. **Regression testing:**
- Test previous use cases when adding new customizations
- Ensure new changes don't break earlier improvements
- Maintain a test checklist
**Example test checklist:**
```markdown
# Test Checklist for my-pdf-tables v2.1
- [ ] Basic table extraction works
- [ ] Financial numbers preserve formatting
- [ ] Multi-page tables handled correctly
- [ ] CSV output has correct headers
- [ ] Page numbers included in filename
- [ ] Previous customizations still work:
- [ ] v1.1: Concise output format
- [ ] v1.5: Auto-header detection
- [ ] v2.0: Multiple table separation
```
---
## Advanced Techniques
### Technique 1: Layered Customization
Create a hierarchy of customizations for progressive specialization:
```
pdf (base skill)
└── my-pdf-workflow (general personal customizations)
├── financial-pdf (financial reports)
└── research-pdf (academic papers)
```
**Implementation:**
1. First fork: Personal preferences (output format, defaults)
2. Second fork: Domain-specific (financial vs. research)
3. Document fork hierarchy in metadata
**Benefits:**
- Share common customizations
- Specialize without duplication
- Easy to maintain related forks
### Technique 2: Plugin/Extension Pattern
Design customizations as plugins that extend base skill without modifying it:
**Structure:**
```
my-pdf/
├── SKILL.md (references base + extensions)
├── scripts/
│ ├── extensions/
│ │ ├── financial_formatter.py
│ │ └── auto_namer.py
└── references/
└── base_skill.md (copy of original for reference)
```
**In SKILL.md:**
```markdown
## Base Capabilities
Refer to references/base_skill.md for standard PDF operations.
## Extensions
This customized version adds:
- Financial number formatting (scripts/extensions/financial_formatter.py)
- Smart file naming (scripts/extensions/auto_namer.py)
Use base capabilities as documented, then apply extensions as needed.
```
**Benefits:**
- Clear separation of base vs. custom
- Easier to maintain
- Simple to add/remove extensions
### Technique 3: Template-Based Customization
For skills that generate content, use templates to customize output:
**Structure:**
```
my-comms/
├── SKILL.md
├── scripts/
│ └── template_renderer.py
└── assets/
├── templates/
│ ├── status_update.md
│ ├── project_brief.md
│ └── incident_report.md
```
**Usage:**
```python
# scripts/template_renderer.py
from jinja2 import Template
def render_status_update(data):
template_path = Path('assets/templates/status_update.md')
template = Template(template_path.read_text())
return template.render(**data)
```
**Benefits:**
- Easy to customize without code changes
- Non-technical users can update templates
- Consistent formatting across outputs
### Technique 4: Conditional Behavior Based on Context
Adapt skill behavior based on detected context:
```python
# scripts/context_detector.py
def detect_context(document_path):
"""Detect document type/context to apply appropriate customizations"""
content = read_document(document_path)
if 'QUARTERLY REPORT' in content[:1000]:
return 'financial_quarterly'
elif 'BALANCE SHEET' in content[:1000]:
return 'financial_balance'
elif 'CLINICAL NOTES' in content[:500]:
return 'medical_clinical'
else:
return 'general'
def process_with_context(document_path):
context = detect_context(document_path)
if context == 'financial_quarterly':
return process_financial_quarterly(document_path)
elif context == 'medical_clinical':
return process_medical_clinical(document_path)
else:
return process_general(document_path)
```
**Benefits:**
- Single skill handles multiple specialized scenarios
- Automatic context adaptation
- User doesn't need to specify type
### Technique 5: Feedback-Driven Auto-Refinement
Build in feedback collection and analysis:
```python
# scripts/track_usage.py
def log_usage(task_type, user_satisfaction, notes):
"""Log usage to identify improvement opportunities"""
usage_log = Path('USAGE_LOG.jsonl')
entry = {
'timestamp': datetime.now().isoformat(),
'task_type': task_type,
'satisfaction': user_satisfaction, # 1-5
'notes': notes
}
with open(usage_log, 'a') as f:
f.write(json.dumps(entry) + '\n')
def analyze_usage_patterns():
"""Analyze usage log to identify customization opportunities"""
# Find low-satisfaction tasks
# Identify common pain points
# Suggest targeted improvements
pass
```
**Benefits:**
- Data-driven customization decisions
- Identify patterns over time
- Prioritize highest-impact improvements
---
## Maintenance Best Practices
### Best Practice 1: Regular Review Cycles
**Schedule:** Review customized skills quarterly or after major projects
**Review checklist:**
- Are customizations still relevant?
- Any new pain points to address?
- Can any customizations be generalized?
- Are there unused customizations to remove?
- Does documentation need updates?
### Best Practice 2: Version Control
Use git or similar for tracking changes:
```bash
cd my-customized-skill/
git init
git add .
git commit -m "Initial fork from base skill"
# After each customization iteration
git add .
git commit -m "v1.1: Changed default output format to Markdown
- Modified SKILL.md output section
- Updated examples
- Tested on sample documents
Addresses feedback from 2025-10-15"
```
**Benefits:**
- Track change history
- Easy to revert problematic changes
- Collaborate with others
- Maintain multiple versions
### Best Practice 3: Documentation as Code
Keep documentation close to implementation:
```python
# scripts/financial_formatter.py
"""
Financial number formatter for PDF table extraction
Customization History:
- v1.1 (2025-10-15): Added comma preservation
- v1.2 (2025-10-18): Added currency symbol detection
- v2.0 (2025-10-20): Support for European number formats
Related customization log entries: v1.1, v1.2, v2.0
"""
def format_financial_number(value, preserve_commas=True):
"""
Format extracted number for financial reports
Args:
value: Extracted number string
preserve_commas: Keep thousand separators (default: True per v1.1)
Returns:
Formatted number string
Examples:
>>> format_financial_number("1,234.56")
"1,234.56"
>>> format_financial_number("1.234,56") # European format, v2.0
"1.234,56"
"""
pass
```
### Best Practice 4: Maintain a CHANGELOG
Separate from CUSTOMIZATION_LOG.md, maintain a user-facing changelog:
```markdown
# Changelog: my-pdf-tables
## [2.0.0] - 2025-10-20
### Added
- Support for European number formats (commas/periods swapped)
- Auto-detection of number format from document locale
### Changed
- Default output includes source page numbers
- Table headers now auto-detected (previously manual)
### Fixed
- Multi-page tables no longer split incorrectly
## [1.2.0] - 2025-10-18
### Added
- Currency symbol detection and preservation
- Support for parenthetical negative numbers (accounting format)
## [1.1.0] - 2025-10-15
### Changed
- Default output format: CSV (was JSON)
- Preserve comma thousand separators (was stripping)
### Removed
- Unused image extraction code from base skill
## [1.0.0] - 2025-10-10
### Added
- Initial fork from 'pdf' base skill
- Focus on table extraction workflow
```
### Best Practice 5: Share and Learn
**Within teams:**
- Share successful customization patterns
- Document what worked and what didn't
- Create organization-wide customization library
- Hold periodic skill review sessions
**With community:**
- Contribute useful patterns back to base skills
- Share generalized customizations
- Learn from others' customization approaches
**Documentation:**
- Maintain README.md for customized skill
- Include setup instructions
- Document prerequisites
- Provide troubleshooting guide
---
## Quick Reference: When to Use Each Pattern
| Scenario | Recommended Pattern | Key Resources |
|----------|-------------------|---------------|
| Different output format | Output Format Customization | Modify SKILL.md, add formatter script |
| Only use subset of features | Workflow Simplification | Restructure SKILL.md, remove unused sections |
| Specialized domain/industry | Domain Context Addition | Add references/, update examples |
| Different default settings | Parameter Default Adjustment | Update SKILL.md, modify script defaults |
| Need to connect to other tools | Tool Integration | Add scripts/, integration docs |
| Team with varying preferences | Configuration-driven | Add config.yaml, profile system |
| Progressive specialization | Layered Customization | Multiple forks in hierarchy |
| Extend without modifying | Plugin/Extension Pattern | Extension scripts, modular design |
| Content generation | Template-Based | Templates in assets/, renderer script |
| Handle multiple scenarios | Conditional Behavior | Context detector, branching logic |
---
## Conclusion
Effective skill customization is an iterative process that balances specificity with reusability. Use these patterns as starting points, adapt them to your needs, and always document your customizations thoroughly for future reference.
Remember:
- Start small with targeted improvements
- Test each customization thoroughly
- Document rationale, not just changes
- Review and refine regularly
- Share learnings with others

View File

@@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""
Skill Packager for Customized Skills - Creates a timestamped zip file
Usage:
python scripts/finalize_skill.py <path/to/skill-folder> [output-directory]
Example:
python scripts/finalize_skill.py my-custom-skill
python scripts/finalize_skill.py my-custom-skill ./dist
"""
import sys
import zipfile
from pathlib import Path
from datetime import datetime
from quick_validate import validate_skill
def package_skill(skill_path, output_dir=None):
"""
Package a skill folder into a timestamped zip file.
Args:
skill_path: Path to the skill folder
output_dir: Optional output directory for the zip file (defaults to current directory)
Returns:
Path to the created zip file, or None if error
"""
skill_path = Path(skill_path).resolve()
# Validate skill folder exists
if not skill_path.exists():
print(f"❌ Error: Skill folder not found: {skill_path}")
return None
if not skill_path.is_dir():
print(f"❌ Error: Path is not a directory: {skill_path}")
return None
# Validate SKILL.md exists
skill_md = skill_path / "SKILL.md"
if not skill_md.exists():
print(f"❌ Error: SKILL.md not found in {skill_path}")
return None
# Run validation before packaging
print("🔍 Validating skill...")
valid, message = validate_skill(skill_path)
if not valid:
print(f"❌ Validation failed: {message}")
print(" Please fix the validation errors before packaging.")
return None
print(f"{message}\n")
# Determine output location
skill_name = skill_path.name
if output_dir:
output_path = Path(output_dir).resolve()
output_path.mkdir(parents=True, exist_ok=True)
else:
output_path = Path.cwd()
# Generate timestamp for version tracking
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
zip_filename = output_path / f"{skill_name}-{timestamp}.zip"
# Create the zip file
try:
with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
# Walk through the skill directory
for file_path in skill_path.rglob('*'):
if file_path.is_file():
# Calculate the relative path within the zip
arcname = file_path.relative_to(skill_path.parent)
zipf.write(file_path, arcname)
print(f" Added: {arcname}")
print(f"\n✅ Successfully packaged skill to: {zip_filename}")
return zip_filename
except Exception as e:
print(f"❌ Error creating zip file: {e}")
return None
def main():
if len(sys.argv) < 2:
print("Usage: python scripts/finalize_skill.py <path/to/skill-folder> [output-directory]")
print("\nExample:")
print(" python scripts/finalize_skill.py my-custom-skill")
print(" python scripts/finalize_skill.py my-custom-skill ./dist")
sys.exit(1)
skill_path = sys.argv[1]
output_dir = sys.argv[2] if len(sys.argv) > 2 else None
print(f"📦 Packaging skill: {skill_path}")
if output_dir:
print(f" Output directory: {output_dir}")
print()
result = package_skill(skill_path, output_dir)
if result:
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,260 @@
#!/usr/bin/env python3
"""
Skill Forker - Creates a customized copy of an existing skill
This script copies an existing skill to a new location with a new name,
preserving all structure and resources while updating metadata to reflect
the customization.
Usage:
fork_skill.py <source-skill-path> <new-skill-name> --path <output-directory>
Examples:
fork_skill.py ./pdf my-pdf-workflow --path ./custom-skills
fork_skill.py ../skills/canvas-design my-design-style --path .
fork_skill.py ./internal-comms company-comms --path ~/my-skills
The script will:
- Copy all files and directories from the source skill
- Update the skill name in SKILL.md frontmatter
- Append customization metadata
- Preserve all scripts, references, and assets
- Create a customization log for tracking changes
"""
import sys
import shutil
import re
from pathlib import Path
from datetime import datetime
def update_skill_metadata(skill_md_path, new_name, source_skill_name):
"""
Update the SKILL.md file with new name and customization metadata.
Args:
skill_md_path: Path to the SKILL.md file
new_name: New skill name
source_skill_name: Original skill name for reference
"""
content = skill_md_path.read_text()
# Update the name in frontmatter
content = re.sub(
r'(name:\s*)([^\n]+)',
f'\\1{new_name}',
content,
count=1
)
# Add or update metadata section in frontmatter
frontmatter_match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if frontmatter_match:
frontmatter = frontmatter_match.group(1)
# Check if metadata already exists
if 'metadata:' not in frontmatter:
# Add metadata before the closing ---
new_frontmatter = frontmatter + f'\nmetadata:\n customized-from: {source_skill_name}\n customization-date: {datetime.now().strftime("%Y-%m-%d")}'
content = content.replace(
f'---\n{frontmatter}\n---',
f'---\n{new_frontmatter}\n---'
)
else:
# Update existing metadata
if 'customized-from:' not in frontmatter:
# Add to existing metadata section
content = re.sub(
r'(metadata:)',
f'\\1\n customized-from: {source_skill_name}\n customization-date: {datetime.now().strftime("%Y-%m-%d")}',
content,
count=1
)
skill_md_path.write_text(content)
def create_customization_log(target_dir, source_skill_name, new_name):
"""
Create a customization log to track changes.
Args:
target_dir: Target skill directory
source_skill_name: Original skill name
new_name: New skill name
"""
log_content = f"""# Customization Log: {new_name}
## Base Skill
- **Source**: {source_skill_name}
- **Forked on**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
## Customization History
### Version 1.0 - Initial Fork
- Created customized version from `{source_skill_name}`
- Ready for iterative improvements based on user feedback
---
## How to Track Changes
Document each customization iteration below with:
1. Date and version number
2. What was changed (SKILL.md, scripts, references, assets)
3. Why it was changed (user feedback, preference, workflow improvement)
4. How to test the change
### Example Entry:
### Version 1.1 - [Date]
**Changes:**
- Modified SKILL.md: Updated default output format from JSON to Markdown
- Added script: custom_formatter.py for company-specific formatting
**Reason:**
- User prefers Markdown output for easier sharing with team
- Company style guide requires specific heading formats
**Testing:**
- Run the skill on sample document
- Verify output matches company style guide
---
## Modification Notes
Add your customization notes here as you iterate...
"""
log_path = target_dir / 'CUSTOMIZATION_LOG.md'
log_path.write_text(log_content)
return log_path
def fork_skill(source_path, new_name, output_path):
"""
Fork an existing skill to create a customized version.
Args:
source_path: Path to the source skill directory
new_name: Name for the new customized skill
output_path: Directory where the new skill should be created
Returns:
Path to the created skill directory, or None if error
"""
source_path = Path(source_path).resolve()
output_path = Path(output_path).resolve()
# Validate source skill exists
if not source_path.exists():
print(f"❌ Error: Source skill not found: {source_path}")
return None
if not source_path.is_dir():
print(f"❌ Error: Source path is not a directory: {source_path}")
return None
# Validate SKILL.md exists in source
source_skill_md = source_path / 'SKILL.md'
if not source_skill_md.exists():
print(f"❌ Error: SKILL.md not found in source skill: {source_path}")
return None
# Extract source skill name from directory or SKILL.md
source_skill_name = source_path.name
# Create target directory
target_dir = output_path / new_name
if target_dir.exists():
print(f"❌ Error: Target directory already exists: {target_dir}")
return None
# Copy the entire skill directory
try:
print(f"📋 Copying skill from {source_path} to {target_dir}...")
shutil.copytree(source_path, target_dir)
print(f"✅ Copied all files and directories")
except Exception as e:
print(f"❌ Error copying skill directory: {e}")
return None
# Update SKILL.md metadata
try:
target_skill_md = target_dir / 'SKILL.md'
update_skill_metadata(target_skill_md, new_name, source_skill_name)
print(f"✅ Updated SKILL.md metadata")
except Exception as e:
print(f"❌ Error updating SKILL.md: {e}")
return None
# Create customization log
try:
log_path = create_customization_log(target_dir, source_skill_name, new_name)
print(f"✅ Created customization log: {log_path.name}")
except Exception as e:
print(f"⚠️ Warning: Could not create customization log: {e}")
print(f"\n✅ Successfully forked '{source_skill_name}' to '{new_name}'")
print(f" Location: {target_dir}")
print(f"\n📝 Next steps:")
print(f" 1. Review SKILL.md and identify customization needs")
print(f" 2. Use the skill on real tasks to gather feedback")
print(f" 3. Make iterative improvements based on user preferences")
print(f" 4. Document changes in CUSTOMIZATION_LOG.md")
return target_dir
def main():
if len(sys.argv) < 4 or '--path' not in sys.argv:
print("Usage: fork_skill.py <source-skill-path> <new-skill-name> --path <output-directory>")
print("\nExamples:")
print(" fork_skill.py ./pdf my-pdf-workflow --path ./custom-skills")
print(" fork_skill.py ../skills/canvas-design my-design-style --path .")
print(" fork_skill.py ./internal-comms company-comms --path ~/my-skills")
print("\nSkill name requirements:")
print(" - Hyphen-case (lowercase with hyphens)")
print(" - Alphanumeric characters and hyphens only")
print(" - Must match directory name")
sys.exit(1)
# Parse arguments
source_path = sys.argv[1]
new_name = sys.argv[2]
try:
path_index = sys.argv.index('--path')
output_path = sys.argv[path_index + 1]
except (ValueError, IndexError):
print("❌ Error: --path flag requires an output directory")
sys.exit(1)
# Validate new skill name format
if not re.match(r'^[a-z0-9-]+$', new_name):
print(f"❌ Error: Skill name '{new_name}' must be hyphen-case (lowercase, hyphens only)")
sys.exit(1)
if new_name.startswith('-') or new_name.endswith('-') or '--' in new_name:
print(f"❌ Error: Skill name '{new_name}' cannot start/end with hyphen or contain consecutive hyphens")
sys.exit(1)
print(f"🔀 Forking skill...")
print(f" Source: {source_path}")
print(f" New name: {new_name}")
print(f" Output: {output_path}")
print()
result = fork_skill(source_path, new_name, output_path)
if result:
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""
Quick validation script for skills - minimal version
"""
import sys
import re
from pathlib import Path
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:
name = name_match.group(1).strip()
# Check naming convention (hyphen-case: lowercase with hyphens)
if not re.match(r'^[a-z0-9-]+$', name):
return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)"
if name.startswith('-') or name.endswith('-') or '--' in name:
return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens"
# Extract and validate description
desc_match = re.search(r'description:\s*(.+)', frontmatter)
if desc_match:
description = desc_match.group(1).strip()
# Check for angle brackets
if '<' in description or '>' in description:
return False, "Description cannot contain angle brackets (< or >)"
return True, "Skill is valid!"
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python quick_validate.py <skill_directory>")
sys.exit(1)
valid, message = validate_skill(sys.argv[1])
print(message)
sys.exit(0 if valid else 1)

View File

@@ -0,0 +1,257 @@
#!/usr/bin/env python3
"""
Feedback Tracker - Captures and organizes user feedback for skill customization
This script helps structure user feedback about skill performance, making it
easier to identify specific areas for improvement and track customization needs.
Usage:
track_feedback.py <skill-directory>
Interactive mode:
The script will guide you through collecting structured feedback about:
- What task was attempted
- What worked well
- What didn't match expectations
- Specific preferences or requirements
- Suggested improvements
Output:
Creates/appends to FEEDBACK.md in the skill directory with structured feedback entries
"""
import sys
from pathlib import Path
from datetime import datetime
FEEDBACK_TEMPLATE = """# Skill Feedback Log
This file tracks user feedback and customization needs for iterative skill improvement.
---
"""
FEEDBACK_ENTRY_TEMPLATE = """
## Feedback Entry #{entry_num} - {date}
### Task Context
**What were you trying to accomplish?**
{task_description}
### What Worked Well
{what_worked}
### What Didn't Match Expectations
{what_didnt_work}
### Specific Preferences/Requirements
{preferences}
### Suggested Improvements
{improvements}
### Priority
{priority}
---
"""
def collect_feedback_interactive():
"""
Interactively collect structured feedback from user.
Returns:
Dictionary with feedback components
"""
print("\n📝 Skill Feedback Collection")
print("=" * 60)
print("Please provide detailed feedback to help customize this skill.\n")
feedback = {}
# Task context
print("1⃣ What task were you trying to accomplish?")
print(" (Be specific: e.g., 'Extract tables from a 20-page PDF report')")
feedback['task_description'] = input(" > ").strip()
print()
# What worked
print("2⃣ What aspects of the skill worked well?")
print(" (e.g., 'Text extraction was accurate', 'Fast processing')")
feedback['what_worked'] = input(" > ").strip()
if not feedback['what_worked']:
feedback['what_worked'] = "N/A"
print()
# What didn't work
print("3⃣ What didn't match your expectations?")
print(" (e.g., 'Output format was JSON, I needed Markdown', 'Too verbose')")
feedback['what_didnt_work'] = input(" > ").strip()
if not feedback['what_didnt_work']:
feedback['what_didnt_work'] = "N/A"
print()
# Preferences
print("4⃣ What are your specific preferences or requirements?")
print(" (e.g., 'Always output in Markdown', 'Include source page numbers')")
feedback['preferences'] = input(" > ").strip()
if not feedback['preferences']:
feedback['preferences'] = "N/A"
print()
# Improvements
print("5⃣ What specific improvements would help?")
print(" (e.g., 'Add option to filter by date range', 'Default to concise output')")
feedback['improvements'] = input(" > ").strip()
if not feedback['improvements']:
feedback['improvements'] = "N/A"
print()
# Priority
print("6⃣ How important is this customization?")
print(" Options: critical, high, medium, low")
priority = input(" > ").strip().lower()
if priority not in ['critical', 'high', 'medium', 'low']:
priority = 'medium'
feedback['priority'] = priority.capitalize()
print()
return feedback
def save_feedback(skill_dir, feedback):
"""
Save feedback to FEEDBACK.md file.
Args:
skill_dir: Path to skill directory
feedback: Dictionary with feedback components
Returns:
Path to feedback file
"""
feedback_path = skill_dir / 'FEEDBACK.md'
# Create feedback file if it doesn't exist
if not feedback_path.exists():
feedback_path.write_text(FEEDBACK_TEMPLATE)
entry_num = 1
else:
# Count existing entries
content = feedback_path.read_text()
entry_num = content.count('## Feedback Entry #') + 1
# Format feedback entry
entry = FEEDBACK_ENTRY_TEMPLATE.format(
entry_num=entry_num,
date=datetime.now().strftime("%Y-%m-%d %H:%M"),
task_description=feedback['task_description'],
what_worked=feedback['what_worked'],
what_didnt_work=feedback['what_didnt_work'],
preferences=feedback['preferences'],
improvements=feedback['improvements'],
priority=feedback['priority']
)
# Append to file
with open(feedback_path, 'a') as f:
f.write(entry)
return feedback_path
def analyze_feedback_patterns(feedback_path):
"""
Analyze feedback file for common patterns.
Args:
feedback_path: Path to feedback file
Returns:
Dictionary with analysis results
"""
if not feedback_path.exists():
return None
content = feedback_path.read_text()
analysis = {
'total_entries': content.count('## Feedback Entry #'),
'critical_priority': content.count('Priority\nCritical'),
'high_priority': content.count('Priority\nHigh'),
'common_themes': []
}
# Simple keyword analysis for common themes
keywords = {
'output format': ['format', 'markdown', 'json', 'output'],
'verbosity': ['verbose', 'concise', 'too much', 'too little'],
'performance': ['slow', 'fast', 'speed', 'performance'],
'accuracy': ['accurate', 'wrong', 'incorrect', 'missing'],
}
for theme, words in keywords.items():
if any(word.lower() in content.lower() for word in words):
analysis['common_themes'].append(theme)
return analysis
def main():
if len(sys.argv) < 2:
print("Usage: track_feedback.py <skill-directory>")
print("\nThis script helps collect structured feedback for skill customization.")
print("Run it after using a skill to capture what needs to be improved.")
sys.exit(1)
skill_path = Path(sys.argv[1]).resolve()
# Validate skill directory
if not skill_path.exists():
print(f"❌ Error: Skill directory not found: {skill_path}")
sys.exit(1)
if not skill_path.is_dir():
print(f"❌ Error: Path is not a directory: {skill_path}")
sys.exit(1)
skill_md = skill_path / 'SKILL.md'
if not skill_md.exists():
print(f"❌ Error: Not a valid skill directory (SKILL.md not found): {skill_path}")
sys.exit(1)
print(f"📂 Skill: {skill_path.name}")
# Collect feedback
feedback = collect_feedback_interactive()
# Save feedback
try:
feedback_path = save_feedback(skill_path, feedback)
print(f"\n✅ Feedback saved to: {feedback_path.name}")
except Exception as e:
print(f"\n❌ Error saving feedback: {e}")
sys.exit(1)
# Analyze patterns
analysis = analyze_feedback_patterns(feedback_path)
if analysis and analysis['total_entries'] > 1:
print(f"\n📊 Feedback Summary:")
print(f" Total entries: {analysis['total_entries']}")
print(f" Critical priority: {analysis['critical_priority']}")
print(f" High priority: {analysis['high_priority']}")
if analysis['common_themes']:
print(f" Common themes: {', '.join(analysis['common_themes'])}")
print(f"\n💡 Next steps:")
print(f" 1. Review feedback in {feedback_path.name}")
print(f" 2. Identify specific changes to make in SKILL.md or scripts")
print(f" 3. Apply improvements and test")
print(f" 4. Document changes in CUSTOMIZATION_LOG.md")
if __name__ == "__main__":
main()