RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/n8n-io-n8n-packages-nodes-base-agents ↔ n8n-io-n8n-agents

Comparison

A · AGENTS.md · n8n-io/n8nB · AGENTS.md · n8n-io/n8n
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections419229%
Commands11224%
Section tags81462%

What each file covers

Sections

4 shared · 19 only in A · 22 only in B
  • − Node Structure
  • − Node Types
  • − Programmatic Nodes
  • − Declarative Nodes
  • − Trigger Nodes
  • − Node Parameters
  • − Versioning
  • − Credentials
  • − Unit Tests
  • − Workflow Tests
  • − Creating a New Node
  • − Adding Dynamic Options
  • − Adding Resource Locator
  • − Best Practices
  • − TypeScript
  • − Security
  • − Code Organization
  • − UI/UX
  • − Example Nodes
  • + Project Overview
  • + General Guidelines
  • + Agent Skills and Claude Code Plugin
  • + Essential Commands
  • + Fresh checkout / agent setup
  • + Building
  • + Code Quality
  • + Architecture Overview
  • + Package Structure
  • + Technology Stack
  • + Key Architectural Patterns
  • + Key Development Patterns
  • + Workflow Traversal Utilities
  • + TypeScript Best Practices
  • + Persistence layer & the TypeORM boundary
  • + Frontend Development
  • + Testing Guidelines
  • + Design Principles
  • + Security Must Not Degrade the Building Experience
  • + Security Fix Hygiene
  • + Customer Confidentiality
  • + Github Guidelines
  •   AGENTS.md
  •   Testing
  •   Common Development Tasks
  •   Error Handling

Commands

1 shared · 1 only in A · 22 only in B
  • − vitest-mock-extended
  • + pnpm agent:setup
  • + pnpm agent:setup install
  • + pnpm agent:setup --json
  • + pnpm build > build.log 2>&1
  • + pnpm --filter @n8n/telemetry catalog
  • + pnpm build
  • + pnpm reset
  • + pnpm reset --full
  • + pnpm test:affected
  • + pnpm test <test-file>
  • + pnpm lint
  • + pnpm typecheck
  • + node-dev
  • + pnpm dev:ai
  • + eslint-disable
  • + vitest
  • + pnpm --filter=n8n-playwright test:local
  • + pnpm dev
  • + pnpm --filter n8n-containers services --services postgres,redis,mailpit,proxy
  • + node-1234-improve-request-handling
  • + node-1234-fix-ddos-vulnerability
  • + gh pr create --draft
  •   pnpm test

Section tags

8 shared · 1 only in A · 4 only in B
  • − ui
  • + setup
  • + build
  • + lint-format
  • + git-pr
  •   test
  •   code-style
  •   architecture
  •   types
  •   testing-strategy
  •   security
  •   do-not
  •   agent-behaviour

Line diff

+294 added−106 removed40 unchanged12.0% identical
n8n-io/n8n · packages/nodes-base/AGENTS.md
@@ −1 @@
1# AGENTS.md
2 
3Guidance for node development in the nodes-base package.
4 
5## Node Structure
6 
7Every node implements the `INodeType` interface with:
8- `description: INodeTypeDescription` - Node metadata and UI configuration
9- `execute?()` - For programmatic nodes
10- `poll?()` - For polling triggers (set `polling: true` in description)
11- `trigger?()` - For generic triggers
12- `webhook?()` - For webhook triggers
13- `webhookMethods?` - Webhook lifecycle (checkExists, create, delete)
14- `methods?` - loadOptions, listSearch, credentialTest, resourceMapping
15 
16## Node Types
17 
18### Programmatic Nodes
19Use `execute` function for custom logic. Example: `nodes/Discord/v2/DiscordV2.node.ts`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20 
21### Declarative Nodes
22Use `requestDefaults` and routing configuration instead of `execute`. Example: `nodes/Okta/Okta.node.ts`
23 
24### Trigger Nodes
25- **Webhook triggers**: Implement `webhook` and `webhookMethods` (checkExists, create, delete). Example: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`
26- **Polling triggers**: Set `polling: true` and implement `poll`. Use `getWorkflowStaticData('node')` to persist state. Example: `nodes/Google/Gmail/GmailTrigger.node.ts`
27- **Generic triggers**: Implement `trigger` function. Example: `nodes/MQTT/MqttTrigger.node.ts`
 
28 
29## Node Parameters
 
 
 
30 
31Common parameter types:
32- `string` - Text input
33- `options` - Dropdown (static or dynamic via `loadOptionsMethod`)
34- `resourceLocator` - Select by list, ID, or URL
35- `collection` - Key-value pairs
36- `fixedCollection` - Structured collections
37 
38Use `displayOptions` to show/hide fields based on other parameters. Use `noDataExpression: true` for resource/operation selectors.
39 
40## Versioning
 
 
 
 
 
 
 
41 
42- **Light versioning**: Use version arrays in description: `version: [3, 3.1, 3.2]`
43- **Full versioning**: Use `VersionedNodeType` class with separate version implementations. Example: `nodes/Set/Set.node.ts`
 
 
 
44 
45## Credentials
 
 
46 
47Credentials are defined in `credentials/` directory and implement `ICredentialType`:
48- `name` - Internal identifier
49- `displayName` - Human-readable name
50- `properties` - Credential fields
51- `authenticate` - Authentication configuration (generic or custom function)
52- `test` - Credential test request
53 
54Nodes can test credentials via `methods.credentialTest`.
 
 
 
55 
56## Testing
 
 
 
 
 
57 
58### Unit Tests
59- Use `vitest-mock-extended` for mocking interfaces
60- Use `nock` for HTTP mocking
61- Mock all external dependencies
62- Test happy paths, error handling, edge cases, and binary data
63 
64### Workflow Tests
65- Use `NodeTestHarness` with JSON workflow definitions
66- Mock external APIs with nock
67- Use `pnpm test` for running tests. Example: `cd packages/nodes-base/ && pnpm test TestFileName`
68 
69## Common Development Tasks
 
 
70 
71### Creating a New Node
721. Create directory: `nodes/YourService/`
732. Create `YourService.node.ts` implementing `INodeType`
743. Add icon SVG files in node directory
754. Define credentials in `credentials/` if needed
765. Write tests following testing guidelines
776. Register in `package.json` nodes array if needed
78 
79### Adding Dynamic Options
80Add `loadOptionsMethod` to parameter's `typeOptions` and implement method in `methods.loadOptions`.
 
 
 
 
81 
82### Adding Resource Locator
83Change parameter type to `'resourceLocator'`, define modes (list, id, url), add `searchListMethod` for list mode, add `extractValue` regex for URL mode.
84 
85## Best Practices
86 
87### TypeScript
88- Never use `any` type - use proper types or `unknown`
89- Avoid type casting with `as` - use type guards instead
90- Define interfaces for API responses
91 
92### Error Handling
93- Use `NodeOperationError` for user-facing errors
94- Use `NodeApiError` for API-related errors
95- Support `continueOnFail` option when appropriate
96 
97### Security
 
 
 
 
 
 
 
 
 
 
98 
99User input is untrusted. In nodes it arrives mainly through
100`this.getNodeParameter(...)` (and incoming `item.json`), and a workflow author
101controls these values.
102 
103**Never use an untrusted value as a computed object key in an assignment.** A
104value such as `__proto__`, `constructor`, or `prototype` pollutes the prototype
105chain:
 
 
106 
107```ts
108// UNSAFE — `table`/`key` come from this.getNodeParameter(...)
109if (acc[table] === undefined) acc[table] = {};
110acc[table][key] = value;
111```
112 
113Route dynamic-key writes through the `n8n-workflow` helpers, or build the
114accumulator as a `Map` / `Object.create(null)`:
 
 
 
 
 
 
115 
116```ts
117import { setSafeObjectProperty, isSafeObjectProperty } from 'n8n-workflow';
118 
119if (isSafeObjectProperty(table) && acc[table] === undefined) {
120 setSafeObjectProperty(acc, table, {});
121}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122```
123 
124This only applies to dynamic-key **writes** (grouping/aggregating rows by a
125user-chosen column is the common case). Reads like `const x = obj[key]` are
126safe. Reference usage: `nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts`.
 
 
 
 
127 
128### Code Organization
129- Separate operation/field descriptions into separate files
130- Create reusable API request helpers in GenericFunctions
131- Use kebab-case for files, PascalCase for classes
 
 
 
 
 
 
 
132 
133### UI/UX
134- Use clear `displayName` and `description` fields
135- Set sensible default values
136- Use `displayOptions` to show/hide fields conditionally
137 
138## Example Nodes
 
 
 
 
 
139 
140- Declarative: `nodes/Okta/Okta.node.ts`
141- Programmatic: `nodes/Discord/v2/DiscordV2.node.ts`
142- Webhook Trigger: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`
143- Polling Trigger: `nodes/Google/Gmail/GmailTrigger.node.ts`
144- Generic Trigger: `nodes/MQTT/MqttTrigger.node.ts`
145- Versioned: `nodes/Set/Set.node.ts`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146 
n8n-io/n8n · AGENTS.md
@@ +1 @@
1# AGENTS.md
2 
3This file provides guidance on how to work with the n8n repository.
4 
5## Project Overview
6 
7n8n is a workflow automation platform written in TypeScript, using a monorepo
8structure managed by pnpm workspaces. It consists of a Node.js backend, Vue.js
9frontend, and extensible node-based workflow engine.
 
 
 
 
 
