### Basic Usage
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/route-handlers.md
Demonstrates the basic setup for GET and POST requests using `route.ts` files.
```APIDOC
## GET /api/users
### Description
Handles GET requests to retrieve users.
### Method
GET
### Endpoint
`/api/users`
### Response
#### Success Response (200)
- `users` (array) - A list of users.
#### Response Example
```json
[
{
"id": "1",
"name": "John Doe"
}
]
```
## POST /api/users
### Description
Handles POST requests to create a new user.
### Method
POST
### Endpoint
`/api/users`
### Parameters
#### Request Body
- `body` (object) - Required - The user data to create.
### Request Example
```json
{
"name": "Jane Doe"
}
```
### Response
#### Success Response (201)
- `user` (object) - The newly created user.
#### Response Example
```json
{
"id": "2",
"name": "Jane Doe"
}
```
```
--------------------------------
### Dockerfile Setup
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/references/dockerfile.md
This Dockerfile configures a Node.js 20 environment, installs development and network tools, sets up a non-root user, installs Claude Code, and configures ZSH with fzf and Powerlevel10k.
```dockerfile
FROM node:20
ARG TZ
ENV TZ="$TZ"
ARG CLAUDE_CODE_VERSION=latest
# Install basic development tools and iptables/ipset
RUN apt-get update && apt-get install -y --no-install-recommends \
less \
git \
procps \
sudo \
fzf \
zsh \
man-db \
unzip \
gnupg2 \
gh \
iptables \
ipset \
iproute2 \
dnsutils \
aggregate \
jq \
nano \
vim \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Ensure default node user has access to /usr/local/share
RUN mkdir -p /usr/local/share/npm-global && \
chown -R node:node /usr/local/share
ARG USERNAME=node
# Persist bash history.
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
&& mkdir /commandhistory \
&& touch /commandhistory/.bash_history \
&& chown -R $USERNAME /commandhistory
# Set `DEVCONTAINER` environment variable to help with orientation
ENV DEVCONTAINER=true
# Create workspace and config directories and set permissions
RUN mkdir -p /workspace /home/node/.claude && \
chown -R node:node /workspace /home/node/.claude
WORKDIR /workspace
ARG GIT_DELTA_VERSION=0.18.2
RUN ARCH=$(dpkg --print-architecture) && \
wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
# Set up non-root user
USER node
# Install global packages
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
ENV PATH=$PATH:/usr/local/share/npm-global/bin
# Set the default shell to zsh rather than sh
ENV SHELL=/bin/zsh
# Set the default editor and visual
ENV EDITOR=nano
ENV VISUAL=nano
# Default powerline10k theme
ARG ZSH_IN_DOCKER_VERSION=1.2.0
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
-p git \
-p fzf \
-a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
-a "source /usr/share/doc/fzf/examples/completion.zsh" \
-a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
-x
# Install Claude
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
# Copy and set up firewall script
COPY init-firewall.sh /usr/local/bin/
USER root
RUN chmod +x /usr/local/bin/init-firewall.sh && \
echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
chmod 0440 /etc/sudoers.d/node-firewall
USER node
```
--------------------------------
### Install ts-dev-kit Plugin
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Use these commands to add the ts-dev-kit plugin to your marketplace and then install it.
```bash
/plugin marketplace add jgamaraalv/ts-dev-kit
```
```bash
/plugin install ts-dev-kit@ts-dev-kit
```
--------------------------------
### Install Event: Pre-cache Assets
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/service-worker/SKILL.md
Use the 'install' event to pre-cache static assets. `event.waitUntil()` ensures the installation process completes successfully before the service worker becomes active. If the promise rejects, installation fails.
```javascript
// sw.js
const CACHE_NAME = "v1";
const PRECACHE_URLS = ["/", "/index.html", "/style.css", "/app.js"];
self.addEventListener("install", (event) => {
event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(PRECACHE_URLS)));
});
```
--------------------------------
### Start Docker Daemon on Linux
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
Starts the Docker daemon using systemctl on Linux systems. This is used when the Docker daemon is installed but not running.
```bash
sudo systemctl start docker
```
--------------------------------
### Install all skills using skills.sh
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install all skills from the ts-dev-kit using the skills.sh script. This method installs skills only and works with various editors.
```bash
npx skills add jgamaraalv/ts-dev-kit
```
--------------------------------
### Provider Setup for Next.js App Router
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/tanstack-query/references/ssr-nextjs.md
Set up a `QueryClientProvider` in `app/providers.tsx` for the App Router. This example uses a singleton pattern for the query client on the browser to maintain state across renders.
```tsx
'use client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState } from 'react'
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // must be > 0 for SSR
},
},
})
}
let browserQueryClient: QueryClient | undefined
function getQueryClient() {
if (typeof window === 'undefined') {
// Server: always make a new query client
return makeQueryClient()
}
// Browser: reuse singleton
if (!browserQueryClient) browserQueryClient = makeQueryClient()
return browserQueryClient
}
export default function Providers({ children }: { children: React.ReactNode }) {
const queryClient = getQueryClient()
return (
{children}
)
}
```
--------------------------------
### Start Docker on macOS
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
Opens the Docker application on macOS to start the Docker daemon. This is used when Docker is installed but not running.
```bash
open -a Docker
```
--------------------------------
### Install context7 MCP Server
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install the context7 MCP server using the 'mcp add' command. This server is used for querying up-to-date library documentation and does not require an API key.
```bash
claude mcp add context7 -- npx -y @upstash/context7-mcp@latest
```
--------------------------------
### Setup QueryClient and QueryClientProvider
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/tanstack-query/SKILL.md
Demonstrates how to set up the QueryClient with default options and provide it to the application using QueryClientProvider.
```APIDOC
## Setup
```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 min (default is 0)
gcTime: 5 * 60 * 1000, // 5 min (default)
retry: 3, // 3 retries with exponential backoff (default)
refetchOnWindowFocus: true, // default
},
},
})
function App() {
return (
)
}
```
```
--------------------------------
### Example: Get Errors via MCP
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/debug-tricks.md
A concrete example of using curl to request errors from the `/_next/mcp` endpoint. Replace `` with the correct development server port.
```bash
curl -X POST http://localhost:/_next/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"get_errors","arguments":{}}}'
```
--------------------------------
### Interpreting EXPLAIN Output Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/performance.md
This example shows typical output from `EXPLAIN (ANALYZE, BUFFERS)`. Pay attention to actual times, row counts, and buffer usage.
```text
Seq Scan on orders (cost=0.00..45231.00 rows=2000001 width=88)
(actual time=0.028..312.483 rows=2000001 loops=1)
Buffers: shared hit=22727 read=4615
Planning Time: 0.086 ms
Execution Time: 401.123 ms
```
--------------------------------
### Install ts-dev-kit from GitHub
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Clone the ts-dev-kit repository from GitHub and configure the Claude plugin directory.
```bash
git clone https://github.com/jgamaraalv/ts-dev-kit.git
claude --plugin-dir ./ts-dev-kit
```
--------------------------------
### PostgreSQL List Partitioning Setup
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/ddl-schema.md
Sets up a table partitioned by list on a text column, defining partitions for specific regions.
```sql
-- List partitioning
CREATE TABLE orders (id bigint, region text, ...) PARTITION BY LIST (region);
CREATE TABLE orders_br PARTITION OF orders FOR VALUES IN ('BR', 'PT');
CREATE TABLE orders_us PARTITION OF orders FOR VALUES IN ('US', 'CA');
```
--------------------------------
### Integration Test Example with Vitest and Fastify
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/agents/test-generator.md
Shows an integration test for a Fastify application endpoint. Requires setting up the application instance before tests and closing it afterwards. Ensure Fastify and necessary types are installed.
```typescript
import { describe, it, expect, beforeAll, afterAll } from "vitest";
import { buildApp } from "../../app";
import type { FastifyInstance } from "fastify";
describe("GET /health", () => {
let app: FastifyInstance;
beforeAll(async () => { app = await buildApp({ logger: false }); });
afterAll(async () => { await app.close(); });
it("returns ok status", async () => {
const response = await app.inject({ method: "GET", url: "/health" });
expect(response.statusCode).toBe(200);
});
});
```
--------------------------------
### Install skills globally using skills.sh
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install skills from the ts-dev-kit globally using the skills.sh script.
```bash
npx skills add jgamaraalv/ts-dev-kit --global
```
--------------------------------
### Install ts-dev-kit via CLI
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Alternative method to install the ts-dev-kit using the Claude CLI.
```bash
claude plugin install ts-dev-kit --scope user
```
--------------------------------
### Custom Migration SQL Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/drizzle-pg/references/migrations.md
Example of SQL content for a custom migration, including inserting data into the 'users' table.
```sql
-- Custom migration: seed-users
INSERT INTO "users" ("name", "email") VALUES ('Dan', 'dan@example.com');
INSERT INTO "users" ("name", "email") VALUES ('Andrew', 'andrew@example.com');
```
--------------------------------
### Install MCP Plugins
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install recommended MCP servers as Claude Code plugins to enhance skill functionality for tasks like documentation lookup and browser debugging.
```bash
claude plugin add context7
claude plugin add playwright
claude plugin add firecrawl
```
--------------------------------
### List PostgreSQL Extensions
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/psql-cli.md
Use \dx to list installed extensions.
```sql
-- Extensions
\dx -- installed extensions
```
--------------------------------
### Install a specific skill using skills.sh
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install a specific skill from the ts-dev-kit using the skills.sh script.
```bash
npx skills add jgamaraalv/ts-dev-kit --skill fastify-best-practices
```
--------------------------------
### Install TS Dev Kit Skills Only
Source: https://context7.com/jgamaraalv/ts-dev-kit/llms.txt
Install only the skills from TS Dev Kit using the 'skills.sh' utility. This can be used to install all skills, a single skill, or globally.
```bash
# All skills
npx skills add jgamaraalv/ts-dev-kit
# A single skill
npx skills add jgamaraalv/ts-dev-kit --skill fastify-best-practices
# Global install
npx skills add jgamaraalv/ts-dev-kit --global
```
--------------------------------
### Install ts-dev-kit via npm
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install the ts-dev-kit package globally using npm and configure the Claude plugin directory.
```bash
npm install -g @jgamaraalv/ts-dev-kit
claude --plugin-dir ./node_modules/@jgamaraalv/ts-dev-kit
```
--------------------------------
### Dispatch Task Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/execute-task/references/agent-dispatch.md
Example of dispatching an agent to build resource API routes. Specify the agent, model, and a detailed prompt including task, patterns, and success criteria.
```typescript
// Use the agent name as registered in your context.
// Project-scoped: "api-builder". Plugin-scoped: "ts-dev-kit:api-builder".
Task(
description: "Build resource API routes",
subagent_type: "api-builder", // or "ts-dev-kit:api-builder" if plugin-scoped
model: "sonnet",
prompt: """
## Your task
Create REST endpoints for the [feature name]:
- POST /api/ — create a new resource
- GET /api//:id — get resource details
- PATCH /api//:id — update resource
## Existing patterns to follow
Discover from the codebase:
- Route structure: look for existing route handlers and follow the same pattern
- Shared schemas: look for existing schema/type definitions in shared packages
- Use case pattern: look for existing use case or service implementations
## Success criteria
- All endpoints respond with correct status codes
- Request/response validated with shared schemas
- Endpoints follow the project's routing conventions
"""
)
```
--------------------------------
### Multi-Agent Dispatch Plan Example
Source: https://context7.com/jgamaraalv/ts-dev-kit/llms.txt
An example output from the multi-agent-coordinator, detailing a phased dispatch plan for a workflow involving shared types, database schema, and quality gates.
```markdown
# Example output from multi-agent-coordinator:
## Dispatch Plan
### Phase 1: Foundation + Data Layer
> Dependencies: none
> Parallel: yes
#### Task 1.1: Shared types and Zod schemas
- **subagent_type**: typescript-pro
- **model**: haiku
- **isolation**: worktree
- **description**: Define shared user schemas
- **prompt**: |
Create `packages/shared/src/schemas/user.ts` with Zod schemas for CreateUser and User.
Run: pnpm --filter @acme/shared typecheck
#### Task 1.2: Database schema and migration
- **subagent_type**: database-expert
- **model**: sonnet
- **isolation**: worktree
- **description**: Add users table schema
- **prompt**: |
Add `users` table to `apps/api/src/db/schema/users.ts`. Run: npx drizzle-kit generate
### Phase 2: Quality Gates
> Dependencies: Phase 1
> Parallel: no
#### Task 2.1: Verify integration
- **subagent_type**: Bash
- **prompt**: pnpm typecheck && pnpm lint && pnpm build
```
--------------------------------
### Verify Devcontainer Installation
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
These commands can be used to verify that the `.devcontainer` directory and its contents have been created correctly.
```bash
ls -la .devcontainer/
cat .devcontainer/devcontainer.json | head -5
```
--------------------------------
### Fix Commit with Body and Footers Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/conventional-commits/SKILL.md
A detailed example of a fix commit, including a multi-line body and various footers like 'Reviewed-by' and 'Refs'.
```text
fix: prevent racing of requests
Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from latest request.
Remove timeouts which were used to mitigate the racing issue but are
obsolete now.
Reviewed-by: Z
Refs: #123
```
--------------------------------
### Install playwright MCP Server
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/README.md
Install the playwright MCP server using the 'mcp add' command. This server is used for browser automation and E2E testing and does not require an API key.
```bash
claude mcp add playwright -- npx -y @playwright/mcp@latest
```
--------------------------------
### Add Project Dependencies
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
To install project-specific dependencies, add `RUN` commands to the `Dockerfile` before the `USER node` line.
```dockerfile
RUN apt-get update && apt-get install -y your-package
```
--------------------------------
### BullMQ Quick Start: Producer, Consumer, and Events
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/bullmq/SKILL.md
Sets up a basic BullMQ producer to add jobs and a consumer (worker) to process them. Includes global event listeners for job completion and failure.
```typescript
import { Queue, Worker, QueueEvents } from "bullmq";
// --- Producer ---
const queue = new Queue("my-queue", {
connection: { host: "localhost", port: 6379 },
});
await queue.add("job-name", { foo: "bar" });
// --- Consumer ---
const worker = new Worker(
"my-queue",
async (job) => {
// process job
await job.updateProgress(50);
return { result: "done" };
},
{ connection: { host: "localhost", port: 6379 } },
);
worker.on("completed", (job, returnvalue) => {
console.log(`${job.id} completed with`, returnvalue);
});
worker.on("failed", (job, err) => {
console.error(`${job.id} failed with`, err.message);
});
// IMPORTANT: always attach an error handler
worker.on("error", (err) => {
console.error(err);
});
// --- Global event listener (all workers) ---
const queueEvents = new QueueEvents("my-queue", {
connection: { host: "localhost", port: 6379 },
});
queueEvents.on("completed", ({ jobId, returnvalue }) => {
console.log(`Job ${jobId} completed`);
});
queueEvents.on("failed", ({ jobId, failedReason }) => {
console.error(`Job ${jobId} failed: ${failedReason}`);
});
```
--------------------------------
### Request Timing Hook Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/fastify-best-practices/references/hooks-and-lifecycle.md
Measure request duration by recording a start time in `onRequest` and calculating the difference in `onResponse`.
```typescript
fastify.addHook("onRequest", async (request) => {
request.startTime = Date.now();
});
fastify.addHook("onResponse", async (request, reply) => {
request.log.info({ ms: Date.now() - request.startTime }, "request completed");
});
```
--------------------------------
### Cluster Pub/Sub Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/ioredis/references/cluster-sentinel.md
Standard Pub/Sub works in a cluster. One node handles subscriptions, broadcasting messages cluster-wide.
```typescript
const pub = new Cluster(nodes);
const sub = new Cluster(nodes);
sub.on("message", (channel, message) => console.log(channel, message));
await sub.subscribe("news");
pub.publish("news", "hello");
```
--------------------------------
### Prevent Waterfall Chains in API Routes (TypeScript)
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/react-best-practices/references/async-patterns.md
Start independent operations immediately in API routes and Server Actions. This example shows how to fetch authentication and configuration concurrently.
```typescript
export async function GET(request: Request) {
const session = await auth();
const config = await fetchConfig();
const data = await fetchData(session.user.id);
return Response.json({ data, config });
}
```
```typescript
export async function GET(request: Request) {
const sessionPromise = auth();
const configPromise = fetchConfig();
const session = await sessionPromise;
const [config, data] = await Promise.all([configPromise, fetchData(session.user.id)]);
return Response.json({ data, config });
}
```
--------------------------------
### Redis Cluster Initialization
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/ioredis/references/cluster-sentinel.md
Demonstrates how to initialize a new ioredis Cluster instance with startup nodes and perform basic operations like SET and GET.
```APIDOC
## Redis Cluster Initialization
### Description
Initializes a new ioredis Cluster instance with a list of startup nodes. ioredis will automatically discover the rest of the cluster topology.
### Method
`new Cluster(nodes: ClusterNode[], options?: ClusterOptions)`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```typescript
import { Cluster } from "ioredis";
const cluster = new Cluster([
{ host: "127.0.0.1", port: 6380 },
{ host: "127.0.0.1", port: 6381 },
]);
await cluster.set("foo", "bar");
const val = await cluster.get("foo"); // "bar"
```
### Response
#### Success Response (200)
N/A (This is a constructor)
#### Response Example
N/A
```
--------------------------------
### Apply Fastify Best Practices
Source: https://context7.com/jgamaraalv/ts-dev-kit/llms.txt
This command loads Fastify 5 best practices as a reference, covering request lifecycle, anti-patterns, plugin encapsulation, hooks, validation, and serialization. It's automatically used by `api-builder`.
```bash
/fastify-best-practices # load as reference
```
```typescript
// Global error handler (enforced pattern)
fastify.setErrorHandler((error, request, reply) => {
request.log.error(error);
const statusCode = error.statusCode ?? 500;
reply.code(statusCode).send({
error: statusCode >= 500 ? "Internal Server Error" : error.message,
});
});
// Request lifecycle (exact hook order):
// onRequest → preParsing → Content-Type Parsing → preValidation
// → Schema Validation (400 on failure) → preHandler
// → Route Handler → preSerialization → onSend → Response → onResponse
```
--------------------------------
### Mock API Responses with nock
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/tanstack-query/references/testing.md
Use the nock library to mock HTTP requests in your tests. This example shows how to mock a GET request to an API endpoint and assert that the hook fetches the data correctly.
```tsx
import nock from 'nock'
test('fetches data from API', async () => {
nock('http://example.com')
.get('/api/todos')
.reply(200, [{ id: 1, title: 'Test' }])
const { result } = renderHook(() => useTodos(), {
wrapper: createWrapper(),
})
await waitFor(() => expect(result.current.isSuccess).toBe(true))
expect(result.current.data).toEqual([{ id: 1, title: 'Test' }])
})
```
--------------------------------
### Repeatable Read Isolation Level Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/transactions.md
Shows how to set the Repeatable Read isolation level for a transaction. This ensures that all reads within the transaction see a consistent snapshot of the database taken at the start of the transaction.
```sql
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT SUM(balance) FROM accounts; -- snapshot taken here
-- Other transactions' commits won't affect our subsequent reads
COMMIT;
```
--------------------------------
### PostgreSQL Range Partitioning Setup
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/ddl-schema.md
Defines a parent table partitioned by range on a timestamp column and creates monthly partitions with specific value ranges. Includes creating a default partition.
```sql
-- Create parent table
CREATE TABLE metrics (
id bigint GENERATED ALWAYS AS IDENTITY,
recorded_at timestamptz NOT NULL,
value numeric
) PARTITION BY RANGE (recorded_at);
```
```sql
-- Create monthly partitions
CREATE TABLE metrics_2025_01 PARTITION OF metrics
FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
CREATE TABLE metrics_2025_02 PARTITION OF metrics
FOR VALUES FROM ('2025-02-01') TO ('2025-03-01');
```
```sql
-- Default partition (catches anything not matched)
CREATE TABLE metrics_default PARTITION OF metrics DEFAULT;
```
--------------------------------
### Redis Cache Handler for Next.js
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/self-hosting.md
Implement a custom cache handler using Redis for Next.js ISR. This example provides `get`, `set`, and a placeholder for `revalidateTag` to manage shared caching across distributed instances.
```javascript
import { Redis } from "ioredis";
const redis = new Redis(process.env.REDIS_URL);
const CACHE_PREFIX = "nextjs:";
export default class CacheHandler {
constructor(options) {
this.options = options;
}
async get(key) {
const data = await redis.get(CACHE_PREFIX + key);
if (!data) return null;
const parsed = JSON.parse(data);
return {
value: parsed.value,
lastModified: parsed.lastModified,
};
}
async set(key, data, ctx) {
const cacheData = {
value: data,
lastModified: Date.now(),
};
if (ctx?.revalidate) {
await redis.setex(CACHE_PREFIX + key, ctx.revalidate, JSON.stringify(cacheData));
} else {
await redis.set(CACHE_PREFIX + key, JSON.stringify(cacheData));
}
}
async revalidateTag(tags) {
// Implement tag-based invalidation
// This requires tracking which keys have which tags
}
}
```
--------------------------------
### PostgreSQL LATERAL Joins
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/queries.md
Shows how to use LATERAL joins to reference columns from preceding tables in a FROM clause subquery. Includes examples for getting the latest N records per group and using LEFT JOIN LATERAL.
```sql
-- Get latest N orders per customer
SELECT c.name, o.*
FROM customers c,
LATERAL (
SELECT * FROM orders WHERE customer_id = c.id ORDER BY created_at DESC LIMIT 3
) o;
-- With LEFT JOIN LATERAL (include customers with no orders)
SELECT c.name, o.id
FROM customers c
LEFT JOIN LATERAL (
SELECT id FROM orders WHERE customer_id = c.id ORDER BY created_at DESC LIMIT 1
) o ON true;
```
--------------------------------
### Multi-Stage Dockerfile for Yarn 4 Monorepo
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/docker/references/monorepo-dockerfile.md
This Dockerfile uses multiple stages to build a production-ready API image. It starts with a base Node.js image, installs dependencies, builds workspaces, and finally copies only necessary artifacts to a lean runtime image.
```dockerfile
# ============================================
# Stage 1: Base with Yarn 4 Berry
# ============================================
FROM node:22-alpine AS base
ENV YARN_ENABLE_GLOBAL_CACHE=false
WORKDIR /app
# Install Yarn Berry
COPY .yarnrc.yml ./
COPY .yarn/ .yarn/
COPY package.json yarn.lock ./
# ============================================
# Stage 2: Install ALL dependencies (for building)
# ============================================
FROM base AS deps
# Copy all workspace package.json files
COPY apps/api/package.json apps/api/
COPY apps/web/package.json apps/web/
COPY packages/shared/package.json packages/shared/
COPY packages/config/package.json packages/config/
RUN yarn install --immutable
# ============================================
# Stage 3: Build shared packages first
# ============================================
FROM deps AS builder
COPY . .
# Build in dependency order
RUN yarn workspace @myapp/shared build
RUN yarn workspace @myapp/api build
# Or for web: RUN yarn workspace @myapp/web build
# ============================================
# Stage 4: Production runtime (API)
# ============================================
FROM node:22-alpine AS api-runner
WORKDIR /app
# Security: non-root user
RUN addgroup --system app && adduser --system --ingroup app app
# Copy only production dependencies and built output
COPY --from=builder /app/apps/api/dist ./apps/api/dist
COPY --from=builder /app/apps/api/package.json ./apps/api/
COPY --from=builder /app/packages/shared/dist ./packages/shared/dist
COPY --from=builder /app/packages/shared/package.json ./packages/shared/
COPY --from=builder /app/package.json ./
COPY --from=builder /app/yarn.lock ./
COPY --from=builder /app/.yarnrc.yml ./
COPY --from=builder /app/.yarn/ ./.yarn/
# Install production dependencies only
RUN yarn workspaces focus @myapp/api --production && yarn cache clean
USER app
EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3
CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1
CMD ["node", "apps/api/dist/index.js"]
```
--------------------------------
### PostgreSQL Schema Creation and Usage
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/ddl-schema.md
Shows how to create a new schema, create tables within it, and manage the search path to include the new schema.
```sql
CREATE SCHEMA analytics;
CREATE TABLE analytics.events (...);
```
```sql
-- Search path (which schemas to look in, in order)
SET search_path TO myapp, public;
SHOW search_path;
```
--------------------------------
### Next.js Parallel Routes Setup
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/file-conventions.md
Shows how to set up parallel routes using named slots and how the layout receives these slots as props.
```typescript
app/
├── @analytics/
│ └── page.tsx
├── @sidebar/
│ └── page.tsx
└── layout.tsx # Receives { analytics, sidebar } as props
```
--------------------------------
### Install TS Dev Kit Plugin
Source: https://context7.com/jgamaraalv/ts-dev-kit/llms.txt
Install the TS Dev Kit as a Claude Code plugin via the marketplace or CLI. This installs both agents and skills.
```bash
# Via Claude Code plugin marketplace
/plugin marketplace add jgamaraalv/ts-dev-kit
/plugin install ts-dev-kit@ts-dev-kit
# Or via CLI
claude plugin install ts-dev-kit --scope user
```
--------------------------------
### Basic Fastify Logging Setup
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/fastify-best-practices/references/typescript-and-logging.md
Enable Pino logging in Fastify by setting the `logger` option to `true` or configuring it with a specific log level.
```typescript
const fastify = Fastify({
logger: true, // default Pino with info level
});
// Or with options:
const fastify = Fastify({
logger: {
level: "info",
},
});
```
--------------------------------
### Basic GET and POST Route Handlers
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/route-handlers.md
Define GET and POST request handlers for an API endpoint. The GET handler fetches users, and the POST handler creates a user from the request body.
```typescript
// app/api/users/route.ts
export async function GET() {
const users = await getUsers();
return Response.json(users);
}
export async function POST(request: Request) {
const body = await request.json();
const user = await createUser(body);
return Response.json(user, { status: 201 });
}
```
--------------------------------
### Initialize ioredis Cluster
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/ioredis/references/cluster-sentinel.md
Instantiate a new ioredis Cluster client. Provide startup nodes; ioredis will auto-discover the rest. This is the basic setup for connecting to a Redis Cluster.
```typescript
import { Cluster } from "ioredis";
const cluster = new Cluster([
{ host: "127.0.0.1", port: 6380 },
{ host: "127.0.0.1", port: 6381 },
]);
await cluster.set("foo", "bar");
const val = await cluster.get("foo"); // "bar"
```
--------------------------------
### Select Queries
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/drizzle-pg/references/queries.md
Demonstrates various ways to select data, from basic all-column selects to partial selects, selects with SQL expressions, and using WHERE, ORDER BY, LIMIT, and OFFSET clauses.
```APIDOC
## Select Queries
### Basic Select
Selects all columns from a table.
```typescript
// All columns
await db.select().from(users);
// Partial select (flat result)
await db.select({ id: users.id, name: users.name }).from(users);
// With SQL expression
await db
.select({
id: users.id,
lowerName: sql`lower(${users.name})`.as("lower_name"),
})
.from(users);
```
### Select with Filtering, Ordering, and Pagination
Applies WHERE, ORDER BY, LIMIT, and OFFSET clauses to refine query results.
```typescript
await db.select().from(users)
.where(eq(users.id, 42))
.orderBy(asc(users.name))
.limit(10)
.offset(20);
// Multiple order columns
.orderBy(desc(users.createdAt), asc(users.name))
```
### Conditional WHERE Clause
Builds WHERE clauses dynamically based on input conditions.
```typescript
async function getProducts({ name, category, maxPrice }: Filters) {
const filters: SQL[] = [];
if (name) filters.push(ilike(products.name, `%${name}%`));
if (category) filters.push(eq(products.category, category));
if (maxPrice) filters.push(lte(products.price, maxPrice));
return db
.select()
.from(products)
.where(and(...filters));
}
```
### Subqueries
Utilizes subqueries within a select statement.
```typescript
const subquery = db
.select({ avgPrice: sql`avg(${products.price})`.as("avg_price") })
.from(products)
.as("sub");
await db.select().from(subquery);
```
### WITH Clause (CTEs)
Implements Common Table Expressions (CTEs) for complex queries.
```typescript
const topUsers = db.$with("top_users").as(db.select().from(users).where(gt(users.score, 100)));
await db.with(topUsers).select().from(topUsers);
```
### DISTINCT Clause
Selects unique rows, with an option for `DISTINCT ON` (PostgreSQL specific).
```typescript
await db.selectDistinct().from(users);
await db.selectDistinctOn([users.name]).from(users); // PG-specific
```
### Aggregations
Performs aggregate functions like COUNT and AVG, with GROUP BY and HAVING clauses.
```typescript
await db
.select({
category: products.category,
count: sql`count(*)`.mapWith(Number),
avgPrice: sql`avg(${products.price})`.mapWith(Number),
})
.from(products)
.groupBy(products.category)
.having(sql`count(*) > 5`);
```
### Prepared Statements
Defines and executes prepared statements for efficiency and security.
```typescript
const prepared = db
.select()
.from(users)
.where(eq(users.id, sql.placeholder("id")))
.prepare("get_user");
await prepared.execute({ id: 42 });
```
```
--------------------------------
### Simple Fix Commit Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/conventional-commits/SKILL.md
A basic example of a commit message for a bug fix.
```text
fix: prevent racing of requests
```
--------------------------------
### PostgreSQL EXPLAIN Options
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/performance.md
Use `EXPLAIN (ANALYZE, BUFFERS)` for real data analysis. Other options provide different levels of detail or output formats.
```sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...;
```
```sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT ...;
```
```sql
EXPLAIN (ANALYZE, BUFFERS, SETTINGS) SELECT ...;
```
```sql
EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT ...;
```
--------------------------------
### PostgreSQL BRIN Index Examples
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/indexes.md
Shows how to create BRIN indexes, which have a small footprint and are effective for columns with values correlated to their physical storage order, like timestamps on append-only tables. Avoid BRIN for frequently updated or randomly distributed data.
```sql
CREATE INDEX idx_logs_created ON logs USING BRIN (created_at);
```
```sql
-- pages_per_range controls granularity (default 128)
CREATE INDEX idx_metrics_time ON metrics USING BRIN (recorded_at) WITH (pages_per_range = 32);
```
--------------------------------
### PostgreSQL GiST Index Examples
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/indexes.md
Demonstrates creating GiST indexes for geometric types, range types, full-text search, and PostGIS geometry. Use GiST for custom index types and specialized data.
```sql
CREATE INDEX idx_locations_point ON locations USING GIST (coordinates);
-- Query: SELECT * FROM locations ORDER BY coordinates <-> '(0,0)'::point LIMIT 10;
```
```sql
-- Range type (no overlap)
CREATE INDEX idx_reservations_period ON reservations USING GIST (period);
-- Query: WHERE period && '[2025-01-01, 2025-01-07)'::daterange
```
```sql
-- Full-text (alternative to GIN — smaller index, slower search)
CREATE INDEX idx_posts_fts ON posts USING GIST (to_tsvector('english', body));
```
```sql
-- PostGIS
CREATE INDEX idx_geom ON places USING GIST (geom);
```
--------------------------------
### Docs Commit with No Body Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/conventional-commits/SKILL.md
A simple example of a commit message for documentation changes, without a body.
```text
docs: correct spelling of CHANGELOG
```
--------------------------------
### Get PostgreSQL Database Size
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/psql-cli.md
Query pg_size_pretty(pg_database_size(current_database())) to get the human-readable size of the current database.
```sql
-- Database size
SELECT pg_size_pretty(pg_database_size(current_database()));
```
--------------------------------
### Drizzle-ORM Studio Command Options
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/drizzle-pg/references/migrations.md
Options for the 'studio' command, which launches the Drizzle Studio visual database explorer. Specify the '--port' and '--host' for the studio, or use '--config' to point to the config file.
```bash
--port= Studio port (default: 4983)
--host= Studio host (default: localhost)
--config= Config file path
```
--------------------------------
### Run Lighthouse Audit via CLI
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/core-web-vitals/references/tools.md
Install Lighthouse globally and run an audit on a specified URL, outputting the report to an HTML file. Use `--throttling-method=simulate` for reproducible scores.
```bash
npm install -g lighthouse
lighthouse https://example.com --output html --output-path ./report.html
```
--------------------------------
### PostgreSQL Self-Join Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/postgresql/references/queries.md
Illustrates a self-join where a table is joined with itself to query hierarchical data. This example shows employees and their managers.
```sql
-- Self-join
SELECT e.name, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
```
--------------------------------
### Queue Class Operations
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/bullmq/SKILL.md
Demonstrates how to instantiate and use the Queue class for adding jobs with various options, and performing queue-level operations.
```APIDOC
## Queue Class
### Description
Provides methods to interact with a BullMQ queue, including adding jobs with specific options and managing the queue's state.
### Methods
#### `add(name: string, data: any, opts?: AddJobOptions): Promise
Adds a single job to the queue.
**Parameters**
- `name` (string) - The name of the job.
- `data` (any) - The payload of the job.
- `opts` (AddJobOptions) - Optional configuration for the job, such as `delay`, `priority`, `attempts`, `backoff`, `removeOnComplete`, `removeOnFail`.
### Request Example
```ts
const queue = new Queue("paint", { connection });
// Add a job
await queue.add("job-name", { color: "red" });
// Add with options
await queue.add(
"job-name",
{ color: "blue" },
{
delay: 5000, // wait 5s before processing
priority: 1, // lower = higher priority (0 is highest, max 2^21)
attempts: 3, // retry up to 3 times
backoff: { type: "exponential", delay: 1000 },
removeOnComplete: true, // or { count: 100 } to keep last 100
removeOnFail: 1000, // keep last 1000 failed jobs
},
);
```
#### `addBulk(jobs: AddJobOptions[]): Promise
Adds multiple jobs to the queue in a single operation.
**Parameters**
- `jobs` (Array) - An array of job objects, each potentially including `name`, `data`, and `opts`.
### Request Example
```ts
await queue.addBulk([
{ name: "job1", data: { x: 1 } },
{ name: "job2", data: { x: 2 }, opts: { priority: 1 } },
]);
```
#### `pause(): Promise
Pauses the processing of jobs in the queue.
#### `resume(): Promise
Resumes the processing of jobs in the queue.
#### `obliterate(opts?: { force: boolean }): Promise
Removes all data associated with the queue. Requires `force: true` to proceed.
#### `close(): Promise
Closes the connection to the queue and cleans up resources.
```
--------------------------------
### Feature Commit with Scope Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/conventional-commits/SKILL.md
An example of a commit message for a new feature, including a scope to specify the affected section.
```text
feat(lang): add Polish language
```
--------------------------------
### MCP Tool: Get Logs
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/nextjs-best-practices/references/debug-tricks.md
Get the file path to the Next.js development log file, typically located within the `distDir`.
```json
{ "name": "get_logs", "arguments": {} }
```
--------------------------------
### Initialize Firewall Script
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
This script sets up a strict, default-deny firewall policy. It whitelists essential outbound traffic and preserves Docker DNS rules. Ensure this script is executable and run with sudo.
```bash
set -euo pipefail
# Default-deny policy
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Preserve Docker DNS rules
DNS_RULES="$(iptables -S OUTPUT | grep 'dpt:53')"
if [ -n "$DNS_RULES" ]; then
echo "Preserving DNS rules: $DNS_RULES"
echo "$DNS_RULES" | while IFS= read -r line;
do
iptables -I OUTPUT 1 <<< "$line"
done
fi
# Allow loopback
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Whitelist specific domains and services
# Note: Use ipset for efficient CIDR matching. Do NOT add fallback logic.
# npm registry
for domain in "registry.npmjs.org"; do
for ip in $(dig +short "$domain"); do
ipset add npm_registry "$ip"
done
iptables -A OUTPUT -m set --match-set npm_registry dst -j ACCEPT
done
# GitHub API (dynamic IP fetch)
for domain in "api.github.com"; do
for ip in $(dig +short "$domain"); do
ipset add github_api "$ip"
done
iptables -A OUTPUT -m set --match-set github_api dst -j ACCEPT
done
# Anthropic API
for domain in "api.anthropic.com"; do
for ip in $(dig +short "$domain"); do
ipset add anthropic_api "$ip"
done
iptables -A OUTPUT -m set --match-set anthropic_api dst -j ACCEPT
done
# Sentry
for domain in "sentry.io"; do
for ip in $(dig +short "$domain"); do
ipset add sentry "$ip"
done
iptables -A OUTPUT -m set --match-set sentry dst -j ACCEPT
done
# StatsIG
for domain in "statsig.com"; do
for ip in $(dig +short "$domain"); do
ipset add statsig "$ip"
done
iptables -A OUTPUT -m set --match-set statsig dst -j ACCEPT
done
# VS Code Marketplace
for domain in "marketplace.visualstudio.com"; do
for ip in $(dig +short "$domain"); do
ipset add vscode_marketplace "$ip"
done
iptables -A OUTPUT -m set --match-set vscode_marketplace dst -j ACCEPT
done
# Allow DNS resolution for whitelisted domains
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
# Allow SSH (if needed for external access)
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
# Allow localhost communication
iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -j ACCEPT
# Allow host network access
iptables -A OUTPUT -o docker0 -j ACCEPT
iptables -A INPUT -i docker0 -j ACCEPT
# --- Startup Verification ---
# Verify example.com is blocked
if curl --silent --fail http://example.com > /dev/null; then
echo "ERROR: example.com is reachable, but should be blocked."
exit 1
fi
# Verify GitHub API is reachable
if ! curl --silent --fail https://api.github.com > /dev/null; then
echo "ERROR: GitHub API is not reachable."
exit 1
fi
echo "Firewall initialized successfully."
exit 0
```
--------------------------------
### Revert Commit with Footer References Example
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/conventional-commits/SKILL.md
An example of a revert commit message that references the original commits using the 'Refs' footer.
```text
revert: let us never again speak of the noodle incident
Refs: 676104e, a215868
```
--------------------------------
### Set and Get Redis Keys
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/ioredis/SKILL.md
Perform basic key-value operations using `set` to store a value and `get` to retrieve it. These operations are asynchronous.
```javascript
await redis.set("key", "val")
await redis.get("key")
```
--------------------------------
### Start Docker Compose Services
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/docker/SKILL.md
Starts all services defined in your docker-compose.yml file in detached mode. Use '-d' to run containers in the background.
```bash
docker compose up -d
```
--------------------------------
### Install VS Code Dev Containers Extension
Source: https://github.com/jgamaraalv/ts-dev-kit/blob/main/skills/yolo/SKILL.md
Installs the VS Code Remote - Containers extension, which is required for working with devcontainers. This command is idempotent.
```bash
code --install-extension ms-vscode-remote.remote-containers
```