3281d37bdf80098c411a4101736bfd7c5e568d8d
171
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
41ad63a8ab |
[DockerFile] Optimize twenty-server deps and build (#20132)
# Introduction Aiming for faster cd process ## Splitting front end server deps Reduce dependencies bloating when target is server only, installing only root repo dev deps and server dev and prod deps Still pruning before copying to prod node_modules ## Server only remove twenty-ui Also removing twenty-ui from server build as it was not consumed at all Depends on https://github.com/twentyhq/twenty/pull/20140 |
||
|
|
3c7c62c79f |
fix(server): deduplicate @opentelemetry/api to fix NoopMeterProvider (#20231)
## Summary **All OTel metrics in twenty-server have been silently dropped since April 30.** ### Root cause PR #20149 (`bump @sentry/profiling-node 10.27→10.51`) pulled in `@sentry/node@10.51.0`, which declares `@opentelemetry/api: ^1.9.1` as a **dependency** (not peer). Yarn installed it as a **nested** copy at `1.9.1`, while the hoisted copy stayed at `1.9.0`. At startup in `instrument.ts`: 1. `Sentry.init()` uses the **nested `1.9.1`** to register `trace`, `propagation`, `context` on the OTel global → global version becomes **`1.9.1`** 2. `setGlobalMeterProvider()` uses the **hoisted `1.9.0`** → `registerGlobal` sees version mismatch (`1.9.1` ≠ `1.9.0`) → **silently returns `false`** 3. Global stays `NoopMeterProvider` → every counter, gauge, and histogram in the server is a no-op ### What this PR does 1. **Reverts three troubleshooting PRs** that are no longer needed now that the root cause is identified: - #20230 — heartbeat gauge - #20228 — OTLP export lifecycle logs - #20221 — Sentry revert to 10.27 (which never actually downgraded in `yarn.lock` since `^10.27.0` resolved to `10.51.0`) 2. **Fixes the root cause**: - Root Yarn resolution pinning `@opentelemetry/api` to `1.9.1` → single copy in the entire tree, Sentry and Twenty share the same instance - Named import in `instrument.ts` (`import { metrics as otelMetrics }` instead of default import) as defense-in-depth against CJS interop issues ### Verified on dev cluster Exec'd into the running pod and confirmed: - `@sentry/node` nests `@opentelemetry/api@1.9.1`, hoisted is `1.9.0` - `Sentry.init()` → global version `1.9.1` → `setGlobalMeterProvider` with VERSION `1.9.0` → returns `false` → `NoopMeterProvider` - Same-version registration returns `true` → `MeterProvider` ✓ ## Test plan - [ ] CI passes (lint, typecheck, build) - [ ] Deploy to dev cluster and verify metrics flow to collector - [ ] Confirm `node_modules/@opentelemetry/api/package.json` shows `1.9.1` with no nested copy under `@sentry/` --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
ff22988caf |
revert: Sentry #20064 + @sentry 10.27 (prod bisect) (#20221)
## Summary Reverts **#20064** (`feat(sentry): propagate workspace context to all spans`) and downgrades **@sentry** packages from **10.51** back to **10.27** (reversing **#20149**), to validate in production whether recent Sentry/instrumentation changes correlate with OTLP/metrics issues. ## Changes 1. **Revert #20064** — removes `beforeSendSpan` from `instrument.ts`, restores `WorkspaceAuthContextMiddleware` / `BullMQDriver` behavior, and deletes the three `apply-workspace-sentry-*` utils added in that PR. 2. **Sentry versions** — `packages/twenty-server` (`@sentry/nestjs`, `@sentry/node`, `@sentry/profiling-node`) and `packages/twenty-front` (`@sentry/react`) set to `^10.27.0`; `yarn.lock` regenerated via `yarn install`. --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
8a0225e974 |
Dispatch root package.json hoisted deps and devDeps (#20140)
# Introduction Dispatching root package.json devDeps, prod deps Taking care of keeping non imported module used at build/ci level in the root package.json ## Motivation Avoid redundant deps declaration, better scoping allow better workspace deps granularity installation. <img width="385" height="247" alt="image" src="https://github.com/user-attachments/assets/9d7162ec-ba01-4f58-8563-38333733fdf0" /> --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
83db37d33f |
chore(deps): bump @sentry/profiling-node from 10.27.0 to 10.51.0 (#20149)
Bumps [@sentry/profiling-node](https://github.com/getsentry/sentry-javascript) from 10.27.0 to 10.51.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/getsentry/sentry-javascript/releases"><code>@sentry/profiling-node</code>'s releases</a>.</em></p> <blockquote> <h2>10.51.0</h2> <h3>Important Changes</h3> <ul> <li> <p><strong>feat(cloudflare): Add trace propagation for RPC method calls (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/20343">#20343</a>)</strong></p> <p>Trace context is now propagated across Cloudflare Workers RPC calls, connecting traces between Workers and Durable Objects. This feature is opt-in and requires setting <code>enableRpcTracePropagation: true</code> in your SDK configuration:</p> <pre lang="ts"><code>// Worker export default Sentry.withSentry( env => ({ dsn: env.SENTRY_DSN, enableRpcTracePropagation: true, }), handler, ); <p>// Durable Object<br /> export const MyDurableObject = Sentry.instrumentDurableObjectWithSentry(<br /> env => ({<br /> dsn: env.SENTRY_DSN,<br /> enableRpcTracePropagation: true,<br /> }),<br /> MyDurableObjectBase,<br /> );<br /> </code></pre></p> </li> <li> <p><strong>feat(hono)!: Change setup for <code>@sentry/hono/node</code> (<code>init</code> in external file) (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/20497">#20497</a>)</strong></p> <p>To improve Node.js instrumentation, the <code>sentry()</code> middleware exported from <code>@sentry/hono/node</code> no longer accepts configuration options. Instead, you must configure the SDK by calling <code>Sentry.init()</code> in a dedicated instrumentation file that runs before your application code (read more in the <a href="https://github.com/getsentry/sentry-javascript/blob/develop/packages/hono/README.md">Hono SDK readme</a>:</p> <pre lang="ts"><code>// instrument.mjs (or instrument.ts) import * as Sentry from '@sentry/hono/node'; <p>Sentry.init({<br /> dsn: '<strong>DSN</strong>',<br /> tracesSampleRate: 1.0,<br /> });<br /> </code></pre></p> </li> <li> <p><strong>feat(nitro): Add <code>@sentry/nitro</code> SDK (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19224">#19224</a>)</strong></p> <p>A new <code>@sentry/nitro</code> package provides first-class Sentry support for <a href="https://nitro.build/">Nitro</a> applications, with HTTP handler and error instrumentation, middleware tracing, request isolation, and build-time source map uploading via <code>withSentryConfig</code>. Read more in the <a href="https://docs.sentry.io/platforms/javascript/guides/nitro/">Nitro SDK docs</a> and the <a href="https://github.com/getsentry/sentry-javascript/blob/develop/packages/nitro/README.md">Nitro SDK readme</a>.</p> </li> </ul> <h3>Other Changes</h3> <!-- 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/profiling-node</code>'s changelog</a>.</em></p> <blockquote> <h2>10.51.0</h2> <h3>Important Changes</h3> <ul> <li> <p><strong>feat(cloudflare): Add trace propagation for RPC method calls (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/20343">#20343</a>)</strong></p> <p>Trace context is now propagated across Cloudflare Workers RPC calls, connecting traces between Workers and Durable Objects. This feature is opt-in and requires setting <code>enableRpcTracePropagation: true</code> in your SDK configuration:</p> <pre lang="ts"><code>// Worker export default Sentry.withSentry( env => ({ dsn: env.SENTRY_DSN, enableRpcTracePropagation: true, }), handler, ); <p>// Durable Object<br /> export const MyDurableObject = Sentry.instrumentDurableObjectWithSentry(<br /> env => ({<br /> dsn: env.SENTRY_DSN,<br /> enableRpcTracePropagation: true,<br /> }),<br /> MyDurableObjectBase,<br /> );<br /> </code></pre></p> </li> <li> <p><strong>feat(hono)!: Change setup for <code>@sentry/hono/node</code> (<code>init</code> in external file) (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/20497">#20497</a>)</strong></p> <p>To improve Node.js instrumentation, the <code>sentry()</code> middleware exported from <code>@sentry/hono/node</code> no longer accepts configuration options. Instead, you must configure the SDK by calling <code>Sentry.init()</code> in a dedicated instrumentation file that runs before your application code (read more in the <a href="https://github.com/getsentry/sentry-javascript/blob/develop/packages/hono/README.md">Hono SDK readme</a>:</p> <pre lang="ts"><code>// instrument.mjs (or instrument.ts) import * as Sentry from '@sentry/hono/node'; <p>Sentry.init({<br /> dsn: '<strong>DSN</strong>',<br /> tracesSampleRate: 1.0,<br /> });<br /> </code></pre></p> </li> <li> <p><strong>feat(nitro): Add <code>@sentry/nitro</code> SDK (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19224">#19224</a>)</strong></p> <p>A new <code>@sentry/nitro</code> package provides first-class Sentry support for <a href="https://nitro.build/">Nitro</a> applications, with HTTP handler and error instrumentation, middleware tracing, request isolation, and build-time source map uploading via <code>withSentryConfig</code>. Read more in the <a href="https://docs.sentry.io/platforms/javascript/guides/nitro/">Nitro SDK docs</a> and the <a href="https://github.com/getsentry/sentry-javascript/blob/develop/packages/nitro/README.md">Nitro SDK readme</a>.</p> </li> </ul> <h3>Other Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/getsentry/sentry-javascript/commit/dc0b839ff4896cf90a02f5c1a6de54a31302dcf3"><code>dc0b839</code></a> release: 10.51.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/b3cabee9a9348b9e67332262d44d3d1900424199"><code>b3cabee</code></a> Merge pull request <a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20599">#20599</a> from getsentry/prepare-release/10.51.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/3be99a9afa77e49578e6839e4b32f97fb04fb0f8"><code>3be99a9</code></a> meta(changelog): Update changelog for 10.51.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/bea1aad42277db894d5a299bfec3cdd633d6baf0"><code>bea1aad</code></a> test(browser): Unflake some more tests (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20591">#20591</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/50aa0859b3a188d34d0317dab3ad57f2140f02fe"><code>50aa085</code></a> test(node): Unflake postgres tests (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20593">#20593</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/1166839112c4766f210124dc0486ebbfd6db104b"><code>1166839</code></a> fix(hono): Distinguish <code>.use()</code> middleware in sub-apps from <code>.all()</code> handlers...</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/217ad4a69554281806eccbfeac1b27c4f43f6ffa"><code>217ad4a</code></a> test(node): Fix flaky ANR test (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20592">#20592</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/91ffb3fac90835ab160f8152527a54a5d64f3250"><code>91ffb3f</code></a> test(node): Fix flaky worker thread integration test (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20588">#20588</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/c4e3902c9297147158e730f017aba96e83ef619e"><code>c4e3902</code></a> chore(ci): Do not report flaky test issues if we cannot find a test name (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20">#20</a>...</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/c0005cd387f3a7ea6fbb2e85041562c7f32e0484"><code>c0005cd</code></a> test(node): Update timeout for cron integration tests (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/20586">#20586</a>)</li> <li>Additional commits viewable in <a href="https://github.com/getsentry/sentry-javascript/compare/10.27.0...10.51.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: Charles Bochet <charles@twenty.com> |
||
|
|
89ad87aa64 |
Make twenty-front build env agnostic (#20055)
## Introduction
In aim to reduce and optimize the number of twenty-front build we do
during our cd process and allow twenty-front build promotion
### Build time
**Nothing is baked.** The `build/` directory is a clean, env-agnostic
artifact. `index.html` contains the empty placeholder:
```html
<script id="twenty-env-config">
window._env_ = {
// This will be overwritten
};
</script>
```
The JS bundles contain no hardcoded server URL.
---
### Deploy mode 1: Frontend served by the backend (Docker / NestJS)
1. Container starts, NestJS boots in `main.ts`
2. `generateFrontConfig()` runs, reads `process.env.SERVER_URL`
3. Rewrites `dist/front/index.html`, replacing the placeholder with:
```html
<script id="twenty-env-config">
window._env_ = {
REACT_APP_SERVER_BASE_URL: "https://api.example.com"
};
</script>
```
4. NestJS serves the static `dist/front/` directory
5. Browser loads `index.html`, `window._env_` is set before the app JS
executes
6. `src/config/index.ts` reads `window._env_.REACT_APP_SERVER_BASE_URL`
and uses it
---
### Deploy mode 2: Frontend served standalone (CDN / nginx / static
server)
1. Take the `build/` artifact as-is
2. Before serving, run at deploy time:
```bash
REACT_APP_SERVER_BASE_URL=https://api.example.com sh
./scripts/inject-runtime-env.sh
```
3. This does the same `sed` replacement on `build/index.html`
4. Serve the `build/` directory with your static server of choice
5. Same resolution in the browser:
`window._env_.REACT_APP_SERVER_BASE_URL` is picked up by
`src/config/index.ts`
---
### Fallback: no injection at all
If neither mechanism runs (e.g. local dev with `vite dev`),
`window._env_.REACT_APP_SERVER_BASE_URL` is `undefined`, and
`getDefaultUrl()` kicks in:
- **Localhost**: returns `http://localhost:3000`
- **Non-localhost**: returns same-origin (`window.location.origin`)
|
||
|
|
80e8f6d516 |
chore(deps): bump @blocknote/server-util from 0.47.1 to 0.47.3 (#19997)
Bumps [@blocknote/server-util](https://github.com/TypeCellOS/BlockNote/tree/HEAD/packages/server-util) from 0.47.1 to 0.47.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/TypeCellOS/BlockNote/releases"><code>@blocknote/server-util</code>'s releases</a>.</em></p> <blockquote> <h2>v0.47.3</h2> <h2>0.47.3 (2026-03-25)</h2> <h3>🩹 Fixes</h3> <ul> <li><strong>core:</strong> preserve whitespace edge cases but collapse html formatting newlines (BLO-1065) (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2551">#2551</a>, <a href="https://redirect.github.com/TypeCellOS/BlockNote/issues/2230">#2230</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Yousef</li> </ul> <h2>v0.47.2</h2> <h2>0.47.2 (2026-03-20)</h2> <h3>🩹 Fixes</h3> <ul> <li>use <code><details></code> & <code><summary></code> for toggle block HTML export (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2524">#2524</a>)</li> <li>remove <code>@hocuspocus/provider</code> peer dependency by inlining tiptap comment types BLO-1064 (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2564">#2564</a>)</li> <li><strong>core:</strong> slash menu fails in custom blocks after space BLO-1036 (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2553">#2553</a>)</li> <li><strong>i18n:</strong> fix typo in russian translation (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2560">#2560</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Drone</li> <li>Yousef</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/TypeCellOS/BlockNote/blob/main/CHANGELOG.md"><code>@blocknote/server-util</code>'s changelog</a>.</em></p> <blockquote> <h2>0.47.3 (2026-03-25)</h2> <h3>🩹 Fixes</h3> <ul> <li><strong>core:</strong> preserve whitespace edge cases but collapse html formatting newlines (BLO-1065) (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2551">#2551</a>, <a href="https://redirect.github.com/TypeCellOS/BlockNote/issues/2230">#2230</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Yousef</li> </ul> <h2>0.47.2 (2026-03-20)</h2> <h3>🩹 Fixes</h3> <ul> <li>use <!-- raw HTML omitted -->/<!-- raw HTML omitted --> for toggle block HTML export (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2524">#2524</a>)</li> <li>remove <code>@hocuspocus/provider</code> peer dependency by inlining tiptap comment types BLO-1064 (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2564">#2564</a>)</li> <li><strong>core:</strong> slash menu fails in custom blocks after space BLO-1036 (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2553">#2553</a>)</li> <li><strong>i18n:</strong> fix typo in russian translation (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2560">#2560</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Claude Opus 4.6</li> <li>Drone</li> <li>Yousef</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/TypeCellOS/BlockNote/commit/cd92dc21be49397b658fef4e308e01ce8f5c04ad"><code>cd92dc2</code></a> chore(release): publish 0.47.3</li> <li><a href="https://github.com/TypeCellOS/BlockNote/commit/b63b4096daa575f821980ef897fd90f4c76d9e42"><code>b63b409</code></a> chore(release): publish 0.47.2</li> <li><a href="https://github.com/TypeCellOS/BlockNote/commit/d76fd68e016da698f3896f9d349a935a26a52d5f"><code>d76fd68</code></a> test: get snapshots working again (<a href="https://github.com/TypeCellOS/BlockNote/tree/HEAD/packages/server-util/issues/2554">#2554</a>)</li> <li>See full diff in <a href="https://github.com/TypeCellOS/BlockNote/commits/v0.47.3/packages/server-util">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> |
||
|
|
fd7387928c |
feat: queue messages + replace AI SDK with GraphQL SSE subscription (#19203)
## Summary - **Queue messages while streaming**: Messages sent during active AI streaming are queued server-side and auto-flushed when the current stream completes. Frontend renders queued messages optimistically in a dedicated queue UI. - **Drop `@ai-sdk/react` + `resumable-stream`**: Replace the dual HTTP SSE + AI SDK client architecture with a single GraphQL SSE subscription per thread. All events (token chunks, message persistence, queue updates, errors) flow through Redis PubSub → GraphQL subscription. - **Server-driven architecture**: The server decides whether to queue or stream (via `POST /:threadId/message`). The frontend mirrors this decision for optimistic rendering but defers to the server response. - **Reuse AI SDK accumulation logic**: `readUIMessageStream` from the `ai` package handles chunk-to-message accumulation on the frontend, avoiding a custom 780-line accumulator. ## Key files **Backend:** - `agent-chat-event-publisher.service.ts` — publishes events to Redis PubSub - `agent-chat-subscription.resolver.ts` — GraphQL subscription resolver - `stream-agent-chat.job.ts` — publishes chunks via PubSub instead of resumable-stream - `agent-chat.controller.ts` — unified `POST /:threadId/message` endpoint **Frontend:** - `useAgentChatSubscription.ts` — subscribes to `onAgentChatEvent`, bridges to `readUIMessageStream` - `useAgentChat.ts` — send/stop/optimistic rendering (no more AI SDK) - `AgentChatStreamSubscriptionEffect.tsx` — replaces `AgentChatAiSdkStreamEffect.tsx` ## Test plan - [ ] Send message on new thread → optimistic render, streaming response appears - [ ] Send message while streaming → queued instantly (no flash in main thread) - [ ] Queued message auto-flushes after current stream completes - [ ] Remove queued message via queue UI - [ ] Stop streaming mid-response - [ ] Leave chat idle for several minutes → streaming still works after (SSE client recycling) - [ ] Token refresh during session → requests succeed (authenticated fetch) - [ ] Switch threads while streaming → clean subscription handoff Made with [Cursor](https://cursor.com) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
37908114fc |
[SDK] Extract twenty-front-component-renderer outside of twenty-sdk ( 2.8MB ) (#19021)
Followup https://github.com/twentyhq/twenty/pull/19010 ## Dependency diagram ``` ┌─────────────────────┐ │ twenty-front │ │ (React frontend) │ └─────────┬───────────┘ │ imports runtime: │ FrontComponentRenderer │ FrontComponentRendererWithSdkClient │ useFrontComponentExecutionContext ▼ ┌──────────────────────────────────┐ ┌─────────────────────────┐ │ twenty-front-component-renderer │────────▶│ twenty-sdk │ │ (remote-dom host + worker) │ │ (app developer SDK) │ │ │ │ │ │ imports from twenty-sdk: │ │ Public API: │ │ • types only: │ │ defineFrontComponent │ │ FrontComponentExecutionContext│ │ navigate, closeSide… │ │ NavigateFunction │ │ useFrontComponent… │ │ CloseSidePanelFunction │ │ Command components │ │ CommandConfirmation… │ │ conditional avail. │ │ OpenCommandConfirmation… │ │ │ │ EnqueueSnackbarFunction │ │ Internal only: │ │ etc. │ │ frontComponentHost… │ │ │ │ front-component-build │ │ owns locally: │ │ esbuild plugins │ │ • ALLOWED_HTML_ELEMENTS │ │ │ │ • EVENT_TO_REACT │ └────────────┬────────────┘ │ • HTML_TAG_TO_CUSTOM_ELEMENT… │ │ │ • SerializedEventData │ │ types │ • PropertySchema │ ▼ │ • frontComponentHostComm… │ ┌─────────────────────────┐ │ (local ref to globalThis) │ │ twenty-shared │ │ • setFrontComponentExecution… │ │ (common types/utils) │ │ (local impl, same keys) │ │ AppPath, SidePanelP… │ │ │ │ EnqueueSnackbarParams │ └──────────────────────────────────┘ │ isDefined, … │ │ └─────────────────────────┘ │ also depends on ▼ twenty-shared (types) @remote-dom/* (runtime) @quilted/threads (runtime) react (runtime) ``` **Key points:** - **`twenty-front`** depends on the renderer, **not** on `twenty-sdk` directly (for rendering) - **`twenty-front-component-renderer`** depends on `twenty-sdk` for **types only** (function signatures, `FrontComponentExecutionContext`). The runtime bridge (`frontComponentHostCommunicationApi`) is shared via `globalThis` keys, not module imports - **`twenty-sdk`** has no dependency on the renderer — clean one-way dependency - The renderer owns all remote-dom infrastructure (element schemas, event mappings, custom element tags) that was previously leaking through the SDK's public API - The SDK's `./build` entry point was removed entirely (unused) |
||
|
|
b470cb21a1 |
Upgrade Apollo Client to v4 and refactor error handling (#18584)
## Summary This PR upgrades Apollo Client from v3.10.0 to v4 and refactors error handling patterns across the codebase to use a new centralized `useSnackBarOnQueryError` hook. ## Key Changes - **Dependency Update**: Upgraded `@apollo/client` from `^3.10.0` to `^3.11.0` in root package.json - **New Hook**: Added `useSnackBarOnQueryError` hook for centralized Apollo query error handling with snack bar notifications - **Error Handling Refactor**: Updated 100+ files to use the new error handling pattern: - Removed direct `ApolloError` imports where no longer needed - Replaced manual error handling logic with `useSnackBarOnQueryError` hook - Simplified error handling in hooks and components across multiple modules - **GraphQL Codegen**: Updated codegen configuration files to work with Apollo Client v3.11.0 - **Type Definitions**: Added TypeScript declaration file for `apollo-upload-client` module - **Test Updates**: Updated test files to reflect new error handling patterns ## Notable Implementation Details - The new `useSnackBarOnQueryError` hook provides a consistent way to handle Apollo query errors with automatic snack bar notifications - Changes span across multiple feature areas: auth, object records, settings, workflows, billing, and more - All changes maintain backward compatibility while improving code maintainability and reducing duplication - Jest configuration updated to work with the new Apollo Client version https://claude.ai/code/session_019WGZ6Rd7sEHuBg9sTrXRqJ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5b28e59ca7 | Navbar drag drop using dnd kit (#18288) | ||
|
|
9d57bc39e5 |
Migrate from ESLint to OxLint (#18443)
## Summary Fully replaces ESLint with OxLint across the entire monorepo: - **Replaced all ESLint configs** (`eslint.config.mjs`) with OxLint configs (`.oxlintrc.json`) for every package: `twenty-front`, `twenty-server`, `twenty-emails`, `twenty-ui`, `twenty-shared`, `twenty-sdk`, `twenty-zapier`, `twenty-docs`, `twenty-website`, `twenty-apps/*`, `create-twenty-app` - **Migrated custom lint rules** from ESLint plugin format to OxLint JS plugin system (`@oxlint/plugins`), including `styled-components-prefixed-with-styled`, `no-hardcoded-colors`, `sort-css-properties-alphabetically`, `graphql-resolvers-should-be-guarded`, `rest-api-methods-should-be-guarded`, `max-consts-per-file`, and Jotai-related rules - **Migrated custom rule tests** from ESLint `RuleTester` + Jest to `oxlint/plugins-dev` `RuleTester` + Vitest - **Removed all ESLint dependencies** from `package.json` files and regenerated lockfiles - **Updated Nx targets** (`lint`, `lint:diff-with-main`, `fmt`) in `nx.json` and per-project `project.json` to use `oxlint` commands with proper `dependsOn` for plugin builds - **Updated CI workflows** (`.github/workflows/ci-*.yaml`) — no more ESLint executor - **Updated IDE setup**: replaced `dbaeumer.vscode-eslint` with `oxc.oxc-vscode` extension, configured `source.fixAll.oxc` and format-on-save with Prettier - **Replaced all `eslint-disable` comments** with `oxlint-disable` equivalents across the codebase - **Updated docs** (`twenty-docs`) to reference OxLint instead of ESLint - **Renamed** `twenty-eslint-rules` package to `twenty-oxlint-rules` ### Temporarily disabled rules (tracked in `OXLINT_MIGRATION_TODO.md`) | Rule | Package | Violations | Auto-fixable | |------|---------|-----------|-------------| | `twenty/sort-css-properties-alphabetically` | twenty-front | 578 | Yes | | `typescript/consistent-type-imports` | twenty-server | 3814 | Yes | | `twenty/max-consts-per-file` | twenty-server | 94 | No | ### Dropped plugins (no OxLint equivalent) `eslint-plugin-project-structure`, `lingui/*`, `@stylistic/*`, `import/order`, `prefer-arrow/prefer-arrow-functions`, `eslint-plugin-mdx`, `@next/eslint-plugin-next`, `eslint-plugin-storybook`, `eslint-plugin-react-refresh`. Partial coverage for `jsx-a11y` and `unused-imports`. ### Additional fixes (pre-existing issues exposed by merge) - Fixed `EmailThreadPreview.tsx` broken import from main rename (`useOpenEmailThreadInSidePanel`) - Restored truthiness guard in `getActivityTargetObjectRecords.ts` - Fixed `AgentTurnResolver` return types to match entity (virtual `fileMediaType`/`fileUrl` are resolved via `@ResolveField()`) ## Test plan - [x] `npx nx lint twenty-front` passes - [x] `npx nx lint twenty-server` passes - [x] `npx nx lint twenty-docs` passes - [x] Custom oxlint rules validated with Vitest: `npx nx test twenty-oxlint-rules` - [x] `npx nx typecheck twenty-front` passes - [x] `npx nx typecheck twenty-server` passes - [x] CI workflows trigger correctly with `dependsOn: ["twenty-oxlint-rules:build"]` - [x] IDE linting works with `oxc.oxc-vscode` extension |
||
|
|
1affa1e004 |
chore(front): remove vite-plugin-checker background TS/ESLint checks (#18437)
## Summary Removes `vite-plugin-checker` and all references to `VITE_DISABLE_TYPESCRIPT_CHECKER` / `VITE_DISABLE_ESLINT_CHECKER`. These background checks are no longer needed because our dev experience now relies on **independent** linters and type-checkers: - `npx nx lint:diff-with-main twenty-front` for ESLint - `npx nx typecheck twenty-front` for TypeScript Running these as separate processes (rather than inside Vite) is faster, gives cleaner output, and avoids the significant memory overhead that `vite-plugin-checker` introduces during `vite dev` and `vite build`. The old env vars to disable them are removed from `vite.config.ts`, `package.json` scripts, `nx.json`, `.env.example`, and all translated docs. |
||
|
|
6a2e0182ab |
Bump @blocknote/server-util from 0.47.0 to 0.47.1 (#18408)
Bumps [@blocknote/server-util](https://github.com/TypeCellOS/BlockNote/tree/HEAD/packages/server-util) from 0.47.0 to 0.47.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/TypeCellOS/BlockNote/releases"><code>@blocknote/server-util</code>'s releases</a>.</em></p> <blockquote> <h2>v0.47.1</h2> <h2>0.47.1 (2026-03-02)</h2> <h3>🩹 Fixes</h3> <ul> <li>typeerror cannot read properties of undefined (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2522">#2522</a>)</li> <li>handle more delete key cases (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2126">#2126</a>)</li> <li>add delay for <code>data-active</code> in collab cursors (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2383">#2383</a>)</li> <li>disable slash menu in table content <a href="https://github.com/TypeCellOS/BlockNote/tree/HEAD/packages/server-util/issues/2408">#2408</a> (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2504">#2504</a>, <a href="https://redirect.github.com/TypeCellOS/BlockNote/issues/2408">#2408</a>)</li> <li><strong>ai:</strong> selections broken due to floating-ui focus manager (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2527">#2527</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Matthew Lipski <a href="https://github.com/matthewlipski"><code>@matthewlipski</code></a></li> <li>Nick Perez</li> <li>Yousef</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/TypeCellOS/BlockNote/blob/main/CHANGELOG.md"><code>@blocknote/server-util</code>'s changelog</a>.</em></p> <blockquote> <h2>0.47.1 (2026-03-02)</h2> <h3>🩹 Fixes</h3> <ul> <li>typeerror cannot read properties of undefined (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2522">#2522</a>)</li> <li>handle more delete key cases (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2126">#2126</a>)</li> <li>add delay for <code>data-active</code> in collab cursors (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2383">#2383</a>)</li> <li>disable slash menu in table content <a href="https://github.com/TypeCellOS/BlockNote/tree/HEAD/packages/server-util/issues/2408">#2408</a> (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2504">#2504</a>, <a href="https://redirect.github.com/TypeCellOS/BlockNote/issues/2408">#2408</a>)</li> <li><strong>ai:</strong> selections broken due to floating-ui focus manager (<a href="https://redirect.github.com/TypeCellOS/BlockNote/pull/2527">#2527</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Matthew Lipski <a href="https://github.com/matthewlipski"><code>@matthewlipski</code></a></li> <li>Nick Perez</li> <li>Yousef</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/TypeCellOS/BlockNote/commit/d5d056fe3d5362e73fb72e3e3bf1f839aee3e875"><code>d5d056f</code></a> chore(release): publish 0.47.1</li> <li>See full diff in <a href="https://github.com/TypeCellOS/BlockNote/commits/v0.47.1/packages/server-util">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> |
||
|
|
72086fe111 |
Bump @dagrejs/dagre from 1.1.3 to 1.1.8 (#18409)
Bumps [@dagrejs/dagre](https://github.com/dagrejs/dagre) from 1.1.3 to 1.1.8. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/dagrejs/dagre/commit/7e4d15f191678f7f05f3c86d9071a193230e7e00"><code>7e4d15f</code></a> Building for release</li> <li><a href="https://github.com/dagrejs/dagre/commit/d3908e2c13148c9143db585accc10ae0b6634657"><code>d3908e2</code></a> Bumping version</li> <li><a href="https://github.com/dagrejs/dagre/commit/ce295f8e073c4fe96c9e36ecf08ae2940e5e6a10"><code>ce295f8</code></a> Build for release</li> <li><a href="https://github.com/dagrejs/dagre/commit/b64b9057726eee17f24f73579ba0668527276448"><code>b64b905</code></a> Bumping the version</li> <li><a href="https://github.com/dagrejs/dagre/commit/de169d24c13d06c1e9c560f4f4f8f98650109b94"><code>de169d2</code></a> Merge pull request <a href="https://redirect.github.com/dagrejs/dagre/issues/481">#481</a> from Nathan-Fenner/nf/improve-network-simplex-perform...</li> <li><a href="https://github.com/dagrejs/dagre/commit/065e0d8374f4c1c35a7cb4b84df37aaa31598d86"><code>065e0d8</code></a> improve performance of graph node ranking</li> <li><a href="https://github.com/dagrejs/dagre/commit/00d3178d671e49de9c032e3abd281dc9f2739e73"><code>00d3178</code></a> Typo</li> <li><a href="https://github.com/dagrejs/dagre/commit/3982a69d2b323b06aa969a4ec09829d37fe6e7bd"><code>3982a69</code></a> Bump version and set as pre-release</li> <li><a href="https://github.com/dagrejs/dagre/commit/1339f5516508dba0cbcc4ef1c0587e7384bec23d"><code>1339f55</code></a> Building for release</li> <li><a href="https://github.com/dagrejs/dagre/commit/9459f01bc815f16b87db727821d8401acbad2cd3"><code>9459f01</code></a> Bumping the version</li> <li>Additional commits viewable in <a href="https://github.com/dagrejs/dagre/compare/v1.1.3...v1.1.8">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> |
||
|
|
76c7639eb3 |
fix: upgrade storybook to latest to resolve dependabot alert (#18285)
Resolves [Dependabot Alert 509](https://github.com/twentyhq/twenty/security/dependabot/509). Upgraded storybook and related packages to latest, also fixed a failing test to match what the DOM really contains. |
||
|
|
4ed09a3feb |
Upgrade blocknote dependencies from 0.31.1 to 0.47.0. (#18207)
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 |
||
|
|
9107f5bbc7 |
feat: upgrade ai package to version six and the corresponding @ai-sdk/* packages to compatible versions (#18172)
Used the migration guide to carry out this upgrade: https://ai-sdk.dev/docs/migration-guides/migration-guide-6-0 I have not been able to test locally due to credits. <img width="220" height="450" alt="image" src="https://github.com/user-attachments/assets/050b34b9-3239-4010-8c47-b43d44571994" /> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
121788c42f |
Fully deprecate old recoil (#18210)
## Summary Removes the `recoil` dependency entirely from `package.json` and `twenty-front/package.json`, completing the migration to Jotai as the sole state management library. Removes all Recoil infrastructure: `RecoilRoot` wrapper from `App.tsx` and test decorators, `RecoilDebugObserver`, Recoil-specific ESLint rules (`use-getLoadable-and-getValue-to-get-atoms`, `useRecoilCallback-has-dependency-array`), and legacy Recoil utility hooks/types (`useRecoilComponentState`, `useRecoilComponentValue`, `createComponentState`, `createFamilyState`, `getSnapshotValue`, `cookieStorageEffect`, `localStorageEffect`, etc.). Renames all `V2`-suffixed Jotai state files and types to their canonical names (e.g., `ComponentStateV2` -> `ComponentState`, `agentChatInputStateV2` -> `agentChatInputState`, `SelectorCallbacksV2` -> `SelectorCallbacks`), and removes the now-redundant V1 counterparts. Updates ~433 files across the codebase to use the renamed Jotai imports, remove Recoil imports, and clean up test wrappers (`RecoilRootDecorator` -> `JotaiRootDecorator`). |
||
|
|
0e25aeb5be |
chore: upgrade @swc/core to 1.15.11 and align SWC ecosystem (#18088)
## 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> |
||
|
|
d2f8352cb8 |
Start Jotai Migration (#17893)
## 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. |
||
|
|
f0bc9fcb43 |
[FRONT COMPONENTS] Move to twenty-sdk (#17587)
Move front components from twenty-shared to twenty-sdk |
||
|
|
fb97c40cad |
[Dashboards] Replace nivo bar chart with custom canvas bar chart (#17441)
before - https://github.com/user-attachments/assets/01d1ce73-1732-4516-bde0-d43c1bbcb734 after - I got rid of line chart in the after clip -- because now its the line chart thats more laggy :) -- but now could be easily migrated away from nivo https://github.com/user-attachments/assets/430f4697-68cd-47be-b63e-f8df34a2ee0e stress test - before - https://github.com/user-attachments/assets/c3d3e05c-943e-48dc-9429-a2ecf41cd4fe after - https://github.com/user-attachments/assets/98b35a43-f918-4a46-9b66-3bc8deabfdb8 --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com> |
||
|
|
2b60e41374 |
build(deps-dev): bump @typescript-eslint/parser from 8.39.0 to 8.51.0 (#16926)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.39.0 to 8.51.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@typescript-eslint/parser</code>'s releases</a>.</em></p> <blockquote> <h2>v8.51.0</h2> <h2>8.51.0 (2025-12-29)</h2> <h3>🚀 Features</h3> <ul> <li><strong>eslint-plugin:</strong> expose rule name via RuleModule interface (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11719">#11719</a>)</li> <li><strong>eslint-plugin:</strong> [no-useless-default-assignment] fix some cases to optional syntax (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11871">#11871</a>)</li> <li><strong>eslint-plugin:</strong> add namespace to plugin meta (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11885">#11885</a>)</li> <li><strong>tsconfig-utils:</strong> more informative error on parsing failures (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11888">#11888</a>)</li> </ul> <h3>🩹 Fixes</h3> <ul> <li><strong>eslint-plugin:</strong> fix crash and false positives in <code>no-useless-default-assignment</code> (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11845">#11845</a>)</li> <li><strong>eslint-plugin:</strong> remove fixable from no-dynamic-delete rule (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11876">#11876</a>)</li> <li><strong>eslint-plugin:</strong> bump ts-api-utils to 2.2.0 (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11881">#11881</a>)</li> <li><strong>eslint-plugin:</strong> [prefer-optional-chain] handle MemberExpression in final chain position (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11835">#11835</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Josh Goldberg ✨</li> <li>Kirk Waiblinger <a href="https://github.com/kirkwaiblinger"><code>@kirkwaiblinger</code></a></li> <li>mdm317</li> <li>Ulrich Stark</li> <li>Yannick Decat <a href="https://github.com/mho22"><code>@mho22</code></a></li> <li>Yukihiro Hasegawa <a href="https://github.com/y-hsgw"><code>@y-hsgw</code></a></li> </ul> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>v8.50.1</h2> <h2>8.50.1 (2025-12-22)</h2> <h3>🩹 Fixes</h3> <ul> <li><strong>eslint-plugin:</strong> [method-signature-style] ignore methods that return <code>this</code> (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11813">#11813</a>)</li> <li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion] correct handling of undefined vs. void (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11826">#11826</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Josh Goldberg ✨</li> <li>Tamashoo <a href="https://github.com/Tamashoo"><code>@Tamashoo</code></a></li> </ul> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>v8.50.0</h2> <h2>8.50.0 (2025-12-15)</h2> <h3>🚀 Features</h3> <ul> <li><strong>eslint-plugin:</strong> [no-useless-default-assignment] add rule (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11720">#11720</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md"><code>@typescript-eslint/parser</code>'s changelog</a>.</em></p> <blockquote> <h2>8.51.0 (2025-12-29)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.50.1 (2025-12-22)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.50.0 (2025-12-15)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.49.0 (2025-12-08)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.48.1 (2025-12-02)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.48.0 (2025-11-24)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.47.0 (2025-11-17)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.46.4 (2025-11-10)</h2> <p>This was a version bump only for parser to align it with other projects, there were no code changes.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> <h2>8.46.3 (2025-11-03)</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/e4c57f5996a9a3aed8a8c2b02712a9ce37db4928"><code>e4c57f5</code></a> chore(release): publish 8.51.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/d520b88990e1b20674dcfa3db3b0461c1d6d9aa2"><code>d520b88</code></a> chore(release): publish 8.50.1</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/c62e85874f0e482156a54b6744fe90a6f270012a"><code>c62e858</code></a> chore(release): publish 8.50.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/864595a44b56beb9870bf0f41d59cf7f8f48276a"><code>864595a</code></a> chore(release): publish 8.49.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/32b7e891bd60ae993e85018ceefa2a0c07590688"><code>32b7e89</code></a> chore(deps): update dependency <code>@vitest/eslint-plugin</code> to v1.5.1 (<a href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser/issues/11816">#11816</a>)</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/8fe34456f75c1d1e8a4dc518306d5ab93422efec"><code>8fe3445</code></a> chore(release): publish 8.48.1</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/6fb1551634b2ff11718e579098f69e041a2ff92c"><code>6fb1551</code></a> chore(release): publish 8.48.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/a4dc42ac541139f0da344550bce7accd8f3d366a"><code>a4dc42a</code></a> chore: migrate to nx 22 (<a href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser/issues/11780">#11780</a>)</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/28cf8032c2492bb3c55dd7dd145249f2246034ad"><code>28cf803</code></a> chore(release): publish 8.47.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/843f144797c0a94272cdb002c00c5639cf0797c6"><code>843f144</code></a> chore(release): publish 8.46.4</li> <li>Additional commits viewable in <a href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.51.0/packages/parser">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 <code>@typescript-eslint/parser</code> 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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> |
||
|
|
21ff42074d |
feat: implement skills system for AI agents (#16865)
## Summary This PR introduces a Skills system for AI agents, inspired by the [Agent Skills specification](https://agentskills.io/specification). ## Changes ### Backend - **SkillEntity**: New database entity with migration for storing skills - **V2 Sync Mechanism**: Implemented FlatSkill, builders, validators, and action handlers following the v2 flat entity pattern - **Standard Skills**: Pre-defined skills (workflow-building, data-manipulation, dashboard-building, metadata-building, research, code-interpreter, xlsx, pdf, docx, pptx) - **GraphQL API**: CRUD operations for skills with proper guards and permissions - **Workspace Cache**: Integrated skills into the workspace cache system ### Frontend - **Skills Table**: Searchable table in AI settings showing all skills - **Skill Form**: Create/edit page with Label (primary), Description, and Content (markdown editor) - **API Name**: Following existing patterns, name is derived from label with advanced settings toggle for custom API names - **Standard vs Custom**: Standard skills are read-only, custom skills can be edited/deleted ## Key Design Decisions - Skills are stored in the database (Salesforce-like approach) rather than files - Name is derived from Label by default (isLabelSyncedWithName pattern) - Skills reference functions/files via @ mentions in markdown content rather than explicit relations - Standard skills are synced from code, custom skills are created via UI ## Screenshots Skills table and form UI follow existing settings patterns. ## Testing - [x] Lint passes - [x] Typecheck passes - [ ] CI tests |
||
|
|
61addf8b62 |
fix(email threads): linkify Email body so that URL links are properly formatted (#16415)
Closes #16396 Added [linkify-react](https://www.npmjs.com/package/linkify-react) and [linkifyjs](https://www.npmjs.com/package/linkifyjs?activeTab=versions) to dependancies. Both are widely used libraries with millions of weekly downloads. Both of them have 0 dependancies on other packages, so should be safe to use. ### Before URLs were shown as plain text <img width="395" height="699" alt="Screenshot 2025-12-09 at 12 25 03 PM" src="https://github.com/user-attachments/assets/772e6d03-8c48-45a1-985c-f775bbd3465c" /> ### After URLs are shown as link and are clickable now. <img width="367" height="641" alt="Screenshot 2025-12-09 at 2 50 29 PM" src="https://github.com/user-attachments/assets/d15bf23a-7cae-4cd4-b9da-e99706c7db38" /> <img width="376" height="656" alt="Screenshot 2025-12-09 at 2 50 46 PM" src="https://github.com/user-attachments/assets/ba112a65-7550-47e3-b42f-83b94c08bfa6" /> --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> |
||
|
|
3096769616 |
build(deps): bump @monaco-editor/react from 4.6.0 to 4.7.0 (#16829)
Bumps [@monaco-editor/react](https://github.com/suren-atoyan/monaco-react) from 4.6.0 to 4.7.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/releases"><code>@monaco-editor/react</code>'s releases</a>.</em></p> <blockquote> <h2>v4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (<code>v1.5.0</code>) version (this uses <code>monaco-editor</code> <code>v0.52.2</code>)</li> <li>package: inherit all changes from <code>v4.7.0-rc.0</code></li> </ul> <h2>v4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom <code>v19</code> as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/blob/master/CHANGELOG.md"><code>@monaco-editor/react</code>'s changelog</a>.</em></p> <blockquote> <h2>4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version (this uses monaco-editor v0.52.2)</li> <li>package: inherit all changes from v4.7.0-rc.0</li> </ul> <h2>4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom v19 as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/eb120e66378471315620fe5339b73ba003f199ad"><code>eb120e6</code></a> update package to 4.7.0 version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/cdd070c9f080caf4a9a7b13c2c34fa4e10edc9bf"><code>cdd070c</code></a> update snapshots</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/55a063e45d2f2672884b77059ac97850758764ae"><code>55a063e</code></a> update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/52e8c75616e09730b7b1a0b5822385212a082ce8"><code>52e8c75</code></a> update package to 4.7.0-rc.o version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/e72be4edc1b4492eae9f7d85671ee61a43a6aee8"><code>e72be4e</code></a> add react 19 to peerDependencies</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/642be903a9dd21d6fe639ab5c92c234dad77c813"><code>642be90</code></a> update playground's react version to 19</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ceee344fbe26285dabb0fe90985fe18ec867211c"><code>ceee344</code></a> Add Monaco-React AI Bot in Readme (<a href="https://redirect.github.com/suren-atoyan/monaco-react/issues/655">#655</a>)</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/f7cac39fbad0f062dc66458831aaf57a7126dd40"><code>f7cac39</code></a> add electron blog post link</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ea601cf9f6fe9f2cc0c6271d6a9cde9a332b6dc0"><code>ea601cf</code></a> add tea constitution file</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/3327f3c368cb6d56c02f2df8a9d45177ce6f52e9"><code>3327f3c</code></a> add GitHub sponsor button</li> <li>See full diff in <a href="https://github.com/suren-atoyan/monaco-react/compare/v4.6.0...v4.7.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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> |
||
|
|
1fcb8b464c |
fix: move vite plugins into the packages that use them (#16134)
I was looking into [Dependabot Alert 107](https://github.com/twentyhq/twenty/security/dependabot/107) and figured that the alert is caused by `vite-plugin-dts`, which is a development dependency and does not make it into the production build for it to be dangerous. However, while at it, I also saw that some packages used plugins from root package.json while others had them defined in their local package.json. Therefore, I refactored to move plugins where they're required and removed a redundant package. Builds for the following succeed as intended: - twenty-ui - twenty-emails - twenty-website - twenty-front Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
978c0acb90 |
fix: sentry's sensitive headers are leaked when sendDefaultPii is set to true (#16122)
Resolves [Dependabot Alert 323](https://github.com/twentyhq/twenty/security/dependabot/323), [Dependabot Alert 324](https://github.com/twentyhq/twenty/security/dependabot/324) and [Dependabot Alert 325](https://github.com/twentyhq/twenty/security/dependabot/325). It updates Sentry's packages on the server from 10.21.0 to 10.27.0. I also moved @sentry/react to twenty-front package.json and updated the version from 9.26.0 to 10.27.0 - no breaking changes were introduced in the major upgrade in regards to the API exposed by the dependency. Since @sentry/profiling-node was redundant in the root package.json, I removed it - twenty-server has it already and is the only package dependent on @sentry/profiling-node. |
||
|
|
a1bfab82df |
Remove VITE_DISABLE_ESLINT_CHECKER environment variable (#15943)
The `VITE_DISABLE_ESLINT_CHECKER` environment variable is removed from
the codebase. ESLint checker no longer runs during Vite builds
(equivalent to the previous `VITE_DISABLE_ESLINT_CHECKER=true`
behavior).
**Configuration**
- Removed from `.env.example` (active and commented lines)
- Removed from `vite.config.ts` destructuring and conditional logic
- Removed from build scripts in `package.json` and `nx.json`
**Code change in vite.config.ts:**
```diff
- if (VITE_DISABLE_ESLINT_CHECKER !== 'true') {
- checkers['eslint'] = {
- lintCommand: 'eslint ../../packages/twenty-front --max-warnings 0',
- useFlatConfig: true,
- };
- }
```
**Documentation**
- Updated main English troubleshooting guide to remove references to the
variable
- Translated documentation files are intentionally not modified and will
be handled by a separate workflow
> [!NOTE]
> ESLint will not run in the background via Vite's checker plugin.
Developers will need to run `npx nx lint twenty-front` manually or rely
on their IDE's ESLint extension for real-time feedback on open files.
Created from VS Code via the <a
href="https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github">GitHub
Pull Request</a> extension.
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Your job is to delete everything related to
VITE_DISABLE_ESLINT_CHECKER in the codebase.
>
> We mention this env var in documentation: drop the content talking
about it.
>
> We use it in the vite config: drop the check and keep the code paths
that used to run when `VITE_DISABLE_ESLINT_CHECKER=true`.
>
> User has selected text in file packages/twenty-front/.env.example from
3:1 to 3:28
</details>
Created from VS Code via the [GitHub Pull
Request](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)
extension.
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/twentyhq/twenty/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
|
||
|
|
e0d1f74648 |
Page layout conditional display (#15802)
- Allow widgets to be hidden based on device's type conditions: desktop or mobile - Create two widgets for rich text fields on tasks and notes. One widget is displayed below fields on mobile (and in the right drawer); the other is displayed on a separate tab on desktop - In read mode, hide tabs if they contain no visible widgets. If there is no tab left to display, display at least the first one with no widgets. - In edit mode, display all tabs and all widgets. ## Demo https://github.com/user-attachments/assets/65ef1261-3902-4432-a420-48983b763b2c Closes https://github.com/twentyhq/core-team-issues/issues/1811 |
||
|
|
60ed9b53f4 |
fix: vercel’s AI SDK's filetype whitelists can be bypassed when uploading files (#15874)
Resolves [Dependabot Alert 301](https://github.com/twentyhq/twenty/security/dependabot/301). Locked the version of "ai" at 5.0.52 in order to stop it from bumping to 5.0.93 directly when the ^ is introduced since it breaks the code across multiple files. |
||
|
|
7a68aa7f48 |
fix: playwright downloads and installs browsers without verifying the authenticity of the SSL certificate (#15843)
Resolves [Dependabot Alert 293](https://github.com/twentyhq/twenty/security/dependabot/293). Updates the playwright version used to `1.56.1`. The alert could have also been ignored since the playwright download only happens in CI and local environments, not the production environment. However, it's an easy fix instead of just ignoring the alert. |
||
|
|
9f594cda1c |
Slash Command Implementation in Advanced Text Editor (#15488)
Part of Fixing Issue #14976
### Pull Request Summary: SlashCommand Integration in Advanced Text
Editor
This pull request introduces **SlashCommand functionality** within the
Advanced Text Editor, specifically used in the **Workflow node** of
**Send Email body** components. The implementation leverages the
`@tiptap/suggestion` extension from the TipTap ecosystem, enabling
dynamic styling and command execution via a custom dropdown triggered by
typing `/`.
---
### Implementation Overview
#### 1. **Custom Extension & Dropdown Rendering**
- A new extension was created to handle SlashCommand interactions.
- This extension renders a **Dropdown component** that displays
available commands with relevant styles, icons etc.
#### 2. **Command Configuration**
- Each command includes:
- Visibility and active state logic
- Execution behavior upon selection
- All commands are initialized and configured centrally.
#### 3. **Search & Filtering**
- As users type after the `/`, the command list is **filtered based on
the query**.
- For example, typing `/car` filters and displays matching commands in
the dropdown.
#### 4. **Dropdown Lifecycle & Positioning**
- The dropdown is rendered using React lifecycle hooks provided by
`SuggestionTip`:
- `onStart`: Initializes state, sets selected command, and captures
cursor position via `DOMRect`.
- `onUpdate`, `onKeyDown`, `onExit`: Manage dropdown updates and
interactions.
- Positioning is handled via a **`useFloating` hook**, which aligns the
dropdown relative to the cursor and editor bounds.
- The dropdown is rendered in a **react-portal**, wrapped in the current
theme for consistent styling and animation.
#### 6. **State Management**
- A dedicated `SlashCommandState.ts` file manages:
- Callback functions
- Current command and selected item
- Cleanup utilities for event listeners
- Dropdown navigation (arrow keys, enter key)
#### 7. **Integration Points**
- SlashCommand functionality is now **enabled in Send Email body of the
Workflow**.
- Relevant changes have been applied to support this components in
Storybook as well.
[slash command
test.webm](https://github.com/user-attachments/assets/5c537844-8987-4ce5-9fca-b29ea93d8063)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Updates Portuguese (Brazil and Portugal) generated locale files,
including a new editor hint string for “Enter text or type '/' for
commands,” plus assorted translation tweaks.
>
> - **i18n/locales**:
> - **Portuguese (Brazil) `src/locales/generated/pt-BR.ts`**: Add new
editor hint message (`"Enter text or Type '/' for commands"`) and adjust
multiple translations/wording.
> - **Portuguese (Portugal) `src/locales/generated/pt-PT.ts`**: Add the
same editor hint message and refine numerous translations/labels.
> - No functional code changes; translation files regenerated/updated.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
|
||
|
|
be3ceca0a3 |
Add listkit to tiptap extension in workflow node (#15363)
## Description - This PR address issue - https://github.com/twentyhq/core-team-issues/issues/1768 - Added listkit bundle from tiptap which includes BulletList, orderedList, ListItem and ListKeymap in one single import - This bundle also includes keyboards shortcuts - `Cmd + Shift + 7` and `Cmd + Shift + 8` for ordered and bullet list ## Visual Appearance https://github.com/user-attachments/assets/7eff1233-8503-4854-bad2-2521898bc568 ## Why this Approach - our current version of tiptap is 3.4.2 while the latest is 3.8.0 hence installing these versions manually would install the latest version of 3.8.0. The issue when downgrading to 3.4.2 was that Version 3.8.0 of `@tiptap/extension-list` requires `renderNestedMarkdownContent` from @tiptap/core but our `@tiptap/core` version 3.4.2 doesn't export this function. |
||
|
|
998138093f |
Move react-email dependencies to their respective packages. (#15295)
Instead of declaring packages at the workplace-level package.json, moving them into their relevant package-level package.json file. `twenty-front`, `twenty-server` and `twenty-emails` continue to build and work fine because of hoisting, but the dependencies now follow the internal strategy of declaring at the package-level, plus give us a single source of truth to updating package versions. `twenty-front` and `twenty-emails` only use `@react-email/components` while `twenty-server` only depends on `@react-email/render`. |
||
|
|
be85f3776f |
fix: graphql uncontrolled resource consumption vulnerability (#15260)
Fixes [Dependabot Alert 73](https://github.com/twentyhq/twenty/security/dependabot/73) - graphql uncontrolled resource consumption vulnerability. Updated the patch version - from 16.8.0 to 16.8.1 - and this patch only touches the issue identified by the alert. <p align="center"> <img width="1175" height="472" alt="image" src="https://github.com/user-attachments/assets/4f809f03-1e63-4412-822c-227712d1e395" /> </p> Manually tested a few mutations, ran test cases, and everything seems to work fine. Not expecting it to break anything. Two files changed in the original patch fix: https://github.com/graphql/graphql-js/commit/8f4c64eb6a7112a929ffeef00caa67529b3f2fcf |
||
|
|
bc2070410c |
chore(dependencies): remove unused dependencies from package.json and… (#14914)
… yarn.lock |
||
|
|
5623364c4b | chore(dependencies): remove unused Monaco Editor packages (#14913) | ||
|
|
2685f4a5b9 |
Restructure agent chat messages with parts-based architecture (#14749)
Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
2af20a4cf0 |
Add UTC timezone label to CRON trigger form (#14674)
- Added 'Cron will be triggered at UTC time' notice below trigger interval dropdown - Positioned correctly between dropdown and expression field to match design - Only shows when Custom CRON option is selected --------- Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
3cada58908 |
Migrate from Zod v3 to v4 (#14639)
Closes [#1526](https://github.com/twentyhq/core-team-issues/issues/1526) --------- Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
9a2766feae |
feat: rich text email body (#14482)
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
6a96c85eed |
chore: upgrade tiptap to v3 (#14467)
This PR upgrades Tiptap V2 packages into V3, following their [upgrade guide](https://tiptap.dev/docs/guides/upgrade-tiptap-v2). |
||
|
|
74eeb98293 | Page Layout Initialization on Settings (#14156) | ||
|
|
ab9cabce04 |
[Dashboards] Graph bar chart component (#14052)
closes https://github.com/twentyhq/core-team-issues/issues/1372 |
||
|
|
50448c9b16 |
[Dashboards] Graph pie chart component + refactor (#14045)
closes https://github.com/twentyhq/core-team-issues/issues/1373 closes https://github.com/twentyhq/core-team-issues/issues/1368 figma https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=c7GEJKFZKI0JhRv0-0 TODO: - ~~refactor to have a color registry~~ - ~~refactor legend and tooltips into a separate component for reuse across the graphs~~ - also refactor the border in between to be a common logic between pie and gauge graphs - ***open question*** - How should we code this border in between (renderValueEndLine), which is a layer - it's a function that returns JSX I could not figure out if it should be a util/component/hook? None of them fit into the category -- hence kept them inline in both gauge and pie charts for simplicity |
||
|
|
9e9fa6325f |
[Dashboards] Graph gauge chart component (#14035)
closes https://github.com/twentyhq/core-team-issues/issues/1374 figma - https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=C0BfdTmTl69RKZvU-0 --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |
||
|
|
af2dace71c |
chore: scope package.json deps to packages (#13835)
- Move dev-only types to devDependencies - Move frontend-only deps from root to twenty-front - Add website-only deps to twenty-website - Fix react-phone-number-input patch path CI should validate. |
||
|
|
b55a48139c |
Remove hoisting on server (#13821)
Testing a different approach to fix broken buildPackageJson on server build How i have tested: A. Local contributor setup - run yarn - build server - run yarn workspace focus - run server on dist B. self-host - docker build Note: I think the dependencies I have added are suboptimized as the image went from 2GB to 3.5GB. We might need to be more accurate |