Skip to content

Latest commit

 

History

History
599 lines (499 loc) · 28.5 KB

File metadata and controls

599 lines (499 loc) · 28.5 KB

SkillHub — AGENTS.md

SkillHub is an enterprise-grade, self-hosted agent skill registry for publishing, discovering, and managing reusable skill packages across an organization. It provides a REST API backend, a React web UI, a security scanner, and a ClawHub CLI compatibility layer.

Quick Reference

Item Value
Backend Spring Boot 3.2.3, Java 21, Maven multi-module (7 modules)
Frontend React 19, TypeScript, Vite, pnpm
Scanner Python (FastAPI), port 8000
Database PostgreSQL 16 (Flyway migrations)
Cache Redis 7 (sessions, distributed locks, idempotency)
Storage LocalFile (dev) / S3/MinIO (prod)
Build make dev-all (dev), make staging (pre-PR)
Docs docs/ (design), document/ (VitePress user guide)
CI GitHub Actions (.github/workflows/)

Directory Map

skillhub/
├── server/                          # Maven multi-module Spring Boot backend
│   ├── skillhub-app/                # Application layer: bootstrap, controllers, assembly
│   │   ├── bootstrap/               # Bootstrap admin & local dev data initializers
│   │   ├── compat/                  # ClawHub CLI compatibility layer controllers
│   │   ├── config/                  # Spring configuration classes
│   │   ├── controller/              # REST controllers (transport only)
│   │   │   ├── admin/               # Admin controllers (user mgmt, labels, search)
│   │   │   ├── portal/              # Portal controllers (skills, governance, security)
│   │   │   └── support/             # Package extractors (zip, multipart)
│   │   ├── dto/                     # Request/response DTOs
│   │   ├── exception/               # Exception handling
│   │   ├── filter/                  # Servlet filters (auth context, rate limiting)
│   │   ├── listener/                # Event listeners (notification recipients, etc.)
│   │   ├── metrics/                 # Micrometer metrics
│   │   ├── projection/              # Lifecycle projection models
│   │   ├── ratelimit/               # Rate limiting logic
│   │   ├── repository/              # Query repositories (read-model assembly)
│   │   ├── security/                # Security configuration
│   │   ├── service/                 # App services (workflow orchestration)
│   │   ├── stream/                  # SSE streaming endpoints
│   │   ├── task/                    # Background task scheduling
│   │   └── SkillhubApplication.java # Spring Boot entry point
│   │
│   ├── skillhub-domain/             # Domain layer: entities, rules, services (innermost)
│   │   ├── audit/                   # AuditLog entity, repository, service
│   │   ├── auth/                    # Password reset entities
│   │   ├── event/                   # Domain event classes (SkillPublishedEvent, etc.)
│   │   ├── governance/              # Governance notification service
│   │   ├── idempotency/             # Idempotency records
│   │   ├── label/                   # Skill label management
│   │   ├── namespace/               # Namespace, members, roles, policies
│   │   ├── report/                  # Skill reporting/governance
│   │   ├── review/                  # Review tasks, promotion requests
│   │   ├── security/                # Security scanning domain model
│   │   ├── shared/                  # Shared domain utilities
│   │   │   └── exception/           # Domain exceptions (LocalizedDomainException, etc.)
│   │   ├── skill/                   # Core skill entities and services
│   │   │   ├── metadata/            # SKILL.md frontmatter parsing
│   │   │   ├── service/             # Skill domain services (publish, query, governance)
│   │   │   └── validation/          # Package validation (SkillPackagePolicy, etc.)
│   │   ├── social/                  # Star, rating, subscription entities
│   │   └── user/                    # UserAccount, profile moderation
│   │
│   ├── skillhub-auth/               # Authentication & authorization
│   │   ├── config/                  # Spring Security configuration
│   │   ├── device/                  # OAuth Device Flow for CLI auth
│   │   ├── identity/                # Identity binding service
│   │   ├── local/                   # Local (password) auth
│   │   ├── merge/                   # Account merging
│   │   ├── oauth/                   # OAuth2 login handlers
│   │   ├── policy/                  # Route security policies
│   │   ├── rbac/                    # RBAC service and role definitions
│   │   ├── token/                   # API token management
│   │   └── user/                    # User-related auth services
│   │
│   ├── skillhub-search/             # Search SPI + PostgreSQL full-text implementation
│   │   ├── postgres/                # PostgresFullTextIndexService, QueryService
│   │   └── service/                 # Search SPI interfaces
│   │
│   ├── skillhub-storage/            # Object storage SPI
│   │   ├── local/                   # LocalFileStorageService
│   │   └── s3/                      # S3StorageService (AWS SDK v2)
│   │
│   ├── skillhub-infra/              # Infrastructure: JPA repos, utilities
│   │   └── repository/              # Spring Data JPA repository implementations
│   │
│   ├── skillhub-notification/       # Notification service (SSE, email)
│   │   ├── domain/                  # Notification domain model
│   │   ├── service/                 # Notification delivery services
│   │   └── sse/                     # SSE endpoint support
│   │
│   ├── Dockerfile.dev               # Dockerfile for staging builds
│   ├── Dockerfile                   # Production multi-stage build
│   ├── pom.xml                      # Parent POM (Spring Boot 3.2.3 parent)
│   └── scripts/
│       └── run-dev-app.sh           # Local dev startup script
│
├── web/                             # React frontend (Vite + pnpm)
│   ├── src/
│   │   ├── api/                     # OpenAPI-generated types + fetch client
│   │   │   └── generated/
│   │   │       └── schema.d.ts      # Generated OpenAPI types (CHECKED IN)
│   │   ├── app/                     # Router, layout, global providers
│   │   ├── docs/                    # In-app documentation pages
│   │   ├── entities/                # Domain entity display logic
│   │   │   ├── skill/               # Skill card, detail components
│   │   │   ├── user/                # User profile components
│   │   │   └── namespace/           # Namespace display components
│   │   ├── features/                # Business feature modules
│   │   │   ├── admin/               # Admin panel features
│   │   │   ├── auth/                # Login, OAuth flows
│   │   │   ├── governance/          # Skill governance actions
│   │   │   ├── namespace/           # Namespace management
│   │   │   ├── notification/        # User notifications
│   │   │   ├── promotion/           # Skill promotion workflows
│   │   │   ├── publish/             # Skill upload/publish UI
│   │   │   ├── report/              # Skill reporting
│   │   │   ├── review/              # Review workflow UI
│   │   │   ├── search/              # Skill search and filtering
│   │   │   ├── security-audit/      # Security audit viewer
│   │   │   ├── skill/               # Skill detail, listing
│   │   │   ├── social/              # Stars, ratings, subscriptions
│   │   │   └── token/               # API token management
│   │   ├── i18n/                    # Internationalization
│   │   ├── pages/                   # Route-level page components
│   │   ├── shared/                  # Shared UI, hooks, utilities
│   │   │   ├── components/          # Reusable UI components
│   │   │   ├── hooks/               # Custom React hooks
│   │   │   ├── lib/
│   │   │   │   └── utils.ts         # cn() class merging utility
│   │   │   └── ui/                  # Radix UI-based primitives
│   │   └── types/                   # Additional TypeScript types
│   ├── e2e/                         # Playwright E2E tests
│   ├── nginx.conf.template          # Nginx runtime config template
│   ├── Dockerfile                   # Multi-stage build (Node → Nginx)
│   └── package.json                 # Dependencies (React 19, TanStack Query, Radix UI, etc.)
│
├── scanner/                         # Security scanner (Python/FastAPI)
│   ├── docs/                        # Scanner documentation
│   ├── examples/                    # Example scan inputs/outputs
│   └── Dockerfile                   # Scanner container build
│
├── docs/                            # Design documents (source of truth)
│   ├── prds/                        # Product requirement documents
│   ├── skillhub/                    # VitePress user guide source
│   └── superpowers/                 # Internal tooling docs
│
├── document/                        # VitePress documentation site (published)
│   ├── docs/                        # Markdown documentation
│   ├── src/                         # VitePress theme
│   └── i18n/                        # Internationalization
│
├── deploy/k8s/                      # Kubernetes manifests (basic)
├── monitoring/                      # Prometheus + Grafana stack
├── scripts/                         # Build, test, and deployment scripts
│   ├── smoke-test.sh                # Basic API smoke test
│   ├── namespace-smoke-test.sh      # Namespace workflow smoke test
│   ├── governance-smoke-test.sh     # Governance flow smoke test
│   ├── promotion-smoke-test.sh      # Promotion flow smoke test
│   ├── check-openapi-generated.sh   # Verify OpenAPI SDK is not stale
│   ├── validate-release-config.sh   # Validate release env configuration
│   ├── dev-process.sh               # Local process manager (PID-based)
│   ├── runtime.sh                   # Runtime deployment script
│   ├── parallel-init.sh             # Parallel worktree initialization
│   ├── parallel-sync.sh             # Merge worktrees in integration branch
│   ├── parallel-up.sh               # Merge + start dev environment
│   ├── parallel-down.sh             # Stop parallel dev environment
│   └── prepare-pr-batch.sh          # Batch PR preparation
│
├── .github/
│   ├── workflows/                   # GitHub Actions CI/CD
│   ├── ISSUE_TEMPLATE/              # Issue templates
│   └── scripts/                     # Deno scripts for triage, release notes, rewards
│
├── AGENTS.md                        # AI agent rules (this file)
├── .agents/skills/                  # Focused AI skill definitions
├── Makefile                         # Top-level build/test/dev orchestration
├── docker-compose.yml               # Local dev dependency services
├── compose.release.yml              # Production release compose file
├── CONTRIBUTING.md                  # Contribution guidelines
├── CODE_OF_CONDUCT.md               # Community standards
└── README.md                        # Project overview