10 
11## General Guidelines
12 
13- Always use pnpm
14- **Secrets on the command line:** if a developer opted into anonymous dev
15 metrics (`scripts/dev-metrics`), pnpm command arguments are recorded. Arguments
16 of secret-carrying words (`config`, `login`, `publish`, `token`) — whether a
17 subcommand or baked into a flag — are dropped, and the home dir is stripped from
18 paths, but other args are sent as-is — so never put secrets in a command. Pass
19 sensitive values via environment variables, which are never captured.
20- When adding comments, keep them concise and to the point - explain the "why"
21 in a line or two; don't be overly verbose. Comments should be scoped and
22 relevant to the surrounding code, not just to the current task
23- We use Linear as a ticket tracking system
24- We use Posthog for feature flags
25- To find registered telemetry events (names, descriptions, properties), run
26 `pnpm --filter @n8n/telemetry catalog` (`--json` for structured output). The
27 registry is being adopted incrementally, so search call sites if the catalog
28 has no match. The `n8n:telemetry` skill covers adding or changing events
29- When starting to work on a new ticket – create a new branch from fresh
30 master with the name specified in Linear ticket
31- When creating a new branch for a ticket in Linear - use the branch name
32 suggested by Linear, **unless it is a security fix** (see Security Fix
33 Hygiene below)
34- Use mermaid diagrams in MD files when you need to visualise something
35- **Developing v3 features:** land normal feature work on `master` behind an
36 opt-in flag; introduce breaking changes only on the `3.x` branch. See
37 [.github/DEVELOPING_V3.md](.github/DEVELOPING_V3.md).
38 
39## Agent Skills and Claude Code Plugin
 
40 
41n8n shared skills live in `.agents/skills/`. Claude Code consumes them through
42symlinks in `.claude/plugins/n8n/skills/`; OpenCode reads `.agents/skills/`
43directly. Harness-specific overrides remain real directories in the harness
44path, such as `.opencode/skills/setup-mcps/`. See
45[skills README](.agents/skills/AGENTS.md) for editing and sync guidance.
46 
47n8n-specific Claude Code commands and agents live in `.claude/plugins/n8n/` and
48are namespaced under `n8n:`. Use `n8n:` prefix when invoking them (e.g.
49`/n8n:create-pr`, `/n8n:plan`, `n8n:developer` agent). See
50[plugin README](.claude/plugins/n8n/README.md) for structure and details.
51 
52## Essential Commands
 
 
 
 
 
53 
54### Fresh checkout / agent setup
55 
56For a fresh checkout (cat-bot, a new hire, any agent verifying the repo
57builds), prefer `pnpm agent:setup` over running install + build + tests by
58hand. It chains them in one process, caps per-process memory and turbo
59concurrency so a 6GB box doesn't OOM, streams all output to
60`.agent-setup/<step>.log` (gitignored), and surfaces only a one-line summary
61per step plus the tail of the failing log. A machine-readable
62`.agent-setup/summary.json` is always written so a backgrounded run is
63readable in a single shot — no polling, no scrolling logs.
64 
65```bash
66pnpm agent:setup # install → build → test (full suite)
67pnpm agent:setup install # one step at a time
68pnpm agent:setup --json # JSON summary on stdout (for scripts/agents)
69```
70 
71### Building
72Use `pnpm build` to build all packages. ALWAYS redirect the output of the
73build command to a file:
74 
75```bash
76pnpm build > build.log 2>&1
77```
 
 
 
