Skip to content

Commit 6d8cd3c

Browse files
authored
Initial commit
0 parents  commit 6d8cd3c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+12120
-0
lines changed

.claude-plugin/marketplace.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "my-team-plugin-marketplace",
3+
"owner": {
4+
"name": "Your Organization",
5+
"email": "team@your-org.com"
6+
},
7+
"metadata": {
8+
"description": "A curated collection of Claude Code plugins for our team",
9+
"version": "1.3.0"
10+
},
11+
"plugins": [
12+
{
13+
"name": "hello-world",
14+
"description": "A simple example plugin demonstrating basic Claude Code plugin functionality",
15+
"version": "1.0.0",
16+
"author": {
17+
"name": "Your Team"
18+
},
19+
"source": "./plugins/hello-world",
20+
"category": "examples",
21+
"tags": ["example", "tutorial", "getting-started"],
22+
"keywords": ["example", "tutorial", "getting-started"]
23+
},
24+
{
25+
"name": "plugin-development",
26+
"description": "Assist with Claude Code plugin development: scaffold, validate, review, and team-ready distribution",
27+
"version": "1.3.0",
28+
"author": {
29+
"name": "Ivan Magda"
30+
},
31+
"source": "./plugins/plugin-development",
32+
"category": "developer-tools",
33+
"tags": ["development", "plugins", "scaffold", "validation", "tools"],
34+
"keywords": ["claude-code", "plugins", "developer-tools", "scaffold", "validation"]
35+
}
36+
]
37+
}

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Dependabot configuration file
2+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
3+
4+
version: 2
5+
updates:
6+
# Enable version updates for GitHub Actions
7+
- package-ecosystem: "github-actions"
8+
directory: "/"
9+
schedule:
10+
interval: "weekly"
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
name: Validate Plugins
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
validate-structure:
11+
name: Validate Repository Structure
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v6
17+
18+
- name: Setup jq
19+
uses: dcarbone/install-jq-action@v3
20+
21+
- name: Validate marketplace.json
22+
run: |
23+
echo "Validating marketplace.json..."
24+
jq empty .claude-plugin/marketplace.json
25+
echo "✓ Marketplace JSON is valid"
26+
27+
- name: Check required fields in marketplace
28+
run: |
29+
echo "Checking required marketplace fields..."
30+
31+
# Check top-level required fields
32+
if ! jq -e ".name" .claude-plugin/marketplace.json > /dev/null; then
33+
echo "✗ Missing required field: name"
34+
exit 1
35+
fi
36+
echo "✓ Field 'name' present"
37+
38+
if ! jq -e ".owner" .claude-plugin/marketplace.json > /dev/null; then
39+
echo "✗ Missing required field: owner"
40+
exit 1
41+
fi
42+
echo "✓ Field 'owner' present"
43+
44+
# Check owner.name exists
45+
if ! jq -e ".owner.name" .claude-plugin/marketplace.json > /dev/null; then
46+
echo "✗ Missing required field: owner.name"
47+
exit 1
48+
fi
49+
echo "✓ Field 'owner.name' present"
50+
51+
if ! jq -e ".plugins" .claude-plugin/marketplace.json > /dev/null; then
52+
echo "✗ Missing required field: plugins"
53+
exit 1
54+
fi
55+
echo "✓ Field 'plugins' present"
56+
57+
# Check plugins is an array
58+
if ! jq -e ".plugins | type == \"array\"" .claude-plugin/marketplace.json > /dev/null; then
59+
echo "✗ Field 'plugins' must be an array"
60+
exit 1
61+
fi
62+
echo "✓ Field 'plugins' is an array"
63+
64+
validate-marketplace-plugins:
65+
name: Validate Marketplace Plugin Entries
66+
runs-on: ubuntu-latest
67+
68+
steps:
69+
- name: Checkout code
70+
uses: actions/checkout@v6
71+
72+
- name: Setup jq
73+
uses: dcarbone/install-jq-action@v3
74+
75+
- name: Validate marketplace plugin entries
76+
run: |
77+
echo "Validating marketplace plugin entries..."
78+
79+
# Check each plugin entry in marketplace
80+
plugin_count=$(jq '.plugins | length' .claude-plugin/marketplace.json)
81+
82+
for ((i=0; i<$plugin_count; i++)); do
83+
echo ""
84+
echo "Checking marketplace entry $((i+1))..."
85+
86+
# Check required fields for marketplace entries
87+
if ! jq -e ".plugins[$i].name" .claude-plugin/marketplace.json > /dev/null; then
88+
echo "✗ Plugin entry $((i+1)): Missing required field 'name'"
89+
exit 1
90+
fi
91+
92+
if ! jq -e ".plugins[$i].source" .claude-plugin/marketplace.json > /dev/null; then
93+
echo "✗ Plugin entry $((i+1)): Missing required field 'source'"
94+
exit 1
95+
fi
96+
97+
# Check author format if present
98+
if jq -e ".plugins[$i].author" .claude-plugin/marketplace.json > /dev/null; then
99+
if ! jq -e ".plugins[$i].author | type == \"object\"" .claude-plugin/marketplace.json > /dev/null; then
100+
echo "✗ Plugin entry $((i+1)): Field 'author' must be an object"
101+
exit 1
102+
fi
103+
if ! jq -e ".plugins[$i].author.name" .claude-plugin/marketplace.json > /dev/null; then
104+
echo "✗ Plugin entry $((i+1)): Field 'author.name' is required when 'author' is present"
105+
exit 1
106+
fi
107+
echo "✓ Plugin entry $((i+1)): Field 'author' is properly formatted"
108+
fi
109+
110+
plugin_name=$(jq -r ".plugins[$i].name" .claude-plugin/marketplace.json)
111+
echo "✓ Marketplace entry for '$plugin_name' is valid"
112+
done
113+
114+
echo ""
115+
echo "✅ All marketplace plugin entries are valid"
116+
117+
validate-plugins:
118+
name: Validate Individual Plugins
119+
runs-on: ubuntu-latest
120+
121+
steps:
122+
- name: Checkout code
123+
uses: actions/checkout@v6
124+
125+
- name: Setup jq
126+
uses: dcarbone/install-jq-action@v3
127+
128+
- name: Validate each plugin
129+
run: |
130+
echo "Validating plugin files..."
131+
132+
# Get all plugin paths
133+
plugins=$(jq -r '.plugins[] | select(.source | type == "string") | .source' .claude-plugin/marketplace.json)
134+
135+
for plugin_path in $plugins; do
136+
plugin_name=$(basename "$plugin_path")
137+
echo ""
138+
echo "Checking plugin: $plugin_name"
139+
echo "================================"
140+
141+
# Check directory exists
142+
if [ ! -d "$plugin_path" ]; then
143+
echo "✗ Directory not found: $plugin_path"
144+
exit 1
145+
fi
146+
echo "✓ Directory exists"
147+
148+
# Check plugin.json exists
149+
plugin_json="$plugin_path/.claude-plugin/plugin.json"
150+
if [ ! -f "$plugin_json" ]; then
151+
echo "✗ plugin.json not found at $plugin_json"
152+
exit 1
153+
fi
154+
echo "✓ plugin.json exists"
155+
156+
# Validate JSON syntax
157+
if ! jq empty "$plugin_json" 2>/dev/null; then
158+
echo "✗ Invalid JSON in $plugin_json"
159+
exit 1
160+
fi
161+
echo "✓ plugin.json is valid JSON"
162+
163+
# Check required fields (only 'name' is required)
164+
if ! jq -e ".name" "$plugin_json" > /dev/null; then
165+
echo "✗ Missing required field: name"
166+
exit 1
167+
fi
168+
echo "✓ Required field 'name' present"
169+
170+
# Check optional but recommended fields
171+
if jq -e ".author" "$plugin_json" > /dev/null; then
172+
# If author exists, check it's an object
173+
if ! jq -e ".author | type == \"object\"" "$plugin_json" > /dev/null; then
174+
echo "✗ Field 'author' must be an object with 'name' field"
175+
exit 1
176+
fi
177+
if ! jq -e ".author.name" "$plugin_json" > /dev/null; then
178+
echo "✗ Field 'author.name' is required when 'author' is present"
179+
exit 1
180+
fi
181+
echo "✓ Field 'author' is properly formatted"
182+
fi
183+
184+
# Validate repository field if present (should be string, not object)
185+
if jq -e ".repository" "$plugin_json" > /dev/null; then
186+
if ! jq -e ".repository | type == \"string\"" "$plugin_json" > /dev/null; then
187+
echo "✗ Field 'repository' must be a string URL, not an object"
188+
exit 1
189+
fi
190+
echo "✓ Field 'repository' is properly formatted"
191+
fi
192+
193+
# Check README exists
194+
if [ ! -f "$plugin_path/README.md" ]; then
195+
echo "⚠️ Warning: README.md not found (recommended)"
196+
else
197+
echo "✓ README.md exists"
198+
fi
199+
200+
# Check commands directory and validate command files
201+
if [ -d "$plugin_path/commands" ]; then
202+
echo "✓ Commands directory exists"
203+
204+
# Find all markdown files in commands directory
205+
command_files=$(find "$plugin_path/commands" -name "*.md" 2>/dev/null)
206+
207+
if [ -n "$command_files" ]; then
208+
for cmd_file in $command_files; do
209+
cmd_name=$(basename "$cmd_file")
210+
211+
# Check if file has frontmatter (starts with ---)
212+
if head -n 1 "$cmd_file" | grep -q "^---$"; then
213+
echo "✓ Command '$cmd_name' has frontmatter"
214+
else
215+
echo "⚠️ Warning: Command '$cmd_name' missing frontmatter (recommended)"
216+
fi
217+
done
218+
fi
219+
fi
220+
221+
echo "✓ Plugin $plugin_name is valid"
222+
done
223+
224+
echo ""
225+
echo "================================"
226+
echo "✅ All plugins validated successfully!"
227+
228+
check-duplicates:
229+
name: Check for Duplicate Plugin Names
230+
runs-on: ubuntu-latest
231+
232+
steps:
233+
- name: Checkout code
234+
uses: actions/checkout@v6
235+
236+
- name: Setup jq
237+
uses: dcarbone/install-jq-action@v3
238+
239+
- name: Check for duplicate names
240+
run: |
241+
echo "Checking for duplicate plugin names..."
242+
243+
duplicates=$(jq -r '.plugins[].name' .claude-plugin/marketplace.json | sort | uniq -d)
244+
245+
if [ -n "$duplicates" ]; then
246+
echo "✗ Duplicate plugin names found:"
247+
echo "$duplicates"
248+
exit 1
249+
fi
250+
251+
echo "✓ No duplicate plugin names"

.gitignore

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Claude Code
2+
.claude/cache/
3+
.claude/logs/
4+
.claude/temp/
5+
*.log
6+
7+
# OS Files
8+
.DS_Store
9+
Thumbs.db
10+
*.swp
11+
*.swo
12+
*~
13+
14+
# IDE
15+
.vscode/
16+
.idea/
17+
*.sublime-*
18+
19+
# Dependencies
20+
node_modules/
21+
vendor/
22+
.pnp/
23+
.pnp.js
24+
25+
# Environment
26+
.env
27+
.env.local
28+
.env.*.local
29+
secrets.json
30+
credentials.json
31+
32+
# Build outputs
33+
dist/
34+
build/
35+
*.min.js
36+
*.min.css
37+
38+
# Test coverage
39+
coverage/
40+
*.coverage
41+
.nyc_output/
42+
43+
# Temporary files
44+
tmp/
45+
temp/
46+
*.tmp
47+
48+
# Archives
49+
*.zip
50+
*.tar.gz
51+
*.rar

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Your Organization
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)