Commit Graph

715 Commits

Author SHA1 Message Date
Abdullah. 63e258a85c fix(deps): bump @module-federation/node to drop the koa-pinning 0.21.4 stack (#22032)
## Summary

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

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

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

## Result

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

## Verification

- `yarn install --immutable` passes.
- `koa` is absent from `yarn.lock`; no
`@module-federation/enhanced@0.21.x` remains.
- The bump stays within `@nx/module-federation`'s declared range —
recommend the CI frontend build as the runtime check for the
module-federation tooling.
2026-06-23 17:49:54 +02:00
Raphaël Bosi 766d90af7e Remove framer-motion from twenty-ui (#22021)
## What

Removes the `framer-motion` dependency from `twenty-ui` and replaces
every usage with pure CSS animations, reaching for Base UI primitives
where one fits:

- **Collapse/expand** (`AnimatedEaseInOut`,
`AnimatedExpandableContainer`): rebuilt on Base UI `Collapsible`
(CSS-animated `--collapsible-panel-height/width` + transition states).
Public props unchanged, so the ~28 call sites are untouched.
- **ProgressBar**: rebuilt on Base UI `Progress` (proper
`role`/`aria-valuenow`). The snackbar auto-dismiss countdown now uses a
CSS keyframe + `animation-play-state` (pause on hover), removing a
per-frame React re-render; `useProgressAnimation` is deleted.
- The remaining `Animated*` components, the circular spinner, checkmark,
and the placeholder pointer parallax move to plain CSS (SCSS modules +
the `duration()` helper + theme tokens).
- Deletes 3 unused components (`AnimatedTranslation`,
`AnimatedTextWord`, `AnimatedFadeOut`).

## Why

`twenty-ui` is a publicly published library with a size budget, so
dropping framer-motion shrinks what consumers ship. `twenty-front` keeps
its own framer-motion; that is out of scope here.

## Notes for reviewers

- A few `twenty-ui` components received framer props from `twenty-front`
call sites; those were migrated (e.g. `AnimatedLightIconButton` gained a
CSS `rotate` prop, and the `EMPTY_PLACEHOLDER_TRANSITION_PROPS` spreads
were removed).
- Behavior change: Base UI `Collapsible` animates only on open/close
transitions, so the old "animate in on first mount while already open"
case no longer plays (the `initial` prop is kept for API compatibility).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22021?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 17:43:08 +02:00
Abdullah. 11218561d0 fix(deps): pin form-data under nx and zapier-platform-core to 4.0.6 (#22023)
## Summary

Adds two scoped `resolutions` (`nx/form-data` +
`zapier-platform-core/form-data` → `4.0.6`) forcing the lone vulnerable
`form-data@4.0.5` up to the patched `4.0.6`, resolving [Dependabot alert
#1506](https://github.com/twentyhq/twenty/security/dependabot/1506) —
CVE-2026-12143 / GHSA-hmw2-7cc7-3qxx (CRLF injection via unescaped
multipart field names/filenames, vulnerable `>=4.0.0 <4.0.6`).

## Why scoped resolutions (not a parent-bump)

- `form-data@4.0.5` is pinned **exactly** by `nx@22.7.5` (root devDep)
and `zapier-platform-core@19.0.0` (twenty-zapier) — and **both still pin
4.0.5 in their latest release**, so no parent upgrade carries the fix.
- Every *other* form-data consumer already resolves `4.0.6` naturally
via its `^4.0.x` range, so the two scoped pins simply **dedupe**
nx/zapier's copy onto that existing 4.0.6 — no new copy introduced.
- Scoped, not global, to match the existing `express/qs` +
`@cypress/request/qs` two-entry pattern (only form-data 4.x is in the
tree).

## Changes

- `package.json`: the two `resolutions` entries **plus** a matching
`"//resolutions"` doc entry (advisory, why-no-parent-bump, scope
rationale, drop condition).

## Verification

- `yarn install --immutable` passes.
- No form-data in `[4.0.0, 4.0.6)` remains in `yarn.lock`.
2026-06-23 19:40:54 +05:00
Raphaël Bosi 293ff4c462 Auto-generate app cover images from the app logo (#22011)
<img width="1388" height="858" alt="image"
src="https://github.com/user-attachments/assets/59f16bf7-5908-4624-b3af-51416bbebba3"
/>


## What

When an app is built (`twenty build` / `twenty publish`), the SDK now
generates a marketplace cover image and sets it as the app's screenshot,
but only when the app declares a `logoUrl` and has no `screenshots`. The
cover composites the app's logo and the Twenty logo over the branded
halftone backdrop, matching the design reference.

## Why

Most apps ship a logo but no screenshots, so their marketplace detail
page had no hero visual. This gives them a polished cover for free, with
no per-app design work.

## Notes for reviewers

- Generation lives in the build path (`operations/build.ts`), not
`buildManifest`, so `twenty dev` and the shared manifest builder are
untouched. It is best-effort: on failure it logs a warning and the build
continues.
- The cover is written to `.twenty/output` and registered as a public
asset + screenshot, so the existing copy/checksum/serve pipeline handles
it unchanged. No app source files are modified.
- Adds `sharp` as a runtime dependency of `twenty-sdk` (a build-time
tool, like `esbuild`); it is not bundled into built apps.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22011?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 13:41:19 +00:00
Abdullah. 558f2509c2 fix(deps): pin undici under @module-federation/dts-plugin to ^7.28.0 (#22014)
## Summary

Adds a **scoped** `resolutions` entry pinning `undici` under
`@module-federation/dts-plugin` to `^7.28.0`, resolving **6 Dependabot
alerts** — #1523 & #1566 (high), #1522 & #1570 (medium), #1565 & #1572
(low); all `undici >=7.0.0 <7.28.0`.

## Why a scoped resolution (not a parent-bump or a global pin)

- The vulnerable `undici@7.24.7` is pinned **exactly** by the transitive
build tool `@module-federation/dts-plugin@2.5.1`. There's no parent to
bump — its parents pin it and it doesn't loosen the pin at latest — so a
committed scoped resolution (matching the existing `@nestjs/graphql/ws`,
`express/qs` pattern) is the right fix.
- A **global** `undici` resolution would be wrong: the tree also has
`undici@6.27.0` (`^6.25.0`, outside the advisory) and the latest undici
is `8.5.0`, so forcing all undici to 7.x would break the 6.x consumer.
- `^7.28.0` resolves to `7.28.0` (highest 7.x), which **dedupes** with
the `undici@7.28.0` already in the tree (via `^7.25.0`) — no new copy is
introduced.

## Result

- `undici@7.24.7` is gone; the only undici 7.x is now `7.28.0`.
`undici@6.27.0` (6.x) is untouched.
- Build-tooling dependency (module-federation type generation) — not in
the production server runtime; `undici 7.24 → 7.28` is a compatible
minor bump.

## Verification

- `yarn install --immutable` passes (lockfile consistent with CI).
- No undici in `[7.0.0, 7.28.0)` remains in `yarn.lock`.
2026-06-23 15:27:12 +02:00
Abdullah. 6520db22ca fix(deps): bump opentelemetry suite to core 2.8.0 (+ sentry 10.59) (#22010)
## Summary

Bumps the OpenTelemetry suite onto the **`@opentelemetry/core` 2.8.0**
wave (plus Sentry `10.51 → 10.59`, which carries the otel
instrumentation), resolving [Dependabot alert
#1510](https://github.com/twentyhq/twenty/security/dependabot/1510)
(`@opentelemetry/core < 2.8.0`).

## Why a parent-bump, not a `resolutions` entry

The vulnerable `@opentelemetry/core` is transitive, pulled in by the
otel packages we declare (`exporter-metrics-otlp-http`,
`exporter-prometheus`, `sdk-metrics`) **and** by `@sentry/*` (which
bundles `@opentelemetry/instrumentation-*`). The otel **stable**
packages pin `core` to their own exact version and are version-coupled —
forcing `core` ahead of the suite via `resolutions` risks runtime
breakage. So this bumps the declared parents instead.

## Changes

- `twenty-server/package.json`:
  - `@opentelemetry/exporter-metrics-otlp-http` `^0.200.0 → ^0.219.0`
  - `@opentelemetry/exporter-prometheus` `^0.217.0 → ^0.219.0`
  - `@opentelemetry/sdk-metrics` `^2.0.0 → ^2.8.0`
  - `@sentry/{nestjs,node,profiling-node}` `^10.51.0 → ^10.59.0`
- `yarn dedupe` collapses the remaining transitive `core@2.7.1` (caret
consumers) onto `2.8.0` — the whole stable set (`core` / `resources` /
`sdk-trace-base` / `sdk-metrics`) is now `2.8.0`.
- **`@types/pg` added as a direct devDependency.** The newer Sentry
drops the instrumentation that used to *transitively* provide
`@types/pg`; twenty-server imports `pg` directly
(`set-pg-date-type-parser.ts`), so it now declares its own types —
fixing a latent fragility the bump exposed.

## Verification

- `nx typecheck twenty-server` — **0 errors** (validates the otel/sentry
API surface we call is intact).
- `yarn install --immutable` passes.
- No `@opentelemetry/core < 2.8.0` remains.
- Lockfile churn is contained to the observability subtree (otel/sentry
+ their transitive deps; net **−615 lines**).

> Sentry resolved to `10.59.0` rather than the just-published `10.60.0`
due to the repo's `npmMinimalAgeGate`.
> Worth a quick server-boot check during review to confirm Sentry/otel
init at runtime.
2026-06-23 17:32:41 +05:00
Raphaël Bosi 85406a58fb Use minimal babel presets for wyw to fix the website Cloudflare build (#21994)
The website's Cloudflare build (`opennextjs-cloudflare` / Turbopack) was
failing with `_defineProperty is not a function` while linaria/wyw
evaluates `twenty-ui/dist/theme.cjs` at build time. It regressed in
#21946, whose twenty-ui build rework changed the emitted `theme.cjs` so
the theme objects ship as runtime object spreads (`{ ...THEME_COMMON
}`).

**Cause:** wyw evaluates modules in Node through `next/babel`, which
pulls in `preset-env` + `transform-runtime`. Those re-lower the runtime
spreads into `@babel/runtime` helpers imported as ESM; wyw then
`require()`s that ESM module in a CJS context where the export is not
callable, so `_defineProperty` fails.

**Fix:** wyw runs in Node and needs no downleveling, so replace
`next/babel` with minimal presets (`@babel/preset-typescript`,
`@babel/preset-react`, `@wyw-in-js/babel-preset`, plus
`@babel/plugin-transform-export-namespace-from`), matching
twenty-front's wyw config. No `@babel/runtime` helpers get injected.
Kept on the website side so twenty-ui keeps react/react-dom as peer deps
(#21946).

Note: no blocking PR check runs the website production build, so this is
best validated via the website preview build or the twenty-infra deploy.
2026-06-23 13:25:48 +02:00
Etienne 7b45380777 feat(ai): large tool output handling + navigation tools (#21982)
## Summary

Large tool outputs (e.g. a workflow run that serializes to ~70k tokens)
blow the chat context budget and force per-tool "raw" variants. This PR
handles oversized outputs generically in one place:

1. **Producer:** when a tool result exceeds a byte budget, it is spilled
to a `FileFolder.AgentChat` file and replaced with a compact `{ spilled,
outputRef, shape, hint }` envelope.
2. **Consumer:** two bounded, in-server navigation tools —
`extract_json_path` and `search_output` — let the model dig into the
spilled file by `fileId` without spinning up `code_interpreter`.

Together they add a fast, auditable middle tier between "truncated
inline preview" and "full code_interpreter relay," and enable an
enterprise "restricted" mode (spill + navigation, no sandbox).

## Data flow

```mermaid
flowchart TD
  exec["resolveAndExecute / hydrateToolSet closure"] --> compact[compactToolOutput]
  compact --> enabled{"spillLargeOutput enabled? (chat only)"}
  enabled -->|no| inlineRaw["inline raw (MCP, workflow, sandbox bridge)"]
  enabled -->|yes| size{"bytes > MAX_INLINE_TOOL_OUTPUT_BYTES?"}
  size -->|no| inline["inline result"]
  size -->|yes| skeleton["jsonShapeSkeleton + largeOutputHint"]
  skeleton --> write["writeFile(AgentChat)"]
  write --> envelope["return { spilled, outputRef, shape, hint }"]
  envelope --> model[Model]
  model --> nav["extract_json_path / search_output / code_interpreter (by fileId)"]
```

## Part 1 — Navigation tools (consumer)

- `extract_json_path`: extracts a sub-tree from a spilled JSON file by a
JSONPath-lite expression (dot/bracket access, array slicing,
single-level wildcard), with `maxItems`/`maxDepth` bounding. No filters
or recursive descent — those belong to `code_interpreter`.
- `search_output`: grep-like line search with context lines and
stateless `offset` pagination (`{ matches, totalMatches, hasMore }`).
- Both read from `FileFolder.AgentChat` by `fileId`, enforce their own
output byte cap, and are registered in `ActionToolProvider` (always
available; read-only).

## Part 2 — Spill producer

- Spilling slots in right after the existing `compactToolOutput` step at
the two seams in `ToolRegistryService` (`resolveAndExecute` and the
`hydrateToolSet` execute closure).
- `ToolOutputSpillService.spillIfTooLarge()` measures
`Buffer.byteLength`; over `MAX_INLINE_TOOL_OUTPUT_BYTES` (16 KB ≈ 4k
tokens) it writes the full payload and returns the envelope. Spill
failures never block the call (inline + warning).
- `jsonShapeSkeleton` computes a bounded structural map (depth 4, arrays
as `"array[N] of <type>"`, id-keyed maps collapsed, long leaves as size
markers, hard-capped at 1024 bytes) so the model knows the key paths in
one pass.
- Optional per-tool `largeOutputHint` (on the `Tool` type, threaded via
the descriptor) is used as the hint when present, else a generic hint.
The `shape` is always computed generically.

## Surfaces

Spilling is an opt-in flag (`spillLargeOutput`) mirroring
`compactOutput`:

| Surface | `spillLargeOutput` | Behavior |
| --- | --- | --- |
| AI chat / agent | `true` (in `chat-execution.service.ts`) | Spill on;
nav tools + `code_interpreter` in catalog |
| External MCP clients | unset | Raw output |
| Workflow agents | unset | Raw output |
| `code_interpreter` sandbox bridge | unset (it's an MCP call) | Raw
output |

The sandbox bridge inherits "no spill" for free via the MCP path — no
header sniffing, no `ToolContext.source` field.

## Design constraints (anti-micro-OS)

Exactly two navigation tools, no composition/piping, read-only, bounded
output. The boundary is: expressible as a single path lookup or text
search → nav tool; aggregation/correlation/transform →
`code_interpreter`.

## Notes / deviations from the plan

- `jsonShapeSkeleton` and `ToolOutputSpillService` live under the `tool`
module (not `tool-provider/output-transforms`) to avoid a `tool →
tool-provider` import cycle.
- Spill files use `{ isTemporaryFile: false, toDelete: false }` (same as
`code_interpreter`); `isTemporaryFile` here means files-field promotion,
not a TTL.

## Test plan

- [x] `extract-json-path` + `search-output` util unit tests (23 cases)
- [x] `jsonShapeSkeleton` unit tests (6) and `ToolOutputSpillService`
unit tests (4)
- [x] oxlint + oxfmt clean on changed files; `twenty-server` typecheck
clean (pre-existing unrelated errors aside)
- [ ] Manual: trigger an oversized tool result in chat, confirm the
envelope is returned and `extract_json_path` / `search_output` read the
spilled file by `fileId`

## Why no automated e2e

Spilling is chat-only and the chat path runs a live model, so the
black-box MCP integration harness can't deterministically trigger a
spill (MCP intentionally doesn't spill). The seam is small, explicit
flag-threading mirrored on `compactOutput`, covered by the unit suites.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21982?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 10:46:06 +00:00
Abdullah. 84f4ac9082 fix(deps): dedupe esbuild to 0.28.1 (#21993)
## Summary

Dedupes the transitive **esbuild** so the lone `^0.28.0 → 0.28.0` copy
collapses onto the existing `0.28.1`, resolving [Dependabot alert
#1438](https://github.com/twentyhq/twenty/security/dependabot/1438)
(vulnerable range `>=0.27.3 <0.28.1`).

## Details

- `esbuild@^0.28.0` was resolving to `0.28.0`; `0.28.1` is already in
the tree (via `^0.28.1` + existing scoped `esbuild` resolutions), so
`yarn dedupe esbuild` collapses the `^0.28.0` descriptor onto `0.28.1` —
**lockfile-only**, no `package.json` change and no `resolutions` entry.
- The large line count is esbuild's ~25 platform-binary subpackages
(`@esbuild/*@0.28.0`) being pruned as orphans. The diff is
**esbuild-only** (28 removed keys, all `esbuild`/`@esbuild/*`).
- Untouched: `esbuild@0.25.5` and `~0.27.0 → 0.27.2` are outside the
advisory range (`<0.27.3`).

## Verification

- `yarn install --immutable` passes (lockfile consistent with CI).
- No esbuild in `[0.27.3, 0.28.1)` remains in `yarn.lock`.
2026-06-23 10:29:10 +02:00
Abdullah. ec3b9beae5 fix(deps): bump http-proxy-middleware to 2.0.10 (#21992)
## Summary

Bumps the transitive **http-proxy-middleware** `2.0.9` → `2.0.10`,
resolving [Dependabot alert
#1574](https://github.com/twentyhq/twenty/security/dependabot/1574)
(vulnerable range `>=0.16.0 <2.0.10`).

## Details

- The parent's `^2.0.9` range already permits the fix, so this is a
**lockfile-only** bump (`yarn up -R http-proxy-middleware`) — no
`package.json` change and no `resolutions` entry needed.
- The unrelated `http-proxy-middleware@^3.0.5 → 3.0.7` is outside the
advisory range and untouched.
- Transitive **build-tooling** dependency — not part of the production
server runtime; patch-level security fix.

## Verification

- `yarn install --immutable` passes (lockfile consistent with CI).
- No `2.0.9` remnant remains in `yarn.lock`.
2026-06-23 10:17:57 +02:00
Charles Bochet a884945aca fix(deps): remediate HIGH image vulns (multer, ws, nodemailer) (#21984)
## What

Clears the HIGH-severity AWS Inspector findings on the `twenty-server`
container image. All three have stable, in-range fixes — no prereleases.

| Package | From → To | CVE | Path |
|---------|-----------|-----|------|
| multer | 2.1.1 → **2.2.0** (resolution) | CVE-2026-5038, CVE-2026-5079
(DoS) | transitive via `@nestjs/platform-express` |
| ws | 8.20.1 → **8.21.0** (resolution) | CVE-2026-48779 | pinned by
`@nestjs/graphql` (8.21.0 already in tree) |
| nodemailer | 8.0.10 → **9.0.1** | GHSA-p6gq-j5cr-w38f | nested in
`imapflow`; bumped `imapflow` 1.3.6 → 1.4.2 which depends on nodemailer
9.0.1 |

## Notes

- **multer 2.2.0 is the stable fix.** The advisories
([CVE-2026-5038](https://advisories.gitlab.com/npm/multer/CVE-2026-5038/),
[CVE-2026-5079](https://advisories.gitlab.com/npm/multer/CVE-2026-5079/))
list both `2.2.0` and `3.0.0-alpha.2` as fixed; Inspector reported only
the `3.0.0-alpha.2` prerelease, but we stay on the stable 2.x line.
- **nodemailer:** the top-level dep was already `^9.0.1`; only
`imapflow`'s nested copy was stale. imapflow 1.4.0 still ships
nodemailer 8.0.10 and 1.4.1 ships 9.0.0 (< the 9.0.1 fix), so **1.4.2 is
the minimum** that pulls the patched nodemailer.
- Lockfile-only resolution for multer/ws (they're transitive); imapflow
is a direct dep bump. yarn.lock net-shrinks from deduping.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21984?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 00:54:46 +02:00
Raphaël Bosi 8553c574db Improve twenty-ui packaging for standalone publishing (#21946)
Quick packaging wins to move twenty-ui closer to a standalone
publishable library.

- Move `react`/`react-dom` to `peerDependencies` (`^19.0.0`) so
consumers provide a single React and we avoid duplicate-React bugs. They
stay in `devDependencies` for the in-repo build, and `vite.config.ts`
now derives the Rollup `external` list from peer deps too so React stays
externalized instead of bundled.
- Declare `type-fest` in `dependencies`. It was a phantom dep (resolved
only via root hoisting) and its types are referenced by the emitted
json-visualizer `.d.ts`, so standalone consumers need it.
- Move build-only `glob` to `devDependencies` and add `typescript` (both
used only by `generateBarrels.ts`).
- Make `tsconfig.json` self-contained by inlining the base compiler
options, and point the Vite `cacheDir`/`optimizeDeps.exclude` at
package-local paths.

Verified: typecheck, build (React confirmed externalized in `dist`, not
inlined), dts emission, and unit tests all pass.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21946?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-22 15:09:25 +00:00
Abdullah. c171c62099 chore(twenty-server): upgrade typeorm to 0.3.29 (#21957)
## Summary

Upgrades **typeorm `0.3.26` → `0.3.29`** and adapts the twenty-orm
`update`/`upsert` overrides to typeorm's newly-added
`options.returning`. Upgrading to resolve
[this](https://github.com/twentyhq/twenty/security/dependabot/1573)
alert.

## Why

`0.3.29` is the latest release compatible with
`@ptc-org/nestjs-query-typeorm` (peers `typeorm@^0.3.15`; the `1.x` line
has no compatible release, so it's blocked until that dependency moves).

## Changes

**`chore` — bump**
- `typeorm` patch descriptor `0.3.26 → 0.3.29` + `yarn.lock`.
- Local patch carried over **unchanged** (pure rename) — both hunks
(`PickKeysByType` nullable-awareness, `DeleteResult.generatedMaps`) are
still absent upstream in `0.3.29`, so it remains load-bearing.

**`refactor` — adapt overrides**
- `0.3.29` adds `options?: UpdateOptions` (carrying `returning`) to
`EntityManager`/`Repository` `update()`. The override must accept it at
the base-mandated position, so it's added as its **own dedicated
parameter** (not hidden inside `permissionOptions`), honoring
`options.returning` with a fallback to Twenty's permission-aware
`selectedColumns` (`'*'` default).
- The same merge is applied to `upsert()`, which already received
`UpsertOptions` but was dropping its `returning` field — so both write
methods now treat the option identically.
- Internal call sites + specs updated for the new parameter slot.

## Verification

- `nx typecheck twenty-server` — **0 errors**
- twenty-orm unit tests — **191 / 191 pass**
- `oxlint` / `oxfmt` — clean
2026-06-22 16:08:09 +02:00
Raphaël Bosi e0fadfee7c Remove jotai from twenty-ui (#21937)
twenty-ui no longer depends on jotai, so its components work without a
consumer-provided jotai store (better practice for a shared UI library).
twenty-front keeps jotai; this is scoped to the library.

- **Avatar**: tracks image-load failure in local `useState` instead of a
global atom.
- **Icons**: the icon registry moved from a jotai atom to a React
Context. `IconsProvider` and `useIcons` keep identical signatures; the
context itself stays internal.
- Removed the unused `createState` helper, the `invalidAvatarUrlsAtomV2`
/ `iconsState` atoms, and `JotaiRootDecorator`; regenerated barrels and
dropped the `jotai` dependency.

No other package needs changes: nothing imports the removed symbols, and
`twenty-sdk` (which re-exports twenty-ui via `export *`) simply stops
surfacing the two leaked atoms on its next publish.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21937?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-22 13:33:32 +02:00
Abdullah. c8813c3b6a fix(security): drop vulnerable postcss via styled-components bump (XSS) (#21932)
## fix(security): drop vulnerable postcss via styled-components bump
(XSS)

Resolves [Dependabot Alert
#1061](https://github.com/twentyhq/twenty/security/dependabot/1061).

### What

`postcss` `< 8.5.10` is affected by **XSS via an unescaped `</style>` in
its CSS stringify output** (Moderate). Patched in `8.5.10`.

### How — parent-bump, no resolution

The only consumer of the vulnerable `postcss@8.4.49` (exact-pinned) was
`styled-components`, which **dropped the postcss dependency in 6.4.0**.
This bumps `styled-components` `6.1.15`/`6.3.12 -> 6.4.2` within the
existing `^6.1.0` / `^6.1.11` ranges (a minor bump within v6) — removing
`postcss@8.4.49` from the tree **entirely**. The remaining postcss
copies are `8.5.14` / `8.5.15` (both `>= 8.5.10`). No `resolutions`
override.

### Verification

- No `postcss < 8.5.10` resolution remains.
- `styled-components` is not imported directly in twenty-front (used via
`twenty-front-component-renderer` + `@cyntler/react-doc-viewer`);
`typecheck twenty-front-component-renderer` passes.
- Lockfile-only change (styled-components family); `yarn install
--immutable` passes.
2026-06-22 14:02:44 +05:00
Abdullah. bb12f426fd fix(security): bump react-router to 6.30.4 via react-router-dom (open redirect) (#21931)
## fix(security): bump react-router to 6.30.4 via react-router-dom (open
redirect)

Resolves [Dependabot Alert
#1382](https://github.com/twentyhq/twenty/security/dependabot/1382).

### What

`react-router` `>= 6.7.0, < 6.30.4` has an **open redirect**: a
same-origin redirect with a path starting `//` is reinterpreted as a
protocol-relative URL (Moderate). Patched in `6.30.4`.

### How — parent-bump, no resolution

`react-router` is exact-pinned by `react-router-dom`, which is our
**direct** dependency (`^6.4.4` in twenty-front/ui/shared).
`react-router-dom 6.30.4` pins `react-router 6.30.4`, and our range
already permits it — so this refreshes `react-router-dom 6.30.3 ->
6.30.4` within range (and its internal `@remix-run/router` 1.23.2 ->
1.23.3). No `resolutions` override.

### Verification

- No `react-router`/`react-router-dom` `< 6.30.4` resolution remains.
- Patch-level bump; `typecheck twenty-front` passes.
- Lockfile-only change (react-router family only); `yarn install
--immutable` passes.
2026-06-22 10:55:02 +02:00
Abdullah. 6ae2170744 chore(deps): bump wrangler to 4.102.0 and drop the wrangler/esbuild resolution (#21930)
## chore(deps): bump wrangler to 4.102.0 and drop the `wrangler/esbuild`
resolution

Removes a now-redundant `resolutions` override (resolution **cleanup**,
identified by the resolutions audit). It does not close a Dependabot
alert — esbuild stays at `0.28.1` either way — but reduces the standing
override count by one, per the `//resolutions` policy of dropping each
entry once its parent ships a fixed range.

### What

The `wrangler/esbuild: 0.28.1` resolution existed because `wrangler`
exact-pinned a vulnerable esbuild (`0.27.3`). **wrangler 4.102.0 now
ships esbuild `0.28.1` natively**, and our workspaces declare `wrangler
^4.0.0`, so it resolves to the safe version on its own.

### How — parent-bump, then drop the override

- Bumped `wrangler` within `^4.0.0` to `4.102.0` (lockfile-only).
- Removed the `wrangler/esbuild` entry from `resolutions`.
- Updated the `//resolutions` doc: moved wrangler to the "fixed by
parent-bump" list and decremented the esbuild counts (seven → six
resolutions; six → five exact-pin parents).

### Verification

- No `esbuild 0.27.3` regression (wrangler 4.102.0 pins `0.28.1`); the
remaining six esbuild resolutions are unchanged.
- `//resolutions` doc is consistent with the `resolutions` object.
- Lockfile + package.json only; `yarn install --immutable` passes.
2026-06-22 10:26:15 +02:00
Abdullah. e90fb4b55c fix(security): bump dompurify to 3.4.11 (config/hook pollution) (#21905)
## fix(security): bump dompurify to 3.4.11 (config/hook pollution)

Resolves [Dependabot Alert
#1520](https://github.com/twentyhq/twenty/security/dependabot/1520) and
[#1509](https://github.com/twentyhq/twenty/security/dependabot/1509).

### What

`dompurify` is affected by:
- **Permanent `ALLOWED_ATTR` pollution via `setConfig()`**
([#1520](https://github.com/twentyhq/twenty/security/dependabot/1520),
Moderate, `<= 3.4.10`)
- **Trusted Types policy survives `clearConfig()`**
([#1509](https://github.com/twentyhq/twenty/security/dependabot/1509),
Low, `< 3.4.9`)

Both patched in `3.4.11`. Bumps the direct `twenty-server` dep `^3.4.0
-> ^3.4.11`.

### Compatibility

Both advisories are about config/hook state pollution via
`setConfig`/`clearConfig`/hooks. All four of our call sites use plain
`DOMPurify(window).sanitize(...)` with **default config** — no
`setConfig`, `clearConfig`, `addHook`, `ALLOWED_ATTR`, or
`RETURN_TRUSTED_TYPE` — so we are not on the affected path, and the fix
does not change default-`sanitize` behavior.

Verification: `typecheck twenty-server` passes; the
`prepare-file-for-storage`, `create-html-to-text-converter`, and
`email-composer` suites pass (28 tests).

### Verification

- `dompurify` resolves to `3.4.11` (no `<= 3.4.10` remains).
- Lockfile + single package.json pin change; `yarn install --immutable`
passes.
2026-06-21 15:05:17 +02:00
Abdullah. d74b6aeadf fix(security): bump nodemailer to 9.0.1 (raw-option SSRF / file read) (#21903)
## fix(security): bump nodemailer to 9.0.1 (raw-option SSRF / file read)

Resolves [Dependabot Alert
#1518](https://github.com/twentyhq/twenty/security/dependabot/1518) and
[#1519](https://github.com/twentyhq/twenty/security/dependabot/1519).

### What

`nodemailer` `<= 9.0.0` lets the message-level `raw` option bypass
`disableFileAccess`/`disableUrlAccess`, enabling **arbitrary file read**
and **full-response SSRF** in the delivered message ([GHSA
advisory](https://github.com/twentyhq/twenty/security/dependabot/1518),
High). Patched in `9.0.1`.

### How — direct bump, no resolution

- **twenty-server:** `nodemailer ^8.0.5 -> ^9.0.1` (major bump).
- **seed-dependencies:** the application-package template `nodemailer
^8.0.5 -> ^9.0.1`; both `DEFAULT_PACKAGE_JSON_CHECKSUM` and
`DEFAULT_YARN_LOCK_CHECKSUM` regenerated to match the recomputed seed
files (the deps-layer cache key).

### Compatibility — verified nothing breaks

It is a major upgrade, so the 9.0 breaking change was checked against
the current tree. The only behavior change is **stricter TLS validation
when nodemailer fetches remote content** (attachment `href`/`path` URLs,
built-in OAuth2 token endpoints, HTTP/HTTPS proxy `CONNECT`). None of
those paths are reachable here:
- Attachments are passed as **content buffers**, never `path`/`href`.
- Gmail OAuth uses **googleapis**, not nodemailer's built-in OAuth2.
- No proxy on any transport.
- The SMTP socket TLS is governed separately (unchanged).

Verification: `typecheck twenty-server` passes (with `@types/nodemailer
^7.0.3`), and the `email-sender`, `gmail-message-outbound`, and
`imap-smtp-caldav-connection` suites pass (10 tests).

### Not covered (follow-up)

Root alert **#1521** will stay open: `imapflow@1.3.6` exact-pins
`nodemailer@8.0.10`. The clean fix is `imapflow 1.4.2` (which pins
nodemailer `9.0.1`), but it published 2026-06-19 and is **age-gated
until ~2026-06-22** — it will land then as a parent-bump (no
resolution).

### Verification

- `nodemailer` resolves to `9.0.1` for twenty-server; seed lockfile has
`9.0.1`; both seed checksums match the canonical recompute.
- `yarn install --immutable` passes.
2026-06-21 15:05:00 +02:00
Abdullah. a658a8dbb4 fix(security): bump socks to clear vulnerable ip-address (XSS) (#21872) 2026-06-19 19:17:34 +02:00
Abdullah. 8899360ebe fix(security): refresh undici across lockfiles (6.x → 6.27.0, 7.x → 7.28.0) (#21870) 2026-06-19 19:15:47 +02:00
Abdullah. bf2ff5899e fix(security): drop vulnerable serialize-javascript via terser-webpack-plugin bump (#21871)
## fix(security): drop vulnerable serialize-javascript via
terser-webpack-plugin bump

Resolves [Dependabot Alert
#548](https://github.com/twentyhq/twenty/security/dependabot/548) and
[#1290](https://github.com/twentyhq/twenty/security/dependabot/1290).

### What

`serialize-javascript` `< 7.0.5` is affected by:
- **RCE via `RegExp.flags` / `Date.prototype.toISOString`**
([#548](https://github.com/twentyhq/twenty/security/dependabot/548),
High)
- **CPU-exhaustion DoS via crafted array-like objects**
([#1290](https://github.com/twentyhq/twenty/security/dependabot/1290),
Moderate)

### How — parent-bump, no resolution

The only consumer of the vulnerable `serialize-javascript@^6.0.2` in the
tree was `terser-webpack-plugin`, which **removed the
`serialize-javascript` dependency in 5.4.0**. This bumps
`terser-webpack-plugin` `5.3.16 -> 5.6.1` within its existing `^5.3.16`
range — an in-range parent-bump that drops `serialize-javascript` from
the tree **entirely** (preferred over a `resolutions` override).

### Verification

- `serialize-javascript` no longer resolves anywhere in the tree (both
the vulnerable `6.0.2` and the prior `7.0.5` copies are gone).
- `terser-webpack-plugin` is dev/build tooling (webpack minification),
not imported in our source.
- Lockfile-only change (net −22 lines); `yarn install --immutable`
passes.
2026-06-19 22:05:52 +05:00
Félix Malfait adf6eb572b feat(billing): embed Stripe Payment Element in onboarding (#21759)
## What & why

Replaces the hosted Stripe Checkout redirect on the onboarding "Choose
your plan" step (credit-card trial) with an inline Stripe **Payment
Element**, so users never leave the app to enter card details.

## How it works

- **Frontend:** a deferred `<Elements mode="setup">` renders the Payment
Element, themed via the Appearance API. On Continue: `elements.submit()`
→ `checkoutSession` mutation creates the trialing subscription
server-side and returns its pending SetupIntent `clientSecret` →
`stripe.confirmSetup()` confirms the card (handling 3DS) → redirect to
the existing `/plan-required/payment-success`.
- **Backend:** new `BILLING_STRIPE_PUBLISHABLE_KEY` config var exposed
via `/client-config`; the card path creates the subscription with
`payment_behavior: default_incomplete` + a free trial (so Stripe
attaches a `pending_setup_intent`) and returns its client secret. The
hosted-Checkout code path is removed.
- The **no-credit-card** trial path is unchanged.
- Billing address collection is **disabled** in the Payment Element to
reduce friction; `automatic_tax` is correspondingly disabled (tax needs
an address — collect it later, e.g. at conversion / via the billing
portal).

## Required before this works
1. Set `BILLING_STRIPE_PUBLISHABLE_KEY` (`pk_…`) on the server (infra
change pending).
2. Run `nx run twenty-front:graphql:generate --configuration=metadata`
against a server exposing the updated schema (see inline note on the
hand-authored document).
3. Verify in Stripe test mode: happy path, 3DS (`4000 0025 0000 3155`),
a decline.

## Verified
typecheck (front + server), oxlint + oxfmt clean,
`client-config.service.spec` passing. Not run here: the app end-to-end /
Stripe test mode and `graphql:generate` (no server/DB in the dev
container).

I've left self-review comments inline flagging cleanup opportunities
plus a couple of architectural/tech-debt items.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01TxCfinXq7abSrbF7aTw2cA

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

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21759?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: Claude <noreply@anthropic.com>
2026-06-19 11:40:55 +02:00
Abdullah. 569d887d1e [Website] Cut over to the rebuilt site (#21825)
Renaming the package so any further PRs directed to the website are
targeted to the reworked code instead of diverging. Once merged, I will
start preparing this for deployment to dev to test before releasing to
prod. Any improvements will also be applied to this package.

I avoided making significant changes to API routes so nothing breaks,
but will test it thoroughly today to confirm. That said, everything is
ported - double checked.

Big diff PR, impossible to review, but last one! No more rebuilds.
2026-06-19 10:22:46 +02:00
Abdullah. ba7b435885 fix(security): bump webpack-dev-server resolution to 5.2.5 (HMR WS interception) (#21818)
## fix(security): bump webpack-dev-server resolution to 5.2.5 (HMR WS
interception)

Resolves [Dependabot Alert
#1514](https://github.com/twentyhq/twenty/security/dependabot/1514).

### What

`webpack-dev-server` `< 5.2.5` is affected by
[GHSA-mx8g-39q3-5c79](https://github.com/advisories/GHSA-mx8g-39q3-5c79)
(**Moderate**) — HMR WebSocket interception via permissive user proxies.
Patched in `5.2.5`.

### How

`webpack-dev-server` is already force-resolved via a scoped
`resolutions` entry: its sole consumer `@electron-forge/plugin-webpack`
(latest 7.11.2 / 8.x alphas) still declares `webpack-dev-server ^4`, so
the resolution evicts the vulnerable 4.x line up to 5.x. The
newly-disclosed CVE affects the pinned `5.2.4`, so this **bumps the
existing scoped resolution `5.2.4 -> 5.2.5`** and updates its
`//resolutions` doc line — extending an already-documented, load-bearing
entry rather than adding a new one.

**Still-required check:** `@electron-forge/plugin-webpack` still
declares `^4`, so the resolution remains necessary (removing it would
regress to vulnerable 4.x).

### Verification

- `webpack-dev-server` resolves to a single `5.2.5` bucket; no `< 5.2.5`
remains.
- Not imported in our source (electron-forge build tooling only).
- `yarn install --immutable` passes.

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-19 07:17:23 +00:00
Abdullah. 2169e15162 fix(security): patch yaml across both major lines (stack overflow) (#21817)
## fix(security): patch yaml across both major lines (stack overflow)

Resolves [Dependabot Alert
#734](https://github.com/twentyhq/twenty/security/dependabot/734) and
[#697](https://github.com/twentyhq/twenty/security/dependabot/697).

### What

`yaml` is affected by
[GHSA-48c2-rrv3-qjmp](https://github.com/advisories/GHSA-48c2-rrv3-qjmp)
(**Moderate**) — stack overflow via deeply nested YAML collections —
across two major lines:
- **2.x** (`>= 2.0.0, < 2.8.3`, patched `2.8.3`) — alert #734 (runtime).
- **1.x** (`>= 1.0.0, < 1.10.3`, patched `1.10.3`) — alert #697 (dev,
auto-dismissed).

### How

Both vulnerable copies are transitive, and `yaml` is not imported in our
source:
- **2.x:** the `2.8.1` bucket (`^2.0.0` / `^2.4.5`, via `vfile-matter` /
`@mintlify/openapi-parser`) is deduped into the safe `2.9.0` already in
the tree.
- **1.x:** the `1.10.2` bucket (`^1.10.0`, via `cosmiconfig@^7.0.0`) is
refreshed to `1.10.3`.

Both move within ranges the parents already declared — no `resolutions`
override.

### Verification

- No `yaml` `1.x < 1.10.3` or `2.x < 2.8.3` resolution remains.
- `yaml` is not imported in our source (transitive only).
- Lockfile-only change; `yarn install --immutable` passes.
2026-06-19 08:50:17 +02:00
Abdullah. ebdf77075a fix(security): dedupe uuid to 11.1.1 (missing buffer bounds check) (#21815)
## fix(security): dedupe uuid to 11.1.1 (missing buffer bounds check)

Resolves [Dependabot Alert
#1289](https://github.com/twentyhq/twenty/security/dependabot/1289).

### What

`uuid` `< 11.1.1` is affected by
[GHSA-w5hq-g745-h8pq](https://github.com/advisories/GHSA-w5hq-g745-h8pq)
(**Moderate**) — a missing buffer bounds check in `v3`/`v5`/`v6` when a
`buf` argument is provided. Patched in `11.1.1`.

### How

The only vulnerable copy was a transitive `11.1.0` bucket pinned via
`^11.1.0` by `typeorm@0.3.26` and `@recallai/desktop-sdk` — both ranges
already permit `11.1.1`, and a `11.1.1` bucket already existed (our own
packages resolve there). `yarn dedupe uuid` collapses the `^11.1.0`
descriptor into the existing `11.1.1` resolution, removing the
vulnerable copy. No `resolutions` override; the unrelated `13.x` bucket
is left untouched.

### Verification

- No `uuid < 11.1.1` resolution remains.
- Our packages already resolved to `11.1.1`, so compiled output is
unaffected (the change only lifts the transitive `typeorm`/`@recallai`
copy).
- Lockfile-only change (net −9 lines); `yarn install --immutable`
passes.
2026-06-19 08:49:46 +02:00
Abdullah. 6bbd070172 fix(security): bump markdown-it to 14.2.0 (smartquotes ReDoS) (#21814)
## fix(security): bump markdown-it to 14.2.0 (smartquotes ReDoS)

Resolves [Dependabot Alert
#1511](https://github.com/twentyhq/twenty/security/dependabot/1511).

### What

`markdown-it` `<= 14.1.1` is affected by
[GHSA-6v5v-wf23-fmfq](https://github.com/advisories/GHSA-6v5v-wf23-fmfq)
(**Moderate**) — quadratic-complexity DoS in the smartquotes rule via
`replaceAt` string operations. Patched in `14.2.0`.

### How

`markdown-it` is pulled transitively by `@graphiql/react` (`^14.1.0`)
and `prosemirror-markdown` (`^14.0.0`), both of which already permit
`14.2.0`. This refreshes the lockfile resolution `14.1.1 -> 14.2.0`
within the existing range — no `resolutions` override. It is **not**
imported in our source, and the fix is internal to the smartquotes rule
(no public API change).

### Verification

- `markdown-it` resolves to `14.2.0`; no `<= 14.1.1` copy remains.
- Diff limited to `markdown-it` + its own `linkify-it` dep bump.
- Lockfile-only change; `yarn install --immutable` passes.
2026-06-19 08:49:27 +02:00
Abdullah. bebe03e453 fix(security): bump tar to 7.5.16 across lockfiles (PAX file smuggling) (#21813)
## fix(security): bump tar to 7.5.16 across lockfiles (PAX file
smuggling)

Resolves [#1472 1474 1476 1479 1481 1483 1485 1487 1489 1491 1493 1496
1498 1505](https://github.com/twentyhq/twenty/security/dependabot/1472
1474 1476 1479 1481 1483 1485 1487 1489 1491 1493 1496 1498 1505).

### What

`tar` (`node-tar`) `<= 7.5.15` applies a PAX size override to
intermediary GNU long-name/long-link headers, causing a tar-parser
interpretation differential (file smuggling). Patched in `7.5.16`.

### Why these alerts

The advisory is scanned across many independent Yarn projects, so it
surfaced as one alert per lockfile: the root `yarn.lock` plus 13
`packages/twenty-apps/**` lockfiles (each pulls `tar` transitively).

### How

- Refreshed `tar` to `7.5.16` in the root and all 13 app lockfiles —
they hold `tar` via `^7.5.x` ranges that already permit it, so this is
an in-range lockfile refresh (no override) via `yarn up -R tar`.
- The root additionally had `tar@7.5.15` exact-pinned by
`@mintlify/previewing`, which has **no upstream fix** (latest `4.0.1163`
still pins `7.5.15`). Added a scoped resolution
`@mintlify/previewing/tar -> ^7.5.16`, **extending the existing scoped
tar resolutions** already used for `@electron/rebuild` and
`@electron/node-gyp`.

### Not included

`seed-dependencies/yarn.lock` (alert #1500) is intentionally excluded:
that lockfile and its checksum constants are already modified by the
open form-data PR, so its `tar` bump will follow separately to avoid a
conflict.

### Verification

- No `tar <= 7.5.15` remains across the root or any app lockfile.
- `yarn install --immutable` passes.
2026-06-19 08:49:07 +02:00
Abdullah. e2df785aec fix(security): bump http-proxy-middleware to 3.0.7 (multipart field injection) (#21812)
## fix(security): bump http-proxy-middleware to 3.0.7 (multipart field
injection)

Resolves [Dependabot Alert
#1517](https://github.com/twentyhq/twenty/security/dependabot/1517).

### What

`http-proxy-middleware` `3.0.4 – 3.0.6` is affected by
[GHSA-gcq2-9pq2-cxqm](https://github.com/advisories/GHSA-gcq2-9pq2-cxqm)
(**High**) — multipart/form-data field injection via unescaped CRLF in
`fixRequestBody`. Patched in `3.0.7` for the 3.x line.

### How

`http-proxy-middleware` is pulled transitively by
`@nx/module-federation` and `@nx/react` via `^3.0.5`, which already
permits `3.0.7`. This refreshes the stale lockfile resolution `3.0.5 →
3.0.7` within the existing range — no `resolutions` override needed. The
separate `2.0.9` bucket (from `webpack-dev-server`) is outside the
advisory's `>= 3.0.4` range and is left unchanged.

### Verification

- No `http-proxy-middleware` copy in the vulnerable `3.0.4 – 3.0.6`
range remains; the 3.x bucket resolves to `3.0.7`.
- Diff is limited to the resolved version + checksum.
- Lockfile-only change; `yarn install --immutable` passes.
2026-06-19 08:48:47 +02:00
Abdullah. 2eef2f12be fix(security): bump protobufjs to 7.6.4 (DoS + property shadowing) (#21811)
## fix(security): bump protobufjs to 7.6.4 (DoS + property shadowing)

Resolves [Dependabot Alert
#1508](https://github.com/twentyhq/twenty/security/dependabot/1508) and
[#1507](https://github.com/twentyhq/twenty/security/dependabot/1507).

### What

`protobufjs` in the 7.x line is affected by two advisories:
-
[GHSA-wcpc-wj8m-hjx6](https://github.com/advisories/GHSA-wcpc-wj8m-hjx6)
(**High**,
[#1508](https://github.com/twentyhq/twenty/security/dependabot/1508)) —
DoS through unbounded `Any` expansion during JSON conversion. Patched in
`7.6.1`.
-
[GHSA-f38q-mgvj-vph7](https://github.com/advisories/GHSA-f38q-mgvj-vph7)
(**Moderate**,
[#1507](https://github.com/twentyhq/twenty/security/dependabot/1507)) —
schema-derived names can shadow runtime-significant properties. Patched
in `7.6.3`.

### How

`protobufjs` is pulled transitively via `^7.3.0`, which already permits
the patched releases. This refreshes the stale lockfile resolution
`7.6.0 → 7.6.4` (the latest `7.x`; `>= 7.6.3` covers both advisories)
within the existing range — no `resolutions` override needed. The `8.x`
ranges in these advisories do not apply.

### Verification

- `protobufjs` resolves to a single `7.6.4` bucket (`>= 7.6.1` and `>=
7.6.3`), clearing both alerts.
- Diff is limited to the protobufjs family (`protobufjs` + its
`@protobufjs/*` utility deps).
- Lockfile-only change; `yarn install --immutable` passes.
2026-06-19 08:48:24 +02:00
Abdullah. da49ed81e4 fix(security): bump piscina to 4.9.3 (prototype pollution → RCE) (#21810)
## fix(security): bump piscina to 4.9.3 (prototype pollution → RCE)

Resolves [Dependabot Alert
#1515](https://github.com/twentyhq/twenty/security/dependabot/1515).

### What

`piscina` `<= 4.9.2` is affected by
[GHSA-x9g3-xrwr-cwfg](https://github.com/advisories/GHSA-x9g3-xrwr-cwfg)
/ CVE-2026-55388 — a **prototype-pollution gadget enabling RCE via
inherited `options.filename`** (High). For the 4.x line, the first
patched version is `4.9.3`.

### How

`piscina` is pulled transitively by `@swc/cli@0.8.1` via `^4.3.1`, which
already permits `4.9.3`. This refreshes the stale lockfile resolution
`4.9.2 → 4.9.3` within the existing range — no `resolutions` override
needed.

### Verification

- `piscina` resolves to a single `4.9.3` bucket; no `<= 4.9.2` copy
remains.
- Diff is limited to piscina's resolved version + checksum (its
dependency set is unchanged).
- Lockfile-only change; `yarn install --immutable` passes.
2026-06-19 08:47:49 +02:00
Abdullah. d205c72fa2 fix(security): remove vulnerable lodash 4.17.23 (code injection + prototype pollution) (#21809)
## fix(security): remove vulnerable lodash 4.17.23 (code injection +
prototype pollution)

Resolves [Dependabot Alert
#824](https://github.com/twentyhq/twenty/security/dependabot/824) and
[#823](https://github.com/twentyhq/twenty/security/dependabot/823).

### What

`lodash` `<= 4.17.23` is affected by:
- **Code injection via `_.template`**
([#824](https://github.com/twentyhq/twenty/security/dependabot/824),
High)
- **Prototype pollution via `_.unset`/`_.omit`**
([#823](https://github.com/twentyhq/twenty/security/dependabot/823),
Medium)

Both are patched in `4.18.0`. The repo already resolved lodash to
`4.18.1` everywhere **except** one copy held at `4.17.23` by
`@stoplight/spectral-functions@1.10.1`, whose `~4.17.21` range capped
lodash below `4.18.0`.

### How

Instead of a standing `resolutions` override, this bumps the parent that
imposed the cap: **`@stoplight/spectral-functions` 1.10.1 → 1.10.3**
(pulled transitively via `@asyncapi/parser` ← `@mintlify/common`,
accepted through `^1.7.2`). 1.10.3 widened its lodash dependency to
`^4.18.1`, so the capped bucket collapses into the existing `4.18.1`
resolution and the vulnerable copy is removed — leaving the dependency
graph honest with no lingering override.

### Also

Refreshes `@types/lodash` to the latest **4.17.24**: bumps the
`twenty-client-sdk` pin `^4.17.15 → ^4.17.24` and dedupes the stale
transitive `*` bucket (4.17.15) into a single `4.17.24` resolution.
Type-stub only.

### Verification

- The only real `lodash` resolution is now `4.18.1` (remaining `4.17.x`
entries are `@types/lodash` type stubs, not the library);
`@types/lodash` resolves to a single `4.17.24` bucket.
- Lockfile-only dependency change; `yarn install --immutable` passes;
`twenty-client-sdk` typecheck passes.
2026-06-19 08:47:11 +02:00
Abdullah. 26b4d6caed fix(security): bump form-data to 4.0.6 (CRLF injection) (#21808)
Resolves [Dependabot Alert
#1473](https://github.com/twentyhq/twenty/security/dependabot/1473),
[#1475](https://github.com/twentyhq/twenty/security/dependabot/1475),
[#1477](https://github.com/twentyhq/twenty/security/dependabot/1477),
[#1478](https://github.com/twentyhq/twenty/security/dependabot/1478),
[#1480](https://github.com/twentyhq/twenty/security/dependabot/1480),
[#1482](https://github.com/twentyhq/twenty/security/dependabot/1482),
[#1484](https://github.com/twentyhq/twenty/security/dependabot/1484),
[#1486](https://github.com/twentyhq/twenty/security/dependabot/1486),
[#1488](https://github.com/twentyhq/twenty/security/dependabot/1488),
[#1490](https://github.com/twentyhq/twenty/security/dependabot/1490),
[#1492](https://github.com/twentyhq/twenty/security/dependabot/1492),
[#1494](https://github.com/twentyhq/twenty/security/dependabot/1494),
[#1495](https://github.com/twentyhq/twenty/security/dependabot/1495),
[#1497](https://github.com/twentyhq/twenty/security/dependabot/1497),
[#1499](https://github.com/twentyhq/twenty/security/dependabot/1499),
[#1501](https://github.com/twentyhq/twenty/security/dependabot/1501) and
[#1506](https://github.com/twentyhq/twenty/security/dependabot/1506).
2026-06-19 08:46:32 +02:00
Abdullah. b14da2f9e8 [Website] Port partner application form rework (required fields, skills, fail-fast) (#21802)
Ports twenty-website PR #21710 (Rashad) into `twenty-website-redone`.
The old site's partner application form was reworked last week —
required fields, a skills rethink, and fail-fast validation — after the
redone had already ported the form, so the redone was running the
pre-rework behavior. This brings it to parity.
  
Re-derived into the redone's own conventions rather than copied: it
reuses the redone's `STEP_REQUIRED_FIELDS`/`STEP_FORMAT_CHECKS`
validator, keeps one-export-per-file, and injects the new `searchPool`
as an opt-in prop.
2026-06-18 20:43:24 +02:00
Rashad Karanouh 7afc991bd6 Partner application form: required fields, skills rework, fail-fast validation (#21710)
## Summary (twenty-website — partner application form)

- **Required fields**: website URL, city, hourly rate, minimum project
are now required (client step-gate + server zod) with `*` markers. The
final step validates before POSTing, so empty required fields fail fast
client-side instead of round-tripping.
- **Technical skills reworked to *complement* "What you cover"** (the
service categories) rather than duplicate them — now a small shown set +
a larger searchable-only pool of tools / technologies / industries.
Field hint clarifies the intent.
- **No competitor CRMs** in suggestions (Salesforce/HubSpot/Attio
removed); a guard test fails if one ever reappears. Migrations surface
as a generic "CRM migration".
- `Form.TagInput` gains an optional `searchPool` prop (autocomplete-only
entries, not rendered as chips).

Companion to the app-side PR #21709.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21710?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 14:29:35 +00:00
Abdullah. 0f4cb2c2c2 [Website] Full-bleed hero/testimonials, nav restructure, OpenNext deploy config (#21794)
### Full-bleed backgrounds on wide screens

Decorative section backgrounds were capped at the 1512px content width,
leaving large empty gutters on ultra-wide viewports.
- Added an opt-in `fullBleedBackground` prop to `SectionShell` that
lifts the background layer off the content-width cap (default unchanged,
so every other section is untouched).
- Applied it to `HomeHero` (bridge halftone field) and both testimonials
sections.
- Capped the `NotchedCardShape` notch at its width at the content cap,
so the white/dark card can span the full viewport while the notch stays
fixed and centered. The footer and any other capped card are unaffected.

<img width="3024" height="1718" alt="image"
src="https://github.com/user-attachments/assets/a2200677-58af-4740-9257-77f6385ade28"
/>

<img width="3024" height="1224" alt="image"
src="https://github.com/user-attachments/assets/73aa6745-b766-405e-b736-8c0c7591232e"
/>

### Navigation restructure
- Removed **Product** from the menu and footer nav, and promoted **Why**
out of the Resources dropdown to a top-level item in Product's place.
(The Product page itself is unchanged).
- Resources dropdown polish: tightened the preview frame height now that
the list is shorter; restored the cleaner/brighter User Guide and
Developers preview assets from `twenty-website`; gave User Guide a
center + 2× image scale so its halftone fills the frame like Developers,
and raised `NextImage` `sizes` to keep the fine halftone crisp through
that magnification.
- Restored the **current-page highlight** in the Resources dropdown
(active icon/label in highlight blue + marker bar), matching the old
`NavDropdown`.

<p>
<img width="1509" height="323" alt="image"
src="https://github.com/user-attachments/assets/d5702761-31f5-4b4d-9fcc-c33d5c7ae6ab"
/>
</p>

### OpenNext / Cloudflare deployment config
Ported the Cloudflare Workers deployment setup from `twenty-website` so
the same CI/deploy pipeline works against the redone package:
- `open-next.config.ts` (R2 incremental cache + regional cache + skew
protection), `wrangler.jsonc` (dev/prod envs — **worker names, routes,
R2 buckets kept identical** for a seamless cutover),
`initOpenNextCloudflareForDev()` in `next.config.ts`, the
`preview`/`deploy:*`/`cf-typegen` scripts, the `@opennextjs/cloudflare`
+ `wrangler` devDependencies, a `.dev.vars.example` template, and the
relevant `.gitignore` entries.
2026-06-18 19:29:21 +05:00
Etienne c6309fd92b feat(workflow): auto-layout steps on AI workflow creation via shared tidy-up (#21756)
## Context

The workflow builder has a "Tidy up" action that auto-positions steps
using a
Dagre layout. However, this lived entirely in the frontend and depended
on node
dimensions measured by React Flow after rendering in the browser.

As a result, workflows (and steps) created through AI Chat / MCP tools
were never
laid out: `create_complete_workflow` accepted optional `stepPositions`
that the
LLM had to invent, and `create_workflow_version_step` stored an optional
position
verbatim. In practice this produced overlapping / poorly positioned
steps.

## What this does

Extracts the tidy-up layout into a pure, frontend-free util in
`twenty-shared` and
reuses it from both the frontend tidy-up and the server, so
AI/MCP-created
workflows are auto-laid out at creation time.

### twenty-shared
- New `computeWorkflowLayout({ nodes, edges, options? })` — a pure Dagre
layout over
a minimal `{ id, width, height }` / `{ source, target }` graph,
returning
top-left-anchored positions (matching React Flow). Ignores edges
pointing to
  unknown nodes.
- New constants: `WORKFLOW_LAYOUT_DEFAULT_OPTIONS`
(ranksep/nodesep/rankdir) and
`WORKFLOW_DIAGRAM_DEFAULT_NODE_DIMENSIONS` (estimated node size for
server-side
  layout, where measured sizes are unavailable).
- Added `@dagrejs/dagre` dependency.

### twenty-front
- `getOrganizedDiagram` now delegates to `computeWorkflowLayout`,
passing real
  measured node sizes. No behavior change for users.

### twenty-server
- New `WorkflowVersionWorkspaceService.autoLayoutWorkflowVersion(...)`
builds the
graph topology via the existing `buildWorkflowGraph` (covers if-else
branches and
iterator loops), feeds estimated node sizes into
`computeWorkflowLayout`, and
  persists through the existing `updateWorkflowVersionPositions`.
- `create_complete_workflow`: removed `stepPositions` from the tool
schema; the
  server always auto-lays out after creation/edges.
- `create_workflow_version_step`: re-tidies the whole version after each
added step
(wired at the tool level so the builder UI is unaffected) and dropped
the now
  redundant `position` field.

## Notes
- Server-side layout uses estimated node sizes, so it is "good enough";
opening the
workflow and running the existing FE tidy-up refines it with real
measured sizes.
- Auto-layout is wired in the MCP tools, not in the shared creation
service, so
  manual step creation in the builder UI is unchanged.

## Test plan
- [x] `twenty-shared` unit tests for `computeWorkflowLayout` (linear
chain, if-else
  spread, dangling-edge safety)
- [x] `twenty-shared` builds; `twenty-server` and `twenty-front`
typecheck
- [x] Lint/format clean on changed files
- [ ] Create a workflow via AI Chat / MCP and confirm steps are laid out
without
  overlap
- [x] Add a step via MCP and confirm the version is re-tidied
- [ ] Frontend "Tidy up" still behaves as before

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21756?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 14:10:04 +00:00
Abdullah. 465eb05aaf Reworked website. (#21763)
twenty-website had accumulated structural problems that were cheaper to
fix by rebuilding than to refactor in place:
  
- Drift had no guardrails. Values were matched at call sites instead of
single-sourced, so things silently diverged — e.g. the radius token base
was wrong for days (every radius() consumer rendered double) because
nothing measured it against the old site's CSS variables.
- A whole tree escaped quality checks. src/lib/ (~9.8k lines) was never
format-checked, because oxfmt silently ignores directories named lib/.
- Inconsistent rhythm. Hero spacing varied 24–88px between pages
(CEO-flagged), because section spacing wasn't a token.
- Over-extraction. -config.ts sprawl pulled single-component
configuration out into the wrong place.
  
The goal: a ground-up rebuild where drift is structurally impossible,
held to a Linear / Railway / Notion / Attio quality bar. The old site is
treated as source of intent only — nothing is blindly ported; every
piece is re-decided and A/B-verified.

**Rebuild**
  
A full rebuild on Next 16 + Turbopack + Linaria (zero-runtime CSS),
~1,100 files. Marketing pages (home, product, pricing, partners +
marketplace, customers/case-studies, why-twenty, releases, legal), the
interactive AppPreview product mockup, the platform/visuals WebGL system
(engine + rigs, three code-split off every initial chunk), and the
standalone /halftone studio (the dev tool that generates the site's
halftone art — engine, exporters, and full UI ported as an isolated
island).
  
**Architecture & guarantees**
  
- Parity by construction. src/tokens/definitions.ts is the only file
with raw values; the :root CSS-variable block is generated from it at
build time and accessors derive var names through the same helpers —
derived alpha tokens appear in served CSS without ever being
hand-written.
- Mobile-first by API shape. mediaUp() is the only media helper (no
max-width helper exists, on purpose).
- Section rhythm is a token (RHYTHM.section) — the hero-spacing
inconsistency class is fixed by construction.
- Fluid type ramps interpolate font-size and line-height between
designed endpoints [390px → md]; TYPE_SCALE is the single source.
- three.js never enters an initial chunk — confined to platform/visuals
heavy zones, reached only via dynamic(ssr:false), enforced by
check-visual-bundle.
2026-06-18 11:55:24 +02:00
dependabot[bot] 1486203271 chore(deps): bump mintlify from 4.2.595 to 4.2.629 (#21762)
Bumps
[mintlify](https://github.com/mintlify/mint/tree/HEAD/packages/mintlify)
from 4.2.595 to 4.2.629.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/mintlify/mint/commits/HEAD/packages/mintlify">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mintlify&package-manager=npm_and_yarn&previous-version=4.2.595&new-version=4.2.629)](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/21762?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 11:25:02 +02:00
dependabot[bot] cf5166f7c5 chore(deps-dev): bump @electron-forge/maker-zip from 7.11.1 to 7.11.2 (#21761)
Bumps [@electron-forge/maker-zip](https://github.com/electron/forge)
from 7.11.1 to 7.11.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/electron/forge/releases">@​electron-forge/maker-zip's
releases</a>.</em></p>
<blockquote>
<h2>v7.11.2</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump actions/cache from 5.0.1 to 5.0.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4135">electron/forge#4135</a></li>
<li>build(deps): bump electron/github-app-auth-action from 1.1.1 to
2.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4137">electron/forge#4137</a></li>
<li>build(deps): bump actions/setup-node from 6.1.0 to 6.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4138">electron/forge#4138</a></li>
<li>build(deps): bump actions/checkout from 6.0.1 to 6.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4139">electron/forge#4139</a></li>
<li>build(deps): bump actions/stale from 10.1.0 to 10.1.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4136">electron/forge#4136</a></li>
<li>build(deps): bump lodash from 4.17.21 to 4.17.23 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4145">electron/forge#4145</a></li>
<li>build(deps): bump webpack from 5.94.0 to 5.104.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4140">electron/forge#4140</a></li>
<li>build(deps): bump lodash from 4.17.21 to 4.17.23 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4146">electron/forge#4146</a></li>
<li>build(deps): bump actions/setup-python from 6.1.0 to 6.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4153">electron/forge#4153</a></li>
<li>build(deps): bump actions/download-artifact from 7.0.0 to 8.0.0 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4154">electron/forge#4154</a></li>
<li>build(deps): bump actions/stale from 10.1.1 to 10.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4152">electron/forge#4152</a></li>
<li>build(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4151">electron/forge#4151</a></li>
<li>build(deps): bump rollup from 4.53.3 to 4.59.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4156">electron/forge#4156</a></li>
<li>build(deps): upgrade aws-sdk in lockfile by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4155">electron/forge#4155</a></li>
<li>build(deps): bump lodash from 4.17.21 to 4.17.23 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4157">electron/forge#4157</a></li>
<li>build: isolate yarn cache when running verdaccio by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4162">electron/forge#4162</a></li>
<li>build(deps): bump flatted from 3.2.7 to 3.4.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4180">electron/forge#4180</a></li>
<li>ci: auto-label <code>next</code> PRs by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4187">electron/forge#4187</a></li>
<li>test: use yarn instead of npx in cli spec by <a
href="https://github.com/MarshallOfSound"><code>@​MarshallOfSound</code></a>
in <a
href="https://redirect.github.com/electron/forge/pull/4193">electron/forge#4193</a></li>
<li>chore: update funding sources by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4199">electron/forge#4199</a></li>
<li>ci: fix zizmor audit findings by <a
href="https://github.com/MarshallOfSound"><code>@​MarshallOfSound</code></a>
in <a
href="https://redirect.github.com/electron/forge/pull/4200">electron/forge#4200</a></li>
<li>build(deps-dev): bump electron from 39.2.6 to 39.8.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4202">electron/forge#4202</a></li>
<li>chore: replace lodash with eta for config templating by <a
href="https://github.com/MarshallOfSound"><code>@​MarshallOfSound</code></a>
in <a
href="https://redirect.github.com/electron/forge/pull/4208">electron/forge#4208</a></li>
<li>build(deps): bump axios from 1.12.2 to 1.14.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4211">electron/forge#4211</a></li>
<li>build(deps): bump dsanders11/github-app-commit-action from 1.5.0 to
2.1.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4197">electron/forge#4197</a></li>
<li>build(deps): bump axios from 1.14.0 to 1.15.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4216">electron/forge#4216</a></li>
<li>build(deps): bump <code>@​xmldom/xmldom</code> from 0.8.10 to 0.8.12
by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4231">electron/forge#4231</a></li>
<li>build(deps): bump follow-redirects from 1.15.6 to 1.16.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4233">electron/forge#4233</a></li>
<li>fix(cli): allow pre-release package manager ranges by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4242">electron/forge#4242</a></li>
<li>build(deps): bump axios from 1.15.0 to 1.15.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4252">electron/forge#4252</a></li>
<li>build(deps): bump postcss from 8.5.6 to 8.5.13 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4253">electron/forge#4253</a></li>
<li>build(deps): bump <code>@​xmldom/xmldom</code> from 0.8.12 to 0.8.13
by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4254">electron/forge#4254</a></li>
<li>fix(cli): detect TTY for interactive mode instead of hardcoding true
by <a
href="https://github.com/RobertWHurst"><code>@​RobertWHurst</code></a>
in <a
href="https://redirect.github.com/electron/forge/pull/4219">electron/forge#4219</a></li>
<li>build(deps): bump actions/setup-node from 6.2.0 to 6.4.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4257">electron/forge#4257</a></li>
<li>build(deps): audit clearing by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4243">electron/forge#4243</a></li>
<li>build(deps): bump fast-uri from 3.1.0 to 3.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4261">electron/forge#4261</a></li>
<li>build(deps): bump ip-address from 10.0.1 to 10.1.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/electron/forge/pull/4246">electron/forge#4246</a></li>
<li>chore: bump version to 7.11.2 by <a
href="https://github.com/erickzhao"><code>@​erickzhao</code></a> in <a
href="https://redirect.github.com/electron/forge/pull/4262">electron/forge#4262</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/RobertWHurst"><code>@​RobertWHurst</code></a>
made their first contribution in <a
href="https://redirect.github.com/electron/forge/pull/4219">electron/forge#4219</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/electron/forge/compare/v7.11.1...v7.11.2">https://github.com/electron/forge/compare/v7.11.1...v7.11.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/electron/forge/commit/f2a3ec8aa9c836aff95fcd83ce9c99842f0cda8a"><code>f2a3ec8</code></a>
chore: bump version to 7.11.2 (<a
href="https://redirect.github.com/electron/forge/issues/4262">#4262</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/c57487cb840bbcac3578024cfc10fb2493b92f93"><code>c57487c</code></a>
build(deps): bump ip-address from 10.0.1 to 10.1.1 (<a
href="https://redirect.github.com/electron/forge/issues/4246">#4246</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/aa6e75d7b26ce0f8d0312bedb47fc6ef1789b20a"><code>aa6e75d</code></a>
build(deps): bump fast-uri from 3.1.0 to 3.1.2 (<a
href="https://redirect.github.com/electron/forge/issues/4261">#4261</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/c6d261414ddbab597262580910381dcc57a15c51"><code>c6d2614</code></a>
build(deps): audit clearing (<a
href="https://redirect.github.com/electron/forge/issues/4243">#4243</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/aacc96df9dd4bd531a72baffd6d93339ecff8291"><code>aacc96d</code></a>
build(deps): bump actions/setup-node from 6.2.0 to 6.4.0 (<a
href="https://redirect.github.com/electron/forge/issues/4257">#4257</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/2a8c9aded04dce4a47379e1f0337a5e12a7a1b65"><code>2a8c9ad</code></a>
fix(cli): detect TTY for interactive mode instead of hardcoding true (<a
href="https://redirect.github.com/electron/forge/issues/4219">#4219</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/9b4be2dab26090805c35b0e22ba15391706d453a"><code>9b4be2d</code></a>
build(deps): bump <code>@​xmldom/xmldom</code> from 0.8.12 to 0.8.13 (<a
href="https://redirect.github.com/electron/forge/issues/4254">#4254</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/9a6f204f5e0727715c902880e3e8620ccd6d8a6d"><code>9a6f204</code></a>
build(deps): bump postcss from 8.5.6 to 8.5.13 (<a
href="https://redirect.github.com/electron/forge/issues/4253">#4253</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/a59d64c28ac5ad5344969c857c8abe64166a1d74"><code>a59d64c</code></a>
build(deps): bump axios from 1.15.0 to 1.15.2 (<a
href="https://redirect.github.com/electron/forge/issues/4252">#4252</a>)</li>
<li><a
href="https://github.com/electron/forge/commit/0c38d7666bd52121e289ce9849cc01d02d7e7f43"><code>0c38d76</code></a>
fix(cli): allow pre-release package manager ranges (<a
href="https://redirect.github.com/electron/forge/issues/4242">#4242</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/electron/forge/compare/v7.11.1...v7.11.2">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 11:23:57 +02:00
dependabot[bot] 8d6275260d chore(deps-dev): bump @babel/core from 7.28.0 to 7.29.7 (#21760)
Bumps
[@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core)
from 7.28.0 to 7.29.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases">@​babel/core's
releases</a>.</em></p>
<blockquote>
<h2>v7.29.7 (2026-05-25)</h2>
<p>Re-release all packages with npm provenance attestations</p>
<h2>v7.29.6 (2026-05-25)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18014">#18014</a>
Catchup source map position in preserveFormat (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18001">#18001</a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>, <code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17998">#17998</a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 3</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Mateusz Burzyński (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<h2>v7.29.5 (2026-05-05)</h2>
<h4>🏠  Internal</h4>
<ul>
<li><code>babel-preset-env</code>
<ul>
<li>Update <code>@babel/*</code> dependencies</li>
</ul>
</li>
</ul>
<h2>v7.29.4 (2026-05-05)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-plugin-transform-modules-systemjs</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17974">#17974</a>
[7.x backport]fix(systemjs): improve module string name support (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 1</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
<h2>v7.29.3 (2026-04-30)</h2>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17923">#17923</a>
Support flow extends bound (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-helper-create-class-features-plugin</code>,
<code>babel-plugin-proposal-decorators</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17931">#17931</a>
fix(decorators): replace super within all removed static elements (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-register</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17915">#17915</a> Fix
thread synchronization issues in <code>@babel/register</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-compat-data</code>,
<code>babel-plugin-bugfix-safari-rest-destructuring-rhs-array</code>,
<code>babel-preset-env</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17788">#17788</a> Add
bugfix plugin for Safari array rest destructuring bug (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-parser</code></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/babel/babel/commit/4fba7541180bf5f58256d8e358b544e3831ad090"><code>4fba754</code></a>
v7.29.7</li>
<li><a
href="https://github.com/babel/babel/commit/04ea6b27fdac8f40c3481aec2080ac9678779509"><code>04ea6b2</code></a>
v7.29.6</li>
<li><a
href="https://github.com/babel/babel/commit/99f498a9b9fa0b900d603fbe8f6601bb3b9e42bb"><code>99f498a</code></a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/18001">#18001</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/feba0a3654c596bd369d1ef1231f5d56666d56dc"><code>feba0a3</code></a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17998">#17998</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/aa8394e454337d118ac3d40bfa3ee1a3cb3f3ed2"><code>aa8394e</code></a>
v7.29.0</li>
<li><a
href="https://github.com/babel/babel/commit/ad0d03f0c92404a60ec6b1c12f15febd38e2397a"><code>ad0d03f</code></a>
[7.x backport] feat: Allow specifying startLine in code frame (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17739">#17739</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/d7f400889567ae18ef9ac41b024b5120f6060e17"><code>d7f4008</code></a>
v7.28.6</li>
<li><a
href="https://github.com/babel/babel/commit/e130225028e93e106135586f344cfa44c4aac847"><code>e130225</code></a>
Polish(standalone): improve message on invalid preset/plugin (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17606">#17606</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/99dcba5e71de3bd81ce14077cfa5b6df58e9b177"><code>99dcba5</code></a>
chore: enable some ts-eslint rules (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17592">#17592</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/c92c4919771105140015167f25f7bacac77c90d9"><code>c92c491</code></a>
Improve Unicode handling in code-frame tokenizer (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17589">#17589</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/babel/babel/commits/v7.29.7/packages/babel-core">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​babel/core</code> since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@babel/core&package-manager=npm_and_yarn&previous-version=7.28.0&new-version=7.29.7)](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/21760?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 11:21:28 +02:00
Raphaël Bosi 9c9c34fccf Remove twenty-ui-deprecated and migrate frontend to twenty-ui (#21596)
Migrates `twenty-front`, `twenty-sdk`, and
`twenty-front-component-renderer` from `twenty-ui-deprecated` to
`twenty-ui` (mechanical import swap — the packages have API parity) and
deletes the deprecated package along with its workspace/CI/config
wiring.

Also adds `@linaria/react`/`@linaria/core` as direct deps of
`twenty-front` (it used them transitively via the deprecated package).

Note: move the required status check from `ci-ui-status-check` to
`ci-new-ui-status-check`.

Argos: the Storybook box-model/button-reset baseline shift (the bulk of
the visual diffs) is isolated in #21665 — Storybook now loads
twenty-ui's global `reset.scss`, which the production app already ships.
Once #21665 merges and this branch is rebased, the remaining Argos diffs
are component-level visual-parity items only.
2026-06-17 09:41:11 +00:00
Charles Bochet 257f130fff feat(sdk): let docker:start choose the server version (#21690)
## What

Makes `yarn twenty docker:start` version-selectable. Same core feature
as #21686 — but here scaffolded apps default to `latest` (pinning is
**opt-in**) rather than being pinned to the scaffolder's version.

> Alternative to #21686. Pick one; the difference is only the scaffolded
default.

Two layers of resolution:

1. **Explicit flag** — `yarn twenty docker:start [version]`, mirroring
the existing `docker:upgrade [version]`.
2. **App-pinned default** — when no version is passed, `docker:start`
reads `twenty.serverVersion` from the app's `package.json`, falling back
to `latest`.

Generated apps ship `twenty.serverVersion: "latest"`, so default
behavior is unchanged. To make the local server reproducible as code,
set a version:

```json filename="package.json"
{
  "twenty": {
    "serverVersion": "2.2.0"
  }
}
```

## Changes

- `twenty-sdk`: new `getAppServerVersion()` util reads
`twenty.serverVersion` from the cwd's `package.json`; `serverStart`
gains a `version` option and resolves `option → app pin → latest`,
building the image via `getImageForVersion()`; `docker:start [version]`
(and the deprecated `server start [version]` alias) wired up.
- `create-twenty-app`: template `package.json` ships
`twenty.serverVersion: "latest"`. (`create-app` and the scaffolder are
otherwise untouched.)
- Docs: `local-server.mdx` documents version selection and the opt-in
pin.

## Behavior notes

- Default with no pin and no flag is `latest` — same as today.
- Version only matters when **creating** a fresh container — an existing
container keeps its image until `docker:upgrade` / `docker:reset`.

## Testing

- New unit tests for `getAppServerVersion` (5 cases).
- Extended the `app-template` scaffolding test to assert the `latest`
default.
- `twenty-sdk` cli vitest suite (273) and `create-twenty-app` jest suite
(9) pass; oxlint + oxfmt clean on changed files.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21690?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-17 10:55:02 +02:00
Félix Malfait bb6da7b7d1 feat(code-interpreter): reuse a warm sandbox per conversation (E2B) (#21664)
## What

The E2B code-interpreter driver created a **fresh sandbox on every
execution** and killed it in `finally`, so every call in a conversation
paid full cold-start and started blank. This PR keeps **one warm sandbox
per conversation** and, on idle, **pauses** it rather than killing it.

## How

- **Discovery without a registry:** the sandbox is tagged with the chat
`threadId` (scoped `workspaceId:threadId`) via E2B **metadata**, found
with `Sandbox.list({ query: { state: ['running','paused'], metadata }
})` and resumed with `Sandbox.connect()` (which auto-resumes a paused
sandbox). E2B is the source of truth — no Redis/DB mapping.
- **Pause/resume (E2B 2.x):** session sandboxes are created with
`lifecycle: { onTimeout: 'pause', autoResume: true }`. When idle they
**pause** — compute billing stops, filesystem **and** kernel/memory
state are preserved — and resume in ~1s on the next call. This replaces
the earlier keepalive approach.
- **No premature pause mid-run:** the sandbox is kept alive for
`max(execution timeout, idle window)`, so a long execution is never
paused underneath itself.
- **Tenant isolation:** discovery filters by the `twentySessionId` tag
and **re-checks it client-side**, so a loose server-side match can never
hand one conversation's warm sandbox (with its files, kernel state,
token) to another.
- **Concurrency:** executions sharing a session are serialized
in-process (one active stream per thread, run as a single job — the chat
resolver queues concurrent messages), so parallel tool calls can't race
the shared kernel.
- **Output isolation:** `/home/user/output` is reset at the start of
each reused run, so a call only returns the artifacts it actually
produced; durable state lives elsewhere and persists.

## SDK upgrade

`@e2b/code-interpreter` **`^1.0.4` → `^2.6.0`** (pulls `e2b@2.x`). The
typed pause/resume API, `lifecycle`, and the `state`/`metadata` list
filter only exist in the 2.x line; 1.x exposed them only as untyped
OpenAPI internals. `Sandbox.list()` is now a paginator (handled).

## Config

| Var | Default | Purpose |
|---|---|---|
| `CODE_INTERPRETER_TIMEOUT_MS` | `300000` | Max single-execution
duration. |
| `CODE_INTERPRETER_IDLE_TIMEOUT_MS` | `300000` | Idle window before the
warm sandbox auto-pauses. |

Reuse is always-on when a session id is present (chat path). The
workflow-agent path and the dev-only `LocalDriver` are unaffected.

## ⚠️ Open item before merge: paused-sandbox GC

E2B retains paused sandboxes **indefinitely** (no TTL). Unlike the old
keepalive path (which auto-killed on idle), pause means a conversation's
sandbox persists after the chat ends — so without garbage collection,
paused sandboxes accumulate (≈ one per historical conversation) and
consume storage. A GC policy is required; the approach + retention
window are being decided (see PR discussion). Also: the E2B runtime path
can't run in CI, so this still needs a **live smoke test** (reuse hit,
idle→pause, resume) and confirmation of paused-storage pricing before
rollout.

## Tests / checks

- Resolver unit tests (`getOrCreateSessionSandbox`): reuse+extend,
create-when-absent, duplicate reaping, connect-failure fallback,
keep-first-connectable-when-earlier-dead, **ignore cross-tenant
metadata**, and **kill-on-timeout-refresh-failure**.
- `nx typecheck twenty-server` (against e2b 2.x), `oxlint --type-aware`,
`oxfmt --check` all clean.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-17 08:12:24 +00:00
Charles Bochet 9dd097e11e fix(front): set up Monaco workers for GraphQL playground (#21620)
## Problem

The GraphQL API playground (`/settings/playground/graphql/core`) crashes
with:

```
Uncaught Error: Cannot read properties of undefined (reading 'toUrl')
  at FileAccessImpl.toUri (monaco-editor)
  at WorkerManager.getLanguageServiceWorker (graphqlMode)
  at DiagnosticsAdapter._doValidate (graphqlMode)
```

## Root cause

GraphiQL 5 (adopted in the React 19 migration, #21531) renders its
editors with **Monaco** instead of CodeMirror. Monaco spawns web workers
for GraphQL validation/autocomplete and needs a
`globalThis.MonacoEnvironment.getWorker` factory. None was ever
configured, so Monaco fell back to a main-thread worker whose URL
resolves to `undefined` → the `toUrl` crash.

## Why not the official helper

GraphiQL ships `@graphiql/react/setup-workers/vite`, but its bundled
`?worker` imports are incompatible with our rolldown-based Vite setup:
- **pre-bundled** (in `optimizeDeps`): esbuild's optimizer can't process
`?worker` → the dep 504s and the page fails to load the chunk.
- **excluded** from `optimizeDeps`: rolldown tries to load
`editor.worker.js?worker` as a literal path → `UNLOADABLE_DEPENDENCY`,
crashing the dev server.

## Fix

- Register `MonacoEnvironment.getWorker` in **app source**
(`setupGraphiqlMonacoWorkers.ts`), where Vite's worker plugin handles
`?worker` reliably, and side-effect import it from
`GraphQLPlayground.tsx` before GraphiQL mounts.
- Align `monaco-editor` to `0.52.2` and add `monaco-graphql@1.8.0` as
direct deps so the workers run on the **same deduped Monaco instance**
GraphiQL uses on the main thread (a version mismatch would break the
worker protocol).

## Verification

Ran the playground locally against the dev server:
- Editor renders, syntax highlighting works, operation name parses
(GraphQL language service alive).
- All three worker files (`editor`, `json`, `graphql`) load `200` and
instantiate as module workers.
- Console is free of `toUrl` / `Cannot read` errors and the "must define
MonacoEnvironment.getWorker" warning.
- `oxlint`, `oxfmt`, and `nx typecheck twenty-front` pass.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21620?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-15 17:51:51 +02:00
Charles Bochet 88b9294afd feat(front): persist metadata store cache in IndexedDB instead of localStorage (#21586)
## Problem

The metadata store cache (object/field metadata, views, page layouts,
command menu items, …) is persisted client-side to power **cache-first
boot**: the app renders instantly from the cache, then
`MinimalMetadataLoadEffect` revalidates per-collection hashes and only
refetches what's stale.

It was persisted to **localStorage**, which Safari/WebKit caps at **~5
MB per origin, counted in UTF-16 (2 bytes/char)** → an effective ceiling
of ~2.5 M characters. Measured on the seeded demo workspace (33 objects,
612 fields):

| Bucket | Safari quota (UTF-16) |
|---|---|
| `metadataStoreState__*` (26 keys) | **1.9 MB — 37%** |
| Whole origin | **2.47 MB — 48%** |

A workspace ~2.5× the demo's schema blows past 5 MB, and there is **no
`QuotaExceededError` handling** — `setItem` throws and breaks the app.
This is what large-workspace users on Safari have been hitting.

## Fix

Move **only the metadata store** to **IndexedDB** (multi-GB, disk-based
quota), keeping a **fully synchronous read path** so the ~24 consumers
that read these atoms with `useAtomValue` never suspend. The auth/UI
atoms (incl. the synchronously-read `tokenPair`) stay on localStorage —
intentionally scoped.

- **`createIndexedDbBackedJotaiStorage.ts`** — a synchronous Jotai
storage facade backed by an in-memory map, hydrated once from IndexedDB
at boot and written through on every set. IndexedDB access uses the
**`idb-keyval`** library (by the IndexedDB spec co-author, ~0.6 KB)
rather than a hand-rolled wrapper. Each cache gets its own database +
BroadcastChannel (`twenty-front-<cacheName>`), so it's safely reusable.
Swallowed errors are surfaced via `logError`. When IndexedDB is
unavailable the cache stays in memory only (re-fetched each boot).
- **`createAtomFamilyState`** — gains an optional `storage` param;
`metadataStoreState` uses the IndexedDB-backed storage.
- **`index.tsx`** — awaits hydration before mounting so atoms
(`getOnInit: true`) read the persisted snapshot synchronously →
cache-first boot preserved.
- **No migration**: the facade does not touch localStorage at all.
Pre-existing localStorage snapshots are ignored — on first boot of the
new code the IndexedDB cache is empty and atoms re-fetch from the
network (a one-time reconnect). Old `metadataStoreState__*` localStorage
keys are left in place (cleared by the existing logout/reset cleanup);
new writes only ever go to IndexedDB.
- **Cross-tab sync**: the old localStorage atoms synced across tabs for
free via `storage` events; the IndexedDB facade had no equivalent, so a
schema change in one tab left others stale until reload. Restored by
implementing the Jotai storage `subscribe` contract over a
**`BroadcastChannel`** — writes broadcast to other tabs, which update
their in-memory map and notify `atomWithStorage` subscribers so mounted
atoms re-render live. (BroadcastChannel doesn't echo to the sender, so
no feedback loop; guarded for environments without it.)

## Why a synchronous facade (not async `atomWithStorage`)

Consumers use `useAtomValue` directly; an async storage would make the
atoms resolve to Promises and **suspend** every reader. The in-memory
facade keeps reads synchronous (zero ripple on consumers) and confines
the async part to a single bulk read at boot, which the existing
`MinimalMetadataGater` loader already covers.

## Tests

### Automated
- Unit test (10 cases) for the storage facade: synchronous read/write,
IndexedDB write-through, hydration from IndexedDB, `removeItem`/`clear`,
per-cache DB namespacing, persist-failure logging, in-memory-only
behaviour when IndexedDB is unavailable, distinguishing a stored
`undefined` from a missing key, and cross-tab subscriber registration.
- Existing metadata-store tests (`useIsLayoutCustomizationDirty`,
`useDefaultHomePagePath`) still pass.
- `nx typecheck twenty-front` and `nx lint:diff-with-main twenty-front`
clean.

### Manual (local seeded workspace, two tabs, Playwright)
Storage:
- After login the metadata cache lives in **IndexedDB (24 keys, ~945
KB)** and **localStorage drops 48% → 11%** of the Safari quota (the
remainder is `currentUserState` + auth, out of scope).
- Reload boots from the cache (no heavy refetch).

Scenarios:

| Scenario | Result |
|---|---|
| **Sign out** | auth cleared, redirect to sign-in, no leftover
localStorage, no errors |
| **Sign back in** | metadata `up-to-date`, company table renders, token
restored |
| **Add object** (`Gadget`) | write-through to IndexedDB; survives
reload via cache-first hydration |
| **Add view** (`QA Cross Tab View`, TABLE) | persisted to the `views`
collection (`up-to-date`) |
| **Two tabs open** | second tab boots cleanly from the shared IndexedDB
— no lock/crash under concurrent access |
| **Cross-tab live sync** | creating an object in tab A makes it appear
in tab B's open settings object list **without a reload** |

Verified by design (no regression):
- Runtime sign-out (`clearSession`) clears session keys and does a full
`window.location.assign` reload; the metadata-clearing path
(`resetJotaiStore`) is test-only, so there's no
async-`clear()`-vs-sign-in race. Metadata persisting across sign-out is
unchanged from the old localStorage behavior (it's schema, revalidated
by hash on next login).

## Notes / follow-ups (not in this PR)

- **IndexedDB query capabilities** are not used yet: the cache stores
one blob per collection (as it did in localStorage), so this is still a
pure key-value use (`idb-keyval`). If we later want to query individual
metadata records — e.g. fields by `objectMetadataId` via an
index/cursor, or partial hydration — that means record-level storage and
a richer wrapper (`idb` for a thin near-native layer, or **Dexie** for a
full query API + reactive `liveQuery` that could also replace the
BroadcastChannel sync).
- IndexedDB still has a (large) quota and Safari ITP eviction applies to
both stores — the cache-first design already tolerates eviction by
revalidating.
- Complementary "load less" wins remain: the denormalized per-field
`relation` block (~700 chars/field of pure duplication) and persisting
`currentUser.workspaceMembers` (the ~0.5 MB still in localStorage).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21586?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-15 13:25:53 +00:00
dependabot[bot] ebababcda1 chore(deps): bump @ai-sdk/amazon-bedrock from 4.0.97 to 4.0.117 (#21569)
Bumps
[@ai-sdk/amazon-bedrock](https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock)
from 4.0.97 to 4.0.117.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/ai/blob/@ai-sdk/amazon-bedrock@4.0.117/packages/amazon-bedrock/CHANGELOG.md">@​ai-sdk/amazon-bedrock's
changelog</a>.</em></p>
<blockquote>
<h2>4.0.117</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [bfa5864]</li>
<li>Updated dependencies [f42aa79]
<ul>
<li><code>@​ai-sdk/provider-utils</code><a
href="https://github.com/4"><code>@​4</code></a>.0.29</li>
<li><code>@​ai-sdk/anthropic</code><a
href="https://github.com/3"><code>@​3</code></a>.0.84</li>
<li><code>@​ai-sdk/openai</code><a
href="https://github.com/3"><code>@​3</code></a>.0.71</li>
</ul>
</li>
</ul>
<h2>4.0.116</h2>
<h3>Patch Changes</h3>
<ul>
<li>f0b5c16: fix(provider/amazon-bedrock): detect Cohere embedding
models behind cross-region inference profile ids</li>
<li>Updated dependencies [942f2f8]
<ul>
<li><code>@​ai-sdk/provider-utils</code><a
href="https://github.com/4"><code>@​4</code></a>.0.28</li>
<li><code>@​ai-sdk/anthropic</code><a
href="https://github.com/3"><code>@​3</code></a>.0.83</li>
<li><code>@​ai-sdk/openai</code><a
href="https://github.com/3"><code>@​3</code></a>.0.70</li>
</ul>
</li>
</ul>
<h2>4.0.115</h2>
<h3>Patch Changes</h3>
<ul>
<li>c97ede5: fix(provider/amazon-bedrock): extract Cohere embedding
token usage from response header</li>
</ul>
<h2>4.0.114</h2>
<h3>Patch Changes</h3>
<ul>
<li>2a91a17: feat(provider/anthropic): add support for
<code>claude-fable-5</code> and the <code>fallbacks</code> API
parameter</li>
<li>Updated dependencies [9a55f6d]</li>
<li>Updated dependencies [2a91a17]
<ul>
<li><code>@​ai-sdk/openai</code><a
href="https://github.com/3"><code>@​3</code></a>.0.69</li>
<li><code>@​ai-sdk/anthropic</code><a
href="https://github.com/3"><code>@​3</code></a>.0.82</li>
</ul>
</li>
</ul>
<h2>4.0.113</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [c65c952]
<ul>
<li><code>@​ai-sdk/openai</code><a
href="https://github.com/3"><code>@​3</code></a>.0.68</li>
</ul>
</li>
</ul>
<h2>4.0.112</h2>
<h3>Patch Changes</h3>
<ul>
<li>53b002d: added bedrock mantle provider</li>
</ul>
<h2>4.0.111</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/ai/commit/bae9babb22e195e74a9a0c0e26a5e52c8ba8e7f2"><code>bae9bab</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/16026">#16026</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/9ef2c3cfadfc4a469e9eec6a6e8a0ac0fc80a1e5"><code>9ef2c3c</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15998">#15998</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/f0b5c16ce5f17a7c9cc91ce0ae8f292920594e91"><code>f0b5c16</code></a>
Backport: fix(provider/amazon-bedrock): detect Cohere embedding models
behind...</li>
<li><a
href="https://github.com/vercel/ai/commit/dca8c38b09acba1a5eebf354b532833ab055413a"><code>dca8c38</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15992">#15992</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/c97ede5cbbbc0aaca0137ed41c7fd6f5fedd23b6"><code>c97ede5</code></a>
Backport: fix(provider/amazon-bedrock): extract Cohere embedding token
usage ...</li>
<li><a
href="https://github.com/vercel/ai/commit/f6e588173713842794c619f9554a4b341c6e97f5"><code>f6e5881</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15902">#15902</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/2a91a17e0b885968814110fe3581d1ea0fd589ae"><code>2a91a17</code></a>
backport: feat(provider/anthropic): add support for
<code>claude-fable-5</code> and the ...</li>
<li><a
href="https://github.com/vercel/ai/commit/de852ab79aac88345c8a9ae54003fb206e1a64b4"><code>de852ab</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15821">#15821</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/879395199bac3796e6c34b43f6aa43ca5d682940"><code>8793951</code></a>
Version Packages (<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15755">#15755</a>)</li>
<li><a
href="https://github.com/vercel/ai/commit/53b002d2d0701235026b41e0fa11aa1a41c90b8b"><code>53b002d</code></a>
Backport: feat (provider/amazon-bedrock): add bedrock mantle provider
(<a
href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/14246">#14246</a>...</li>
<li>Additional commits viewable in <a
href="https://github.com/vercel/ai/commits/@ai-sdk/amazon-bedrock@4.0.117/packages/amazon-bedrock">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@ai-sdk/amazon-bedrock&package-manager=npm_and_yarn&previous-version=4.0.97&new-version=4.0.117)](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/21569?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: Charles Bochet <charles@twenty.com>
2026-06-15 10:24:09 +02:00
Charles Bochet fb4608e437 chore(deps): upgrade Tier-1 deps (googleapis 173, gaxios 7, express 5, jsdom 29, date-fns 4, stripe 20) (#21570)
## What

Security-driven upgrade of the biggest-drift Tier-1 dependencies
(staying on latest = staying patched). Bundled because they share the
lockfile and the googleapis/gaxios pair must move together.

| Package | From | To | Gap |
|---|---|---|---|
| googleapis | 105.0.0 | **173.0.0** | 68 majors |
| gaxios | 5.1.3 | **7.1.5** | 2 majors |
| express | 4.22.2 | **5.2.1** | 1 major |
| jsdom | 26.1.0 | **29.1.1** | 3 majors |
| date-fns | 2.30.0 | **4.4.0** | 2 majors |
| date-fns-tz | 2.0.0 | **3.2.0** | 1 major |
| stripe | 19.3.1 | **20.4.1** | 1 major |

`yarn npm audit` reports **0 high/critical** advisories before and
after.

## Code changes

- **gaxios v7** — `GaxiosError.code` is now `string | number` (guard the
calendar network-error check by `typeof`); `GaxiosError` config/response
use `URL` + `Headers`; and crucially the v7 constructor drops
`response.data` unless `bodyUsed` is set — updated the synthetic gmail
error mocks accordingly (production gaxios sets it, so real error
parsing is unaffected).
- **google-auth-library / gaxios dedup** — `googleapis-common@8.0.2`
exact-pins `google-auth-library@10.5.0` + `gaxios@7.1.3` while
`googleapis` pulls `^10.2.0`; the two copies made
`OAuth2Client`/`GaxiosError` type-identities diverge across every
gmail/calendar service. Added two singleton `resolutions` (documented
inline in root `package.json`).
- **express 5** — no source changes. `@nestjs/platform-express@11.1.24`
already resolves `express@5.2.1` internally; the old `4.22.2` pin was
the override.
- **jsdom 29** — no source changes, but it now pulls ESM-only transitive
deps (`@csstools/*` `.mjs`, `parse5`, `entities`, `tough-cookie`,
`@exodus/bytes`). Extended the server jest `transformIgnorePatterns`
allowlist and added `.mjs` to the transform/extensions so jest can load
jsdom.
- **stripe 20** — `Subscription` gained a required `customer_account`
field; added to mocks. No runtime changes.
- **date-fns v4** — `Locale` is no longer ambient (import explicitly in
5 files); per-locale entrypoints dropped the typed `default` export (the
locale loader now reads the single named export); fixed the default
locale import in `formatTimeZoneLabel`.

## Tests

- Full suites green locally: **twenty-server 5709 passed**,
**twenty-front 4937 passed**, twenty-ui / twenty-ui-deprecated green;
typecheck + builds (swc + vite) + lint all pass.
- Added regression tests for the two runtime behaviors these upgrades
touch and that had no coverage:
  - `getDateFnsLocale` — named-export locale resolution (date-fns v4).
- `sanitizeFile` — jsdom 29 + DOMPurify still strips `<script>`/event
handlers from uploaded SVGs (security guard).

## Deliberately deferred (not in this PR)

- **stripe → 21/22**: stripe **21** bundles a runtime `Decimal` type for
money fields **and** jumps the pinned API version to `2026-03-25.dahlia`
(changes webhook/billing payload behavior) — too risky to fold into a
deps bump on billing code. stripe **22** additionally drops the
node10-resolvable `types` entry, which would force a repo-wide
`moduleResolution` change. Capped at the latest clean **20.x**.
- **openid-client → 6**: v6 is a full functional rewrite and its
passport strategy manages the OAuth `state` internally, but our SSO flow
uses `state` to carry `identityProviderId` across the shared
`/auth/oidc/callback`. That needs an auth-flow redesign (session-carried
provider id) on Enterprise SSO code with no integration harness — it
deserves its own focused PR rather than riding along here.

## Tier-1 source

Originated from a dependency-drift audit; remaining Tier-1 items
(date-fns done here) plus Tier-2/3 follow-ups tracked separately.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21570?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-15 10:23:42 +02:00
dependabot[bot] e70776f705 chore(deps): bump prettier from 3.8.3 to 3.8.4 (#21568)
Bumps [prettier](https://github.com/prettier/prettier) from 3.8.3 to
3.8.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>3.8.4</h2>
<ul>
<li>Markdown: Fix blank lines between list items and nested sub-lists
being removed in Markdown/MDX (<a
href="https://redirect.github.com/prettier/prettier/pull/17746">prettier/prettier#17746</a>
by <a
href="https://github.com/byplayer"><code>@​byplayer</code></a>)</li>
</ul>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/3.8.4/CHANGELOG.md#384">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>3.8.4</h1>
<p><a
href="https://github.com/prettier/prettier/compare/3.8.3...3.8.4">diff</a></p>
<h4>Markdown: Fix blank lines between list items and nested sub-lists
being removed in Markdown/MDX (<a
href="https://redirect.github.com/prettier/prettier/pull/17746">#17746</a>
by <a
href="https://github.com/byplayer"><code>@​byplayer</code></a>)</h4>
<p>Prettier was removing blank lines between list items and their nested
sub-lists, converting loose lists into tight lists and changing their
semantic meaning.</p>
<!-- raw HTML omitted -->
<pre lang="markdown"><code>&lt;!-- Input --&gt;
- a
<ul>
<li>
<p>b</p>
</li>
<li>
<p>c</p>
<ul>
<li>d</li>
</ul>
</li>
</ul>
<p>&lt;!-- Prettier 3.8.3 --&gt;</p>
<ul>
<li>a
<ul>
<li>b</li>
</ul>
</li>
<li>c
<ul>
<li>d</li>
</ul>
</li>
</ul>
<p>&lt;!-- Prettier 3.8.4 --&gt;</p>
<ul>
<li>
<p>a</p>
<ul>
<li>b</li>
</ul>
</li>
<li>
<p>c</p>
<ul>
<li>d<br />
</code></pre></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/prettier/prettier/commit/1c6ba5539141552e0e8e22d401ea620d8fdff468"><code>1c6ba55</code></a>
Release 3.8.4</li>
<li><a
href="https://github.com/prettier/prettier/commit/4a673dc9b59ddf7296bbab9822093d2971da84a8"><code>4a673dc</code></a>
Fix blank lines between list items and nested sub-lists being removed in
Mark...</li>
<li><a
href="https://github.com/prettier/prettier/commit/074aaedbb052a288e89d15eb0a4214de37a08866"><code>074aaed</code></a>
Replace <code>main</code> branch in changelog link with tags (<a
href="https://redirect.github.com/prettier/prettier/issues/19054">#19054</a>)</li>
<li><a
href="https://github.com/prettier/prettier/commit/c22a003ae97917c5043e8685b4fdff0f93e978f9"><code>c22a003</code></a>
Bump Prettier dependency to 3.8.3</li>
<li><a
href="https://github.com/prettier/prettier/commit/07bad1f04536e9799927007baf466e67151576f0"><code>07bad1f</code></a>
Clean changelog_unreleased</li>
<li>See full diff in <a
href="https://github.com/prettier/prettier/compare/3.8.3...3.8.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=3.8.3&new-version=3.8.4)](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/21568?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-15 00:19:24 +02:00