8774bf86042a38f61f093df00610dce939fb788b
764 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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. |
||
|
|
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. --> |
||
|
|
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).
|
||
|
|
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. --> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. --> |
||
|
|
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">``<img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg">``</a> |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. --> |
||
|
|
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. |
||
|
|
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. -->
|
||
|
|
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. -->
|
||
|
|
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. --> |
||
|
|
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. |
||
|
|
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. --> |
||
|
|
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. --> |
||
|
|
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. --> |
||
|
|
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). |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. -->
|
||
|
|
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> |
||
|
|
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. --> |
||
|
|
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> |
||
|
|
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 "10.4.5" to "10.4.6" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a> Bump version from "10.4.4" to "10.4.5" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a> Bump version from "10.4.3" to "10.4.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a> Bump version from "10.4.2" to "10.4.3" [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 "10.4.1" to "10.4.2" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/cc19ae1a2145e8f7cda8dc869f1b90d5346dcedb"><code>cc19ae1</code></a> Bump version from "10.4.0" to "10.4.1" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/f8c16d115cfcf0f79125b358266c37e5343bb70d"><code>f8c16d1</code></a> Bump version from "10.4.0-beta.0" to "10.4.0" [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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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 & 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 /> [](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> |
||
|
|
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 "feat(cron): add initialDelay option to defer first job execution"</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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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 "10.4.5" to "10.4.6" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a> Bump version from "10.4.4" to "10.4.5" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a> Bump version from "10.4.3" to "10.4.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a> Bump version from "10.4.2" to "10.4.3" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a> Bump version from "10.4.1" to "10.4.2" [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 /> [](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> |
||
|
|
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 -> 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 -> 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 -> 4.1.0</li> <li><a href="https://github.com/bvaughn/react-error-boundary/commit/206bdbad362737480ebd39cefb945c8cec11c1ce"><code>206bdba</code></a> Upgrade pnpm v8 -> 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 /> [](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> |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. -->
|
||
|
|
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). |
||
|
|
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. |