{"owner":"triggerdotdev","repo":"trigger.dev","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.\n\n## Build and Development Commands\n\nThis is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.\n\n**Adding dependencies:** Edit `package.json` directly instead of using `pnpm add`, then run `pnpm i` from the repo root. See `.claude/rules/package-installation.md` for the full process.\n\n```bash\npnpm run docker              # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)\n# pnpm run docker:full       # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling\npnpm run db:migrate           # Run database migrations\npnpm run db:seed              # Seed the database (required for reference projects)\n\n# Build packages (required before running)\npnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk\n\npnpm run dev --filter webapp  # Run webapp (http://localhost:3030)\npnpm run dev --filter trigger.dev --filter \"@trigger.dev/*\"  # Watch CLI and packages\n```\n\n### Verifying Changes\n\nThe verification command depends on where the change lives:\n\n- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.\n- **Public packages** (`packages/*`): Use `build`.\n\n```bash\n# Apps and internal packages — use typecheck\npnpm run typecheck --filter webapp                  # ~1-2 minutes\npnpm run typecheck --filter @internal/run-engine\n\n# Public packages — use build\npnpm run build --filter @trigger.dev/sdk\npnpm run build --filter @trigger.dev/core\n```\n\nOnly run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.\n\n## Testing\n\nWe use vitest exclusively. **Never mock anything** - use testcontainers instead.\n\n```bash\npnpm run test --filter webapp                          # All tests for a package\ncd internal-packages/run-engine\npnpm run test ./src/engine/tests/ttl.test.ts --run     # Single test file\npnpm run build --filter @internal/run-engine           # May need to build deps first\n```\n\nTest files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).\n\n### Testcontainers for Redis/PostgreSQL\n\n```typescript\nimport { redisTest, postgresTest, containerTest } from \"@internal/testcontainers\";\n\nredisTest(\"should use redis\", async ({ redisOptions }) => {\n  /* ... */\n});\npostgresTest(\"should use postgres\", async ({ prisma }) => {\n  /* ... */\n});\ncontainerTest(\"should use both\", async ({ prisma, redisOptions }) => {\n  /* ... */\n});\n```\n\n## Code Style\n\n### Formatting and linting\n\nFormat and lint are enforced by CI (`code-quality` check). Run before committing:\n\n```bash\npnpm run format      # oxfmt — auto-fixes formatting\npnpm run lint:fix    # oxlint — auto-fixes lint violations\npnpm run lint        # oxlint — check only (no fixes)\n```\n\n### Imports\n\n**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:\n- Circular dependencies cannot be resolved otherwise\n- Code splitting is genuinely needed for performance\n- The module must be loaded conditionally at runtime\n\nDynamic imports add unnecessary overhead in hot paths and make code harder to analyze. If you find yourself using `await import()`, ask if a regular `import` statement would work instead.\n\n## Changesets and Server Changes\n\nChangesets and `.server-changes/` files are **user-facing release notes**. They ship verbatim into the changelog that customers read to decide what to upgrade for or pay attention to. They are not a catalog of every change: anyone who wants the exact history reads the commits. So the question is not \"did I touch a public package or a server app?\" but **\"would a user or customer care about this change?\"**\n\n**Add one** when the change is something a user would notice, act on, or want to hear about: a new feature, a bug fix they could have hit, a behavior or performance change they would feel, a breaking change.\n\n**Skip it** (no changeset, no `.server-changes/` file) when the change is not worth communicating to users, even if it touches a public package or a server app. For example:\n\n- internal-only or admin-only changes, refactors, test-only changes, chores\n- performance or query tuning with no user-visible behavior change\n- changes to a public package that is not consumed independently (e.g. `@trigger.dev/redis-worker`), where a version bump means nothing to a user\n\nWhen in doubt, ask a maintainer rather than adding a note by default. An unnecessary entry is noise in the changelog, not a safe default.\n\n### How to add one\n\nWhen a **public package** (`packages/*` or `integrations/*`) change is user-facing, add a changeset:\n\n```bash\npnpm run changeset:add\n```\n\n- Default to **patch** for bug fixes and minor changes\n- Confirm with maintainers before selecting **minor** (new features)\n- **Never** select major without explicit approval\n\nWhen a **server-only** change (`apps/webapp/`, `apps/supervisor/`, etc., with no package changes) is user-facing, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.\n\n**Write the description for users, not maintainers.** Both changesets and `.server-changes/` notes ship verbatim in user-visible release notes. Lead with what changed *for the user*: one plain sentence describing behavior, not implementation, and never naming internal tools or infra. The full writing guidance in `.server-changes/README.md` applies to changesets too.\n\n## Dependency Pinning\n\nZod is pinned to a single version across the entire monorepo (currently `3.25.76`). When adding zod to a new or existing package, use the **exact same version** as the rest of the repo - never a different version or a range. Mismatched zod versions cause runtime type incompatibilities (e.g., schemas from one package can't be used as body validators in another).\n\n## Architecture Overview\n\n### Request Flow\n\nUser API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)\n\n### Apps\n\n- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.\n- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).\n\n### Public Packages\n\n- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks\n- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images\n- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).\n- **packages/build** (`@trigger.dev/build`): Build extensions and types\n- **packages/react-hooks**: React hooks for realtime and triggering\n- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system\n\n### Internal Packages\n\n- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)\n- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries\n- **internal-packages/run-engine**: \"Run Engine 2.0\" - core run lifecycle management\n- **internal-packages/redis**: Redis client creation utilities (ioredis)\n- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers\n- **internal-packages/schedule-engine**: Durable cron scheduling\n\n### v3 (engine V1) removed\n\nv3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code has been removed. The `apps/webapp/app/v3/` directory name is historical - everything there now serves V2 (Run Engine 2.0, `@internal/run-engine` + redis-worker). There is no V1 execution path: a `RunEngineVersion` `V1` branch only rejects or finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `apps/webapp/CLAUDE.md` and `.claude/rules/legacy-v3-code.md`.\n\n### Documentation\n\nDocs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.\n\n### Reference Projects\n\nReference/example projects for testing SDK and platform features live in a separate repo: [`triggerdotdev/references`](https://github.com/triggerdotdev/references). Clone it alongside this repo and use its `projects/hello-world` to manually test changes before submitting PRs. See that repo's README for setup and linking to a local monorepo build.\n\n## Docker Image Guidelines\n\nWhen updating Docker image references:\n\n- **Always use multiplatform/index digests**, not architecture-specific digests\n- Architecture-specific digests cause CI failures on different build environments\n- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant\n\n## Writing Trigger.dev Tasks\n\nAlways import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.\n\n```typescript\nimport { task } from \"@trigger.dev/sdk\";\n\nexport const myTask = task({\n  id: \"my-task\",\n  run: async (payload: { message: string }) => {\n    // Task logic\n  },\n});\n```\n\n### SDK Documentation Rules\n\nThe `rules/` directory contains versioned SDK documentation distributed via the SDK installer. Current version: `rules/manifest.json`. Do NOT update `rules/` or `.claude/skills/trigger-dev-tasks/` unless explicitly asked - these are maintained in separate dedicated passes.\n\n## Testing with the hello-world Reference Project\n\nThe reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.\n\nFirst-time setup:\n\n1. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)\n2. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`\n3. In your `references` clone, follow its README to link to your local monorepo build, then authorize: `cd projects/hello-world && pnpm exec trigger login -a http://localhost:3030`\n\nRunning (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`\n\n## Local Task Testing Workflow\n\n### Step 1: Start Webapp in Background\n\n```bash\n# Run from repo root with run_in_background: true\npnpm run dev --filter webapp\ncurl -s http://localhost:3030/healthcheck  # Verify running\n```\n\n### Step 2: Start Trigger Dev in Background\n\n```bash\n# in your triggerdotdev/references clone\ncd projects/hello-world && pnpm exec trigger dev\n# Wait for \"Local worker ready [node]\"\n```\n\n### Step 3: Trigger and Monitor Tasks via MCP\n\n```\nmcp__trigger__get_current_worker(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\")\nmcp__trigger__trigger_task(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskId: \"hello-world\", payload: {\"message\": \"Hello\"})\nmcp__trigger__list_runs(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskIdentifier: \"hello-world\", limit: 5)\n```\n\nDashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs\n\n<!-- intent-skills:start -->\n\n# Skill mappings — when working in these areas, load the linked skill file into context.\n\nskills:\n\n- task: \"Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md\"\n- task: \"Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md\"\n<!-- intent-skills:end -->\n\n## agentcrumbs\n\nAdd crumbs as you write code — not just when debugging. Mark lines with\n`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the\nbranch throughout development and are stripped by `agentcrumbs strip`\nbefore merge.\n\n### Namespaces\n\n| Namespace         | Description                                    | Path                                |\n| ----------------- | ---------------------------------------------- | ----------------------------------- |\n| `webapp`          | Main Remix app — API, dashboard, orchestration | `apps/webapp`                       |\n| `supervisor`      | Task execution container manager               | `apps/supervisor`                   |\n| `sdk`             | Main SDK for writing tasks                     | `packages/trigger-sdk`              |\n| `cli`             | CLI and task image bundling                    | `packages/cli-v3`                   |\n| `core`            | Shared types and subpath exports               | `packages/core`                     |\n| `build`           | Build extensions and types                     | `packages/build`                    |\n| `react-hooks`     | React hooks for realtime/triggering            | `packages/react-hooks`              |\n| `redis-worker`    | Redis-based background job system              | `packages/redis-worker`             |\n| `run-engine`      | Run Engine 2.0 — core run lifecycle            | `internal-packages/run-engine`      |\n| `database`        | Prisma client and schema                       | `internal-packages/database`        |\n| `clickhouse`      | ClickHouse client, migrations, analytics       | `internal-packages/clickhouse`      |\n| `schedule-engine` | Durable cron scheduling                        | `internal-packages/schedule-engine` |\n| `run-queue`       | Run queue management                           | `internal-packages/run-queue`       |\n\nDo not invent new namespaces — pick from this table or ask first.\n\n### For PR reviewers\n\nDo not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs\nimports in reviews. These are temporary debug instrumentation stripped\nbefore merge. Data logged in crumbs (IDs, names, values) never reaches\nproduction.\n\n### CLI\n\n```bash\npnpm exec agentcrumbs collect    # start collector (multi-service)\npnpm exec agentcrumbs tail --app trigger       # live tail\npnpm exec agentcrumbs clear --app trigger      # remove crumbs before merge\n```\n\nThe preferred way to query for crumbs is to use `pnpm exec agentcrumbs query --app trigger` with the `--limit` option and cursor pagination, and clear existing crumbs before reproducing a bug via `pnpm exec agentcrumbs clear --app trigger`.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.\n\n## Build and Development Commands\n\nThis is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.\n\n**Adding dependencies:** Edit `package.json` directly instead of using `pnpm add`, then run `pnpm i` from the repo root. See `.claude/rules/package-installation.md` for the full process.\n\n```bash\npnpm run docker              # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)\n# pnpm run docker:full       # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling\npnpm run db:migrate           # Run database migrations\npnpm run db:seed              # Seed the database (required for reference projects)\n\n# Build packages (required before running)\npnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk\n\npnpm run dev --filter webapp  # Run webapp (http://localhost:3030)\npnpm run dev --filter trigger.dev --filter \"@trigger.dev/*\"  # Watch CLI and packages\n```\n\n### Verifying Changes\n\nThe verification command depends on where the change lives:\n\n- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.\n- **Public packages** (`packages/*`): Use `build`.\n\n```bash\n# Apps and internal packages — use typecheck\npnpm run typecheck --filter webapp                  # ~1-2 minutes\npnpm run typecheck --filter @internal/run-engine\n\n# Public packages — use build\npnpm run build --filter @trigger.dev/sdk\npnpm run build --filter @trigger.dev/core\n```\n\nOnly run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.\n\n## Testing\n\nWe use vitest exclusively. **Never mock anything** - use testcontainers instead.\n\n```bash\npnpm run test --filter webapp                          # All tests for a package\ncd internal-packages/run-engine\npnpm run test ./src/engine/tests/ttl.test.ts --run     # Single test file\npnpm run build --filter @internal/run-engine           # May need to build deps first\n```\n\nTest files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).\n\n### Testcontainers for Redis/PostgreSQL\n\n```typescript\nimport { redisTest, postgresTest, containerTest } from \"@internal/testcontainers\";\n\nredisTest(\"should use redis\", async ({ redisOptions }) => {\n  /* ... */\n});\npostgresTest(\"should use postgres\", async ({ prisma }) => {\n  /* ... */\n});\ncontainerTest(\"should use both\", async ({ prisma, redisOptions }) => {\n  /* ... */\n});\n```\n\n## Code Style\n\n### Formatting and linting\n\nFormat and lint are enforced by CI (`code-quality` check). Run before committing:\n\n```bash\npnpm run format      # oxfmt — auto-fixes formatting\npnpm run lint:fix    # oxlint — auto-fixes lint violations\npnpm run lint        # oxlint — check only (no fixes)\n```\n\n### Imports\n\n**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:\n- Circular dependencies cannot be resolved otherwise\n- Code splitting is genuinely needed for performance\n- The module must be loaded conditionally at runtime\n\nDynamic imports add unnecessary overhead in hot paths and make code harder to analyze. If you find yourself using `await import()`, ask if a regular `import` statement would work instead.\n\n## Changesets and Server Changes\n\nChangesets and `.server-changes/` files are **user-facing release notes**. They ship verbatim into the changelog that customers read to decide what to upgrade for or pay attention to. They are not a catalog of every change: anyone who wants the exact history reads the commits. So the question is not \"did I touch a public package or a server app?\" but **\"would a user or customer care about this change?\"**\n\n**Add one** when the change is something a user would notice, act on, or want to hear about: a new feature, a bug fix they could have hit, a behavior or performance change they would feel, a breaking change.\n\n**Skip it** (no changeset, no `.server-changes/` file) when the change is not worth communicating to users, even if it touches a public package or a server app. For example:\n\n- internal-only or admin-only changes, refactors, test-only changes, chores\n- performance or query tuning with no user-visible behavior change\n- changes to a public package that is not consumed independently (e.g. `@trigger.dev/redis-worker`), where a version bump means nothing to a user\n\nWhen in doubt, ask a maintainer rather than adding a note by default. An unnecessary entry is noise in the changelog, not a safe default.\n\n### How to add one\n\nWhen a **public package** (`packages/*` or `integrations/*`) change is user-facing, add a changeset:\n\n```bash\npnpm run changeset:add\n```\n\n- Default to **patch** for bug fixes and minor changes\n- Confirm with maintainers before selecting **minor** (new features)\n- **Never** select major without explicit approval\n\nWhen a **server-only** change (`apps/webapp/`, `apps/supervisor/`, etc., with no package changes) is user-facing, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.\n\n**Write the description for users, not maintainers.** Both changesets and `.server-changes/` notes ship verbatim in user-visible release notes. Lead with what changed *for the user*: one plain sentence describing behavior, not implementation, and never naming internal tools or infra. The full writing guidance in `.server-changes/README.md` applies to changesets too.\n\n## Dependency Pinning\n\nZod is pinned to a single version across the entire monorepo (currently `3.25.76`). When adding zod to a new or existing package, use the **exact same version** as the rest of the repo - never a different version or a range. Mismatched zod versions cause runtime type incompatibilities (e.g., schemas from one package can't be used as body validators in another).\n\n## Architecture Overview\n\n### Request Flow\n\nUser API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)\n\n### Apps\n\n- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.\n- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).\n\n### Public Packages\n\n- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks\n- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images\n- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).\n- **packages/build** (`@trigger.dev/build`): Build extensions and types\n- **packages/react-hooks**: React hooks for realtime and triggering\n- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system\n\n### Internal Packages\n\n- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)\n- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries\n- **internal-packages/run-engine**: \"Run Engine 2.0\" - core run lifecycle management\n- **internal-packages/redis**: Redis client creation utilities (ioredis)\n- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers\n- **internal-packages/schedule-engine**: Durable cron scheduling\n\n### v3 (engine V1) removed\n\nv3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code has been removed. The `apps/webapp/app/v3/` directory name is historical - everything there now serves V2 (Run Engine 2.0, `@internal/run-engine` + redis-worker). There is no V1 execution path: a `RunEngineVersion` `V1` branch only rejects or finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `apps/webapp/CLAUDE.md` and `.claude/rules/legacy-v3-code.md`.\n\n### Documentation\n\nDocs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.\n\n### Reference Projects\n\nReference/example projects for testing SDK and platform features live in a separate repo: [`triggerdotdev/references`](https://github.com/triggerdotdev/references). Clone it alongside this repo and use its `projects/hello-world` to manually test changes before submitting PRs. See that repo's README for setup and linking to a local monorepo build.\n\n## Docker Image Guidelines\n\nWhen updating Docker image references:\n\n- **Always use multiplatform/index digests**, not architecture-specific digests\n- Architecture-specific digests cause CI failures on different build environments\n- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant\n\n## Writing Trigger.dev Tasks\n\nAlways import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.\n\n```typescript\nimport { task } from \"@trigger.dev/sdk\";\n\nexport const myTask = task({\n  id: \"my-task\",\n  run: async (payload: { message: string }) => {\n    // Task logic\n  },\n});\n```\n\n### SDK Documentation Rules\n\nThe `rules/` directory contains versioned SDK documentation distributed via the SDK installer. Current version: `rules/manifest.json`. Do NOT update `rules/` or `.claude/skills/trigger-dev-tasks/` unless explicitly asked - these are maintained in separate dedicated passes.\n\n## Testing with the hello-world Reference Project\n\nThe reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.\n\nFirst-time setup:\n\n1. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)\n2. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`\n3. In your `references` clone, follow its README to link to your local monorepo build, then authorize: `cd projects/hello-world && pnpm exec trigger login -a http://localhost:3030`\n\nRunning (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`\n\n## Local Task Testing Workflow\n\n### Step 1: Start Webapp in Background\n\n```bash\n# Run from repo root with run_in_background: true\npnpm run dev --filter webapp\ncurl -s http://localhost:3030/healthcheck  # Verify running\n```\n\n### Step 2: Start Trigger Dev in Background\n\n```bash\n# in your triggerdotdev/references clone\ncd projects/hello-world && pnpm exec trigger dev\n# Wait for \"Local worker ready [node]\"\n```\n\n### Step 3: Trigger and Monitor Tasks via MCP\n\n```\nmcp__trigger__get_current_worker(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\")\nmcp__trigger__trigger_task(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskId: \"hello-world\", payload: {\"message\": \"Hello\"})\nmcp__trigger__list_runs(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskIdentifier: \"hello-world\", limit: 5)\n```\n\nDashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs\n\n<!-- intent-skills:start -->\n\n# Skill mappings — when working in these areas, load the linked skill file into context.\n\nskills:\n\n- task: \"Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md\"\n- task: \"Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md\"\n<!-- intent-skills:end -->\n\n## agentcrumbs\n\nAdd crumbs as you write code — not just when debugging. Mark lines with\n`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the\nbranch throughout development and are stripped by `agentcrumbs strip`\nbefore merge.\n\n### Namespaces\n\n| Namespace         | Description                                    | Path                                |\n| ----------------- | ---------------------------------------------- | ----------------------------------- |\n| `webapp`          | Main Remix app — API, dashboard, orchestration | `apps/webapp`                       |\n| `supervisor`      | Task execution container manager               | `apps/supervisor`                   |\n| `sdk`             | Main SDK for writing tasks                     | `packages/trigger-sdk`              |\n| `cli`             | CLI and task image bundling                    | `packages/cli-v3`                   |\n| `core`            | Shared types and subpath exports               | `packages/core`                     |\n| `build`           | Build extensions and types                     | `packages/build`                    |\n| `react-hooks`     | React hooks for realtime/triggering            | `packages/react-hooks`              |\n| `redis-worker`    | Redis-based background job system              | `packages/redis-worker`             |\n| `run-engine`      | Run Engine 2.0 — core run lifecycle            | `internal-packages/run-engine`      |\n| `database`        | Prisma client and schema                       | `internal-packages/database`        |\n| `clickhouse`      | ClickHouse client, migrations, analytics       | `internal-packages/clickhouse`      |\n| `schedule-engine` | Durable cron scheduling                        | `internal-packages/schedule-engine` |\n| `run-queue`       | Run queue management                           | `internal-packages/run-queue`       |\n\nDo not invent new namespaces — pick from this table or ask first.\n\n### For PR reviewers\n\nDo not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs\nimports in reviews. These are temporary debug instrumentation stripped\nbefore merge. Data logged in crumbs (IDs, names, values) never reaches\nproduction.\n\n### CLI\n\n```bash\npnpm exec agentcrumbs collect    # start collector (multi-service)\npnpm exec agentcrumbs tail --app trigger       # live tail\npnpm exec agentcrumbs clear --app trigger      # remove crumbs before merge\n```\n\nThe preferred way to query for crumbs is to use `pnpm exec agentcrumbs query --app trigger` with the `--limit` option and cursor pagination, and clear existing crumbs before reproducing a bug via `pnpm exec agentcrumbs clear --app trigger`.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.\n\n## Build and Development Commands\n\nThis is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.\n\n**Adding dependencies:** Edit `package.json` directly instead of using `pnpm add`, then run `pnpm i` from the repo root. See `.claude/rules/package-installation.md` for the full process.\n\n```bash\npnpm run docker              # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)\n# pnpm run docker:full       # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling\npnpm run db:migrate           # Run database migrations\npnpm run db:seed              # Seed the database (required for reference projects)\n\n# Build packages (required before running)\npnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk\n\npnpm run dev --filter webapp  # Run webapp (http://localhost:3030)\npnpm run dev --filter trigger.dev --filter \"@trigger.dev/*\"  # Watch CLI and packages\n```\n\n### Verifying Changes\n\nThe verification command depends on where the change lives:\n\n- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.\n- **Public packages** (`packages/*`): Use `build`.\n\n```bash\n# Apps and internal packages — use typecheck\npnpm run typecheck --filter webapp                  # ~1-2 minutes\npnpm run typecheck --filter @internal/run-engine\n\n# Public packages — use build\npnpm run build --filter @trigger.dev/sdk\npnpm run build --filter @trigger.dev/core\n```\n\nOnly run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.\n\n## Testing\n\nWe use vitest exclusively. **Never mock anything** - use testcontainers instead.\n\n```bash\npnpm run test --filter webapp                          # All tests for a package\ncd internal-packages/run-engine\npnpm run test ./src/engine/tests/ttl.test.ts --run     # Single test file\npnpm run build --filter @internal/run-engine           # May need to build deps first\n```\n\nTest files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).\n\n### Testcontainers for Redis/PostgreSQL\n\n```typescript\nimport { redisTest, postgresTest, containerTest } from \"@internal/testcontainers\";\n\nredisTest(\"should use redis\", async ({ redisOptions }) => {\n  /* ... */\n});\npostgresTest(\"should use postgres\", async ({ prisma }) => {\n  /* ... */\n});\ncontainerTest(\"should use both\", async ({ prisma, redisOptions }) => {\n  /* ... */\n});\n```\n\n## Code Style\n\n### Formatting and linting\n\nFormat and lint are enforced by CI (`code-quality` check). Run before committing:\n\n```bash\npnpm run format      # oxfmt — auto-fixes formatting\npnpm run lint:fix    # oxlint — auto-fixes lint violations\npnpm run lint        # oxlint — check only (no fixes)\n```\n\n### Imports\n\n**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:\n- Circular dependencies cannot be resolved otherwise\n- Code splitting is genuinely needed for performance\n- The module must be loaded conditionally at runtime\n\nDynamic imports add unnecessary overhead in hot paths and make code harder to analyze. If you find yourself using `await import()`, ask if a regular `import` statement would work instead.\n\n## Changesets and Server Changes\n\nChangesets and `.server-changes/` files are **user-facing release notes**. They ship verbatim into the changelog that customers read to decide what to upgrade for or pay attention to. They are not a catalog of every change: anyone who wants the exact history reads the commits. So the question is not \"did I touch a public package or a server app?\" but **\"would a user or customer care about this change?\"**\n\n**Add one** when the change is something a user would notice, act on, or want to hear about: a new feature, a bug fix they could have hit, a behavior or performance change they would feel, a breaking change.\n\n**Skip it** (no changeset, no `.server-changes/` file) when the change is not worth communicating to users, even if it touches a public package or a server app. For example:\n\n- internal-only or admin-only changes, refactors, test-only changes, chores\n- performance or query tuning with no user-visible behavior change\n- changes to a public package that is not consumed independently (e.g. `@trigger.dev/redis-worker`), where a version bump means nothing to a user\n\nWhen in doubt, ask a maintainer rather than adding a note by default. An unnecessary entry is noise in the changelog, not a safe default.\n\n### How to add one\n\nWhen a **public package** (`packages/*` or `integrations/*`) change is user-facing, add a changeset:\n\n```bash\npnpm run changeset:add\n```\n\n- Default to **patch** for bug fixes and minor changes\n- Confirm with maintainers before selecting **minor** (new features)\n- **Never** select major without explicit approval\n\nWhen a **server-only** change (`apps/webapp/`, `apps/supervisor/`, etc., with no package changes) is user-facing, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.\n\n**Write the description for users, not maintainers.** Both changesets and `.server-changes/` notes ship verbatim in user-visible release notes. Lead with what changed *for the user*: one plain sentence describing behavior, not implementation, and never naming internal tools or infra. The full writing guidance in `.server-changes/README.md` applies to changesets too.\n\n## Dependency Pinning\n\nZod is pinned to a single version across the entire monorepo (currently `3.25.76`). When adding zod to a new or existing package, use the **exact same version** as the rest of the repo - never a different version or a range. Mismatched zod versions cause runtime type incompatibilities (e.g., schemas from one package can't be used as body validators in another).\n\n## Architecture Overview\n\n### Request Flow\n\nUser API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)\n\n### Apps\n\n- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.\n- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).\n\n### Public Packages\n\n- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks\n- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images\n- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).\n- **packages/build** (`@trigger.dev/build`): Build extensions and types\n- **packages/react-hooks**: React hooks for realtime and triggering\n- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system\n\n### Internal Packages\n\n- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)\n- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries\n- **internal-packages/run-engine**: \"Run Engine 2.0\" - core run lifecycle management\n- **internal-packages/redis**: Redis client creation utilities (ioredis)\n- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers\n- **internal-packages/schedule-engine**: Durable cron scheduling\n\n### v3 (engine V1) removed\n\nv3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code has been removed. The `apps/webapp/app/v3/` directory name is historical - everything there now serves V2 (Run Engine 2.0, `@internal/run-engine` + redis-worker). There is no V1 execution path: a `RunEngineVersion` `V1` branch only rejects or finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `apps/webapp/CLAUDE.md` and `.claude/rules/legacy-v3-code.md`.\n\n### Documentation\n\nDocs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.\n\n### Reference Projects\n\nReference/example projects for testing SDK and platform features live in a separate repo: [`triggerdotdev/references`](https://github.com/triggerdotdev/references). Clone it alongside this repo and use its `projects/hello-world` to manually test changes before submitting PRs. See that repo's README for setup and linking to a local monorepo build.\n\n## Docker Image Guidelines\n\nWhen updating Docker image references:\n\n- **Always use multiplatform/index digests**, not architecture-specific digests\n- Architecture-specific digests cause CI failures on different build environments\n- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant\n\n## Writing Trigger.dev Tasks\n\nAlways import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.\n\n```typescript\nimport { task } from \"@trigger.dev/sdk\";\n\nexport const myTask = task({\n  id: \"my-task\",\n  run: async (payload: { message: string }) => {\n    // Task logic\n  },\n});\n```\n\n### SDK Documentation Rules\n\nThe `rules/` directory contains versioned SDK documentation distributed via the SDK installer. Current version: `rules/manifest.json`. Do NOT update `rules/` or `.claude/skills/trigger-dev-tasks/` unless explicitly asked - these are maintained in separate dedicated passes.\n\n## Testing with the hello-world Reference Project\n\nThe reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.\n\nFirst-time setup:\n\n1. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)\n2. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`\n3. In your `references` clone, follow its README to link to your local monorepo build, then authorize: `cd projects/hello-world && pnpm exec trigger login -a http://localhost:3030`\n\nRunning (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`\n\n## Local Task Testing Workflow\n\n### Step 1: Start Webapp in Background\n\n```bash\n# Run from repo root with run_in_background: true\npnpm run dev --filter webapp\ncurl -s http://localhost:3030/healthcheck  # Verify running\n```\n\n### Step 2: Start Trigger Dev in Background\n\n```bash\n# in your triggerdotdev/references clone\ncd projects/hello-world && pnpm exec trigger dev\n# Wait for \"Local worker ready [node]\"\n```\n\n### Step 3: Trigger and Monitor Tasks via MCP\n\n```\nmcp__trigger__get_current_worker(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\")\nmcp__trigger__trigger_task(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskId: \"hello-world\", payload: {\"message\": \"Hello\"})\nmcp__trigger__list_runs(projectRef: \"proj_rrkpdguyagvsoktglnod\", environment: \"dev\", taskIdentifier: \"hello-world\", limit: 5)\n```\n\nDashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs\n\n<!-- intent-skills:start -->\n\n# Skill mappings — when working in these areas, load the linked skill file into context.\n\nskills:\n\n- task: \"Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md\"\n- task: \"Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init\"\n  load: \"node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md\"\n<!-- intent-skills:end -->\n\n## agentcrumbs\n\nAdd crumbs as you write code — not just when debugging. Mark lines with\n`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the\nbranch throughout development and are stripped by `agentcrumbs strip`\nbefore merge.\n\n### Namespaces\n\n| Namespace         | Description                                    | Path                                |\n| ----------------- | ---------------------------------------------- | ----------------------------------- |\n| `webapp`          | Main Remix app — API, dashboard, orchestration | `apps/webapp`                       |\n| `supervisor`      | Task execution container manager               | `apps/supervisor`                   |\n| `sdk`             | Main SDK for writing tasks                     | `packages/trigger-sdk`              |\n| `cli`             | CLI and task image bundling                    | `packages/cli-v3`                   |\n| `core`            | Shared types and subpath exports               | `packages/core`                     |\n| `build`           | Build extensions and types                     | `packages/build`                    |\n| `react-hooks`     | React hooks for realtime/triggering            | `packages/react-hooks`              |\n| `redis-worker`    | Redis-based background job system              | `packages/redis-worker`             |\n| `run-engine`      | Run Engine 2.0 — core run lifecycle            | `internal-packages/run-engine`      |\n| `database`        | Prisma client and schema                       | `internal-packages/database`        |\n| `clickhouse`      | ClickHouse client, migrations, analytics       | `internal-packages/clickhouse`      |\n| `schedule-engine` | Durable cron scheduling                        | `internal-packages/schedule-engine` |\n| `run-queue`       | Run queue management                           | `internal-packages/run-queue`       |\n\nDo not invent new namespaces — pick from this table or ask first.\n\n### For PR reviewers\n\nDo not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs\nimports in reviews. These are temporary debug instrumentation stripped\nbefore merge. Data logged in crumbs (IDs, names, values) never reaches\nproduction.\n\n### CLI\n\n```bash\npnpm exec agentcrumbs collect    # start collector (multi-service)\npnpm exec agentcrumbs tail --app trigger       # live tail\npnpm exec agentcrumbs clear --app trigger      # remove crumbs before merge\n```\n\nThe preferred way to query for crumbs is to use `pnpm exec agentcrumbs query --app trigger` with the `--limit` option and cursor pagination, and clear existing crumbs before reproducing a bug via `pnpm exec agentcrumbs clear --app trigger`.\n","category":"root","tokens":3564}]}