Files
skillhub/CLAUDE.md
airano 4212b5ba47 sync: stale skill detection, sentry filtering, claim removal, review improvements
Stale Detection:
- Detect skills removed/moved from GitHub (3 consecutive 404s threshold)
- Hide stale skills from browse/search, show warning banner on detail page
- Serve cached files with isStale flag when GitHub returns 404
- Add stale-check crawler command for batch verification
- CLI shows warning when installing stale skills from cache

Sentry & Error Handling:
- Filter browser extension errors and add denyUrls
- Anti-inflation measures and sentinel recalibration for curation

Claim & Removal:
- Enhanced ClaimForm with repo-level removal support
- Add repo-removal-request API endpoint with tests
- Improved owner page with bilingual content

Review Pipeline:
- Review version and reviewer tracking in submit API
- Source format filter for pending reviews
- Updated review tests

Other:
- Updated i18n strings (en/fa)
- BrowseFilters improvements
- Dockerfile updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 05:59:26 +03:30

5.0 KiB

CLAUDE.md

Project Overview

SkillHub is an open-source marketplace for Agent Skills — folders containing a SKILL.md file with instructions that AI agents can load dynamically.

Live Site: https://skills.palebluedot.live | Status: Production (GET /api/stats)

Components:

  • Web App (apps/web): Next.js 15 marketplace
  • CLI (apps/cli): Skill installer (npm install -g skillhub)
  • Indexer (services/indexer): GitHub crawler
  • Packages (packages/*): Core logic, DB, UI components

Common Commands

pnpm install                              # Install dependencies
pnpm dev                                  # Start all apps
pnpm --filter @skillhub/web dev           # Start only web app
pnpm build                                # Build all packages
pnpm test                                 # Run all tests (248 total)
pnpm --filter @skillhub/web test:e2e      # E2E tests (requires running app)
pnpm db:push                              # Push schema changes
docker compose up -d                      # Start all services

Architecture

skillhub/
├── apps/
│   ├── web/           # Next.js 15 + App Router + next-intl (i18n)
│   └── cli/           # Commander.js CLI, builds with tsup
├── packages/
│   ├── core/          # SKILL.md parser, validator, security scanner
│   ├── db/            # Drizzle ORM schema and queries
│   └── ui/            # Shared shadcn/ui components
├── services/
│   └── indexer/       # BullMQ worker for GitHub crawling
└── scripts/           # Database initialization scripts

Database

Schema files (keep in sync):

  • scripts/init-db.sql — SQL schema
  • packages/db/src/schema.ts — Drizzle ORM schema
  • scripts/categories.sql — Production categories
  • scripts/seed-data.sql — Dev sample data

Caching: Skill files cached in cached_files JSONB column, invalidated when commitSha changes.

Important Patterns

Next.js 15 Async Params

params and searchParams are Promises:

export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
  const { locale } = await params;
}

i18n (next-intl)

Routes use [locale] segment. Use setRequestLocale(locale) for static rendering.

Dynamic Rendering

Add export const dynamic = 'force-dynamic' to pages that fetch from database.

Package Imports

  • skillhub-core — Parser/validator
  • @skillhub/db — Database
  • @skillhub/ui — UI components

API Route Pattern

Skill IDs = owner/repo/skill-name. Use catch-all: /api/skills/[...id]/route.ts

CLI Skill ID Encoding

const encodedPath = id.split('/').map(encodeURIComponent).join('/');

Meilisearch IDs

Sanitized: anthropics/skills/pdfanthropics__skills__pdf

Environment Variables

DATABASE_URL, REDIS_URL, GITHUB_TOKEN, MEILI_URL (optional), MEILI_MASTER_KEY, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, AUTH_SECRET

Indexer

docker compose exec indexer node dist/crawl.js full                        # Full crawl
docker compose exec indexer node dist/crawl.js incremental                 # Last 24h
docker compose exec indexer node dist/crawl.js sync-meili                  # Sync to Meilisearch
docker compose exec indexer node dist/crawl.js deep-scan                   # Scan discovered repos
docker compose exec indexer node dist/crawl.js add-repo <owner/repo>       # Manually add a repo to DB
docker compose exec indexer node dist/crawl.js process-add-requests        # Process user-submitted add requests

Database Migration (container)

# Add new columns (run when schema changes are deployed)
docker compose exec db psql -U skillhub -d skillhub -c "ALTER TABLE skills ADD COLUMN IF NOT EXISTS is_owner_claimed boolean NOT NULL DEFAULT false;"
docker compose exec db psql -U skillhub -d skillhub -c "ALTER TABLE discovered_repos ADD COLUMN IF NOT EXISTS is_blocked boolean NOT NULL DEFAULT false;"
docker compose exec db psql -U skillhub -d skillhub -c "CREATE INDEX IF NOT EXISTS idx_skills_owner_claimed ON skills(is_owner_claimed) WHERE is_owner_claimed = true;"
docker compose exec db psql -U skillhub -d skillhub -c "CREATE INDEX IF NOT EXISTS idx_discovered_repos_blocked ON discovered_repos(is_blocked) WHERE is_blocked = true;"

Security

Status stored in security_status column: PASS (green) / WARNING (yellow) / FAIL (red). Indexer scans for dangerous commands, prompt injection, and data exfiltration.

Critical Files

Category Files
Database packages/db/src/schema.ts, packages/db/src/queries.ts
API Routes apps/web/app/api/skills/route.ts, apps/web/app/api/skill-files/route.ts
Auth apps/web/lib/auth.ts, apps/web/components/AuthButton.tsx
Caching apps/web/lib/cache.ts (Redis with TTL)
Rate Limiting apps/web/lib/rate-limit.ts
Indexer services/indexer/src/crawler.ts, services/indexer/src/strategies/
CLI apps/cli/src/commands/install.ts, apps/cli/src/utils/api.ts