Commit Graph

764 Commits

Author SHA1 Message Date
Félix Malfait 8774bf8604 Self-host every font instead of loading them from Google (#23859)
Google Fonts logs the IP and user agent of everyone who loads a font
from it. Any page of ours that links to `fonts.googleapis.com` hands our
users (and every self-hoster's users) to a third party for nothing in
return, since we can serve the same bytes ourselves.

After this PR there is no reference to `fonts.googleapis.com`,
`fonts.gstatic.com` or `next/font/google` left in the repo.

## What changed

**twenty-front, PDF export.** `exportBlockNoteEditorToPdf` registered
Inter by URL against `fonts.gstatic.com`, so exporting a note made the
browser fetch three TTFs from Google. The registration turned out to be
unnecessary altogether: `@blocknote/xl-pdf-exporter` already registers
an `Inter` family for its PDF schema, shipped inlined in the package as
a base64 TTF with the same 2849-codepoint coverage. Deleting our
`Font.register` means no font request leaves the browser, with 41 fewer
lines and nothing vendored.

Only weights 400 and 700 were ever used, and 700 already resolved to
blocknote's `Inter18pt-Bold` before this branch, so the custom 500/600
registrations were dead. The only rendering change is body text going
from `Inter` to `Inter18pt`, the same typeface at its 18pt optical size.

**twenty-sdk, OAuth callback page.** The local "you can close this tab"
page linked to Google Fonts, which meant running `twenty auth` phoned
Google from the developer's browser. Replaced with a system font stack;
a transient callback page did not justify a webfont round trip in the
first place.

**twenty-ui, Storybook.** `preview-head.html` loaded Inter from Google.
It now imports `@fontsource/inter` in `preview.tsx`, matching what
twenty-front's Storybook already does.

**twenty-website.** Host Grotesk, Aleo, Azeret Mono and VT323 came
through `next/font/google`. Next self-hosts those at runtime, so this
was not a visitor-facing leak, but the build still had to reach Google,
which makes builds non-hermetic and fails in an air-gapped environment.
The latin subsets are now vendored in `src/fonts/`, next to the Inter
files that were already there, and loaded with `next/font/local`. All
four are OFL 1.1; `src/fonts/README.md` records each file's upstream and
license. Total added weight is ~78 KB, and these are the exact files
Next was downloading at build time anyway.

Host Grotesk and Azeret Mono ship as single variable files, so they are
declared once over their full `wght` axis rather than as one face per
weight.

## Also removed

Both Storybooks pulled `iframeResizer.contentWindow.min.js` from
`cdnjs.cloudflare.com`. Storybook has not needed it since v7 and nothing
in either package references `iframeResizer` or `parentIFrame`, so it
was a third-party script executing in the preview iframe for no reason.
Argos does not screenshot through the manager iframe either:
`@argos-ci/storybook` hooks Vitest browser mode and calls
`server.commands.argosScreenshot`, so Playwright drives the page
directly.

## Verification

Not just typecheck. The interesting parts were tested end to end, which
caught two bugs an earlier revision of this PR had introduced.

**PDF export** — production Vite build, served over HTTP, real Chromium,
exporting through the actual `exportBlockNoteEditorToPdf`, then
extracting the PDF's text back out:

```
Latin heading  Cyrillic: Привет мир  Greek: Ελληνικά κείμενο
Latin-ext: Zażółć gęślą jaźń, Český  Vietnamese: Tiếng Việt

PASS Latin / Cyrillic / Greek / Polish / Czech / Vietnamese
```

Embedded fonts are `Inter18pt-Regular` / `Inter18pt-Bold`, no Helvetica
fallback, zero requests off-origin.

**Website** — built it, audited the build output (12 `@font-face` rules,
all `/_next/static/media/`, weights `300 800` / `100 900` / `300` /
`400` / `400,500,600`, `display: swap` preserved), then loaded it in
Chromium: 136 requests, zero to Google. The deployed preview was checked
too: no Google references in the served HTML or across all 21 CSS
chunks, every font file returns `200 font/woff2` and parses to the
expected family, and the asset hashes match a local build byte for byte.

**Two bugs this caught**, both in earlier commits on this branch, both
now fixed:

1. Registering `@fontsource/inter`'s latin file dropped coverage from
2849 codepoints to 230, silently removing Cyrillic, Greek, Vietnamese
and extended-Latin from every export. fontsource splits Inter into seven
per-script files chosen by `unicode-range`, but `Font.register` binds
one file per weight with no equivalent.
2. Any woff2 aborts the export outright with `RangeError: Offset is
outside the bounds of the DataView`. fontkit parses woff2, but
`@react-pdf`'s subsetter chokes on the transformed `glyf` table.
Confirmed format was the only variable by running identical content
through local TTF, WOFF and WOFF2 files.

Both are moot now that the registration is gone, but they are why this
is worth a careful look rather than a rubber stamp.

## Left alone, but worth knowing about

More third-party calls exist. None are font-related and each is a
separate decision:

- `twenty-website` loads `dotlottie-player.wasm` from **unpkg.com** at
runtime on the homepage, via `@lottiefiles/dotlottie-react`. This is a
live third-party CDN request on every visit, the same class of problem
as the fonts, and looks like a small config change to self-host.
- The halftone studio loads the Draco decoder from `www.gstatic.com`
and, in exported scenes, three.js from `unpkg.com`.
- The partners marketplace fixtures hotlink logos from
`cdn.simpleicons.org` and `upload.wikimedia.org`.
- reCAPTCHA and the Front support chat are config-gated and off unless
an admin configures them, which seems right.
- `APP_REGISTRY_CDN_URL` defaults to `https://unpkg.com`.
- `twenty-front/index.html` points its `og:image` at
`raw.githubusercontent.com`. Only social crawlers fetch it, so this is
cosmetic.
2026-08-06 17:58:55 +02:00
Charles Bochet 6e30405489 Bump vulnerable dependencies flagged by ECR image scanning (#23813)
## Context

The Oneleet monitor **"AWS ECR repository image vulnerabilities are
remediated"** is alerting on `prod-twenty` images: 1 CRITICAL + 6 HIGH
advisories breach their SLA in 7 days, plus a set of MEDIUMs. All of
them are npm packages baked into the image.

## Changes

| Package | Before | After | How | Advisories |
|---|---|---|---|---|
| undici | 7.28.0 / 6.27.0 | 8.9.0 | jsdom `^30` bump + node-gyp
refresh; global `undici: ^8.9.0` resolution for
@module-federation/dts-plugin, e2b and miniflare, which still pin 7.28.0
at latest (replaces the old scoped dts-plugin resolution) |
CVE-2026-13697 (critical), CVE-2026-14643, CVE-2026-15157/16728/16729 |
| sharp | 0.34.5 | 0.35.3 | direct bump in twenty-sdk; @argos-ci
refresh; `next/sharp` resolution (next 16.3.0 with the fix is still
quarantined by yarn's minimal-age gate) | GHSA-f88m-g3jw-g9cj |
| axios | 1.17.0 | 1.19.0 | lockfile refresh | GHSA-gcfj-64vw-6mp9 + 10
medium |
| ip-address | 10.2.0 | 10.4.0 | lockfile refresh | CVE-2026-69192,
CVE-2026-54272, CVE-2026-69198 |
| brace-expansion | 2.1.2 | 2.1.4 | lockfile refresh (backport exists;
Inspector only lists 5.x) | CVE-2026-69152, CVE-2026-14257,
CVE-2026-13149 |
| typeorm | 0.3.29 | 0.3.31 | pin bump; the local yarn patch applies
unchanged | GHSA-2rp8-mm9q-fp49 |

## Validation

- `yarn.lock` contains no remaining vulnerable versions (undici resolves
only to 8.9.0)
- `yarn npm audit`: no remaining advisories among the bumped packages
- `nx build` green for twenty-server, twenty-front (exercises
module-federation dts-plugin on undici 8), twenty-sdk, twenty-website;
twenty-server typecheck green (typeorm patch is type-level)
- Runtime smoke: jsdom 30 DOM parse, sharp 0.35.3 png encode, undici
8.9.0 load

## Not covered

- **react-router / react-router-dom 6.30.4** (medium, 1–3 month SLA):
react-router-dom 6.x has **no fixed release**; the fix is the v7
migration (~225 files) — separate effort.
- `prod-business-dash` body-parser 2.2.2 → 2.3.0 lives in its own repo.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23813?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-08-05 14:42:43 +00:00
Raphaël Bosi 014b3cdc67 Mirror host element geometry into front component workers (#23264)
Front components run in a Web Worker whose fake DOM has no layout APIs,
so any library that measures itself crashes. This is the reported
recharts bug: `ref.getBoundingClientRect is not a function`.

### Why this is needed

Layout only exists on the host: the worker builds a virtual tree, and
the host renders the real DOM nodes. Nothing in the worker knows how big
anything is.

```mermaid
flowchart LR
    COMP["Front component<br/>recharts, twenty-ui"] -->|"el.getBoundingClientRect()"| DOM["remote-dom fake DOM<br/>in the Web Worker"]
    DOM --> MISS["No layout APIs:<br/>method does not exist"]
    MISS --> BOOM["TypeError, component crashes"]
    HOST["Host: real DOM nodes<br/>with real sizes"] -.->|"never reaches the worker"| DOM
```

The worker cannot simply ask the host and wait: measurement APIs are
synchronous, and the worker must never block on a round trip.

### How the mirror works

The host measures and pushes; the worker only ever reads from a local
copy. Reads stay synchronous and are at most one frame behind.

```mermaid
flowchart TB
    subgraph HOST["Host - main thread, real DOM"]
        WAKE["Wake sources<br/>resize, scroll, mutations, animation events"]
        TRACK["createGeometryTracker<br/>rAF loop, idles after 20 unchanged frames"]
        NODES["Real DOM nodes<br/>registered per remote element id"]
    end

    subgraph WORKER["Web Worker - fake DOM"]
        STORE["workerGeometryStore<br/>snapshot mirror"]
        POLY["Element.prototype polyfill<br/>getBoundingClientRect, offset, client, scroll"]
        COMP2["Front component"]
    end

    WAKE -->|"wake"| TRACK
    NODES -->|"measure changed nodes only"| TRACK
    TRACK ==>|"pushGeometryUpdates over MessagePort"| STORE
    STORE -->|"synchronous read, one frame stale"| POLY
    POLY --> COMP2
    COMP2 -.->|"first read enrolls the element:<br/>observeElementGeometry"| TRACK
```

Enrollment is demand-driven: an element is only measured once the
component actually reads its geometry, so idle components cost nothing.

```mermaid
sequenceDiagram
    participant C as Front component
    participant P as Element polyfill
    participant S as Worker geometry store
    participant T as Host geometry tracker
    participant D as Real DOM

    C->>P: el.getBoundingClientRect
    P->>S: resolve snapshot
    S-->>P: none yet, returns zeros
    S->>T: observeElementGeometry, batched in a microtask
    T->>D: measure on the next animation frame
    D-->>T: rect, offset, client, scroll
    T->>S: pushGeometryUpdates with viewport and changed elements
    Note over T: the loop stops after 20 unchanged frames, any wake source restarts it
    C->>P: el.getBoundingClientRect on a later frame
    P->>S: resolve snapshot
    S-->>P: mirrored values
    P-->>C: real numbers
```

### What changed

- The host measures the real DOM nodes on animation frames while wake
sources report activity, and pushes snapshots over the existing
MessagePort. The loop goes idle when nothing changes, and both sides cap
observation at 500 elements.
- In the worker, `getBoundingClientRect`, the
`offset*`/`client*`/`scroll*` getters and
`window.innerWidth`/`innerHeight` read those snapshots from the
worker-local mirror.
- The worker also gains the small DOM APIs libraries expect:
`getComputedStyle` (returns the element's declared style),
`getElementsByClassName`, `document.getElementById`, and a working
per-element `style` on base elements (remote-dom ships a no-op stub
whose `getPropertyValue` returns undefined, which crashed twenty-ui's
ThemeProvider).

Result: a fixed-size recharts `AreaChart` story renders, and the four
twenty-ui gallery stories that used to fail on the missing
`getComputedStyle` now run in strict zero-failure mode.

Moved, not new: `FrontComponentRenderer` now renders its thread effects
directly instead of through a pass-through component, and its output is
wrapped in a `<div style="width:100%;height:100%">` instead of a
fragment so geometry has a measurable root (a real layout change for
embedders).

Deferred to the ResizeObserver follow-up: text measurement (axis-label
overlap thinning), `offsetParent` mirroring, animation in-flight
tracking, `ResponsiveContainer`, the tooltip, and the
`measureElementGeometry` RPC.

Last of the three PRs splitting the geometry mirror work, after #23262
(host wrapper hooks) and #23263 (style proxy).
2026-07-30 12:02:18 +00:00
BOHEUS a3b54e834c PDF upload fix (#23473)
Sometimes uploading PDF files resulted in "Non-whitespace before first
tag." error, updating parsing library fixes the error

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23473?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-29 09:16:29 +00:00
Abdullah. c7919673af fix: lift root postcss to 8.5.23 (Dependabot) (#23396)
## Summary

Clears the root postcss alert
[1851](https://github.com/twentyhq/twenty/security/dependabot/1851):
**GHSA-r28c-9q8g-f849** (high) - path traversal in previous source map
auto-loading (`sourceMappingURL`) leading to arbitrary `.map` file
disclosure, vulnerable `<= 8.5.17`.

The root lockfile carried **two** vulnerable copies, both behind exact
pins with no fixed upstream release:

| Copy | Pinner | Latest release still pins |
|---|---|---|
| 8.5.15 | `next` (8.4.31 exact) | 16.2.12 -> 8.4.31 |
| 8.5.14 | `@mintlify/common` (8.5.14 exact) | 1.0.1051 -> 8.5.14 |

So no parent upgrade reaches the fix. The existing `next/postcss`
resolution moves **8.5.15 -> 8.5.23** and a matching
**`@mintlify/common/postcss`** pin is added, placed alphabetically among
the other `@mintlify/*` entries. The caret consumers (`^8.4.38`,
`^8.4.47`, `^8.5.15`) dedupe onto the same version.

## Verification

- The two copies **collapse into a single `postcss@8.5.23` entry**;
nothing at or below 8.5.17 remains.
- `yarn install --immutable` passes.
- 8.5.23 published 2026-07-24, clears the 3-day npm age gate.
- `//resolutions` updated with the advisory, both pinners (and their
latest-version evidence) and the drop condition.

The app-lockfile side of this advisory shipped separately in #23340.
2026-07-28 08:06:23 +00:00
Guillaume Flambard 710d4da4b1 fix(emails): bump @react-email/render to ^2.0.6 to fix empty transactional email bodies (#23323)
## Problem

Fixes #23307. Every transactional email (workspace invite, password
reset,
email verification, etc.) is delivered with an **empty body** — no
title, text,
or CTA.

## Root cause

`twenty-server` pins `@react-email/render` directly at `^1.2.3`:

```jsonc
// packages/twenty-server/package.json
"@react-email/render": "^1.2.3",
```

In 1.2.3, `render()` reads `renderToReadableStream` **before** the email
template's async Suspense boundary (i18n/locale load) has resolved. The
result
is the Suspense fallback marker instead of the real markup:

```html
<!DOCTYPE html ...><!--$!--><template></template><!--/$-->
```

This was fixed upstream in `@react-email/render@2.0.6`
(*"await stream.allReady before reading renderToReadableStream
output"*).
`twenty-emails` already resolves a 2.x render via `react-email@6.5.0`,
so the
server's direct pin was simply stale — the two were out of sync.

## Fix

Bump the direct pin to `^2.0.6` (resolves to `2.1.0`) and regenerate the
lockfile. The server's `render()` imports now use the fixed 2.x.

> Note: a `1.2.3` entry remains in `yarn.lock` — it is an internal
transitive
> pin of `@react-email/components@0.5.3`, not the server render path, so
it is
> expected and harmless.

## Verification

Rendering `SendInviteLinkEmail` through the real `render()` (Node 24)
now
returns full markup (5.7 kB) with no Suspense marker and the resolved
invite
link + workspace content, instead of the empty fallback.

A jest unit test was intentionally not added: `@react-email/render` 2.x
uses a
dynamic import that jest's CJS runtime rejects ("A dynamic import
callback was
invoked without --experimental-vm-modules") — which is exactly why the
existing
email specs mock `render`. The fix was verified with a standalone Node
script.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23323?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-07-27 11:37:09 +02:00
Abdullah. 6060d88c54 fix: bump tar 7.5.20 -> 7.5.21 in the root lockfile (Dependabot) (#23330)
## Summary

Bumps **tar 7.5.20 -> 7.5.21** in the root `yarn.lock`, clearing
Dependabot alert
[1852](https://github.com/twentyhq/twenty/security/dependabot/1852):
**GHSA-r292-9mhp-454m** (medium) - uncontrolled recursion in
`mapHas`/`filesFilter` allows an uncatchable stack-overflow DoS via a
crafted long-path tar with member selection, vulnerable `<= 7.5.20`.

Every root tar consumer declares a caret range (`^7.4.3`, `^7.5.4`,
`^7.5.9`, `^7.5.11`, `^7.5.16`) and the existing scoped tar resolutions
for the @electron/rebuild toolchain and @mintlify/previewing are carets
as well (`npm:^7.5.16`), so a recursive `yarn up -R tar` lifts the
single tar entry with **no resolution change and no `package.json`
change**.

## Verification

- `yarn install --immutable` passes.
- Diff is `yarn.lock` only; the single tar entry resolves to 7.5.21,
nothing below remains.
- 7.5.21 published 2026-07-21, clears the 3-day npm age gate.

The same advisory affects the twenty-apps and server fixture lockfiles;
those follow in separate PRs.
2026-07-27 07:55:25 +00:00
Abdullah. 0efc92b3f3 fix: bump shell-quote 1.8.4 -> 1.10.0 (Dependabot) (#23331)
## Summary

Bumps **shell-quote 1.8.4 -> 1.10.0**, clearing Dependabot alert
[1769](https://github.com/twentyhq/twenty/security/dependabot/1769):
**GHSA-395f-4hp3-45gv / CVE-2026-13311** (high) - quadratic-complexity
Denial of Service in `parse()` (CWE-407), vulnerable `<= 1.8.4`, fixed
1.9.0.

Both consumers declare caret ranges - `@graphql-codegen/cli` (`^1.7.3`)
and `concurrently` (`^1.8.1`) - so a recursive `yarn up -R shell-quote`
lifts the single entry with **no resolution and no `package.json`
change**. Yarn resolves to 1.10.0, the latest in range (above the 1.9.0
fix floor).

## Verification

- `yarn install --immutable` passes.
- Diff is `yarn.lock` only; shell-quote resolves to 1.10.0, no 1.8.4
remains.
- 1.10.0 published 2026-07-10, clears the 3-day npm age gate.
2026-07-27 07:55:09 +00:00
Paul Rastoin 24067ec87a chore: remove twenty-companion dead code (#23310)
## What

Removes `packages/twenty-companion` (package name `twenty-desktop`), the
Electron "Twenty Desktop" proof of concept that landed with the
Recall.ai call-recording work in #18281.

## Why it's dead code

- **Not in the nx graph** — no `project.json`, so no target ever runs
against it.
- **Not in CI** — no workflow references it. #21327 said as much when
bumping its Electron: "there's no CI job that builds/tests
twenty-companion, so this isn't exercised by CI".
- **No code references** — nothing imports it, and the only path
references were the root `workspaces` array, `yarn.lock`, and
`.vscode/twenty.code-workspace`. It talks to Twenty over the public REST
API from a separate process, so there is no coupling to remove.
- **Self-declared POC** — its README opens with "This application is a
Proof of Concept (POC) and must NOT be used in production. [...]
Security, stability, and performance have not been validated for
production use."
- **No feature work since it landed** (March 2026). Every commit
touching it since has been a dependency or tooling sweep: React 19
migration, ESLint→OxLint, npm→yarn workspaces, and four CVE bumps.
- **Docs already stale** — its README points at
`packages/twenty-apps/internal/call-recording`, which no longer exists.
The shipped app lives at `packages/twenty-apps/public/call-recorder` and
does not reference the desktop companion.

Meanwhile it pulled a full Electron + electron-forge toolchain into
every root install, and kept generating Dependabot noise against a tree
nothing builds.

## Changes

- Delete `packages/twenty-companion`.
- Drop its entry from root `workspaces` and from
`.vscode/twenty.code-workspace`.
- Drop four root `resolutions` that existed only to evict CVEs from the
Electron tree, along with their entries in the `//resolutions` rationale
doc:
  - `@electron/rebuild/tar`, `@electron/node-gyp/tar`
  - `@electron-forge/plugin-webpack/webpack-dev-server`
- `make-fetch-happen` — its only sub-`^15` consumer was the Electron
`node-gyp` fork; the remaining consumers (`@sigstore/sign`,
`npm-registry-fetch`, `tuf-js`) already declare `^15.x`
- Regenerate `yarn.lock`.

## Lockfile impact

469 descriptors removed, **zero version changes for any surviving
descriptor** (verified with a descriptor-level diff of old vs new
resolutions). Two descriptors show up as new —
`make-fetch-happen@npm:^15.0.1` and `@npm:^15.0.4` — only because the
global resolution was previously rewriting them; both still resolve to
`15.0.6`. Re-running resolution produces a byte-identical lockfile.

## Test plan

- [x] Repo-wide grep confirms no remaining references to
`twenty-companion` / `twenty-desktop` / the Electron toolchain.
- [x] `yarn install --mode=update-lockfile` is stable and idempotent
under hardened mode.
- [x] Descriptor-level lockfile diff shows no resolution changes outside
the removed tree.
- [ ] CI green (nothing targets the removed package, so the risk surface
is the lockfile).


---
_Generated by [Claude
Code](https://claude.ai/code/session_019NttPZiJWSJz56RW8pZ5jN)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23310?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-26 16:52:52 +00:00
Félix Malfait 3a8f086d15 Converge drag and drop on shared dnd-kit primitives, remove @hello-pangea/dnd (#23211)
Follow-ups recorded in #23023, done in one pass.

## Shared primitives

- Folded `PageLayoutWidgetSortableItem` and `PageLayoutWidgetDropLine`
into the shared `DragDropItemSortableCell` / new `DragDropItemDropLine`
(new `data`, `dropLine`, `highlightWhileDragging`, `hasTransition`
props).
- Added generic `DragDropProviderDragStartEvent` (and
DragMove/DragOver/DragEnd/DropTarget) helpers and deleted the 7 copied
`Parameters<...>` extractions across the dnd hooks.
- Replaced the `useMovePageLayoutWidgetUp/Down` implementations (~140
lines) with `moveWidgetWithinTabInDraft`.
- Migrated the remaining page-layout test suites onto
`pageLayoutDraftFixtures`.

## Tab reordering off Pangea

- Tabs are sortable cells on the same provider as widget drags,
segregated by dnd type, so widget drops on tab buttons keep working
while tabs reorder.
- Reordering is ID based (`reorderTabInDraft`: insert before the hovered
tab), which keeps the pinned first tab in place without index
arithmetic.
- Preserved overflow behaviors: the dropdown stays open while a tab drag
is in flight, dropping a tab on the "+N More" button appends it and
opens the dropdown, and both the visible strip and the overflow list
have end drop zones.

## Fields configuration editors off Pangea

- Group reorder, field reorder and cross-group field moves now run on
the shared cells (same drop line and end-zone patterns).

## DraggableList off Pangea

- `DraggableList` / `DraggableItem` keep their consumer-facing API — the
~9 consumers now type their handlers with a local
`DraggableListDropResult` instead of pangea's `DropResult` — but run on
the shared sortable cells; each list's uuid group doubles as its dnd
type so nested lists stay isolated from page-level providers.
- Items register their index in a list-scoped registry so the end drop
zone can resolve the append index at drop time (with insert-before
semantics an item could otherwise never reach the last position).
- Deleted three dead files that only existed for pangea plumbing (the
side panel navigation placeholder, `getCssCompatibleDraggableProps`, the
orphaned `recordGroupPendingDragEndReorderState`).

## Record table row drag off Pangea

- Rows register through `useSortable` directly on the row element — no
wrapper div, so row CSS, sticky cells and virtualization stay untouched
— with the grip cell wired as the drag handle via the shared sortable
handle ref context.
- Both table modes (virtualized flat list and record groups) share a
`DragOverlay` clone that replaces pangea's virtual-mode `renderClone`,
and end drop zones per record group (and after the virtualized list)
allow dropping after the last row or into an empty group.
- The drop handlers keep their pangea-shaped result object, retyped as a
local `RecordDragDropResult`, so the position computation logic is
untouched.

## Pangea removed

`@hello-pangea/dnd` is gone from `package.json` and the lockfile, along
with its orphaned transitive entries (`css-box-model`, `raf-schd`,
`react-redux`, `redux`). Nothing in the repo imports it anymore.

## Dashboards: cross-tab widget drag for grids

react-grid-layout drags never enter dnd-kit, so the bridge hit-tests the
pointer against the tab buttons' `data-page-layout-tab-drop-target-id`
rects during grid drags, highlights the hovered tab through state, and
on drop moves the widget to the destination grid below its existing
content (`moveWidgetToGridTabInDraft`, `buildTabWidgetLayouts`). The
grid's own post-drag layout commit is suppressed once so it does not
overwrite the cross-tab move.

## Fixes found while testing

- With `feedback: 'clone'`, the drag source is its own initial drop
target and its placeholder is a DOM clone taken at drag start, so the
drop line rendered into the source got baked into the placeholder and
stuck there for the whole drag. The line is now hidden on the source
cell, leaving a single indicator at the actual target.
- Reorderable tabs collapsed to text height and sat top-aligned next to
"+ New Tab" because the sortable cell wrapper defaults to `display:
block; height: auto`, breaking the tab height chain — the tab list now
uses the cell's `fill` mode so tabs stretch to the strip height again.

## Testing

Playwright against the dev app:
- Record page: widget reorder up and down in the pinned column (single
blue drop line at the target), drag to another tab via its tab button
(highlight + move), drag back into content at a specific position,
chained cross-tab moves, tab reorder with vertical drop line, new tab
creation.
- Overflow (narrow viewport): drop a tab on "+N More" (appends last,
dropdown opens), reorder inside the dropdown (stays open), drag a tab
from the dropdown back to the visible strip.
- Dashboard: grid drag within a tab, cross-tab drag onto a tab button
(hover highlight, widget lands below destination content, remaining
widgets keep their positions), save and reload persistence in both
directions.
- Fields editor: field reorder, group reorder, field move across groups,
plus the Move Up / Move Down widget actions.

Since the pangea-removal commits:
- Typecheck, oxlint and oxfmt green over the full front source; unit
suites green including the migrated `useStartRecordDrag` test (jest
needed a scoped transform exemption for `@preact/signals-core` once
dnd-kit reached the side-panel suites).
- Storybook visual regression unchanged across ~700 stories — expected,
since the migrated surfaces render identical DOM at rest (drop lines and
drag overlays only exist mid-drag).
- The tab strip fix reverses the exact regression mechanism: the
sortable cell wrapper defaulted to `display: block; height: auto`,
collapsing the tab height chain next to the full-height "+ New Tab"
button; `fill` restores the stretch.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01XKRCzzu8oGyocXZtFp7VEG)_


<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23211?utm_source=github"
rel="nofollow noreferrer noopener" target="_blank">``&lt;img alt="Review
in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"&gt;``</a>
2026-07-24 14:04:13 +02:00
Abdullah. d53ef11fe2 fix: bump linkify-it to 5.0.2 (Dependabot) (#23236)
Bumps **linkify-it -> 5.0.2** (sole descriptor `^5.0.1`, caret already
permits it; recursive `yarn up`, lockfile-only, no resolution). Clears
[1799](https://github.com/twentyhq/twenty/security/dependabot/1799)
(GHSA-v245-v573-v5vm, high). `yarn install --immutable` passes. 5.0.2
published 2026-07-01, clears the age gate.
2026-07-24 16:38:58 +05:00
Abdullah. 0a53cc745d fix: bump brace-expansion 1.x/2.x lines (Dependabot) (#23240)
Bumps **brace-expansion 1.x -> 1.1.16** and **2.x -> 2.1.2** (caret
consumer ranges permit both; recursive `yarn up`, lockfile-only, no
resolution). Clears
[1766](https://github.com/twentyhq/twenty/security/dependabot/1766) and
[1767](https://github.com/twentyhq/twenty/security/dependabot/1767) for
GHSA-3jxr-9vmj-r5cp (high, ReDoS).

**Deliberately not covered:** the 5.x line stays at 5.0.6 because
`nx@22.7.5` pins it exact (minimatch's `^5.0.x` consumers do lift to
5.0.7, but the nx copy remains), so alert
[1765](https://github.com/twentyhq/twenty/security/dependabot/1765)
stays open. Same nx-exact-pin situation as axios; will be handled in the
resolutions batch.

`yarn install --immutable` passes. 1.1.16 and 2.1.2 published
2026-07-08, clear the age gate.
2026-07-24 12:00:10 +05:00
Abdullah. d6abb26cdb fix: bump body-parser to 1.20.6 / 2.3.0 (Dependabot) (#23239)
Bumps **body-parser** on both lines: `~1.20.3`/`~1.20.5` -> **1.20.6**
and `^2.2.1` -> **2.3.0** (all within declared ranges; recursive `yarn
up`, lockfile-only, no resolution). Clears
[1779](https://github.com/twentyhq/twenty/security/dependabot/1779) and
[1780](https://github.com/twentyhq/twenty/security/dependabot/1780)
(GHSA-v422-hmwv-36x6, low). `yarn install --immutable` passes. 1.20.6
published 2026-07-09, 2.3.0 published 2026-06-15, both clear the age
gate.
2026-07-24 11:59:52 +05:00
Abdullah. 78e0c11b34 fix: bump svgo to 3.3.4 (Dependabot) (#23238)
Bumps **svgo -> 3.3.4** (sole descriptor `^3.0.2`, caret already permits
it; recursive `yarn up`, lockfile-only, no resolution). Clears
[1802](https://github.com/twentyhq/twenty/security/dependabot/1802)
(GHSA-2p49-hgcm-8545, high). `yarn install --immutable` passes. 3.3.4
published 2026-07-11, clears the age gate.
2026-07-24 11:59:23 +05:00
Abdullah. 35e6f58d70 fix: bump dompurify to 3.4.12 (Dependabot) (#23237)
Bumps **dompurify -> 3.4.12** (sole descriptor `^3.4.11`, caret already
permits it; recursive `yarn up`, lockfile-only, no resolution). Clears
[1801](https://github.com/twentyhq/twenty/security/dependabot/1801)
(GHSA-c2j3-45gr-mqc4, low). `yarn install --immutable` passes. 3.4.12
published 2026-07-11, clears the age gate.
2026-07-24 11:59:05 +05:00
Abdullah. b2a61adee7 fix: bump immutable to 5.1.8 (Dependabot) (#23235)
Bumps **immutable -> 5.1.8** (sole descriptor `^5.1.5`, caret already
permits it; recursive `yarn up`, lockfile-only, no resolution). Clears
[1796](https://github.com/twentyhq/twenty/security/dependabot/1796)
(GHSA-v56q-mh7h-f735, high) and
[1797](https://github.com/twentyhq/twenty/security/dependabot/1797)
(GHSA-xvcm-6775-5m9r, high). `yarn install --immutable` passes. 5.1.8
published 2026-06-25, clears the age gate.
2026-07-24 11:58:45 +05:00
Abdullah. 5ee50b16db fix: bump fast-uri to 3.1.4 (Dependabot) (#23234)
Bumps **fast-uri -> 3.1.4** (sole descriptor `^3.0.1`, caret already
permits it; recursive `yarn up`, lockfile-only, no resolution). Clears
[1798](https://github.com/twentyhq/twenty/security/dependabot/1798)
(GHSA-4c8g-83qw-93j6, high) and
[1805](https://github.com/twentyhq/twenty/security/dependabot/1805)
(GHSA-v2hh-gcrm-f6hx, high). `yarn install --immutable` passes. 3.1.4
published 2026-07-19, clears the 3-day age gate.
2026-07-24 11:58:33 +05:00
Abdullah. 15f571837e fix: bump js-yaml pins 4.2.0 -> 4.3.0 (Dependabot) (#23178)
## Summary

Bumps all nine scoped **js-yaml resolutions 4.2.0 -> 4.3.0** and lifts
the caret copy, clearing Dependabot alert
[1768](https://github.com/twentyhq/twenty/security/dependabot/1768):
**GHSA-52cp-r559-cp3m / CVE-2026-59869** (high) - YAML merge-key chains
force quadratic CPU consumption, vulnerable `>= 4.0.0, < 4.3.0`, fixed
**4.3.0**. Follow-up to the merge-key DoS fixed in 4.2.0
(GHSA-h67p-54hq-rp68).

## Why the pins move (not drop)

Checked upstream first: all seven 4.1.1 exact-pinners are unchanged at
latest (`@mintlify/cli@4.0.1331`, `@mintlify/common@1.0.1037`,
`@mintlify/prebuild@1.0.1185`, `@mintlify/previewing@4.0.1254`,
`@mintlify/scraping@4.0.902`, `@mintlify/validation@0.1.795`,
`@verdaccio/config@8.1.2` - every one still pins `js-yaml 4.1.1` exact).
front-matter and @istanbuljs/load-nyc-config remain EOL on `^3.13.1`. So
no parent upgrade carries 4.3.0; the existing scoped pins just move up,
plus a recursive `yarn up` for the cosmiconfig caret consumers. The
`//resolutions` doc entry is updated with the new advisory and drop
condition (`>=4.3.0`).

## Verification

- Single `js-yaml 4.3.0` entry remains in the lockfile (no 4.2.0, no
3.x).
- `yarn install --immutable` passes.
- front-matter patch intact (`loader = parser.load`); docs front-matter
parses cleanly on 4.3.0.
- `mintlify validate` reports only pre-existing ChartIcon MDX import
warnings from #23091 (content, unrelated - zero `.mdx` files in this
diff).
- 4.3.0 published 2026-06-26, clears the 3-day age gate.
2026-07-23 17:24:05 +05:00
Abdullah. 7e79b19f73 fix: bump vitest family 4.1.8 -> 4.1.10 (Dependabot) (#23166)
## Summary

Bumps the **vitest family 4.1.8 -> 4.1.10** to clear the **critical**
Dependabot alert
[1800](https://github.com/twentyhq/twenty/security/dependabot/1800):
GHSA-p63j-vcc4-9vmv, @vitest/browser Browser Mode provider commands
bypass the file-access permission gate (no CVE yet; fixed 4.1.10).

`@vitest/browser` is exact-pinned by `@vitest/browser-playwright`
(vitest family version-locks), so the fix is a recursive `yarn up` on
the caret parents (`vitest` and `@vitest/browser-playwright`, both
declared `^4.1.0` by twenty-ui, twenty-front-component-renderer,
twenty-client-sdk). The whole family (browser, expect, mocker,
pretty-format, etc.) moves together to 4.1.10. No resolution, no
`package.json` change.

## Verification

- `yarn install --immutable` passes.
- Diff is `yarn.lock` only; `@vitest/browser` resolves to 4.1.10, no
4.1.8 remains.
- 4.1.10 published 2026-07-06, clears the 3-day npm age gate.
- Dev-scope tooling (vitest test runner), patch-level bump within 4.1.x.
2026-07-22 17:44:39 +05:00
Abdullah. 3e97b355b4 fix: bump tar 7.5.16 -> 7.5.20 (Dependabot) (#23159)
## Summary

Bumps **tar 7.5.16 -> 7.5.20** on the root `yarn.lock` to clear **4
Dependabot alerts** from this week's node-tar advisory chain, including
the critical one.

| Severity | Advisory | Vulnerable | Fixed | Alert |
|---|---|---|---|---|
| critical | GHSA-23hp-3jrh-7fpw | <= 7.5.18 | 7.5.19 |
[1772](https://github.com/twentyhq/twenty/security/dependabot/1772) |
| high | GHSA-8x88-c5mf-7j5w | <= 7.5.17 | 7.5.18 |
[1771](https://github.com/twentyhq/twenty/security/dependabot/1771) |
| medium | GHSA-w8wr-v893-vjvp | <= 7.5.17 | 7.5.18 |
[1773](https://github.com/twentyhq/twenty/security/dependabot/1773) |
| medium | GHSA-gvwx-54wh-qm9j | <= 7.5.16 | 7.5.17 |
[1770](https://github.com/twentyhq/twenty/security/dependabot/1770) |

The root lockfile has a single tar entry with all-caret consumer ranges
(`^7.4.0` ... `^7.5.16`), so a recursive `yarn up -R tar` lifts it to
the latest patch (7.5.20, published 2026-07-12, clears the 3-day age
gate). The existing scoped tar resolutions (`npm:^7.5.16` for the
@electron/rebuild toolchain and @mintlify/previewing) are caret ranges
and permit it unchanged, so no `package.json` edit.

Note: the remaining 52 tar alerts live in the twenty-apps and
seed-dependencies mini-lockfiles and will be handled separately.

## Verification

- `yarn install --immutable` passes.
- Diff is `yarn.lock` only; single tar entry now 7.5.20, nothing below
remains.
2026-07-22 13:25:55 +02:00
Abdullah. 8b0cd00357 fix: bump websocket-driver 0.7.4 -> 0.7.5 (Dependabot) (#23142)
## Summary

Bumps **websocket-driver 0.7.4 -> 0.7.5** to clear **2 Dependabot
alerts** on the root `yarn.lock`, including the critical one from this
week's advisory wave.

| Severity | Advisory | CVE | Alert |
|---|---|---|---|
| critical | GHSA-xv26-6w52-cph6 | CVE-2026-54466 |
[1577](https://github.com/twentyhq/twenty/security/dependabot/1577) -
message corruption via abuse of protocol length headers |
| medium | GHSA-mp7j-qc5w-4988 | CVE-2026-54490 |
[1576](https://github.com/twentyhq/twenty/security/dependabot/1576) -
resource limit bypass via message compression |

websocket-driver is transitive via **faye-websocket** (`>=0.5.1`) and
**sockjs** (`^0.7.4`); both ranges already permit 0.7.5, so a recursive
`yarn up -R websocket-driver` lifts it with no resolution and no
`package.json` change.

## Verification

- `yarn install --immutable` passes.
- Diff is `yarn.lock` only; websocket-driver resolves to 0.7.5, no 0.7.4
remains.
- 0.7.5 published 2026-06-04, clears the 3-day npm age gate.
2026-07-22 14:05:01 +05:00
Rashad Karanouh 6742cfe861 Marketplace glowup — live partner profiles, case studies & matching (website) (#23016)
Rebuilds the partners marketplace on live CRM-backed partner data: real
profiles, case studies, matching/scope cards, and a "match me" entry
point in the grid.

## What changed
- Marketplace grid and partner cards now fetch, rank, and filter live
partner data instead of static fixtures
- Partner profile pages render live profile data, including services,
portfolio/case studies, and clients
- Partner scope/matching cards on the profile page, plus a
`MarketplaceMatchCard` as the first tile in the marketplace grid,
routing into the client-brief flow
- Rich CTA rail on partner profiles (calendar link, website, socials)
built from live partner links
- Markdown rendering (`react-markdown`) for partner descriptions and
case study bodies, including proper heading rendering
- Minor route/sitemap adjustments to support the live-data pages

## Architecture / notes
This branch was 463 commits behind `main` and was resynced via a single
merge (not rebase) to avoid re-resolving the same conflicts repeatedly.
Several of the branch's earlier commits (client-brief wizard,
`MarketplaceBriefPrompt`, `MarketplaceMatchCard`'s base styling,
`PricingEngagementBand`) had already landed on `main` independently, in
some cases refactored into shared components (`EngagementBand`,
`MarketplaceCardFrame`, `createWebhookForwardingRoute`) — those
conflicts were resolved by taking `main`'s already-shipped version.
`PartnerCard.tsx` had diverged into two different designs (`main` gained
chip rows / money row / LinkedIn icon; this branch gained the live
case-study/portfolio data model with markdown descriptions and
structured partner links); the resolution keeps this branch's data model
(`description` as markdown, `links`/`linkUrls`) while adopting `main`'s
card layout, adapting field references accordingly.
`PartnerProfileCtas.tsx` keeps this branch's richer link-rail
implementation since it's the one that matches the live data model
already wired into `PartnerProfile.tsx`.

This is the website counterpart to app PR #22929 (glowup, v1.3.0),
already deployed to prod, and supersedes the closed drafts #22471 and
#22402.

Lint, format, targeted marketplace/client-brief jest tests, and `nx
typecheck twenty-website` all pass after the merge.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23016?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-21 11:03:46 +02:00
Félix Malfait 7e133a4930 Converge email recipient fields on existing patterns: shared parser/formatter, search-index members, one display-name rule (#22997)
# Why

Follow-up to #22668, addressing @charlesBochet's five post-merge review
comments. They all point the same direction: the recipient fields
rebuilt things the codebase already had. This PR converges on the
existing patterns where that holds up, and answers on the threads where
it deliberately does not.

# What changed, per comment

**Parser duplication
([comment](https://github.com/twentyhq/twenty/pull/22668#discussion_r3553064242))**:
`parseEmailAddressList` now lives in twenty-shared (addressparser, group
flattening, try/catch). The server's `safeParseEmailAddresses` delegates
to it, the front wrapper keeps only paste normalization (newlines to
commas) and invalid-token preservation for red chips. The
`addressparser` dependency moves from twenty-front to twenty-shared.
Side effect worth knowing: RFC 5322 group members in inbound To/Cc
headers were previously dropped entirely (group entries have no
top-level address, so the filter removed them); flattening now imports
those participants. Covered by a new regression test.

**Formatter duplication
([comment](https://github.com/twentyhq/twenty/pull/22668#discussion_r3553064243))**:
`formatEmailAddress` (quote only when specials require it) lives in
twenty-shared. The composer chips and the server's
`formatMessageFromHeader` both delegate to it. The Gmail From header
output is byte-identical: the name is mime-encoded first and encoded
words never contain characters that trigger quoting. CodeQL then caught
that the quoting (ported from the original front util) escaped quotes
but not backslashes, letting a crafted name close the quoted string
early; escaping now covers both as RFC 5322 quoted-pairs, with a
containment test proving a hostile name cannot split into extra
recipients on reparse.

**Member search divergence
([comment](https://github.com/twentyhq/twenty/pull/22668#discussion_r3553064231))**:
suggestions now search WorkspaceMember through the search index in the
same `useObjectRecordSearchRecords` call as Person (one ranked query),
and enrich hits from `currentWorkspaceMembersState`, exactly like
`SettingsRoleAssignmentWorkspaceMemberPickerDropdown`. The client-side
`filterBySearchQuery` pass is gone. The hook is now what the comment
described: the merge of context people, searched people, and members
into one ranked list, rendered with the same
`SelectableList`/`MenuItemAvatar` primitives the pickers use. Also fixed
while in there: searched person ids are sliced to the suggestion limit
before hydration, so top-ranked people can no longer be crowded out of
the hydration page.

**Chip resolution duplication
([comment](https://github.com/twentyhq/twenty/pull/22668#discussion_r3553064236))**:
the display-name preference is now one rule,
`getEmailIdentityDisplayName`, used by both
`getDisplayNameFromParticipant` (threads) and the composer chip/menu, so
the same address renders identically everywhere. The order is workspace
member, then person, then display name, then handle: when an address
belongs to both a teammate and a Person record, the internal identity
wins (product call from Felix). `BaseChip.maxLabelWidth` is renamed
`maxWidth` to match the twenty-ui `Chip` API. `ParticipantChip` itself
is not used inside the field: it renders a navigating `RecordChip` when
a person is linked, and navigation from the composer destroys the draft
(no draft persistence yet), plus the field chips need
remove/selected/danger/edit affordances it does not have.

**Rebuilding on MultiItemFieldInput
([comment](https://github.com/twentyhq/twenty/pull/22668#discussion_r3553064221))**:
answered on the thread rather than in code, deliberately.
`MultiItemFieldInput` is a dropdown-panel list editor (vertical rows,
one input at a time, bound to record-field contexts and
`FieldMetadataType`), and its own TODO says the API should be refactored
into a hook before growing. The inline wrapping chip row commits batches
(paste), dedupes with a flash, and keeps a persistent inline input with
suggestions; layering that through `renderItem`/`renderInput` would
strain both components. On the menu overlap: after comparing side by
side, the shared surface between `MultiItemFieldMenuItem`'s dropdown and
the chip menu is three `MenuItem` rows with different copy, order, and
neighbors; `MenuItem` is already the shared primitive, and a
config-driven fragment would be indirection without deduplication. If
deeper convergence is wanted, the honest path is the existing TODO
(extract the multi-item state machine into a hook, rebase both editors
on it); that touches the Links/Phones/Emails/Array/Files cell editors
and deserves its own PR.

# Verification

- New twenty-shared suites for the parser and formatter (16 tests),
including parse/format round-trips, the encoded-word case, and the
backslash-escaping containment case.
- Server messaging util specs all pass (70 tests), including new
group-flattening regression tests; From-header spec output unchanged.
- Front email module suites all pass (59 tests) with the slimmed
wrappers.
- Typecheck and lint green on twenty-shared, twenty-front,
twenty-server; oxfmt clean on all three.
- Playwright smoke against the seeded dev stack passes end to end:
context suggestions on the Google company, typed search showing people
and the workspace member row (now served by the search index), Enter
picking the top suggestion, duplicate merge, keyboard delete, chip menu
with clipboard copy, Ctrl+Enter committing the buffer then triggering
send.
2026-07-17 21:20:14 +02:00
Félix Malfait 6897fff632 Rebuild email composer recipient fields as a structured chip input with person resolution and autocomplete (#22668)
# Why

The To/Cc/Bcc fields reused `FormMultiTextFieldInput`, the workflow
Tiptap tag editor, with recipients stored as a comma-separated string.
That caused every reported issue: duplicates were allowed, the field was
locked to one 32px line with a hidden horizontal scrollbar, chips did
nothing on click, `First Last <email>` could not even be typed (space
committed a tag) and was rejected by the backend when pasted, chips
could not be edited, invalid addresses only failed server-side after
pressing Send, and there was no autocomplete at all.

## The model

A recipient is `{ address, displayName? }`. Person and workspace member
are never stored in composer state; they are resolved live from the
address at render time, mirroring how `MatchParticipantService` links
`messageParticipant.handle` to `personId`/`workspaceMemberId` on the
receive side. Entities appear at the edges (autocomplete in, chip
display out); state, dedupe, validation, and send operate on addresses
only. The send path is unchanged: `SendEmailInput.to/cc/bcc` stay
comma-separated bare addresses.

# What changed

New module `activities/emails/recipients/` (the workflow editor is
untouched; its other consumers are unaffected):

- **`EmailRecipientsFieldInput`**: wrapping chip rows (up to ~3 lines,
then scroll), commit on Enter/Tab/comma/semicolon/blur, space commits
only when the buffer is already a valid email, paste parses RFC 5322
lists (names, quoted commas, semicolons, newlines), case-insensitive
dedupe with a flash on the existing chip, invalid addresses become red
chips that disable Send, double-click or keyboard editing in place with
Escape revert, Backspace select-then-delete, arrow-key chip navigation,
Ctrl/Cmd+Enter commits a pending buffer or sends when the buffer is
empty.
- **Person resolution**: chips resolve against People
(`emails.primaryEmail`, case-insensitive) and workspace members,
rendering avatar + name when known and degrading to a plain address chip
otherwise.
- **Chip menu**: person/member header, Copy email, Edit, Remove, and Add
as person for unknown addresses (creates the Person; the chip upgrades
in place).
- **Autocomplete**: blends context people (company you are composing
from, or the company behind a person/opportunity), ranked people search,
workspace members with a Team member badge, and a literal "Use this
email" row ranked first when the typed buffer is a valid address.
Suggestions exclude addresses already present in any field. Enter picks
the highlighted or top row.
- **Prefill**: replies and drafts preserve participant display names
(`getEmailDraftPrefillFromMessage`, `useReplyContext`).
- `useEmailComposerState` holds `EmailRecipient[]` per field and blocks
send on invalid recipients; the recipient-limit warning is surfaced
again in the composer.
- The Send Email engine command passes the record context so context
suggestions work from the record page action.
- `EmailsFilter` was missing from the shared `LeafFilter` union, so
nothing could filter on `emails.primaryEmail`; added (additive).
- New dependency `addressparser@1.0.1` in twenty-front, the same package
and version the server already uses to parse inbound mail headers, so
both sides parse identically. Tiny, dependency-free, browser-safe.

# Decisions and tradeoffs

- Person resolution matches on `emails.primaryEmail` only,
case-insensitively via per-address `ilike` filters (no `%` wildcards,
`%_\` escaped). `additionalEmails` is a JSONB array and not cleanly
filterable through the GraphQL filter API today; the server-side matcher
checks additional emails too, so a chip may show as a plain address even
though the send still links to the person via participant matching.
- Chip flash-on-duplicate replays its CSS animation by remounting the
chip subtree (nonce in the React key), chosen over animation-restart
hacks; the remount is invisible.
- Keyboard chip selection keeps DOM focus on the input and tracks a
virtual `selectedChipIndex` (`aria-activedescendant`) instead of roving
focus across chips: one focus point, no focus juggling, standard
combobox listbox pattern.
- `flushSync` (precedent: `Dropdown.tsx`) focuses and places the caret
after entering chip-edit mode; the alternative was a useEffect on
editing state.
- Suggestion rows `preventDefault` on mousedown so picking a suggestion
never blurs the input (blur would first commit the half-typed buffer as
a junk chip).
- Cmd/Ctrl+Enter inside a recipient field: with a non-empty buffer it
commits the buffer only; with an empty buffer it sends via an `onSubmit`
prop wired to `handleSend`. Not commit+send in one stroke: `handleSend`
holds a same-render closure over composer state, so sending in the same
event would read the pre-commit recipients. E2E also showed the side
panel's own ctrl+Enter hotkey never fires while any form field is
focused (focus-stack scoping, applies to the old composer too), which is
why the field triggers the submit itself.
- Enter with suggestions open picks the highlighted (or top) suggestion,
Gmail-style. When the typed buffer is itself a valid email, the literal
row is ranked first so Enter keeps meaning "add what I typed".
- Suggestions are disabled while editing a chip (the edit buffer holds
`Name <email>` text, a poor search query).
- Dedupe blocks within a field; across fields typed duplicates are
allowed (sometimes intentional), but suggestions exclude addresses
already present in any of To/Cc/Bcc.
- Chip menu actions never navigate: navigating the side panel (or main
view) unmounts the composer and silently destroys the draft, since
composer state is component-local with no draft persistence. "Add as
person" creates the record and shows a snackbar while the chip upgrades
in place; the person header row is informational. "Open person"
navigation should come back once drafts survive navigation.
- The reply composer gets no context record: its widget target record is
the message thread, not a person/company, and replies already prefill
participants.
- If two people share a primary email, the last fetched match wins for
chip display (no ambiguity UI).
- "Add as person" splits the display name on the first space for
firstName/lastName, the same heuristic the contact-creation manager uses
server-side.

# Deferred

- Display names on the wire (`Name <email>` in outbound headers): needs
`SendEmailInput` / `EmailComposerService.validateEmails` changes
server-side.
- Drag chips between To/Cc/Bcc; collapse-on-blur to one line with a "+N
others" summary.
- Frequency/recency ranking of suggestions from `messageParticipant`
aggregates.
- "Open person" from the chip menu, pending draft persistence across
navigation.

# Verification

Unit tests cover the parser, formatter round-trip, merge/dedupe, and the
field state machine (commit, dedupe flash, edit, cancel, keyboard
selection). Typecheck, lint, and the email module suites pass, plus the
shared and side-panel suites.

Every flow was also driven end to end with Playwright against seeded
data: prefill resolution, context and typed suggestions, keyboard
navigation and picks, dedupe flash, RFC 5322 paste, invalid chips gating
Send, wrapping, in-place editing, chip menus, clipboard copy, Add as
person with live chip upgrade, Cc/Bcc exclusions, and the Ctrl+Enter
send path (the mutation reached the server; it failed only on the seeded
account's missing refresh token, expected outside a real provider
connection).

Screenshots of each verified behavior:
https://claude.ai/code/artifact/1743f05d-422e-43d0-bbea-a34a0470c180

---
_Generated by [Claude
Code](https://claude.ai/code/session_0199wDARiw48GqVTpgWzbXWw)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22668?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-09 13:11:09 +02:00
martmull dcccdbd148 Fix flaky "read EINVAL" in integration tests: bump msw to 2.12.14 (#22702)
# Context

Part of a CI flakiness sweep. Integration shards are intermittently
killed by an uncaught socket error that poisons a whole spec file (e.g.
`sync-failure-lifecycle.integration-spec.ts`, 4 tests, on unrelated PR
branches — example run 28940565117, shard 8):

```
Error: read EINVAL
    at MockHttpSocket.emit (@mswjs/interceptors/.../MockHttpSocket.ts:161)
```

# Root cause

The integration setup routes **all** HTTP (including
supertest/node-fetch calls to the in-process app) through msw's
ClientRequest interceptor, with localhost passthrough. msw `2.12.7` pins
`@mswjs/interceptors` `0.40.0`, where:

- `passthrough()` aliases the real socket's libuv `_handle` onto the
mock socket (two owners of one handle) and forwards the real socket's
`error` events into `MockHttpSocket.emit`,
- `destroy()` never destroys the passthrough socket, so it stays
orphaned with its error-forwarding listener attached.

When the server side closes such a connection later, a read on the stale
shared handle yields `EINVAL`, forwarded into `emit()` with no request
(and no error listener) attached → uncaught exception → jest kills the
in-flight file. This is upstream
[mswjs/interceptors#753](https://github.com/mswjs/interceptors/issues/753);
the stack frames match line-for-line.

# Fix

Bump `msw` to **exactly `2.12.14`** in `twenty-server` and
`twenty-front` (shared lock entry). msw 2.12.9+ requires interceptors
`^0.41.2` → resolves 0.41.9, which ships
[interceptors#755](https://github.com/mswjs/interceptors/pull/755):
passthrough sockets get their listeners removed and are destroyed on
close, severing the exact error path above.

Notes from adversarial review:
- Pinned exact (`2.12.14`, not `^`) because the caret would resolve to
2.15.0 today — a bigger jump than reviewed.
- Compatibility checked: no deep imports of msw/interceptors anywhere;
interceptors 0.41.x externals already covered by
`transformIgnorePatterns`; `msw-storybook-addon@2.0.6` peer range
satisfied; `mockServiceWorker.js` integrity checksum unchanged between
2.12.7 and 2.12.14; 0.41.7+ adds Node 24 compatibility (repo targets
Node 24).
- Residual risk disclosed: #753 is still open upstream and the `_handle`
aliasing remains in 0.41.9 — this removes the observed orphaned-socket
path, but keep an eye out for recurrence.

Dependency-only change: 2 package.json lines + lockfile.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01AtD2wWm3EthV6t3Hs31QyB)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22702?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-09 10:58:26 +02:00
neo773 d99e6db93d test(messaging): messaging and calendar sync integration suites (#22567)
13 integration suites driving the real sync pipeline end to end — OAuth
connect via the actual `/auth/google-apis/get-access-token` /
`microsoft-apis` callbacks (transient token + mocked provider token
exchange), real queue workers, provider APIs mocked at the HTTP layer
with msw.

**Messaging (8):** Gmail list fetch + import, Gmail folder discovery,
Microsoft folder discovery, history-based incremental sync, stale-sync
recovery, sync failure lifecycle (429 throttle → exhaustion → relaunch;
declined refresh token → insufficient permissions), token refresh,
connected-account cleanup cascade.

**Calendar (5):** Google events import (full + sync-token incremental),
Microsoft events import (delta fetch + import), stale-sync recovery,
failure lifecycle, cleanup cascade.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22567?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-07 18:38:05 +05:30
Marie 8a4bcd1445 (Billing for self hosts) Tie enterprise key to server (#22464)
# Enterprise key: bind to a server, free dev instances, self-serve
transfer, shorter license

## Summary

Enterprise keys were being reused across multiple instances (e.g. one
prod + one dev, or several environments), which broke seat accounting
and made licensing ambiguous. This PR ties each enterprise key to a
**single server**, while giving customers a legitimate, self-serve way
to run a **free development instance** and to **move their key** when
they replace a server.

## Product behavior

### 1. Enterprise key is bound to one server
- The first server to validate an enterprise key **claims** it
(claim-on-first-use). From then on, that key is bound to that one server
(until unbound - see 3.).
- Any other instance that presents the **same key from a different
server is hard-rejected**: it does not receive a license, so enterprise
features stay off there.
- Each instance has a stable server identifier. If one isn't set, the
instance generates and persists one automatically on first validation
(in keyValuePair table), so existing customers generally don't need to
do anything (unless they have disabled config variables in db then they
should add it to .env).

### 2. Free development instance
- Every enterprise subscription gets **one free, non-billable
development instance** in addition to its production instance.
- An instance registers as development by declaring its instance type as
`development` (done by default when validating the enterprise key, then
can be toggled from UI or by updating value in keyValuePair table).
- The free dev slot is only granted while there is an **active
production instance** on the same subscription (so it's a perk for
paying customers, not a way to run for free).
- Only **one** dev instance can be active at a time per subscription,
and it is **not counted as a billable seat**.

### 3. Self-serve unbind / rebind (transfer)
- Admins can **release** the binding from the enterprise settings, which
frees the key so it can be **claimed by a new server**.
- This is the intended path when **sunsetting an instance and standing
up a new one** (migration, re-hosting, disaster recovery): release on
the old/dead box, then the new box claims it on its next validation.
- To prevent abuse, releases are **rate-limited (10 per rolling 30
days)**; hitting the limit shows a clear message.

### 4. Automatic release of dead servers
- If a bound server stops checking in for **14 days**, its binding is
considered stale and is **auto-released**, so a replacement can claim
the key without any manual step. This covers the case where the old
server is already gone and can't release itself.

### 5. Shorter license validity (30 → 7 days)
- The license (validity token) now expires after **7 days** instead of
30. The daily background refresh keeps healthy instances licensed
transparently.
- This limits the value of copying a license from one instance to
another, since a copied license now stops working within a week.

### 6. License issuance is rate-limited
- Issuing a new license is capped at **twice per 24h, independently for
production and for development**. This tolerates the normal daily
refresh (including small drift between runs) while blocking bursts of
license minting for cloned instances.
- Hitting this limit never revokes an existing, still-valid license —
the current one keeps working until it expires; the manual "refresh"
button just reports that the daily limit was reached.

## What changes for existing self-hosted customers

**If you run a single production instance with one enterprise key:**
nothing to do. On the next validation your instance reports its server
identifier, claims the binding, and keeps working.

**If you reuse one key across several instances (e.g. prod + dev, or
multiple environments):** only the **first** instance to validate keeps
its license. The others will **lose enterprise features**. To migrate:
- Keep your production instance as-is (it claims the binding).
- For a secondary/testing box, mark it as a **development instance**
(set the instance type to `development`) to use the free dev slot — no
extra cost.
- If you genuinely need multiple production instances, you'll need
**separate subscriptions/keys** for each.

**If you're replacing a server (decommissioning + rebuilding):**
- **Release** the binding from enterprise settings on the old instance,
then start the new one — it will claim the key automatically.
- If the old server is already gone, just wait for the **14-day
auto-release**, or contact support.

**Legacy instances that can't persist a server identifier
automatically:** set the server identifier explicitly in your
environment configuration (the instance logs a message telling you to do
so).

**Offline instances:** because licenses now last 7 days, an instance
that can't reach our licensing endpoint for more than a week will lose
enterprise features until it can check in again.

> A migration email will be sent to affected customers separately.

## Technical implementation (brief)

- Binding state lives in the **subscription's billing metadata** (bound
server id + last-seen timestamps for prod and dev, release timestamps,
and license-issuance timestamps). No new database is introduced on the
licensing side; the billing provider's subscription metadata is the
source of truth.
<img width="976" height="413" alt="metadata_3"
src="https://github.com/user-attachments/assets/ccc64822-e177-4223-a65a-4a4602aedf0e"
/>

- On each validation, a pure **binding resolver** takes the reported
server id + instance type + current metadata and returns `allowed` (with
the metadata to persist and whether the seat is billable) or `rejected`.
It handles claim-on-first-use, staleness/auto-release, the
dev-requires-active-prod rule, and the single-dev-slot rule.
- **Rate limits** (release + license issuance) use a shared
sliding-window helper stored as pruned timestamp lists in the same
metadata, so the metadata self-cleans and never grows unbounded. License
issuance uses **separate windows per instance type**.
- The self-hosted instance **generates and persists a server
identifier** if none is configured, and sends it (plus instance type) as
instance metadata on validation.
- A rejected binding returns a specific error code; the instance
**revokes its stored license** on that code. A license-issuance
rate-limit instead **throws a typed exception that surfaces to the
manual refresh** while leaving the existing license untouched; the daily
refresh job swallows it.
- License lifetime is a configurable duration (defaulted from 30 to **7
days**), clamped to the subscription's cancellation date when sooner.
2026-07-06 18:07:03 +02:00
martmull 1a85b88d38 feat(files): direct-to-storage upload endpoints with pending file lifecycle (#22449)
<img width="1484" height="404" alt="image"
src="https://github.com/user-attachments/assets/b2d363bf-d9e1-49fb-9811-8cc98041aa79"
/>


## Context

Uploading large files currently OOMs the server: every upload resolver
buffers the whole file in memory (`streamToBuffer`) before writing it to
storage. This PR is the first of a series introducing direct
client-to-storage uploads. It adds the server-side endpoints and driver
support only — it is non-breaking and nothing consumes the new flow yet.
Follow-up PRs will migrate the frontend upload paths, add a
stale-pending-file cleanup cron, and cap the legacy buffered resolvers.

## What it does

**New upload flow (initiate → PUT → confirm):**

- `createFileUpload(filename, size, fileFolder, fieldMetadataId?)`
validates the request (folder allowlist: `FilesField`/`Workflow`, max
size, extension-derived mime type), creates the file record in a new
`PENDING` status, and returns an upload target:
- **S3 with presign enabled** → a presigned PUT URL with
`Content-Type`/`Content-Length` pinned in the signature, so the client
uploads straight to the bucket;
- **local storage, or S3 without presign** → a token-authenticated
streaming endpoint on the server (`PUT /file-upload/:id?token=…`, new
`FILE_UPLOAD` JWT type) that pipes the request body to the storage
driver with constant memory usage and a declared-size cap.
- `completeFileUpload(fileId)` verifies the bytes actually landed in
storage (HEAD + size match against the declared size) and flips the
record to `UPLOADED`. Idempotent.

**Pending lifecycle safety:**

- New `status` column on `core.file` (`PENDING`/`UPLOADED`, default
`UPLOADED` so all existing rows and the legacy upload path are
unaffected) + fast instance command.
- Files are refused by the serving endpoints and by FILES-field sync
while `PENDING`.

**Driver support (both drivers):**

- `getPresignedUploadUrl` (S3: presigned PUT; local: `null` →
server-endpoint fallback)
- `writeFileStream` (local: `fs` pipeline with the existing
symlink/containment hardening, partial-file cleanup on error; S3:
`@aws-sdk/lib-storage` `Upload` for bounded-memory streaming)
- `getFileMetadata` (HEAD/stat for confirm-time verification)

## Tests

- `file-upload.service.spec.ts`: initiate validation (folder allowlist,
size), presigned vs fallback target, confirm verification (missing
object, size mismatch, happy path, idempotency)
- `local.driver.spec.ts`: `writeFileStream` (content, symlink rejection,
partial-file cleanup on stream error), `getFileMetadata`
- `s3.driver.spec.ts`: `getPresignedUploadUrl` (disabled → null, PUT
command with signed content-type/content-length)
- `direct-file-upload.integration-spec.ts`: full end-to-end flow against
the local driver (initiate → PUT → complete → download), plus error
paths (complete without upload, oversized PUT → 413, invalid token →
403, unsupported folder, size above max)

## Notes for reviewers

- The upload-size ceiling for direct uploads is
`settings.storage.maxDirectUploadFileSize` (1GB), separate from the 10MB
`maxFileSize` used for pictures.
- Since content can't be sniffed before it reaches storage, the mime
type is derived from the file extension (with the existing
`TWENTY_MIME_POLICY` override) and unknown extensions fall back to
`application/octet-stream`; the serving path already forces
`Content-Disposition: attachment` for anything not on the inline-safe
allowlist.
- Self-hosters using S3 presign will need a bucket CORS policy allowing
`PUT` from the frontend origin (config variable description updated).

https://claude.ai/code/session_015UH8KWmsB9zdYaog8MFG1d

---
_Generated by [Claude
Code](https://claude.ai/code/session_015UH8KWmsB9zdYaog8MFG1d)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22449?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-03 15:11:53 +02:00
Félix Malfait 3aeb2b0d5d Self-host Inter and DM Mono fonts (#22506)
Replaces the two Google Fonts stylesheets with self-hosted fonts via
`@fontsource`, imported in the app entry (and Storybook preview), and
removes the duplicate Inter that BlockNote was shipping.

## Why

- **The caching argument for Google Fonts is dead.** Browsers partition
the HTTP cache by top-level site (Chrome 86+, Firefox 85+, Safari even
earlier), so a font cached from another website is never reused on ours.
Every first-time visitor downloads the fonts either way — Google just
adds a detour.
- **Faster first paint.** This removes two render-blocking cross-origin
stylesheets from `index.html` (DNS + TLS to `fonts.googleapis.com`, then
a second connection to `fonts.gstatic.com`, with no preconnect today).
The fonts now ship from our own `/assets` alongside the rest of the app,
behind the same CDN and cache policy.
- **Privacy.** Visitor IPs are no longer sent to Google on every page
load. A German court ruled in 2022 that Google Fonts embedding violates
GDPR, and privacy-conscious self-hosters currently have no way to opt
out of the dependency.
- **Air-gapped / offline self-hosted instances** currently render
fallback system fonts; they now get the real ones.

## Font unification

We were actually loading Inter from two places: the Google stylesheet,
plus `@blocknote/core/fonts/inter.css` (8 weights, latin-only,
woff+woff2) imported by the two rich-text editors — whichever loaded
last won the cascade. Both are gone; `@fontsource` is now the single
source:

- Inter 400/500/600 (theme weights) + 700 (rich-text bold, previously
only covered by the BlockNote copy)
- DM Mono 400/500 (DM Mono has no 600 upstream; the old Google link
requested one anyway)

Fontsource ships the same `unicode-range` subsets as the Google CSS, so
browsers still only download the subset they need (~60KB of woff2 for
latin), and non-latin locales keep full coverage — which the latin-only
BlockNote copy didn't provide.

## Notes

- The BlockNote PDF export (`exportBlockNoteEditorToPdf.ts`) still
fetches Inter TTFs from `fonts.gstatic.com` at export time — react-pdf
needs TTF files, left unchanged here.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22506?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-03 10:12:27 +02:00
Raphaël Bosi ff6a0c6e69 Fix front component crash on unknown elements (#22455)
## What

Front components are third-party React components rendered on the host
via remote-dom against an allow-list of elements. Today the host
renderer throws on any element tag it has no component for (e.g. a raw
tag produced by `innerHTML`), and there is no error boundary, so a
single unknown element crashes the whole widget.

This wraps the component registry with a fallback:
- a raw tag that has an allow-listed `html-*` equivalent is routed to
that safe wrapper (so a raw `iframe` renders through the existing
sandbox-forcing renderer instead of being dropped),
- tags with no safe renderer (`script`, `object`, `embed`, `link`,
`meta`, `base`, `noscript`, `style`) render nothing,
- any other unknown tag renders children only.

`RemoteRootRenderer` is also wrapped in an error boundary that fails
closed to the existing error panel, so a render error can no longer take
down the host.

## Notes

The host allow-list remains the single rendering gate. This is the first
hardening step of a broader effort to widen the DOM/Web API surface
available to front components; it is self-contained and does not change
behavior for components that only use allow-listed elements.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22455?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-02 13:13:50 +00:00
Abdullah. a99431902d fix: bump json-2-csv 5.5.10 -> 5.5.11 (Dependabot) (#22438)
## Summary

Bumps **json-2-csv 5.5.10 → 5.5.11** to clear **1 medium Dependabot
alert** ([alert
1575](https://github.com/twentyhq/twenty/security/dependabot/1575) —
GHSA-g27c-q7cp-mhx6 / CVE-2026-9673, CSV Injection via the
`preventCsvInjection` option, vulnerable `>= 3.15.0, < 5.5.11`).

json-2-csv is a **direct dependency** of `twenty-front` (`"json-2-csv":
"^5.4.0"`). The caret already permits 5.5.11, so this is a
**lockfile-only** bump — no `package.json` change (matches Dependabot's
`versioning-strategy: lockfile-only`).

## Verification

- `yarn install --immutable` passes (CI parity).
- Diff is `yarn.lock`-only; json-2-csv resolves to 5.5.11.
- 5.5.11 is the latest and cleared twenty's 3-day npm age gate
(published 2026-05-26).
2026-07-02 09:19:31 +00:00
Abdullah. be8102c4a4 fix: evict js-yaml 3.x via front-matter patch + scoped resolutions (#22312)
## Summary

Closes the last open Dependabot alert on `main` — [alert
1504](https://github.com/twentyhq/twenty/security/dependabot/1504)
(GHSA-h67p-54hq-rp68 / CVE-2026-53550, js-yaml merge-key
quadratic-complexity DoS; medium, dev scope).

The 4.x js-yaml copies are already pinned to 4.2.0 (the seven
`@mintlify/*` + `@verdaccio/config` resolutions). The remaining
vulnerable copy was **js-yaml 3.14.2**, held by two `^3.13.1` consumers
with no fixed upstream release:
- `@istanbuljs/load-nyc-config@1.1.0` (jest coverage)
- `front-matter@4.0.2` (mintlify docs tooling — EOL, latest is 4.0.2)

## Approach

Both are forced to **js-yaml 4.2.0** via scoped resolutions, which
evicts the 3.x copy entirely:

```jsonc
"front-matter/js-yaml": "4.2.0",
"@istanbuljs/load-nyc-config/js-yaml": "4.2.0",
```

- **load-nyc-config** already calls `yaml.load` (present +
safe-by-default in 4.x), so its pin alone works.
- **front-matter** crashed on js-yaml 4.x because its default loader
called the removed `safeLoad`, so it's also **patched**
(`.yarn/patches/front-matter-npm-4.0.2-e1cc0efa69.patch`):

  ```diff
  -  var loader = allowUnsafe ? parser.load : parser.safeLoad
  +  var loader = parser.load
  ```

On 4.x `load` is already safe-by-default and there's no full/unsafe
schema, so the `allowUnsafe` ternary is dead.

**Why the version move is a separate resolution, not folded into the
patch:** a `yarn patch` only rewrites a package's *files* — it does
**not** change the resolved dependency graph. Bumping js-yaml inside the
patched `package.json` is ignored by resolution (verified:
front-matter@patch still pulled 3.14.2 until the explicit pin was
added). This is the repo's first *transitive* patch; like every other
transitive override it lives in root `resolutions`. Documented in the
`//resolutions` note.

## Verification

- js-yaml 3.x **fully evicted** — the tree resolves js-yaml to **4.2.0
only** (no `^3.13.1` descriptor remains).
- `yarn install --immutable` passes.
- front-matter parses real docs front-matter correctly on 4.2.0 (unit
smoke test).
- **`mintlify validate` passes** — the docs toolchain builds with the
patched front-matter.
2026-06-29 20:14:17 +05:00
Abdullah. e69c3ae5ce fix(website): bump @opennextjs/cloudflare to 1.20.0 (R2 deploy on Node 24) (#22266)
## What

The twenty-infra **"Deploy Website"** workflow has failed every run
since 06-26 — at OpenNext's R2 incremental-cache step, **not** the
build:

```
Failed to provision remote R2 bucket "twenty-website-cache-dev"
for binding "NEXT_INC_CACHE_R2_BUCKET":
Failed to check whether bucket exists: … Premature close
```

## Root cause

`@opennextjs/cloudflare`'s `ensureR2Bucket()` calls the Cloudflare SDK's
`r2.buckets.get()`. On **Node 24** (which the deploy pins) undici
truncates the **gzip-compressed** Cloudflare API response → `Premature
close`. The SDK's own retries don't help (it's systematic, not flaky),
and pre-creating the bucket doesn't help (it always `.get()`s first).

This is **pre-existing and unrelated to the multi-locale change**
(#22257): the *Build Worker* step succeeds, and the identical error
appears on 06-26 runs (two days before that merged).

## Fix

opennext **1.20.0** fixes this precisely — it passes `defaultHeaders: {
"Accept-Encoding": "identity" }` to the Cloudflare SDK client, so the
API returns **uncompressed** responses (no decompression → no premature
close). **Node 24 is kept**, and no twenty-infra change is needed — the
deploy runs `twenty`'s own `npx opennextjs-cloudflare`, so bumping the
dep here is enough.

`^1.0.0 → ^1.20.0`. **1.20.0, not the latest 1.20.1**, because the
repo's `npmMinimalAgeGate: 3d` still quarantines 1.20.1 (published
06-26); 1.20.0 (06-25) is past the gate and carries the same fix.

## Verification

- Resolved to `1.20.0`; confirmed `Accept-Encoding: identity` is in the
installed `dist/cli/utils/ensure-r2-bucket.js`.
- `nx typecheck twenty-website` green (OpenNext config API unchanged
across the bump).
- Diff is just `package.json` + `yarn.lock`.

⚠️ Full confirmation needs a **Deploy Website** run (exercises the build
+ the R2 provision step), which I can't trigger — please re-run it after
merge.
2026-06-28 16:18:31 +00:00
Félix Malfait 538b180824 feat(dpa): self-serve Data Processing Agreement generator (#22243)
## What

A single, region-aware DPA that serves all customers, generated
automatically from the customer's deployment. Two layers:

1. **Click-through DPA** — recorded at signup (acceptance = execution),
resolving merge fields from the deployment region. Cloud only.
2. **In-app signed-PDF generator** — Settings → Legal → Generate DPA:
preview the agreement, enter legal entity + authorized signatory,
download a PDF pre-signed by Twenty, and store the executed copy against
the workspace with its template version + timestamp. Deep-linkable at
`/dpa` (login-gated) for `twenty.com/dpa`.

## How it resolves

A typed variable matrix (`dpa-region-config.constant.ts`) maps the
deployment region to the contracting Processor entity and terms:

- **EU (default)** → Twenty.com SAS, hosting EU/Frankfurt, governing law
France, SCC section dormant.
- **US (custom)** → Twenty, Inc., hosting US, SCC section active.

Region is a deployment-wide setting (`DPA_DEPLOYMENT_REGION`, default
EU) behind a `DpaRegionService` seam so it can later become
per-workspace without touching callers. The legal text is verbatim from
the template (generated into `dpa-template.constant.ts` directly from
the source `.docx`); only the 6 merge fields are filled and the SCC
sections (7.2–7.5) stay in the document for every region per the spec —
only field values branch. Sub-processors are deferred to
trust.twenty.com (not enumerated). Billing stays decoupled (Twenty, Inc.
remains merchant of record regardless of Processor).

## UI

Standard list + create-page pattern (mirrors API keys / webhooks): a
list of executed copies (with re-download) — or the agreement preview
when none exists — and a top-right blue **Generate DPA** CTA opening a
standard create page. The "Legal" item is intentionally **not** in the
settings menu; the page is reached via the `/dpa` deep link.

## Notable implementation details

- **PDF** is rendered server-side with `@react-pdf/renderer`. The
built-in standard-14 fonts only encode ASCII and crash on the template's
curly quotes / em–en dashes / accented Latin, so Liberation Sans (OFL)
is **subset to a Latin glyph set and embedded as base64 data: URLs** —
no font files to ship or resolve at runtime (works in dev, prod-Docker
and CI).
- New `core.dpaAgreement` table via a fast instance command (FK hash
reproduced to match TypeORM).
- Self-hosted deployments (billing disabled) skip click-through
recording and stamp a prominent "not a valid agreement" banner on the
preview and PDF.

## Tests

- Unit: resolver (per-region entity/law/SCC state, EU default, no
unresolved `{{ }}`, SCC sections present in both regions, self-hosted
notice) and HTML renderer.
- Integration (`test/integration/graphql/suites/dpa`): preview has no
unresolved fields; `generateSignedDpa` renders + persists + returns a
downloadable PDF (asserted with accented input to guard the font
regression); list re-download.

## ⚠ Needs legal input before go-live (marked `TODO_CONFIRM` in
`dpa-region-config.constant.ts`)

- Registered-office addresses for Twenty.com SAS and Twenty, Inc.
- US deployment governing law (the template only specifies France).
- DPO name and the Twenty pre-signed authorized signatory name/title.

## Out of scope (flagged per spec)

Intra-group legal agreement and any Stripe/billing-entity changes. A
future e-sign provider would plug in at `DpaService.generateSignedDpa` +
the signatory input.

> Draft until the integration test passes in CI and the legal
`TODO_CONFIRM` values are supplied.

https://claude.ai/code/session_01Ahjydxx6J1souz1s1NeA9a

---
_Generated by [Claude
Code](https://claude.ai/code/session_01Ahjydxx6J1souz1s1NeA9a)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22243?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-27 17:46:38 +02:00
Félix Malfait 0e22ae0521 feat: create calendar events on Google and Microsoft accounts (#22231)
## Context

Twenty can import calendar events and send emails, but cannot create
calendar events. This adds calendar event creation on connected
**Google** and **Microsoft** accounts, mirroring the existing email-send
architecture (`message-outbound-manager`).

## What it adds

The capability is exposed three ways, all backed by the same composer →
driver → persist pipeline:

- **GraphQL mutation** `createCalendarEvent` (metadata API)
- **AI agent tool** `create_calendar_event` (flows to MCP
automatically), gated by a new `CREATE_CALENDAR_EVENT_TOOL` permission
flag
- **Workflow builder node** "Create Calendar Event" in the **Core**
section, with a full settings form (variable interpolation supported)

CalDAV/IMAP is intentionally out of scope for now (different long pole).

## Design notes

- **Reuse over reinvention** — the created event is run through the
existing inbound formatters (`formatGoogleCalendarEvents` /
`formatMicrosoftCalendarEvents`) and persisted immediately via the
existing `CalendarSaveEventsService`, so it appears in Twenty right away
and is reconciled by the next provider sync (dedup on external id).
Persistence is best-effort.
- **OAuth scopes** — Google already requests `calendar.events`
(read+write), so no change there. Microsoft moves `Calendars.Read` →
`Calendars.ReadWrite`; existing Microsoft accounts must re-consent
(surfaced as a clear "reconnect" error via a missing-scope check).
- **Deliberate invitation semantics** — `sendInvitations` is off by
default. When off, the event is created with **no attendees** on either
provider, so creating an event never silently emails external people.
When on, attendees are attached and notified (Google `sendUpdates: all`,
Microsoft's default). This sidesteps Microsoft Graph having no
per-request suppression.
- **Timezone correctness** — Microsoft Graph interprets `dateTime` as
wall-clock in the supplied `timeZone` and ignores the offset, so the
absolute instant is converted to its wall-clock form before sending
(Google honors the offset directly). Both providers end up scheduling
the same instant.
- **Conferencing** — optional Google Meet
(`conferenceData.createRequest`, with a follow-up `events.get` to
resolve the async link) / Microsoft Teams (`isOnlineMeeting`).
- Attendees are a comma-separated string everywhere (tool input, GraphQL
DTO, workflow input), consistent with `send_email` recipients; the
composer parses to its internal list.

## Test plan

- **Unit**: 45 tests covering the composer (validation, all-day
boundaries, offset enforcement, timezone, scope checks, default-account
resolution), both provider drivers, the dispatcher, and the workflow
step-log builder.
- **Integration**: `createCalendarEvent` on the `/metadata` API fails
closed with a structured error for a non-existent account (the
auth/ownership/validation path that doesn't require provider mocking).
- **Manual**: verified the workflow node appears in the Core section,
the settings form renders and round-trips (edit → autosave → reload),
and the live mutation returns a structured failure for a bogus account.

## Open question for reviewers

The metadata mutation `createCalendarEvent` shares a name with the core
schema's auto-generated `createCalendarEvent(data:)` CRUD mutation for
the CalendarEvent object — they live on different endpoints (`/metadata`
vs `/graphql`) so there's no runtime conflict, but it's a potential
point of confusion for API consumers. Happy to rename (e.g.
`createCalendarEventOnConnectedAccount`) if preferred.

## Out of scope / follow-ups

- CalDAV/IMAP support
- Event update/delete and recurrence
- Existing Microsoft accounts need re-consent for the widened scope


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22231?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: neo773 <neo773@protonmail.com>
2026-06-27 14:05:58 +02:00
Charles Bochet fe1a8ad5f0 fix(ci): patch danger to decline gzip, fixing ERR_STREAM_PREMATURE_CLOSE on Node 24 (#22171)
## Problem

The `danger-js` check (`twenty-utils:danger:ci`) started failing
intermittently with:

```
FetchError: Invalid response body while trying to fetch
https://api.github.com/repos/twentyhq/twenty/pulls/<n>/files: Premature close
  errno: 'ERR_STREAM_PREMATURE_CLOSE'
```

It fails before the Dangerfile even runs, while fetching PR files / diff
/ commits. The existing retry wrapper
([#22151](https://github.com/twentyhq/twenty/pull/22151)) reduced it but
can't absorb longer GitHub-API windows, so checks still go red.

## Root cause

Not "node-fetch is old" generically — a specific recent regression:

- Node **22.23.0 / 24.17.0** shipped a security fix for CVE-2026-48931
(http.Agent response-queue poisoning) that attaches a `'data'` listener
to idle keep-alive sockets.
- `node-fetch@2` misreads that listener as an unclean connection close —
but only on **gzip-encoded responses without `Content-Length`**, which
is exactly what `api.github.com` returns.
- The GitHub-hosted runners rolling into the patched Node 24.17.x in
recent weeks is why this surfaced now.

See
[danger/danger-js#1515](https://github.com/danger/danger-js/issues/1515),
[nodejs/node#63989](https://github.com/nodejs/node/issues/63989).

## Why this approach

- `node-fetch@2` can't be removed downstream — Danger imports it
directly, and it's pervasive transitively (gaxios/googleapis). Dropping
it is an upstream migration.
- We don't want to pin an old Node version.

So: bump `danger` 13.0.4 → 13.0.8 and backport
[danger/danger-js#1516](https://github.com/danger/danger-js/pull/1516)
via a yarn patch — set `compress: false` on Danger's shared `api()`
wrapper. GitHub then returns identity-encoded responses with
`Content-Length`, and node-fetch's faulty premature-close detector never
fires. Negligible bandwidth cost on these small JSON payloads; explicit
caller overrides are preserved via an `=== undefined` guard.

## Changes

- `packages/twenty-utils/package.json` — `danger` → patched 13.0.8
- `yarn.lock` — registers the `danger@patch:` resolution
- `.yarn/patches/danger-npm-13.0.8-48aba2788c.patch` — the `compress:
false` fix

## Verification

- Patch dry-run applies cleanly against pristine danger 13.0.8 source.
- Inspected yarn's materialized patched cache package — the `compress`
fix is present in the linked `distribution/api/fetch.js`.
- Confirmed the failing calls (`getPullRequestInfo` /
`getPullRequestCommits` / `getPullRequestDiff`) all route through
`this.api` → the patched wrapper.

## Lifecycle

Temporary backport. When #1516 ships in a Danger release, drop the patch
and bump to that version (flagged in a comment inside the patch). The
existing CI retry wrapper stays as defense-in-depth.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22171?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-25 14:32:25 +02:00
Parship Chowdhury 6ee5413951 chore(vite): replace vite-tsconfig-paths with resolve.tsconfigPaths (#22100)
### Summary
Migrates main monorepo packages from the `vite-tsconfig-paths` plugin to
vite’s built-in path resolution.

Vite 8 showing this warning when the plugin is detected:
> The plugin "vite-tsconfig-paths" is detected. Vite now supports
tsconfig paths resolution natively via the resolve.tsconfigPaths option.
You can remove the plugin and set resolve.tsconfigPaths: true in your
Vite config instead.

### References
- https://vite.dev/config/shared-options#resolve-tsconfigpaths
- https://vite.dev/guide/features#paths
- https://github.com/vitejs/vite/pull/21781

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22100?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Signed-off-by: Parship Chowdhury <parshipchowdhury@gmail.com>
2026-06-24 19:03:18 +02:00
dependabot[bot] 8830ef89bd chore(deps-dev): bump @storybook/addon-docs from 10.3.4 to 10.4.6 (#22110)
Bumps
[@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs)
from 10.3.4 to 10.4.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/addon-docs's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.6</h2>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>v10.4.5</h2>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>v10.4.4</h2>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>v10.4.3</h2>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>v10.4.2</h2>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>v10.4.1</h2>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run `npx expo install --fix` after init for Expo projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support `peerDependencies` in framework detection for component
libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>v10.4.0</h2>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/addon-docs's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run <code>npx expo install --fix</code> after init for Expo
projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support <code>peerDependencies</code> in framework detection
for component libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<ul>
<li>🤖 Agentic Setup: New CLI workflow for AI-assisted Storybook setup
and onboarding</li>
<li>🔍 Change review: Sidebar filtering to highlight new, modified, and
related stories based on git changes</li>
<li>🧭 Sidebar review tools: Status filtering, URL-persisted filters, and
clearer review signals in the sidebar</li>
<li>⚛️ TanStack React: New <code>@storybook/tanstack-react</code>
framework with routing and server function support</li>
<li>🧩 React MCP: Faster, more accurate component docgen powered by the
TypeScript Language Server</li>
<li>📱 React Native: Zero config RN project initialization</li>
<li>🤝 Sharing: Easily publish and share your local Storybook with
teammates, powered by Chromatic</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/5496a4270da7f3a8e0203185792685cba671fdc5"><code>5496a42</code></a>
Bump version from &quot;10.4.5&quot; to &quot;10.4.6&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a>
Bump version from &quot;10.4.4&quot; to &quot;10.4.5&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a>
Bump version from &quot;10.4.3&quot; to &quot;10.4.4&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a>
Bump version from &quot;10.4.2&quot; to &quot;10.4.3&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c89882282295be3bc05b3a366916c53d7a499841"><code>c898822</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/34496">#34496</a>
from NYCU-Chung/fix/docs-blocks-custom-mdx</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c920fd08c79c57879fa2ddb4e8538e1684c71ec2"><code>c920fd0</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/35021">#35021</a>
from LongTangGithub/fix/docs-hmr-scroll-to-top</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/1750494e9f36748b2d89335e77f23f125fc5ec78"><code>1750494</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/35031">#35031</a>
from storybookjs/jeppe/fix-mdx-no-dev-tag</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a>
Bump version from &quot;10.4.1&quot; to &quot;10.4.2&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/cc19ae1a2145e8f7cda8dc869f1b90d5346dcedb"><code>cc19ae1</code></a>
Bump version from &quot;10.4.0&quot; to &quot;10.4.1&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f8c16d115cfcf0f79125b358266c37e5343bb70d"><code>f8c16d1</code></a>
Bump version from &quot;10.4.0-beta.0&quot; to &quot;10.4.0&quot; [skip
ci]</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/addons/docs">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@storybook/addon-docs&package-manager=npm_and_yarn&previous-version=10.3.4&new-version=10.4.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22110?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-24 18:37:04 +02:00
dependabot[bot] 264d0a7671 chore(deps): bump @ai-sdk/mistral from 3.0.39 to 3.0.40 (#22117)
Bumps
[@ai-sdk/mistral](https://github.com/vercel/ai/tree/HEAD/packages/mistral)
from 3.0.39 to 3.0.40.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/ai/blob/@ai-sdk/mistral@3.0.40/packages/mistral/CHANGELOG.md">@​ai-sdk/mistral's
changelog</a>.</em></p>
<blockquote>
<h2>3.0.40</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [779f5cd]
<ul>
<li><code>@​ai-sdk/provider-utils</code><a
href="https://github.com/4"><code>@​4</code></a>.0.30</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/ai/commit/caebb44016dbd084e5bf7b7f4ab5194fd2c7c045"><code>caebb44</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/mistral/issues/16157">#16157</a>)</li>
<li>See full diff in <a
href="https://github.com/vercel/ai/commits/@ai-sdk/mistral@3.0.40/packages/mistral">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@ai-sdk/mistral&package-manager=npm_and_yarn&previous-version=3.0.39&new-version=3.0.40)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22117?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 18:36:41 +02:00
dependabot[bot] 9574476395 chore(deps): bump @scalar/api-reference-react from 0.9.46 to 0.9.48 (#22115)
Bumps
[@scalar/api-reference-react](https://github.com/scalar/scalar/tree/HEAD/packages/api-reference-react)
from 0.9.46 to 0.9.48.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/scalar/scalar/blob/main/packages/api-reference-react/CHANGELOG.md">@​scalar/api-reference-react's
changelog</a>.</em></p>
<blockquote>
<h2>0.9.48</h2>
<h2>0.9.47</h2>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/scalar/scalar/commits/HEAD/packages/api-reference-react">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@scalar/api-reference-react&package-manager=npm_and_yarn&previous-version=0.9.46&new-version=0.9.48)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22115?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 16:19:16 +00:00
dependabot[bot] 5bb3ff4e43 chore(deps): bump @sentry/react from 10.51.0 to 10.60.0 (#22111)
Bumps [@sentry/react](https://github.com/getsentry/sentry-javascript)
from 10.51.0 to 10.60.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-javascript/releases">@​sentry/react's
releases</a>.</em></p>
<blockquote>
<h2>10.60.0</h2>
<h3>Other Changes</h3>
<ul>
<li>feat(cloudflare): Add R2 bucket auto-instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21327">#21327</a>)</li>
<li>feat(core): Add <code>bindScopeToEmitter</code> to bind a scope to
an event emitter (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21594">#21594</a>)</li>
<li>feat(deps): Bump <code>@​hapi/wreck</code> from 18.1.0 to 18.1.2 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21178">#21178</a>)</li>
<li>fix(browser): Ensure <code>url.full</code> and <code>http.url</code>
attributes have the same values on <code>http.client</code> spans (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21660">#21660</a>)</li>
<li>fix(server-utils): Avoid directly importing
<code>tracingChannel</code> for Node v18 compatibility (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21662">#21662</a>)</li>
<li>fix(server-utils): Remove optional <code>vite</code> peer dependency
(<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21677">#21677</a>)</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>chore: Add bundler-plugins to craft (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21701">#21701</a>)</li>
<li>chore: Cleanup unused imports of <code>@opentelemetry/core</code>
(<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21679">#21679</a>)</li>
<li>fix(bundler-plugins): Integration with monorepo build (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21479">#21479</a>)</li>
<li>ref(core): Gate updateName() custom source on an OTel inference
brand (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21649">#21649</a>)</li>
<li>ref(core/opentelemetry): Move OTel span data inference from
<code>captureSpan</code> to <code>SentrySpanProcessor</code> (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21648">#21648</a>)</li>
<li>ref(node): Remove unused sql-common helper and
<code>@opentelemetry/core</code> dep (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21688">#21688</a>)</li>
<li>ref(node): Streamline kafkajs instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21647">#21647</a>)</li>
<li>ref(node): Streamline undici (node-fetch) instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21650">#21650</a>)</li>
<li>ref(vercel-edge): Drop unused
<code>@opentelemetry/semantic-conventions</code> dependency (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21691">#21691</a>)</li>
<li>ref(vercel-edge): Remove <code>@opentelemetry/resources</code>
dependency (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21690">#21690</a>)</li>
</ul>
<!-- raw HTML omitted -->
<h2>Bundle size 📦</h2>
<table>
<thead>
<tr>
<th>Path</th>
<th>Size</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>@​sentry/browser</code></td>
<td>26.83 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> - with treeshaking flags</td>
<td>25.3 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing)</td>
<td>44.89 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing + Span Streaming)</td>
<td>46.6 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing, Profiling)</td>
<td>49.56 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing, Replay)</td>
<td>83.18 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing, Replay) - with
treeshaking flags</td>
<td>73.02 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing, Replay with
Canvas)</td>
<td>87.76 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Tracing, Replay, Feedback)</td>
<td>100.12 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Feedback)</td>
<td>43.61 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. sendFeedback)</td>
<td>31.5 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. FeedbackAsync)</td>
<td>36.52 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Metrics)</td>
<td>27.87 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Logs)</td>
<td>28.11 KB</td>
</tr>
<tr>
<td><code>@​sentry/browser</code> (incl. Metrics &amp; Logs)</td>
<td>28.78 KB</td>
</tr>
<tr>
<td><code>@​sentry/react</code></td>
<td>28.59 KB</td>
</tr>
<tr>
<td><code>@​sentry/react</code> (incl. Tracing)</td>
<td>47.14 KB</td>
</tr>
<tr>
<td><code>@​sentry/vue</code></td>
<td>31.86 KB</td>
</tr>
<tr>
<td><code>@​sentry/vue</code> (incl. Tracing)</td>
<td>46.71 KB</td>
</tr>
<tr>
<td><code>@​sentry/svelte</code></td>
<td>26.85 KB</td>
</tr>
</tbody>
</table>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md">@​sentry/react's
changelog</a>.</em></p>
<blockquote>
<h2>10.60.0</h2>
<h3>Other Changes</h3>
<ul>
<li>feat(cloudflare): Add R2 bucket auto-instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21327">#21327</a>)</li>
<li>feat(core): Add <code>bindScopeToEmitter</code> to bind a scope to
an event emitter (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21594">#21594</a>)</li>
<li>feat(deps): Bump <code>@​hapi/wreck</code> from 18.1.0 to 18.1.2 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21178">#21178</a>)</li>
<li>fix(browser): Ensure <code>url.full</code> and <code>http.url</code>
attributes have the same values on <code>http.client</code> spans (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21660">#21660</a>)</li>
<li>fix(server-utils): Avoid directly importing
<code>tracingChannel</code> for Node v18 compatibility (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21662">#21662</a>)</li>
<li>fix(server-utils): Remove optional <code>vite</code> peer dependency
(<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21677">#21677</a>)</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>chore: Add bundler-plugins to craft (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21701">#21701</a>)</li>
<li>chore: Cleanup unused imports of <code>@opentelemetry/core</code>
(<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21679">#21679</a>)</li>
<li>fix(bundler-plugins): Integration with monorepo build (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21479">#21479</a>)</li>
<li>ref(core): Gate updateName() custom source on an OTel inference
brand (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21649">#21649</a>)</li>
<li>ref(core/opentelemetry): Move OTel span data inference from
<code>captureSpan</code> to <code>SentrySpanProcessor</code> (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21648">#21648</a>)</li>
<li>ref(node): Remove unused sql-common helper and
<code>@opentelemetry/core</code> dep (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21688">#21688</a>)</li>
<li>ref(node): Streamline kafkajs instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21647">#21647</a>)</li>
<li>ref(node): Streamline undici (node-fetch) instrumentation (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21650">#21650</a>)</li>
<li>ref(vercel-edge): Drop unused
<code>@opentelemetry/semantic-conventions</code> dependency (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21691">#21691</a>)</li>
<li>ref(vercel-edge): Remove <code>@opentelemetry/resources</code>
dependency (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21690">#21690</a>)</li>
</ul>
<!-- raw HTML omitted -->
<h2>10.59.0</h2>
<h3>Important Changes</h3>
<ul>
<li>
<p><strong>feat(react-router): Add support for React Router v8 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21633">#21633</a>)</strong></p>
<p>The SDK now supports React Router v8, in both the framework and SPA
(<code>@sentry/react</code>) modes.</p>
</li>
<li>
<p><strong>feat(react): Add version-agnostic React Router SPA exports
(<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/21633">#21633</a>)</strong></p>
<p><code>@sentry/react</code> now exports version-agnostic wrappers for
React Router v6+ SPA instrumentation.
The new exports replace the version-specific
<code>V6</code>/<code>V7</code> variants, which are now deprecated:</p>
<table>
<thead>
<tr>
<th>Deprecated</th>
<th>New</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>reactRouterV6BrowserTracingIntegration</code> /
<code>V7</code></td>
<td><code>reactRouterBrowserTracingIntegration</code></td>
</tr>
<tr>
<td><code>withSentryReactRouterV6Routing</code> / <code>V7</code></td>
<td><code>wrapReactRouterRouting</code></td>
</tr>
<tr>
<td><code>wrapCreateBrowserRouterV6</code> / <code>V7</code></td>
<td><code>wrapCreateBrowserRouter</code></td>
</tr>
<tr>
<td><code>wrapCreateMemoryRouterV6</code> / <code>V7</code></td>
<td><code>wrapCreateMemoryRouter</code></td>
</tr>
<tr>
<td><code>wrapUseRoutesV6</code> / <code>V7</code></td>
<td><code>wrapUseRoutes</code></td>
</tr>
</tbody>
</table>
<p>The deprecated exports continue to work and will be removed in the
next major version.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/4548afc27908146dca23db7a6722de714119909c"><code>4548afc</code></a>
test: Make bundler plugins tests work after release</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/499c327ea9240c6daa183ff76a734ce89117c230"><code>499c327</code></a>
chore: fix yarn.lock</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/4d26c19e7367d870e2e0758ba51def5d41637b52"><code>4d26c19</code></a>
release: 10.60.0</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/cc7dea46c1915b4a2a7d39e21248c938f2ed800c"><code>cc7dea4</code></a>
Merge pull request <a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/21703">#21703</a>
from getsentry/prepare-release/10.60.0</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/bcef5d9c1cfb9d58f10fa5e9f5dfb42be1e4ff9c"><code>bcef5d9</code></a>
meta(changelog): Update changelog for 10.60.0</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/8285066e1cfb58493d1434f895bd43f986e4d917"><code>8285066</code></a>
chore: Add bundler-plugins to craft (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/21701">#21701</a>)</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/b953c6f74d9ac83eecbae0dc65cd09fedabda7a4"><code>b953c6f</code></a>
fix(browser): Ensure <code>url.full</code> and <code>http.url</code>
attributes have the same value...</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/b54777a859f5e8b7bcb90ab218bef1a55d133d7a"><code>b54777a</code></a>
ref(vercel-edge): Drop unused
<code>@opentelemetry/semantic-conventions</code> dependenc...</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/2e29cd32769084a46a5ce66b36a49b1295741a79"><code>2e29cd3</code></a>
ref(vercel-edge): Remove <code>@opentelemetry/resources</code>
dependency (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/21690">#21690</a>)</li>
<li><a
href="https://github.com/getsentry/sentry-javascript/commit/c5e245f869eca352e5d11833dd9b3264da448ac9"><code>c5e245f</code></a>
ref(node): Remove unusued sql-common helper and
<code>@opentelemetry/core</code> dep (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/2">#2</a>...</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-javascript/compare/10.51.0...10.60.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@sentry/react&package-manager=npm_and_yarn&previous-version=10.51.0&new-version=10.60.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22111?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 18:03:37 +02:00
dependabot[bot] f2bed8359d chore(deps): bump @nestjs/schedule from 6.1.0 to 6.1.3 (#22112)
Bumps [@nestjs/schedule](https://github.com/nestjs/schedule) from 6.1.0
to 6.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nestjs/schedule/releases">@​nestjs/schedule's
releases</a>.</em></p>
<blockquote>
<h2>6.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(cron): add initialDelay option to defer first job execution by
<a
href="https://github.com/kyungseopk1m"><code>@​kyungseopk1m</code></a>
in <a
href="https://redirect.github.com/nestjs/schedule/pull/2251">nestjs/schedule#2251</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nestjs/schedule/compare/6.1.2...6.1.3">https://github.com/nestjs/schedule/compare/6.1.2...6.1.3</a></p>
<h2>Release 6.1.2</h2>
<ul>
<li>Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2247">#2247</a>
from kyungseopk1m/feat/cron-initial-delay (a57ce2c)</li>
<li>chore(deps): update dependency prettier to v3.8.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2248">#2248</a>)
(bb3490d)</li>
<li>feat(cron): add initialDelay option to defer first job execution
(1c5677f)</li>
<li>Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2245">#2245</a>
from nestjs/renovate/nest-monorepo (59046bd)</li>
<li>Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2246">#2246</a>
from nestjs/renovate/oxlint-monorepo (be4eee3)</li>
<li>chore(deps): update dependency oxlint to v1.60.0 (32a9ce2)</li>
<li>chore(deps): update nest monorepo to v11.1.19 (7d3844f)</li>
<li>chore: migrate to oxlint, vitest, ts6 (29de71b)</li>
<li>chore(deps): update dependency globals to v17.5.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2244">#2244</a>)
(6c62cca)</li>
<li>chore(deps): update dependency sinon to v21.1.2 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2243">#2243</a>)
(ee3b31a)</li>
<li>chore(deps): update dependency sinon to v21.1.1 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2241">#2241</a>)
(eba9799)</li>
<li>Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2242">#2242</a>
from nestjs/renovate/prettier-3.x (c3ad0f7)</li>
<li>chore(deps): update dependency prettier to v3.8.2 (798e2a9)</li>
<li>Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2199">#2199</a>
from nestjs/renovate/cimg-node-24.x (a05354a)</li>
<li>chore(deps): update dependency typescript-eslint to v8.58.1 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2240">#2240</a>)
(0367ac1)</li>
<li>chore(deps): update dependency eslint to v10.2.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2239">#2239</a>)
(fa93e06)</li>
<li>chore(deps): update nest monorepo to v11.1.18 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2238">#2238</a>)
(8cd4c02)</li>
<li>chore(deps): update dependency <code>@​types/node</code> to v24.12.2
(<a
href="https://redirect.github.com/nestjs/schedule/issues/2237">#2237</a>)
(01482df)</li>
<li>chore(deps): update dependency <code>@​types/sinon</code> to v21.0.1
(<a
href="https://redirect.github.com/nestjs/schedule/issues/2236">#2236</a>)
(f05b5bd)</li>
<li>chore(deps): update dependency ts-jest to v29.4.9 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2235">#2235</a>)
(af545e6)</li>
<li>chore(deps): update dependency typescript-eslint to v8.58.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2233">#2233</a>)
(4dad22a)</li>
<li>chore(deps): update node.js to v24.14.1 (28db9bc)</li>
<li>chore(deps): update dependency eslint to v10.1.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2232">#2232</a>)
(413f390)</li>
<li>chore(deps): update nest monorepo to v11.1.17 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2230">#2230</a>)
(46c2bc5)</li>
<li>chore(deps): update dependency typescript-eslint to v8.57.1 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2231">#2231</a>)
(8fd063b)</li>
<li>chore(deps): update dependency sinon to v21.0.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2229">#2229</a>)
(1671ad9)</li>
<li>chore(deps): update commitlint monorepo to v20.5.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2228">#2228</a>)
(2ecd2f1)</li>
<li>chore(deps): update dependency lint-staged to v16.4.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2227">#2227</a>)
(aa0de01)</li>
<li>chore(deps): update commitlint monorepo to v20.4.4 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2226">#2226</a>)
(75034fe)</li>
<li>chore(deps): update dependency lint-staged to v16.3.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2225">#2225</a>)
(f1c7d31)</li>
<li>chore(deps): update dependency jest to v30.3.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2224">#2224</a>)
(1a208d4)</li>
<li>chore(deps): update dependency typescript-eslint to v8.57.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2223">#2223</a>)
(60dd2c9)</li>
<li>chore(deps): update dependency eslint to v10.0.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2221">#2221</a>)
(791b6ba)</li>
<li>chore(deps): update dependency <code>@​eslint/eslintrc</code> to
v3.3.5 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2220">#2220</a>)
(0da1ca7)</li>
<li>chore(deps): update dependency <code>@​types/node</code> to v24.12.0
(<a
href="https://redirect.github.com/nestjs/schedule/issues/2219">#2219</a>)
(934a93e)</li>
<li>chore(deps): update nest monorepo to v11.1.16 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2218">#2218</a>)
(5f44e9b)</li>
<li>chore(deps): update dependency sinon to v21.0.2 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2217">#2217</a>)
(b807746)</li>
<li>chore(deps): update dependency lint-staged to v16.3.2 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2216">#2216</a>)
(4ca32bd)</li>
<li>chore(deps): update commitlint monorepo to v20.4.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2215">#2215</a>)
(d3ceb76)</li>
<li>chore(deps): update nest monorepo to v11.1.15 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2214">#2214</a>)
(b084ffc)</li>
<li>chore(deps): update dependency lint-staged to v16.3.1 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2213">#2213</a>)
(8a201b2)</li>
<li>chore(deps): update dependency globals to v17.4.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2212">#2212</a>)
(6f61793)</li>
<li>chore(deps): update dependency lint-staged to v16.3.0 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2211">#2211</a>)
(aa9213a)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nestjs/schedule/commit/059f19678aac04fc4132b1aeaebd7a9ae4f34e30"><code>059f196</code></a>
Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2249">#2249</a>
from nestjs/renovate/release-it-20.x</li>
<li><a
href="https://github.com/nestjs/schedule/commit/557730ee8b898a0e2b03cdd5b207e176b60f8b1e"><code>557730e</code></a>
Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2251">#2251</a>
from kyungseopk1m/feat/cron-initial-delay-v2</li>
<li><a
href="https://github.com/nestjs/schedule/commit/14f5b80a16f2ce25c77a2f6de9370705b27a2acb"><code>14f5b80</code></a>
feat(cron): add initialDelay option to defer first job execution</li>
<li><a
href="https://github.com/nestjs/schedule/commit/536367da7d59609b3595d440101fc24aaefb7cb5"><code>536367d</code></a>
chore(deps): update dependency release-it to v20</li>
<li><a
href="https://github.com/nestjs/schedule/commit/57e2861f5e8cf5e9e3a709a2918f478d03e57aa5"><code>57e2861</code></a>
Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2250">#2250</a>
from nestjs/revert-2247-feat/cron-initial-delay</li>
<li><a
href="https://github.com/nestjs/schedule/commit/e08f457e4bddc83801d7bf0c60aff4a821290c9f"><code>e08f457</code></a>
Revert &quot;feat(cron): add initialDelay option to defer first job
execution&quot;</li>
<li><a
href="https://github.com/nestjs/schedule/commit/3198abea06f82b658b5bc4aa1dee6018c92cf04b"><code>3198abe</code></a>
chore(): release v6.1.2</li>
<li><a
href="https://github.com/nestjs/schedule/commit/a57ce2c329b0662cffd56b16d71fb9da3b84c743"><code>a57ce2c</code></a>
Merge pull request <a
href="https://redirect.github.com/nestjs/schedule/issues/2247">#2247</a>
from kyungseopk1m/feat/cron-initial-delay</li>
<li><a
href="https://github.com/nestjs/schedule/commit/bb3490dde2c3852463f231c3c556dd6d5b3a06d7"><code>bb3490d</code></a>
chore(deps): update dependency prettier to v3.8.3 (<a
href="https://redirect.github.com/nestjs/schedule/issues/2248">#2248</a>)</li>
<li><a
href="https://github.com/nestjs/schedule/commit/1c5677f46f100b03e5ae867306f089ba3381fab0"><code>1c5677f</code></a>
feat(cron): add initialDelay option to defer first job execution</li>
<li>Additional commits viewable in <a
href="https://github.com/nestjs/schedule/compare/6.1.0...6.1.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@nestjs/schedule&package-manager=npm_and_yarn&previous-version=6.1.0&new-version=6.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22112?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 18:03:13 +02:00
dependabot[bot] 6a7458f20d chore(deps): bump @e2b/code-interpreter from 2.6.0 to 2.6.1 (#22106)
Bumps
[@e2b/code-interpreter](https://github.com/e2b-dev/code-interpreter/tree/HEAD/js)
from 2.6.0 to 2.6.1.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/e2b-dev/code-interpreter/commit/fe3e5db60ba8f1b13623289a1b17a6f7e1a18f67"><code>fe3e5db</code></a>
Throw descriptive error when sandbox is killed mid-request (<a
href="https://github.com/e2b-dev/code-interpreter/tree/HEAD/js/issues/291">#291</a>)</li>
<li><a
href="https://github.com/e2b-dev/code-interpreter/commit/efadb49cc87e06766bdb1cc6f33d3c54cd3e2607"><code>efadb49</code></a>
[skip ci] Release new versions</li>
<li>See full diff in <a
href="https://github.com/e2b-dev/code-interpreter/commits/@e2b/code-interpreter@2.6.1/js">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@e2b/code-interpreter&package-manager=npm_and_yarn&previous-version=2.6.0&new-version=2.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22106?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 15:45:33 +00:00
dependabot[bot] e9d67a4bb3 chore(deps-dev): bump @storybook/addon-a11y from 10.4.1 to 10.4.6 (#22103)
Bumps
[@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y)
from 10.4.1 to 10.4.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/addon-a11y's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.6</h2>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>v10.4.5</h2>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>v10.4.4</h2>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>v10.4.3</h2>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>v10.4.2</h2>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/addon-a11y's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/5496a4270da7f3a8e0203185792685cba671fdc5"><code>5496a42</code></a>
Bump version from &quot;10.4.5&quot; to &quot;10.4.6&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a>
Bump version from &quot;10.4.4&quot; to &quot;10.4.5&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a>
Bump version from &quot;10.4.3&quot; to &quot;10.4.4&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a>
Bump version from &quot;10.4.2&quot; to &quot;10.4.3&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a>
Bump version from &quot;10.4.1&quot; to &quot;10.4.2&quot; [skip
ci]</li>
<li>See full diff in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/addons/a11y">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@storybook/addon-a11y&package-manager=npm_and_yarn&previous-version=10.4.1&new-version=10.4.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22103?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 15:45:11 +00:00
dependabot[bot] fef53b9915 chore(deps): bump react-error-boundary from 4.0.13 to 4.1.2 (#22105)
Bumps
[react-error-boundary](https://github.com/bvaughn/react-error-boundary)
from 4.0.13 to 4.1.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/bvaughn/react-error-boundary/releases">react-error-boundary's
releases</a>.</em></p>
<blockquote>
<h2>4.1.2</h2>
<ul>
<li>Remove <code>engines</code> field from Package JSON entirely</li>
</ul>
<h2>4.1.1</h2>
<ul>
<li>Remove node constraint from engines</li>
</ul>
<h2>4.1.0</h2>
<ul>
<li>Relax fallback prop to support broader ReactNode type</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/9688d9f80d47834011dccfa9d1f1377968a4108f"><code>9688d9f</code></a>
4.1.1 -&gt; 4.1.2</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/8f48596c6702107ad0bffee105ed9eb95c30f869"><code>8f48596</code></a>
Remove engines field</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/434282742a2f14190aa8c0b27d0d1292d082a914"><code>4342827</code></a>
4.1.0 -&gt; 4.1.1</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/e3d6eb9962d1a6515756f7af7994302d2cb566c6"><code>e3d6eb9</code></a>
Remove node constraint from engines</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/defdae05746cb6571152414661e8c78592608465"><code>defdae0</code></a>
style(types.ts): remove unused imports (<a
href="https://redirect.github.com/bvaughn/react-error-boundary/issues/200">#200</a>)</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/a1e634faef0fc4fd23a731143b5ae6e2c69f8c55"><code>a1e634f</code></a>
chore(package.json): add rimraf (<a
href="https://redirect.github.com/bvaughn/react-error-boundary/issues/199">#199</a>)</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/96bb33370f9b9f0c9c6f3733a90d55dd7a1c34d2"><code>96bb333</code></a>
4.0.12 -&gt; 4.1.0</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/206bdbad362737480ebd39cefb945c8cec11c1ce"><code>206bdba</code></a>
Upgrade pnpm v8 -&gt; v9 (<a
href="https://redirect.github.com/bvaughn/react-error-boundary/issues/198">#198</a>)</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/23167c532dd6da0b8f106ab6ff8705ff64de81eb"><code>23167c5</code></a>
Relax fallback prop to support broader ReactNode type</li>
<li><a
href="https://github.com/bvaughn/react-error-boundary/commit/4aaf9b023a20fbfda67db74bf550124e8bbfa00c"><code>4aaf9b0</code></a>
chore: update CI workflows version to v4 and node version to 20 (<a
href="https://redirect.github.com/bvaughn/react-error-boundary/issues/194">#194</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/bvaughn/react-error-boundary/compare/4.0.13...4.1.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=react-error-boundary&package-manager=npm_and_yarn&previous-version=4.0.13&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22105?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 15:45:07 +00:00
Abdullah. 20ac0a52bf fix(deps): scope js-yaml to 4.2.0 under the mintlify/verdaccio pinners (#22078)
## Summary

Resolves [Dependabot alert
#1504](https://github.com/twentyhq/twenty/security/dependabot/1504) —
js-yaml **CVE-2026-53550 / GHSA-h67p-54hq-rp68** (quadratic-complexity
DoS in YAML merge-key handling, vulnerable `<=4.1.1`, fixed `4.2.0`) —
by lifting the vulnerable **js-yaml 4.1.1 → 4.2.0**.

## Why scoped resolutions (not a global pin)

- js-yaml 4.1.1 is held alive by **7 packages that hard-pin it exact**
(no caret, still 4.1.1 in their latest):
`@mintlify/{cli,common,prebuild,previewing,scraping,validation}` +
`@verdaccio/config`. No parent upgrade carries the fix, so each is
scoped to 4.2.0 — matching the repo's `parent/child` convention.
- The 5 alert paths (`@graphql-codegen/cli`, `@lingui/cli`,
`@lingui/vite-plugin`, `@wyw-in-js/vite`, `vite-plugin-svgr`) only
*shared* that 4.1.1 via `cosmiconfig` (`^4.1.0`) — once the exact pins
are lifted, they **dedupe onto 4.2.0 on their own**.
- Forcing 4.1.1 → 4.2.0 is a **safe minor** (same 4.x `.load` API; the
fix just bounds merge-key complexity).

## The js-yaml 3.x remnant (deliberately left)

`front-matter@4.0.2` (via mintlify) and
`@istanbuljs/load-nyc-config@1.1.0` (via storybook coverage) declare
`js-yaml ^3.13.1 → 3.14.2`. **front-matter calls the `safeLoad` API that
js-yaml 4.x removed**, so it cannot take 4.2.0 — a global pin would
break it (which is why this is scoped). That 3.x copy is left in place;
both parse only **first-party trusted YAML** (nycrc + docs
front-matter), so the merge-key DoS isn't reachable. If Dependabot still
flags that 3.x copy, it's a dismiss candidate (no safe transitive fix —
front-matter is EOL on the `safeLoad` API).

## Verification

- `yarn install --immutable` passes.
- No `js-yaml@4.1.1` remains; js-yaml is now `4.2.0` (+ the documented
`3.14.2` remnant).
- Diff is js-yaml-only; matching `"//resolutions"` doc entry included.
2026-06-24 18:24:00 +05:00
Abdullah. b7cd6db458 fix(deps): resolve qs to 6.15.2 (dedupe caret group + scope body-parser) (#22050)
## Summary

Closes [Dependabot alert
#1305](https://github.com/twentyhq/twenty/security/dependabot/1305) — qs
**CVE-2026-8723 / GHSA-q8mj-m7cp-5q26** (vulnerable `>=6.11.1 <=6.15.1`,
fixed `6.15.2`) — via two changes:

1. **`yarn dedupe qs`** collapses the caret-range consumers (gitbeaker,
formidable, superagent, googleapis-common, union, body-parser@2.2.2)
from `6.15.0` onto the `6.15.2` already in the tree. Clean, no
resolution.
2. A scoped **`body-parser/qs: 6.15.2`** resolution for the lone
tilde-pinned holdout.

## Why the one resolution

- After the dedupe, the only vulnerable qs left was `6.14.2`, from
**`body-parser@1.20.4`** which declares `qs ~6.14.0` (capped at 6.14.x).
- body-parser **2.x** uses `qs ^6.15.2`, but that needs **express 5** —
and the `body-parser@1.20.4` here comes from **express 4.22.x**, pulled
by `@mintlify/previewing` + verdaccio (build/dev tooling, not bumpable
to express 5).
- So a scoped `body-parser/qs: 6.15.2` is the right fix — qs `6.14 →
6.15` is a compatible minor. It's grouped with the existing `express/qs`
+ `@cypress/request/qs` entries (same CVE, same express-4.x root cause)
in both the `resolutions` block and the `"//resolutions"` doc.

## Verification

- `yarn install --immutable` passes.
- No qs in `[6.11.1, 6.15.1]` remains — all qs is now `6.15.2`.
- `qs` is build/dev tooling here (mintlify, verdaccio, gitbeaker, etc.),
not the production server runtime.
2026-06-24 08:51:19 +02:00
Etienne 0f4c4e69a9 fix(ai-tool): make search_output a raw-text occurrence search (#22034)
## Summary

`search_output` (the spilled-output navigation tool) was built around a
JSON-centric, line-based model that breaks for the data it actually
receives. Spilled outputs are written as compact
`JSON.stringify(output)` (single line, escaped newlines), so the tool's
line-by-line matching collapsed to at most one match, and its schema
described searching "the indented JSON representation" even though it
falls back to raw text for non-JSON. It also ran arbitrary,
model-supplied regexes through the native engine with no ReDoS
protection.

This reworks the tool into a `grep -o` style search over the raw file
bytes: it finds every occurrence of a pattern regardless of newlines and
returns a character window around each hit. It works uniformly for
compact/pretty JSON, CSV, HTML, and plain text.

## Changes

- **Occurrence-based matching** (`search-output.util.ts`): search the
raw content for every match via a global-regex `exec` loop (with a
zero-width-match guard), bounded by `offset + maxMatches`. Results are
now `{ charOffset, match, context }` with a character window around each
occurrence and a centered-ellipsis cap for very long single matches. The
line model (`split`, line numbers, line context) is removed.
- **ReDoS hardening**: matching now uses `re2` (already a dependency)
with the global flag, guaranteeing linear-time matching. Unsupported
regex features (lookahead/backreferences) and invalid patterns fall back
to escaped-literal search instead of throwing.
- **No more reserialization** (`search-output-tool.ts`): the
`JSON.stringify(JSON.parse(...))` round-trip is gone; the tool searches
the exact bytes on disk, so there is no coordinate divergence with
`extract_json_paths`.
- **API** (`search-output-tool.schema.ts`): `contextLines` →
`contextChars` (default 100, max 2000); honest descriptions reflecting
raw-text occurrence search and the regex-or-literal fallback. The result
message reports occurrence counts.
- **Cleanup**: removed unused constants
(`default-search-output-context-lines`,
`search-output-max-line-length`); added
`default-search-output-context-chars` and
`search-output-max-match-length`.

`extract_json_paths` and the spill service are untouched.

## Tradeoff

Results use character offsets/windows rather than line numbers and line
context. For an LLM extracting values from a spilled blob this is more
robust (works on single-line content); the cost is no line-based context
for genuinely line-structured content.

## Test plan

- [x] `search-output.util.spec.ts` rewritten for occurrence semantics:
multiple hits on a single newline-free line, zero-width-pattern
termination, catastrophic-backtracking pattern stays fast (RE2),
lookahead/invalid-regex literal fallback, char-window clipping, offset
pagination, long-match truncation. 12/12 pass.
- [x] `npx nx typecheck twenty-server` clean.
- [x] `npx nx lint:diff-with-main twenty-server` clean (lint + format).

## Deploy note

`re2` is a native addon. It was declared in `package.json` but never
imported/built before this PR, so its binary may be absent in some
environments (local install required `npm rebuild re2`). Confirm the
install/build pipeline (CI, Docker images) compiles native modules so
the tool doesn't throw `Cannot find module 're2.node'` at runtime.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22034?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 17:18:46 +00:00
Abdullah. 9c9041c9f9 fix(deps): bump engine.io + socket.io-adapter to drop vulnerable ws 8.17.1 (#22044)
## Summary

Bumps the transitive **`engine.io`** `6.6.4 → 6.6.9` and
**`socket.io-adapter`** `2.5.5 → 2.5.8` (both within socket.io's
declared ranges — socket.io is pulled by mintlify / react-email build
tooling), which declare `ws ~8.21.0` instead of `~8.17.1`, **evicting
the last vulnerable `ws@8.17.1`**. Resolves two Dependabot alerts:

- [#1502](https://github.com/twentyhq/twenty/security/dependabot/1502)
(high) — GHSA-96hv-2xvq-fx4p, ws memory-exhaustion DoS (`>=8.0.0
<8.21.0`)
- [#1238](https://github.com/twentyhq/twenty/security/dependabot/1238)
(med) — GHSA-58qx-3vcg-4xpx, ws uninitialized memory disclosure
(`>=8.0.0 <8.20.1`)

## Why a parent-bump (not a resolution)

- The only vulnerable ws left was `8.17.1`, pinned by `engine.io@6.6.4`
(`ws ~8.17.1`) and `socket.io-adapter@2.5.5` (`ws ~8.17.1`). (The
earlier koa PR already dropped the dts-plugin `ws@8.18.0`.)
- `engine.io@6.6.9` and `socket.io-adapter@2.5.8` declare `ws ~8.21.0`,
and both bumps are within socket.io's existing ranges — so `yarn up -R`
carries the fix in-range, with no `resolutions` entry to maintain.
- (The pre-existing `@nestjs/graphql/ws: 8.21.0` resolution is unrelated
and untouched.)

## Result

- ws is now `8.21.0` (plus non-vulnerable `7.5.11` / `6.2.4`); nothing
in `[8.0.0, 8.21.0)`.
- `package.json` untouched; engine.io/socket.io are build /
email-preview tooling, not the server runtime.

## Verification

- `yarn install --immutable` passes.
- No vulnerable ws remains in `yarn.lock`; diff is contained to ws /
engine.io / socket.io-adapter (+ a `debug` descriptor cleanup).
2026-06-23 19:17:15 +02:00
Abdullah. 63e258a85c fix(deps): bump @module-federation/node to drop the koa-pinning 0.21.4 stack (#22032)
## Summary

Bumps the transitive **`@module-federation/node`** `2.7.23 → 2.7.45`
(within `@nx/module-federation`'s declared `^2.7.21`), which
consolidates the module-federation stack onto `enhanced 2.6.0` and
**prunes the duplicate 0.21.4 sub-stack that pinned koa 3.0.3** —
resolving [Dependabot alert
#547](https://github.com/twentyhq/twenty/security/dependabot/547):
CVE-2026-27959 / GHSA-7gcc-r8m5-44qm (koa Host Header Injection via
`ctx.hostname`, vulnerable `>=3.0.0 <3.1.2`). Lockfile-only, **no
resolution**.

## Why a parent-bump (not a resolution)

- koa 3.0.3 was pinned **exactly** by
`@module-federation/dts-plugin@0.21.4`. Newer dts-plugin (2.5.1, 2.6.0)
**dropped koa entirely**.
- The old 0.21.4 stack survived only because
`@module-federation/node@2.7.23` declared `@module-federation/enhanced:
0.21.4` (a stale internal pin). `@module-federation/node@2.7.45`
declares `enhanced: 2.6.0`, and `@nx/module-federation@22.7.5` already
requires node `^2.7.21` — so 2.7.45 is in range.
- `yarn up -R @module-federation/node` therefore eliminates the
vulnerable dependency honestly, in-range, with no `resolutions` entry to
maintain.

## Result

- `koa@3.0.3` gone, and with it the entire duplicate
`@module-federation/*@0.21.4` stack — **net −678 lines** of lockfile.
- Bonus: the dts-plugin-pinned `ws@8.18.0` dropped too (the remaining
`ws@8.17.1` comes from socket.io/engine.io — a separate, upcoming fix).
- `package.json` untouched. This is **build-tooling** (module-federation
type generation), not the production server runtime.

## Verification

- `yarn install --immutable` passes.
- `koa` is absent from `yarn.lock`; no
`@module-federation/enhanced@0.21.x` remains.
- The bump stays within `@nx/module-federation`'s declared range —
recommend the CI frontend build as the runtime check for the
module-federation tooling.
2026-06-23 17:49:54 +02:00