Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion packages/autoskills/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface RegistryEntry {
sha256: Record<string, string>;
bundleHash: string;
review: {
status: "approved" | "flagged";
status: "approved" | "flagged" | "skipped";
flags: string[];
summary: string;
model: string;
Expand Down
5 changes: 5 additions & 0 deletions packages/autoskills/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,13 @@ export function collectSkills({
}
}

const hasSvelteShadcn = combos.some((c) => c.id === "svelte-shadcn");

for (const tech of detected) {
for (const skill of tech.skills) {
if (hasSvelteShadcn && skill === "shadcn/ui/shadcn") {
continue;
}
addSkill(skill, tech.name);
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/autoskills/scripts/sync-skills.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import { SKILLS_MAP, COMBO_SKILLS_MAP, FRONTEND_BONUS_SKILLS } from "../skills-m
import { parseSkillPath } from "../lib.ts";
import { bold, cyan, dim, green, log, red, yellow } from "../colors.ts";

process.loadEnvFile();
if (typeof process.loadEnvFile === "function") {
process.loadEnvFile();
}

// ── Config ───────────────────────────────────────────────────

Expand Down
40 changes: 35 additions & 5 deletions packages/autoskills/skills-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ export const SKILLS_MAP: Technology[] = [
configFiles: ["svelte.config.js"],
},
skills: [
"ejirocodes/agent-skills/svelte5-best-practices",
"sveltejs/ai-tools/svelte-code-writer",
"spences10/skills/svelte-runes",
"spences10/skills/sveltekit-structure",
"spences10/skills/svelte-core-bestpractices",
"spences10/skills/sveltekit-data-flow",
"spences10/skills/svelte-components",
"spences10/skills/svelte-layerchart",
],
},
{
Expand Down Expand Up @@ -633,8 +637,17 @@ export const SKILLS_MAP: Technology[] = [
configFiles: ["go.mod", "go.work"],
},
skills: [
"affaan-m/everything-claude-code/golang-patterns",
"affaan-m/everything-claude-code/golang-testing",
"samber/cc-skills-golang/golang-code-style",
"samber/cc-skills-golang/golang-concurrency",
"samber/cc-skills-golang/golang-context",
"samber/cc-skills-golang/golang-database",
"samber/cc-skills-golang/golang-error-handling",
"samber/cc-skills-golang/golang-performance",
"samber/cc-skills-golang/golang-testing",
"samber/cc-skills-golang/golang-observability",
"samber/cc-skills-golang/golang-security",
"samber/cc-skills-golang/golang-structs-interfaces",
"seba3567/go-fiber",
],
},
{
Expand Down Expand Up @@ -917,12 +930,23 @@ export const SKILLS_MAP: Technology[] = [
},
{
id: "postgres-ruby",
name: "PostgreSQL",
name: "PostgreSQL (Ruby)",
detect: {
gems: ["pg"],
},
skills: [],
},
{
id: "postgresql",
name: "PostgreSQL",
detect: {
packages: ["pg", "postgres", "pg-promise"],
},
skills: [
"neondatabase/postgres-skills/postgres-best-practices",
"github/awesome-copilot/sql-optimization",
],
},
{
id: "python",
name: "Python",
Expand Down Expand Up @@ -1238,6 +1262,12 @@ export const COMBO_SKILLS_MAP: ComboSkill[] = [
requires: ["react", "shadcn"],
skills: ["shadcn/ui/shadcn", "vercel-labs/agent-skills/react-best-practices"],
},
{
id: "svelte-shadcn",
name: "Svelte + shadcn-svelte",
requires: ["svelte", "shadcn"],
skills: ["huntabyte/shadcn-svelte/shadcn-svelte"],
},
{
id: "tailwind-shadcn",
name: "Tailwind CSS + shadcn/ui",
Expand Down
74 changes: 74 additions & 0 deletions packages/autoskills/skills-registry/go-fiber/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
name: go-fiber
description: "Use when building Go Fiber services, including routing, middleware, WebSockets, request validation, structured errors, and performance tuning."
license: MIT
metadata:
author: cubis-foundry
version: "3.0"
compatibility: Claude Code, Codex, GitHub Copilot
---

# Go Fiber v3

## Purpose

Production-grade guidance for building high-performance HTTP APIs and real-time services using Go Fiber v3. Fiber is built on top of fasthttp, delivering Express-inspired ergonomics with Go's concurrency model and near-zero allocation routing.

## When to Use

- Building REST or JSON APIs with Go Fiber v3.
- Configuring middleware stacks for logging, auth, CORS, rate limiting, and recovery.
- Setting up WebSocket endpoints alongside HTTP routes.
- Structuring large Fiber applications with route groups and modular handlers.
- Optimizing request throughput, reducing allocations, and benchmarking Fiber services.
- Migrating from Express.js or net/http to Fiber.

## Instructions

1. **Initialize the Fiber app with explicit configuration** -- create the app with `fiber.New(fiber.Config{...})` and set `ErrorHandler`, `ReadTimeout`, `WriteTimeout`, `IdleTimeout`, and `BodyLimit` explicitly. Leaving these at defaults in production leads to resource exhaustion under load.

2. **Use the Fiber v3 context API, not fasthttp directly** -- access request data through `c.Params()`, `c.Query()`, `c.Body()`, and `c.JSON()`. Reaching into `c.Context()` for raw fasthttp access breaks Fiber's middleware chain and makes code fragile across version upgrades.

3. **Structure routes with `app.Group()` and mount sub-routers** -- group related endpoints under a common prefix (e.g., `/api/v1`) and attach group-level middleware for auth or rate limiting. This keeps route registration readable and lets you apply cross-cutting concerns at the right scope without global middleware bloat.

4. **Build middleware as `fiber.Handler` functions that call `c.Next()`** -- each middleware must either call `c.Next()` to continue the chain or return an error/response to short-circuit. Place recovery middleware first, then logging, then auth, then route-specific middleware. Order determines execution sequence and matters for correctness.

5. **Validate request bodies with a dedicated validator** -- use `go-playground/validator/v10` or a similar library and bind it through a reusable `validate()` helper that calls `c.BodyParser()` then validates the struct. Return `400` with structured field errors. Do not scatter validation logic across handlers because it becomes inconsistent and hard to test.

6. **Return structured error responses with a custom `ErrorHandler`** -- define an `ErrorHandler` in the app config that maps `*fiber.Error`, sentinel errors, and validation errors to consistent JSON envelopes with `code`, `message`, and optional `details`. This centralizes error formatting and prevents handlers from inventing their own response shapes.

7. **Use `c.Locals()` to pass request-scoped data through middleware** -- store authenticated user, request ID, or trace context in locals. Retrieve with type-safe helper functions. Do not use global variables or package-level state for per-request data because fasthttp reuses contexts across connections.

8. **Handle WebSocket connections with `websocket.New()`** -- register WebSocket routes using `app.Get("/ws", websocket.New(handler))` and guard them with an upgrade-check middleware. Manage connection lifecycles with ping/pong deadlines, read limits, and graceful close. Do not mix WebSocket handler logic with REST handlers.

9. **Implement graceful shutdown with `os.Signal` and `app.ShutdownWithTimeout()`** -- listen for `SIGINT`/`SIGTERM` in a goroutine, then call `app.ShutdownWithTimeout(timeout)` to drain in-flight requests. This prevents dropped connections during deploys and lets health checks report the correct state.

10. **Write handler tests using `app.Test()` with `httptest.NewRequest`** -- construct a Fiber app in the test, register the handler under test, build an `*http.Request`, and call `app.Test(req)`. Assert status codes, headers, and JSON bodies. This avoids spinning up a real server and keeps tests fast and deterministic.

11. **Benchmark with `testing.B` and Fiber's built-in test helper** -- write benchmarks that exercise the full middleware chain per request. Use `b.ReportAllocs()` to track allocation regressions. Profile with `pprof` for CPU and heap hotspots before optimizing.

12. **Configure CORS, Helmet, and Rate Limiter middleware from the official packages** -- use `fiber/middleware/cors`, `fiber/middleware/helmet`, and `fiber/middleware/limiter` with explicit allow-lists and limits. Do not rely on permissive defaults (`AllowOrigins: "*"`) in production because it disables credential-based CORS.

13. **Use `fiber/middleware/recover` as the outermost middleware** -- recover catches panics inside handlers and converts them to 500 responses. Without it, a panic in any handler crashes the entire process. Place it before all other middleware so it wraps the full chain.

14. **Serve static files and templates through Fiber's built-in engines** -- use `app.Static()` for file serving with cache headers and `fiber/template/*` engines for server-side rendering. Configure `MaxAge` and `Compress` to reduce bandwidth. Do not serve static files through custom handlers because it bypasses Fiber's optimized file serving.

15. **Propagate `context.Context` for downstream service calls** -- extract the request context with `c.UserContext()` and pass it to database queries, HTTP clients, and gRPC calls. This ensures cancellation propagates when clients disconnect or timeouts fire.

16. **Keep Fiber-specific code at the boundary** -- handlers should parse the request, delegate to a service layer, and format the response. Business logic must not import `gofiber/fiber`. This separation makes logic testable without HTTP concerns and portable across frameworks.

## Output Format

Produces Go source files with Fiber v3 handler signatures, grouped route registration, middleware chains, structured error types, and table-driven handler tests. Includes `go.mod` dependencies and configuration constants where applicable.

## References

Load only what the current step needs.

| File | Load when |
| --- | --- |
| `references/routing.md` | Route registration, groups, parameter parsing, or sub-router mounting needs detail. |
| `references/middleware.md` | Middleware authoring, ordering, or built-in middleware configuration is in scope. |
| `references/error-handling.md` | Custom error handler, structured errors, or panic recovery patterns are needed. |
| `references/testing.md` | Handler testing, integration tests, or benchmark setup is needed. |
| `references/performance.md` | Allocation profiling, fasthttp tuning, or throughput optimization is in scope. |
37 changes: 37 additions & 0 deletions packages/autoskills/skills-registry/go-fiber/evals/assertions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Go Fiber Eval Assertions

## Eval 1: REST API with Middleware Stack

### fiber-app-config
Verifies the Fiber application is initialized with explicit production configuration rather than defaults. The response must show `fiber.New(fiber.Config{...})` with a custom `ErrorHandler` function, timeout settings (`ReadTimeout`, `WriteTimeout`), and a `BodyLimit`. This ensures the service is hardened against resource exhaustion and has centralized error formatting from the start.

### route-grouping-middleware
Verifies routes are organized under a versioned group (`/api/v1`) and middleware is layered in the correct order. Recovery must come first to catch panics, followed by request ID injection, logging, and authentication. Rate limiting should be scoped to specific endpoints, not applied globally. This tests that the response understands middleware ordering semantics and does not apply everything globally.

### validation-binding
Verifies request payloads are validated through struct tags and a validator library, not through ad-hoc checks in the handler. The handler must call `c.BodyParser()` to bind the request body, run validation, and return structured 400 errors with per-field detail. This assertion catches responses that skip validation, validate only at the handler level, or return unstructured error strings.

### custom-error-handler
Verifies a centralized `ErrorHandler` exists that handles different error types (Fiber errors, validation errors, sentinel errors) and maps them to a consistent JSON shape. The response must not have handlers formatting their own error responses in different ways. This tests for production-quality error consistency.

### handler-tests
Verifies tests use Fiber's `app.Test()` helper with `httptest.NewRequest` and follow a table-driven pattern. Tests must cover both create and list endpoints, assert on HTTP status codes and JSON response bodies. This catches responses that skip testing, write only happy-path tests, or spin up a real server for unit tests.

---

## Eval 2: WebSocket Endpoint

### websocket-setup
Verifies the WebSocket route uses the Fiber WebSocket package (`websocket.New()`) and includes an upgrade-check middleware that validates the request is a genuine WebSocket upgrade before allowing connection establishment. This prevents non-WebSocket requests from reaching the handler.

### connection-lifecycle
Verifies WebSocket connections are configured with read limits and ping/pong handlers for liveness detection. The response must set `SetReadLimit` to prevent oversized messages and configure pong/ping handlers with deadlines. This ensures connections do not hang indefinitely or accept unbounded payloads.

### broadcast-pattern
Verifies a hub or registry pattern manages active connections with thread safety. The REST endpoint must be able to push messages to all connected WebSocket clients through this shared structure. This tests that the response correctly bridges HTTP and WebSocket communication without race conditions.

### graceful-disconnect
Verifies the handler properly cleans up when a client disconnects. The connection must be removed from the hub, close frames should be sent, and the read loop must break on error. This catches responses that leak connections or fail silently on client disconnect.

### rest-and-ws-tests
Verifies both the REST health endpoint and the WebSocket upgrade path are tested. The health test should use `app.Test()` and assert 200. The WebSocket test should verify upgrade behavior or middleware rejection for non-WebSocket requests. This ensures both transport mechanisms have test coverage.
74 changes: 74 additions & 0 deletions packages/autoskills/skills-registry/go-fiber/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[
{
"id": "go-fiber-rest-middleware",
"prompt": "Build a Go Fiber v3 REST API for a task management service with the following requirements: Create CRUD endpoints for tasks under /api/v1/tasks with proper route grouping. Include a middleware stack with recovery, request ID injection, structured JSON logging, JWT authentication, and rate limiting. Validate request bodies using go-playground/validator. Return structured JSON error responses from a custom ErrorHandler. Implement graceful shutdown. Include table-driven tests for the create and list endpoints.",
"assertions": [
{
"id": "fiber-app-config",
"type": "contains_concept",
"expected": "Fiber app is created with fiber.New(fiber.Config{...}) including a custom ErrorHandler, ReadTimeout, WriteTimeout, and BodyLimit configuration",
"weight": 1.0
},
{
"id": "route-grouping-middleware",
"type": "contains_concept",
"expected": "Routes are organized with app.Group('/api/v1') and middleware is applied in the correct order: recovery first, then request ID, logging, and auth middleware on the group, with rate limiter on specific routes",
"weight": 1.0
},
{
"id": "validation-binding",
"type": "contains_concept",
"expected": "Request structs have validate tags, c.BodyParser() is called to parse the body, and a validator instance validates the struct with structured field-level error responses returned as 400 JSON",
"weight": 1.0
},
{
"id": "custom-error-handler",
"type": "contains_concept",
"expected": "A custom ErrorHandler function is defined that checks for *fiber.Error, validation errors, and sentinel errors, mapping each to a consistent JSON envelope with code, message, and optional details fields",
"weight": 1.0
},
{
"id": "handler-tests",
"type": "contains_concept",
"expected": "Tests use app.Test() with httptest.NewRequest to exercise the create and list endpoints, asserting on status codes and JSON response bodies in a table-driven pattern with t.Run subtests",
"weight": 1.0
}
]
},
{
"id": "go-fiber-websocket",
"prompt": "Create a Go Fiber v3 service that serves both REST endpoints and WebSocket connections. The REST part should have a GET /api/health endpoint and a POST /api/messages endpoint that publishes messages. The WebSocket part at /ws should upgrade connections with a middleware check, manage connection lifecycles with ping/pong, broadcast messages from the REST endpoint to all connected WebSocket clients, handle client disconnection gracefully, and set read limits. Include tests for both the REST health endpoint and a test that verifies the WebSocket upgrade handshake.",
"assertions": [
{
"id": "websocket-setup",
"type": "contains_concept",
"expected": "WebSocket route is registered with app.Get('/ws', websocket.New(handler)) and an upgrade-check middleware verifies the websocket upgrade header before allowing the connection",
"weight": 1.0
},
{
"id": "connection-lifecycle",
"type": "contains_concept",
"expected": "WebSocket handler sets read deadline, read limit (SetReadLimit), and configures ping/pong handlers with SetPongHandler or SetPingHandler for connection liveness detection",
"weight": 1.0
},
{
"id": "broadcast-pattern",
"type": "contains_concept",
"expected": "A connection hub or registry manages active WebSocket connections with thread-safe add/remove operations using a mutex or channel, and the REST POST endpoint publishes messages through this hub to all connected clients",
"weight": 1.0
},
{
"id": "graceful-disconnect",
"type": "contains_concept",
"expected": "The WebSocket handler defers connection removal from the hub and connection close, handles read errors by breaking the read loop, and sends close frames before disconnecting",
"weight": 1.0
},
{
"id": "rest-and-ws-tests",
"type": "contains_concept",
"expected": "Tests verify the health endpoint returns 200 with app.Test(), and a separate test verifies the WebSocket upgrade path returns 101 or tests the upgrade middleware rejection for non-WebSocket requests",
"weight": 1.0
}
]
}
]
Loading