Skip to content

Latest commit

 

History

History
294 lines (205 loc) · 9.29 KB

File metadata and controls

294 lines (205 loc) · 9.29 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build and Development Commands

This is a pnpm 10.23.0 monorepo using Turborepo. Run commands from root with pnpm run.

Essential Commands

# Start Docker services (PostgreSQL, Redis, Electric)
pnpm run docker

# Run database migrations
pnpm run db:migrate

# Seed the database (required for reference projects)
pnpm run db:seed

# Build packages (required before running)
pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk

# Run webapp in development mode (http://localhost:3030)
pnpm run dev --filter webapp

# Build and watch for changes (CLI and packages)
pnpm run dev --filter trigger.dev --filter "@trigger.dev/*"

Testing

We use vitest exclusively. Never mock anything - use testcontainers instead.

# Run all tests for a package
pnpm run test --filter webapp

# Run a single test file (preferred - cd into directory first)
cd internal-packages/run-engine
pnpm run test ./src/engine/tests/ttl.test.ts --run

# May need to build dependencies first
pnpm run build --filter @internal/run-engine

Test files go next to source files (e.g., MyService.tsMyService.test.ts).

Testcontainers for Redis/PostgreSQL

import { redisTest, postgresTest, containerTest } from "@internal/testcontainers";

// Redis only
redisTest("should use redis", async ({ redisOptions }) => {
  /* ... */
});

// PostgreSQL only
postgresTest("should use postgres", async ({ prisma }) => {
  /* ... */
});

// Both Redis and PostgreSQL
containerTest("should use both", async ({ prisma, redisOptions }) => {
  /* ... */
});

Changesets

