RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/triggerdotdev-trigger-dev-agents ↔ triggerdotdev-trigger-dev-apps-webapp-claude

Comparison

A · AGENTS.md · triggerdotdev/trigger.devB · CLAUDE.md · triggerdotdev/trigger.dev
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections236174%
Commands22318%
Section tags57431%

What each file covers

Sections

2 shared · 36 only in A · 17 only in B
  • − AGENTS.md
  • − Build and Development Commands
  • − pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
  • − Build packages (required before running)
  • − Apps and internal packages — use typecheck
  • − Public packages — use build
  • − Testing
  • − Testcontainers for Redis/PostgreSQL
  • − Code Style
  • − Formatting and linting
  • − Imports
  • − Changesets and Server Changes
  • − Dependency Pinning
  • − Architecture Overview
  • − Request Flow
  • − Apps
  • − Public Packages
  • − Internal Packages
  • − Documentation
  • − Reference Projects
  • − Docker Image Guidelines
  • − Writing Trigger.dev Tasks
  • − SDK Documentation Rules
  • − Testing with the hello-world Reference Project
  • − Local Task Testing Workflow
  • − Step 1: Start Webapp in Background
  • − Run from repo root with run_in_background: true
  • − Step 2: Start Trigger Dev in Background
  • − in your triggerdotdev/references clone
  • − Wait for "Local worker ready [node]"
  • − Step 3: Trigger and Monitor Tasks via MCP
  • − Skill mappings — when working in these areas, load the linked skill file into context.
  • − agentcrumbs
  • − Namespaces
  • − For PR reviewers
  • − CLI
  • + Webapp
  • + Testing Dashboard Changes with Chrome DevTools MCP
  • + Login
  • + Navigating and Verifying
  • + Tips
  • + Key File Locations
  • + Route Convention
  • + Abort Signals
  • + Environment Variables
  • + Run Engine 2.0
  • + Background Workers
  • + Real-time
  • + Performance: Trigger Hot Path
  • + Prisma Query Patterns
  • + Transactions
  • + PAT-authenticated API routes
  • + React Patterns
  •   Verifying Changes
  •   v3 (engine V1) removed

Commands

2 shared · 23 only in A · 1 only in B
  • − pnpm run docker
  • − pnpm run db:migrate
  • − pnpm run db:seed
  • − pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
  • − pnpm run dev --filter trigger.dev --filter "@trigger.dev/*"
  • − pnpm run typecheck --filter @internal/run-engine
  • − pnpm run build --filter @trigger.dev/sdk
  • − pnpm run build --filter @trigger.dev/core
  • − pnpm run test --filter webapp
  • − pnpm run test ./src/engine/tests/ttl.test.ts --run
  • − pnpm run build --filter @internal/run-engine
  • − pnpm run format
  • − pnpm run lint:fix
  • − pnpm run lint
  • − pnpm run changeset:add
  • − pnpm exec agentcrumbs collect
  • − pnpm exec agentcrumbs tail --app trigger
  • − pnpm exec agentcrumbs clear --app trigger
  • − pnpm run
  • − pnpm add
  • − pnpm i
  • − pnpm run build --filter trigger.dev
  • − pnpm exec agentcrumbs query --app trigger
  • + pnpm run build --filter webapp
  •   pnpm run dev --filter webapp
  •   pnpm run typecheck --filter webapp

Section tags

5 shared · 7 only in A · 4 only in B
  • − lint-format
  • − architecture
  • − testing-strategy
  • − git-pr
  • − dependencies
  • − agent-behaviour
  • − docs
  • + security
  • + database
  • + api
  • + performance
  •   setup
  •   build
  •   test
  •   code-style
  •   do-not

Line diff

+80 added−224 removed52 unchanged18.8% identical
triggerdotdev/trigger.dev · AGENTS.md
@@ −1 @@
1# AGENTS.md
2 
3This file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.
4 
5## Build and Development Commands
6 
7This is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.
8 
9**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.
10 
11```bash
12pnpm run docker # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)
13# pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
14pnpm run db:migrate # Run database migrations
15pnpm run db:seed # Seed the database (required for reference projects)
16 
17# Build packages (required before running)
18pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
19 
20pnpm run dev --filter webapp # Run webapp (http://localhost:3030)
21pnpm run dev --filter trigger.dev --filter "@trigger.dev/*" # Watch CLI and packages
22```
23 
24### Verifying Changes
25 
26The verification command depends on where the change lives:
27 
28- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.
29- **Public packages** (`packages/*`): Use `build`.
30 
31```bash
32# Apps and internal packages — use typecheck
33pnpm run typecheck --filter webapp # ~1-2 minutes
34pnpm run typecheck --filter @internal/run-engine
35 
36# Public packages — use build
37pnpm run build --filter @trigger.dev/sdk
38pnpm run build --filter @trigger.dev/core
39```
40 
41Only run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
42 
43## Testing
44 
45We use vitest exclusively. **Never mock anything** - use testcontainers instead.
46 
47```bash
48pnpm run test --filter webapp # All tests for a package
49cd internal-packages/run-engine
50pnpm run test ./src/engine/tests/ttl.test.ts --run # Single test file
51pnpm run build --filter @internal/run-engine # May need to build deps first
52```
53 
54Test files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).
55 
56### Testcontainers for Redis/PostgreSQL
57 
58```typescript
59import { redisTest, postgresTest, containerTest } from "@internal/testcontainers";
60 
61redisTest("should use redis", async ({ redisOptions }) => {
62 /* ... */
63});
64postgresTest("should use postgres", async ({ prisma }) => {
65 /* ... */
66});
67containerTest("should use both", async ({ prisma, redisOptions }) => {
68 /* ... */
69});
70```
71 
72## Code Style
73 
74### Formatting and linting
 
 
 
 
 
