Compare commits

...

988 Commits

Author SHA1 Message Date
Riqwan Thamir
7a334e3b15
refactor(core): Remove the build-agent sub-agent (no-changelog) (#41356)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 21:10:02 +00:00
Riqwan Thamir
e532aae35b
feat(core): Run Agent Builder tools in the Instance AI orchestrator (no-changelog) (#41355)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 21:09:54 +00:00
Riqwan Thamir
6e8064c6af
refactor(core): Prefix Instance AI and Agent Builder tool names (no-changelog) (#41354)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 20:58:37 +00:00
Luka Zivkovic
f73dc337f8
fix(core): Trace verification helpers and provider attempts (#40936)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:38:11 +00:00
Stephen Wright
967591041e
fix(core): Keep offline_access when a protected resource omits it (#41384) 2026-10-19 17:28:19 +00:00
srinivas-kannepalli
791c7bc418
fix(core): Allow gateway model IDs and forward credential headers in agents (#40470)
Co-authored-by: Michael Drury <michael.drury@n8n.io>
2026-10-19 16:20:58 +00:00
Irénée
d4bde146d6
fix: Align data table and variable editing on protected instances (#41258)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 15:43:43 +00:00
Jaakko Husso
16fb42d76e
feat(core): Add a system chat surface to the Agents runtime (no-changelog) (#41231)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 15:33:53 +00:00
Rick Gale
dd30fc447b
chore: Assign agent code to the Agent team (no-changelog) (#41394)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 15:28:29 +00:00
Stephen Wright
14d2d30563
fix(editor): Offer the managed OAuth choice when the app is supplied (#40284) 2026-10-19 15:01:55 +00:00
Jaakko Husso
ef30f75e7b
refactor(core): Move the Agents chat relay into its own service (no-changelog) (#41230)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:58:57 +00:00
Bernhard Wittmann
70f0131be5
fix(editor): Stop credential icon overlapping the credential name in the agent credential picker (#41262) 2026-10-19 14:58:31 +00:00
Yen Su
f527f748fd
feat(Databricks Node): Add the Lakebase Chat Memory sub-node (no-changelog) (#41055) 2026-10-19 14:57:01 +00:00
n8n-cat-bot[bot]
35874f421d
chore: Flaky test: InputPanel.test.ts (2 master or merge-queue commits in 72 h) (#41445)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-19 14:50:51 +00:00
Jaakko Husso
c94ff47cd8
feat(core): Add instance-scoped agents to the Agents (no-changelog) (#40616)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:37:16 +00:00
Svetoslav Dekov
804033af54
feat(core): Add skills hub CRUD tools to the MCP server (no-changelog) (#41398)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:35:54 +00:00
Mike Repeć
de4411b6b8
fix(core): Copy native evaluation results as JSON and hand other values to the engine (no-changelog) (#41082) 2026-10-19 14:28:55 +00:00
Bernhard Wittmann
51e53ad9b7
fix(editor): Match the credential dropdown width to its field and remove horizontal scroll (#41260) 2026-10-19 13:57:53 +00:00
Thanasis G
d6d24f267c
feat(core): Report the CPU and memory limits n8n was given in telemetry (#40421)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 13:50:59 +00:00
Michael Drury
d74f3f2cdd
fix(core): Keep cancelled Assistant activity settled (#40786) 2026-10-19 13:42:22 +00:00
n8n-cat-bot[bot]
b850125fbd
chore: Flaky test: AgentBuilderView.test.ts (2 master or merge-queue commits in 72 h) (#41427)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-19 12:57:09 +00:00
Riqwan Thamir
198127f9cd
feat(core): Support legacy tool names and extending runtime skill sources (no-changelog) (#41353)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 12:51:33 +00:00
Riqwan Thamir
5ad13f6606
feat(core): Record builder success metrics in Instance AI traces (no-changelog) (#40714)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 12:38:33 +00:00
Ricardo Espinoza
b27f132218
fix(core): Copy each agent draft into the skills hub only once (no-changelog) (#41350) 2026-10-19 12:36:57 +00:00
Rob Hough
20ea6717a0
fix(editor): Restore From AI button corner radii (#41176)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
Co-authored-by: Sebastien Powell <sebpowell@users.noreply.github.com>
2026-10-19 12:33:32 +00:00
Jaakko Husso
35e9ee9da5
feat(editor): Track the concise style experiment for Instance AI (no-changelog) (#41423)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:31:00 +00:00
Thanasis G
0c1a78793a
feat(Azure OpenAI Chat Model Node): Add an optional Project field to the Foundry credentials (#41181)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:25:17 +00:00
Jaakko Husso
f4f606754c
feat(core): Report prompt size on Instance AI credit claims (no-changelog) (#41402)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:18:44 +00:00
Eugene
4fd7a1bad7
fix(core): Apply partial Agent plan updates and report finish time (no-changelog) (#41267) 2026-10-19 12:16:51 +00:00
Ricardo Espinoza
086fcf9437
feat(core): Add SCIM user provisioning (no-changelog) (#40419) 2026-10-19 12:16:33 +00:00
Yash Rajeshbhai Darji
660849d93e
fix(Send Email Node): Send to every recipient when a recipient field is an array (#36467)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-19 12:13:03 +00:00
Bernhard Wittmann
117aa146ce
fix(editor): Show the agent's own icon on Microsoft Teams install cards (no-changelog) (#41273) 2026-10-19 12:01:36 +00:00
Svetoslav Dekov
8323dfd1e1
fix(core): Let preview chat agents make changes through their tools (#41403)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:50:31 +00:00
Mike Repeć
95b54e5390
fix(core): Decline the whole expression when the extension rewrite reaches an optional chain (no-changelog) (#41371) 2026-10-19 11:45:21 +00:00
yehorkardash
d27de60b95
feat: Don't save MCP connections without user approval (#39996)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-19 11:28:03 +00:00
Svetoslav Dekov
38a1b15646
feat(core): Let skills API callers report their telemetry source (no-changelog) (#41397)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:11:15 +00:00
Jan
d9d6c027f6
fix(editor): Center notification title with its icon in design-system (no-changelog) (#40323)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 11:04:35 +00:00
Sebastien Powell
28602ed56e
fix(editor): Place sticky notes and nodes at the right-click and clear the selection (#41365) 2026-10-19 10:56:37 +00:00
Jan
c084d996af
feat(editor): Extend N8nCopyInput with accessibility, redaction, loading and actions (#34942)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Sebastien Powell <sebpowell@users.noreply.github.com>
2026-10-19 10:54:01 +00:00
Stephen Wright
06ba85cbb9
fix(Gmail Node): Keep the References header on a draft created in a thread (#41392) 2026-10-19 10:23:26 +00:00
Tariq Shatat
b98640f0ab
fix(editor): Improve NDV credential options performance on large instances (#40198)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 10:18:17 +00:00
Charlie Kolb
04761593da
fix(editor): Support IPv6 connections to the dev server (no-changelog) (#41401) 2026-10-19 10:16:46 +00:00
Csaba Tuncsik
191ea98482
feat(Databricks Node): Show the Vector Store, Embeddings and AI Agent nodes in the node picker (#41206) 2026-10-19 10:08:35 +00:00
yehorkardash
9a025a188f
fix(editor): Load credential types on startup (#41400) 2026-10-19 09:53:26 +00:00
Shireen Missi
4ceb7dc33e
chore: Assign Nodes and Relay ownership in OWNERS (no-changelog) (#41073)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-19 09:50:10 +00:00
Toni Devine
275f7ebf68
feat(editor): Align the WhatsApp channel setup and settings with the … (#41283) 2026-10-19 09:48:19 +00:00
Mike Repeć
6e04287582
fix(core): Key queue job outcomes by job on shutdown resume (#40569) 2026-10-19 09:42:09 +00:00
Thanasis G
b2edcb5727
feat(core): Report the runtime n8n runs on in telemetry (#40420)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 09:32:53 +00:00
Stephen Wright
952cbf2bf2
feat(Databricks Node): Add the Lakebase Insert or Update operation (no-changelog) (#40645) 2026-10-19 09:29:04 +00:00
Bernhard Wittmann
5a02fc57aa
feat(core): Let Teams agents send messages from scheduled tasks (no-changelog) (#41244) 2026-10-19 09:14:29 +00:00
Tuukka Kantola
9eb7cb9849
refactor(editor): Apply brand icons to more product surfaces (no-changelog) (#41380)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 08:56:48 +00:00
Joco-95
eac2f46b0c
feat: Implements workflow previews above Assistant empty state experiment (#40913) 2026-10-19 08:52:09 +00:00
Stephen Wright
9d2df34333
feat(Databricks Node): Add the Lakebase Update operation (no-changelog) (#40546) 2026-10-19 08:48:54 +00:00
Anne Aguirre
4d292a6009
feat(core): Only show execution input and output for agent subworkflows in timeline (#41189) 2026-10-19 08:40:35 +00:00
Riqwan Thamir
10b1b30e72
chore(core): Remove leftover runtime skill references from Instance AI (#41351)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 08:39:52 +00:00
Lorent Lempereur
ffec16672c
feat(core): Run the idempotency-key cleanup as a durable system task (no-changelog) (#41009)
Co-authored-by: Veljko Terzic <veljko.terzic@n8n.io>
2026-10-19 08:25:25 +00:00
n8n-assistant[bot]
0544d7e597
chore: Update e2e impact map (#41387)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-19 08:21:51 +00:00
Veljko Terzic
d9cfa767ab
test(core): Add integration tests for the system task runner across mains (no-changelog) (#40878) 2026-10-19 08:20:18 +00:00
Kai
f6d70c140b
feat(editor): Show multiple workflows in the review detail view (#40695) 2026-10-19 07:54:56 +00:00
MHMD
862c7eceab
feat(core): Run the Form and Chat trigger redirect login against a trusted source (#41123) 2026-10-19 07:50:33 +00:00
James Martin
60d6231375
chore(core): Update redaction message to explain that it was redacted because of a child (no-changelog) (#41171)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 07:41:40 +00:00
MHMD
0936dfddc3
feat(core): Refuse revoked access tokens of the local server on the inbound pipeline (#41266) 2026-10-19 07:17:35 +00:00
Ilfat Mindubaev
b10c97ed45
feat(core): Surface the responding model name in LLM sub-node run data (#41161)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 06:44:22 +00:00
Lukas
e9723095d6
fix(OpenAI Node): Send max_completion_tokens when it analyzes an image (#38656) 2026-10-19 04:33:59 +00:00
n8n-assistant[bot]
b8a02f70dc
chore: Update node popularity data (#41359)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-19 00:42:27 +00:00
n8n-assistant[bot]
d2dc2f9ce5
chore: Update e2e impact map (#41339)
Some checks failed
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Util: Update Credential Setupability / update-setupability (push) Has been cancelled
Util: Update Node Popularity / approve-and-automerge (push) Has been cancelled
Util: Update Credential Setupability / approve-and-automerge (push) Has been cancelled
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-18 08:18:22 +00:00
Ricardo Espinoza
84943adc6c
fix(editor): Show which reference blocks a skill save (no-changelog) (#41298) 2026-10-18 07:50:57 +00:00
Riqwan Thamir
ff975f1b9e
perf(core): Stop writing Instance AI skills to the sandbox (no-changelog) (#41220)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 14:02:07 +00:00
n8n-assistant[bot]
936349a9c7
chore: Update e2e impact map (#41317)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-17 08:18:42 +00:00
Olivier
842ec5b62d
fix(core): Turn off expression spans by default (#41211)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 22:23:07 +00:00
n8n-cat-bot[bot]
ec074519d9
feat: Add policy attachment read endpoints (no-changelog) (#41122)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:13:10 +00:00
Rúben Castro
6f3b397a1e
feat(editor): Mark community packages with blocked node types (no-changelog) (#41105)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Guillaume Jacquart <jacquart.guillaume@gmail.com>
2026-10-16 15:43:39 +00:00
n8n-cat-bot[bot]
21221adc78
fix: Validate attendee values (#40953)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 14:56:23 +00:00
Guillaume Jacquart
532e8ef930
fix(core): Save policy rules that name uninstalled packages (no-changelog) (#41210)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-16 14:48:56 +00:00
n8n-cat-bot[bot]
24621ad4ca
chore: Add review/lint rule to discourage open-ended fields in nodes (warn level) (#39959)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 14:47:15 +00:00
n8n-cat-bot[bot]
8ee5cf1845
chore: Flaky test: frontend.service.test.ts (3 master or merge-queue commits in 72 h) (#41279)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 14:44:01 +00:00
Stephen Wright
7f16040253
feat(Databricks Node): Add the Lakebase Delete operation (no-changelog) (#40543) 2026-10-16 14:42:03 +00:00
Csaba Tuncsik
ddc97694b5
fix(Microsoft Teams Node): Add the TeamMember.Read.All scope and correct the Trigger scope notice (#39819) 2026-10-16 14:27:44 +00:00
Rúben Castro
eaf47cfe39
fix(editor): Improve destination validation and surface save errors (#40897)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Guillaume Jacquart <jacquart.guillaume@gmail.com>
2026-10-16 14:14:55 +00:00
Ricardo Espinoza
986b82fa28
feat: Add telemetry events to the skills hub (no-changelog) (#41234) 2026-10-16 14:12:37 +00:00
Jan
76cce99626
fix(editor): Unify documentation links across settings pages (#40289)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 13:57:10 +00:00
Jaakko Husso
f34c093f08
feat(core): Add an optional model for n8n Assistant memory tasks (#41137)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:55:06 +00:00
Mike Repeć
158152496a
fix(core): Reuse connections in the log streaming webhook destination (#41261)
Co-authored-by: Theo Nastos <theodore.nastos@n8n.io>
2026-10-16 13:54:34 +00:00
Jan
1f223c85f8
fix(editor): Start the empty-state icon cards cycling on load and use them on the MCP and external secrets pages (#40232)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 13:53:32 +00:00
Ricardo Espinoza
6a015ecb18
fix(core): Check the delete permission when the agent page moves a skill (no-changelog) (#41222) 2026-10-16 13:52:18 +00:00
n8n-cat-bot[bot]
033ec05bff
chore: Bump handlebars 4.7.9 → 4.7.10 (patch) to clear 6 Aikido findings (#41277)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 13:46:42 +00:00
Theodore Nastos
dd79a610c5
feat(core): Enable node and credential type policies by default (#41022) 2026-10-16 13:44:56 +00:00
Martin Rechenberger
a63a8edb55
fix(editor): Hide the Community Plus enrollment modal on Cloud (no-changelog) (#41251) 2026-10-16 13:40:37 +00:00
symbiote15
f5dc06f753
fix(Postgres Node): Keep comma-containing values as one query parameter (#40240) 2026-10-16 13:28:55 +00:00
Jaakko Husso
b78913f75d
fix(core): Keep the workflow source file when n8n Assistant sends blank source (#41201)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:28:54 +00:00
Guillaume Jacquart
dfec6dee81
fix(editor): Allow copy and cut of a selection with a restricted node (no-changelog) (#41276)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 13:25:51 +00:00
Uddish Verma
f92b4c11d6
feat(API): Limit Public API requests for each API key (no-changelog) (#41008)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:19:34 +00:00
Luigi Gubello
5120d25cbc
fix(editor): Count missing input apart in the QuickJS shadow report (no-changelog) (#41214)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:15:19 +00:00
Bernhard Wittmann
a6719b8db7
fix(Email Trigger (IMAP) Node): Check the mailbox when the trigger activates (#41013) 2026-10-16 13:10:25 +00:00
Bernhard Wittmann
7001886432
fix(core): Give each new Microsoft Teams sign-in credential a unique name (no-changelog) (#41256) 2026-10-16 13:04:21 +00:00
Sam Wooler
a906d2fdfc
feat(API): Return the parent folder on workflow read endpoints (#40981)
Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-16 12:48:25 +00:00
Anne Aguirre
683fd11259
fix(core): Pass reasoning effort on open router model node (#41179) 2026-10-16 12:43:58 +00:00
Mike Repeć
1b02863c00
fix(core): Hand node reference results without an item shape to the engine (no-changelog) (#41083) 2026-10-16 12:25:04 +00:00
n8n-cat-bot[bot]
d0cb582163
chore: Bump fast-uri 3.1.5 → 3.1.8 (patch) to clear 12 Aikido findings (#41255)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 12:21:08 +00:00
Anne Aguirre
ea98bd0600
fix(AI Agent Node): Replay Anthropic thinking turns with their tool arguments (#41241) 2026-10-16 12:09:01 +00:00
Predrag Ristic
1405d4a351
feat(core): Add self-healing results to Inbox (#40741) 2026-10-16 12:07:09 +00:00
Anne Aguirre
f84413516a
fix(core): Web search misconfigs in agents as UserError (#41257) 2026-10-16 12:00:35 +00:00
Sandra Zollner
333a010112
feat(core): Store promotion exports in n8n directory (#40863)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 12:00:28 +00:00
Ali Elkhateeb
b7b3d72737
feat(API): Honor Idempotency-Key on Public API POST requests (#40978)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 11:58:36 +00:00
n8n-cat-bot[bot]
5a3fc39972
fix: Skip dependency files and continue after custom node load (#41117)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-16 11:53:13 +00:00
Rúben Castro
d460eb28ca
fix(editor): Explain why copy, cut, duplicate and pin refuse a restricted node (no-changelog) (#40997)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-16 11:51:01 +00:00
Francesca Sargent
4a5fdd5b68
fix(editor): Return to the requested page after SSO sign-in (#41151) 2026-10-16 11:42:25 +00:00
MHMD
e7f0607bf1
fix(core): Allow switching a node back to a credential the user cannot use after a save (#41198) 2026-10-16 11:39:13 +00:00
Sandra Zollner
64d8a3ad19
feat(core): Add promotion run and review data model (no-changelog) (#40794)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 11:28:06 +00:00
James Martin
c70b5d49b3
fix(core): Redact a parent execution if any sub-workflows have redaction enabled (#41129)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 11:02:43 +00:00
Stephen Wright
c28d130c6c
feat(Databricks Node): Explain Lakebase setup failures (no-changelog) (#40523) 2026-10-16 10:49:36 +00:00
MHMD
ca9661c091
fix(editor): Keep the used-in rows on the credential sharing tab when personal-space sharing is disabled (#41207) 2026-10-16 10:40:31 +00:00
Emre Caglar
a94f5dc8b7
feat(editor): Move the check rule and delete actions in the agent check row (no-changelog) (#41170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:26:51 +00:00
Emre Caglar
fffea4c0c0
fix(editor): Remove the warning badge from the needs-work agent avatar (no-changelog) (#41164)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:26:41 +00:00
Emre Caglar
14e633d481
fix(editor): Keep rounded corners on a single row in the agent checks list (no-changelog) (#41166)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:26:28 +00:00
Emre Caglar
575eb6fa43
fix(editor): Show the check conversation stripes in dark mode (no-changelog) (#41167)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:26:19 +00:00
Emre Caglar
3ea0a3da98
fix(editor): Join the check conversation box to the practice-run strip (no-changelog) (#41168)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:26:06 +00:00
Emre Caglar
fed8b1ec69
feat(editor): Use a segment control for the agent checks status filter (no-changelog) (#41169)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:09:00 +00:00
Jan Kalkan
eba25caa70
feat(core): Require credential:create scope for create-with-values package imports (no-changelog) (#41131)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:55:56 +00:00
Sam Wooler
fe3627914a
fix(API): Log errors before returning generic 500 in Public API (#41186)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:54:41 +00:00
Jaakko Husso
aba5258930
feat(core): Add the scope column to the agents table (no-changelog) (#41165)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:52:52 +00:00
Bernhard Wittmann
aadbb7c498
fix(editor): Let the Assistant chat finish the Microsoft Teams setup (no-changelog) (#41188) 2026-10-16 09:38:51 +00:00
Predrag Ristic
8bee1eeb20
refactor(core): Prepare the shared Inbox (#40739)
Co-authored-by: kgrhartlage <kai.hartlage@n8n.io>
2026-10-16 09:37:52 +00:00
Eugene
2eab299dfa
fix(core): Pass Agent stop signals to foreground workflow tools (no-changelog) (#40776) 2026-10-16 09:21:44 +00:00
João Almeida
fc9f9575e2
fix(editor): Keep workflow name in edit mode after Rename menu action (#41120)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:04:26 +00:00
João Almeida
116a81e06e
fix(editor): Keep pending navigation when workflows list query is unchanged (#41125)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:04:20 +00:00
João Almeida
b36f6c0baf
test: Fix flaky zoom after route changes e2e test (#41130)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:04:09 +00:00
Riqwan Thamir
fa88c3e251
feat(core): Write finish_setup credentials into node tools (no-changelog) (#41219)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-16 08:49:51 +00:00
Dominik
8120328661
fix(editor): Rename Admin Panel to Cloud console (#41187) 2026-10-16 08:38:56 +00:00
Ricardo Espinoza
1ee29b2875
fix(editor): Lock the skill scope for users who cannot delete the skill (no-changelog) (#41221) 2026-10-16 08:28:41 +00:00
Ricardo Espinoza
f553331100
fix(editor): Keep the builder skill modal open on a taken name (no-changelog) (#41227) 2026-10-16 08:28:19 +00:00
Ricardo Espinoza
1a6b6a65d4
feat(editor): Name the project in the skill "available to" options (no-changelog) (#41229) 2026-10-16 08:27:34 +00:00
Ricardo Espinoza
88a2426947
fix(core): Trim skill names and refuse a name of only spaces (no-changelog) (#41223) 2026-10-16 08:18:55 +00:00
n8n-assistant[bot]
f5febab84d
chore: Update e2e impact map (#41245)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-16 08:18:15 +00:00
Ricardo Espinoza
dde9871497
feat(editor): Link to the skills settings page from the agent skill picker (no-changelog) (#41228) 2026-10-16 08:18:13 +00:00
Bernhard Wittmann
cc83b5bd77
feat(core): Use the agent's icon in the Microsoft Teams app package (no-changelog) (#40322) 2026-10-16 08:14:01 +00:00
Guillaume Jacquart
1ea18e9ef9
feat(editor): Show policy-blocked items in the source control pull modal (#40604)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:04:25 +00:00
n8n-cat-bot[bot]
1ba56b6579
chore: Bug - Credentials sharing tab placeholder text misleading (#41239)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: kgrhartlage <kai.hartlage@n8n.io>
2026-10-16 07:47:39 +00:00
Jaakko Husso
baa38dbdc6
feat(core): Add owned-session queries to the Agents thread repositories (no-changelog) (#40615)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 07:45:16 +00:00
Jaakko Husso
601f6ac0da
feat(editor): Let the Agents chat host render host events by placement (no-changelog) (#40720)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 07:40:56 +00:00
OrdoAbChao
e29c3a4085
fix(Splunk Node): Preserve errors when continuing after failed items (#40368) 2026-10-16 07:35:28 +00:00
Jaakko Husso
447fc866bb
feat(core): Add hidden turns, turn options and a system kind to the Agents queue (no-changelog) (#40614)
Some checks failed
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:25:36 +00:00
Ricardo Espinoza
860f1273eb
feat(editor): Add the Skills page to Context settings (no-changelog) (#41031) 2026-10-15 15:35:20 +00:00
Jan Kalkan
deed9a2f32
feat(core): Report credentials created with partial package data separately (no-changelog) (#41156)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:29:25 +00:00
nvonahsen
a32c652c09
fix(editor): Prevent doubled base path when opening folders with N8N_PATH set (#33065)
Signed-off-by: Niclas von Ahsen <niclas.vonahsen@elementx.ai>
Signed-off-by: James Gee <1285296+geemanjs@users.noreply.github.com>
Co-authored-by: James Gee <1285296+geemanjs@users.noreply.github.com>
2026-10-15 15:25:39 +00:00
Ricardo Espinoza
1903d53bc0
fix(editor): Save only the OpenTelemetry status when enabling or disabling (#41142) 2026-10-15 14:43:53 +00:00
n8n-cat-bot[bot]
131e9c8679
fix: Keep free-floating sticky notes clear of workflow nodes (#41195)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-15 14:41:40 +00:00
Bernhard Wittmann
236220b248
fix(Email Trigger (IMAP) Node): Find new mail on servers with a broken IMAP4rev2 mode (#41018) 2026-10-15 14:33:49 +00:00
Toni Devine
af0202d840
feat(editor): Rework the WhatsApp channel setup to match the new design (#40923)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:33:41 +00:00
yehorkardash
adc6d35388
feat: Update Slack Bot to n8n rebrand (no-changelog) (#41203) 2026-10-15 14:25:48 +00:00
Svetoslav Dekov
b2b2a8641a
feat(editor): Attach skills hub skills from a picker in the agent builder (no-changelog) (#41104)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:14:18 +00:00
James Martin
952b1e73b2
fix(core): Display an error message when failing to connect to oauth credentials (#41058) 2026-10-15 14:03:47 +00:00
Anne Aguirre
f596162dc7
fix(core): Close agent after run when invoked from workflow (#41128) 2026-10-15 13:44:45 +00:00
MHMD
378847ae1e
refactor(core): Share the inbound admission steps between protected-resource surfaces (#41162) 2026-10-15 13:32:58 +00:00
n8n-cat-bot[bot]
9e3b52cbbb
fix: Restore command bar focus and standardize creation icons (#41185)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-15 12:58:16 +00:00
Checo
054288e488
fix(GitlabTrigger): use NodeApiError.httpCode and safe description access in webhook checkExists (#35486)
Signed-off-by: sergioperezcheco <checo520@outlook.com>
2026-10-15 12:53:34 +00:00
Mike Repeć
c839d6cd49
fix(core): Remove unused N8N_SCHEDULER_MIN_INTERVAL setting (#41194) 2026-10-15 12:29:35 +00:00
Nour Alhadi Mahmoud
154cd63bbc
feat(editor): Add GitLab promotion connector setup (no-changelog) (#41019) 2026-10-15 11:58:24 +00:00
Ricardo Espinoza
3c447b42a7
fix(core): Key each OAuth authorization request to its own session (#39930)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-15 11:43:45 +00:00
Yen Su
1659fa3737
feat(Databricks Node): Refuse the Vector Store metadata filter on non-standard endpoints (no-changelog) (#41047) 2026-10-15 11:18:08 +00:00
Luigi Gubello
9806798e89
chore: Update @langchain/langgraph to 1.4.21 (#40680)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 11:14:29 +00:00
Charlie Kolb
cdeb405948
refactor(core): Extract Workflow Builder session persistence into a backend module (#41075) 2026-10-15 10:56:13 +00:00
Dimitri Lavrenük
e45a65a9bf
fix(core): Improve base URL check for declarative nodes (#40778) 2026-10-15 10:51:15 +00:00
Charlie Kolb
b68bd3129b
refactor(core): Move auth registries and OAuth proxies into shared packages (#41088) 2026-10-15 10:32:13 +00:00
Lukas
e8ded61fe1
build: Update eslint-plugin-n8n-nodes-base to 2.0.0 for ESLint 10 (#38653)
Co-authored-by: Bernhard Wittmann <bernhard.wittmann@n8n.io>
2026-10-15 10:28:37 +00:00
Bernhard Wittmann
d046047dd0
feat(editor): Update the Microsoft Teams setup copy and give both flows a Done step (no-changelog) (#41010) 2026-10-15 10:10:06 +00:00
Srinjoy
f483ebd9d1
fix(MCP Trigger Node): Pass through MCP content arrays instead of double-wrapping tool results (#39131) 2026-10-15 10:08:42 +00:00
Luigi Gubello
fddef57734
chore: Update toml to 4.2.0 (#40672)
Some checks failed
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Build: Benchmark Image / build (push) Has been cancelled
Util: Publish API Schema / Cloudflare Pages (push) Has been cancelled
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:34:39 +00:00
Sebastien Powell
ba97e46afc
fix(editor): Cleanup legacy button variants (#41175) 2026-10-15 09:31:34 +00:00
Anne Aguirre
4cb7a6ee3d
fix(core): Clear agent runtime cache when credential is updated (#40961) 2026-10-15 09:26:22 +00:00
Luigi Gubello
8ed8607a52
chore: Update simple-git to 4.0.2 (#40675)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:24:16 +00:00
Yen Su
67c1981f2f
fix(core): Let LLM failed-attempt handling retry and honour Retry-After (#41002) 2026-10-15 09:13:44 +00:00
Luigi Gubello
a8880cb449
chore: Update pdfjs-dist to 6.3.289 (#40677)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:13:43 +00:00
Stephen Wright
d411a44be0
feat(Databricks Node): Add the Lakebase Insert operation (no-changelog) (#40520) 2026-10-15 09:12:26 +00:00
Ricardo Espinoza
0c0b38e3cb
feat(core): Turn the skills hub on with an environment variable instead of a PostHog flag (no-changelog) (#41143) 2026-10-15 08:59:25 +00:00
Mayank SIngh
315e0a5377
fix(Convert to File Node): Decode data URIs and validate Base64 input (#38554)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-10-15 08:57:21 +00:00
Gigi
efd4e21aad
fix(core): Evict idle mcp-browser sessions to prevent connection leak (#36850)
Signed-off-by: Luigi Colluto <luigicolluto2006@gmail.com>
2026-10-15 08:56:27 +00:00
Jaakko Husso
bab83634ce
perf(core): Reuse the prebaked runtime skills bundle in the sandbox (no-changelog) (#41027)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:35:34 +00:00
n8n-assistant[bot]
d6c9b9fba3
chore: Update e2e impact map (#41163)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-15 08:18:58 +00:00
Luigi Gubello
b36befcb75
chore: Update nodemailer to 10.0.14 (#40674)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:09:12 +00:00
Charlie Kolb
ed2500ffb2
refactor(core): Move feature provider proxies into backend services (#41087) 2026-10-15 08:00:25 +00:00
n8n-cat-bot[bot]
9c0b546a30
chore: Bug - Delete project confirmation dialog button misaligned (#41160)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-15 07:54:00 +00:00
Charlie Kolb
07595a0007
ci: Respect pnpm workspace exclusions in dependency verifier (#41159) 2026-10-15 07:48:25 +00:00
Nour Alhadi Mahmoud
1e67d0315d
feat(API): Add GitLab promotion repository and branch discovery (no-changelog) (#40788) 2026-10-15 07:15:40 +00:00
Charlie Kolb
338b0ca3fd
refactor(core): Move published workflow data into backend services (#41086) 2026-10-15 07:13:46 +00:00
Jaakko Husso
48edbef643
fix(core): Keep Observer detail lines instead of discarding the response (#41134)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:13:19 +00:00
Charlie Kolb
5d79c16f51
test(core): Stabilize transport timeout test (#41150) 2026-10-15 07:03:20 +00:00
Theodore Nastos
40094e363b
chore: Assign policy and OpenTelemetry code to Governance & Observability in OWNERS (no-changelog) (#41050) 2026-10-15 06:30:12 +00:00
Alex Antoniuk
e2529a8494
perf(editor): Load prettier only when the user formats code (#41014)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
2026-10-14 21:48:42 +00:00
Raúl Gómez Morales
50c4ced224
fix(core): Keep pending setup for nodes that n8n Assistant added in an earlier build (#41070) 2026-10-14 16:52:18 +00:00
Bernhard Wittmann
b7a5500d16
feat(editor): Align the Microsoft Teams channel settings with the new design (no-changelog) (#41054) 2026-10-14 16:52:09 +00:00
Mayank SIngh
f6b24d0ae9
fix(editor): Display custom evaluation metrics correctly (#40852) 2026-10-14 16:15:34 +00:00
Raúl Gómez Morales
3c7dcf902d
feat(ai-builder): Write LangTracer results from the routing evals (no-changelog) (#40954) 2026-10-14 15:42:42 +00:00
Mike Repeć
fbe743b9df
fix(core): Charge element content for comparing array methods in native evaluation (no-changelog) (#41079) 2026-10-14 15:40:38 +00:00
Andreas Fitzek
f5924004ca
feat(core): Accept OAuth2 bearers on the public API through the trusted-source pipeline (no-changelog) (#41127)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-14 15:34:39 +00:00
Mike Repeć
b270d48686
fix(core): Charge node reference calls against the native evaluation work budget (no-changelog) (#41080) 2026-10-14 15:19:55 +00:00
Mike Repeć
3277f8c3b5
test(core): Give node reference parity cases a slim fixture item (no-changelog) (#41081) 2026-10-14 15:19:46 +00:00
Yuliia Pominchuk
a57c8f3aba
fix(core): Redact the parent execution when a sub-workflow uses a credential the viewer cannot use (#41085)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 15:15:42 +00:00
Ricardo Espinoza
dcd312c5a9
feat(core): Copy inline agent skills into the skills hub at startup (no-changelog) (#41030)
Co-authored-by: Roman Makowiak <roman.makowiak@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:08:50 +00:00
Mike Repeć
a6d5b4de3f
test(core): Pin the quickjs nested -0 conversion in native evaluation parity (no-changelog) (#41092) 2026-10-14 15:04:02 +00:00
Temo
3968a60bf7
fix(ERPNext Node): Return each row once and tolerate empty Get Many options (#36860) 2026-10-14 14:51:43 +00:00
Theodore Nastos
17fb3c0e17
docs(API): Label type availability policy endpoints as Preview (no-changelog) (#41101) 2026-10-14 14:26:59 +00:00
Nikhil Kuriakose
b965e90307
test: Move Adore-owned specs to Knowledge and retire the Adore owner (#40933)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-14 14:18:23 +00:00
Bernhard Wittmann
38135e1f83
feat: Read files attached in Microsoft Teams channels and group chats (no-changelog) (#41001) 2026-10-14 13:51:02 +00:00
Anne Aguirre
616062487a
feat(editor): Show agent personalisation icon in subagent modal (#41094) 2026-10-14 13:47:36 +00:00
Mike Repeć
1950434a27
fix(core): Create an XML parser for each webhook request body (#41098) 2026-10-14 13:42:48 +00:00
Anne Aguirre
b3e8b7d9ce
fix(editor): Use the deployment name on the Az Foundry path (#41103) 2026-10-14 13:35:40 +00:00
Jaakko Husso
56eac665c3
fix(core): Make the Assistant check the n8n side before it names a failure cause (no-changelog) (#41097)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:26:37 +00:00
Luigi Gubello
8bc7161ab1
feat(editor): Compare the QuickJS expression engine with legacy behind a flag (no-changelog) (#40496)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:24:09 +00:00
Uddish Verma
57e26feda4
feat(API): Add the Public API rate limit environment variables (no-changelog) (#41003)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:21:34 +00:00
n8n-cat-bot[bot]
9c42a76b1a
test: Stabilize user select email-filtering tests (#41095)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-14 13:17:45 +00:00
Irénée
ae374e79ab
feat(core): Add a credential conflict policy to package import (no-changelog) (#40963)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 13:11:32 +00:00
n8n-cat-bot[bot]
ef8d61bda7
fix(API): Check scope version when replacing policy attachments (no-changelog) (#40964)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-14 13:06:15 +00:00
Ilfat Mindubaev
caeaff7230
feat(editor): Show the model that answered in the AI log header (#40988)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:58:13 +00:00
Johannes Nicolai
a3f47117cf
fix(OpenAI Node): Report token usage for image operations (#38463)
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-14 12:56:44 +00:00
Toni Devine
9a524e7c21
feat(core): Add WhatsApp credential check and webhook handshake status (#40921)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:48:31 +00:00
Toni Devine
adedbbf560
feat(core): Add typing indicator, media download and media retention … (#40920)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:48:20 +00:00
Bernhard Wittmann
4eb63d6f41
feat: Update Browser Use extension to n8n rebrand (no-changelog) (#41096) 2026-10-14 12:38:28 +00:00
Charlie Kolb
b6d39e2d30
refactor(core): Move JWT support into backend services (#41089) 2026-10-14 12:10:59 +00:00
Sam Wooler
7920e6cf6b
refactor(API): Retire the express-openapi-validator stack from the Public API (no-changelog) (#40801)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:07:18 +00:00
Charlie Kolb
76c43094cd
refactor(core): Extract Quick Connect into a backend package (#41076) 2026-10-14 12:04:16 +00:00
Jaakko Husso
898701b05b
fix(core): Skip resource mapper validation when the mapped value is null (#41069)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:00:20 +00:00
Kai
f63111202f
fix(core): Confirm project deletions before instance apply (#40941) 2026-10-14 11:50:52 +00:00
Mike Repeć
633eacaae6
fix(editor): Use an outline button for bulk notify in the migration report (no-changelog) (#41084) 2026-10-14 11:29:29 +00:00
José Braulio González Valido
1b0cdd5998
fix(ai-builder): Report eval helper model failures as infrastructure, not as bad JSON (no-changelog) (#40415)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 11:23:25 +00:00
Raúl Gómez Morales
578eea403d
fix(core): Stop asking to set up a node when n8n Assistant only adds a step next to it (#41067) 2026-10-14 11:20:43 +00:00
José Braulio González Valido
7c38974070
fix(ai-builder): Keep eval mock notes to data, not response layouts (no-changelog) (#40818)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:20:06 +00:00
Mike Repeć
d68ad7e97b
feat(core): Evaluate pure expression extensions in native expression evaluation (no-changelog) (#40865) 2026-10-14 10:49:37 +00:00
Declan Carroll
0650b9cce0
refactor: Move idle memory baselines to efficiency (#41037) 2026-10-14 10:32:11 +00:00
Mike Repeć
df7b3a19c6
fix(editor): Use outline buttons for secondary actions in the migration report (no-changelog) (#41072) 2026-10-14 10:28:04 +00:00
Mike Repeć
de42c9515d
feat(editor): Let admins notify workflow owners in bulk from the migration rule detail (#41060) 2026-10-14 10:26:05 +00:00
Jaakko Husso
d26f914e3d
fix(editor): Cancel the Assistant thread when the hand-off navigation fails (#41056)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:12:32 +00:00
Johannes Nicolai
8b5ea6d9e0
fix(editor): Stop auto-selecting the Evaluation Trigger over other triggers (#38883)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Bernhard Wittmann <bernhard.wittmann@n8n.io>
2026-10-14 09:57:23 +00:00
Charlie Kolb
bfd4885026
ci: Automate get-n8n fallback version updates (#40973) 2026-10-14 09:53:55 +00:00
Stephen Wright
3800bce812
feat(Text Classifier Node): Add opt-in confidence scores to the output (#40743) 2026-10-14 09:42:05 +00:00
Mike Repeć
aae8eb63d7
docs: Add env-var-docs skill for JSDoc on @Env config properties (#41053) 2026-10-14 09:19:42 +00:00
Mutasem Aldmour
0b4c99f10d
fix(core): Pick output schemas by parameter value for Gmail and Notion (no-changelog) (#40757)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 09:11:49 +00:00
n8n-cat-bot[bot]
066480d8db
fix: Check provisioning license on Users settings page (#41048)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-14 08:59:23 +00:00
Florian Gareis
b8780d8fee
fix(HomeAssistant Node): Only sent Home Assistant attributes on upsert if set (#36298) 2026-10-14 08:58:22 +00:00
Anne Aguirre
e47940eecd
feat(editor): Publish agent modal and modal for warning about unpublished workflows (#40987)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 08:47:05 +00:00
Jaakko Husso
e3b2603d7b
chore(core): Remove activation-capped AI Assistant trial variant (no-changelog) (#41036)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 08:21:20 +00:00
Jaakko Husso
726a5829c8
fix(core): Use the module registry to decide if the Assistant has the Agents features (#41026)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 08:19:48 +00:00
n8n-assistant[bot]
54f1670791
chore: Update e2e impact map (#41051)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-14 08:18:31 +00:00
Jan
b3e8634c83
fix(editor): Apply the standard settings layout to the Context preferences page (#40716)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 08:02:30 +00:00
Rick Gale
1643a8598b
chore: Assign evaluation code to the AI Trust team (no-changelog) (#40918)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-14 08:01:17 +00:00
Anne Aguirre
9498088256
feat(core): Apply budget alerts and stops to sub-agent run (#40884)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-14 07:56:27 +00:00
Yuliia Pominchuk
da3491fc87
feat(editor): Link to the credential sharing tab when execution data is redacted (#40976) 2026-10-14 07:48:34 +00:00
Yen Su
d83f95b377
fix(Databricks Node): Mark the MLflow tool span ERROR when the tool returned an error string (no-changelog) (#40990) 2026-10-14 07:27:56 +00:00
n8n-assistant[bot]
46761a60a9
chore: Bundle/2.x (#41035)
Co-authored-by: Matsu <matias.huhta@n8n.io>
Co-authored-by: Bernhard Wittmann <bernhard.wittmann@n8n.io>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Elias Meire <elias@meire.dev>
Co-authored-by: n8n-assistant[bot] <n8n-assistant[bot]@users.noreply.github.com>
Co-authored-by: João Almeida <jg.almeida56@gmail.com>
Co-authored-by: Savelii <savelii.sychov@n8n.io>
Co-authored-by: Rick Gale <richardgale90@gmail.com>
Co-authored-by: Emilia <100027345+sovietspaceship@users.noreply.github.com>
Co-authored-by: oleg <me@olegivaniv.com>
Co-authored-by: RomanDavydchuk <roman.davydchuk@n8n.io>
Co-authored-by: Stephen Wright <sjw948@gmail.com>
Co-authored-by: Yuliia Pominchuk <31064937+yuliia-pominchuk@users.noreply.github.com>
Co-authored-by: Shireen Missi <94372015+ShireenMissi@users.noreply.github.com>
Co-authored-by: Miguel Ángel Moreno <1411774+miguelsaddress@users.noreply.github.com>
Co-authored-by: Anne Aguirre <anne.aguirre@n8n.io>
Co-authored-by: Dimitri Lavrenük <20122620+dlavrenuek@users.noreply.github.com>
Co-authored-by: Kai <kai.hartlage@n8n.io>
Co-authored-by: Luigi Gubello <27034386+luigigubello@users.noreply.github.com>
Co-authored-by: Danny Martini <danny@n8n.io>
Co-authored-by: MHMD <45968454+dou-mhmd@users.noreply.github.com>
Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Charlie Kolb <charlie@n8n.io>
2026-10-14 06:33:56 +00:00
Bernhard Wittmann
ccf42e3213
fix(ai-builder): Make browser credential-setup evals grade the right thing (no-changelog) (#40858) 2026-10-14 06:24:28 +00:00
Svetoslav Dekov
94bdf85a8a
feat(core): Switch agent skills to the skills hub (no-changelog) (#40860)
Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
Co-authored-by: Roman Makowiak <roman.makowiak@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:12:36 +00:00
José Braulio González Valido
29de1c63ae
fix(ai-builder): Remove the Context7 docs lookup from the eval mock (no-changelog) (#40021)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 21:30:08 +00:00
José Braulio González Valido
92f8eb51b3
chore(Message an Agent Node): Add output schemas (no-changelog) (#40821)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:29:33 +00:00
José Braulio González Valido
146d7804af
fix(ai-builder): Count eval runs that read another build's workflow as framework issues (no-changelog) (#40717)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 21:29:00 +00:00
José Braulio González Valido
88de3cac20
feat(ai-builder): Move eval judges to Sonnet 5.5 and add per-role eval LLM settings (no-changelog) (#40330)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 21:28:25 +00:00
Roman Makowiak
04f4afe3dc
feat(core): Add skills repository, service and REST API (no-changelog) (#40653)
Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:28:55 +00:00
Nikhil Kuriakose
6924027e93
test: Move Adore-owned specs for Context features to Context (#40932)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-13 19:41:28 +00:00
Nikhil Kuriakose
ef183e632d
test: Move Adore-owned specs for the updates panel to Cloud Growth (#40931)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-13 19:41:27 +00:00
Nikhil Kuriakose
ed1c1e561a
test: Move Adore-owned specs for node features to NODES (#40930)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-13 19:41:27 +00:00
Nikhil Kuriakose
a3a014422f
test: Move Adore-owned specs for Catalysts features to Catalysts (#40929)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-13 19:41:26 +00:00
Ricardo Espinoza
f1fecf97e9
feat(core): Add skills hub tables (no-changelog) (#40464) 2026-10-13 19:03:23 +00:00
Andreas Fitzek
5da4d19e50
feat(core): Add the trusted sources management API (no-changelog) (#40975)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-13 18:24:34 +00:00
Uddish Verma
2019ea5593
feat(API): Expose the API key ID on the token grant (no-changelog) (#40986)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:16:50 +00:00
Guillaume Jacquart
4419fc4ba2
feat(core): Add the blocking project and opt-in state to policy violations (#40985)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 17:49:51 +00:00
yehorkardash
52aed7ac97
fix(Execute Command Node): Don't spawn console on Windows (#40909) 2026-10-13 16:07:56 +00:00
n8n-cat-bot[bot]
1d2c879fab
fix: Pass structured inputs to OpenAI Responses tools (#40638)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-13 16:07:14 +00:00
Rob Hough
bffe7d8392
feat(editor): Update UI with n8n rebrand (#40342)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
Co-authored-by: Sebastien Powell <sebpowell@users.noreply.github.com>
Co-authored-by: Tuukka Kantola <tuukka@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:06:30 +00:00
n8n-cat-bot[bot]
d245b17b89
fix: Allow skipping table initialization (#40437)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-13 16:03:37 +00:00
daniel-hai
8977833ee2
feat(Monday.com Node): Add V2 with full V1 parity as the default (#35515)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Stephen Wright <sjw948@gmail.com>
2026-10-13 15:53:55 +00:00
Alexander Gekov
acf5291d80
feat: Show Gemini models by name and list prioritized models first in model pickers (#40965)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-13 15:41:36 +00:00
Rob Hough
ebf078b64c
fix(editor): Restore the new session shortcut in agent chat (#40907)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
2026-10-13 15:29:20 +00:00
Charlie Kolb
9052f8ff3e
test(editor): Reduce publish timeline paging test work (#40993) 2026-10-13 15:05:18 +00:00
Kai
e0fe04084e
fix(core): Allow project promotion without an instance export (#40939) 2026-10-13 14:31:19 +00:00
Yen Su
e859abaf18
fix(Databricks Node): Bring the AI Agent panel to parity with AI Agent 2.2 (#40989) 2026-10-13 14:10:45 +00:00
Mike Repeć
a972eebe51
feat(editor): Let admins notify workflow owners from the migration rule detail (#40949) 2026-10-13 13:57:26 +00:00
yehorkardash
739c59e991
feat(core): Implement automated migrations for removed nodes (#40877) 2026-10-13 13:45:24 +00:00
Mike Repeć
de090cb2a0
feat(core): Evaluate primitive reads off $now and $today natively (no-changelog) (#40945) 2026-10-13 13:31:32 +00:00
MHMD
b97fe7c7d4
fix(core): Hide personal credentials from agents until they are fully supported (no-changelog) (#40789) 2026-10-13 13:31:17 +00:00
Riqwan Thamir
38e4aebfc8
perf(core): Reduce Agent Builder round trips in an initial build (no-changelog) (#40719)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 13:29:11 +00:00
Mike Repeć
d8a06666da
feat(core): Add an endpoint that notifies workflow owners about migration findings (#40952) 2026-10-13 13:07:59 +00:00
Bernhard Wittmann
60e0cb1e7b
feat(core): Publish the Microsoft Teams app to the organisation (no-changelog) (#40697)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-13 13:01:48 +00:00
Rup Sarmah
b09efb706c
fix(core): Handle every escaped closing bracket in an expression (#40487) 2026-10-13 12:58:10 +00:00
Tomi Turtiainen
f090f53480
refactor(core): Select CLI start trigger for workflow runs (#40375)
Co-authored-by: Danny Martini <danny@n8n.io>
2026-10-13 12:35:36 +00:00
Mike Repeć
347385b07b
feat(core): Treat notified migration findings as unresolved (#40951) 2026-10-13 12:19:30 +00:00
Guillaume Jacquart
bb45bca5ff
feat(editor): Show the policy reason when an agent tool call is refused (#40673)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:19:29 +00:00
Sam Wooler
3075b60576
fix(API): Apply projectId filter to executions for member API keys (#40887)
Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-13 12:03:20 +00:00
Sam Wooler
4fcb628fca
refactor(API): Migrate n8n-packages export endpoint to PublicApiController (no-changelog) (#40756)
Some checks failed
Build: Benchmark Image / build (push) Has been cancelled
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
Util: Publish API Schema / Cloudflare Pages (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 11:56:11 +00:00
Bernhard Wittmann
1ee379898b
feat(core): Add the recommended Microsoft Teams channel setup (no-changelog) (#40696)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-13 11:55:56 +00:00
Lorent Lempereur
366ed6ed0e
refactor(core): Declare system tasks with a typed schedule and target (no-changelog) (#40703) 2026-10-13 11:42:37 +00:00
Anne Aguirre
248c86355b
fix(core): Describe MCP servers only from user or registry text in Agent Builder (#40974) 2026-10-13 11:19:46 +00:00
Stephen Wright
e5866ac6c1
feat(Kafka Node): Make version 2 the default for new Kafka nodes and triggers (#40744) 2026-10-13 11:07:10 +00:00
Jaakko Husso
2bc3265e63
perf(ai-builder): Trust a matching prebaked bundle manifest in the sandbox (no-changelog) (#40820)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 11:04:18 +00:00
Lorent Lempereur
f6861fe494
feat(core): Enable the durable scheduler by default (#40891)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-13 10:47:35 +00:00
Anne Aguirre
632d8b9eb0
feat(editor): Update budget panel when agent executes (#40971)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-13 10:44:26 +00:00
Declan Carroll
5549374241
chore: Upgrade agent harness to 0.6.0 (no-changelog) (#40967) 2026-10-13 10:28:40 +00:00
Alex Grozav
cba16247b9
feat(editor): Open the migration workflow from its name (no-changelog) (#40895)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 10:24:15 +00:00
Alex Grozav
e528f948ce
fix(editor): Use full width for the migration rule header (no-changelog) (#40890)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 10:24:02 +00:00
James Gee
d3bc2754b4
feat(core): Add create-with-values credential missing mode to package import (#36767) 2026-10-13 10:21:33 +00:00
Jaakko Husso
ffda639b3f
fix(editor): Show follow-up run events in the Assistant after a reconnect (#40883)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:12:33 +00:00
Declan Carroll
97e5ae56e4
test: Add Dive checks and reusable Playwright CLI fixtures (#40831) 2026-10-13 10:02:00 +00:00
yehorkardash
bda9118168
feat: Overhaul MCP tool permissions for Agents (#39878)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-13 09:54:46 +00:00
Csaba Tuncsik
96eff1efb9
fix(core): Reflect failed publications in the active workflows endpoints (#40641) 2026-10-13 09:49:33 +00:00
Guillaume Jacquart
eb66e1bde0
docs(API): Mark type availability policy endpoints as beta (#40959)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 09:04:12 +00:00
Tomi Turtiainen
a8a028e2dc
docs: Clarify primary key selection order in migration skill (#40958)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-13 09:03:31 +00:00
Yen Su
44c8a312c3
feat(core): Append node tool attributions to agent replies and add Genie attribution and deep links to the Databricks node (#40765) 2026-10-13 08:42:57 +00:00
Declan Carroll
7bad46ee7e
chore: Upgrade agent harness to 0.5.1 (no-changelog) (#40956) 2026-10-13 08:34:04 +00:00
Veljko Terzic
45eea1bc35
feat(core): Remove the startup pass from workflow history compaction (#40886) 2026-10-13 08:02:51 +00:00
Stephen Wright
c8c8c3a81e
feat(Databricks Node): Add the Lakebase Get Many operation (no-changelog) (#40508) 2026-10-13 07:52:26 +00:00
Florian Gößler
e74f1c19da
fix(core): Log custom data truncation only above the 512-character limit (#40899)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 07:49:13 +00:00
Alex Grozav
f16c1375b1
feat(editor): Add bulk migration to the migration rule detail (no-changelog) (#40896)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 07:48:53 +00:00
n8n-release-tag-merge[bot]
5146e3960f Merge tag 'n8n@2.44.0' 2026-10-13 07:44:08 +00:00
Yen Su
14c77900df
fix(Databricks Node): Rename Genie resource labels to Genie Agent and the MCP tile to Databricks Genie One (#40760) 2026-10-13 07:21:37 +00:00
n8n-assistant[bot]
bae368caca
🚀 Release 2.44.0 (#40943)
Co-authored-by: n8n-release-helper[bot] <265227495+n8n-release-helper[bot]@users.noreply.github.com>
2026-10-13 07:12:07 +00:00
Mike Repeć
f3e2bd83b3
feat(core): Suspend in-flight production executions at worker shutdown (#40568) 2026-10-13 07:04:07 +00:00
Jaakko Husso
27fcb968fb
fix(core): Require workflow create scope for single node runs in n8n Assistant (#40908)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 06:40:58 +00:00
n8n-assistant[bot]
2562744611
chore: Update e2e impact map (#40942)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-13 06:40:48 +00:00
Pierantonio Cangianiello
8d93e31d1d
chore: Make the create-pr skill write shorter PR descriptions for new reviewers (#40811)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 05:25:35 +00:00
ADITYA KUMAR JHA
2596f3ac1c
fix(core): Match regex case-insensitively when ignore case is enabled (#33589)
Co-authored-by: Michael Kret <michael.k@radency.com>
2026-10-13 04:03:35 +00:00
Svetoslav Dekov
e2c4054cba
feat(editor): Replace Windsurf with Devin in the MCP client dialog (#40912)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:17:07 +00:00
Anne Aguirre
2ca4e55502
fix(core): Stabilise background child approval wait (#40834)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-12 21:18:01 +00:00
n8n-cat-bot[bot]
cea974e770
test: Stabilize MCP workflow select empty-state test (no-changelog) (#40926)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-12 18:39:14 +00:00
Luka Zivkovic
ce20d1dea4
fix: Load agent evals by default and share the rollout flag (no-changelog) (#40915) 2026-10-12 16:42:27 +00:00
Svetoslav Dekov
53d1fd5991
feat(editor): Show last updated date on the Preferences page (no-changelog) (#40869)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:16:43 +00:00
Veljko Terzic
776f4e1944
feat(core): Run the execution pruning hard delete as a durable system task (no-changelog) (#40661) 2026-10-12 15:01:55 +00:00
Mike Repeć
3ff9c83bda
fix(core): Validate the size argument of the chunk() expression extension (#40880) 2026-10-12 14:54:04 +00:00
Guillaume Jacquart
89733cdb9a
feat(core): Send telemetry when a policy blocks an action (no-changelog) (#40871)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 14:51:40 +00:00
Jaakko Husso
0209caafff
feat(editor): Let the Agents chat host render results of finished tool calls (no-changelog) (#40611)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 14:26:14 +00:00
Andreas Fitzek
0755255c35
feat(core): Add internal API for running the inbound authentication pipeline (no-changelog) (#40894) 2026-10-12 14:05:26 +00:00
James Martin
36ae8f74ce
chore(core): Seeds the default internal trusted source (no-changelog) (#40758)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:55:20 +00:00
Nour Alhadi Mahmoud
160c126c6e
feat(core): Add GitLab promotion providers (no-changelog) (#40749) 2026-10-12 13:55:19 +00:00
Mike Repeć
d3deffbfa5
fix(core): Match the Brazilian real symbol in the in-isolate currency regex (#40893) 2026-10-12 13:55:17 +00:00
Anne Aguirre
b542f66119
fix(editor): Remove redundant description for create workflow option in agent config (#40882) 2026-10-12 13:54:15 +00:00
n8n-cat-bot[bot]
f0a38cfe58
feat: Add Antigravity to the MCP client connection dialog (#40879)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:53:19 +00:00
Jan Kalkan
27b43de85f
feat(core): Pair data table columns by id on package import (#40709)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:40:47 +00:00
Alex Grozav
7ceb84f06c
fix(editor): Fix the last updated label in the migration report (no-changelog) (#40889)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:38:00 +00:00
Alex Grozav
2a51f38d55
fix(editor): Rename the "Executions fail" label to "Executions will fail" (#40888)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:37:54 +00:00
Alex Grozav
e0958fe094
feat(editor): Suggest won't fix for workflows that have not run in 12 months (no-changelog) (#40782)
Co-authored-by: Michael Siega <michael.siega@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 13:33:30 +00:00
MHMD
bc8b803471
test: Wait for the Overview list before the sidebar click in a flaky project test (no-changelog) (#40864) 2026-10-12 13:26:08 +00:00
Danny Martini
26d93b601a
docs(engine): Record the resume-token decision (no-changelog) (#39089)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-12 13:17:09 +00:00
Pierantonio Cangianiello
c9cb3ee3ab
fix(core): Let the editor download binary data of an Engine v2 execution (#40663) 2026-10-12 13:08:38 +00:00
Svetoslav Dekov
22ff2a0636
feat(editor): Show who created each preference on the Preferences page (#40868)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:04:59 +00:00
Alex Grozav
7dae1b64de
feat(editor): Add bulk state actions to the migration rule detail (no-changelog) (#40780)
Co-authored-by: Michael Siega <michael.siega@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 12:51:08 +00:00
Stephen Wright
27aa660a74
fix(Microsoft SharePoint Trigger Node): Name the real cause in the missing-target error (no-changelog) (#40400) 2026-10-12 12:44:08 +00:00
Veljko Terzic
6cd3539b1e
feat(core): Run the pending-authorization cleanup as a durable system task (no-changelog) (#40859) 2026-10-12 12:17:23 +00:00
Jaakko Husso
97ca4c49e0
feat(editor): Let the Agents chat host provide its own interactive cards (no-changelog) (#40609)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 12:08:23 +00:00
Robin Braumann
bd22105646
feat(core): Add Google Vertex AI support for agents (no-changelog) (#40545) 2026-10-12 12:05:53 +00:00
Lorent Lempereur
e16066c322
feat(core): Give long system tasks an explicit timeout (no-changelog) (#40521) 2026-10-12 12:00:59 +00:00
Andreas Fitzek
7cd9fcd3d1
feat(core): Map roles from trusted-source rules on resolve (no-changelog) (#40809)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 11:53:47 +00:00
Mutasem Aldmour
2176819865
fix(core): Validate execution timeout against the configured maximum in Instance AI saves (#40769)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:48:02 +00:00
Ali Elkhateeb
d038f89e91
feat(API): Delete expired Public API idempotency keys (no-changelog) (#40748)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Sam Wooler <swooler592@gmail.com>
2026-10-12 11:45:00 +00:00
Lorent Lempereur
3dd805d9ed
feat(core): Bound a poll by the timeout of its occurrence (no-changelog) (#40518)
Some checks are pending
Build: Benchmark Image / build (push) Waiting to run
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Veljko Terzic <veljko.terzic@n8n.io>
2026-10-12 11:31:52 +00:00
Michael Drury
16e29da52f
fix(editor): Keep typed characters in Markdown fields (#40805) 2026-10-12 11:25:33 +00:00
n8n-cat-bot[bot]
b8b0387a31
fix: Use ID token claims when UserInfo is unavailable (#40779)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Andreas Fitzek <andreas.fitzek@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 11:14:06 +00:00
Lorent Lempereur
8b6352a6fa
feat(core): Report a timed-out system task run as timed out (no-changelog) (#40516)
Co-authored-by: Veljko Terzic <veljko.terzic@n8n.io>
2026-10-12 10:46:12 +00:00
Lorent Lempereur
839b841dda
feat(core): Stop a scheduled task run at its timeout (no-changelog) (#40515)
Co-authored-by: Veljko Terzic <veljko.terzic@n8n.io>
2026-10-12 10:46:11 +00:00
Lorent Lempereur
53a6019ad5
feat(core): Store and provision the timeout of scheduled jobs (no-changelog) (#40513) 2026-10-12 10:46:10 +00:00
Lorent Lempereur
2a1fde3634
feat(core): Add settings for the timeout of scheduled tasks (no-changelog) (#40512) 2026-10-12 10:46:09 +00:00
Mutasem Aldmour
37799ad2f2
fix(editor): Align nodes panel to the embedded canvas in the n8n Assistant split view (#40795)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:29:40 +00:00
n8n-cat-bot[bot]
a1800105ef
fix: Report resource-operation violations as errors (#40830)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-12 09:52:15 +00:00
Aryan Bahl
6b77613ee8
fix(Odoo Node): Normalize datetime fields to Odoo format before write (#34186)
Co-authored-by: Toni Devine <tonidevine24@gmail.com>
Co-authored-by: Toni Devine <118546181+devinetoni@users.noreply.github.com>
2026-10-12 09:46:07 +00:00
n8n-cat-bot[bot]
205c1c3ee5
refactor: Share appender for connection changes (#39472)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-12 09:11:50 +00:00
Andreas Fitzek
65cc931018
feat(core): Link and provision users from trusted-source identities (no-changelog) (#40755)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 09:01:17 +00:00
Andreas Fitzek
3dd3efc42f
feat(core): Resolve trusted-source subjects to users on the read path (no-changelog) (#40698)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 09:01:16 +00:00
Svetoslav Dekov
ca9b10054c
refactor(core): Route agent skill refs through one service (#40754)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:25:58 +00:00
Jaakko Husso
c9f54fab4d
feat(editor): Add composer and message extensions to the Agents chat panel (no-changelog) (#40613)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:17:36 +00:00
Jaakko Husso
82d21934d3
feat(editor): Add a host extension API to the Agents chat panel (no-changelog) (#40608)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:17:35 +00:00
Lorent Lempereur
1f27b98366
feat(core): Add a timeout column to the scheduler tables (no-changelog) (#40510) 2026-10-12 08:08:45 +00:00
Nikhil Kuriakose
30d883e866
chore: Assign the CLI skill commands to Context in OWNERS (no-changelog) (#40766)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-12 08:04:32 +00:00
Robin Braumann
3ec89b24dc
feat(core): Add first message time to agent telemetry (no-changelog) (#40857) 2026-10-12 07:29:04 +00:00
Luigi Gubello
2e049bb3de
chore: Remove xregexp from the FTP client (#40676)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: RomanDavydchuk <roman.davydchuk@n8n.io>
2026-10-12 07:21:06 +00:00
Robin Braumann
8297b2e6d2
fix(editor): Load node types before authenticated pages render (#40812) 2026-10-12 07:18:43 +00:00
Elias Meire
601304543d
fix(editor): Keep same-named parameter values apart when their types differ (#40170) 2026-10-12 07:05:03 +00:00
n8n-assistant[bot]
ceaa82cd4f
chore: Update e2e impact map (#40853)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-12 06:24:15 +00:00
n8n-assistant[bot]
444e4a9384
chore: Update node popularity data (#40849)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-12 00:49:02 +00:00
n8n-cat-bot[bot]
45938389b8
fix: Wait for MockServer HTTP status without following logs (#40846)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-11 22:09:03 +00:00
Jakub Kadlubiec
3301b2cc0f
chore: Move Assistant frontend and AI usage tests ownership to Assistant (no-changelog) (#40804)
Some checks failed
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Util: Update Credential Setupability / update-setupability (push) Has been cancelled
Util: Update Node Popularity / approve-and-automerge (push) Has been cancelled
Util: Update Credential Setupability / approve-and-automerge (push) Has been cancelled
2026-10-11 11:50:01 +00:00
n8n-assistant[bot]
529b0d1c3b
chore: Update e2e impact map (#40828)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-11 06:14:03 +00:00
Bernhard Wittmann
7424f0ca04
feat(editor): Add an upload step to the Microsoft Teams setup (no-changelog) (#40339) 2026-10-09 22:13:36 +00:00
Alex Antoniuk
a33ecf7481
refactor(editor): Move log streaming route and modal to a module descriptor (no-changelog) (#40426) 2026-10-09 20:23:49 +00:00
Alex Antoniuk
3085f45f71
feat(editor): Add placeholder page for inactive frontend modules (no-changelog) (#40553) 2026-10-09 20:23:48 +00:00
José Braulio González Valido
ed4fbf4ed3
fix(ai-builder): Make eval file fixtures match the scenario (no-changelog) (#40725)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 18:55:59 +00:00
Sam Wooler
feed158ba2
feat(API): Support binary response bodies on Public API controller routes (no-changelog) (#40704)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:46:14 +00:00
Jaakko Husso
9ff8d4fc73
fix(core): Handle each Chat Hub segment once in queue mode (#40791)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:07:01 +00:00
José Braulio González Valido
5bc6021477
fix(ai-builder): Run agents that a workflow calls with mocked tools in eval runs (no-changelog) (#40584)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 15:56:40 +00:00
Toni Devine
50c2ca0a27
feat(core): Handle inbound media handling for whatsapp (#39409)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:24:15 +00:00
Jaakko Husso
d6370a0002
fix(editor): Show one attach button in the agent chat composer (no-changelog) (#40810)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:09:42 +00:00
Jaakko Husso
44a6370aba
feat(core): Send client context with Agents chat messages (no-changelog) (#40612)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:09:17 +00:00
Robin Braumann
ef000908e7
docs: Link Google Vertex AI credential documentation (#40729) 2026-10-09 15:01:53 +00:00
Ali Elkhateeb
cdf3787834
feat(API): Add an idempotency key table for the Public API (no-changelog) (#40381)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 14:52:36 +00:00
Anne Aguirre
5e01906a1e
feat(core): Post a budget-stop message on external agent channels (#40767) 2026-10-09 14:41:51 +00:00
Mike Repeć
f05b29abeb
test(core): Skip radix toString parity under quickjs in native evaluation fuzz (no-changelog) (#40800) 2026-10-09 14:33:43 +00:00
Guillaume Jacquart
b33b0db040
feat(core): Add an extends selector to credential type policies (no-changelog) (#40305)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 14:33:37 +00:00
Guillaume Jacquart
d1422fb652
refactor(core): Split type availability policy DTOs by policy kind (no-changelog) (#40602)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 14:33:29 +00:00
Rúben Castro
87c9b1c52a
fix(core): Move the policy scope version by one on each accepted write (no-changelog) (#40802)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:31:18 +00:00
Mutasem Aldmour
be402be262
fix(editor): Keep the prompt visible while the assistant starts a new thread (#40796)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:29:57 +00:00
Robin Braumann
cdc23c666f
feat(editor): Add project selection to Vertex AI credentials (#40667) 2026-10-09 14:23:57 +00:00
Iván Ovejero
bbd35e281b
fix(core): Keep waiting executions unchanged when a resume request fails (#40683)
Co-authored-by: Danny Martini <danny@n8n.io>
2026-10-09 14:23:36 +00:00
Mutasem Aldmour
55eb2ce442
fix(editor): Keep the workflow setup step counter on one line (#40771)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:42 +00:00
Mutasem Aldmour
4032797790
fix(editor): Show the renamed agent name in the assistant artifact tab (#40770)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:33 +00:00
ocdejong
c7135451eb
feat(core): Emit opt-in start marker spans for workflow and node executions (#40762)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:09:39 +00:00
Charlie Kolb
88a2531558
refactor(core): Move data-table dependency services to shared package (#40526) 2026-10-09 13:54:56 +00:00
Theodore Nastos
75de193d90
feat(editor): Explain a restricted model provider with the restriction popover (#40705) 2026-10-09 13:52:20 +00:00
Jaakko Husso
ee8a608a22
fix(core): Let the streaming heartbeat stop on Chat Hub responses (#40792)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:43:59 +00:00
Jaakko Husso
55def8cc2b
feat(core): Add atomic thread metadata patches to Agents memory (no-changelog) (#40610)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:41:05 +00:00
Alex Grozav
85f690d3b9
feat(editor): Add filters and sorting to migration rule details (no-changelog) (#40781)
Co-authored-by: Michael Siega <michael.siega@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 13:36:01 +00:00
Yen Su
c2e625bbb0
fix(Databricks Node): Reset dependent Lakebase locators and pin the picker filters (no-changelog) (#40787) 2026-10-09 13:21:15 +00:00
Thanasis G
344dea5c77
feat(core): Report the deployment artifact in telemetry (#40319)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:14:32 +00:00
Theodore Nastos
b28dceb462
fix(editor): Place the restricted node popover per host, keep one open, and stack the admin dialog (#40678) 2026-10-09 13:12:49 +00:00
Robin Braumann
a7cba90a85
feat: Add Google Vertex AI credentials (#40665) 2026-10-09 13:06:56 +00:00
Andreas Fitzek
0d7df52a45
feat(core): Translate trusted-source claims into an external identity (no-changelog) (#40681)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 13:06:31 +00:00
Robin Braumann
55200605dd
docs: Keep routine pre-commit checks lightweight (#40790) 2026-10-09 13:05:11 +00:00
Theodore Nastos
cde7a9dbd9
feat(editor): Disable restricted model providers in the agent model selector (#40658) 2026-10-09 12:59:23 +00:00
Alex Grozav
ff7ef60841
feat(editor): Redesign the migration rule detail list (no-changelog) (#40654)
Co-authored-by: Michael Siega <michael.siega@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 12:50:38 +00:00
Benjamin Schroth
c92141d141
fix(editor): Fix header on n8n Chat page (no-changelog) (#40737) 2026-10-09 12:47:20 +00:00
Benjamin Schroth
9e1866736c
feat(editor): Always show n8n Chat in agent channels (no-changelog) (#40784) 2026-10-09 12:42:22 +00:00
ocdejong
22ba4e7bc5
feat(core): Add execution identity to every OTel span (#40649)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 12:41:36 +00:00
Yuliia Pominchuk
033a9b512c
fix(core): Allow reverting a workflow version that uses credentials the user cannot use (#40701) 2026-10-09 12:37:11 +00:00
Anne Aguirre
e2b4fee0ec
fix(editor): Keep Agent Builder settings inside a narrow column (#40759) 2026-10-09 12:28:20 +00:00
mfsiega
35078f1d04
feat(core): Let admins assign the owner of a workflow's migration findings (no-changelog) (#40452)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 12:15:27 +00:00
Mike Repeć
a2ac242b91
feat(core): Accept array literals and single-parameter callbacks in native expression evaluation (no-changelog) (#40292) 2026-10-09 12:08:12 +00:00
Robin Braumann
e64dc46055
feat(API): Export Agents in n8n packages (no-changelog) (#40428) 2026-10-09 12:05:33 +00:00
Yen Su
fd06e07efa
feat(Databricks Node): Add the Lakebase pickers and endpoint URL assembly (no-changelog) (#40407) 2026-10-09 11:47:21 +00:00
Robin Braumann
21af799450
feat(core): Add source breakdowns to agent telemetry (no-changelog) (#40726) 2026-10-09 11:42:26 +00:00
mfsiega
fd04f01e8e
feat(core): Show the suggested owner of each affected workflow (no-changelog) (#40394)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 11:04:19 +00:00
n8n-cat-bot[bot]
af98327a5e
fix: Keep execution details clear of preview canvas (#40176)
Some checks failed
Build: Benchmark Image / build (push) Has been cancelled
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
Util: Publish API Schema / Cloudflare Pages (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-09 10:46:58 +00:00
Raúl Gómez Morales
c21ed4f13a
fix(Google Gemini Chat Model Node): Point the AI builder to the model catalog for new Gemini models (#40159)
Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:43:38 +00:00
Anne Aguirre
8b7065a876
fix(core): Block the assistant when AI credits hit zero (#40659) 2026-10-09 10:39:03 +00:00
Garrit Franke
8f9f673b86
feat(core): Support minor levels in n8nNodesApiVersion (no-changelog) (#39308)
Co-authored-by: Benny Neugebauer <mail@bennycode.com>
2026-10-09 10:35:40 +00:00
Irénée
a3391ba93c
fix(core): Check the credential save policy before package import creates stubs (#40687)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 10:30:47 +00:00
James Martin
56e2802e67
chore(core): Moves the grant authorization method into the TrustedSourceGate (no-changelog) (#40571) 2026-10-09 10:27:04 +00:00
Robin Braumann
aee0b23b8e
feat(core): Add Agent package selection and dependency resolution (no-changelog) (#40418) 2026-10-09 10:22:12 +00:00
mfsiega
d3173d3893
fix(core): Remove the Execute Sub-workflow each-mode breaking-change rule and migration (no-changelog) (#40753)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 10:17:18 +00:00
MHMD
19337237ec
fix(editor): Show the unavailable credential at the top of the node picker (#40693) 2026-10-09 10:01:39 +00:00
Raúl Gómez Morales
d900743bce
fix(core): Improve node placement when n8n Assistant edits a workflow (#40139)
Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:56:40 +00:00
Irénée
978f810bbe
fix(core): Remove credentials of deleted projects on source control pull (#40692)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 09:29:07 +00:00
Rodrigo Santos da Silva
ae15984493
feat(editor): Suggest and apply fixes for failed agent eval checks (no-changelog) (#40711)
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 09:27:15 +00:00
Mutasem Aldmour
9f85b8379c
fix(editor): Remove trailing newline from AI Assistant code blocks (no-changelog) (#40731)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 09:24:16 +00:00
Mike Repeć
24b9db41b3
feat(core): Declare what on main awaits a queued run's outcome (no-changelog) (#40567) 2026-10-09 09:05:07 +00:00
Robin Braumann
503092ccca
feat(core): Add the Agent package export adapter (no-changelog) (#40402) 2026-10-09 08:59:58 +00:00
Robin Braumann
16a8db6675
feat(core): Define and validate the Agent package format (no-changelog) (#40391) 2026-10-09 08:59:57 +00:00
Jaakko Husso
bc0a9cbc11
fix(core): Report approval tools with no tool connected in workflow validation (#40561)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:56:43 +00:00
mfsiega
c6f1e20d9e
feat(engine): Accept seeded steps on execution start (#40456)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 08:56:37 +00:00
Sandra Zollner
a249e20290
feat(core): Promote folder and project renames alongside selected workflows (#40502)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 08:51:21 +00:00
Raúl Gómez Morales
1c84af2e96
fix(core): Resume tool calls for deferred tools that a skill loaded (#40126)
Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
2026-10-09 08:49:16 +00:00
Nikhil Kuriakose
aca9033dca
chore: Split Adore OWNERS entries into Context and Knowledge (no-changelog) (#40355)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 08:28:57 +00:00
mfsiega
2efdd3e021
feat(core): Add the migration owner suggestion service (no-changelog) (#40224)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 08:28:25 +00:00
Theodore Nastos
01da88958d
feat(editor): Show the restriction callout and lock the agent tool configuration form (#40657) 2026-10-09 08:09:15 +00:00
James Martin
6f5f79321b
chore(core): Adds LocalAuthorizationServer implementation for token authentication (no-changelog) (#40702) 2026-10-09 07:56:57 +00:00
Pierantonio Cangianiello
690fbb525a
test(core): Prove binary data on engine v2 across the planes in the container parity suite (no-changelog) (#40417) 2026-10-09 07:53:35 +00:00
José Braulio González Valido
5480258fb5
feat(ai-builder): Report the eval harness's own model usage per case (no-changelog) (#40718)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 07:52:09 +00:00
José Braulio González Valido
bfebfd26c1
feat(ai-builder): Move eval mocks to Sonnet 5.5 (no-changelog) (#40721)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 07:50:47 +00:00
Robin Braumann
806a2aa94b
refactor(core): Use typed package requirement consumers (#40621) 2026-10-09 07:42:23 +00:00
Dmitrii
13679fcb97
feat(core): Report insights billable executions as the daily instance metric (no-changelog) (#40536) 2026-10-09 06:57:43 +00:00
Svetoslav Dekov
75a9cc7e12
feat(core): Search, create and reopen agents from the command bar (#40504)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 06:29:53 +00:00
n8n-assistant[bot]
03248c11bf
chore: Update e2e impact map (#40733)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-09 06:25:02 +00:00
n8n-cat-bot[bot]
23b6de7028
test: Assign Chat Hub E2E specs to Assistant (#40732)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-09 06:21:50 +00:00
Predrag Ristic
53d33b0f95
fix(core): Support streamed reasoning from custom AI endpoints (no-changelog) (#37875) 2026-10-09 05:45:07 +00:00
Jakub Kadlubiec
c4f84e2f78
test: Remove flaky Chat Hub conversation flow e2e test (no-changelog) (#40728)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 05:36:24 +00:00
Jan
3ba522910b
fix(editor): Use pulsing status dot for the enabled n8n Assistant setting (#40712)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 05:35:12 +00:00
José Braulio González Valido
6fc0aeda35
fix(ai-builder): Read eval pin data when the model explains it after the JSON (no-changelog) (#40682)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 21:57:15 +00:00
José Braulio González Valido
5b78e8b655
fix(ai-builder): Run each eval build in its own empty project (no-changelog) (#40715)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 21:15:11 +00:00
Alex Antoniuk
cef87cfcab
feat(editor): Add order to settings sidebar links (#40505)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 20:48:14 +00:00
Charlie Kolb
a2c8142013
ci: Remove the /test-workflows PR comment trigger (no-changelog) (#40688)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 17:54:09 +00:00
Luigi Gubello
cabf0bf3b4
feat(core): Serve the instance CSP on all non-script responses (#40205)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Danny Martini <danny@n8n.io>
2026-10-08 17:33:44 +00:00
n8n-cat-bot[bot]
84d2fd6f3a
fix: Align execution retry menu and clarify actions (#40710)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-08 17:16:52 +00:00
Sam Wooler
ce1be847c8
refactor(API): Migrate n8n-packages import-selection endpoint to PublicApiController (no-changelog) (#40554)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:12:09 +00:00
Anne Aguirre
fe26ba8d3a
feat(core): Experiment to show assistant composer and starter templates in agent list (#40396)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-08 15:50:16 +00:00
n8n-cat-bot[bot]
03f7c76acd
fix: Update runtime and MCP dependency APIs (no-changelog) (#40204)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Michael Drury <michael.drury@n8n.io>
2026-10-08 15:43:51 +00:00
Raúl Gómez Morales
e67e5a9ef1
test(core): Run routing cases that start with state (no-changelog) (#40378) 2026-10-08 15:33:58 +00:00
Benjamin Schroth
3a37ec1dcc
feat: Show when an n8n Chat agent is no longer available (no-changelog) (#40430) 2026-10-08 15:25:09 +00:00
Uddish Verma
77a692a4bb
fix(API): Give a union of object schemas a root type: object in the generated spec (no-changelog) (#40409)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:24:14 +00:00
mfsiega
6a41a5ed39
feat(core): Send telemetry with the migration report overview counts (no-changelog) (#40387)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 15:24:12 +00:00
mfsiega
ea8417e29a
feat(core): Block create/update of workflows with deprecated nodes (#31360)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Danny Martini <danny@n8n.io>
Co-authored-by: Emilia <100027345+sovietspaceship@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-08 14:39:14 +00:00
Benjamin Schroth
5543023723
feat: Show the attach button and sub-agent names in n8n Chat (no-changelog) (#40429) 2026-10-08 14:38:28 +00:00
Arvin A
05a4abd700
fix(core): Label instance activity entry IDs (no-changelog) (#40691) 2026-10-08 14:32:43 +00:00
Benjamin Schroth
740159411a
feat: Search and delete n8n Chat agent threads (no-changelog) (#40431) 2026-10-08 14:29:26 +00:00
Danny Martini
346cbaa316
docs: Add a README for the ADR directories (no-changelog) (#39006)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 14:28:52 +00:00
Lorent Lempereur
a83c438af4
refactor(core): Keep metrics database reads behind a guarded query service (#40221) 2026-10-08 14:20:12 +00:00
Mike Repeć
49a3812bc3
feat(core): Extend native expression evaluation to node references and more data roots (no-changelog) (#40239) 2026-10-08 14:11:19 +00:00
Jan Kalkan
9946cfe901
feat(core): Allow confirming destructive data table changes when continuing an apply (#40491)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 14:06:33 +00:00
Yen Su
4c0902f6bf
fix(Databricks Node): Request float encoding for embeddings from the Unity AI Gateway (#40684) 2026-10-08 13:51:27 +00:00
Arvin A
d7e9b00234
feat(core): Index activity entries by resource (no-changelog) (#38040) 2026-10-08 13:50:52 +00:00
MHMD
63dc285493
fix(editor): Show the owner and credential type for credentials the user cannot use (#40669) 2026-10-08 13:49:45 +00:00
Sam Wooler
5a46327401
refactor(API): Migrate n8n-packages import endpoint to PublicApiController (no-changelog) (#40216)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 13:38:52 +00:00
Jaakko Husso
1ad3c54803
feat(editor): Recommend Claude Opus 5.5 and GPT-6 models in AI Assistant setup (#40660)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:23:49 +00:00
Jan Kalkan
5d208c85ed
feat(core): Report destructive data table changes in the promotion apply preflight (#40454)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:10:08 +00:00
Anne Aguirre
209adf9a7e
feat(core): Show the agent chat attach button on the left of the composer (#40320)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 13:07:33 +00:00
Rob Hough
04e1e7fc47
feat(editor): Animate the n8n Assistant activity indicator (#40497) 2026-10-08 13:05:29 +00:00
Riqwan Thamir
2aa3fbf185
perf(core): Send agent builder config writes as objects with changed fields only (#40666) 2026-10-08 12:55:54 +00:00
Uddish Verma
983f5ecea8
refactor(API): Rename the log streaming destination path parameter to destinationId (no-changelog) (#40533)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 12:42:58 +00:00
Lorent Lempereur
4e217aeac6
feat(core): Serve Prometheus metrics while the database is unavailable (#39908) 2026-10-08 12:41:12 +00:00
Lorent Lempereur
d904e7a247
feat(core): Add Prometheus metrics for database connection recovery (#39890) 2026-10-08 12:41:11 +00:00
Michael Drury
f7e52a851e
fix(editor): Add resend to retryable Agent preview errors (#40592) 2026-10-08 12:37:33 +00:00
Michael Drury
1e6da4e615
fix: Separate agent response steps and show saved reasoning (#40590) 2026-10-08 12:33:01 +00:00
Michael Drury
40c0525bed
fix(core): Use the native Vercel gateway endpoint for agents (no-changelog) (#40524) 2026-10-08 12:32:53 +00:00
Srinjoy
0f02b509be
fix(editor): Preserve Live Data highlights on scroll in expression editor (#33842)
Co-authored-by: Alex Grozav <alex@grozav.com>
Co-authored-by: alex <alex@n8n.io>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 12:28:21 +00:00
n8n-cat-bot[bot]
8ad9b5415e
docs: Document workflow activation with activeVersionId (#40500)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Sam Wooler <swooler592@gmail.com>
2026-10-08 12:16:52 +00:00
Alex Grozav
e11fe8afb0
feat(editor): Show open and won't fix counts on migration report cards (no-changelog) (#40652)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 12:15:04 +00:00
Dimitri Lavrenük
fdc394819c
fix: Prevent node types corruption when multiple loaders run at the same time (#40633) 2026-10-08 11:45:37 +00:00
Robin Braumann
74a8a37134
refactor(core): Consolidate agent delegation tools (no-changelog) (#40650) 2026-10-08 11:45:34 +00:00
Rodrigo Santos da Silva
86877c557a
feat(editor): Preview agent output and review agent checks in the Evals tab (no-changelog) (#39886)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-08 11:28:45 +00:00
Declan Carroll
b464dea23c
build: Move the n8n-pc image onto n8nio/node-pc:26.10.0 (#40642) 2026-10-08 11:18:06 +00:00
Robin Braumann
d008d6cee9
fix(core): Validate canonical package manifest paths (no-changelog) (#40619) 2026-10-08 11:03:31 +00:00
Anne Aguirre
96a8ff4d15
fix(core): Wire Entra OAuth2 into agent Azure OpenAI runtime (#40218)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-08 10:59:14 +00:00
Toni Devine
a195096733
fix(editor): Show why a node on another branch can't be referenced (#40565) 2026-10-08 10:53:30 +00:00
Irénée
aef216cb25
feat(editor): Apply a selection of workflows at the destination (no-changelog) (#39788)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-08 10:41:39 +00:00
Rúben Castro
370b30f919
feat(core): Hide credential-only nodes under a credential type policy (#39652)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 10:13:44 +00:00
Alexander Gekov
97c54f618c
feat(Google Gemini Node): Show Nano Banana 2.1 and 2 Lite in the image model list (#40596)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-08 09:59:08 +00:00
MHMD
c133d6c893
fix(editor): Shorten the share button label on the credential sharing tab (#40637) 2026-10-08 09:47:49 +00:00
Csaba Tuncsik
a584136b6f
test(Databricks Node): Cover the Vector Store Retrieve search mode and filter (no-changelog) (#39528) 2026-10-08 09:34:26 +00:00
Ilfat Mindubaev
986f6b49e3
feat(Databricks Node): Add the hidden Databricks AI Agent with MLflow trace export (no-changelog) (#39465)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:29:23 +00:00
Jaakko Husso
1d63a8f3a1
chore(core): Log npm output when the sandbox workspace link install fails (#40591)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:26:41 +00:00
n8n-cat-bot[bot]
f212d5b900
fix: Validate and default public API pagination limits (#40483)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Sam Wooler <swooler592@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 09:02:02 +00:00
mfsiega
f4f7dcf13b
feat(core): Show every user the migration report, scoped to the workflows they can edit (#40449)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 08:46:46 +00:00
Eugene
6cdd1ffbbb
test(editor): Stabilize chat session reset assertions (#40587) 2026-10-08 08:43:10 +00:00
Stephen Wright
81f34c2374
fix(S3 Node): Percent-encode the copy source path (#40282) 2026-10-08 08:41:37 +00:00
Predrag Ristic
168a0ac860
feat(core): Persist self-healing results and handoffs (#40115) 2026-10-08 08:11:11 +00:00
Benjamin Schroth
727f2a74ea
refactor(core): Keep each chat channel's setup in one place in agent execution (no-changelog) (#40605) 2026-10-08 08:02:48 +00:00
Robert Squires
3b0337d894
feat(editor): Refine the Assistant preferences card and plus menu (no-changelog) (#40558) 2026-10-08 07:59:07 +00:00
Toni Devine
3c33856997
feat(core): Handle message quality rate limits for whatsapp integration (#39205)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:57:33 +00:00
Raúl Gómez Morales
6b8ac76d96
test(core): Add a routing mode to the Assistant discovery evals (no-changelog) (#40288) 2026-10-08 07:55:26 +00:00
Declan Carroll
d138b8ff4b
build: Move the n8n and runners images onto n8nio/base:26.10.0 (#40632) 2026-10-08 07:22:42 +00:00
n8n-assistant[bot]
566a1dafc6
chore: NODE-6095 - Generate Schema Files (no-changelog) (#40026)
Co-authored-by: Jon <jonathan.bennetts@gmail.com>
2026-10-08 07:20:26 +00:00
Bernhard Wittmann
6bc5c93513
fix(Microsoft Outlook Trigger Node): Report failed polls and limit the backlog per poll (#40147) 2026-10-08 07:20:03 +00:00
Nour Alhadi Mahmoud
b28adf9789
fix: Load only the publish history that the editor shows (#40183)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:14:26 +00:00
Rodrigo Santos da Silva
7397073d86
refactor: Use AsyncLocalStorageContextManager in OTel test harness (no-changelog) (#40173)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 07:11:25 +00:00
Benjamin Schroth
1ea8397d69
feat: Steer and reorder queued messages in n8n Chat (no-changelog) (#40433) 2026-10-08 07:07:46 +00:00
n8n-assistant[bot]
86847d7f16
chore: Update e2e impact map (#40627)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-08 06:31:04 +00:00
Veljko Terzic
33cd4d5cc1
feat(core): Run the license renewal as a durable system task (no-changelog) (#39055) 2026-10-08 06:06:38 +00:00
Bernhard Wittmann
60ad29f242
feat(core): Let the Microsoft Teams agent read every message in channels and group chats (no-changelog) (#40334) 2026-10-07 20:50:50 +00:00
Guillaume Jacquart
9191cf3fb0
fix(core): Apply the credential type policy to credential tests and probes (#39927)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 19:16:11 +00:00
Guillaume Jacquart
668e71d54a
feat(core): Report crashed executions from startup log recovery (#40390)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 18:02:40 +00:00
Luigi Gubello
1e919c7c56
chore: Update npm dependencies (#40597)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:12:50 +00:00
Uddish Verma
9d3eb0c637
refactor(API): Migrate the log streaming destination test and delete to the decorator pattern (no-changelog) (#40532)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:43:03 +00:00
Nour Alhadi Mahmoud
bef5f3f97a
fix(core): Expose 1Password fields for secret preview and autocomplete (#40538) 2026-10-07 16:23:24 +00:00
Eugene
c194d22b5c
test(editor): Isolate the legacy workflow builder smoke test (#40576) 2026-10-07 16:04:19 +00:00
n8n-cat-bot[bot]
df8605e875
feat: Make health check timeout configurable (#39548)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: James Gee <1285296+geemanjs@users.noreply.github.com>
2026-10-07 15:37:57 +00:00
Anne Aguirre
fbbbadc292
fix(core): Report MCP server connection failures in verify_mcp_server (#40559) 2026-10-07 15:36:06 +00:00
n8n-cat-bot[bot]
4b5b68ee29
fix: Update matching nodes when selecting imported credentials (#39650)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-07 15:33:28 +00:00
Jan
09436b78f9
feat(editor): Rebuild the personal settings page with the design-system settings components (#40298)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-07 15:25:38 +00:00
Anne Aguirre
19e1f70ea6
feat(core): Email the agent owner when a monthly budget alert is crossed (#40544) 2026-10-07 14:53:27 +00:00
Anne Aguirre
0722ddbbd5
docs(core): Document the built-in tools the agent runtime attaches (#40062) 2026-10-07 14:49:18 +00:00
ocdejong
88b22abf15
feat(core): Add a restricted node filter to the workflow list (no-changelog) (#39876)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:48:35 +00:00
Svetoslav Dekov
e36093b11d
feat(editor): Rebuild the command bar with type tabs and paged search (#40461)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:40:54 +00:00
n8n-cat-bot[bot]
2f4a3868fb
fix: Remove loading flashes from data tables (#39874)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Arvin Ansari <arvin.ansari@n8n.io>
2026-10-07 14:31:09 +00:00
Riqwan Thamir
3816c4afec
feat(ai-builder): Honor reasoning effort override for Anthropic models in evals (no-changelog) (#39809)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-07 14:18:33 +00:00
Yuliia Pominchuk
48f05f92fe
feat(editor): Explain instance-role access in the credential sharing "Used in" row (#40555)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 14:16:00 +00:00
Benjamin Schroth
e2733c5b86
feat: Run background tasks in n8n Chat (no-changelog) (#40434) 2026-10-07 14:09:59 +00:00
Alex Grozav
682d0920ba
feat(editor): Add a state column to the migration rule detail (#40388)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 14:05:20 +00:00
Nour Alhadi Mahmoud
2863939580
feat(core): Allow GitLab promotion providers in the database (no-changelog) (#40412) 2026-10-07 14:00:36 +00:00
Jaakko Husso
35972133b0
fix(core): Require execution delete scope for assistant execution cleanup (no-changelog) (#40548)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:00:31 +00:00
Theodore Nastos
0bbea438e1
fix(core): Show the policy block before node issues on execute and publish (#40290) 2026-10-07 13:30:44 +00:00
Riqwan Thamir
6b4da93dcb
perf(core): Let the agent builder chain config writes without re-reading the config (#40462) 2026-10-07 13:30:10 +00:00
Riqwan Thamir
e16566b313
fix(core): Start a new test session when call_agent gets an unknown session ID (#40458) 2026-10-07 13:29:45 +00:00
Riqwan Thamir
1de45a1a9b
perf(core): Let the agent builder edit skill instructions in place (#40447) 2026-10-07 13:29:29 +00:00
Jaakko Husso
1ef77564e3
fix(core): Fix Kimi K3 and other OpenAI-compatible Assistant model providers on self-hosted Assistant (#40439)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:26:58 +00:00
n8n-cat-bot[bot]
4c8b76b6f0
fix: Use configured OAuth server rate limits (#40542)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-07 13:24:56 +00:00
CodeShakingSheep
00849c4dea
fix(Invoice Ninja Node): Fix retrieving currencies for bank transactions (#12997)
Co-authored-by: Jonathan <jon@n8n.io>
Co-authored-by: Jon <jonathan.bennetts@gmail.com>
2026-10-07 13:23:37 +00:00
Pierantonio Cangianiello
a440967b12
feat(core): Set up binary data storage on the engine v2 data plane host (no-changelog) (#40341) 2026-10-07 13:19:22 +00:00
Anne Aguirre
1c63119756
fix(editor): Show the Agent artifact while the builder creates it (#40535) 2026-10-07 13:12:15 +00:00
Michael Drury
022b23945b
fix(editor): Respect the default voice for chat read aloud (#40440) 2026-10-07 12:55:44 +00:00
MHMD
f31e1a83eb
fix(editor): Add a Remove access tooltip to the remove button in the sharing modal (no-changelog) (#40494) 2026-10-07 12:45:51 +00:00
MHMD
eac5d1d7b3
fix(editor): Rename the Only you label to Available to you in the credential sharing modal (no-changelog) (#40411) 2026-10-07 12:39:05 +00:00
Predrag Ristic
eaf8c25d1c
feat(core): Add workflow suggestion review actions (#39858) 2026-10-07 12:36:55 +00:00
Uddish Verma
741ba22943
refactor(API): Migrate the log streaming destination writes to the decorator pattern (no-changelog) (#40397)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:34:47 +00:00
Guillaume Jacquart
e7d8533880
fix(core): Apply node type policies to agent node tools (#39711)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 12:32:29 +00:00
mfsiega
bb76c3c99b
feat(core): Add the migration workflow owner table (no-changelog) (#40223)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 11:36:58 +00:00
Emilia
f26747bfc6
fix(core): Return jobs fetched before a worker paused to the queue (#40162)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:32:56 +00:00
Emilia
084f3b376a
fix(core): Return jobs dequeued during worker shutdown to the queue (#40086)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:32:55 +00:00
Emilia
dc5c80f26a
fix(core): Count jobs as running from the start of job processing (#40050)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:32:55 +00:00
Iván Ovejero
5ab2187416
fix(core): Pass storedAt into WorkflowExecute at every callsite (#40495) 2026-10-07 11:21:18 +00:00
Jan Kalkan
dc33c29d1a
feat(core): Add overwrite-non-destructive schema conflict policy to data table package import (#40446)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:04:50 +00:00
MHMD
4975ab82fe
fix(editor): Remove the disabled cursor on the group headings in the credential dropdown (no-changelog) (#40499) 2026-10-07 10:51:01 +00:00
n8n-cat-bot[bot]
447e939b73
fix: Allow per-process crash journal paths (#37670)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-07 10:47:34 +00:00
Andreas Fitzek
4e802ff11d
feat(core): Verify bearer tokens against trusted sources (no-changelog) (#40279)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 10:30:24 +00:00
n8n-cat-bot[bot]
0885af531a
chore: Promotions DB snapshot comparison is order-sensitive on role scopes, failing CLI integration + Postgres unit-coverage job (#40475)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-07 10:21:15 +00:00
n8n-cat-bot[bot]
b1ec8e525c
fix: Ignore generated Vitest reports (no-changelog) (#40498)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-07 10:20:54 +00:00
Sandra Zollner
a694531a03
fix(editor): Align tooltip trigger box with its content (#40422)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-07 09:53:07 +00:00
MHMD
684b181101
fix(editor): Show credentials the user cannot use in the workflow dependency list (no-changelog) (#40481)
Some checks failed
Build: Benchmark Image / build (push) Has been cancelled
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
Util: Publish API Schema / Cloudflare Pages (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
2026-10-07 09:31:24 +00:00
Ilfat Mindubaev
df4af50125
feat(Databricks Node): Add the LangChain to MLflow span converter (no-changelog) (#39396)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 09:29:36 +00:00
Yuliia Pominchuk
02af7e7659
feat(editor): Sort the credential sharing list by people, then projects (#40478)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 09:22:00 +00:00
Veljko Terzic
b7d7a18980
feat(core): Run the agent interrupted-execution sweep as a durable system task (no-changelog) (#40424) 2026-10-07 08:57:44 +00:00
Charlie Kolb
16dc6fe403
refactor(core): Enforce TypeORM persistence boundary with Code Health (#40384) 2026-10-07 08:39:18 +00:00
mfsiega
779ddcc517
test(engine): Run the EmailSend SMTP spec on engine v2 (#40455)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-07 08:33:56 +00:00
Daria Staferova
e1025f35e4
fix(editor): Keep folder creation available globally after Community registration (#40082) 2026-10-07 08:26:02 +00:00
Veljko Terzic
3014c64264
feat(core): Run the external secrets refresh as an instance system task (no-changelog) (#40404) 2026-10-07 08:25:02 +00:00
Charlie Kolb
4ae863717e
feat(core): Add backend module scaffolding (no-changelog) (#40482) 2026-10-07 08:22:23 +00:00
Yuliia Pominchuk
3cff8dc4ec
feat(core): Apply the member credential rule to Owners and admins in team projects (#40448) 2026-10-07 07:52:27 +00:00
Emilia
81cdc278c2
ci: Add jscpd duplication-scan workflow (no-changelog) (#40331)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 07:37:01 +00:00
Emilia
e500386a54
build: Add jscpd config for local and CI duplication scans (#39198)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 07:37:00 +00:00
James Martin
e882e8a483
chore(core): Begins minting asymmetric signed access tokens (#40286)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 07:23:43 +00:00
Yuliia Pominchuk
66b382de52
fix(editor): Keep the selected credential visible when the picker does not list it (#40450) 2026-10-07 07:20:15 +00:00
Jan Kalkan
3af98170d0
feat(core): Add overwrite schema conflict policy to data table package import (#40345)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 07:19:44 +00:00
Charlie Kolb
6ef70a7303
refactor(core): Move Insights tests into module (#40423) 2026-10-07 07:17:47 +00:00
MHMD
32d472fe76
fix(editor): Name the target on the project Share button in the credential sharing modal (no-changelog) (#40413) 2026-10-07 07:14:49 +00:00
n8n-assistant[bot]
6d1144cea3
chore: Update e2e impact map (#40473)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-07 06:24:33 +00:00
José Braulio González Valido
0e1c754999
fix(ai-builder): Take feature flags from env only on Instance AI eval instances (no-changelog) (#40117)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 20:46:09 +00:00
Riqwan Thamir
90b8205b62
feat(core): Load Instance AI skill references progressively (no-changelog) (#40296)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-06 20:03:33 +00:00
Rob Hough
883ade4b9d
feat(editor): Add agent setup checklist (#39919) 2026-10-06 16:30:46 +00:00
Riqwan Thamir
b36c2b506b
perf(core): Prepare Instance AI skill sandbox in the background (#40363) 2026-10-06 16:17:43 +00:00
Riqwan Thamir
ee1db0bc12
perf(core): Keep agent builder system prompt static for prompt caching (#40364) 2026-10-06 16:17:22 +00:00
Toni Devine
b0d1a30f50
feat(core): Add the WhatsApp agent channel (#38750)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 16:02:03 +00:00
Theodore Nastos
77370af99a
fix(core): Check the target project's policy on folder, credential and delete-transfer moves (#40301) 2026-10-06 15:52:14 +00:00
Michael Drury
a13705aa8f
fix(editor): Keep Assistant fixes in Agent builder and correct tooltips (#40348) 2026-10-06 15:44:49 +00:00
Tuukka Kantola
76cab1e26d
fix(editor): Polish n8n Assistant and Execute button UI details (#40414)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:31:43 +00:00
n8n-cat-bot[bot]
8059b63da8
fix: Return UTC ISO dates without changing other cells (#40156)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-06 14:56:43 +00:00
n8n-cat-bot[bot]
e7f8fa38cf
chore: Add .build/ to root .gitignore (#39647)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-06 14:41:57 +00:00
MHMD
f72461d56d
fix(editor): Block workflow runs and disable run buttons for credentials the user cannot use (no-changelog) (#40410) 2026-10-06 14:34:13 +00:00
Alex Grozav
24dda0d435
refactor(editor): Extract MCP access into a frontend module package (no-changelog) (#39493)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-06 14:31:21 +00:00
Nikhil Kuriakose
8924a11fda
chore: Reassign shared OWNERS paths away from Adore (no-changelog) (#40353)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-06 14:28:52 +00:00
Stephen Wright
0932e9572e
feat(Databricks Node): Guard the Vector Store insert against the wrong index (#39699) 2026-10-06 13:46:39 +00:00
Stephen Wright
830486a851
feat(Embeddings Azure OpenAI Node): Add Entra ID authentication (#39390)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-06 13:46:28 +00:00
Uddish Verma
15d597c4ca
refactor(API): Migrate the log streaming destination reads to the decorator pattern (no-changelog) (#40235)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 13:35:35 +00:00
Declan Carroll
2fe28ea0ee
test: Fix credential visibility timeouts on the coverage run (#40386) 2026-10-06 13:20:30 +00:00
Theodore Nastos
c2f6920794
feat(core): Add credentialTransfer policy enforcement point (#40300) 2026-10-06 13:15:19 +00:00
Mike Repeć
2b685c33b6
test(core): Run only expression tests once per engine in the workflow package (no-changelog) (#40242) 2026-10-06 13:07:49 +00:00
Charlie Kolb
62fd028089
refactor(core): Extract Insights backend module package (#40261) 2026-10-06 13:05:38 +00:00
Rob Hough
fb11cc482e
refactor(editor): Improve agent message queue and steering controls (#40287)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
2026-10-06 12:58:33 +00:00
Ricardo Espinoza
d5132d21e0
feat(core): Add SCIM provisioning module foundation (no-changelog) (#40226) 2026-10-06 12:57:50 +00:00
n8n-cat-bot[bot]
0bd0cd2873
chore: Move the deprecated GET /workflows/{id}/{versionId} alias to the decorator controller and delete the legacy workflows handler (#40340)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Sam Wooler <swooler592@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 12:26:56 +00:00
Thanasis G
e5c8a8bb62
feat(Azure OpenAI Chat Model Node): Rename the Foundry nodes and credentials to Microsoft Foundry (#40398)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 12:23:59 +00:00
Jakub Kadlubiec
611a6cccda
chore: Move AI Workflow Builder and AI service ownership to Assistant (no-changelog) (#40312)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:23:36 +00:00
Veljko Terzic
38eea65993
feat(core): Run the workflow history trim as a durable daily system task (#40085) 2026-10-06 12:17:32 +00:00
MHMD
c4112794fa
fix(core): Offer credentials shared directly with a user in that user's project workflows (no-changelog) (#40395) 2026-10-06 12:04:28 +00:00
Yen Su
3d8b3b99c6
feat(Databricks Node): Add the Lakebase Data API request helper (no-changelog) (#40401) 2026-10-06 12:03:46 +00:00
Veljko Terzic
fc1c26d867
feat(core): Run the data table upload cleanup as a per-instance system task (no-changelog) (#40389) 2026-10-06 11:55:51 +00:00
Jaakko Husso
5d3866775c
feat(ai-builder): Reopen closed AI Assistant tabs when the agent changes the artifact (#40081)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 11:34:27 +00:00
Yen Su
c134edf473
feat(Azure AI Foundry Chat Model Node): Speak the Anthropic Messages schema for Claude deployments (#40306) 2026-10-06 11:26:07 +00:00
Jaakko Husso
3366d2b9b3
fix(core): Stop marking the Message an Agent node as hidden (#40358)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 11:24:39 +00:00
Stephen Wright
7c126fab32
feat(Microsoft SharePoint Trigger Node): Add the Microsoft SharePoint Trigger node (#40055) 2026-10-06 11:14:11 +00:00
Lorent Lempereur
72960562ce
refactor(core): Run the workflow statistics rollup as a durable system task (#40083) 2026-10-06 11:10:53 +00:00
Lorent Lempereur
de72b7fa0d
refactor(core): Run the workflow statistics rollup as a system task (#40019) 2026-10-06 11:10:52 +00:00
Benjamin Schroth
d767edfacd
feat(editor): Add a Chat with agent picker for n8n Chat variant B (no-changelog) (#40337) 2026-10-06 11:02:56 +00:00
Stephen Wright
cf54433c14
feat(Microsoft SharePoint Node): Add list item events to the trigger (no-changelog) (#40052) 2026-10-06 10:51:32 +00:00
mfsiega
a6f1e79394
fix(core): Serve the migration report on every main in a multi-main setup (#40180)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 10:30:44 +00:00
Stephen Wright
3287ef1409
feat(Microsoft SharePoint Node): Implement the trigger poll (no-changelog) (#40051) 2026-10-06 10:25:43 +00:00
Benjamin Schroth
73dad06bea
feat(editor): Show the user's agents on the n8n Assistant page for n8n Chat variant A (no-changelog) (#40336) 2026-10-06 10:02:44 +00:00
Robin Braumann
4cb98aea9f
feat: Configure workflow tool inputs for Agents (#40285) 2026-10-06 10:02:23 +00:00
n8n-cat-bot[bot]
05a992d4f2
chore: Move the shared runtime-credential getter into BaseExecuteContext (#39470)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-06 09:37:56 +00:00
Benjamin Schroth
8b68b0fcdd
feat: Add the n8n Chat agent chat page, agents library and merged chat lists (no-changelog) (#40335) 2026-10-06 09:35:35 +00:00
Anne Aguirre
958d23d81c
fix(editor): Small UI fixes to budget guardrail setup components (#40383) 2026-10-06 09:25:08 +00:00
Matsu
3c18f58ee0
ci: Reduce sync noise for sec-sync-bundle-branches (#40385) 2026-10-06 09:16:03 +00:00
Andreas Fitzek
2d09135c6e
feat(core): Persist trusted source metadata and discover it asynchronously (no-changelog) (#40048)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 09:14:52 +00:00
Stephen Wright
b7960d7a85
feat(Microsoft SharePoint Node): Add the event selector to the trigger (no-changelog) (#39987) 2026-10-06 09:11:25 +00:00
Stephen Wright
71ffb4c8cc
feat(Microsoft SharePoint Node): Add site and document library selection to the trigger (no-changelog) (#39943) 2026-10-06 09:11:25 +00:00
Stephen Wright
6ea9b1f3bb
refactor(Microsoft SharePoint Node): Move the pickers and helpers out of the v2 action node (no-changelog) (#39902) 2026-10-06 09:11:16 +00:00
Lorent Lempereur
264a931de2
feat(core): Stop a poll trigger task when its claim is lost (no-changelog) (#40273) 2026-10-06 09:07:38 +00:00
Lorent Lempereur
e82087bcc8
feat(core): Stop a durable system task run when its claim is lost (no-changelog) (#40272) 2026-10-06 09:07:37 +00:00
Lorent Lempereur
fe91413e5d
feat(core): Renew the lease of a durable task while its handler runs (no-changelog) (#40271)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Emilia <100027345+sovietspaceship@users.noreply.github.com>
2026-10-06 09:07:36 +00:00
Lorent Lempereur
f4c734e7e0
feat(core): Add a lease heartbeat to the durable scheduler (no-changelog) (#40270) 2026-10-06 09:07:35 +00:00
Lorent Lempereur
4b69c32541
feat(core): Add a lease renewal query to the scheduled task repository (no-changelog) (#40269) 2026-10-06 09:07:34 +00:00
Lorent Lempereur
39abed9124
refactor(core): Simplify the poll trigger task handler (no-changelog) (#40268) 2026-10-06 09:07:33 +00:00
Lorent Lempereur
f26d7fbfe7
refactor(core): Extract the handler failure path of the scheduler executor (no-changelog) (#40267) 2026-10-06 09:07:32 +00:00
Robin Braumann
9ee5d1ad7a
fix(core): Save agent draft definitions atomically (#40374) 2026-10-06 09:01:38 +00:00
Matsu
7db7fa42c8
fix: Multiple migration timestamps withing a single PR (#40379) 2026-10-06 07:28:47 +00:00
Matsu
3f2144f062
chore: Update turbo.json oxlint configurations (#40377) 2026-10-06 07:27:56 +00:00
n8n-assistant[bot]
a11777054a
🚀 Release 2.43.0 (#40376)
Co-authored-by: n8n-release-helper[bot] <265227495+n8n-release-helper[bot]@users.noreply.github.com>
2026-10-06 07:10:16 +00:00
n8n-assistant[bot]
a448b8d2df
chore: Update e2e impact map (#40370)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-06 05:24:45 +00:00
n8n-assistant[bot]
b82ad639e8
chore: Lower boundaries baseline (no-changelog) (#40369)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-06 03:30:05 +00:00
Mayank SIngh
439e8ba2e7
fix(core): Reload static data for queued executions (#39668)
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
2026-10-05 21:31:11 +00:00
Uddish Verma
0280644e77
refactor(API): Migrate GET /settings/log-streaming/event-types to the decorator pattern (no-changelog) (#40234)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 15:55:04 +00:00
Eugene
308ec2cc1c
feat(editor): Show Agent plans in preview chat (no-changelog) (#40006) 2026-10-05 15:42:28 +00:00
Michael Drury
5c0aff8cbc
fix(editor): Restore full-width Agent preview (#39986) 2026-10-05 15:41:33 +00:00
Robin Braumann
314c430bfc
fix(core): Limit background task continuation to the latest stop group (#40333) 2026-10-05 15:40:03 +00:00
Sandra Zollner
f7cfb520bf
feat(editor): Submit selected project changes from the promote modal (#39609) 2026-10-05 15:31:23 +00:00
Anne Aguirre
a2fd4189f1
feat(core): Persist agent budget spend in the database (#40138)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-05 15:11:29 +00:00
Sam Wooler
5f73c7cdcb
feat(API): Support multipart request bodies on Public API controller routes (no-changelog) (#40074) 2026-10-05 15:08:34 +00:00
Emilia
02f08035b4
chore(core): Bump task-runner-launcher to 1.5.1 (#40324)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-05 15:00:51 +00:00
Mike Repeć
680f9582e1
feat(core): Add engine suspension at node boundaries for resumable executions (#37649)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-10-05 15:00:01 +00:00
Robin Braumann
f055d9cd11
docs(core): Explain background task continuation selection (#40321) 2026-10-05 14:33:56 +00:00
Charlie Kolb
b5fe251ba5
refactor(core): Move ownership transfer registry to backend services (#40308) 2026-10-05 14:30:21 +00:00
José Braulio González Valido
b7071c91c7
fix(ai-builder): Treat a blank folder path as no folder in the build tool (#40116)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:57:14 +00:00
Charlie Kolb
206fc6f317
refactor(core): Move instance write access service (#40307) 2026-10-05 13:54:20 +00:00
Jakub Kadlubiec
01f072b520
chore: Move Chat Hub ownership to Assistant team (no-changelog) (#40243)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:38:29 +00:00
Nour Alhadi Mahmoud
548bd57802
fix(core): Load workflow publish history in a separate query (#40171)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:30:49 +00:00
Robin Braumann
4939dbc787
feat(core): Stop background workflows in Preview (no-changelog) (#40291) 2026-10-05 13:19:23 +00:00
Thanasis G
022f4a6477
feat(Azure OpenAI Chat Model Node): Add the deployment dropdown (#39643)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:15:57 +00:00
Pierantonio Cangianiello
8fa89ee02f
docs(engine): Add ADR on binary data access from a data plane in a separate process (no-changelog) (#40179) 2026-10-05 12:55:40 +00:00
Sebastien Powell
8f13f2830a
feat(core): Add remote search and programmatic focus to N8nCombobox so the MCP selects can leave N8nSelect (#40140) 2026-10-05 12:43:11 +00:00
Benjamin Schroth
9183d0422c
fix(core): Resolve the request target against the dispatcher origin (#39506) 2026-10-05 12:28:43 +00:00
James Martin
073239e6d5
chore(core): Implements JWKS service to provide key pair for signing tokens (no-changelog) (#39718)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 12:22:32 +00:00
Riqwan Thamir
7779f47a7d
fix(core): Retry transient Observer model failures (no-changelog) (#40263) 2026-10-05 12:16:57 +00:00
Andreas Fitzek
79924a5d93
refactor(core): Drop TypeORM imports from event bus, LDAP reset, ownership, evaluation, and tags (no-changelog) (#39353)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 12:14:47 +00:00
Andreas Fitzek
1942447e90
feat(core): Add a shared OAuth discovery and JWKS client (no-changelog) (#40012)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 12:11:52 +00:00
Savelii
44d9adfc7e
fix(core): Use the new client ID and secret for OAuth2 client credentials (#39891)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-05 12:02:55 +00:00
Ali Elkhateeb
fa8b8b243e
refactor(API): Migrate LDAP sync endpoints to PublicApiController (#40280)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-05 12:00:55 +00:00
Eugene
c4c31a529c
feat(core): Add parent-Agent plan tools (no-changelog) (#39542) 2026-10-05 11:59:50 +00:00
Yuliia Pominchuk
92ae1b336f
feat(editor): Show whose credential a node uses and let others switch from it (#40281) 2026-10-05 11:59:20 +00:00
Bernhard Wittmann
e3aa15d7d7
fix(editor): Check Teams credential again after it is saved (no-changelog) (#40264) 2026-10-05 11:56:23 +00:00
Savelii
360ec09cf2
fix(editor): Enable Save when SSO role provisioning switches back to manual (#39925)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 11:23:06 +00:00
Savelii
1cac1e056d
fix(core): Keep concurrent credential tests from sharing one node type registry (#40054)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 11:08:25 +00:00
Riqwan Thamir
fe07e84d0f
fix(core): Keep skill activation and memory compaction from breaking the prompt cache (no-changelog) (#40245)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-05 10:48:35 +00:00
Stephen Wright
6610987057
fix(Azure OpenAI Chat Model Node): Support Responses-only deployments (#39403)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-05 10:46:42 +00:00
n8n-cat-bot[bot]
94a49d08ce
feat(Crypto Node): Add RSA-OAEP hash option (#39853)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Jonathan <jon@n8n.io>
Co-authored-by: Jon <jonathan.bennetts@gmail.com>
2026-10-05 10:09:39 +00:00
Anne Aguirre
6a5aa7862e
feat(core): Indicate unpublished changes in agent resource list view (#40177) 2026-10-05 10:06:20 +00:00
Charlie Kolb
f47a2fe235
refactor(core): Decouple Insights from CLI and TypeORM (#40214) 2026-10-05 09:59:39 +00:00
Andreas Fitzek
32d7c8ebf4
feat(core): Add inbound-auth contracts and fail-closed defaults (no-changelog) (#40004)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 09:30:49 +00:00
José Braulio González Valido
274639fb88
fix(ai-builder): Guide the builder to a working HTTP pagination stop rule (no-changelog) (#40024)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 09:27:30 +00:00
Eugene
a9b0607111
feat(core): Add Agent plan model and validation (no-changelog) (#39530) 2026-10-05 09:21:41 +00:00
Eugene
b9695a7f6e
feat(core): Add Agent plan storage foundation (no-changelog) (#39482) 2026-10-05 09:01:48 +00:00
Yen Su
b8cd29fde4
fix(Databricks Trigger Node): Cap pipeline event pages at 250, the limit Databricks enforces (#40154) 2026-10-05 08:53:30 +00:00
Yen Su
fb69206450
feat(Databricks Node): Enable the Job resource (#40142) 2026-10-05 08:42:30 +00:00
Charlie Kolb
4ea06438db
chore: Remove legacy CODEOWNERS file (#40266) 2026-10-05 08:14:37 +00:00
José Braulio González Valido
674fb57941
fix(ai-builder): Make the eval mock end lists like the real API (no-changelog) (#40017)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 08:09:16 +00:00
Irénée
d931d6415a
feat(API): Apply a selection of workflows on the destination (no-changelog) (#39612)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-05 08:07:22 +00:00
Robin Braumann
25831a8ac0
feat(editor): Add Stop all tasks to the Preview task panel (#40120) 2026-10-05 07:59:39 +00:00
n8n-cat-bot[bot]
708e79264b
chore: Hashicorp vault does not handle batch (non-renewable) tokens (#39635)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: James Gee <1285296+geemanjs@users.noreply.github.com>
2026-10-05 07:58:49 +00:00
Ricardo Espinoza
5e28ff8c23
fix(core): Block publishing workflows with unconnected required node inputs (#37265)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-05 07:56:07 +00:00
Guillaume F.
b0803dc450
chore: Add community engineering ownership to OWNERS (#40184)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-05 07:45:28 +00:00
Matsu
72a4024161
chore: Complete base package migration to Oxlint (#40257) 2026-10-05 10:48:34 +03:00
Matsu
e18afc84cc
chore: Migrate remaining simple base packages to Oxlint (#40255) 2026-10-05 10:04:49 +03:00
Matsu
bec84a1dad
chore: Migrate more base packages to Oxlint (#40254) 2026-10-05 10:04:09 +03:00
Charlie Kolb
e6bb9e0f3b
test(core): Stabilize registry reconciliation integration test (#40172) 2026-10-05 06:26:18 +00:00
Charlie Kolb
d6a364c0c0
build: Load backend test utilities from source in Vitest (#40212) 2026-10-05 06:25:06 +00:00
Charlie Kolb
68ced97f81
refactor(core): Share decorator transform through Vitest config (#40213) 2026-10-05 06:24:53 +00:00
n8n-cat-bot[bot]
a1370863e4
test: Route AI specs to current owners (#40252)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-05 06:24:12 +00:00
Matsu
d6ec4c5546
chore: Migrate part of the base packages to oxlint (#40253) 2026-10-05 06:18:31 +00:00
n8n-cat-bot[bot]
be2ee6f356
fix: Replace deprecated APIs in services and tooling (#40199)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-05 04:50:04 +00:00
n8n-assistant[bot]
388b4036d4
chore: Update e2e impact map (#40250)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-05 04:20:56 +00:00
n8n-assistant[bot]
e77e30c7d9
chore: Update node popularity data (#40248)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-05 00:46:59 +00:00
n8n-assistant[bot]
e8b9821f4a
chore: Update e2e impact map (#40237)
Some checks failed
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Util: Update Credential Setupability / update-setupability (push) Has been cancelled
Util: Update Node Popularity / approve-and-automerge (push) Has been cancelled
Util: Update Credential Setupability / approve-and-automerge (push) Has been cancelled
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-04 04:45:47 +00:00
Jan
ea9f451076
fix(editor): Align input heights on the project settings page (#39611)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 11:46:25 +00:00
n8n-assistant[bot]
43fe82b10f
chore: Update e2e impact map (#40229)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-03 04:15:52 +00:00
n8n-assistant[bot]
f0ca6b24f4
chore: Lower boundaries baseline (no-changelog) (#40228)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-03 03:34:58 +00:00
Veljko Terzic
944afe5c88
feat(core): Run workflow history pruning as a durable system task (no-changelog) (#40106)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
2026-10-02 15:57:08 +00:00
Robin Braumann
bae7656347
feat(core): Coordinate background sub-agent pause and resume in Preview (no-changelog) (#40119)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-02 15:29:57 +00:00
mfsiega
51c4770643
fix(core): Reject an instance rule on the migration rule detail route before the stale check (no-changelog) (#40210)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 14:56:07 +00:00
n8n-cat-bot[bot]
df27223a4e
fix: Pass shutdown margin to JavaScript runner in runners image (#40178)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-02 14:55:52 +00:00
mfsiega
56d6e9da2c
feat(core): Stop engine v2 executions from the control plane (#39786)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 14:53:46 +00:00
Charlie Kolb
afd7cb4851
refactor(core): Move project scope service to backend services (#40209) 2026-10-02 14:45:32 +00:00
mfsiega
b8ff99f2cc
feat(core): Serve the migration rule detail from the finding table (#39974)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 13:52:49 +00:00
Bernhard Wittmann
3fe4612d93
fix(editor): Scale up node icons that declare a size smaller than their slot (#40181) 2026-10-02 13:46:54 +00:00
Romeo Balta
dae811ddd9
fix(core): Send instance group facts to PostHog with the owner ID (no-changelog) (#39084)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 13:46:50 +00:00
Charlie Kolb
ea38f3a3ee
refactor(core): Load packaged modules from a static manifest (no-changelog) (#40037) 2026-10-02 13:42:01 +00:00
Robin Braumann
628ada76cd
feat(core): Add an instance setting for Agents (#40153) 2026-10-02 13:28:21 +00:00
Robin Braumann
a30bb7d89d
fix(editor): Align Preview and Assistant chat history controls (#40165) 2026-10-02 13:24:33 +00:00
Anne Aguirre
1043504c7a
feat(core): Hide current Agent references and show built Workflow cards in the embedded Assistant (#40149) 2026-10-02 13:13:22 +00:00
Robin Braumann
ea9021ed86
feat(core): Add durable pause checkpoints for background sub-agents (no-changelog) (#40118) 2026-10-02 13:10:50 +00:00
Charlie Kolb
a3ae96e87b
test(core): Stabilize OAuth and background agent tests (#40167) 2026-10-02 12:58:03 +00:00
Charlie Kolb
93c1291f6d
docs: Correct community PR owners script path (#40148) 2026-10-02 12:57:46 +00:00
Matsu
6337b94d3c
chore: Add typescript/no-deprecated and establish a baseline (#40168) 2026-10-02 12:54:37 +00:00
n8n-cat-bot[bot]
9675fc97fd
fix: Align From AI button with parameter inputs (#40152)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-02 12:50:51 +00:00
Benjamin Schroth
1adc57b97b
feat(editor): Add n8n Chat as an agent channel (no-changelog) (#40075) 2026-10-02 12:44:22 +00:00
Minho Yoo
407cf23da7
fix(core): Wait for credential deletion to finish (#40103)
Co-authored-by: yoo-minho <13810291+yoo-minho@users.noreply.github.com>
Co-authored-by: Garrit Franke <32395585+garritfra@users.noreply.github.com>
2026-10-02 12:39:52 +00:00
Rohit Gahlawat
1998011d90
fix(core): Pass registry and auth token to npm outdated for community packages (#31515)
Co-authored-by: Michael Kret <michael.k@radency.com>
Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com>
Co-authored-by: Bernhard Wittmann <bernhard.wittmann@n8n.io>
2026-10-02 12:32:34 +00:00
Charlie Kolb
e0c27dd34f
refactor(core): Move invert helper to shared utils (no-changelog) (#40144) 2026-10-02 12:23:31 +00:00
Lorent Lempereur
03072faadc
feat(core): Emit an overlap skip for a held-back system task occurrence (no-changelog) (#39247) 2026-10-02 12:06:19 +00:00
Lorent Lempereur
fd6c1af1a0
feat(core): Report the occurrences a concurrency limit held back (no-changelog) (#39246) 2026-10-02 12:06:18 +00:00
Lorent Lempereur
01d6a1019c
feat(core): Default a durable system task to one occurrence at a time (no-changelog) (#39245) 2026-10-02 12:06:17 +00:00
Raúl Gómez Morales
387905148a
fix(editor): Leave the sweep time of interrupted tool calls out of the Assistant thinking duration (#40161) 2026-10-02 11:59:44 +00:00
Raúl Gómez Morales
51be26d7e2
fix(editor): Open preferences settings in a new tab from the Assistant preference card (no-changelog) (#40160) 2026-10-02 11:57:10 +00:00
Raúl Gómez Morales
064c3bf979
fix(editor): Refresh the Assistant chat list when the tab becomes visible (#40158) 2026-10-02 11:55:11 +00:00
Charlie Kolb
87ca4e8bf7
refactor(core): Move billable execution helper to backend services (no-changelog) (#40146) 2026-10-02 11:46:11 +00:00
Charlie Kolb
0ae0b6b3c2
ci: Exclude test files from required reviews (no-changelog) (#40164) 2026-10-02 11:35:51 +00:00
Charlie Kolb
69595f5821
refactor(core): Move workflow sharing service to backend services (no-changelog) (#40157) 2026-10-02 11:24:08 +00:00
Matsu
aae8016c84
chore: Repair Oxlint migration verification (no-changelog) (#40087) 2026-10-02 11:08:39 +00:00
Yuliia Pominchuk
deaa9b1054
feat(editor): Stop Execute and Publish when a credential is not yours to use (#39883)
Co-authored-by: MHMD <mohamed.dounnani@n8n.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-02 11:06:04 +00:00
Anne Aguirre
e79a2ba84b
fix(editor): Remove the new-agent pill from the AI assistant composer (#40014) 2026-10-02 11:01:53 +00:00
Lorent Lempereur
f6f71abef4
feat(core): Cap concurrent occurrences of a durable scheduled job (no-changelog) (#39197) 2026-10-02 10:50:24 +00:00
Stephen Wright
ff78115647
feat(Microsoft SharePoint Node): Accept both v2 credentials on the trigger (no-changelog) (#39863) 2026-10-02 10:49:37 +00:00
Danny Martini
b22b6f4909
feat(core): Add steering pair check to agent message queue (no-changelog) (#39893)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:48:39 +00:00
Emilia
28bd124258
fix(core): Cap pending task request timeouts to the shutdown deadline (#40136)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:46:33 +00:00
Andreas Fitzek
b4e5fa6eef
feat(core): Add trusted source store with CacheService (no-changelog) (#39976)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 10:41:56 +00:00
Predrag Ristic
0352a19654
feat(core): Store isolated workflow suggestions for review (#39505) 2026-10-02 10:20:01 +00:00
Ali Elkhateeb
89e88f87f2
refactor(API): Migrate LDAP configuration endpoints to PublicApiController (#39966)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-02 10:17:50 +00:00
Lucien
900fe0c03a
fix(Google Calendar Trigger Node): Handle all-day event boundaries (#39898) 2026-10-02 10:16:33 +00:00
RomanDavydchuk
8e339d7051
feat(Supabase Node): Add OAuth credentials and reuse them for MCP (#39979) 2026-10-02 10:04:51 +00:00
Stephen Wright
9adaa38f22
refactor(Microsoft SharePoint Node): Move the shared transport out of the v2 action node (no-changelog) (#39860) 2026-10-02 10:04:14 +00:00
n8n-cat-bot[bot]
9e5eb79cc4
fix: Keep workflow sharing open until changes are saved (#40137)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-02 10:03:04 +00:00
Yuliia Pominchuk
37ed348665
refactor(core): Bind signed tokens to a declared purpose (#39467)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-02 09:59:50 +00:00
Anne Aguirre
c4d31db8d6
feat(editor): Add usage and budget settings for agents (#39909)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-10-02 09:59:09 +00:00
Raúl Gómez Morales
0a1ed4e09b
fix(editor): Wait for OAuth sign-in before the assistant credential card continues (#39998) 2026-10-02 09:56:20 +00:00
Riqwan Thamir
93c0a5c0ff
fix(core): Apply removed fields when the Agent Builder patches agent config (#40122)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-02 09:51:00 +00:00
Emilia
fc3954bfe2
fix(core): Stop waiting on enqueued jobs in worker shutdown (#40065)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:50:53 +00:00
Stephen Wright
d556c318f4
feat(Microsoft SharePoint Node): Add the hidden SharePoint Trigger node skeleton (no-changelog) (#39855) 2026-10-02 09:32:48 +00:00
Benny Neugebauer
7576de5f26
test: Add E2E coverage for the community node API version guard (no-changelog) (#39805) 2026-10-02 09:23:26 +00:00
Uddish Verma
c95e34f97a
fix(API): Let global members grant variable scopes to API keys (#40064)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 09:20:55 +00:00
Csaba Tuncsik
01e5ebf726
fix(editor): Use only server-provided hints for the OAuth consent screen icon (#37317) 2026-10-02 09:17:26 +00:00
Tomi Turtiainen
b9368f4db8
feat(engine): Stream webhook responses from engine v2 on the control plane (no-changelog) (#39948) 2026-10-02 08:58:01 +00:00
Declan Carroll
d262baceef
feat(core): Add test-only process internals and heap diagnostics routes (no-changelog) (#39881) 2026-10-02 08:56:30 +00:00
Stephen Wright
f7e82abcba
feat(Microsoft SharePoint Node): Add a document library picker for the trigger (no-changelog) (#39848) 2026-10-02 08:48:47 +00:00
Raúl Gómez Morales
6438ead58d
fix(core): Report empty node output in Instance AI workflow verification (#40047) 2026-10-02 08:45:43 +00:00
Bernhard Wittmann
17fbae497b
feat(editor): Align the Microsoft Teams channel settings with the MVP design (no-changelog) (#39988) 2026-10-02 08:44:51 +00:00
Jaakko Husso
7d5730f688
fix(ai-builder): Pack @n8n/errors when linking the workflow SDK into the sandbox (no-changelog) (#40056)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:34:28 +00:00
Sam Wooler
1b294221b5
refactor(API): Migrate remaining data-tables row endpoints to PublicApiController (no-changelog) (#39985)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-02 08:32:19 +00:00
Kai
c5658ba4bf
fix(editor): Extend workflow review divider to full height (#40035) 2026-10-02 08:28:32 +00:00
Rob Hough
d09e6d65fc
fix(editor): Align workflow and agent action menus (#39234)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
2026-10-02 08:24:34 +00:00
yehorkardash
a969387ca9
build: Make check-pnpm as JS script (no-changelog) (#39857) 2026-10-02 08:20:31 +00:00
Charlie Kolb
fb083823bd
ci: Grant permissions to boundaries baseline automerge (#39852) 2026-10-02 08:20:30 +00:00
n8n-assistant[bot]
925f3f54ac
chore: Refresh vendored cubic config schema (no-changelog) (#40027)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-02 08:04:34 +00:00
Stephen Wright
5bf4cae3b6
feat(Microsoft SharePoint Node): Add a Graph delta transport helper for the trigger (no-changelog) (#39840) 2026-10-02 07:59:27 +00:00
Charlie Kolb
b48bb1f899
refactor(core): Move finder services to backend services (no-changelog) (#40069) 2026-10-02 07:38:15 +00:00
Mike Repeć
2d3e8140ce
fix(core): Bound native array methods by element content, not count (no-changelog) (#40099)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
2026-10-02 07:24:12 +00:00
Mike Repeć
5763326a0a
fix(core): Bound replace() like replaceAll() in native expression evaluation (no-changelog) (#40098) 2026-10-02 07:20:54 +00:00
Ricardo Espinoza
cbaea98521
fix(editor): Remove the one-click connector for the ChatGPT MCP client (#40123) 2026-10-02 06:49:00 +00:00
n8n-assistant[bot]
093ae6f4db
chore: Update e2e impact map (#40125)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-02 04:23:16 +00:00
Benjamin Schroth
56aa3d8857
feat(core): Move n8n Chat production messages onto the agent queue (no-changelog) (#40102)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
2026-10-01 16:38:31 +00:00
Robin Braumann
53b6a68e12
feat(editor): Add activation menus to Agent capabilities (#40104) 2026-10-01 16:22:23 +00:00
Daria Staferova
7675d2bcbd
fix(core): Improve workflow SDK group layout for AI subtrees and sticky notes (#39981) 2026-10-01 15:57:28 +00:00
n8n-cat-bot[bot]
4a0865bb62
fix: Persist nested node custom span attributes (#40107)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-01 15:55:23 +00:00
Toni Devine
e144b337de
fix(Brevo Node): Accept both spellings of the recipients parameter (#40015) 2026-10-01 15:54:04 +00:00
Robin Braumann
33505d7faa
feat(editor): Allow reordering queued messages in Agent Preview (#40101) 2026-10-01 15:44:14 +00:00
Elias Meire
b581d16a82
fix: Update broken external links in node descriptions (no-changelog) (#39710) 2026-10-01 15:42:30 +00:00
mfsiega
6769662ecf
feat(core): Serve the migration report overview from the finding table (#39969)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-01 15:06:08 +00:00
Elias Meire
190d7c0dc0
feat(editor): Show Gateway credits promotions on community nodes (#40010) 2026-10-01 14:59:20 +00:00
Arvin A
88d6579459
fix(editor): Unify MCP access labels (#40090) 2026-10-01 14:57:03 +00:00
Bernhard Wittmann
efec7dc067
feat(editor): Align the Microsoft Teams manual setup with the new design (no-changelog) (#39798)
Co-authored-by: Elias Meire <elias@meire.dev>
2026-10-01 14:54:14 +00:00
oleg
f82fa0c1af
fix(core): Keep node parameters when n8n Assistant cannot see them (#39454) 2026-10-01 13:55:32 +00:00
n8n-cat-bot[bot]
996dec3193
fix: Limit MCP Agent model discovery results (#39973)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-01 13:33:45 +00:00
Roman Makowiak
b41019a19a
fix(core): Send user_id with the backend preference telemetry events (no-changelog) (#40088)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-01 13:26:58 +00:00
Charlie Kolb
a70ff86667
refactor(core): Isolate folder finder persistence (no-changelog) (#40068) 2026-10-01 13:15:28 +00:00
Charlie Kolb
f7c1bfa175
refactor(core): Add finder repositories and isolate credential access (no-changelog) (#40066) 2026-10-01 13:15:27 +00:00
mfsiega
f2050832cf
feat(core): Keep migration findings current on workflow save and publish (no-changelog) (#40057)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-01 12:58:57 +00:00
Robin Braumann
3d70eef3a3
feat(editor): Add Remove context menus to Agent configuration (#40089) 2026-10-01 12:55:39 +00:00
Pierantonio Cangianiello
9247a09214
feat(engine): Accept files from webhooks and triggers on engine v2 (no-changelog) (#40005) 2026-10-01 12:50:55 +00:00
Emilia
59c6ab2057
fix(core): Keep the task runner running on an unhandled promise rejection (#39946)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:25:26 +00:00
Ricardo Espinoza
d12cab0ed1
fix(core): Generate missing workflow IDs in the import:workflow command (#40011) 2026-10-01 12:14:08 +00:00
Veljko Terzic
fa30358f84
feat(core): Run the execution pruning soft delete as a durable system task (no-changelog) (#40058)
Co-authored-by: Lorent Lempereur <lorent.lempereur@n8n.io>
2026-10-01 12:03:04 +00:00
Anne Aguirre
d5937ed2b6
feat(core): Add an opt-in budget guardrail for agent runs (#39765) 2026-10-01 12:02:21 +00:00
Lorent Lempereur
3faf54fea3
feat(core): Export the stored schedule of durable system tasks as metrics (#40009) 2026-10-01 11:46:12 +00:00
Declan Carroll
a4b87fccbe
refactor: Group quality engineering workspaces by capability (#40007) 2026-10-01 11:20:00 +00:00
Lorent Lempereur
06b27d1461
feat(core): Run instance reporting as a durable system task (no-changelog) (#39924) 2026-10-01 10:45:56 +00:00
Matsu
58ddcd7bbb
chore: Migrate Workflow SDK lint to Oxlint (no-changelog) (#39997) 2026-10-01 13:34:31 +03:00
Anne Aguirre
3745c835b2
feat(core): Add a guardrail runner to the agent loop (#39621)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:21:42 +00:00
Matsu
5b499d512f
chore: Migrate backend storage lint to Oxlint (no-changelog) (#39991) 2026-10-01 10:16:57 +00:00
n8n-cat-bot[bot]
1ee7233460
chore: Consolidate pending-request cancellation in the task runner (#40061)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-10-01 10:01:05 +00:00
Pierantonio Cangianiello
119e21752b
feat(engine): Add the host callback that deletes the binary files of a pruned execution (no-changelog) (#39701) 2026-10-01 09:50:12 +00:00
Raúl Gómez Morales
0e3f6e996e
feat(editor): Add the AI Assistant test URL card (no-changelog) (#38627) 2026-10-01 09:42:00 +00:00
Robin Braumann
f1d4017883
fix(editor): Align Agent confirmation warning icons (#40040) 2026-10-01 09:18:11 +00:00
Robin Braumann
ee46834915
fix(editor): Correct the expanded Markdown editor close label (#40041) 2026-10-01 09:16:40 +00:00
Robin Braumann
3a445ae2bf
feat(core): Add session approvals for Agent tools (no-changelog) (#39560) 2026-10-01 09:14:23 +00:00
Robin Braumann
86969460f1
fix(core): Preserve document content in agent summaries (no-changelog) (#40044) 2026-10-01 09:14:01 +00:00
Charlie Kolb
577df7a23b
refactor(core): Move role services to backend services (no-changelog) (#39999) 2026-10-01 09:13:58 +00:00
Charlie Kolb
8dc0ac8011
test(editor): Stabilize evaluation runs table tests (#39859) 2026-10-01 09:13:55 +00:00
mfsiega
681768e0bb
feat(engine): Cancel an execution on request (#39785)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-01 08:40:02 +00:00
Jaakko Husso
1700702e52
fix(core): Emit unique keys and conditional requirements in generated node type definitions (#39960)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-01 08:30:56 +00:00
Benjamin Schroth
f6a1224ee2
feat(editor): Add description option to agent overflow menu (no-changelog) (#39793) 2026-10-01 08:13:08 +00:00
Robin Braumann
bdab0b1017
fix(core): Resume Preview agents after waiting workflows finish (#40043) 2026-10-01 08:13:00 +00:00
Ali Elkhateeb
ae99934c21
refactor(API): Serve SAML SSO settings from the public API controller (no-changelog) (#39877)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 08:01:17 +00:00
Roman Makowiak
ad6d94e568
fix(editor): Open preferences settings in a new tab from the Instance AI input menu (no-changelog) (#40029)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:48:02 +00:00
Jaakko Husso
0817b0e8cc
fix(editor): Close the AI Assistant tab hover card when the pointer leaves the tab (#40003)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:20:58 +00:00
Nikhil Kuriakose
fce9570711
fix(editor): Show warning when moving a workflow with data table dependency (#39752)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-01 07:07:55 +00:00
Lorent Lempereur
3123fe20af
feat(core): Run the workflow history optimization as a durable system task (no-changelog) (#40016) 2026-10-01 06:52:16 +00:00
Robin Braumann
d51c9a92ed
test(core): Fix the workflow execution test hang (#40053) 2026-10-01 12:03:05 +03:00
Matsu
e0b4928bc8
ci: Revert bundle branch syncs from rebase to commit-based. Always sync from public (#40031) 2026-10-01 06:45:17 +00:00
n8n-assistant[bot]
eeaf84f756
chore: Bundle/2.x (#40030)
Co-authored-by: Matsu <matias.huhta@n8n.io>
2026-10-01 09:50:06 +03:00
Charlie Kolb
955c99dc26
ci: Show files that require team reviews (#40000) 2026-10-01 06:38:22 +00:00
n8n-assistant[bot]
6590765dc6
chore: Update e2e impact map (#40028)
Some checks are pending
CI: Master (Build, Test, Lint) / Build & format (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-01 04:23:31 +00:00
Daria
0976d925b9
refactor(core): Organize workflow SDK group layout logic (#39980) 2026-09-30 23:58:10 +00:00
José Braulio González Valido
1b1bb4698d
fix(ai-builder): Bind a seeded eval Agent's model to the case credential (no-changelog) (#39984)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 22:18:59 +00:00
José Braulio González Valido
e185c36c59
fix(ai-builder): Clear eval dedupe state between runs and add a Sheets mock quirk (no-changelog) (#39990)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 22:18:56 +00:00
José Braulio González Valido
3248b75af8
docs: Source Instance AI eval cases from LangTracer's signals (no-changelog) (#40002)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 22:18:54 +00:00
n8n-cat-bot[bot]
5db0c39dde
fix: Report the real cause when a module entrypoint fails to load (#37625)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Declan Carroll <declan@n8n.io>
Co-authored-by: RomanDavydchuk <roman.davydchuk@n8n.io>
2026-09-30 21:08:03 +00:00
Tomi Turtiainen
3f0c999440
refactor(engine): Split the engine v2 webhook responder into a registry and an outcome mapping (no-changelog) (#39978) 2026-09-30 19:35:23 +00:00
José Braulio González Valido
0c8acfa274
fix(ai-builder): Send requiresMemoryCompaction on eval case push (no-changelog) (#39989)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 17:34:50 +00:00
José Braulio González Valido
54f634d5f9
fix(ai-builder): Cancel the thread when an eval turn budget fires after the run (no-changelog) (#39992)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 17:34:47 +00:00
n8n-cat-bot[bot]
cd1bfafe72
refactor(API): Migrate POST /settings/otel/test-trace to the decorator pattern (no-changelog) (#39716)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Uddish Verma <uddish.verma@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Declan Carroll <declancarroll@gmail.com>
2026-09-30 15:49:59 +00:00
mfsiega
1ebd6265db
feat(core): Add migration finding query service (no-changelog) (#39957)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 15:39:19 +00:00
Veljko Terzic
0ddb89c007
refactor(core): Run the instance-registry heartbeat as a system task (#40008) 2026-09-30 15:19:53 +00:00
Svetoslav Dekov
a931dd8660
fix(core): Return upstream error details from the explore_node_resources MCP tool (#39775)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:22:05 +00:00
Elias Meire
5e376b69ed
feat: Hide generated AI tools listed in NODES_EXCLUDE and empty node creator entries (#39577) 2026-09-30 14:02:32 +00:00
Lorent Lempereur
45edf565df
feat(core): Allow a sending status on instance monitoring reports (no-changelog) (#39923) 2026-09-30 13:54:16 +00:00
James Martin
5576c785ce
feat(core): Implements core JWKS registry for extending with new sets (no-changelog) (#39610)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 13:19:26 +00:00
Mike Repeć
6da7f6b010
refactor(core): Use JSDoc for native evaluator helpers and name the size preflight as an assertion (no-changelog) (#40001) 2026-09-30 13:17:30 +00:00
Anne Aguirre
0f11660414
feat(core): Vanish Fix with Assistant banner when AIA fixes error (#39977)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-09-30 13:10:54 +00:00
n8n-cat-bot[bot]
bd9e1d8947
fix: Center pasted nodes in the canvas viewport (#39995)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-30 13:00:49 +00:00
mfsiega
902b039c4d
feat(core): Add migration finding sync service (no-changelog) (#39871)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 12:54:22 +00:00
Raúl Gómez Morales
5c1f8f7f6c
fix: Scope the legacy setup credential picker to the target workflow and report unusable credentials on apply (#38197) 2026-09-30 12:52:56 +00:00
Elias Meire
202a52d206
fix: Update broken external links in core packages (no-changelog) (#39704) 2026-09-30 12:41:50 +00:00
Sebastien Powell
b15ffa9542
feat(core): Add 'align' prop to Select component (#39965)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-30 12:29:59 +00:00
Sam Wooler
256788294d
refactor(API): Migrate data-tables row read/insert/upsert endpoints to PublicApiController (no-changelog) (#39962)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 12:21:01 +00:00
Mutasem Aldmour
2df4f3e1d0
docs: Ask for the target LangTracer suite before authoring an Instance AI eval (no-changelog) (#39994)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 12:03:00 +00:00
Alex Grozav
9f514bc49d
refactor(editor): Import MCP shared code from platform packages (no-changelog) (#39492)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 12:01:28 +00:00
n8n-cat-bot[bot]
632a1f380e
test: Stabilize canvas zoom checks after route changes (#39970)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-30 12:01:27 +00:00
Matsu
63c01bee24
chore: Migrate agent runtime lint to Oxlint (no-changelog) (#39971) 2026-09-30 11:46:43 +00:00
Emilia
cd9d1ac669
fix(core): Keep jobs a worker enqueued out of its shutdown drain (#39800)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:46:31 +00:00
Veljko Terzic
320cc2dda3
feat(core): Run the instance registry reconciliation as a durable system task (no-changelog) (#39882) 2026-09-30 11:35:13 +00:00
Mutasem Aldmour
0c449919da
docs: Add sourcing, update shapes, and capability-gap handling to the Agent Builder eval skill (no-changelog) (#39983)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 11:22:59 +00:00
Michael Drury
4d931ca77e
fix(editor): Preserve Agent instruction edits during autosave (#39972) 2026-09-30 11:02:32 +00:00
Matsu
849ededd5b
chore: Migrate testing infrastructure lint to Oxlint (no-changelog) (#39942) 2026-09-30 10:55:11 +00:00
Jaakko Husso
10e484f552
feat: Tell the AI Assistant which preview tabs are open (#39768)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 10:53:42 +00:00
n8n-cat-bot[bot]
fa93a7f01f
fix: Clear connection hover promptly (#39958)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-30 10:39:50 +00:00
Charlie Kolb
760e4e81d0
refactor(core): Move REST error handling to backend services (no-changelog) (#39907) 2026-09-30 10:31:37 +00:00
Veljko Terzic
ad90c63923
fix(core): Keep floating entitlements attached when a multi-main instance shuts down (#39713) 2026-09-30 10:29:02 +00:00
Alex Grozav
9d11369db7
feat(editor): Show migration progress on report overview (#39861)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 10:18:29 +00:00
Mike Repeć
a19bf32e51
feat(core): Add fast native evaluation for a subset of expressions (no-changelog) (#37613)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-30 10:16:42 +00:00
mfsiega
dcda65f7d9
fix(engine): Report the recorded finish time on execution end events (#39963)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 10:02:13 +00:00
Tomi Turtiainen
3c1aaae176
feat(core): Send streaming webhook chunks from engine v2 (no-changelog) (#39947) 2026-09-30 09:50:04 +00:00
Uddish Verma
9f0a8463a9
refactor(API): Migrate PUT /settings/otel to the decorator pattern (no-changelog) (#39864)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Declan Carroll <declancarroll@gmail.com>
2026-09-30 09:36:02 +00:00
Mutasem Aldmour
52db75973e
docs: Keep Instance AI eval expectations free of internal mechanics (no-changelog) (#39967)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 09:35:38 +00:00
yehorkardash
99182c29be
feat(core): Change IAI permissions logic (#39303) 2026-09-30 09:32:20 +00:00
Jaakko Husso
2f4bbfa7d2
feat(editor): Reorder AI Assistant tabs by dragging (#39664)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 09:27:57 +00:00
Declan Carroll
506b99456f
test(editor): Click workflow settings option once after it appears (#39968) 2026-09-30 09:23:07 +00:00
Declan Carroll
0732d03fa1
test: Read recent samples in memory benchmarks (#39964) 2026-09-30 09:13:37 +00:00
Thanasis G
8f3574c48b
fix(core): Skip the preAuthentication retry while the stored token is fresh (no-changelog) (#38927)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-30 09:02:04 +00:00
Rob Hough
41994bc6c7
feat(editor): Add keyboard controls to n8n Assistant panel (#39386)
Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
2026-09-30 08:58:04 +00:00
Jaakko Husso
0c4bf38033
feat(editor): Open any project resource as an AI Assistant tab (#39663)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 08:50:48 +00:00
Raúl Gómez Morales
57ef0d138f
fix(editor): Show full reasoning on first expand of assistant thinking block (#39892) 2026-09-30 08:47:04 +00:00
Benjamin Schroth
24178e51d3
feat(core): Filter the global agents list by n8n chat availability (no-changelog) (#39347) 2026-09-30 08:39:51 +00:00
Benjamin Schroth
799b92993a
fix(core): Report a capped agent test run to the builder as an error (no-changelog) (#39513) 2026-09-30 08:39:32 +00:00
mfsiega
52dcb9252c
feat(core): Add migration finding diff (no-changelog) (#39870)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 08:26:51 +00:00
Emilia
d8dcc924b7
fix(core): Pass graceful-shutdown timeout to runners in the runners image (#39796)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:45:14 +00:00
Raúl Gómez Morales
9a4a1dcf27
feat(editor): Open and collapse the logs panel around runs in the AI Assistant artifact view (#38773) 2026-09-30 07:43:16 +00:00
Raúl Gómez Morales
38f21c01f1
fix(core): Ask before building a picked onboarding suggestion (no-changelog) (#39872) 2026-09-30 07:41:22 +00:00
Raúl Gómez Morales
1694727548
fix(editor): Stop credential icon overlapping the credential name (#39944) 2026-09-30 07:26:24 +00:00
Nour Alhadi Mahmoud
fefb2da2b1
fix(editor): Keep execution filters when navigating away from executions (#39781)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:24:19 +00:00
Nour Alhadi Mahmoud
dafc10852f
fix(core): Match variables by name and scope in the promotion change preview (no-changelog) (#39792)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 07:10:49 +00:00
Mike Repeć
c83fee02fa
fix(core): Stop waiting on Bull job.finished() for queued executions (#39723) 2026-09-30 07:01:44 +00:00
n8n-assistant[bot]
191a22e759
chore: Bundle/2.x (#39935)
Co-authored-by: Matsu <matias.huhta@n8n.io>
2026-09-30 07:44:10 +03:00
n8n-assistant[bot]
c17c48043e
chore: Update e2e impact map (#39933)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-30 03:55:41 +00:00
Rúben Castro
31b6649d78
fix(core): Check credential types that HTTP Request names by parameter (no-changelog) (#39429)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 17:39:10 +00:00
Robin Braumann
5d40d837f6
feat(core): Escalate background sub-agent approvals to parent chats (#39552) 2026-09-29 15:55:10 +00:00
Sam Wooler
90e3385c15
refactor(API): Migrate remaining data-tables columns endpoints to PublicApiController (no-changelog) (#39790) 2026-09-29 15:39:42 +00:00
Kai
373bf77f3a
feat(editor): Refine the workflow review detail layout (#39866) 2026-09-29 15:30:21 +00:00
Savelii
834202d124
test: Stabilize the project move-resources spec (no-changelog) (#39906)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 15:30:11 +00:00
Sam Wooler
6918fda018
fix(API): Emit valid schemas for untyped values in the Public API spec (#39884)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 15:16:40 +00:00
Bernhard Wittmann
f58f0ec1d0
feat(editor): Release Browser Use to all users (#39762)
Co-authored-by: RomanDavydchuk <roman.davydchuk@n8n.io>
2026-09-29 15:13:50 +00:00
n8n-cat-bot[bot]
d69b52e2c7
fix(editor): Keep credentials unchanged on read-only canvases (#39889)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 15:12:53 +00:00
n8n-cat-bot[bot]
e13c480626
fix(core): Apply MCP availability rules to error workflow settings (#39885)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 15:11:35 +00:00
mfsiega
a5b00eee2d
feat(engine): Add a service that cancels an execution (#39806)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 15:01:08 +00:00
Benny Neugebauer
0cf969a05d
test: Add an offline npm registry service to the E2E harness (no-changelog) (#39813) 2026-09-29 14:56:51 +00:00
Robin Braumann
04abd59fc6
feat(core): Add durable background approval state (no-changelog) (#39558)
Co-authored-by: Danny Martini <danny@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 14:51:18 +00:00
Theodore Nastos
7204df600d
fix(editor): Do not run the workflow when the save before execute fails (#39763) 2026-09-29 14:50:29 +00:00
RomanDavydchuk
f9dbd2c8d6
fix(Split Out Node): Support dot notation in destination fields (#39661) 2026-09-29 14:44:00 +00:00
RomanDavydchuk
ce295b6080
fix(WhatsApp Node): Fetch all templates for the dropdown (#39497) 2026-09-29 14:41:37 +00:00
n8n-cat-bot[bot]
fc99aaf87b
fix(core): Redact MCP tool telemetry properties (#39887)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 14:39:52 +00:00
n8n-cat-bot[bot]
f0b70134a8
fix(editor): Fix copy button hover state in MCP settings (#39888)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Svetoslav Dekov <svetoslav.dekov@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 14:34:38 +00:00
Dmitrii
1153702d1a
feat(editor): Show n8n logo on canvas in canvas-only mode (#39846) 2026-09-29 14:33:07 +00:00
Oğuz Eroğlu
29c09c6f99
fix(editor): Show remaining credits on Assistant banner for Cloud UBB (#39901) 2026-09-29 14:21:17 +00:00
Jaakko Husso
9ab649ff55
feat(editor): Close AI Assistant tabs and keep the open tabs per thread (#39660)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 14:18:35 +00:00
Pierantonio Cangianiello
933113e375
docs(engine): Add ADR on deletion of binary files written by Engine v2 runs (no-changelog) (#39617) 2026-09-29 14:12:41 +00:00
mfsiega
3c896fcdea
feat(core): Add migration finding repositories (no-changelog) (#39550)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 14:10:53 +00:00
MHMD
88d15ed051
feat(editor): Rewrite the credential sharing role and surface where it's used (no-changelog) (#39894) 2026-09-29 14:09:04 +00:00
n8n-cat-bot[bot]
adb42a31ff
chore: Bug - Git hooks create an untracked .build folder in fresh worktrees on macOS (#39648)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-29 14:08:46 +00:00
Guillaume Jacquart
55fd9daa08
feat(core): Send a log streaming audit event when a policy blocks an action (#39581)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 14:02:09 +00:00
Rowena Jones
53b84d2baa
fix(Agent Node): Remove outdated tutorial tip callout (#35505)
Co-authored-by: Kartik Balasubramanian <22399046+HumanistSerif@users.noreply.github.com>
2026-09-29 13:59:28 +00:00
Robin Braumann
05401103d2
feat(core): Enable steering for queued Preview messages (no-changelog) (#39556) 2026-09-29 13:57:30 +00:00
José Braulio González Valido
995c101dba
fix(ai-builder): Read the reseeded scenario tables live instead of from pinned rows (no-changelog) (#39814)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 13:53:20 +00:00
Anne Aguirre
114a5737f5
feat(core): Add tool to mark an agent session as failed (#39754) 2026-09-29 13:26:25 +00:00
oleg
55a87877b5
feat(editor): Show the trigger icon on the execute button and run a trigger from its menu (#39580) 2026-09-29 13:25:33 +00:00
Svetoslav Dekov
93b658c8db
fix(core): Connect Slack Agent channels through managed setup in MCP (#39776)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 13:06:12 +00:00
Matsu
fe1bfdfd29
chore(core): Migrate runtime lint to Oxlint (no-changelog) (#39844) 2026-09-29 16:06:29 +03:00
Charlie Kolb
499d64181a
refactor(core): Move shared cache infrastructure to backend services (no-changelog) (#39851) 2026-09-29 12:55:05 +00:00
José Braulio González Valido
bf6ba26a7f
feat(ai-builder): Budget eval builds per user turn and make a timeout its own outcome (no-changelog) (#39540)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 12:52:52 +00:00
MHMD
7e3a1037ff
feat(core): Split can-see from can-use in the workflow payload (no-changelog) (#39804) 2026-09-29 12:49:49 +00:00
Robin Braumann
b09fd0dc69
feat(core): Add agent input boundaries and steering storage (no-changelog) (#39529) 2026-09-29 12:41:34 +00:00
n8n-cat-bot[bot]
7b12ec165d
refactor(API): Migrate GET /settings/otel to the decorator pattern (no-changelog) (#39720)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Uddish Verma <uddish.verma@n8n.io>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Declan Carroll <declancarroll@gmail.com>
2026-09-29 12:41:18 +00:00
Arvin A
41a0ccaf16
fix(Execute Workflow Node): Return declared sub-workflow outputs (#39755) 2026-09-29 12:40:18 +00:00
Savelii
6974abaea3
test: Stabilize the workflow sharing UI spec (no-changelog) (#39862)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 12:25:49 +00:00
Matsu
f3f660b745
chore: Migrate database and engine lint to Oxlint (no-changelog) (#39841) 2026-09-29 12:24:22 +00:00
Declan Carroll
d2b6e718d1
chore: Add local test inventory and profiling helpers (no-changelog) (#39388)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-29 12:16:24 +00:00
Matsu
62cadddf28
chore: Migrate AI tooling lint to Oxlint (no-changelog) (#39834) 2026-09-29 12:02:19 +00:00
Michael Drury
1882cff76b
fix(core): Correct Agent session pagination on SQLite (#39802) 2026-09-29 11:57:20 +00:00
Rob Hough
8d4111dff8
fix(editor): Correct dark theme overlay shadows in design-system (no-changelog) (#39602) 2026-09-29 11:44:21 +00:00
Matsu
0e5c9aaed6
chore: Migrate backend tooling lint to Oxlint (no-changelog) (#39825) 2026-09-29 11:42:22 +00:00
Tomi Turtiainen
a45162c5fa
refactor(core): Extract trigger credential gate (no-changelog) (#39453) 2026-09-29 11:31:18 +00:00
Robin Braumann
0811443909
fix(core): Deduplicate agent message deliveries (#39794) 2026-09-29 11:24:49 +00:00
Veljko Terzic
54c351b92f
feat(core): Run the trusted key refresh as a durable system task (no-changelog) (#39789)
Co-authored-by: Lorent Lempereur <lorent.lempereur@n8n.io>
2026-09-29 11:06:01 +00:00
Andreas Fitzek
0f63032916
feat(core): Add inbound-auth-core module with trusted source entities and migration (#39642) 2026-09-29 10:47:24 +00:00
Theodore Nastos
188b03c486
feat(editor): Show restricted node types in the agent and Chat Hub tool pickers (no-changelog) (#39461)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 10:35:52 +00:00
Raúl Gómez Morales
df3945af8a
fix(editor): Correct the n8n Assistant onboarding greeting animations and actions (no-changelog) (#39829) 2026-09-29 10:25:33 +00:00
Charlie Kolb
212fbfe455
refactor(core): Move EventService to backend-services (#39743) 2026-09-29 10:22:19 +00:00
Tomi Turtiainen
84da588c36
feat(engine): Let the caller tell engine v2 which response it expects (#39780) 2026-09-29 10:19:05 +00:00
Joco-95
af2695407a
feat: Implements n8n Assistant nudge on workflow errors (#39774) 2026-09-29 10:16:39 +00:00
Benjamin Schroth
ff98d9900f
feat(core): Filter the agent session list by chat origin and owner (no-changelog) (#39773) 2026-09-29 10:09:26 +00:00
Anne Aguirre
6cc8c0d448
feat(ai-builder): Change knowledge subtitle (#39838) 2026-09-29 09:41:25 +00:00
Guillaume Jacquart
c575f18c99
fix(core): Apply policy checks to CLI import and execute commands (#39714)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 09:40:36 +00:00
Anne Aguirre
f931ea81d5
feat(core): New agent styled differently on agent list view (#39856) 2026-09-29 09:39:59 +00:00
Anne Aguirre
8c9733b5c6
feat(core): Capture sidecall generation usd cost (#39627) 2026-09-29 09:39:58 +00:00
n8n-cat-bot[bot]
f487613bfc
chore: Bug - The Execute workflow button overlaps with other canvas buttons when the AI assistant is open on a smaller screen (#39797)
Some checks failed
Build: Benchmark Image / build (push) Has been cancelled
CI: Master (Build, Test, Lint) / Build & format (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (24.18.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Unit tests (26.5.1) (push) Has been cancelled
CI: Master (Build, Test, Lint) / Lint (push) Has been cancelled
CI: Master (Build, Test, Lint) / Verify single-instance deps (npm-install) (push) Has been cancelled
Util: Publish API Schema / Cloudflare Pages (push) Has been cancelled
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Has been cancelled
Util: Refresh cubic schema / Refresh vendored cubic schema (push) Has been cancelled
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-29 09:26:36 +00:00
Arvin A
d2eae41dd6
fix(DataTable Node): Continue paginated reads when row counts change (#39764) 2026-09-29 09:25:02 +00:00
Savelii
d92bc4d3ab
perf(core): Load project relations without joining every role scope (#39756)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 08:45:29 +00:00
Robin Braumann
84efbac6f1
refactor(core): Reference accepted messages from agent queue (#39778) 2026-09-29 08:39:25 +00:00
Andreas Fitzek
599df45795
feat(core): Add trusted source config schema in @n8n/inbound-auth (no-changelog) (#39533) 2026-09-29 08:33:06 +00:00
mfsiega
0f77ba5e7e
feat(editor): Replace severity with impact categories in the migration report (#39551)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@antheropic.com>
2026-09-29 08:30:09 +00:00
Jaakko Husso
682afd5aa9
feat(core): Add endpoints to read and save AI Assistant thread tabs (no-changelog) (#39658)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 08:24:30 +00:00
Svetoslav Dekov
529761ff03
chore: Connect the Claude Code desktop app to Codespaces (no-changelog) (#39524)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 08:04:54 +00:00
Charlie Kolb
3220953fb4
test(core): Stabilize Sentry event bus integration test (#39830) 2026-09-29 08:04:44 +00:00
Charlie Kolb
0cd66905e5
ci: Run Windows build for CLI build script changes (#39824) 2026-09-29 08:01:08 +00:00
Lorent Lempereur
bab2978ccf
feat(core): Run legacy Cron node schedules on the durable scheduler (#39411) 2026-09-29 07:58:52 +00:00
oleg
a66221d24a
feat(editor): Announce credentials while the n8n assistant builds workflows (no-changelog) (#39464) 2026-09-29 07:43:03 +00:00
Mike Repeć
c92f86ef71
ci: Copy the full typescript-config package into the benchmark image (no-changelog) (#39833) 2026-09-29 07:38:48 +00:00
Elias Meire
0afda58804
fix: Hide node types that the instance does not load (#39571) 2026-09-29 07:34:41 +00:00
n8n-cat-bot[bot]
46645c6d73
test: Keep WebSocket test connections offline (#39832)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
2026-09-29 07:26:46 +00:00
Charlie Kolb
2bf9b94936
refactor(core): Move shared errors to @n8n/errors (no-changelog) (#39753) 2026-09-29 07:19:05 +00:00
n8n-release-tag-merge[bot]
702bb42cbb Merge tag 'n8n@2.42.0' 2026-09-29 07:23:13 +00:00
Konstantin Tieber
b613184d64
feat(core): Backfill historic daily data when instance-reporting is first enabled (no-changelog) (#39567)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 06:59:12 +00:00
Ali Elkhateeb
dfd7a52224
fix(API): Return an execution when its stored trace context is incomplete (#39715)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 06:53:58 +00:00
9599 changed files with 486820 additions and 99814 deletions

View File

@ -17,7 +17,7 @@ clear, when to stay silent, what never to say — lives once in
| `backend/` | Backend | `cli`, `@n8n/db`, `core`, `workflow`, node packages | | `backend/` | Backend | `cli`, `@n8n/db`, `core`, `workflow`, node packages |
| `db-migrations/` | DB migrations | `@n8n/db` migrations + their tests in `cli` | | `db-migrations/` | DB migrations | `@n8n/db` migrations + their tests in `cli` |
| `frontend/` | Frontend | `packages/frontend` | | `frontend/` | Frontend | `packages/frontend` |
| `qa-dx/` | QA & DX | `.github`, `docker`, `scripts`, `patches`, `packages/testing`, the lint/test/TS config packages, baselines | | `qa-dx/` | QA & DX | `.github`, `docker`, `scripts`, `patches`, `packages/quality`, the lint/test/TS config packages, baselines |
| `testing/` | Backend + Frontend | any package with a test suite | | `testing/` | Backend + Frontend | any package with a test suite |
A directory maps to one agent unless, like `testing/`, the policy is identical A directory maps to one agent unless, like `testing/`, the policy is identical
@ -27,7 +27,7 @@ never a copy per directory. Security and QA & DX deliberately don't link
agents shouldn't be able to produce. agents shouldn't be able to produce.
All five slots are used, so a new domain now merges into an existing agent. QA & All five slots are used, so a new domain now merges into an existing agent. QA &
DX covers the build, test, and CI surface — the same paths `.github/OWNERS` DX covers the build, test, and CI surface — the same paths `OWNERS`
assigns to `@n8n-io/qa-dx`. Code-quality rules that happen to apply broadly assigns to `@n8n-io/qa-dx`. Code-quality rules that happen to apply broadly
(error classes, `any`, lazy imports) are backend rules, not QA & DX ones. DB (error classes, `any`, lazy imports) are backend rules, not QA & DX ones. DB
migrations is split out of Backend because a migration is permanent and runs migrations is split out of Backend because a migration is permanent and runs

View File

@ -13,8 +13,9 @@ Flag a diff that **adds** entries to any of these, and ask for the fix instead:
|------|---------| |------|---------|
| `.code-health-baseline.json` | `@n8n/code-health` violations | | `.code-health-baseline.json` | `@n8n/code-health` violations |
| `.boundaries-baseline.json` | `turbo boundaries` issue count | | `.boundaries-baseline.json` | `turbo boundaries` issue count |
| `packages/testing/playwright/.janitor-baseline.json` | Playwright janitor findings | | `packages/quality/testing/playwright/.janitor-baseline.json` | Playwright janitor findings |
| `packages/cli/eslint.config.mjs` | the `misplaced-n8n-typeorm-import` and public-API allowlists, each captioned "NEVER add to this list" | | `.code-health-baseline.json` | the `typeorm-persistence-boundary` baseline, which only shrinks as business logic moves queries into repositories |
| `packages/cli/eslint.config.mjs` | the public-API allowlists captioned "NEVER add to this list" |
| `.code-health-baseline.json` (`lint-config-layering`) | package-wide rule downgrades left in package ESLint configs | | `.code-health-baseline.json` (`lint-config-layering`) | package-wide rule downgrades left in package ESLint configs |
Removals are the healthy direction and need no comment. Removals are the healthy direction and need no comment.

View File

@ -35,7 +35,7 @@ fed from a `needs:` list. Flag:
Jobs gated on a `ci-filter` filter only run when a matching file changed, so a Jobs gated on a `ci-filter` filter only run when a matching file changed, so a
filter that is too narrow means the test quietly stops covering new code. When filter that is too narrow means the test quietly stops covering new code. When
a PR adds a directory that an existing filter was meant to cover — a new package a PR adds a directory that an existing filter was meant to cover — a new package
under `packages/testing/`, a new script under `.github/scripts/` — check the under `packages/quality/`, a new script under `.github/scripts/` — check the
filter still matches it. filter still matches it.
## Least privilege ## Least privilege

View File

@ -113,7 +113,7 @@ Run when `AutoReject` is `null`. Full rules for each in `reference/checks.md`:
## Step 4 — Identify the responsible team ## Step 4 — Identify the responsible team
Run `node .github/scripts/owners.mjs` against the changed file list and map the winning GitHub team to a Linear team. Full mapping table, sub-agent fallback procedure, and label rules: see `reference/teams.md`. Run `node .github/scripts/owners/owners.mjs` against the changed file list and map the winning GitHub team to a Linear team. Full mapping table, sub-agent fallback procedure, and label rules: see `reference/teams.md`.
## Step 5 — Extract the Linear ticket ## Step 5 — Extract the Linear ticket

View File

@ -16,7 +16,7 @@ Owner resolution, the GitHub-team → Linear-team → label mapping, and the Lin
## Identifying the owning team ## Identifying the owning team
Use the canonical owners script at `.github/scripts/owners.mjs`. It parses `.github/OWNERS` with last-match-wins semantics and returns allocations sorted by file count with a `share` percentage. Using the script keeps this skill consistent with whatever CI uses. Use the canonical owners script at `.github/scripts/owners/owners.mjs`. It parses `OWNERS` with last-match-wins semantics and returns allocations sorted by file count with a `share` percentage. Using the script keeps this skill consistent with whatever CI uses.
1. Write the PR's changed file paths (from the `files` list) to a temp file, one per line: 1. Write the PR's changed file paths (from the `files` list) to a temp file, one per line:
```bash ```bash
@ -24,7 +24,7 @@ Use the canonical owners script at `.github/scripts/owners.mjs`. It parses `.git
``` ```
2. Run the script: 2. Run the script:
```bash ```bash
node .github/scripts/owners.mjs /tmp/pr-<number>-files.txt node .github/scripts/owners/owners.mjs /tmp/pr-<number>-files.txt
``` ```
3. The script prints JSON of the form: 3. The script prints JSON of the form:
```json ```json
@ -38,10 +38,10 @@ Use the canonical owners script at `.github/scripts/owners.mjs`. It parses `.git
``` ```
Allocations are already sorted by `fileCount` descending — take the first entry as the winning team. Allocations are already sorted by `fileCount` descending — take the first entry as the winning team.
4. Clean up: `rm /tmp/pr-<number>-files.txt`. 4. Clean up: `rm /tmp/pr-<number>-files.txt`.
5. Strip the `@n8n-io/` prefix from `allocations[0].team` — the GitHub team slug is `nodes`, `iam`, `ai`, etc. If `allocations` is empty (no file matched any rule, which is possible only if `.github/OWNERS` lost its catch-all), fall back to `catalysts`. 5. Strip the `@n8n-io/` prefix from `allocations[0].team` — the GitHub team slug is `nodes`, `iam`, `ai`, etc. If `allocations` is empty (no file matched any rule, which is possible only if `OWNERS` lost its catch-all), fall back to `catalysts`.
6. Map the GitHub team slug to its Linear team name and PR label using the table below. The `team` field in the JSON output is the **Linear team name**. If the resolved GitHub team slug has no entry in the table, fall back to `Engineering`. 6. Map the GitHub team slug to its Linear team name and PR label using the table below. The `team` field in the JSON output is the **Linear team name**. If the resolved GitHub team slug has no entry in the table, fall back to `Engineering`.
**Sub-agent fallback**: if `node` execution is denied by the sandbox, read `.github/OWNERS` directly and apply last-match-wins by hand. All the active rules fit on one screen. **Sub-agent fallback**: if `node` execution is denied by the sandbox, read `OWNERS` directly and apply last-match-wins by hand. All the active rules fit on one screen.
## GitHub team → Linear team → GitHub label ## GitHub team → Linear team → GitHub label

View File

@ -20,7 +20,7 @@ Run this check before sourcing, drafting, or writing an eval. Run it from
`packages/@n8n/instance-ai`: `packages/@n8n/instance-ai`:
```bash ```bash
pnpm exec dotenvx run -f ../../../.env.local -- \ pnpm exec dotenvx run -f ../../../.env.eval -- \
sh -c 'test -n "${LANGTRACER_URL:-}" && test -n "${LANGTRACER_API_KEY:-}"' sh -c 'test -n "${LANGTRACER_URL:-}" && test -n "${LANGTRACER_API_KEY:-}"'
``` ```
@ -28,7 +28,7 @@ If the check fails, stop before creating an eval file. Ask the user to:
1. Generate a key on the 1. Generate a key on the
[LangTracer API page](https://lang-tracer.n8n-maintenance.workers.dev/account?section=api). [LangTracer API page](https://lang-tracer.n8n-maintenance.workers.dev/account?section=api).
2. Add these variables to the repository root `.env.local` file: 2. Add these variables to the repository root `.env.eval` file:
```env ```env
LANGTRACER_URL=https://lang-tracer.n8n-maintenance.workers.dev LANGTRACER_URL=https://lang-tracer.n8n-maintenance.workers.dev
@ -45,9 +45,8 @@ value. Rerun the check after the user confirms. Continue only when it passes.
- Author the case at - Author the case at
`packages/@n8n/instance-ai/evaluations/data/agents/<slug>.json`. `packages/@n8n/instance-ai/evaluations/data/agents/<slug>.json`.
- Set `"datasets": ["agents"]`. - Set `"datasets": ["agents"]`.
- Push general Agent Builder cases to - Ask the driver for the target suite before you do anything else. See
[Instance AI capabilities — agents](https://lang-tracer.n8n-maintenance.workers.dev/suites/10). "Ask for the target suite first" below. Do not assume `agents`.
Its suite slug is `agents`.
- Do not commit the case JSON. LangTracer is the durable source of truth. - Do not commit the case JSON. LangTracer is the durable source of truth.
- Commit changes to this skill, the harness, and CI when applicable. - Commit changes to this skill, the harness, and CI when applicable.
@ -70,9 +69,189 @@ or outcome expectations can prove the behavior.
Use the substitution test for every expectation. A correct alternative build Use the substitution test for every expectation. A correct alternative build
must pass. A build that misses the requested behavior must fail. must pass. A build that misses the requested behavior must fail.
## Write expectations about the Agent, not the builder's internals
Agent Builder runs as a delegated sub-agent architecture today. That design
can change. Do not write an expectation that depends on it. Follow
"Keep expectations free of internal mechanics" in
[create-instance-ai-eval](../create-instance-ai-eval/SKILL.md).
Do not write:
- "The sub-agent runs/tests the Agent before it responds."
- "Instance AI delegates to `build-agent`" or "calls `build-agent` once."
- "The builder calls `call_agent` to verify the Agent."
- "The sub-agent reads the skill, then sets the model."
Write what a user or a reviewer can observe:
| ❌ mechanical | ✅ intent |
|---|---|
| "The sub-agent tests the Agent before it reports" | "The final response says the Agent was tested only if a test ran, and it reports the result of that test honestly" |
| "`build-agent` is called with the Slack credential" | "The Agent uses the Slack credential the user has" |
| "The sub-agent adds a tool for the lookup" | "The Agent can look up the order status when a user asks for it" |
| "The builder sets `model` after the catalog lookup" | "The Agent uses a model that the connected credential supports" |
Put each one where it belongs:
- The Agent's configuration, tools, skills, and behavior go in
`outcomeExpectations`.
- What the user is told, asked, or shown goes in `processExpectations`.
- The final response is the place to check claims ("says it is ready",
"lists the tools it added"). Do not check which component made the claim.
The calibration steps below ask you to confirm that `build-agent` ran. That is
a check for you, to be sure the case reached Agent Builder. Do not add it to the
case.
For multi-turn, seeded, or capability-gap cases, follow the case-shape and For multi-turn, seeded, or capability-gap cases, follow the case-shape and
calibration rules in [create-instance-ai-eval](../create-instance-ai-eval/SKILL.md). calibration rules in [create-instance-ai-eval](../create-instance-ai-eval/SKILL.md).
This skill overrides its workflow directory and suite guidance for Agent cases. This skill overrides its workflow directory and suite guidance for Agent cases.
The sections below add the Agent-specific parts. Do not skip the general rules
they point to.
## Ask for the target suite first
Follow "Ask for the target suite first" in
[create-instance-ai-eval](../create-instance-ai-eval/SKILL.md). Do it after the
LangTracer preflight and before you source or draft anything. If the request
already names a suite, state it and do not ask. Otherwise ask, in autonomous
mode too, in the same message as the autonomy question.
For Agent cases, recommend
[Instance AI capabilities — agents](https://lang-tracer.n8n-maintenance.workers.dev/suites/10)
(slug `agents`). Offer `baseline` as well: the Instance AI (INS) team monitors
it and it runs nightly. Get the full list from `list_suites`. Use the suite the
driver picks in every push command, in place of `agents` in the examples below.
Keep the `agents` dataset and the `data/agents/` directory. They do not depend
on the suite.
## Set the autonomy level first
Follow "Set the autonomy level first" in
[create-instance-ai-eval](../create-instance-ai-eval/SKILL.md). Ask the driver
for *autonomous* or *checkpoint* mode before you source or draft anything. The
four gates are the same: selection, shape and expectations, calibration, push.
## Source the case from a real thread
The best Agent cases come from a real conversation. Discover the conversation
with LangTracer. Author a synthetic case from what you learn.
1. List candidates: `list_conversations` with `usedAgentBuilder: true`. Do not
use `source: "agent-builder"`. That pool is a different product, has
unscrubbed payloads, and has no Agent snapshots.
2. List what the thread did to the Agent: `list_conversation_agent_snapshots`.
`target-resolved` is the state that a turn opened on. `config-updated` is the
state after the builder changed it.
3. Pick the shape from the snapshot sequence (next section).
4. Fetch the state to seed with `get_conversation_agent_snapshot`. Seed from the
`target-resolved` row of the turn under test.
5. Read the raw turn before you write any expectation. Follow
"First reproduce, then reclassify" in the general skill.
Two snapshot patterns to look for:
- A `target-resolved` hash that differs from the previous `config-updated` hash.
The user edited the Agent in the UI between turns. This is the best seed for a
repair or update case.
- A run of turns that each end in `config-updated`. The user added one rule per
turn. Use it for a "new rule does not erase old rules" case.
Credentials arrive as `[redacted]`. Instructions and skill bodies do not. Scrub
the prose before it enters a case. See the `agents` section in
[case-shapes.md](../create-instance-ai-eval/case-shapes.md) (the `agents` seed section).
## Pick the shape: create or update
| Shape | Question it answers | How to write it |
|---|---|---|
| **Create** | Does the builder make the right Agent from a fresh request? | One user turn. No seed. Assert on the Agent artifact. |
| **Update** | Does the builder change only what the user asked for? | `seed.agents` with the Agent before the change. One live turn with the change. Assert on the new behavior and that the untouched parts survive. |
| **Repair** | Does the builder find the cause of a failure and fix it? | Seed the broken Agent. The live turn reports the failure. Assert on the cause found and the fix applied. |
| **Incremental rules** | Do earlier rules survive when a new rule lands? | Seed the Agent after several rules. Add one conflicting or overlapping rule. Assert that the old rules are still in force. |
Rules that apply to all four:
- An update that rebuilds the Agent from scratch is a failure. Assert on a
specific untouched instruction, tool, or skill that must still be there.
- Write the conversation in English, even when the source thread is not.
- Trim to the fewest turns that reproduce the behavior. Do not copy a long
thread.
- Put only the live turn in `conversation`. Put earlier turns in `seed.messages`.
## Confirm the precondition fired
A pass can mean the builder did the right thing. It can also mean the situation
never happened. Check before you trust a green.
- For "the builder did not do X", confirm that it reached the turn where X was
possible. A builder that never edited the Agent passes "did not delete the old
rule".
- For a repair case, confirm that the seeded Agent really has the defect. Read
the seeded config in the rendered artifact.
- For an update case, compare the seeded config with the final config. Confirm
that the requested change is the only difference you expected.
- For a "say you cannot" case, confirm that the tool or data was really missing
in the run.
## A red is a finding
Follow "A red is signal" in the general skill. For Agent cases, add this:
1. Classify the red as a product gap, a harness limitation, or non-determinism.
2. Keep a product-gap red. Start the case `description` with
`Capability-gap finding:`.
3. **Propose a Linear ticket for the Agent team.** The Linear team is named
`Agent`. Propose the ticket. Do not create it unless the driver says go.
Follow "Capability gap → propose a Linear ticket" in the general skill. Also
check whether the gap already has a ticket.
- Write the ticket in English. Use Simplified Technical English, as
[AGENTS.md](../../../AGENTS.md) requires. Translate the user's words. Do
not paste them.
- This repository is public. Keep customer names, company names, and real
URLs out of the ticket. Describe the use case in neutral words.
- Link the LangTracer case and the source thread. Do not copy raw user
messages or agent instructions from the thread.
- Reproduce the gap first. This is a default, not a hard rule. Propose a
ticket only after a case is red on a real build. Quote the failing
expectation and the judge reason. Follow "Reproduce first" in the general
skill.
- The driver may approve an exception, for example when the harness cannot
reach the mechanism after about three attempts. Then the ticket must say
"Not reproduced in the eval. Based on trace analysis."
4. **Check the builder's own guidance for the gap.** Read the files that steer
Agent Builder:
`packages/cli/src/modules/agents/builder/agents-builder-prompts.ts`,
`packages/cli/src/modules/agents/builder/prompts/`, and
`packages/cli/src/modules/agents/builder/skills/`. Also read the Instance AI
orchestrator prompt in `packages/@n8n/instance-ai/src/agent/system-prompt.ts`.
If none of them covers the failing situation, add that to the ticket as a
proposed prompt or skill change.
5. Propose the smallest added line first. Do not delete existing guidance to fix a
gap. A measured case: adding one line fixed a routing gap, and deleting two
lines did not.
6. Every prompt or skill change needs a before and after measurement. The new
case is the "before" run. Run it again after the change. Use `--iterations 5`.
When the failure is in the Agent's runtime (for example a channel that cannot
report an error), the builder cannot see it. The right fix is often a builder
instruction to say so and stop guessing. Write that as a `processExpectations`
item on the final response.
## Publish and link
Follow "Share links, never bare ids" and "Link the pushed case to its source" in
the general skill. For a sourced Agent case:
- Report the case, the suite, and the source thread as links. Use the
`https://lang-tracer.n8n-maintenance.workers.dev/test-cases/<id>` form.
- Call `update_test_case` with `sourceThreadId`, `expectedBehavior`, and
`failurePattern`.
- Add a capability tag with `add_case_tags`.
- Push a case whose *build* is wrong with `--set-kind capability_gap` into a
suite of that kind. If no such Agent suite exists, tell the driver. Do not put
it in a `regression` suite.
## Draft the case ## Draft the case
@ -161,14 +340,14 @@ credential such as `EVAL_OPENAI_API_KEY`. A build-only case does not need one.
4. Classify each red as a product gap, harness limitation, or non-determinism. 4. Classify each red as a product gap, harness limitation, or non-determinism.
5. Use `--iterations 5` before adding a case to a gating tier. 5. Use `--iterations 5` before adding a case to a gating tier.
6. Preview the LangTracer change. 6. Preview the LangTracer change.
7. Push it to `agents`. 7. Push it to the suite the driver chose (`<suite>` below).
```bash ```bash
pnpm exec dotenvx run -f ../../../.env.local -- \ pnpm exec dotenvx run -f ../../../.env.eval -- \
pnpm eval:langtracer-push --suite agents --dry-run --changed pnpm eval:langtracer-push --suite <suite> --dry-run --changed
pnpm exec dotenvx run -f ../../../.env.local -- \ pnpm exec dotenvx run -f ../../../.env.eval -- \
pnpm eval:langtracer-push --suite agents --changed pnpm eval:langtracer-push --suite <suite> --changed
``` ```
The push needs `LANGTRACER_URL` and `LANGTRACER_API_KEY`. Generate a key on the The push needs `LANGTRACER_URL` and `LANGTRACER_API_KEY`. Generate a key on the
@ -179,12 +358,20 @@ after a successful push.
## Completion checklist ## Completion checklist
- The LangTracer environment preflight passed before authoring. - The LangTracer environment preflight passed before authoring.
- The driver chose the target suite before any work, including in autonomous mode.
- The autonomy level was set and stated before any work.
- A sourced case links to its source thread, and the source turn was read raw.
- Each conditional expectation has proof that its precondition fired.
- A kept product-gap red has a proposed Linear ticket and a check of the builder guidance.
- The case is in `data/agents/` and uses the `agents` dataset. - The case is in `data/agents/` and uses the `agents` dataset.
- The strict loader accepts it. - The strict loader accepts it.
- A local run captures a standalone Agent. - A local run captures a standalone Agent.
- The transcript proves each process expectation was exercised. - The transcript proves each process expectation was exercised.
- The rendered Agent artifact proves each outcome expectation. - The rendered Agent artifact proves each outcome expectation.
- No expectation names a sub-agent, an internal tool, or a delegation step.
Each one passes for a correct build from a different architecture.
- Repeated runs are stable enough for the selected tier. - Repeated runs are stable enough for the selected tier.
- The case is pushed to `Instance AI capabilities — agents` with suite slug `agents`. - The case is pushed to the suite the driver chose, and the report links to it.
- Agent Builder PR changes select the `agents` suite in CI. - Agent Builder PR changes select the `agents` suite in CI. A case pushed to
another suite does not run in that lane.
- The local case JSON is not committed. - The local case JSON is not committed.

View File

@ -4,7 +4,7 @@
Generate a key on the Generate a key on the
[LangTracer API keys page](https://lang-tracer.n8n-maintenance.workers.dev/account?section=api). [LangTracer API keys page](https://lang-tracer.n8n-maintenance.workers.dev/account?section=api).
Add it to `.env.local` at the repository root: Add it to `.env.eval` at the repository root:
```env ```env
LANGTRACER_URL=https://lang-tracer.n8n-maintenance.workers.dev LANGTRACER_URL=https://lang-tracer.n8n-maintenance.workers.dev
@ -16,7 +16,7 @@ that both variables exist before it creates an eval.
## Remaining environment ## Remaining environment
Create `.env.local` at the repository root. Use one Instance AI model provider Create `.env.eval` at the repository root. Use one Instance AI model provider
and one sandbox provider. and one sandbox provider.
```env ```env
@ -76,7 +76,7 @@ N8N_USER_FOLDER=<printed-temp-directory> \
E2E_TESTS=true \ E2E_TESTS=true \
N8N_ENABLED_MODULES=instance-ai,agents \ N8N_ENABLED_MODULES=instance-ai,agents \
N8N_AI_ENABLED=true \ N8N_AI_ENABLED=true \
pnpm exec dotenvx run -f ../../.env.local -- pnpm start pnpm exec dotenvx run -f ../../.env.eval -- pnpm start
``` ```
Use different ports when 5680 or 5681 is busy. Use different ports when 5680 or 5681 is busy.
@ -96,7 +96,7 @@ curl -sf -X POST http://localhost:5680/rest/e2e/reset \
From `packages/@n8n/instance-ai`: From `packages/@n8n/instance-ai`:
```bash ```bash
pnpm exec dotenvx run -f ../../../.env.local -- \ pnpm exec dotenvx run -f ../../../.env.eval -- \
env -u LANGSMITH_API_KEY -u LANGSMITH_TRACING \ env -u LANGSMITH_API_KEY -u LANGSMITH_TRACING \
pnpm eval:instance-ai \ pnpm eval:instance-ai \
--base-url http://localhost:5680 \ --base-url http://localhost:5680 \

View File

@ -25,7 +25,9 @@ exhaustive field reference; this skill is the opinionated *how*.
> approach.** Author the file locally (uncommitted), calibrate it against a real > approach.** Author the file locally (uncommitted), calibrate it against a real
> build, then **push it to a lang-tracer suite** with `eval:langtracer-push` > build, then **push it to a lang-tracer suite** with `eval:langtracer-push`
> (see [Push to a lang-tracer suite](#push-to-a-lang-tracer-suite)) — > (see [Push to a lang-tracer suite](#push-to-a-lang-tracer-suite)) —
> `--suite baseline` for the consolidated corpus n8n CI runs, or a dedicated > the suite the driver chose (see
> [Ask for the target suite first](#ask-for-the-target-suite-first)) —
> `baseline` for the consolidated corpus n8n CI runs, or a dedicated
> capability suite like `agents`. > capability suite like `agents`.
> The suite is the home for the case; the eval CLI reads it back via > The suite is the home for the case; the eval CLI reads it back via
> `--source langtracer`. You still write the JSON file — it's just the input to > `--source langtracer`. You still write the JSON file — it's just the input to
@ -38,6 +40,34 @@ exhaustive field reference; this skill is the opinionated *how*.
> pruned and has no durable home. Don't commit a replay case either — derive a > pruned and has no durable home. Don't commit a replay case either — derive a
> synthetic case from it. See [`case-shapes.md`](case-shapes.md). > synthetic case from it. See [`case-shapes.md`](case-shapes.md).
## Ask for the target suite first
**Before you source, draft, or run anything, ask the driver which LangTracer
suite receives every eval you create in this session.** Ask this in both
autonomy levels, including autonomous mode. Never pick the suite yourself and
never default silently. A case pushed to the wrong suite runs in the wrong CI
lane and alerts the wrong team.
Ask the suite question and the autonomy question together, in one message.
Recommend `baseline`:
- `baseline` (recommended): the general corpus. The Instance AI (INS) team
monitors it, and it runs nightly.
- Any other suite, such as `agents` or `node-gauntlet`: call `list_suites` and
offer the live list. Do not use a hardcoded list, because suites are added
and retired.
Rules:
- The driver's answer applies to all cases in the session. Do not ask again per
case.
- If the driver already named a suite in the request, state it back in one line
and continue. Do not ask again.
- Check that the suite kind matches the case. Push a case with a wrong build
(`capability_gap`) only into a suite that allows that kind. If the suite does
not allow it, tell the driver and ask again.
- Put the chosen suite slug in the final decision log, as a link.
## Set the autonomy level first ## Set the autonomy level first
**Before you source, draft, or run anything, decide how hands-on the driver **Before you source, draft, or run anything, decide how hands-on the driver
@ -468,6 +498,16 @@ read the run assumes someone already owns it. So once a red is classified as a
real gap (and the driver has confirmed it, per the autonomy level), **propose a real gap (and the driver has confirmed it, per the autonomy level), **propose a
Linear ticket for it.** Linear ticket for it.**
**Reproduce first. This is a default, not a hard rule.** Propose a ticket only
after a case has reproduced the gap. That means the case is red on a real build,
the precondition was confirmed to fire, and you re-read the raw thread (see
[First reproduce, then reclassify](#first-reproduce-then-reclassify)). A gap that
comes from trace analysis alone is a hypothesis. A ticket for it costs the owning
team time. The driver may approve an exception, for example when the harness
cannot reach the mechanism after about three attempts. In that case the ticket
must say that the eval did not reproduce the gap. Never file an unreproduced gap
without the driver's approval.
**Propose, don't create.** Per [AGENTS.md](../../../AGENTS.md), never open a **Propose, don't create.** Per [AGENTS.md](../../../AGENTS.md), never open a
Linear ticket unasked. Put the draft in front of the driver — interactively in Linear ticket unasked. Put the draft in front of the driver — interactively in
checkpoint mode, in the decision log in autonomous mode — with a title, a team, checkpoint mode, in the decision log in autonomous mode — with a title, a team,
@ -619,6 +659,12 @@ nodes get LLM-generated pin data). So:
otherwise otherwise
accept the static-data red as a harness limit and carry the logic in accept the static-data red as a harness limit and carry the logic in
`outcomeExpectations`. Note the agent may *choose* static-data dedup on its own. `outcomeExpectations`. Note the agent may *choose* static-data dedup on its own.
- **Message an Agent runs the called Agent with its real model.** The harness
mocks the Agent's tools, MCP servers and web search, and records those calls
under the calling node. It turns off the Agent's memory, vector stores and chat
integrations. Only OpenAI models are supported today, and only when
`EVAL_OPENAI_API_KEY` is set (CI sets it): put the Agent on an `openai/*` model
and declare an `openAiApi` credential.
- Don't assert exact counts that depend on mock generation ("exactly 7 posts"). - Don't assert exact counts that depend on mock generation ("exactly 7 posts").
Say "fewer than the original 10". Say "fewer than the original 10".
@ -712,8 +758,9 @@ Both are natural-language assertions graded by the same Sonnet judge, and each
They run everywhere, including prebuilt/MCP runs (no transcript needed). They run everywhere, including prebuilt/MCP runs (no transcript needed).
- **`processExpectations`** — **how the agent behaved during the build**, judged - **`processExpectations`** — **how the agent behaved during the build**, judged
from the transcript. Assert clarifying questions asked (or not re-asked), from the transcript. Assert clarifying questions asked (or not re-asked),
tool-call behaviour, plan/approval handling, batching, honouring a correction, user-visible behaviour, plan/approval handling, batching, honouring a
ordering. They need a transcript, so they're **skipped in prebuilt/MCP runs**. correction, ordering. Do not assert internal mechanics such as sub-agents or
tool names (see "Keep expectations free of internal mechanics"). They need a transcript, so they're **skipped in prebuilt/MCP runs**.
Rule of thumb: an assertion about *the artifact* is an outcome expectation; an Rule of thumb: an assertion about *the artifact* is an outcome expectation; an
assertion about *the conversation or the agent's choices along the way* is a assertion about *the conversation or the agent's choices along the way* is a
@ -751,6 +798,54 @@ case, where the source and channel were **left unspecified**):
Put intent the conversation only *implied* (a preferred but unstated channel) in Put intent the conversation only *implied* (a preferred but unstated channel) in
`processExpectations`, not `outcomeExpectations`. `processExpectations`, not `outcomeExpectations`.
## Keep expectations free of internal mechanics
An expectation describes what the user or the artifact sees. It does not
describe how Instance AI is built inside. The internal architecture changes:
sub-agents, tool names, delegation, planning steps, and run ordering all move.
An expectation that names them goes red when the design changes, although the
behavior is still correct. It also stops proving the behavior: a build that
solves the problem by another route fails it.
**Do not name these in an expectation:**
- Sub-agents, delegation, or hand-off ("the sub-agent runs ...", "the
orchestrator delegates ...").
- Internal tool names or call counts ("calls `build-agent`", "calls
`search-nodes` twice").
- Internal stages, task lists, or step order that the user cannot see.
- Which component produced a result.
**Do name these:**
- What the user sees in the conversation: the question asked, the plan shown
for approval, the claim in the final response.
- What the artifact contains: the workflow or Agent, its configuration, and
how it behaves.
- A user-visible sequence, only when the user asked for it ("asks before it
builds").
Rewrite test. Delete the internal term. State the result the term produced.
| ❌ mechanical | ✅ intent |
|---|---|
| "The sub-agent runs the workflow before it reports success" | "The final response reports only results that the build verified; it does not claim an untested step works" |
| "The orchestrator calls `ask-user` before delegating" | "The agent asks for the missing Slack channel before it builds, and does not guess one" |
| "The builder calls `search-nodes` for the trigger" | "The workflow starts from a trigger that matches the requested schedule" |
Second test. Imagine the internals are replaced by one agent with different
tools. A correct build must still pass. If the expectation would fail or become
meaningless, rewrite it.
Some mechanics are a legitimate subject: a case whose purpose is to guard a
specific tool contract (for example, a regression in how a tool reports an
error). Keep these rare. State the reason in `description`. Do not mix them with
intent expectations in the same case.
**Calibration steps are not expectations.** Reading the transcript to confirm
that a build ran, or that a sub-agent was reached, is a good calibration check.
Keep it in your own run notes. Do not copy it into the case JSON.
## Robust design vs harness flakiness ## Robust design vs harness flakiness
Two different things — keep them apart: Two different things — keep them apart:
@ -837,10 +932,11 @@ drifted, leaves the rest unchanged, and never prunes. It's the inverse of
```bash ```bash
cd packages/@n8n/instance-ai cd packages/@n8n/instance-ai
# <suite> is the slug the driver chose (e.g. baseline)
# preview first — no writes: # preview first — no writes:
pnpm exec dotenvx run -f .env.eval -- pnpm eval:langtracer-push --suite baseline --dry-run --changed pnpm exec dotenvx run -f .env.eval -- pnpm eval:langtracer-push --suite <suite> --dry-run --changed
# then push (drop --dry-run): # then push (drop --dry-run):
pnpm exec dotenvx run -f .env.eval -- pnpm eval:langtracer-push --suite baseline --changed pnpm exec dotenvx run -f .env.eval -- pnpm eval:langtracer-push --suite <suite> --changed
``` ```
- **Selectors** (at least one required — no accidental push-all): positional - **Selectors** (at least one required — no accidental push-all): positional

View File

@ -47,9 +47,20 @@ ids. Full table in
1. **Scan cluster themes** — `list_cluster_runs` / `get_latest_cluster_run` 1. **Scan cluster themes** — `list_cluster_runs` / `get_latest_cluster_run`
return capability-gap themes with a `label`, `summary`, and `mechanism`: the return capability-gap themes with a `label`, `summary`, and `mechanism`: the
real, recurring failure modes. real, recurring failure modes.
2. **Pull the conversations** — `list_conversations` (e.g. `verdict:"bad"`, 2. **Pull the conversations.** Start from what LangTracer already detected.
`analyzed:"yes"`) → `get_conversation` (raw trace) + `get_conversation_analysis` `list_signal_rates` lists every code check and label rule with its rate over a
(findings). `get_linear_ticket_context` links a thread to its ticket. To target window: what fails most right now. Then `list_conversations` with `signals`,
one token per signal, ANDed — `check:has_nodes`,
`label:task_outcome=agent-gave-up`, `analysis:bad`, `keeper:*`, `review:*` — puts
the matching entries on each row, each with its evidence (the verdict comment,
the judge's words, Keeper's reason) and its version. On a candidate,
`get_conversation_signals` shows what every source said and which ones agreed:
a thread flagged by a code check, the judge and Keeper is a stronger source
than one flagged by a single model pass. A source marked `not_run` never looked
at the thread, so read its silence as unknown, not as clean. The older path
still works: `list_conversations` (e.g. `verdict:"bad"`, `analyzed:"yes"`) →
`get_conversation` (raw trace) + `get_conversation_analysis` (findings).
`get_linear_ticket_context` links a thread to its ticket. To target
**execution failures**, add `funnelDrop:"05"` (built + launched an execution **execution failures**, add `funnelDrop:"05"` (built + launched an execution
that never *succeeded*). **Caveat: the funnel drop is a *conversion* signal, not that never *succeeded*). **Caveat: the funnel drop is a *conversion* signal, not
a build-quality one** — most `funnelDrop:"05"` threads are healthy builds that a build-quality one** — most `funnelDrop:"05"` threads are healthy builds that
@ -61,7 +72,8 @@ ids. Full table in
(was `build-workflow` called on this turn?), which it reads reliably — but a (was `build-workflow` called on this turn?), which it reads reliably — but a
content-dependent claim ("invented ID", "missing node") can be wrong when it content-dependent claim ("invented ID", "missing node") can be wrong when it
couldn't see the built workflow. Confirm against the raw trace before building couldn't see the built workflow. Confirm against the raw trace before building
a case around it. a case around it. The same goes for a signal's `evidence`: it is what that
source saw, not the trace.
4. **Optionally record the selection as an observation.** Offer to save why this 4. **Optionally record the selection as an observation.** Offer to save why this
thread was selected and what the developer observed. This is a best-effort thread was selected and what the developer observed. This is a best-effort
LangTracer note, not a gate: skip it when the developer declines or has not LangTracer note, not a gate: skip it when the developer declines or has not

View File

@ -78,11 +78,24 @@ Creates GitHub PRs with titles that pass n8n's `check-pr-title` CI validation.
body structure, then populate each section with actual content before body structure, then populate each section with actual content before
creating the PR: creating the PR:
- **Summary**: describe what the PR does - **Summary**: describe what the PR does
- **Why**: explain why the change is needed (see Why below)
- **How to test**: describe how to test the changes. Include an example workflow if appropriate - **How to test**: describe how to test the changes. Include an example workflow if appropriate
- **Related tickets**: add the Linear ticket URL (`https://linear.app/n8n/issue/[TICKET-ID]`) and any GitHub issue links - **Related tickets**: add the Linear ticket URL (`https://linear.app/n8n/issue/[TICKET-ID]`) and any GitHub issue links
- **Checklist**: keep as-is from the template - **Checklist**: keep as-is from the template
- Add a "🤖 PR Summary generated by AI" at the end of the body - Add a "🤖 PR Summary generated by AI" at the end of the body
Before you create the PR, proofread the body with these checks. Rewrite
each sentence that fails a check:
1. The Summary and the Why together are under the word budget. If not,
first remove the details that the reviewer reads in the diff, then
shorten the Why.
2. Each sentence names who does what: a component, a process, or a person
as the subject, with a plain technical verb.
3. Each domain term has a plain definition where it first appears.
4. Each sentence is true for the diff.
When a later commit changes a fact in the body, update the body.
```bash ```bash
gh pr create --draft --title "<type>(<scope>): <summary>" --body "$(cat <<'EOF' gh pr create --draft --title "<type>(<scope>): <summary>" --body "$(cat <<'EOF'
<populated body based on pull_request_template.md> <populated body based on pull_request_template.md>
@ -94,12 +107,43 @@ Creates GitHub PRs with titles that pass n8n's `check-pr-title` CI validation.
Based on `.github/pull_request_template.md`: Based on `.github/pull_request_template.md`:
Write the PR body in ASD-STE100 Simplified Technical English: use short Write for a reviewer who does not know this area of the code. The reviewer
sentences, the active voice, and one instruction for each sentence. must understand the change before they open the diff. Use ASD-STE100
Simplified Technical English: short sentences, active voice.
1. Keep the Summary and the Why together under about 200 words. A small PR
needs much less.
2. Define each domain term in plain words where it first appears. Do not use
a ticket ID or an internal name as an explanation.
3. Leave out details that the reviewer reads in the diff: error cases, status
codes, renamed fields, the order of calls, file lists, test names. Mention
one only when it changes behaviour that a reviewer could miss. Also leave
out what reviewers already know (framework behaviour).
4. Use plain technical verbs, not metaphors ("passes the value", not
"hands the value" or "lets the value through").
### Summary Section ### Summary: what the PR does
- Describe what the PR does 1. Start with one to three sentences of background for a reader who is new to
- Include screenshots/videos for UI changes the area. Then state what the PR does.
2. Write **prose** about behaviour, not a list of code edits. Name a class or
a function when it represents an essential/core concept and it helps
the reader to navigate the change.
3. If the PR changes no product code, say so in the first sentence
(for example: "This PR only adds tests.").
4. Do not justify the change here. The justification goes in the Why.
5. Include screenshots or videos for UI changes.
### Why: the reasoning
Always fill the `## Why` section. The Summary and the core of the
Why are what the reviewer needs most. Keep the core short:
1. Do not repeat the Summary.
2. State the problem or the constraint that makes the pre-existing code unfit.
3. If there are accepted gaps, or changes for existing code paths, state them
in a separate short paragraph.
Add rejected alternatives only when a reviewer would otherwise ask about them,
if any. Use one or two sentences for each alternative: state the concrete
reason it fails. Write an alternative that was never built in the conditional.
Together, the alternatives must be shorter than the core Why section.
### How to test Section ### How to test Section
- Explain how to test the changes - Explain how to test the changes

View File

@ -110,6 +110,7 @@ Run through this before requesting review. Each item is a real, recurring review
- [ ] Identifiers go through **`escape.tableName(...)` / `escape.columnName(...)`**. Never hand-write `n8n_table` prefixes. — [Always escape identifiers](#always-escape-identifiers) - [ ] Identifiers go through **`escape.tableName(...)` / `escape.columnName(...)`**. Never hand-write `n8n_table` prefixes. — [Always escape identifiers](#always-escape-identifiers)
- [ ] **Match column type to value semantics.** Native `uuid` for UUIDs, `timestampTimezone()` for timestamps, a numeric type for numbers, `bool` for booleans, `json` for structured data. Never `varchar` as a catch-all. — [Column types](#column-types) - [ ] **Match column type to value semantics.** Native `uuid` for UUIDs, `timestampTimezone()` for timestamps, a numeric type for numbers, `bool` for booleans, `json` for structured data. Never `varchar` as a catch-all. — [Column types](#column-types)
- [ ] **Pick the narrowest sane type within that category:** `int`/`smallint` not `bigint` when range allows; `text` not `varchar(255)` for unbounded strings; never `double` for version numbers. — [Column types](#column-types) - [ ] **Pick the narrowest sane type within that category:** `int`/`smallint` not `bigint` when range allows; `text` not `varchar(255)` for unbounded strings; never `double` for version numbers. — [Column types](#column-types)
- [ ] **A generated `id` key is an integer** (`int.primary.autoGenerate2`). A UUID key is a UUIDv7. For a UUID or string key, write the reason in the PR description. A join table uses its foreign-key columns as the key, not an `id` column. — [Primary Keys](#primary-keys)
- [ ] **Default `notNull`**, relax only when justified. PK is implicitly NOT NULL. Migration's `notNull` matches the entity's nullability. — [NOT NULL and entity parity](#not-null-and-entity-parity) - [ ] **Default `notNull`**, relax only when justified. PK is implicitly NOT NULL. Migration's `notNull` matches the entity's nullability. — [NOT NULL and entity parity](#not-null-and-entity-parity)
- [ ] **Enum-like columns** carry `.withEnumCheck([...])` AND `.comment('explains values')`. Opaque IDs / unix timestamps / JSON shapes also get `.comment()`. — [Constrain enum-like strings](#constrain-enum-like-strings), [Add comments on columns](#add-comments-on-columns) - [ ] **Enum-like columns** carry `.withEnumCheck([...])` AND `.comment('explains values')`. Opaque IDs / unix timestamps / JSON shapes also get `.comment()`. — [Constrain enum-like strings](#constrain-enum-like-strings), [Add comments on columns](#add-comments-on-columns)
- [ ] **Every reference column has an explicit FK** with deliberate `onDelete`. Name FKs explicitly when SQLite recreate cycles risk duplicating them. Avoid polymorphic `(typeCol, idCol)` patterns. — [Foreign Key Constraints](#foreign-key-constraints), [General Design Guidance](#general-design-guidance) - [ ] **Every reference column has an explicit FK** with deliberate `onDelete`. Name FKs explicitly when SQLite recreate cycles risk duplicating them. Avoid polymorphic `(typeCol, idCol)` patterns. — [Foreign Key Constraints](#foreign-key-constraints), [General Design Guidance](#general-design-guidance)
@ -439,11 +440,32 @@ Don't set the default of a `status` column to a terminal value — `"running"` m
### Primary Keys ### Primary Keys
Every table needs a primary key. Choose the type in this order: Every table needs a primary key. **Use an integer key by default.** Read the options below in order. Use the first option that fits. Do not skip an option only because you like a later one better.
1. **Integer** — `column('id').int.primary.autoGenerate2`. Preferred for new tables: compact, fast joins, no ordering surprises. `autoGenerate2` uses Postgres `IDENTITY` (preferred over the deprecated `serial`-based `autoGenerate`). 1. **Integer (default)** — `column('id').int.primary.autoGenerate2`. Use this for every new table. Use a different option only when one of its conditions is true. Integer keys are small and make joins fast. `autoGenerate2` uses Postgres `IDENTITY`. Do not use `autoGenerate`. It uses `serial`, which is deprecated.
2. **UUID** — `column('id').uuid.primary`. Use when IDs are generated client-side, exposed in URLs, or need to be unguessable. Generate UUIDs in application code via `randomUUID()` from `node:crypto`; do **not** chain `.autoGenerate2` on `.uuid` (the DSL throws — `DEFAULT uuid_generate_v4()` fails on managed Postgres like Supabase because it needs the `uuid-ossp` extension in `public`). Use `.uuid` instead of `.varchar(36)`. 2. **UUID** — `column('id').uuid.primary`. Use this only when one of these conditions is true:
3. **String** — `column('id').varchar(36).primary` for IDs whose format isn't a UUID (e.g. nanoid-style IDs). Convention: nanoid length 16 for entity IDs. - The application must know the ID before the insert. For example, the client makes the ID.
- The ID is in a URL or a public API. Users must not see how many rows exist or guess other IDs.
**You must use UUIDv7.** Make the ID in application code with the `uuid` package: `import { v7 as uuidv7 } from 'uuid'`.
Why: a UUIDv7 starts with a timestamp. Thus, new rows go near the end of the index. A UUIDv4 is random, for example `randomUUID()` from `node:crypto`. New rows go to random positions in the index. This splits index pages and makes the index larger.
A UUIDv7 does not give an exact creation order. Two IDs made in the same millisecond can sort in the wrong order. Clock differences between hosts can also cause this. If you need the exact order, sort by a timestamp column.
Do **not** chain `.autoGenerate2` on `.uuid`. The DSL throws an error. The database default makes a UUIDv4. Also, `uuid_generate_v4()` needs the `uuid-ossp` extension. Some managed Postgres services, such as Supabase, do not have it. Use `.uuid`, not `.varchar(36)`.
3. **String** — `column('id').varchar(36).primary`. Use this only when one of these conditions is true:
- The entity already uses IDs in a format that is not a UUID. For example, the public API or the UI already shows nanoid IDs for this entity.
- The UI shows the ID to users. A UUID is too long to read, copy, or type.
Entity IDs are usually nanoids with 16 characters.
**Give a reason for every key that is not an integer.** Write the reason in the PR description. Reviewers will ask for it. These reasons are not sufficient:
- "Other tables use string IDs."
- "This module already does it this way."
- "We might need it later."
**These options apply to a generated `id` column only.** A join table that only links other tables does not need an `id` column. Use its foreign-key columns as a composite key (see below). A foreign-key column always has the same type as the key that it refers to.
**Keep ID-column types consistent across related tables.** Mixing `uuid` and `varchar(36)` for what is "the same kind of ID" creates JOIN footguns. **Keep ID-column types consistent across related tables.** Mixing `uuid` and `varchar(36)` for what is "the same kind of ID" creates JOIN footguns.
@ -696,7 +718,7 @@ If only Postgres needs the change, just put the file in `postgresdb/`; don't wri
### Postgres-version-aware UUID generation ### Postgres-version-aware UUID generation
`gen_random_uuid()` requires Postgres ≥ 13. n8n dropped Postgres 12 — prefer it over `uuid_generate_v4()` (which needs the `uuid-ossp` extension and breaks on managed services like Supabase). For UUID PKs, generate at the application level with `randomUUID()` — see [Primary Keys](#primary-keys). `gen_random_uuid()` requires Postgres ≥ 13. n8n dropped Postgres 12 — prefer it over `uuid_generate_v4()` (which needs the `uuid-ossp` extension and breaks on managed services like Supabase). For UUID PKs, make a UUIDv7 in application code — see [Primary Keys](#primary-keys).
### SQLite doesn't enforce `varchar(N)` length ### SQLite doesn't enforce `varchar(N)` length

View File

@ -0,0 +1,158 @@
---
name: n8n:env-var-docs
description: >-
Writes and reviews the JSDoc on `@Env(...)` config properties. The docs team
extracts these comments from source into the public environment variable
reference, so they are user documentation, not code comments. Use when adding
or changing an `@Env` property, a config class, or reviewing a PR that touches
one.
---
# Environment variable docs
The JSDoc above every `@Env('...')` property is exported almost verbatim into
the [environment variables reference](https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables)
on docs.n8n.io. The generated table has four columns: variable name,
description, data type, default. Your JSDoc is the description column. The
reader is a self-hosting operator, not an n8n developer.
Follow the [n8n docs style guide](https://docs.n8n.io/contribute/contribution-guide-for-n8n-docs/style-guide-for-n8n-docs)
for these comments. It overrides the ASD-STE100 rule in `AGENTS.md` for this
one case. The rules below are the parts of that guide that matter for a
one-paragraph description.
## Rules
- **Every `@Env` property has a JSDoc.** No exceptions. A missing comment
ships as an empty description cell.
- **Write for the operator.** Say what the setting does, when to change it,
and what happens when it's unset or wrong. Don't explain why the code is
written the way it is.
- **No code references.** No file names, class names, function names,
constants, license keys, or other internals the reader can't open. Values
the operator types into the variable are fine and often needed, for example
a credential type ID like `googleOAuth2Api` or a mode like `postgresdb`.
The test: would the operator paste this into a config file, or would they
need the source to know what it means? Details for developers go in a
regular `//` comment on the implementation, not in the JSDoc.
- **No attack scenarios.** Say what the setting protects, not how an
attacker would exploit it. This is a public page.
- **Don't repeat the default.** The default renders in its own column. Don't
write "Defaults to true" or "Default: 1 hour". Do say what the unset state
means when it's not obvious, for example "When unset, n8n uses the Redis
host".
- **State units and formats.** Say "in milliseconds", "in bytes", "a
comma-separated list", "a JSON object". The data type column only says
`Number` or `String`.
- **Use allowed values when the set is small.** "One of `sqlite`,
`postgresdb`." For a list, show one inline example in the sentence.
- **No JSDoc tags.** No `@example`, `@default`, `@see`, `@deprecated`. The
exporter copies the tag name into the docs. Put the example or the
deprecation notice in a sentence instead.
- **Product names:** "Gateway credits", not "n8n Connect" or "AI Gateway".
"Publish a workflow", not "activate". `n8n` is always lowercase.
- **Style:** present tense, active voice, second person. Use contractions.
No em dashes, use a comma or a new sentence. No "e.g." or "i.e.", write
"for example" and "that is". Spell out zero to nine, numerals from 10.
Values the operator types stay numerals, for example "Set to 0".
Sentence case. One idea per sentence. End every sentence with a period.
- **Plain words:** "use" not "utilize", "lets you" not "allows you to", cut
"powerful", "seamless", "simply", "it's important to note".
- **Length:** one to three sentences. If the setting needs more, the extra
belongs in a docs page the comment can't link to yet; keep the comment to
what fits a table cell.
## Examples
Bad, as found in the generated docs:
```ts
/**
* Instance-level enablement for n8n Connect (AI Gateway). Licensed instances
* are enabled by default; false opts out. Budget / free allowance still comes
* from the license (`quota:aiGatewayBudget`).
*/
```
Wrong product name, a restated default, and an internal license key. Good:
```ts
/**
* Whether Gateway credits are available on this instance. Set to false to
* turn them off on a licensed instance. The credit allowance comes from your
* license.
*/
```
Bad:
```ts
/**
* Time to live in milliseconds for Redis cache entries. Set to 0 to disable
* expiry. Default: 1 hour.
*/
```
The default is already in the table. Good:
```ts
/**
* Time to live in milliseconds for Redis cache entries. Set to 0 to keep
* entries until Redis evicts them.
*/
```
Bad:
```ts
/**
* Comma-separated list of credential types for which overwrites are skipped
* when the credential has been customized.
* @example `N8N_SKIP_CREDENTIAL_OVERWRITE=zohoOAuth2Api,salesforceOAuth2Api`
*/
```
The `@example` tag lands in the description as literal text. Good:
```ts
/**
* Comma-separated list of credential types to skip when applying credential
* overwrites, for example `zohoOAuth2Api,salesforceOAuth2Api`. n8n skips an
* overwrite only when a user has already changed one of its fields.
*/
```
Bad:
```ts
/**
* Bind OAuth credential callbacks to the browser that initiated the flow.
* When enabled, a session-scoped `n8n-oauth-binding` cookie is set on flow
* initiation and verified on callback. Defeats phishing attacks where an
* attacker injects an OAuth authorize URL into a victim's browser to land
* tokens on the attacker's credential.
*/
```
Attack narrative and an internal cookie name on a public page. Good:
```ts
/**
* Whether an OAuth credential connection must finish in the same browser
* that started it. When enabled, n8n rejects the callback if it arrives
* from a different browser.
*/
```
## Review checklist
When you review a PR that adds or changes an `@Env` property, check each
comment against this list and quote the fix in the review:
1. JSDoc present.
2. No code identifiers, file names, or internal keys.
3. No default restated.
4. Units, format, or allowed values stated.
5. No JSDoc tags.
6. No em dashes, Latin abbreviations, or filler words.
7. Reads correctly as a sentence in a table cell with no surrounding context.

View File

@ -21,8 +21,7 @@ check the code, not license to drop a team default.
## Non-negotiable rules ## Non-negotiable rules
- New endpoints are `@PublicApiController` classes under `v1/controllers/`, one - New endpoints are `@PublicApiController` classes under `v1/controllers/`, one
`*.public.controller.ts` per feature. A controller is a class — never `*.public.controller.ts` per feature.
`export =` (the legacy tuple style; `require-public-api-controller` flags it).
- Public API and internal REST are separate HTTP surfaces. A public controller - Public API and internal REST are separate HTTP surfaces. A public controller
never calls an internal controller/endpoint; both reuse the same service. never calls an internal controller/endpoint; both reuse the same service.
- Controllers and handlers delegate to a service — never import a repository or - Controllers and handlers delegate to a service — never import a repository or
@ -31,7 +30,6 @@ check the code, not license to drop a team default.
`@ApiResponse(Dto)`. `@ApiResponse(Dto)`.
- Register each controller via a side-effect import in `v1/controllers/index.ts` - Register each controller via a side-effect import in `v1/controllers/index.ts`
(`public-api-controllers.test.ts` fails otherwise). (`public-api-controllers.test.ts` fails otherwise).
- Don't add business logic to legacy `express-openapi-validator` (EOV) handlers.
- Migrating a legacy endpoint must not change its public contract. - Migrating a legacy endpoint must not change its public contract.
These are `n8n-local-rules` ESLint rules (see `packages/cli/eslint.config.mjs`) These are `n8n-local-rules` ESLint rules (see `packages/cli/eslint.config.mjs`)
@ -109,10 +107,10 @@ model; reuse only what applies. Decorators, all from `@n8n/decorators`:
| `@Get/@Post/@Put/@Patch/@Delete('/path')` | Route method. | | `@Get/@Post/@Put/@Patch/@Delete('/path')` | Route method. |
| `@ApiKeyScope('res:action')` | API-key grant check. | | `@ApiKeyScope('res:action')` | API-key grant check. |
| `@ProjectScope/@GlobalScope('res:action')` | User RBAC check. | | `@ProjectScope/@GlobalScope('res:action')` | User RBAC check. |
| `@ApiResponse(status)` / `@ApiResponse(status, Dto)` | Success status + (optional) output DTO; registry `.parse()`s + strips the return value. Exactly one per route — a second `@ApiResponse` throws. `204` can't carry a DTO — throws. | | `@ApiResponse(status)` / `@ApiResponse(status, Dto)` | Success status + (optional) output DTO; registry `.parse()`s + strips the return value. Exactly one per route — a second `@ApiResponse` throws. `204` can't carry a DTO or a binary body — throws. For a binary response body (returned as `{ body, headers? }`), use `@ApiResponse(status, { mediaType, description?, headers? })` — see [Binary response bodies](reference.md#binary-response-bodies). |
| `@ApiErrorResponse(status)` | Declares an additional documented non-2xx status (e.g. `404`, `409`). Stack multiple for more than one. `400`/`401`/`403` are added automatically (body/query present, always, and `@ApiKeyScope` present, respectively) — don't declare those yourself. | | `@ApiErrorResponse(status)` | Declares an additional documented non-2xx status (e.g. `404`, `409`). Stack multiple for more than one. `400`/`401`/`403` are added automatically (body/query present, always, and `@ApiKeyScope` present, respectively) — don't declare those yourself. |
| `@ApiSummary(text)` / `@ApiDescription(text)` / `@ApiTags([...])` | OpenAPI summary/description/tags. `@ApiTags` sorts alphabetically regardless of the order you pass. All optional but expected on every real route. | | `@ApiSummary(text)` / `@ApiDescription(text)` / `@ApiTags([...])` | OpenAPI summary/description/tags. `@ApiTags` sorts alphabetically regardless of the order you pass. All optional but expected on every real route. |
| `@Query` / `@Body` / `@Param('name')` | Bind + validate via a `Z.class` DTO / path param. | | `@Query` / `@Body` / `@Param('name')` | Bind + validate via a `Z.class` DTO / path param. `@Body` is JSON by default; `@Body({ mediaType: 'multipart/form-data', uploadLimits })` takes a `multipart/form-data` body instead — see [Request body media types](reference.md#request-body-media-types). |
| `@Licensed('feat')` | Gates the route on a single `BooleanLicenseFeature`; `PublicApiControllerRegistry` runs its own license middleware (after auth/`@ApiKeyScope`/`@ProjectScope`|`@GlobalScope`, before the handler) and 403s unlicensed requests. Only takes one feature — if the gate is an any-of/all-of combination (e.g. `LicenseState.isProvisioningLicensed()`, which is `feat:saml` OR `feat:oidc`), `@Licensed` can't express that; check manually in the handler instead, same as the internal `provisioning.controller.ee.ts`/`role-mapping-rule.controller.ee.ts` do today (throwing `ForbiddenError` on failure). | | `@Licensed('feat')` | Gates the route on a single `BooleanLicenseFeature`; `PublicApiControllerRegistry` runs its own license middleware (after auth/`@ApiKeyScope`/`@ProjectScope`|`@GlobalScope`, before the handler) and 403s unlicensed requests. Only takes one feature — if the gate is an any-of/all-of combination (e.g. `LicenseState.isProvisioningLicensed()`, which is `feat:saml` OR `feat:oidc`), `@Licensed` can't express that; check manually in the handler instead, same as the internal `provisioning.controller.ee.ts`/`role-mapping-rule.controller.ee.ts` do today (throwing `ForbiddenError` on failure). |
## Authorization (easy to get wrong) ## Authorization (easy to get wrong)
@ -200,6 +198,5 @@ existing tests.
- [Test-before-save endpoints](reference.md#test-before-save-endpoints) - [Test-before-save endpoints](reference.md#test-before-save-endpoints)
- [Errors](reference.md#errors) - [Errors](reference.md#errors)
- [Testing matrix](reference.md#testing-matrix) - [Testing matrix](reference.md#testing-matrix)
- [Migrating legacy EOV endpoints](reference.md#migrating-legacy-eov-endpoints)
- [Verifying a migration](reference.md#verifying-a-migration) - [Verifying a migration](reference.md#verifying-a-migration)
- [CI and merging](reference.md#ci-and-merging) - [CI and merging](reference.md#ci-and-merging)

View File

@ -103,55 +103,76 @@ scope, RBAC denial. Add whichever apply, matching the nearest existing tests:
unchanged. Tests alone cannot show this — see unchanged. Tests alone cannot show this — see
[Verifying a migration](#verifying-a-migration). [Verifying a migration](#verifying-a-migration).
## Migrating legacy EOV endpoints ## Request body media types
Legacy `express-openapi-validator` endpoints live under `@Body` defaults to `application/json`; the body is already parsed by the
`v1/handlers/`, wired through `openapi.yml` with `x-eov-operation-*` and request app-wide `bodyParser` before the registry sees it. Declaring
types in `packages/cli/src/public-api/types.ts`. Treat these as migration targets, `@Body({ mediaType: 'multipart/form-data', uploadLimits })` instead takes a
not templates. `multipart/form-data` body:
- Prefer migrating to `@PublicApiController` over extending the handler. - `uploadLimits: () => MultipartUploadLimits` is a thunk, read once the route
- Preserve the public contract: path, method, scopes, status codes, response handles its first request (not at startup) — read live config inside it
shape, and pagination. (e.g. `Container.get(GlobalConfig)`), don't inline a literal.
- Move HTTP concerns into the controller and business orchestration into the - The route's `@Body` DTO validates text fields merged with uploaded files,
shared service; keep the controller a thin HTTP boundary. If the legacy not `req.body` alone. A text field and a file share the same flat object;
handler was itself already just a thin wrapper around an internal a file field uses `publicApiUploadedFileSchema` (`@n8n/api-types`) — a
`@RestController` (calling its methods directly, e.g. multer-file-shaped schema that documents itself as `{ type: 'string',
`Container.get(SomeController).createThing(req, res, payload)`), the new format: 'binary' }`. Several files under the same field name become an
public controller can call that same internal controller directly — no need array.
to duplicate its validation/business logic. - An unknown field (one the DTO doesn't declare, on a `{ strict: true }` DTO)
- A route must be served by either the EOV handler or a controller, not both — fails with `Unexpected form field "<name>"` — not the default "unrecognized
the build's `mergeDecoratorDocument` (`v1/openapi-gen/generate.ts`) throws on keys" wording.
a path+method declared by both sides. Remove the legacy wiring (its path's - Multer parsing errors map to these statuses: `413` for a size or count limit,
`$ref` entry in `openapi.yml`, the `x-eov-operation-*` handler, and its `500` for `LIMIT_UNEXPECTED_FILE`, `400` for any other multer error, and `500`
`handler.ts`) only after the new controller is registered, `pnpm build` for anything else (a malformed body). The `500` is not masked, because it is a
regenerates the spec cleanly, and tests are updated. `ResponseError`. A missing boundary gives `400` with `multipart file(s) required`.
- Fully delete the migrated legacy files: the handler's `.ts`, its - The body is parsed **after** every auth/scope/license/quota gate and
`spec/paths/*.yml` and `spec/schemas/*.yml`, and any now-dead request type **before** controller/route middlewares — a caller those gates would reject
in `packages/cli/src/public-api/types.ts`. Then check never has their (possibly huge) body read off the socket, and a middleware
`v1/shared/spec/schemas/_index.yml` and `v1/shared/spec/parameters/_index.yml` that reads `req.body` sees it already parsed.
for entries that `$ref` one of the deleted schema/parameter files — those are - `/discover` shows no request schema for a multipart route (same as a legacy
separate from the path's own `$ref` in `openapi.yml` and are easy to miss; multipart route today) — a client can't assume a JSON schema it never gets.
left dangling, the next bundle fails on a broken `$ref`. - The generator documents the body under the `multipart/form-data` content
- If the legacy handler gated on a license (`isLicensed('feat:x')` middleware), key (not `application/json`) and adds `413` alongside `415` to the route's
`@Licensed('feat:x')` now replicates that for a controller route (see the documented responses automatically.
decorator table in [SKILL.md](SKILL.md#declaring-a-controller)) — but only for
a single feature. If the legacy check was an any-of/all-of over several flags Everything above lives in `packages/cli/src/public-api/media-types/`, one
(e.g. `LicenseState.isProvisioningLicensed()`), `@Licensed` can't express handler per media type (`REQUEST_BODY_HANDLERS` in
that; replicate it manually in the controller instead, don't drop it - this `media-types/request-body/index.ts`). Adding a further media type (e.g.
is exactly what the internal `provisioning.controller.ee.ts` and `application/octet-stream`) means: add it to `RequestBodyMediaOptions` in
`role-mapping-rule.controller.ee.ts` already do, since neither uses `@n8n/decorators`'s `controller/types.ts`, write a handler implementing
`@Licensed` for that reason. `RequestBodyHandler` in `media-types/request-body/`, and register it in
- As a legacy file drops repository access / the `export =` tuple, remove its `REQUEST_BODY_HANDLERS` — the registry, resolver, generator and `/discover`
entry from the `off` allowlists for `no-repository-in-public-api-handler` and need no change, since they all read the handler, not the media type.
`require-public-api-controller` in `packages/cli/eslint.config.mjs` (shrink-only
— never extend them). ## Binary response bodies
- For complex legacy-only, multipart, or non-standard endpoints, study the
nearest existing handler first. `@ApiResponse(status, { mediaType, description?, headers? })` declares a
- Keep each field in its original position when you extract a request shape shared success body that the controller method returns as `{ body, headers? }`, for
by two routes, and destructure out the ones a route doesn't take. The generator example an `application/gzip` stream. The framework treats options whose
emits properties in shape order, so a moved field rewrites the `*.generated.yml` `mediaType` is in `BINARY_RESPONSE_MEDIA_TYPES` as a binary response.
of a route the PR wasn't changing. `mediaType` accepts only those types.
- `body` is a `Buffer` or a `Readable`. The method returns the result and never
writes to `res`.
- `headers` holds the response headers. Every header declared in `headers` must
be in the result. A missing header fails the request with a `500`. Matching is
case-insensitive.
- The registry checks the headers, then sets the declared status, the headers,
and `Content-Type: <mediaType>`. A header in the result cannot replace the
`Content-Type`.
- A stream's first chunk is read before any header is set. So a stream that
fails before its first chunk gives the normal JSON error response, with no
binary `Content-Type`. A method that throws before it returns does the same.
- After the first chunk is sent, an error ends the response. A client that
disconnects is not an error, and the framework destroys the stream.
- A method that returns no binary body fails with a `500`.
- The generator documents the body as `{ type: string, format: binary }`
under the `mediaType` content key, with the description and headers.
The description defaults to `Operation successful.`.
The runtime part is `sendBinaryResponse` in
`packages/cli/src/public-api/media-types/binary-response.ts`.
## Verifying a migration ## Verifying a migration

View File

@ -32,7 +32,7 @@ Based on the affected area, pick the test layer and pattern:
| CLI / API | Vitest integration | setupTestServer + supertest | `packages/cli/test/integration/` | | CLI / API | Vitest integration | setupTestServer + supertest | `packages/cli/test/integration/` |
| Config | Vitest unit | GlobalConfig + Container | `packages/@n8n/config/src/configs/__tests__/` | | Config | Vitest unit | GlobalConfig + Container | `packages/@n8n/config/src/configs/__tests__/` |
| Editor UI | Vitest | Vue Test Utils + Pinia | `packages/frontend/editor-ui/src/**/__tests__/` | | Editor UI | Vitest | Vue Test Utils + Pinia | `packages/frontend/editor-ui/src/**/__tests__/` |
| E2E / Canvas | Playwright | Test containers + composables | `packages/testing/playwright/` | | E2E / Canvas | Playwright | Test containers + composables | `packages/quality/testing/playwright/` |
## Step 3: Locate Source Files ## Step 3: Locate Source Files

View File

@ -8,7 +8,7 @@ exclude:
# Machine-generated instance-AI expectation traces. Contain ephemeral # Machine-generated instance-AI expectation traces. Contain ephemeral
# credential reference IDs (nanoids) that re-trip the secrets scanner # credential reference IDs (nanoids) that re-trip the secrets scanner
# on every regeneration. No secret material. # on every regeneration. No secret material.
- packages/testing/playwright/expectations - packages/quality/testing/playwright/expectations
# Test code repo-wide. Fixtures routinely contain synthetic PEM blocks, # Test code repo-wide. Fixtures routinely contain synthetic PEM blocks,
# basic-auth strings, and deliberately fake keys (including the secret # basic-auth strings, and deliberately fake keys (including the secret

View File

@ -1,3 +1,3 @@
{ {
"issues": 141 "issues": 110
} }

View File

@ -0,0 +1 @@
../../../../.agents/skills/env-var-docs

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
Run long-lived, human-steered agent sessions (Claude Code / OpenCode) on a Run long-lived, human-steered agent sessions (Claude Code / OpenCode) on a
GitHub Codespace instead of your laptop: start a task, close the lid, steer it GitHub Codespace instead of your laptop: start a task, close the lid, steer it
from anywhere with a terminal, resume tomorrow. from anywhere, resume tomorrow.
This is a separate devcontainer config from the laptop one in This is a separate devcontainer config from the laptop one in
`.devcontainer/` — it ships both agent CLIs, `tmux` for session persistence, `.devcontainer/` — it ships both agent CLIs, `tmux` for session persistence,
@ -11,17 +11,61 @@ Playwright system deps, and Docker-in-Docker (for testcontainers and
## One-time setup (~5 min) ## One-time setup (~5 min)
1. Add provider keys at [github.com/settings/codespaces](https://github.com/settings/codespaces). 1. Give the GitHub CLI the codespace scope:
Add `ANTHROPIC_API_KEY` for Claude Code. Add `OPENROUTER_API_KEY` for OpenCode.
Give both secrets access to `n8n-io/n8n`.
(Alternative for Max subscriptions: `CLAUDE_CODE_OAUTH_TOKEN` from `claude setup-token`.)
2. Give the GitHub CLI the codespace scope:
```bash ```bash
gh auth refresh -h github.com -s codespace gh auth refresh -h github.com -s codespace
``` ```
## Daily flow 2. Add provider keys at [github.com/settings/codespaces](https://github.com/settings/codespaces)
if your client needs them. Give each secret access to `n8n-io/n8n`.
- `ANTHROPIC_API_KEY` for Claude Code in the terminal (`pnpm session`).
Alternative for Max subscriptions: `CLAUDE_CODE_OAUTH_TOKEN` from
`claude setup-token`. The desktop app does not need either secret.
- `OPENROUTER_API_KEY` for OpenCode.
## Choose a client
All clients run the agent, its tools, and builds in the Codespace. Your laptop
shows the conversation only.
| Client | Command | Use it when |
|---|---|---|
| Claude Code desktop app | `pnpm session ssh-config` once | You want the full desktop experience. |
| Claude Code in VS Code | Open the codespace in VS Code or the browser | You already work in VS Code. |
| Claude Code in a terminal | `pnpm session` | You want a plain terminal, or you are on a remote machine. |
| OpenCode | `pnpm session:opencode` | You use OpenCode. See [Local OpenCode clients](#local-opencode-clients). |
### Claude Code desktop app
1. From a local checkout, add an SSH host for your codespace:
```bash
pnpm session ssh-config
```
The command creates or starts the codespace. It writes the host
`n8n-codespace` to `~/.ssh/n8n-codespace.conf` and includes that file from
`~/.ssh/config`.
2. In the desktop app, add an SSH connection to the host `n8n-codespace`.
3. Open the folder `/workspaces/n8n`, or a worktree under `/workspaces`.
The desktop app installs its own Claude Code on the codespace and signs in
with your desktop account. Sessions continue when you close the app. They stop
when the codespace stops.
- **Run `pnpm session ssh-config` again after you recreate the codespace.**
- **If the connection times out**, the codespace is probably starting. Run
`pnpm session ssh-config`, then connect again.
- **Test the connection** with `ssh n8n-codespace`.
### Claude Code in VS Code
The dev container installs the Claude Code extension. Open the codespace in
VS Code or the browser, then open the Claude Code panel. Sign in from the
extension if you did not add `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN`.
### Claude Code in a terminal
```bash ```bash
pnpm session # attach Claude Code (creates everything on first run) pnpm session # attach Claude Code (creates everything on first run)
@ -33,6 +77,7 @@ pnpm session:opencode --legacy # use the remote TUI in tmux
pnpm session fix-flaky # Claude Code in a separate worktree pnpm session fix-flaky # Claude Code in a separate worktree
pnpm session ls # what's running pnpm session ls # what's running
pnpm session tunnel # forward n8n ports (default 5678, 8080); Ctrl-C to stop pnpm session tunnel # forward n8n ports (default 5678, 8080); Ctrl-C to stop
pnpm session ssh-config # add the n8n-codespace SSH host for the desktop app
pnpm session stop # end of day: billing stops, disk survives pnpm session stop # end of day: billing stops, disk survives
pnpm session rm # delete the codespace pnpm session rm # delete the codespace
``` ```
@ -332,11 +377,15 @@ session rarely needs a cold `pnpm install` or a full `pnpm build`. Both are slow
Claude sessions and the headless OpenCode worker get the `flaky` MCP server automatically: Currents Claude sessions and the headless OpenCode worker get the `flaky` MCP server automatically: Currents
flaky/quarantine data, the `qa_*` BigQuery dataset, Sentry RCA, live Linear, flaky/quarantine data, the `qa_*` BigQuery dataset, Sentry RCA, live Linear,
and repo investigation. The worker keeps the token in its environment and puts and repo investigation. The worker keeps the token in its environment and puts
only an environment reference in the OpenCode config. Claude login registers only an environment reference in the OpenCode config. Forks have no secrets and
the same server without writing the token to disk. Forks have no secrets and
skip it. Tell the agent to call `get_flaky_context` first — it returns the rules skip it. Tell the agent to call `get_flaky_context` first — it returns the rules
the tools assume. the tools assume.
`post-start.mjs` registers the server for Claude Code on each container start.
Its `headersHelper` reads the token from the secrets file on each connect, so
the server works in every client. The token is not copied into the Claude Code
MCP configuration.
## Quality and security skills (Claude plugins) ## Quality and security skills (Claude plugins)
Claude sessions can also load the private skills from the Claude sessions can also load the private skills from the
@ -398,7 +447,8 @@ to pull the skills into context.
## Viewing the dev UI locally ## Viewing the dev UI locally
Two terminal windows: `pnpm session tunnel` works with every client. With the terminal client, use
two terminal windows:
```bash ```bash
pnpm session # window 1: attach the agent session pnpm session # window 1: attach the agent session
@ -448,10 +498,10 @@ After a stop, `pnpm session <name>` restarts the codespace (~30–60 s); run
agent injects them into VS Code sessions only; they're delivered agent injects them into VS Code sessions only; they're delivered
base64-encoded to `/workspaces/.codespaces/shared/.env-secrets`. The image base64-encoded to `/workspaces/.codespaces/shared/.env-secrets`. The image
sources `/usr/local/lib/codespaces-env.sh` in login shells (profile.d), in sources `/usr/local/lib/codespaces-env.sh` in login shells (profile.d), in
interactive shells (bashrc), and in the `pnpm session` prelude. If Claude interactive shells (bashrc), and in the `pnpm session` prelude. Desktop app
Code shows `Missing environment variables: FLAKY_MCP_TOKEN`, the shell that sessions do not source it. `git`, `gh`, `scripts/codespace-env.mjs`, and the
started Claude did not source the file. Run `flaky` MCP entry read the file when they run, so they work everywhere. New
`. /usr/local/lib/codespaces-env.sh` and start Claude again. code that needs a secret must do the same.
- **Do not read `CODESPACE_NAME` or `GITHUB_USER` from the process env** — use - **Do not read `CODESPACE_NAME` or `GITHUB_USER` from the process env** — use
`scripts/codespace-env.mjs`. Codespaces gives these variables to VS Code `scripts/codespace-env.mjs`. Codespaces gives these variables to VS Code
sessions only. Other processes read them from `codespaces-env.sh`, and a sessions only. Other processes read them from `codespaces-env.sh`, and a
@ -460,7 +510,7 @@ After a stop, `pnpm session <name>` restarts the codespace (~30–60 s); run
polled correctly as its owner while `dev:up` in the same session saw an empty polled correctly as its owner while `dev:up` in the same session saw an empty
box name, printed the localhost URL, and did not share the port. The helper box name, printed the localhost URL, and did not share the port. The helper
reads `/workspaces/.codespaces/shared`, which is always correct. reads `/workspaces/.codespaces/shared`, which is always correct.
- **You cannot paste images into a remote Claude session.** Image paste reads - **You cannot paste images into a terminal Claude session.** Image paste reads
the clipboard of the machine where `claude` runs — the codespace, not your the clipboard of the machine where `claude` runs — the codespace, not your
laptop. Drag the file into the VS Code explorer (or laptop. Drag the file into the VS Code explorer (or
`gh codespace cp shot.png remote:/workspaces/n8n/`) and give Claude the `gh codespace cp shot.png remote:/workspaces/n8n/`) and give Claude the

View File

@ -12,14 +12,6 @@
'{"hasCompletedOnboarding":true,"theme":"dark","projects":{"/workspaces/n8n":{"hasTrustDialogAccepted":true}}}' \ '{"hasCompletedOnboarding":true,"theme":"dark","projects":{"/workspaces/n8n":{"hasTrustDialogAccepted":true}}}' \
>"$HOME/.claude.json" >"$HOME/.claude.json"
# Register the Flaky MCP server for Claude Code. The config keeps a literal
# ${FLAKY_MCP_TOKEN}; Claude Code expands it at connect time, so the token is
# not written to disk. Forks have no repo secrets and skip this.
if [ -n "$FLAKY_MCP_URL" ] && ! grep -qs '"flaky"' "$HOME/.claude.json" && command -v claude >/dev/null 2>&1; then
claude mcp add --scope user --transport http flaky "$FLAKY_MCP_URL" \
--header 'Authorization: Bearer ${FLAKY_MCP_TOKEN}' >/dev/null 2>&1 || true
fi
# Register the credential helper in the user config, because Codespaces # Register the credential helper in the user config, because Codespaces
# regenerates the managed /etc/gitconfig. When the env token is missing, the # regenerates the managed /etc/gitconfig. When the env token is missing, the
# system helper exits 0 without output, and git falls through to ours. # system helper exits 0 without output, and git falls through to ours.

View File

@ -18,9 +18,13 @@
"ghcr.io/devcontainers/features/docker-in-docker:2": {} "ghcr.io/devcontainers/features/docker-in-docker:2": {}
}, },
"forwardPorts": [8080, 5678], "forwardPorts": [8080, 5678],
// Grant the Codespace token read access to the private skills and harness repositories.
// Each user authorizes this access once when they create the Codespace.
"customizations": { "customizations": {
// Claude Code in VS Code or the browser editor. It runs in the codespace.
"vscode": {
"extensions": ["anthropic.claude-code"]
},
// Grant the Codespace token read access to the private skills and harness repositories.
// Each user authorizes this access once when they create the Codespace.
"codespaces": { "codespaces": {
"repositories": { "repositories": {
"n8n-io/n8n-agent-skills": { "permissions": { "contents": "read" } }, "n8n-io/n8n-agent-skills": { "permissions": { "contents": "read" } },

View File

@ -1,10 +1,11 @@
#!/usr/bin/env node #!/usr/bin/env node
// Runs on each Codespace start. Installs the skills and harness, then starts the worker. // Runs on each Codespace start. Installs the skills and harness, then starts the worker.
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { rmSync, writeFileSync } from 'node:fs'; import { readFileSync, rmSync, writeFileSync } from 'node:fs';
import { homedir } from 'node:os'; import { homedir } from 'node:os';
import { join } from 'node:path'; import { join } from 'node:path';
import { installAgentHarness } from '../../scripts/agent-harness.mjs'; import { installAgentHarness } from '../../scripts/agent-harness.mjs';
import { codespaceSecret } from '../../scripts/codespace-env.mjs';
import { MARKETPLACE, PLUGINS } from './plugins.mjs'; import { MARKETPLACE, PLUGINS } from './plugins.mjs';
const STATUS_FILE = '/tmp/post-start-status.json'; const STATUS_FILE = '/tmp/post-start-status.json';
@ -49,6 +50,42 @@ function addMarketplace() {
return add('marketplace add (retry)'); return add('marketplace add (retry)');
} }
// Claude Code reads the Flaky token when it connects. An env reference such as
// ${FLAKY_MCP_TOKEN} fails in processes that did not load the secrets file, for
// example the desktop app's SSH server. The helper reads the file on each connect,
// so it also gets a rotated token. The token is not copied into ~/.claude.json.
const FLAKY_HEADERS_HELPER =
'. /usr/local/lib/codespaces-env.sh; printf %s "{\\"Authorization\\":\\"Bearer $FLAKY_MCP_TOKEN\\"}"';
function registerFlakyMcp() {
// Forks have no repository secrets.
const url = codespaceSecret('FLAKY_MCP_URL');
if (!url || !codespaceSecret('FLAKY_MCP_TOKEN')) return;
let current;
try {
current = JSON.parse(readFileSync(join(homedir(), '.claude.json'), 'utf8')).mcpServers?.flaky;
} catch {
// No readable config yet: register the server below.
}
if (current?.url === url && current.headersHelper === FLAKY_HEADERS_HELPER && !current.headers) {
return;
}
if (current) tryRun('flaky mcp remove', 'claude', ['mcp', 'remove', '--scope', 'user', 'flaky']);
const config = { type: 'http', url, headersHelper: FLAKY_HEADERS_HELPER };
tryRun('flaky mcp add', 'claude', [
'mcp',
'add-json',
'--scope',
'user',
'flaky',
JSON.stringify(config),
]);
}
registerFlakyMcp();
tryRun('skills repo reachable', 'git', ['ls-remote', `https://github.com/${MARKETPLACE}`, 'HEAD']); tryRun('skills repo reachable', 'git', ['ls-remote', `https://github.com/${MARKETPLACE}`, 'HEAD']);
const installed = []; const installed = [];

View File

@ -0,0 +1,32 @@
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { aliasHostConfig, withInclude } from '../../scripts/cloud-session-ssh-config.mjs';
const GH_CONFIG = `Host cs.ominous-doodle.master
User node
ProxyCommand gh cs ssh -c ominous-doodle --stdio
UserKnownHostsFile=/dev/null
`;
test('replaces the gh host name with the fixed alias', () => {
assert.equal(
aliasHostConfig(GH_CONFIG),
GH_CONFIG.replace('cs.ominous-doodle.master', 'n8n-codespace'),
);
});
test('rejects gh output without exactly one proxied host', () => {
assert.throws(() => aliasHostConfig(''));
assert.throws(() => aliasHostConfig(`${GH_CONFIG}Host other\n`));
assert.throws(() => aliasHostConfig('Host cs.x\n\tUser node\n'));
});
test('adds the Include line at the top once', () => {
const include = 'Include ~/.ssh/n8n-codespace.conf';
assert.equal(withInclude(''), `${include}\n`);
const updated = withInclude('Host github.com\n\tUser git\n');
assert.equal(updated, `${include}\n\nHost github.com\n\tUser git\n`);
assert.equal(withInclude(updated), undefined);
});

View File

@ -26,7 +26,7 @@
!docker/images/runners !docker/images/runners
!docker/images/runners/n8n-task-runners.json !docker/images/runners/n8n-task-runners.json
# === benchmark image (packages/@n8n/benchmark/Dockerfile) === # === benchmark image (packages/quality/efficiency/scale/benchmark/Dockerfile) ===
!package.json !package.json
!pnpm-lock.yaml !pnpm-lock.yaml
!pnpm-workspace.yaml !pnpm-workspace.yaml
@ -34,8 +34,10 @@
!patches/** !patches/**
!scripts !scripts
!scripts/** !scripts/**
!packages/@n8n/benchmark !packages/quality
!packages/@n8n/benchmark/** !packages/quality/efficiency
!packages/quality/efficiency/scale
!packages/quality/efficiency/scale/benchmark
!packages/quality/efficiency/scale/benchmark/**
!packages/@n8n/typescript-config !packages/@n8n/typescript-config
!packages/@n8n/typescript-config/** !packages/@n8n/typescript-config/**

36
.githooks/check-pnpm.mjs Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env node
// Git hook helper (post-merge, post-rewrite, post-checkout): warn when the
// installed pnpm major differs from the one pinned in package.json.
// Usage: node .githooks/check-pnpm.mjs [checkout-type]
// For post-checkout, pass lefthook's {3}: "0" is a file checkout, which we skip.
import { spawnSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { homedir } from 'node:os';
import { fileURLToPath } from 'node:url';
if (process.argv[2] === '0') process.exit(0);
const packageJsonPath = fileURLToPath(new URL('../package.json', import.meta.url));
const { packageManager = '' } = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
const wanted = /^pnpm@(\d+)/.exec(packageManager)?.[1];
if (!wanted) process.exit(0);
// Run from the home dir so pnpm reports the installed version,
// not the version pinned by this repo.
// `shell` lets Windows resolve pnpm.cmd. The command has no user input.
const result = spawnSync('pnpm --version', { cwd: homedir(), shell: true, encoding: 'utf8' });
const current = result.status === 0 ? result.stdout.trim().split('.')[0] : '';
if (wanted === current) process.exit(0);
const installCommand =
process.platform === 'win32'
? 'powershell -c "irm https://get.pnpm.io/install.ps1 | iex"'
: 'curl -fsSL https://get.pnpm.io/install.sh | sh -';
console.log(`
⚠ This repo now pins pnpm ${wanted} (you have ${current || 'none'}).
pnpm should auto-download it on the next install command.
If that fails (some pnpm 10 versions can't install v12), reinstall:
${installCommand}
`);

View File

@ -1,13 +0,0 @@
#!/bin/sh
# .githooks/check-pnpm — symlink or call from post-merge, post-rewrite, post-checkout
WANTED=$(sed -n 's/.*"packageManager": *"pnpm@\([0-9]*\).*/\1/p' package.json)
CURRENT=$(cd ~ && pnpm --version 2>/dev/null | cut -d. -f1)
[ -z "$WANTED" ] || [ "$WANTED" = "$CURRENT" ] && exit 0
echo ""
echo "⚠ This repo now pins pnpm $WANTED (you have ${CURRENT:-none})."
echo " pnpm should auto-download it on the next install command."
echo " If that fails (some pnpm 10 versions can't install v12), reinstall:"
echo " curl -fsSL https://get.pnpm.io/install.sh | sh -"
echo ""
exit 0

View File

@ -81,11 +81,12 @@ return 'blacksmith';
| Telemetry | Source | Metrics | | Telemetry | Source | Metrics |
|-----------|--------|---------| |-----------|--------|---------|
| Playwright perf/benchmark | `packages/testing/playwright/reporters/metrics-reporter.ts` | Any metric attached via `attachMetric()` | | Playwright perf/benchmark | `packages/quality/testing/playwright/reporters/metrics-reporter.ts` | Any metric attached via `attachMetric()` |
| Accessibility buckets | `packages/testing/playwright/reporters/a11y-reporter.ts` | Per-bucket axe score, violated rules, violating elements | | Accessibility buckets | `packages/quality/testing/playwright/reporters/a11y-reporter.ts` | Per-bucket axe score, violated rules, violating elements |
| Build stats | `.github/scripts/send-build-stats.mjs` | Per-package build duration, cache hit/miss, run total | | Build stats | `.github/scripts/send-build-stats.mjs` | Per-package build duration, cache hit/miss, run total |
| Docker stats | `.github/scripts/send-docker-stats.mjs` | Image size per platform, docker build duration | | Docker stats | `.github/scripts/send-docker-stats.mjs` | Image size per platform, docker build duration |
| Container stack | `packages/testing/containers/telemetry.ts` | E2E stack startup times per service | | Dive image efficiency | `packages/quality/efficiency/images/image-efficiency.spec.ts` | Layer content size, estimated waste, efficiency score, and layer count through the shared Playwright reporter |
| Container stack | `packages/quality/environments/containers/telemetry.ts` | E2E stack startup times per service |
## Secrets ## Secrets

11
.github/CODEOWNERS vendored
View File

@ -1,11 +0,0 @@
# Temporary: kept side by side with the top-level OWNERS file while the
# "Required Reviews" enforcement is on trial. Do not add entries here;
# add them to OWNERS. See "Transition from CODEOWNERS" in WORKFLOWS.md.
packages/@n8n/db/src/migrations/ @n8n-io/migrations-review
/OWNERS @n8n-io/qa-dx
.github/workflows @n8n-io/qa-dx
.github/scripts @n8n-io/qa-dx
.github/actions @n8n-io/qa-dx
.github/poutine-rules @n8n-io/qa-dx
docker/get-n8n.sh @n8n-io/qa-dx
.code-health-baseline.json @n8n-io/qa-dx

110
.github/WORKFLOWS.md vendored
View File

@ -10,7 +10,6 @@ Complete reference for n8n's `.github/` folder.
.github/ .github/
├── WORKFLOWS.md # This document ├── WORKFLOWS.md # This document
├── CI-TELEMETRY.md # Telemetry & metrics guide ├── CI-TELEMETRY.md # Telemetry & metrics guide
├── CODEOWNERS # Temporary, side by side with OWNERS during the trial
├── pull_request_template.md # PR description template ├── pull_request_template.md # PR description template
├── pull_request_title_conventions.md # Title format rules (Angular) ├── pull_request_title_conventions.md # Title format rules (Angular)
├── actionlint.yml # Workflow linter config ├── actionlint.yml # Workflow linter config
@ -178,7 +177,7 @@ These only run if specific files changed:
| `docker/images/n8n-base/Dockerfile` | `build-base-image.yml` | any | | `docker/images/n8n-base/Dockerfile` | `build-base-image.yml` | any |
| `**/package.json`, `**/turbo.json` | `build-windows.yml` | master | | `**/package.json`, `**/turbo.json` | `build-windows.yml` | master |
| `packages/@n8n/ai-workflow-builder.ee/evaluations/programmatic/python/**` | `test-evals-python.yml` | any | | `packages/@n8n/ai-workflow-builder.ee/evaluations/programmatic/python/**` | `test-evals-python.yml` | any |
| `packages/@n8n/benchmark/**` | `build-benchmark-image.yml` | master | | `packages/quality/efficiency/scale/benchmark/**` | `build-benchmark-image.yml` | master |
| `packages/cli/src/public-api/**/*.yml`, `packages/cli/src/public-api/**/*.yaml`, `packages/cli/src/public-api/**/*.css`, `packages/cli/src/public-api/v1/openapi-gen/**/*.ts`, `packages/cli/scripts/build.mjs`, `packages/cli/package.json` | `util-publish-api-schema.yml` | master | | `packages/cli/src/public-api/**/*.yml`, `packages/cli/src/public-api/**/*.yaml`, `packages/cli/src/public-api/**/*.css`, `packages/cli/src/public-api/v1/openapi-gen/**/*.ts`, `packages/cli/scripts/build.mjs`, `packages/cli/package.json` | `util-publish-api-schema.yml` | master |
| `packages/@n8n/instance-ai/src/**`, `packages/@n8n/instance-ai/skills/**`, `packages/@n8n/instance-ai/knowledge-base/**`, `packages/@n8n/instance-ai/evaluations/**`, `packages/cli/src/modules/instance-ai/**`, `packages/core/src/execution-engine/eval-mock-helpers.ts`, `packages/@n8n/agents/src/**` | `ci-instance-ai-evals.yml` | on PR `opened` / `reopened` / `ready_for_review` | | `packages/@n8n/instance-ai/src/**`, `packages/@n8n/instance-ai/skills/**`, `packages/@n8n/instance-ai/knowledge-base/**`, `packages/@n8n/instance-ai/evaluations/**`, `packages/cli/src/modules/instance-ai/**`, `packages/core/src/execution-engine/eval-mock-helpers.ts`, `packages/@n8n/agents/src/**` | `ci-instance-ai-evals.yml` | on PR `opened` / `reopened` / `ready_for_review` |
| `docker/get-n8n.sh`, `docker/get-n8n-compose.yml`, `docker/test-get-n8n.sh` | `test-get-n8n.yml` | any | | `docker/get-n8n.sh`, `docker/get-n8n-compose.yml`, `docker/test-get-n8n.sh` | `test-get-n8n.yml` | any |
@ -237,14 +236,6 @@ parallelism). See the `--build-via-mcp` section in
| PR merged to `release/*` | `release-publish.yml` | | PR merged to `release/*` | `release-publish.yml` |
| PR closed with `codespace-preview` | `util-codespace-preview.yml` | | PR closed with `codespace-preview` | `util-codespace-preview.yml` |
### Manual Triggers (PR Comments)
| Command | Workflow | Permissions |
|--------------------|------------------------------|---------------------|
| `/test-workflows` | `test-workflows-callable.yml`| admin/write/maintain|
**Why:** Re-run tests without pushing commits. Useful for flaky test investigation.
### Label Triggers ### Label Triggers
| Label | Workflow | Effect | | Label | Workflow | Effect |
@ -420,7 +411,9 @@ Run-workflow dropdown, which only a user with write access can pick.
|-----------------------------|---------------------------------------------------------| |-----------------------------|---------------------------------------------------------|
| `util-codespace-preview.yml`| Wake, re-serve or delete a PR preview instance by hand | | `util-codespace-preview.yml`| Wake, re-serve or delete a PR preview instance by hand |
| `util-data-tooling.yml` | SQLite/PostgreSQL export/import validation (manual) | | `util-data-tooling.yml` | SQLite/PostgreSQL export/import validation (manual) |
| `test-image-efficiency.yml` | Measure n8n and runners image size and layer waste with Dive |
| `util-probe-registry.yml` | Diagnose slow npm metadata fetches (temporary) | | `util-probe-registry.yml` | Diagnose slow npm metadata fetches (temporary) |
| `sec-sync-bundle-branches.yml` | Sync both bundle branches on demand, including before a bundle cut |
--- ---
@ -454,10 +447,6 @@ test-sbom-nightly.yml
test-workflows-nightly.yml (manual dispatch only — nightly schedule disabled, DEVP-544) test-workflows-nightly.yml (manual dispatch only — nightly schedule disabled, DEVP-544)
└──────────────────────────▶ test-workflows-callable.yml └──────────────────────────▶ test-workflows-callable.yml
PR Comment Dispatchers (triggered by /command in PR comments):
test-workflows-pr-comment.yml
└──────────────────────────▶ test-workflows-callable.yml
``` ```
--- ---
@ -598,7 +587,7 @@ Push to master
| Daily 03:00 | `sec-sync-bundle-branches.yml` | Merge the base into `bundle/*` | | Daily 03:00 | `sec-sync-bundle-branches.yml` | Merge the base into `bundle/*` |
| Daily 00:00 | `docker-build-push.yml` | Nightly Docker images | | Daily 00:00 | `docker-build-push.yml` | Nightly Docker images |
| Daily 00:00 | `test-db.yml` | Database compatibility | | Daily 00:00 | `test-db.yml` | Database compatibility |
| Daily 00:00 | `test-e2e-performance-reusable.yml`| Performance E2E | | Daily 00:00 | `test-e2e-performance-reusable.yml`| Browser performance and idle memory baselines |
| Daily 00:00 | `release-storybook.yml` | Storybook deploy | | Daily 00:00 | `release-storybook.yml` | Storybook deploy |
| Daily 00:00 | `release-chromatic.yml` | Visual regression | | Daily 00:00 | `release-chromatic.yml` | Visual regression |
| Daily 00:00 | `util-check-docs-urls.yml` | Doc link validation | | Daily 00:00 | `util-check-docs-urls.yml` | Doc link validation |
@ -611,6 +600,7 @@ Push to master
| Daily 08:00 | `build-v3-nightly.yml` | Nightly v3 Docker images | | Daily 08:00 | `build-v3-nightly.yml` | Nightly v3 Docker images |
| Monday 00:00 | `util-update-node-popularity.yml` | Node usage stats | | Monday 00:00 | `util-update-node-popularity.yml` | Node usage stats |
| Monday 02:00 | `test-e2e-coverage-weekly.yml` | Weekly E2E coverage | | Monday 02:00 | `test-e2e-coverage-weekly.yml` | Weekly E2E coverage |
| Wednesday 04:00 | `util-update-get-n8n-versions.yml` | get-n8n stable versions |
| Saturday 22:00 | `test-evals-ai.yml` | AI workflow evals | | Saturday 22:00 | `test-evals-ai.yml` | AI workflow evals |
| 1st of month 04:00 | `util-refresh-cubic-schema.yml` | Refresh vendored cubic schema | | 1st of month 04:00 | `util-refresh-cubic-schema.yml` | Refresh vendored cubic schema |
@ -850,9 +840,8 @@ See **[CI-TELEMETRY.md](CI-TELEMETRY.md)** for:
## OWNERS ## OWNERS
Team ownership lives in the top-level `OWNERS` file (this replaces the Team ownership lives in the top-level `OWNERS` file. The scripts that consume
GitHub-native `CODEOWNERS` file; see the transition note below). The scripts it live in `.github/scripts/owners/`. Line format:
that consume it live in `.github/scripts/owners/`. Line format:
``` ```
<pattern> <@org/team> [required] <pattern> <@org/team> [required]
@ -884,8 +873,10 @@ The file drives four workflows:
### Required reviews ### Required reviews
An entry with the `required` option makes team approval mandatory: when a PR An entry with the `required` option makes team approval mandatory: when a PR
changes a file whose winning entry carries `required`, a member of each listed changes a non-test file whose winning entry carries `required`, a member of each
team must approve the PR. `ci-owners-required-reviews.yml` evaluates this on listed team must approve the PR. Test files match the shared patterns in
`test-files.mjs` and do not trigger required reviews.
`ci-owners-required-reviews.yml` evaluates this on
PR changes and review events, and reports a commit status PR changes and review events, and reports a commit status
named **Required Reviews** on the head SHA. A missing approval reports named **Required Reviews** on the head SHA. A missing approval reports
`pending` ("Waiting for approval from: …"), not `failure`, so an unreviewed PR `pending` ("Waiting for approval from: …"), not `failure`, so an unreviewed PR
@ -920,8 +911,7 @@ Reviews** status succeed without required OWNERS team approvals. A team member
must apply the `large-scale-change` label. The gate checks the actor from the must apply the `large-scale-change` label. The gate checks the actor from the
label event and verifies their current team membership. The label alone is not label event and verifies their current team membership. The label alone is not
sufficient. Label changes re-evaluate the status. Removing the label removes sufficient. Label changes re-evaluate the status. Removing the label removes
the exemption. During the CODEOWNERS trial, GitHub still enforces its separate the exemption.
code-owner review requirement.
Every path that writes the status runs in the base repository context, because Every path that writes the status runs in the base repository context, because
a fork-context run has no secrets and a read-only token. PR changes arrive a fork-context run has no secrets and a read-only token. PR changes arrive
@ -935,16 +925,6 @@ contribution whose runs still wait for approval gets no review-event
re-evaluation until a maintainer approves the runs; `workflow_dispatch` with re-evaluation until a maintainer approves the runs; `workflow_dispatch` with
the PR number is the manual fallback. the PR number is the manual fallback.
### Transition from CODEOWNERS
During a trial period, `.github/CODEOWNERS` stays in place next to OWNERS:
GitHub's native code-owner enforcement keeps gating merges while the
"Required Reviews" status runs side by side. The two must agree — CODEOWNERS
holds exactly the `required` entries of OWNERS (plus the OWNERS file itself)
and must not gain new entries; new ownership goes into OWNERS. After the
trial, delete `.github/CODEOWNERS`, remove "Require review from Code Owners"
from the master ruleset, and delete this section (tracked in DEVP-887).
--- ---
## Runner Selection ## Runner Selection
@ -1161,40 +1141,28 @@ open the PR there. That PR **must stay a single-parent squash** — the publish
posts to `#alerts-build` when that gate fails on a PR opened *from* `bundle/2.x` or posts to `#alerts-build` when that gate fails on a PR opened *from* `bundle/2.x` or
`bundle/1.x` (link only, no PR title, since the branch is embargoed). `bundle/1.x` (link only, no PR title, since the branch is embargoed).
`sec-sync-bundle-branches.yml` keeps those branches current, daily plus whenever a PR is `sec-sync-bundle-branches.yml` keeps those branches current nightly at 03:00 UTC and on
merged into one (and on `workflow_dispatch`). It **merges the base into** the bundle branch `workflow_dispatch`, including before a bundle cut. It **merges the public base into** the
via [`scripts/sync-bundle-branch.mjs`](scripts/sync-bundle-branch.mjs) and pushes without bundle branch via
forcing. Every push is verified to carry exactly the tree a merge of the two sides would [`scripts/sync-bundle-branch.mjs`](scripts/sync-bundle-branch.mjs) and pushes without forcing.
produce (`git merge-tree`); a mismatch, or a conflict marker, fails the run instead of pushing. Every push is verified to carry exactly the tree a merge of the two sides would produce (`git
merge-tree`); a mismatch, or a conflict marker, fails the run instead of pushing.
**A bundle branch is only ever built on published history.** Before it creates or merges **A bundle branch is only ever built on published history.** The sync fetches `master` or `1.x`
anything, the sync fetches the same-named branch from `https://github.com/n8n-io/n8n.git` directly from `https://github.com/n8n-io/n8n.git`. It creates a missing bundle branch at that
(anonymously — its token is scoped to the private repo) and checks that the private base tip is exact public SHA and merges that public SHA into an existing bundle branch. It never reads the
contained in it. This matters because the `chore: Bundle/*` squash on private `master` is private base branch. This matters because the `chore: Bundle/*` squash on private `master` is
*private-only*: the mirror above discards it in favour of the public cherry-pick of the same private-only until publication. The mirror can replace that commit with the public copy after
changes. A sync in that window would root the branch on a commit that is about to disappear, the bundle branch is deleted. The next bundle branch must not inherit the replaced commit.
leaving it carrying two commits for one set of fixes — and every fix PR cut from it inherits the
dead one. The window is real: this workflow's daily cron and the mirror's hourly cron both fire
at `:00` with nothing ordering them, which is why the check lives in the script rather than in
step ordering.
An unpublished cut is a **skip**, not a failure: the mirror discards that commit every hour
regardless, so the run exits green with the reason in the log and the next one proceeds. A
missing branch also self-heals, because the mirror re-dispatches this workflow while one is
absent. A base ahead of public for **any other reason** fails the run — the mirror is stuck and
will not clear it on its own, so fix that first (remove the commit, or dispatch **Security: Sync
from Public** with `force`) and re-run. To sync a bundle branch immediately, dispatch the mirror
and then this workflow. The blocking commits are listed in the run log; the failure annotation
carries only a count, since a subject hints at the fix.
Deleting a bundle branch takes its open PRs with it: GitHub moves each one onto the deleted Deleting a bundle branch takes its open PRs with it: GitHub moves each one onto the deleted
branch's own base, and re-creating the branch does not move them back. So the sync then calls branch's own base, and re-creating the branch does not move them back. The next nightly or manual
sync re-creates the branch and then calls
[`sec-sync-retarget-prs.yml`](workflows/sec-sync-retarget-prs.yml), which moves every open PR [`sec-sync-retarget-prs.yml`](workflows/sec-sync-retarget-prs.yml), which moves every open PR
on `master` onto `bundle/2.x` and every one on `1.x` onto `bundle/1.x`. It skips a bundle on `master` onto `bundle/2.x` and every one on `1.x` onto `bundle/1.x`. It skips a bundle
branch that does not exist, and skips PRs whose *head* is `bundle/*` — those are the branch that does not exist, and skips PRs whose *head* is `bundle/*` — those are the
`chore: Bundle/*` cut PRs, which target the base on purpose. It is also dispatchable on its `chore: Bundle/*` cut PRs, which target the base on purpose. It is also dispatchable on its
own. `sec-sync-public-to-private.yml` only *dispatches* the bundle sync when it finds a branch own. The retarget runs inside the bundle sync after a missing branch is recreated.
missing; the retarget runs inside that dispatched run, once the branch exists.
**`bundle/*` is append-only — never rebase it, never force-push it.** These branches receive **`bundle/*` is append-only — never rebase it, never force-push it.** These branches receive
PRs, and rewriting a branch that receives PRs orphans the copies of its commits that the open PRs, and rewriting a branch that receives PRs orphans the copies of its commits that the open
@ -1207,21 +1175,19 @@ itself. To refresh a fix branch, use GitHub's **Update branch** button or
sibling PR's merge base untouched, which is why only a rewrite breaks this. sibling PR's merge base untouched, which is why only a rewrite breaks this.
The costs of merging are deliberate and paid for: a merge commit per run, and fixes that have The costs of merging are deliberate and paid for: a merge commit per run, and fixes that have
already been published staying in the branch's log (the old rebase dropped them as empty already been published staying in the branch's log. Neither reaches anything downstream,
commits). Neither reaches anything downstream, because a bundle publishes as one squashed because a bundle publishes as one squashed commit taken from the tree rather than the history —
commit taken from the tree rather than the history — the `chore: Bundle/*` PR's **diff** stays the `chore: Bundle/*` PR's **diff** stays
exactly the pending fixes even when its commit list does not. For a list of what a bundle exactly the pending fixes even when its commit list does not. For a list of what a bundle
actually carries, read the fix PRs merged into the branch since the last cut, not actually carries, read the fix PRs merged into the branch since the last cut, not `base..bundle`.
`base..bundle`. A lower cadence than the base's is fine too: a base push never re-triggered
CI on the fix PRs, so syncing more often bought them nothing.
There is **one job per bundle branch**. A conflict is detected from the merge tree before the There is **one job per bundle branch**. A conflict is detected from the merge tree before the
working tree is touched, so the branch is left exactly as it was, that job **fails** (no working tree is touched, so the branch is left exactly as it was, that job **fails** (no
green runs hiding a stalled branch) and `#alerts-security` gets a run link — while the other green runs hiding a stalled branch) and `#alerts-security` gets a run link — while the other
branch still syncs. Recovery is deliberate: merge the base into the branch locally, resolve, branch still syncs. Recovery is deliberate: merge the public base into the branch locally,
push, then re-run the workflow — and that resolution then lives in the merge commit instead of resolve, push, then re-run the workflow — and that resolution then lives in the merge commit
being re-litigated on every later run. The sync never resolves a conflict itself, unlike instead of being re-litigated on every later run. The sync never resolves a conflict itself,
`util-sync-master-to-3x.yml`. unlike `util-sync-master-to-3x.yml`.
See **[`../AGENTS.md`](../AGENTS.md)** ("Security Fix Hygiene") for the naming rules that See **[`../AGENTS.md`](../AGENTS.md)** ("Security Fix Hygiene") for the naming rules that
keep the vulnerability out of public branch names, commits, and test descriptions. keep the vulnerability out of public branch names, commits, and test descriptions.
@ -1291,12 +1257,6 @@ Adding a new channel requires inviting the bot first; the first run otherwise fa
## Future Vision ## Future Vision
### Redundancy Review
Comment trigger (`/test-workflows`) is a workaround.
Long-term: Main CI should be reliable enough to not need these.
### Workflow Testability ### Workflow Testability
- Tools like `act` for local testing - Tools like `act` for local testing

View File

@ -58,6 +58,15 @@ describe('matchGlob', () => {
); );
}); });
it('backend module pattern matches packaged module files', () => {
assert.ok(
matchGlob(
'packages/modules/insights/backend/src/insights.service.ts',
'packages/modules/*/backend/**',
),
);
});
it('* matches single-level only', () => { it('* matches single-level only', () => {
assert.ok(matchGlob('README.md', '*.md')); assert.ok(matchGlob('README.md', '*.md'));
assert.ok(!matchGlob('docs/README.md', '*.md')); assert.ok(!matchGlob('docs/README.md', '*.md'));
@ -242,7 +251,7 @@ describe('runtime filter', () => {
'!**/CHANGELOG.md', '!**/CHANGELOG.md',
'!**/*.test.ts', '!**/*.test.ts',
'!**/*.spec.ts', '!**/*.spec.ts',
'!packages/testing/playwright/**', '!packages/quality/testing/playwright/**',
'!packages/frontend/@n8n/storybook/**', '!packages/frontend/@n8n/storybook/**',
'!scripts/agent-setup.mjs', '!scripts/agent-setup.mjs',
'!scripts/backend-module/**', '!scripts/backend-module/**',
@ -265,7 +274,7 @@ describe('runtime filter', () => {
it('does not trigger on playwright tests', () => { it('does not trigger on playwright tests', () => {
assert.equal( assert.equal(
evaluateFilter(['packages/testing/playwright/tests/x.spec.ts'], runtimePatterns), evaluateFilter(['packages/quality/testing/playwright/tests/x.spec.ts'], runtimePatterns),
false, false,
); );
}); });

View File

@ -1,6 +1,6 @@
services: services:
postgres: postgres:
image: ${TEST_IMAGE_POSTGRES:?set it from packages/testing/containers/postgres-versions.json} image: ${TEST_IMAGE_POSTGRES:?set it from packages/quality/environments/containers/postgres-versions.json}
restart: always restart: always
environment: environment:
- POSTGRES_DB=n8n - POSTGRES_DB=n8n

View File

@ -1,8 +1,15 @@
## Summary ## Summary
<!-- <!--
Describe what the PR does. Start with 1 to 3 sentences of background for a new reader. Then describe what the PR does, in prose, not as a list of edits.
Photos and videos are recommended. Add photos or videos for UI changes.
-->
## Why
<!--
State the problem or the constraint that makes the current code unfit. Do not repeat the Summary.
Add a rejected alternative only when a reviewer would ask about it, in one or two sentences.
--> -->
## How to test ## How to test

View File

@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
export const POSTGRES_VERSIONS_PATH = 'packages/testing/containers/postgres-versions.json'; export const POSTGRES_VERSIONS_PATH = 'packages/quality/environments/containers/postgres-versions.json';
/** The matrix wall is bounded by its slowest leg, so a larger runner buys nothing. */ /** The matrix wall is bounded by its slowest leg, so a larger runner buys nothing. */
const RUNNER = 'blacksmith-4vcpu-ubuntu-2204'; const RUNNER = 'blacksmith-4vcpu-ubuntu-2204';

View File

@ -30,9 +30,9 @@ describe('matchesGlob', () => {
}); });
it('matches a prefix pattern', () => { it('matches a prefix pattern', () => {
assert.equal(matchesGlob('packages/testing/playwright/a.ts', 'packages/testing/**'), true); assert.equal(matchesGlob('packages/quality/testing/playwright/a.ts', 'packages/quality/**'), true);
assert.equal(matchesGlob('packages/testing', 'packages/testing/**'), false); assert.equal(matchesGlob('packages/quality', 'packages/quality/**'), false);
assert.equal(matchesGlob('packages/cli/a.ts', 'packages/testing/**'), false); assert.equal(matchesGlob('packages/cli/a.ts', 'packages/quality/**'), false);
}); });
it('matches a literal path only exactly', () => { it('matches a literal path only exactly', () => {
@ -55,8 +55,8 @@ describe('matchesGlob', () => {
'packages/cli/__snapshots__/a.ts.snap', 'packages/cli/__snapshots__/a.ts.snap',
'packages/nodes-base/nodes/Foo/test/fixtures/a.json', 'packages/nodes-base/nodes/Foo/test/fixtures/a.json',
'packages/frontend/editor-ui/src/__mocks__/a.ts', 'packages/frontend/editor-ui/src/__mocks__/a.ts',
'packages/testing/playwright/a.ts', 'packages/quality/testing/playwright/a.ts',
'packages/testing', 'packages/quality',
'.github/scripts/glob.test.mjs', '.github/scripts/glob.test.mjs',
'.github/workflows/ci.yml', '.github/workflows/ci.yml',
'a/.hidden/b.spec.js', 'a/.hidden/b.spec.js',

View File

@ -1,6 +1,8 @@
import { readFileSync, statSync } from "node:fs"; import { readFileSync, statSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
import { isTestFile } from "../test-files.mjs";
/** /**
* @typedef OwnersEntry * @typedef OwnersEntry
* @property { string } pattern * @property { string } pattern
@ -236,7 +238,7 @@ export function assignOwnership(files, entries) {
/** /**
* Determine which teams must approve the changeset: a team is required when * Determine which teams must approve the changeset: a team is required when
* its `required` entry wins (last-match) for a changed file. * its `required` entry wins (last-match) for a changed non-test file.
* *
* @param { Set<string> } files * @param { Set<string> } files
* @param { OwnersEntry[] } entries * @param { OwnersEntry[] } entries
@ -247,6 +249,8 @@ export function resolveRequiredTeams(files, entries) {
const teamToFiles = new Map(); const teamToFiles = new Map();
for (const file of [...files].sort()) { for (const file of [...files].sort()) {
if (isTestFile(file)) continue;
const entry = findOwningEntry(file, entries); const entry = findOwningEntry(file, entries);
if (!entry?.required) continue; if (!entry?.required) continue;

View File

@ -293,6 +293,22 @@ describe('resolveRequiredTeams', () => {
assert.equal(result.size, 0); assert.equal(result.size, 0);
}); });
it('ignores test files whose winning entry is required', () => {
const result = resolveRequiredTeams(
new Set([
'.github/scripts/check.test.mjs',
'.github/workflows/__tests__/check.ts',
'.github/workflows/ci.yml',
]),
[
entry({ pattern: '.github/scripts/', team: '@n8n-io/qa-dx', required: true }),
entry({ pattern: '.github/workflows/', team: '@n8n-io/qa-dx', required: true }),
],
);
assert.deepEqual(result.get('@n8n-io/qa-dx'), ['.github/workflows/ci.yml']);
});
it('a later non-required entry overrides an earlier required one', () => { it('a later non-required entry overrides an earlier required one', () => {
const result = resolveRequiredTeams(new Set(['db/migrations/1-init.ts']), [ const result = resolveRequiredTeams(new Set(['db/migrations/1-init.ts']), [
entry({ pattern: 'db/', team: '@n8n-io/migrations-review', required: true }), entry({ pattern: 'db/', team: '@n8n-io/migrations-review', required: true }),

View File

@ -1,7 +1,7 @@
/** /**
* Required-review enforcement for OWNERS entries marked `required`. * Required-review enforcement for OWNERS entries marked `required`.
* *
* Computes the teams whose approval the changeset needs (per OWNERS) * Computes the teams whose approval the non-test changes need (per OWNERS)
* and reports the verdict as a "Required Reviews" commit status on the PR * and reports the verdict as a "Required Reviews" commit status on the PR
* head SHA. A ruleset that lists this status as a required check blocks the * head SHA. A ruleset that lists this status as a required check blocks the
* merge until a member of each required team has approved the PR. Merge-queue * merge until a member of each required team has approved the PR. Merge-queue

View File

@ -31,6 +31,38 @@ import {
*/ */
const BOT_MARKER = '<!-- pr-recommendations -->'; const BOT_MARKER = '<!-- pr-recommendations -->';
const REQUIRED_FILES_DISPLAY_LIMIT = 5;
/**
* @param { string } value
* @returns { string }
*/
function escapeHtml(value) {
return value
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('|', '&#124;');
}
/**
* @param { string[] } files
* @returns { string }
*/
function formatRequiredFiles(files) {
const displayedFiles = files
.slice(0, REQUIRED_FILES_DISPLAY_LIMIT)
.map((file) => `<code>${escapeHtml(file)}</code>`);
const omittedFileCount = files.length - displayedFiles.length;
if (omittedFileCount > 0) {
displayedFiles.push(
`<em>${omittedFileCount} more file${omittedFileCount === 1 ? '' : 's'}</em>`,
);
}
return displayedFiles.join('<br>');
}
function createEmptyLineStats() { function createEmptyLineStats() {
return { return {
@ -210,9 +242,11 @@ export function buildRequiredReviewsSection(requiredTeamFiles) {
'', '',
'Some changed files have a `required` owner in `OWNERS`. A member of each of these teams must approve this PR before it can merge:', 'Some changed files have a `required` owner in `OWNERS`. A member of each of these teams must approve this PR before it can merge:',
'', '',
'| Team | Files |', '| Team | Files owned | Owned files |',
'| --- | ---: |', '| --- | ---: | --- |',
...[...requiredTeamFiles].map(([team, files]) => `| ${team} | ${files.length} |`), ...[...requiredTeamFiles].map(
([team, files]) => `| ${team} | ${files.length} | ${formatRequiredFiles(files)} |`,
),
'', '',
`Request a review from the team${plural ? 's' : ''} — GitHub assigns reviewers according to the team's review settings. The \`Auto-assign reviewers\` label does this for all owning teams.`, `Request a review from the team${plural ? 's' : ''} — GitHub assigns reviewers according to the team's review settings. The \`Auto-assign reviewers\` label does this for all owning teams.`,
].join('\n'); ].join('\n');

View File

@ -217,7 +217,7 @@ describe('computeLineStats', () => {
['*.snap extension', 'src/foo.snap'], ['*.snap extension', 'src/foo.snap'],
['fixtures/ directory', 'src/fixtures/data.json'], ['fixtures/ directory', 'src/fixtures/data.json'],
['__mocks__/ directory', 'src/__mocks__/axios.ts'], ['__mocks__/ directory', 'src/__mocks__/axios.ts'],
['packages/testing/**', 'packages/testing/playwright/spec.ts'], ['packages/quality/**', 'packages/quality/testing/playwright/spec.ts'],
['dot-directory *.test.mjs', '.github/scripts/owners/owners.test.mjs'], ['dot-directory *.test.mjs', '.github/scripts/owners/owners.test.mjs'],
]) { ]) {
it(`classifies ${label} as testFiles`, () => { it(`classifies ${label} as testFiles`, () => {
@ -322,7 +322,7 @@ describe('buildRequiredReviewsSection', () => {
assert.equal(buildRequiredReviewsSection(new Map()), null); assert.equal(buildRequiredReviewsSection(new Map()), null);
}); });
it('lists each required team with its file count', () => { it('lists each required team with its file count and owned files', () => {
const section = buildRequiredReviewsSection( const section = buildRequiredReviewsSection(
new Map([ new Map([
['@n8n-io/qa-dx', ['a.yml', 'b.yml']], ['@n8n-io/qa-dx', ['a.yml', 'b.yml']],
@ -331,8 +331,30 @@ describe('buildRequiredReviewsSection', () => {
); );
assert.match(section, /### Required reviews/); assert.match(section, /### Required reviews/);
assert.match(section, /\| @n8n-io\/qa-dx \| 2 \|/); assert.match(
assert.match(section, /\| @n8n-io\/migrations-review \| 1 \|/); section,
/\| @n8n-io\/qa-dx \| 2 \| <code>a\.yml<\/code><br><code>b\.yml<\/code> \|/,
);
assert.match(section, /\| @n8n-io\/migrations-review \| 1 \| <code>m\.ts<\/code> \|/);
});
it('shows no more than five files for each team', () => {
const section = buildRequiredReviewsSection(
new Map([['@n8n-io/qa-dx', ['a.yml', 'b.yml', 'c.yml', 'd.yml', 'e.yml', 'f.yml', 'g.yml']]]),
);
assert.match(section, /<code>a\.yml<\/code>/);
assert.match(section, /<code>e\.yml<\/code>/);
assert.doesNotMatch(section, /<code>f\.yml<\/code>/);
assert.match(section, /<em>2 more files<\/em>/);
});
it('escapes file paths before adding them to the table', () => {
const section = buildRequiredReviewsSection(
new Map([['@n8n-io/qa-dx', ['packages/a|b/<script>.ts']]]),
);
assert.match(section, /<code>packages\/a&#124;b\/&lt;script&gt;\.ts<\/code>/);
}); });
it('prompts to request review from the team, plural when several teams are required', () => { it('prompts to request review from the team, plural when several teams are required', () => {
@ -447,7 +469,7 @@ describe('run', () => {
const body = postOrUpdateComment.mock.calls[0].arguments[1]; const body = postOrUpdateComment.mock.calls[0].arguments[1];
assert.match(body, /### Required reviews/); assert.match(body, /### Required reviews/);
assert.match(body, /\| @n8n-io\/qa-dx \| 1 \|/); assert.match(body, /\| @n8n-io\/qa-dx \| 1 \| <code>\.github\/workflows\/ci\.yml<\/code> \|/);
assert.match(body, /Request a review from the team —/); assert.match(body, /Request a review from the team —/);
}); });
}); });

View File

@ -747,8 +747,8 @@ packages:
fast-deep-equal@3.1.3: fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-uri@3.1.5: fast-uri@3.1.8:
resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==}
fd-package-json@2.0.0: fd-package-json@2.0.0:
resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
@ -1694,7 +1694,7 @@ snapshots:
ajv@8.20.0: ajv@8.20.0:
dependencies: dependencies:
fast-deep-equal: 3.1.3 fast-deep-equal: 3.1.3
fast-uri: 3.1.5 fast-uri: 3.1.8
json-schema-traverse: 1.0.0 json-schema-traverse: 1.0.0
require-from-string: 2.0.2 require-from-string: 2.0.2
@ -1994,7 +1994,7 @@ snapshots:
fast-deep-equal@3.1.3: {} fast-deep-equal@3.1.3: {}
fast-uri@3.1.5: {} fast-uri@3.1.8: {}
fd-package-json@2.0.0: fd-package-json@2.0.0:
dependencies: dependencies:

View File

@ -14,32 +14,13 @@
import { initGithub, getEventFromGithubEventPath } from '../github-helpers.mjs'; import { initGithub, getEventFromGithubEventPath } from '../github-helpers.mjs';
import { matchesGlob } from '../glob.mjs'; import { matchesGlob } from '../glob.mjs';
import { isTestFile, TEST_PATTERNS } from '../test-files.mjs';
export { isTestFile, TEST_PATTERNS };
export const SIZE_LIMIT = 1000; export const SIZE_LIMIT = 1000;
export const OVERRIDE_COMMAND = '/size-limit-override'; export const OVERRIDE_COMMAND = '/size-limit-override';
export const TEST_PATTERNS = [
// Test files (by extension)
'**/*.test.ts',
'**/*.test.js',
'**/*.test.mjs',
'**/*.spec.ts',
'**/*.spec.js',
'**/*.spec.mjs',
// Test directories
'**/test/**',
'**/tests/**',
'**/__tests__/**',
// Snapshots
'**/__snapshots__/**',
'**/*.snap',
// Fixtures and mocks
'**/fixtures/**',
'**/__mocks__/**',
// Dedicated testing package
'packages/testing/**',
];
export const MISC_PATTERNS = [ export const MISC_PATTERNS = [
// Lock file (can produce massive diffs on dependency changes) // Lock file (can produce massive diffs on dependency changes)
'pnpm-lock.yaml', 'pnpm-lock.yaml',
@ -56,7 +37,7 @@ export const EXCLUDE_PATTERNS = [...TEST_PATTERNS, ...MISC_PATTERNS];
* @returns { 'testFiles' | 'misc' | 'sourceCode' } * @returns { 'testFiles' | 'misc' | 'sourceCode' }
*/ */
export function categorizeFile(filename) { export function categorizeFile(filename) {
if (TEST_PATTERNS.some((pattern) => matchesGlob(filename, pattern))) return 'testFiles'; if (isTestFile(filename)) return 'testFiles';
if (MISC_PATTERNS.some((pattern) => matchesGlob(filename, pattern))) return 'misc'; if (MISC_PATTERNS.some((pattern) => matchesGlob(filename, pattern))) return 'misc';
return 'sourceCode'; return 'sourceCode';
} }

View File

@ -203,14 +203,21 @@ describe('countFilteredAdditions', () => {
assert.equal(countFilteredAdditions(files, EXCLUDE_PATTERNS), 50); assert.equal(countFilteredAdditions(files, EXCLUDE_PATTERNS), 50);
}); });
it('applies EXCLUDE_PATTERNS to packages/testing and pnpm-lock.yaml', () => { it('excludes former testing workspaces but counts benchmark CLI source', () => {
const files = [ const files = [
{ filename: 'packages/cli/src/service.ts', additions: 50 }, { filename: 'packages/cli/src/service.ts', additions: 50 },
{ filename: 'packages/testing/playwright/tests/workflow.spec.ts', additions: 100 }, { filename: 'packages/quality/testing/playwright/tests/workflow.spec.ts', additions: 100 },
{ filename: 'packages/testing/playwright/pages/CanvasPage.ts', additions: 100 }, { filename: 'packages/quality/testing/playwright/pages/CanvasPage.ts', additions: 100 },
{ filename: 'packages/quality/policy/code-health/src/cli.ts', additions: 100 },
{ filename: 'packages/quality/environments/containers/service-stack.ts', additions: 100 },
{
filename: 'packages/quality/efficiency/microbenchmarks/benchmarks/bench-options.ts',
additions: 100,
},
{ filename: 'packages/quality/efficiency/scale/benchmark/src/commands/list.ts', additions: 100 },
{ filename: 'pnpm-lock.yaml', additions: 500 }, { filename: 'pnpm-lock.yaml', additions: 500 },
]; ];
assert.equal(countFilteredAdditions(files, EXCLUDE_PATTERNS), 50); assert.equal(countFilteredAdditions(files, EXCLUDE_PATTERNS), 150);
}); });
it('applies EXCLUDE_PATTERNS to markdown files', () => { it('applies EXCLUDE_PATTERNS to markdown files', () => {

View File

@ -5,7 +5,9 @@
"description": "JSON schema for cubic.yaml (and the legacy .cubic.yaml) so editors can validate and autocomplete repository settings.", "description": "JSON schema for cubic.yaml (and the legacy .cubic.yaml) so editors can validate and autocomplete repository settings.",
"type": "object", "type": "object",
"additionalProperties": true, "additionalProperties": true,
"required": ["version"], "required": [
"version"
],
"properties": { "properties": {
"version": { "version": {
"const": 1, "const": 1,
@ -16,13 +18,26 @@
"description": "AI review behavior and optional YAML-defined custom agents.", "description": "AI review behavior and optional YAML-defined custom agents.",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"senior_reviewers": {
"type": "array",
"maxItems": 5,
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$"
},
"description": "GitHub usernames to learn review patterns from. Overrides dashboard selections; an empty list disables senior reviewer learning."
},
"enabled": { "enabled": {
"type": "boolean", "type": "boolean",
"description": "Master toggle for AI reviews on this repository." "description": "Master toggle for AI reviews on this repository."
}, },
"sensitivity": { "sensitivity": {
"type": "string", "type": "string",
"enum": ["low", "medium", "high"], "enum": [
"low",
"medium",
"high"
],
"description": "Controls how strictly Cubic flags issues." "description": "Controls how strictly Cubic flags issues."
}, },
"incremental_commits": { "incremental_commits": {
@ -63,12 +78,21 @@
}, },
"auto_approve_behavior": { "auto_approve_behavior": {
"type": "string", "type": "string",
"enum": ["disabled", "shadow", "live"], "enum": [
"disabled",
"shadow",
"live"
],
"description": "Controls whether auto-approval is disabled, simulated in shadow mode, or submitted live to GitHub." "description": "Controls whether auto-approval is disabled, simulated in shadow mode, or submitted live to GitHub."
}, },
"auto_approve": { "auto_approve": {
"type": "string", "type": "string",
"enum": ["disabled", "always", "low_risk_only", "custom"], "enum": [
"disabled",
"always",
"low_risk_only",
"custom"
],
"description": "Auto-approve mode: disabled, always approve clean runs, use low-risk heuristics, or use a custom prompt." "description": "Auto-approve mode: disabled, always approve clean runs, use low-risk heuristics, or use a custom prompt."
}, },
"auto_approve_custom_prompt": { "auto_approve_custom_prompt": {
@ -80,12 +104,20 @@
}, },
"ultrareview": { "ultrareview": {
"type": "string", "type": "string",
"enum": ["disabled", "manual", "automatic"], "enum": [
"disabled",
"manual",
"automatic"
],
"description": "Master switch for ultrareviews. disabled blocks all ultrareviews (manual and automatic), manual allows only manual triggers (the default), automatic also enables the automatic triggers." "description": "Master switch for ultrareviews. disabled blocks all ultrareviews (manual and automatic), manual allows only manual triggers (the default), automatic also enables the automatic triggers."
}, },
"auto_ultrareview": { "auto_ultrareview": {
"type": "string", "type": "string",
"enum": ["disabled", "high_risk_only", "custom"], "enum": [
"disabled",
"high_risk_only",
"custom"
],
"description": "Auto-trigger ultrareview mode: disabled, let cubic decide per PR using built-in high-risk criteria, or use a custom prompt." "description": "Auto-trigger ultrareview mode: disabled, let cubic decide per PR using built-in high-risk criteria, or use a custom prompt."
}, },
"auto_ultrareview_custom_prompt": { "auto_ultrareview_custom_prompt": {
@ -159,7 +191,10 @@
}, },
"coding_agent_provider": { "coding_agent_provider": {
"type": "string", "type": "string",
"enum": ["cubic", "cursor_cloud_agent"], "enum": [
"cubic",
"cursor_cloud_agent"
],
"description": "Which coding agent applies automatic fixes. 'cubic' uses cubic's built-in agent; 'cursor_cloud_agent' dispatches a Cursor cloud agent (requires Cursor configuration)." "description": "Which coding agent applies automatic fixes. 'cubic' uses cubic's built-in agent; 'cursor_cloud_agent' dispatches a Cursor cloud agent (requires Cursor configuration)."
} }
} }
@ -222,8 +257,20 @@
}, },
"exclude_external_contributors": { "exclude_external_contributors": {
"type": "boolean", "type": "boolean",
"default": false, "default": true,
"description": "If true, public-repository PRs from external contributors are reviewed but never auto-approved." "description": "If true, public-repository PRs from external contributors, or from authors cubic cannot verify, are reviewed but never auto-approved."
},
"allow_open_issues": {
"type": "string",
"enum": [
"none",
"p3",
"p2_and_p3",
"p1_to_p3",
"all"
],
"default": "none",
"description": "Open cubic findings that don't block auto-approval, by priority. none blocks on any open finding; p3, p2_and_p3, and p1_to_p3 allow that range; all allows every open finding. A finding without a recorded priority blocks unless this is all. Every other auto-approval rule still applies."
}, },
"exclude_authors": { "exclude_authors": {
"$ref": "#/$defs/globList", "$ref": "#/$defs/globList",
@ -271,13 +318,19 @@
"type": "object", "type": "object",
"description": "Definition of a YAML-managed custom agent.", "description": "Definition of a YAML-managed custom agent.",
"additionalProperties": false, "additionalProperties": false,
"required": ["name"], "required": [
"name"
],
"anyOf": [ "anyOf": [
{ {
"required": ["description"] "required": [
"description"
]
}, },
{ {
"required": ["file_paths"] "required": [
"file_paths"
]
} }
], ],
"properties": { "properties": {

68
.github/scripts/split-jscpd-report.mjs vendored Normal file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env node
// Splits a jscpd JSON report's `duplicates` array into N bucket files so a
// caller can download and sample one small file instead of the whole report
// (which can run into tens of MB on a large monorepo). Round-robin, not
// contiguous chunks, so a run of similarly-sized clusters in scan order
// doesn't pile up in one bucket.
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
export function splitDuplicates(duplicates, bucketCount) {
const buckets = Array.from({ length: bucketCount }, () => []);
duplicates.forEach((dup, i) => buckets[i % bucketCount].push(dup));
return buckets;
}
export function writeBuckets(buckets, outputDir, deps = {}) {
const mkdirImpl = deps.mkdir ?? mkdirSync;
const writeImpl = deps.write ?? writeFileSync;
mkdirImpl(outputDir, { recursive: true });
return buckets.map((duplicates, i) => {
const path = join(outputDir, `bucket-${i}.json`);
writeImpl(path, JSON.stringify({ duplicates }));
return path;
});
}
export function parseBucketCount(raw) {
const count = Number(raw ?? 20);
if (!Number.isInteger(count) || count <= 0) {
throw new Error(`BUCKET_COUNT must be a positive integer, got '${raw}'`);
}
return count;
}
export function loadDuplicates(reportPath, deps = {}) {
const readImpl = deps.read ?? readFileSync;
const report = JSON.parse(readImpl(reportPath, 'utf8'));
if (!Array.isArray(report.duplicates)) {
throw new Error('report.duplicates must be an array');
}
return report.duplicates;
}
// Exits non-zero on any failure. The workflow step already runs with
// continue-on-error, so this can't fail the job — it only stops a broken
// split (zero buckets written) from reporting success.
function main() {
const reportPath = process.env.REPORT_PATH;
const outputDir = process.env.OUTPUT_DIR;
if (!reportPath || !outputDir) {
process.stderr.write('split-jscpd-report: REPORT_PATH and OUTPUT_DIR are required\n');
process.exit(1);
}
try {
const bucketCount = parseBucketCount(process.env.BUCKET_COUNT);
const duplicates = loadDuplicates(reportPath);
const buckets = splitDuplicates(duplicates, bucketCount);
writeBuckets(buckets, outputDir);
} catch (err) {
process.stderr.write(`split-jscpd-report: ${err.message}\n`);
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main();
}

View File

@ -0,0 +1,111 @@
/**
* Run these tests by running
*
* node --test .github/scripts/split-jscpd-report.test.mjs
* */
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { splitDuplicates, writeBuckets, parseBucketCount, loadDuplicates } from './split-jscpd-report.mjs';
describe('splitDuplicates', () => {
it('distributes entries round-robin across buckets', () => {
const duplicates = [1, 2, 3, 4, 5, 6];
const buckets = splitDuplicates(duplicates, 3);
assert.deepEqual(buckets, [
[1, 4],
[2, 5],
[3, 6],
]);
});
it('leaves later buckets empty when there are fewer entries than buckets', () => {
const buckets = splitDuplicates([1, 2], 5);
assert.equal(buckets.length, 5);
assert.deepEqual(buckets[0], [1]);
assert.deepEqual(buckets[1], [2]);
assert.deepEqual(buckets[2], []);
});
it('returns bucketCount empty arrays for an empty report', () => {
const buckets = splitDuplicates([], 4);
assert.deepEqual(buckets, [[], [], [], []]);
});
});
describe('writeBuckets', () => {
it('writes one JSON file per bucket, named by index', () => {
const written = [];
const paths = writeBuckets([[{ a: 1 }], [{ b: 2 }]], '/tmp/buckets', {
mkdir: () => {},
write: (path, contents) => written.push({ path, contents }),
});
assert.deepEqual(paths, ['/tmp/buckets/bucket-0.json', '/tmp/buckets/bucket-1.json']);
assert.deepEqual(JSON.parse(written[0].contents), { duplicates: [{ a: 1 }] });
assert.deepEqual(JSON.parse(written[1].contents), { duplicates: [{ b: 2 }] });
});
it('creates the output directory before writing', () => {
let mkdirCalledWith = null;
writeBuckets([[]], '/tmp/buckets', {
mkdir: (dir, opts) => {
mkdirCalledWith = { dir, opts };
},
write: () => {},
});
assert.deepEqual(mkdirCalledWith, { dir: '/tmp/buckets', opts: { recursive: true } });
});
});
describe('parseBucketCount', () => {
it('parses a numeric string', () => {
assert.equal(parseBucketCount('20'), 20);
});
it('defaults to 20 when unset', () => {
assert.equal(parseBucketCount(undefined), 20);
});
it('rejects zero', () => {
assert.throws(() => parseBucketCount('0'), /positive integer/);
});
it('rejects a negative count', () => {
assert.throws(() => parseBucketCount('-1'), /positive integer/);
});
it('rejects a non-integer', () => {
assert.throws(() => parseBucketCount('1.5'), /positive integer/);
});
it('rejects a non-numeric value', () => {
assert.throws(() => parseBucketCount('abc'), /positive integer/);
});
});
describe('loadDuplicates', () => {
it('returns the duplicates array from a valid report', () => {
const duplicates = loadDuplicates('/tmp/report.json', {
read: () => JSON.stringify({ duplicates: [{ a: 1 }] }),
});
assert.deepEqual(duplicates, [{ a: 1 }]);
});
it('rejects a report missing the duplicates array', () => {
assert.throws(
() => loadDuplicates('/tmp/report.json', { read: () => JSON.stringify({}) }),
/duplicates must be an array/,
);
});
it('rejects a report whose duplicates field is not an array', () => {
assert.throws(
() => loadDuplicates('/tmp/report.json', { read: () => JSON.stringify({ duplicates: 'x' }) }),
/duplicates must be an array/,
);
});
it('propagates a JSON parse failure', () => {
assert.throws(() => loadDuplicates('/tmp/report.json', { read: () => 'not json' }), SyntaxError);
});
});

View File

@ -12,7 +12,7 @@
* why only a rewrite breaks this. * why only a rewrite breaks this.
* *
* The cost of merging is a merge commit per run, plus already-published fixes staying in the * The cost of merging is a merge commit per run, plus already-published fixes staying in the
* branch's log (the rebase used to drop them as empty). Neither reaches anything downstream: * branch's log. Neither reaches anything downstream:
* a bundle is published as one squashed, deliberately obfuscated commit, and the squash is * a bundle is published as one squashed, deliberately obfuscated commit, and the squash is
* taken from the tree, not the history. For a list of what a bundle actually carries, read * taken from the tree, not the history. For a list of what a bundle actually carries, read
* the fix PRs merged into the branch since the last cut, not `base..bundle`. * the fix PRs merged into the branch since the last cut, not `base..bundle`.
@ -26,17 +26,13 @@
* of being re-litigated on every later run. Contrast `sync-master-to-3x.mjs`, which * of being re-litigated on every later run. Contrast `sync-master-to-3x.mjs`, which
* auto-resolves mechanical files and opens a conflict PR. * auto-resolves mechanical files and opens a conflict PR.
* *
* PUBLISHED HISTORY ONLY: the base is synced in only once the public repo already has it. A cut * PUBLIC HISTORY ONLY: the base is fetched directly from the public repo. Private master can
* squash-merges the bundle branch into private master as `chore: Bundle …`, and the hourly * temporarily contain a bundle cut that public master does not have yet. Using the private base
* public→private mirror then DISCARDS that commit in favour of the public cherry-pick of the same * would strand that commit on a recreated bundle branch after the private mirror replaces it.
* changes. Building on it would strand the discarded commit on a branch that fix PRs are cut
* from, and the replacement gets merged in on top of it later. An unpublished cut is a SKIP (the
* mirror clears it within the hour, whatever the cut is, so waiting cannot deadlock); a base
* ahead of public for any other reason is a FAILURE, because the mirror will not clear it.
* *
* Runs from a full checkout (fetch-depth 0) of any branch. Assumes credentials are NOT * Runs from a full checkout (fetch-depth 0) of any branch. Assumes credentials are NOT
* persisted by checkout — every private fetch and the push go through an explicit token URL, * persisted by checkout. The bundle fetch and push use an explicit token URL. The public base
* which matters because the repository is private. The public fetch is anonymous. * fetch is anonymous.
* *
* Env: BUNDLE_BRANCH (e.g. bundle/2.x), BASE_BRANCH (e.g. master), * Env: BUNDLE_BRANCH (e.g. bundle/2.x), BASE_BRANCH (e.g. master),
* GH_TOKEN (installation token with contents:write), * GH_TOKEN (installation token with contents:write),
@ -60,10 +56,6 @@ const BOT_EMAIL = 'n8n-assistant[bot]@users.noreply.github.com';
// installation token this script holds is scoped to the private repo. // installation token this script holds is scoped to the private repo.
const PUBLIC_REMOTE = 'https://github.com/n8n-io/n8n.git'; const PUBLIC_REMOTE = 'https://github.com/n8n-io/n8n.git';
// What a cut lands on private base before it is published. Anything else ahead of public means
// the mirror is stuck, not that a cut is in flight.
const BUNDLE_SUBJECT = /^chore: Bundle/;
function required(env, name) { function required(env, name) {
const value = env[name]; const value = env[name];
if (!value) throw new Error(`${name} env var is required`); if (!value) throw new Error(`${name} env var is required`);
@ -76,49 +68,8 @@ export function annotation(title, message) {
return `::error title=${title}::${message.replace(/\n/g, '%0A')}`; return `::error title=${title}::${message.replace(/\n/g, '%0A')}`;
} }
/**
* Whether the base tip is still private-only, and what to do about it.
*
* `null` means the public repo already has it, so the sync may proceed. The predicate is
* containment in public rather than "is not a bundle commit", so a direct push that bypassed
* ci-restrict-private-merges.yml is caught too; the subjects only decide how to react.
*/
function unconvergedBase({ git, log, bundle, base, baseSha, publicSha }) {
if (isAncestor(git, baseSha, publicSha)) return null;
const ahead = git(['log', '--format=%h %s', `${publicSha}..${baseSha}`])
.split('\n')
.filter(Boolean);
const subjects = ahead.map((line) => line.slice(line.indexOf(' ') + 1));
// All-or-nothing: one unexplained commit means the mirror will not clear the base on its own.
// An empty range here means unrelated histories, which `every` treats as a skip — the safe
// direction, since forcing past an ancestry check we could not evaluate is never right.
if (subjects.every((subject) => BUNDLE_SUBJECT.test(subject))) {
log(
`${base} ${baseSha} has not reached public ${base} ${publicSha} yet; leaving ${bundle} ` +
'untouched. The hourly public → private sync clears this.',
);
return { status: 'unconverged' };
}
// Subjects go to the run log, which is private. The annotation stays a count: it is the
// headline of a failed run, and a subject hints at the fix.
log(ahead.join('\n'));
log(
annotation(
`${base} is ahead of public`,
`${base} carries ${ahead.length} commit(s) that public does not have and that are not ` +
`bundle cuts, so the mirror cannot clear them. Fix the mirror, then re-run this workflow.`,
),
);
throw new Error(`${base} is ahead of public by commits that are not bundle cuts.`);
}
// Takes `baseSha` explicitly. This path never fetches the bundle branch, so FETCH_HEAD still
// holds the PUBLIC tip here, not the base — never swap the argument for FETCH_HEAD.
function createBundleBranch({ git, log, bundle, base, baseSha, remote }) { function createBundleBranch({ git, log, bundle, base, baseSha, remote }) {
log(`${bundle} does not exist yet; creating it at ${base} ${baseSha}.`); log(`${bundle} does not exist yet; creating it at public ${base} ${baseSha}.`);
git(['checkout', '--force', '-B', bundle, baseSha]); git(['checkout', '--force', '-B', bundle, baseSha]);
const push = attempt(git, ['push', remote, `HEAD:refs/heads/${bundle}`]); const push = attempt(git, ['push', remote, `HEAD:refs/heads/${bundle}`]);
@ -132,28 +83,15 @@ function createBundleBranch({ git, log, bundle, base, baseSha, remote }) {
/** /**
* One fetch-merge-push cycle. `status: 'rejected'` means the branch moved under us — the * One fetch-merge-push cycle. `status: 'rejected'` means the branch moved under us — the
* caller re-runs from a fresh fetch rather than forcing anything. `status: 'unconverged'` means * caller re-runs from a fresh fetch rather than forcing anything.
* the base is not published yet and nothing was touched.
*/ */
function mergeBaseIntoBundle({ git, log, bundle, base, remote }) { function mergeBaseIntoBundle({ git, log, bundle, base, remote }) {
// Pin every side to the SHA fetched for it — fetching by URL never updates the origin/* // Pin the base to the public SHA. Private master can temporarily contain an unpublished cut.
// tracking refs, so FETCH_HEAD is the only handle, and each of the three fetches below
// overwrites the last. Read FETCH_HEAD on the line after its own fetch; never separate a
// fetch from the read that consumes it.
git(['fetch', remote, base]);
const baseSha = git(['rev-parse', 'FETCH_HEAD']);
// The base branch is named the same on both sides (master, 1.x). If that ever stops being
// true, map it here rather than at the call site.
const publicFetch = attempt(git, ['fetch', PUBLIC_REMOTE, base]); const publicFetch = attempt(git, ['fetch', PUBLIC_REMOTE, base]);
if (!publicFetch.ok) { if (!publicFetch.ok) {
// A guard that cannot be evaluated must stop the run, not be assumed satisfied.
throw new Error(`Could not fetch ${base} from the public repo:\n${publicFetch.out}`); throw new Error(`Could not fetch ${base} from the public repo:\n${publicFetch.out}`);
} }
const publicSha = git(['rev-parse', 'FETCH_HEAD']); const baseSha = git(['rev-parse', 'FETCH_HEAD']);
const unconverged = unconvergedBase({ git, log, bundle, base, baseSha, publicSha });
if (unconverged) return unconverged;
const listed = attempt(git, ['ls-remote', '--heads', remote, `refs/heads/${bundle}`]); const listed = attempt(git, ['ls-remote', '--heads', remote, `refs/heads/${bundle}`]);
if (!listed.ok) { if (!listed.ok) {
@ -179,7 +117,9 @@ function mergeBaseIntoBundle({ git, log, bundle, base, remote }) {
'--format=%h %s', '--format=%h %s',
`${baseSha}..${preHead}`, `${baseSha}..${preHead}`,
]); ]);
log(`Merging ${base} ${baseSha} into ${bundle}. Commits on ${bundle}:\n${pending || '(none)'}`); log(
`Merging public ${base} ${baseSha} into ${bundle}. Commits on ${bundle}:\n${pending || '(none)'}`,
);
// The content the merge must produce — and whether the two sides conflict at all. Computed // The content the merge must produce — and whether the two sides conflict at all. Computed
// without touching the working tree, so a conflict costs the branch nothing. // without touching the working tree, so a conflict costs the branch nothing.
@ -211,7 +151,7 @@ function mergeBaseIntoBundle({ git, log, bundle, base, remote }) {
if (push.out) log(push.out); if (push.out) log(push.out);
return { status: 'rejected' }; return { status: 'rejected' };
} }
log(`Merged ${base} into ${bundle} — nothing rewritten.`); log(`Merged public ${base} into ${bundle}; nothing was rewritten.`);
return { status: 'merged' }; return { status: 'merged' };
} }

View File

@ -28,7 +28,6 @@ const fail =
}; };
const PRE_HEAD = 'PREHEAD'; const PRE_HEAD = 'PREHEAD';
const BASE = 'BASESHA';
const PUBLIC = 'PUBLICSHA'; const PUBLIC = 'PUBLICSHA';
const MERGE_TREE = 'MERGETREEOID'; const MERGE_TREE = 'MERGETREEOID';
const REMOTE = 'https://x-access-token:tok@github.com/n8n-io/n8n-private.git'; const REMOTE = 'https://x-access-token:tok@github.com/n8n-io/n8n-private.git';
@ -52,37 +51,27 @@ const conflictedMergeTree = (...paths) =>
fail(`${MERGE_TREE}\n${paths.join('\n')}\n\nCONFLICT (content): Merge conflict in ${paths[0]}`); fail(`${MERGE_TREE}\n${paths.join('\n')}\n\nCONFLICT (content): Merge conflict in ${paths[0]}`);
// FETCH_HEAD is one slot holding whatever the last fetch brought down, so the stub has to answer // FETCH_HEAD is one slot holding whatever the last fetch brought down, so the stub has to answer
// by looking back at that fetch. Resolving both fetches to the same SHA would let the // by looking back at that fetch.
// convergence guard pass by accident and assert nothing.
const fetchHead = (_args, calls) => { const fetchHead = (_args, calls) => {
const [, url, ref] = [...calls].reverse().find((a) => a[0] === 'fetch') ?? []; const [, url, ref] = [...calls].reverse().find((a) => a[0] === 'fetch') ?? [];
if (url === PUBLIC_REMOTE) return PUBLIC; if (url === PUBLIC_REMOTE) return PUBLIC;
if (ref?.startsWith('bundle/')) return PRE_HEAD; if (ref?.startsWith('bundle/')) return PRE_HEAD;
return BASE; return '';
}; };
// Routes shared by every path: base fetched and already published, the bundle branch hasn't // Routes shared by every path: the bundle branch has not absorbed the public base yet, the
// absorbed it yet, the merge tree is computable, and the merge lands on exactly that tree. git // merge tree is computable, and the merge lands on exactly that tree. git grep exits non-zero
// grep exits non-zero => no markers. // => no markers.
const baseGitRoutes = [ const baseGitRoutes = [
[(a) => a[0] === 'ls-remote', `${PRE_HEAD}\trefs/heads/bundle/2.x`], [(a) => a[0] === 'ls-remote', `${PRE_HEAD}\trefs/heads/bundle/2.x`],
[(a) => a[0] === 'rev-parse' && a[1] === 'FETCH_HEAD', fetchHead], [(a) => a[0] === 'rev-parse' && a[1] === 'FETCH_HEAD', fetchHead],
[(a) => a[0] === 'rev-parse' && a[1] === 'HEAD', PRE_HEAD], [(a) => a[0] === 'rev-parse' && a[1] === 'HEAD', PRE_HEAD],
// Split by descendant: the base has reached public, but the bundle branch has not absorbed
// it. One `merge-base` matcher would answer both and decide convergence by accident.
[(a) => a[0] === 'merge-base' && a[3] === PUBLIC, ''],
[(a) => a[0] === 'merge-base' && a[3] === PRE_HEAD, fail()], [(a) => a[0] === 'merge-base' && a[3] === PRE_HEAD, fail()],
[(a) => a[0] === 'merge-tree', MERGE_TREE], [(a) => a[0] === 'merge-tree', MERGE_TREE],
[(a) => a[0] === 'rev-parse' && a[1] === 'HEAD^{tree}', MERGE_TREE], [(a) => a[0] === 'rev-parse' && a[1] === 'HEAD^{tree}', MERGE_TREE],
[(a) => a[0] === 'grep', fail()], [(a) => a[0] === 'grep', fail()],
]; ];
// A base that is ahead of public by the commits given, so the guard trips.
const unpublishedRoutes = (...lines) => [
[(a) => a[0] === 'merge-base' && a[3] === PUBLIC, fail()],
[(a) => a[0] === 'log' && a[1] === '--format=%h %s', lines.join('\n')],
];
const silent = () => {}; const silent = () => {};
test('a missing branch env var fails before any git command runs', () => { test('a missing branch env var fails before any git command runs', () => {
@ -107,14 +96,14 @@ test('a clean sync merges the base in and pushes without forcing', () => {
'--no-edit', '--no-edit',
'-m', '-m',
'Merge master into bundle/2.x', 'Merge master into bundle/2.x',
BASE, PUBLIC,
]); ]);
// No lease and no --force: the branch is append-only, so a non-fast-forward must be // No lease and no --force: the branch is append-only, so a non-fast-forward must be
// refused by git rather than resolved by overwriting whatever landed. // refused by git rather than resolved by overwriting whatever landed.
assert.deepEqual(git.calls.find(isPush), ['push', REMOTE, 'HEAD:refs/heads/bundle/2.x']); assert.deepEqual(git.calls.find(isPush), ['push', REMOTE, 'HEAD:refs/heads/bundle/2.x']);
}); });
test('the private fetches are authenticated and the public one is not', () => { test('the bundle fetch is authenticated and the public base fetch is not', () => {
const git = makeStub(baseGitRoutes); const git = makeStub(baseGitRoutes);
syncBundleBranch({ git, env, log: silent }); syncBundleBranch({ git, env, log: silent });
@ -122,7 +111,6 @@ test('the private fetches are authenticated and the public one is not', () => {
assert.deepEqual( assert.deepEqual(
git.calls.filter((a) => a[0] === 'fetch'), git.calls.filter((a) => a[0] === 'fetch'),
[ [
['fetch', REMOTE, 'master'],
['fetch', PUBLIC_REMOTE, 'master'], ['fetch', PUBLIC_REMOTE, 'master'],
['fetch', REMOTE, 'bundle/2.x'], ['fetch', REMOTE, 'bundle/2.x'],
], ],
@ -145,8 +133,6 @@ test('the public tip is read straight after its own fetch', () => {
assert.deepEqual( assert.deepEqual(
git.calls.filter((a) => a[0] === 'fetch' || (a[0] === 'rev-parse' && a[1] === 'FETCH_HEAD')), git.calls.filter((a) => a[0] === 'fetch' || (a[0] === 'rev-parse' && a[1] === 'FETCH_HEAD')),
[ [
['fetch', REMOTE, 'master'],
['rev-parse', 'FETCH_HEAD'],
['fetch', PUBLIC_REMOTE, 'master'], ['fetch', PUBLIC_REMOTE, 'master'],
['rev-parse', 'FETCH_HEAD'], ['rev-parse', 'FETCH_HEAD'],
['fetch', REMOTE, 'bundle/2.x'], ['fetch', REMOTE, 'bundle/2.x'],
@ -156,8 +142,6 @@ test('the public tip is read straight after its own fetch', () => {
test('a bundle branch that already contains its base is left alone', () => { test('a bundle branch that already contains its base is left alone', () => {
const git = makeStub([ const git = makeStub([
// Only the bundle-branch ancestry is overridden; the convergence probe keeps its own
// answer from baseGitRoutes, or this would pass without the guard being exercised.
[(a) => a[0] === 'merge-base' && a[3] === PRE_HEAD, ''], // --is-ancestor succeeds [(a) => a[0] === 'merge-base' && a[3] === PRE_HEAD, ''], // --is-ancestor succeeds
...baseGitRoutes, ...baseGitRoutes,
]); ]);
@ -226,9 +210,8 @@ test('a fix landing mid-run is retried from a fresh fetch, never forced', () =>
assert.deepEqual(result, { status: 'merged' }); assert.deepEqual(result, { status: 'merged' });
assert.equal(pushes, 2); assert.equal(pushes, 2);
// The retry re-fetches rather than reusing the tip it already merged onto — including the // The retry re-fetches both tips instead of reusing the merge that lost the push race.
// public tip, so the convergence guard is re-evaluated instead of carried over. assert.equal(git.calls.filter((a) => a[0] === 'fetch').length, 4);
assert.equal(git.calls.filter((a) => a[0] === 'fetch').length, 6);
assert.equal(git.calls.filter((a) => a[1] === PUBLIC_REMOTE).length, 2); assert.equal(git.calls.filter((a) => a[1] === PUBLIC_REMOTE).length, 2);
assert.equal( assert.equal(
git.calls.every((a) => !a.some((arg) => String(arg).includes('force-with-lease'))), git.calls.every((a) => !a.some((arg) => String(arg).includes('force-with-lease'))),
@ -244,22 +227,19 @@ test('a branch that keeps moving fails instead of forcing', () => {
}); });
}); });
test('a bundle branch that does not exist yet is created at its base', () => { test('a bundle branch that does not exist yet is created at the public base', () => {
const git = makeStub([[(a) => a[0] === 'ls-remote', ''], ...baseGitRoutes]); const git = makeStub([[(a) => a[0] === 'ls-remote', ''], ...baseGitRoutes]);
const result = syncBundleBranch({ git, env, log: silent }); const result = syncBundleBranch({ git, env, log: silent });
assert.deepEqual(result, { status: 'created' }); assert.deepEqual(result, { status: 'created' });
assert.deepEqual( assert.deepEqual(
git.calls.find((a) => a[0] === 'checkout'), git.calls.find((a) => a[0] === 'checkout'),
['checkout', '--force', '-B', 'bundle/2.x', BASE], ['checkout', '--force', '-B', 'bundle/2.x', PUBLIC],
); );
assert.equal(git.calls.some(isMerge), false); assert.equal(git.calls.some(isMerge), false);
assert.deepEqual( assert.deepEqual(
git.calls.filter((a) => a[0] === 'fetch'), git.calls.filter((a) => a[0] === 'fetch'),
[ [['fetch', PUBLIC_REMOTE, 'master']],
['fetch', REMOTE, 'master'],
['fetch', PUBLIC_REMOTE, 'master'],
],
); );
assert.deepEqual(git.calls.find(isPush), ['push', REMOTE, 'HEAD:refs/heads/bundle/2.x']); assert.deepEqual(git.calls.find(isPush), ['push', REMOTE, 'HEAD:refs/heads/bundle/2.x']);
}); });
@ -301,97 +281,6 @@ test('annotation keeps a multi-line message on one line', () => {
assert.equal(annotation('t', 'a\nb'), '::error title=t::a%0Ab'); assert.equal(annotation('t', 'a\nb'), '::error title=t::a%0Ab');
}); });
test('a base that has not reached the public repo is left alone', () => {
const git = makeStub([
...unpublishedRoutes('abc1234 chore: Bundle 2.x (#123)'),
...baseGitRoutes,
]);
const logs = [];
const result = syncBundleBranch({ git, env, log: (m) => logs.push(m) });
assert.deepEqual(result, { status: 'unconverged' });
// Nothing about the bundle branch is even asked: no existence probe, no fetch, no checkout.
assert.equal(
git.calls.some((a) => a[0] === 'ls-remote'),
false,
);
assert.equal(
git.calls.some((a) => a[0] === 'checkout'),
false,
);
assert.equal(git.calls.some(isMerge), false);
assert.equal(git.calls.some(isPush), false);
assert.equal(git.calls.filter((a) => a[0] === 'fetch').length, 2);
assert.match(logs.join('\n'), /has not reached public master/);
});
test('a missing bundle branch is not created from an unpublished base', () => {
const git = makeStub([
[(a) => a[0] === 'ls-remote', ''],
...unpublishedRoutes('abc1234 chore: Bundle/1.x'),
...baseGitRoutes,
]);
// One guard covers both paths: the branch must not be conjured onto a doomed commit either.
assert.deepEqual(syncBundleBranch({ git, env, log: silent }), { status: 'unconverged' });
assert.equal(
git.calls.some((a) => a[0] === 'checkout'),
false,
);
assert.equal(git.calls.some(isPush), false);
});
test('a base ahead of public by a non-bundle commit fails loudly', () => {
const git = makeStub([
...unpublishedRoutes('abc1234 fix(core): Something a human pushed directly'),
...baseGitRoutes,
]);
const logs = [];
assert.throws(() => syncBundleBranch({ git, env, log: (m) => logs.push(m) }), {
message: /master is ahead of public by commits that are not bundle cuts/,
});
assert.equal(git.calls.some(isPush), false);
// The annotation is the headline of a failed run: a count, never a subject.
const annotations = logs.filter((m) => m.startsWith('::error'));
assert.match(annotations.join('\n'), /carries 1 commit\(s\)/);
assert.doesNotMatch(annotations.join('\n'), /Something a human pushed directly/);
});
test('one stray commit among bundle cuts still fails', () => {
const git = makeStub([
...unpublishedRoutes('abc1234 chore: Bundle 2.x (#123)', 'def5678 fix(core): Stray'),
...baseGitRoutes,
]);
// All-or-nothing: a single unexplained commit means the mirror cannot clear the base.
assert.throws(() => syncBundleBranch({ git, env, log: silent }), {
message: /not bundle cuts/,
});
});
test('an unrelated history skips rather than forcing anything', () => {
const git = makeStub([...unpublishedRoutes(), ...baseGitRoutes]);
// Ancestry fails but the range is empty, so there is nothing to classify. Skipping is the
// only safe default here.
assert.deepEqual(syncBundleBranch({ git, env, log: silent }), { status: 'unconverged' });
assert.equal(git.calls.some(isPush), false);
});
test('an unconverged base is not retried as a push race', () => {
const git = makeStub([...unpublishedRoutes('abc1234 chore: Bundle 2.x'), ...baseGitRoutes]);
const logs = [];
syncBundleBranch({ git, env, log: (m) => logs.push(m) });
// Only 'rejected' earns a second attempt; the mirror runs hourly, not within this run.
assert.equal(git.calls.filter((a) => a[0] === 'fetch').length, 2);
assert.doesNotMatch(logs.join('\n'), /retrying/);
});
test('a public fetch that fails stops the run instead of guessing', () => { test('a public fetch that fails stops the run instead of guessing', () => {
const git = makeStub([ const git = makeStub([
[(a) => a[0] === 'fetch' && a[1] === PUBLIC_REMOTE, fail('could not read from remote')], [(a) => a[0] === 'fetch' && a[1] === PUBLIC_REMOTE, fail('could not read from remote')],
@ -423,7 +312,6 @@ test('the 1.x bundle branch is checked against public 1.x', () => {
assert.deepEqual( assert.deepEqual(
git.calls.filter((a) => a[0] === 'fetch'), git.calls.filter((a) => a[0] === 'fetch'),
[ [
['fetch', REMOTE, '1.x'],
['fetch', PUBLIC_REMOTE, '1.x'], ['fetch', PUBLIC_REMOTE, '1.x'],
['fetch', REMOTE, 'bundle/1.x'], ['fetch', REMOTE, 'bundle/1.x'],
], ],

34
.github/scripts/test-files.mjs vendored Normal file
View File

@ -0,0 +1,34 @@
import { matchesGlob } from './glob.mjs';
export const TEST_PATTERNS = [
// Test files (by extension)
'**/*.test.ts',
'**/*.test.js',
'**/*.test.mjs',
'**/*.spec.ts',
'**/*.spec.js',
'**/*.spec.mjs',
// Test directories
'**/test/**',
'**/tests/**',
'**/__tests__/**',
// Snapshots
'**/__snapshots__/**',
'**/*.snap',
// Fixtures and mocks
'**/fixtures/**',
'**/__mocks__/**',
// Former packages/testing workspaces
'packages/quality/policy/**',
'packages/quality/testing/**',
'packages/quality/environments/**',
'packages/quality/efficiency/microbenchmarks/**',
];
/**
* @param { string } filename
* @returns { boolean }
*/
export function isTestFile(filename) {
return TEST_PATTERNS.some((pattern) => matchesGlob(filename, pattern));
}

File diff suppressed because one or more lines are too long

View File

@ -32,11 +32,11 @@ jobs:
# when updating. # when updating.
include: include:
- node_version: '22' - node_version: '22'
dhi_ref: dhi.io/node:22.23.2-alpine3.24-dev@sha256:155a95d59244a71e9479e191ff718f03a7197d6829612e0707608be92988cb87 dhi_ref: dhi.io/node:22.23.3-alpine3.24-dev@sha256:23ee07ace431ea7d14e22c0e52fb52b0bd1853dabdacd89ba75f937f6dff8a8d
- node_version: '24.19.0' - node_version: '24.21.0'
dhi_ref: dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd dhi_ref: dhi.io/node:24.21.0-alpine3.24-dev@sha256:d22ba0e9ab2a54609ae533df4ebfd6f36c1f233b662a4c547f5a3195e8c21937
- node_version: '26.7.0' - node_version: '26.10.0'
dhi_ref: dhi.io/node:26.7.0-alpine3.24-dev@sha256:4b494d89fb26c950ce97865acf45b480dc7a6868fdc2b81c2d66599702eeac3f dhi_ref: dhi.io/node:26.10.0-alpine3.24-dev@sha256:8da859df5dc853c923ace53c4cfe994a909a28917f7fcfc8508869beab8cf132
steps: steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

View File

@ -6,7 +6,7 @@ on:
branches: branches:
- master - master
paths: paths:
- 'packages/@n8n/benchmark/**' - 'packages/quality/efficiency/scale/benchmark/**'
- 'pnpm-lock.yaml' - 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml' - 'pnpm-workspace.yaml'
- '.github/workflows/build-benchmark-image.yml' - '.github/workflows/build-benchmark-image.yml'
@ -33,7 +33,7 @@ jobs:
DOCKER_BUILD_SUMMARY: false DOCKER_BUILD_SUMMARY: false
with: with:
context: . context: .
file: ./packages/@n8n/benchmark/Dockerfile file: ./packages/quality/efficiency/scale/benchmark/Dockerfile
platforms: linux/amd64 platforms: linux/amd64
provenance: false provenance: false
push: true push: true

View File

@ -25,7 +25,7 @@ on:
type: boolean type: boolean
env: env:
NODE_VERSION: '26.7.0' NODE_VERSION: '26.10.0'
jobs: jobs:
build: build:

View File

@ -23,6 +23,7 @@ on:
paths: paths:
- '**/package.json' - '**/package.json'
- '**/turbo.json' - '**/turbo.json'
- 'packages/cli/scripts/build.mjs'
- '.github/workflows/build-windows.yml' - '.github/workflows/build-windows.yml'
- '.github/actions/setup-nodejs/**' - '.github/actions/setup-nodejs/**'

View File

@ -69,8 +69,8 @@ jobs:
steps: steps:
# Defaults for the CLA endpoints, status context, comment marker and label # Defaults for the CLA endpoints, status context, comment marker and label
# are already n8n's production values. # are already n8n's production values.
- uses: n8n-io/github-actions/cla-check@ea082925743265a61d9fd0a69a32b211551f88f0 # v1.0.2 - uses: n8n-io/github-actions/cla-check@ea082925743265a61d9fd0a69a32b211551f88f0 # v1.0.2
with: with:
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }} app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }} private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
pr-number: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number || github.event.issue.number }} pr-number: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number || github.event.issue.number }}

View File

@ -99,8 +99,8 @@ jobs:
mode: filter mode: filter
filters: | filters: |
janitor: janitor:
packages/testing/playwright/** packages/quality/testing/playwright/**
packages/testing/janitor/** packages/quality/testing/janitor/**
check-static-analysis: check-static-analysis:
name: Static Analysis name: Static Analysis

View File

@ -79,7 +79,8 @@ jobs:
!**/CHANGELOG.md !**/CHANGELOG.md
!**/*.test.ts !**/*.test.ts
!**/*.spec.ts !**/*.spec.ts
!packages/testing/playwright/** !packages/quality/testing/playwright/**
!packages/quality/efficiency/**
!packages/frontend/@n8n/storybook/** !packages/frontend/@n8n/storybook/**
!.devcontainer/** !.devcontainer/**
!scripts/agent-setup.mjs !scripts/agent-setup.mjs
@ -92,7 +93,7 @@ jobs:
unit: unit:
** **
!packages/@n8n/task-runner-python/** !packages/@n8n/task-runner-python/**
!packages/testing/playwright/** !packages/quality/testing/playwright/**
!.github/** !.github/**
.github/workflows/test-unit-reusable.yml .github/workflows/test-unit-reusable.yml
!**/*.md !**/*.md
@ -111,8 +112,8 @@ jobs:
.github/workflows/prepare-docker-reusable.yml .github/workflows/prepare-docker-reusable.yml
.github/actions/build-n8n-docker/** .github/actions/build-n8n-docker/**
.github/actions/load-n8n-docker/** .github/actions/load-n8n-docker/**
packages/testing/playwright/** packages/quality/testing/playwright/**
packages/testing/containers/** packages/quality/environments/containers/**
dev-server-smoke: dev-server-smoke:
packages/frontend/editor-ui/vite.config.mts packages/frontend/editor-ui/vite.config.mts
# If this job becomes too slow, use a smaller glob. Do not delete the assertion. # If this job becomes too slow, use a smaller glob. Do not delete the assertion.
@ -120,10 +121,10 @@ jobs:
pnpm-workspace.yaml pnpm-workspace.yaml
packages/@n8n/*/package.json packages/@n8n/*/package.json
packages/frontend/@n8n/frontend-vite-config/** packages/frontend/@n8n/frontend-vite-config/**
packages/testing/playwright/tests/dev-server-smoke/** packages/quality/testing/playwright/tests/dev-server-smoke/**
packages/testing/playwright/playwright.config.ts packages/quality/testing/playwright/playwright.config.ts
packages/testing/playwright/playwright-projects.ts packages/quality/testing/playwright/playwright-projects.ts
packages/testing/playwright/package.json packages/quality/testing/playwright/package.json
.github/workflows/test-dev-server-smoke-reusable.yml .github/workflows/test-dev-server-smoke-reusable.yml
frontend-declarations: frontend-declarations:
packages/frontend/@n8n/design-system/** packages/frontend/@n8n/design-system/**
@ -146,10 +147,17 @@ jobs:
cubic.yaml cubic.yaml
.agents/review-rules/** .agents/review-rules/**
e2e-performance: e2e-performance:
packages/testing/playwright/tests/performance/** packages/quality/efficiency/memory/idle/**
packages/testing/playwright/utils/performance-helper.ts packages/quality/efficiency/playwright.config.ts
packages/testing/containers/** packages/quality/efficiency/package.json
packages/quality/testing/playwright/package.json
packages/quality/testing/playwright/quality-*.ts
packages/quality/testing/playwright/fixtures/**
packages/quality/testing/playwright/tests/performance/**
packages/quality/testing/playwright/utils/performance-helper.ts
packages/quality/environments/containers/**
.github/workflows/test-e2e-performance-reusable.yml .github/workflows/test-e2e-performance-reusable.yml
.github/workflows/test-e2e-reusable.yml
# Whole directories, not the `engine-*` files alone. Engine v2 # Whole directories, not the `engine-*` files alone. Engine v2
# routing lives in ordinary control plane code: `workflow-runner.ts` # routing lives in ordinary control plane code: `workflow-runner.ts`
# and the webhook and trigger paths decide whether a run reaches the # and the webhook and trigger paths decide whether a run reaches the
@ -169,8 +177,8 @@ jobs:
packages/cli/src/webhooks/** packages/cli/src/webhooks/**
packages/cli/src/workflows/triggers/** packages/cli/src/workflows/triggers/**
packages/cli/src/workflow-runner.ts packages/cli/src/workflow-runner.ts
packages/testing/containers/** packages/quality/environments/containers/**
packages/testing/playwright/** packages/quality/testing/playwright/**
instance-ai-workflow-eval: instance-ai-workflow-eval:
packages/@n8n/instance-ai/src/** packages/@n8n/instance-ai/src/**
packages/@n8n/instance-ai/evaluations/** packages/@n8n/instance-ai/evaluations/**
@ -178,6 +186,7 @@ jobs:
packages/core/src/execution-engine/eval-mock-helpers.ts packages/core/src/execution-engine/eval-mock-helpers.ts
.github/workflows/test-evals-discovery.yml .github/workflows/test-evals-discovery.yml
db: db:
packages/modules/*/backend/**
packages/cli/src/databases/** packages/cli/src/databases/**
packages/cli/src/modules/*/database/** packages/cli/src/modules/*/database/**
packages/cli/src/modules/**/*.entity.ts packages/cli/src/modules/**/*.entity.ts
@ -185,18 +194,19 @@ jobs:
packages/cli/test/integration/** packages/cli/test/integration/**
packages/cli/test/migration/** packages/cli/test/migration/**
packages/cli/test/shared/db/** packages/cli/test/shared/db/**
packages/cli/test/setup-testcontainers.js packages/cli/test/setup-testcontainers.ts
packages/cli/test/teardown-testcontainers.js
packages/@n8n/db/** packages/@n8n/db/**
packages/@n8n/backend-test-utils/** packages/@n8n/backend-test-utils/**
packages/@n8n/scheduler/src/** packages/@n8n/scheduler/src/**
packages/cli/src/scheduling/**
packages/cli/src/**/*.integration.test.ts packages/cli/src/**/*.integration.test.ts
packages/cli/src/modules/instance-registry/** packages/cli/src/modules/instance-registry/**
packages/cli/vitest.* packages/cli/vitest.*
packages/testing/containers/services/postgres.ts packages/quality/environments/containers/services/postgres.ts
packages/testing/containers/services/redis.ts packages/quality/environments/containers/services/redis.ts
packages/testing/containers/postgres-versions.json packages/quality/environments/containers/test-db-global-setup.ts
packages/testing/containers/test-containers.ts packages/quality/environments/containers/postgres-versions.json
packages/quality/environments/containers/test-containers.ts
.github/workflows/test-db-reusable.yml .github/workflows/test-db-reusable.yml
.github/scripts/db-test-matrix.mjs .github/scripts/db-test-matrix.mjs
docs/generated/** docs/generated/**
@ -209,15 +219,14 @@ jobs:
packages/@n8n/backend-test-utils/** packages/@n8n/backend-test-utils/**
packages/cli/test/migration/** packages/cli/test/migration/**
packages/cli/test/shared/db/** packages/cli/test/shared/db/**
packages/cli/test/setup-testcontainers.js packages/cli/test/setup-testcontainers.ts
packages/cli/test/teardown-testcontainers.js
packages/cli/vitest.config.base.ts packages/cli/vitest.config.base.ts
packages/cli/vitest.config.migration.ts packages/cli/vitest.config.migration.ts
packages/cli/vitest.config.migration.testcontainers.ts packages/cli/vitest.config.migration.testcontainers.ts
packages/testing/containers/services/postgres.ts packages/quality/environments/containers/services/postgres.ts
packages/testing/containers/services/redis.ts packages/quality/environments/containers/services/redis.ts
packages/testing/containers/postgres-versions.json packages/quality/environments/containers/postgres-versions.json
packages/testing/containers/test-containers.ts packages/quality/environments/containers/test-containers.ts
.github/workflows/test-db-reusable.yml .github/workflows/test-db-reusable.yml
.github/scripts/db-test-matrix.mjs .github/scripts/db-test-matrix.mjs
@ -247,7 +256,7 @@ jobs:
env: env:
CHANGED_FILES: ${{ steps.ci-filter.outputs.changed-files }} CHANGED_FILES: ${{ steps.ci-filter.outputs.changed-files }}
run: | run: |
PACKAGES=$(node packages/testing/janitor/dist/cli.js affected-packages | tr '\n' ' ' | sed 's/ *$//') PACKAGES=$(node packages/quality/testing/janitor/dist/cli.js affected-packages | tr '\n' ' ' | sed 's/ *$//')
echo "Affected packages: $PACKAGES" echo "Affected packages: $PACKAGES"
echo "list=$PACKAGES" >> "$GITHUB_OUTPUT" echo "list=$PACKAGES" >> "$GITHUB_OUTPUT"
@ -393,7 +402,7 @@ jobs:
PLAYWRIGHT_PROJECT: ${{ github.event.pull_request.head.repo.fork == true && 'sqlite:e2e' || 'multi-main:e2e' }} PLAYWRIGHT_PROJECT: ${{ github.event.pull_request.head.repo.fork == true && 'sqlite:e2e' || 'multi-main:e2e' }}
run: | run: |
FILES_CSV=$(echo "$CHANGED_FILES" | tr '\n' ',' | sed 's/,$//') FILES_CSV=$(echo "$CHANGED_FILES" | tr '\n' ',' | sed 's/,$//')
MATRIX=$(node packages/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --impact "--project=$PLAYWRIGHT_PROJECT" "--files=$FILES_CSV" "--base=$MERGE_BASE") MATRIX=$(node packages/quality/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --impact "--project=$PLAYWRIGHT_PROJECT" "--files=$FILES_CSV" "--base=$MERGE_BASE")
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
echo "skip-tests=$(node -e "process.stdout.write(JSON.parse(process.argv[1])[0]?.skip === true ? 'true' : 'false')" "$MATRIX")" >> "$GITHUB_OUTPUT" echo "skip-tests=$(node -e "process.stdout.write(JSON.parse(process.argv[1])[0]?.skip === true ? 'true' : 'false')" "$MATRIX")" >> "$GITHUB_OUTPUT"

View File

@ -3,7 +3,7 @@ name: 'CI: Terraform'
on: on:
pull_request: pull_request:
paths: paths:
- packages/@n8n/benchmark/infra/** - packages/quality/efficiency/scale/benchmark/infra/**
- .github/workflows/ci-terraform.yml - .github/workflows/ci-terraform.yml
# The job only reads the repo and runs terraform. It writes nothing. # The job only reads the repo and runs terraform. It writes nothing.
@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
defaults: defaults:
run: run:
working-directory: packages/@n8n/benchmark/infra working-directory: packages/quality/efficiency/scale/benchmark/infra
steps: steps:
- name: Check out project - name: Check out project
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

View File

@ -8,7 +8,7 @@ run-name: "${{ github.event_name == 'workflow_dispatch' && format('Docker: Build
env: env:
NODE_OPTIONS: '--max-old-space-size=7168' NODE_OPTIONS: '--max-old-space-size=7168'
NODE_VERSION: '26.7.0' NODE_VERSION: '26.10.0'
on: on:
schedule: schedule:

View File

@ -12,7 +12,7 @@ env:
# The images copy native bindings from the host build, so both have to use the same # The images copy native bindings from the host build, so both have to use the same
# Node. dockerize-n8n.mjs reads this env for the image builds. Keep in sync with # Node. dockerize-n8n.mjs reads this env for the image builds. Keep in sync with
# NODE_VERSION in docker-build-push.yml, which is what the published images use. # NODE_VERSION in docker-build-push.yml, which is what the published images use.
NODE_VERSION: '26.7.0' NODE_VERSION: '26.10.0'
# Also build the distroless runners image and exec-check # Also build the distroless runners image and exec-check
# both runners images' interpreters, so a broken runtime assembly (e.g. a # both runners images' interpreters, so a broken runtime assembly (e.g. a
# missing shared library after a Node bump) fails at PR time. The smoke # missing shared library after a Node bump) fails at PR time. The smoke

View File

@ -19,7 +19,7 @@ on:
default: false default: false
env: env:
NODE_VERSION: '26.7.0' NODE_VERSION: '26.10.0'
SCRATCH_TAG: sbom-probe-${{ github.run_id }} SCRATCH_TAG: sbom-probe-${{ github.run_id }}
# A separate package. These are throwaway fixtures (one is a two-layer # A separate package. These are throwaway fixtures (one is a two-layer
# alpine), and ghcr.io/<repo> is where the real release tags live - they # alpine), and ghcr.io/<repo> is where the real release tags live - they

View File

@ -29,10 +29,10 @@ on:
# verify themselves (both modes) before the merge. # verify themselves (both modes) before the merge.
pull_request: pull_request:
paths: paths:
- 'packages/testing/playwright/tests/infrastructure/encryption/**' - 'packages/quality/testing/playwright/tests/infrastructure/encryption/**'
- 'packages/testing/containers/services/n8n.ts' - 'packages/quality/environments/containers/services/n8n.ts'
- 'packages/testing/containers/services/types.ts' - 'packages/quality/environments/containers/services/types.ts'
- 'packages/testing/containers/stack.ts' - 'packages/quality/environments/containers/stack.ts'
- '.github/workflows/encryption-upgrade-test.yml' - '.github/workflows/encryption-upgrade-test.yml'
permissions: permissions:

309
.github/workflows/jscpd.yml vendored Normal file
View File

@ -0,0 +1,309 @@
# 🍝 jscpd — deterministic copy-paste/duplication scan.
#
# Runs jscpd against this repo and uploads the full JSON+HTML report, plus
# the report split into BUCKET_COUNT small JSON files, so a caller can
# download one small bucket at random per invocation instead of the full
# report (which can run into tens of MB on a monorepo this size).
#
# Reporters/ignores/threshold come from this repo's own .jscpd.json; this
# workflow passes none of those flags itself.
name: 🍝 jscpd
on:
workflow_dispatch:
permissions:
contents: read
env:
# Number of small sample files the report is split into (split-jscpd-report.mjs).
# Fixed, not an input: changing it means adding/removing the matching
# per-bucket upload steps below, so it's a code change, not a dispatch option.
BUCKET_COUNT: '20'
jobs:
jscpd:
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-4vcpu-ubuntu-2204' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
persist-credentials: false
- name: Setup Node.js and install dependencies
uses: ./.github/actions/setup-nodejs
with:
build-command: ''
- name: Run jscpd
id: jscpd
continue-on-error: true
run: |
mkdir -p "$RUNNER_TEMP/jscpd-report"
pnpm jscpd -- . --output "$RUNNER_TEMP/jscpd-report" --silent
- name: Upload jscpd report
id: report-artifact
if: always()
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-report-${{ github.run_id }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/jscpd-report
retention-days: 31
if-no-files-found: warn
# jscpd exits non-zero once duplication crosses .jscpd.json's threshold,
# but still writes the report first. Gating the split on the report
# file existing (not on steps.jscpd.outcome) means an over-threshold
# run still gets its buckets instead of silently dropping all of them.
- name: Check jscpd report exists
id: report-exists
if: always()
run: |
if [ -f "$RUNNER_TEMP/jscpd-report/jscpd-report.json" ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
# Splits `duplicates` into BUCKET_COUNT files so a caller can download
# one small sample instead of the full report (tens of MB on a large
# monorepo). Logic + tests live in split-jscpd-report.mjs.
- name: Split report into buckets
id: split
if: always() && steps.report-exists.outputs.exists == 'true'
continue-on-error: true
env:
REPORT_PATH: ${{ runner.temp }}/jscpd-report/jscpd-report.json
OUTPUT_DIR: ${{ runner.temp }}/jscpd-buckets
run: node .github/scripts/split-jscpd-report.mjs
# BUCKET_COUNT static upload steps, one per bucket file: GitHub Actions
# has no per-job step loop, and each bucket needs its own small
# artifact (not one artifact holding all of them) so a caller can
# fetch a single sample without pulling the rest. Keep this block's
# step count in sync with BUCKET_COUNT above.
- name: Upload jscpd bucket 0
id: bucket-artifact-0
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-0
path: ${{ runner.temp }}/jscpd-buckets/bucket-0.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 1
id: bucket-artifact-1
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-1
path: ${{ runner.temp }}/jscpd-buckets/bucket-1.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 2
id: bucket-artifact-2
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-2
path: ${{ runner.temp }}/jscpd-buckets/bucket-2.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 3
id: bucket-artifact-3
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-3
path: ${{ runner.temp }}/jscpd-buckets/bucket-3.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 4
id: bucket-artifact-4
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-4
path: ${{ runner.temp }}/jscpd-buckets/bucket-4.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 5
id: bucket-artifact-5
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-5
path: ${{ runner.temp }}/jscpd-buckets/bucket-5.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 6
id: bucket-artifact-6
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-6
path: ${{ runner.temp }}/jscpd-buckets/bucket-6.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 7
id: bucket-artifact-7
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-7
path: ${{ runner.temp }}/jscpd-buckets/bucket-7.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 8
id: bucket-artifact-8
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-8
path: ${{ runner.temp }}/jscpd-buckets/bucket-8.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 9
id: bucket-artifact-9
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-9
path: ${{ runner.temp }}/jscpd-buckets/bucket-9.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 10
id: bucket-artifact-10
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-10
path: ${{ runner.temp }}/jscpd-buckets/bucket-10.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 11
id: bucket-artifact-11
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-11
path: ${{ runner.temp }}/jscpd-buckets/bucket-11.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 12
id: bucket-artifact-12
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-12
path: ${{ runner.temp }}/jscpd-buckets/bucket-12.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 13
id: bucket-artifact-13
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-13
path: ${{ runner.temp }}/jscpd-buckets/bucket-13.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 14
id: bucket-artifact-14
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-14
path: ${{ runner.temp }}/jscpd-buckets/bucket-14.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 15
id: bucket-artifact-15
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-15
path: ${{ runner.temp }}/jscpd-buckets/bucket-15.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 16
id: bucket-artifact-16
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-16
path: ${{ runner.temp }}/jscpd-buckets/bucket-16.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 17
id: bucket-artifact-17
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-17
path: ${{ runner.temp }}/jscpd-buckets/bucket-17.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 18
id: bucket-artifact-18
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-18
path: ${{ runner.temp }}/jscpd-buckets/bucket-18.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 19
id: bucket-artifact-19
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-19
path: ${{ runner.temp }}/jscpd-buckets/bucket-19.json
retention-days: 31
if-no-files-found: error

View File

@ -9,6 +9,16 @@ name: 'Prepare n8n Docker (reusable)'
on: on:
workflow_call: workflow_call:
secrets:
QA_METRICS_WEBHOOK_URL:
description: 'QA metrics webhook URL.'
required: false
QA_METRICS_WEBHOOK_USER:
description: 'QA metrics webhook username.'
required: false
QA_METRICS_WEBHOOK_PASSWORD:
description: 'QA metrics webhook password.'
required: false
inputs: inputs:
build-variant: build-variant:
description: 'standard, coverage, or pc' description: 'standard, coverage, or pc'

View File

@ -68,4 +68,4 @@ jobs:
run: | run: |
node .github/scripts/slack/notify.mjs \ node .github/scripts/slack/notify.mjs \
--channel '#alerts-security' \ --channel '#alerts-security' \
--text 'Security fix PR creation failed (1.x). Run "Security: Sync from Public" workflow, rebase your branch, reopen PR. (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})' --text 'Security fix PR creation failed (1.x). Run "Security: Sync from Public", merge the refreshed bundle branch into the fix branches, and reopen the bundle PR. (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})'

View File

@ -58,4 +58,4 @@ jobs:
run: | run: |
node .github/scripts/slack/notify.mjs \ node .github/scripts/slack/notify.mjs \
--channel '#alerts-security' \ --channel '#alerts-security' \
--text 'Security fix PR creation failed. Run "Security: Sync from Public" workflow, rebase your branch, reopen PR. (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})' --text 'Security fix PR creation failed. Run "Security: Sync from Public", merge the refreshed bundle branch into the fix branches, and reopen the bundle PR. (${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})'

View File

@ -1,8 +1,8 @@
# Keeps the bundle integration branches in sync with their base, in n8n-io/n8n-private. # Keeps the bundle integration branches in sync with their base, in n8n-io/n8n-private.
# #
# Fixes are integrated on bundle/2.x and bundle/1.x and eventually merged into private # Fixes are integrated on bundle/2.x and bundle/1.x and eventually merged into private
# master/1.x as a squashed `chore: Bundle/*` PR. Those branches must not drift from their # master/1.x as a squashed `chore: Bundle/*` PR. Each bundle branch tracks its public base
# base, or the bundle cut turns into a conflict-resolution session. # directly, so a private-only bundle cut can never become part of the next bundle branch.
# #
# The base is MERGED IN, never replayed: these branches receive PRs, and rewriting a branch # The base is MERGED IN, never replayed: these branches receive PRs, and rewriting a branch
# that receives PRs orphans the commits its PR branches already hold — each such PR then shows # that receives PRs orphans the commits its PR branches already hold — each such PR then shows
@ -12,18 +12,11 @@
# Every push is verified to carry exactly the tree a merge would produce. See # Every push is verified to carry exactly the tree a merge would produce. See
# sync-bundle-branch.mjs. # sync-bundle-branch.mjs.
# #
# Daily rather than hourly on purpose: a base force-push never re-triggered CI on the fix PRs, # Runs nightly at 03:00 UTC. Maintainers can also dispatch it before a bundle cut or when a
# so a faster cadence bought them nothing while re-running the full suite on the cut PR (whose # bundle branch needs to be synced sooner.
# head is the bundle branch). A merged fix and a manual dispatch before a cut are the moments
# that matter.
#
# Only published history is synced in. A cut leaves a private-only `chore: Bundle/*` commit on
# private master that the hourly public→private mirror later discards for the public copy, so a
# run in that window skips instead of building the branch on it — a dispatch or a merged fix PR
# right after a cut can legitimately do nothing. See sync-bundle-branch.mjs.
# #
# One job per bundle branch: a conflict on one FAILS THAT JOB and leaves its branch untouched, # One job per bundle branch: a conflict on one FAILS THAT JOB and leaves its branch untouched,
# while the other still syncs. Recovery is manual and deliberate — merge the base in locally, # while the other still syncs. Recovery is manual and deliberate — merge the public base locally,
# resolve, push, then re-run this workflow. That resolution then lives in the merge commit, # resolve, push, then re-run this workflow. That resolution then lives in the merge commit,
# instead of being re-litigated on every later run. # instead of being re-litigated on every later run.
@ -32,11 +25,6 @@ name: 'Security: Sync Bundle Branches'
on: on:
schedule: schedule:
- cron: '0 3 * * *' - cron: '0 3 * * *'
pull_request: # a fix landing on a bundle branch is when freshness matters most
types: [closed]
branches:
- 'bundle/2.x'
- 'bundle/1.x'
workflow_dispatch: workflow_dispatch:
# Least privilege by default; the sync job opts into exactly what it needs. # Least privilege by default; the sync job opts into exactly what it needs.
@ -45,9 +33,7 @@ permissions: {}
jobs: jobs:
sync: sync:
name: Sync ${{ matrix.bundle }} name: Sync ${{ matrix.bundle }}
if: | if: github.repository == 'n8n-io/n8n-private'
github.repository == 'n8n-io/n8n-private' &&
(github.event_name != 'pull_request' || github.event.pull_request.merged == true)
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
@ -75,17 +61,12 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
# Always run the script from the default branch, never from a pull_request merge # Always run the script from the default branch. The sync fetches both branches itself.
# ref — the sync holds a contents:write token and fetches what it needs itself,
# so the checked-out branch is irrelevant beyond supplying trusted code.
ref: master ref: master
fetch-depth: 0 fetch-depth: 0
persist-credentials: false # we push with an explicit token URL instead persist-credentials: false # we push with an explicit token URL instead
- name: Merge the base into the bundle branch - name: Merge the base into the bundle branch
# On a merged bundle PR, only the branch that received it needs syncing.
# (`matrix` is not available in a job-level `if`, so the filter lives here.)
if: github.event_name != 'pull_request' || github.event.pull_request.base.ref == matrix.bundle
env: env:
GH_TOKEN: ${{ steps.app-token.outputs.token }} GH_TOKEN: ${{ steps.app-token.outputs.token }}
BUNDLE_BRANCH: ${{ matrix.bundle }} BUNDLE_BRANCH: ${{ matrix.bundle }}

View File

@ -7,10 +7,6 @@
# Manual runs always sync (for conflict recovery after failed cherry-pick). # Manual runs always sync (for conflict recovery after failed cherry-pick).
# #
# A skipped branch or a hard failure is reported to #alerts-build. # A skipped branch or a hard failure is reported to #alerts-build.
#
# The bundle/* integration branches are kept current by sec-sync-bundle-branches.yml, which
# depends on this mirror: it refuses to build a bundle branch on a base commit the public repo
# does not have yet. So while this workflow is stuck, bundle syncing is stuck too.
name: 'Security: Sync from Public' name: 'Security: Sync from Public'
run-name: "${{ github.event_name == 'workflow_dispatch' && format('Security: Sync from Public (force={0})', inputs.force) || '' }}" run-name: "${{ github.event_name == 'workflow_dispatch' && format('Security: Sync from Public (force={0})', inputs.force) || '' }}"
@ -31,7 +27,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
actions: write
steps: steps:
- name: Generate App Token - name: Generate App Token
@ -104,28 +99,6 @@ jobs:
git reset --hard public-1.x git reset --hard public-1.x
git push origin 1.x --force-with-lease git push origin 1.x --force-with-lease
# Dispatch only: the bundle sync creates the branch and moves its PRs back onto it.
- name: Dispatch re-creation of missing bundle branches
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
EXISTING=$(git ls-remote --heads origin 'refs/heads/bundle/*')
MISSING=()
for BRANCH in bundle/2.x bundle/1.x; do
if ! grep -qF "refs/heads/$BRANCH" <<<"$EXISTING"; then
MISSING+=("$BRANCH")
fi
done
if [ ${#MISSING[@]} -eq 0 ]; then
echo 'Both bundle branches exist; nothing to dispatch.'
exit 0
fi
echo "Missing: ${MISSING[*]} - dispatching Security: Sync Bundle Branches"
gh workflow run sec-sync-bundle-branches.yml --ref master
- name: Notify Slack on failure - name: Notify Slack on failure
if: failure() if: failure()
env: env:

View File

@ -36,4 +36,4 @@ jobs:
- name: Destroy cloud env - name: Destroy cloud env
run: pnpm destroy-cloud-env run: pnpm destroy-cloud-env
working-directory: packages/@n8n/benchmark working-directory: packages/quality/efficiency/scale/benchmark

View File

@ -62,11 +62,11 @@ jobs:
- name: Destroy any existing environment - name: Destroy any existing environment
run: pnpm destroy-cloud-env run: pnpm destroy-cloud-env
working-directory: packages/@n8n/benchmark working-directory: packages/quality/efficiency/scale/benchmark
- name: Provision the environment - name: Provision the environment
run: pnpm provision-cloud-env ${{ env.DEBUG }} run: pnpm provision-cloud-env ${{ env.DEBUG }}
working-directory: packages/@n8n/benchmark working-directory: packages/quality/efficiency/scale/benchmark
- name: Run the benchmark - name: Run the benchmark
id: benchmark id: benchmark
@ -81,7 +81,7 @@ jobs:
--n8nTag ${{ env.N8N_TAG }} \ --n8nTag ${{ env.N8N_TAG }} \
--benchmarkTag ${{ env.N8N_BENCHMARK_TAG }} \ --benchmarkTag ${{ env.N8N_BENCHMARK_TAG }} \
${{ env.DEBUG }} ${{ env.DEBUG }}
working-directory: packages/@n8n/benchmark working-directory: packages/quality/efficiency/scale/benchmark
# We need to login again because the access token expires # We need to login again because the access token expires
- name: Azure login - name: Azure login
@ -95,7 +95,7 @@ jobs:
- name: Destroy the environment - name: Destroy the environment
if: always() if: always()
run: pnpm destroy-cloud-env ${{ env.DEBUG }} run: pnpm destroy-cloud-env ${{ env.DEBUG }}
working-directory: packages/@n8n/benchmark working-directory: packages/quality/efficiency/scale/benchmark
- name: Fail `build` job if `benchmark` step failed - name: Fail `build` job if `benchmark` step failed
if: steps.benchmark.outcome == 'failure' if: steps.benchmark.outcome == 'failure'

View File

@ -55,6 +55,13 @@ jobs:
working-directory: packages/cli working-directory: packages/cli
run: ${{ matrix.test-cmd }} run: ${{ matrix.test-cmd }}
# A packaged backend module opts in by defining `test:postgres`.
- name: Run packaged backend module PostgreSQL tests
if: matrix.TEST_IMAGE_POSTGRES != ''
env:
COVERAGE_ENABLED: 'false'
run: pnpm --filter './packages/modules/*/backend' --if-present run test:postgres --maxWorkers=100%
# Regenerates the schema docs for this leg's database (sqlite temp file / # Regenerates the schema docs for this leg's database (sqlite temp file /
# postgres testcontainer) and fails if they differ from what's committed. # postgres testcontainer) and fails if they differ from what's committed.
# tbls runs as a Docker image in CI. # tbls runs as a Docker image in CI.

View File

@ -10,7 +10,7 @@ on:
env: env:
NODE_OPTIONS: '--max-old-space-size=6144' NODE_OPTIONS: '--max-old-space-size=6144'
PLAYWRIGHT_BROWSERS_PATH: packages/testing/playwright/.playwright-browsers PLAYWRIGHT_BROWSERS_PATH: packages/quality/testing/playwright/.playwright-browsers
jobs: jobs:
smoke: smoke:
@ -53,6 +53,6 @@ jobs:
with: with:
name: dev-server-smoke-report name: dev-server-smoke-report
path: | path: |
packages/testing/playwright/test-results/ packages/quality/testing/playwright/test-results/
packages/testing/playwright/playwright-report/ packages/quality/testing/playwright/playwright-report/
retention-days: 7 retention-days: 7

View File

@ -53,7 +53,7 @@ jobs:
- name: Generate matrix (up to 20 shards, duration-weighted) - name: Generate matrix (up to 20 shards, duration-weighted)
id: gen id: gen
run: | run: |
MATRIX=$(node packages/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --project=coverage) MATRIX=$(node packages/quality/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --project=coverage)
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
e2e: e2e:
@ -215,7 +215,7 @@ jobs:
# Merges all lcovs into one lcov.info (SF: paths normalised to repo-root- # Merges all lcovs into one lcov.info (SF: paths normalised to repo-root-
# relative) and builds the per-spec E2E impact map for PR selection. # relative) and builds the per-spec E2E impact map for PR selection.
- name: Aggregate coverage + build impact map - name: Aggregate coverage + build impact map
working-directory: packages/testing/playwright working-directory: packages/quality/testing/playwright
run: | run: |
node scripts/aggregate-coverage.mjs \ node scripts/aggregate-coverage.mjs \
--shards=/tmp/shards \ --shards=/tmp/shards \
@ -227,7 +227,7 @@ jobs:
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: coverage-report name: coverage-report
path: packages/testing/playwright/coverage/ path: packages/quality/testing/playwright/coverage/
retention-days: 14 retention-days: 14
- name: Upload Combined Coverage to Codecov - name: Upload Combined Coverage to Codecov
@ -235,7 +235,7 @@ jobs:
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
files: packages/testing/playwright/coverage/lcov.info files: packages/quality/testing/playwright/coverage/lcov.info
flags: nightly-full flags: nightly-full
name: nightly-full-coverage name: nightly-full-coverage
fail_ci_if_error: false fail_ci_if_error: false
@ -256,7 +256,7 @@ jobs:
env: env:
CODECOV_API_TOKEN: ${{ secrets.CODECOV_API_TOKEN }} CODECOV_API_TOKEN: ${{ secrets.CODECOV_API_TOKEN }}
run: | run: |
node packages/testing/playwright/scripts/coverage-analysis.mjs \ node packages/quality/testing/playwright/scripts/coverage-analysis.mjs \
--md --top=15 --out-json=coverage-gaps.json >> "$GITHUB_STEP_SUMMARY" --md --top=15 --out-json=coverage-gaps.json >> "$GITHUB_STEP_SUMMARY"
- name: Upload Coverage Gap Report - name: Upload Coverage Gap Report

View File

@ -5,8 +5,8 @@ on:
pull_request: pull_request:
paths: paths:
- '.github/workflows/test-e2e-helm.yml' - '.github/workflows/test-e2e-helm.yml'
- 'packages/testing/containers/helm-stack.ts' - 'packages/quality/environments/containers/helm-stack.ts'
- 'packages/testing/containers/helm-start-stack.ts' - 'packages/quality/environments/containers/helm-start-stack.ts'
workflow_dispatch: workflow_dispatch:
inputs: inputs:
branch: branch:
@ -83,7 +83,7 @@ jobs:
build-command: 'pnpm build' build-command: 'pnpm build'
- name: Install Browsers - name: Install Browsers
working-directory: packages/testing/playwright working-directory: packages/quality/testing/playwright
run: pnpm exec playwright install chromium run: pnpm exec playwright install chromium
- name: Install Helm - name: Install Helm
@ -115,7 +115,7 @@ jobs:
echo "KUBECONFIG=${KUBECONFIG_PATH}" >> "$GITHUB_ENV" echo "KUBECONFIG=${KUBECONFIG_PATH}" >> "$GITHUB_ENV"
- name: Run Building Blocks E2E Tests - name: Run Building Blocks E2E Tests
working-directory: packages/testing/playwright working-directory: packages/quality/testing/playwright
run: | run: |
N8N_BASE_URL="${{ env.N8N_BASE_URL }}" \ N8N_BASE_URL="${{ env.N8N_BASE_URL }}" \
RESET_E2E_DB=true \ RESET_E2E_DB=true \
@ -150,8 +150,8 @@ jobs:
with: with:
name: helm-e2e-report-${{ inputs.mode || 'queue' }} name: helm-e2e-report-${{ inputs.mode || 'queue' }}
path: | path: |
packages/testing/playwright/test-results/ packages/quality/testing/playwright/test-results/
packages/testing/playwright/playwright-report/ packages/quality/testing/playwright/playwright-report/
retention-days: 7 retention-days: 7
cleanup-ghcr: cleanup-ghcr:

View File

@ -74,7 +74,7 @@ jobs:
# The aggregator auto-detects n8n version and commit SHA from the repo # The aggregator auto-detects n8n version and commit SHA from the repo
# (anchored to its own file location), so no path/version glue is needed. # (anchored to its own file location), so no path/version glue is needed.
- name: Aggregate sizing matrix - name: Aggregate sizing matrix
working-directory: packages/testing/playwright working-directory: packages/quality/testing/playwright
run: | run: |
pnpm exec tsx scripts/sizing-matrix-aggregate.ts \ pnpm exec tsx scripts/sizing-matrix-aggregate.ts \
--input /tmp/benchmark-reports \ --input /tmp/benchmark-reports \
@ -86,8 +86,8 @@ jobs:
with: with:
name: sizing-matrix name: sizing-matrix
path: | path: |
packages/testing/playwright/sizing-matrix.json packages/quality/testing/playwright/sizing-matrix.json
packages/testing/playwright/sizing-matrix.md packages/quality/testing/playwright/sizing-matrix.md
retention-days: 14 retention-days: 14
if-no-files-found: error if-no-files-found: error

View File

@ -77,7 +77,7 @@ jobs:
- name: Generate matrix (up to 20 shards, duration-weighted) - name: Generate matrix (up to 20 shards, duration-weighted)
id: gen id: gen
run: | run: |
MATRIX=$(node packages/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --project=sqlite:e2e) MATRIX=$(node packages/quality/testing/playwright/scripts/distribute-tests.mjs --matrix 20 --orchestrate --project=sqlite:e2e)
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
e2e: e2e:

View File

@ -1,5 +1,8 @@
name: 'Test: E2E Performance' name: 'Test: E2E Performance'
permissions:
contents: read
on: on:
workflow_call: workflow_call:
workflow_dispatch: workflow_dispatch:
@ -24,6 +27,17 @@ jobs:
artifact-prefix: performance artifact-prefix: performance
secrets: inherit secrets: inherit
idle-memory-baselines:
needs: [prepare-docker]
uses: ./.github/workflows/test-e2e-reusable.yml
with:
test-mode: docker-artifact
test-command: pnpm --filter=@n8n/efficiency test:memory
workers: '1'
currents-project-id: 'O9BJaN'
artifact-prefix: memory-performance
secrets: inherit
canvas-perf-sentinels: canvas-perf-sentinels:
name: Canvas Perf Sentinels name: Canvas Perf Sentinels
# Sentinels are nightly only — wall-clock browser perf has 15-30% variance, # Sentinels are nightly only — wall-clock browser perf has 15-30% variance,
@ -37,7 +51,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
sparse-checkout: packages/testing/playwright/scripts/canvas-perf-sentinels.mjs sparse-checkout: packages/quality/testing/playwright/scripts/canvas-perf-sentinels.mjs
sparse-checkout-cone-mode: false sparse-checkout-cone-mode: false
- name: Download performance shard artifacts - name: Download performance shard artifacts
@ -54,4 +68,4 @@ jobs:
echo "::warning::No test-results.json found in performance artifacts — sentinel skipped." echo "::warning::No test-results.json found in performance artifacts — sentinel skipped."
exit 0 exit 0
fi fi
node packages/testing/playwright/scripts/canvas-perf-sentinels.mjs "${RESULTS_PATHS[@]}" node packages/quality/testing/playwright/scripts/canvas-perf-sentinels.mjs "${RESULTS_PATHS[@]}"

View File

@ -69,7 +69,7 @@ env:
# Browser cache location - must match install-browsers script. # Browser cache location - must match install-browsers script.
# Absolute so nested pnpm invocations (e.g. coverage shard runner) don't # Absolute so nested pnpm invocations (e.g. coverage shard runner) don't
# re-resolve a relative path against the package's INIT_CWD and double it. # re-resolve a relative path against the package's INIT_CWD and double it.
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/packages/testing/playwright/.playwright-browsers PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/packages/quality/testing/playwright/.playwright-browsers
# docker-artifact loads the image locally as n8nio/n8n:local; unused in local mode. # docker-artifact loads the image locally as n8nio/n8n:local; unused in local mode.
TEST_IMAGE_N8N: 'n8nio/n8n:local' TEST_IMAGE_N8N: 'n8nio/n8n:local'
N8N_SKIP_LICENSES: 'true' N8N_SKIP_LICENSES: 'true'
@ -123,7 +123,7 @@ jobs:
GITHUB_RUN_ID: ${{ github.run_id }} GITHUB_RUN_ID: ${{ github.run_id }}
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: | run: |
FILTERED=$(echo "$CANDIDATES" | node packages/testing/janitor/dist/cli.js filter-shard | tr '\n' ' ' | sed 's/ *$//') FILTERED=$(echo "$CANDIDATES" | node packages/quality/testing/janitor/dist/cli.js filter-shard | tr '\n' ' ' | sed 's/ *$//')
echo "specs=$FILTERED" >> "$GITHUB_OUTPUT" echo "specs=$FILTERED" >> "$GITHUB_OUTPUT"
- name: Resolve shard args - name: Resolve shard args
@ -195,13 +195,14 @@ jobs:
with: with:
name: ${{ inputs.artifact-prefix }}-shard-${{ matrix.shard }} name: ${{ inputs.artifact-prefix }}-shard-${{ matrix.shard }}
path: | path: |
packages/testing/playwright/test-results/ packages/quality/*/test-results*
packages/testing/playwright/test-results.json packages/quality/*/playwright-report/
packages/testing/playwright/playwright-report/ packages/quality/*/*/test-results*
packages/testing/playwright/coverage/lcov.info packages/quality/*/*/playwright-report/
packages/testing/playwright/coverage/by-spec/ packages/quality/testing/playwright/coverage/lcov.info
packages/testing/playwright/coverage/index.html packages/quality/testing/playwright/coverage/by-spec/
packages/testing/playwright/coverage/assets/ packages/quality/testing/playwright/coverage/index.html
packages/quality/testing/playwright/coverage/assets/
retention-days: 1 retention-days: 1
if-no-files-found: ignore if-no-files-found: ignore
@ -214,7 +215,7 @@ jobs:
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: ${{ inputs.artifact-prefix }}-a11y-report-shard-${{ matrix.shard }} name: ${{ inputs.artifact-prefix }}-a11y-report-shard-${{ matrix.shard }}
path: packages/testing/playwright/a11y-report/ path: packages/quality/testing/playwright/a11y-report/
retention-days: 7 retention-days: 7
if-no-files-found: ignore if-no-files-found: ignore

View File

@ -346,7 +346,7 @@ jobs:
# ANTHROPIC_API_KEY is the provider-native key resolveEvalModelConfig prefers # ANTHROPIC_API_KEY is the provider-native key resolveEvalModelConfig prefers
# when N8N_INSTANCE_AI_EVAL_MODEL differs from N8N_INSTANCE_AI_MODEL. # when N8N_INSTANCE_AI_EVAL_MODEL differs from N8N_INSTANCE_AI_MODEL.
MODEL_ARGS+=( MODEL_ARGS+=(
-e N8N_INSTANCE_AI_EVAL_MODEL=anthropic/claude-sonnet-4-6 -e N8N_INSTANCE_AI_EVAL_MODEL=anthropic/claude-sonnet-5-5
-e ANTHROPIC_API_KEY="$EVALS_ANTHROPIC_KEY" -e ANTHROPIC_API_KEY="$EVALS_ANTHROPIC_KEY"
) )

View File

@ -0,0 +1,71 @@
name: 'Test: Image Efficiency'
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prepare-docker:
uses: ./.github/workflows/prepare-docker-reusable.yml
secrets:
QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }}
QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }}
QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }}
image-efficiency:
name: Image Efficiency
needs: prepare-docker
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-2vcpu-ubuntu-2204' }}
timeout-minutes: 20
env:
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_PROJECT_ID: 'nHHLA5'
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}-images
QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }}
QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }}
QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }}
steps:
- name: Checkout
uses: useblacksmith/checkout@bcec731f1eb1367240608d1c889a75b96db6ec53 # v1.5.0
- name: Setup Environment
uses: ./.github/actions/setup-nodejs
with:
build-command: pnpm turbo run build --filter=@n8n/utils...
- name: Load images from cache
uses: ./.github/actions/load-n8n-docker
- name: Install Dive
shell: bash
run: |
set -euo pipefail
# Keep this version in sync with efficiency/images/dive-results.ts.
VERSION=0.13.1
DIR=$(mktemp -d "$RUNNER_TEMP/dive.XXXXXX")
ARCHIVE="$DIR/dive.tar.gz"
curl --fail --location --retry 3 \
"https://github.com/wagoodman/dive/releases/download/v${VERSION}/dive_${VERSION}_linux_amd64.tar.gz" \
--output "$ARCHIVE"
echo "0970549eb4a306f8825a84145a2534153badb4d7dcf3febd1967c706367c3d0e $ARCHIVE" | sha256sum --check
tar -xzf "$ARCHIVE" -C "$DIR" dive
echo "$DIR" >> "$GITHUB_PATH"
- name: Measure image layer efficiency
run: >-
pnpm --filter=@n8n/efficiency exec playwright test
--project=image-efficiency:n8n --project=image-efficiency:runners
- name: Upload image efficiency reports
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: image-efficiency-${{ github.run_attempt }}
path: |
packages/quality/efficiency/test-results/
packages/quality/efficiency/test-results.json
packages/quality/efficiency/playwright-report/
retention-days: 7
if-no-files-found: ignore

View File

@ -90,13 +90,13 @@ jobs:
env: env:
BASE_BRANCH: ${{ inputs.base-branch }} BASE_BRANCH: ${{ inputs.base-branch }}
run: | run: |
if [ -f packages/testing/code-health/package.json ]; then if [ -f packages/quality/policy/code-health/package.json ]; then
echo 'present=true' >> "$GITHUB_OUTPUT" echo 'present=true' >> "$GITHUB_OUTPUT"
elif [ -n "$BASE_BRANCH" ]; then elif [ -n "$BASE_BRANCH" ]; then
echo 'present=false' >> "$GITHUB_OUTPUT" echo 'present=false' >> "$GITHUB_OUTPUT"
echo "::notice::packages/testing/code-health is absent on \"$BASE_BRANCH\"; nothing to verify." echo "::notice::packages/quality/policy/code-health is absent on \"$BASE_BRANCH\"; nothing to verify."
else else
echo '::error::packages/testing/code-health is missing (moved or renamed?).' echo '::error::packages/quality/policy/code-health is missing (moved or renamed?).'
exit 1 exit 1
fi fi
@ -119,10 +119,10 @@ jobs:
# REPORT_ONLY is a single flag or empty. Quoting it would pass an empty argument, which # REPORT_ONLY is a single flag or empty. Quoting it would pass an empty argument, which
# the CLI reads as an (unknown) package name and rejects. # the CLI reads as an (unknown) package name and rejects.
# shellcheck disable=SC2086 # shellcheck disable=SC2086
pnpm --dir packages/testing/code-health exec tsx src/cli.ts verify-npm-install --changed="$BASE_REF" $REPORT_ONLY pnpm --dir packages/quality/policy/code-health exec tsx src/cli.ts verify-npm-install --changed="$BASE_REF" $REPORT_ONLY
- name: Verify npm-install closure (all packages) - name: Verify npm-install closure (all packages)
if: steps.verifier.outputs.present == 'true' && inputs.scope == 'all' if: steps.verifier.outputs.present == 'true' && inputs.scope == 'all'
run: | run: |
# shellcheck disable=SC2086 # see the scoped step above # shellcheck disable=SC2086 # see the scoped step above
pnpm --dir packages/testing/code-health exec tsx src/cli.ts verify-npm-install --all $REPORT_ONLY pnpm --dir packages/quality/policy/code-health exec tsx src/cli.ts verify-npm-install --all $REPORT_ONLY

View File

@ -1,110 +0,0 @@
name: 'Test: Workflows PR Comment'
on:
issue_comment:
types: [created]
permissions:
pull-requests: read
contents: read
jobs:
handle_comment_command:
name: Handle /test-workflows Command
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/test-workflows')
runs-on: ubuntu-latest
outputs:
permission_granted: ${{ steps.pr_check_and_details.outputs.permission_granted }}
git_ref: ${{ steps.pr_check_and_details.outputs.head_sha }}
pr_number: ${{ steps.pr_check_and_details.outputs.pr_number_string }}
steps:
- name: Validate User, Get PR Details, and React
id: pr_check_and_details
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const commenter = context.actor;
const issueOwner = context.repo.owner;
const issueRepo = context.repo.repo;
const commentId = context.payload.comment.id;
const prNumber = context.issue.number; // In issue_comment on a PR, issue.number is the PR number
// Function to add a reaction to the comment
async function addReaction(content) {
try {
await github.rest.reactions.createForIssueComment({
owner: issueOwner,
repo: issueRepo,
comment_id: commentId,
content: content
});
} catch (reactionError) {
// Log if reaction fails but don't fail the script for this
console.log(`Failed to add reaction '${content}': ${reactionError.message}`);
}
}
// Initialize outputs to a non-triggering state
core.setOutput('permission_granted', 'false');
core.setOutput('head_sha', '');
core.setOutput('pr_number_string', '');
// 1. Check user permissions
try {
const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: issueOwner,
repo: issueRepo,
username: commenter
});
const allowedPermissions = ['admin', 'write', 'maintain'];
if (!allowedPermissions.includes(permissions.permission)) {
console.log(`User @${commenter} has '${permissions.permission}' permission. Needs 'admin', 'write', or 'maintain'.`);
await addReaction('-1'); // User does not have permission
return; // Exit script, tests will not be triggered
}
console.log(`User @${commenter} has '${permissions.permission}' permission.`);
} catch (error) {
console.log(`Could not verify permissions for @${commenter}: ${error.message}`);
await addReaction('confused'); // Error checking permissions
return; // Exit script
}
// 2. Fetch PR details (if permission check passed)
let headSha;
try {
const { data: pr } = await github.rest.pulls.get({
owner: issueOwner,
repo: issueRepo,
pull_number: prNumber,
});
headSha = pr.head.sha;
console.log(`Workspaced PR details: SHA - ${headSha}, PR Number - ${prNumber}`);
// Set outputs for the next job
core.setOutput('permission_granted', 'true');
core.setOutput('head_sha', headSha);
core.setOutput('pr_number_string', prNumber.toString());
await addReaction('+1'); // Command accepted, tests will be triggered
} catch (error) {
console.log(`Failed to fetch PR details for PR #${prNumber}: ${error.message}`);
core.setOutput('permission_granted', 'false'); // Ensure this is false if PR fetch fails
await addReaction('confused'); // Error fetching PR details
}
trigger_reusable_tests:
name: Trigger Reusable Test Workflow
needs: handle_comment_command
if: >
always() &&
needs.handle_comment_command.result != 'skipped' &&
needs.handle_comment_command.outputs.permission_granted == 'true' &&
needs.handle_comment_command.outputs.git_ref != ''
uses: ./.github/workflows/test-workflows-callable.yml
with:
git_ref: ${{ needs.handle_comment_command.outputs.git_ref }}
secrets: inherit

View File

@ -71,7 +71,7 @@ jobs:
- name: Resolve Postgres image - name: Resolve Postgres image
if: fromJSON(steps.paths-filter.outputs.results).db if: fromJSON(steps.paths-filter.outputs.results).db
run: | run: |
IMAGE=$(node -p "require('./packages/testing/containers/postgres-versions.json').primary") IMAGE=$(node -p "require('./packages/quality/environments/containers/postgres-versions.json').primary")
echo "TEST_IMAGE_POSTGRES=$IMAGE" >> "$GITHUB_ENV" echo "TEST_IMAGE_POSTGRES=$IMAGE" >> "$GITHUB_ENV"
- name: Start Postgres - name: Start Postgres

View File

@ -100,6 +100,9 @@ jobs:
approve-and-automerge: approve-and-automerge:
needs: [update-baseline] needs: [update-baseline]
if: needs.update-baseline.outputs.pull-request-number != '' if: needs.update-baseline.outputs.pull-request-number != ''
permissions:
contents: write
pull-requests: write
# The callee's app credentials live on the release environment and cannot # The callee's app credentials live on the release environment and cannot
# be forwarded as named secrets by the caller. # be forwarded as named secrets by the caller.
uses: ./.github/workflows/util-approve-and-set-automerge.yml # zizmor: ignore[secrets-inherit] uses: ./.github/workflows/util-approve-and-set-automerge.yml # zizmor: ignore[secrets-inherit]

View File

@ -0,0 +1,118 @@
name: 'Util: Update get-n8n Versions'
on:
schedule:
# Run every Wednesday at 04:00 UTC.
- cron: '0 4 * * 3'
workflow_dispatch:
permissions: {}
concurrency:
group: update-get-n8n-versions
cancel-in-progress: false
jobs:
update-versions:
name: Update get-n8n versions
if: >-
github.ref_name == github.event.repository.default_branch &&
(github.event_name == 'workflow_dispatch' ||
(github.event_name == 'schedule' && github.repository == 'n8n-io/n8n'))
runs-on: ubuntu-latest
timeout-minutes: 25
permissions:
contents: read
steps:
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Resolve stable versions
id: versions
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
n8n_version="$(gh api repos/n8n-io/n8n/releases/latest --jq '.tag_name | sub("^n8n@"; "")')"
registry_token="$(curl -fsSL --retry 3 'https://ghcr.io/token?scope=repository:n8n-io/n8n-sandbox-service-api:pull' | jq -er '.token')"
stable_digest="$(docker buildx imagetools inspect \
'ghcr.io/n8n-io/n8n-sandbox-service-api:stable' \
--format '{{json .Manifest}}' | jq -er '.digest')"
sandbox_version=''
while IFS= read -r version; do
version_digest="$(docker buildx imagetools inspect \
"ghcr.io/n8n-io/n8n-sandbox-service-api:${version}" \
--format '{{json .Manifest}}' | jq -er '.digest')"
if [ "$version_digest" = "$stable_digest" ]; then
sandbox_version="$version"
break
fi
done < <(curl -fsSL --retry 3 \
-H "Authorization: Bearer $registry_token" \
'https://ghcr.io/v2/n8n-io/n8n-sandbox-service-api/tags/list?n=1000' |
jq -r '.tags[]' |
grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' |
sort -Vr)
printf '%s\n' "$n8n_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'
printf '%s\n' "$sandbox_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'
for image in api runner-dind sandbox; do
docker manifest inspect "ghcr.io/n8n-io/n8n-sandbox-service-${image}:${sandbox_version}" >/dev/null
done
sed -i "s/^FALLBACK_N8N_VERSION=.*/FALLBACK_N8N_VERSION=\"${n8n_version}\"/" docker/get-n8n.sh
sed -i "s/^SANDBOX_VERSION=.*/SANDBOX_VERSION=\"${sandbox_version}\"/" docker/get-n8n.sh
echo "n8n_version=$n8n_version" >> "$GITHUB_OUTPUT"
echo "sandbox_version=$sandbox_version" >> "$GITHUB_OUTPUT"
- name: Check for changes
id: changes
run: |
if git diff --quiet -- docker/get-n8n.sh; then
echo 'has-changes=false' >> "$GITHUB_OUTPUT"
else
echo 'has-changes=true' >> "$GITHUB_OUTPUT"
fi
- name: Test installer upgrade
if: steps.changes.outputs.has-changes == 'true'
run: |
shellcheck docker/get-n8n.sh docker/test-get-n8n.sh
dash -n docker/get-n8n.sh
dash -n docker/test-get-n8n.sh
sh docker/test-get-n8n.sh --e2e
- name: Create pull request
if: steps.changes.outputs.has-changes == 'true'
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
token: ${{ steps.generate-token.outputs.token }}
add-paths: docker/get-n8n.sh
commit-message: 'chore: Update get-n8n fallback versions'
labels: 'automation:scheduled-update'
title: 'chore: Update get-n8n fallback versions'
body: |
This automated PR updates the get-n8n fallback release to ${{ steps.versions.outputs.n8n_version }}.
It also updates the sandbox service release to ${{ steps.versions.outputs.sandbox_version }}.
The workflow verified that all sandbox images use the same release. It also upgraded a legacy installation to these versions and checked the running stack.
_Generated by the weekly get-n8n version update workflow._
branch: update-get-n8n-versions
base: master
delete-branch: true
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

23
.gitignore vendored
View File

@ -1,4 +1,5 @@
node_modules node_modules
.build/
.pnpm-store .pnpm-store
.DS_Store .DS_Store
.tmp .tmp
@ -8,6 +9,7 @@ dist
coverage coverage
coverage-by-spec coverage-by-spec
coverage-by-spec-backend coverage-by-spec-backend
/report
npm-debug.log* npm-debug.log*
yarn.lock yarn.lock
google-generated-credentials.json google-generated-credentials.json
@ -25,6 +27,7 @@ nodelinter.config.json
!.github/scripts/package-lock.json !.github/scripts/package-lock.json
packages/**/.turbo packages/**/.turbo
.turbo .turbo
.build/
.stryker-tmp/ .stryker-tmp/
**/reports/mutation/ **/reports/mutation/
*.tsbuildinfo *.tsbuildinfo
@ -38,23 +41,25 @@ build.log
tcr-dry.log tcr-dry.log
.agent-setup/ .agent-setup/
.agent-recordings/ .agent-recordings/
.vitest/
.vitest-profile/
.pi-subagents/ .pi-subagents/
sbom-source.cdx.json sbom-source.cdx.json
*.junit.xml *.junit.xml
junit.xml junit.xml
test-results.json test-results.json
*.0x *.0x
packages/testing/playwright/playwright-report packages/quality/testing/playwright/playwright-report
packages/testing/playwright/eval-report packages/quality/testing/playwright/eval-report
packages/testing/playwright/a11y-report packages/quality/testing/playwright/a11y-report
packages/testing/playwright/test-results packages/quality/testing/playwright/test-results
packages/testing/playwright/results.xml packages/quality/testing/playwright/results.xml
packages/testing/playwright/eval-results.json packages/quality/testing/playwright/eval-results.json
packages/@n8n/instance-ai/eval-results.json packages/@n8n/instance-ai/eval-results.json
packages/@n8n/instance-ai/.eval-output/ packages/@n8n/instance-ai/.eval-output/
packages/@n8n/instance-ai/eval-pr-comment.md packages/@n8n/instance-ai/eval-pr-comment.md
packages/testing/playwright/.playwright-browsers packages/quality/testing/playwright/.playwright-browsers
packages/testing/playwright/.playwright-cli packages/quality/testing/playwright/.playwright-cli
test-results/ test-results/
compiled_app_output compiled_app_output
trivy_report* trivy_report*
@ -63,7 +68,7 @@ docker-build-manifest.json
packages/cli/src/modules/my-feature packages/cli/src/modules/my-feature
.secrets .secrets
act-event.json act-event.json
packages/testing/**/.cursor/rules/ packages/quality/**/.cursor/rules/
.venv .venv
.ruff_cache .ruff_cache
__pycache__ __pycache__

26
.jscpd.json Normal file
View File

@ -0,0 +1,26 @@
{
"threshold": 10.5,
"reporters": ["json", "html"],
"gitignore": true,
"ignore": [
"**/__snapshots__/**",
"**/*.snap",
"**/fixtures/**",
"**/locales/**",
"**/i18n/**",
"**/*.generated.*",
"**/__schema__/**",
"**/cassettes/**",
"packages/@n8n/typeorm/test/**",
"docs/generated/**",
"**/test/**/*.workflow.json",
"**/tests/**/*.workflow.json",
"**/__tests__/**/*.workflow.json",
"**/test/**/workflow.*.json",
"**/tests/**/workflow.*.json",
"**/__tests__/**/workflow.*.json",
"**/test/**/workflows/**/*.json",
"**/tests/**/workflows/**/*.json",
"**/__tests__/**/workflows/**/*.json"
]
}

View File

@ -52,8 +52,8 @@ skip:
# Uses merge commit SHA from GitHub - the code has already been reviewed # Uses merge commit SHA from GitHub - the code has already been reviewed
# and merged, not arbitrary PR code. # and merged, not arbitrary PR code.
- .github/workflows/test-unit-reusable.yml - .github/workflows/test-unit-reusable.yml
# Permission-gated: only maintainers (admin/write/maintain) can trigger # Reachable only from test-workflows-nightly.yml, which is
# via /test-workflows comment. Verified in test-workflows-pr-comment.yml. # workflow_dispatch-only, so the ref comes from a maintainer, not a PR.
- .github/workflows/test-workflows-callable.yml - .github/workflows/test-workflows-callable.yml
# Reusable workflow reachable only via workflow_dispatch (manual) or from # Reusable workflow reachable only via workflow_dispatch (manual) or from
# ci-mcp-evals.yml, which is itself workflow_dispatch-only — never from a # ci-mcp-evals.yml, which is itself workflow_dispatch-only — never from a

View File

@ -14,6 +14,11 @@ frontend, and extensible node-based workflow engine.
- Write all technical text (code comments, PR descriptions, issue and ticket - Write all technical text (code comments, PR descriptions, issue and ticket
descriptions, docs) in ASD-STE100 Simplified Technical English: use short descriptions, docs) in ASD-STE100 Simplified Technical English: use short
sentences, the active voice, and one instruction for each sentence sentences, the active voice, and one instruction for each sentence
- **JSDoc on `@Env(...)` config properties is public documentation.** The
docs team exports these comments into the environment variable reference on
docs.n8n.io. Write them for a self-hosting operator and follow the
`n8n:env-var-docs` skill, which applies the n8n docs style guide and
overrides the ASD-STE100 rule above for these comments
- **Secrets on the command line:** if a developer opted into anonymous dev - **Secrets on the command line:** if a developer opted into anonymous dev
metrics (`scripts/dev-metrics`), pnpm command arguments are recorded. Arguments metrics (`scripts/dev-metrics`), pnpm command arguments are recorded. Arguments
of secret-carrying words (`config`, `login`, `publish`, `token`) — whether a of secret-carrying words (`config`, `login`, `publish`, `token`) — whether a
@ -35,6 +40,10 @@ frontend, and extensible node-based workflow engine.
suggested by Linear, **unless it is a security fix** (see Security Fix suggested by Linear, **unless it is a security fix** (see Security Fix
Hygiene below) Hygiene below)
- Use mermaid diagrams in MD files when you need to visualise something - Use mermaid diagrams in MD files when you need to visualise something
- Write an ADR only when asked. When a change makes a decision that an
engineer could challenge in 12 months, say so in one line and let the
human decide. Read [docs/adr/README.md](docs/adr/README.md) before you
write one. CI enforces its conventions
- **Developing v3 features:** land normal feature work on `master` behind an - **Developing v3 features:** land normal feature work on `master` behind an
opt-in flag; introduce breaking changes only on the `3.x` branch. See opt-in flag; introduce breaking changes only on the `3.x` branch. See
[.github/DEVELOPING_V3.md](.github/DEVELOPING_V3.md). [.github/DEVELOPING_V3.md](.github/DEVELOPING_V3.md).
@ -43,7 +52,8 @@ frontend, and extensible node-based workflow engine.
comments keep the historical `n8nConnect` / `n8n credits` / AI Gateway names comments keep the historical `n8nConnect` / `n8n credits` / AI Gateway names
- **Shared utilities:** before you hand-roll a utility (`isRecord`, secret or - **Shared utilities:** before you hand-roll a utility (`isRecord`, secret or
PII redaction, JSON extraction from LLM output, Zod to JSON Schema, model-id PII redaction, JSON extraction from LLM output, Zod to JSON Schema, model-id
parsing, …), you MUST check the shared packages for an existing parsing, AI client HTTP transport and response-size limiting, …), you MUST
check the shared packages for an existing
implementation and use it: `@n8n/utils` (generic helpers, redaction), implementation and use it: `@n8n/utils` (generic helpers, redaction),
`@n8n/ai-utilities` (AI- and LLM-specific helpers) and `n8n-workflow` `@n8n/ai-utilities` (AI- and LLM-specific helpers) and `n8n-workflow`
(workflow graph and traversal). A new shared helper usually belongs in one of (workflow graph and traversal). A new shared helper usually belongs in one of
@ -64,10 +74,15 @@ are namespaced under `n8n:`. Use `n8n:` prefix when invoking them (e.g.
## Essential Commands ## Essential Commands
For full-repo lint and typecheck, use `pnpm agent:lint` and For routine pre-commit checks, follow [Verify changes](#verify-changes).
`pnpm agent:typecheck`. They save full logs and return compact results.
For focused tests, use `pnpm agent:test` or `pnpm agent:playwright`. For focused tests, use `pnpm agent:test` or `pnpm agent:playwright`.
Run each command with `--help` for its package, script, and file options. Pass test files and worker limits after `--`. Run each command with `--help`
for its options.
`pnpm agent:lint` and `pnpm agent:typecheck` run full-repo checks by default.
With `--filter <package>`, they still check the whole package. These wrappers
save logs and reduce console output. They do not reduce CPU or memory use.
Do not use them as routine pre-commit checks.
### Fresh checkout / agent setup ### Fresh checkout / agent setup
@ -214,12 +229,16 @@ const children = getChildNodes(workflow.connections, 'NodeName', 'main', 1);
### Persistence layer & the TypeORM boundary ### Persistence layer & the TypeORM boundary
TypeORM (`@n8n/typeorm`) must stay in the **persistence layer** — the `@n8n/db` TypeORM (`@n8n/typeorm`) must stay in the **persistence layer**. The shared
package or a backend module's own `database/` folder (entity/repository files). `@n8n/db` package and backend persistence adapters can import it. A module can
colocate or group its entities and repositories according to its domain.
Business logic — services, controllers, handlers, commands, factories — must not Business logic — services, controllers, handlers, commands, factories — must not
import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). In import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). The
`packages/cli` this is enforced by the `misplaced-n8n-typeorm-import` lint rule; `typeorm-persistence-boundary` Code Health rule recognizes entity and repository
a new import (or an inline `eslint-disable` of the rule) fails CI. declarations. It scans backend packages that depend on `@n8n/db` or
`@n8n/typeorm`. Tests, migrations, and explicit helper-only adapters are
exceptions. Existing business-logic imports stay in the shrink-only Code Health
baseline. A new business-logic import fails CI.
- **Pattern:** when a query needs operators (`In`, `IsNull`, `LessThan`, - **Pattern:** when a query needs operators (`In`, `IsNull`, `LessThan`,
`FindOptionsWhere`, …), put it behind a **use-case-named repository method** `FindOptionsWhere`, …), put it behind a **use-case-named repository method**
@ -305,18 +324,29 @@ extends one of those layers):
### Verify changes ### Verify changes
- Run focused tests from the owning package: `pnpm test <test-file>`. - Before committing, run formatting and lint checks on changed files. Use
- Run that package's `pnpm lint` and `pnpm typecheck` before committing code. the package's configured tools through `pnpm exec` with explicit file paths.
Build first when shared types or cross-package dependencies change. Do not append file paths to `pnpm lint`; package scripts can still check
the whole package.
- Run tests that cover the changed behavior from the owning package:
`pnpm test <test-file> --maxWorkers=1`. Or use the root wrapper:
`pnpm agent:test --filter <package> -- <test-file> --maxWorkers=1`.
For Playwright, use `pnpm agent:playwright -- <spec-file> --workers=1`.
- For routine commits, run checks one at a time. Use one test worker by
default. Do not run full frontend typechecks locally. Use CI for
comprehensive lint, typechecks, and test suites.
- For documentation-only changes, review the diff and run `git diff --check`.
Skip code tests when no behavior changed.
- Report which checks ran and which checks were left to CI.
- Use Vitest for unit tests. Use - Use Vitest for unit tests. Use
[Playwright](packages/testing/playwright/AGENTS.md) when a test needs its [Playwright](packages/quality/testing/playwright/AGENTS.md) when a test needs its
browser, fixtures, or managed containers. browser, fixtures, or managed containers.
- For Vitest packages with `@n8n/di` decorators, use - For Vitest packages with `@n8n/di` decorators, use
`createVitestConfigWithDecorators` from `@n8n/vitest-config/node-decorators`. `createVitestConfigWithDecorators` from `@n8n/vitest-config/node-decorators`.
- Check import and mock side effects before running tests. Keep tests out of - Check import and mock side effects before running tests. Keep tests out of
user-owned directories. Set `N8N_USER_FOLDER` to a test-owned directory before user-owned directories. Set `N8N_USER_FOLDER` to a test-owned directory before
importing n8n settings. Clean up only paths that the test created. importing n8n settings. Clean up only paths that the test created.
- CI runs [`@n8n/code-health`](packages/testing/code-health/README.md) static - CI runs [`@n8n/code-health`](packages/quality/policy/code-health/README.md) static
analysis on PRs. It checks monorepo rules, including dependency hygiene and analysis on PRs. It checks monorepo rules, including dependency hygiene and
encryption-boundary coverage. encryption-boundary coverage.
@ -330,7 +360,7 @@ extends one of those layers):
| Start a Codespace backend and share its port | `pnpm dev:up` | | Start a Codespace backend and share its port | `pnpm dev:up` |
The root `pnpm dev` command does not start a server. See the The root `pnpm dev` command does not start a server. See the
[Playwright guide](packages/testing/playwright/README.md) and the [Playwright guide](packages/quality/testing/playwright/README.md) and the
[Codespaces guide](.devcontainer/codespaces/README.md) for details. [Codespaces guide](.devcontainer/codespaces/README.md) for details.
### Common Development Tasks ### Common Development Tasks

View File

@ -1,3 +1,305 @@
# [2.44.0](https://github.com/n8n-io/n8n/compare/n8n@2.43.0...n8n@2.44.0) (2026-10-13)
### Bug Fixes
* Align execution retry menu and clarify actions ([#40710](https://github.com/n8n-io/n8n/issues/40710)) ([84d2fd6](https://github.com/n8n-io/n8n/commit/84d2fd6f3ae68e973aa49f7e2b1dd5dbf06ad18c))
* Allow per-process crash journal paths ([#37670](https://github.com/n8n-io/n8n/issues/37670)) ([447e939](https://github.com/n8n-io/n8n/commit/447e939b732b778662572098d81f014527e3ffe2))
* **core:** Allow reverting a workflow version that uses credentials the user cannot use ([#40701](https://github.com/n8n-io/n8n/issues/40701)) ([033a9b5](https://github.com/n8n-io/n8n/commit/033a9b512c2d52d05b43d4dd2d0e10634dc36e2a))
* **core:** Apply node type policies to agent node tools ([#39711](https://github.com/n8n-io/n8n/issues/39711)) ([e7d8533](https://github.com/n8n-io/n8n/commit/e7d8533880df0d36438e39a07f0594fcaaaaab55))
* **core:** Apply the credential type policy to credential tests and probes ([#39927](https://github.com/n8n-io/n8n/issues/39927)) ([9191cf3](https://github.com/n8n-io/n8n/commit/9191cf3fb07ce6bbb7b2217592ce56372b52f6c2))
* **core:** Block the assistant when AI credits hit zero ([#40659](https://github.com/n8n-io/n8n/issues/40659)) ([8b7065a](https://github.com/n8n-io/n8n/commit/8b7065a87684bb3a055d8bcfc5d34c9b70094080))
* **core:** Check the credential save policy before package import creates stubs ([#40687](https://github.com/n8n-io/n8n/issues/40687)) ([a3391ba](https://github.com/n8n-io/n8n/commit/a3391ba93c4574405d06e79e2efc791b6ba8a21f))
* **core:** Check the target project's policy on folder, credential and delete-transfer moves ([#40301](https://github.com/n8n-io/n8n/issues/40301)) ([77370af](https://github.com/n8n-io/n8n/commit/77370af99a273073faf7df57a1fe8f71d3833bbe))
* **core:** Count jobs as running from the start of job processing ([#40050](https://github.com/n8n-io/n8n/issues/40050)) ([dc5c80f](https://github.com/n8n-io/n8n/commit/dc5c80f26af8d32e5887ccbf7634f3da1be5f771))
* **core:** Expose 1Password fields for secret preview and autocomplete ([#40538](https://github.com/n8n-io/n8n/issues/40538)) ([bef5f3f](https://github.com/n8n-io/n8n/commit/bef5f3f97aca163ac289af61e10869c0fa7fff60))
* **core:** Fix Kimi K3 and other OpenAI-compatible Assistant model providers on self-hosted Assistant ([#40439](https://github.com/n8n-io/n8n/issues/40439)) ([1ef7756](https://github.com/n8n-io/n8n/commit/1ef77564e3bef2e34c57d8a67df892ace3858a5d))
* **core:** Handle each Chat Hub segment once in queue mode ([#40791](https://github.com/n8n-io/n8n/issues/40791)) ([9ff8d4f](https://github.com/n8n-io/n8n/commit/9ff8d4fc738ca0e54db863c574e5a6d93df9ce2e))
* **core:** Improve node placement when n8n Assistant edits a workflow ([#40139](https://github.com/n8n-io/n8n/issues/40139)) ([d900743](https://github.com/n8n-io/n8n/commit/d900743bce0cf8274c42e1f4a579fc8b5cf74997))
* **core:** Keep waiting executions unchanged when a resume request fails ([#40683](https://github.com/n8n-io/n8n/issues/40683)) ([bbd35e2](https://github.com/n8n-io/n8n/commit/bbd35e281b100a36aa209518c5ab027eabf85a1f))
* **core:** Let the editor download binary data of an Engine v2 execution ([#40663](https://github.com/n8n-io/n8n/issues/40663)) ([c9cb3ee](https://github.com/n8n-io/n8n/commit/c9cb3ee3abd23fe146cd4a2daed49c4bddb80d97))
* **core:** Let the streaming heartbeat stop on Chat Hub responses ([#40792](https://github.com/n8n-io/n8n/issues/40792)) ([ee8a608](https://github.com/n8n-io/n8n/commit/ee8a608a22ec7a23dc795ee0554edd34186e87d2))
* **core:** Match regex case-insensitively when ignore case is enabled ([#33589](https://github.com/n8n-io/n8n/issues/33589)) ([2596f3a](https://github.com/n8n-io/n8n/commit/2596f3ac1c657aa4d2ddf40430b9e5940fb9c1b0))
* **core:** Match the Brazilian real symbol in the in-isolate currency regex ([#40893](https://github.com/n8n-io/n8n/issues/40893)) ([d3deffb](https://github.com/n8n-io/n8n/commit/d3deffbfa59d358614458f8b1ae2d56d118a9ca5))
* **core:** Pass `storedAt` into `WorkflowExecute` at every callsite ([#40495](https://github.com/n8n-io/n8n/issues/40495)) ([5ab2187](https://github.com/n8n-io/n8n/commit/5ab21874169d44eb01a19d6f0ba19bb7a254d952))
* **core:** Remove credentials of deleted projects on source control pull ([#40692](https://github.com/n8n-io/n8n/issues/40692)) ([978f810](https://github.com/n8n-io/n8n/commit/978f810bbef9e284b564db4897be7085257064b1))
* **core:** Report approval tools with no tool connected in workflow validation ([#40561](https://github.com/n8n-io/n8n/issues/40561)) ([bc0a9cb](https://github.com/n8n-io/n8n/commit/bc0a9cbc112aaed2853f14c32157082f41ba42b4))
* **core:** Report MCP server connection failures in verify_mcp_server ([#40559](https://github.com/n8n-io/n8n/issues/40559)) ([fbbbadc](https://github.com/n8n-io/n8n/commit/fbbbadc292791112e30101edee229e9d5f4dbc02))
* **core:** Require workflow create scope for single node runs in n8n Assistant ([#40908](https://github.com/n8n-io/n8n/issues/40908)) ([27fcb96](https://github.com/n8n-io/n8n/commit/27fcb968fb711a9957eed48fa78c5adfa78fc607))
* **core:** Resume tool calls for deferred tools that a skill loaded ([#40126](https://github.com/n8n-io/n8n/issues/40126)) ([1c84af2](https://github.com/n8n-io/n8n/commit/1c84af2e96bda41cd84852af82e5cae5b823f0f8))
* **core:** Return jobs dequeued during worker shutdown to the queue ([#40086](https://github.com/n8n-io/n8n/issues/40086)) ([084f3b3](https://github.com/n8n-io/n8n/commit/084f3b376a0d64594320853bae90f13537d3b8c9))
* **core:** Return jobs fetched before a worker paused to the queue ([#40162](https://github.com/n8n-io/n8n/issues/40162)) ([f26747b](https://github.com/n8n-io/n8n/commit/f26747bfc665ce0c137b0b7645245b1a97d1d01b))
* **core:** Save agent draft definitions atomically ([#40374](https://github.com/n8n-io/n8n/issues/40374)) ([9ee5d1a](https://github.com/n8n-io/n8n/commit/9ee5d1ad7a54cde445ac945fc56a7ba5a4ee4707))
* **core:** Serve the migration report on every main in a multi-main setup ([#40180](https://github.com/n8n-io/n8n/issues/40180)) ([a6f1e79](https://github.com/n8n-io/n8n/commit/a6f1e79394adced5958219f812e8ca14a10b9962))
* **core:** Show the policy block before node issues on execute and publish ([#40290](https://github.com/n8n-io/n8n/issues/40290)) ([0bbea43](https://github.com/n8n-io/n8n/commit/0bbea438e1906a0773cdbb46e273b4c01fea359b))
* **core:** Stabilise background child approval wait ([#40834](https://github.com/n8n-io/n8n/issues/40834)) ([2ca4e55](https://github.com/n8n-io/n8n/commit/2ca4e55502e03985d2c9b1b0033b6f5151ccb8f4))
* **core:** Start a new test session when call_agent gets an unknown session ID ([#40458](https://github.com/n8n-io/n8n/issues/40458)) ([e16566b](https://github.com/n8n-io/n8n/commit/e16566b31324991a369708b7eb1f46027f80445b))
* **core:** Stop marking the Message an Agent node as hidden ([#40358](https://github.com/n8n-io/n8n/issues/40358)) ([3366d2b](https://github.com/n8n-io/n8n/commit/3366d2b9b3151a769116a66499668c3a36cf65a4))
* **core:** Validate execution timeout against the configured maximum in Instance AI saves ([#40769](https://github.com/n8n-io/n8n/issues/40769)) ([2176819](https://github.com/n8n-io/n8n/commit/2176819865a03e9247dac0a61177572ac4f7711c))
* **core:** Validate the size argument of the chunk() expression extension ([#40880](https://github.com/n8n-io/n8n/issues/40880)) ([3ff9c83](https://github.com/n8n-io/n8n/commit/3ff9c83bdaf873509e4470f97e26919e0653add8))
* **core:** Wire Entra OAuth2 into agent Azure OpenAI runtime ([#40218](https://github.com/n8n-io/n8n/issues/40218)) ([96a8ff4](https://github.com/n8n-io/n8n/commit/96a8ff4d15baa2ab15debc8ea02da81847f5a504))
* **Databricks Node:** Request float encoding for embeddings from the Unity AI Gateway ([#40684](https://github.com/n8n-io/n8n/issues/40684)) ([4c0902f](https://github.com/n8n-io/n8n/commit/4c0902f6bf4a0aa6634d5598e75fc677aa55f429))
* **editor:** Add resend to retryable Agent preview errors ([#40592](https://github.com/n8n-io/n8n/issues/40592)) ([f7e52a8](https://github.com/n8n-io/n8n/commit/f7e52a851ed9416615167826daf706d90a19d53b))
* **editor:** Align nodes panel to the embedded canvas in the n8n Assistant split view ([#40795](https://github.com/n8n-io/n8n/issues/40795)) ([37799ad](https://github.com/n8n-io/n8n/commit/37799ad2f21067ec7951c2656c9e938dc87443e1))
* **editor:** Align tooltip trigger box with its content ([#40422](https://github.com/n8n-io/n8n/issues/40422)) ([a694531](https://github.com/n8n-io/n8n/commit/a694531a0367bc6b7991b194ec762e7ad51aaa0a))
* **editor:** Keep Agent Builder settings inside a narrow column ([#40759](https://github.com/n8n-io/n8n/issues/40759)) ([e2b4fee](https://github.com/n8n-io/n8n/commit/e2b4fee0ec0f0f34245664c23869153089362236))
* **editor:** Keep Assistant fixes in Agent builder and correct tooltips ([#40348](https://github.com/n8n-io/n8n/issues/40348)) ([a13705a](https://github.com/n8n-io/n8n/commit/a13705aa8fff5a170ba5b069946e205e9acc1985))
* **editor:** Keep folder creation available globally after Community registration ([#40082](https://github.com/n8n-io/n8n/issues/40082)) ([e1025f3](https://github.com/n8n-io/n8n/commit/e1025f35e4203b49436aedb89dcb679e96169528))
* **editor:** Keep same-named parameter values apart when their types differ ([#40170](https://github.com/n8n-io/n8n/issues/40170)) ([6013045](https://github.com/n8n-io/n8n/commit/601304543d2b87e6aa42211c3a8c6c2766c2c61d))
* **editor:** Keep the prompt visible while the assistant starts a new thread ([#40796](https://github.com/n8n-io/n8n/issues/40796)) ([be402be](https://github.com/n8n-io/n8n/commit/be402be262974d46f79ba3464e20efc0ee734ac4))
* **editor:** Keep the selected credential visible when the picker does not list it ([#40450](https://github.com/n8n-io/n8n/issues/40450)) ([66b382d](https://github.com/n8n-io/n8n/commit/66b382de52fb56db87987910929e932292837305))
* **editor:** Keep the workflow setup step counter on one line ([#40771](https://github.com/n8n-io/n8n/issues/40771)) ([55eb2ce](https://github.com/n8n-io/n8n/commit/55eb2ce44291648adf6ca05b5b1605efea8d77f7))
* **editor:** Keep typed characters in Markdown fields ([#40805](https://github.com/n8n-io/n8n/issues/40805)) ([16e29da](https://github.com/n8n-io/n8n/commit/16e29da52f3173ee5edc7b96697a4c227b4983d0))
* **editor:** Load node types before authenticated pages render ([#40812](https://github.com/n8n-io/n8n/issues/40812)) ([8297b2e](https://github.com/n8n-io/n8n/commit/8297b2e6d263d63571926545bf8b5c490f5125bf))
* **editor:** Place the restricted node popover per host, keep one open, and stack the admin dialog ([#40678](https://github.com/n8n-io/n8n/issues/40678)) ([b28dceb](https://github.com/n8n-io/n8n/commit/b28dceb462d8e51855d4e13a87e9c975638ef977))
* **editor:** Polish n8n Assistant and Execute button UI details ([#40414](https://github.com/n8n-io/n8n/issues/40414)) ([76cab1e](https://github.com/n8n-io/n8n/commit/76cab1e26d97cbbf50790926f1bbb14cfb12d078))
* **editor:** Preserve Live Data highlights on scroll in expression editor ([#33842](https://github.com/n8n-io/n8n/issues/33842)) ([0f02b50](https://github.com/n8n-io/n8n/commit/0f02b509be304523955e7700c7c9eeefe58d0aa9))
* **editor:** Remove redundant description for create workflow option in agent config ([#40882](https://github.com/n8n-io/n8n/issues/40882)) ([b542f66](https://github.com/n8n-io/n8n/commit/b542f6611998c23b40b54d25d1e923841ee24160))
* **editor:** Rename the "Executions fail" label to "Executions will fail" ([#40888](https://github.com/n8n-io/n8n/issues/40888)) ([2a51f38](https://github.com/n8n-io/n8n/commit/2a51f38d55f37f65382ebf3900a340fc62b15314))
* **editor:** Respect the default voice for chat read aloud ([#40440](https://github.com/n8n-io/n8n/issues/40440)) ([022b239](https://github.com/n8n-io/n8n/commit/022b23945ba576024685bfe1702489f427a3c9fe))
* **editor:** Shorten the share button label on the credential sharing tab ([#40637](https://github.com/n8n-io/n8n/issues/40637)) ([c133d6c](https://github.com/n8n-io/n8n/commit/c133d6c893a879c907d20bb71a10817d358db553))
* **editor:** Show the Agent artifact while the builder creates it ([#40535](https://github.com/n8n-io/n8n/issues/40535)) ([1c63119](https://github.com/n8n-io/n8n/commit/1c631197563b8f65d343d060355050c4551f381d))
* **editor:** Show the owner and credential type for credentials the user cannot use ([#40669](https://github.com/n8n-io/n8n/issues/40669)) ([63dc285](https://github.com/n8n-io/n8n/commit/63dc2854936f3e282ca422cd9b9babeab65a2375))
* **editor:** Show the renamed agent name in the assistant artifact tab ([#40770](https://github.com/n8n-io/n8n/issues/40770)) ([4032797](https://github.com/n8n-io/n8n/commit/40327977903613fee5d033efd31c6e01416a2bf0))
* **editor:** Show the unavailable credential at the top of the node picker ([#40693](https://github.com/n8n-io/n8n/issues/40693)) ([1933723](https://github.com/n8n-io/n8n/commit/19337237ec59bd03c89e300a23289d2bdfbf269e))
* **editor:** Show why a node on another branch can't be referenced ([#40565](https://github.com/n8n-io/n8n/issues/40565)) ([a195096](https://github.com/n8n-io/n8n/commit/a19509673336fbbf6687b107ce0af5bcfec68393))
* **editor:** Small UI fixes to budget guardrail setup components ([#40383](https://github.com/n8n-io/n8n/issues/40383)) ([958d23d](https://github.com/n8n-io/n8n/commit/958d23d81cd99d7b9fd63d2484b79382c2d20c23))
* **editor:** Use pulsing status dot for the enabled n8n Assistant setting ([#40712](https://github.com/n8n-io/n8n/issues/40712)) ([3ba5229](https://github.com/n8n-io/n8n/commit/3ba522910b1cc3009c108a202634388fd838717f))
* **Google Gemini Chat Model Node:** Point the AI builder to the model catalog for new Gemini models ([#40159](https://github.com/n8n-io/n8n/issues/40159)) ([c21ed4f](https://github.com/n8n-io/n8n/commit/c21ed4f13aee6a1551207a92122bea2859e1b8d3))
* **Invoice Ninja Node:** Fix retrieving currencies for bank transactions ([#12997](https://github.com/n8n-io/n8n/issues/12997)) ([00849c4](https://github.com/n8n-io/n8n/commit/00849c4deabada87641c146773c0981e873a6328))
* Keep execution details clear of preview canvas ([#40176](https://github.com/n8n-io/n8n/issues/40176)) ([af98327](https://github.com/n8n-io/n8n/commit/af98327a5e4f2332b78b4d460e6eb208f0782d28))
* Load only the publish history that the editor shows ([#40183](https://github.com/n8n-io/n8n/issues/40183)) ([b28adf9](https://github.com/n8n-io/n8n/commit/b28adf97895bbdba2e0c777bdfb5cd11d04c0e56))
* **Microsoft Outlook Trigger Node:** Report failed polls and limit the backlog per poll ([#40147](https://github.com/n8n-io/n8n/issues/40147)) ([6bc5c93](https://github.com/n8n-io/n8n/commit/6bc5c93513efbe4d236c5794cfd07e1ac4d916f6))
* Multiple migration timestamps withing a single PR ([#40379](https://github.com/n8n-io/n8n/issues/40379)) ([7db7fa4](https://github.com/n8n-io/n8n/commit/7db7fa42c80a8a24fb5ca5ec7448ffb12431fad9))
* **Odoo Node:** Normalize datetime fields to Odoo format before write ([#34186](https://github.com/n8n-io/n8n/issues/34186)) ([6b77613](https://github.com/n8n-io/n8n/commit/6b77613ee827560d9f34f551478a74daf4848dec))
* Prevent node types corruption when multiple loaders run at the same time ([#40633](https://github.com/n8n-io/n8n/issues/40633)) ([fdc3948](https://github.com/n8n-io/n8n/commit/fdc394819cecf96379ed7ba475364912099a6296))
* Remove loading flashes from data tables ([#39874](https://github.com/n8n-io/n8n/issues/39874)) ([2f4a386](https://github.com/n8n-io/n8n/commit/2f4a3868fbd74c07e91888eb35b1f3d4bcb2acb1))
* Report resource-operation violations as errors ([#40830](https://github.com/n8n-io/n8n/issues/40830)) ([a180010](https://github.com/n8n-io/n8n/commit/a1800105ef8f7c229ffd044e1233d273e95b6cd2))
* Return UTC ISO dates without changing other cells ([#40156](https://github.com/n8n-io/n8n/issues/40156)) ([8059b63](https://github.com/n8n-io/n8n/commit/8059b63da89ba89309cbc6eacce715110c9c5748))
* **S3 Node:** Percent-encode the copy source path ([#40282](https://github.com/n8n-io/n8n/issues/40282)) ([81f34c2](https://github.com/n8n-io/n8n/commit/81f34c23744424d17ca99eaf03beb9861c21a1ca))
* Separate agent response steps and show saved reasoning ([#40590](https://github.com/n8n-io/n8n/issues/40590)) ([1e6da4e](https://github.com/n8n-io/n8n/commit/1e6da4e615900d7665e6eeafe9ce6002d1510c31))
* Update matching nodes when selecting imported credentials ([#39650](https://github.com/n8n-io/n8n/issues/39650)) ([4b5b68e](https://github.com/n8n-io/n8n/commit/4b5b68ee2929344288b93469efe732379e3904a1))
* Use configured OAuth server rate limits ([#40542](https://github.com/n8n-io/n8n/issues/40542)) ([4c8b76b](https://github.com/n8n-io/n8n/commit/4c8b76b6f08d090bf6e7cf22f66d60ec3d0efdc6))
* Use ID token claims when UserInfo is unavailable ([#40779](https://github.com/n8n-io/n8n/issues/40779)) ([b8b0387](https://github.com/n8n-io/n8n/commit/b8b0387a31b556e296529235f9c4a75b307bb8f1))
* Validate and default public API pagination limits ([#40483](https://github.com/n8n-io/n8n/issues/40483)) ([f212d5b](https://github.com/n8n-io/n8n/commit/f212d5b900fe92c3012001b32f4cf17bd831921e))
* Wait for MockServer HTTP status without following logs ([#40846](https://github.com/n8n-io/n8n/issues/40846)) ([4593838](https://github.com/n8n-io/n8n/commit/45938389b86b6bfe25a8a8f3d132b600ee807f58))
### Features
* Add Antigravity to the MCP client connection dialog ([#40879](https://github.com/n8n-io/n8n/issues/40879)) ([f0a38cf](https://github.com/n8n-io/n8n/commit/f0a38cfe5801ba8d62b97f6d4ffeb031f23aa231))
* Add Google Vertex AI credentials ([#40665](https://github.com/n8n-io/n8n/issues/40665)) ([a7cba90](https://github.com/n8n-io/n8n/commit/a7cba90a854ea34198dd9c1fcb4f7eeae08c364d))
* **ai-builder:** Reopen closed AI Assistant tabs when the agent changes the artifact ([#40081](https://github.com/n8n-io/n8n/issues/40081)) ([5d38667](https://github.com/n8n-io/n8n/commit/5d3866775c828e766ca16642d5ae2a340d4133ca))
* **Azure AI Foundry Chat Model Node:** Speak the Anthropic Messages schema for Claude deployments ([#40306](https://github.com/n8n-io/n8n/issues/40306)) ([c134edf](https://github.com/n8n-io/n8n/commit/c134edf473276ff63387d28aea0d08c9ff676f7c))
* **Azure OpenAI Chat Model Node:** Rename the Foundry nodes and credentials to Microsoft Foundry ([#40398](https://github.com/n8n-io/n8n/issues/40398)) ([e5c8a8b](https://github.com/n8n-io/n8n/commit/e5c8a8bb62d2ce468d1cda3965562eeaa69996f8))
* Configure workflow tool inputs for Agents ([#40285](https://github.com/n8n-io/n8n/issues/40285)) ([4cb98ae](https://github.com/n8n-io/n8n/commit/4cb98aea9fbcede8ae414c3f817c7b0490d401f8))
* **core:** Add credentialTransfer policy enforcement point ([#40300](https://github.com/n8n-io/n8n/issues/40300)) ([c2f6920](https://github.com/n8n-io/n8n/commit/c2f6920794e66e7108b0005233506f7694a11a7e))
* **core:** Add execution identity to every OTel span ([#40649](https://github.com/n8n-io/n8n/issues/40649)) ([22ba4e7](https://github.com/n8n-io/n8n/commit/22ba4e7bc5c6fbe5243ff5c227c718ab7197c5e1))
* **core:** Add overwrite schema conflict policy to data table package import ([#40345](https://github.com/n8n-io/n8n/issues/40345)) ([3af9817](https://github.com/n8n-io/n8n/commit/3af98170d0d98a201df1a45f2ecee17f5f00f298))
* **core:** Add overwrite-non-destructive schema conflict policy to data table package import ([#40446](https://github.com/n8n-io/n8n/issues/40446)) ([dc33c29](https://github.com/n8n-io/n8n/commit/dc33c29d1af3f47a6179a76ff21ccc7bd1f75357))
* **core:** Add Prometheus metrics for database connection recovery ([#39890](https://github.com/n8n-io/n8n/issues/39890)) ([d904e7a](https://github.com/n8n-io/n8n/commit/d904e7a2476794acdf3928faacd86ae9b3e45220))
* **core:** Add the WhatsApp agent channel ([#38750](https://github.com/n8n-io/n8n/issues/38750)) ([b0d1a30](https://github.com/n8n-io/n8n/commit/b0d1a30f50fdf6b3720c2a5773e28efff5c5b0b5))
* **core:** Add workflow suggestion review actions ([#39858](https://github.com/n8n-io/n8n/issues/39858)) ([eaf8c25](https://github.com/n8n-io/n8n/commit/eaf8c25d1c2b680fe55f58fc9f6d10647e6ae640))
* **core:** Allow confirming destructive data table changes when continuing an apply ([#40491](https://github.com/n8n-io/n8n/issues/40491)) ([9946cfe](https://github.com/n8n-io/n8n/commit/9946cfe901b538ec5ca29e85cde3ec2044d33d00))
* **core:** Apply the member credential rule to Owners and admins in team projects ([#40448](https://github.com/n8n-io/n8n/issues/40448)) ([3cff8dc](https://github.com/n8n-io/n8n/commit/3cff8dc4ecac5fd173d198f3e319ab473cdd7b22))
* **core:** Block create/update of workflows with deprecated nodes ([#31360](https://github.com/n8n-io/n8n/issues/31360)) ([ea8417e](https://github.com/n8n-io/n8n/commit/ea8417e29ad6f8b981d9a04b17283d5d77f2b5bb))
* **core:** Email the agent owner when a monthly budget alert is crossed ([#40544](https://github.com/n8n-io/n8n/issues/40544)) ([19e1f70](https://github.com/n8n-io/n8n/commit/19e1f70ea62ad151abe18b5a25721caa35d7bedd))
* **core:** Emit opt-in start marker spans for workflow and node executions ([#40762](https://github.com/n8n-io/n8n/issues/40762)) ([c713545](https://github.com/n8n-io/n8n/commit/c7135451ebd552267aedf4898d845c53a97aab54))
* **core:** Experiment to show assistant composer and starter templates in agent list ([#40396](https://github.com/n8n-io/n8n/issues/40396)) ([fe26ba8](https://github.com/n8n-io/n8n/commit/fe26ba8d3a63963d6c7868338e73fb77378e94a9))
* **core:** Handle inbound media handling for whatsapp ([#39409](https://github.com/n8n-io/n8n/issues/39409)) ([50c2ca0](https://github.com/n8n-io/n8n/commit/50c2ca0a27189136d82339bdafd5d8c7513a9916))
* **core:** Handle message quality rate limits for whatsapp integration ([#39205](https://github.com/n8n-io/n8n/issues/39205)) ([3c33856](https://github.com/n8n-io/n8n/commit/3c33856997b084a3a87038c0d72f80d9b91af1b7))
* **core:** Hide credential-only nodes under a credential type policy ([#39652](https://github.com/n8n-io/n8n/issues/39652)) ([370b30f](https://github.com/n8n-io/n8n/commit/370b30f9195ba8d5ceaf75fb4cdfcf127105a3c6))
* **core:** Pair data table columns by id on package import ([#40709](https://github.com/n8n-io/n8n/issues/40709)) ([27b43de](https://github.com/n8n-io/n8n/commit/27b43de85f987ddd783e7c7ccbde7977d09a6d03))
* **core:** Persist self-healing results and handoffs ([#40115](https://github.com/n8n-io/n8n/issues/40115)) ([168a0ac](https://github.com/n8n-io/n8n/commit/168a0ac86056afd743bfde63863abbab4e8515f4))
* **core:** Post a budget-stop message on external agent channels ([#40767](https://github.com/n8n-io/n8n/issues/40767)) ([5e01906](https://github.com/n8n-io/n8n/commit/5e01906a1e6c177c0ce02d18317ce2d7b6ee7e97))
* **core:** Promote folder and project renames alongside selected workflows ([#40502](https://github.com/n8n-io/n8n/issues/40502)) ([a249e20](https://github.com/n8n-io/n8n/commit/a249e202905f30829fe3a7eacd2eba8dff6573ef))
* **core:** Report crashed executions from startup log recovery ([#40390](https://github.com/n8n-io/n8n/issues/40390)) ([668e71d](https://github.com/n8n-io/n8n/commit/668e71d54a26da7c12d092a7375a7cb3349a8471))
* **core:** Report destructive data table changes in the promotion apply preflight ([#40454](https://github.com/n8n-io/n8n/issues/40454)) ([5d208c8](https://github.com/n8n-io/n8n/commit/5d208c85ed275c22cc5597124b7a9cf590d18f11))
* **core:** Report the deployment artifact in telemetry ([#40319](https://github.com/n8n-io/n8n/issues/40319)) ([344dea5](https://github.com/n8n-io/n8n/commit/344dea5c77fc5f61ce10171a2553faa9bef4e609))
* **core:** Run the workflow history trim as a durable daily system task ([#40085](https://github.com/n8n-io/n8n/issues/40085)) ([38eea65](https://github.com/n8n-io/n8n/commit/38eea65993339ea3e8156cdbacef247749331351))
* **core:** Search, create and reopen agents from the command bar ([#40504](https://github.com/n8n-io/n8n/issues/40504)) ([75a9cc7](https://github.com/n8n-io/n8n/commit/75a9cc7e1219d35b441b02c20446dd89db186ff7))
* **core:** Serve Prometheus metrics while the database is unavailable ([#39908](https://github.com/n8n-io/n8n/issues/39908)) ([4e217ae](https://github.com/n8n-io/n8n/commit/4e217aeac6b029692fb8a692a3849ae8e5310b5a))
* **core:** Serve the instance CSP on all non-script responses ([#40205](https://github.com/n8n-io/n8n/issues/40205)) ([cabf0bf](https://github.com/n8n-io/n8n/commit/cabf0bf3b466a725deada3b532347b7db530dcac))
* **core:** Show every user the migration report, scoped to the workflows they can edit ([#40449](https://github.com/n8n-io/n8n/issues/40449)) ([f4f7dcf](https://github.com/n8n-io/n8n/commit/f4f7dcf13b6d93d46a2860e2c2577f9f6dda4c52))
* **core:** Show the agent chat attach button on the left of the composer ([#40320](https://github.com/n8n-io/n8n/issues/40320)) ([209adf9](https://github.com/n8n-io/n8n/commit/209adf9a7ee9e71cfe3d5119316ca9fce4b3ac68))
* **Databricks Node:** Guard the Vector Store insert against the wrong index ([#39699](https://github.com/n8n-io/n8n/issues/39699)) ([0932e95](https://github.com/n8n-io/n8n/commit/0932e9572e2650165b260fc591d1f02204c17aae))
* **editor:** Add a state column to the migration rule detail ([#40388](https://github.com/n8n-io/n8n/issues/40388)) ([682d092](https://github.com/n8n-io/n8n/commit/682d0920ba5cb2ab5e3ac0671f993c8e529e8389))
* **editor:** Add agent setup checklist ([#39919](https://github.com/n8n-io/n8n/issues/39919)) ([883ade4](https://github.com/n8n-io/n8n/commit/883ade4b9d2505f359057eb10c8d71ab153033a7))
* **editor:** Add order to settings sidebar links ([#40505](https://github.com/n8n-io/n8n/issues/40505)) ([cef87cf](https://github.com/n8n-io/n8n/commit/cef87cfcab3f59a657c8c27309f4807bd2d4a93a))
* **editor:** Add project selection to Vertex AI credentials ([#40667](https://github.com/n8n-io/n8n/issues/40667)) ([cdc23c6](https://github.com/n8n-io/n8n/commit/cdc23c666ffd6ed55f019aa24c99efdaf10fad14))
* **editor:** Animate the n8n Assistant activity indicator ([#40497](https://github.com/n8n-io/n8n/issues/40497)) ([04e1e7f](https://github.com/n8n-io/n8n/commit/04e1e7fc4771ff1371ac41f1d74aef7ced26b175))
* **editor:** Disable restricted model providers in the agent model selector ([#40658](https://github.com/n8n-io/n8n/issues/40658)) ([cde7a9d](https://github.com/n8n-io/n8n/commit/cde7a9dbd985ae9e83de2d39dccc508a41d9a676))
* **editor:** Explain a restricted model provider with the restriction popover ([#40705](https://github.com/n8n-io/n8n/issues/40705)) ([75de193](https://github.com/n8n-io/n8n/commit/75de193d9090d160dd191667adb85dc423951045))
* **editor:** Explain instance-role access in the credential sharing "Used in" row ([#40555](https://github.com/n8n-io/n8n/issues/40555)) ([48f05f9](https://github.com/n8n-io/n8n/commit/48f05f92fe9e7bd1c1d220a53a8c17055a17e70c))
* **editor:** Rebuild the command bar with type tabs and paged search ([#40461](https://github.com/n8n-io/n8n/issues/40461)) ([e36093b](https://github.com/n8n-io/n8n/commit/e36093b11db0580add10306d27d090a27790f4fb))
* **editor:** Rebuild the personal settings page with the design-system settings components ([#40298](https://github.com/n8n-io/n8n/issues/40298)) ([09436b7](https://github.com/n8n-io/n8n/commit/09436b78f9f6f320073f911ca11160ad9a66d94f))
* **editor:** Recommend Claude Opus 5.5 and GPT-6 models in AI Assistant setup ([#40660](https://github.com/n8n-io/n8n/issues/40660)) ([1ad3c54](https://github.com/n8n-io/n8n/commit/1ad3c54803569dd83976c055785b51b62555bf44))
* **editor:** Replace Windsurf with Devin in the MCP client dialog ([#40912](https://github.com/n8n-io/n8n/issues/40912)) ([e2c4054](https://github.com/n8n-io/n8n/commit/e2c4054cba14a2f1dc29215fc623f6ae42b7a238))
* **editor:** Show the restriction callout and lock the agent tool configuration form ([#40657](https://github.com/n8n-io/n8n/issues/40657)) ([01da889](https://github.com/n8n-io/n8n/commit/01da88958d490e5006874cce2b05554347301b9b))
* **editor:** Show who created each preference on the Preferences page ([#40868](https://github.com/n8n-io/n8n/issues/40868)) ([22ff2a0](https://github.com/n8n-io/n8n/commit/22ff2a06368b49fa25b0ad1c2cf74640c56a0284))
* **editor:** Sort the credential sharing list by people, then projects ([#40478](https://github.com/n8n-io/n8n/issues/40478)) ([02af7e7](https://github.com/n8n-io/n8n/commit/02af7e7659cce85749c719bb6a1b910043357baf))
* **Embeddings Azure OpenAI Node:** Add Entra ID authentication ([#39390](https://github.com/n8n-io/n8n/issues/39390)) ([830486a](https://github.com/n8n-io/n8n/commit/830486a851ceb3eeada1eb945e7cd11c05262901))
* **Google Gemini Node:** Show Nano Banana 2.1 and 2 Lite in the image model list ([#40596](https://github.com/n8n-io/n8n/issues/40596)) ([97c54f6](https://github.com/n8n-io/n8n/commit/97c54f618c6210bbe1dcfadaac702d40e89a820b))
* Make health check timeout configurable ([#39548](https://github.com/n8n-io/n8n/issues/39548)) ([df8605e](https://github.com/n8n-io/n8n/commit/df8605e8750443d66388060212306cd205a4f5d3))
* **Microsoft SharePoint Trigger Node:** Add the Microsoft SharePoint Trigger node ([#40055](https://github.com/n8n-io/n8n/issues/40055)) ([7c126fa](https://github.com/n8n-io/n8n/commit/7c126fab32772241473e1f180c6806af4ce189f8))
### Performance Improvements
* **core:** Keep agent builder system prompt static for prompt caching ([#40364](https://github.com/n8n-io/n8n/issues/40364)) ([ee1db0b](https://github.com/n8n-io/n8n/commit/ee1db0bc12bebb572afd04e6e53efc30ffa01209))
* **core:** Let the agent builder chain config writes without re-reading the config ([#40462](https://github.com/n8n-io/n8n/issues/40462)) ([6b4da93](https://github.com/n8n-io/n8n/commit/6b4da93dcbb909bcf86c03251e3c74033d0dd70f))
* **core:** Let the agent builder edit skill instructions in place ([#40447](https://github.com/n8n-io/n8n/issues/40447)) ([1de45a1](https://github.com/n8n-io/n8n/commit/1de45a1a9b0b0db7036cb25e27bffc95a7df41e2))
* **core:** Prepare Instance AI skill sandbox in the background ([#40363](https://github.com/n8n-io/n8n/issues/40363)) ([b36c2b5](https://github.com/n8n-io/n8n/commit/b36c2b506b92f391f859ec10067e57d96c8b09c8))
* **core:** Send agent builder config writes as objects with changed fields only ([#40666](https://github.com/n8n-io/n8n/issues/40666)) ([2aa3fbf](https://github.com/n8n-io/n8n/commit/2aa3fbf18547cfb6719baabdcd8719fa6d0f53af))
# [2.43.0](https://github.com/n8n-io/n8n/compare/n8n@2.42.0...n8n@2.43.0) (2026-10-06)
### Bug Fixes
* **Agent Node:** Remove outdated tutorial tip callout ([#35505](https://github.com/n8n-io/n8n/issues/35505)) ([53b84d2](https://github.com/n8n-io/n8n/commit/53b84d2baac4f6975627f85ff3d550d84008e749))
* **ai-builder:** Treat a blank folder path as no folder in the build tool ([#40116](https://github.com/n8n-io/n8n/issues/40116)) ([b7071c9](https://github.com/n8n-io/n8n/commit/b7071c91c7ef959e1cc3d703495e4fee9fcc9744))
* Align From AI button with parameter inputs ([#40152](https://github.com/n8n-io/n8n/issues/40152)) ([9675fc9](https://github.com/n8n-io/n8n/commit/9675fc97fd193c0474b36c084bd3d6e928885fed))
* **API:** Emit valid schemas for untyped values in the Public API spec ([#39884](https://github.com/n8n-io/n8n/issues/39884)) ([6918fda](https://github.com/n8n-io/n8n/commit/6918fda0182e55e41efa847a8e6831d08cb3085d))
* **API:** Let global members grant variable scopes to API keys ([#40064](https://github.com/n8n-io/n8n/issues/40064)) ([c95e34f](https://github.com/n8n-io/n8n/commit/c95e34f97af49af5d21bf544faacf92e87fe6319))
* **API:** Return an execution when its stored trace context is incomplete ([#39715](https://github.com/n8n-io/n8n/issues/39715)) ([dfd7a52](https://github.com/n8n-io/n8n/commit/dfd7a522244720ca536e73b8cb3da7802a850a48))
* **Azure OpenAI Chat Model Node:** Support Responses-only deployments ([#39403](https://github.com/n8n-io/n8n/issues/39403)) ([6610987](https://github.com/n8n-io/n8n/commit/66109870570bf195e70bd2ed9c56483945ca6ffd))
* **Brevo Node:** Accept both spellings of the recipients parameter ([#40015](https://github.com/n8n-io/n8n/issues/40015)) ([e144b33](https://github.com/n8n-io/n8n/commit/e144b337de3e1f7a54d653c4ae8eb6dedab94c5b))
* Center pasted nodes in the canvas viewport ([#39995](https://github.com/n8n-io/n8n/issues/39995)) ([bd9e1d8](https://github.com/n8n-io/n8n/commit/bd9e1d8947cb5a4fd187fa6bbf93c6bf0ff1116f))
* Clear connection hover promptly ([#39958](https://github.com/n8n-io/n8n/issues/39958)) ([fa93a7f](https://github.com/n8n-io/n8n/commit/fa93a7f01f0b405f060b3f3c0c43b524e4d2855f))
* **core:** Apply MCP availability rules to error workflow settings ([#39885](https://github.com/n8n-io/n8n/issues/39885)) ([e13c480](https://github.com/n8n-io/n8n/commit/e13c4806262469bca3888da0ad91a3e8354e6d78))
* **core:** Apply policy checks to CLI import and execute commands ([#39714](https://github.com/n8n-io/n8n/issues/39714)) ([c575f18](https://github.com/n8n-io/n8n/commit/c575f18c999d2f7740ff57862ff1077f08107f9e))
* **core:** Apply removed fields when the Agent Builder patches agent config ([#40122](https://github.com/n8n-io/n8n/issues/40122)) ([93c0a5c](https://github.com/n8n-io/n8n/commit/93c0a5c0ff716089047d3b7bb0c233025585f286))
* **core:** Block publishing workflows with unconnected required node inputs ([#37265](https://github.com/n8n-io/n8n/issues/37265)) ([5e28ff8](https://github.com/n8n-io/n8n/commit/5e28ff8c238e9481706ebd8aee3f65704f734235))
* **core:** Cap pending task request timeouts to the shutdown deadline ([#40136](https://github.com/n8n-io/n8n/issues/40136)) ([28bd124](https://github.com/n8n-io/n8n/commit/28bd124258f0d2c16b76c2485675dd6bbc92b4b9))
* **core:** Connect Slack Agent channels through managed setup in MCP ([#39776](https://github.com/n8n-io/n8n/issues/39776)) ([93b658c](https://github.com/n8n-io/n8n/commit/93b658c8db04869c992fc8311a1fec1faf5b195e))
* **core:** Correct Agent session pagination on SQLite ([#39802](https://github.com/n8n-io/n8n/issues/39802)) ([1882cff](https://github.com/n8n-io/n8n/commit/1882cff76b8bcac8259ef2ceb55bcedce31132ff))
* **core:** Deduplicate agent message deliveries ([#39794](https://github.com/n8n-io/n8n/issues/39794)) ([0811443](https://github.com/n8n-io/n8n/commit/081144390982a1589433a9f318d349109c23ec5c))
* **core:** Emit unique keys and conditional requirements in generated node type definitions ([#39960](https://github.com/n8n-io/n8n/issues/39960)) ([1700702](https://github.com/n8n-io/n8n/commit/1700702e52255efadec3def48e9c7575a6c1b956))
* **core:** Generate missing workflow IDs in the import:workflow command ([#40011](https://github.com/n8n-io/n8n/issues/40011)) ([d12cab0](https://github.com/n8n-io/n8n/commit/d12cab0ed18abbfb27881afa6cc52f2cddc5a078))
* **core:** Improve workflow SDK group layout for AI subtrees and sticky notes ([#39981](https://github.com/n8n-io/n8n/issues/39981)) ([7675d2b](https://github.com/n8n-io/n8n/commit/7675d2bcbd7d9942685179254d9d88b38afaad96))
* **core:** Keep concurrent credential tests from sharing one node type registry ([#40054](https://github.com/n8n-io/n8n/issues/40054)) ([1cac1e0](https://github.com/n8n-io/n8n/commit/1cac1e056daade255b123d48a4b39ce8a38f9247))
* **core:** Keep floating entitlements attached when a multi-main instance shuts down ([#39713](https://github.com/n8n-io/n8n/issues/39713)) ([ad90c63](https://github.com/n8n-io/n8n/commit/ad90c6392320c5f2d417ea5ae81c15f314af03b0))
* **core:** Keep jobs a worker enqueued out of its shutdown drain ([#39800](https://github.com/n8n-io/n8n/issues/39800)) ([cd9d1ac](https://github.com/n8n-io/n8n/commit/cd9d1ac669c48e8c0fa68be8feffc4e51e651183))
* **core:** Keep node parameters when n8n Assistant cannot see them ([#39454](https://github.com/n8n-io/n8n/issues/39454)) ([f82fa0c](https://github.com/n8n-io/n8n/commit/f82fa0c1af43b2278bb9f689a2dd73390f1693b4))
* **core:** Keep the task runner running on an unhandled promise rejection ([#39946](https://github.com/n8n-io/n8n/issues/39946)) ([59c6ab2](https://github.com/n8n-io/n8n/commit/59c6ab2057ead5026a04e99427c0151c62ecdca6))
* **core:** Limit background task continuation to the latest stop group ([#40333](https://github.com/n8n-io/n8n/issues/40333)) ([314c430](https://github.com/n8n-io/n8n/commit/314c430bfc2a1fc38ccf1d11a952a5dcc77b6c3a))
* **core:** Load workflow publish history in a separate query ([#40171](https://github.com/n8n-io/n8n/issues/40171)) ([548bd57](https://github.com/n8n-io/n8n/commit/548bd57802f64694d98e70ab1a5fbfa1cdd0fcbe))
* **core:** Pass graceful-shutdown timeout to runners in the runners image ([#39796](https://github.com/n8n-io/n8n/issues/39796)) ([d8dcc92](https://github.com/n8n-io/n8n/commit/d8dcc924b730d4f5c713803372006cbfe11aeab4))
* **core:** Pass registry and auth token to npm outdated for community packages ([#31515](https://github.com/n8n-io/n8n/issues/31515)) ([1998011](https://github.com/n8n-io/n8n/commit/1998011d90c1c4bec561d8c9007e140cd8a01481))
* **core:** Redact MCP tool telemetry properties ([#39887](https://github.com/n8n-io/n8n/issues/39887)) ([fc99aaf](https://github.com/n8n-io/n8n/commit/fc99aaf87be94082f56e3f061e96907c1806a89d))
* **core:** Reload static data for queued executions ([#39668](https://github.com/n8n-io/n8n/issues/39668)) ([439e8ba](https://github.com/n8n-io/n8n/commit/439e8ba2e70be371268bbdb86f6afb9bc5e50699))
* **core:** Report empty node output in Instance AI workflow verification ([#40047](https://github.com/n8n-io/n8n/issues/40047)) ([6438ead](https://github.com/n8n-io/n8n/commit/6438ead58d109b51b9e29752ea5d58f492bd5fcb))
* **core:** Resolve the request target against the dispatcher origin ([#39506](https://github.com/n8n-io/n8n/issues/39506)) ([9183d04](https://github.com/n8n-io/n8n/commit/9183d0422c66b70d83669f255f6d710d6b9c7e7c))
* **core:** Resume Preview agents after waiting workflows finish ([#40043](https://github.com/n8n-io/n8n/issues/40043)) ([bdab0b1](https://github.com/n8n-io/n8n/commit/bdab0b10172a7355804cf6e38afbeb8aa5bd194c))
* **core:** Return upstream error details from the explore_node_resources MCP tool ([#39775](https://github.com/n8n-io/n8n/issues/39775)) ([a931dd8](https://github.com/n8n-io/n8n/commit/a931dd8660b29bb8cbe6424bb1f9a7a7f1412479))
* **core:** Stop waiting on Bull job.finished() for queued executions ([#39723](https://github.com/n8n-io/n8n/issues/39723)) ([c83fee0](https://github.com/n8n-io/n8n/commit/c83fee02fac194543fa4936cfa4f3a57a1da7931))
* **core:** Stop waiting on enqueued jobs in worker shutdown ([#40065](https://github.com/n8n-io/n8n/issues/40065)) ([fc3954b](https://github.com/n8n-io/n8n/commit/fc3954bfe2d88338b8d22453cbb4c111a69d057e))
* **core:** Use the new client ID and secret for OAuth2 client credentials ([#39891](https://github.com/n8n-io/n8n/issues/39891)) ([44d9adf](https://github.com/n8n-io/n8n/commit/44d9adfc7e311e721a6cc70797b854abe3ed528e))
* **core:** Wait for credential deletion to finish ([#40103](https://github.com/n8n-io/n8n/issues/40103)) ([407cf23](https://github.com/n8n-io/n8n/commit/407cf23da75d6027b7490c00ec274114e6438786))
* **Databricks Trigger Node:** Cap pipeline event pages at 250, the limit Databricks enforces ([#40154](https://github.com/n8n-io/n8n/issues/40154)) ([b8cd29f](https://github.com/n8n-io/n8n/commit/b8cd29fde40288d0f14db15bd50429035c210174))
* **DataTable Node:** Continue paginated reads when row counts change ([#39764](https://github.com/n8n-io/n8n/issues/39764)) ([d2eae41](https://github.com/n8n-io/n8n/commit/d2eae41dd6e46d2cb2d430d9df661c4ea8afd4da))
* **editor:** Align Agent confirmation warning icons ([#40040](https://github.com/n8n-io/n8n/issues/40040)) ([f1d4017](https://github.com/n8n-io/n8n/commit/f1d4017883bdae464d0a7588b5eff84443e50351))
* **editor:** Align input heights on the project settings page ([#39611](https://github.com/n8n-io/n8n/issues/39611)) ([ea9f451](https://github.com/n8n-io/n8n/commit/ea9f451076722a6784e0f9d78af4410952be9a99))
* **editor:** Align Preview and Assistant chat history controls ([#40165](https://github.com/n8n-io/n8n/issues/40165)) ([a30bb7d](https://github.com/n8n-io/n8n/commit/a30bb7d89d051f26030800db9f7e31003a8aaa4e))
* **editor:** Align workflow and agent action menus ([#39234](https://github.com/n8n-io/n8n/issues/39234)) ([d09e6d6](https://github.com/n8n-io/n8n/commit/d09e6d65fcb3398098341d63b7df1b7116baf4c7))
* **editor:** Close the AI Assistant tab hover card when the pointer leaves the tab ([#40003](https://github.com/n8n-io/n8n/issues/40003)) ([0817b0e](https://github.com/n8n-io/n8n/commit/0817b0e8cc605565d269cfcf329eb8336eafc8ef))
* **editor:** Correct the expanded Markdown editor close label ([#40041](https://github.com/n8n-io/n8n/issues/40041)) ([ee46834](https://github.com/n8n-io/n8n/commit/ee46834915197609cd75ce56fdce2c2e8409f787))
* **editor:** Do not run the workflow when the save before execute fails ([#39763](https://github.com/n8n-io/n8n/issues/39763)) ([7204df6](https://github.com/n8n-io/n8n/commit/7204df600d9c9b2dc3c8ac2bc635082d207f72e6))
* **editor:** Enable Save when SSO role provisioning switches back to manual ([#39925](https://github.com/n8n-io/n8n/issues/39925)) ([360ec09](https://github.com/n8n-io/n8n/commit/360ec09cf2a32da71dc595be2618a3e2d834dac8))
* **editor:** Extend workflow review divider to full height ([#40035](https://github.com/n8n-io/n8n/issues/40035)) ([c5658ba](https://github.com/n8n-io/n8n/commit/c5658ba4bf21e839464fc313bb04940ae93506d6))
* **editor:** Fix copy button hover state in MCP settings ([#39888](https://github.com/n8n-io/n8n/issues/39888)) ([f0b7013](https://github.com/n8n-io/n8n/commit/f0b70134a8acec730d69a46d71ee76b7358fb4e8))
* **editor:** Keep credentials unchanged on read-only canvases ([#39889](https://github.com/n8n-io/n8n/issues/39889)) ([d69b52e](https://github.com/n8n-io/n8n/commit/d69b52e2c78fa1e2c993e11ce270f48f11590d05))
* **editor:** Keep execution filters when navigating away from executions ([#39781](https://github.com/n8n-io/n8n/issues/39781)) ([fefb2da](https://github.com/n8n-io/n8n/commit/fefb2da2b1ed670114aa5f38f22bf7fe82e8dd97))
* **editor:** Leave the sweep time of interrupted tool calls out of the Assistant thinking duration ([#40161](https://github.com/n8n-io/n8n/issues/40161)) ([3879051](https://github.com/n8n-io/n8n/commit/387905148a793e83f0fa5d4877947b3c52fd0f22))
* **editor:** Preserve Agent instruction edits during autosave ([#39972](https://github.com/n8n-io/n8n/issues/39972)) ([4d931ca](https://github.com/n8n-io/n8n/commit/4d931ca77e9fd2250cb75ce3b7a55b995c39cef7))
* **editor:** Refresh the Assistant chat list when the tab becomes visible ([#40158](https://github.com/n8n-io/n8n/issues/40158)) ([064c3bf](https://github.com/n8n-io/n8n/commit/064c3bf979538b1ac9e309590b34842265545427))
* **editor:** Remove the new-agent pill from the AI assistant composer ([#40014](https://github.com/n8n-io/n8n/issues/40014)) ([e79a2ba](https://github.com/n8n-io/n8n/commit/e79a2ba84bce39a65151d4ba7ad72da08266daeb))
* **editor:** Remove the one-click connector for the ChatGPT MCP client ([#40123](https://github.com/n8n-io/n8n/issues/40123)) ([cbaea98](https://github.com/n8n-io/n8n/commit/cbaea9852139ceabdd629d582291965f924d9de1))
* **editor:** Restore full-width Agent preview ([#39986](https://github.com/n8n-io/n8n/issues/39986)) ([5c0aff8](https://github.com/n8n-io/n8n/commit/5c0aff8cbc82b384a4205fb3e99bd86954aaade5))
* **editor:** Scale up node icons that declare a size smaller than their slot ([#40181](https://github.com/n8n-io/n8n/issues/40181)) ([3fe4612](https://github.com/n8n-io/n8n/commit/3fe4612d93b8ecf7e04e86d985329650411bc256))
* **editor:** Show full reasoning on first expand of assistant thinking block ([#39892](https://github.com/n8n-io/n8n/issues/39892)) ([57ef0d1](https://github.com/n8n-io/n8n/commit/57ef0d138fb609c472521d9e8b09981625a8b201))
* **editor:** Show remaining credits on Assistant banner for Cloud UBB ([#39901](https://github.com/n8n-io/n8n/issues/39901)) ([29c09c6](https://github.com/n8n-io/n8n/commit/29c09c6f997bcee2fa8133a716d08c3cf2121d0e))
* **editor:** Show warning when moving a workflow with data table dependency ([#39752](https://github.com/n8n-io/n8n/issues/39752)) ([fce9570](https://github.com/n8n-io/n8n/commit/fce9570711e5b14c42204ac2b184680f36b956d6))
* **editor:** Stop credential icon overlapping the credential name ([#39944](https://github.com/n8n-io/n8n/issues/39944)) ([1694727](https://github.com/n8n-io/n8n/commit/169472754843910279010e1007a842030206c4c1))
* **editor:** Unify MCP access labels ([#40090](https://github.com/n8n-io/n8n/issues/40090)) ([88d6579](https://github.com/n8n-io/n8n/commit/88d657945995973b939156b0fb43cdf5baa8cf9d))
* **editor:** Use only server-provided hints for the OAuth consent screen icon ([#37317](https://github.com/n8n-io/n8n/issues/37317)) ([01e5ebf](https://github.com/n8n-io/n8n/commit/01e5ebf7267d7d4eb39ba2caded51e92c5ba2945))
* **editor:** Wait for OAuth sign-in before the assistant credential card continues ([#39998](https://github.com/n8n-io/n8n/issues/39998)) ([0a1ed4e](https://github.com/n8n-io/n8n/commit/0a1ed4e09b0e16cd55a29ada08b2641447a5f815))
* **Execute Workflow Node:** Return declared sub-workflow outputs ([#39755](https://github.com/n8n-io/n8n/issues/39755)) ([41a0cca](https://github.com/n8n-io/n8n/commit/41a0ccaf160c22839ab82211e7741d4a607ba03f))
* **Google Calendar Trigger Node:** Handle all-day event boundaries ([#39898](https://github.com/n8n-io/n8n/issues/39898)) ([900fe0c](https://github.com/n8n-io/n8n/commit/900fe0c03a96009aee9103e8ec83e756daa6d943))
* Hide node types that the instance does not load ([#39571](https://github.com/n8n-io/n8n/issues/39571)) ([0afda58](https://github.com/n8n-io/n8n/commit/0afda588042c712da6225663669f847cdfe788f7))
* Keep workflow sharing open until changes are saved ([#40137](https://github.com/n8n-io/n8n/issues/40137)) ([9e5eb79](https://github.com/n8n-io/n8n/commit/9e5eb79cc46b2d6fe806be00a078225905ee77f5))
* Limit MCP Agent model discovery results ([#39973](https://github.com/n8n-io/n8n/issues/39973)) ([996dec3](https://github.com/n8n-io/n8n/commit/996dec31936c7aeba7a9212df8476ead584f7d3d))
* Pass shutdown margin to JavaScript runner in runners image ([#40178](https://github.com/n8n-io/n8n/issues/40178)) ([df27223](https://github.com/n8n-io/n8n/commit/df27223a4edf9cca4287bdd321d4acfba1effac9))
* Persist nested node custom span attributes ([#40107](https://github.com/n8n-io/n8n/issues/40107)) ([4a0865b](https://github.com/n8n-io/n8n/commit/4a0865bb62a602397a61f6f635bdf16bb4b99e6a))
* Replace deprecated APIs in services and tooling ([#40199](https://github.com/n8n-io/n8n/issues/40199)) ([be2ee6f](https://github.com/n8n-io/n8n/commit/be2ee6f35661f4e052cc600047594a153a71bdc3))
* Report the real cause when a module entrypoint fails to load ([#37625](https://github.com/n8n-io/n8n/issues/37625)) ([5db0c39](https://github.com/n8n-io/n8n/commit/5db0c39dde9086dbd5ad6041e53ad6d896af0b8f))
* Scope the legacy setup credential picker to the target workflow and report unusable credentials on apply ([#38197](https://github.com/n8n-io/n8n/issues/38197)) ([5c1f8f7](https://github.com/n8n-io/n8n/commit/5c1f8f7f6c7537bfd5a65e94a886d8cc29196908))
* **Split Out Node:** Support dot notation in destination fields ([#39661](https://github.com/n8n-io/n8n/issues/39661)) ([f9dbd2c](https://github.com/n8n-io/n8n/commit/f9dbd2c8d63413c61ba781ab1050ec77a2499973))
* **WhatsApp Node:** Fetch all templates for the dropdown ([#39497](https://github.com/n8n-io/n8n/issues/39497)) ([ce295b6](https://github.com/n8n-io/n8n/commit/ce295b6080f34cc0c9b0c51119d2b1469d19a5ac))
### Features
* **ai-builder:** Change knowledge subtitle ([#39838](https://github.com/n8n-io/n8n/issues/39838)) ([6cc8c0d](https://github.com/n8n-io/n8n/commit/6cc8c0d4480b4a7a0ea44d38655060325fe939f7))
* **Azure OpenAI Chat Model Node:** Add the deployment dropdown ([#39643](https://github.com/n8n-io/n8n/issues/39643)) ([022f4a6](https://github.com/n8n-io/n8n/commit/022f4a6477d0f53f61acda88d5b71617cdd4ca5b))
* **core:** Add 'align' prop to Select component ([#39965](https://github.com/n8n-io/n8n/issues/39965)) ([b15ffa9](https://github.com/n8n-io/n8n/commit/b15ffa95423c8a238a155f1d379fcf031bf1a4eb))
* **core:** Add a guardrail runner to the agent loop ([#39621](https://github.com/n8n-io/n8n/issues/39621)) ([3745c83](https://github.com/n8n-io/n8n/commit/3745c835b2b47ed484246fcd7aefd5e9be3be5bf))
* **core:** Add an instance setting for Agents ([#40153](https://github.com/n8n-io/n8n/issues/40153)) ([628ada7](https://github.com/n8n-io/n8n/commit/628ada76cde4f51348849893dceaa61c3528e36e))
* **core:** Add an opt-in budget guardrail for agent runs ([#39765](https://github.com/n8n-io/n8n/issues/39765)) ([d5937ed](https://github.com/n8n-io/n8n/commit/d5937ed2b6e947cb309566b9fb2cbfb32bb33c66))
* **core:** Add engine suspension at node boundaries for resumable executions ([#37649](https://github.com/n8n-io/n8n/issues/37649)) ([680f958](https://github.com/n8n-io/n8n/commit/680f9582e16bff0d6e8c4077a13f2ac26061bb88))
* **core:** Add inbound-auth-core module with trusted source entities and migration ([#39642](https://github.com/n8n-io/n8n/issues/39642)) ([0f63032](https://github.com/n8n-io/n8n/commit/0f630329167896a1452a2d6c9b5e12cf6dce165b))
* **core:** Add remote search and programmatic focus to N8nCombobox so the MCP selects can leave N8nSelect ([#40140](https://github.com/n8n-io/n8n/issues/40140)) ([8f13f28](https://github.com/n8n-io/n8n/commit/8f13f2830a771e10ecfcc3c178a60c614103e3b5))
* **core:** Add tool to mark an agent session as failed ([#39754](https://github.com/n8n-io/n8n/issues/39754)) ([114a573](https://github.com/n8n-io/n8n/commit/114a5737f57b271cb4d63dc849a13e8d27e148a4))
* **core:** Capture sidecall generation usd cost ([#39627](https://github.com/n8n-io/n8n/issues/39627)) ([8c9733b](https://github.com/n8n-io/n8n/commit/8c9733b5c68202dc17a41aa7d72816879e223c66))
* **core:** Change IAI permissions logic ([#39303](https://github.com/n8n-io/n8n/issues/39303)) ([99182c2](https://github.com/n8n-io/n8n/commit/99182c29be23cd2d8cdb1e1e5b46d3d37ceaf716))
* **core:** Escalate background sub-agent approvals to parent chats ([#39552](https://github.com/n8n-io/n8n/issues/39552)) ([5d40d83](https://github.com/n8n-io/n8n/commit/5d40d837f632799d3b81b9a4d8dcd0d0dad8ad03))
* **core:** Export the stored schedule of durable system tasks as metrics ([#40009](https://github.com/n8n-io/n8n/issues/40009)) ([3faf54f](https://github.com/n8n-io/n8n/commit/3faf54fea360d8bebb2c598d6a730c9e034dee90))
* **core:** Hide current Agent references and show built Workflow cards in the embedded Assistant ([#40149](https://github.com/n8n-io/n8n/issues/40149)) ([1043504](https://github.com/n8n-io/n8n/commit/1043504c7a76de1809a9dcf2e1e6f0c88f5b1b9f))
* **core:** Indicate unpublished changes in agent resource list view ([#40177](https://github.com/n8n-io/n8n/issues/40177)) ([6a5aa78](https://github.com/n8n-io/n8n/commit/6a5aa7862ea38cbf75445b13993018aaff587c79))
* **core:** New agent styled differently on agent list view ([#39856](https://github.com/n8n-io/n8n/issues/39856)) ([f931ea8](https://github.com/n8n-io/n8n/commit/f931ea81d52b920d14000c57eaf71a646981467f))
* **core:** Persist agent budget spend in the database ([#40138](https://github.com/n8n-io/n8n/issues/40138)) ([a2fd418](https://github.com/n8n-io/n8n/commit/a2fd4189f1788a8656e63c8d17cf2c3be197f5ca))
* **core:** Run legacy Cron node schedules on the durable scheduler ([#39411](https://github.com/n8n-io/n8n/issues/39411)) ([bab2978](https://github.com/n8n-io/n8n/commit/bab2978ccf0a9bcb8a55c71386e973531bd958d9))
* **core:** Send a log streaming audit event when a policy blocks an action ([#39581](https://github.com/n8n-io/n8n/issues/39581)) ([55fd9da](https://github.com/n8n-io/n8n/commit/55fd9daa089b3af5f387f968644a6cc10e57c451))
* **core:** Serve the migration report overview from the finding table ([#39969](https://github.com/n8n-io/n8n/issues/39969)) ([6769662](https://github.com/n8n-io/n8n/commit/6769662ecf875317187dd70e4b82b6dc099893ed))
* **core:** Serve the migration rule detail from the finding table ([#39974](https://github.com/n8n-io/n8n/issues/39974)) ([b8ff99f](https://github.com/n8n-io/n8n/commit/b8ff99f2cc66c64c8347d97d803fb1ed63c13547))
* **core:** Stop engine v2 executions from the control plane ([#39786](https://github.com/n8n-io/n8n/issues/39786)) ([56d6e9d](https://github.com/n8n-io/n8n/commit/56d6e9da2c64a3671ead1dfa399f94b934b1f149))
* **core:** Store isolated workflow suggestions for review ([#39505](https://github.com/n8n-io/n8n/issues/39505)) ([0352a19](https://github.com/n8n-io/n8n/commit/0352a196542703a8af80a116c7f94973b6eb2cf2))
* **core:** Vanish Fix with Assistant banner when AIA fixes error ([#39977](https://github.com/n8n-io/n8n/issues/39977)) ([0f11660](https://github.com/n8n-io/n8n/commit/0f11660414aa34e0792c102d174f59d0dda126cd))
* **Crypto Node:** Add RSA-OAEP hash option ([#39853](https://github.com/n8n-io/n8n/issues/39853)) ([94a49d0](https://github.com/n8n-io/n8n/commit/94a49d08ce39efc8c20e46ac4b23138dd9419f06))
* **Databricks Node:** Enable the Job resource ([#40142](https://github.com/n8n-io/n8n/issues/40142)) ([fb69206](https://github.com/n8n-io/n8n/commit/fb69206450729bf96f659ed9b7ff5789b395619a))
* **editor:** Add activation menus to Agent capabilities ([#40104](https://github.com/n8n-io/n8n/issues/40104)) ([53b6a68](https://github.com/n8n-io/n8n/commit/53b6a68e12483fed869ac907e089bf86b502291b))
* **editor:** Add keyboard controls to n8n Assistant panel ([#39386](https://github.com/n8n-io/n8n/issues/39386)) ([41994bc](https://github.com/n8n-io/n8n/commit/41994bc6c7476e051fe6d5b960dd6d6f03924de5))
* **editor:** Add Remove context menus to Agent configuration ([#40089](https://github.com/n8n-io/n8n/issues/40089)) ([3d70eef](https://github.com/n8n-io/n8n/commit/3d70eef3a3593f368110d8d76411769b0c6e90f6))
* **editor:** Add Stop all tasks to the Preview task panel ([#40120](https://github.com/n8n-io/n8n/issues/40120)) ([25831a8](https://github.com/n8n-io/n8n/commit/25831a8ac0d0f2b5c060dcc39c7ed28ef5da5306))
* **editor:** Add usage and budget settings for agents ([#39909](https://github.com/n8n-io/n8n/issues/39909)) ([c4d31db](https://github.com/n8n-io/n8n/commit/c4d31db8d61f972e29d0d48e03987d67edbfec0a))
* **editor:** Allow reordering queued messages in Agent Preview ([#40101](https://github.com/n8n-io/n8n/issues/40101)) ([33505d7](https://github.com/n8n-io/n8n/commit/33505d7faade510f270f032a6f7aa44744e3ab8d))
* **editor:** Close AI Assistant tabs and keep the open tabs per thread ([#39660](https://github.com/n8n-io/n8n/issues/39660)) ([9ab649f](https://github.com/n8n-io/n8n/commit/9ab649ff55b8b5af3d3331c4355d841d37a41b34))
* **editor:** Open and collapse the logs panel around runs in the AI Assistant artifact view ([#38773](https://github.com/n8n-io/n8n/issues/38773)) ([9a4a1dc](https://github.com/n8n-io/n8n/commit/9a4a1dcf27d1a16b32ea6c68a6e7764403853e6a))
* **editor:** Open any project resource as an AI Assistant tab ([#39663](https://github.com/n8n-io/n8n/issues/39663)) ([0c4bf38](https://github.com/n8n-io/n8n/commit/0c4bf38033be064f021bcaea2fcfc50d82c874c6))
* **editor:** Refine the workflow review detail layout ([#39866](https://github.com/n8n-io/n8n/issues/39866)) ([373bf77](https://github.com/n8n-io/n8n/commit/373bf77f3a4d97cb616f6f1248cdf487ac598f6e))
* **editor:** Release Browser Use to all users ([#39762](https://github.com/n8n-io/n8n/issues/39762)) ([f58f0ec](https://github.com/n8n-io/n8n/commit/f58f0ec1d046204b1e1047f6c104606a0277cb41))
* **editor:** Reorder AI Assistant tabs by dragging ([#39664](https://github.com/n8n-io/n8n/issues/39664)) ([2f4bbfa](https://github.com/n8n-io/n8n/commit/2f4bbfa7d2e0debdbfa8b8db981b44393c262c33))
* **editor:** Replace severity with impact categories in the migration report ([#39551](https://github.com/n8n-io/n8n/issues/39551)) ([0f77ba5](https://github.com/n8n-io/n8n/commit/0f77ba5e7ee90bb378764a2dc5689a1d6fe3f7a6))
* **editor:** Show Gateway credits promotions on community nodes ([#40010](https://github.com/n8n-io/n8n/issues/40010)) ([190d7c0](https://github.com/n8n-io/n8n/commit/190d7c0dc0fb6dcef315de97d8cb2d24579afdff))
* **editor:** Show migration progress on report overview ([#39861](https://github.com/n8n-io/n8n/issues/39861)) ([9d11369](https://github.com/n8n-io/n8n/commit/9d11369db77719f43ff52e6d48455251c3358f87))
* **editor:** Show n8n logo on canvas in canvas-only mode ([#39846](https://github.com/n8n-io/n8n/issues/39846)) ([1153702](https://github.com/n8n-io/n8n/commit/1153702d1a29223f7b80a51e1d73d4772f4bc462))
* **editor:** Show the trigger icon on the execute button and run a trigger from its menu ([#39580](https://github.com/n8n-io/n8n/issues/39580)) ([55a8787](https://github.com/n8n-io/n8n/commit/55a87877b5ba82f7e460ac9894fcfc515263e3b3))
* **editor:** Show whose credential a node uses and let others switch from it ([#40281](https://github.com/n8n-io/n8n/issues/40281)) ([92ae1b3](https://github.com/n8n-io/n8n/commit/92ae1b336f1542b73eb0c65f01426d9c3739836d))
* **editor:** Stop Execute and Publish when a credential is not yours to use ([#39883](https://github.com/n8n-io/n8n/issues/39883)) ([deaa9b1](https://github.com/n8n-io/n8n/commit/deaa9b105477ef0ace3ddedaa32f37c77a106ca3))
* **editor:** Submit selected project changes from the promote modal ([#39609](https://github.com/n8n-io/n8n/issues/39609)) ([f7cfb52](https://github.com/n8n-io/n8n/commit/f7cfb520bf666a6122bb8b99e7ae2f976f9a0b0a))
* Hide generated AI tools listed in NODES_EXCLUDE and empty node creator entries ([#39577](https://github.com/n8n-io/n8n/issues/39577)) ([5e376b6](https://github.com/n8n-io/n8n/commit/5e376b69edf3eb10dfa7f4a735ddf36a5cb027bf))
* Implements n8n Assistant nudge on workflow errors ([#39774](https://github.com/n8n-io/n8n/issues/39774)) ([af26954](https://github.com/n8n-io/n8n/commit/af2695407abd2d299819f94aa8c4a9eb254587f3))
* **Supabase Node:** Add OAuth credentials and reuse them for MCP ([#39979](https://github.com/n8n-io/n8n/issues/39979)) ([8e339d7](https://github.com/n8n-io/n8n/commit/8e339d70513d5bed3d708d6ea25b4e43c9ed6099))
* Tell the AI Assistant which preview tabs are open ([#39768](https://github.com/n8n-io/n8n/issues/39768)) ([10e484f](https://github.com/n8n-io/n8n/commit/10e484f552abbddf3694f13ccda2875323ba8e68))
### Performance Improvements
* **core:** Load project relations without joining every role scope ([#39756](https://github.com/n8n-io/n8n/issues/39756)) ([d92bc4d](https://github.com/n8n-io/n8n/commit/d92bc4d3ab1ca45e0e2d096e4d66a9dcc7e14511))
# [2.42.0](https://github.com/n8n-io/n8n/compare/n8n@2.41.0...n8n@2.42.0) (2026-09-29) # [2.42.0](https://github.com/n8n-io/n8n/compare/n8n@2.41.0...n8n@2.42.0) (2026-09-29)

View File

@ -432,7 +432,7 @@ Each instance gets its own port, and the webhook URL matches the main URL. Multi
>- This does not work with Podman out of the box. You need to [configure Testcontainers for Podman](https://podman-desktop.io/tutorial/testcontainers-with-podman) first. >- This does not work with Podman out of the box. You need to [configure Testcontainers for Podman](https://podman-desktop.io/tutorial/testcontainers-with-podman) first.
>- Alternatively, you can use colima and set DOCKER_HOST and TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variables as described [here](https://node.testcontainers.org/supported-container-runtimes/#colima) >- Alternatively, you can use colima and set DOCKER_HOST and TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variables as described [here](https://node.testcontainers.org/supported-container-runtimes/#colima)
Refer to [packages/testing/containers/README.md](packages/testing/containers/README.md) for more information. Refer to [packages/quality/environments/containers/README.md](packages/quality/environments/containers/README.md) for more information.
### Work locally with syslog ### Work locally with syslog
@ -661,7 +661,7 @@ E2E tests can be started via one of the following commands:
- `pnpm --filter=n8n-playwright test:local --ui` - Run tests in interactive UI mode (useful for debugging) - `pnpm --filter=n8n-playwright test:local --ui` - Run tests in interactive UI mode (useful for debugging)
- `pnpm --filter=n8n-playwright test:local --grep="test-name"` - Run specific tests matching pattern - `pnpm --filter=n8n-playwright test:local --grep="test-name"` - Run specific tests matching pattern
See `packages/testing/playwright/README.md` for more test commands and `packages/testing/playwright/CONTRIBUTING.md` for writing guidelines. See `packages/quality/testing/playwright/README.md` for more test commands and `packages/quality/testing/playwright/CONTRIBUTING.md` for writing guidelines.
## Create custom nodes ## Create custom nodes

235
OWNERS
View File

@ -8,8 +8,8 @@
# #
# Last-match-wins: specific rules MUST come AFTER general rules. # Last-match-wins: specific rules MUST come AFTER general rules.
# #
# The `required` option makes team approval mandatory: a member of the team # The `required` option makes team approval mandatory for non-test files: a
# must approve the PR before merge. This is enforced by the # member of the team must approve the PR before merge. This is enforced by the
# "Required Reviews" commit status (ci-owners-required-reviews.yml). # "Required Reviews" commit status (ci-owners-required-reviews.yml).
# All other entries are advisory (reviewer recommendations and opt-in # All other entries are advisory (reviewer recommendations and opt-in
# reviewer auto-assignment). # reviewer auto-assignment).
@ -28,6 +28,9 @@ packages/@n8n/config/ @n8n-io/catalysts
packages/@n8n/backend-common/ @n8n-io/catalysts packages/@n8n/backend-common/ @n8n-io/catalysts
packages/@n8n/backend-network/ @n8n-io/catalysts packages/@n8n/backend-network/ @n8n-io/catalysts
packages/@n8n/backend-services/ @n8n-io/catalysts packages/@n8n/backend-services/ @n8n-io/catalysts
packages/@n8n/backend-services/src/services/role.service.ts @n8n-io/iam
packages/@n8n/backend-services/src/services/role-cache.service.ts @n8n-io/iam
packages/@n8n/backend-services/src/services/jwt.service.ts @n8n-io/iam
packages/@n8n/backend-test-utils/ @n8n-io/catalysts packages/@n8n/backend-test-utils/ @n8n-io/catalysts
packages/@n8n/di/ @n8n-io/catalysts packages/@n8n/di/ @n8n-io/catalysts
packages/@n8n/errors/ @n8n-io/catalysts packages/@n8n/errors/ @n8n-io/catalysts
@ -50,21 +53,20 @@ packages/@n8n/db/src/migrations/ @n8n-io/migrations-revie
# Top-level paths # Top-level paths
scripts/ @n8n-io/qa-dx scripts/ @n8n-io/qa-dx
patches/ @n8n-io/qa-dx patches/ @n8n-io/qa-dx
assets/ @n8n-io/adore
security/ @n8n-io/qa-dx security/ @n8n-io/qa-dx
.code-health-baseline.json @n8n-io/qa-dx required .code-health-baseline.json @n8n-io/qa-dx required
OWNERS @n8n-io/qa-dx required OWNERS @n8n-io/qa-dx required
# @n8n/cli # @n8n/cli
packages/@n8n/cli/ @n8n-io/adore packages/@n8n/cli/ @n8n-io/context
packages/@n8n/cli/src/commands/credential/ @n8n-io/iam packages/@n8n/cli/src/commands/credential/ @n8n-io/iam
packages/@n8n/cli/src/commands/user/ @n8n-io/iam packages/@n8n/cli/src/commands/user/ @n8n-io/iam
packages/@n8n/cli/src/commands/data-table/ @n8n-io/adore packages/@n8n/cli/src/commands/data-table/ @n8n-io/knowledge
packages/@n8n/cli/src/commands/tag/ @n8n-io/adore packages/@n8n/cli/src/commands/tag/ @n8n-io/context
packages/@n8n/cli/src/commands/project/ @n8n-io/ligo packages/@n8n/cli/src/commands/project/ @n8n-io/ligo
packages/@n8n/cli/src/commands/source-control/ @n8n-io/ligo packages/@n8n/cli/src/commands/source-control/ @n8n-io/ligo
packages/@n8n/cli/src/commands/variable/ @n8n-io/ligo packages/@n8n/cli/src/commands/variable/ @n8n-io/ligo
packages/@n8n/cli/src/commands/skill/ @n8n-io/ai packages/@n8n/cli/src/commands/skill/ @n8n-io/context
# packages/cli # packages/cli
packages/cli/ @n8n-io/catalysts packages/cli/ @n8n-io/catalysts
@ -83,7 +85,6 @@ packages/cli/src/security-audit/ @n8n-io/catalysts
packages/cli/src/modules/workflow-index/ @n8n-io/catalysts packages/cli/src/modules/workflow-index/ @n8n-io/catalysts
packages/cli/src/modules/breaking-changes/ @n8n-io/catalysts packages/cli/src/modules/breaking-changes/ @n8n-io/catalysts
packages/cli/src/workflows/publication/ @n8n-io/catalysts required packages/cli/src/workflows/publication/ @n8n-io/catalysts required
packages/cli/src/modules/otel/ @n8n-io/ligo
packages/cli/src/auth/ @n8n-io/iam packages/cli/src/auth/ @n8n-io/iam
packages/cli/src/credentials/ @n8n-io/iam packages/cli/src/credentials/ @n8n-io/iam
@ -107,23 +108,22 @@ packages/cli/src/environments.ee/ @n8n-io/ligo
packages/cli/src/public-api/ @n8n-io/ligo packages/cli/src/public-api/ @n8n-io/ligo
packages/cli/src/modules/source-control.ee/ @n8n-io/ligo packages/cli/src/modules/source-control.ee/ @n8n-io/ligo
packages/cli/src/modules/external-secrets.ee/ @n8n-io/ligo packages/cli/src/modules/external-secrets.ee/ @n8n-io/ligo
packages/cli/src/modules/insights/ @n8n-io/ligo packages/modules/insights/ @n8n-io/ligo
packages/cli/src/collaboration/ @n8n-io/catalysts packages/cli/src/collaboration/ @n8n-io/catalysts
packages/cli/src/binary-data/ @n8n-io/catalysts packages/cli/src/binary-data/ @n8n-io/catalysts
packages/cli/src/posthog/ @n8n-io/adore packages/cli/src/posthog/ @n8n-io/growth
packages/cli/src/modules/data-table/ @n8n-io/adore packages/cli/src/modules/data-table/ @n8n-io/knowledge
packages/cli/src/evaluation.ee/ @n8n-io/ai packages/cli/src/evaluation.ee/ @n8n-io/ai-trust
packages/cli/src/chat/ @n8n-io/ai packages/cli/src/chat/ @n8n-io/ai-agents
packages/cli/src/modules/agents/ @n8n-io/ai-agents
packages/cli/src/tool-generation/ @n8n-io/ai packages/cli/src/tool-generation/ @n8n-io/ai
packages/cli/src/modules/workflow-builder/ @n8n-io/ai packages/modules/workflow-builder/ @n8n-io/ai-assistant
packages/cli/src/modules/mcp/ @n8n-io/adore packages/cli/src/modules/mcp/ @n8n-io/context
packages/cli/src/modules/quick-connect/ @n8n-io/ai packages/cli/src/modules/chat-hub/ @n8n-io/ai-assistant
packages/cli/src/modules/chat-hub/ @n8n-io/ai
packages/cli/src/modules/instance-ai/ @n8n-io/ai-assistant packages/cli/src/modules/instance-ai/ @n8n-io/ai-assistant
packages/modules/inbox/ @n8n-io/ligo
packages/cli/src/modules/community-packages/ @n8n-io/nodes
# CLI controllers # CLI controllers
packages/cli/src/controllers/auth.controller.ts @n8n-io/iam packages/cli/src/controllers/auth.controller.ts @n8n-io/iam
@ -138,14 +138,14 @@ packages/cli/src/controllers/user-settings.controller.ts @n8n-io/iam
packages/cli/src/controllers/api-keys.controller.ts @n8n-io/iam packages/cli/src/controllers/api-keys.controller.ts @n8n-io/iam
packages/cli/src/controllers/security-settings.controller.ts @n8n-io/iam packages/cli/src/controllers/security-settings.controller.ts @n8n-io/iam
packages/cli/src/controllers/oauth/ @n8n-io/iam packages/cli/src/controllers/oauth/ @n8n-io/iam
packages/cli/src/controllers/ai.controller.ts @n8n-io/ai packages/cli/src/controllers/ai.controller.ts @n8n-io/ai-assistant
packages/cli/src/controllers/annotation-tags.controller.ee.ts @n8n-io/ai packages/cli/src/controllers/annotation-tags.controller.ee.ts @n8n-io/ai
packages/cli/src/controllers/cta.controller.ts @n8n-io/adore packages/cli/src/controllers/cta.controller.ts @n8n-io/knowledge
packages/cli/src/controllers/folder.controller.ts @n8n-io/adore packages/cli/src/controllers/folder.controller.ts @n8n-io/context
packages/cli/src/controllers/tags.controller.ts @n8n-io/adore packages/cli/src/controllers/tags.controller.ts @n8n-io/context
packages/cli/src/controllers/binary-data.controller.ts @n8n-io/adore packages/cli/src/controllers/binary-data.controller.ts @n8n-io/knowledge
packages/cli/src/controllers/posthog.controller.ts @n8n-io/adore packages/cli/src/controllers/posthog.controller.ts @n8n-io/context
packages/cli/src/controllers/translation.controller.ts @n8n-io/adore packages/cli/src/controllers/translation.controller.ts @n8n-io/catalysts
packages/cli/src/controllers/project.controller.ts @n8n-io/ligo packages/cli/src/controllers/project.controller.ts @n8n-io/ligo
packages/cli/src/controllers/workflow-statistics.controller.ts @n8n-io/ligo packages/cli/src/controllers/workflow-statistics.controller.ts @n8n-io/ligo
packages/cli/src/controllers/node-types.controller.ts @n8n-io/nodes packages/cli/src/controllers/node-types.controller.ts @n8n-io/nodes
@ -153,24 +153,23 @@ packages/cli/src/controllers/dynamic-node-parameters.controller.ts @n8n-io/node
packages/cli/src/controllers/e2e.controller.ts @n8n-io/qa-dx packages/cli/src/controllers/e2e.controller.ts @n8n-io/qa-dx
# CLI services # CLI services
packages/cli/src/services/jwt.service.ts @n8n-io/iam
packages/cli/src/services/user.service.ts @n8n-io/iam packages/cli/src/services/user.service.ts @n8n-io/iam
packages/cli/src/services/role.service.ts @n8n-io/iam
packages/cli/src/services/role-cache.service.ts @n8n-io/iam
packages/cli/src/services/password.utility.ts @n8n-io/iam packages/cli/src/services/password.utility.ts @n8n-io/iam
packages/cli/src/services/public-api-key.service.ts @n8n-io/iam packages/cli/src/services/public-api-key.service.ts @n8n-io/iam
packages/cli/src/services/security-settings.service.ts @n8n-io/iam packages/cli/src/services/security-settings.service.ts @n8n-io/iam
packages/cli/src/services/static-auth-service.ts @n8n-io/iam packages/cli/src/services/static-auth-service.ts @n8n-io/iam
packages/cli/src/services/access.service.ts @n8n-io/iam packages/cli/src/services/access.service.ts @n8n-io/iam
packages/cli/src/services/ai.service.ts @n8n-io/ai packages/cli/src/services/ai.service.ts @n8n-io/ai-assistant
packages/cli/src/services/ai-usage.service.ts @n8n-io/ai packages/cli/src/services/ai-usage.service.ts @n8n-io/ai-assistant
packages/cli/src/services/ai-workflow-builder.service.ts @n8n-io/ai packages/cli/src/services/__tests__/ai-usage.service.test.ts @n8n-io/ai-assistant
packages/cli/src/services/annotation-tag.service.ee.ts @n8n-io/ai packages/cli/src/controllers/__tests__/ai.controller.test.ts @n8n-io/ai-assistant
packages/cli/src/services/folder.service.ts @n8n-io/adore packages/cli/src/services/ai-workflow-builder.service.ts @n8n-io/ai-assistant
packages/cli/src/services/tag.service.ts @n8n-io/adore packages/cli/src/services/annotation-tag.service.ee.ts @n8n-io/context
packages/cli/src/services/cta.service.ts @n8n-io/adore packages/cli/src/services/folder.service.ts @n8n-io/context
packages/cli/src/services/frontend.service.ts @n8n-io/adore packages/cli/src/services/tag.service.ts @n8n-io/context
packages/cli/src/services/banner.service.ts @n8n-io/adore packages/cli/src/services/cta.service.ts @n8n-io/knowledge
packages/cli/src/services/frontend.service.ts @n8n-io/catalysts
packages/cli/src/services/banner.service.ts @n8n-io/context
packages/cli/src/services/project.service.ee.ts @n8n-io/ligo packages/cli/src/services/project.service.ee.ts @n8n-io/ligo
packages/cli/src/services/workflow-statistics.service.ts @n8n-io/ligo packages/cli/src/services/workflow-statistics.service.ts @n8n-io/ligo
packages/cli/src/services/export.service.ts @n8n-io/ligo packages/cli/src/services/export.service.ts @n8n-io/ligo
@ -178,10 +177,11 @@ packages/cli/src/services/import.service.ts @n8n-io/ligo
packages/cli/src/services/ownership.service.ts @n8n-io/ligo packages/cli/src/services/ownership.service.ts @n8n-io/ligo
packages/cli/src/services/dynamic-node-parameters.service.ts @n8n-io/nodes packages/cli/src/services/dynamic-node-parameters.service.ts @n8n-io/nodes
# Adore
packages/frontend/editor-ui/ @n8n-io/frontend packages/frontend/editor-ui/ @n8n-io/frontend
packages/frontend/editor-ui/src/features/ai/ @n8n-io/ai packages/frontend/editor-ui/src/features/ai/ @n8n-io/ai
packages/frontend/editor-ui/src/features/ai/assistant/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/ai/chatHub/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/ai/instanceAi/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/credentials/ @n8n-io/iam packages/frontend/editor-ui/src/features/credentials/ @n8n-io/iam
packages/frontend/editor-ui/src/features/execution/ @n8n-io/ligo packages/frontend/editor-ui/src/features/execution/ @n8n-io/ligo
packages/frontend/editor-ui/src/features/integrations/ @n8n-io/ligo packages/frontend/editor-ui/src/features/integrations/ @n8n-io/ligo
@ -194,19 +194,59 @@ packages/frontend/@n8n/storybook/ @n8n-io/design-engineeri
packages/frontend/@n8n/i18n/ @n8n-io/frontend packages/frontend/@n8n/i18n/ @n8n-io/frontend
packages/@n8n/stylelint-config/ @n8n-io/qa-dx packages/@n8n/stylelint-config/ @n8n-io/qa-dx
packages/frontend/editor-ui/src/features/ai/gateway/ @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useAiGatewayTopUp.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useFreeAiCredits.ts @n8n-io/relay
packages/frontend/editor-ui/src/features/settings/communityNodes/ @n8n-io/nodes
packages/frontend/editor-ui/src/features/credentials/quickConnect/ @n8n-io/nodes required
packages/frontend/editor-ui/src/features/ndv/runData/schemaPreview.api.ts @n8n-io/nodes
packages/frontend/editor-ui/src/features/ndv/runData/schemaPreview.store.ts @n8n-io/nodes
packages/frontend/editor-ui/src/features/agents/channels/ @n8n-io/nodes
# AI # AI
packages/@n8n/instance-ai/ @n8n-io/ai-assistant packages/@n8n/instance-ai/ @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/ @n8n-io/ai packages/@n8n/nodes-langchain/ @n8n-io/ai
packages/@n8n/ai-utilities/ @n8n-io/ai packages/@n8n/nodes-langchain/nodes/agents/ @n8n-io/ai-agents
packages/@n8n/ai-node-sdk/ @n8n-io/ai packages/@n8n/nodes-langchain/nodes/chains/ @n8n-io/ai-agents
packages/@n8n/ai-workflow-builder.ee/ @n8n-io/ai packages/@n8n/nodes-langchain/nodes/code/ @n8n-io/ai-agents
packages/@n8n/agents/ @n8n-io/ai packages/@n8n/nodes-langchain/nodes/output_parser/ @n8n-io/ai-agents
packages/frontend/@n8n/chat/ @n8n-io/ai packages/@n8n/nodes-langchain/nodes/llms/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/vendors/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/ModelSelector/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/embeddings/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/vector_store/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/document_loaders/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/text_splitters/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/retrievers/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/rerankers/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/memory/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/tools/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/ToolExecutor/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/trigger/ @n8n-io/ai-agents
packages/@n8n/ai-utilities/ @n8n-io/ai-agents
packages/@n8n/ai-workflow-builder.ee/ @n8n-io/ai-assistant
packages/@n8n/agents/ @n8n-io/ai-agents
packages/frontend/@n8n/chat/ @n8n-io/ai-agents
packages/frontend/editor-ui/src/features/agents/ @n8n-io/ai-agents
# Chat # Chat Hub
packages/@n8n/chat-hub/ @n8n-io/ai packages/@n8n/chat-hub/ @n8n-io/ai-assistant
packages/@n8n/api-types/src/chat-hub.ts @n8n-io/ai-assistant
packages/@n8n/api-types/src/push/chat-hub.ts @n8n-io/ai-assistant
packages/@n8n/config/src/configs/chat-hub.config.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/vector_store/ChatHubVectorStorePGVector/ @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/vector_store/ChatHubVectorStorePinecone/ @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/vector_store/ChatHubVectorStoreQdrant/ @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/vector_store/shared/chatHub.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStorePGVectorApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStorePineconeApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStoreQdrantApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/mcp/ @n8n-io/nodes required
packages/frontend/editor-ui/src/features/shared/commandBar/composables/useChatHubCommands.ts @n8n-io/ai-assistant
packages/cli/src/modules/breaking-changes/rules/v3/chat-hub-deprecated.rule.ts @n8n-io/ai-assistant
# Nodes # Nodes
@ -214,37 +254,95 @@ packages/@n8n/codemirror-lang/ @n8n-io/nodes
packages/@n8n/codemirror-lang-html/ @n8n-io/nodes packages/@n8n/codemirror-lang-html/ @n8n-io/nodes
packages/@n8n/codemirror-lang-sql/ @n8n-io/nodes packages/@n8n/codemirror-lang-sql/ @n8n-io/nodes
packages/nodes-base/ @n8n-io/nodes packages/nodes-base/ @n8n-io/nodes
packages/nodes-base/nodes/Code/ @n8n-io/nodes required
packages/nodes-base/nodes/ExecuteCommand/ @n8n-io/nodes required
packages/nodes-base/nodes/Ssh/ @n8n-io/nodes required
packages/nodes-base/nodes/HttpRequest/ @n8n-io/nodes required
packages/nodes-base/nodes/Webhook/ @n8n-io/nodes required
packages/nodes-base/nodes/RespondToWebhook/ @n8n-io/nodes required
packages/nodes-base/nodes/Form/ @n8n-io/nodes required
packages/nodes-base/nodes/Wait/ @n8n-io/nodes required
packages/nodes-base/utils/sendAndWait/ @n8n-io/nodes required
packages/nodes-base/nodes/Git/ @n8n-io/nodes required
packages/@n8n/decorators/ @n8n-io/catalysts packages/@n8n/decorators/ @n8n-io/catalysts
packages/node-dev/ @n8n-io/nodes packages/node-dev/ @n8n-io/nodes
packages/@n8n/create-node/ @n8n-io/nodes packages/@n8n/imap/ @n8n-io/nodes
packages/@n8n/node-cli/ @n8n-io/nodes packages/@n8n/computer-use/ @n8n-io/nodes required
packages/@n8n/imap/ @n8n-io/iam packages/@n8n/local-gateway/ @n8n-io/nodes required
packages/@n8n/syslog-client/ @n8n-io/iam packages/@n8n/mcp-browser/ @n8n-io/nodes required
packages/@n8n/scan-community-package/ @n8n-io/nodes packages/@n8n/mcp-browser-extension/ @n8n-io/nodes required
packages/@n8n/eslint-plugin-community-nodes/ @n8n-io/nodes packages/modules/quick-connect/ @n8n-io/nodes required
packages/@n8n/computer-use/ @n8n-io/nodes packages/@n8n/api-types/src/dto/quick-connect/ @n8n-io/nodes required
packages/@n8n/local-gateway/ @n8n-io/nodes packages/@n8n/api-types/src/quick-connect.ts @n8n-io/nodes required
packages/@n8n/mcp-browser/ @n8n-io/nodes packages/cli/src/modules/community-packages/ @n8n-io/nodes
packages/@n8n/mcp-browser-extension/ @n8n-io/nodes packages/cli/src/modules/mcp-registry/ @n8n-io/nodes required
packages/cli/src/modules/agents/integrations/ @n8n-io/nodes
packages/@n8n/api-types/src/schemas/mcp-registry.schema.ts @n8n-io/nodes required
packages/cli/templates/send-and-wait-no-action-required.handlebars @n8n-io/nodes required
packages/@n8n/ai-node-sdk/ @n8n-io/nodes required
# Relay (AI gateway & credits)
packages/cli/src/services/ai-gateway.service.ts @n8n-io/relay required
packages/cli/src/services/ai-gateway-eligibility.ts @n8n-io/relay required
packages/cli/src/services/free-ai-credits.service.ts @n8n-io/relay required
packages/@n8n/config/src/configs/ai-gateway.config.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-config-response.dto.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-usage-response.dto.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-wallet-response.dto.ts @n8n-io/relay
packages/cli/src/modules/instance-ai/instance-ai-gateway.service.ts @n8n-io/relay
packages/cli/src/modules/mcp/mcp-ai-gateway.helper.ts @n8n-io/relay
packages/cli/src/modules/agents/json-config/node-tool-ai-gateway.service.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/stores/aiGateway.store.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useAiGateway.ts @n8n-io/relay
packages/frontend/editor-ui/src/features/credentials/gatewayCreditsPromotion/ @n8n-io/relay
packages/frontend/editor-ui/src/features/shared/nodeCreator/components/SectionHeaderCreditsTag.vue @n8n-io/relay
# Community engineering
.agents/skills/create-community-node-lint-rule/ @n8n-io/community-engineering
.agents/skills/community-pr-readiness-check/ @n8n-io/community-engineering
packages/@n8n/scan-community-package/ @n8n-io/community-engineering
packages/@n8n/eslint-plugin-community-nodes/ @n8n-io/community-engineering
packages/@n8n/node-cli/ @n8n-io/community-engineering
packages/@n8n/create-node/ @n8n-io/community-engineering
# IAM # IAM
packages/@n8n/permissions/ @n8n-io/iam packages/@n8n/permissions/ @n8n-io/iam
packages/@n8n/client-oauth2/ @n8n-io/iam packages/@n8n/client-oauth2/ @n8n-io/iam
packages/@n8n/inbound-auth/ @n8n-io/iam
# LiGo packages/@n8n/syslog-client/ @n8n-io/iam
packages/extensions/insights/ @n8n-io/ligo
# Governance & Observability # Governance & Observability
packages/modules/type-availability-policies/ @n8n-io/governance-and-observability packages/modules/type-availability-policies/ @n8n-io/governance-and-observability
packages/cli/src/modules/type-availability-policies/ @n8n-io/governance-and-observability packages/cli/src/modules/type-availability-policies/ @n8n-io/governance-and-observability
packages/modules/otel/ @n8n-io/governance-and-observability
packages/cli/src/modules/otel/ @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/otel.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/shared/otel.mapper.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/node-type-policies.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/credential-type-policies.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/handlers/node-type-policies/ @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/handlers/credential-type-policies/ @n8n-io/governance-and-observability
packages/cli/src/modules/policy-infrastructure/ @n8n-io/governance-and-observability
packages/cli/src/policy/ @n8n-io/governance-and-observability
packages/@n8n/decorators/src/policy-check/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/dto/otel/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/dto/type-availability-policies/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/node-type-availability.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/credential-type-availability.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/schemas/policy-check-failure.schema.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/schemas/policy-violation.schema.ts @n8n-io/governance-and-observability
packages/@n8n/telemetry/src/events/policies.ts @n8n-io/governance-and-observability
packages/@n8n/telemetry/src/events/type-availability-policies.ts @n8n-io/governance-and-observability
packages/workflow/src/errors/policy-refusal.ts @n8n-io/governance-and-observability
packages/frontend/editor-ui/src/app/composables/usePolicyViolationToast.ts @n8n-io/governance-and-observability
# CI/CD # CI/CD
.github/ @n8n-io/qa-dx .github/ @n8n-io/qa-dx
.github/workflows/ @n8n-io/qa-dx required .github/workflows/ @n8n-io/qa-dx required
.github/workflows/community-pr-close-stale.yml @n8n-io/community-engineering
.github/scripts/ @n8n-io/qa-dx required .github/scripts/ @n8n-io/qa-dx required
.github/actions/ @n8n-io/qa-dx required .github/actions/ @n8n-io/qa-dx required
.github/poutine-rules/ @n8n-io/qa-dx required .github/poutine-rules/ @n8n-io/qa-dx required
@ -253,8 +351,7 @@ docker/get-n8n.sh @n8n-io/qa-dx required
# QA # QA
packages/testing/ @n8n-io/qa-dx packages/quality/ @n8n-io/qa-dx
packages/@n8n/benchmark/ @n8n-io/qa-dx
packages/@n8n/vitest-config/ @n8n-io/qa-dx packages/@n8n/vitest-config/ @n8n-io/qa-dx
# Encryption boundary (IAM) — the encryption area and its guardrail rules. # Encryption boundary (IAM) — the encryption area and its guardrail rules.
@ -267,3 +364,15 @@ packages/@n8n/db/src/entities/deployment-key.ts @n8n-io/iam required
packages/@n8n/db/src/repositories/deployment-key.repository.ts @n8n-io/iam required packages/@n8n/db/src/repositories/deployment-key.repository.ts @n8n-io/iam required
packages/@n8n/eslint-config/src/configs/encryption-boundary.ts @n8n-io/iam required packages/@n8n/eslint-config/src/configs/encryption-boundary.ts @n8n-io/iam required
packages/@n8n/eslint-config/src/rules/no-encryption-guardrail-disable.ts @n8n-io/iam required packages/@n8n/eslint-config/src/rules/no-encryption-guardrail-disable.ts @n8n-io/iam required
# AI Trust (evaluations)
# Placed last so these rules override the broader package rules above.
packages/@n8n/instance-ai/evaluations/ @n8n-io/ai-trust
packages/cli/src/modules/instance-ai/eval/ @n8n-io/ai-trust
packages/quality/testing/playwright/tests/evals/instance-ai/ @n8n-io/ai-trust
.agents/skills/create-instance-ai-eval/ @n8n-io/ai-trust
.agents/skills/create-agent-builder-eval/ @n8n-io/ai-trust
packages/cli/src/modules/agent-evals/ @n8n-io/ai-trust
packages/@n8n/agents/src/evals/ @n8n-io/ai-trust
packages/frontend/editor-ui/src/features/ai/evaluation.ee/ @n8n-io/ai-trust

View File

@ -1,6 +1,6 @@
{ {
"repository": "n8n-io/cat-bot", "repository": "n8n-io/cat-bot",
"releaseTag": "harness-v0.3.0", "releaseTag": "harness-v0.6.0",
"version": "0.3.0", "version": "0.6.0",
"assetName": "n8n-opencode-harness-0.3.0.tgz" "assetName": "n8n-opencode-harness-0.6.0.tgz"
} }

View File

@ -18,6 +18,7 @@
"**/cl100k_base.json", "**/cl100k_base.json",
"**/o200k_base.json", "**/o200k_base.json",
"**/*.generated.ts", "**/*.generated.ts",
"**/benchmark/scripts/mock-api/**",
"**/expectations/**" "**/expectations/**"
] ]
}, },

View File

@ -89,6 +89,7 @@ component_management:
- packages/@n8n/expression-runtime/** - packages/@n8n/expression-runtime/**
- packages/@n8n/extension-sdk/** - packages/@n8n/extension-sdk/**
- packages/@n8n/imap/** - packages/@n8n/imap/**
- packages/@n8n/inbound-auth/**
- packages/@n8n/local-gateway/** - packages/@n8n/local-gateway/**
- packages/@n8n/permissions/** - packages/@n8n/permissions/**
- packages/@n8n/scan-community-package/** - packages/@n8n/scan-community-package/**
@ -149,5 +150,5 @@ ignore:
- (?s:.*/migrations/(postgresdb|sqlite|mysqldb)/.*\.ts.*)\Z - (?s:.*/migrations/(postgresdb|sqlite|mysqldb)/.*\.ts.*)\Z
- (?s:.*/scripts/.*)\Z - (?s:.*/scripts/.*)\Z
# Test/build infrastructure packages # Test/build infrastructure packages
- (?s:.*/packages/testing/.*)\Z - (?s:.*/packages/quality/.*)\Z
- (?s:.*/packages/@n8n/(benchmark|eslint-config|eslint-plugin-community-nodes|stylelint-config|typescript-config|vitest-config)/.*)\Z - (?s:.*/packages/@n8n/(benchmark|eslint-config|eslint-plugin-community-nodes|stylelint-config|typescript-config|vitest-config)/.*)\Z

View File

@ -202,7 +202,7 @@ reviews:
- docker/** - docker/**
- scripts/** - scripts/**
- patches/** - patches/**
- packages/testing/** - packages/quality/**
- packages/@n8n/eslint-config/** - packages/@n8n/eslint-config/**
- packages/@n8n/stylelint-config/** - packages/@n8n/stylelint-config/**
- packages/@n8n/vitest-config/** - packages/@n8n/vitest-config/**

View File

@ -1,7 +1,7 @@
# Every n8n image build uses this file. `pnpm build:docker` and CI both drive # Every n8n image build uses this file. `pnpm build:docker` and CI both drive
# these targets, so a pin changed here changes both. # these targets, so a pin changed here changes both.
variable "NODE_VERSION" { default = "26.7.0" } variable "NODE_VERSION" { default = "26.10.0" }
variable "N8N_VERSION" { default = "snapshot" } variable "N8N_VERSION" { default = "snapshot" }
variable "N8N_RELEASE_TYPE" { default = "dev" } variable "N8N_RELEASE_TYPE" { default = "dev" }
@ -15,14 +15,14 @@ variable "BUILDER_IMAGE" { default = "" }
variable "RUNTIME_IMAGE" { default = "" } variable "RUNTIME_IMAGE" { default = "" }
variable "PC_BUILDER_IMAGE" { variable "PC_BUILDER_IMAGE" {
default = "n8nio/node-pc:26.7.0-dev@sha256:c64642dcb9464e50bd08aef8504affafeb795d01aed2f7ab158976c334a36ef6" default = "n8nio/node-pc:26.10.0-dev@sha256:61e4b1f3b3824ffb908812e01bcbddabb64a01ef23d408d561696c344c6679e3"
} }
variable "PC_RUNTIME_IMAGE" { variable "PC_RUNTIME_IMAGE" {
default = "n8nio/node-pc:26.7.0@sha256:6577d0742ad043baaa39db7dda2ce8aeb73f32c84eb241c49bf716f170c53297" default = "n8nio/node-pc:26.10.0@sha256:386bae24d41c0091d21b4eee124a86464710fff24d5cb7f37386c4c5649b0c89"
} }
variable "DHI_REF" { variable "DHI_REF" {
default = "dhi.io/node:26.7.0-alpine3.24-dev@sha256:4b494d89fb26c950ce97865acf45b480dc7a6868fdc2b81c2d66599702eeac3f" default = "dhi.io/node:26.10.0-alpine3.24-dev@sha256:8da859df5dc853c923ace53c4cfe994a909a28917f7fcfc8508869beab8cf132"
} }
variable "N8N_TAGS" { default = "" } variable "N8N_TAGS" { default = "" }

View File

@ -15,11 +15,11 @@ set -eu
SCRIPT_VERSION="1.4.0" SCRIPT_VERSION="1.4.0"
# The version to install is derived from the latest stable GitHub release in # The version to install is derived from the latest stable GitHub release in
# resolve_n8n_version(); this fallback only applies when that lookup fails. # resolve_n8n_version(); this fallback only applies when that lookup fails.
FALLBACK_N8N_VERSION="2.32.0" FALLBACK_N8N_VERSION="2.43.4"
# Sandbox service release (API, runner and sandbox images ship together). # Sandbox service release (API, runner and sandbox images ship together).
# Pinned here, not resolved at run time: the stack definition must match it. # Pinned here, not resolved at run time: the stack definition must match it.
# --upgrade moves existing installs to this pin. # --upgrade moves existing installs to this pin.
SANDBOX_VERSION="1.3.4" SANDBOX_VERSION="1.8.1"
N8N_DIR="${N8N_DIR:-./n8n}" N8N_DIR="${N8N_DIR:-./n8n}"
N8N_PORT=5678 N8N_PORT=5678
SOURCE_URL="https://github.com/n8n-io/n8n/blob/master/docker/get-n8n.sh" SOURCE_URL="https://github.com/n8n-io/n8n/blob/master/docker/get-n8n.sh"

View File

@ -1,6 +1,6 @@
# CI passes one DHI reference per published Node version (see the matrix in # CI passes one DHI reference per published Node version (see the matrix in
# build-base-image.yml). The default keeps plain `docker build` working. # build-base-image.yml). The default keeps plain `docker build` working.
ARG DHI_REF=dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd ARG DHI_REF=dhi.io/node:24.21.0-alpine3.24-dev@sha256:d22ba0e9ab2a54609ae533df4ebfd6f36c1f233b662a4c547f5a3195e8c21937
FROM ${DHI_REF} FROM ${DHI_REF}
# Install all dependencies in a single layer to minimize image size # Install all dependencies in a single layer to minimize image size

View File

@ -1,9 +1,9 @@
ARG NODE_VERSION=26.7.0 ARG NODE_VERSION=26.10.0
ARG N8N_VERSION=snapshot ARG N8N_VERSION=snapshot
# The digest pins node:26.7.0-alpine3.24 for amd64 and arm64. Change the tag and the digest together. # The digest pins node:26.10.0-alpine3.24 for amd64 and arm64. Change the tag and the digest together.
ARG BUILDER_IMAGE=node:26.7.0-alpine3.24@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 ARG BUILDER_IMAGE=node:26.10.0-alpine3.24@sha256:0b36e8c136b94cd4fcf02188228e76c31ad5872eef3fec8cbd2eee500cfd9e80
ARG RUNTIME_IMAGE=n8nio/base:26.7.0@sha256:33687300c4e94dc00f42ec79ae15082ae07330ecd82ae1167125905b65908ff8 ARG RUNTIME_IMAGE=n8nio/base:26.10.0@sha256:9205c76a7745bfe71de35c2a0b7420238ccb0bdf69fc5273ab2e617fe918cf5f
# The runtime base has no compiler, so this stage supplies one. # The runtime base has no compiler, so this stage supplies one.
FROM ${BUILDER_IMAGE} AS toolchain FROM ${BUILDER_IMAGE} AS toolchain

Some files were not shown because too many files have changed in this diff Show More