From 97e5b56214196248b8d98d22a0e7900e6689ce75 Mon Sep 17 00:00:00 2001 From: KeyInfo Bot Date: Thu, 11 Jun 2026 16:51:52 +0800 Subject: [PATCH] Publish current skill market snapshot Constraint: EAPIL Skill Market is a distribution repository and intentionally does not preserve generated artifact history. Rejected: Preserve generated plugin history | inflates clone and ZIP size for users. Confidence: high Scope-risk: moderate Directive: Collapse market history again after public plugin updates. Tested: python scripts/validate_marketplace.py; validate_plugin.py oh-my-codex; codex plugin add oh-my-codex@eapil-skill-market. Not-tested: PowerShell sync script unavailable locally; Codex model-level smoke invocation timed out on remote request. --- .../plugins/oh-my-codex/skills/skill/SKILL.md | 836 ++++++++++++++++++ .../validate_marketplace.cpython-314.pyc | Bin 0 -> 13113 bytes 2 files changed, 836 insertions(+) create mode 100644 plugins/codex/plugins/oh-my-codex/skills/skill/SKILL.md create mode 100644 scripts/__pycache__/validate_marketplace.cpython-314.pyc diff --git a/plugins/codex/plugins/oh-my-codex/skills/skill/SKILL.md b/plugins/codex/plugins/oh-my-codex/skills/skill/SKILL.md new file mode 100644 index 000000000..cc57a6b17 --- /dev/null +++ b/plugins/codex/plugins/oh-my-codex/skills/skill/SKILL.md @@ -0,0 +1,836 @@ +--- +name: skill +description: Manage local skills - list, add, remove, search, edit, setup wizard +argument-hint: " [args]" +--- + +# Skill Management CLI + +Meta-skill for managing oh-my-codex skills via CLI-like commands. + +## Subcommands + +### /skill list + +Show all local skills organized by scope. + +**Behavior:** +1. Scan user skills at `~/.codex/skills/` +2. Scan project skills at `.codex/skills/` +3. Parse YAML frontmatter for metadata +4. Display in organized table format: + +``` +USER SKILLS (~/.codex/skills/): +| Name | Triggers | Quality | Usage | Scope | +|-------------------|--------------------|---------|-------|-------| +| error-handler | fix, error | 95% | 42 | user | +| api-builder | api, endpoint | 88% | 23 | user | + +PROJECT SKILLS (.codex/skills/): +| Name | Triggers | Quality | Usage | Scope | +|-------------------|--------------------|---------|-------|---------| +| test-runner | test, run | 92% | 15 | project | +``` + +**Fallback:** If quality/usage stats not available, show "N/A" + +--- + +### /skill add [name] + +Interactive wizard for creating a new skill. + +**Behavior:** +1. **Ask for skill name** (if not provided in command) + - Validate: lowercase, hyphens only, no spaces +2. **Ask for description** + - Clear, concise one-liner +3. **Ask for triggers** (comma-separated keywords) + - Example: "error, fix, debug" +4. **Ask for argument hint** (optional) + - Example: " [options]" +5. **Ask for scope:** + - `user` → `~/.codex/skills//SKILL.md` + - `project` → `.codex/skills//SKILL.md` +6. **Create skill file** with template: + +```yaml +--- +name: +description: +triggers: + - + - +argument-hint: "" +--- + +# Skill + +## Purpose + +[Describe what this skill does] + +## When to Activate + +[Describe triggers and conditions] + +## Workflow + +1. [Step 1] +2. [Step 2] +3. [Step 3] + +## Examples + +``` +/oh-my-codex: example-arg +``` + +## Notes + +[Additional context, edge cases, gotchas] +``` + +7. **Report success** with file path +8. **Suggest:** "Edit `/skill edit ` to customize content" + +**Example:** +``` +User: /skill add custom-logger +Assistant: Creating new skill 'custom-logger'... + +Description: Enhanced logging with structured output +Triggers (comma-separated): log, logger, logging +Argument hint (optional): [message] +Scope (user/project): user + +✓ Created skill at ~/.codex/skills/custom-logger/SKILL.md +→ Edit with: /skill edit custom-logger +``` + +--- + +### /skill remove + +Remove a skill by name. + +**Behavior:** +1. **Search for skill** in both scopes: + - `~/.codex/skills//SKILL.md` + - `.codex/skills//SKILL.md` +2. **If found:** + - Display skill info (name, description, scope) + - **Ask for confirmation:** "Delete '' skill from ? (yes/no)" +3. **If confirmed:** + - Delete entire skill directory (e.g., `~/.codex/skills//`) + - Report: "✓ Removed skill '' from " +4. **If not found:** + - Report: "✗ Skill '' not found in user or project scope" + +**Safety:** Never delete without explicit user confirmation. + +**Example:** +``` +User: /skill remove old-logger +Assistant: Found skill 'old-logger' in user scope: + Description: Legacy logging utility + Scope: user (~/.codex/skills/) + +Delete 'old-logger' skill? (yes/no) + +User: yes +Assistant: ✓ Removed skill 'old-logger' from user scope +``` + +--- + +### /skill edit + +Edit an existing skill interactively. + +**Behavior:** +1. **Find skill** by name (search both scopes) +2. **Read current content** via Read tool +3. **Display current values:** + ``` + Current skill 'custom-logger': + - Description: Enhanced logging with structured output + - Triggers: log, logger, logging + - Argument hint: [message] + - Scope: user + ``` +4. **Ask what to change:** + - `description` - Update description + - `triggers` - Update trigger keywords + - `argument-hint` - Update argument hint + - `content` - Edit full markdown content + - `rename` - Rename skill (move file) + - `cancel` - Exit without changes +5. **For selected field:** + - Show current value + - Ask for new value + - Update YAML frontmatter or content + - Write back to file +6. **Report success** with summary of changes + +**Example:** +``` +User: /skill edit custom-logger +Assistant: Current skill 'custom-logger': + - Description: Enhanced logging with structured output + - Triggers: log, logger, logging + - Argument hint: [message] + +What would you like to edit? (description/triggers/argument-hint/content/rename/cancel) + +User: triggers +Assistant: Current triggers: log, logger, logging +New triggers (comma-separated): log, logger, logging, trace + +✓ Updated triggers for 'custom-logger' +``` + +--- + +### /skill search + +Search skills by content, triggers, name, or description. + +**Behavior:** +1. **Scan all skills** in both scopes +2. **Match query** (case-insensitive) against: + - Skill name + - Description + - Triggers + - Full markdown content +3. **Display matches** with context: + +``` +Found 3 skills matching "typescript error": + +1. typescript-fixer (user) + Description: Fix common TypeScript errors + Match: "typescript error handling patterns" + +2. error-handler (user) + Description: Generic error handling utilities + Match: "Supports TypeScript and JavaScript errors" + +3. lint-fix (project) + Description: Auto-fix linting errors + Match: "TypeScript ESLint error resolution" +``` + +**Ranking:** Prioritize matches in name/triggers over content matches + +**Example:** +``` +User: /skill search api endpoint +Assistant: Found 2 skills matching "api endpoint": + +1. api-builder (user) + Description: Generate REST API endpoints + Triggers: api, endpoint, rest + +2. backend-scaffold (project) + Description: Scaffold backend services + Match: "Creates API endpoint boilerplate" +``` + +--- + +### /skill info + +Show detailed information about a skill. + +**Behavior:** +1. **Find skill** by name (search both scopes) +2. **Parse YAML frontmatter** and content +3. **Display complete details:** + +``` +Skill: custom-logger +Scope: user (~/.codex/skills/custom-logger/) +Description: Enhanced logging with structured output +Triggers: log, logger, logging +Argument Hint: [message] +Quality: 95% (if available) +Usage Count: 42 times (if available) +File Path: /home/user/.codex/skills/custom-logger/SKILL.md + +--- FULL CONTENT --- +[entire markdown content] +``` + +**If not found:** Report error with suggestion to use `/skill search` + +**Example:** +``` +User: /skill info custom-logger +Assistant: Skill: custom-logger +Scope: user +Description: Enhanced logging with structured output +Triggers: log, logger, logging +File: ~/.codex/skills/custom-logger/SKILL.md + +--- CONTENT --- +# Custom Logger Skill + +## Purpose +Enhanced logging with structured JSON output... +[rest of content] +``` + +--- + +### /skill sync + +Sync skills between user and project scopes. + +**Behavior:** +1. **Scan both scopes:** + - User skills: `~/.codex/skills/` + - Project skills: `.codex/skills/` +2. **Compare and categorize:** + - User-only skills (not in project) + - Project-only skills (not in user) + - Common skills (in both) +3. **Display sync opportunities:** + +``` +SYNC REPORT: + +User-only skills (5): + - error-handler + - api-builder + - custom-logger + - test-generator + - deploy-helper + +Project-only skills (2): + - test-runner + - backend-scaffold + +Common skills (3): + - design + - frontend-ui-ux (deprecated; use design or visual-ralph) + - git-master + - planner + +Options: + [1] Copy user skill to project + [2] Copy project skill to user + [3] View differences + [4] Cancel +``` + +4. **Handle user choice:** + - Option 1: Select skill(s) to copy to project + - Option 2: Select skill(s) to copy to user + - Option 3: Show side-by-side diff for common skills + - Option 4: Exit + +**Safety:** Never overwrite without confirmation + +**Example:** +``` +User: /skill sync +Assistant: Found 5 user-only skills and 2 project-only skills. + +Copy 'error-handler' from user to project? (yes/no/skip) +User: yes +Assistant: ✓ Copied 'error-handler' to .codex/skills/ + +Copy 'api-builder' from user to project? (yes/no/skip) +User: skip +... +``` + +--- + +### /skill setup + +Interactive wizard for setting up and managing local skills (formerly local-skills-setup). + +**Behavior:** + +#### Step 1: Directory Check and Setup + +First, check if skill directories exist and create them if needed: + +```bash +# Check and create user-level skills directory +USER_SKILLS_DIR="$HOME/.codex/skills" +if [ -d "$USER_SKILLS_DIR" ]; then + echo "User skills directory exists: $USER_SKILLS_DIR" +else + mkdir -p "$USER_SKILLS_DIR" + echo "Created user skills directory: $USER_SKILLS_DIR" +fi + +# Check and create project-level skills directory +PROJECT_SKILLS_DIR=".codex/skills" +if [ -d "$PROJECT_SKILLS_DIR" ]; then + echo "Project skills directory exists: $PROJECT_SKILLS_DIR" +else + mkdir -p "$PROJECT_SKILLS_DIR" + echo "Created project skills directory: $PROJECT_SKILLS_DIR" +fi +``` + +#### Step 2: Skill Scan and Inventory + +Scan both directories and show a comprehensive inventory: + +```bash +# Scan user-level skills +echo "=== USER-LEVEL SKILLS (~/.codex/skills/) ===" +if [ -d "$HOME/.codex/skills" ]; then + USER_COUNT=$(find "$HOME/.codex/skills" -name "*.md" 2>/dev/null | wc -l) + echo "Total skills: $USER_COUNT" + + if [ $USER_COUNT -gt 0 ]; then + echo "" + echo "Skills found:" + find "$HOME/.codex/skills" -name "*.md" -type f -exec sh -c ' + FILE="$1" + NAME=$(grep -m1 "^name:" "$FILE" 2>/dev/null | sed "s/name: //") + DESC=$(grep -m1 "^description:" "$FILE" 2>/dev/null | sed "s/description: //") + MODIFIED=$(stat -c "%y" "$FILE" 2>/dev/null || stat -f "%Sm" "$FILE" 2>/dev/null) + echo " - $NAME" + [ -n "$DESC" ] && echo " Description: $DESC" + echo " Modified: $MODIFIED" + echo "" + ' sh {} \; + fi +else + echo "Directory not found" +fi + +echo "" +echo "=== PROJECT-LEVEL SKILLS (.codex/skills/) ===" +if [ -d ".codex/skills" ]; then + PROJECT_COUNT=$(find ".codex/skills" -name "*.md" 2>/dev/null | wc -l) + echo "Total skills: $PROJECT_COUNT" + + if [ $PROJECT_COUNT -gt 0 ]; then + echo "" + echo "Skills found:" + find ".codex/skills" -name "*.md" -type f -exec sh -c ' + FILE="$1" + NAME=$(grep -m1 "^name:" "$FILE" 2>/dev/null | sed "s/name: //") + DESC=$(grep -m1 "^description:" "$FILE" 2>/dev/null | sed "s/description: //") + MODIFIED=$(stat -c "%y" "$FILE" 2>/dev/null || stat -f "%Sm" "$FILE" 2>/dev/null) + echo " - $NAME" + [ -n "$DESC" ] && echo " Description: $DESC" + echo " Modified: $MODIFIED" + echo "" + ' sh {} \; + fi +else + echo "Directory not found" +fi + +# Summary +TOTAL=$((USER_COUNT + PROJECT_COUNT)) +echo "=== SUMMARY ===" +echo "Total skills across all directories: $TOTAL" +``` + +#### Step 3: Quick Actions Menu + +After scanning, use the AskUserQuestion tool to offer these options: + +**Question:** "What would you like to do with your local skills?" + +**Options:** +1. **Add new skill** - Start the skill creation wizard (invoke `/skill add`) +2. **List all skills with details** - Show comprehensive skill inventory (invoke `/skill list`) +3. **Scan conversation for patterns** - Analyze current conversation for skill-worthy patterns +4. **Import skill** - Import a skill from URL or paste content +5. **Done** - Exit the wizard + +**Option 3: Scan Conversation for Patterns** + +Analyze the current conversation context to identify potential skill-worthy patterns. Look for: +- Recent debugging sessions with non-obvious solutions +- Tricky bugs that required investigation +- Codebase-specific workarounds discovered +- Error patterns that took time to resolve + +Report findings and ask if user wants to extract any as skills (invoke `/learner` if yes). + +**Option 4: Import Skill** + +Ask user to provide either: +- **URL**: Download skill from a URL (e.g., GitHub gist) +- **Paste content**: Paste skill markdown content directly + +Then ask for scope: +- **User-level** (~/.codex/skills/) - Available across all projects +- **Project-level** (.codex/skills/) - Only for this project + +Validate the skill format and save to the chosen location. + +--- + +### /skill scan + +Quick command to scan both skill directories (subset of `/skill setup`). + +**Behavior:** +Run the scan from Step 2 of `/skill setup` without the interactive wizard. + +--- + +## Skill Templates + +When creating skills via `/skill add` or `/skill setup`, offer quick templates for common skill types: + +### Error Solution Template + +```markdown +--- +id: error-[unique-id] +name: [Error Name] +description: Solution for [specific error in specific context] +source: conversation +triggers: ["error message fragment", "file path", "symptom"] +quality: high +--- + +# [Error Name] + +## The Insight +What is the underlying cause of this error? What principle did you discover? + +## Why This Matters +What goes wrong if you don't know this? What symptom led here? + +## Recognition Pattern +How do you know when this applies? What are the signs? +- Error message: "[exact error]" +- File: [specific file path] +- Context: [when does this occur] + +## The Approach +Step-by-step solution: +1. [Specific action with file/line reference] +2. [Specific action with file/line reference] +3. [Verification step] + +## Example +\`\`\`typescript +// Before (broken) +[problematic code] + +// After (fixed) +[corrected code] +\`\`\` +``` + +### Workflow Skill Template + +```markdown +--- +id: workflow-[unique-id] +name: [Workflow Name] +description: Process for [specific task in this codebase] +source: conversation +triggers: ["task description", "file pattern", "goal keyword"] +quality: high +--- + +# [Workflow Name] + +## The Insight +What makes this workflow different from the obvious approach? + +## Why This Matters +What fails if you don't follow this process? + +## Recognition Pattern +When should you use this workflow? +- Task type: [specific task] +- Files involved: [specific patterns] +- Indicators: [how to recognize] + +## The Approach +1. [Step with specific commands/files] +2. [Step with specific commands/files] +3. [Verification] + +## Gotchas +- [Common mistake and how to avoid it] +- [Edge case and how to handle it] +``` + +### Code Pattern Template + +```markdown +--- +id: pattern-[unique-id] +name: [Pattern Name] +description: Pattern for [specific use case in this codebase] +source: conversation +triggers: ["code pattern", "file type", "problem domain"] +quality: high +--- + +# [Pattern Name] + +## The Insight +What's the key principle behind this pattern? + +## Why This Matters +What problems does this pattern solve in THIS codebase? + +## Recognition Pattern +When do you apply this pattern? +- File types: [specific files] +- Problem: [specific problem] +- Context: [codebase-specific context] + +## The Approach +Decision-making heuristic, not just code: +1. [Principle-based step] +2. [Principle-based step] + +## Example +\`\`\`typescript +[Illustrative example showing the principle] +\`\`\` + +## Anti-Pattern +What NOT to do and why: +\`\`\`typescript +[Common mistake to avoid] +\`\`\` +``` + +### Integration Skill Template + +```markdown +--- +id: integration-[unique-id] +name: [Integration Name] +description: How [system A] integrates with [system B] in this codebase +source: conversation +triggers: ["system name", "integration point", "config file"] +quality: high +--- + +# [Integration Name] + +## The Insight +What's non-obvious about how these systems connect? + +## Why This Matters +What breaks if you don't understand this integration? + +## Recognition Pattern +When are you working with this integration? +- Files: [specific integration files] +- Config: [specific config locations] +- Symptoms: [what indicates integration issues] + +## The Approach +How to work with this integration correctly: +1. [Configuration step with file paths] +2. [Setup step with specific details] +3. [Verification step] + +## Gotchas +- [Integration-specific pitfall #1] +- [Integration-specific pitfall #2] +``` + +--- + +## Error Handling + +**All commands must handle:** +- File/directory doesn't exist +- Permission errors +- Invalid YAML frontmatter +- Duplicate skill names +- Invalid skill names (spaces, special chars) + +**Error format:** +``` +✗ Error: +→ Suggestion: +``` + +--- + +## Usage Examples + +```bash +# List all skills +/skill list + +# Create a new skill +/skill add my-custom-skill + +# Remove a skill +/skill remove old-skill + +# Edit existing skill +/skill edit error-handler + +# Search for skills +/skill search typescript error + +# Get detailed info +/skill info my-custom-skill + +# Sync between scopes +/skill sync + +# Run setup wizard +/skill setup + +# Quick scan +/skill scan +``` + +## Usage Modes + +### Direct Command Mode + +When invoked with an argument, skip the interactive wizard: + +- `/skill list` - Show detailed skill inventory +- `/skill add` - Start skill creation (invoke learner) +- `/skill scan` - Scan both skill directories + +### Interactive Mode + +When invoked without arguments, run the full guided wizard. + +--- + +## Benefits of Local Skills + +**Automatic Application**: Codex detects triggers and applies skills automatically - no need to remember or search for solutions. + +**Version Control**: Project-level skills (.codex/skills/) are committed with your code, so the whole team benefits. + +**Evolving Knowledge**: Skills improve over time as you discover better approaches and refine triggers. + +**Reduced Token Usage**: Instead of re-solving the same problems, Codex applies known patterns efficiently. + +**Codebase Memory**: Preserves institutional knowledge that would otherwise be lost in conversation history. + +--- + +## Skill Quality Guidelines + +Good skills are: + +1. **Non-Googleable** - Can't easily find via search + - BAD: "How to read files in TypeScript" + - GOOD: "This codebase uses custom path resolution requiring fileURLToPath" + +2. **Context-Specific** - References actual files/errors from THIS codebase + - BAD: "Use try/catch for error handling" + - GOOD: "The aiohttp proxy in server.py:42 crashes on ClientDisconnectedError" + +3. **Actionable with Precision** - Tells exactly WHAT to do and WHERE + - BAD: "Handle edge cases" + - GOOD: "When seeing 'Cannot find module' in dist/, check tsconfig.json moduleResolution" + +4. **Hard-Won** - Required significant debugging effort + - BAD: Generic programming patterns + - GOOD: "Race condition in worker.ts - Promise.all at line 89 needs await" + +--- + +## Related Skills + +- `/learner` - Extract a skill from current conversation +- `/note` - Save quick notes (less formal than skills) + +--- + +## Example Session + +``` +> /skill list + +Checking skill directories... +✓ User skills directory exists: ~/.codex/skills/ +✓ Project skills directory exists: .codex/skills/ + +Scanning for skills... + +=== USER-LEVEL SKILLS === +Total skills: 3 + - async-network-error-handling + Description: Pattern for handling independent I/O failures in async network code + Modified: 2026-01-20 14:32:15 + + - esm-path-resolution + Description: Custom path resolution in ESM requiring fileURLToPath + Modified: 2026-01-19 09:15:42 + +=== PROJECT-LEVEL SKILLS === +Total skills: 5 + - session-timeout-fix + Description: Fix for sessionId undefined after restart in session.ts + Modified: 2026-01-22 16:45:23 + + - build-cache-invalidation + Description: When to clear TypeScript build cache to fix phantom errors + Modified: 2026-01-21 11:28:37 + +=== SUMMARY === +Total skills: 8 + +What would you like to do? +1. Add new skill +2. List all skills with details +3. Scan conversation for patterns +4. Import skill +5. Done +``` + +--- + +## Tips for Users + +- Run `/skill list` periodically to review your skill library +- After solving a tricky bug, immediately run learner to capture it +- Use project-level skills for codebase-specific knowledge +- Use user-level skills for general patterns that apply everywhere +- Review and refine triggers over time to improve matching accuracy + +--- + +## Implementation Notes + +1. **YAML Parsing:** Use frontmatter extraction for metadata +2. **File Operations:** Use Read/Write tools, never Edit for new files +3. **User Confirmation:** Always confirm destructive operations +4. **Clear Feedback:** Use checkmarks (✓), crosses (✗), arrows (→) for clarity +5. **Scope Resolution:** Always check both user and project scopes +6. **Validation:** Enforce naming conventions (lowercase, hyphens only) + +--- + +## Related Skills + +- `/learner` - Extract a skill from current conversation +- `/note` - Save quick notes (less formal than skills) + +--- + +## Future Enhancements + +- `/skill export ` - Export skill as shareable file +- `/skill import ` - Import skill from file +- `/skill stats` - Show usage statistics across all skills +- `/skill validate` - Check all skills for format errors +- `/skill template ` - Create from predefined templates diff --git a/scripts/__pycache__/validate_marketplace.cpython-314.pyc b/scripts/__pycache__/validate_marketplace.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28c0a5b85e3edae042bcbe03beed3a3851b57858 GIT binary patch literal 13113 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 R$3fZQMT{3@f!RwY{ePELwT}P* literal 0 HcmV?d00001