75 
76Format and lint are enforced by CI (`code-quality` check). Run before committing:
77 
78```bash
79pnpm run format # oxfmt — auto-fixes formatting
80pnpm run lint:fix # oxlint — auto-fixes lint violations
81pnpm run lint # oxlint — check only (no fixes)
82```
83 
84### Imports
85 
86**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:
87- Circular dependencies cannot be resolved otherwise
88- Code splitting is genuinely needed for performance
89- The module must be loaded conditionally at runtime
 
 
 
90 
91Dynamic 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.
92 
93## Changesets and Server Changes
 
94 
95When modifying any public package (`packages/*` or `integrations/*`), add a changeset:
96 
97```bash
98pnpm run changeset:add
99```
100 
101- Default to **patch** for bug fixes and minor changes
102- Confirm with maintainers before selecting **minor** (new features)
103- **Never** select major without explicit approval
104 
105When modifying only server components (`apps/webapp/`, `apps/supervisor/`, etc.) with no package changes, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.
106 
107**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.
108 
109## Dependency Pinning
110 
111Zod 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).
112 
113## Architecture Overview
114 
115### Request Flow
116 
117User API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)
118 
119### Apps
120 
121- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.
122- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).
123 
124### Public Packages
125 
126- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks
127- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images
128- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).
129- **packages/build** (`@trigger.dev/build`): Build extensions and types
130- **packages/react-hooks**: React hooks for realtime and triggering
131- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system
132 
133### Internal Packages
134 
135- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)
136- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries
137- **internal-packages/run-engine**: "Run Engine 2.0" - core run lifecycle management
138- **internal-packages/redis**: Redis client creation utilities (ioredis)
139- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers
140- **internal-packages/schedule-engine**: Durable cron scheduling
141 
142### v3 (engine V1) removed
143 
144v3 (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`.
145 
146### Documentation
147 
148Docs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.
149 
150### Reference Projects
151 
152Reference/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.
153 
154## Docker Image Guidelines
155 
156When updating Docker image references:
157 
158- **Always use multiplatform/index digests**, not architecture-specific digests
159- Architecture-specific digests cause CI failures on different build environments
160- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant
161 
162## Writing Trigger.dev Tasks
163 
164Always import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.
165 
166```typescript
167import { task } from "@trigger.dev/sdk";
168 
169export const myTask = task({
170 id: "my-task",
171 run: async (payload: { message: string }) => {
172 // Task logic
173 },
174});
175```
176 
177### SDK Documentation Rules
178 
179The `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.
180 
181## Testing with the hello-world Reference Project
 
 
182 
183The reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.
184 
185First-time setup:
186 
1871. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)
1882. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`
1893. 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`
190 
191Running (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`
192 
193## Local Task Testing Workflow
 
 
 
194 
195### Step 1: Start Webapp in Background
196 
197```bash
198# Run from repo root with run_in_background: true
199pnpm run dev --filter webapp
200curl -s http://localhost:3030/healthcheck # Verify running
201```
202 
203### Step 2: Start Trigger Dev in Background
204 
205```bash
206# in your triggerdotdev/references clone
207cd projects/hello-world && pnpm exec trigger dev
208# Wait for "Local worker ready [node]"
209```
210 
211### Step 3: Trigger and Monitor Tasks via MCP
212 
213```
214mcp__trigger__get_current_worker(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev")
215mcp__trigger__trigger_task(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskId: "hello-world", payload: {"message": "Hello"})
216mcp__trigger__list_runs(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskIdentifier: "hello-world", limit: 5)
217```
218 
219Dashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs
 
 
 
 
 
220 
221<!-- intent-skills:start -->
222 
223# Skill mappings — when working in these areas, load the linked skill file into context.
224 
225skills:
226 
227- task: "Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge"
228 load: "node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md"
229- task: "Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init"
230 load: "node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md"
231<!-- intent-skills:end -->
232 
233## agentcrumbs
234 
235Add crumbs as you write code — not just when debugging. Mark lines with
236`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the
237branch throughout development and are stripped by `agentcrumbs strip`
238before merge.
239 
240### Namespaces
241 
242| Namespace | Description | Path |
243| ----------------- | ---------------------------------------------- | ----------------------------------- |
244| `webapp` | Main Remix app — API, dashboard, orchestration | `apps/webapp` |
245| `supervisor` | Task execution container manager | `apps/supervisor` |
246| `sdk` | Main SDK for writing tasks | `packages/trigger-sdk` |
247| `cli` | CLI and task image bundling | `packages/cli-v3` |
248| `core` | Shared types and subpath exports | `packages/core` |
249| `build` | Build extensions and types | `packages/build` |
250| `react-hooks` | React hooks for realtime/triggering | `packages/react-hooks` |
251| `redis-worker` | Redis-based background job system | `packages/redis-worker` |
252| `run-engine` | Run Engine 2.0 — core run lifecycle | `internal-packages/run-engine` |
253| `database` | Prisma client and schema | `internal-packages/database` |
254| `clickhouse` | ClickHouse client, migrations, analytics | `internal-packages/clickhouse` |
255| `schedule-engine` | Durable cron scheduling | `internal-packages/schedule-engine` |
256| `run-queue` | Run queue management | `internal-packages/run-queue` |
257 
258Do not invent new namespaces — pick from this table or ask first.
259 
260### For PR reviewers
261 
262Do not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs
263imports in reviews. These are temporary debug instrumentation stripped
264before merge. Data logged in crumbs (IDs, names, values) never reaches
265production.
266 
267### CLI
268 
269```bash
270pnpm exec agentcrumbs collect # start collector (multi-service)
271pnpm exec agentcrumbs tail --app trigger # live tail
272pnpm exec agentcrumbs clear --app trigger # remove crumbs before merge
273```
274 
275The 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`.
276 
triggerdotdev/trigger.dev · apps/webapp/CLAUDE.md
@@ +1 @@
1# Webapp
2 
3Remix 2.17.4 app serving as the main API, dashboard, and orchestration engine. Uses an Express server (`server.ts`).
4 
5## Verifying Changes
6 
7**Never run `pnpm run build --filter webapp` to verify changes.** Building proves almost nothing about correctness. The webapp is an app, not a public package — use typecheck from the repo root:
8 
 
 
9```bash
10pnpm run typecheck --filter webapp # ~1-2 minutes
 
 
 
 
 
 
 
 
 
11```
12 
13Only run typecheck after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
14 
15Note: Public packages (`packages/*`) use `build` instead. See the root CLAUDE.md for details.
16 
17## Testing Dashboard Changes with Chrome DevTools MCP
 
18 
19Use the `chrome-devtools` MCP server to visually verify local dashboard changes. The webapp must be running (`pnpm run dev --filter webapp` from repo root).
 
 
 
20 
21### Login
 
 
 
22 
 
 
 
 
 
 
 
 
 
 
 
23```
241. mcp__chrome-devtools__new_page(url: "http://localhost:3030")
25 → Redirects to /login
262. mcp__chrome-devtools__click the "Continue with Email" link
273. mcp__chrome-devtools__fill the email field with "local@trigger.dev"
284. mcp__chrome-devtools__click "Send a magic link"
29 → Auto-logs in and redirects to the dashboard (no email verification needed locally)
 
 
 
 
 
 
 
 
 
 
 
30```
31 
32### Navigating and Verifying
33 
34- **take_snapshot**: Get an a11y tree of the page (text content, element UIDs for interaction). Prefer this over screenshots for understanding page structure.
35- **take_screenshot**: Capture what the page looks like visually. Use to verify styling, layout, and visual changes.
36- **navigate_page**: Go to specific URLs, e.g. `http://localhost:3030/orgs/references-bc08/projects/hello-world-SiWs/env/dev/runs`
37- **click / fill**: Interact with elements using UIDs from `take_snapshot`.
38- **evaluate_script**: Run JS in the browser console for debugging.
39- **list_console_messages**: Check for console errors after navigating.
40 
41### Tips
42 
43- Snapshots can be very large on complex pages (200K+ chars). Use `take_screenshot` first to orient, then `take_snapshot` only when you need element UIDs to interact.
44- The local seeded user email is `local@trigger.dev`.
45- Dashboard URL pattern: `http://localhost:3030/orgs/{orgSlug}/projects/{projectSlug}/env/{envSlug}/{section}`
 
 
46 
47## Key File Locations
48 
49- **Trigger API**: `app/routes/api.v1.tasks.$taskId.trigger.ts`
50- **Batch trigger**: `app/routes/api.v1.tasks.batch.ts`
51- **OTEL endpoints**: `app/routes/otel.v1.logs.ts`, `app/routes/otel.v1.traces.ts`
52- **Prisma setup**: `app/db.server.ts`
53- **Run engine config**: `app/v3/runEngine.server.ts`
54- **Services**: `app/v3/services/**/*.server.ts`
55- **Presenters**: `app/v3/presenters/**/*.server.ts`
56 
57## Route Convention
58 
59Routes use Remix flat-file convention with dot-separated segments:
60`api.v1.tasks.$taskId.trigger.ts` -> `/api/v1/tasks/:taskId/trigger`
61 
62## Abort Signals
63 
64**Never use `request.signal`** for detecting client disconnects. It is broken due to a Node.js bug ([nodejs/node#55428](https://github.com/nodejs/node/issues/55428)) where the AbortSignal chain is severed when Remix internally clones the Request object. Instead, use `getRequestAbortSignal()` from `app/services/httpAsyncStorage.server.ts`, which is wired directly to Express `res.on("close")` and fires reliably.
 
 
65 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66```typescript
67import { getRequestAbortSignal } from "~/services/httpAsyncStorage.server";
68 
69// In route handlers, SSE streams, or any server-side code:
70const signal = getRequestAbortSignal();
 
 
 
 
71```
72 
73## Environment Variables
74 
75Access via `env` export from `app/env.server.ts`. **Never use `process.env` directly.**
76 
77For testable code, **never import env.server.ts** in test files. Pass configuration as options instead:
78- `realtime/nativeRealtimeClient.server.ts` (testable service, takes config as constructor arg)
79- `realtime/nativeRealtimeClientInstance.server.ts` (creates singleton with env config)
80 
81## Run Engine 2.0
82 
83The webapp integrates `@internal/run-engine` via `app/v3/runEngine.server.ts`. This is the singleton engine instance. Services in `app/v3/services/` call engine methods for all run lifecycle operations (triggering, completing, cancelling, etc.).
84 
85The `engineVersion.server.ts` file determines V1 vs V2 for a given environment. New code should always target V2.
 
 
86 
87## Background Workers
88 
89Background job workers use `@trigger.dev/redis-worker`:
90- `app/v3/commonWorker.server.ts`
91- `app/v3/alertsWorker.server.ts`
92- `app/v3/batchTriggerWorker.server.ts`
93 
94## Real-time
95 
96- Socket.io: `app/v3/handleSocketIo.server.ts`, `app/v3/handleWebsockets.server.ts`
97- Electric SQL: Powers real-time data sync for the dashboard
 
 
 
98 
99## v3 (engine V1) removed
100 
101v3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code is gone. The `app/v3/` directory name is historical; everything under it now serves V2. There is no V1 execution path: a `RunEngineVersion` `V1` branch (e.g. in `triggerTask.server.ts`, `cancelTaskRun.server.ts`) only rejects/finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `.claude/rules/legacy-v3-code.md` for the deprecation boundary.
 
 
 
 
102 
103## Performance: Trigger Hot Path
104 
105The `triggerTask.server.ts` service is the **highest-throughput code path** in the system. Every API trigger call goes through it. Keep it fast:
 
 
 
 
106 
107- **Do NOT add database queries** to `triggerTask.server.ts` or `batchTriggerV3.server.ts`. Task defaults (TTL, etc.) are resolved via `backgroundWorkerTask.findFirst()` in the queue concern (`queues.server.ts`) - one query per request, in mutually exclusive branches depending on locked/non-locked path. Piggyback on the existing query instead of adding new ones.
108- **Two-stage resolution pattern**: Task metadata is resolved in two stages by design:
109 1. **Trigger time** (`triggerTask.server.ts`): Only TTL is resolved from task defaults. Everything else uses whatever the caller provides.
110 2. **Dequeue time** (`dequeueSystem.ts`): Full `BackgroundWorkerTask` is loaded and retry config, machine config, maxDuration, etc. are resolved against task defaults.
111- If you need to add a new task-level default, **add it to the existing `select` clause** in the `backgroundWorkerTask.findFirst()` query — do NOT add a second query. If the default doesn't need to be known at trigger time, resolve it at dequeue time instead.
112- Batch triggers (`batchTriggerV3.server.ts`) follow the same pattern — keep batch paths equally fast.
113 
114## Prisma Query Patterns
115 
116- **Always use `findFirst` instead of `findUnique`.** Prisma's `findUnique` has an implicit DataLoader that batches concurrent calls into a single `IN` query. This batching cannot be disabled and has active bugs even in Prisma 6.x: uppercase UUIDs returning null (#25484, confirmed 6.4.1), composite key SQL correctness issues (#22202), and 5-10x worse performance than manual DataLoader (#6573, open since 2021). `findFirst` is never batched and avoids this entire class of issues.
117 
118## Transactions
119 
120- **Always use the `$transaction` helper from `~/db.server`, never `prisma.$transaction` (or `$replica.$transaction`) directly.** The helper wraps the raw call with tracing (an OTEL span + an `isolation_level` attribute) and boundary logging for infrastructure errors (e.g. `PrismaClientInitializationError`) that the raw client swallows. Signature: `$transaction(prisma, name?, async (tx) => { ... }, options?)`.
121- Pass the isolation level via options as a string: `{ isolationLevel: "Serializable" }`. Reach for `Serializable` when a read-then-write must be atomic against concurrent transactions (e.g. a count-then-delete invariant); the loser of a race fails and can retry, which is the right trade for rare, correctness-critical paths.
122- The helper returns `R | undefined` — guard the result (`if (!result) throw ...`) when callers need a definite value.
 
 
123 
124## PAT-authenticated API routes
125 
126- **A PAT route must resolve its target org/project scoped to the caller's membership** (`members: { some: { userId } }`, or a helper like `findProjectByRef` / `resolveOrganizationForApiUser`). A PAT is user-scoped and can name any org/project by id/slug, and the OSS RBAC fallback ability is permissive — so `ability.can(...)` alone does NOT reject a non-member on self-hosted. The RBAC `authorization` gate enforces the *role*; the membership-scoped query is the *tenant* floor. Skipping it opens cross-org access on OSS.
 
 
 
127 
128## React Patterns
129 
130- Only use `useCallback`/`useMemo` for context provider values, expensive derived data that is a dependency elsewhere, or stable refs required by a dependency array. Don't wrap ordinary event handlers or trivial computations.
131- Use named constants for sentinel/placeholder values (e.g. `const UNSET_VALUE = "__unset__"`) instead of raw string literals scattered across comparisons.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132 
@@ −1 +1 @@
1−# AGENTS.md
1+# Webapp
22  
3−This file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.
3+Remix 2.17.4 app serving as the main API, dashboard, and orchestration engine. Uses an Express server (`server.ts`).
44  
5−## Build and Development Commands
5+## Verifying Changes
66  
7−This is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.
7+**Never run `pnpm run build --filter webapp` to verify changes.** Building proves almost nothing about correctness. The webapp is an app, not a public package — use typecheck from the repo root:
88  
9−**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.
10− 
119 ```bash
12−pnpm run docker # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)
13−# pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
14−pnpm run db:migrate # Run database migrations
15−pnpm run db:seed # Seed the database (required for reference projects)
16− 
17−# Build packages (required before running)
18−pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
19− 
20−pnpm run dev --filter webapp # Run webapp (http://localhost:3030)
21−pnpm run dev --filter trigger.dev --filter "@trigger.dev/*" # Watch CLI and packages
10+pnpm run typecheck --filter webapp # ~1-2 minutes
2211 ```
2312  
24−### Verifying Changes
13+Only run typecheck after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
2514  
26−The verification command depends on where the change lives:
15+Note: Public packages (`packages/*`) use `build` instead. See the root CLAUDE.md for details.
2716  
28−- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.
29−- **Public packages** (`packages/*`): Use `build`.
17+## Testing Dashboard Changes with Chrome DevTools MCP
3018  
31−```bash
32−# Apps and internal packages — use typecheck
33−pnpm run typecheck --filter webapp # ~1-2 minutes
34−pnpm run typecheck --filter @internal/run-engine
19+Use the `chrome-devtools` MCP server to visually verify local dashboard changes. The webapp must be running (`pnpm run dev --filter webapp` from repo root).
3520  
36−# Public packages — use build
37−pnpm run build --filter @trigger.dev/sdk
38−pnpm run build --filter @trigger.dev/core
39−```
21+### Login
4022  
41−Only run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
42− 
43−## Testing
44− 
45−We use vitest exclusively. **Never mock anything** - use testcontainers instead.
46− 
47−```bash
48−pnpm run test --filter webapp # All tests for a package
49−cd internal-packages/run-engine
50−pnpm run test ./src/engine/tests/ttl.test.ts --run # Single test file
51−pnpm run build --filter @internal/run-engine # May need to build deps first
5223 ```
53− 
54−Test files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).
55− 
56−### Testcontainers for Redis/PostgreSQL
57− 
58−```typescript
59−import { redisTest, postgresTest, containerTest } from "@internal/testcontainers";
60− 
61−redisTest("should use redis", async ({ redisOptions }) => {
62− /* ... */
63−});
64−postgresTest("should use postgres", async ({ prisma }) => {
65− /* ... */
66−});
67−containerTest("should use both", async ({ prisma, redisOptions }) => {
68− /* ... */
69−});
24+1. mcp__chrome-devtools__new_page(url: "http://localhost:3030")
25+ → Redirects to /login
26+2. mcp__chrome-devtools__click the "Continue with Email" link
27+3. mcp__chrome-devtools__fill the email field with "local@trigger.dev"
28+4. mcp__chrome-devtools__click "Send a magic link"
29+ → Auto-logs in and redirects to the dashboard (no email verification needed locally)
7030 ```
7131  
72−## Code Style
32+### Navigating and Verifying
7333  
74−### Formatting and linting
34+- **take_snapshot**: Get an a11y tree of the page (text content, element UIDs for interaction). Prefer this over screenshots for understanding page structure.
35+- **take_screenshot**: Capture what the page looks like visually. Use to verify styling, layout, and visual changes.
36+- **navigate_page**: Go to specific URLs, e.g. `http://localhost:3030/orgs/references-bc08/projects/hello-world-SiWs/env/dev/runs`
37+- **click / fill**: Interact with elements using UIDs from `take_snapshot`.
38+- **evaluate_script**: Run JS in the browser console for debugging.
39+- **list_console_messages**: Check for console errors after navigating.
7540  
76−Format and lint are enforced by CI (`code-quality` check). Run before committing:
41+### Tips
7742  
78−```bash
79−pnpm run format # oxfmt — auto-fixes formatting
80−pnpm run lint:fix # oxlint — auto-fixes lint violations
81−pnpm run lint # oxlint — check only (no fixes)
82−```
43+- Snapshots can be very large on complex pages (200K+ chars). Use `take_screenshot` first to orient, then `take_snapshot` only when you need element UIDs to interact.
44+- The local seeded user email is `local@trigger.dev`.
45+- Dashboard URL pattern: `http://localhost:3030/orgs/{orgSlug}/projects/{projectSlug}/env/{envSlug}/{section}`
8346  
84−### Imports
47+## Key File Locations
8548  
86−**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:
87−- Circular dependencies cannot be resolved otherwise
88−- Code splitting is genuinely needed for performance
89−- The module must be loaded conditionally at runtime
49+- **Trigger API**: `app/routes/api.v1.tasks.$taskId.trigger.ts`
50+- **Batch trigger**: `app/routes/api.v1.tasks.batch.ts`
51+- **OTEL endpoints**: `app/routes/otel.v1.logs.ts`, `app/routes/otel.v1.traces.ts`
52+- **Prisma setup**: `app/db.server.ts`
53+- **Run engine config**: `app/v3/runEngine.server.ts`
54+- **Services**: `app/v3/services/**/*.server.ts`
55+- **Presenters**: `app/v3/presenters/**/*.server.ts`
9056  
91−Dynamic 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.
57+## Route Convention
9258  
93−## Changesets and Server Changes
59+Routes use Remix flat-file convention with dot-separated segments:
60+`api.v1.tasks.$taskId.trigger.ts` -> `/api/v1/tasks/:taskId/trigger`
9461  
95−When modifying any public package (`packages/*` or `integrations/*`), add a changeset:
62+## Abort Signals
9663  
97−```bash
98−pnpm run changeset:add
99−```
64+**Never use `request.signal`** for detecting client disconnects. It is broken due to a Node.js bug ([nodejs/node#55428](https://github.com/nodejs/node/issues/55428)) where the AbortSignal chain is severed when Remix internally clones the Request object. Instead, use `getRequestAbortSignal()` from `app/services/httpAsyncStorage.server.ts`, which is wired directly to Express `res.on("close")` and fires reliably.
10065  
101−- Default to **patch** for bug fixes and minor changes
102−- Confirm with maintainers before selecting **minor** (new features)
103−- **Never** select major without explicit approval
104− 
105−When modifying only server components (`apps/webapp/`, `apps/supervisor/`, etc.) with no package changes, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.
106− 
107−**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.
108− 
109−## Dependency Pinning
110− 
111−Zod 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).
112− 
113−## Architecture Overview
114− 
115−### Request Flow
116− 
117−User API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)
118− 
119−### Apps
120− 
121−- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.
122−- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).
123− 
124−### Public Packages
125− 
126−- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks
127−- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images
128−- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).
129−- **packages/build** (`@trigger.dev/build`): Build extensions and types
130−- **packages/react-hooks**: React hooks for realtime and triggering
131−- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system
132− 
133−### Internal Packages
134− 
135−- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)
136−- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries
137−- **internal-packages/run-engine**: "Run Engine 2.0" - core run lifecycle management
138−- **internal-packages/redis**: Redis client creation utilities (ioredis)
139−- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers
140−- **internal-packages/schedule-engine**: Durable cron scheduling
141− 
142−### v3 (engine V1) removed
143− 
144−v3 (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`.
145− 
146−### Documentation
147− 
148−Docs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.
149− 
150−### Reference Projects
151− 
152−Reference/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.
153− 
154−## Docker Image Guidelines
155− 
156−When updating Docker image references:
157− 
158−- **Always use multiplatform/index digests**, not architecture-specific digests
159−- Architecture-specific digests cause CI failures on different build environments
160−- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant
161− 
162−## Writing Trigger.dev Tasks
163− 
164−Always import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.
165− 
16666 ```typescript
167−import { task } from "@trigger.dev/sdk";
67+import { getRequestAbortSignal } from "~/services/httpAsyncStorage.server";
16868  
169−export const myTask = task({
170− id: "my-task",
171− run: async (payload: { message: string }) => {
172− // Task logic
173− },
174−});
69+// In route handlers, SSE streams, or any server-side code:
70+const signal = getRequestAbortSignal();
17571 ```
17672  
177−### SDK Documentation Rules
73+## Environment Variables
17874  
179−The `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.
75+Access via `env` export from `app/env.server.ts`. **Never use `process.env` directly.**
18076  
181−## Testing with the hello-world Reference Project
77+For testable code, **never import env.server.ts** in test files. Pass configuration as options instead:
78+- `realtime/nativeRealtimeClient.server.ts` (testable service, takes config as constructor arg)
79+- `realtime/nativeRealtimeClientInstance.server.ts` (creates singleton with env config)
18280  
183−The reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.
81+## Run Engine 2.0
18482  
185−First-time setup:
83+The webapp integrates `@internal/run-engine` via `app/v3/runEngine.server.ts`. This is the singleton engine instance. Services in `app/v3/services/` call engine methods for all run lifecycle operations (triggering, completing, cancelling, etc.).
18684  
187−1. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)
188−2. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`
189−3. 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`
85+The `engineVersion.server.ts` file determines V1 vs V2 for a given environment. New code should always target V2.
19086  
191−Running (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`
87+## Background Workers
19288  
193−## Local Task Testing Workflow
89+Background job workers use `@trigger.dev/redis-worker`:
90+- `app/v3/commonWorker.server.ts`
91+- `app/v3/alertsWorker.server.ts`
92+- `app/v3/batchTriggerWorker.server.ts`
19493  
195−### Step 1: Start Webapp in Background
94+## Real-time
19695  
197−```bash
198−# Run from repo root with run_in_background: true
199−pnpm run dev --filter webapp
200−curl -s http://localhost:3030/healthcheck # Verify running
201−```
96+- Socket.io: `app/v3/handleSocketIo.server.ts`, `app/v3/handleWebsockets.server.ts`
97+- Electric SQL: Powers real-time data sync for the dashboard
20298  
203−### Step 2: Start Trigger Dev in Background
99+## v3 (engine V1) removed
204100  
205−```bash
206−# in your triggerdotdev/references clone
207−cd projects/hello-world && pnpm exec trigger dev
208−# Wait for "Local worker ready [node]"
209−```
101+v3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code is gone. The `app/v3/` directory name is historical; everything under it now serves V2. There is no V1 execution path: a `RunEngineVersion` `V1` branch (e.g. in `triggerTask.server.ts`, `cancelTaskRun.server.ts`) only rejects/finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `.claude/rules/legacy-v3-code.md` for the deprecation boundary.
210102  
211−### Step 3: Trigger and Monitor Tasks via MCP
103+## Performance: Trigger Hot Path
212104  
213−```
214−mcp__trigger__get_current_worker(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev")
215−mcp__trigger__trigger_task(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskId: "hello-world", payload: {"message": "Hello"})
216−mcp__trigger__list_runs(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskIdentifier: "hello-world", limit: 5)
217−```
105+The `triggerTask.server.ts` service is the **highest-throughput code path** in the system. Every API trigger call goes through it. Keep it fast:
218106  
219−Dashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs
107+- **Do NOT add database queries** to `triggerTask.server.ts` or `batchTriggerV3.server.ts`. Task defaults (TTL, etc.) are resolved via `backgroundWorkerTask.findFirst()` in the queue concern (`queues.server.ts`) - one query per request, in mutually exclusive branches depending on locked/non-locked path. Piggyback on the existing query instead of adding new ones.
108+- **Two-stage resolution pattern**: Task metadata is resolved in two stages by design:
109+ 1. **Trigger time** (`triggerTask.server.ts`): Only TTL is resolved from task defaults. Everything else uses whatever the caller provides.
110+ 2. **Dequeue time** (`dequeueSystem.ts`): Full `BackgroundWorkerTask` is loaded and retry config, machine config, maxDuration, etc. are resolved against task defaults.
111+- If you need to add a new task-level default, **add it to the existing `select` clause** in the `backgroundWorkerTask.findFirst()` query — do NOT add a second query. If the default doesn't need to be known at trigger time, resolve it at dequeue time instead.
112+- Batch triggers (`batchTriggerV3.server.ts`) follow the same pattern — keep batch paths equally fast.
220113  
221−<!-- intent-skills:start -->
114+## Prisma Query Patterns
222115  
223−# Skill mappings — when working in these areas, load the linked skill file into context.
116+- **Always use `findFirst` instead of `findUnique`.** Prisma's `findUnique` has an implicit DataLoader that batches concurrent calls into a single `IN` query. This batching cannot be disabled and has active bugs even in Prisma 6.x: uppercase UUIDs returning null (#25484, confirmed 6.4.1), composite key SQL correctness issues (#22202), and 5-10x worse performance than manual DataLoader (#6573, open since 2021). `findFirst` is never batched and avoids this entire class of issues.
224117  
225−skills:
118+## Transactions
226119  
227−- task: "Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge"
228− load: "node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md"
229−- task: "Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init"
230− load: "node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md"
231−<!-- intent-skills:end -->
120+- **Always use the `$transaction` helper from `~/db.server`, never `prisma.$transaction` (or `$replica.$transaction`) directly.** The helper wraps the raw call with tracing (an OTEL span + an `isolation_level` attribute) and boundary logging for infrastructure errors (e.g. `PrismaClientInitializationError`) that the raw client swallows. Signature: `$transaction(prisma, name?, async (tx) => { ... }, options?)`.
121+- Pass the isolation level via options as a string: `{ isolationLevel: "Serializable" }`. Reach for `Serializable` when a read-then-write must be atomic against concurrent transactions (e.g. a count-then-delete invariant); the loser of a race fails and can retry, which is the right trade for rare, correctness-critical paths.
122+- The helper returns `R | undefined` — guard the result (`if (!result) throw ...`) when callers need a definite value.
232123  
233−## agentcrumbs
124+## PAT-authenticated API routes
234125  
235−Add crumbs as you write code — not just when debugging. Mark lines with
236−`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the
237−branch throughout development and are stripped by `agentcrumbs strip`
238−before merge.
126+- **A PAT route must resolve its target org/project scoped to the caller's membership** (`members: { some: { userId } }`, or a helper like `findProjectByRef` / `resolveOrganizationForApiUser`). A PAT is user-scoped and can name any org/project by id/slug, and the OSS RBAC fallback ability is permissive — so `ability.can(...)` alone does NOT reject a non-member on self-hosted. The RBAC `authorization` gate enforces the *role*; the membership-scoped query is the *tenant* floor. Skipping it opens cross-org access on OSS.
239127  
240−### Namespaces
128+## React Patterns
241129  
242−| Namespace | Description | Path |
243−| ----------------- | ---------------------------------------------- | ----------------------------------- |
244−| `webapp` | Main Remix app — API, dashboard, orchestration | `apps/webapp` |
245−| `supervisor` | Task execution container manager | `apps/supervisor` |
246−| `sdk` | Main SDK for writing tasks | `packages/trigger-sdk` |
247−| `cli` | CLI and task image bundling | `packages/cli-v3` |
248−| `core` | Shared types and subpath exports | `packages/core` |
249−| `build` | Build extensions and types | `packages/build` |
250−| `react-hooks` | React hooks for realtime/triggering | `packages/react-hooks` |
251−| `redis-worker` | Redis-based background job system | `packages/redis-worker` |
252−| `run-engine` | Run Engine 2.0 — core run lifecycle | `internal-packages/run-engine` |
253−| `database` | Prisma client and schema | `internal-packages/database` |
254−| `clickhouse` | ClickHouse client, migrations, analytics | `internal-packages/clickhouse` |
255−| `schedule-engine` | Durable cron scheduling | `internal-packages/schedule-engine` |
256−| `run-queue` | Run queue management | `internal-packages/run-queue` |
257− 
258−Do not invent new namespaces — pick from this table or ask first.
259− 
260−### For PR reviewers
261− 
262−Do not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs
263−imports in reviews. These are temporary debug instrumentation stripped
264−before merge. Data logged in crumbs (IDs, names, values) never reaches
265−production.
266− 
267−### CLI
268− 
269−```bash
270−pnpm exec agentcrumbs collect # start collector (multi-service)
271−pnpm exec agentcrumbs tail --app trigger # live tail
272−pnpm exec agentcrumbs clear --app trigger # remove crumbs before merge
273−```
274− 
275−The 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`.
130+- Only use `useCallback`/`useMemo` for context provider values, expensive derived data that is a dependency elsewhere, or stable refs required by a dependency array. Don't wrap ordinary event handlers or trivial computations.
131+- Use named constants for sentinel/placeholder values (e.g. `const UNSET_VALUE = "__unset__"`) instead of raw string literals scattered across comparisons.
276132  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack