Marketplace share-skill
Automatically share skills, migrate local skills to code repositories, open source skills, skill version management, configure git remote
git clone https://github.com/aiskillstore/marketplace
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/guo-yu/share-skill" ~/.claude/skills/aiskillstore-marketplace-share-skill && rm -rf "$T"
skills/guo-yu/share-skill/SKILL.mdShare Skill
Migrate user's locally created temporary skills to a project repository via symlinks, and initialize Git for version tracking.
Usage
| Command | Description |
|---|---|
| Migrate specified skill to code repository and initialize git |
| Configure code_root and other settings |
| Migrate and configure remote URL |
| List all local skills available for migration |
| Configure Git remote alias |
| List configured remote aliases |
| Generate documentation website for the repository |
| Generate docs with specified design style |
| Use specified UI skill to design docs |
| Configure default design style or UI skill |
| One-time authorization for this skill's permissions |
| Natural language | e.g., "Help me open source port-allocator and push to github" |
Configuration File
All settings are stored in
~/.claude/share-skill-config.json:
{ "code_root": "~/Codes", "skills_repo": "skills", "github_username": "guo-yu", "remotes": { "github": "git@github.com:guo-yu/skills", "gitlab": "git@gitlab.com:guo-yu/skills" }, "default_remote": "github", "auto_detected": true, "docs": { "style": "botanical", "custom_skill": null, "custom_domain": null } }
Configuration Fields:
| Field | Description | Default |
|---|---|---|
| Base directory for code repositories | |
| Name of skills repository folder | |
| GitHub username for URLs | Auto-detected |
| Git remote aliases | Auto-configured |
| Custom domain for docs site | (use GitHub Pages) |
Path Variables:
Throughout this document, the following variables are used:
→ Value of{code_root}
config (e.g.,code_root
)~/Codes
→ Value of{skills_repo}
config (e.g.,skills_repo
)skills
→{skills_path}
(e.g.,{code_root}/{skills_repo}
)~/Codes/skills
→ Value of{username}
configgithub_username
Auto-detection on First Run
On first invocation of share-skill, it automatically detects settings:
Auto-detection Logic:
-
Check if config file exists
if [ ! -f ~/.claude/share-skill-config.json ]; then # First run, perform auto-detection fi -
Detect code_root directory
# Check common code directory locations in order for dir in ~/Codes ~/Code ~/Projects ~/Dev ~/Development ~/repos; do if [ -d "$dir" ]; then CODE_ROOT="$dir" break fi done # If none found, default to ~/Codes CODE_ROOT="${CODE_ROOT:-~/Codes}" -
Read Git global config for username
# Try to get username USERNAME=$(git config --global user.name) # If username contains spaces, try extracting from GitHub email if [[ "$USERNAME" == *" "* ]]; then EMAIL=$(git config --global user.email) # Extract from xxx@users.noreply.github.com USERNAME=$(echo "$EMAIL" | grep -oP '^\d+-?\K[^@]+(?=@users\.noreply\.github\.com)') fi # If still unable to determine, try extracting from remote URL if [ -z "$USERNAME" ]; then USERNAME=$(git config --global --get-regexp "url.*github.com" | grep -oP 'github\.com[:/]\K[^/]+' | head -1) fi -
Generate default config
{ "code_root": "<detected-code-root>", "skills_repo": "skills", "github_username": "<detected-username>", "remotes": { "github": "git@github.com:<detected-username>/skills" }, "default_remote": "github", "auto_detected": true, "docs": { "style": "botanical", "custom_skill": null, "custom_domain": null } } -
Output detection result
First run, auto-detecting settings... Detected settings: Code root: ~/Codes GitHub username: guo-yu Auto-configured: Skills path: ~/Codes/skills Remote: git@github.com:guo-yu/skills Config file: ~/.claude/share-skill-config.json To modify, use: /share-skill config
Command: /share-skill config
/share-skill configInteractive configuration for share-skill settings:
TUI Interface (AskUserQuestion):
Configure share-skill settings: Code root directory: Current: ~/Codes [ ] ~/Codes [ ] ~/Code [ ] ~/Projects [ ] Other... (enter custom path) Custom domain for documentation: Current: (none - using GitHub Pages) [ ] No custom domain (use {username}.github.io/{repo}) [ ] Enter custom domain...
Implementation:
# Read current config CONFIG=$(cat ~/.claude/share-skill-config.json 2>/dev/null || echo '{}') # After user selection, update config # Example: Update code_root jq --arg root "$NEW_CODE_ROOT" '.code_root = $root' <<< "$CONFIG" > ~/.claude/share-skill-config.json
Handling Detection Failure
If settings cannot be auto-detected, prompt user to configure:
Unable to auto-detect settings Please configure manually: /share-skill config Or specify when migrating: /share-skill <skill-name> --remote git@github.com:your-username/skills.git
Natural Language Invocation
When user invokes via natural language, intelligent analysis is needed:
1. Identify User's Referenced Skill
User might say:
- "Help me open source xxx skill" -> Extract skill name
xxx - "Share the skill I just created" -> Find most recently modified skill
- "Migrate this skill to repository" -> Determine from current context
- "Open source port-allocator" -> Use name directly
2. Identify Remote Address
Default behavior: Use auto-detected username + default repository name
skills
User might say:
- "Help me open source xxx" -> Use default:
git@github.com:<username>/skills/<skill-name>.git - "push to github" -> Use default github config
- "Push to git@github.com:other-user/repo.git" -> Must explicitly specify full address
- "Open source to my my-tools repository" -> Must explicitly specify repository name
Important rule: Modifying remote path requires explicit specification
If user wants to use non-default remote path, must explicitly specify via:
-
Explicit command-line specification
/share-skill <skill-name> --remote git@github.com:other-user/other-repo.git -
Explicit path in natural language
OK: "Help me push port-allocator to git@github.com:my-org/tools.git" OK: "Open source to gitlab, address is git@gitlab.com:team/shared-skills.git" NOT OK: "Help me push to somewhere else" (unclear, will ask for specific address) NOT OK: "Use another repository" (unclear, will ask for specific address)
Address Resolution Rules:
"Help me open source xxx" -> Use default config: git@github.com:<auto-detected-user>/skills -> Final address: git@github.com:<user>/skills/<skill-name>.git "Push to git@github.com:other-user/repo.git" -> Detected full address, use directly "Open source to gitlab" (gitlab not configured) -> Prompt: Please specify full GitLab address
3. Auto-search Skill Location
Skills may exist at the following locations, searched by priority:
# 1. Standard skills directory ~/.claude/skills/<skill-name>/SKILL.md # 2. User custom skills directory ~/.claude/skills/*/<skill-name>/SKILL.md # 3. Standalone skill file ~/.claude/skills/<skill-name>.md # 4. Project-level skills (current working directory) .claude/skills/<skill-name>/SKILL.md
Search command:
# Search for directories containing SKILL.md under ~/.claude find ~/.claude -name "SKILL.md" -type f 2>/dev/null | while read f; do dir=$(dirname "$f") name=$(basename "$dir") echo "$name: $dir" done # Or search for specific name find ~/.claude -type d -name "<skill-name>" 2>/dev/null
4. Post-confirmation Actions
After finding skill:
- Display found location, ask user to confirm
- If multiple matches found, list options for user to choose
- Execute migration after confirmation
- If user didn't specify remote, ask whether to configure after migration completes
Execution Steps
Command: /share-skill remote <alias> <endpoint>
/share-skill remote <alias> <endpoint>Configure Git remote alias:
-
Read existing config
cat ~/.claude/share-skill-config.json 2>/dev/null || echo '{"remotes":{}}' -
Update config
{ "remotes": { "<alias>": "<endpoint>" } } -
Write config file (preserve existing config)
-
Output confirmation
Remote alias configured Alias: github Address: git@github.com:guo-yu/skills Usage: /share-skill <skill-name> --remote github or: "Help me open source xxx to github"
Command: /share-skill remote list
/share-skill remote listList configured remote aliases:
cat ~/.claude/share-skill-config.json | jq '.remotes'
Output format:
Configured remote aliases: github -> git@github.com:guo-yu/skills gitlab -> git@gitlab.com:guo-yu/skills gitee -> git@gitee.com:guo-yu/skills Default: github
Command: /share-skill <skill-name> [--remote <url|alias>]
/share-skill <skill-name> [--remote <url|alias>]Migrate specified skill from
~/.claude/ directory to {skills_path}/:
-
Search skill location
# First check standard location if [ -d ~/.claude/skills/<skill-name> ]; then SKILL_PATH=~/.claude/skills/<skill-name> else # Recursive search SKILL_PATH=$(find ~/.claude -type d -name "<skill-name>" 2>/dev/null | head -1) fi- If not found, error and exit
- If already a symlink, prompt already migrated and show link target
- If multiple found, list for user to choose
-
Check target directory
ls {skills_path}/<skill-name> 2>/dev/null- If target exists, error and exit (avoid overwriting)
-
Execute migration
# Create target directory (if doesn't exist) mkdir -p {skills_path} # Move skill to code directory mv ~/.claude/skills/<skill-name> {skills_path}/ # Create symlink ln -s {skills_path}/<skill-name> ~/.claude/skills/<skill-name> -
Create .gitignore
cat > {skills_path}/<skill-name>/.gitignore << 'EOF' # OS .DS_Store Thumbs.db # Editor .vscode/ .idea/ *.swp *.swo # Logs *.log # Temp tmp/ temp/ EOF -
Initialize Git
cd {skills_path}/<skill-name> git init git add . git commit -m "Initial commit: <skill-name> skill" -
Configure remote (if specified)
If user specified
:--remote# If it's an alias, resolve to full address if [ "<remote>" is alias ]; then ENDPOINT=$(read alias's endpoint from config) REMOTE_URL="${ENDPOINT}/<skill-name>.git" else REMOTE_URL="<remote>" fi cd {skills_path}/<skill-name> git remote add origin "$REMOTE_URL" git push -u origin master -
Ask when remote not specified
If user didn't specify remote, ask after migration using AskUserQuestion:
Do you want to configure Git remote address? Options: - Use github (git@github.com:guo-yu/skills/<skill-name>.git) - Use gitlab (git@gitlab.com:guo-yu/skills/<skill-name>.git) - Enter custom address - Skip for now -
Post-migration automation (automatic, no interaction)
After migration completes, automatically update all related files:
8.1 Update docs/js/main.js SKILLS config
// Add new skill to SKILLS object const SKILLS = { // ... existing skills '<skill-name>': { name: '<skill-name>', description: '<extracted from SKILL.md frontmatter>', path: '<skill-name>' } };8.2 Update docs/js/main.js SKILL_MARKETING config
// Generate marketing content for the new skill const SKILL_MARKETING = { // ... existing skills '<skill-name>': { en: { headline: '<generated from skill description>', why: '<generated explanation>', painPoints: [ { icon: '🔥', title: '...', desc: '...' }, { icon: '🧠', title: '...', desc: '...' }, { icon: '💥', title: '...', desc: '...' } ] }, 'zh-CN': { /* Chinese translation */ }, ja: { /* Japanese translation */ } } };8.3 Update all README files
Add new skill to the skills table in all language versions:
# Files to update: # - {skills_path}/README.md # - {skills_path}/README.zh-CN.md # - {skills_path}/README.ja.md # Extract description from SKILL.md frontmatter DESCRIPTION=$(grep -A1 "^description:" {skills_path}/<skill-name>/SKILL.md | tail -1 | sed 's/^description: //') # Add row to skills table in each README # English: | [skill-name](./skill-name/) | Description | # Chinese: | [skill-name](./skill-name/) | 中文描述 | # Japanese: | [skill-name](./skill-name/) | 日本語説明 |8.4 (Automatic) Skill lists are dynamically generated
The skill lists in navigation dropdown, mobile menu, and sidebar are dynamically generated from the
object inSKILLS
. No manual HTML editing required - step 8.1 handles this automatically.main.jsIcon SVG path guidelines (for step 8.1):
Skill Type SVG Icon Path Port/Network <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>Sharing/Export <circle cx="18" cy="5" r="3"/>...(share icon)Security/Permissions <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>Translation/i18n <circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3..."/>8.5 Generate translations using skill-i18n
Automatically invoke skill-i18n to translate SKILL.md:
# Check if skill-i18n is available if [ -d ~/.claude/skills/skill-i18n ] || [ -L ~/.claude/skills/skill-i18n ]; then # Use Skill tool to invoke skill-i18n with integration flags # Skill: skill-i18n # Args: --lang zh-CN,ja --files SKILL.md --skill <skill-name> --no-prompt --overwrite # # This generates: # - {skills_path}/<skill-name>/SKILL.zh-CN.md # - {skills_path}/<skill-name>/SKILL.ja.md fiImplementation: Use the
tool to invoke skill-i18n:SkillSkill(skill: "skill-i18n", args: "--lang zh-CN,ja --files SKILL.md --skill <skill-name> --no-prompt --overwrite")If skill-i18n is not available, skip this step and output:
⚠ skill-i18n not found, skipping translations Install with: ln -s {skills_path}/skill-i18n ~/.claude/skills/skill-i18n8.6 Update cache version
# Update version numbers in docs/index.html VERSION=$(date +%s) sed -i '' "s/main.js?v=[0-9]*/main.js?v=$VERSION/" {skills_path}/docs/index.html sed -i '' "s/custom.css?v=[0-9]*/custom.css?v=$VERSION/" {skills_path}/docs/index.html8.7 Commit all changes
cd {skills_path} git add . git commit -m "Add <skill-name>: update docs, README, and translations" git push # If remote is configuredPost-migration output:
Post-migration updates completed: ✓ Updated docs/js/main.js (SKILLS + SKILL_MARKETING) ✓ Updated README.md, README.zh-CN.md, README.ja.md ✓ Generated SKILL.zh-CN.md, SKILL.ja.md ✓ Updated cache version in docs/index.html ✓ Committed and pushed changes Note: Skill lists (navbar, mobile menu, sidebar) are dynamically generated from SKILLS config - no HTML changes needed.
Command: /share-skill list
/share-skill listList all local skills available for migration (excluding symlinks):
# Search for all directories containing SKILL.md under ~/.claude echo "Discovered skills:" find ~/.claude -name "SKILL.md" -type f 2>/dev/null | while read f; do dir=$(dirname "$f") name=$(basename "$dir") if [ -L "$dir" ]; then target=$(readlink "$dir") echo " $name -> $target (migrated)" else echo " $name: $dir (available)" fi done
Output Format
Migration Success (with remote)
Skill migration successful skill: <skill-name> New location: {skills_path}/<skill-name> Symlink: ~/.claude/skills/<skill-name> -> {skills_path}/<skill-name> Git: Initialized and committed Remote: git@github.com:guo-yu/skills/<skill-name>.git Post-migration updates: ✓ Updated docs/js/main.js (SKILLS + SKILL_MARKETING) ✓ Updated README.md, README.zh-CN.md, README.ja.md ✓ Generated SKILL.zh-CN.md, SKILL.ja.md ✓ Updated cache version in docs/index.html ✓ Committed and pushed changes Repository URL: https://github.com/guo-yu/skills
Migration Success (without remote)
Skill migration successful skill: <skill-name> New location: {skills_path}/<skill-name> Symlink: ~/.claude/skills/<skill-name> -> {skills_path}/<skill-name> Git: Initialized and committed Post-migration updates: ✓ Updated docs/js/main.js (SKILLS + SKILL_MARKETING) ✓ Updated README.md, README.zh-CN.md, README.ja.md ✓ Generated SKILL.zh-CN.md, SKILL.ja.md ✓ Updated cache version in docs/index.html ✓ Committed changes (not pushed - no remote configured) Do you want to configure remote address?
Already Migrated
Skill already migrated <skill-name> is already a symlink: ~/.claude/skills/<skill-name> -> {skills_path}/<skill-name>
List
Local skills available for migration (N): - art-master - design-master - prompt-generator Migrated skills (M): - port-allocator -> {skills_path}/port-allocator - share-skill -> {skills_path}/share-skill
Directory Structure
Hybrid Git Management Mode
share-skill supports two Git management modes:
| Mode | Trigger | Git Structure | Remote |
|---|---|---|---|
| Monorepo | Default endpoint | Parent repo managed | |
| Standalone | Custom endpoint | Independent .git | User specified |
Monorepo Mode (Default)
When using default endpoint, all skills are managed by parent repo
{skills_path}/.git:
{skills_path}/ ├── .git/ # Parent repo -> guo-yu/skills ├── .gitignore ├── README.md ├── port-allocator/ # No independent .git, managed by parent │ ├── .gitignore │ └── SKILL.md ├── share-skill/ │ ├── .gitignore │ └── SKILL.md └── skill-permissions/ ├── .gitignore └── SKILL.md
Operations:
# After adding new skill cd {skills_path} git add <new-skill>/ git commit -m "Add <new-skill>" git push
Standalone Mode (Custom Endpoint)
When user specifies custom endpoint, that skill has independent .git:
{skills_path}/ ├── .git/ # Parent repo ├── .gitignore # Contains: /custom-skill/ ├── custom-skill/ # Independent repo -> user specified address │ ├── .git/ │ └── SKILL.md └── port-allocator/ # Managed by parent repo
Parent repo .gitignore auto-updates:
# Skills with custom endpoints /custom-skill/
Symlinks
Regardless of mode,
~/.claude/skills/ uses symlinks:
~/.claude/skills/ ├── port-allocator -> {skills_path}/port-allocator ├── share-skill -> {skills_path}/share-skill └── skill-permissions -> {skills_path}/skill-permissions
First Use
If you encounter permission prompts, first run:
/share-skill allow
Command: /share-skill allow
/share-skill allowExecute one-time authorization, adding permissions required by this skill to Claude Code config:
- Read
~/.claude/settings.json - Merge following permissions to
:permissions.allow
{ "permissions": { "allow": [ "Bash(cat ~/.claude/*)", "Bash(find ~/.claude *)", "Bash(ls {skills_path}/*)", "Bash(mkdir -p {skills_path}*)", "Bash(mv ~/.claude/skills/* *)", "Bash(ln -s {skills_path}/* *)", "Bash(git *)", "Bash(dirname *)", "Bash(basename *)", "Bash(readlink *)" ] } }
- Write config file (preserve existing permissions)
- Output authorization result
Output format:
Claude Code permissions configured Added allowed command patterns: - Bash(cat ~/.claude/*) - Bash(find ~/.claude *) - Bash(ls {skills_path}/*) - Bash(mkdir -p {skills_path}*) - Bash(mv ~/.claude/skills/* *) - Bash(ln -s {skills_path}/* *) - Bash(git *) - Bash(dirname *) - Bash(basename *) - Bash(readlink *) Config file: ~/.claude/settings.json
Notes
- No overwrite - If target directory exists, error instead of overwrite
- Maintain compatibility - Symlinks ensure Claude Code can still read skills normally
- Git tracking - Automatically initialize git and create initial commit
- Alias priority - When using alias, automatically append skill name as repository name
- Ask about remote - When remote not specified, proactively ask user after migration
- First authorization - Recommend running
to configure permissions first/share-skill allow
Documentation Website Generation
share-skill supports automatically generating elegant documentation websites to showcase skill usage instructions.
Command: /share-skill docs
/share-skill docsGenerate GitHub Pages documentation website for skills repository.
Parameters:
: Use preset design style (default:--style <name>
)botanical
: Use specified UI skill for design--skill <ui-skill>
: Configure custom domain--domain <domain>
: Enable i18n language selection for SKILL.md and README files--i18n
i18n Language Selection
Since generating multi-language documentation is time-consuming and token-intensive, users can select which languages to generate via an interactive TUI checkbox.
Trigger: When running
/share-skill docs with --i18n flag, or when the command detects SKILL.md files need translation.
TUI Interface:
Select languages for documentation (Space to toggle, Enter to confirm): [x] English (en) - Always generated [ ] 简体中文 (zh-CN) - Simplified Chinese [ ] 日本語 (ja) - Japanese [ ] Other... - Enter custom language code Selected: English
Default Selection:
- English: checked (required, always generated)
- Chinese (zh-CN): unchecked
- Japanese (ja): unchecked
- Other: unchecked (allows custom language code input)
Custom Language Input: When user selects "Other...", prompt for language code:
Enter language code (e.g., 'ko' for Korean, 'de' for German): > ko Language added: 한국어 (ko)
AskUserQuestion Implementation:
{ "questions": [ { "question": "Which languages should be generated for documentation?", "header": "Languages", "multiSelect": true, "options": [ { "label": "English (en)", "description": "Required, always generated" }, { "label": "简体中文 (zh-CN)", "description": "Simplified Chinese translation" }, { "label": "日本語 (ja)", "description": "Japanese translation" }, { "label": "Other...", "description": "Enter a custom language code" } ] } ] }
Generated Files Based on Selection:
| Selection | SKILL Files | README Files |
|---|---|---|
| English only | | |
| +Chinese | , | , |
| +Japanese | , | , |
| +Korean | , | , |
Execution steps:
-
Check repository structure
# Confirm in skills repository directory if [ ! -d {skills_path}/.git ]; then echo "Please run this command in skills repository first" exit 1 fi -
Read config
# Read design preferences from config cat ~/.claude/share-skill-config.json | jq '.docs' -
Select design method
- If
specified: call corresponding UI skill (e.g.,--skill
)ui-ux-pro-max - Otherwise use preset style specified by
(default--style
)botanical
- If
-
Generate documentation website
mkdir -p {skills_path}/docs mkdir -p {skills_path}/docs/css mkdir -p {skills_path}/docs/js -
Configure local development server
Handle based on endpoint config and existing package.json:
Scenario A: Monorepo mode (default endpoint)
Check if
exists:{skills_path}/package.jsonif [ -f {skills_path}/package.json ]; then # Exists, only add docs-related scripts (don't overwrite existing content) # Use jq or manual merge for scripts else # Doesn't exist, create new package.json fi-
package.json exists: Append
scriptdev:docs# Read existing package.json, add new script jq '.scripts["dev:docs"] = "npx serve . -l <port>"' package.json > tmp.json mv tmp.json package.json -
package.json doesn't exist: Create new file
{ "name": "claude-code-skills", "version": "1.0.0", "private": true, "scripts": { "dev": "npx serve . -l <port>" } }
Scenario B: Standalone mode (custom endpoint)
Each skill has independent Git repository, check each package.json:
SKILL_DIR={skills_path}/<skill-name> if [ -f "$SKILL_DIR/package.json" ]; then # Important: don't overwrite user's existing package.json # Only append docs script (if doesn't exist) echo "Detected existing package.json, appending dev:docs script" else # Create minimal package.json echo "Creating package.json..." fiPort allocation flow:
- Read
to get next available port~/.claude/port-registry.json - Update port-registry to register this project
- Append or create development script in package.json
Safety rules:
- Never overwrite existing package.json
- Only append new commands in
fieldscripts - If
script exists, usedev
as alternative command namedev:docs
-
-
Configure custom domain
Handle custom domain based on config:
# Read custom_domain from config CUSTOM_DOMAIN=$(cat ~/.claude/share-skill-config.json | jq -r '.docs.custom_domain // empty') USERNAME=$(cat ~/.claude/share-skill-config.json | jq -r '.github_username') REPO=$(cat ~/.claude/share-skill-config.json | jq -r '.skills_repo') # Check if CNAME already exists if [ -f {skills_path}/docs/CNAME ]; then EXISTING_DOMAIN=$(cat {skills_path}/docs/CNAME) echo "CNAME already exists: $EXISTING_DOMAIN" fiFirst-time setup - Ask user via AskUserQuestion:
{ "questions": [{ "question": "Do you want to configure a custom domain for the documentation site?", "header": "Domain", "multiSelect": false, "options": [ { "label": "No custom domain", "description": "Use {username}.github.io/{repo}" }, { "label": "Enter custom domain", "description": "e.g., docs.example.com" } ] }] }Based on user selection:
if [ -n "$CUSTOM_DOMAIN" ]; then # User has custom domain configured echo "$CUSTOM_DOMAIN" > {skills_path}/docs/CNAME # Update config jq --arg domain "$CUSTOM_DOMAIN" '.docs.custom_domain = $domain' \ ~/.claude/share-skill-config.json > tmp.json && mv tmp.json ~/.claude/share-skill-config.json else # No custom domain - remove CNAME if exists rm -f {skills_path}/docs/CNAME fiUpdate footer link based on domain:
// main.js - Dynamic footer URL function getDocsUrl() { const config = { /* loaded from config or constants */ }; if (config.custom_domain) { return `https://${config.custom_domain}/`; } return `https://${REPO_OWNER}.github.io/${REPO_NAME}/`; } -
Update cache version number
Auto-update resource file version numbers each time docs content is modified to avoid browser cache issues:
# Generate version number (using timestamp) VERSION=$(date +%s) # Update version number in index.html sed -i '' "s/main.js?v=[0-9]*/main.js?v=$VERSION/" docs/index.html sed -i '' "s/custom.css?v=[0-9]*/custom.css?v=$VERSION/" docs/index.htmlOr use file hash:
JS_HASH=$(md5 -q docs/js/main.js | head -c 8) CSS_HASH=$(md5 -q docs/css/custom.css | head -c 8) sed -i '' "s/main.js?v=[a-z0-9]*/main.js?v=$JS_HASH/" docs/index.html sed -i '' "s/custom.css?v=[a-z0-9]*/custom.css?v=$CSS_HASH/" docs/index.htmlindex.html template should contain version placeholders:
<link rel="stylesheet" href="css/custom.css?v=1"> <script src="js/main.js?v=1"></script> -
Commit and push
git add docs/ git commit -m "Update documentation site" git push
Documentation Site Features
The generated documentation site includes the following features:
1. Dynamic Navbar Brand
The navbar brand (avatar + title) links to the repository URL and is dynamically populated from GitHub API:
<!-- index.html --> <a class="navbar-brand" id="repoLink" href="https://github.com/{username}/{repo}" target="_blank"> <img class="brand-avatar" id="userAvatar" src="" alt="Avatar"> <span class="brand-text" id="brandTitle">Skills</span> </a>
// main.js - Update repo link dynamically const repoLink = document.getElementById('repoLink'); if (repoLink) { repoLink.href = `https://github.com/${REPO_OWNER}/${REPO_NAME}`; }
2. Dynamic Favicon
The favicon uses the GitHub user's avatar image:
<!-- index.html head section --> <link rel="icon" id="favicon" type="image/png" href="">
// main.js - Set favicon to user's avatar const favicon = document.getElementById('favicon'); if (favicon) { favicon.href = user.avatar_url; }
3. Footer Attribution
Footer links to the documentation site, dynamically choosing between custom domain and GitHub Pages:
<footer class="footer"> <div class="footer-content"> <p>Made with <span class="heart">♥</span> by <a id="footerLink" href="">Yu's skills</a></p> </div> </footer>
// main.js - Set footer link based on custom_domain config const CUSTOM_DOMAIN = null; // Set to domain string or null for GitHub Pages function getDocsUrl() { if (CUSTOM_DOMAIN) { return `https://${CUSTOM_DOMAIN}/`; } return `https://${REPO_OWNER}.github.io/${REPO_NAME}/`; } // Update footer link const footerLink = document.getElementById('footerLink'); if (footerLink) { footerLink.href = getDocsUrl(); }
URL Selection Logic:
config | Footer URL |
|---|---|
| |
| |
4. i18n Cache Busting for SKILL.md
When loading language-specific SKILL.md files, add cache busting to ensure fresh content:
// main.js const CACHE_VERSION = Date.now(); function getBasePath(skillName, lang = 'en') { const fileName = lang === 'en' ? 'SKILL.md' : `SKILL.${lang}.md`; if (isGitHubPages) { // Add cache busting for GitHub raw content return `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${BRANCH}/${skillName}/${fileName}?v=${CACHE_VERSION}`; } else { // Add cache busting for local development return `../${skillName}/${fileName}?v=${CACHE_VERSION}`; } }
5. main.js Configuration
The
main.js file should include repository configuration at the top:
// Repository configuration - UPDATE THESE VALUES const REPO_OWNER = '{github-username}'; // e.g., 'guo-yu' const REPO_NAME = '{repo-name}'; // e.g., 'skills' const BRANCH = 'master'; // or 'main' // Cache busting version const CACHE_VERSION = Date.now();
6. Marketing Section (Why Use This Skill?)
Each skill displays a compelling marketing section above the documentation content, highlighting:
- Headline: A catchy one-liner explaining the value proposition
- Why: A paragraph explaining why users should use this skill
- Pain Points: Three cards showing problems the skill solves
SKILL_MARKETING Data Structure in main.js:
const SKILL_MARKETING = { 'skill-name': { en: { headline: 'Compelling one-liner value proposition', why: 'Detailed explanation of why this skill exists and how it helps users...', painPoints: [ { icon: '🔥', title: 'Problem Title', desc: 'Description of the problem this skill solves.' }, { icon: '🧠', title: 'Another Problem', desc: 'Description of another pain point.' }, { icon: '💥', title: 'Third Problem', desc: 'Description of the third issue addressed.' } ] }, 'zh-CN': { headline: '中文标题', why: '中文说明...', painPoints: [/* ... */] }, ja: { headline: '日本語タイトル', why: '日本語説明...', painPoints: [/* ... */] } } };
Render Function:
function renderMarketingSection(skillName) { const marketing = SKILL_MARKETING[skillName]; if (!marketing) return ''; const content = marketing[currentLang] || marketing['en']; // Returns HTML with .marketing-section structure }
CSS Classes:
- Container with gradient background.marketing-section
- Gradient text headline.marketing-title
- Value proposition paragraph.marketing-why
- 3-column responsive grid.pain-points-grid
- Glass card with icon, title, description.pain-point-card
Guidelines for Writing Marketing Content:
- Write from the user's perspective ("You" not "This skill")
- Lead with the pain point, then show the solution
- Use specific, relatable examples (e.g., "Port 3000 is already in use")
- Keep headlines under 10 words
- Pain point titles should be the problem, not the solution
7. Three-Column Layout
The documentation site uses a three-column responsive layout:
<div class="main-container three-column"> <!-- Left Sidebar: Skills navigation + Table of Contents --> <aside class="sidebar glass"> <div class="sidebar-content"> <div class="sidebar-section"> <h4 class="sidebar-heading" data-i18n="skills">Skills</h4> <nav class="sidebar-nav"> <a class="sidebar-link" href="?skill=port-allocator">port-allocator</a> <a class="sidebar-link" href="?skill=share-skill">share-skill</a> <!-- ... more skills --> </nav> </div> <div class="sidebar-section"> <h4 class="sidebar-heading" data-i18n="onThisPage">On This Page</h4> <div class="js-toc"></div> <!-- Tocbot generates TOC here --> </div> </div> </aside> <!-- Main Content: Markdown documentation --> <main class="main-content"> <article class="js-toc-content content-card glass" id="content"> <!-- Rendered markdown content --> </article> </main> <!-- Right Sidebar: Installation instructions --> <aside class="sidebar-right glass"> <!-- Installation section --> </aside> </div>
Responsive Behavior:
- Desktop: Three columns visible
- Tablet: Right sidebar hidden
- Mobile: Both sidebars hidden, mobile menu available
8. Right Sidebar - Installation Section
The right sidebar provides quick installation instructions:
<aside class="sidebar-right glass"> <div class="sidebar-content"> <div class="sidebar-section"> <h4 class="sidebar-heading" data-i18n="installation">Installation</h4> <p class="install-desc" data-i18n="installDesc">The easiest way to install:</p> <div class="install-code"> <pre><code><span class="comment"># <span data-i18n="addMarketplace">Add marketplace</span></span> <span class="cmd">/plugin marketplace add {username}/{repo}</span> <span class="comment"># <span data-i18n="installSkills">Install skills</span></span> <span class="cmd">/plugin install {skill-name}@{username}-{repo}</span></code></pre> </div> <a class="install-link" href="https://github.com/{username}/{repo}#installation" target="_blank" data-i18n="moreOptions">More installation options</a> </div> </div> </aside>
i18n Support for Installation:
const I18N = { en: { installation: 'Installation', installDesc: 'The easiest way to install:', addMarketplace: 'Add marketplace', installSkills: 'Install skills', moreOptions: 'More installation options' }, 'zh-CN': { installation: '安装方法', installDesc: '最简单的安装方式:', addMarketplace: '添加技能市场', installSkills: '安装技能', moreOptions: '更多安装选项' }, ja: { installation: 'インストール', installDesc: '最も簡単なインストール方法:', addMarketplace: 'マーケットプレイスを追加', installSkills: 'スキルをインストール', moreOptions: 'その他のインストールオプション' } };
9. Table of Contents (Tocbot)
Use Tocbot library to auto-generate table of contents from headings:
<!-- In <head> --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.min.css"> <!-- Before closing </body> --> <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.min.js"></script>
// Initialize after content loads tocbot.init({ tocSelector: '.js-toc', contentSelector: '.js-toc-content', headingSelector: 'h1, h2, h3', scrollSmooth: true, scrollSmoothDuration: 300, headingsOffset: 100, scrollSmoothOffset: -100 });
10. Code Syntax Highlighting (highlight.js)
Use highlight.js for code block syntax highlighting:
<!-- In <head> --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css"> <!-- Before closing </body> --> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
// After rendering markdown document.querySelectorAll('pre code').forEach((block) => { hljs.highlightElement(block); });
Command: /share-skill docs config
/share-skill docs configConfigure documentation generation default settings.
Interactive options:
Configure documentation website design Design method: 1. Use preset style 2. Use UI skill Preset styles: - botanical (default): Natural botanical style, elegant and soft - minimal: Minimalist black and white - tech: Modern tech-forward style UI skills: - ui-ux-pro-max: Professional UI/UX design skill - (other UI skills user has installed) Custom domain: (optional)
Design Style Presets
botanical
- Natural Botanical Style (default)
botanicalDesign Philosophy: A digital tribute to nature—breathing, flowing, rooted in organic beauty. Soft, refined, and thoughtful, rejecting the rigid technocratic coldness and hyper-digital sharpness of modern tech aesthetic in favor of warmth, tactility, and the imperfections of the natural world.
Core Elements:
- Organic softness: Rounded corners everywhere, shapes flow like terrazzo
- Elegant typography: Playfair Display high-contrast serif + Source Sans 3 humanist sans-serif
- Earth tones: Forest green (#2D3A31), sage green (#8C9A84), terracotta (#C27B66), rice paper white (#F9F8F4)
- Paper texture: Essential SVG noise overlay, transforming cold digital pixels into warm tactile feel
- Breathing space: Generous whitespace, section spacing py-32, card spacing gap-16
- Slow motion: Like plants swaying in breeze, duration-500 to duration-700
Color System:
| Usage | Color | Value |
|---|---|---|
| Background | Warm white/Rice paper | |
| Foreground | Deep forest green | |
| Primary | Sage green | |
| Secondary | Soft clay/Mushroom | |
| Border | Stone | |
| Interactive | Terracotta | |
Font Pairing:
- Headings: Playfair Display (Google Font) - Transitional serif, high-contrast strokes
- Body: Source Sans 3 (Google Font) - Clear, readable humanist sans-serif
Border Radius Rules:
- Cards:
(24px)rounded-3xl - Buttons:
(pill shape)rounded-full - Images:
(arch) orrounded-t-fullrounded-[40px]
Paper Texture Overlay (Critical):
<div className="pointer-events-none fixed inset-0 z-50 opacity-[0.015]" style={{ backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`, backgroundRepeat: "repeat", }} />
Shadow System:
/* Default */ box-shadow: 0 4px 6px -1px rgba(45, 58, 49, 0.05); /* Medium */ box-shadow: 0 10px 15px -3px rgba(45, 58, 49, 0.05); /* Large */ box-shadow: 0 20px 40px -10px rgba(45, 58, 49, 0.05);
Motion Guidelines:
- Fast interaction:
(button hover, link color)duration-300 - Standard:
(card lift, transforms)duration-500 - Slow dramatic:
toduration-700
(image zoom)duration-1000 - Hover behavior:
with enhanced shadow-translate-y-1
Responsive Strategy:
- Mobile: Hide sidebar, title from text-8xl down to text-5xl
- Touch targets: Maintain minimum 44px height
- Grid breakpoints:
->grid-cols-1md:grid-cols-3
Using External UI Skills
If user has installed
ui-ux-pro-max or other UI skills, can call it to design docs:
/share-skill docs --skill ui-ux-pro-max
Execution flow:
-
Detect if skill exists
if [ -d ~/.claude/skills/ui-ux-pro-max ] || [ -L ~/.claude/skills/ui-ux-pro-max ]; then echo "Detected ui-ux-pro-max skill" fi -
Call skill to generate design
- Pass current skills list and structure info to UI skill
- UI skill generates complete HTML/CSS/JS
- Output to
directory{skills_path}/docs/
-
Ask design preference (if UI skill supports)
Using ui-ux-pro-max to design documentation website Please select design style: 1. glassmorphism 2. claymorphism 3. minimalism 4. brutalism 5. neumorphism 6. bento-grid
Output Format
Generation success:
Documentation website generated Location: {skills_path}/docs/ Design style: botanical (Natural Botanical Style) Custom domain: skill.guoyu.me File structure: docs/ ├── index.html ├── CNAME ├── css/ │ └── custom.css └── js/ └── main.js Pushed to GitHub Visit: https://skill.guoyu.me GitHub Pages setup: 1. Repository Settings -> Pages 2. Source: Deploy from a branch 3. Branch: master, /docs
Using UI skill:
Documentation website generated Location: {skills_path}/docs/ Design: ui-ux-pro-max (glassmorphism style) Custom domain: skill.guoyu.me Visit: https://skill.guoyu.me
README Auto-generation
share-skill automatically generates/updates multi-language README files when creating or updating repositories.
Supported Languages
| Language | Filename | Language Code |
|---|---|---|
| English (default) | | |
| Simplified Chinese | | |
| Japanese | | |
File Structure
skills/ ├── README.md # English (default) ├── README.zh-CN.md # Simplified Chinese ├── README.ja.md # Japanese └── ...
Language Switch Navigation
Each README file contains language switch links at the top:
<p align="center"> <a href="README.md">English</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja.md">日本語</a> </p>
README Title Rules
| Repository Type | English | Simplified Chinese | Japanese |
|---|---|---|---|
| Skill Set | | | |
| Single Skill | | | |
README Template - English (README.md)
<p align="center"> <a href="README.md">English</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja.md">日本語</a> </p> # {username}'s Skills My collection of custom Claude Code skills for productivity and automation. ## Skills | Skill | Description | |-------|-------------| | [port-allocator](./port-allocator/) | Automatically allocate development server ports | | [share-skill](./share-skill/) | Migrate skills to repositories with Git support | ## Documentation This skill set has an online documentation site generated by [share-skill](https://github.com/guo-yu/skills/tree/master/share-skill). **With Custom Domain:**
https://{custom_domain}/
**GitHub Pages:**
https://{username}.github.io/{repo-name}/
### Setup GitHub Pages 1. Go to repository **Settings** -> **Pages** 2. Under "Source", select **Deploy from a branch** 3. Choose branch: `master` (or `main`), folder: `/docs` 4. (Optional) Add custom domain ## License MIT --- Made with ♥ by [Yu's skills](https://skill.guoyu.me/)
README Template - Simplified Chinese (README.zh-CN.md)
<p align="center"> <a href="README.md">English</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja.md">日本語</a> </p> # {username} 的技能集 我的 Claude Code 自定义技能集合,用于提高生产力和自动化。 ## 技能列表 | 技能 | 说明 | |------|------| | [port-allocator](./port-allocator/) | 自动分配开发服务器端口 | | [share-skill](./share-skill/) | 将技能迁移到仓库并支持 Git 版本管理 | ## 在线文档 本技能集有一个由 [share-skill](https://github.com/guo-yu/skills/tree/master/share-skill) 生成的在线文档网站。 **自定义域名访问:**
https://{custom_domain}/
**GitHub Pages 访问:**
https://{username}.github.io/{repo-name}/
### 配置 GitHub Pages 1. 进入仓库 **Settings** -> **Pages** 2. 在 "Source" 下选择 **Deploy from a branch** 3. 选择分支: `master` (或 `main`),文件夹: `/docs` 4. (可选) 在 "Custom domain" 中添加自定义域名 ## 许可证 MIT --- Made with ♥ by [Yu's skills](https://skill.guoyu.me/)
README Template - Japanese (README.ja.md)
<p align="center"> <a href="README.md">English</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja.md">日本語</a> </p> # {username} のスキル 生産性と自動化のための Claude Code カスタムスキルコレクション。 ## スキル一覧 | スキル | 説明 | |--------|------| | [port-allocator](./port-allocator/) | 開発サーバーポートの自動割り当て | | [share-skill](./share-skill/) | Git サポート付きでスキルをリポジトリに移行 | ## ドキュメント このスキルセットには [share-skill](https://github.com/guo-yu/skills/tree/master/share-skill) で生成されたオンラインドキュメントサイトがあります。 **カスタムドメイン:**
https://{custom_domain}/
**GitHub Pages:**
https://{username}.github.io/{repo-name}/
### GitHub Pages の設定 1. リポジトリの **Settings** -> **Pages** に移動 2. "Source" で **Deploy from a branch** を選択 3. ブランチ: `master` (または `main`)、フォルダ: `/docs` を選択 4. (オプション) "Custom domain" にカスタムドメインを追加 ## ライセンス MIT --- Made with ♥ by [Yu's skills](https://skill.guoyu.me/)
Execution Steps
When executing
/share-skill docs or /share-skill <skill-name>:
-
Read config
CONFIG=$(cat ~/.claude/share-skill-config.json) GITHUB_URL=$(echo "$CONFIG" | jq -r '.remotes.github') GITHUB_USERNAME=$(echo "$GITHUB_URL" | grep -oP 'github\.com[:/]\K[^/]+') CUSTOM_DOMAIN=$(echo "$CONFIG" | jq -r '.docs.custom_domain // empty') REPO_NAME=$(basename "$(git rev-parse --show-toplevel)") -
Generate language switch navigation
LANG_NAV='<p align="center"> <a href="README.md">English</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja.md">日本語</a> </p>' -
Generate README for all languages
# Define language config declare -A LANG_CONFIG LANG_CONFIG[en]="README.md" LANG_CONFIG[zh-CN]="README.zh-CN.md" LANG_CONFIG[ja]="README.ja.md" # Generate README for each language for lang in en zh-CN ja; do FILE="${LANG_CONFIG[$lang]}" generate_readme "$lang" "$FILE" done -
Write README files
generate_readme() { local lang=$1 local file=$2 # Select template based on language case $lang in en) TITLE="${GITHUB_USERNAME}'s Skills" # ... English content ;; zh-CN) TITLE="${GITHUB_USERNAME} 的技能集" # ... Chinese content ;; ja) TITLE="${GITHUB_USERNAME} のスキル" # ... Japanese content ;; esac cat > "$file" << EOF $LANG_NAV # $TITLE ... EOF }
Output Format
README multi-language files updated Generated files: - README.md (English) - README.zh-CN.md (Simplified Chinese) - README.ja.md (Japanese) Documentation link: https://skill.guoyu.me/ Included sections: - Language switch navigation - Skills list - Documentation (online docs instructions) - License - Attribution (Made with ♥)
Local Testing
share-skill provides a verification script to ensure generated documentation matches the SKILL.md specifications.
Verification Script
Location:
share-skill/test/verify-docs.sh
Usage:
# Test current directory ./share-skill/test/verify-docs.sh . # Test specific repository ./share-skill/test/verify-docs.sh ~/Codes/skills
Checks performed:
| Category | Checks |
|---|---|
| Directory Structure | docs/index.html, docs/js/main.js, docs/css/custom.css, docs/CNAME |
| index.html | Favicon, navbar brand, three-column layout, language switcher, installation section, tocbot, highlight.js, footer, version numbers |
| main.js | REPO_OWNER, REPO_NAME, BRANCH, CACHE_VERSION, I18N object, getBasePath, dynamic favicon/repoLink, tocbot.init, hljs |
| README Files | README.md, README.zh-CN.md, README.ja.md, language navigation links, footer attribution |
| Skill Files | SKILL.md, SKILL.zh-CN.md, SKILL.ja.md for each skill |
| Skills Config | Each skill configured in main.js SKILLS object |
Sample Output:
╔════════════════════════════════════════════════════════════╗ ║ share-skill Documentation Verification Script ║ ╚════════════════════════════════════════════════════════════╝ Repository: /Users/username/Codes/skills ── 1. Directory Structure ── ✓ docs/index.html exists ✓ docs/js/main.js exists ✓ docs/css/custom.css exists ✓ docs/CNAME exists (custom domain configured) ── 2. index.html Structure ── ✓ Favicon element with id='favicon' ✓ Navbar brand with id='repoLink' ... ════════════════════════════════════════════════════════════ Summary ════════════════════════════════════════════════════════════ Passed: 71 Failed: 0 Warnings: 0 ✓ All required checks passed!
Exit Codes:
: All checks passed0
: One or more checks failed1
When to Run
Run the verification script:
- After generating documentation with
/share-skill docs - Before committing documentation changes
- When troubleshooting documentation issues
- As part of CI/CD pipeline for documentation