# Share Skill

> Automatically share skills, migrate local skills to code repositories, open source skills, skill version management, configure git remote

- Skill: `aiskillstore/share-skill` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add aiskillstore/share-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aiskillstore/share-skill/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: aiskillstore (https://skillmd.com/u/aiskillstore)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/aiskillstore/share-skill

---


# Share Skill

Migrate user's locally created temporary skills to a project repository via symlinks, and initialize Git for version tracking.

## Usage

| Command | Description |
|---------|-------------|
| `/share-skill <skill-name>` | Migrate specified skill to code repository and initialize git |
| `/share-skill config` | Configure code_root and other settings |
| `/share-skill <skill-name> --remote <url>` | Migrate and configure remote URL |
| `/share-skill list` | List all local skills available for migration |
| `/share-skill remote <alias> <endpoint>` | Configure Git remote alias |
| `/share-skill remote list` | List configured remote aliases |
| `/share-skill docs` | Generate documentation website for the repository |
| `/share-skill docs --style <name>` | Generate docs with specified design style |
| `/share-skill docs --skill <ui-skill>` | Use specified UI skill to design docs |
| `/share-skill docs config` | Configure default design style or UI skill |
| `/share-skill allow` | 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`:

```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 |
|-------|-------------|---------|
| `code_root` | Base directory for code repositories | `~/Codes` |
| `skills_repo` | Name of skills repository folder | `skills` |
| `github_username` | GitHub username for URLs | Auto-detected |
| `remotes` | Git remote aliases | Auto-configured |
| `docs.custom_domain` | Custom domain for docs site | `null` (use GitHub Pages) |

**Path Variables:**

Throughout this document, the following variables are used:
- `{code_root}` → Value of `code_root` config (e.g., `~/Codes`)
- `{skills_repo}` → Value of `skills_repo` config (e.g., `skills`)
- `{skills_path}` → `{code_root}/{skills_repo}` (e.g., `~/Codes/skills`)
- `{username}` → Value of `github_username` config

## Plugin Marketplace

share-skill automatically creates a Claude Code Plugin Marketplace structure, enabling users to install skills via the `/plugin` command.

### Installation via Marketplace

Once your skills repository is set up, users can install skills with:

```bash
# Add the marketplace (one-time setup)
/plugin marketplace add {username}/{skills_repo}

# Install individual skills
/plugin install port-allocator@{username}-{skills_repo}
/plugin install share-skill@{username}-{skills_repo}
```

### Marketplace Structure

The repository requires two types of manifest files:

**1. Root marketplace.json** (`{skills_path}/.claude-plugin/marketplace.json`):
```json
{
  "name": "{username}-{skills_repo}",
  "owner": {
    "name": "{display-name}",
    "email": "{username}@users.noreply.github.com"
  },
  "metadata": {
    "description": "A collection of productivity skills for Claude Code",
    "version": "1.0.0"
  },
  "plugins": [
    {
      "name": "skill-name",
      "source": "./skill-name",
      "description": "Skill description from SKILL.md frontmatter"
    }
  ]
}
```

**2. Plugin manifest** (`{skills_path}/<skill-name>/.claude-plugin/plugin.json`):
```json
{
  "name": "skill-name",
  "description": "Skill description",
  "version": "1.0.0"
}
```

### Directory Structure with Plugin Support

```
{skills_path}/
├── .claude-plugin/
│   └── marketplace.json         # Root marketplace config
├── port-allocator/
│   ├── .claude-plugin/
│   │   └── plugin.json          # Plugin manifest
│   ├── SKILL.md
│   └── ...
├── share-skill/
│   ├── .claude-plugin/
│   │   └── plugin.json
│   ├── SKILL.md
│   └── ...
└── docs/
    └── ...
```

### Marketplace Commands Reference

| Command | Description |
|---------|-------------|
| `/plugin marketplace add <repo>` | Add a marketplace (GitHub: `owner/repo`) |
| `/plugin marketplace update` | Update all marketplace indexes |
| `/plugin install <name>@<marketplace>` | Install a plugin from marketplace |
| `/plugin validate .` | Validate marketplace structure |

### Auto-detection on First Run

On first invocation of share-skill, it automatically detects settings:

**Auto-detection Logic:**

1. **Check if config file exists**
   ```bash
   if [ ! -f ~/.claude/share-skill-config.json ]; then
     # First run, perform auto-detection
   fi
   ```

2. **Detect code_root directory**
   ```bash
   # 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}"
   ```

3. **Read Git global config for username**
   ```bash
   # 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
   ```

4. **Generate default config**
   ```json
   {
     "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
     }
   }
   ```

5. **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`

Interactive 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:**
```bash
# 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:

1. **Explicit command-line specification**
   ```bash
   /share-skill <skill-name> --remote git@github.com:other-user/other-repo.git
   ```

2. **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:

```bash
# 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:**
```bash
# 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:
1. Display found location, ask user to confirm
2. If multiple matches found, list options for user to choose
3. Execute migration after confirmation
4. **If user didn't specify remote, ask whether to configure after migration completes**

## Execution Steps

### Command: `/share-skill remote <alias> <endpoint>`

Configure Git remote alias:

1. **Read existing config**
   ```bash
   cat ~/.claude/share-skill-config.json 2>/dev/null || echo '{"remotes":{}}'
   ```

2. **Update config**
   ```json
   {
     "remotes": {
       "<alias>": "<endpoint>"
     }
   }
   ```

3. **Write config file** (preserve existing config)

4. **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`

List configured remote aliases:

```bash
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>]`

Migrate specified skill from `~/.claude/` directory to `{skills_path}/`:

1. **Search skill location**
   ```bash
   # 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

