diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..c8060bb --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,101 @@ +{ + "name": "claude-code-showcase", + "description": "A curated collection of Claude Code skills, commands, agents, and automation hooks. Production-ready patterns for React, TypeScript, testing, and CI/CD workflows.", + "owner": { + "name": "aviadr1", + "url": "https://github.com/aviadr1/claude-code-showcase" + }, + "plugins": [ + { + "name": "testing-patterns", + "source": "./plugins/testing-patterns", + "description": "Jest testing patterns, factory functions, mocking strategies, and TDD workflow.", + "version": "1.0.0", + "keywords": ["testing", "jest", "tdd", "mocking"] + }, + { + "name": "systematic-debugging", + "source": "./plugins/systematic-debugging", + "description": "Four-phase debugging methodology with root cause analysis.", + "version": "1.0.0", + "keywords": ["debugging", "troubleshooting", "root-cause"] + }, + { + "name": "react-ui-patterns", + "source": "./plugins/react-ui-patterns", + "description": "Modern React UI patterns for loading states, error handling, and data fetching.", + "version": "1.0.0", + "keywords": ["react", "ui", "loading-states", "hooks"] + }, + { + "name": "formik-patterns", + "source": "./plugins/formik-patterns", + "description": "Formik form handling with validation patterns.", + "version": "1.0.0", + "keywords": ["formik", "forms", "validation"] + }, + { + "name": "graphql-schema", + "source": "./plugins/graphql-schema", + "description": "GraphQL queries, mutations, and code generation patterns.", + "version": "1.0.0", + "keywords": ["graphql", "apollo", "codegen"] + }, + { + "name": "core-components", + "source": "./plugins/core-components", + "description": "Core component library and design system patterns.", + "version": "1.0.0", + "keywords": ["components", "design-system", "tokens"] + }, + { + "name": "pr-toolkit", + "source": "./plugins/pr-toolkit", + "description": "Complete PR workflow toolkit with review commands and git workflow agent.", + "version": "1.0.0", + "keywords": ["pr", "github", "git", "review"] + }, + { + "name": "code-review-suite", + "source": "./plugins/code-review-suite", + "description": "Comprehensive code review with quality checks agent and command.", + "version": "1.0.0", + "keywords": ["code-review", "quality", "linting"] + }, + { + "name": "ticket-workflow", + "source": "./plugins/ticket-workflow", + "description": "End-to-end ticket workflow for JIRA/Linear integration.", + "version": "1.0.0", + "keywords": ["jira", "linear", "tickets", "workflow"] + }, + { + "name": "docs-sync", + "source": "./plugins/docs-sync", + "description": "Documentation synchronization command.", + "version": "1.0.0", + "keywords": ["documentation", "docs", "sync"] + }, + { + "name": "skill-activation", + "source": "./plugins/skill-activation", + "description": "Intelligent skill suggestion system based on prompt analysis.", + "version": "1.0.0", + "keywords": ["skills", "automation", "hooks"] + }, + { + "name": "plugin-marketplace", + "source": "./plugins/plugin-marketplace", + "description": "Create a Claude Code plugin marketplace from existing components using symlinks.", + "version": "1.0.0", + "keywords": ["marketplace", "plugins", "symlinks", "distribution"] + }, + { + "name": "github-actions", + "source": "./plugins/github-actions", + "description": "Showcase GitHub Actions workflows for Claude Code CI/CD automation.", + "version": "1.0.0", + "keywords": ["github-actions", "ci-cd", "workflows", "automation", "pr-review"] + } + ] +} diff --git a/.claude/commands/setup-github-actions.md b/.claude/commands/setup-github-actions.md new file mode 100644 index 0000000..9b55af6 --- /dev/null +++ b/.claude/commands/setup-github-actions.md @@ -0,0 +1,130 @@ +--- +description: Set up Claude Code GitHub Actions workflows in your repository +allowed-tools: Read, Write, Bash(mkdir:*), Bash(ls:*), AskUserQuestion +--- + +# Setup GitHub Actions for Claude Code + +Help the user set up showcase Claude Code GitHub Actions workflows in their repository. + +## Available Workflows + +| Workflow | Stack | Description | +|----------|-------|-------------| +| **PR Review** | Any | Automatically review pull requests with Claude | +| **Documentation Sync** | Any | Keep docs in sync with code changes | +| **Node.js Code Quality** | Node.js | Periodic code quality audits (requires npm) | +| **Node.js Dependency Audit** | Node.js | Check for outdated/vulnerable dependencies (requires npm) | + +## Your Tasks + +1. **Ask which workflows to set up:** + Use AskUserQuestion to ask which workflows they want: + - PR Review (recommended for all projects, works with any language) + - Documentation Sync (works with any language) + - Node.js Code Quality (Node.js projects only) + - Node.js Dependency Audit (Node.js projects only) + +2. **Check prerequisites:** + - Verify `.github/workflows/` directory exists (create if needed) + - Check if ANTHROPIC_API_KEY secret reminder is needed + +3. **For each selected workflow, create the caller workflow:** + +### PR Review Workflow +```yaml +name: Claude PR Review + +on: + pull_request: + issue_comment: + types: [created] + +permissions: + contents: read + pull-requests: write + issues: read + +jobs: + review: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-pr-review.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +### Documentation Sync Workflow +```yaml +name: Monthly Documentation Sync + +on: + schedule: + - cron: '0 9 1 * *' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + sync: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-docs-sync.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +### Code Quality Workflow +```yaml +name: Weekly Code Quality Review + +on: + schedule: + - cron: '0 8 * * 0' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + quality: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-nodejs-code-quality.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +### Dependency Audit Workflow +```yaml +name: Bi-weekly Dependency Audit + +on: + schedule: + - cron: '0 10 1,15 * *' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + audit: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-nodejs-dependency-audit.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +4. **Remind about secrets:** + Tell the user to add `ANTHROPIC_API_KEY` to their repository secrets: + - Go to Settings → Secrets and variables → Actions + - Click "New repository secret" + - Name: `ANTHROPIC_API_KEY` + - Value: Their Anthropic API key + +5. **Offer customization:** + Ask if they want to customize any inputs (model, timeout, schedule, etc.) + +## Guidelines + +- Create workflows in `.github/workflows/` directory +- Use descriptive filenames like `claude-pr-review.yml` +- Don't overwrite existing workflows without asking +- Remind about the API key secret requirement diff --git a/.claude/settings.json b/.claude/settings.json index 976575d..9cd7007 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,10 +1,10 @@ { - "includeCoAuthoredBy": true, "env": { "INSIDE_CLAUDE_CODE": "1", "BASH_DEFAULT_TIMEOUT_MS": "420000", "BASH_MAX_TIMEOUT_MS": "420000" }, + "includeCoAuthoredBy": true, "hooks": { "UserPromptSubmit": [ { @@ -71,5 +71,11 @@ ] } ] + }, + "enabledPlugins": { + "context7@claude-plugins-official": true, + "github@claude-plugins-official": true, + "plugin-dev@claude-plugins-official": true, + "hookify@claude-plugins-official": true } } diff --git a/.claude/skills/github-actions/SKILL.md b/.claude/skills/github-actions/SKILL.md new file mode 100644 index 0000000..eb0a823 --- /dev/null +++ b/.claude/skills/github-actions/SKILL.md @@ -0,0 +1,316 @@ +# GitHub Actions for Claude Code + +Reusable GitHub Actions workflows that integrate Claude Code into your CI/CD pipeline. + +## How It Works + +These are **reusable workflows** (using GitHub's `workflow_call` trigger). You don't copy them—you **call them** from your own repository using a simple caller workflow: + +```yaml +# In YOUR repository: .github/workflows/claude-pr-review.yml +jobs: + review: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-pr-review.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +**Quick setup:** Run `/setup-github-actions` in Claude Code to interactively create caller workflows. + +--- + +## Workflow Compatibility + +| Workflow | Stack | Notes | +|----------|-------|-------| +| [PR Review](#1-pr-review) | **Any** | Language-agnostic, uses git only | +| [Docs Sync](#2-documentation-sync) | **Any** | Language-agnostic, uses git only | +| [Code Quality](#3-code-quality-review) | **Node.js** | Requires npm, configurable lint command | +| [Dependency Audit](#4-dependency-audit) | **Node.js** | Requires npm for dependency management | + +--- + +## Generic Workflows (Any Stack) + +### 1. PR Review (`showcase-pr-review.yml`) + +**Stack: Any** - Uses only git commands, works with any language. + +Automatically reviews pull requests using Claude Code. + +**Triggers on:** +- Pull request opened/synchronized +- Issue comments mentioning `@claude` + +**Usage:** +```yaml +name: Claude PR Review + +on: + pull_request: + issue_comment: + types: [created] + +jobs: + review: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-pr-review.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + with: + model: 'opus' # Optional, auto-updates to latest Opus + timeout_minutes: 30 # Optional +``` + +**Inputs:** +| Input | Type | Default | Description | +|-------|------|---------|-------------| +| `model` | string | `opus` | Claude model alias (`opus`, `sonnet`, `haiku`) | +| `timeout_minutes` | number | `30` | Timeout in minutes | +| `review_prompt` | string | (built-in) | Custom review prompt | + +--- + +### 2. Documentation Sync (`showcase-docs-sync.yml`) + +**Stack: Any** - Uses only git commands, works with any language. + +Periodically checks if documentation is out of sync with code changes. + +**Usage:** +```yaml +name: Monthly Docs Sync + +on: + schedule: + - cron: '0 9 1 * *' # 1st of each month + workflow_dispatch: + +jobs: + sync: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-docs-sync.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + with: + days_back: 30 + code_patterns: '*.py *.go *.rs' # Customize for your stack + docs_paths: 'docs/ README.md' +``` + +**Inputs:** +| Input | Type | Default | Description | +|-------|------|---------|-------------| +| `model` | string | `opus` | Claude model alias | +| `timeout_minutes` | number | `60` | Timeout | +| `days_back` | number | `30` | Days to look back for changes | +| `base_branch` | string | `main` | Base branch for PRs | +| `code_patterns` | string | `*.ts *.tsx *.js *.jsx` | File patterns to check (customize for your stack) | +| `docs_paths` | string | `docs/ README.md` | Documentation paths | +| `custom_prompt` | string | (built-in) | Custom prompt | + +**Stack-specific `code_patterns` examples:** +- **Python**: `*.py` +- **Go**: `*.go` +- **Rust**: `*.rs` +- **Java**: `*.java` +- **Ruby**: `*.rb` + +--- + +## Node.js Workflows + +### 3. Code Quality Review (`showcase-nodejs-code-quality.yml`) + +**Stack: Node.js** - Requires `npm` and a `package.json` with lint scripts. + +Periodically reviews random directories for code quality issues and creates fix PRs. + +**Requirements:** +- Node.js project with `package.json` +- Lint script defined (e.g., `npm run lint`) + +**Usage:** +```yaml +name: Weekly Code Quality + +on: + schedule: + - cron: '0 8 * * 0' # Every Sunday + workflow_dispatch: + +jobs: + quality: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-nodejs-code-quality.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + with: + num_dirs: 3 + source_dir: 'src' + file_extensions: '.ts .tsx' + lint_command: 'npm run lint' +``` + +**Inputs:** +| Input | Type | Default | Description | +|-------|------|---------|-------------| +| `model` | string | `opus` | Claude model alias | +| `timeout_minutes` | number | `45` | Timeout per directory | +| `num_dirs` | number | `3` | Directories to review | +| `source_dir` | string | `src` | Source directory | +| `base_branch` | string | `main` | Base branch for PRs | +| `file_extensions` | string | `.ts .tsx` | Extensions to review | +| `lint_command` | string | `npm run lint` | Lint command | +| `review_checklist_path` | string | `.claude/agents/code-reviewer.md` | Checklist path | +| `custom_prompt` | string | (built-in) | Custom prompt | + +--- + +### 4. Dependency Audit (`showcase-nodejs-dependency-audit.yml`) + +**Stack: Node.js** - Requires `npm` for dependency management. + +Periodically audits dependencies for updates and security vulnerabilities. + +**Requirements:** +- Node.js project with `package.json` and `package-lock.json` +- Test script defined (e.g., `npm test`) + +**Usage:** +```yaml +name: Bi-weekly Dependency Audit + +on: + schedule: + - cron: '0 10 1,15 * *' # 1st and 15th + workflow_dispatch: + +jobs: + audit: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-nodejs-dependency-audit.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + with: + node_version: '20' + lint_command: 'npm run lint' + test_command: 'npm test' +``` + +**Inputs:** +| Input | Type | Default | Description | +|-------|------|---------|-------------| +| `model` | string | `opus` | Claude model alias | +| `timeout_minutes` | number | `45` | Timeout | +| `base_branch` | string | `main` | Base branch for PRs | +| `node_version` | string | `20` | Node.js version | +| `lint_command` | string | `npm run lint` | Lint command | +| `test_command` | string | `npm test` | Test command | +| `custom_prompt` | string | (built-in) | Custom prompt | + +--- + +## Adapting for Other Stacks + +### Python Projects + +The Node.js workflows can be adapted for Python. Here's a guide: + +**Code Quality (Python adaptation):** +```yaml +# Create your own workflow based on showcase-nodejs-code-quality.yml +# Replace npm steps with: +- name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + +- name: Install dependencies + run: pip install -r requirements.txt + +# Change lint_command to: 'ruff check .' or 'flake8' +``` + +**Dependency Audit (Python adaptation):** +```yaml +# Use pip-audit instead of npm audit +- name: Check dependencies + run: | + pip install pip-audit + pip-audit --json > /tmp/audit.json +``` + +### Go Projects + +**Code Quality (Go adaptation):** +```yaml +- name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + +# Change lint_command to: 'golangci-lint run' +# Change file_extensions to: '.go' +``` + +### Rust Projects + +**Code Quality (Rust adaptation):** +```yaml +- name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + +# Change lint_command to: 'cargo clippy -- -D warnings' +# Change file_extensions to: '.rs' +``` + +--- + +## Setup Requirements + +### 1. Add Anthropic API Key + +Add `ANTHROPIC_API_KEY` to your repository secrets: +1. Go to Settings → Secrets and variables → Actions +2. Click "New repository secret" +3. Name: `ANTHROPIC_API_KEY` +4. Value: Your Anthropic API key + +### 2. Configure Permissions + +Ensure your workflow has appropriate permissions: +```yaml +permissions: + contents: write # For creating branches + pull-requests: write # For creating PRs + issues: read # For reading issue comments (PR review) +``` + +### 3. Allow Workflow Calls (for reusable workflows) + +If your repository is private, you may need to allow workflow calls from other repositories in Settings → Actions → General. + +--- + +## Model Aliases + +All workflows use auto-updating model aliases: + +| Alias | Description | +|-------|-------------| +| `opus` | Latest Claude Opus (best for complex analysis) | +| `sonnet` | Latest Claude Sonnet (balanced speed/quality) | +| `haiku` | Latest Claude Haiku (fastest, most economical) | + +--- + +## Quick Start + +Run `/setup-github-actions` to interactively set up these workflows in your repository. + +--- + +## Best Practices + +1. **Start with PR Review** - Works with any stack, immediate value +2. **Use generic workflows first** - PR Review and Docs Sync work everywhere +3. **Customize `code_patterns`** - Match your project's file extensions +4. **Fork for other stacks** - Use Node.js workflows as templates for Python/Go/Rust +5. **Set appropriate timeouts** - Complex codebases may need longer timeouts diff --git a/.claude/skills/plugin-marketplace/SKILL.md b/.claude/skills/plugin-marketplace/SKILL.md new file mode 100644 index 0000000..b477b11 --- /dev/null +++ b/.claude/skills/plugin-marketplace/SKILL.md @@ -0,0 +1,543 @@ +--- +name: plugin-marketplace +description: Create a Claude Code plugin marketplace from existing skills, commands, agents, and hooks using symlinks. Use when converting a showcase repo to an installable marketplace, or when you need to share Claude Code components with others. +--- + +# Plugin Marketplace Pattern + +Transform a showcase repository into an installable Claude Code plugin marketplace while maintaining a single source of truth using symlinks. + +## When to Use + +- Converting existing `.claude/` components to installable plugins +- Creating a shareable marketplace from your team's patterns +- Maintaining both showcase documentation and installable packages +- Enabling `git pull` updates to flow through to installed plugins + +## Architecture + +``` +your-repo/ +├── .claude/ # Source of truth (showcase structure) +│ ├── skills/ +│ │ └── testing-patterns/ +│ │ └── SKILL.md +│ ├── commands/ +│ │ └── pr-review.md +│ └── agents/ +│ └── code-reviewer.md +│ +├── .claude-plugin/ # Marketplace manifest +│ └── marketplace.json +│ +└── plugins/ # Plugin packages (symlinks) + ├── testing-patterns/ + │ ├── .claude-plugin/ + │ │ └── plugin.json # Real file + │ └── skills/ + │ └── testing-patterns/ # Symlink → ../../../.claude/skills/testing-patterns + └── code-review-suite/ + ├── .claude-plugin/ + │ └── plugin.json + ├── commands/ # Symlink to specific files + └── agents/ # Symlink to specific files +``` + +## Step-by-Step Implementation + +### 1. Create Marketplace Manifest + +Create `.claude-plugin/marketplace.json` at repo root: + +```json +{ + "name": "your-marketplace-name", + "description": "Description of your marketplace", + "owner": { + "name": "Your Name or Org", + "url": "https://github.com/you/repo" + }, + "plugins": [ + { + "name": "plugin-name", + "source": "./plugins/plugin-name", + "description": "What this plugin does", + "version": "1.0.0", + "keywords": ["keyword1", "keyword2"] + } + ] +} +``` + +### 2. Create Plugin Structure with Symlinks + +For each plugin: + +```bash +# Create plugin directory +mkdir -p plugins/testing-patterns/.claude-plugin +mkdir -p plugins/testing-patterns/skills + +# Create symlink to source skill +ln -s ../../../.claude/skills/testing-patterns plugins/testing-patterns/skills/testing-patterns +``` + +### 3. Create Plugin Manifest + +Each plugin needs `.claude-plugin/plugin.json`: + +```json +{ + "name": "testing-patterns", + "version": "1.0.0", + "description": "Jest testing patterns, TDD workflow", + "keywords": ["testing", "jest", "tdd"], + "skills": "./skills/" +} +``` + +### 4. Bundle Related Components + +For plugins with multiple components: + +```bash +# Create bundle plugin +mkdir -p plugins/code-review-suite/{.claude-plugin,commands,agents} + +# Symlink individual files +ln -s ../../../.claude/commands/code-quality.md plugins/code-review-suite/commands/code-quality.md +ln -s ../../../.claude/agents/code-reviewer.md plugins/code-review-suite/agents/code-reviewer.md +``` + +## Plugin.json Component Fields + +| Field | Type | Description | +|-------|------|-------------| +| `skills` | string | Path to skills directory | +| `commands` | string/array | Path to commands or array of specific files | +| `agents` | string | Path to agents directory | +| `hooks` | string | Path to hooks JSON configuration | +| `mcpServers` | string | Path to MCP configuration | + +## User Installation + +Once structured, users install from your marketplace: + +```bash +# Add your marketplace +/plugin marketplace add owner/repo-name + +# Install specific plugins +/plugin install testing-patterns@repo-name +/plugin install code-review-suite@repo-name +``` + +## Why Symlinks Work + +1. **Claude Code honors symlinks** when copying plugins to cache +2. **Single source of truth** - edits in `.claude/` flow to plugins +3. **Git pull updates** - pulling changes automatically updates symlinked content +4. **No build step** - no sync scripts or generated files needed + +## Validation Script + +Optional: Add a script to verify symlinks are intact: + +```bash +#!/bin/bash +# scripts/validate-symlinks.sh + +errors=0 +for link in $(find plugins -type l); do + if [ ! -e "$link" ]; then + echo "Broken symlink: $link" + errors=$((errors + 1)) + fi +done + +if [ $errors -eq 0 ]; then + echo "All symlinks valid" + exit 0 +else + echo "$errors broken symlinks found" + exit 1 +fi +``` + +## Anti-Patterns + +### Don't Duplicate Content + +```bash +# Bad - copying files +cp .claude/skills/testing-patterns plugins/testing-patterns/skills/ + +# Good - symlinking +ln -s ../../../.claude/skills/testing-patterns plugins/testing-patterns/skills/testing-patterns +``` + +### Don't Use Absolute Paths + +```bash +# Bad - breaks on other machines +ln -s /home/user/repo/.claude/skills/testing-patterns plugins/testing-patterns/skills/ + +# Good - relative paths +ln -s ../../../.claude/skills/testing-patterns plugins/testing-patterns/skills/testing-patterns +``` + +## Integration with Git + +Symlinks are tracked by Git, so: +- Collaborators get the same structure +- CI/CD can validate the marketplace +- Pull requests can update both source and plugin structure + +## Updating Versions + +When updating a plugin version: +1. Update version in `.claude-plugin/marketplace.json` +2. Update version in `plugins/{name}/.claude-plugin/plugin.json` +3. Source content updates flow automatically via symlinks + +## Auditing Atoms Coverage + +"Atoms" are the fundamental units in Claude Code: **skills**, **commands**, **agents**, and **hooks**. Use this audit process to ensure all atoms in your `.claude/` directory are exposed as installable plugins. + +### Audit Script + +Create `scripts/audit-atoms.sh` to check coverage: + +```bash +#!/bin/bash +# Audits whether all atoms in .claude/ are exposed in plugins/ + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +echo "=== Atom Coverage Audit ===" +echo "" + +missing=0 + +# Audit Skills +echo "Skills:" +for skill_dir in "$REPO_ROOT"/.claude/skills/*/; do + skill_name=$(basename "$skill_dir") + [ "$skill_name" = "README.md" ] && continue + + # Check if this skill is symlinked in any plugin + found=$(find "$REPO_ROOT/plugins" -type l -name "$skill_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $skill_name" + else + echo " ✗ $skill_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Commands +echo "Commands:" +for cmd_file in "$REPO_ROOT"/.claude/commands/*.md; do + cmd_name=$(basename "$cmd_file") + + found=$(find "$REPO_ROOT/plugins" -type l -name "$cmd_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $cmd_name" + else + echo " ✗ $cmd_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Agents +echo "Agents:" +for agent_file in "$REPO_ROOT"/.claude/agents/*.md; do + agent_name=$(basename "$agent_file") + + found=$(find "$REPO_ROOT/plugins" -type l -name "$agent_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $agent_name" + else + echo " ✗ $agent_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Hooks (check for any hook files) +echo "Hooks:" +hook_files=$(find "$REPO_ROOT"/.claude/hooks -type f \( -name "*.sh" -o -name "*.js" -o -name "*.json" \) 2>/dev/null) +if [ -n "$hook_files" ]; then + hooks_in_plugin=$(find "$REPO_ROOT/plugins" -path "*/hooks/*" -type l 2>/dev/null | head -1) + if [ -n "$hooks_in_plugin" ]; then + echo " ✓ Hook system exposed in plugins" + else + echo " ✗ Hook system NOT exposed in plugins" + missing=$((missing + 1)) + fi +fi + +echo "" +echo "=== Summary ===" +if [ $missing -eq 0 ]; then + echo "All atoms are exposed in plugins!" + exit 0 +else + echo "$missing atom(s) missing from plugins" + exit 1 +fi +``` + +### Running the Audit + +```bash +chmod +x scripts/audit-atoms.sh +./scripts/audit-atoms.sh +``` + +Example output: +``` +=== Atom Coverage Audit === + +Skills: + ✓ testing-patterns + ✓ react-ui-patterns + ✗ new-skill (NOT IN ANY PLUGIN) + +Commands: + ✓ pr-review.md + ✓ ticket.md + +Agents: + ✓ code-reviewer.md + +Hooks: + ✓ Hook system exposed in plugins + +=== Summary === +1 atom(s) missing from plugins +``` + +### Integrating with CI + +Add to your GitHub Actions workflow: + +```yaml +- name: Audit atom coverage + run: ./scripts/audit-atoms.sh +``` + +### Quick Manual Check + +To quickly see what's in `.claude/` vs what's symlinked: + +```bash +# List all atoms in .claude/ +echo "=== Skills ===" && ls .claude/skills/ +echo "=== Commands ===" && ls .claude/commands/ +echo "=== Agents ===" && ls .claude/agents/ +echo "=== Hooks ===" && ls .claude/hooks/ + +# List all symlinks in plugins/ +find plugins -type l | sort +``` + +### When Atoms Are Missing + +If the audit finds missing atoms: + +1. **Decide on packaging**: Should it be standalone or bundled? +2. **Create the plugin structure**: + ```bash + mkdir -p plugins/new-skill/{.claude-plugin,skills} + ln -s ../../../.claude/skills/new-skill plugins/new-skill/skills/new-skill + ``` +3. **Add plugin.json manifest** +4. **Update marketplace.json** +5. **Re-run the audit** to verify + +## Content Change Tracking with Git + +Use git to detect which atoms have changed since the last release. This is simpler and more reliable than maintaining separate checksum files. + +### Version Tagging Strategy + +Tag releases to mark version boundaries: + +```bash +# Tag a marketplace release +git tag -a v1.0.0 -m "Initial marketplace release" + +# Tag individual plugin releases (optional, for granular tracking) +git tag -a testing-patterns/v1.0.0 -m "testing-patterns v1.0.0" +``` + +### Check Changes Since Last Release + +Create `scripts/check-atom-changes.sh`: + +```bash +#!/bin/bash +# Detects which atoms have changed since the last release tag +# Usage: ./scripts/check-atom-changes.sh [base-ref] +# base-ref: git ref to compare against (default: latest tag) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +# Get base reference (default to latest tag) +BASE_REF="${1:-$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")}" + +echo "=== Atom Changes Since $BASE_REF ===" +echo "" + +changes=0 + +check_changes() { + local atom_type="$1" + local atom_path="$2" + local atom_name="$3" + + # Check if path has changes since base ref + if git diff --quiet "$BASE_REF" -- "$atom_path" 2>/dev/null; then + echo " ✓ $atom_name (unchanged)" + else + echo " CHANGED: $atom_name" + # Show brief summary of changes + local lines_changed=$(git diff --stat "$BASE_REF" -- "$atom_path" 2>/dev/null | tail -1) + [ -n "$lines_changed" ] && echo " $lines_changed" + changes=$((changes + 1)) + fi +} + +# Check skills +echo "Skills:" +for skill_dir in "$REPO_ROOT"/.claude/skills/*/; do + [ ! -d "$skill_dir" ] && continue + skill_name=$(basename "$skill_dir") + check_changes "skill" "$skill_dir" "$skill_name" +done + +echo "" + +# Check commands +echo "Commands:" +for cmd_file in "$REPO_ROOT"/.claude/commands/*.md; do + [ ! -f "$cmd_file" ] && continue + cmd_name=$(basename "$cmd_file" .md) + check_changes "command" "$cmd_file" "$cmd_name" +done + +echo "" + +# Check agents +echo "Agents:" +for agent_file in "$REPO_ROOT"/.claude/agents/*.md; do + [ ! -f "$agent_file" ] && continue + agent_name=$(basename "$agent_file" .md) + check_changes "agent" "$agent_file" "$agent_name" +done + +echo "" + +# Check hooks +echo "Hooks:" +hooks_dir="$REPO_ROOT/.claude/hooks" +if [ -d "$hooks_dir" ]; then + if git diff --quiet "$BASE_REF" -- "$hooks_dir" 2>/dev/null; then + echo " ✓ hooks (unchanged)" + else + echo " CHANGED: hooks" + changes=$((changes + 1)) + fi +fi + +echo "" +echo "=== Summary ===" +echo "Comparing against: $BASE_REF" +if [ $changes -eq 0 ]; then + echo "No atoms have changed" + exit 0 +else + echo "$changes atom(s) changed - consider version bump for affected plugins" + echo "" + echo "To see full diff for a specific atom:" + echo " git diff $BASE_REF -- .claude/skills/SKILL_NAME/" + exit 1 +fi +``` + +### View Detailed Changes + +```bash +# See what changed in a specific skill since last release +git diff v1.0.0 -- .claude/skills/testing-patterns/ + +# See commit history for a skill +git log --oneline v1.0.0..HEAD -- .claude/skills/testing-patterns/ + +# See which files changed in an atom +git diff --name-only v1.0.0 -- .claude/skills/testing-patterns/ +``` + +### Workflow + +1. **Before releasing**, check what changed: + ```bash + ./scripts/check-atom-changes.sh + # Or compare against a specific version: + ./scripts/check-atom-changes.sh v1.0.0 + ``` + +2. **For changed atoms**, bump version in: + - `plugins/{name}/.claude-plugin/plugin.json` + - `.claude-plugin/marketplace.json` + +3. **Tag the release**: + ```bash + git tag -a v1.1.0 -m "Release v1.1.0" + git push --tags + ``` + +### CI Integration + +```yaml +- name: Check for unreleased changes + run: | + # Fail if atoms changed since last tag but versions weren't bumped + ./scripts/check-atom-changes.sh +``` + +### Why Git-Based Tracking is Better + +| Aspect | Checksum File | Git-Based | +|--------|---------------|-----------| +| Extra files to maintain | Yes | No | +| Shows what changed | Hash only | Full diff | +| History | None | Complete | +| Can get out of sync | Yes | No | +| Works offline | Yes | Yes | +| Native to workflow | No | Yes | + +### Quick Commands + +```bash +# What changed since last tag? +git diff $(git describe --tags --abbrev=0) -- .claude/ + +# List commits touching a specific skill +git log --oneline -- .claude/skills/testing-patterns/ + +# Find which release introduced a change +git log --tags --oneline -- .claude/skills/testing-patterns/SKILL.md +``` diff --git a/.github/workflows/pr-claude-code-review.yml b/.github/workflows/pr-claude-code-review.yml index dc724c0..9dfde87 100644 --- a/.github/workflows/pr-claude-code-review.yml +++ b/.github/workflows/pr-claude-code-review.yml @@ -14,6 +14,7 @@ permissions: contents: read pull-requests: write issues: read + id-token: write jobs: review: @@ -62,14 +63,12 @@ jobs: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} model: claude-opus-4-5-20251101 timeout_minutes: 30 - track_progress: true - prompt: | + max_turns: 10 + allowed_tools: "Read,Glob,Grep,Bash(git:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + direct_prompt: | Review this Pull Request using the standards in .claude/agents/code-reviewer.md 1. Read .claude/agents/code-reviewer.md for the full checklist 2. Run `git diff origin/${{ steps.pr-info.outputs.base_ref }}...HEAD` to see changes 3. Apply the review checklist to modified files 4. Provide feedback organized by severity (Critical, Warning, Suggestion) - claude_args: | - --max-turns 10 - --allowedTools "Read,Glob,Grep,Bash(git:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" diff --git a/.github/workflows/scheduled-claude-code-dependency-audit.yml b/.github/workflows/scheduled-claude-code-dependency-audit.yml index 6142266..006453d 100644 --- a/.github/workflows/scheduled-claude-code-dependency-audit.yml +++ b/.github/workflows/scheduled-claude-code-dependency-audit.yml @@ -13,6 +13,7 @@ concurrency: permissions: contents: write pull-requests: write + id-token: write jobs: dependency-audit: @@ -70,8 +71,9 @@ jobs: timeout_minutes: 45 base_branch: main branch_prefix: claude/deps-update- - track_progress: true - prompt: | + max_turns: 40 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(npm:*)" + direct_prompt: | # Dependency Audit You are running a scheduled dependency audit. @@ -105,9 +107,6 @@ jobs: - If tests fail after an update, revert that update - Group related updates together - If NO updates are possible, report that and don't create a PR - claude_args: | - --max-turns 40 - --allowedTools "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(npm:*)" - name: Report no updates needed if: steps.check-outdated.outputs.has_outdated == 'false' && steps.security-audit.outputs.vulnerabilities == '0' diff --git a/.github/workflows/scheduled-claude-code-docs-sync.yml b/.github/workflows/scheduled-claude-code-docs-sync.yml index a75255b..5f5b67d 100644 --- a/.github/workflows/scheduled-claude-code-docs-sync.yml +++ b/.github/workflows/scheduled-claude-code-docs-sync.yml @@ -18,6 +18,7 @@ concurrency: permissions: contents: write pull-requests: write + id-token: write jobs: docs-sync: @@ -64,8 +65,9 @@ jobs: timeout_minutes: 60 base_branch: main branch_prefix: claude/docs-sync- - track_progress: true - prompt: | + max_turns: 30 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*)" + direct_prompt: | # Monthly Documentation Sync You are running a scheduled documentation sync. Code has changed since ${{ steps.check-changes.outputs.since_date }}. @@ -105,9 +107,6 @@ jobs: - DO NOT add changelog-style entries - ONLY update docs when they are incorrect or misleading - If no problems are found, report that and DO NOT create a PR - claude_args: | - --max-turns 30 - --allowedTools "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*)" - name: Report no changes if: steps.check-changes.outputs.has_changes == 'false' diff --git a/.github/workflows/scheduled-claude-code-quality.yml b/.github/workflows/scheduled-claude-code-quality.yml index 1afd88a..ce28bd4 100644 --- a/.github/workflows/scheduled-claude-code-quality.yml +++ b/.github/workflows/scheduled-claude-code-quality.yml @@ -18,6 +18,7 @@ concurrency: permissions: contents: write pull-requests: write + id-token: write jobs: select-directories: @@ -90,8 +91,9 @@ jobs: timeout_minutes: 45 base_branch: main branch_prefix: claude/code-quality- - track_progress: true - prompt: | + max_turns: 35 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(npm run lint*)" + direct_prompt: | # Weekly Code Quality Review You are performing a scheduled code quality review of a specific directory. @@ -136,9 +138,6 @@ jobs: - Fix issues that are clear improvements - Don't refactor working code just for style - If no issues found, report that and skip PR creation - claude_args: | - --max-turns 35 - --allowedTools "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(npm run lint*)" report-completion: needs: [select-directories, review-directory] diff --git a/.github/workflows/showcase-docs-sync.yml b/.github/workflows/showcase-docs-sync.yml new file mode 100644 index 0000000..0690633 --- /dev/null +++ b/.github/workflows/showcase-docs-sync.yml @@ -0,0 +1,152 @@ +name: Showcase - Claude Documentation Sync + +on: + workflow_call: + inputs: + model: + description: 'Claude model to use' + required: false + type: string + default: 'opus' + timeout_minutes: + description: 'Timeout in minutes' + required: false + type: number + default: 60 + days_back: + description: 'Number of days to look back for changes' + required: false + type: number + default: 30 + base_branch: + description: 'Base branch for PRs' + required: false + type: string + default: 'main' + code_patterns: + description: 'File patterns to check for changes (space-separated globs)' + required: false + type: string + default: '*.ts *.tsx *.js *.jsx' + docs_paths: + description: 'Documentation paths to update (space-separated)' + required: false + type: string + default: 'docs/ README.md' + custom_prompt: + description: 'Custom prompt (optional, uses default if not provided)' + required: false + type: string + default: '' + secrets: + ANTHROPIC_API_KEY: + required: true + +permissions: + contents: write + pull-requests: write + id-token: write + +jobs: + docs-sync: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check for code changes in period + id: check-changes + run: | + DAYS_BACK="${{ inputs.days_back }}" + SINCE_DATE=$(date -d "-${DAYS_BACK} days" +%Y-%m-%d) + + echo "Checking for changes since: $SINCE_DATE" + + # Build glob patterns for git log + PATTERNS="${{ inputs.code_patterns }}" + GIT_ARGS="" + for pattern in $PATTERNS; do + GIT_ARGS="$GIT_ARGS $pattern" + done + + # Get changed code files (excluding tests) + CHANGED_FILES=$(git log --since="$SINCE_DATE" --name-only --pretty=format: -- \ + $GIT_ARGS \ + ':!*.test.*' ':!*.spec.*' ':!*.stories.*' \ + | sort -u | grep -v '^$' | head -100) + + if [ -z "$CHANGED_FILES" ]; then + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "No code changes found in the last $DAYS_BACK days" + else + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "changed_files<> $GITHUB_OUTPUT + echo "$CHANGED_FILES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "Found $(echo "$CHANGED_FILES" | wc -l) changed files" + fi + + echo "since_date=$SINCE_DATE" >> $GITHUB_OUTPUT + + - name: Claude Documentation Sync + if: steps.check-changes.outputs.has_changes == 'true' + uses: anthropics/claude-code-action@beta + env: + SINCE_DATE: ${{ steps.check-changes.outputs.since_date }} + CHANGED_FILES: ${{ steps.check-changes.outputs.changed_files }} + DOCS_PATHS: ${{ inputs.docs_paths }} + BASE_BRANCH: ${{ inputs.base_branch }} + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + model: ${{ inputs.model }} + timeout_minutes: ${{ inputs.timeout_minutes }} + base_branch: ${{ inputs.base_branch }} + branch_prefix: claude/docs-sync- + max_turns: 30 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*)" + direct_prompt: ${{ inputs.custom_prompt != '' && inputs.custom_prompt || ' + # Documentation Sync + + You are running a documentation sync. Check the environment variables for context: + - SINCE_DATE: Date to check changes from + - CHANGED_FILES: List of modified code files + - DOCS_PATHS: Documentation paths to update + - BASE_BRANCH: Branch to create PRs against + + ## Your Tasks + + 1. **Read the changed files list** from the CHANGED_FILES environment variable + + 2. **Analyze Changes**: Review the changed files to understand what functionality was added, modified, or removed. + + 3. **Find Related Documentation**: Search for documentation in the paths specified by DOCS_PATHS. + + 4. **Check for Actual Problems**: For each code change, determine if existing docs are now WRONG: + - Do code examples still work? + - Are API signatures/types now incorrect? + - Are prop interfaces outdated? + + 5. **Fix Only What is Broken**: If you find documentation that is actually wrong: + - Fix incorrect code examples + - Update wrong API signatures and types + - Add docs ONLY for significant new features that have zero documentation + + 6. **Create a PR**: If you made any changes: + - Create a new branch from the BASE_BRANCH + - Commit all documentation updates + - Create a PR with a summary of what was fixed + + ## CRITICAL Guidelines + - Documentation is a LIVING DOCUMENT - only fix things that are actually WRONG + - DO NOT add changelog-style entries + - ONLY update docs when they are incorrect or misleading + - If no problems are found, report that and DO NOT create a PR + ' }} + + - name: Report no changes + if: steps.check-changes.outputs.has_changes == 'false' + run: | + echo "No code changes found in the last ${{ inputs.days_back }} days." + echo "Skipping documentation sync." diff --git a/.github/workflows/showcase-nodejs-code-quality.yml b/.github/workflows/showcase-nodejs-code-quality.yml new file mode 100644 index 0000000..e5ff2b8 --- /dev/null +++ b/.github/workflows/showcase-nodejs-code-quality.yml @@ -0,0 +1,209 @@ +name: Showcase - Node.js Code Quality Review + +on: + workflow_call: + inputs: + model: + description: 'Claude model to use' + required: false + type: string + default: 'opus' + timeout_minutes: + description: 'Timeout in minutes per directory' + required: false + type: number + default: 45 + num_dirs: + description: 'Number of random directories to review' + required: false + type: number + default: 3 + source_dir: + description: 'Source directory to search for code' + required: false + type: string + default: 'src' + base_branch: + description: 'Base branch for PRs' + required: false + type: string + default: 'main' + file_extensions: + description: 'File extensions to review (space-separated)' + required: false + type: string + default: '.ts .tsx' + lint_command: + description: 'Lint command to verify changes' + required: false + type: string + default: 'npm run lint' + review_checklist_path: + description: 'Path to code review checklist (optional)' + required: false + type: string + default: '.claude/agents/code-reviewer.md' + custom_prompt: + description: 'Custom review prompt (optional)' + required: false + type: string + default: '' + secrets: + ANTHROPIC_API_KEY: + required: true + +permissions: + contents: write + pull-requests: write + id-token: write + +jobs: + select-directories: + runs-on: ubuntu-latest + outputs: + directories: ${{ steps.select.outputs.directories }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Select random directories + id: select + run: | + NUM_DIRS="${{ inputs.num_dirs }}" + SOURCE_DIR="${{ inputs.source_dir }}" + EXTENSIONS="${{ inputs.file_extensions }}" + + # Find directories with matching files (excluding tests) + # Build ls pattern by converting ".ts .tsx" to "*.ts *.tsx" + LS_PATTERNS="" + for ext in $EXTENSIONS; do + LS_PATTERNS="$LS_PATTERNS *$ext" + done + + # Find directories containing files with any of the extensions + DIRS=$(find "$SOURCE_DIR" -type d 2>/dev/null | while read -r dir; do + # Check if directory has matching files (excluding test files) + for ext in $EXTENSIONS; do + if ls "$dir"/*"$ext" 2>/dev/null | grep -qvE '\.(test|spec|stories)\.'; then + echo "$dir" + break + fi + done + done | sort -u | shuf -n "$NUM_DIRS") + + if [ -z "$DIRS" ]; then + echo "No suitable directories found" + echo "directories=[]" >> $GITHUB_OUTPUT + exit 0 + fi + + # Convert to JSON array + JSON_DIRS=$(echo "$DIRS" | jq -R -s -c 'split("\n") | map(select(length > 0))') + echo "directories=$JSON_DIRS" >> $GITHUB_OUTPUT + echo "Selected directories:" + echo "$DIRS" + + review-directory: + needs: select-directories + if: needs.select-directories.outputs.directories != '[]' + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 3 + matrix: + directory: ${{ fromJson(needs.select-directories.outputs.directories) }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Generate branch name + id: branch + run: | + DIR_SLUG=$(echo "${{ matrix.directory }}" | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//' | sed 's/-$//' | cut -c1-30) + BRANCH_NAME="claude/code-quality-${DIR_SLUG}-$(date +%Y%m%d)" + echo "name=$BRANCH_NAME" >> $GITHUB_OUTPUT + + - name: Claude Code Quality Review + uses: anthropics/claude-code-action@beta + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + model: ${{ inputs.model }} + timeout_minutes: ${{ inputs.timeout_minutes }} + base_branch: ${{ inputs.base_branch }} + branch_prefix: claude/code-quality- + max_turns: 35 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(${{ inputs.lint_command }}*)" + direct_prompt: | + ${{ inputs.custom_prompt != '' && inputs.custom_prompt || format(' + # Code Quality Review + + You are performing a code quality review of a specific directory. + + ## Target Directory + **Review: `{0}`** + + ## Your Tasks + + 1. **Read the code review standards**: If `{1}` exists, read it for the full checklist + + 2. **Analyze all files in the directory**: + - List all code files (excluding .test., .spec., .stories.) + - Read each file thoroughly + - Apply the review checklist + + 3. **Focus on finding and FIXING issues**: + - TypeScript strict mode violations (any types, missing types) + - React anti-patterns (bad useEffect, unnecessary memoization) + - Code style issues (mutations, deep nesting, poor naming) + - Missing error handling + - Security issues + - Performance problems + + 4. **Make the fixes yourself**: + - Do not just report issues - FIX THEM + - Use Edit tool to update files + - Ensure fixes do not break anything + + 5. **Run verification**: + - Run `{2}` - verify no lint errors introduced + - If errors occur, fix them or revert changes + + 6. **Create PR if fixes were made**: + - Create a branch from {3} + - Commit all fixes with descriptive message + - PR title: "fix({0}): code quality improvements" + - PR body should list fixes applied + + ## Guidelines + - Be thorough but focused on this directory only + - Fix issues that are clear improvements + - Do not refactor working code just for style + - If no issues found, report that and skip PR creation + ', matrix.directory, inputs.review_checklist_path, inputs.lint_command, inputs.base_branch) }} + + report-completion: + needs: [select-directories, review-directory] + if: always() + runs-on: ubuntu-latest + steps: + - name: Summary + run: | + echo "## Code Quality Review Complete" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Reviewed directories:" >> $GITHUB_STEP_SUMMARY + echo '${{ needs.select-directories.outputs.directories }}' | jq -r '.[]' | while read dir; do + echo "- \`$dir\`" >> $GITHUB_STEP_SUMMARY + done + echo "" >> $GITHUB_STEP_SUMMARY + echo "Check for any PRs created by this workflow." >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/showcase-nodejs-dependency-audit.yml b/.github/workflows/showcase-nodejs-dependency-audit.yml new file mode 100644 index 0000000..03535c3 --- /dev/null +++ b/.github/workflows/showcase-nodejs-dependency-audit.yml @@ -0,0 +1,149 @@ +name: Showcase - Node.js Dependency Audit + +on: + workflow_call: + inputs: + model: + description: 'Claude model to use' + required: false + type: string + default: 'opus' + timeout_minutes: + description: 'Timeout in minutes' + required: false + type: number + default: 45 + base_branch: + description: 'Base branch for PRs' + required: false + type: string + default: 'main' + node_version: + description: 'Node.js version to use' + required: false + type: string + default: '20' + lint_command: + description: 'Lint command to verify changes' + required: false + type: string + default: 'npm run lint' + test_command: + description: 'Test command to verify changes' + required: false + type: string + default: 'npm test' + custom_prompt: + description: 'Custom audit prompt (optional)' + required: false + type: string + default: '' + secrets: + ANTHROPIC_API_KEY: + required: true + +permissions: + contents: write + pull-requests: write + id-token: write + +jobs: + dependency-audit: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node_version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Check for outdated dependencies + id: check-outdated + run: | + echo "Checking for outdated dependencies..." + npm outdated --json > /tmp/outdated.json 2>/dev/null || true + + if [ ! -s /tmp/outdated.json ] || [ "$(cat /tmp/outdated.json)" = "{}" ]; then + echo "has_outdated=false" >> $GITHUB_OUTPUT + echo "No outdated dependencies found" + else + echo "has_outdated=true" >> $GITHUB_OUTPUT + echo "Found outdated dependencies" + cat /tmp/outdated.json + fi + + - name: Run security audit + id: security-audit + run: | + echo "Running security audit..." + npm audit --json > /tmp/audit.json 2>/dev/null || true + + if [ -s /tmp/audit.json ]; then + VULNERABILITIES=$(cat /tmp/audit.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('metadata',{}).get('vulnerabilities',{}).get('total',0))" 2>/dev/null || echo "0") + echo "vulnerabilities=$VULNERABILITIES" >> $GITHUB_OUTPUT + echo "Found $VULNERABILITIES vulnerabilities" + else + echo "vulnerabilities=0" >> $GITHUB_OUTPUT + fi + + - name: Claude Dependency Analysis & Update + if: steps.check-outdated.outputs.has_outdated == 'true' || steps.security-audit.outputs.vulnerabilities != '0' + uses: anthropics/claude-code-action@beta + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + model: ${{ inputs.model }} + timeout_minutes: ${{ inputs.timeout_minutes }} + base_branch: ${{ inputs.base_branch }} + branch_prefix: claude/deps-update- + max_turns: 40 + allowed_tools: "Read,Write,Edit,Glob,Grep,Bash(git:*),Bash(gh:*),Bash(npm:*)" + direct_prompt: | + ${{ inputs.custom_prompt != '' && inputs.custom_prompt || format(' + # Dependency Audit + + You are running a dependency audit. + + ## Your Tasks + + 1. **Analyze outdated packages**: Run `npm outdated` and review results + + 2. **Analyze security vulnerabilities**: Run `npm audit` and review results + + 3. **Update packages safely**: + - Use `npm update package-name` for minor/patch updates + - For major versions, use `npm install package-name@latest` only if safe + - Run `npm audit fix` for security fixes + + 4. **Verify updates**: + - Run `{0}` to check for lint issues + - Run `{1}` to verify tests pass + - If anything fails, revert that specific update + + 5. **Create PR** if any updates were made: + - Create branch from {2} + - Commit package.json and package-lock.json changes + - PR title: "chore(deps): update dependencies" + - PR body should list: + - Each package updated with old to new version + - Security vulnerabilities fixed (if any) + + ## Guidelines + - Be CONSERVATIVE - when in doubt, do not update + - If tests fail after an update, revert that update + - Group related updates together + - If NO updates are possible, report that and do not create a PR + ', inputs.lint_command, inputs.test_command, inputs.base_branch) }} + + - name: Report no updates needed + if: steps.check-outdated.outputs.has_outdated == 'false' && steps.security-audit.outputs.vulnerabilities == '0' + run: | + echo "All dependencies are up to date and no security vulnerabilities found." + echo "No action needed." diff --git a/.github/workflows/showcase-pr-review.yml b/.github/workflows/showcase-pr-review.yml new file mode 100644 index 0000000..6532cfd --- /dev/null +++ b/.github/workflows/showcase-pr-review.yml @@ -0,0 +1,94 @@ +name: Showcase - Claude PR Review + +on: + workflow_call: + inputs: + model: + description: 'Claude model to use' + required: false + type: string + default: 'opus' + timeout_minutes: + description: 'Timeout in minutes' + required: false + type: number + default: 30 + review_prompt: + description: 'Custom review prompt (optional, uses default if not provided)' + required: false + type: string + default: '' + secrets: + ANTHROPIC_API_KEY: + required: true + +permissions: + contents: read + pull-requests: write + issues: read + id-token: write + +jobs: + review: + # Run on PR events, or on issue comments that mention @claude + if: | + github.event_name == 'pull_request' || + (github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '@claude')) + runs-on: ubuntu-latest + steps: + - name: Checkout repository (PR event) + if: github.event_name == 'pull_request' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Checkout repository (issue_comment event) + if: github.event_name == 'issue_comment' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Checkout PR branch (issue_comment event) + if: github.event_name == 'issue_comment' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh pr checkout ${{ github.event.issue.number }} + + - name: Get PR base branch + id: pr-info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + echo "base_ref=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT + else + BASE_REF=$(gh pr view ${{ github.event.issue.number }} --json baseRefName -q '.baseRefName') + echo "base_ref=$BASE_REF" >> $GITHUB_OUTPUT + fi + + - name: Claude Code Review + uses: anthropics/claude-code-action@beta + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + model: ${{ inputs.model }} + timeout_minutes: ${{ inputs.timeout_minutes }} + max_turns: 10 + allowed_tools: "Read,Glob,Grep,Bash(git:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + direct_prompt: | + ${{ inputs.review_prompt != '' && inputs.review_prompt || format(' + Review this Pull Request thoroughly. + + 1. Run `git diff origin/{0}...HEAD` to see all changes + 2. Analyze the code for: + - Correctness and potential bugs + - TypeScript type safety (no `any` types) + - Error handling + - Security issues + - Performance concerns + - Code style and readability + 3. If a .claude/agents/code-reviewer.md exists, use it as the review checklist + 4. Provide feedback organized by severity (Critical, Warning, Suggestion) + ', steps.pr-info.outputs.base_ref) }} diff --git a/README.md b/README.md index 43a3fad..8ac0092 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ # Claude Code Project Configuration Showcase +> **Install any of these skills, agents, commands, and hooks directly into your projects:** +> ``` +> /plugin marketplace add aviadr1/claude-code-showcase +> /plugin install testing-patterns@claude-code-showcase +> ``` +> See [Plugin Marketplace](#plugin-marketplace) for all available plugins. + +--- + > Most software engineers are seriously sleeping on how good LLM agents are right now, especially something like Claude Code. Once you've got Claude Code set up, you can point it at your codebase, have it learn your conventions, pull in best practices, and refine everything until it's basically operating like a super-powered teammate. **The real unlock is building a solid set of reusable "[skills](#skills---domain-knowledge)" plus a few "[agents](#agents---specialized-assistants)" for the stuff you do all the time.** @@ -45,6 +54,62 @@ We even use Claude Code for ticket triage. It reads the ticket, digs into the co - [GitHub Actions Workflows](#github-actions-workflows) - [Best Practices](#best-practices) - [Examples in This Repository](#examples-in-this-repository) +- [Plugin Marketplace](#plugin-marketplace) + +--- + +## Plugin Marketplace + +This repository is also a **Claude Code plugin marketplace**. You can install individual components directly into your projects. + +### Quick Install + +```bash +# Add this marketplace to Claude Code +/plugin marketplace add aviadr1/claude-code-showcase + +# Browse available plugins +/plugin + +# Install specific plugins +/plugin install testing-patterns@claude-code-showcase +/plugin install code-review-suite@claude-code-showcase +/plugin install pr-toolkit@claude-code-showcase +``` + +### Available Plugins + +| Plugin | Type | Description | +|--------|------|-------------| +| `testing-patterns` | Skill | Jest testing, factory functions, TDD workflow | +| `systematic-debugging` | Skill | Four-phase debugging methodology | +| `react-ui-patterns` | Skill | Loading states, error handling, data fetching | +| `formik-patterns` | Skill | Form handling and validation | +| `graphql-schema` | Skill | GraphQL queries, mutations, codegen | +| `core-components` | Skill | Design system and component library | +| `pr-toolkit` | Bundle | `/pr-review`, `/pr-summary` + github-workflow agent | +| `code-review-suite` | Bundle | code-reviewer agent + `/code-quality` command | +| `ticket-workflow` | Bundle | `/ticket` + `/onboard` commands | +| `docs-sync` | Command | Documentation synchronization | +| `skill-activation` | Hook | Intelligent skill suggestions | +| `plugin-marketplace` | Skill | Create marketplaces using symlinks | +| `github-actions` | Bundle | Showcase Claude Code workflows + `/setup-github-actions` | + +### Architecture + +This marketplace uses **symlinks** to maintain a single source of truth: + +``` +.claude/ # Source of truth (showcase) +├── skills/testing-patterns/ +└── commands/pr-review.md + +plugins/ # Plugin packages (symlinks) +└── testing-patterns/ + └── skills/testing-patterns/ → symlink to .claude/skills/testing-patterns +``` + +Updates to `.claude/` automatically flow to the plugins. See the [plugin-marketplace skill](.claude/skills/plugin-marketplace/SKILL.md) for details on this pattern. --- @@ -778,7 +843,47 @@ Recent commits: !`git log --oneline -5` Automate code review, quality checks, and maintenance with Claude Code. -**📄 Examples:** +### Showcase Workflows (Reusable) + +This repository provides **reusable GitHub Actions workflows** that you can call from your own repositories using GitHub's `workflow_call` feature. No need to copy workflow files—just reference them directly. + +**Quick Setup:** +```yaml +# In your repository's .github/workflows/claude-pr-review.yml +name: Claude PR Review + +on: + pull_request: + issue_comment: + types: [created] + +jobs: + review: + uses: aviadr1/claude-code-showcase/.github/workflows/showcase-pr-review.yml@main + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} +``` + +**Available Showcase Workflows:** + +| Workflow | Stack | Purpose | Key Inputs | +|----------|-------|---------|------------| +| [`showcase-pr-review.yml`](.github/workflows/showcase-pr-review.yml) | **Any** | Automatic PR review | `model`, `timeout_minutes`, `review_prompt` | +| [`showcase-docs-sync.yml`](.github/workflows/showcase-docs-sync.yml) | **Any** | Keep docs in sync with code | `days_back`, `docs_paths`, `code_patterns` | +| [`showcase-nodejs-code-quality.yml`](.github/workflows/showcase-nodejs-code-quality.yml) | **Node.js** | Periodic code quality audits | `num_dirs`, `source_dir`, `lint_command` | +| [`showcase-nodejs-dependency-audit.yml`](.github/workflows/showcase-nodejs-dependency-audit.yml) | **Node.js** | Dependency updates & security | `node_version`, `lint_command`, `test_command` | + +**📄 Full documentation:** [github-actions skill](.claude/skills/github-actions/SKILL.md) + +**🛠️ Interactive setup:** Run `/setup-github-actions` in Claude Code + +--- + +### Local Workflows (Examples) + +These are **caller workflows** used by this repository—examples of how to call the reusable showcase workflows above: + +**📄 Example caller workflows:** - [pr-claude-code-review.yml](.github/workflows/pr-claude-code-review.yml) - Auto PR review - [scheduled-claude-code-docs-sync.yml](.github/workflows/scheduled-claude-code-docs-sync.yml) - Monthly docs sync - [scheduled-claude-code-quality.yml](.github/workflows/scheduled-claude-code-quality.yml) - Weekly quality review diff --git a/plugins/code-review-suite/.claude-plugin/plugin.json b/plugins/code-review-suite/.claude-plugin/plugin.json new file mode 100644 index 0000000..768e83f --- /dev/null +++ b/plugins/code-review-suite/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "code-review-suite", + "version": "1.0.0", + "description": "Comprehensive code review with quality checks. Includes code-reviewer agent and /code-quality command.", + "keywords": ["code-review", "quality", "linting", "standards"], + "commands": "./commands/", + "agents": "./agents/" +} diff --git a/plugins/code-review-suite/agents/code-reviewer.md b/plugins/code-review-suite/agents/code-reviewer.md new file mode 120000 index 0000000..51de951 --- /dev/null +++ b/plugins/code-review-suite/agents/code-reviewer.md @@ -0,0 +1 @@ +../../../.claude/agents/code-reviewer.md \ No newline at end of file diff --git a/plugins/code-review-suite/commands/code-quality.md b/plugins/code-review-suite/commands/code-quality.md new file mode 120000 index 0000000..ae4c4ba --- /dev/null +++ b/plugins/code-review-suite/commands/code-quality.md @@ -0,0 +1 @@ +../../../.claude/commands/code-quality.md \ No newline at end of file diff --git a/plugins/core-components/.claude-plugin/plugin.json b/plugins/core-components/.claude-plugin/plugin.json new file mode 100644 index 0000000..21ec127 --- /dev/null +++ b/plugins/core-components/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "core-components", + "version": "1.0.0", + "description": "Core component library and design system patterns. Use when building UI, using design tokens, or working with the component library.", + "keywords": ["components", "design-system", "tokens", "ui-library"], + "skills": "./skills/" +} diff --git a/plugins/core-components/skills/core-components b/plugins/core-components/skills/core-components new file mode 120000 index 0000000..bcd6c3c --- /dev/null +++ b/plugins/core-components/skills/core-components @@ -0,0 +1 @@ +../../../.claude/skills/core-components \ No newline at end of file diff --git a/plugins/docs-sync/.claude-plugin/plugin.json b/plugins/docs-sync/.claude-plugin/plugin.json new file mode 100644 index 0000000..bd8a569 --- /dev/null +++ b/plugins/docs-sync/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "docs-sync", + "version": "1.0.0", + "description": "Documentation synchronization command. Ensures docs stay aligned with code changes.", + "keywords": ["documentation", "docs", "sync", "maintenance"], + "commands": "./commands/" +} diff --git a/plugins/docs-sync/commands/docs-sync.md b/plugins/docs-sync/commands/docs-sync.md new file mode 120000 index 0000000..497d76c --- /dev/null +++ b/plugins/docs-sync/commands/docs-sync.md @@ -0,0 +1 @@ +../../../.claude/commands/docs-sync.md \ No newline at end of file diff --git a/plugins/formik-patterns/.claude-plugin/plugin.json b/plugins/formik-patterns/.claude-plugin/plugin.json new file mode 100644 index 0000000..879bfba --- /dev/null +++ b/plugins/formik-patterns/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "formik-patterns", + "version": "1.0.0", + "description": "Formik form handling with validation patterns. Use when building forms, implementing validation, or handling form submission.", + "keywords": ["formik", "forms", "validation", "react"], + "skills": "./skills/" +} diff --git a/plugins/formik-patterns/skills/formik-patterns b/plugins/formik-patterns/skills/formik-patterns new file mode 120000 index 0000000..48a82d1 --- /dev/null +++ b/plugins/formik-patterns/skills/formik-patterns @@ -0,0 +1 @@ +../../../.claude/skills/formik-patterns \ No newline at end of file diff --git a/plugins/github-actions/.claude-plugin/plugin.json b/plugins/github-actions/.claude-plugin/plugin.json new file mode 100644 index 0000000..63db402 --- /dev/null +++ b/plugins/github-actions/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "github-actions", + "version": "1.0.0", + "description": "Showcase GitHub Actions workflows for Claude Code CI/CD automation. Includes PR review, docs sync, code quality, and dependency audit workflows.", + "keywords": ["github-actions", "ci-cd", "workflows", "automation", "pr-review", "code-quality"], + "skills": "./skills/", + "commands": "./commands/" +} diff --git a/plugins/github-actions/commands/setup-github-actions.md b/plugins/github-actions/commands/setup-github-actions.md new file mode 120000 index 0000000..85984fe --- /dev/null +++ b/plugins/github-actions/commands/setup-github-actions.md @@ -0,0 +1 @@ +../../../.claude/commands/setup-github-actions.md \ No newline at end of file diff --git a/plugins/github-actions/skills/github-actions b/plugins/github-actions/skills/github-actions new file mode 120000 index 0000000..ad3a1d7 --- /dev/null +++ b/plugins/github-actions/skills/github-actions @@ -0,0 +1 @@ +../../../.claude/skills/github-actions \ No newline at end of file diff --git a/plugins/graphql-schema/.claude-plugin/plugin.json b/plugins/graphql-schema/.claude-plugin/plugin.json new file mode 100644 index 0000000..a5f73bb --- /dev/null +++ b/plugins/graphql-schema/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "graphql-schema", + "version": "1.0.0", + "description": "GraphQL queries, mutations, and code generation patterns. Use when creating GraphQL operations, working with Apollo Client, or generating types.", + "keywords": ["graphql", "apollo", "queries", "mutations", "codegen"], + "skills": "./skills/" +} diff --git a/plugins/graphql-schema/skills/graphql-schema b/plugins/graphql-schema/skills/graphql-schema new file mode 120000 index 0000000..6160136 --- /dev/null +++ b/plugins/graphql-schema/skills/graphql-schema @@ -0,0 +1 @@ +../../../.claude/skills/graphql-schema \ No newline at end of file diff --git a/plugins/plugin-marketplace/.claude-plugin/plugin.json b/plugins/plugin-marketplace/.claude-plugin/plugin.json new file mode 100644 index 0000000..8db31ad --- /dev/null +++ b/plugins/plugin-marketplace/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "plugin-marketplace", + "version": "1.0.0", + "description": "Create a Claude Code plugin marketplace from existing skills, commands, agents, and hooks using symlinks. Use when converting a showcase repo to an installable marketplace.", + "keywords": ["marketplace", "plugins", "symlinks", "distribution"], + "skills": "./skills/" +} diff --git a/plugins/plugin-marketplace/skills/plugin-marketplace b/plugins/plugin-marketplace/skills/plugin-marketplace new file mode 120000 index 0000000..1a4cba7 --- /dev/null +++ b/plugins/plugin-marketplace/skills/plugin-marketplace @@ -0,0 +1 @@ +../../../.claude/skills/plugin-marketplace \ No newline at end of file diff --git a/plugins/pr-toolkit/.claude-plugin/plugin.json b/plugins/pr-toolkit/.claude-plugin/plugin.json new file mode 100644 index 0000000..c32abbd --- /dev/null +++ b/plugins/pr-toolkit/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "pr-toolkit", + "version": "1.0.0", + "description": "Complete PR workflow toolkit with review commands and git workflow agent. Includes /pr-review, /pr-summary commands and github-workflow agent.", + "keywords": ["pr", "pull-request", "github", "git", "review"], + "commands": "./commands/", + "agents": "./agents/" +} diff --git a/plugins/pr-toolkit/agents/github-workflow.md b/plugins/pr-toolkit/agents/github-workflow.md new file mode 120000 index 0000000..8761388 --- /dev/null +++ b/plugins/pr-toolkit/agents/github-workflow.md @@ -0,0 +1 @@ +../../../.claude/agents/github-workflow.md \ No newline at end of file diff --git a/plugins/pr-toolkit/commands/pr-review.md b/plugins/pr-toolkit/commands/pr-review.md new file mode 120000 index 0000000..3fa4ccb --- /dev/null +++ b/plugins/pr-toolkit/commands/pr-review.md @@ -0,0 +1 @@ +../../../.claude/commands/pr-review.md \ No newline at end of file diff --git a/plugins/pr-toolkit/commands/pr-summary.md b/plugins/pr-toolkit/commands/pr-summary.md new file mode 120000 index 0000000..5db931d --- /dev/null +++ b/plugins/pr-toolkit/commands/pr-summary.md @@ -0,0 +1 @@ +../../../.claude/commands/pr-summary.md \ No newline at end of file diff --git a/plugins/react-ui-patterns/.claude-plugin/plugin.json b/plugins/react-ui-patterns/.claude-plugin/plugin.json new file mode 100644 index 0000000..af2b588 --- /dev/null +++ b/plugins/react-ui-patterns/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "react-ui-patterns", + "version": "1.0.0", + "description": "Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states.", + "keywords": ["react", "ui", "loading-states", "error-handling", "hooks"], + "skills": "./skills/" +} diff --git a/plugins/react-ui-patterns/skills/react-ui-patterns b/plugins/react-ui-patterns/skills/react-ui-patterns new file mode 120000 index 0000000..12d11ba --- /dev/null +++ b/plugins/react-ui-patterns/skills/react-ui-patterns @@ -0,0 +1 @@ +../../../.claude/skills/react-ui-patterns \ No newline at end of file diff --git a/plugins/skill-activation/.claude-plugin/plugin.json b/plugins/skill-activation/.claude-plugin/plugin.json new file mode 100644 index 0000000..86fb69a --- /dev/null +++ b/plugins/skill-activation/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "skill-activation", + "version": "1.0.0", + "description": "Intelligent skill suggestion system. Analyzes prompts and suggests relevant skills based on keywords, patterns, and file paths.", + "keywords": ["skills", "automation", "hooks", "suggestions"], + "hooks": "./hooks/hooks.json" +} diff --git a/plugins/skill-activation/hooks/hooks.json b/plugins/skill-activation/hooks/hooks.json new file mode 100644 index 0000000..6143bf6 --- /dev/null +++ b/plugins/skill-activation/hooks/hooks.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/skill-eval.sh\"", + "timeout": 5 + } + ] + } + ] + } +} diff --git a/plugins/skill-activation/hooks/skill-eval.js b/plugins/skill-activation/hooks/skill-eval.js new file mode 120000 index 0000000..85590cc --- /dev/null +++ b/plugins/skill-activation/hooks/skill-eval.js @@ -0,0 +1 @@ +../../../.claude/hooks/skill-eval.js \ No newline at end of file diff --git a/plugins/skill-activation/hooks/skill-eval.sh b/plugins/skill-activation/hooks/skill-eval.sh new file mode 120000 index 0000000..cde2062 --- /dev/null +++ b/plugins/skill-activation/hooks/skill-eval.sh @@ -0,0 +1 @@ +../../../.claude/hooks/skill-eval.sh \ No newline at end of file diff --git a/plugins/skill-activation/hooks/skill-rules.json b/plugins/skill-activation/hooks/skill-rules.json new file mode 120000 index 0000000..41abfea --- /dev/null +++ b/plugins/skill-activation/hooks/skill-rules.json @@ -0,0 +1 @@ +../../../.claude/hooks/skill-rules.json \ No newline at end of file diff --git a/plugins/skill-activation/hooks/skill-rules.schema.json b/plugins/skill-activation/hooks/skill-rules.schema.json new file mode 120000 index 0000000..97687d7 --- /dev/null +++ b/plugins/skill-activation/hooks/skill-rules.schema.json @@ -0,0 +1 @@ +../../../.claude/hooks/skill-rules.schema.json \ No newline at end of file diff --git a/plugins/systematic-debugging/.claude-plugin/plugin.json b/plugins/systematic-debugging/.claude-plugin/plugin.json new file mode 100644 index 0000000..f8207d1 --- /dev/null +++ b/plugins/systematic-debugging/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "systematic-debugging", + "version": "1.0.0", + "description": "Four-phase debugging methodology with root cause analysis. Use when investigating bugs, fixing test failures, or troubleshooting unexpected behavior.", + "keywords": ["debugging", "troubleshooting", "root-cause", "bug-fix"], + "skills": "./skills/" +} diff --git a/plugins/systematic-debugging/skills/systematic-debugging b/plugins/systematic-debugging/skills/systematic-debugging new file mode 120000 index 0000000..93c737d --- /dev/null +++ b/plugins/systematic-debugging/skills/systematic-debugging @@ -0,0 +1 @@ +../../../.claude/skills/systematic-debugging \ No newline at end of file diff --git a/plugins/testing-patterns/.claude-plugin/plugin.json b/plugins/testing-patterns/.claude-plugin/plugin.json new file mode 100644 index 0000000..22df799 --- /dev/null +++ b/plugins/testing-patterns/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "testing-patterns", + "version": "1.0.0", + "description": "Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle.", + "keywords": ["testing", "jest", "tdd", "mocking", "factory-pattern"], + "skills": "./skills/" +} diff --git a/plugins/testing-patterns/skills/testing-patterns b/plugins/testing-patterns/skills/testing-patterns new file mode 120000 index 0000000..dd8d778 --- /dev/null +++ b/plugins/testing-patterns/skills/testing-patterns @@ -0,0 +1 @@ +../../../.claude/skills/testing-patterns \ No newline at end of file diff --git a/plugins/ticket-workflow/.claude-plugin/plugin.json b/plugins/ticket-workflow/.claude-plugin/plugin.json new file mode 100644 index 0000000..ff3ca8d --- /dev/null +++ b/plugins/ticket-workflow/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "ticket-workflow", + "version": "1.0.0", + "description": "End-to-end ticket workflow for JIRA/Linear integration. Read tickets, implement features, update status. Includes /ticket and /onboard commands.", + "keywords": ["jira", "linear", "tickets", "workflow", "onboarding"], + "commands": "./commands/" +} diff --git a/plugins/ticket-workflow/commands/onboard.md b/plugins/ticket-workflow/commands/onboard.md new file mode 120000 index 0000000..45a3b83 --- /dev/null +++ b/plugins/ticket-workflow/commands/onboard.md @@ -0,0 +1 @@ +../../../.claude/commands/onboard.md \ No newline at end of file diff --git a/plugins/ticket-workflow/commands/ticket.md b/plugins/ticket-workflow/commands/ticket.md new file mode 120000 index 0000000..fb45e38 --- /dev/null +++ b/plugins/ticket-workflow/commands/ticket.md @@ -0,0 +1 @@ +../../../.claude/commands/ticket.md \ No newline at end of file diff --git a/scripts/audit-atoms.sh b/scripts/audit-atoms.sh new file mode 100755 index 0000000..96037c2 --- /dev/null +++ b/scripts/audit-atoms.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Audits whether all atoms in .claude/ are exposed in plugins/ +# Atoms = skills, commands, agents, hooks + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +echo "=== Atom Coverage Audit ===" +echo "" + +missing=0 + +# Audit Skills +echo "Skills:" +for skill_dir in "$REPO_ROOT"/.claude/skills/*/; do + [ ! -d "$skill_dir" ] && continue + skill_name=$(basename "$skill_dir") + + # Check if this skill is symlinked in any plugin + found=$(find "$REPO_ROOT/plugins" -type l -name "$skill_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $skill_name" + else + echo " ✗ $skill_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Commands +echo "Commands:" +for cmd_file in "$REPO_ROOT"/.claude/commands/*.md; do + [ ! -f "$cmd_file" ] && continue + cmd_name=$(basename "$cmd_file") + + found=$(find "$REPO_ROOT/plugins" -type l -name "$cmd_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $cmd_name" + else + echo " ✗ $cmd_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Agents +echo "Agents:" +for agent_file in "$REPO_ROOT"/.claude/agents/*.md; do + [ ! -f "$agent_file" ] && continue + agent_name=$(basename "$agent_file") + + found=$(find "$REPO_ROOT/plugins" -type l -name "$agent_name" 2>/dev/null | head -1) + if [ -n "$found" ]; then + echo " ✓ $agent_name" + else + echo " ✗ $agent_name (NOT IN ANY PLUGIN)" + missing=$((missing + 1)) + fi +done + +echo "" + +# Audit Hooks (check for any hook files) +echo "Hooks:" +hook_files=$(find "$REPO_ROOT"/.claude/hooks -type f \( -name "*.sh" -o -name "*.js" -o -name "*.json" \) 2>/dev/null | head -1) +if [ -n "$hook_files" ]; then + hooks_in_plugin=$(find "$REPO_ROOT/plugins" -path "*/hooks/*" -type l 2>/dev/null | head -1) + if [ -n "$hooks_in_plugin" ]; then + echo " ✓ Hook system exposed in plugins" + else + echo " ✗ Hook system NOT exposed in plugins" + missing=$((missing + 1)) + fi +else + echo " (no hooks found)" +fi + +echo "" +echo "=== Summary ===" +if [ $missing -eq 0 ]; then + echo "All atoms are exposed in plugins!" + exit 0 +else + echo "$missing atom(s) missing from plugins" + exit 1 +fi diff --git a/scripts/check-atom-changes.sh b/scripts/check-atom-changes.sh new file mode 100755 index 0000000..7c579c3 --- /dev/null +++ b/scripts/check-atom-changes.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Detects which atoms have changed since the last release tag +# Usage: ./scripts/check-atom-changes.sh [base-ref] +# base-ref: git ref to compare against (default: latest tag) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +# Get base reference (default to latest tag, or HEAD~10 if no tags) +BASE_REF="${1:-$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")}" + +echo "=== Atom Changes Since $BASE_REF ===" +echo "" + +changes=0 + +check_changes() { + local atom_type="$1" + local atom_path="$2" + local atom_name="$3" + + # Check if path has changes since base ref + if git diff --quiet "$BASE_REF" -- "$atom_path" 2>/dev/null; then + echo " ✓ $atom_name (unchanged)" + else + echo " CHANGED: $atom_name" + # Show brief summary of changes + local lines_changed=$(git diff --stat "$BASE_REF" -- "$atom_path" 2>/dev/null | tail -1) + [ -n "$lines_changed" ] && echo " $lines_changed" + changes=$((changes + 1)) + fi +} + +# Check skills +echo "Skills:" +for skill_dir in "$REPO_ROOT"/.claude/skills/*/; do + [ ! -d "$skill_dir" ] && continue + skill_name=$(basename "$skill_dir") + check_changes "skill" "$skill_dir" "$skill_name" +done + +echo "" + +# Check commands +echo "Commands:" +for cmd_file in "$REPO_ROOT"/.claude/commands/*.md; do + [ ! -f "$cmd_file" ] && continue + cmd_name=$(basename "$cmd_file" .md) + check_changes "command" "$cmd_file" "$cmd_name" +done + +echo "" + +# Check agents +echo "Agents:" +for agent_file in "$REPO_ROOT"/.claude/agents/*.md; do + [ ! -f "$agent_file" ] && continue + agent_name=$(basename "$agent_file" .md) + check_changes "agent" "$agent_file" "$agent_name" +done + +echo "" + +# Check hooks +echo "Hooks:" +hooks_dir="$REPO_ROOT/.claude/hooks" +if [ -d "$hooks_dir" ]; then + if git diff --quiet "$BASE_REF" -- "$hooks_dir" 2>/dev/null; then + echo " ✓ hooks (unchanged)" + else + echo " CHANGED: hooks" + changes=$((changes + 1)) + fi +fi + +echo "" +echo "=== Summary ===" +echo "Comparing against: $BASE_REF" +if [ $changes -eq 0 ]; then + echo "No atoms have changed" + exit 0 +else + echo "$changes atom(s) changed - consider version bump for affected plugins" + echo "" + echo "To see full diff for a specific atom:" + echo " git diff $BASE_REF -- .claude/skills/SKILL_NAME/" + exit 1 +fi diff --git a/scripts/validate-symlinks.sh b/scripts/validate-symlinks.sh new file mode 100755 index 0000000..f3ab59c --- /dev/null +++ b/scripts/validate-symlinks.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Validates that all symlinks in the plugins directory point to valid targets +# Run after git pull to ensure marketplace integrity + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" +PLUGINS_DIR="$REPO_ROOT/plugins" + +if [ ! -d "$PLUGINS_DIR" ]; then + echo "No plugins directory found at $PLUGINS_DIR" + exit 0 +fi + +errors=0 +checked=0 + +echo "Validating symlinks in plugins/..." + +while IFS= read -r -d '' link; do + checked=$((checked + 1)) + if [ ! -e "$link" ]; then + echo " BROKEN: $link -> $(readlink "$link")" + errors=$((errors + 1)) + fi +done < <(find "$PLUGINS_DIR" -type l -print0) + +echo "" +echo "Checked $checked symlinks" + +if [ $errors -eq 0 ]; then + echo "All symlinks are valid" + exit 0 +else + echo "$errors broken symlink(s) found" + exit 1 +fi