📦 deps(thirdparty): update snapshots
This commit is contained in:
+217
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# create-marketplace.sh - Create a new Claude Code plugin marketplace
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
print_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [options]
|
||||
|
||||
Create a new Claude Code plugin marketplace.
|
||||
|
||||
Options:
|
||||
-n, --name NAME Marketplace name (kebab-case)
|
||||
-o, --owner NAME Owner name
|
||||
-e, --email EMAIL Owner email
|
||||
-d, --description DESC Marketplace description
|
||||
-r, --plugin-root PATH Base path for relative plugin sources
|
||||
--dir DIRECTORY Output directory (default: current)
|
||||
-h, --help Show this help message
|
||||
|
||||
Example:
|
||||
$0 --name my-marketplace --owner "John Doe" --email "john@example.com"
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
MARKETPLACE_NAME=""
|
||||
OWNER_NAME=""
|
||||
OWNER_EMAIL=""
|
||||
DESCRIPTION=""
|
||||
PLUGIN_ROOT=""
|
||||
OUTPUT_DIR="."
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-n|--name)
|
||||
MARKETPLACE_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--owner)
|
||||
OWNER_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--email)
|
||||
OWNER_EMAIL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-d|--description)
|
||||
DESCRIPTION="$2"
|
||||
shift 2
|
||||
;;
|
||||
-r|--plugin-root)
|
||||
PLUGIN_ROOT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dir)
|
||||
OUTPUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate marketplace name
|
||||
if [[ -z "$MARKETPLACE_NAME" ]]; then
|
||||
print_error "Marketplace name is required"
|
||||
usage
|
||||
fi
|
||||
|
||||
if ! echo "$MARKETPLACE_NAME" | grep -qE '^[a-z][a-z0-9-]*$'; then
|
||||
print_error "Marketplace name must be in kebab-case: $MARKETPLACE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get owner info if not provided
|
||||
if [[ -z "$OWNER_NAME" ]]; then
|
||||
OWNER_NAME=$(git config user.name 2>/dev/null || echo "")
|
||||
if [[ -z "$OWNER_NAME" ]]; then
|
||||
read -p "Owner name: " OWNER_NAME
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$OWNER_EMAIL" ]]; then
|
||||
OWNER_EMAIL=$(git config user.email 2>/dev/null || echo "")
|
||||
if [[ -z "$OWNER_EMAIL" ]]; then
|
||||
read -p "Owner email: " OWNER_EMAIL
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create output directory
|
||||
MARKETPLACE_DIR="$OUTPUT_DIR/.claude-plugin"
|
||||
mkdir -p "$MARKETPLACE_DIR"
|
||||
|
||||
print_info "Creating marketplace: $MARKETPLACE_NAME"
|
||||
|
||||
# Build marketplace JSON
|
||||
MARKETPLACE_JSON=$(jq -n \
|
||||
--arg name "$MARKETPLACE_NAME" \
|
||||
--arg owner_name "$OWNER_NAME" \
|
||||
--arg owner_email "$OWNER_EMAIL" \
|
||||
'{
|
||||
name: $name,
|
||||
owner: {
|
||||
name: $owner_name,
|
||||
email: $owner_email
|
||||
},
|
||||
plugins: []
|
||||
}')
|
||||
|
||||
# Add optional fields
|
||||
if [[ -n "$DESCRIPTION" ]]; then
|
||||
MARKETPLACE_JSON=$(echo "$MARKETPLACE_JSON" | jq \
|
||||
--arg desc "$DESCRIPTION" \
|
||||
'.metadata.description = $desc')
|
||||
fi
|
||||
|
||||
if [[ -n "$PLUGIN_ROOT" ]]; then
|
||||
MARKETPLACE_JSON=$(echo "$MARKETPLACE_JSON" | jq \
|
||||
--arg root "$PLUGIN_ROOT" \
|
||||
'.metadata.pluginRoot = $root')
|
||||
fi
|
||||
|
||||
# Write marketplace.json
|
||||
echo "$MARKETPLACE_JSON" | jq '.' > "$MARKETPLACE_DIR/marketplace.json"
|
||||
|
||||
print_info "Created marketplace.json at $MARKETPLACE_DIR/marketplace.json"
|
||||
|
||||
# Create README
|
||||
README_PATH="$OUTPUT_DIR/README.md"
|
||||
if [[ ! -f "$README_PATH" ]]; then
|
||||
cat > "$README_PATH" << EOF
|
||||
# $MARKETPLACE_NAME
|
||||
|
||||
$DESCRIPTION
|
||||
|
||||
## Installation
|
||||
|
||||
\`\`\`bash
|
||||
/plugin marketplace add path/to/$MARKETPLACE_NAME
|
||||
\`\`\`
|
||||
|
||||
## Available Plugins
|
||||
|
||||
[List your plugins here]
|
||||
|
||||
## Usage
|
||||
|
||||
\`\`\`bash
|
||||
# Install a plugin
|
||||
/plugin install plugin-name@$MARKETPLACE_NAME
|
||||
\`\`\`
|
||||
|
||||
## Contributing
|
||||
|
||||
[Add contribution guidelines]
|
||||
|
||||
## License
|
||||
|
||||
[Specify license]
|
||||
EOF
|
||||
print_info "Created README.md"
|
||||
fi
|
||||
|
||||
# Create .gitignore if it doesn't exist
|
||||
GITIGNORE_PATH="$OUTPUT_DIR/.gitignore"
|
||||
if [[ ! -f "$GITIGNORE_PATH" ]]; then
|
||||
cat > "$GITIGNORE_PATH" << EOF
|
||||
*.log
|
||||
.DS_Store
|
||||
node_modules/
|
||||
__pycache__/
|
||||
.env
|
||||
EOF
|
||||
print_info "Created .gitignore"
|
||||
fi
|
||||
|
||||
# Initialize git if not already a repo
|
||||
if [[ ! -d "$OUTPUT_DIR/.git" ]] && command -v git &> /dev/null; then
|
||||
print_info "Initializing git repository"
|
||||
cd "$OUTPUT_DIR"
|
||||
git init -q
|
||||
git add .
|
||||
git commit -q -m "feat: initial marketplace structure"
|
||||
cd - > /dev/null
|
||||
fi
|
||||
|
||||
# Success message
|
||||
print_info "Marketplace created successfully!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Add plugins to $MARKETPLACE_DIR/marketplace.json"
|
||||
echo " 2. Create plugin directories"
|
||||
echo " 3. Test locally:"
|
||||
echo " /plugin marketplace add $OUTPUT_DIR"
|
||||
echo " 4. Push to Git hosting:"
|
||||
echo " git remote add origin <url>"
|
||||
echo " git push -u origin main"
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# scaffold-plugin.sh - Create a new Claude Code plugin structure
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Print colored output
|
||||
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
print_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Usage information
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [options] <plugin-name>
|
||||
|
||||
Create a new Claude Code plugin with proper structure.
|
||||
|
||||
Options:
|
||||
-d, --directory DIR Create plugin in specified directory (default: current)
|
||||
-a, --author NAME Author name
|
||||
-e, --email EMAIL Author email
|
||||
-l, --license LICENSE License (default: MIT)
|
||||
--with-commands Include sample command
|
||||
--with-agent Include sample agent
|
||||
--with-hooks Include sample hooks
|
||||
--with-mcp Include MCP server template
|
||||
-h, --help Show this help message
|
||||
|
||||
Example:
|
||||
$0 my-plugin --author "John Doe" --with-commands
|
||||
$0 my-plugin -d ./plugins --with-agent --with-hooks
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
PLUGIN_DIR="."
|
||||
AUTHOR_NAME=""
|
||||
AUTHOR_EMAIL=""
|
||||
LICENSE="MIT"
|
||||
WITH_COMMANDS=false
|
||||
WITH_AGENT=false
|
||||
WITH_HOOKS=false
|
||||
WITH_MCP=false
|
||||
|
||||
# Parse arguments
|
||||
PLUGIN_NAME=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-d|--directory)
|
||||
PLUGIN_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-a|--author)
|
||||
AUTHOR_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--email)
|
||||
AUTHOR_EMAIL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-l|--license)
|
||||
LICENSE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--with-commands)
|
||||
WITH_COMMANDS=true
|
||||
shift
|
||||
;;
|
||||
--with-agent)
|
||||
WITH_AGENT=true
|
||||
shift
|
||||
;;
|
||||
--with-hooks)
|
||||
WITH_HOOKS=true
|
||||
shift
|
||||
;;
|
||||
--with-mcp)
|
||||
WITH_MCP=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
-*)
|
||||
print_error "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$PLUGIN_NAME" ]]; then
|
||||
PLUGIN_NAME="$1"
|
||||
else
|
||||
print_error "Unexpected argument: $1"
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate plugin name
|
||||
if [[ -z "$PLUGIN_NAME" ]]; then
|
||||
print_error "Plugin name is required"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Validate plugin name format (kebab-case)
|
||||
if ! echo "$PLUGIN_NAME" | grep -qE '^[a-z][a-z0-9-]*$'; then
|
||||
print_error "Plugin name must be in kebab-case (lowercase with hyphens): $PLUGIN_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get author info if not provided
|
||||
if [[ -z "$AUTHOR_NAME" ]]; then
|
||||
# Try to get from git config
|
||||
AUTHOR_NAME=$(git config user.name 2>/dev/null || echo "")
|
||||
if [[ -z "$AUTHOR_NAME" ]]; then
|
||||
read -p "Author name: " AUTHOR_NAME
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$AUTHOR_EMAIL" ]]; then
|
||||
AUTHOR_EMAIL=$(git config user.email 2>/dev/null || echo "")
|
||||
if [[ -z "$AUTHOR_EMAIL" ]]; then
|
||||
read -p "Author email: " AUTHOR_EMAIL
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create plugin directory
|
||||
PLUGIN_PATH="$PLUGIN_DIR/$PLUGIN_NAME"
|
||||
if [[ -d "$PLUGIN_PATH" ]]; then
|
||||
print_error "Directory already exists: $PLUGIN_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_info "Creating plugin: $PLUGIN_NAME"
|
||||
mkdir -p "$PLUGIN_PATH"
|
||||
|
||||
# Create plugin.json
|
||||
print_info "Creating plugin.json"
|
||||
cat > "$PLUGIN_PATH/plugin.json" << EOF
|
||||
{
|
||||
"name": "$PLUGIN_NAME",
|
||||
"version": "0.1.0",
|
||||
"description": "A Claude Code plugin",
|
||||
"author": {
|
||||
"name": "$AUTHOR_NAME",
|
||||
"email": "$AUTHOR_EMAIL"
|
||||
},
|
||||
"license": "$LICENSE"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create README.md
|
||||
print_info "Creating README.md"
|
||||
cat > "$PLUGIN_PATH/README.md" << EOF
|
||||
# $PLUGIN_NAME
|
||||
|
||||
A Claude Code plugin.
|
||||
|
||||
## Installation
|
||||
|
||||
\`\`\`bash
|
||||
/plugin marketplace add path/to/$PLUGIN_NAME
|
||||
/plugin install $PLUGIN_NAME@$PLUGIN_NAME
|
||||
\`\`\`
|
||||
|
||||
## Features
|
||||
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
|
||||
## Usage
|
||||
|
||||
Describe how to use this plugin.
|
||||
|
||||
## License
|
||||
|
||||
$LICENSE
|
||||
EOF
|
||||
|
||||
# Create CHANGELOG.md
|
||||
print_info "Creating CHANGELOG.md"
|
||||
cat > "$PLUGIN_PATH/CHANGELOG.md" << EOF
|
||||
# Changelog
|
||||
|
||||
## [0.1.0] - $(date +%Y-%m-%d)
|
||||
|
||||
### Added
|
||||
- Initial release
|
||||
EOF
|
||||
|
||||
# Create LICENSE
|
||||
print_info "Creating LICENSE"
|
||||
if [[ "$LICENSE" == "MIT" ]]; then
|
||||
cat > "$PLUGIN_PATH/LICENSE" << EOF
|
||||
MIT License
|
||||
|
||||
Copyright (c) $(date +%Y) $AUTHOR_NAME
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
EOF
|
||||
else
|
||||
touch "$PLUGIN_PATH/LICENSE"
|
||||
print_warn "Please add $LICENSE license text to LICENSE file"
|
||||
fi
|
||||
|
||||
# Create .gitignore
|
||||
cat > "$PLUGIN_PATH/.gitignore" << EOF
|
||||
*.log
|
||||
.DS_Store
|
||||
.env
|
||||
node_modules/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
EOF
|
||||
|
||||
# Create sample command if requested
|
||||
if [[ "$WITH_COMMANDS" == true ]]; then
|
||||
print_info "Creating sample command"
|
||||
mkdir -p "$PLUGIN_PATH/commands"
|
||||
cat > "$PLUGIN_PATH/commands/hello.md" << EOF
|
||||
---
|
||||
description: "Say hello with a friendly greeting"
|
||||
---
|
||||
|
||||
Generate a friendly greeting for {{0:name}}.
|
||||
|
||||
Make the greeting:
|
||||
- Warm and welcoming
|
||||
- Include time of day
|
||||
- Professional yet friendly
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Create sample agent if requested
|
||||
if [[ "$WITH_AGENT" == true ]]; then
|
||||
print_info "Creating sample agent"
|
||||
mkdir -p "$PLUGIN_PATH/agents"
|
||||
cat > "$PLUGIN_PATH/agents/helper.md" << EOF
|
||||
---
|
||||
name: helper
|
||||
description: "A helpful assistant for common tasks"
|
||||
---
|
||||
|
||||
You are a helpful assistant specialized in [your domain].
|
||||
|
||||
Your responsibilities:
|
||||
1. Task 1
|
||||
2. Task 2
|
||||
3. Task 3
|
||||
|
||||
Guidelines:
|
||||
- Be clear and concise
|
||||
- Provide examples
|
||||
- Explain your reasoning
|
||||
EOF
|
||||
|
||||
# Update plugin.json to reference agent
|
||||
tmp=$(mktemp)
|
||||
jq '.agents = ["./agents/helper.md"]' "$PLUGIN_PATH/plugin.json" > "$tmp"
|
||||
mv "$tmp" "$PLUGIN_PATH/plugin.json"
|
||||
fi
|
||||
|
||||
# Create sample hooks if requested
|
||||
if [[ "$WITH_HOOKS" == true ]]; then
|
||||
print_info "Creating sample hooks"
|
||||
mkdir -p "$PLUGIN_PATH/hooks"
|
||||
cat > "$PLUGIN_PATH/hooks/pre-write.sh" << 'EOF'
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Pre-write validation hook
|
||||
input=$(cat)
|
||||
|
||||
file_path=$(echo "$input" | jq -r '.parameters.file_path')
|
||||
content=$(echo "$input" | jq -r '.parameters.content')
|
||||
|
||||
# Add your validation logic here
|
||||
|
||||
# Allow the operation
|
||||
echo '{"allowed": true}'
|
||||
EOF
|
||||
chmod +x "$PLUGIN_PATH/hooks/pre-write.sh"
|
||||
|
||||
# Update plugin.json to reference hooks
|
||||
tmp=$(mktemp)
|
||||
jq '.hooks = {"PreToolUse": [{"matcher": "Write", "hooks": [{"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre-write.sh"}]}]}' "$PLUGIN_PATH/plugin.json" > "$tmp"
|
||||
mv "$tmp" "$PLUGIN_PATH/plugin.json"
|
||||
fi
|
||||
|
||||
# Create MCP server template if requested
|
||||
if [[ "$WITH_MCP" == true ]]; then
|
||||
print_info "Creating MCP server template"
|
||||
mkdir -p "$PLUGIN_PATH/servers/$PLUGIN_NAME-server"
|
||||
|
||||
cat > "$PLUGIN_PATH/servers/$PLUGIN_NAME-server/server.py" << 'EOF'
|
||||
"""MCP server for PLUGIN_NAME"""
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
mcp = FastMCP("PLUGIN_NAME")
|
||||
|
||||
@mcp.tool()
|
||||
async def example_tool(param: str) -> str:
|
||||
"""
|
||||
Example tool implementation.
|
||||
|
||||
Args:
|
||||
param: Parameter description
|
||||
|
||||
Returns:
|
||||
Result description
|
||||
"""
|
||||
return f"Processed: {param}"
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp.run(transport='stdio')
|
||||
EOF
|
||||
|
||||
# Replace PLUGIN_NAME in template
|
||||
sed -i.bak "s/PLUGIN_NAME/$PLUGIN_NAME/g" "$PLUGIN_PATH/servers/$PLUGIN_NAME-server/server.py"
|
||||
rm "$PLUGIN_PATH/servers/$PLUGIN_NAME-server/server.py.bak"
|
||||
|
||||
cat > "$PLUGIN_PATH/servers/$PLUGIN_NAME-server/pyproject.toml" << EOF
|
||||
[project]
|
||||
name = "$PLUGIN_NAME-server"
|
||||
version = "0.1.0"
|
||||
description = "MCP server for $PLUGIN_NAME"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"mcp>=1.2.0",
|
||||
]
|
||||
EOF
|
||||
|
||||
# Update plugin.json to reference MCP server
|
||||
tmp=$(mktemp)
|
||||
jq --arg name "$PLUGIN_NAME" '.mcpServers = {($name): {"command": "uv", "args": ["--directory", "${CLAUDE_PLUGIN_ROOT}/servers/\($name)-server", "run", "server.py"]}}' "$PLUGIN_PATH/plugin.json" > "$tmp"
|
||||
mv "$tmp" "$PLUGIN_PATH/plugin.json"
|
||||
fi
|
||||
|
||||
# Initialize git repository
|
||||
if command -v git &> /dev/null; then
|
||||
print_info "Initializing git repository"
|
||||
cd "$PLUGIN_PATH"
|
||||
git init -q
|
||||
git add .
|
||||
git commit -q -m "feat: initial plugin structure"
|
||||
cd - > /dev/null
|
||||
fi
|
||||
|
||||
# Success message
|
||||
print_info "Plugin created successfully!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " cd $PLUGIN_PATH"
|
||||
echo " # Edit plugin.json to update description"
|
||||
if [[ "$WITH_COMMANDS" == true ]]; then
|
||||
echo " # Customize commands in commands/"
|
||||
fi
|
||||
if [[ "$WITH_AGENT" == true ]]; then
|
||||
echo " # Customize agent in agents/"
|
||||
fi
|
||||
if [[ "$WITH_HOOKS" == true ]]; then
|
||||
echo " # Implement hooks in hooks/"
|
||||
fi
|
||||
if [[ "$WITH_MCP" == true ]]; then
|
||||
echo " # Implement MCP server in servers/"
|
||||
fi
|
||||
echo ""
|
||||
echo "Test locally:"
|
||||
echo " /plugin marketplace add $PLUGIN_PATH"
|
||||
echo " /plugin install $PLUGIN_NAME@$PLUGIN_NAME"
|
||||
Reference in New Issue
Block a user