78 
79You can inspect the last few lines of the build log file to check for errors:
80```bash
81tail -n 20 build.log
82```
83 
84If build outputs or the turbo cache are stale (e.g. after switching branches
85or worktrees) but dependencies haven't changed, use `pnpm reset` (lightweight
86by default) for a fast recovery: it cleans build outputs and force-rebuilds
87(keeping `node_modules` and untracked files). If that doesn't fix your issue,
88use `pnpm reset --full`, which also wipes untracked files and reinstalls
89dependencies.
90 
91### Testing
92- `pnpm test` - Run all tests
93- `pnpm test:affected` - Runs tests based on what has changed since the last
94 commit
 
95 
96Running a particular test file requires going to the directory of that test
97and running: `pnpm test <test-file>`.
 
 
98 
99When changing directories, use `pushd` to navigate into the directory and
100`popd` to return to the previous directory. When in doubt, use `pwd` to check
101your current directory.
102 
103### Code Quality
104- `pnpm lint` - Lint code
105- `pnpm typecheck` - Run type checks
 
 
 
 
106 
107Always run lint and typecheck before committing code to ensure quality.
108Execute these commands from within the specific package directory you're
109working on (e.g., `cd packages/cli && pnpm lint`). Run the full repository
110check only when preparing the final PR. When your changes affect type
111definitions, interfaces in `@n8n/api-types`, or cross-package dependencies,
112build the system before running lint and typecheck.
113 
114## Architecture Overview
 
115 
116**Monorepo Structure:** pnpm workspaces with Turbo build orchestration
117 
118### Package Structure
 
 
 
119 
120The monorepo is organized into these key packages:
 
 
 
121 
122- **`packages/@n8n/api-types`**: Shared TypeScript interfaces between frontend and backend
123- **`packages/workflow`**: Core workflow interfaces and types
124- **`packages/core`**: Workflow execution engine
125- **`packages/cli`**: Express server, REST API, and CLI commands
126- **`packages/frontend/editor-ui`**: Vue 3 frontend application
127- **`packages/frontend/@n8n/i18n`**: Internationalization for UI text
128- **`packages/nodes-base`**: Built-in nodes for integrations
129- **`packages/@n8n/nodes-langchain`**: AI/LangChain nodes
130- **`packages/@n8n/instance-ai`**: "AI Assistant" in the UI, "Instance AI" in code — AI assistant backend. See its `CLAUDE.md` for architecture docs.
131- **`@n8n/design-system`**: Vue component library for UI consistency
132- **`@n8n/config`**: Centralized configuration management
133 
134## Technology Stack
 
 
135 
136- **Frontend:** Vue 3 + TypeScript + Vite + Pinia + Storybook UI Library
137- **Backend:** Node.js + TypeScript + Express + TypeORM
138- **Testing:** Vitest (unit) + Playwright (E2E)
139- **Database:** TypeORM with SQLite/PostgreSQL support
140- **Code Quality:** Biome (for formatting) + ESLint + lefthook git hooks
141 
142### Key Architectural Patterns
 
 
 
 
143 
1441. **Dependency Injection**: Uses `@n8n/di` for IoC container
1452. **Controller-Service-Repository**: Backend follows MVC-like pattern
1463. **Event-Driven**: Internal event bus for decoupled communication
1474. **Context-Based Execution**: Different contexts for different node types
1485. **State Management**: Frontend uses Pinia stores
1496. **Design System**: Reusable components and design tokens are centralized in
150 `@n8n/design-system`, where all pure Vue components should be placed to
151 ensure consistency and reusability
152 
153## Key Development Patterns
 
154 
155- Each package has isolated build configuration and can be developed independently
156- Hot reload works across the full stack during development
157- Node development uses dedicated `node-dev` CLI tool
158- Workflow tests are JSON-based for integration testing
159- AI features have dedicated development workflow (`pnpm dev:ai`)
160 
161### Workflow Traversal Utilities
162 
163The `n8n-workflow` package exports graph traversal utilities from
164`packages/workflow/src/common/`. Use these instead of custom traversal logic.
165 
166**Key concept:** `workflow.connections` is indexed by **source node**.
167To find parent nodes, use `mapConnectionsByDestination()` to invert it first.
168 
169```typescript
170import { getParentNodes, getChildNodes, mapConnectionsByDestination } from 'n8n-workflow';
171 
172// Finding parent nodes (predecessors) - requires inverted connections
173const connectionsByDestination = mapConnectionsByDestination(workflow.connections);
174const parents = getParentNodes(connectionsByDestination, 'NodeName', 'main', 1);
175 
176// Finding child nodes (successors) - uses connections directly
177const children = getChildNodes(workflow.connections, 'NodeName', 'main', 1);
178```
179 
180### TypeScript Best Practices
181- **NEVER use `any` type** - use proper types or `unknown`
182- **Avoid type casting with `as`** - use type guards or type predicates instead (except in test code where `as` is acceptable)
183- **Define shared interfaces in `@n8n/api-types`** package for FE/BE communication
184- **Lazy-load heavy modules** — if a module is only used in a specific code
185 path (not every request), use `await import()` at point of use instead of
186 top-level `import`. Applies especially to native modules and large parsers.
187 
188### Error Handling
189- Don't use the deprecated `ApplicationError` class anywhere — it's a
190 compatibility shim kept only so community nodes keep resolving. Use one of
191 these instead, picking by cause:
192 - `UserError` — the user caused it (invalid input, unauthorized action,
193 business-rule violation).
194 - `OperationalError` — a transient, expected issue (network request failing,
195 DB query timing out) that should be handled gracefully.
196 - `UnexpectedError` — a bug in the code (logic mistake, unhandled case,
197 failed assertion) that developers need to fix.
198- Import from appropriate error classes in each package
199 
200### Persistence layer & the TypeORM boundary
 
 
 