Key Locations for Common Tasks:

Task Where to Look
Add REST endpoint server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/
Add domain entity/service server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/
Add auth logic server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/
Add search logic server/skillhub-search/src/main/java/com/iflytek/skillhub/search/
Add query repository server/skillhub-app/src/main/java/com/iflytek/skillhub/repository/
Change RBAC/roles server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/rbac/
Change skill validation server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/validation/
Add frontend page web/src/pages/
Add frontend feature web/src/features/
Add shared component web/src/shared/components/
Change API contract Backend controller → run make generate-api → commit generated file
Add smoke test scripts/ (new .sh file)
Add E2E test web/e2e/ (Playwright)
Add backend test server/skillhub-*/src/test/java/ (alongside source module)

Critical Rules

Do Not Manually Edit Generated Files

  • web/src/api/generated/schema.d.ts — regenerated via make generate-api
  • document/docs/ — auto-generated user documentation (VitePress)
  • server/skillhub-app/src/main/java/com/iflytek/skillhub/dto/ — some DTOs may be generated

After Making Changes

Backend changes:

  • Edit Java code → make dev-server-restart (local dev)
  • Add/modify controller → make generate-api to regenerate frontend types
  • Add/modify domain service → make test-backend-app to verify tests

Frontend changes:

  • Edit TypeScript/React → Vite HMR handles reload automatically
  • After make generate-api → commit updated web/src/api/generated/schema.d.ts

Always run before PR:

make test-backend-app   # Backend tests (with dependent modules)
make typecheck-web      # Frontend type check
make lint-web           # Frontend lint
make staging            # Full staging regression + smoke test

File-Specific Requirements

  • Controllers (skillhub-app/controller/) are transport only: extract auth context, bind request params, wrap responses. No business logic.
  • App Services (skillhub-app/service/) orchestrate workflows. Do not embed complex read-model assembly here — extract to query repositories.
  • Query Repositories (skillhub-app/repository/) handle read-model joins and presentation projection. Named like *QueryRepository.
  • Domain Services (skillhub-domain/*/service/) contain business rules and state transitions. Return domain objects, not DTOs.
  • Repository Interfaces are defined in skillhub-domain, implemented in skillhub-infra.
  • Domain Exceptions use LocalizedDomainException for user-facing messages with i18n keys.
  • Package-info files (package-info.java) should exist for all packages.

Development Workflow

Build & Start

make dev-all          # Start full stack: Postgres, Redis, MinIO, backend, frontend
make dev-all-down     # Stop everything
make dev-all-reset    # Full reset (clears data volumes)
make dev-status       # Check service status
make dev-server-restart  # Restart backend after Java changes

Access points:

  • Web UI: http://localhost:3000
  • Backend API: http://localhost:8080
  • Scanner: http://localhost:8000

Local mock users (no password needed):

User ID Role Header
local-user Regular user X-Mock-User-Id: local-user
local-admin Super admin X-Mock-User-Id: local-admin

Bootstrap admin (password-based, local profile):

  • Username: admin / Password: ChangeMe!2026
  • Disable with BOOTSTRAP_ADMIN_ENABLED=false

Lint & Format

# Backend: enforced by Maven build (no separate lint target)
# Frontend:
make lint-web           # ESLint check
make typecheck-web      # TypeScript check

Testing

make test-backend-app         # Backend unit tests (skillhub-app + dependencies)
make test-backend             # All backend module tests
make test-frontend            # Frontend unit tests (Vitest)
make test-e2e-frontend        # Frontend E2E tests (Playwright)
make test-e2e-smoke-frontend  # Frontend E2E smoke tests
./scripts/smoke-test.sh       # API smoke test
make namespace-smoke          # Namespace workflow smoke test

Staging (Pre-PR Regression)

make staging          # Build backend Docker image + frontend static + smoke test
make staging-down     # Tear down
SERVICE=web make staging-logs  # View Nginx logs

Staging validates the containerized deployment path:

  • Backend: built as Docker image from local source
  • Frontend: built as static files, served by Nginx
  • Dependencies: same Postgres/Redis/MinIO as local dev

Parallel Agent Workflow

For parallel development with isolated worktrees:

make parallel-init TASK=feature-name

Creates dedicated Claude, Codex, and integration worktrees as sibling directories. See docs/13-parallel-workflow.md for details.

PR Submission

PR Title Format

Use conventional commit style:

<type>(<scope>): <description>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • test: Adding or updating tests
  • refactor: Code restructuring (no behavior change)
  • chore: Build, CI, or maintenance tasks

Scopes: Module or domain name (e.g., auth, search, publish, review, namespace)

Examples:

feat(auth): add local account login
fix(publish): resolve null pointer in skill validation
docs(deploy): clarify runtime image usage
test(namespace): add membership service tests
refactor(review): extract query repository for governance list
chore(ci): add parallel workflow scripts

Pre-PR Checklist

  • Backend tests pass: make test-backend-app
  • Frontend typecheck passes: make typecheck-web
  • If API changed: make generate-api was run and web/src/api/generated/schema.d.ts is committed
  • Smoke test passes: make staging
  • Follow existing module boundaries and dependency direction
  • Add/update tests for new behavior
  • Update docs when APIs, auth flows, deployment, or operator workflows change

Core Concepts

Backend Clean Architecture

app → domain, auth, search, storage, infra, notification
infra → domain          # implements domain repository interfaces
auth → domain
search → domain
notification → domain
storage → (independent) # pure SPI

Design intent: skillhub-domain is the innermost layer. It defines entities, repository interfaces, and domain services without depending on infra, auth, search, or storage.

Code reality: skillhub-domain declares a Maven dependency on skillhub-storage, and several domain services (SkillHardDeleteService, SkillDownloadService, SkillPublishService, SkillGovernanceService, SkillQueryService, SkillStorageDeletionCompensationService) import com.iflytek.skillhub.storage.ObjectStorageService. This is an existing deviation from the ideal. New code should avoid adding further cross-module dependencies from domain.

Repository / Query Boundary

When adding new read logic, follow these rules:

  1. Domain repository ports (skillhub-domain): Aggregate reads, state transitions, rule evaluation. Used by domain services.
  2. App query repositories (com.iflytek.skillhub.repository): Read-model assembly that joins multiple sources, presentation projection. Used by controllers and app services.
  3. App services (com.iflytek.skillhub.service): Workflow orchestration. Should express "what this endpoint does", not "how it assembles DTOs".
  4. Direct SQL / EntityManager: Only when necessary, with class-level comment explaining why.

Do not add complex read-model assembly logic inside app services. Extract it into a query repository when it joins multiple sources, does presentation projection, or is reused across services.

Skill Lifecycle

SkillVersionStatus values: DRAFT, SCANNING, SCAN_FAILED, UPLOADED, PENDING_REVIEW, PUBLISHED, REJECTED, YANKED.

SkillStatus enum values: ACTIVE, HIDDEN, ARCHIVED.

The design doc (docs/14-skill-lifecycle.md) specifies that hidden should be treated as a governance overlay rather than a lifecycle state. The current code still defines SkillStatus.HIDDEN in the enum. Follow the design doc's intent for new code.

Key transitions:

  • Normal user first upload → PENDING_REVIEW (no initial DRAFT)
  • SUPER_ADMIN first upload → PUBLISHED (direct publish)
  • Review approve → PENDING_REVIEWPUBLISHED (updates latestVersionId)
  • Review reject → PENDING_REVIEWREJECTED
  • Withdraw review → PENDING_REVIEWUPLOADED (also deletes pending review_task)
  • Yank → PUBLISHEDYANKED (must recalculate latestVersionId)
  • Hide/restore → independent hidden flag (governance overlay)
  • Archive/Unarchive → ACTIVEARCHIVED (container state)

Namespace Coordinate System

SkillHub uses @{namespace_slug}/{skill_slug}:

  • @global/my-skill — Platform-level public namespace
  • @my-team/my-skill — Team/department namespace

ClawHub CLI compatibility maps:

SkillHub Canonical Slug
@global/my-skill my-skill
@team-name/my-skill team-name--my-skill

Authentication

  • Web: OAuth2 (GitHub) + local password auth
  • CLI: OAuth Device Flow (web authorization → CLI credentials)
  • Programmatic: API tokens (prefix-based secure hashing)
  • Session: Spring Session + Redis

RBAC

Platform roles: SUPER_ADMIN, SKILL_ADMIN, USER_ADMIN, AUDITOR Namespace roles: OWNER, ADMIN, MEMBER

Skill Package Protocol

  • Root: SKILL.md with YAML frontmatter (name, description required)
  • Allowed extensions (50+ types): .md, .txt, .json, .yaml, .yml, .js, .ts, .py, .sh, .png, .jpg, .svg, and many more (see SkillPackagePolicy.ALLOWED_EXTENSIONS)
  • Limits: 10MB per file, 100MB total, 500 files max
  • File type signatures validated (PNG magic bytes, SVG content check, etc.)

Frontend State Management

  • TanStack Query (@tanstack/react-query): All server state (API data)
  • Zustand: Local/UI state (theme, sidebar, modals)
  • Never use useEffect for data fetching

Frontend Component Composition

  • Radix UI primitives: @radix-ui/react-dropdown-menu, @radix-ui/react-select
  • class-variance-authority (cva) for component variants
  • clsx + tailwind-merge for class merging
  • cn() utility: web/src/shared/lib/utils.ts
  • shadcn/ui is NOT used as a library — only Radix primitives + utility composition

Common Patterns

Code Style

Java:

  • User identity type is always String throughout the codebase
  • Use Java 21 features (records, pattern matching, virtual threads)
  • Follow existing naming patterns in the domain layer
  • Error strings for DomainBadRequestException, etc. should be clear and actionable

TypeScript:

  • Strict mode. No any types.
  • Use generated OpenAPI types for all API interactions.
  • Feature-Sliced Design: place code at the lowest appropriate layer.

Testing Philosophy

  • Backend: JUnit 5 + Mockito + AssertJ
  • Frontend: Vitest for unit tests, Playwright for E2E
  • Use make test-backend-app (includes -am for dependent modules) — never run ./mvnw -pl skillhub-app clean test directly, as it can use stale Maven cache artifacts
  • Test behaviors, not implementations
  • Use Spring Boot test slices where possible (@WebMvcTest, @DataJpaTest)

Frontend Testing

make test-frontend            # Vitest unit tests
make test-e2e-frontend        # Playwright E2E
make test-e2e-smoke-frontend  # Playwright smoke (subset of E2E)

Logging Conventions

  • Backend: SLF4J + Spring Boot logging. Use structured logging with MDC for request tracing.
  • Frontend: console.error for errors, console.warn for deprecations, avoid console.log in production code.
  • Scanner: Python logging module with structured JSON output.

Security

  • API tokens are stored as prefix-based secure hashes, never in plaintext
  • OAuth2 client secrets and other secrets must not be logged or committed
  • User identity is String (supports external SSO/OIDC/SCIM identity sources)
  • The bootstrap admin (BOOTSTRAP_ADMIN_ENABLED) is for zero-config quickstart only

Search Tips

# Find all REST endpoints
rg "@(Get|Post|Put|Delete|Patch)Mapping" --type java

# Find domain services
rg "class.*Service" server/skillhub-domain/

# Find query repositories
rg "QueryRepository" server/skillhub-app/

# Find controllers
rg "@RestController" server/skillhub-app/

# Find RBAC role checks
rg "@PreAuthorize" server/skillhub-app/

# Find skill validation logic
rg "SkillPackage" server/skillhub-domain/

# Find frontend features
rg "export" web/src/features/

# Find OpenAPI type generation script
rg "generate-api" web/package.json

# Find event listeners
rg "@EventListener" server/

Design Philosophy

  • Hub first: The server-side registry is the core product; CLI and agent integrations are entry capabilities
  • Compatibility first: Support SKILL.md format and common directory conventions
  • Layered architecture: Search and object storage must have replaceable boundaries (SPI pattern)
  • Open authentication: OAuth2-based, extensible to multiple providers beyond GitHub
  • Audit first: Enterprise distribution requires audit trails for publish, download, delete, and authorization

References

Essential Files

  • Makefile — All build/test/dev automation targets
  • CONTRIBUTING.md — Contribution guidelines and commit style
  • CODE_OF_CONDUCT.md — Community standards
  • server/pom.xml — Maven parent POM, module definitions, dependency versions
  • web/package.json — Frontend dependencies and scripts
  • .github/workflows/pr-tests.yml — PR test pipeline
  • .github/workflows/publish-images.yml — Docker image publish to GHCR

Key Directories

  • server/skillhub-domain/ — Core domain (entities, services, rules)
  • server/skillhub-app/controller/ — REST API endpoints
  • server/skillhub-app/repository/ — Query repositories
  • server/skillhub-app/compat/ — ClawHub CLI compatibility layer
  • server/skillhub-auth/ — Authentication and authorization
  • web/src/features/ — Frontend feature modules
  • web/src/api/generated/ — Generated OpenAPI types
  • docs/ — Design documents
  • scripts/ — Build, test, and deployment scripts

Important Scripts

  • scripts/smoke-test.sh — Basic API smoke test
  • scripts/namespace-smoke-test.sh — Namespace workflow test
  • scripts/check-openapi-generated.sh — Verify frontend SDK is current
  • scripts/validate-release-config.sh — Validate production env config
  • scripts/dev-process.sh — Local process manager (PID-based lifecycle)
  • scripts/parallel-init.sh — Create isolated worktrees for parallel development

Design Documents

  • 00-product-direction.md — Product positioning, MVP scope, coordinate system
  • 01-system-architecture.md — System architecture, module structure, dependency rules
  • 02-domain-model.md — Domain entities and relationships
  • 03-authentication-design.md — OAuth2, CLI Device Flow, API tokens
  • 04-search-architecture.md — Search SPI and implementations
  • 05-business-flows.md — Business process flows
  • 06-api-design.md — API contract specifications
  • 07-skill-protocol.md — SKILL.md format, package structure, CLI compatibility
  • 08-frontend-architecture.md — Frontend patterns and conventions
  • 14-skill-lifecycle.md — Skill state model (authoritative)
  • dev-workflow.md — Local development workflow guide

External Resources