When modifying any public package (packages/* or integrations/*), add a changeset:

pnpm run changeset:add
  • Default to patch for bug fixes and minor changes
  • Confirm with maintainers before selecting minor (new features)
  • Never select major (breaking changes) without explicit approval

Architecture Overview

Apps

  • apps/webapp: Remix 2.1.0 app - main API, dashboard, and Docker image. Uses Express server.
  • apps/supervisor: Node.js app handling task execution, interfacing with Docker/Kubernetes.

Public Packages

  • packages/trigger-sdk (@trigger.dev/sdk): Main SDK
  • packages/cli-v3 (trigger.dev): CLI package
  • packages/core (@trigger.dev/core): Shared code between SDK and webapp. Import subpaths only (never root).
  • packages/build: Build extensions and types
  • packages/react-hooks: React hooks for realtime and triggering
  • packages/redis-worker (@trigger.dev/redis-worker): Custom Redis-based background job system

Internal Packages

  • internal-packages/database (@trigger.dev/database): Prisma 6.14.0 client and schema
  • internal-packages/clickhouse (@internal/clickhouse): ClickHouse client and schema migrations
  • internal-packages/run-engine (@internal/run-engine): "Run Engine 2.0" - run lifecycle management
  • internal-packages/redis (@internal/redis): Redis client creation utilities
  • internal-packages/testcontainers (@internal/testcontainers): Test helpers for Redis/PostgreSQL containers
  • internal-packages/zodworker (@internal/zodworker): Graphile-worker wrapper (being replaced by redis-worker)

Reference Projects

The references/ directory contains test workspaces for developing and testing new SDK and platform features. Use these projects (e.g., references/hello-world) to manually test changes to the CLI, SDK, core packages, and webapp before submitting PRs.

Webapp Development

Key Locations

  • Trigger API: apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
  • Batch trigger: apps/webapp/app/routes/api.v1.tasks.batch.ts
  • Prisma setup: apps/webapp/app/db.server.ts
  • Run engine config: apps/webapp/app/v3/runEngine.server.ts
  • Services: apps/webapp/app/v3/services/**/*.server.ts
  • Presenters: apps/webapp/app/v3/presenters/**/*.server.ts
  • OTEL endpoints: apps/webapp/app/routes/otel.v1.logs.ts, otel.v1.traces.ts

Environment Variables

Access via env export from apps/webapp/app/env.server.ts, never process.env directly.

For testable code, never import env.server.ts in test files. Pass configuration as options instead. Example pattern:

  • realtimeClient.server.ts (testable service)
  • realtimeClientGlobal.server.ts (configuration)

Legacy vs Run Engine 2.0

The codebase is transitioning from the "legacy run engine" (spread across codebase) to "Run Engine 2.0" (@internal/run-engine). Focus on Run Engine 2.0 for new work.

Database Migrations (PostgreSQL)

  1. Edit internal-packages/database/prisma/schema.prisma
  2. Create migration:
    cd internal-packages/database
    pnpm run db:migrate:dev:create --name "add_new_column"
  3. Important: Generated migration includes extraneous changes. Remove lines related to:
    • _BackgroundWorkerToBackgroundWorkerFile
    • _BackgroundWorkerToTaskQueue
    • _TaskRunToTaskRunTag
    • _WaitpointRunConnections
    • _completedWaitpoints
    • SecretStore_key_idx
    • Various TaskRun indexes unless you added them
  4. Apply migration:
    pnpm run db:migrate:deploy && pnpm run generate

Index Migration Rules

  • Indexes must use CONCURRENTLY to avoid table locks
  • CONCURRENTLY indexes must be in their own separate migration file - they cannot be combined with other schema changes

ClickHouse Migrations

ClickHouse migrations use Goose format and live in internal-packages/clickhouse/schema/.

  1. Create a new numbered SQL file (e.g., 010_add_new_column.sql)

  2. Use Goose markers:

    -- +goose Up
    ALTER TABLE trigger_dev.your_table
    ADD COLUMN new_column String DEFAULT '';
    
    -- +goose Down
    ALTER TABLE trigger_dev.your_table
    DROP COLUMN new_column;

Follow naming conventions in internal-packages/clickhouse/README.md:

  • raw_ prefix for input tables
  • _v1, _v2 suffixes for versioning
  • _mv_v1 suffix for materialized views

Writing Trigger.dev Tasks

Always import from @trigger.dev/sdk. Never use @trigger.dev/sdk/v3 or deprecated client.defineJob pattern.

import { task } from "@trigger.dev/sdk";

// Every task must be exported
export const myTask = task({
  id: "my-task", // Unique ID
  run: async (payload: { message: string }) => {
    // Task logic - no timeouts
  },
});

SDK Documentation Rules

The rules/ directory contains versioned documentation for writing Trigger.dev tasks, distributed to users via the SDK installer. Current version is defined in rules/manifest.json.

  • rules/4.3.0/ - Latest: batch trigger v2 (1,000 items, 3MB payloads), debouncing
  • rules/4.1.0/ - Realtime streams v2, updated config
  • rules/4.0.0/ - Base v4 SDK documentation

When adding new SDK features, create a new version directory with only the files that changed from the previous version. Update manifest.json to point unchanged files to previous versions.

Claude Code Skill

The .claude/skills/trigger-dev-tasks/ skill provides Claude Code with Trigger.dev task expertise. It includes:

  • SKILL.md - Core instructions and patterns
  • Reference files for basic tasks, advanced tasks, scheduled tasks, realtime, and config

Keep the skill in sync with the latest rules version when SDK features change.

Testing with hello-world Reference Project

First-time setup:

  1. Run pnpm run db:seed to seed the database (creates the hello-world project)
  2. Build CLI: pnpm run build --filter trigger.dev && pnpm i
  3. Authorize CLI: cd references/hello-world && pnpm exec trigger login -a http://localhost:3030

Running:

cd references/hello-world
pnpm exec trigger dev  # or with --log-level debug

Local Task Testing Workflow

This workflow enables Claude Code to run the webapp and trigger dev simultaneously, trigger tasks, and inspect results for testing code changes.

Step 1: Start Webapp in Background

# Run from repo root with run_in_background: true
pnpm run dev --filter webapp

Verify webapp is running:

curl -s http://localhost:3030/healthcheck  # Should return 200

Step 2: Start Trigger Dev in Background

# Run from hello-world directory with run_in_background: true
cd references/hello-world && pnpm exec trigger dev

The worker will build and register tasks. Check output for "Local worker ready [node]" message.

Step 3: Trigger and Monitor Tasks via MCP

Use the Trigger.dev MCP tools to interact with tasks:

# Get current worker and registered tasks
mcp__trigger__get_current_worker(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev")

# Trigger a task
mcp__trigger__trigger_task(
  projectRef: "proj_rrkpdguyagvsoktglnod",
  environment: "dev",
  taskId: "hello-world",
  payload: {"message": "Hello from Claude"}
)

# List runs to see status
mcp__trigger__list_runs(
  projectRef: "proj_rrkpdguyagvsoktglnod",
  environment: "dev",
  taskIdentifier: "hello-world",
  limit: 5
)

Step 4: Monitor Execution

Key Project Refs

  • hello-world: proj_rrkpdguyagvsoktglnod