feat: Universal cross-tool skill installation (14 platforms, format adapters, .agents/skills/)

- Fix install-template.sh POSIX compliance (set -eu, no bashisms, dash-tested)
- Fix incorrect paths: Windsurf → .windsurf/rules/, Codex → ~/.agents/skills/
- Add 7 new platforms: universal, kiro, trae, goose, opencode, roo-code, antigravity
- Add format adapters: auto-generate .mdc (Cursor), .md rules (Windsurf), plain .md (Cline/Roo/Trae)
- Add ~/.agents/skills/ universal secondary symlink after every install
- Add --all flag to install to every detected tool at once
- Add 3-tier platform support in cross-platform-guide.md (Native/Adapter/Manual)
- Update all 6 files with consistent paths across 14 platforms
- Fix set -e safety: replace ||/&& chaining with if/then/fi in detect_all_platforms
- Fix awk idempotency: exact marker match prevents substring collision

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Francy Lisboa Charuto 2026-03-04 08:51:11 -03:00
parent cb66ad17cc
commit 80f60c5380
6 changed files with 819 additions and 173 deletions

View file

@ -27,6 +27,9 @@ Every AI agent (Claude Code, GitHub Copilot, Cursor, Windsurf, Codex, Gemini) st
### 1. Install (one command) ### 1. Install (one command)
```bash ```bash
# Universal path (works with Codex CLI, Gemini CLI, Kiro, Antigravity, and more)
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.agents/skills/agent-skill-creator
# Claude Code (global — works in all projects) # Claude Code (global — works in all projects)
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.claude/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.claude/skills/agent-skill-creator
@ -187,7 +190,17 @@ The registry is a git repo on GitHub or GitLab. Clone it once, and every team me
Works in IDEs and CLI tools. Same install, same invocation, same results. Works in IDEs and CLI tools. Same install, same invocation, same results.
### Global install (available in all projects) ### Universal install (works with 6+ tools from one path)
The `~/.agents/skills/` directory is the emerging cross-tool convention. Install once and multiple tools discover the skill automatically:
```bash
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.agents/skills/agent-skill-creator
```
Tools that read `~/.agents/skills/`: Codex CLI, Gemini CLI, Kiro, Antigravity, and growing.
### Global install per tool
These platforms support a global user-level skills directory. Install once, use in every project: These platforms support a global user-level skills directory. Install once, use in every project:
@ -197,6 +210,15 @@ git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.claude/sk
# Also works via the Copilot-specific global path # Also works via the Copilot-specific global path
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.copilot/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.copilot/skills/agent-skill-creator
# Gemini CLI
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.gemini/skills/agent-skill-creator
# Goose
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.config/goose/skills/agent-skill-creator
# OpenCode
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.config/opencode/skills/agent-skill-creator
``` ```
VS Code Copilot (1.108+, December 2025) adopted the [Agent Skills Open Standard](https://code.visualstudio.com/docs/copilot/customization/agent-skills) and searches `~/.claude/skills/` and `~/.copilot/skills/` by default. One install at `~/.claude/skills/` makes a skill globally available on both Claude Code and VS Code Copilot. VS Code Copilot (1.108+, December 2025) adopted the [Agent Skills Open Standard](https://code.visualstudio.com/docs/copilot/customization/agent-skills) and searches `~/.claude/skills/` and `~/.copilot/skills/` by default. One install at `~/.claude/skills/` makes a skill globally available on both Claude Code and VS Code Copilot.
@ -210,10 +232,19 @@ For platforms without a global skills directory, or if you prefer per-project in
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .github/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .github/skills/agent-skill-creator
# Windsurf # Windsurf
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .windsurf/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .windsurf/rules/agent-skill-creator
# Cline (VS Code Extension) # Cline (VS Code Extension)
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .clinerules/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .clinerules/agent-skill-creator
# Kiro
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .kiro/skills/agent-skill-creator
# Trae
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .trae/rules/agent-skill-creator
# Roo Code
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .roo/rules/agent-skill-creator
``` ```
### Cursor — global install ### Cursor — global install
@ -245,11 +276,17 @@ git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.claude/sk
# GitHub Copilot CLI # GitHub Copilot CLI
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.copilot/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.copilot/skills/agent-skill-creator
# OpenAI Codex CLI # OpenAI Codex CLI (uses universal path)
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .codex/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.agents/skills/agent-skill-creator
# Gemini CLI # Gemini CLI
git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git .gemini/skills/agent-skill-creator git clone https://github.com/FrancyJGLisboa/agent-skill-creator.git ~/.gemini/skills/agent-skill-creator
```
### Alternative: npx
```bash
npx skills add https://github.com/FrancyJGLisboa/agent-skill-creator.git
``` ```
### Claude Desktop / claude.ai ### Claude Desktop / claude.ai

View file

@ -159,14 +159,20 @@ After the skill passes validation and security scan, install it immediately on t
**Detection logic** (check in order): **Detection logic** (check in order):
``` ```
~/.claude/ exists → Claude Code ~/.claude/ exists → Claude Code
.cursor/ exists → Cursor (project-level) .cursor/ exists → Cursor (project-level)
~/.cursor/ exists → Cursor (user-level) ~/.cursor/ exists → Cursor (user-level)
.github/ exists → GitHub Copilot .github/ exists → GitHub Copilot
.windsurf/ exists → Windsurf ~/.codeium/windsurf/ exists → Windsurf (user-level)
.clinerules/ exists → Cline .windsurf/ exists → Windsurf (project-level)
.codex/ exists → Codex CLI .clinerules/ exists → Cline
.gemini/ exists → Gemini CLI ~/.gemini/ exists → Gemini CLI
.kiro/ exists → Kiro
.trae/ exists → Trae
.roo/ exists → Roo Code
~/.config/goose/ exists → Goose
~/.config/opencode/ exists → OpenCode
~/.agents/ exists → Universal (.agents/skills/)
``` ```
**Install action**: Copy or symlink the generated skill directory into the platform's skill path: **Install action**: Copy or symlink the generated skill directory into the platform's skill path:
@ -175,6 +181,9 @@ After the skill passes validation and security scan, install it immediately on t
# Example for Claude Code (user-level): # Example for Claude Code (user-level):
cp -R ./sales-report-skill ~/.claude/skills/sales-report-skill cp -R ./sales-report-skill ~/.claude/skills/sales-report-skill
# Example for universal path (works with Codex CLI, Gemini CLI, Kiro, Antigravity, etc.):
cp -R ./sales-report-skill ~/.agents/skills/sales-report-skill
# Example for Cursor (project-level): # Example for Cursor (project-level):
cp -R ./sales-report-skill .cursor/rules/sales-report-skill cp -R ./sales-report-skill .cursor/rules/sales-report-skill
``` ```
@ -201,6 +210,14 @@ I couldn't auto-detect your platform. To install, run:
Or specify your platform: Or specify your platform:
./sales-report-skill/install.sh --platform cursor ./sales-report-skill/install.sh --platform cursor
Or install to all detected platforms at once:
./sales-report-skill/install.sh --all
Alternative (if npx is available):
npx skills add ./sales-report-skill
``` ```
The `install.sh` inside the skill handles auto-detection, platform-specific paths, project vs user level, dry-run mode, and post-install activation instructions. It is the fallback for users who receive the skill as a package (not created in their current session). The `install.sh` inside the skill handles auto-detection, platform-specific paths, project vs user level, dry-run mode, and post-install activation instructions. It is the fallback for users who receive the skill as a package (not created in their current session).
@ -460,13 +477,20 @@ Generated skills work on all platforms supporting the SKILL.md standard:
| Platform | Install Location | Command | | Platform | Install Location | Command |
|----------|-----------------|---------| |----------|-----------------|---------|
| **Universal** | `~/.agents/skills/` or `.agents/skills/` | `./install.sh --platform universal` |
| Claude Code | `~/.claude/skills/` or `.claude/skills/` | `./install.sh` or copy | | Claude Code | `~/.claude/skills/` or `.claude/skills/` | `./install.sh` or copy |
| GitHub Copilot | `.github/skills/` | `./install.sh --platform copilot` | | GitHub Copilot | `.github/skills/` | `./install.sh --platform copilot` |
| Cursor | `.cursor/rules/` | `./install.sh --platform cursor` | | Cursor | `.cursor/rules/` (auto-generates `.mdc`) | `./install.sh --platform cursor` |
| Windsurf | `.windsurf/skills/` | `./install.sh --platform windsurf` | | Windsurf | `.windsurf/rules/` or `global_rules.md` | `./install.sh --platform windsurf` |
| Cline | `.clinerules/` | `./install.sh --platform cline` | | Cline | `.clinerules/` | `./install.sh --platform cline` |
| Codex CLI | `.codex/skills/` | `./install.sh --platform codex` | | Codex CLI | `~/.agents/skills/` | `./install.sh --platform codex` |
| Gemini CLI | `.gemini/skills/` | `./install.sh --platform gemini` | | Gemini CLI | `~/.gemini/skills/` | `./install.sh --platform gemini` |
| Kiro | `.kiro/skills/` | `./install.sh --platform kiro` |
| Trae | `.trae/rules/` | `./install.sh --platform trae` |
| Goose | `~/.config/goose/skills/` | `./install.sh --platform goose` |
| OpenCode | `~/.config/opencode/skills/` | `./install.sh --platform opencode` |
| Roo Code | `.roo/rules/` | `./install.sh --platform roo-code` |
| Antigravity | `.agents/skills/` | `./install.sh --platform antigravity` |
See `references/cross-platform-guide.md` for full platform details. See `references/cross-platform-guide.md` for full platform details.

View file

@ -1,33 +1,57 @@
# Cross-Platform Compatibility Guide # Cross-Platform Compatibility Guide
**Version:** 4.0 **Version:** 5.0
**Purpose:** Complete compatibility matrix for Agent Skills across all platforms supporting the Agent Skills Open Standard **Purpose:** Complete compatibility matrix for Agent Skills across all platforms supporting the Agent Skills Open Standard
--- ---
## Overview ## Overview
Skills created by agent-skill-creator are compliant with the **Agent Skills Open Standard** and work across all platforms that support the SKILL.md format. As of v4.0, this includes 8+ major platforms. Skills created by agent-skill-creator are compliant with the **Agent Skills Open Standard** and work across all platforms that support the SKILL.md format. As of v5.0, this includes 14+ platforms across 3 support tiers.
### Supported Platforms ### Supported Platforms
| Platform | Type | SKILL.md Location | #### Tier 1 — Native SKILL.md Support
|----------|------|-------------------|
| **Claude Code** | CLI | `~/.claude/skills/` or `.claude/skills/` | These platforms read SKILL.md natively with no conversion needed:
| **GitHub Copilot CLI** | CLI | `.github/skills/` |
| **VS Code Copilot** | IDE Extension | `.github/skills/` | | Platform | Type | User-Level Path | Project-Level Path |
| **Cursor** | IDE | `.cursor/rules/` | |----------|------|-----------------|-------------------|
| **Windsurf** | IDE | `.windsurf/skills/` | | **Claude Code** | CLI | `~/.claude/skills/` | `.claude/skills/` |
| **Cline** | VS Code Extension | `.clinerules/` | | **GitHub Copilot CLI** | CLI | `~/.copilot/skills/` | `.github/skills/` |
| **OpenAI Codex CLI** | CLI | `.codex/skills/` | | **VS Code Copilot** | IDE Extension | `~/.claude/skills/` | `.github/skills/` |
| **Gemini CLI** | CLI | `.gemini/skills/` | | **Codex CLI** | CLI | `~/.agents/skills/` | `.agents/skills/` |
| **Claude Desktop** | Desktop App | .zip upload | | **Gemini CLI** | CLI | `~/.gemini/skills/` | `.gemini/skills/` |
| **claude.ai** | Web | .zip upload | | **Kiro** | IDE | — | `.kiro/skills/` |
| **Claude API** | API | Programmatic upload | | **Antigravity** | CLI | — | `.agents/skills/` |
| **Goose** | CLI | `~/.config/goose/skills/` | — |
| **OpenCode** | CLI | `~/.config/opencode/skills/` | — |
#### Tier 2 — SKILL.md via Format Adapter
These platforms use their own rule format. The installer auto-generates the native format from SKILL.md:
| Platform | Type | Native Format | Adapter Output | Install Path |
|----------|------|--------------|----------------|-------------|
| **Cursor** | IDE | `.mdc` | Auto-generated `.mdc` with frontmatter | `.cursor/rules/` |
| **Windsurf** | IDE | `.md` rules | `.md` rule file or `global_rules.md` append | `.windsurf/rules/` (project) or `~/.codeium/windsurf/memories/global_rules.md` (global) |
| **Cline** | VS Code Ext | Plain `.md` | Stripped frontmatter `.md` | `.clinerules/` |
| **Roo Code** | VS Code Ext | Plain `.md` | Stripped frontmatter `.md` | `.roo/rules/` |
| **Trae** | IDE | Plain `.md` | Stripped frontmatter `.md` | `.trae/rules/` |
#### Tier 3 — Manual Configuration
These platforms require manual integration:
| Platform | Config File | Instructions |
|----------|------------|-------------|
| **Zed** | `.rules` | Copy SKILL.md body into `.rules` file |
| **Junie** | `.junie/guidelines.md` | Copy SKILL.md body into guidelines |
| **Aider** | `CONVENTIONS.md` | Copy SKILL.md body into CONVENTIONS.md |
### The Unifying Standard ### The Unifying Standard
All these platforms read the same SKILL.md format: All Tier 1 and Tier 2 platforms read from the same SKILL.md source:
```yaml ```yaml
--- ---
@ -41,7 +65,68 @@ metadata:
# Skill content here... # Skill content here...
``` ```
A skill created once works everywhere without modification. A skill created once works everywhere — directly on Tier 1, via auto-adapter on Tier 2.
---
## Universal Path: `.agents/skills/`
The `.agents/skills/` directory is an emerging cross-tool convention for agent skill discovery. Multiple tools already read from this path:
- **Codex CLI** — reads `~/.agents/skills/` and `.agents/skills/`
- **Gemini CLI** — discovers skills in `~/.agents/skills/`
- **Kiro** — reads `.agents/skills/` (project-level)
- **Antigravity** — reads `.agents/skills/` (project-level)
The installer creates a **secondary symlink** at `~/.agents/skills/<skill-name>` after every install (unless the primary target is already `.agents/`). This means a skill installed for Claude Code is also discoverable by Codex CLI, Gemini CLI, and other universal-path tools automatically.
```bash
# Install for Claude Code — also creates ~/.agents/skills/ symlink
./install.sh --platform claude-code
# Install directly to universal path
./install.sh --platform universal
# Install to ALL detected platforms at once
./install.sh --all
```
---
## Format Adapters
The installer automatically converts SKILL.md to platform-native formats when needed. No separate format files are committed to the skill repo — SKILL.md remains the single source of truth.
### Cursor (.mdc)
The adapter generates a `.mdc` file with Cursor-specific frontmatter:
```
---
description: <extracted from SKILL.md frontmatter>
globs:
alwaysApply: true
---
<SKILL.md body without YAML frontmatter>
```
### Windsurf (.md rules)
**Project-level**: Creates a `.md` file in `.windsurf/rules/`.
**User-level (global)**: Appends to `~/.codeium/windsurf/memories/global_rules.md` with idempotent markers:
```markdown
<!-- BEGIN skill-name -->
<SKILL.md body>
<!-- END skill-name -->
```
Re-running the installer replaces the existing block rather than duplicating.
### Cline / Roo Code / Trae (plain .md)
The adapter strips YAML frontmatter and outputs plain markdown. These tools read `.md` files from their respective rule directories.
--- ---
@ -77,23 +162,23 @@ cp -r skill-name/ .github/skills/skill-name/
### Cursor ### Cursor
```bash ```bash
# Using install.sh # Using install.sh (auto-generates .mdc)
./install.sh --platform cursor ./install.sh --platform cursor
# Manual # Manual
cp -r skill-name/ .cursor/rules/skill-name/ cp -r skill-name/ .cursor/rules/skill-name/
``` ```
**Best for:** Cursor IDE users. Cursor reads SKILL.md natively alongside its `.mdc` rules. **Best for:** Cursor IDE users. The installer auto-generates a `.mdc` file alongside SKILL.md.
### Windsurf ### Windsurf
```bash ```bash
# Using install.sh # Using install.sh (project-level — creates .windsurf/rules/ rule)
./install.sh --platform windsurf ./install.sh --platform windsurf --project
# Manual # Using install.sh (user-level — appends to global_rules.md)
cp -r skill-name/ .windsurf/skills/skill-name/ ./install.sh --platform windsurf
``` ```
**Best for:** Windsurf IDE users. **Best for:** Windsurf IDE users.
@ -110,17 +195,17 @@ cp -r skill-name/ .clinerules/skill-name/
**Best for:** Cline extension users in VS Code. **Best for:** Cline extension users in VS Code.
### OpenAI Codex CLI ### Codex CLI
```bash ```bash
# Using install.sh # Using install.sh (installs to ~/.agents/skills/)
./install.sh --platform codex ./install.sh --platform codex
# Manual # Manual
cp -r skill-name/ .codex/skills/skill-name/ cp -r skill-name/ ~/.agents/skills/skill-name/
``` ```
**Best for:** Codex CLI users. **Best for:** OpenAI Codex CLI users. Codex reads from `~/.agents/skills/`.
### Gemini CLI ### Gemini CLI
@ -129,11 +214,109 @@ cp -r skill-name/ .codex/skills/skill-name/
./install.sh --platform gemini ./install.sh --platform gemini
# Manual # Manual
cp -r skill-name/ .gemini/skills/skill-name/ cp -r skill-name/ ~/.gemini/skills/skill-name/
``` ```
**Best for:** Gemini CLI users. **Best for:** Gemini CLI users.
### Kiro
```bash
# Using install.sh
./install.sh --platform kiro
# Manual
cp -r skill-name/ .kiro/skills/skill-name/
```
**Best for:** Kiro IDE users (project-level).
### Trae
```bash
# Using install.sh (auto-generates plain .md)
./install.sh --platform trae
# Manual
cp -r skill-name/ .trae/rules/skill-name/
```
**Best for:** Trae IDE users.
### Goose
```bash
# Using install.sh
./install.sh --platform goose
# Manual
cp -r skill-name/ ~/.config/goose/skills/skill-name/
```
**Best for:** Goose CLI users.
### OpenCode
```bash
# Using install.sh
./install.sh --platform opencode
# Manual
cp -r skill-name/ ~/.config/opencode/skills/skill-name/
```
**Best for:** OpenCode CLI users.
### Roo Code
```bash
# Using install.sh (auto-generates plain .md)
./install.sh --platform roo-code
# Manual
cp -r skill-name/ .roo/rules/skill-name/
```
**Best for:** Roo Code extension users in VS Code.
### Antigravity
```bash
# Using install.sh
./install.sh --platform antigravity
# Manual
cp -r skill-name/ .agents/skills/skill-name/
```
**Best for:** Antigravity CLI users.
### Universal Path
```bash
# Using install.sh
./install.sh --platform universal
# Manual
cp -r skill-name/ ~/.agents/skills/skill-name/
```
**Best for:** Multi-tool users. One install discoverable by Codex CLI, Gemini CLI, Kiro, Antigravity, and other tools that read `.agents/skills/`.
### Install All
```bash
# Install to every detected tool at once
./install.sh --all
```
### Alternative: npx
```bash
npx skills add <repo-url>
npx skills add ./local-skill-dir
```
### Claude Desktop / claude.ai (Web) ### Claude Desktop / claude.ai (Web)
These platforms use .zip upload instead of directory copying: These platforms use .zip upload instead of directory copying:
@ -167,20 +350,21 @@ response = client.messages.create(
### Core Functionality ### Core Functionality
| Feature | CLI Platforms | Desktop/Web | Claude API | | Feature | Tier 1 Platforms | Tier 2 Platforms | Desktop/Web | Claude API |
|---------|-------------|-------------|------------| |---------|-----------------|-----------------|-------------|------------|
| **SKILL.md support** | Full | Full | Full | | **SKILL.md support** | Native | Via adapter | Full | Full |
| **Python scripts** | Full | Full | Sandboxed* | | **Python scripts** | Full | Full | Full | Sandboxed* |
| **References/docs** | Full | Full | Full | | **References/docs** | Full | Full | Full | Full |
| **Assets/templates** | Full | Full | Full | | **Assets/templates** | Full | Full | Full | Full |
| **install.sh** | Full | N/A | N/A | | **install.sh** | Full | Full | N/A | N/A |
| **Format adapters** | N/A | Auto | N/A | N/A |
\* API: No network access, no pip install at runtime \* API: No network access, no pip install at runtime
### Technical Specifications ### Technical Specifications
| Specification | CLI Platforms | Desktop/Web | Claude API | | Specification | CLI/IDE Platforms | Desktop/Web | Claude API |
|---------------|-------------|-------------|------------| |---------------|-----------------|-------------|------------|
| **Max skill size** | No limit | ~10MB | 8MB hard limit | | **Max skill size** | No limit | ~10MB | 8MB hard limit |
| **Network access** | Yes | Yes | No | | **Network access** | Yes | Yes | No |
| **Package install** | Yes | Yes | No | | **Package install** | Yes | Yes | No |
@ -231,8 +415,8 @@ skill-name/
Skills are directly portable. Just copy the directory to the target platform's skill location: Skills are directly portable. Just copy the directory to the target platform's skill location:
```bash ```bash
# From Claude Code to Copilot # From Claude Code to Codex CLI
cp -r ~/.claude/skills/my-skill/ .github/skills/my-skill/ cp -r ~/.claude/skills/my-skill/ ~/.agents/skills/my-skill/
# From Cursor to Cline # From Cursor to Cline
cp -r .cursor/rules/my-skill/ .clinerules/my-skill/ cp -r .cursor/rules/my-skill/ .clinerules/my-skill/
@ -262,12 +446,13 @@ python scripts/export_utils.py ./my-skill --variant api
1. **Develop once, deploy everywhere**: Create and test in your preferred CLI tool, then install on other platforms. 1. **Develop once, deploy everywhere**: Create and test in your preferred CLI tool, then install on other platforms.
2. **Use install.sh**: Include the cross-platform installer for easy deployment. 2. **Use install.sh**: Include the cross-platform installer for easy deployment.
3. **Keep SKILL.md lean**: Under 500 lines, detailed content in `references/`. 3. **Use `--all` for multi-tool users**: Install to every detected tool with a single command.
4. **Test activation**: Verify the `description` triggers correctly on your target platform. 4. **Keep SKILL.md lean**: Under 500 lines, detailed content in `references/`.
5. **Include README.md**: Document installation instructions for all platforms. 5. **Test activation**: Verify the `description` triggers correctly on your target platform.
6. **No platform hacks**: Avoid platform-specific code or configuration. The standard format works everywhere. 6. **Include README.md**: Document installation instructions for all platforms.
7. **No platform hacks**: Avoid platform-specific code or configuration. The standard format works everywhere; adapters handle the rest.
--- ---
**Generated by:** agent-skill-creator v4.0 **Generated by:** agent-skill-creator v5.0
**Standard:** Agent Skills Open Standard (agentskills.io/specification) **Standard:** Agent Skills Open Standard (agentskills.io/specification)

View file

@ -1104,59 +1104,23 @@ Detailed documentation files. Each must be self-contained with real content.
### Step 6: Generate install.sh ### Step 6: Generate install.sh
Create a cross-platform installer script: Generate the installer from `scripts/install-template.sh` — the canonical template. Replace `{{SKILL_NAME}}` with the actual skill name and `chmod +x`:
```bash ```bash
#!/usr/bin/env bash # During skill generation:
set -euo pipefail sed "s/{{SKILL_NAME}}/skill-name/g" scripts/install-template.sh > skill-name/install.sh
chmod +x skill-name/install.sh
SKILL_NAME="skill-name"
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
# Platform detection
detect_platform() {
case "${1:-auto}" in
claude|claude-code) echo "$HOME/.claude/skills" ;;
copilot|github) echo ".github/skills" ;;
cursor) echo ".cursor/rules" ;;
windsurf) echo ".windsurf/skills" ;;
cline) echo ".clinerules" ;;
codex) echo ".codex/skills" ;;
gemini) echo ".gemini/skills" ;;
auto)
# Auto-detect based on environment
if command -v claude >/dev/null 2>&1; then
echo "$HOME/.claude/skills"
elif [ -d ".github" ]; then
echo ".github/skills"
elif [ -d ".cursor" ]; then
echo ".cursor/rules"
else
echo "$HOME/.claude/skills" # default
fi
;;
*)
echo "Unknown platform: $1" >&2
echo "Supported: claude, copilot, cursor, windsurf, cline, codex, gemini" >&2
exit 1
;;
esac
}
PLATFORM="${1:-auto}"
TARGET_BASE=$(detect_platform "$PLATFORM")
TARGET_DIR="$TARGET_BASE/$SKILL_NAME"
echo "Installing $SKILL_NAME..."
echo "Target: $TARGET_DIR"
mkdir -p "$TARGET_DIR"
cp -r "$SKILL_DIR"/* "$TARGET_DIR/" 2>/dev/null || true
cp -r "$SKILL_DIR"/.[!.]* "$TARGET_DIR/" 2>/dev/null || true
echo "Installed successfully to $TARGET_DIR"
``` ```
The template handles:
- POSIX-compatible shell (`set -eu`, no bashisms)
- 14 platforms: claude-code, copilot, cursor, windsurf, cline, codex, gemini, kiro, trae, goose, opencode, roo-code, antigravity, universal
- Corrected paths: Codex → `~/.agents/skills/`, Windsurf → `.windsurf/rules/` (project) / `global_rules.md` (global)
- Format adapters: auto-generates `.mdc` for Cursor, `.md` rules for Windsurf, plain `.md` for Cline/Roo/Trae
- Universal `.agents/skills/` secondary symlink after every install
- `--all` flag to install to every detected tool at once
- `--dry-run` for preview without changes
### Step 7: Write README.md ### Step 7: Write README.md
Multi-platform installation instructions: Multi-platform installation instructions:
@ -1168,27 +1132,49 @@ Brief description.
## Installation ## Installation
### Universal Path (works with 6+ tools)
```bash
git clone <repo-url> ~/.agents/skills/skill-name
```
Works with Codex CLI, Gemini CLI, Kiro, Antigravity, and other tools that read `~/.agents/skills/`.
### Using install.sh (Recommended) ### Using install.sh (Recommended)
```bash ```bash
chmod +x install.sh chmod +x install.sh
./install.sh # Auto-detect platform ./install.sh # Auto-detect platform
./install.sh claude # Claude Code ./install.sh --platform claude-code # Claude Code
./install.sh copilot # GitHub Copilot ./install.sh --platform cursor # Cursor (auto-generates .mdc)
./install.sh cursor # Cursor ./install.sh --all # All detected platforms
./install.sh --dry-run # Preview without installing
```
### Alternative: npx
```bash
npx skills add <repo-url>
``` ```
### Manual Installation ### Manual Installation
| Platform | Copy to | | Platform | Copy to |
|---|---| |---|---|
| Universal | `~/.agents/skills/skill-name/` |
| Claude Code | `~/.claude/skills/skill-name/` or `.claude/skills/skill-name/` | | Claude Code | `~/.claude/skills/skill-name/` or `.claude/skills/skill-name/` |
| GitHub Copilot | `.github/skills/skill-name/` | | GitHub Copilot | `.github/skills/skill-name/` |
| Cursor | `.cursor/rules/skill-name/` | | Cursor | `.cursor/rules/skill-name/` |
| Windsurf | `.windsurf/skills/skill-name/` | | Windsurf | `.windsurf/rules/skill-name/` |
| Cline | `.clinerules/skill-name/` | | Cline | `.clinerules/skill-name/` |
| Codex CLI | `.codex/skills/skill-name/` | | Codex CLI | `~/.agents/skills/skill-name/` |
| Gemini CLI | `.gemini/skills/skill-name/` | | Gemini CLI | `~/.gemini/skills/skill-name/` |
| Kiro | `.kiro/skills/skill-name/` |
| Trae | `.trae/rules/skill-name/` |
| Goose | `~/.config/goose/skills/skill-name/` |
| OpenCode | `~/.config/opencode/skills/skill-name/` |
| Roo Code | `.roo/rules/skill-name/` |
| Antigravity | `.agents/skills/skill-name/` |
## Prerequisites ## Prerequisites

View file

@ -369,6 +369,14 @@ def generate_installation_guide(
This skill works on all platforms supporting the Agent Skills Open Standard. This skill works on all platforms supporting the Agent Skills Open Standard.
### Universal Path (works with 6+ tools)
```bash
cp -r {skill_name}/ ~/.agents/skills/{skill_name}/
```
Works with Codex CLI, Gemini CLI, Kiro, Antigravity, and other tools that read `~/.agents/skills/`.
### Using install.sh (Recommended) ### Using install.sh (Recommended)
If the skill includes an `install.sh` script: If the skill includes an `install.sh` script:
@ -382,6 +390,9 @@ If the skill includes an `install.sh` script:
./install.sh --platform copilot ./install.sh --platform copilot
./install.sh --platform cursor ./install.sh --platform cursor
# Install to ALL detected platforms
./install.sh --all
# Project-level install # Project-level install
./install.sh --project ./install.sh --project
@ -389,6 +400,12 @@ If the skill includes an `install.sh` script:
./install.sh --dry-run ./install.sh --dry-run
``` ```
### Alternative: npx
```bash
npx skills add ./{skill_name}
```
### Manual Installation by Platform ### Manual Installation by Platform
#### Claude Code #### Claude Code
@ -412,7 +429,8 @@ cp -r {skill_name}/ .cursor/rules/{skill_name}/
#### Windsurf #### Windsurf
```bash ```bash
cp -r {skill_name}/ .windsurf/skills/{skill_name}/ # Project-level
cp -r {skill_name}/ .windsurf/rules/{skill_name}/
``` ```
#### Cline #### Cline
@ -422,12 +440,42 @@ cp -r {skill_name}/ .clinerules/{skill_name}/
#### OpenAI Codex CLI #### OpenAI Codex CLI
```bash ```bash
cp -r {skill_name}/ .codex/skills/{skill_name}/ cp -r {skill_name}/ ~/.agents/skills/{skill_name}/
``` ```
#### Gemini CLI #### Gemini CLI
```bash ```bash
cp -r {skill_name}/ .gemini/skills/{skill_name}/ cp -r {skill_name}/ ~/.gemini/skills/{skill_name}/
```
#### Kiro
```bash
cp -r {skill_name}/ .kiro/skills/{skill_name}/
```
#### Trae
```bash
cp -r {skill_name}/ .trae/rules/{skill_name}/
```
#### Goose
```bash
cp -r {skill_name}/ ~/.config/goose/skills/{skill_name}/
```
#### OpenCode
```bash
cp -r {skill_name}/ ~/.config/opencode/skills/{skill_name}/
```
#### Roo Code
```bash
cp -r {skill_name}/ .roo/rules/{skill_name}/
```
#### Antigravity
```bash
cp -r {skill_name}/ .agents/skills/{skill_name}/
``` ```
### Claude Desktop / claude.ai (Web) ### Claude Desktop / claude.ai (Web)
@ -454,13 +502,19 @@ with open('{skill_name}-api-{{version}}.zip', 'rb') as f:
| Platform | Install Method | Updates | marketplace.json | | Platform | Install Method | Updates | marketplace.json |
|----------|---------------|---------|-----------------| |----------|---------------|---------|-----------------|
| **Universal** | install.sh / copy | git pull | Not used |
| **Claude Code** | install.sh / copy | git pull | Optional | | **Claude Code** | install.sh / copy | git pull | Optional |
| **GitHub Copilot** | install.sh / copy | git pull | Not used | | **GitHub Copilot** | install.sh / copy | git pull | Not used |
| **Cursor** | install.sh / copy | git pull | Not used | | **Cursor** | install.sh / copy (+ .mdc) | git pull | Not used |
| **Windsurf** | install.sh / copy | git pull | Not used | | **Windsurf** | install.sh / copy | git pull | Not used |
| **Cline** | install.sh / copy | git pull | Not used | | **Cline** | install.sh / copy | git pull | Not used |
| **Codex CLI** | install.sh / copy | git pull | Not used | | **Codex CLI** | install.sh / copy | git pull | Not used |
| **Gemini CLI** | install.sh / copy | git pull | Not used | | **Gemini CLI** | install.sh / copy | git pull | Not used |
| **Kiro** | install.sh / copy | git pull | Not used |
| **Trae** | install.sh / copy | git pull | Not used |
| **Goose** | install.sh / copy | git pull | Not used |
| **OpenCode** | install.sh / copy | git pull | Not used |
| **Roo Code** | install.sh / copy | git pull | Not used |
| **Desktop/Web** | .zip upload | Re-upload | Not used | | **Desktop/Web** | .zip upload | Re-upload | Not used |
| **Claude API** | API upload | New upload | Not used | | **Claude API** | API upload | New upload | Not used |

View file

@ -11,7 +11,7 @@
# 2 — Platform not detected # 2 — Platform not detected
# 3 — Permission denied # 3 — Permission denied
set -euo pipefail set -eu
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Constants # Constants
@ -60,9 +60,11 @@ USAGE
OPTIONS OPTIONS
--platform PLATFORM Explicit platform selection. One of: --platform PLATFORM Explicit platform selection. One of:
claude-code, copilot, cursor, windsurf, claude-code, copilot, cursor, windsurf,
cline, codex, gemini cline, codex, gemini, kiro, trae, goose,
opencode, roo-code, antigravity, universal
--project Install at project level (current directory) --project Install at project level (current directory)
--path PATH Custom install path (overrides detection) --path PATH Custom install path (overrides detection)
--all Install to ALL detected tool paths at once
--dry-run Show what would happen without making changes --dry-run Show what would happen without making changes
-h, --help Show this help message -h, --help Show this help message
@ -71,6 +73,7 @@ EXAMPLES
./install.sh --project # Auto-detect platform, project-level ./install.sh --project # Auto-detect platform, project-level
./install.sh --platform cursor # Force Cursor, user-level ./install.sh --platform cursor # Force Cursor, user-level
./install.sh --path ~/my-skills/ # Custom destination ./install.sh --path ~/my-skills/ # Custom destination
./install.sh --all # Install to every detected tool
./install.sh --dry-run # Preview without installing ./install.sh --dry-run # Preview without installing
EOF EOF
} }
@ -82,6 +85,7 @@ PLATFORM=""
PROJECT_LEVEL=false PROJECT_LEVEL=false
CUSTOM_PATH="" CUSTOM_PATH=""
DRY_RUN=false DRY_RUN=false
INSTALL_ALL=false
parse_args() { parse_args() {
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
@ -100,6 +104,10 @@ parse_args() {
CUSTOM_PATH="$2" CUSTOM_PATH="$2"
shift 2 shift 2
;; ;;
--all)
INSTALL_ALL=true
shift
;;
--dry-run) --dry-run)
DRY_RUN=true DRY_RUN=true
shift shift
@ -121,7 +129,7 @@ parse_args() {
# SKILL.md validation # SKILL.md validation
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
validate_skill_md() { validate_skill_md() {
local skill_md="${SCRIPT_DIR}/SKILL.md" skill_md="${SCRIPT_DIR}/SKILL.md"
if [ ! -f "$skill_md" ]; then if [ ! -f "$skill_md" ]; then
error "SKILL.md not found in ${SCRIPT_DIR}" error "SKILL.md not found in ${SCRIPT_DIR}"
@ -130,7 +138,6 @@ validate_skill_md() {
fi fi
# Check that the file starts with YAML frontmatter delimiter # Check that the file starts with YAML frontmatter delimiter
local first_line
first_line="$(head -n 1 "$skill_md")" first_line="$(head -n 1 "$skill_md")"
if [ "$first_line" != "---" ]; then if [ "$first_line" != "---" ]; then
error "SKILL.md must start with YAML frontmatter (---)" error "SKILL.md must start with YAML frontmatter (---)"
@ -138,11 +145,10 @@ validate_skill_md() {
fi fi
# Verify required frontmatter fields: name and description # Verify required frontmatter fields: name and description
# We look between the opening --- and closing --- for these fields. in_frontmatter=false
local in_frontmatter=false found_name=false
local found_name=false found_description=false
local found_description=false line_num=0
local line_num=0
while IFS= read -r line; do while IFS= read -r line; do
line_num=$((line_num + 1)) line_num=$((line_num + 1))
@ -153,7 +159,6 @@ validate_skill_md() {
fi fi
if $in_frontmatter && [ "$line" = "---" ]; then if $in_frontmatter && [ "$line" = "---" ]; then
# End of frontmatter
break break
fi fi
@ -181,18 +186,20 @@ validate_skill_md() {
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Platform detection # Platform detection
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Returns the detected platform slug or exits with code 2. SUPPORTED_PLATFORMS="claude-code, copilot, cursor, windsurf, cline, codex, gemini, kiro, trae, goose, opencode, roo-code, antigravity, universal"
detect_platform() { detect_platform() {
# If explicitly provided, validate and return it. # If explicitly provided, validate and return it.
if [ -n "$PLATFORM" ]; then if [ -n "$PLATFORM" ]; then
case "$PLATFORM" in case "$PLATFORM" in
claude-code|copilot|cursor|windsurf|cline|codex|gemini) claude-code|copilot|cursor|windsurf|cline|codex|gemini|\
kiro|trae|goose|opencode|roo-code|antigravity|universal)
info "Platform explicitly set to: ${PLATFORM}" info "Platform explicitly set to: ${PLATFORM}"
return 0 return 0
;; ;;
*) *)
error "Unknown platform: ${PLATFORM}" error "Unknown platform: ${PLATFORM}"
error "Supported: claude-code, copilot, cursor, windsurf, cline, codex, gemini" error "Supported: ${SUPPORTED_PLATFORMS}"
exit 2 exit 2
;; ;;
esac esac
@ -204,26 +211,85 @@ detect_platform() {
PLATFORM="claude-code" PLATFORM="claude-code"
elif [ -d "${HOME}/.cursor" ] || [ -d ".cursor" ]; then elif [ -d "${HOME}/.cursor" ] || [ -d ".cursor" ]; then
PLATFORM="cursor" PLATFORM="cursor"
elif [ -d "${HOME}/.windsurf" ]; then elif [ -d "${HOME}/.codeium/windsurf" ] || [ -d ".windsurf" ]; then
PLATFORM="windsurf" PLATFORM="windsurf"
elif [ -d "${HOME}/.cline" ] || [ -d ".clinerules" ]; then elif [ -d "${HOME}/.cline" ] || [ -d ".clinerules" ]; then
PLATFORM="cline" PLATFORM="cline"
elif [ -d "${HOME}/.codex" ]; then
PLATFORM="codex"
elif [ -d "${HOME}/.gemini" ]; then elif [ -d "${HOME}/.gemini" ]; then
PLATFORM="gemini" PLATFORM="gemini"
elif [ -d ".kiro" ]; then
PLATFORM="kiro"
elif [ -d ".trae" ]; then
PLATFORM="trae"
elif [ -d ".roo" ]; then
PLATFORM="roo-code"
elif [ -d "${HOME}/.config/goose" ]; then
PLATFORM="goose"
elif [ -d "${HOME}/.config/opencode" ]; then
PLATFORM="opencode"
elif [ -d "${HOME}/.agents" ]; then
PLATFORM="universal"
elif [ -d "${HOME}/.copilot" ] || [ -d ".github" ]; then elif [ -d "${HOME}/.copilot" ] || [ -d ".github" ]; then
PLATFORM="copilot" PLATFORM="copilot"
else else
error "Could not auto-detect any supported AI coding platform." error "Could not auto-detect any supported AI coding platform."
error "Use --platform PLATFORM to specify one explicitly." error "Use --platform PLATFORM to specify one explicitly."
error "Supported: claude-code, copilot, cursor, windsurf, cline, codex, gemini" error "Supported: ${SUPPORTED_PLATFORMS}"
exit 2 exit 2
fi fi
info "Auto-detected platform: ${PLATFORM}" info "Auto-detected platform: ${PLATFORM}"
} }
# ---------------------------------------------------------------------------
# Detect all installed platforms (for --all)
# ---------------------------------------------------------------------------
detect_all_platforms() {
ALL_PLATFORMS=""
if [ -d "${HOME}/.claude" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} claude-code"
fi
if [ -d "${HOME}/.cursor" ] || [ -d ".cursor" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} cursor"
fi
if [ -d "${HOME}/.codeium/windsurf" ] || [ -d ".windsurf" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} windsurf"
fi
if [ -d "${HOME}/.cline" ] || [ -d ".clinerules" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} cline"
fi
if [ -d "${HOME}/.gemini" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} gemini"
fi
if [ -d ".kiro" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} kiro"
fi
if [ -d ".trae" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} trae"
fi
if [ -d ".roo" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} roo-code"
fi
if [ -d "${HOME}/.config/goose" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} goose"
fi
if [ -d "${HOME}/.config/opencode" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} opencode"
fi
if [ -d "${HOME}/.copilot" ] || [ -d ".github" ]; then
ALL_PLATFORMS="${ALL_PLATFORMS} copilot"
fi
# Always include universal
ALL_PLATFORMS="${ALL_PLATFORMS} universal"
# Trim leading space
ALL_PLATFORMS="$(printf '%s' "$ALL_PLATFORMS" | sed 's/^ //')"
if [ -z "$ALL_PLATFORMS" ]; then
ALL_PLATFORMS="universal"
fi
}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Install path resolution # Install path resolution
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -236,30 +302,44 @@ resolve_install_path() {
return 0 return 0
fi fi
local base="" base=""
if $PROJECT_LEVEL; then if $PROJECT_LEVEL; then
# Project-level: paths are relative to the current working directory. # Project-level: paths are relative to the current working directory.
case "$PLATFORM" in case "$PLATFORM" in
claude-code) base=".claude/skills" ;; claude-code) base=".claude/skills" ;;
copilot) base=".github/skills" ;; copilot) base=".github/skills" ;;
cursor) base=".cursor/rules" ;; cursor) base=".cursor/rules" ;;
windsurf) base=".windsurf/skills" ;; windsurf) base=".windsurf/rules" ;;
cline) base=".clinerules" ;; cline) base=".clinerules" ;;
codex) base=".codex/skills" ;; codex) base=".agents/skills" ;;
gemini) base=".gemini/skills" ;; gemini) base=".gemini/skills" ;;
kiro) base=".kiro/skills" ;;
trae) base=".trae/rules" ;;
goose) base=".agents/skills" ;;
opencode) base=".agents/skills" ;;
roo-code) base=".roo/rules" ;;
antigravity) base=".agents/skills" ;;
universal) base=".agents/skills" ;;
esac esac
INSTALL_DIR="$(pwd)/${base}/${SKILL_NAME}" INSTALL_DIR="$(pwd)/${base}/${SKILL_NAME}"
else else
# User-level: paths are under the home directory. # User-level: paths are under the home directory.
case "$PLATFORM" in case "$PLATFORM" in
claude-code) base="${HOME}/.claude/skills" ;; claude-code) base="${HOME}/.claude/skills" ;;
copilot) base="${HOME}/.copilot/skills" ;; copilot) base="${HOME}/.copilot/skills" ;;
cursor) base="${HOME}/.cursor/rules" ;; cursor) base="${HOME}/.cursor/rules" ;;
windsurf) base="${HOME}/.windsurf/skills" ;; windsurf) base="${HOME}/.codeium/windsurf/skills" ;;
cline) base="${HOME}/.cline/rules" ;; cline) base="${HOME}/.cline/rules" ;;
codex) base="${HOME}/.codex/skills" ;; codex) base="${HOME}/.agents/skills" ;;
gemini) base="${HOME}/.gemini/skills" ;; gemini) base="${HOME}/.gemini/skills" ;;
kiro) base="${HOME}/.agents/skills" ;;
trae) base="${HOME}/.agents/skills" ;;
goose) base="${HOME}/.config/goose/skills" ;;
opencode) base="${HOME}/.config/opencode/skills" ;;
roo-code) base="${HOME}/.agents/skills" ;;
antigravity) base="${HOME}/.agents/skills" ;;
universal) base="${HOME}/.agents/skills" ;;
esac esac
INSTALL_DIR="${base}/${SKILL_NAME}" INSTALL_DIR="${base}/${SKILL_NAME}"
fi fi
@ -267,14 +347,164 @@ resolve_install_path() {
info "Install directory: ${INSTALL_DIR}" info "Install directory: ${INSTALL_DIR}"
} }
# ---------------------------------------------------------------------------
# Format adapters — convert SKILL.md to platform-native formats
# ---------------------------------------------------------------------------
# Generate a .mdc file for Cursor from SKILL.md
generate_cursor_mdc() {
target_dir="$1"
skill_md="${SCRIPT_DIR}/SKILL.md"
# Extract description from frontmatter
desc=""
in_fm=false
lnum=0
while IFS= read -r line; do
lnum=$((lnum + 1))
if [ "$lnum" -eq 1 ]; then in_fm=true; continue; fi
if $in_fm && [ "$line" = "---" ]; then break; fi
if $in_fm; then
case "$line" in
description:*) desc="$(echo "$line" | sed 's/^description:[[:space:]]*//')" ;;
esac
fi
done < "$skill_md"
mdc_file="${target_dir}/${SKILL_NAME}.mdc"
if $DRY_RUN; then
info "Would generate Cursor .mdc: ${mdc_file}"
return 0
fi
# Extract body (everything after second ---)
body="$(awk 'BEGIN{c=0} /^---$/{c++;next} c>=2{print}' "$skill_md")"
cat > "$mdc_file" <<MDCEOF
---
description: ${desc}
globs:
alwaysApply: true
---
${body}
MDCEOF
success "Generated Cursor .mdc: ${mdc_file}"
}
# Generate a .md rule file for Windsurf (.windsurf/rules/ or global_rules.md)
generate_windsurf_rule() {
target_dir="$1"
is_global="$2" # "true" or "false"
skill_md="${SCRIPT_DIR}/SKILL.md"
# Extract body (everything after second ---)
body="$(awk 'BEGIN{c=0} /^---$/{c++;next} c>=2{print}' "$skill_md")"
if [ "$is_global" = "true" ]; then
# Append to global_rules.md with idempotent markers
global_file="${HOME}/.codeium/windsurf/memories/global_rules.md"
if $DRY_RUN; then
info "Would append to Windsurf global_rules.md: ${global_file}"
return 0
fi
mkdir -p "$(dirname "$global_file")"
# Remove existing block if present (idempotent, exact match)
if [ -f "$global_file" ]; then
awk -v begin_marker="<!-- BEGIN ${SKILL_NAME} -->" \
-v end_marker="<!-- END ${SKILL_NAME} -->" '
BEGIN { skip=0 }
$0 == begin_marker { skip=1; next }
$0 == end_marker { skip=0; next }
!skip { print }
' "$global_file" > "${global_file}.tmp"
mv "${global_file}.tmp" "$global_file"
fi
# Append new block
cat >> "$global_file" <<WSEOF
<!-- BEGIN ${SKILL_NAME} -->
${body}
<!-- END ${SKILL_NAME} -->
WSEOF
success "Appended to Windsurf global_rules.md"
else
# Project-level: create a .md rule file
rule_file="${target_dir}/${SKILL_NAME}.md"
if $DRY_RUN; then
info "Would generate Windsurf rule: ${rule_file}"
return 0
fi
mkdir -p "$target_dir"
printf '%s\n' "$body" > "$rule_file"
success "Generated Windsurf rule: ${rule_file}"
fi
}
# Generate plain markdown (strip YAML frontmatter) for Cline/Roo/Trae
generate_plain_rule() {
target_dir="$1"
filename="$2"
skill_md="${SCRIPT_DIR}/SKILL.md"
plain_file="${target_dir}/${filename}"
if $DRY_RUN; then
info "Would generate plain rule: ${plain_file}"
return 0
fi
mkdir -p "$target_dir"
awk 'BEGIN{c=0} /^---$/{c++;next} c>=2{print}' "$skill_md" > "$plain_file"
success "Generated plain rule: ${plain_file}"
}
# ---------------------------------------------------------------------------
# Universal .agents/skills/ secondary install (symlink or copy)
# ---------------------------------------------------------------------------
install_universal_secondary() {
# Skip if primary target is already .agents/
case "$PLATFORM" in
codex|antigravity|universal) return 0 ;;
esac
universal_dir="${HOME}/.agents/skills/${SKILL_NAME}"
if $DRY_RUN; then
info "Would create universal symlink: ${universal_dir} -> ${INSTALL_DIR}"
return 0
fi
mkdir -p "${HOME}/.agents/skills"
# Remove existing entry if present
if [ -e "$universal_dir" ] || [ -L "$universal_dir" ]; then
rm -rf "$universal_dir"
fi
# Try symlink first, fallback to copy
if ln -s "$INSTALL_DIR" "$universal_dir" 2>/dev/null; then
success "Universal symlink: ${universal_dir} -> ${INSTALL_DIR}"
elif cp -R "$INSTALL_DIR" "$universal_dir" 2>/dev/null; then
success "Universal copy: ${universal_dir}"
else
warn "Could not create universal path at ${universal_dir}"
fi
}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# File installation # File installation
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
install_files() { install_files() {
# Collect the list of files to install. # Collect the list of files to install.
# We copy everything in SCRIPT_DIR except the install script itself. # We copy everything in SCRIPT_DIR except the install script itself.
local file_count=0 file_count=0
local install_script_name
install_script_name="$(basename "$0")" install_script_name="$(basename "$0")"
if $DRY_RUN; then if $DRY_RUN; then
@ -282,7 +512,6 @@ install_files() {
info "Would create directory: ${INSTALL_DIR}" info "Would create directory: ${INSTALL_DIR}"
for file in "${SCRIPT_DIR}"/*; do for file in "${SCRIPT_DIR}"/*; do
[ -e "$file" ] || continue [ -e "$file" ] || continue
local fname
fname="$(basename "$file")" fname="$(basename "$file")"
# Skip the install script itself # Skip the install script itself
[ "$fname" = "$install_script_name" ] && continue [ "$fname" = "$install_script_name" ] && continue
@ -292,9 +521,8 @@ install_files() {
# Also handle dotfiles # Also handle dotfiles
for file in "${SCRIPT_DIR}"/.*; do for file in "${SCRIPT_DIR}"/.*; do
[ -e "$file" ] || continue [ -e "$file" ] || continue
local fname
fname="$(basename "$file")" fname="$(basename "$file")"
[ "$fname" = "." ] || [ "$fname" = ".." ] && continue if [ "$fname" = "." ] || [ "$fname" = ".." ]; then continue; fi
info "Would copy: ${fname}" info "Would copy: ${fname}"
file_count=$((file_count + 1)) file_count=$((file_count + 1))
done done
@ -313,7 +541,6 @@ install_files() {
# Copy files. # Copy files.
for file in "${SCRIPT_DIR}"/*; do for file in "${SCRIPT_DIR}"/*; do
[ -e "$file" ] || continue [ -e "$file" ] || continue
local fname
fname="$(basename "$file")" fname="$(basename "$file")"
[ "$fname" = "$install_script_name" ] && continue [ "$fname" = "$install_script_name" ] && continue
@ -328,7 +555,6 @@ install_files() {
# Copy dotfiles (if any). # Copy dotfiles (if any).
for file in "${SCRIPT_DIR}"/.*; do for file in "${SCRIPT_DIR}"/.*; do
[ -e "$file" ] || continue [ -e "$file" ] || continue
local fname
fname="$(basename "$file")" fname="$(basename "$file")"
[ "$fname" = "." ] || [ "$fname" = ".." ] && continue [ "$fname" = "." ] || [ "$fname" = ".." ] && continue
@ -343,6 +569,33 @@ install_files() {
success "Copied ${file_count} file(s) to ${INSTALL_DIR}" success "Copied ${file_count} file(s) to ${INSTALL_DIR}"
} }
# ---------------------------------------------------------------------------
# Run format adapters based on platform
# ---------------------------------------------------------------------------
run_adapters() {
case "$PLATFORM" in
cursor)
generate_cursor_mdc "$INSTALL_DIR"
;;
windsurf)
if $PROJECT_LEVEL; then
generate_windsurf_rule "$(pwd)/.windsurf/rules" "false"
else
generate_windsurf_rule "" "true"
fi
;;
cline)
generate_plain_rule "$INSTALL_DIR" "${SKILL_NAME}.md"
;;
roo-code)
generate_plain_rule "$INSTALL_DIR" "${SKILL_NAME}.md"
;;
trae)
generate_plain_rule "$INSTALL_DIR" "${SKILL_NAME}.md"
;;
esac
}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Activation instructions # Activation instructions
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -372,21 +625,25 @@ print_activation_instructions() {
printf "To activate the skill in Cursor:\n" printf "To activate the skill in Cursor:\n"
printf " 1. Open your project in Cursor.\n" printf " 1. Open your project in Cursor.\n"
printf " 2. The rule is loaded automatically from:\n" printf " 2. The rule is loaded automatically from:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " ${BOLD}${INSTALL_DIR}/${SKILL_NAME}.mdc${NC}\n"
printf " 3. Use trigger phrases to invoke the skill.\n" printf " 3. Use trigger phrases to invoke the skill.\n"
;; ;;
windsurf) windsurf)
printf "To activate the skill in Windsurf:\n" printf "To activate the skill in Windsurf:\n"
printf " 1. Open your project in Windsurf.\n" if $PROJECT_LEVEL; then
printf " 2. The skill is available at:\n" printf " 1. Open your project in Windsurf.\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 2. The rule is loaded from .windsurf/rules/\n"
else
printf " 1. Open Windsurf.\n"
printf " 2. The skill was added to global_rules.md.\n"
fi
printf " 3. Use trigger phrases to invoke the skill.\n" printf " 3. Use trigger phrases to invoke the skill.\n"
;; ;;
cline) cline)
printf "To activate the skill in Cline:\n" printf "To activate the skill in Cline:\n"
printf " 1. Open your project in VS Code with Cline.\n" printf " 1. Open your project in VS Code with Cline.\n"
printf " 2. The rule is loaded from:\n" printf " 2. The rule is loaded from:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " ${BOLD}${INSTALL_DIR}/${SKILL_NAME}.md${NC}\n"
printf " 3. Cline will pick up the rule automatically.\n" printf " 3. Cline will pick up the rule automatically.\n"
;; ;;
codex) codex)
@ -394,7 +651,7 @@ print_activation_instructions() {
printf " 1. Start a new Codex CLI session.\n" printf " 1. Start a new Codex CLI session.\n"
printf " 2. The skill is available at:\n" printf " 2. The skill is available at:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. Reference the skill in your instructions.\n" printf " 3. Codex reads from ~/.agents/skills/ automatically.\n"
;; ;;
gemini) gemini)
printf "To activate the skill in Gemini CLI:\n" printf "To activate the skill in Gemini CLI:\n"
@ -403,11 +660,118 @@ print_activation_instructions() {
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. The skill will be loaded automatically.\n" printf " 3. The skill will be loaded automatically.\n"
;; ;;
kiro)
printf "To activate the skill in Kiro:\n"
printf " 1. Open your project in Kiro.\n"
printf " 2. The skill is available at:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. Kiro reads from .kiro/skills/ automatically.\n"
;;
trae)
printf "To activate the skill in Trae:\n"
printf " 1. Open your project in Trae.\n"
printf " 2. The rule is loaded from:\n"
printf " ${BOLD}${INSTALL_DIR}/${SKILL_NAME}.md${NC}\n"
printf " 3. Use trigger phrases to invoke the skill.\n"
;;
goose)
printf "To activate the skill in Goose:\n"
printf " 1. Start a new Goose session.\n"
printf " 2. The skill is available at:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. Goose reads from ~/.config/goose/skills/ automatically.\n"
;;
opencode)
printf "To activate the skill in OpenCode:\n"
printf " 1. Start a new OpenCode session.\n"
printf " 2. The skill is available at:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. OpenCode reads from ~/.config/opencode/skills/ automatically.\n"
;;
roo-code)
printf "To activate the skill in Roo Code:\n"
printf " 1. Open your project in VS Code with Roo Code.\n"
printf " 2. The rule is loaded from:\n"
printf " ${BOLD}${INSTALL_DIR}/${SKILL_NAME}.md${NC}\n"
printf " 3. Roo Code will pick up the rule automatically.\n"
;;
antigravity)
printf "To activate the skill in Antigravity:\n"
printf " 1. Open your project.\n"
printf " 2. The skill is available at:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n"
printf " 3. Antigravity reads from .agents/skills/ automatically.\n"
;;
universal)
printf "The skill is installed at the universal path:\n"
printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n\n"
printf "Tools that read ~/.agents/skills/ (Codex CLI, Gemini CLI,\n"
printf "Kiro, Antigravity, and others) will discover it automatically.\n"
;;
esac esac
printf "\n" printf "\n"
} }
# ---------------------------------------------------------------------------
# Install for a single platform
# ---------------------------------------------------------------------------
install_single() {
detect_platform
resolve_install_path
install_files
run_adapters
install_universal_secondary
print_activation_instructions
if $DRY_RUN; then
info "Dry run complete. No changes were made."
else
success "Skill '${SKILL_NAME}' installed successfully for ${PLATFORM}."
fi
}
# ---------------------------------------------------------------------------
# Install for all detected platforms (--all)
# ---------------------------------------------------------------------------
install_all() {
detect_all_platforms
info "Installing to all detected platforms: ${ALL_PLATFORMS}"
printf "%-40s\n" "----------------------------------------"
installed_count=0
first_non_agents_dir=""
for plat in $ALL_PLATFORMS; do
printf "\n"
info "--- Installing for: ${plat} ---"
PLATFORM="$plat"
resolve_install_path
install_files
run_adapters
installed_count=$((installed_count + 1))
# Remember the first non-.agents/ install dir for universal symlink
if [ -z "$first_non_agents_dir" ]; then
case "$plat" in
codex|antigravity|universal) ;;
*) first_non_agents_dir="$INSTALL_DIR" ;;
esac
fi
done
# Create universal symlink from the first non-.agents/ install
if [ -n "$first_non_agents_dir" ]; then
INSTALL_DIR="$first_non_agents_dir"
install_universal_secondary
fi
printf "\n"
if $DRY_RUN; then
info "Dry run complete. No changes were made."
else
success "Skill '${SKILL_NAME}' installed to ${installed_count} platform(s)."
fi
}
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Main # Main
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -417,15 +781,11 @@ main() {
parse_args "$@" parse_args "$@"
validate_skill_md validate_skill_md
detect_platform
resolve_install_path
install_files
print_activation_instructions
if $DRY_RUN; then if $INSTALL_ALL; then
info "Dry run complete. No changes were made." install_all
else else
success "Skill '${SKILL_NAME}' installed successfully for ${PLATFORM}." install_single
fi fi
exit 0 exit 0