201 
202TypeORM (`@n8n/typeorm`) must stay in the **persistence layer** — the `@n8n/db`
203package or a backend module's own `database/` folder (entity/repository files).
204Business logic — services, controllers, handlers, commands, factories — must not
205import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). In
206`packages/cli` this is enforced by the `misplaced-n8n-typeorm-import` lint rule;
207a new import (or an inline `eslint-disable` of the rule) fails CI.
208 
209- **Pattern:** when a query needs operators (`In`, `IsNull`, `LessThan`,
210 `FindOptionsWhere`, …), put it behind a **use-case-named repository method**
211 that takes plain parameters and returns domain-shaped values — not a generic
212 `find(options)` passthrough.
213- **Transactions:** transaction orchestration belongs in the persistence layer.
214 Don't reach for `.manager` / `.manager.transaction(...)` or
215 `createQueryBuilder(...)` in business logic. Use the sanctioned primitive in
216 `@n8n/db`: inject the abstract `TransactionRunner` and wrap the unit of work in
217 `txRunner.run(ctx, async (ctx) => …)`. The callback receives an
218 `OperationContext` carrying the active transaction; thread that `ctx` into the
219 repository methods you call. `run` **requires** a context — pass an empty `{}`
220 at the operation entry point, and reuse the one you were handed everywhere
221 below it (a context that already carries a transaction is joined, not nested).
222 Repositories extend `BaseRepository` and resolve the right `EntityManager` with
223 `this.managerFor(ctx)`; the `Transaction` handle is opaque and never exposes a
224 driver type to business logic. See `oauth-token.service.ts` +
225 `oauth-*-token.repository.ts` for a worked example.
226- **Anti-patterns reviewers reject** — they hide the dependency instead of
227 removing it:
228 - String-matching TypeORM errors, e.g. `error.name === 'QueryFailedError'`.
229 - Relabeling the import from `@n8n/typeorm` to `@n8n/db` to silence the rule
230 (`@n8n/db` re-exports several operators/types, but this relabels the
231 dependency rather than removing it).
232 - Pushing `.manager` / `createQueryBuilder` into business logic to avoid an
233 operator import — trades a visible leak for an invisible one.
234 
235### Frontend Development
236- Refer to `packages/frontend/AGENTS.md`
237- **All UI text must use i18n** - add translations to `@n8n/i18n` package
238- **Use CSS variables directly** - never hardcode spacing as px values
239- **data-testid must be a single value** (no spaces or multiple values)
240- Always use `design-system-rules` skill in reviews
241 
242### Testing Guidelines
243- **Always work from within the package directory** when running tests
244- **Mock all external dependencies** in unit tests
245- **Prefer reusing hoisted shared `mock<T>(...)` fixtures** when a typed mock is immutable and used across tests. This rule exists to avoid massive test slowdowns from repeatedly creating nested proxy mocks while preserving the type contract. Avoid replacing these with `as unknown as T` helpers for entities like `User`.
246- **Confirm test cases with user** before writing unit tests
247- **Typecheck is critical before committing** - always run `pnpm typecheck`
248- **When modifying pinia stores**, check for unused computed properties
249- **For Vitest packages that use `@n8n/di` decorators**, use `createVitestConfigWithDecorators` from `@n8n/vitest-config/node-decorators`. It enables SWC `decoratorMetadata` (esbuild doesn't emit it) and externalizes workspace packages that register services (`@n8n/di`, `@n8n/config`, `@n8n/constants`, `n8n-workflow`) so a single DI `Container` instance is shared across the runtime. Loading them through Vitest's pipeline alongside their CJS dist produces two `Container`s and `Container.get(...)` returns `undefined`.
250 
251What we use for testing and writing tests:
252- For testing nodes and other backend components, we use Vitest for unit tests. Examples can be found in `packages/nodes-base/nodes/**/*test*`.
253- We use `nock` for server mocking
254- For frontend we use `vitest`
255- For E2E tests we use Playwright. Run with `pnpm --filter=n8n-playwright test:local`.
256 See `packages/testing/playwright/README.md` for details.
257- **To iterate on a feature without docker rebuilds**, boot service containers
258 and run `pnpm dev` locally — `pnpm --filter n8n-containers services --services postgres,redis,mailpit,proxy`
259 then `pnpm dev`. See [Develop against running containers](packages/testing/playwright/README.md#develop-against-running-containers-avoid-docker-rebuilds).
260- **For Playwright test maintenance/cleanup**, see `packages/testing/playwright/AGENTS.md` (includes janitor tool for static analysis, dead code removal, architecture enforcement, and TCR workflows).
261 
262### Common Development Tasks
263 
264When implementing features:
2651. Define API types in `packages/@n8n/api-types`
2662. Implement backend logic in `packages/cli` module, follow
267 `scripts/backend-module/backend-module-guide.md`
2683. Add API endpoints via controllers
2694. Update frontend in `packages/frontend/editor-ui` with i18n support
2705. Write tests with proper mocks
2716. Run `pnpm typecheck` to verify types
272 
273## Design Principles
274 
275### Security Must Not Degrade the Building Experience
276 
277Security improvements, whether driven by enterprise requirements or internal
278standards, must NEVER add friction to the common-case building experience. When
279designing security-related features (defaults, behaviors, flows, error
280handling), apply these checks:
281 
282- **No friction for the common case:** A community builder's workflow should
283 remain intuitive. Security should be invisible when it can be.
284- **Migration and upgrade paths:** Existing users must have a clear,
285 non-disruptive path forward when defaults or behaviors change.
286- **Security layers on top, not in competition:** Great UX and strong security
287 are not trade-offs. They're both required. If a design forces a choice
288 between them, the design needs more work.
289 
290### Security Fix Hygiene
291 
292**This is a public repository.** When working on security fixes, never expose
293the attack vector or vulnerability type in any public-facing artifact. Attackers
294monitor open-source repos for signals like branch names, commit messages, PR
295titles, test descriptions, and Linear URLs.
296 
297**Rules for security fixes:**
298 
299- **Branch names:** Do NOT use the Linear-suggested branch name if it reveals
300 the vulnerability. Rename to describe the fix neutrally
301 (e.g. `node-1234-improve-request-handling`, not
302 `node-1234-fix-ddos-vulnerability`).
303- **Commit messages:** Describe what the code now does, not the threat it
304 prevents (e.g. `fix: add payload size validation`, not
305 `fix: prevent denial of service`).
306- **Test descriptions:** Use neutral, functional language
307 (e.g. `'should sanitize query parameters'`, not
308 `'should prevent SQL injection'`).
309- **Code comments:** Do not describe the attack scenario in comments.
310- **Linear references:** Never include the URL slug
311 (e.g. `.../N8N-1234/fix-ssrf-vulnerability`).
312 
313### Customer Confidentiality
314 
315**This is a public repository.** Never mention customer names in any
316public-facing artifact — not all customers have agreed to be named publicly,
317and naming them can reveal security-relevant details about their setup.
318 
319This applies to PR titles and descriptions, branch names, commit messages,
320code, code comments, test names and test data, and fixtures. When implementing
321a customer request, describe the use case neutrally (e.g. "a customer with a
322large multi-main setup", not the company name) and use generic placeholder
323names (e.g. `Acme Corp`) in tests and examples.
324 
325## Github Guidelines
326- When creating a PR, use the conventions in
327 `.github/pull_request_template.md` and
328 `.github/pull_request_title_conventions.md`.
329- Use `gh pr create --draft` to create draft PRs.
330- If there is a corresponding Linear ticket, reference it in the PR
331 description using `https://linear.app/n8n/issue/[TICKET-ID]`. Do not
332 create a Linear ticket on your own — ask first.
333- always link to the github issue if mentioned in the linear ticket.
334 
@@ −1 +1 @@
11 # AGENTS.md
22  
3−Guidance for node development in the nodes-base package.
3+This file provides guidance on how to work with the n8n repository.
44  
5−## Node Structure
5+## Project Overview
66  
7−Every node implements the `INodeType` interface with:
8−- `description: INodeTypeDescription` - Node metadata and UI configuration
9−- `execute?()` - For programmatic nodes
10−- `poll?()` - For polling triggers (set `polling: true` in description)
11−- `trigger?()` - For generic triggers
12−- `webhook?()` - For webhook triggers
13−- `webhookMethods?` - Webhook lifecycle (checkExists, create, delete)
14−- `methods?` - loadOptions, listSearch, credentialTest, resourceMapping
7+n8n is a workflow automation platform written in TypeScript, using a monorepo
8+structure managed by pnpm workspaces. It consists of a Node.js backend, Vue.js
9+frontend, and extensible node-based workflow engine.
1510  
16−## Node Types
11+## General Guidelines
1712  
18−### Programmatic Nodes
19−Use `execute` function for custom logic. Example: `nodes/Discord/v2/DiscordV2.node.ts`
13+- Always use pnpm
14+- **Secrets on the command line:** if a developer opted into anonymous dev
15+ metrics (`scripts/dev-metrics`), pnpm command arguments are recorded. Arguments
16+ of secret-carrying words (`config`, `login`, `publish`, `token`) — whether a
17+ subcommand or baked into a flag — are dropped, and the home dir is stripped from
18+ paths, but other args are sent as-is — so never put secrets in a command. Pass
19+ sensitive values via environment variables, which are never captured.
20+- When adding comments, keep them concise and to the point - explain the "why"
21+ in a line or two; don't be overly verbose. Comments should be scoped and
22+ relevant to the surrounding code, not just to the current task
23+- We use Linear as a ticket tracking system
24+- We use Posthog for feature flags
25+- To find registered telemetry events (names, descriptions, properties), run
26+ `pnpm --filter @n8n/telemetry catalog` (`--json` for structured output). The
27+ registry is being adopted incrementally, so search call sites if the catalog
28+ has no match. The `n8n:telemetry` skill covers adding or changing events
29+- When starting to work on a new ticket – create a new branch from fresh
30+ master with the name specified in Linear ticket
31+- When creating a new branch for a ticket in Linear - use the branch name
32+ suggested by Linear, **unless it is a security fix** (see Security Fix
33+ Hygiene below)
34+- Use mermaid diagrams in MD files when you need to visualise something
35+- **Developing v3 features:** land normal feature work on `master` behind an
36+ opt-in flag; introduce breaking changes only on the `3.x` branch. See
37+ [.github/DEVELOPING_V3.md](.github/DEVELOPING_V3.md).
2038  
21−### Declarative Nodes
22−Use `requestDefaults` and routing configuration instead of `execute`. Example: `nodes/Okta/Okta.node.ts`
39+## Agent Skills and Claude Code Plugin
2340  
24−### Trigger Nodes
25−- **Webhook triggers**: Implement `webhook` and `webhookMethods` (checkExists, create, delete). Example: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`
26−- **Polling triggers**: Set `polling: true` and implement `poll`. Use `getWorkflowStaticData('node')` to persist state. Example: `nodes/Google/Gmail/GmailTrigger.node.ts`
27−- **Generic triggers**: Implement `trigger` function. Example: `nodes/MQTT/MqttTrigger.node.ts`
41+n8n shared skills live in `.agents/skills/`. Claude Code consumes them through
42+symlinks in `.claude/plugins/n8n/skills/`; OpenCode reads `.agents/skills/`
43+directly. Harness-specific overrides remain real directories in the harness
44+path, such as `.opencode/skills/setup-mcps/`. See
45+[skills README](.agents/skills/AGENTS.md) for editing and sync guidance.
2846  
29−## Node Parameters
47+n8n-specific Claude Code commands and agents live in `.claude/plugins/n8n/` and
48+are namespaced under `n8n:`. Use `n8n:` prefix when invoking them (e.g.
49+`/n8n:create-pr`, `/n8n:plan`, `n8n:developer` agent). See
50+[plugin README](.claude/plugins/n8n/README.md) for structure and details.
3051  
31−Common parameter types:
32−- `string` - Text input
33−- `options` - Dropdown (static or dynamic via `loadOptionsMethod`)
34−- `resourceLocator` - Select by list, ID, or URL
35−- `collection` - Key-value pairs
36−- `fixedCollection` - Structured collections
52+## Essential Commands
3753  
38−Use `displayOptions` to show/hide fields based on other parameters. Use `noDataExpression: true` for resource/operation selectors.
54+### Fresh checkout / agent setup
3955  
40−## Versioning
56+For a fresh checkout (cat-bot, a new hire, any agent verifying the repo
57+builds), prefer `pnpm agent:setup` over running install + build + tests by
58+hand. It chains them in one process, caps per-process memory and turbo
59+concurrency so a 6GB box doesn't OOM, streams all output to
60+`.agent-setup/<step>.log` (gitignored), and surfaces only a one-line summary
61+per step plus the tail of the failing log. A machine-readable
62+`.agent-setup/summary.json` is always written so a backgrounded run is
63+readable in a single shot — no polling, no scrolling logs.
4164  
42−- **Light versioning**: Use version arrays in description: `version: [3, 3.1, 3.2]`
43−- **Full versioning**: Use `VersionedNodeType` class with separate version implementations. Example: `nodes/Set/Set.node.ts`
65+```bash
66+pnpm agent:setup # install → build → test (full suite)
67+pnpm agent:setup install # one step at a time
68+pnpm agent:setup --json # JSON summary on stdout (for scripts/agents)
69+```
4470  
45−## Credentials
71+### Building
72+Use `pnpm build` to build all packages. ALWAYS redirect the output of the
73+build command to a file:
4674  
47−Credentials are defined in `credentials/` directory and implement `ICredentialType`:
48−- `name` - Internal identifier
49−- `displayName` - Human-readable name
50−- `properties` - Credential fields
51−- `authenticate` - Authentication configuration (generic or custom function)
52−- `test` - Credential test request
75+```bash
76+pnpm build > build.log 2>&1
77+```
5378  
54−Nodes can test credentials via `methods.credentialTest`.
79+You can inspect the last few lines of the build log file to check for errors:
80+```bash
81+tail -n 20 build.log
82+```
5583  
56−## Testing
84+If build outputs or the turbo cache are stale (e.g. after switching branches
85+or worktrees) but dependencies haven't changed, use `pnpm reset` (lightweight
86+by default) for a fast recovery: it cleans build outputs and force-rebuilds
87+(keeping `node_modules` and untracked files). If that doesn't fix your issue,
88+use `pnpm reset --full`, which also wipes untracked files and reinstalls
89+dependencies.
5790  
58−### Unit Tests
59−- Use `vitest-mock-extended` for mocking interfaces
60−- Use `nock` for HTTP mocking
61−- Mock all external dependencies
62−- Test happy paths, error handling, edge cases, and binary data
91+### Testing
92+- `pnpm test` - Run all tests
93+- `pnpm test:affected` - Runs tests based on what has changed since the last
94+ commit
6395  
64−### Workflow Tests
65−- Use `NodeTestHarness` with JSON workflow definitions
66−- Mock external APIs with nock
67−- Use `pnpm test` for running tests. Example: `cd packages/nodes-base/ && pnpm test TestFileName`
96+Running a particular test file requires going to the directory of that test
97+and running: `pnpm test <test-file>`.
6898  
69−## Common Development Tasks
99+When changing directories, use `pushd` to navigate into the directory and
100+`popd` to return to the previous directory. When in doubt, use `pwd` to check
101+your current directory.
70102  
71−### Creating a New Node
72−1. Create directory: `nodes/YourService/`
73−2. Create `YourService.node.ts` implementing `INodeType`
74−3. Add icon SVG files in node directory
75−4. Define credentials in `credentials/` if needed
76−5. Write tests following testing guidelines
77−6. Register in `package.json` nodes array if needed
103+### Code Quality
104+- `pnpm lint` - Lint code
105+- `pnpm typecheck` - Run type checks
78106  
79−### Adding Dynamic Options
80−Add `loadOptionsMethod` to parameter's `typeOptions` and implement method in `methods.loadOptions`.
107+Always run lint and typecheck before committing code to ensure quality.
108+Execute these commands from within the specific package directory you're
109+working on (e.g., `cd packages/cli && pnpm lint`). Run the full repository
110+check only when preparing the final PR. When your changes affect type
111+definitions, interfaces in `@n8n/api-types`, or cross-package dependencies,
112+build the system before running lint and typecheck.
81113  
82−### Adding Resource Locator
83−Change parameter type to `'resourceLocator'`, define modes (list, id, url), add `searchListMethod` for list mode, add `extractValue` regex for URL mode.
114+## Architecture Overview
84115  
85−## Best Practices
116+**Monorepo Structure:** pnpm workspaces with Turbo build orchestration
86117  
87−### TypeScript
88−- Never use `any` type - use proper types or `unknown`
89−- Avoid type casting with `as` - use type guards instead
90−- Define interfaces for API responses
118+### Package Structure
91119  
92−### Error Handling
93−- Use `NodeOperationError` for user-facing errors
94−- Use `NodeApiError` for API-related errors
95−- Support `continueOnFail` option when appropriate
120+The monorepo is organized into these key packages:
96121  
97−### Security
122+- **`packages/@n8n/api-types`**: Shared TypeScript interfaces between frontend and backend
123+- **`packages/workflow`**: Core workflow interfaces and types
124+- **`packages/core`**: Workflow execution engine
125+- **`packages/cli`**: Express server, REST API, and CLI commands
126+- **`packages/frontend/editor-ui`**: Vue 3 frontend application
127+- **`packages/frontend/@n8n/i18n`**: Internationalization for UI text
128+- **`packages/nodes-base`**: Built-in nodes for integrations
129+- **`packages/@n8n/nodes-langchain`**: AI/LangChain nodes
130+- **`packages/@n8n/instance-ai`**: "AI Assistant" in the UI, "Instance AI" in code — AI assistant backend. See its `CLAUDE.md` for architecture docs.
131+- **`@n8n/design-system`**: Vue component library for UI consistency
132+- **`@n8n/config`**: Centralized configuration management
98133  
99−User input is untrusted. In nodes it arrives mainly through
100−`this.getNodeParameter(...)` (and incoming `item.json`), and a workflow author
101−controls these values.
134+## Technology Stack
102135  
103−**Never use an untrusted value as a computed object key in an assignment.** A
104−value such as `__proto__`, `constructor`, or `prototype` pollutes the prototype
105−chain:
136+- **Frontend:** Vue 3 + TypeScript + Vite + Pinia + Storybook UI Library
137+- **Backend:** Node.js + TypeScript + Express + TypeORM
138+- **Testing:** Vitest (unit) + Playwright (E2E)
139+- **Database:** TypeORM with SQLite/PostgreSQL support
140+- **Code Quality:** Biome (for formatting) + ESLint + lefthook git hooks
106141  
107−```ts
108−// UNSAFE — `table`/`key` come from this.getNodeParameter(...)
109−if (acc[table] === undefined) acc[table] = {};
110−acc[table][key] = value;
111−```
142+### Key Architectural Patterns
112143  
113−Route dynamic-key writes through the `n8n-workflow` helpers, or build the
114−accumulator as a `Map` / `Object.create(null)`:
144+1. **Dependency Injection**: Uses `@n8n/di` for IoC container
145+2. **Controller-Service-Repository**: Backend follows MVC-like pattern
146+3. **Event-Driven**: Internal event bus for decoupled communication
147+4. **Context-Based Execution**: Different contexts for different node types
148+5. **State Management**: Frontend uses Pinia stores
149+6. **Design System**: Reusable components and design tokens are centralized in
150+ `@n8n/design-system`, where all pure Vue components should be placed to
151+ ensure consistency and reusability
115152  
116−```ts
117−import { setSafeObjectProperty, isSafeObjectProperty } from 'n8n-workflow';
153+## Key Development Patterns
118154  
119−if (isSafeObjectProperty(table) && acc[table] === undefined) {
120− setSafeObjectProperty(acc, table, {});
121−}
155+- Each package has isolated build configuration and can be developed independently
156+- Hot reload works across the full stack during development
157+- Node development uses dedicated `node-dev` CLI tool
158+- Workflow tests are JSON-based for integration testing
159+- AI features have dedicated development workflow (`pnpm dev:ai`)
160+ 
161+### Workflow Traversal Utilities
162+ 
163+The `n8n-workflow` package exports graph traversal utilities from
164+`packages/workflow/src/common/`. Use these instead of custom traversal logic.
165+ 
166+**Key concept:** `workflow.connections` is indexed by **source node**.
167+To find parent nodes, use `mapConnectionsByDestination()` to invert it first.
168+ 
169+```typescript
170+import { getParentNodes, getChildNodes, mapConnectionsByDestination } from 'n8n-workflow';
171+ 
172+// Finding parent nodes (predecessors) - requires inverted connections
173+const connectionsByDestination = mapConnectionsByDestination(workflow.connections);
174+const parents = getParentNodes(connectionsByDestination, 'NodeName', 'main', 1);
175+ 
176+// Finding child nodes (successors) - uses connections directly
177+const children = getChildNodes(workflow.connections, 'NodeName', 'main', 1);
122178 ```
123179  
124−This only applies to dynamic-key **writes** (grouping/aggregating rows by a
125−user-chosen column is the common case). Reads like `const x = obj[key]` are
126−safe. Reference usage: `nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts`.
180+### TypeScript Best Practices
181+- **NEVER use `any` type** - use proper types or `unknown`
182+- **Avoid type casting with `as`** - use type guards or type predicates instead (except in test code where `as` is acceptable)
183+- **Define shared interfaces in `@n8n/api-types`** package for FE/BE communication
184+- **Lazy-load heavy modules** — if a module is only used in a specific code
185+ path (not every request), use `await import()` at point of use instead of
186+ top-level `import`. Applies especially to native modules and large parsers.
127187  
128−### Code Organization
129−- Separate operation/field descriptions into separate files
130−- Create reusable API request helpers in GenericFunctions
131−- Use kebab-case for files, PascalCase for classes
188+### Error Handling
189+- Don't use the deprecated `ApplicationError` class anywhere — it's a
190+ compatibility shim kept only so community nodes keep resolving. Use one of
191+ these instead, picking by cause:
192+ - `UserError` — the user caused it (invalid input, unauthorized action,
193+ business-rule violation).
194+ - `OperationalError` — a transient, expected issue (network request failing,
195+ DB query timing out) that should be handled gracefully.
196+ - `UnexpectedError` — a bug in the code (logic mistake, unhandled case,
197+ failed assertion) that developers need to fix.
198+- Import from appropriate error classes in each package
132199  
133−### UI/UX
134−- Use clear `displayName` and `description` fields
135−- Set sensible default values
136−- Use `displayOptions` to show/hide fields conditionally
200+### Persistence layer & the TypeORM boundary
137201  
138−## Example Nodes
202+TypeORM (`@n8n/typeorm`) must stay in the **persistence layer** — the `@n8n/db`
203+package or a backend module's own `database/` folder (entity/repository files).
204+Business logic — services, controllers, handlers, commands, factories — must not
205+import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). In
206+`packages/cli` this is enforced by the `misplaced-n8n-typeorm-import` lint rule;
207+a new import (or an inline `eslint-disable` of the rule) fails CI.
139208  
140−- Declarative: `nodes/Okta/Okta.node.ts`
141−- Programmatic: `nodes/Discord/v2/DiscordV2.node.ts`
142−- Webhook Trigger: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`
143−- Polling Trigger: `nodes/Google/Gmail/GmailTrigger.node.ts`
144−- Generic Trigger: `nodes/MQTT/MqttTrigger.node.ts`
145−- Versioned: `nodes/Set/Set.node.ts`
209+- **Pattern:** when a query needs operators (`In`, `IsNull`, `LessThan`,
210+ `FindOptionsWhere`, …), put it behind a **use-case-named repository method**
211+ that takes plain parameters and returns domain-shaped values — not a generic
212+ `find(options)` passthrough.
213+- **Transactions:** transaction orchestration belongs in the persistence layer.
214+ Don't reach for `.manager` / `.manager.transaction(...)` or
215+ `createQueryBuilder(...)` in business logic. Use the sanctioned primitive in
216+ `@n8n/db`: inject the abstract `TransactionRunner` and wrap the unit of work in
217+ `txRunner.run(ctx, async (ctx) => …)`. The callback receives an
218+ `OperationContext` carrying the active transaction; thread that `ctx` into the
219+ repository methods you call. `run` **requires** a context — pass an empty `{}`
220+ at the operation entry point, and reuse the one you were handed everywhere
221+ below it (a context that already carries a transaction is joined, not nested).
222+ Repositories extend `BaseRepository` and resolve the right `EntityManager` with
223+ `this.managerFor(ctx)`; the `Transaction` handle is opaque and never exposes a
224+ driver type to business logic. See `oauth-token.service.ts` +
225+ `oauth-*-token.repository.ts` for a worked example.
226+- **Anti-patterns reviewers reject** — they hide the dependency instead of
227+ removing it:
228+ - String-matching TypeORM errors, e.g. `error.name === 'QueryFailedError'`.
229+ - Relabeling the import from `@n8n/typeorm` to `@n8n/db` to silence the rule
230+ (`@n8n/db` re-exports several operators/types, but this relabels the
231+ dependency rather than removing it).
232+ - Pushing `.manager` / `createQueryBuilder` into business logic to avoid an
233+ operator import — trades a visible leak for an invisible one.
234+ 
235+### Frontend Development
236+- Refer to `packages/frontend/AGENTS.md`
237+- **All UI text must use i18n** - add translations to `@n8n/i18n` package
238+- **Use CSS variables directly** - never hardcode spacing as px values
239+- **data-testid must be a single value** (no spaces or multiple values)
240+- Always use `design-system-rules` skill in reviews
241+ 
242+### Testing Guidelines
243+- **Always work from within the package directory** when running tests
244+- **Mock all external dependencies** in unit tests
245+- **Prefer reusing hoisted shared `mock<T>(...)` fixtures** when a typed mock is immutable and used across tests. This rule exists to avoid massive test slowdowns from repeatedly creating nested proxy mocks while preserving the type contract. Avoid replacing these with `as unknown as T` helpers for entities like `User`.
246+- **Confirm test cases with user** before writing unit tests
247+- **Typecheck is critical before committing** - always run `pnpm typecheck`
248+- **When modifying pinia stores**, check for unused computed properties
249+- **For Vitest packages that use `@n8n/di` decorators**, use `createVitestConfigWithDecorators` from `@n8n/vitest-config/node-decorators`. It enables SWC `decoratorMetadata` (esbuild doesn't emit it) and externalizes workspace packages that register services (`@n8n/di`, `@n8n/config`, `@n8n/constants`, `n8n-workflow`) so a single DI `Container` instance is shared across the runtime. Loading them through Vitest's pipeline alongside their CJS dist produces two `Container`s and `Container.get(...)` returns `undefined`.
250+ 
251+What we use for testing and writing tests:
252+- For testing nodes and other backend components, we use Vitest for unit tests. Examples can be found in `packages/nodes-base/nodes/**/*test*`.
253+- We use `nock` for server mocking
254+- For frontend we use `vitest`
255+- For E2E tests we use Playwright. Run with `pnpm --filter=n8n-playwright test:local`.
256+ See `packages/testing/playwright/README.md` for details.
257+- **To iterate on a feature without docker rebuilds**, boot service containers
258+ and run `pnpm dev` locally — `pnpm --filter n8n-containers services --services postgres,redis,mailpit,proxy`
259+ then `pnpm dev`. See [Develop against running containers](packages/testing/playwright/README.md#develop-against-running-containers-avoid-docker-rebuilds).
260+- **For Playwright test maintenance/cleanup**, see `packages/testing/playwright/AGENTS.md` (includes janitor tool for static analysis, dead code removal, architecture enforcement, and TCR workflows).
261+ 
262+### Common Development Tasks
263+ 
264+When implementing features:
265+1. Define API types in `packages/@n8n/api-types`
266+2. Implement backend logic in `packages/cli` module, follow
267+ `scripts/backend-module/backend-module-guide.md`
268+3. Add API endpoints via controllers
269+4. Update frontend in `packages/frontend/editor-ui` with i18n support
270+5. Write tests with proper mocks
271+6. Run `pnpm typecheck` to verify types
272+ 
273+## Design Principles
274+ 
275+### Security Must Not Degrade the Building Experience
276+ 
277+Security improvements, whether driven by enterprise requirements or internal
278+standards, must NEVER add friction to the common-case building experience. When
279+designing security-related features (defaults, behaviors, flows, error
280+handling), apply these checks:
281+ 
282+- **No friction for the common case:** A community builder's workflow should
283+ remain intuitive. Security should be invisible when it can be.
284+- **Migration and upgrade paths:** Existing users must have a clear,
285+ non-disruptive path forward when defaults or behaviors change.
286+- **Security layers on top, not in competition:** Great UX and strong security
287+ are not trade-offs. They're both required. If a design forces a choice
288+ between them, the design needs more work.
289+ 
290+### Security Fix Hygiene
291+ 
292+**This is a public repository.** When working on security fixes, never expose
293+the attack vector or vulnerability type in any public-facing artifact. Attackers
294+monitor open-source repos for signals like branch names, commit messages, PR
295+titles, test descriptions, and Linear URLs.
296+ 
297+**Rules for security fixes:**
298+ 
299+- **Branch names:** Do NOT use the Linear-suggested branch name if it reveals
300+ the vulnerability. Rename to describe the fix neutrally
301+ (e.g. `node-1234-improve-request-handling`, not
302+ `node-1234-fix-ddos-vulnerability`).
303+- **Commit messages:** Describe what the code now does, not the threat it
304+ prevents (e.g. `fix: add payload size validation`, not
305+ `fix: prevent denial of service`).
306+- **Test descriptions:** Use neutral, functional language
307+ (e.g. `'should sanitize query parameters'`, not
308+ `'should prevent SQL injection'`).
309+- **Code comments:** Do not describe the attack scenario in comments.
310+- **Linear references:** Never include the URL slug
311+ (e.g. `.../N8N-1234/fix-ssrf-vulnerability`).
312+ 
313+### Customer Confidentiality
314+ 
315+**This is a public repository.** Never mention customer names in any
316+public-facing artifact — not all customers have agreed to be named publicly,
317+and naming them can reveal security-relevant details about their setup.
318+ 
319+This applies to PR titles and descriptions, branch names, commit messages,
320+code, code comments, test names and test data, and fixtures. When implementing
321+a customer request, describe the use case neutrally (e.g. "a customer with a
322+large multi-main setup", not the company name) and use generic placeholder
323+names (e.g. `Acme Corp`) in tests and examples.
324+ 
325+## Github Guidelines
326+- When creating a PR, use the conventions in
327+ `.github/pull_request_template.md` and
328+ `.github/pull_request_title_conventions.md`.
329+- Use `gh pr create --draft` to create draft PRs.
330+- If there is a corresponding Linear ticket, reference it in the PR
331+ description using `https://linear.app/n8n/issue/[TICKET-ID]`. Do not
332+ create a Linear ticket on your own — ask first.
333+- always link to the github issue if mentioned in the linear ticket.
146334  
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