## Summary
Completes the migration of the frontend styling system from **Emotion**
(`@emotion/styled`, `@emotion/react`) to **Linaria** (`@linaria/react`,
`@linaria/core`), a zero-runtime CSS-in-JS library where styles are
extracted at build time.
This is the final step of the migration — all ~494 files across
`twenty-front`, `twenty-ui`, `twenty-website`, and `twenty-sdk` are now
fully converted.
## Changes
### Styling Migration (across ~480 component files)
- Replaced all `@emotion/styled` imports with `@linaria/react`
- Converted runtime theme access patterns (`({ theme }) => theme.x.y`)
to build-time `themeCssVariables` CSS custom properties
- Replaced `useTheme()` hook (from Emotion) with
`useContext(ThemeContext)` where runtime theme values are still needed
(e.g., passing colors to non-CSS props like icon components)
- Removed `@emotion/react` `css` helper usages in favor of Linaria
template literals
### Dependency & Configuration Changes
- **Removed**: `@emotion/react`, `@emotion/styled` from root
`package.json`
- **Added**: `@wyw-in-js/babel-preset`, `next-with-linaria` (for
twenty-website SSR support)
- Updated Nx generator defaults from `@emotion/styled` to
`@linaria/react` in `nx.json`
- Simplified `vite.config.ts` (removed Emotion-specific configuration)
- Updated `twenty-website/next.config.js` to use `next-with-linaria` for
SSR Linaria support
### Storybook & Testing
- Removed `ThemeProvider` from Emotion in Storybook previews
(`twenty-front`, `twenty-sdk`)
- Now relies solely on `ThemeContextProvider` for theme injection
### Documentation
- Removed the temporary `docs/emotion-to-linaria-migration-plan.md`
(migration complete)
- Updated `CLAUDE.md` and `README.md` to reflect Linaria as the styling
stack
- Updated frontend style guide docs across all locales
## How it works
Linaria extracts styles at build time via the `@wyw-in-js/vite` plugin.
All expressions in `styled` template literals must be **statically
evaluable** — no runtime theme objects or closures over component state.
- **Static styles** use `themeCssVariables` which map to CSS custom
properties (`var(--theme-color-x)`)
- **Runtime theme access** (for non-CSS use cases like icon `color`
props) uses `useContext(ThemeContext)` instead of Emotion's `useTheme()`
- Fixes self host application
- add new telemetry information
- add serverId to identify a server instance
- remove .twenty from git tracking
- tree-shake "twenty-sdk" usage in built logic functions and front
components
- fix "twenty-sdk" version usage
- fix twenty-zapier cli
---------
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This PR pgrades all BlockNote packages (@blocknote/core,
@blocknote/react, @blocknote/mantine, @blocknote/server-util,
@blocknote/xl-docx-exporter, @blocknote/xl-pdf-exporter) to 0.47.0 and
adapts the codebase to the new API.
### Changes
- Dependency upgrades: Bumped all BlockNote packages to 0.47.0, added
required Mantine v8 peer dependencies, removed unnecessary prosemirror
resolutions
- Formatting toolbar: Replaced the manual reimplementation of
FormattingToolbarController (which handled visibility, positioning,
portal rendering, text-alignment-based placement, and a
dangerouslySetInnerHTML transition trick) with BlockNote's built-in
FormattingToolbarController. The toolbar buttons themselves are
unchanged.
- Side menu: Replaced manual drag handle menu positioning and rendering
(DashboardBlockDragHandleMenu, DashboardBlockColorPicker, and their
floating configs) with BlockNote's built-in SideMenuController,
DragHandleButton, and DragHandleMenu components. Deleted 4 files that
became dead code.
- Extension API migration: Replaced deprecated editor.suggestionMenus
and editor.formattingToolbar APIs with the new extension system
(SuggestionMenu, useExtensionState, editor.getExtension())
- Slash menu fixes: Filtered out BlockNote's new default "File" item
(added in 0.47) to avoid duplicates with our custom one; added icon
mappings for new block types (Toggle List, Divider, Toggle Headings,
Headings 4-6)
- Server-side: Switched @blocknote/server-util to dynamic import() to
handle ESM-only transitive dependencies in CJS context
Bumps [@emotion/styled](https://github.com/emotion-js/emotion) from
11.13.0 to 11.14.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/emotion-js/emotion/releases"><code>@emotion/styled</code>'s
releases</a>.</em></p>
<blockquote>
<h2><code>@emotion/styled</code><a
href="https://github.com/11"><code>@11</code></a>.14.1</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/emotion-js/emotion/pull/3334">#3334</a>
<a
href="0facbe47bd"><code>0facbe4</code></a>
Thanks <a
href="https://github.com/ZachRiegel"><code>@ZachRiegel</code></a>! -
Renamed default-exported variable in <code>@emotion/styled</code> to aid
inferred import names in auto-import completions in IDEs</li>
</ul>
<h2><code>@emotion/styled</code><a
href="https://github.com/11"><code>@11</code></a>.14.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/emotion-js/emotion/pull/3284">#3284</a>
<a
href="a19d019bd4"><code>a19d019</code></a>
Thanks <a
href="https://github.com/Andarist"><code>@Andarist</code></a>! - Source
code has been migrated to TypeScript. From now on type declarations will
be emitted based on that, instead of being hand-written.</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="e1bf17ee87"><code>e1bf17e</code></a>]:
<ul>
<li><code>@emotion/use-insertion-effect-with-fallbacks</code><a
href="https://github.com/1"><code>@1</code></a>.2.0</li>
</ul>
</li>
</ul>
<h2><code>@emotion/styled</code><a
href="https://github.com/11"><code>@11</code></a>.13.5</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/emotion-js/emotion/pull/3270">#3270</a>
<a
href="77d930dc70"><code>77d930d</code></a>
Thanks <a
href="https://github.com/emmatown"><code>@emmatown</code></a>! - Fix
inconsistent hashes using development vs production
bundles/<code>exports</code> conditions when using
<code>@emotion/babel-plugin</code> with <code>sourceMap: true</code>
(the default). This is particularly visible when using Emotion with the
Next.js Pages router where the <code>development</code> condition is
used when bundling code but not when importing external code with
Node.js.</p>
</li>
<li>
<p>Updated dependencies [<a
href="77d930dc70"><code>77d930d</code></a>]:</p>
<ul>
<li><code>@emotion/serialize</code><a
href="https://github.com/1"><code>@1</code></a>.3.3</li>
<li><code>@emotion/utils</code><a
href="https://github.com/1"><code>@1</code></a>.4.2</li>
<li><code>@emotion/babel-plugin</code><a
href="https://github.com/11"><code>@11</code></a>.13.5</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4922955396"><code>4922955</code></a>
Version Packages (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3335">#3335</a>)</li>
<li><a
href="0facbe47bd"><code>0facbe4</code></a>
Renamed default-exported variable in <code>@emotion/styled</code> to aid
inferred import...</li>
<li><a
href="cce67ec6b2"><code>cce67ec</code></a>
Bump parcel (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3258">#3258</a>)</li>
<li><a
href="3c19ce5997"><code>3c19ce5</code></a>
Version Packages (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3280">#3280</a>)</li>
<li><a
href="a19d019bd4"><code>a19d019</code></a>
Convert <code>@emotion/styled</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3284">#3284</a>)</li>
<li><a
href="5974e33fcb"><code>5974e33</code></a>
Fix JSX namespace <a
href="https://github.com/ts-ignores"><code>@ts-ignores</code></a> (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3282">#3282</a>)</li>
<li><a
href="fc4d7bd744"><code>fc4d7bd</code></a>
Convert <code>@emotion/react</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3281">#3281</a>)</li>
<li><a
href="8dc1a6dd19"><code>8dc1a6d</code></a>
Convert <code>@emotion/cache</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3277">#3277</a>)</li>
<li><a
href="282b61d2ad"><code>282b61d</code></a>
Convert <code>@emotion/css-prettifier</code>'s source code to TypeScript
(<a
href="https://redirect.github.com/emotion-js/emotion/issues/3278">#3278</a>)</li>
<li><a
href="e1bf17ee87"><code>e1bf17e</code></a>
Convert <code>@emotion/use-insertion-effect-with-fallbacks</code>'s
source code to TypeS...</li>
<li>Additional commits viewable in <a
href="https://github.com/emotion-js/emotion/compare/@emotion/styled@11.13.0...@emotion/styled@11.14.1">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@sentry/react](https://github.com/getsentry/sentry-javascript)
from 10.27.0 to 10.40.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-javascript/releases"><code>@sentry/react</code>'s
releases</a>.</em></p>
<blockquote>
<h2>10.40.0</h2>
<h3>Important Changes</h3>
<ul>
<li>
<p><strong>feat(tanstackstart-react): Add global sentry exception
middlewares (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19330">#19330</a>)</strong></p>
<p>The <code>sentryGlobalRequestMiddleware</code> and
<code>sentryGlobalFunctionMiddleware</code> global middlewares capture
unhandled exceptions thrown in TanStack Start API routes and server
functions. Add them as the first entries in the
<code>requestMiddleware</code> and <code>functionMiddleware</code>
arrays of <code>createStart()</code>:</p>
<pre lang="ts"><code>import { createStart } from
'@tanstack/react-start/server';
import { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware }
from '@sentry/tanstackstart-react';
<p>export default createStart({
requestMiddleware: [sentryGlobalRequestMiddleware, myRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware,
myFunctionMiddleware],
});
</code></pre></p>
</li>
<li>
<p><strong>feat(tanstackstart-react)!: Export Vite plugin from
<code>@sentry/tanstackstart-react/vite</code> subpath (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19182">#19182</a>)</strong></p>
<p>The <code>sentryTanstackStart</code> Vite plugin is now exported from
a dedicated subpath. Update your import:</p>
<pre lang="diff"><code>- import { sentryTanstackStart } from
'@sentry/tanstackstart-react';
+ import { sentryTanstackStart } from
'@sentry/tanstackstart-react/vite';
</code></pre>
</li>
<li>
<p><strong>fix(node-core): Reduce bundle size by removing apm-js-collab
and requiring pino >= 9.10 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/18631">#18631</a>)</strong></p>
<p>In order to keep receiving pino logs, you need to update your pino
version to >= 9.10, the reason for the support bump is to reduce the
bundle size of the node-core SDK in frameworks that cannot tree-shake
the apm-js-collab dependency.</p>
</li>
<li>
<p><strong>fix(browser): Ensure user id is consistently added to
sessions (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19341">#19341</a>)</strong></p>
<p>Previously, the SDK inconsistently set the user id on sessions,
meaning sessions were often lacking proper coupling to the user set for
example via <code>Sentry.setUser()</code>.
Additionally, the SDK incorrectly skipped starting a new session for the
first soft navigation after the pageload.
This patch fixes these issues. As a result, metrics around sessions,
like "Crash Free Sessions" or "Crash Free Users"
might change.
This could also trigger alerts, depending on your set thresholds and
conditions.
We apologize for any inconvenience caused!</p>
<p>While we're at it, if you're using Sentry in a Single Page App or
meta framework, you might want to give the new <code>'page'</code>
session lifecycle a try!
This new mode no longer creates a session per soft navigation but
continues the initial session until the next hard page refresh.
Check out the <a
href="https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/browsersession/">docs</a>
to learn more!</p>
</li>
<li>
<p><strong>ref!(gatsby): Drop Gatsby v2 support (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19467">#19467</a>)</strong></p>
<p>We drop support for Gatsby v2 (which still relies on webpack 4) for a
critical security update in <a
href="https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0">https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0</a></p>
</li>
</ul>
<h3>Other Changes</h3>
<ul>
<li>feat(astro): Add support for Astro on CF Workers (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19265">#19265</a>)</li>
<li>feat(cloudflare): Instrument async KV API (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19404">#19404</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md"><code>@sentry/react</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>10.40.0</h2>
<h3>Important Changes</h3>
<ul>
<li>
<p><strong>feat(tanstackstart-react): Add global sentry exception
middlewares (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19330">#19330</a>)</strong></p>
<p>The <code>sentryGlobalRequestMiddleware</code> and
<code>sentryGlobalFunctionMiddleware</code> global middlewares capture
unhandled exceptions thrown in TanStack Start API routes and server
functions. Add them as the first entries in the
<code>requestMiddleware</code> and <code>functionMiddleware</code>
arrays of <code>createStart()</code>:</p>
<pre lang="ts"><code>import { createStart } from
'@tanstack/react-start/server';
import { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware }
from '@sentry/tanstackstart-react/server';
<p>export default createStart({
requestMiddleware: [sentryGlobalRequestMiddleware, myRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware,
myFunctionMiddleware],
});
</code></pre></p>
</li>
<li>
<p><strong>feat(tanstackstart-react)!: Export Vite plugin from
<code>@sentry/tanstackstart-react/vite</code> subpath (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19182">#19182</a>)</strong></p>
<p>The <code>sentryTanstackStart</code> Vite plugin is now exported from
a dedicated subpath. Update your import:</p>
<pre lang="diff"><code>- import { sentryTanstackStart } from
'@sentry/tanstackstart-react';
+ import { sentryTanstackStart } from
'@sentry/tanstackstart-react/vite';
</code></pre>
</li>
<li>
<p><strong>fix(node-core): Reduce bundle size by removing apm-js-collab
and requiring pino >= 9.10 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/18631">#18631</a>)</strong></p>
<p>In order to keep receiving pino logs, you need to update your pino
version to >= 9.10, the reason for the support bump is to reduce the
bundle size of the node-core SDK in frameworks that cannot tree-shake
the apm-js-collab dependency.</p>
</li>
<li>
<p><strong>fix(browser): Ensure user id is consistently added to
sessions (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19341">#19341</a>)</strong></p>
<p>Previously, the SDK inconsistently set the user id on sessions,
meaning sessions were often lacking proper coupling to the user set for
example via <code>Sentry.setUser()</code>.
Additionally, the SDK incorrectly skipped starting a new session for the
first soft navigation after the pageload.
This patch fixes these issues. As a result, metrics around sessions,
like "Crash Free Sessions" or "Crash Free Users"
might change.
This could also trigger alerts, depending on your set thresholds and
conditions.
We apologize for any inconvenience caused!</p>
<p>While we're at it, if you're using Sentry in a Single Page App or
meta framework, you might want to give the new <code>'page'</code>
session lifecycle a try!
This new mode no longer creates a session per soft navigation but
continues the initial session until the next hard page refresh.
Check out the <a
href="https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/browsersession/">docs</a>
to learn more!</p>
</li>
<li>
<p><strong>ref!(gatsby): Drop Gatsby v2 support (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19467">#19467</a>)</strong></p>
<p>We drop support for Gatsby v2 (which still relies on webpack 4) for a
critical security update in <a
href="https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0">https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0</a></p>
</li>
</ul>
<h3>Other Changes</h3>
<ul>
<li>feat(astro): Add support for Astro on CF Workers (<a
href="https://redirect.github.com/getsentry/sentry-javascript/pull/19265">#19265</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="663fd5e7e3"><code>663fd5e</code></a>
Increase bundler-tests timeout to 30s</li>
<li><a
href="8033ea380f"><code>8033ea3</code></a>
release: 10.40.0</li>
<li><a
href="eb3c4d2489"><code>eb3c4d2</code></a>
Merge pull request <a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19488">#19488</a>
from getsentry/prepare-release/10.40.0</li>
<li><a
href="9a10630c6b"><code>9a10630</code></a>
meta(changelog): Update changelog for 10.40.0</li>
<li><a
href="39d1ef7784"><code>39d1ef7</code></a>
fix(deps): Bump to latest version of each minimatch major (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19486">#19486</a>)</li>
<li><a
href="e8ed6d262f"><code>e8ed6d2</code></a>
test(nextjs): Deactivate canary test for cf-workers (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19483">#19483</a>)</li>
<li><a
href="6eb320eb3e"><code>6eb320e</code></a>
chore(deps): Bump Sentry CLI to latest v2 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19477">#19477</a>)</li>
<li><a
href="8fc81d2cd4"><code>8fc81d2</code></a>
fix: Bump bundler plugins to v5 (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19468">#19468</a>)</li>
<li><a
href="365f7fab4e"><code>365f7fa</code></a>
chore(ci): Adapt max turns of triage issue agent (<a
href="https://redirect.github.com/getsentry/sentry-javascript/issues/19473">#19473</a>)</li>
<li><a
href="11e5412d42"><code>11e5412</code></a>
feat(tanstackstart-react)!: Export Vite plugin from
<code>@sentry/tanstackstart-rea</code>...</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-javascript/compare/10.27.0...10.40.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
- **Model pricing overhaul**: All model constants updated with accurate
pricing in dollars per 1M tokens, including cached input rates, cache
creation rates, and tiered >200k context pricing
- **New providers**: Added Google (Gemini 3.x), Mistral, and AWS Bedrock
as inference providers. Bedrock serves Claude Opus 4.6 and Sonnet 4.6
via AWS, with proper credential handling following the existing S3/SES
pattern
- **InferenceProvider/ModelFamily split**: Refactored `ModelProvider`
into two orthogonal enums — `InferenceProvider` (who serves the model:
auth, SDK, metadata format) and `ModelFamily` (who created it: token
counting semantics). This eliminates growing `||` chains for token
normalization checks like `excludesCachedTokens`
- **Billing improvements**: Reasoning tokens charged at output rate,
cache token discounts applied accurately, real errors thrown to Sentry
on billing failures
## Test plan
- [x] All existing unit tests updated and passing (23 tests across 3
test files)
- [x] Lint passes for both twenty-server and twenty-front
- [ ] CI checks pass
Made with [Cursor](https://cursor.com)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary
- Upgrades `@swc/core` from 1.13.3 to **1.15.11** (swc_core v56), which
introduces CBOR-based plugin serialization replacing rkyv, eliminating
strict version-matching between SWC core and Wasm plugins
- Upgrades `@lingui/swc-plugin` from ^5.6.0 to **^5.11.0** (swc_core
50.2.3, built with `--cfg=swc_ast_unknown` for cross-version
compatibility)
- Upgrades `@swc/plugin-emotion` from 10.0.4 to **14.6.0** (swc_core 53,
also with backward-compat feature)
- Upgrades companion packages: `@swc-node/register` 1.8.0 → 1.11.1,
`@swc/helpers` ~0.5.2 → ~0.5.18, `@vitejs/plugin-react-swc` 3.11.0 →
4.2.3
### Why this is safe now
Starting from `@swc/core v1.15.0`, SWC replaced the rkyv serialization
scheme with CBOR (a self-describing format) and added `Unknown` AST enum
variants. Plugins built with `swc_core >= 47` and
`--cfg=swc_ast_unknown` are now forward-compatible across `@swc/core`
versions. Both `@lingui/swc-plugin@5.10.1+` and
`@swc/plugin-emotion@14.0.0+` have this support, meaning the old
version-matching nightmare between Lingui and SWC is largely solved.
Reference: https://github.com/lingui/swc-plugin/issues/179
## Test plan
- [x] `yarn install` resolves without errors
- [x] `npx nx build twenty-shared` succeeds
- [x] `npx nx build twenty-ui` succeeds (validates
@swc/plugin-emotion@14.6.0)
- [x] `npx nx typecheck twenty-front` succeeds
- [x] `npx nx build twenty-front` succeeds (validates vite + swc +
lingui pipeline)
- [x] `npx nx build twenty-emails` succeeds (validates lingui plugin)
- [x] Frontend jest tests pass (validates @swc/jest +
@lingui/swc-plugin)
- [x] Server jest tests pass (validates server-side SWC + lingui)
Made with [Cursor](https://cursor.com)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Bumps
[eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next)
from 14.2.33 to 14.2.35.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7b940d9ce9"><code>7b940d9</code></a>
v14.2.35</li>
<li><a
href="f3073688ce"><code>f307368</code></a>
v14.2.34</li>
<li>See full diff in <a
href="https://github.com/vercel/next.js/commits/v14.2.35/packages/eslint-config-next">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[@xyflow/react](https://github.com/xyflow/xyflow/tree/HEAD/packages/react)
from 12.4.2 to 12.10.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/xyflow/xyflow/releases"><code>@xyflow/react</code>'s
releases</a>.</em></p>
<blockquote>
<h2><code>@xyflow/react</code><a
href="https://github.com/12"><code>@12</code></a>.10.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5637">#5637</a> <a
href="0c7261a6dc"><code>0c7261a6d</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Add <code>zIndexMode</code> to control how z-index is calculated for
nodes and edges</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5484">#5484</a> <a
href="a523919d67"><code>a523919d6</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Add
<code>experimental_useOnNodesChangeMiddleware</code> hook</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5629">#5629</a> <a
href="9030fab2df"><code>9030fab2d</code></a>
Thanks <a
href="https://github.com/AlaricBaraou"><code>@AlaricBaraou</code></a>!
- Prevent unnecessary re-render in <code>FlowRenderer</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5592">#5592</a> <a
href="38dbf41c46"><code>38dbf41c4</code></a>
Thanks <a
href="https://github.com/svilen-ivanov-kubit"><code>@svilen-ivanov-kubit</code></a>!
- Always create a new measured object in apply changes.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5635">#5635</a> <a
href="2d7fa40e26"><code>2d7fa40e2</code></a>
Thanks <a
href="https://github.com/tornado-softwares"><code>@tornado-softwares</code></a>!
- Update an ongoing connection when user moves node with keyboard.</p>
</li>
<li>
<p>Updated dependencies [<a
href="0c7261a6dc"><code>0c7261a6d</code></a>,
<a
href="8598b6bc2a"><code>8598b6bc2</code></a>,
<a
href="2d7fa40e26"><code>2d7fa40e2</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.74</li>
</ul>
</li>
</ul>
<h2><code>@xyflow/react</code><a
href="https://github.com/12"><code>@12</code></a>.9.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5621">#5621</a> <a
href="c1304dba7a"><code>c1304dba7</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Set <code>paneClickDistance</code> default value to
<code>1</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5578">#5578</a> <a
href="00bcb9f5f4"><code>00bcb9f5f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Pass
current pointer position to connection</p>
</li>
<li>
<p>Updated dependencies [<a
href="00bcb9f5f4"><code>00bcb9f5f</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.73</li>
</ul>
</li>
</ul>
<h2><code>@xyflow/react</code><a
href="https://github.com/12"><code>@12</code></a>.9.2</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5593">#5593</a> <a
href="a8ee089d76"><code>a8ee089d7</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Reset selection box when user selects a node</li>
</ul>
<h2><code>@xyflow/react</code><a
href="https://github.com/12"><code>@12</code></a>.9.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5572">#5572</a> <a
href="5ec0cac7fa"><code>5ec0cac7f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Fix
onPaneClick events being suppressed when selectionOnDrag=true</p>
</li>
<li>
<p>Updated dependencies [<a
href="5ec0cac7fa"><code>5ec0cac7f</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.72</li>
</ul>
</li>
</ul>
<h2><code>@xyflow/react</code><a
href="https://github.com/12"><code>@12</code></a>.9.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5544">#5544</a> <a
href="c17b49f4c1"><code>c17b49f4c</code></a>
Thanks <a
href="https://github.com/0x0f0f0f"><code>@0x0f0f0f</code></a>! - Add
<code>EdgeToolbar</code> component</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5550">#5550</a> <a
href="6ffb9f7901"><code>6ffb9f790</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! -
Prevent child nodes of different parents from overlapping</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5551">#5551</a> <a
href="6bb64b3ed6"><code>6bb64b3ed</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Allow to start a selection above a node</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/xyflow/xyflow/blob/main/packages/react/CHANGELOG.md"><code>@xyflow/react</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>12.10.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5637">#5637</a> <a
href="0c7261a6dc"><code>0c7261a6d</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Add <code>zIndexMode</code> to control how z-index is calculated for
nodes and edges</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5484">#5484</a> <a
href="a523919d67"><code>a523919d6</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Add
<code>experimental_useOnNodesChangeMiddleware</code> hook</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5629">#5629</a> <a
href="9030fab2df"><code>9030fab2d</code></a>
Thanks <a
href="https://github.com/AlaricBaraou"><code>@AlaricBaraou</code></a>!
- Prevent unnecessary re-render in <code>FlowRenderer</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5592">#5592</a> <a
href="38dbf41c46"><code>38dbf41c4</code></a>
Thanks <a
href="https://github.com/svilen-ivanov-kubit"><code>@svilen-ivanov-kubit</code></a>!
- Always create a new measured object in apply changes.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5635">#5635</a> <a
href="2d7fa40e26"><code>2d7fa40e2</code></a>
Thanks <a
href="https://github.com/tornado-softwares"><code>@tornado-softwares</code></a>!
- Update an ongoing connection when user moves node with keyboard.</p>
</li>
<li>
<p>Updated dependencies [<a
href="0c7261a6dc"><code>0c7261a6d</code></a>,
<a
href="8598b6bc2a"><code>8598b6bc2</code></a>,
<a
href="2d7fa40e26"><code>2d7fa40e2</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.74</li>
</ul>
</li>
</ul>
<h2>12.9.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5621">#5621</a> <a
href="c1304dba7a"><code>c1304dba7</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Set <code>paneClickDistance</code> default value to
<code>1</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5578">#5578</a> <a
href="00bcb9f5f4"><code>00bcb9f5f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Pass
current pointer position to connection</p>
</li>
<li>
<p>Updated dependencies [<a
href="00bcb9f5f4"><code>00bcb9f5f</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.73</li>
</ul>
</li>
</ul>
<h2>12.9.2</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5593">#5593</a> <a
href="a8ee089d76"><code>a8ee089d7</code></a>
Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>!
- Reset selection box when user selects a node</li>
</ul>
<h2>12.9.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5572">#5572</a> <a
href="5ec0cac7fa"><code>5ec0cac7f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@peterkogo</code></a>! - Fix
onPaneClick events being suppressed when selectionOnDrag=true</p>
</li>
<li>
<p>Updated dependencies [<a
href="5ec0cac7fa"><code>5ec0cac7f</code></a>]:</p>
<ul>
<li><code>@xyflow/system</code><a
href="https://github.com/0"><code>@0</code></a>.0.72</li>
</ul>
</li>
</ul>
<h2>12.9.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5544">#5544</a> <a
href="c17b49f4c1"><code>c17b49f4c</code></a>
Thanks <a
href="https://github.com/0x0f0f0f"><code>@0x0f0f0f</code></a>! - Add
<code>EdgeToolbar</code> component</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c0ed3c33a3"><code>c0ed3c3</code></a>
chore(packages): bump</li>
<li><a
href="83a312b2e1"><code>83a312b</code></a>
chore(zIndexMode): use basic as default</li>
<li><a
href="14fd41b1f1"><code>14fd41b</code></a>
change default back to elevateEdgesOnSelect=false and
zIndexMode=basic</li>
<li><a
href="3680a6a0e6"><code>3680a6a</code></a>
Merge branch 'main' into feat/zindexmode</li>
<li><a
href="a523919d67"><code>a523919</code></a>
chore(middleware): cleanup</li>
<li><a
href="e4e3605d62"><code>e4e3605</code></a>
Merge branch 'main' into middlewares</li>
<li><a
href="2c05b3224a"><code>2c05b32</code></a>
Merge branch 'feat/zindexmode' of github.com:xyflow/xyflow into
feat/zindexmode</li>
<li><a
href="ddbb9280f6"><code>ddbb928</code></a>
chore(examples): add zindexmode</li>
<li><a
href="9faca3357d"><code>9faca33</code></a>
Merge branch 'main' into feat/zindexmode</li>
<li><a
href="4eb42952f0"><code>4eb4295</code></a>
feat(svelte): add zIndexMode</li>
<li>Additional commits viewable in <a
href="https://github.com/xyflow/xyflow/commits/@xyflow/react@12.10.0/packages/react">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline
### Why
The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.
### How
- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.
- moves workspace:* dependencies to dev-dependencies to avoid spreading
them in npm releases
- remove fix on rollup.external
- remove prepublishOnly and postpublish scripts
- set bundle packages to private
- add release-dump-version that update package.json version before
releasing to npm
- add release-verify-build that check no externalized twenty package
exists in `dist` before releasing to npm
- works with new release github action here ->
https://github.com/twentyhq/twenty-infra/pull/397
## Split twenty-sdk build into separate Node and browser targets
The SDK was bundling Node.js code (CLI, SDK API) and browser code (UI
components, front-component renderer) through a single Vite config. This
caused incorrect externalization — Node builtins leaked into browser
bundles and browser-specific chunking logic applied to CLI output.
This PR splits the build into `vite.config.node.ts` and
`vite.config.browser.ts` so each target gets the right externals and
output format.
Also includes a few housekeeping renames:
- `front-component` export path → `front-component-renderer` (matches
what it actually is)
- `front-component-common` merged into `front-component-api` (was a
needless extra module)
## Summary
- Removed `vite-plugin-dts` (which used `tsc` internally) from the Vite
build and replaced DTS generation with `tsgo` as a sequential post-build
step — **~0.7s vs 1-10s**.
- Disabled `reportCompressedSize` to skip gzip computation for 64 output
files.
- Converted the build target to an explicit `nx:run-commands` executor
with sequential `vite build` → `tsgo` commands.
The `twenty-emails:build` step goes from ~22s to ~7s under load.
## Test plan
- [x] `nx build twenty-emails` produces both JS (64 files) and DTS (74
files) correctly
- [x] `dist/index.d.ts` exports match the source `src/index.ts`
- [x] Full `nx build twenty-server` succeeds end-to-end
- [ ] CI build passes
Made with [Cursor](https://cursor.com)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
## Remove Recoil from twenty-ui
Completely removes the `recoil` dependency from `twenty-ui` by
converting all atoms, hooks, and providers to Jotai equivalents.
### twenty-ui
- `createState` now returns a Jotai `PrimitiveAtom` instead of a Recoil
atom
- `iconsState`, `IconsProvider`, `useIcons` converted to Jotai
(`useSetAtom`, `useAtomValue`)
- `RecoilRootDecorator` now uses Jotai `Provider` (name kept for compat)
- Deleted unused `invalidAvatarUrlsState` (Avatar already uses
`invalidAvatarUrlsAtomV2`)
- Removed `recoil` from `package.json`
### twenty-front
- Created local Recoil `createState` at
`@/ui/utilities/state/utils/createState` for ~112 state files still on
Recoil
- Updated all imports accordingly
- Removed `iconsState` from Recoil snapshot preservation in `useAuth`
(lives in Jotai store now)
## Recoil → Jotai progressive migration: infrastructure +
ChipFieldDisplay
### Benchmark
In the beginning, there was no hope:
<img width="1180" height="948" alt="image"
src="https://github.com/user-attachments/assets/f8635991-52e6-4958-8240-6ba7214132b2"
/>
Then the hope was reborn
<img width="2070" height="948" alt="image"
src="https://github.com/user-attachments/assets/be1182b9-1c8d-4fdc-ab4c-1484ad74449d"
/>
### Approach
We introduce a **V2 state management layer** backed by Jotai that
mirrors the existing Recoil API, enabling component-by-component
migration without a big-bang rewrite.
#### V2 API (Jotai-backed, Recoil-ergonomic)
- `createStateV2` / `createFamilyStateV2` — drop-in replacements for
`createState` / `createFamilyState`, returning wrapper types over Jotai
atoms
- `useRecoilValueV2`, `useRecoilStateV2`, `useFamilyRecoilValueV2`, etc.
— thin wrappers around Jotai's `useAtomValue` / `useAtom` / `useSetAtom`
- A shared `jotaiStore` (via `createStore()`) passed to a
`<JotaiProvider>` wrapping `<RecoilRoot>`, also accessible imperatively
for dual-writes
#### Dual-write bridge for progressive migration
For state shared between migrated and non-migrated components, we use
**dual-write**: writers update both the Recoil atom and the Jotai V2
atom (via `jotaiStore.set()`). This avoids sync components or extra
subscriptions.
Write sites updated: `useUpsertRecordsInStore`, `useSetRecordTableData`,
`ListenRecordUpdatesEffect`, `RecordShowEffect`,
`useLoadRecordIndexStates`, `useUpdateObjectViewOptions`.
#### First migration: ChipFieldDisplay render path
- `useChipFieldDisplay` → reads `recordStoreFamilyStateV2` via
`useFamilyRecoilValueV2` (was `useRecoilValue(recordStoreFamilyState)`)
- `RecordChip` → reads `recordIndexOpenRecordInStateV2` via
`useRecoilValueV2` (was `useRecoilValue(recordIndexOpenRecordInState)`)
- `Avatar` (twenty-ui) and event handlers (`useOpenRecordInCommandMenu`)
left on Recoil — not on the render path / in a different package
#### Pattern for migrating additional state
1. Create V2 atom: `createStateV2` or `createFamilyStateV2`
2. Add `jotaiStore.set(v2Atom, value)` at each write site
3. Switch readers to `useRecoilValueV2(v2Atom)`
4. Once all readers are migrated, remove the Recoil atom and dual-writes
#### Why not jotai-recoil-adapter?
Evaluated
[jotai-recoil-adapter](https://github.com/clockelliptic/jotai-recoil-adapter)
— not production-ready (21 open issues, no React 19, forces providerless
mode, missing types). We built a purpose-built thin layer instead.
Bumps
[react-loading-skeleton](https://github.com/dvtng/react-loading-skeleton)
from 3.4.0 to 3.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dvtng/react-loading-skeleton/releases">react-loading-skeleton's
releases</a>.</em></p>
<blockquote>
<h2>v3.5.0</h2>
<h3>Features</h3>
<ul>
<li>Add optional <code>customHighlightBackground</code> prop. (<a
href="https://redirect.github.com/dvtng/react-loading-skeleton/issues/233">#233</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/dvtng/react-loading-skeleton/blob/master/CHANGELOG.md">react-loading-skeleton's
changelog</a>.</em></p>
<blockquote>
<h2>3.5.0</h2>
<h3>Features</h3>
<ul>
<li>Add optional <code>customHighlightBackground</code> prop. (<a
href="https://redirect.github.com/dvtng/react-loading-skeleton/issues/233">#233</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f8b040dade"><code>f8b040d</code></a>
Merge pull request <a
href="https://redirect.github.com/dvtng/react-loading-skeleton/issues/233">#233</a>
from dvtng/srmagura/highlight-width</li>
<li><a
href="c0973458b8"><code>c097345</code></a>
Update changelog</li>
<li><a
href="d9f88d9eec"><code>d9f88d9</code></a>
update README</li>
<li><a
href="b1b27e8a2a"><code>b1b27e8</code></a>
Custom highlight background</li>
<li><a
href="d8c1492840"><code>d8c1492</code></a>
fix: Improved the type of styleOptionsToCssProperties (<a
href="https://redirect.github.com/dvtng/react-loading-skeleton/issues/222">#222</a>)</li>
<li>See full diff in <a
href="https://github.com/dvtng/react-loading-skeleton/compare/v3.4.0...v3.5.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Abdullah. <125115953+mabdullahabaid@users.noreply.github.com>
Bumps
[@types/bytes](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bytes)
from 3.1.4 to 3.1.5.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bytes">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com>
## Reduce type leakage between GraphQL schemas
### Why
Twenty runs two separate GraphQL schemas: **core** and **metadata**.
NestJS's `@nestjs/graphql` uses a global `TypeMetadataStorage` that
accumulates all decorated types across all modules. When each schema is
built, every registered type leaks into both schemas regardless of which
module it belongs to.
This means the core schema's generated TypeScript
(`generated/graphql.ts`) contained ~2,700 lines of types that only
belong to the metadata schema (and vice versa). This creates confusion
about type ownership, inflates generated code, and makes it harder to
reason about which API surface each schema actually exposes.
### How
**1. Patch `@nestjs/graphql` to support schema-scoped type resolution**
- **(Already done)** Added a `resolverSchemaScope` option to
`GqlModuleOptions`, allowing each schema to declare a scope (e.g.
`'metadata'`)
- `ResolversExplorerService` now filters resolvers by a
`RESOLVER_SCHEMA_SCOPE` metadata key, so each schema only sees its own
resolvers
- `GraphQLSchemaFactory` now performs a **reachability walk**
(`computeReachableTypes`) starting from scoped resolver return types and
arguments, only including types that are transitively referenced —
handling unions, interfaces, and prototype chains
- Type definition storage and orphaned reference registry are cleared
between schema builds to prevent cross-contamination
**2. Register `ClientConfig` as orphaned type in metadata schema**
Since `ClientConfig` is needed in the metadata schema but not directly
returned by a resolver, it's explicitly declared via
`buildSchemaOptions.orphanedTypes`.
**3. Regenerate frontend types and fix imports**
- `generated/graphql.ts` shrank by ~2,700 lines (types moved to where
they belong)
- `generated-metadata/graphql.ts` gained types like `ClientConfig` that
were previously missing
- ~500 frontend files updated to import from the correct generated file
## Add application-scoped GraphQL schema generation
When an application token is used to authenticate, the `/graphql` schema
is now dynamically filtered to only include entities belonging to that
application (plus the Twenty Standard Application). This enables
third-party applications and the SDK to introspect a schema that is
relevant to their scope, rather than seeing the full workspace schema
with all custom objects.
### Changes
- **New `generateApplicationToken` mutation** on the `/metadata`
endpoint, allowing callers to exchange an API key for an
application-scoped JWT token
- **Schema filtering by application** in `WorkspaceSchemaFactory` — when
`request.application` is present (from an application token), flat
entity maps are filtered by `[appId, standardAppId]` before schema
generation
- **Per-app caching** — both the Yoga in-memory cache and Redis cache
now include the `appId` in their keys to avoid serving wrong schemas
- **Consolidated `getSubFlatEntityMapsByApplicationIdsOrThrow`** —
unified the single-ID and multi-ID filtering utilities into one
- **Integration tests** covering token generation (admin + API key auth)
and schema introspection filtering (standard app token excludes custom
objects)
Schema generated on seeds with applicationToken (see that pets is
missing)
<img width="782" height="994" alt="image"
src="https://github.com/user-attachments/assets/82510031-0965-435d-bc26-77c9f5d74e1f"
/>
- Migration command
- Check IS_FILES_FIELD_MIGRATED:false
- Check or create avatarFile field
- Fetch all people with avatarUrl
- Move (Copy/move) file in storage
- Create core.file record
- Update person record
- bonus : attachment migration : fullPath > file (same logic)
- BE logic
- Add avatarFile field on person
- FE logic
- Adapt logic to upload on/display avatarFile data
The whole imageIdentifier logic will be done later
## Fix resolver schema leaking between `/metadata` and `/graphql`
endpoints
### Summary
- Patch `@nestjs/graphql` to support a `resolverSchemaScope` option that
filters resolvers at both schema generation and runtime, preventing
cross-endpoint leaking
- Introduce `@CoreResolver()` and `@MetadataResolver()` decorators to
explicitly scope each resolver to its endpoint
- Move most resolvers (auth, billing, workspace, user, etc.) to the
metadata schema where the frontend expects them; only workflow and
timeline calendar/messaging resolvers remain on `/graphql`
- Fix frontend `SSEQuerySubscribeEffect` to use the default (metadata)
Apollo client instead of the core client
### Problem
NestJS GraphQL's module-based resolver discovery traverses transitive
imports, causing resolvers from `/metadata` modules to leak into the
`/graphql` schema and vice versa. This made the schemas unpredictable
and tightly coupled to module import order.
### Approach
- Added `resolverSchemaScope` to `GqlModuleOptions` via a patch on
`@nestjs/graphql`, filtering in both `filterResolvers()` (runtime
binding) and `getAllCtors()` (schema generation)
- Each resolver is explicitly decorated with `@CoreResolver()` or
`@MetadataResolver()`
- Organized decorator, constant, and type files under `graphql-config/`
following project conventions
Core GQL Schema: (see: no more fields!)
<img width="827" height="894" alt="image"
src="https://github.com/user-attachments/assets/668f3f0f-485e-43f0-92be-4345aeccacb6"
/>
Metadata GQL Schema (see no more getTimelineCalendarEventsFromCompany)
<img width="827" height="894" alt="image"
src="https://github.com/user-attachments/assets/443913db-e5fe-4161-b0e7-4a971cc80a71"
/>
Last upgrade PR left stale entries for transitive import of Axios.
Raising this PR to fix and ensure Axios 1.13.5 is the de-facto in
yarn.lock for consistency.
⚠️ **AI-generated PR — not ready for review** ⚠️
cc @FelixMalfait
---
## Changes
### System prompt improvements
- Explicit skill-before-tools workflow to prevent the model from calling
tools without loading the matching skill first
- Data efficiency guidance (default small limits, use filters)
- Pluralized `load_skill` → `load_skills` for consistency with
`load_tools`
### Token usage reduction
- Output serialization layer: strips null/undefined/empty values from
tool results
- Lowered default `find_*` limit from 100 → 10, max from 1000 → 100
### System object tool generation
- System objects (calendar events, messages, etc.) now generate AI tools
- Only workflow-related and favorite-related objects are excluded
### Context window display fix
- **Bug**: UI compared cumulative tokens (sum of all turns) against
single-request context window → showed 100% after a few turns
- **Fix**: Track `conversationSize` (last step's `inputTokens`) which
represents the actual conversation history size sent to the model
- New `conversationSize` column on thread entity with migration
### Workspace AI instructions
- Support for custom workspace-level AI instructions
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Bumps [drizzle-kit](https://github.com/drizzle-team/drizzle-orm) from
0.31.5 to 0.31.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/drizzle-team/drizzle-orm/releases">drizzle-kit's
releases</a>.</em></p>
<blockquote>
<h2>drizzle-kit@0.31.8</h2>
<h3>Bug fixes</h3>
<ul>
<li>Fixed <code>algorythm</code> => <code>algorithm</code> typo.</li>
<li>Fixed external dependencies in build configuration.</li>
</ul>
<h2>drizzle-kit@0.31.6</h2>
<h3>Bug fixes</h3>
<ul>
<li><a
href="https://redirect.github.com/drizzle-team/drizzle-orm/issues/2853">[BUG]:
Importing drizzle-kit/api fails in ESM modules</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c445637df3"><code>c445637</code></a>
Merge pull request <a
href="https://redirect.github.com/drizzle-team/drizzle-orm/issues/5095">#5095</a>
from drizzle-team/main-workflows</li>
<li><a
href="e7b3aaa264"><code>e7b3aaa</code></a>
Merge branch 'main' into main-workflows</li>
<li><a
href="0d885a54dd"><code>0d885a5</code></a>
refactor: Update condition for run-feature job to improve clarity and
functio...</li>
<li><a
href="45a1ffbcbf"><code>45a1ffb</code></a>
Merge pull request <a
href="https://redirect.github.com/drizzle-team/drizzle-orm/issues/5087">#5087</a>
from drizzle-team/main-workflows</li>
<li><a
href="6357645bd3"><code>6357645</code></a>
chore: Comment out NEON_HTTP_CONNECTION_STRING requirement in release
workflows</li>
<li><a
href="53dec98a93"><code>53dec98</code></a>
refactor: Simplify release router workflow by removing unnecessary
switch job...</li>
<li><a
href="ce88a181e0"><code>ce88a18</code></a>
Merge remote-tracking branch 'origin/ext-deps-kit' into
main-workflows</li>
<li><a
href="5c8a4c508b"><code>5c8a4c5</code></a>
+</li>
<li><a
href="73e2ea486f"><code>73e2ea4</code></a>
feat: Add release router workflow to manage feature and latest
releases</li>
<li><a
href="378b0432d5"><code>378b043</code></a>
Merge pull request <a
href="https://redirect.github.com/drizzle-team/drizzle-orm/issues/5002">#5002</a>
from drizzle-team/main-next-pack</li>
<li>Additional commits viewable in <a
href="https://github.com/drizzle-team/drizzle-orm/compare/drizzle-kit@0.31.5...drizzle-kit@0.31.8">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by [GitHub Actions](<a
href="https://www.npmjs.com/~GitHub">https://www.npmjs.com/~GitHub</a>
Actions), a new releaser for drizzle-kit since your current version.</p>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com>
## Summary
The lockfile had a stale reference to `dist/cli/index.cjs` but the
twenty CLI bin was changed to `dist/cli.cjs`.
This was causing CI to fail with:
```
YN0028: - twenty: dist/cli/index.cjs
YN0028: + twenty: dist/cli.cjs
YN0028: The lockfile would have been modified by this install, which is explicitly forbidden.
```
This PR updates the lockfile to match the new path.
Bumps
[@cyntler/react-doc-viewer](https://github.com/cyntler/react-doc-viewer)
from 1.17.0 to 1.17.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cyntler/react-doc-viewer/releases"><code>@cyntler/react-doc-viewer</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v1.17.1</h2>
<ul>
<li>style: prettier fix tr.json (2392605)</li>
<li>Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/305">#305</a>
from wangyinyuan/main (36029ea)</li>
<li>Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/297">#297</a>
from ysaribulut/feature/turkish-translation (fa591ca)</li>
<li>fix: correct Chinese and special characters display in HTML renderer
(c358c9d)</li>
<li>Update README.md (e6fe4e0)</li>
<li>feat: add Turkish translations (4066963)</li>
<li>Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/290">#290</a>
from Pespiri/main (c6ded83)</li>
<li>fix styled components prop pollution (5bd551a)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="955795bca8"><code>955795b</code></a>
Release 1.17.1</li>
<li><a
href="2392605076"><code>2392605</code></a>
style: prettier fix tr.json</li>
<li><a
href="36029ea39c"><code>36029ea</code></a>
Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/305">#305</a>
from wangyinyuan/main</li>
<li><a
href="fa591caf45"><code>fa591ca</code></a>
Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/297">#297</a>
from ysaribulut/feature/turkish-translation</li>
<li><a
href="c358c9d103"><code>c358c9d</code></a>
fix: correct Chinese and special characters display in HTML
renderer</li>
<li><a
href="e6fe4e089b"><code>e6fe4e0</code></a>
Update README.md</li>
<li><a
href="4066963b06"><code>4066963</code></a>
feat: add Turkish translations</li>
<li><a
href="c6ded83f90"><code>c6ded83</code></a>
Merge pull request <a
href="https://redirect.github.com/cyntler/react-doc-viewer/issues/290">#290</a>
from Pespiri/main</li>
<li><a
href="5bd551a738"><code>5bd551a</code></a>
fix styled components prop pollution</li>
<li>See full diff in <a
href="https://github.com/cyntler/react-doc-viewer/compare/v1.17.0...v1.17.1">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- An app will declare its `twenty-sdk` version in the manifest.
- `twenty-sdk` will be served by a CDN to be imported in front component
host.
- When we render the host we will load twenty-ui through the correct
version of the sdk
We will proceed this way because twenty-ui is not mature enough yet to
be deployed as its own package. So instead, since the sdk is already
deployed as its own package, we will serve the ui with it. It allows us
to have versioning to handle breaking changes in twenty-ui.