Skip to content

Commit 8e896e3

Browse files
stbenjamclaude
authored andcommitted
Add marketplace website for AI Helpers plugins
Adds a comprehensive marketplace website to showcase all plugins, commands, and skills in the ai-helpers repository: - Interactive plugin browser with search functionality - Linkable install instructions and plugin details - Copy-to-clipboard install commands for each plugin - Responsive design with dark theme - Auto-generated from plugin metadata via `make update` - Updated linter to verify docs/data.json stays in sync The website is served from docs/ for GitHub Pages deployment. Co-Authored-By: Claude <[email protected]>
1 parent dc1278c commit 8e896e3

File tree

7 files changed

+1532
-11
lines changed

7 files changed

+1532
-11
lines changed

.claudelint-custom.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515

1616

1717
class PluginsDocUpToDateRule(Rule):
18-
"""Check that PLUGINS.md is up-to-date by running 'make update'"""
18+
"""Check that PLUGINS.md and docs/data.json are up-to-date by running 'make update'"""
1919

2020
@property
2121
def rule_id(self) -> str:
2222
return "plugins-doc-up-to-date"
2323

2424
@property
2525
def description(self) -> str:
26-
return "PLUGINS.md must be up-to-date with plugin metadata. Run 'make update' to regenerate."
26+
return "PLUGINS.md and docs/data.json must be up-to-date with plugin metadata. Run 'make update' to regenerate."
2727

2828
def default_severity(self) -> Severity:
2929
return Severity.ERROR
@@ -36,6 +36,8 @@ def check(self, context: RepositoryContext) -> List[RuleViolation]:
3636
return violations
3737

3838
plugins_md_path = context.root_path / "PLUGINS.md"
39+
data_json_path = context.root_path / "docs" / "data.json"
40+
3941
if not plugins_md_path.exists():
4042
return violations
4143

@@ -45,8 +47,9 @@ def check(self, context: RepositoryContext) -> List[RuleViolation]:
4547
return violations
4648

4749
try:
48-
# Read current PLUGINS.md content
49-
original_content = plugins_md_path.read_text()
50+
# Read current content of files to check
51+
original_plugins_md = plugins_md_path.read_text()
52+
original_data_json = data_json_path.read_text() if data_json_path.exists() else None
5053

5154
# Run the docs generation script
5255
result = subprocess.run(
@@ -66,13 +69,31 @@ def check(self, context: RepositoryContext) -> List[RuleViolation]:
6669
)
6770
return violations
6871

69-
# Read the generated PLUGINS.md content
70-
generated_content = plugins_md_path.read_text()
72+
# Also run build-website.py if it exists
73+
website_script_path = context.root_path / "scripts" / "build-website.py"
74+
if website_script_path.exists():
75+
result = subprocess.run(
76+
["python3", str(website_script_path)],
77+
cwd=str(context.root_path),
78+
capture_output=True,
79+
text=True,
80+
timeout=30
81+
)
82+
83+
if result.returncode != 0:
84+
violations.append(
85+
self.violation(
86+
f"build-website.py failed: {result.stderr}",
87+
file_path=data_json_path if data_json_path.exists() else plugins_md_path
88+
)
89+
)
90+
return violations
7191

72-
# Compare
73-
if original_content != generated_content:
92+
# Check if PLUGINS.md changed
93+
generated_plugins_md = plugins_md_path.read_text()
94+
if original_plugins_md != generated_plugins_md:
7495
# Restore original content
75-
plugins_md_path.write_text(original_content)
96+
plugins_md_path.write_text(original_plugins_md)
7697

7798
violations.append(
7899
self.violation(
@@ -81,6 +102,21 @@ def check(self, context: RepositoryContext) -> List[RuleViolation]:
81102
)
82103
)
83104

105+
# Check if docs/data.json changed
106+
if data_json_path.exists():
107+
generated_data_json = data_json_path.read_text()
108+
if original_data_json != generated_data_json:
109+
# Restore original content
110+
if original_data_json is not None:
111+
data_json_path.write_text(original_data_json)
112+
113+
violations.append(
114+
self.violation(
115+
"docs/data.json is out of sync with plugin metadata. Run 'make update' to update.",
116+
file_path=data_json_path
117+
)
118+
)
119+
84120
except subprocess.TimeoutExpired:
85121
violations.append(
86122
self.violation(
@@ -91,7 +127,7 @@ def check(self, context: RepositoryContext) -> List[RuleViolation]:
91127
except Exception as e:
92128
violations.append(
93129
self.violation(
94-
f"Error checking PLUGINS.md up-to-date status: {e}",
130+
f"Error checking files up-to-date status: {e}",
95131
file_path=plugins_md_path
96132
)
97133
)

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ lint-pull: ## Pull the latest claudelint image
2222
$(CONTAINER_RUNTIME) pull $(CLAUDELINT_IMAGE)
2323

2424
.PHONY: update
25-
update: ## Update plugin documentation in PLUGINS.md
25+
update: ## Update plugin documentation and website data
2626
@echo "Updating plugin documentation..."
2727
@python3 scripts/generate_plugin_docs.py
28+
@echo "Building website data..."
29+
@python3 scripts/build-website.py
2830

2931
.DEFAULT_GOAL := help
3032

docs/.nojekyll

Whitespace-only changes.

docs/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# AI Helpers Website
2+
3+
This directory contains the GitHub Pages website for the ai-helpers project.
4+
5+
## Structure
6+
7+
- `index.html` - Main website with plugin browser
8+
- `data.json` - Plugin and command metadata (generated)
9+
- `.nojekyll` - Tells GitHub Pages not to use Jekyll processing
10+
11+
## Building
12+
13+
The website data is generated from the repository structure:
14+
15+
```bash
16+
# From repository root
17+
python3 scripts/build-website.py
18+
```
19+
20+
This extracts information from:
21+
- `.claude-plugin/marketplace.json` - Plugin registry
22+
- `plugins/*/commands/*.md` - Command definitions
23+
- `plugins/*/skills/*/SKILL.md` - Skill definitions
24+
- `plugins/*/.claude-plugin/plugin.json` - Plugin metadata
25+
26+
## Local Development
27+
28+
To test the website locally:
29+
30+
```bash
31+
cd docs
32+
python3 -m http.server 8000
33+
# Visit http://localhost:8000
34+
```
35+
36+
## Deployment
37+
38+
The website is automatically deployed via GitHub Pages from the `docs/` directory.
39+
40+
To enable GitHub Pages:
41+
1. Go to repository Settings > Pages
42+
2. Set Source to "Deploy from a branch"
43+
3. Select branch (e.g., `main`) and `/docs` folder
44+
4. Save
45+
46+
The site will be available at: `https://openshift-eng.github.io/ai-helpers/`
47+
48+
## Updating
49+
50+
When plugins or commands are added/modified:
51+
52+
1. Run `python3 scripts/build-website.py` to regenerate `data.json`
53+
2. Commit both `data.json` and any changes
54+
3. Push to trigger GitHub Pages rebuild
55+
56+
Alternatively, set up a GitHub Action to automatically rebuild on changes.

0 commit comments

Comments
 (0)