2. **Check target directory**
   ```bash
   ls {skills_path}/<skill-name> 2>/dev/null
   ```
   - If target exists, error and exit (avoid overwriting)

3. **Execute migration**
   ```bash
   # 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>
   ```

4. **Create .gitignore**
   ```bash
   cat > {skills_path}/<skill-name>/.gitignore << 'EOF'
   # OS
   .DS_Store
   Thumbs.db

   # Editor
   .vscode/
   .idea/
   *.swp
   *.swo

   # Logs
   *.log

   # Temp
   tmp/
   temp/
   EOF
   ```

5. **Initialize Git**
   ```bash
   cd {skills_path}/<skill-name>
   git init
   git add .
   git commit -m "Initial commit: <skill-name> skill"
   ```

6. **Configure remote (if specified)**

   If user specified `--remote`:
   ```bash
   # 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
   ```

7. **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
   ```

8. **Post-migration automation (automatic, no interaction)**

   After migration completes, automatically update all related files:

   **8.1 Update docs/js/main.js SKILLS config**
   ```javascript
   // 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**
   ```javascript
   // 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: '...' }
               ],
               triggers: [
                   '<natural language example 1>',
                   '<natural language example 2>'
               ]
           },
           'zh-CN': { /* Chinese translation including triggers */ },
           ja: { /* Japanese translation including triggers */ }
       }
   };
   ```

   **8.3 Update all README files**

   Add new skill to the skills table in all language versions:
   ```bash
   # 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 `SKILLS` object in `main.js`. No manual
   HTML editing required - step 8.1 handles this automatically.

   **Icon 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:
   ```bash
   # 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
   fi
   ```

   **Implementation:** Use the `Skill` tool to invoke skill-i18n:
   ```
   Skill(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-i18n
   ```

   **8.6 Update cache version**
   ```bash
   # 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.html
   ```

   **8.7 Create/Update Plugin Marketplace structure**

   To enable installation via `/plugin marketplace`, create the plugin manifest files:

   ```bash
   # Create plugin.json for the new skill
   mkdir -p {skills_path}/<skill-name>/.claude-plugin
   cat > {skills_path}/<skill-name>/.claude-plugin/plugin.json << EOF
   {
     "name": "<skill-name>",
     "description": "<extracted from SKILL.md frontmatter>",
     "version": "1.0.0"
   }
   EOF
   ```

   Update the root marketplace.json to include the new skill:
   ```bash
   # Read existing marketplace.json and add new plugin entry
   # File: {skills_path}/.claude-plugin/marketplace.json

   # Add to plugins array:
   {
     "name": "<skill-name>",
     "source": "./<skill-name>",
     "description": "<extracted from SKILL.md frontmatter>"
   }
   ```

   **Marketplace structure after migration:**
   ```
   {skills_path}/
   ├── .claude-plugin/
   │   └── marketplace.json          # Root marketplace config
   ├── <skill-name>/
   │   ├── .claude-plugin/
   │   │   └── plugin.json           # Plugin manifest
   │   ├── SKILL.md
   │   └── ...
   └── ...
   ```

   **8.8 Commit all changes**
   ```bash
   cd {skills_path}
   git add .
   git commit -m "Add <skill-name>: update docs, README, translations, and plugin manifest"
   git push  # If remote is configured
   ```

   **Post-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
     ✓ Created .claude-plugin/plugin.json
     ✓ Updated .claude-plugin/marketplace.json
     ✓ Committed and pushed changes

   Note: Skill lists (navbar, mobile menu, sidebar, install commands) are
   dynamically generated from SKILLS config - no HTML editing needed.
   ```

### Command: `/share-skill list`

List all local skills available for migration (excluding symlinks):

```bash
# 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 | `guo-yu/skills` |
| **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:**
```bash
# 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:**
```gitignore
# 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`

Execute one-time authorization, adding permissions required by this skill to Claude Code config:

1. Read `~/.claude/settings.json`
2. Merge following permissions to `permissions.allow`:

```json
{
  "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 *)"
    ]
  }
}
```

3. Write config file (preserve existing permissions)
4. 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

1. **No overwrite** - If target directory exists, error instead of overwrite
2. **Maintain compatibility** - Symlinks ensure Claude Code can still read skills normally
3. **Git tracking** - Automatically initialize git and create initial commit
4. **Alias priority** - When using alias, automatically append skill name as repository name
5. **Ask about remote** - When remote not specified, proactively ask user after migration
6. **First authorization** - Recommend running `/share-skill allow` to configure permissions first

---

## Documentation Website Generation

share-skill supports automatically generating elegant documentation websites to showcase skill usage instructions.

### Command: `/share-skill docs`

Generate GitHub Pages documentation website for skills repository.

**Parameters:**
- `--style <name>`: Use preset design style (default: `botanical`)
- `--skill <ui-skill>`: Use specified UI skill for design
- `--domain <domain>`: Configure custom domain
- `--i18n`: Enable i18n language selection for SKILL.md and README files

### 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:**
```json
{
  "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 | `SKILL.md` | `README.md` |
| +Chinese | `SKILL.md`, `SKILL.zh-CN.md` | `README.md`, `README.zh-CN.md` |
| +Japanese | `SKILL.md`, `SKILL.ja.md` | `README.md`, `README.ja.md` |
| +Korean | `SKILL.md`, `SKILL.ko.md` | `README.md`, `README.ko.md` |

**Execution steps:**

1. **Check repository structure**
   ```bash
   # Confirm in skills repository directory
   if [ ! -d {skills_path}/.git ]; then
     echo "Please run this command in skills repository first"
     exit 1
   fi
   ```

2. **Read config**
   ```bash
   # Read design preferences from config
   cat ~/.claude/share-skill-config.json | jq '.docs'
   ```

3. **Select design method**
   - If `--skill` specified: call corresponding UI skill (e.g., `ui-ux-pro-max`)
   - Otherwise use preset style specified by `--style` (default `botanical`)

4. **Generate documentation website**
   ```bash
   mkdir -p {skills_path}/docs
   mkdir -p {skills_path}/docs/css
   mkdir -p {skills_path}/docs/js
   ```

5. **Configure local development server**

   Handle based on endpoint config and existing package.json:

   **Scenario A: Monorepo mode (default endpoint)**

   Check if `{skills_path}/package.json` exists:

   ```bash
   if [ -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 `dev:docs` script
     ```bash
     # 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
     ```json
     {
       "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:

   ```bash
   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..."
   fi
   ```

   **Port allocation flow:**
   - Read `~/.claude/port-registry.json` to get next available port
   - 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 `scripts` field
   - If `dev` script exists, use `dev:docs` as alternative command name

6. **Configure custom domain**

   Handle custom domain based on config:

   ```bash
   # 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"
   fi
   ```

   **First-time setup - Ask user via AskUserQuestion:**
   ```json
   {
     "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:**
   ```bash
   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
   fi
   ```

   **Update footer link based on domain:**
   ```javascript
   // 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}/`;
   }
   ```

7. **Update cache version number**

   Auto-update resource file version numbers each time docs content is modified to avoid browser cache issues:

   ```bash
   # 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.html
   ```

   **Or use file hash:**
   ```bash
   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.html
   ```

   **index.html template should contain version placeholders:**
   ```html
   <link rel="stylesheet" href="css/custom.css?v=1">
   <script src="js/main.js?v=1"></script>
   ```

8. **Commit and push**
   ```bash
   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:

```html
<!-- 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>
```

```javascript
// 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:

```html
<!-- index.html head section -->
<link rel="icon" id="favicon" type="image/png" href="">
```

```javascript
// 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:

```html
<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>
```

```javascript
// 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:**
| `custom_domain` config | Footer URL |
|------------------------|------------|
| `null` | `https://{username}.github.io/{repo}/` |
| `"docs.example.com"` | `https://docs.example.com/` |

#### 4. i18n Cache Busting for SKILL.md

When loading language-specific SKILL.md files, add cache busting to ensure fresh content:

```javascript
// 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:

```javascript
// 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:**

```javascript
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.'
                }
            ],
            triggers: [
                'Example natural language prompt 1',
                'Example natural language prompt 2'
            ]
        },
        'zh-CN': {
            headline: '中文标题',
            why: '中文说明...',
            painPoints: [/* ... */],
            triggers: [
                '自然语言触发示例 1',
                '自然语言触发示例 2'
            ]
        },
        ja: {
            headline: '日本語タイトル',
            why: '日本語説明...',
            painPoints: [/* ... */],
            triggers: [
                '自然言語トリガー例 1',
                '自然言語トリガー例 2'
            ]
        }
    }
};
```

**Render Function:**

```javascript
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:**
- `.marketing-section` - Container with gradient background
- `.marketing-title` - Gradient text headline
- `.marketing-why` - Value proposition paragraph
- `.pain-points-grid` - 3-column responsive grid
- `.pain-point-card` - Glass card with icon, title, description

**Triggers Section (Natural Language Examples):**

Display 2-3 example phrases users can say to trigger this skill. Shown below pain points.

```javascript
// triggers field in SKILL_MARKETING
triggers: [
    'Help me allocate a port for my project',
    'Start the dev server for me'
]
```

**Render Function for Triggers:**

```javascript
function renderTriggersSection(skillName) {
    const marketing = SKILL_MARKETING[skillName];
    if (!marketing) return '';

    const content = marketing[currentLang] || marketing['en'];
    if (!content || !content.triggers || content.triggers.length === 0) return '';

    const t = I18N[currentLang];

    const triggersHtml = content.triggers.map(trigger => `
        <div class="trigger-item">
            <span class="trigger-quote">"${trigger}"</span>
        </div>
    `).join('');

    return `
        <div class="triggers-section">
            <h3 class="triggers-title">💬 ${t.triggersTitle}</h3>
            <p class="triggers-desc">${t.triggersDesc}</p>
            <div class="triggers-list">
                ${triggersHtml}
            </div>
        </div>
    `;
}
```

**CSS Classes for Triggers:**
- `.triggers-section` - Container with subtle background
- `.triggers-title` - Section heading with emoji
- `.triggers-desc` - Instruction text
- `.triggers-list` - Vertical list of examples
- `.trigger-item` - Individual example with left border accent
- `.trigger-quote` - Italic quoted text

**Guidelines for Writing Marketing Content:**
1. Write from the user's perspective ("You" not "This skill")
2. Lead with the pain point, th

…(truncated)
