d1ba63d4a46d10045d4e9952b04b0991ec58bb3a
12740 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d1ba63d4a4 |
Postcard app e2e front component rendering test (#21600)
# Introduction Creating a playwright test, quite granular and verbose that will verify that the post card preview front component is rendered as expected on the tested twenty instance This covers everything e2e from twenty front, front comp renderer, assets cdn rendered redirection etc Style bridge etc ## Note The playwright test setup assumes the application has already been installed once, it's mainly used by the merge queue as a high level front component and logic function ( will be in the same ci ) regression bottleneck The goal isn't for this test to be run locally |
||
|
|
4be76e3fd1 |
Support morph relations in workflow record nodes (#21403)
## Support morph (polymorphic) relations in workflow record nodes
Morph relations (e.g. a polymorphic `Owner` on `Pet` targeting `Person`
or `Company`) were not selectable in the workflow **Create / Update /
Upsert Record** nodes. This PR adds full support for setting them.
### What changed
**Frontend**
- `shouldDisplayFormField`: allow `MORPH_RELATION` (many-to-one) so
morph fields appear in record forms.
- New `FormMorphRelationToOneFieldInput`: a polymorphic record picker
across the morph's target objects, storing a self-describing value `{
targetObjectMetadataId, id }`.
- Wired the morph branch into `FormFieldInput`.
**Backend**
- New `formatWorkflowRecordMorphRelationFields` util: resolves the form
value (stored under the base field name, e.g. `owner`) into the correct
per-target join column (`ownerCompanyId`), nulling siblings to keep
exactly one target referenced.
- Wired into the create / update / upsert workflow actions (update also
expands `fieldsToUpdate` to the concrete join columns).
### Permissions handling
- The picker's search is scoped to only the morph targets the user can
read (`canReadObjectRecords`), so it no longer breaks when a target
object is inaccessible.
- If an existing value points to an object the user can't read, the
field shows the reused **"Not shared"** lock display instead of an empty
field, while remaining editable when other targets are readable.
### Notes
- No data schema / migration changes — reuses the existing per-target
morph columns and stores the selection in the existing workflow step
JSON settings.
<img width="607" height="717" alt="Screenshot 2026-06-10 at 14 57 40"
src="https://github.com/user-attachments/assets/496442a1-04a5-40f8-8b56-b28e38b00d5a"
/>
Also handles the case where the selected record is not readable
<img width="596" height="737" alt="image"
src="https://github.com/user-attachments/assets/c5ffb94e-3838-4db5-853e-f8e490331f23"
/>
|
||
|
|
5207493cda |
Add useColorScheme hook to twenty-sdk (#21595)
Ability to update front compoonent design according to the dark or white theme of the UI <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21595?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
02d6e2d76f |
perf(server): avoid O(n²) when building flat entity maps (#21585)
## Problem
After 2.13, server CPU stepped up and stayed up. Sentry profiling of
`POST /metadata` pins it on
`addFlatEntityToFlatEntityMapsThroughMutationOrThrow` — ~26% self-time
plus a long tail, turning metadata-write requests into multi-second
(~18s observed) operations.
The hot stack is:
```
WorkspaceMigrationValidateBuildAndRunService.computeAllRelatedFlatEntityMaps
└ getSubFlatEntityMapsByApplicationIdsOrThrow
└ addFlatEntityToFlatEntityMapsThroughMutationOrThrow
```
Every metadata migration rebuilds the twenty-standard application's flat
sub-maps — thousands of entities, across every involved metadata type —
through this util.
## Root cause
`addFlatEntityToFlatEntityMapsThroughMutationOrThrow` maintains
`universalIdentifiersByApplicationId` and deduped each insert with
`Array.includes`:
```ts
if (!existingUniversalIdentifiers.includes(flatEntity.universalIdentifier)) {
existingUniversalIdentifiers.push(flatEntity.universalIdentifier);
}
```
That scan is O(n) per insert, so building a map for an application with
`n` entities is **O(n²)**. The twenty-standard application groups
thousands of standard entities under one `applicationId`, so its sub-map
rebuild dominates.
The dedup is also redundant: the function throws `ENTITY_ALREADY_EXISTS`
at the top if the `universalIdentifier` is already in
`byUniversalIdentifier`, and every id pushed to the per-application list
is also written there. So reaching the push guarantees the id is new —
the `.includes()` is always `false`.
## Fix
Drop the scan and push directly → map building is **O(n)**. Behavior is
unchanged (the early throw already enforces uniqueness).
## Test
Adds a unit spec covering indexing, the no-`applicationId` case, the
duplicate throw, and a 20k-entity build that completes instantly (guards
against re-introducing the quadratic).
## Follow-up (separate PR)
This is the bleed-stopper. The deeper issue is that
`computeAllInvolvedApplicationIds` pulls the **entire** twenty-standard
application into the dependency set of every migration and rebuilds
those sub-maps per request instead of caching them. Worth scoping the
dependency set to referenced entities (or caching the standard-app
sub-maps), which I'll raise separately.
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21585?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
|
||
|
|
0a99f784eb |
fix(front): dedupe morph relation fields in view field pickers (#21580)
## Issue Reported in quality-feedbacks: **"Issues with morph relation view field"** — a morph relation column added to a view **disappears after refresh** (and can be added several times). ## Root cause — the SSE metadata sync A morph relation is stored as **one `fieldMetadata` row per target object**, all sharing a `morphId`. Collapsing those rows into the single field that represents the relation is a **read-time projection** in the server's `objects.fieldsList` resolver — it is *not* a storage invariant, and the rows are never merged. The frontend metadata store is kept in sync with the raw rows **one row at a time over SSE** (`MetadataStoreSSEEffect`): every metadata change broadcasts a single created/updated record that's pushed straight into the store. Creating a morph relation creates N rows (one per target), so **N `create` events arrive and N raw sub-fields land in the store — bypassing the `fieldsList` projection entirely.** The view-field pickers read straight from that store, so they saw the morph relation **once per target**. Each could be added as a column referencing a different sub-field id; after a refresh the view reloads from the projected (deduped) data, the non-survivor columns no longer resolve, and they disappear. ## Fix & architecture note Because the store deliberately mirrors raw rows (that's what the SSE sync maintains), the fix applies the **same read-time projection on the client** — deduping morph rows by `morphId` in `useActiveFieldMetadataItems` — rather than filtering rows at each insert path (SSE, optimistic create, …). This matches how the backend already models morph fields and is robust regardless of which path delivered the rows. The survivor-selection rule (which sub-field id represents the relation) now lives in `twenty-shared` (`pickMorphGroupSurvivor`) so client and server can't drift. |
||
|
|
ecc7b38b75 |
Remove randomness from flaky twenty-front Storybook stories (#21594)
Several twenty-front Storybook stories were flagged flaky by Argos because they render different pixels across runs. This removes the non-determinism behind them. **What changed** - **Images** — replaced random `picsum.photos` URLs in the Logo and TabList stories with the existing `AVATAR_URL_MOCK`, and added global MSW handlers in `.storybook/preview.tsx` that serve a deterministic image for every remote host (picsum, twenty-icons.com, twentyhq.github.io, etc.) so no story depends on a network image load. - **Numbers** — the line-chart story built its data with `Math.random()`; now uses a deterministic formula. - **Dates** — the terminal "long output" story stamped its lines with `new Date()`; now uses a fixed base timestamp. The calendar-channel date/time format previews and example event used render-time `Date.now()`/`new Date()` in shared components; they now use a fixed reference date (`DateTimeSettingsPreviewDate`). - **Lazy-load timing** — the date-picker story now waits for the lazily-loaded calendar before the snapshot. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21594?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
c848ac34fd |
Fix default view widget visibility (#21590)
Tim logged on the left, Phil on the right, Tim created view widget ## Before <img width="1512" height="938" alt="image" src="https://github.com/user-attachments/assets/7f993f41-a244-42db-b56a-b17c15fb3409" /> ## After Fix Tim created a second view widget, Phil can see it <img width="1512" height="982" alt="image" src="https://github.com/user-attachments/assets/3908a70d-538b-4adf-95df-7373a2f6e269" /> ## After slow migration Phil can see first widget <img width="1512" height="982" alt="image" src="https://github.com/user-attachments/assets/6b30429e-1acf-4119-ba32-26db3155975e" /> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21590?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Weiko <corentin@twenty.com> |
||
|
|
5f59ae20bf |
chore: bump version to 2.14.0 (#21593)
## Summary - Moves current version to previous versions array - Sets TWENTY_CURRENT_VERSION to the new version - Updates TWENTY_NEXT_VERSIONS with the next minor version - Bumps twenty-client-sdk, twenty-sdk, and create-twenty-app to the same version ## Checklist - [ ] Verify version constants are correct - [ ] Verify npm package versions match <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21593?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Co-authored-by: Github Action Deploy <github-action-deploy@twenty.com> |
||
|
|
04a304aa99 |
Ignore generated Storybook/Argos screenshot output (#21589)
## Context `packages/twenty-front/screenshots/` (and the equivalent under other Storybook packages) holds Argos visual-regression baselines that are generated on demand and not meant to be committed. The existing rules in `.gitignore` were: ``` screenshots/ !**/screenshots/ ``` The `!**/screenshots/` negation was added so app images committed under `public/screenshots/` (github-connector) and `assets/screenshots/` (codex-plugin) stay tracked — but it is too broad: it also re-includes the generated output, so a `git add -A` can accidentally commit hundreds of baseline PNGs. ## What this does Narrows the negation to the two locations where screenshots are intentionally committed: ``` screenshots/ !**/public/screenshots/ !**/assets/screenshots/ ``` Generated `screenshots/` directories at package roots (twenty-front, twenty-ui, twenty-ui-deprecated, twenty-front-component-renderer) are now ignored again, while committed app images remain tracked. Verified with `git check-ignore`. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21589?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
ebababcda1 |
chore(deps): bump @ai-sdk/amazon-bedrock from 4.0.97 to 4.0.117 (#21569)
Bumps [@ai-sdk/amazon-bedrock](https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock) from 4.0.97 to 4.0.117. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vercel/ai/blob/@ai-sdk/amazon-bedrock@4.0.117/packages/amazon-bedrock/CHANGELOG.md">@ai-sdk/amazon-bedrock's changelog</a>.</em></p> <blockquote> <h2>4.0.117</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [bfa5864]</li> <li>Updated dependencies [f42aa79] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.29</li> <li><code>@ai-sdk/anthropic</code><a href="https://github.com/3"><code>@3</code></a>.0.84</li> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.71</li> </ul> </li> </ul> <h2>4.0.116</h2> <h3>Patch Changes</h3> <ul> <li>f0b5c16: fix(provider/amazon-bedrock): detect Cohere embedding models behind cross-region inference profile ids</li> <li>Updated dependencies [942f2f8] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.28</li> <li><code>@ai-sdk/anthropic</code><a href="https://github.com/3"><code>@3</code></a>.0.83</li> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.70</li> </ul> </li> </ul> <h2>4.0.115</h2> <h3>Patch Changes</h3> <ul> <li>c97ede5: fix(provider/amazon-bedrock): extract Cohere embedding token usage from response header</li> </ul> <h2>4.0.114</h2> <h3>Patch Changes</h3> <ul> <li>2a91a17: feat(provider/anthropic): add support for <code>claude-fable-5</code> and the <code>fallbacks</code> API parameter</li> <li>Updated dependencies [9a55f6d]</li> <li>Updated dependencies [2a91a17] <ul> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.69</li> <li><code>@ai-sdk/anthropic</code><a href="https://github.com/3"><code>@3</code></a>.0.82</li> </ul> </li> </ul> <h2>4.0.113</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [c65c952] <ul> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.68</li> </ul> </li> </ul> <h2>4.0.112</h2> <h3>Patch Changes</h3> <ul> <li>53b002d: added bedrock mantle provider</li> </ul> <h2>4.0.111</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vercel/ai/commit/bae9babb22e195e74a9a0c0e26a5e52c8ba8e7f2"><code>bae9bab</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/16026">#16026</a>)</li> <li><a href="https://github.com/vercel/ai/commit/9ef2c3cfadfc4a469e9eec6a6e8a0ac0fc80a1e5"><code>9ef2c3c</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15998">#15998</a>)</li> <li><a href="https://github.com/vercel/ai/commit/f0b5c16ce5f17a7c9cc91ce0ae8f292920594e91"><code>f0b5c16</code></a> Backport: fix(provider/amazon-bedrock): detect Cohere embedding models behind...</li> <li><a href="https://github.com/vercel/ai/commit/dca8c38b09acba1a5eebf354b532833ab055413a"><code>dca8c38</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15992">#15992</a>)</li> <li><a href="https://github.com/vercel/ai/commit/c97ede5cbbbc0aaca0137ed41c7fd6f5fedd23b6"><code>c97ede5</code></a> Backport: fix(provider/amazon-bedrock): extract Cohere embedding token usage ...</li> <li><a href="https://github.com/vercel/ai/commit/f6e588173713842794c619f9554a4b341c6e97f5"><code>f6e5881</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15902">#15902</a>)</li> <li><a href="https://github.com/vercel/ai/commit/2a91a17e0b885968814110fe3581d1ea0fd589ae"><code>2a91a17</code></a> backport: feat(provider/anthropic): add support for <code>claude-fable-5</code> and the ...</li> <li><a href="https://github.com/vercel/ai/commit/de852ab79aac88345c8a9ae54003fb206e1a64b4"><code>de852ab</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15821">#15821</a>)</li> <li><a href="https://github.com/vercel/ai/commit/879395199bac3796e6c34b43f6aa43ca5d682940"><code>8793951</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/15755">#15755</a>)</li> <li><a href="https://github.com/vercel/ai/commit/53b002d2d0701235026b41e0fa11aa1a41c90b8b"><code>53b002d</code></a> Backport: feat (provider/amazon-bedrock): add bedrock mantle provider (<a href="https://github.com/vercel/ai/tree/HEAD/packages/amazon-bedrock/issues/14246">#14246</a>...</li> <li>Additional commits viewable in <a href="https://github.com/vercel/ai/commits/@ai-sdk/amazon-bedrock@4.0.117/packages/amazon-bedrock">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21569?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
fb4608e437 |
chore(deps): upgrade Tier-1 deps (googleapis 173, gaxios 7, express 5, jsdom 29, date-fns 4, stripe 20) (#21570)
## What Security-driven upgrade of the biggest-drift Tier-1 dependencies (staying on latest = staying patched). Bundled because they share the lockfile and the googleapis/gaxios pair must move together. | Package | From | To | Gap | |---|---|---|---| | googleapis | 105.0.0 | **173.0.0** | 68 majors | | gaxios | 5.1.3 | **7.1.5** | 2 majors | | express | 4.22.2 | **5.2.1** | 1 major | | jsdom | 26.1.0 | **29.1.1** | 3 majors | | date-fns | 2.30.0 | **4.4.0** | 2 majors | | date-fns-tz | 2.0.0 | **3.2.0** | 1 major | | stripe | 19.3.1 | **20.4.1** | 1 major | `yarn npm audit` reports **0 high/critical** advisories before and after. ## Code changes - **gaxios v7** — `GaxiosError.code` is now `string | number` (guard the calendar network-error check by `typeof`); `GaxiosError` config/response use `URL` + `Headers`; and crucially the v7 constructor drops `response.data` unless `bodyUsed` is set — updated the synthetic gmail error mocks accordingly (production gaxios sets it, so real error parsing is unaffected). - **google-auth-library / gaxios dedup** — `googleapis-common@8.0.2` exact-pins `google-auth-library@10.5.0` + `gaxios@7.1.3` while `googleapis` pulls `^10.2.0`; the two copies made `OAuth2Client`/`GaxiosError` type-identities diverge across every gmail/calendar service. Added two singleton `resolutions` (documented inline in root `package.json`). - **express 5** — no source changes. `@nestjs/platform-express@11.1.24` already resolves `express@5.2.1` internally; the old `4.22.2` pin was the override. - **jsdom 29** — no source changes, but it now pulls ESM-only transitive deps (`@csstools/*` `.mjs`, `parse5`, `entities`, `tough-cookie`, `@exodus/bytes`). Extended the server jest `transformIgnorePatterns` allowlist and added `.mjs` to the transform/extensions so jest can load jsdom. - **stripe 20** — `Subscription` gained a required `customer_account` field; added to mocks. No runtime changes. - **date-fns v4** — `Locale` is no longer ambient (import explicitly in 5 files); per-locale entrypoints dropped the typed `default` export (the locale loader now reads the single named export); fixed the default locale import in `formatTimeZoneLabel`. ## Tests - Full suites green locally: **twenty-server 5709 passed**, **twenty-front 4937 passed**, twenty-ui / twenty-ui-deprecated green; typecheck + builds (swc + vite) + lint all pass. - Added regression tests for the two runtime behaviors these upgrades touch and that had no coverage: - `getDateFnsLocale` — named-export locale resolution (date-fns v4). - `sanitizeFile` — jsdom 29 + DOMPurify still strips `<script>`/event handlers from uploaded SVGs (security guard). ## Deliberately deferred (not in this PR) - **stripe → 21/22**: stripe **21** bundles a runtime `Decimal` type for money fields **and** jumps the pinned API version to `2026-03-25.dahlia` (changes webhook/billing payload behavior) — too risky to fold into a deps bump on billing code. stripe **22** additionally drops the node10-resolvable `types` entry, which would force a repo-wide `moduleResolution` change. Capped at the latest clean **20.x**. - **openid-client → 6**: v6 is a full functional rewrite and its passport strategy manages the OAuth `state` internally, but our SSO flow uses `state` to carry `identityProviderId` across the shared `/auth/oidc/callback`. That needs an auth-flow redesign (session-carried provider id) on Enterprise SSO code with no integration harness — it deserves its own focused PR rather than riding along here. ## Tier-1 source Originated from a dependency-drift audit; remaining Tier-1 items (date-fns done here) plus Tier-2/3 follow-ups tracked separately. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21570?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
d7d4b36d5e |
fix(front): keep the filename when a file has no extension (#21576)
Closes #21575. ## Summary `getFileNameAndExtension` split filenames with `lastIndexOf('.')`. For an extensionless name (`README`, `Makefile`), `lastIndexOf` returns `-1` and `substring`'s negative-index clamping returned `{ name: '', extension: 'README' }` — losing the whole name into the extension. In the attachments UI this rendered an empty rename field and corrupted the name on edit. ## Changes - Early return `{ name, extension: '' }` when there is no dot - Correct the existing test that asserted the buggy output; add no-dot + trailing-dot cases ## Testing Pure, dependency-free function — verified deterministically (17/17 assertions, red-green proven: reverting the fix fails the corrected `README` assertion). Note: twenty's full nx lint/test wasn't run locally (repo wants Node ^24.5.0; this box is on Node 26), so CI is the authoritative check for lint/format. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21576?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
e70776f705 |
chore(deps): bump prettier from 3.8.3 to 3.8.4 (#21568)
Bumps [prettier](https://github.com/prettier/prettier) from 3.8.3 to 3.8.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/releases">prettier's releases</a>.</em></p> <blockquote> <h2>3.8.4</h2> <ul> <li>Markdown: Fix blank lines between list items and nested sub-lists being removed in Markdown/MDX (<a href="https://redirect.github.com/prettier/prettier/pull/17746">prettier/prettier#17746</a> by <a href="https://github.com/byplayer"><code>@byplayer</code></a>)</li> </ul> <p>🔗 <a href="https://github.com/prettier/prettier/blob/3.8.4/CHANGELOG.md#384">Changelog</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's changelog</a>.</em></p> <blockquote> <h1>3.8.4</h1> <p><a href="https://github.com/prettier/prettier/compare/3.8.3...3.8.4">diff</a></p> <h4>Markdown: Fix blank lines between list items and nested sub-lists being removed in Markdown/MDX (<a href="https://redirect.github.com/prettier/prettier/pull/17746">#17746</a> by <a href="https://github.com/byplayer"><code>@byplayer</code></a>)</h4> <p>Prettier was removing blank lines between list items and their nested sub-lists, converting loose lists into tight lists and changing their semantic meaning.</p> <!-- raw HTML omitted --> <pre lang="markdown"><code><!-- Input --> - a <ul> <li> <p>b</p> </li> <li> <p>c</p> <ul> <li>d</li> </ul> </li> </ul> <p><!-- Prettier 3.8.3 --></p> <ul> <li>a <ul> <li>b</li> </ul> </li> <li>c <ul> <li>d</li> </ul> </li> </ul> <p><!-- Prettier 3.8.4 --></p> <ul> <li> <p>a</p> <ul> <li>b</li> </ul> </li> <li> <p>c</p> <ul> <li>d<br /> </code></pre></li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/prettier/prettier/commit/1c6ba5539141552e0e8e22d401ea620d8fdff468"><code>1c6ba55</code></a> Release 3.8.4</li> <li><a href="https://github.com/prettier/prettier/commit/4a673dc9b59ddf7296bbab9822093d2971da84a8"><code>4a673dc</code></a> Fix blank lines between list items and nested sub-lists being removed in Mark...</li> <li><a href="https://github.com/prettier/prettier/commit/074aaedbb052a288e89d15eb0a4214de37a08866"><code>074aaed</code></a> Replace <code>main</code> branch in changelog link with tags (<a href="https://redirect.github.com/prettier/prettier/issues/19054">#19054</a>)</li> <li><a href="https://github.com/prettier/prettier/commit/c22a003ae97917c5043e8685b4fdff0f93e978f9"><code>c22a003</code></a> Bump Prettier dependency to 3.8.3</li> <li><a href="https://github.com/prettier/prettier/commit/07bad1f04536e9799927007baf466e67151576f0"><code>07bad1f</code></a> Clean changelog_unreleased</li> <li>See full diff in <a href="https://github.com/prettier/prettier/compare/3.8.3...3.8.4">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21568?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
1f30d4df97 |
chore(deps): bump @ai-sdk/azure from 3.0.55 to 3.0.74 (#21566)
Bumps [@ai-sdk/azure](https://github.com/vercel/ai/tree/HEAD/packages/azure) from 3.0.55 to 3.0.74. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vercel/ai/releases">@ai-sdk/azure's releases</a>.</em></p> <blockquote> <h2><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.71</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [bfa5864]</li> <li>Updated dependencies [f42aa79] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.29</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vercel/ai/blob/@ai-sdk/azure@3.0.74/packages/azure/CHANGELOG.md">@ai-sdk/azure's changelog</a>.</em></p> <blockquote> <h2>3.0.74</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [bfa5864]</li> <li>Updated dependencies [f42aa79] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.29</li> <li><code>@ai-sdk/deepseek</code><a href="https://github.com/2"><code>@2</code></a>.0.38</li> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.71</li> </ul> </li> </ul> <h2>3.0.73</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [942f2f8] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.28</li> <li><code>@ai-sdk/deepseek</code><a href="https://github.com/2"><code>@2</code></a>.0.37</li> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.70</li> </ul> </li> </ul> <h2>3.0.72</h2> <h3>Patch Changes</h3> <ul> <li>79f0ae6: feat(azure): add deepseek model support to azure</li> <li>Updated dependencies [79f0ae6] <ul> <li><code>@ai-sdk/deepseek</code><a href="https://github.com/2"><code>@2</code></a>.0.36</li> </ul> </li> </ul> <h2>3.0.71</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [9a55f6d] <ul> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.69</li> </ul> </li> </ul> <h2>3.0.70</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [c65c952] <ul> <li><code>@ai-sdk/openai</code><a href="https://github.com/3"><code>@3</code></a>.0.68</li> </ul> </li> </ul> <h2>3.0.69</h2> <h3>Patch Changes</h3> <ul> <li>cbc161a: Add Microsoft Entra ID token provider authentication for Azure OpenAI.</li> </ul> <h2>3.0.68</h2> <h3>Patch Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vercel/ai/commit/bae9babb22e195e74a9a0c0e26a5e52c8ba8e7f2"><code>bae9bab</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/16026">#16026</a>)</li> <li><a href="https://github.com/vercel/ai/commit/9ef2c3cfadfc4a469e9eec6a6e8a0ac0fc80a1e5"><code>9ef2c3c</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15998">#15998</a>)</li> <li><a href="https://github.com/vercel/ai/commit/174255acffab2833236b94fd49af3497ff9ff618"><code>174255a</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15955">#15955</a>)</li> <li><a href="https://github.com/vercel/ai/commit/79f0ae6c23aee02f816fa3123c8d589a27e61bb9"><code>79f0ae6</code></a> feat(azure): add deepseek model support to azure (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15945">#15945</a>)</li> <li><a href="https://github.com/vercel/ai/commit/f6e588173713842794c619f9554a4b341c6e97f5"><code>f6e5881</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15902">#15902</a>)</li> <li><a href="https://github.com/vercel/ai/commit/de852ab79aac88345c8a9ae54003fb206e1a64b4"><code>de852ab</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15821">#15821</a>)</li> <li><a href="https://github.com/vercel/ai/commit/7aca1fc2004800171233ae16c2456ef297552441"><code>7aca1fc</code></a> backport: chore: update TypeScript references and fix `pnpm update-references...</li> <li><a href="https://github.com/vercel/ai/commit/7e449f2b40d21aeec94dd9f41ebc5581e7971d94"><code>7e449f2</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15766">#15766</a>)</li> <li><a href="https://github.com/vercel/ai/commit/cbc161ae49b8a6708f1a6cf271081d8ba54ffe4e"><code>cbc161a</code></a> Backport: feat(azure): support Microsoft Entra ID auth (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15740">#15740</a>) (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15764">#15764</a>)</li> <li><a href="https://github.com/vercel/ai/commit/d4893c4421aeaea6dc8db407c35cdeae71a65aaa"><code>d4893c4</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/azure/issues/15700">#15700</a>)</li> <li>Additional commits viewable in <a href="https://github.com/vercel/ai/commits/@ai-sdk/azure@3.0.74/packages/azure">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21566?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
b81641808a |
chore(deps): bump @graphiql/plugin-explorer from 5.1.2 to 5.1.3 (#21565)
Bumps [@graphiql/plugin-explorer](https://github.com/graphql/graphiql/tree/HEAD/packages/graphiql-plugin-explorer) from 5.1.2 to 5.1.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/graphql/graphiql/releases">@graphiql/plugin-explorer's releases</a>.</em></p> <blockquote> <h2><code>@graphiql/plugin-explorer</code><a href="https://github.com/5"><code>@5</code></a>.1.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/graphql/graphiql/pull/4346">#4346</a> <a href="https://github.com/graphql/graphiql/commit/0f5a2a0b250a568ca618e934a5ad119a869bb973"><code>0f5a2a0</code></a> Thanks <a href="https://github.com/trevor-scheer"><code>@trevor-scheer</code></a>! - Release a patch version of the packages served from esm.sh in the <a href="https://github.com/graphql/graphiql/tree/HEAD/packages/graphiql-plugin-explorer/blob/HEAD/examples/graphiql-cdn/index.html">GraphiQL CDN example</a> to trigger a rebuild on esm.sh now that a longstanding esm.sh issue has been fixed.</li> </ul> <h2><code>@graphiql/plugin-explorer</code><a href="https://github.com/5"><code>@5</code></a>.1.3-alpha.0</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/graphql/graphiql/commit/5f44a27ae0ff370b4f9eaffe8f92975091bfeb89"><code>5f44a27</code></a>]: <ul> <li><code>@graphiql/react</code><a href="https://github.com/0"><code>@0</code></a>.37.6-alpha.0</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/graphql/graphiql/blob/main/packages/graphiql-plugin-explorer/CHANGELOG.md">@graphiql/plugin-explorer's changelog</a>.</em></p> <blockquote> <h2>5.1.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/graphql/graphiql/pull/4346">#4346</a> <a href="https://github.com/graphql/graphiql/commit/0f5a2a0b250a568ca618e934a5ad119a869bb973"><code>0f5a2a0</code></a> Thanks <a href="https://github.com/trevor-scheer"><code>@trevor-scheer</code></a>! - Release a patch version of the packages served from esm.sh in the <a href="https://github.com/graphql/graphiql/blob/main/packages/graphiql-plugin-explorer/examples/graphiql-cdn/index.html">GraphiQL CDN example</a> to trigger a rebuild on esm.sh now that a longstanding esm.sh issue has been fixed.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/graphql/graphiql/commit/987eb5c51fa29d0a9babf86aa54764acc9a17f2c"><code>987eb5c</code></a> Version Packages (<a href="https://github.com/graphql/graphiql/tree/HEAD/packages/graphiql-plugin-explorer/issues/4343">#4343</a>)</li> <li><a href="https://github.com/graphql/graphiql/commit/d23f3b1a0b67cd3ae82d43b049b2651ef946c95e"><code>d23f3b1</code></a> Cut over from tsc to tsgo (<a href="https://github.com/graphql/graphiql/tree/HEAD/packages/graphiql-plugin-explorer/issues/4274">#4274</a>)</li> <li>See full diff in <a href="https://github.com/graphql/graphiql/commits/@graphiql/plugin-explorer@5.1.3/packages/graphiql-plugin-explorer">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21565?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
9d5561c96c |
chore(deps): bump @xyflow/react from 12.10.0 to 12.11.0 (#21561)
Bumps [@xyflow/react](https://github.com/xyflow/xyflow/tree/HEAD/packages/react) from 12.10.0 to 12.11.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/xyflow/xyflow/releases">@xyflow/react's releases</a>.</em></p> <blockquote> <h2><code>@xyflow/react</code><a href="https://github.com/12"><code>@12</code></a>.11.0</h2> <h2>12.11.0</h2> <h3>Minor Changes</h3> <ul> <li><a href="https://redirect.github.com/xyflow/xyflow/pull/5677">#5677</a> <a href="https://github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62"><code>e6661de</code></a> - Add <code>autoPanOnSelection</code> to auto-pan when user drags a selection close to the edge of the viewport.</li> </ul> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5791">#5791</a> <a href="https://github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c"><code>732c8eb</code></a> - Adds a type error when <code>handleId</code> is used without <code>handleType</code> in <code>useNodeConnections</code></p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5793">#5793</a> <a href="https://github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb"><code>c5c853d</code></a> - Dev Warnings now use library-specific messaging with the correct documentation links.</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5776">#5776</a> <a href="https://github.com/xyflow/xyflow/commit/0441e9f9471380b5ba057fc0a6a8cbdc6ff5ed7b"><code>0441e9f</code></a> - Export <code>NodeHandle</code> type</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5755">#5755</a> <a href="https://github.com/xyflow/xyflow/commit/88737f9713f3a6f99c6448e02b6518c7aeedae28"><code>88737f9</code></a> - Add <code>@types/react</code> and <code>@types/react-dom</code> as optional peer dependencies to prevent issues with pnpm strict mode (<code>hoist: false</code>)</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5105">#5105</a> <a href="https://github.com/xyflow/xyflow/commit/076ad3893725f654641f7b8c39e7a4e7935eb702"><code>076ad38</code></a> - Fix type for event passed to onNodeDrag</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5784">#5784</a> <a href="https://github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472"><code>7055140</code></a> - Fix node resizing possible beyond absolute extents</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5769">#5769</a> <a href="https://github.com/xyflow/xyflow/commit/ad4d547724a1c2debf8eb7c6e117aabbfd601934"><code>ad4d547</code></a> - Use <code>useEffect</code> for StoreUpdater to restore previous behaviour</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c"><code>732c8eb</code></a>, <a href="https://github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb"><code>c5c853d</code></a>, <a href="https://github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62"><code>e6661de</code></a>, <a href="https://github.com/xyflow/xyflow/commit/737194d571894dd84ce7cbab02f2a4d0b779d018"><code>737194d</code></a>, <a href="https://github.com/xyflow/xyflow/commit/40660cdb054fb1a110799a3ad7cecbf51371727f"><code>40660cd</code></a>, <a href="https://github.com/xyflow/xyflow/commit/4806e7cde6d69cd7570098ecca86523666b80175"><code>4806e7c</code></a>, <a href="https://github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472"><code>7055140</code></a>]:</p> <ul> <li><code>@xyflow/system</code><a href="https://github.com/0"><code>@0</code></a>.0.77</li> </ul> </li> </ul> <h2><code>@xyflow/react</code><a href="https://github.com/12"><code>@12</code></a>.10.2</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5735">#5735</a> <a href="https://github.com/xyflow/xyflow/commit/a6c938fb2e5ed030512ef75d665ac80dc3a66bc6"><code>a6c938fb2</code></a> Thanks <a href="https://github.com/nvie"><code>@nvie</code></a>! - Allow <code>type</code> field to be missing in <code>BuiltInNode</code> (no <code>type</code> field is the same as <code>type: "default"</code>)</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5722">#5722</a> <a href="https://github.com/xyflow/xyflow/commit/8c9b7e726e0bb79871c85017dace0f1ccf1b478c"><code>8c9b7e726</code></a> Thanks <a href="https://github.com/dfblhmm"><code>@dfblhmm</code></a>! - Add <code>snapGrid</code> to <code>screenToFlowPosition</code> options</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5723">#5723</a> <a href="https://github.com/xyflow/xyflow/commit/82249517a3338d7bd0d6d499abecfaa6bca8c339"><code>82249517a</code></a> Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>! - Pass options to useReactFlow/useSvelteFlow viewport helper functions correctly</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">@xyflow/react's changelog</a>.</em></p> <blockquote> <h2>12.11.0</h2> <h3>Minor Changes</h3> <ul> <li><a href="https://redirect.github.com/xyflow/xyflow/pull/5677">#5677</a> <a href="https://github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62"><code>e6661de</code></a> - Add <code>autoPanOnSelection</code> to auto-pan when user drags a selection close to the edge of the viewport.</li> </ul> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5791">#5791</a> <a href="https://github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c"><code>732c8eb</code></a> - Adds a type error when <code>handleId</code> is used without <code>handleType</code> in <code>useNodeConnections</code></p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5793">#5793</a> <a href="https://github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb"><code>c5c853d</code></a> - Dev Warnings now use library-specific messaging with the correct documentation links.</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5776">#5776</a> <a href="https://github.com/xyflow/xyflow/commit/0441e9f9471380b5ba057fc0a6a8cbdc6ff5ed7b"><code>0441e9f</code></a> - Export <code>NodeHandle</code> type</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5755">#5755</a> <a href="https://github.com/xyflow/xyflow/commit/88737f9713f3a6f99c6448e02b6518c7aeedae28"><code>88737f9</code></a> - Add <code>@types/react</code> and <code>@types/react-dom</code> as optional peer dependencies to prevent issues with pnpm strict mode (<code>hoist: false</code>)</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5105">#5105</a> <a href="https://github.com/xyflow/xyflow/commit/076ad3893725f654641f7b8c39e7a4e7935eb702"><code>076ad38</code></a> - Fix type for event passed to onNodeDrag</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5784">#5784</a> <a href="https://github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472"><code>7055140</code></a> - Fix node resizing possible beyond absolute extents</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5769">#5769</a> <a href="https://github.com/xyflow/xyflow/commit/ad4d547724a1c2debf8eb7c6e117aabbfd601934"><code>ad4d547</code></a> - Use <code>useEffect</code> for StoreUpdater to restore previous behaviour</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c"><code>732c8eb</code></a>, <a href="https://github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb"><code>c5c853d</code></a>, <a href="https://github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62"><code>e6661de</code></a>, <a href="https://github.com/xyflow/xyflow/commit/737194d571894dd84ce7cbab02f2a4d0b779d018"><code>737194d</code></a>, <a href="https://github.com/xyflow/xyflow/commit/40660cdb054fb1a110799a3ad7cecbf51371727f"><code>40660cd</code></a>, <a href="https://github.com/xyflow/xyflow/commit/4806e7cde6d69cd7570098ecca86523666b80175"><code>4806e7c</code></a>, <a href="https://github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472"><code>7055140</code></a>]:</p> <ul> <li><code>@xyflow/system</code><a href="https://github.com/0"><code>@0</code></a>.0.77</li> </ul> </li> </ul> <h2>12.10.2</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5735">#5735</a> <a href="https://github.com/xyflow/xyflow/commit/a6c938fb2e5ed030512ef75d665ac80dc3a66bc6"><code>a6c938fb2</code></a> Thanks <a href="https://github.com/nvie"><code>@nvie</code></a>! - Allow <code>type</code> field to be missing in <code>BuiltInNode</code> (no <code>type</code> field is the same as <code>type: "default"</code>)</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5722">#5722</a> <a href="https://github.com/xyflow/xyflow/commit/8c9b7e726e0bb79871c85017dace0f1ccf1b478c"><code>8c9b7e726</code></a> Thanks <a href="https://github.com/dfblhmm"><code>@dfblhmm</code></a>! - Add <code>snapGrid</code> to <code>screenToFlowPosition</code> options</p> </li> <li> <p><a href="https://redirect.github.com/xyflow/xyflow/pull/5723">#5723</a> <a href="https://github.com/xyflow/xyflow/commit/82249517a3338d7bd0d6d499abecfaa6bca8c339"><code>82249517a</code></a> Thanks <a href="https://github.com/moklick"><code>@moklick</code></a>! - Pass options to useReactFlow/useSvelteFlow viewport helper functions correctly</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/xyflow/xyflow/commit/6970ded32ff745e8fb6ecc97eb6b78956d7cc016"><code>6970ded</code></a> chore(packages): bump</li> <li><a href="https://github.com/xyflow/xyflow/commit/c9db70d050830fa1b06703ef775b12120a0662e2"><code>c9db70d</code></a> Merge branch 'main' of <a href="https://github.com/xyflow/xyflow">https://github.com/xyflow/xyflow</a> into 5780-svelte-flow...</li> <li><a href="https://github.com/xyflow/xyflow/commit/af23aef9de095f68fc893b8d18296398c54329bf"><code>af23aef</code></a> chore: cleanup error messages</li> <li><a href="https://github.com/xyflow/xyflow/commit/9d58ab9d2ff1bbf1dc79bb556cc9eed725d116d6"><code>9d58ab9</code></a> fix: make error messages framework-specific</li> <li><a href="https://github.com/xyflow/xyflow/commit/e52bb557888fbae0237432300142180aaca1774f"><code>e52bb55</code></a> Merge pull request <a href="https://github.com/xyflow/xyflow/tree/HEAD/packages/react/issues/5105">#5105</a> from thedanchez/xydrag-type-generics</li> <li><a href="https://github.com/xyflow/xyflow/commit/03e3dc0ae6ac64d77ab9281a3dbf629ee8b75d4e"><code>03e3dc0</code></a> Merge pull request <a href="https://github.com/xyflow/xyflow/tree/HEAD/packages/react/issues/5755">#5755</a> from nielskaspers/fix/issue-5738-react-types-peer-dep</li> <li><a href="https://github.com/xyflow/xyflow/commit/caebfd681b997020fe20444c181113d161ff7aa0"><code>caebfd6</code></a> Merge pull request <a href="https://github.com/xyflow/xyflow/tree/HEAD/packages/react/issues/5784">#5784</a> from xyflow/fix-node-resizer-again</li> <li><a href="https://github.com/xyflow/xyflow/commit/9dc7ec938bed30b59417bade64473cb8f795e039"><code>9dc7ec9</code></a> chore(react): fix util function</li> <li><a href="https://github.com/xyflow/xyflow/commit/c4e783308c2adb022a431a4eb0fb8e46706e27c7"><code>c4e7833</code></a> Merge pull request <a href="https://github.com/xyflow/xyflow/tree/HEAD/packages/react/issues/5785">#5785</a> from xyflow/fix-useless-promises</li> <li><a href="https://github.com/xyflow/xyflow/commit/01fb1f1524d6b514145c1c906e1e5b2b8bb359bb"><code>01fb1f1</code></a> chore(system): add UseNodeConnectionsParams type</li> <li>Additional commits viewable in <a href="https://github.com/xyflow/xyflow/commits/@xyflow/react@12.11.0/packages/react">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for <code>@xyflow/react</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 show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21561?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
a84a4c1ab7 |
fix(server): load integration jest config transpile-only; drop tsx pin (#21563)
## Context Follow-up to [#21559](https://github.com/twentyhq/twenty/pull/21559) (the esbuild 0.28.1 security bump). That PR had to pin `tsx` to `4.21.0` to avoid a CI-only `server-integration-test` failure. This removes the need for that pin by fixing the root cause. ## Root cause The integration-test command boots jest with `NODE_OPTIONS="--import tsx/esm"`, while jest *also* compiles `jest-integration.config.ts` with **ts-node, type-checking on**. Two TypeScript transformers run over the same file: - tsx's loader transpiles `node-environment.interface.ts` via esbuild, downleveling the enum to `var NodeEnvironment = (…)(NodeEnvironment || {})`. - jest's ts-node then *type-checks that downleveled output* and rejects it with `TS7022: 'NodeEnvironment' … referenced directly or indirectly in its own initializer`. It's not a real type error and not esbuild's fault — esbuild's output is valid JS, just not valid TS to re-type-check. It only surfaced once `tsx` resolved to `4.22.x` (whose loader feeds that output into ts-node), which is why #21559 pinned tsx to 4.21.0. Verified in isolation: ts-node type-checking esbuild's downleveled enum → `TS7022`; the same under `transpileOnly`/`TS_NODE_TRANSPILE_ONLY=true` → clean. ## Fix Run the integration jest config **transpile-only** (`TS_NODE_TRANSPILE_ONLY=true` on the `test:integration` target, base + `with-db-reset`). The config file doesn't need type-checking at boot, and jest's ts-node now emits JS without re-type-checking esbuild's output — eliminating the whole class of tsx/esbuild-downleveling sensitivity. With the collision gone, drop the workaround from the root `package.json`: - removed the `tsx: 4.21.0` resolution - removed the `tsx/esbuild: 0.28.1` resolution `tsx`'s `^4.x` ranges now resolve to **4.22.4**, which pins esbuild `~0.28.0` → **0.28.1** on its own, so esbuild stays 0.28.1 across the lockfile with no resolution. The `//resolutions` doc block is updated accordingly. ## Verification - `yarn install` clean; lockfile has only esbuild 0.28.1; tsx resolves to 4.22.4. - `jest --config ./jest-integration.config.ts --listTests` with tsx 4.22.4 + `TS_NODE_TRANSPILE_ONLY=true` loads the config and lists all 420 suites. - CI `server-integration-test` is the real validator (the failure was CI-only). <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21563?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
6a6fe81d3a |
chore(deps): ignore chokidar in dependabot (#21564)
## Context Dependabot keeps proposing a chokidar v3 to v4 bump (e.g. #21555), but chokidar is intentionally pinned to v3 via a `resolutions` entry in the root `package.json`. chokidar v4 removed the native macOS FSEvents backend and falls back to `node:fs.watch`, which hits `EMFILE` on a repo this size. That was diagnosed and fixed in #20316. The bump can't even be satisfied while the resolution is in place, so the lockfile and `package.json` end up inconsistent and CI goes red. ## Change Add `chokidar` to the dependabot ignore list so it stops re-proposing the bump every cycle. The pin stays until upstream restores a native watcher backend. Closes out #21555. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21564?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
c5c8cf1379 |
fix(setup-script): add database schema initialization to setup script (#20063)
fixes #20062 ### Changes Made packages/twenty-utils/setup-dev-env.sh: - Added step 4 to header comment (line 11) - Added schema_exists() helper function (lines 83-91) — checks if core schema exists in default database - Added schema initialization step (lines 255-270) — runs npx nx database:reset twenty-server when schema doesn't exist - Fixed conflicting error message (line 267) CLAUDE.md: - Updated line 210 to document that the script now initializes database schema --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
fa80eb68b3 |
fix(deps): upgrade esbuild to 0.28.1 (GHSA-gv7w-rqvm-qjhr) (#21559)
## Context Clears [Dependabot alert #1469](https://github.com/twentyhq/twenty/security/dependabot/1469) — esbuild Deno-module binary-integrity RCE (`GHSA-gv7w-rqvm-qjhr`, vulnerable `>=0.17.0 <0.28.1`, fixed in `0.28.1`). The advisory's range is much wider than the previous esbuild one (`>=0.27.3`), so it re-exposed several older transitive esbuild copies in the tree. ## Approach Prefer upgrading the parent over adding a resolution; resolutions only where the latest upstream release still pins a vulnerable esbuild **outside** the `0.28.1` range (so an upgrade can't help). **Upgraded parent (no resolution needed):** - `tsx` → `^4.22.4` across all workspaces (its `~0.28.0` esbuild now resolves to 0.28.1) - `size-limit` / `@size-limit/preset-small-lib` → `^12.1.0` in `twenty-ui` (v12 pins esbuild `^0.28.0`) **Resolutions added** (verified against npm — latest still pins vulnerable esbuild): - `@opennextjs/aws` (exact-pins 0.25.4, still 0.25.4 in latest 4.0.3) - `@lingui/cli` (`^0.25.1`, caps `<0.26`, unchanged in latest 6.3.0) - `storybook` (range tops at `^0.27.0`, caps `<0.28`, unchanged in latest 10.4.4) - `zapier-platform-cli` (exact-pins 0.25.8, latest) The three existing esbuild resolutions (`wrangler`, `@react-email/ui`, `react-email`) remain. The `//resolutions` doc in `package.json` and the `.yarnrc.yml` age-gate comment were updated to cover both advisories. ## Result Every esbuild copy in `yarn.lock` now resolves to a single `0.28.1` entry — no version `<0.28.1` remains. Lockfile change is a net reduction (dropped duplicate esbuild trees + their `@esbuild/*` platform binaries); no unrelated deps bumped. `yarn install` passes with constraint checks enabled. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21559?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
3cebae3be0 |
chore(deps): bump @quilted/threads from 4.0.1 to 4.0.3 (#21560)
Bumps [@quilted/threads](https://github.com/lemonmade/quilt/tree/HEAD/packages/threads) from 4.0.1 to 4.0.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/lemonmade/quilt/releases">@quilted/threads's releases</a>.</em></p> <blockquote> <h2><code>@quilted/threads</code><a href="https://github.com/4"><code>@4</code></a>.0.3</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/lemonmade/quilt/pull/950">#950</a> <a href="https://github.com/lemonmade/quilt/commit/226730924331208b252a128299f445f80150f9d3"><code>2267309</code></a> Thanks <a href="https://github.com/lemonmade"><code>@lemonmade</code></a>! - Upgraded the Preact and Hono dependency ecosystems to their current releases: preact 10.29.2, preact-render-to-string 6.7.0, <code>@preact/signals</code> 2.9, <code>@preact/signals-core</code> 1.14.2, <code>@prefresh/vite</code> 3, hono 4.12, and <code>@hono/node-server</code> 2. These are bumped together, and pinned to a single version tree-wide (via pnpm overrides), because mixing Preact copies crashes server rendering.</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/lemonmade/quilt/commit/226730924331208b252a128299f445f80150f9d3"><code>2267309</code></a>]:</p> <ul> <li><code>@quilted/events</code><a href="https://github.com/2"><code>@2</code></a>.1.5</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/lemonmade/quilt/blob/main/packages/threads/CHANGELOG.md">@quilted/threads's changelog</a>.</em></p> <blockquote> <h2>4.0.3</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/lemonmade/quilt/pull/950">#950</a> <a href="https://github.com/lemonmade/quilt/commit/226730924331208b252a128299f445f80150f9d3"><code>2267309</code></a> Thanks <a href="https://github.com/lemonmade"><code>@lemonmade</code></a>! - Upgraded the Preact and Hono dependency ecosystems to their current releases: preact 10.29.2, preact-render-to-string 6.7.0, <code>@preact/signals</code> 2.9, <code>@preact/signals-core</code> 1.14.2, <code>@prefresh/vite</code> 3, hono 4.12, and <code>@hono/node-server</code> 2. These are bumped together, and pinned to a single version tree-wide (via pnpm overrides), because mixing Preact copies crashes server rendering.</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/lemonmade/quilt/commit/226730924331208b252a128299f445f80150f9d3"><code>2267309</code></a>]:</p> <ul> <li><code>@quilted/events</code><a href="https://github.com/2"><code>@2</code></a>.1.5</li> </ul> </li> </ul> <h2>4.0.2</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://github.com/lemonmade/quilt/commit/e6fa47e93981ce0eaebbe1546659aaa08cc22689"><code>e6fa47e</code></a> Thanks <a href="https://github.com/lemonmade"><code>@lemonmade</code></a>! - Update Preact and Signal dependencies</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/lemonmade/quilt/commit/e6fa47e93981ce0eaebbe1546659aaa08cc22689"><code>e6fa47e</code></a>]:</p> <ul> <li><code>@quilted/events</code><a href="https://github.com/2"><code>@2</code></a>.1.4</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/lemonmade/quilt/commit/f1ade77a713a4ec7975e396e605574d4729d9026"><code>f1ade77</code></a> Publish packages 🚀 (<a href="https://github.com/lemonmade/quilt/tree/HEAD/packages/threads/issues/952">#952</a>)</li> <li><a href="https://github.com/lemonmade/quilt/commit/226730924331208b252a128299f445f80150f9d3"><code>2267309</code></a> deps: TypeScript 6, dependency refresh, and the Preact/Hono ecosystems (<a href="https://github.com/lemonmade/quilt/tree/HEAD/packages/threads/issues/950">#950</a>)</li> <li><a href="https://github.com/lemonmade/quilt/commit/b66448a0dcd513280aad4a90e9afc0d8057bb638"><code>b66448a</code></a> Publish packages (<a href="https://github.com/lemonmade/quilt/tree/HEAD/packages/threads/issues/896">#896</a>)</li> <li><a href="https://github.com/lemonmade/quilt/commit/e6fa47e93981ce0eaebbe1546659aaa08cc22689"><code>e6fa47e</code></a> Update Preact dependencies</li> <li>See full diff in <a href="https://github.com/lemonmade/quilt/commits/@quilted/threads@4.0.3/packages/threads">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for <code>@quilted/threads</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 show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21560?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
18fde38b43 |
chore(deps): bump @ai-sdk/anthropic from 3.0.72 to 3.0.84 (#21557)
Bumps [@ai-sdk/anthropic](https://github.com/vercel/ai/tree/HEAD/packages/anthropic) from 3.0.72 to 3.0.84. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vercel/ai/releases">@ai-sdk/anthropic's releases</a>.</em></p> <blockquote> <h2><code>@ai-sdk/google</code><a href="https://github.com/3"><code>@3</code></a>.0.82</h2> <h3>Patch Changes</h3> <ul> <li> <p>3258f22: fix(google): prevent prototype pollution when streaming tool args</p> </li> <li> <p>bfa5864: fix: only send provider credentials to same-origin response-supplied URLs</p> <p>Several provider clients followed a URL taken from the provider's API response (a polling/status URL or a final media URL such as <code>polling_url</code>, <code>urls.get</code>, <code>result_url</code>, <code>result.sample</code>, or <code>video.uri</code>) and reused the authenticated headers — or appended <code>?key=<API_KEY></code> — on that request. Because the host of the response-supplied URL was never validated, the long-lived API key was sent to whatever host the response named (a CDN in the benign case, or an attacker-chosen host if the provider response was tampered with), allowing credential exfiltration.</p> <p>A new <code>isSameOrigin</code> helper is added to <code>@ai-sdk/provider-utils</code>, and the affected fetches in <code>@ai-sdk/black-forest-labs</code>, <code>@ai-sdk/fireworks</code>, <code>@ai-sdk/replicate</code>, <code>@ai-sdk/gladia</code>, <code>@ai-sdk/fal</code>, and <code>@ai-sdk/google</code> now attach credentials only when the followed URL is same-origin with the provider's configured API origin. Requests to a foreign origin are made without the credential.</p> </li> <li> <p>Updated dependencies [bfa5864]</p> </li> <li> <p>Updated dependencies [f42aa79]</p> <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.29</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vercel/ai/blob/@ai-sdk/anthropic@3.0.84/packages/anthropic/CHANGELOG.md">@ai-sdk/anthropic's changelog</a>.</em></p> <blockquote> <h2>3.0.84</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [bfa5864]</li> <li>Updated dependencies [f42aa79] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.29</li> </ul> </li> </ul> <h2>3.0.83</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [942f2f8] <ul> <li><code>@ai-sdk/provider-utils</code><a href="https://github.com/4"><code>@4</code></a>.0.28</li> </ul> </li> </ul> <h2>3.0.82</h2> <h3>Patch Changes</h3> <ul> <li>2a91a17: feat(provider/anthropic): add support for <code>claude-fable-5</code> and the <code>fallbacks</code> API parameter</li> </ul> <h2>3.0.81</h2> <h3>Patch Changes</h3> <ul> <li>4084fcd: feat(provider/anthropic): add support for <code>claude-opus-4-8</code></li> </ul> <h2>3.0.80</h2> <h3>Patch Changes</h3> <ul> <li>263d3e6: fix(provider/anthropic): fix remaining errors with Anthropic <code>code_execution</code> tool dynamic calls from latest <code>web_fetch</code> or <code>web_search</code></li> </ul> <h2>3.0.79</h2> <h3>Patch Changes</h3> <ul> <li>d61a788: Handle errors from anthropic websearch tool</li> </ul> <h2>3.0.78</h2> <h3>Patch Changes</h3> <ul> <li>6e28d25: fix(anthropic): propagate toModelOutput providerOption to anthropic tool results</li> </ul> <h2>3.0.77</h2> <h3>Patch Changes</h3> <ul> <li>d53314d: feat(anthropic): add the new advisor tool</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vercel/ai/commit/bae9babb22e195e74a9a0c0e26a5e52c8ba8e7f2"><code>bae9bab</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/16026">#16026</a>)</li> <li><a href="https://github.com/vercel/ai/commit/9ef2c3cfadfc4a469e9eec6a6e8a0ac0fc80a1e5"><code>9ef2c3c</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15998">#15998</a>)</li> <li><a href="https://github.com/vercel/ai/commit/f6e588173713842794c619f9554a4b341c6e97f5"><code>f6e5881</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15902">#15902</a>)</li> <li><a href="https://github.com/vercel/ai/commit/2a91a17e0b885968814110fe3581d1ea0fd589ae"><code>2a91a17</code></a> backport: feat(provider/anthropic): add support for <code>claude-fable-5</code> and the ...</li> <li><a href="https://github.com/vercel/ai/commit/7aca1fc2004800171233ae16c2456ef297552441"><code>7aca1fc</code></a> backport: chore: update TypeScript references and fix `pnpm update-references...</li> <li><a href="https://github.com/vercel/ai/commit/974e161bed15b0f5bb9980a3f0845ad77ae66d3c"><code>974e161</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15677">#15677</a>)</li> <li><a href="https://github.com/vercel/ai/commit/4084fcd041b47ad11f74d80a82d659748edf0a78"><code>4084fcd</code></a> backport: feat(provider/anthropic): add support for <code>claude-opus-4-8</code> (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15675">#15675</a>)</li> <li><a href="https://github.com/vercel/ai/commit/097c1cdb46226fbfe741764a009ea14baab7c3df"><code>097c1cd</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15612">#15612</a>)</li> <li><a href="https://github.com/vercel/ai/commit/263d3e664503c955f492a33941e2060c4b51aa77"><code>263d3e6</code></a> Backport: fix(provider/anthropic): fix remaining errors with Anthropic `code_...</li> <li><a href="https://github.com/vercel/ai/commit/7ebba33ab965b5b26f93705719d76db45089bb3c"><code>7ebba33</code></a> Version Packages (<a href="https://github.com/vercel/ai/tree/HEAD/packages/anthropic/issues/15557">#15557</a>)</li> <li>Additional commits viewable in <a href="https://github.com/vercel/ai/commits/@ai-sdk/anthropic@3.0.84/packages/anthropic">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21557?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
0fe1ae205d |
chore(deps): bump fs-extra from 11.2.0 to 11.3.5 (#21556)
Bumps [fs-extra](https://github.com/jprichardson/node-fs-extra) from 11.2.0 to 11.3.5. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/jprichardson/node-fs-extra/blob/master/CHANGELOG.md">fs-extra's changelog</a>.</em></p> <blockquote> <h2>11.3.5 / 2026-05-06</h2> <ul> <li>Fix <code>ensureLink*</code>/<code>ensureSymlink*</code> identical file detection on Windows (<a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1068">#1068</a>)</li> <li>Fix error handling in timestamp preservation code (<a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1065">#1065</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1069">#1069</a>)</li> <li>Fix potential file descriptor leak on error in synchronous timestamp preservation code (<a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1066">#1066</a>)</li> </ul> <h2>11.3.4 / 2026-03-03</h2> <ul> <li>Fix bug where calling <code>ensureSymlink</code>/<code>ensureSymlinkSync</code> with a relative <code>srcPath</code> would fail if the symlink already existed (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1038">#1038</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1064">#1064</a>)</li> </ul> <h2>11.3.3 / 2025-12-18</h2> <ul> <li>Fix copying symlink when destination is a symlink to the same target (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1019">#1019</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1060">#1060</a>)</li> </ul> <h2>11.3.2 / 2025-09-15</h2> <ul> <li>Fix spurrious <code>UnhandledPromiseRejectionWarning</code> that could occur when calling <code>.copy()</code> in some cases (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1056">#1056</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1058">#1058</a>)</li> </ul> <h2>11.3.1 / 2025-08-05</h2> <ul> <li>Fix case where <code>move</code>/<code>moveSync</code> could incorrectly think files are identical on Windows (<a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1050">#1050</a>)</li> </ul> <h2>11.3.0 / 2025-01-15</h2> <ul> <li>Add promise support for newer <code>fs</code> methods (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1044">#1044</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1045">#1045</a>)</li> <li>Use <code>fs.opendir</code> in <code>copy()</code>/<code>copySync()</code> for better perf/scalability (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/972">#972</a>, <a href="https://redirect.github.com/jprichardson/node-fs-extra/pull/1028">#1028</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/8a88f58e2cc38e3bbd0505b19e3a573a62e8c84b"><code>8a88f58</code></a> 11.3.5</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/81a1311ec86597e28f50fc8ab6a5e74706990c06"><code>81a1311</code></a> Mirror all utimesMillis() tests for utimesMillisSync() (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1070">#1070</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/b7ab7f86a7a01b00e64a081a1df240e30b2e55af"><code>b7ab7f8</code></a> Properly handle close errors in utimesMillis*() (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1069">#1069</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/1c248ed4b309072c5e1a14287db6b9e6de14d172"><code>1c248ed</code></a> Fix file descriptor leak in <code>utimesMillisSync</code> (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1066">#1066</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/a4000d6c9dcd9db8c8f82f7bd966c68710a3d737"><code>a4000d6</code></a> Ensure all usages of areIdentical receive bigint stats (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1068">#1068</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/1e9c57de9fc5e766d3c9938fc7289080c444a568"><code>1e9c57d</code></a> Fix error handling in utimesMillis (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1065">#1065</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/353a29b18c883fa0f3997fd8be90a89077633af4"><code>353a29b</code></a> 11.3.4</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/3e65fbe81e565e2cd16a5f0ff1b3d8623610bb7a"><code>3e65fbe</code></a> fix(ensureSymlink): resolve relative srcpath correctly when symlink exists (#...</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/e2615e501e7b261b832170b3eb7e26c82668b215"><code>e2615e5</code></a> Fix git URL in package.json (<a href="https://redirect.github.com/jprichardson/node-fs-extra/issues/1062">#1062</a>)</li> <li><a href="https://github.com/jprichardson/node-fs-extra/commit/1de81e98a8ff3afb5cf4a6b4dc63a93216728dd3"><code>1de81e9</code></a> 11.3.3</li> <li>Additional commits viewable in <a href="https://github.com/jprichardson/node-fs-extra/compare/11.2.0...11.3.5">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21556?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
965ff4337f |
fix(front): mass update targets explicitly selected records (#21548)
## Problem Mass update silently does nothing for explicitly-selected records in a filtered view (reported in [quality-feedbacks](https://discord.com/channels/1130383047699738754/1515444299934728213) — "Mass update does not work (for boolean?)", high severity). When you select specific records (selection mode) and run **Update records**, the action built its target filter with `computeContextStoreFilters`, which intersects the selected record ids with the **current view filters**: ```ts // selection mode (before) queryFilter = makeAndFilterVariables([ anyFieldFilter, { id: { in: selectedRecordIds } }, computeRecordGqlOperationFilter({ ...view filters... }), // ← intersect with view ]); ``` `useIncrementalUpdateManyRecords` first **fetches** the ids matching that filter, then updates them: ```ts if (firstPageRecordIds.length > 0) { await mutateRecordsBatch(...); // never runs when the fetch returns 0 } ``` So any selected record that doesn't match the view filter is silently dropped. When *none* of the selected records match, the fetch returns 0 → the `updateMany` mutation never fires → only the trailing refetch/aggregate queries run, and nothing changes. The confirmation modal still says "Update N records" (it reads `selectedRecordIds.length`), and the side-panel header shows "0 selected" (it reads the find result) — the exact symptoms in the report. This is especially easy to hit when updating the very field a view is filtered on (e.g. a view filtered "QA Done = false" and you set "QA Done = true" on the selected rows). ## Fix In **selection mode**, target exactly the selected ids — the user picked those records, so the action must act on them regardless of the active view filter / any-field search: ```ts // selection mode (after) return { id: { in: contextStoreTargetedRecordsRule.selectedRecordIds } }; ``` Exclusion mode (select-all) is unchanged — it still needs the view filter to define "all matching except N". This also makes the side-panel "N selected" count and other selection-mode actions (delete, export, …) consistent with the explicit selection. ## Reproduction (deterministic) 1. Companies view filtered **QA Done = false**. 2. Select 3 rows individually. 3. Change those rows so they no longer match the filter (set `qaDone = true`) without refetching the view — they stay selected. 4. Open **Update**, set **Employees = 100**, confirm "Update 3 records". **Before:** `Employees` stays `NULL`; side panel shows "0 selected". **After:** `Employees = 100` on all 3; side panel shows "3 selected". ## Tests - Updated `computeContextStoreFilters` selection-mode test to the new shape. - Added a regression test asserting selection mode targets only the selected ids and ignores active view filters / any-field search. `nx lint:diff-with-main`, `nx typecheck twenty-front`, and the unit tests pass. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21548?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
25b0e4d81c |
fix: #19173 correct labels and icons for custom object default relations (#19224)
**### Problem**
When creating a custom Data Model object, the auto-generated Note and
Task relations had incorrect labels ("Note Targets", "Task Targets") and
a wrong hardcoded icon (IconBuildingSkyscraper).
Expected behavior is to use user-friendly labels ("Notes", "Tasks") and
proper icons, consistent with standard objects like Company and Person.
**Root causes:**
* `icon` in `createFieldInput` was hardcoded to
`'IconBuildingSkyscraper'`
* `label` was derived from `targetFlatObjectMetadata.labelPlural`, which
returns system labels (e.g., "Note Targets") instead of display labels
---
**Fix**
* Added `sourceFieldOverridesByRelationObjectNameSingular` map to define
correct labels and icons for all default relation types
* Ensures consistency with standard objects
Mappings:
* noteTarget: "Note Targets" → "Notes", IconBuildingSkyscraper →
IconNotes
* taskTarget: "Task Targets" → "Tasks", IconBuildingSkyscraper →
IconCheckbox
* attachment: "Attachments" → "Attachments", IconBuildingSkyscraper →
IconFileImport
* timelineActivity: "Timeline Activities" → "Timeline Activities",
IconBuildingSkyscraper → IconTimelineEvent
* favorite: "Favorites" → "Favorites", IconBuildingSkyscraper →
IconHeart
* Added type safety using:
`satisfies Record<(typeof
DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS)[number], ...>`
This ensures new default relations must be explicitly defined
* Renamed variable:
`icon` → `targetFieldIcon`
for better clarity (it is only used for the target field)
---
**Limitations**
* Applies only to newly created custom objects
* Existing objects will keep incorrect labels/icons
* Requires a separate data migration to fix existing data
---
**Testing**
1. Go to Settings → Data Model
2. Create a new custom object
3. Verify:
* Labels show "Notes" and "Tasks" (not "Note Targets"/"Task Targets")
* Icons match those used in standard objects (e.g., Company, Person)
---
## Update (reworked while merging main)
The original approach was reworked:
- The label/icon mapping now lives in a shared
`STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT` constant
(`msg`-based, so labels stay translatable), used as the single source of
truth. Dropped the unused `favorite` entry.
- Standard objects now reference that same constant explicitly at each
call site (uniformization) instead of duplicating the values. Objects
that intentionally differ keep their explicit overrides: note/task →
`Relations`, person/workspaceMember → `Events`, workflow attachments →
`IconFileUpload`.
- Fixed an unrelated typo found along the way: Company's
`timelineActivities` icon was `IconIconTimelineEvent`.
- For the history (supersedes the "Limitations" above): added a `2.9.0`
workspace upgrade command
`upgrade:2-9:fix-standard-relation-field-labels-icons` that re-syncs
**standard** objects' default relation labels/icons against the source
of truth. It deliberately leaves **custom** objects untouched — their
relation fields are user-editable and must not be overwritten by an
upgrade.
## Testing / Verification
Verified locally end-to-end:
**New custom objects**
- Created a custom object via the Data Model UI and via the metadata API
— its note/task/attachment/timeline relations now show `Notes` / `Tasks`
/ `Attachments` / `Timeline Activities` with the correct icons instead
of `Note Targets` + `IconBuildingSkyscraper`.
**Standard uniformization (value-preserving)**
- Re-seeded a workspace on this branch and inspected all 25
default-relation field definitions across the 10 standard objects: every
canonical value is unchanged, every intentional variant (Relations /
Events / IconFileUpload) is preserved, and the only diff vs `main` is
the Company `IconIconTimelineEvent` → `IconTimelineEvent` fix.
**Upgrade command (existing workspaces)**
- Simulated a real upgrade: seeded a workspace on `main` (Company icon
typo present), created a custom object via the metadata API (it came out
with the old buggy labels, as expected on `main`), then switched to this
branch and ran the command.
- Confirmed via both the metadata API and direct DB inspection:
Company's standard `timelineActivities` icon healed to
`IconTimelineEvent`, while the custom object's relations were left
untouched.
- Idempotent: re-running reports "already up to date".
**CI**: typecheck, lint, server unit tests, and all server
integration-test shards green.
---------
Co-authored-by: Manish Kumar <manishkumar@Mac.lan>
Co-authored-by: Charles Bochet <charles@twenty.com>
|
||
|
|
a3fe9efb69 |
chore(apps): bump twenty-sdk & twenty-client-sdk to 2.13.0, vitest to 4 (#21553)
## What Bumps **all 14 `twenty-apps`** (internal, examples, community) to the freshly published SDK **2.13.0**, and upgrades `vitest` 3 → 4 so `vite` resolves to 8 (rolldown). - `twenty-sdk` / `twenty-client-sdk`: `2.10.1` → `2.13.0` (each app's original spec format preserved — plain, `^`, and `npm:…@`). - `vitest`: `^3.x` → `^4.0.0` in the 13 apps that use it (`call-recording` has no vitest). ## Why Each app's `yarn.lock` had open Dependabot esbuild alerts — high `GHSA-gv7w-rqvm-qjhr` and low `GHSA-g7r4-m6w7-qqqr`, both fixed in esbuild `0.28.1`. The SDK bump alone does **not** clear them: the advisories fire on *any* esbuild `< 0.28.1`, and each app pulled a vulnerable `esbuild@0.27.7` transitively via **vite** (through the `vitest` devDependency), independent of the SDK. Bumping `vitest` to 4 resolves `vite@8` (rolldown), which drops the esbuild dependency entirely. `twenty-partners` additionally needed a recursive esbuild re-resolution (its `tsx` dep had `esbuild@~0.28.0` pinned at the still-vulnerable `0.28.0`). After this change, **all 14 lockfiles resolve esbuild `0.28.1` only** — zero copies `< 0.28.1`. ## Test - All 14 lockfiles verified free of esbuild `< 0.28.1`. - vitest 4 + vite 8 confirmed working: `people-data-labs` runs **334 tests across 83 files, all passing**. - `twenty-for-twenty`'s suite fails only because its global setup requires a live Twenty server (`/healthz`) — environmental, would fail identically under vitest 3. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21553?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
adfef5c830 |
fix(twenty-front): prevent stale transition page from blocking scroll (#21551)
## Problem Switching from the app to Settings sometimes makes every settings page unscrollable until a full page reload. ## Cause `MainAppLayoutOutlet` cross-fades between the app and settings with `AnimatePresence`, rendering both pages into the same grid cell (`grid-area: 1 / 1`). When an exit animation doesn't clean up, the outgoing page stays mounted on top of the active one. With the default `pointer-events: auto`, that (now invisible) stale node intercepts wheel/scroll events before they reach the page underneath — so the page won't scroll even though its own scroll container is fine. The node lives in the always-mounted layout, which is why it survives in-app navigation and only a reload clears it. A broken vs. working DOM snapshot differs only in the number of children in the transition grid cell (2 vs 1) and which element sits under the cursor; the scroll container, its CSS, and the whole flex/height chain are identical. ## Fix Set `pointer-events: none` on exiting pages so a stale exit node can't capture input from the active page. Tested by reproducing the stale-node-on-top state and confirming `pointer-events: none` lets wheel/scroll reach the live page across the content area, while the entering page stays interactive. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21551?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
0baa333809 |
feat(lint): forbid data mutations in fast instance command up() (#21547)
## Why Fast instance commands run in the ArgoCD **PreSync** hook, before the new pods roll. A bulk `UPDATE`/`INSERT`/`DELETE` held in the **same transaction** as an `ADD COLUMN`/`ALTER` keeps an `ACCESS EXCLUSIVE` lock on the table for the whole write, blocking every read of it. That is what froze prod during the 2.13 `isUIReadOnly → isUIEditable` rename — a bulk `UPDATE "fieldMetadata"` inside the same `up()` transaction as the `ADD COLUMN`s → read timeouts → failed PreSync → aborted sync. @charlesBochet already caught this exact pattern by hand on #21527 ("data migration => make a slow instance command :)"). This turns that manual review into something CI enforces. ## What New oxlint rule **`twenty/no-data-mutation-in-fast-instance-command`**: - Flags statement-leading `UPDATE`/`INSERT`/`DELETE`/`MERGE` passed to `.query(...)` **inside `up()`** of a `*-instance-command-fast-*` file. - Allows: schema DDL (`ALTER`/`CREATE`/`DROP`); `ON DELETE CASCADE` / a column named `updatedAt` (not statement-leading, so never matched); rollback DML in `down()`; and data migrations in **slow** commands' `runDataMigration()`. - The error message points the author straight at the slow-command pattern. Enabled as `error` in `twenty-server`. ## Grandfathering Scoping to `up()` means **only one** existing file violates the rule: the already-shipped 2.13 rename command. It's recorded complete in cloud and must not be rewritten, so it's grandfathered with a documented file-level `oxlint-disable` (the comment makes clear it's an exception, not a precedent). The four other fast commands that contain DML keep theirs in `down()` and are correctly unaffected. ## Tests - 9 RuleTester cases — valid: DDL, FK cascade, `updatedAt`, `down()` DML, slow-command DML, non-upgrade files; invalid: `UPDATE`/`INSERT`/`DELETE` in `up()`. - Verified end-to-end with oxlint: a throwaway violating file → 1 error; all 141 upgrade-command files → 0 errors; full oxlint-rules suite 225/225; typecheck clean. Part of the v2.13 deploy post-mortem follow-ups. https://claude.ai/code/session_013Az1etaGyxWRRVhgjhPWeB --- _Generated by [Claude Code](https://claude.ai/code/session_013Az1etaGyxWRRVhgjhPWeB)_ <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21547?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
47b31acc21 |
ci: exclude all twenty-apps from dependabot (#21554)
Dependabot currently only excludes `packages/twenty-apps/community/**`, but the `twenty-apps` package also contains `examples`, `fixtures`, and `internal` apps that shouldn't be picked up either. This broadens the `exclude-paths` to `packages/twenty-apps/**` so Dependabot ignores apps entirely. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21554?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
53de4c557b |
Fix record index sync when view fields arrive via SSE (#19069)
Fixes #19023 ## What changed This updates the record index/view field state flow so the current view can react to late-arriving `viewFields` coming from SSE without requiring a page refresh. Changes: - extracted a narrower `syncRecordIndexViewFields` path in `useLoadRecordIndexStates` - kept the initial full record-index load for first entry into a view - added a follow-up sync in `RecordIndexLoadBaseOnContextStoreEffect` when the same view receives updated `viewFields` - updated `ViewBarRecordFieldEffect` so it re-syncs current record fields when `currentView.viewFields` changes instead of only initializing once ## Why There is a race when a user navigates to a custom object while AI is still creating metadata. In that case, the record index can initialize from a partial view, and later SSE `viewFields` updates were not being applied to the active view state. That could leave the table visually empty or incomplete until a refresh. ## Impact This should allow: - record index columns to update live when view fields arrive via SSE - view bar field state to update live as well - the current view to stay usable without a refresh while AI-created metadata is still streaming in ## Validation Validated locally with: - `npx prettier --check` on modified files - `npx oxlint --type-aware` on modified files Manual verification: - confirmed live record creation appeared without refresh - manual AI/SSE testing was partially limited by Groq TPM/token caps on the selected model, but the state-sync path was verified in code and local behavior checks <img width="3024" height="1964" alt="image" src="https://github.com/user-attachments/assets/f71c7490-bf57-4357-9d5f-087b2424b53b" /> --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
f45c54679c |
[Fix] : fix: Allow label identifier system fields in view creation and fix resulting duplicate header columns (#19009)
fixes #18994 After : <img width="767" height="230" alt="Screenshot 2026-03-26 at 7 11 04 PM" src="https://github.com/user-attachments/assets/73de0154-7da1-48fa-92fc-d51a3ef5b06e" /> Before : <img width="905" height="314" alt="Screenshot 2026-03-26 at 6 56 38 PM" src="https://github.com/user-attachments/assets/89b1249b-8889-4034-a6c8-d41330154c1a" /> --------- Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local> Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
7c0136b97b |
feat(deps): migrate frontend to React 19 (#21531)
## What Migrates the frontend stack from **React 18.3 → 19.2**. The website, sdk, companion and emails packages were already on React 19; this brings the remaining holdouts (`twenty-front`, `twenty-ui`, `twenty-ui-deprecated`, `twenty-front-component-renderer`) and `twenty-server`'s email rendering onto 19, and pins a single React version repo-wide. ## Why React 18.x is now the legacy line. Staying current keeps us on the patched/maintained branch and unblocks downstream library majors (react-router 7, mantine 9, etc.) that require React 19 peers. ## Dependency bumps (required by React 19 peers / removed APIs) | Package | From | To | Reason | |---|---|---|---| | react / react-dom | 18.3.1 | 19.2.3 | core | | @hello-pangea/dnd | 16 | 18 | peer `^18 \|\| ^19` | | react-datepicker | 6 | 9 | v<7 used removed `findDOMNode`; drops `@types/react-datepicker` | | react-data-grid | beta.13 | beta.59 | peer `^19.2`; new render API | | graphiql (+ @graphiql/react, plugin-explorer) | 3 / 0.23 / 1 | 5 / 0.37 / 5.1 | peer `^18 \|\| ^19` | | react-helmet-async | 1.3 | **@dr.pogodin/react-helmet** 3.2 | upstream caps peer at `^18`; drop-in React 19 fork | A `resolutions` pin enforces a single React (19.2.3) + `@types/react` (19.2.14) across the monorepo to avoid duplicate copies / type-identity splits. Versions are the aged lockfile patches (clears the `npmMinimalAgeGate`). ## Code changes - **Global `JSX` shim** (`react-jsx-global.d.ts` per package): React 19 moved the `JSX` namespace under `React.JSX`; several deps' published types (notably `@linaria/react`'s `styled.d.ts`, which types every `styled.x` via `keyof JSX.IntrinsicElements`) still reference the global namespace. Without the shim, every styled component degrades to `any` props. - **Ref nullability**: `useRef<T>(null)` now returns `RefObject<T | null>`; widened consumer prop/hook ref types accordingly (incl. the shared `useListenClickOutside`). - **react-datepicker v9**: `onChange`/`onSelect` accept `Date | null`, `calendarStartDay` typing, `ReactDatePickerProps`→`DatePickerProps`, relaxed the dynamic `selectsMultiple` discriminated union. - **react-data-grid beta.59**: `formatter`→`renderCell`, `editor`→`renderEditCell`, `headerRenderer`→`renderHeaderCell`, `components`→`renderers`, `onRowClick`→`onCellClick`, object-shaped `useRowSelection`, Set-based selection. - **dnd style cast**: `@radix-ui/react-popper` augments `CSSProperties` with a `--radix-*` index signature that dnd's closed `DraggingStyle` doesn't satisfy → cast at the spread. ## Status / testing - ✅ `typecheck` green: twenty-front, twenty-ui, twenty-ui-deprecated, twenty-front-component-renderer, twenty-server - ⏳ build / lint / unit tests / storybook+argos / runtime smoke-test in progress Draft until local + CI verification completes. Notable behavior to QA manually: spreadsheet import (data-grid), date pickers, drag-and-drop boards/lists, GraphQL playground, page titles/favicon. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21531?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
9901fa93d9 |
fix(server): write 2.13 UI capability flags directly, bypassing validation (#21543)
## Context The `v1.22 → v2.13.x` cross-version upgrade test (twenty-infra) still fails *after* #21537. This is the **same root cause from a deeper layer**, and the fix here ends the class. ## What's actually happening The 2.13 `SyncStandardUiCapabilityFlags` workspace command heals drifted `isUIEditable`/`isUICreatable` on standard metadata by running a **bulk update through `validateBuildAndRunWorkspaceMigration`** — the validation pipeline meant for *user-initiated* metadata edits. That pipeline has multiple "you may not mutate property X on entity Y" guards, and `isSystemBuild: true` only bypasses **some** of them: | guard | gated on `isSystemBuild`? | |---|---| | system-**field** allow-list (`flat-field-metadata-validator.ts:83`) | ✅ bypassed | | system-**object** guard (`flat-object-metadata-validator.ts:63`) | ✅ bypassed | | **relation-field** allow-list (`flat-field-metadata-validator.ts:143`) | ❌ not gated | So the healing command fails on exactly the workspaces that have real drift (the genuinely cross-version-upgraded ones). #21537 patched the relation allow-list by adding `isUIEditable` to it — one guard — and the build then failed on the next. From this run's logs: `Upgrade summary: 42 workspace(s) succeeded, 2 workspace(s) failed` (the 2 drifted workspaces; the build returns `status=fail`, the per-workspace error detail isn't surfaced in logs). **Root cause:** a trusted system flag-backfill should not run through the user-mutation validation layer at all. ## Fix (direct metadata write) `isUIEditable`/`isUICreatable` are UI-affordance columns on `core.fieldMetadata`/`core.objectMetadata` — changing them needs **no workspace-schema migration**. The command now writes them **directly** to those tables (mirroring the 2.13 slow backfill's raw `UPDATE core."objectMetadata"`) and invalidates the flat-metadata cache, bypassing the validation pipeline entirely. Drift detection is unchanged. This removes the whole class of guard rejections instead of patching guards one at a time. ## Verification - `nx typecheck twenty-server` ✅, `oxlint --type-aware` ✅ (the file is intentionally oxfmt-ignored via `**/upgrade-version-command/**`). - ⚠️ I could **not** run a live cross-version repro from the dev container (no Docker/Postgres available here). The fix categorically can't hit the previous failure (the validation pipeline is gone), but the definitive runtime gate is the twenty-infra `cross-version-upgrade` job against a new image. Quick local repro to confirm: on a reset dev DB, flip `isUIEditable` on a standard relation field (e.g. an `activityTargets` `target*` field) so it drifts, run `yarn command:prod upgrade:2-13:sync-standard-ui-capability-flags -w <workspaceId>`, and confirm it completes (pre-fix it threw on the relation field). --- _Generated by [Claude Code](https://claude.ai/code/session_013Az1etaGyxWRRVhgjhPWeB)_ <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21543?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
09f0c9e29a |
fix(address): coerce addressLat/addressLng to numbers in ORM result formatting (#21542)
## Fixes #21390 Saved addresses render as the **"Empty"** placeholder in the record detail / side panel when `addressLat`/`addressLng` are populated (e.g. after picking a Google autocomplete suggestion). The list view shows the address correctly. ## Root cause `addressLat`/`addressLng` are `NUMERIC` composite subfields, stored as Postgres `numeric` columns — which the `pg` driver returns as **strings** to preserve precision. The ORM result formatter already normalizes this for Currency, but not for Address. In `packages/twenty-server/src/engine/twenty-orm/utils/format-result.util.ts`, `formatCompositeFieldValue` had a case for `CURRENCY.amountMicros` (`parseInt`) but **no case for `ADDRESS`**, so coordinates were passed through as raw strings. This only breaks the **record detail**, not the list view, because: - The **standard GraphQL (Yoga) path** masks it — the `BigFloat` scalar's `serialize()` runs `parseFloat()` and quietly turns the string into a number on the wire. - The **direct-execution path** formats results itself and bypasses scalar serialization, so the string reaches the frontend. There, `addressFieldValueSchema` validates lat/lng with `z.number()` → `isFieldAddressValue` returns `false` → `isFieldValueEmpty` returns `true` → `RecordInlineCellDisplayMode` renders the placeholder. The table cell renders the value directly with no empty-check, so the list view is unaffected. ## Why it surfaced now The `z.number()` constraint on lat/lng is old ("latent since the address guard was introduced"). The trigger was **#19254 (2026-04-03) "Remove direct execution feature flag"**, which made direct execution always-on for workspace queries — the same PR added string→number coercion for aggregates but not for composite subfields. **#21033** (the PR the issue blames) only made `addressStreet1` nullable; it didn't touch lat/lng, but by fixing the overlapping null-street1 case it isolated and exposed this one. ## Fix Add the `ADDRESS` case to `formatCompositeFieldValue`, mirroring Currency. Coordinates are fractional, so `parseFloat` is used (Currency uses `parseInt` because micros are integers). This is the exact operation the `BigFloat` scalar already performs, so there is no behavior change on the standard path — it just makes direct execution consistent, and lat/lng are now numbers everywhere (matching `FieldAddressValue`). No frontend change is needed. ## Scope check — similar bugs in other field types/composites This bug class = a transforming scalar `serialize` that direct execution doesn't replicate. The only scalar that changes a pg-returned type for a real field is `BigFloat` (`NUMERIC` → number). The only `NUMERIC` fields are the two composite subfields: - `CURRENCY.amountMicros` — already handled ✅ - `ADDRESS.addressLat` / `addressLng` — fixed here ✅ Standalone `NUMERIC` is not user-creatable (it's in `SettingsExcludedFieldType`). Other scalars were checked and don't diverge: `Date.serialize` is identity; `NUMBER`/`POSITION` are stored as `float8` and returned as numbers (and `NUMBER` is already coerced in direct execution); `DATE_TIME` resolves to the same ISO string via both paths. So `ADDRESS` was the last gap. ## Tests - New `format-result.util.spec.ts`: `addressLat`/`addressLng` strings parse to numbers, already-number coordinates pass through, numeric-looking text subfields (e.g. `addressPostcode: "10001"`) are **not** coerced, and the existing Currency `amountMicros` coercion still holds. - `npx jest format-result.util.spec` → 4 passed - `npx nx lint:diff-with-main twenty-server` → 0 warnings, 0 errors - `npx nx typecheck twenty-server` → pass ## Follow-ups (not in this PR) - The cross-path parity integration test (#18972) doesn't cover a record with address coordinates — worth adding so this class can't regress. - `formatAddressDisplay` falls back to `ALLOWED_ADDRESS_SUBFIELDS` (which includes lat/lng) when a field has no `subFields` configured, unlike `getEnabledAddressSubFields` (which falls back to the text-only `DEFAULT_VISIBLE_ADDRESS_SUBFIELDS`). Harmless now that coordinates are numbers (filtered by `isNonEmptyString`), but a latent inconsistency. https://claude.ai/code/session_011pf9KQn4UDZGr4V4k8rRHh --- _Generated by [Claude Code](https://claude.ai/code/session_011pf9KQn4UDZGr4V4k8rRHh)_ <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21542?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
d06e687b77 |
Fix settings UI polish pass 2 (#21540)
## Summary This PR groups the requested second UI polish pass across the app shell, settings pages, data model, community, AI tools, and developer setup surfaces. ### Shell and navigation polish - Lets the app content card fill the available viewport and removes the bottom-left radius on the main container. - Uses an outside-looking container border treatment so the rounded top-left edge matches the Figma frame without a double border. - Restores the separator between the AI chat side panel and the record container. - Updates navigation drawer background/skeleton tones to use gray/3 consistently. - Simplifies the full-screen backend error fallback so the white screen fills the viewport. ### Settings page polish - Moves the layout customization action from the settings navbar into a settings card under the hero. - Tightens layout page copy now that the customization surfaces are not directly manageable yet. - Aligns role detail title sizing and hover treatment with other settings headers. - Supports settings card brand icon colors, then restores Discord and X brand logos on the Community page. - Adds the Community discovery cover, moves community/social content to the top, and reorganizes Partners and Features. - Keeps setting card subtitle and separator behavior available for the updated settings cards. ### Data model and object settings polish - Adds a shared data-model table body wrapper so object, field, and relation tables all keep the expected bottom border. - Displays the object icon in the object settings navbar. - Shares the new-field wizard parent object icon wrapper and keeps the object icon at 64% opacity in wizard headers. - Updates the new-field type selector icon treatment to match the wizard header opacity behavior. ### Integrations, tools, and API polish - Reworks the MCP setup config card with light syntax coloring and a top-right copy icon button instead of the bottom copy section. - Fixes email import icons to match the Figma asset shape. - Ensures AI tool table icons and chevrons never fall back to black. ## Validation - `npx nx lint:diff-with-main twenty-front` - `npx tsc -p packages/twenty-front/tsconfig.json --noEmit` - `git diff --check` - Manual local visual pass on `apple.localhost:3001` for companies, settings/community, data model, object settings, new-field wizard, layout settings, account import, MCP setup, AI tools, and role detail pages. ## Visual QA ### Shell and settings frame <img width="1308" height="1397" alt="Shell and settings frame before/after board" src="https://raw.githubusercontent.com/twentyhq/twenty/pr-assets/ui-fixes-2/visual-qa/ui-fixes-2/shell-settings-frame.png" /> ### Community and data model <img width="1308" height="1806" alt="Community and data model before/after board" src="https://raw.githubusercontent.com/twentyhq/twenty/pr-assets/ui-fixes-2/visual-qa/ui-fixes-2/community-data-model.png" /> ### Integrations and tools <img width="1308" height="1397" alt="Integrations and tools before/after board" src="https://raw.githubusercontent.com/twentyhq/twenty/pr-assets/ui-fixes-2/visual-qa/ui-fixes-2/integrations-tools.png" /> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21540?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
5d0a4b8db4 |
fix(twenty-front): keep paging record board columns past the second page (#21348)
Fixes #21355 ## Problem On a Record Board (Kanban) view, columns that contain more than 20 records stop loading at exactly 20. The initial query loads the first page, one automatic fetch brings the column to 20, and then the loading placeholder at the bottom of the column **spins forever** — scrolling all the way down triggers no further requests. Every column is permanently capped at `2 * RECORD_BOARD_QUERY_PAGE_SIZE` (20) records. ### Steps to reproduce 1. Open any object in board view, grouped by a field where at least one group has > 20 matching records. 2. Wait for the board to load — the first 20 cards in the large column appear. 3. Scroll that column to the bottom. **Expected:** more cards load as you approach the bottom, until the column is exhausted. **Actual:** the placeholder stays forever; no additional group-by request is fired. ## Root cause An **edge-triggered consumer reading a level signal that is stuck high.** The fetch-more trigger (`RecordBoardFetchMoreInViewTriggerComponent`) is an `IntersectionObserver` sentinel that writes its `inView` state into the board-level `recordBoardShouldFetchMoreComponentState`. Its `rootMargin` is: ```ts const rootMargin = `${estimatedCardHeight * RECORD_BOARD_QUERY_PAGE_SIZE * 2}px`; ``` With `estimatedCardHeight ≈ 130px` and `RECORD_BOARD_QUERY_PAGE_SIZE = 10`, that's ~2600px — roughly two pages, i.e. as tall as the entire already-loaded board. So the sentinel reports `inView = true` across the whole loaded board, and the boolean **latches `true` after the first auto-fetch and never toggles back**. The consumer in `RecordBoardQueryEffect` only reacts to the **false→true edge** of that boolean, and `triggerRecordBoardFetchMore` is a stable `useCallback`. Once the boolean is stuck `true` and the dependency array stops changing, the effect never re-runs — so it fetches exactly once. The signal is *level* ("the bottom is in view, keep loading") but it's consumed as an *edge* ("the bottom just appeared, load once"), and the oversized `rootMargin` guarantees the level is permanently high so the single edge never repeats. The large `rootMargin` is intentional prefetch buffering and is not the bug; the consumer simply needs to keep paging while the signal is high. ## Fix Make the consumer **re-arm** the trigger after every page that actually returned records: 1. `useTriggerRecordBoardFetchMore` now returns a `boolean` — `true` only once at least one column received records this round, `false` on every early-exit / empty result. 2. `RecordBoardQueryEffect` resets `recordBoardShouldFetchMoreComponentState` to `false` after a **productive** fetch. The sentinel is still inside the inflated `rootMargin`, so the observer immediately re-asserts `true`, which re-runs the effect and fetches the next page. The loop terminates naturally and never spins: - **Buffer filled** — enough cards load that the sentinel finally leaves the `rootMargin` → observer reports `false` → loop stops. As the user scrolls, it re-arms (normal infinite scroll). - **Columns exhausted** — `triggerRecordBoardFetchMore` returns `false` (per-column `shouldFetchMore` flags already get set `false` when a page returns `< PAGE_SIZE`), so the boolean is not reset and no further fetch fires — no busy-loop on a fully-loaded board. The existing `recordBoardIsFetchingMore` re-entrancy guard prevents any overlapping/double fetch during the round-trip. ## Test - `npx nx typecheck twenty-front` → passes - `npx nx lint twenty-front` (oxlint --type-aware + oxfmt) → 0 warnings, 0 errors, formatting clean - Manually verified on a board with columns of 38 and 74 records: pre-fix both froze at 20; post-fix they page to completion on scroll, and a fully-loaded board issues no extra requests. ## Notes / alternatives considered - **Shrinking `rootMargin`** would mask the bug for tall boards but defeat the intended prefetch buffering and reintroduce it whenever the buffer is smaller than the loaded content. The level/edge mismatch is the real defect. - **Moving the loop into the trigger component** was rejected — it only knows `inView`, not whether a fetch was productive or whether columns are exhausted, so self-looping there would increase coupling. The query effect is the right owner of fetch orchestration. --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
c05f01f2a3 |
fix(server): repair 2.13 isUIReadOnly→isUIEditable rename fallout (#21504) (#21537)
## Context Follow-up to #21504 ("Rename isUIReadOnly to isUIEditable, add isUICreatable…"), which surfaced two issues: 1. **`column FieldMetadataEntity.isUIReadOnly does not exist`** on twenty-main.com. 2. **`cross-version-upgrade` CI failure** — `SyncStandardUiCapabilityFlags` aborts the v1.22 → 2.13 upgrade. ## Fix 1 — don't drop `isUIReadOnly` in the 2.13 rename command The 2.13 fast instance command physically dropped `isUIReadOnly` from `core."fieldMetadata"` and `core."objectMetadata"`. But migrations run in an ArgoCD **PreSync** hook **before** the new pods roll out (`charts/prod-eu/apps/twenty-server` migration Job is `hook: PreSync`, sync-wave `2`; the api/worker Deployments are sync-wave `10`). So the **previous** release's pods keep serving and still `SELECT isUIReadOnly`, throwing `column ... does not exist` from the moment the column is dropped until the rollout finishes. This keeps the column (already hidden from the app via `@WasRemovedInUpgrade` on both entities) and **defers the physical drop** to a later release. Since 2.13 hasn't shipped to self-hosters yet, the committed command is amended in place. Both tables handled; `isUICreatable` (new, additive column) is unaffected. The eventual physical drop + GraphQL-compat removals are tracked in twentyhq/core-team-issues#2542. ## Fix 2 — allow `isUIEditable` updates on relation field metadata `SyncStandardUiCapabilityFlags` re-syncs `isUIEditable` on standard fields, including morph/relation fields (the activityTargets `target*` relations). The flat-field-metadata validator only permits a fixed property allow-list on relation fields, which omitted `isUIEditable`, so the command failed with `FIELD_MUTATION_NOT_ALLOWED` and aborted the upgrade (leaving workspaces in a FAILED state). `isUIEditable` is a per-field UI-affordance flag that applies to relation fields too, so it's added to the relation-field updatable properties (a constant used **only** by that validator — no diff-engine side effects). ## Coherence notes - Object-level is covered: the drop is deferred on **both** tables, and `ObjectMetadataEntity` has the identical decorators. - `isUICreatable` needs no change: object-only and additive (no drop → no rolling-deploy hazard), and never reaches the field relation allow-list. - The object-metadata validator has no relation allow-list, so there's no object-level analog to change. ## Verification - `nx typecheck twenty-server` ✅ (the `satisfies` guard holds — `isUIEditable` is a `toCompare` property of `fieldMetadata`) - `oxlint --type-aware` + `oxfmt --check` ✅ on changed files - Fix 2's path is exercised end-to-end by the `cross-version-upgrade` CI that originally caught it. --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
fefb6cdb94 |
feat(page-layout): add number format option to aggregate chart widget (#21521)
## Context Closes #21522 Large values in the dashboard **Number** widget are always abbreviated (e.g. `1300090` → `1.3m`) with no way to display the full number. Following a discussion with the core team who were interested in this feature (https://discordapp.com/channels/1130383047699738754/1509604545381142649) , this adds a **Format** option in the **Style** section of the Number (aggregate chart) widget, letting users choose between **Short** (abbreviated, current behavior) and **Full** (complete number with thousand separators). Only the displayed value of the Number widget is affected — axes, labels and tooltips of other chart types are intentionally left untouched. ## What's inside **Server** - New `ChartNumberFormat` GraphQL enum (`SHORT` / `FULL`), following the `AxisNameDisplay` pattern - The existing — and previously unused — `format` field on `AggregateChartConfigurationDTO` is now typed with this enum and validated with `@IsEnum` - The dashboard AI tool schema (`widget.schema.ts`) accepts the new `format` option - Regenerated GraphQL types and the `twenty-client-sdk` metadata client to reflect the enum **Front** - New **Format** setting in the Style section of the Number widget settings, with a Short/Full selection dropdown (same pattern as the Axis name setting) - `transformAggregateRawValueIntoAggregateDisplayValue` takes an optional `numberFormat`: - `FULL` → full number via `formatNumber` (currency values keep up to 2 decimals) - `SHORT` → abbreviated via `formatToShortNumber` - not set → behavior unchanged (currency short, number full), so existing widgets and the record table/board footers render exactly as before ## Screenshots | Full UI Look | <img width="1917" height="955" alt="Twenty_Showcas_FullShort" src="https://github.com/user-attachments/assets/05d05779-395d-4e1a-8ff0-964f6fbef182" /> | Menu UI Look | <img width="291" height="308" alt="Screenshot_2" src="https://github.com/user-attachments/assets/82b5a1de-32fe-46ec-a9b8-add11ab4c6cd" /> ## Tests - Extended `transformAggregateRawValueIntoAggregateDisplayValue` unit tests with SHORT/FULL cases for currency and number fields - Updated the page-layout-widget creation/update integration tests and snapshots to use `ChartNumberFormat.SHORT` <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21521?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
f869ce87b1 |
[Experiment] perf(front): cache-first currentUser bootstrap (#21532)
## Experiment — not for merge as-is A perf experiment for discussion. Opening as a draft to gather feedback and let CI run. ## Problem On a warm (returning) load, the app gate ([`MinimalMetadataGater`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-front/src/modules/metadata-store/components/MinimalMetadataGater.tsx)) blocks first paint until **both** object/view metadata **and** `currentUser` are ready. The metadata store is already cache-first: it persists each entity (including `status: 'up-to-date'`) to `localStorage` with `getOnInit`, opens from cache, and revalidates in the background via collection hashes. 👏 `currentUser` (and `currentWorkspace` / `currentWorkspaceMember` / `currentUserWorkspace`) is **not** — it lives in an in-memory atom, so every load fires a blocking `GetCurrentUser` round-trip before the gate opens. That round-trip is the one remaining network hop on the warm-load critical path; everything else the first screen needs is already in `localStorage`. ## Approach Generalize the pattern the metadata store already proves out, to the user bootstrap — **without adding any new `useEffect`**: - Persist the four bootstrap atoms (`currentUser`, `currentWorkspace`, `currentWorkspaceMember`, `currentUserWorkspace`) via the existing `createAtomState({ useLocalStorage, localStorageOptions: { getOnInit: true } })`. - The gate opens from cache on its own: the existing `IsMinimalMetadataReadyEffect` already derives readiness from the `currentUser` atom alongside metadata status, so persisting the atoms is enough — no new effect. - Keep firing `GetCurrentUser` (now `network-only`, no longer skipped when a user is present) so it **revalidates in the background** and the existing write-through effect updates the atoms with the fresh result. - Clear the cached identity on sign-out by adding the four keys to `clearSessionLocalStorageKeys` (already invoked by `clearSession`, which then hard-reloads). Net effect: warm loads no longer wait on `GetCurrentUser`; the shell paints from cache and corrects within one round-trip. Cold loads (no cache) are unchanged. ## Risks to validate - **Permission staleness** — `currentUserWorkspace` carries `objectsPermissions` / `permissionFlags`. Cache-first means a brief stale-permission window before revalidation. Not a security boundary (the server authorizes every request), but it can momentarily show a menu item the user no longer has; worst case it 401s and corrects on the next paint. - **Feature-flag / workspace staleness** — `currentWorkspace.featureFlags` may be one round-trip stale on warm load. - **`X-Schema-Version` header** — sourced from `currentWorkspace.metadataVersion`; caching it actually makes the header *consistent* with the already-cached metadata rather than absent, but worth confirming against the server's mismatch handling. - **Test isolation** — these atoms now persist; tests relying on the default `null` could see cross-test leakage if `localStorage` isn't reset. The directly-affected suites pass locally (`useAuth`, `useDefaultHomePagePath`, `useSetNextOnboardingStatus`); CI's full run is the real check. ## Validation - [ ] Full CI (types/lint/unit) green - [ ] Manual: throttle network, hard-reload a logged-in workspace, confirm the shell paints before `GetCurrentUser` resolves and that fresh data writes through - [ ] Sign out → sign in as a different user on the same browser; confirm no stale identity flashes |
||
|
|
5d892bdfd0 |
[WIP] Feat/marketing emails (#21173)
Marketing/campaign emails on top of the emailing-domain (SES) feature:
send a broadcast to a hand-picked list, with per-customer-domain
unsubscribe links and opt-out-only **unsubscribe topics**.
## Model
Standard objects (workspace schema, flat-metadata):
- `messageCampaign` — a campaign send (subject, body template, from
address, status, list, optional unsubscribe topic).
- `messageList` + `messageListMember` — the hand-picked audience (person
↔ list join). A campaign's recipients are its list's members; everyone
is sendable unless suppressed.
Core entities (`core` schema, workspace-scoped — readable by the public
unsubscribe flow without a workspace context):
- `unsubscribeTopic` — an opt-out-only category (name, description,
visibility). There is no opt-in subscription state.
- `messageSuppression` — the single consent store: a row with
`unsubscribeTopicId` NULL is a global block; a row with an
`unsubscribeTopicId` and reason `UNSUBSCRIBE` is a per-topic opt-out.
Two partial unique indexes dedupe global vs per-topic rows (Postgres
treats NULLs as distinct).
- `emailingDomain` — the workspace's SES sending domain,
auto-provisioned when an email channel is added (and cleaned up when its
last channel is removed), with verification status + DNS records.
Campaign messages reuse the existing `message` / `messageThread` /
`messageParticipant` model — one outbound `message` per recipient with a
`deliveryStatus` state machine.
## Sending
- `sendMessageCampaign` resolves the audience **under the caller's
permissions**, creates the campaign, and enqueues a single fan-out job
(the request never materializes per-recipient rows or jobs).
- The fan-out job materializes one QUEUED message per recipient
(deterministic ids → idempotent re-runs, reconciles crash-orphaned rows)
and fans out per-recipient send jobs carrying **only ids**.
- Each send job renders per-recipient `{{variable}}` merge fields and
sends via `EmailingDomainSenderService`, which applies suppression
(global + per-topic) and the unsubscribe footer/headers. Suppressed
recipients are recorded `SKIPPED`.
- The campaign finalizes `SENT`, or `SENT_WITH_ERRORS` if any recipient
terminally failed.
- `previewMessageCampaignAudience` returns a pre-send breakdown (total /
without-email / duplicate / globally-unsubscribed / topic-unsubscribed /
sendable), shown as a hint under the composer pickers.
## Unsubscribe
- Encrypted (AES-256-GCM) token carrying workspaceId, address, optional
`unsubscribeTopicId`, `issuedAt`, and a `preview` flag.
- One-click POST (RFC 8058) + `mailto:` — topic-scoped when the token
carries a topic, global otherwise.
- Preferences page: a checkbox per visible topic (checked = still
receiving); submitting creates per-topic opt-outs for unchecked topics
and lifts re-checked ones (UNSUBSCRIBE only — never
`BOUNCE`/`COMPLAINT`, never a global block).
- A **Preview** action in settings opens the live page via a
preview-claim token; opt-out POSTs are no-ops for preview tokens, so
previewing never mutates state.
- SES webhooks: inbound unsubscribe + outbound bounce/complaint →
suppression (race-safe against at-least-once delivery, with reason
escalation that never downgrades).
- Per-customer unsubscribe hostname (Cloudflare DNS); sends are gated on
it being active, except in LOG/demo mode.
## Architecture
Campaign orchestration, suppression, the sender, the unsubscribe
controller, and the SES webhook handlers live in `src/modules/emailing`
+ `src/modules/messaging-webhooks` (the workspace-feature layer).
`core-modules/emailing-domain` keeps the SES driver, domain
provisioning, the `unsubscribeTopic` / `messageSuppression` core
entities, and the unsubscribe token/hostname plumbing. Domain creation
is validated (`CreateEmailingDomainInput` — domain-format regex,
lowercased) before any value reaches SES or the unsubscribe hostname.
## Frontend
- Campaign composer side panel (from / list / unsubscribe topic /
subject / body) with a live audience-preview hint.
- Email settings: email channels each showing their auto-provisioned
sending domain in a single section (status + DNS records + a "Check
verification" action), plus an **Unsubscribe Topics** section to
create/manage topics and preview the recipient page. A demo-mode banner
is shown when the LOG driver is active.
---------
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
|
||
|
|
2c5da39dc5 |
perf(front): load Front chat during browser idle time (#21533)
## Context
The Front support chat bundle
(`chat-assets.frontapp.com/v1/chat.bundle.js`, ~2.3s in a profiling
trace) was being injected only `500ms` after auth + client-config +
workspace-member resolved (`useInstantiateSupportChat.ts`). Because the
effect's gating conditions are themselves network-bound, that `500ms`
still lands the fetch + execute **inside the critical boot window**
(metadata load + first render), where the bundle competes for bandwidth
and main-thread time.
Two pre-existing issues:
- The `500ms` delay was too short to clear the critical window.
- The injected `<script>` already had `defer = true`, but `defer` is a
no-op on dynamically-inserted scripts (they're `async` by default), so
it contributed nothing.
- The `setTimeout` was never cleared, so an effect re-run within the
delay could schedule duplicate loads.
## Change
- Add a small `scheduleIdleCallback(callback, { timeout })` helper
(`src/utils/`) that runs work during a browser idle period via
`requestIdleCallback`, capped by `timeout`, and returns a canceller.
- Use it in `useInstantiateSupportChat` with a `2000ms` cap, and
**return the canceller from the effect** so a pending load is cancelled
on re-run/unmount.
### Why not gate on first interaction?
The launcher must appear proactively to surface an unread-reply badge,
so it has to load without user action. `requestIdleCallback` keeps it
proactive while yielding to the critical path.
### Safari / iOS
`requestIdleCallback` is disabled by default in all shipping Safari/iOS
versions (not Baseline). The helper falls back to a plain `setTimeout`
of the same duration there. Because `requestIdleCallback`'s `timeout` is
a *maximum* (it fires earlier at the first idle gap) while `setTimeout`
fires *at* that value, a single `2000ms` value gives:
- **Chrome/Firefox/Edge/Android**: loads at first idle, guaranteed
within 2s.
- **Safari/iOS**: loads at 2s (a fixed, longer delay — 4× the old
500ms).
Both paths are strictly better than the previous behavior.
## Testing
- `scheduleIdleCallback` unit tests (both the `requestIdleCallback` and
the fallback path, plus cancellation) — 4/4 pass.
- `npx nx typecheck twenty-front` — passes.
- `oxlint --type-aware` + `oxfmt` on changed files — clean.
https://claude.ai/code/session_013YXr5yNGFH1NYUe4ysmiEy
---
_Generated by [Claude
Code](https://claude.ai/code/session_013YXr5yNGFH1NYUe4ysmiEy)_
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21533?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
76f69efb43 |
Keep synced messages and events when removing a workspace member (#21443)
## Context Removing a workspace member deletes their connected accounts, which cascades into deleting every message and calendar event those accounts synced. For a CRM, losing the email history of departed teammates is a big deal. ## What this does Connected accounts are now kept and reassigned instead of deleted when a member is removed: - Ownership moves to the acting user (whoever removed the member). When members remove themselves (leave workspace, account deletion), it falls back to the oldest admin. - OAuth tokens are revoked, credentials wiped, message/calendar channels get `isSyncEnabled = false`, and the account is stamped with a new `archivedAt` column (fast instance command included). - Synced messages, threads and calendar events stay in the workspace. Channel visibility settings keep applying as before, since channels and associations survive. - The reassigned account appears in the new owner's Settings → Accounts, where it can still be deleted (with its data) like any other account. The transfer happens synchronously during removal, while the member's userWorkspace row still exists. This also removes `DeleteWorkspaceMemberConnectedAccountsCleanupJob` and its listener: the async job had to reconstruct the account-owner link from rows the removal flow had just deleted, which was race-prone (see 2181fb541e). Archived accounts are excluded from the workflow send-email default account resolution, and both removal confirmation modals now mention what happens to synced data. --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> |
||
|
|
f63f053444 |
CommandMenuItem overridable entity (#21486)
## Context Second PR of the overridable-entities track (after #21436 for views): command menu items become overridable so that edits on non-owned items are stored as overrides instead of mutating the row, and deletion/deactivation becomes reversible. ## What this does - `CommandMenuItemEntity` now extends `OverridableEntity<CommandMenuItemOverrides>` (adds `isActive` + `overrides`). All editable properties are overridable for now (to discuss). - **Update**: mutations on a command item not owned by the caller (standard items) are written into `overrides`; reads merge them in the DTO. The command palette edit mode (pin, reorder, shortLabel) now preserves standard values, "Reset label to default" gains true post-save semantics. - **Delete**: protected items are deactivated (`isActive = false`) instead of deleted; custom items still hard-delete. - **Object deactivate/enable toggle**: now flips `isActive` on the command item (merged into the main migration call) instead of delete/recreate; a create-if-missing fallback covers legacy deactivated objects. - **Front**: inactive command items are filtered out of the palette selector. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21486?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
036d9a2bcf |
feat: gate record creation on isUICreatable only, decoupled from isSystem (#21527)
## Context The generic "create a record" UI affordance previously required `!isSystem`, conflating two distinct concerns: **"hidden from Data Model"** and **"not user-creatable"**. This blocked legitimately creatable system objects (e.g. marketing message lists kept `isSystem: true` only to stay out of the Data Model). This PR makes creatability depend on `isUICreatable` alone, so visibility (`isSystem`) and creatability (`isUICreatable`) become independent. ## Changes - **Front gate** (`canCreateRecordsForObjectMetadataItem.ts`): drop the `!isSystem` clause — creatability is now `isUICreatable && !readOnly`. Updated comment + unit test. - **Command menu** (`standard-command-menu-item.constant.ts`): drop the matching `not objectMetadataItem.isSystem` clause from the `createNewRecord` availability expression so the "Create new X" command mirrors the front gate. Existing workspaces get this via the already-present `SyncCreateRecordCommandAvailabilityExpressionCommand`, which re-syncs from the live definition. - **Standard object audit** (`create-standard-flat-object-metadata.util.ts`): the 15 sync/system-created standard objects that relied on `!isSystem` to stay non-creatable now set `isUICreatable: false` (attachment, blocklist, calendar*/message*/note/task targets, message, messageThread, messageParticipant, timelineActivity, callRecording, workflowAutomatedTrigger, …). `workflowRun`/`workflowVersion`/`workspaceMember` were already `false`. Non-system objects (company, person, note, opportunity, dashboard, task, workflow) are untouched. - **Backfill**: new fast instance command (`2-13-…-1781277480000-backfill-non-ui-creatable-standard-system-objects.ts`) runs `UPDATE core.objectMetadata SET isUICreatable = false` for those standard system objects (symmetric `down`), registered in `instance-commands.constant.ts`. `isSystem` and Data-Model visibility logic are unchanged. ## Verification - Front gate unit test (7 pass), standard-application suite incl. callRecording (10 pass) - `oxlint` clean on all changed files - `twenty-server` and `twenty-front` typecheck green 🤖 https://claude.ai/code/session_01TF4kjD56hHjP31wkHPxPv3 --- _Generated by [Claude Code](https://claude.ai/code/session_01TF4kjD56hHjP31wkHPxPv3)_ <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21527?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e4a0dfe262 |
fix(e2e): reach Settings via workspace dropdown to unbreak merge queue (#21528)
## Problem
The merge queue is red. Two e2e tests fail consistently on `merge_group`
runs, both timing out while clicking `Settings`:
- `tests/create-kanban-view.spec.ts` ("Create Industry Select Field")
- `tests/authentication/signup_invite_email.spec.ts` ("Go to Settings
and copy invite link")
The earlier tokenPair localStorage fix (#21507 / e2e read in #21519)
restored login, so auth works again — but the navigation/settings polish
in #21523 then **moved the Settings entry out of the main app navigation
and into the workspace switcher dropdown** ("Moves Settings below
Support in the workspace switcher menu").
The e2e tests still looked for a top-level `getByRole('button', { name:
'Settings' })`, which no longer exists, so they timed out.
## Fix
Reach Settings the new way — open the workspace switcher dropdown, then
click the `Settings` link (it is now an `UndecoratedLink`/`MenuItem`,
role `link`, in `MultiWorkspaceDropdownDefaultComponents`):
- `lib/pom/leftMenu.ts`: `goToSettings()` now opens `workspace-dropdown`
first; `settingsTab` locator switched from `button` to `link`.
- `tests/create-kanban-view.spec.ts`: open the workspace dropdown before
clicking the Settings link.
- `tests/authentication/signup_invite_email.spec.ts`: the post-signup
"logged in" assertion now checks the `workspace-dropdown` is visible
instead of the removed Settings button.
## Testing
Triggering the merge-queue e2e suite via the `run-merge-queue` label on
this PR.
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21528?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
|
||
|
|
d2fbc165b6 |
fix(messaging): emit channel and account deletion events from core metadata services (#21491)
/closes #21425 <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21491?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> |
||
|
|
b14195428a |
Fix navigation and settings UI polish (#21523)
## Summary This PR groups the requested UI polish pass across navigation, settings, AI settings, data model, community/lab, and dashboard chips. ### Navigation and drawer polish - Smooths app/settings route switching with a 300ms content transition. - Smooths app menu/settings menu drawer swaps with a fade transition while preserving the existing drawer dimensions. - Keeps navigation and AI chat history panes mounted to avoid flicker when switching tabs. - Aligns the first app/settings section with the AI chat history section title. - Removes the main app navigation "Other" section. - Aligns the settings exit header with the workspace switcher header. - Sets the settings exit icon gap to 8px, uses the small icon stroke token, and keeps the icon color on text-secondary. - Makes the workspace switcher button 28px high inside its 32px container, moves the dropdown up so the workspace name does not jump, and keeps a 2px gap between header icon buttons. - Moves Settings below Support in the workspace switcher menu. - Pins the Advanced toggle to the bottom of the settings drawer and aligns its right padding with nav items. ### Settings surface polish - Fixes vertically cropped dropdown menu headers. - Makes wizard parent titles tertiary when a nested wizard title is visible. - Places danger-zone buttons side by side. - Uses a 32px Visualize button. - Restores 8px top/bottom padding on settings tables. - Separates AI overview counts into three columns like layout overview. - Adds separators inside setting cards, including the Smart Model / Fast Model card. - Groups lab/early-access toggles into one card with separators and full-width row backgrounds. - Replaces deprecated Enterprise adornment tags with the Organization adornment on gated AI/security/settings surfaces. - Uses the Discord brand icon in Community while keeping the standard icon component rendering pattern. - Tightens Skills/Tools search-to-table spacing so switching tabs does not shake the table top. - Fixes the small gap in nested navigation breadcrumbs between Emails and Calendars. ### Dashboard/data table polish - Fixes vertically cropped "Not shared" chips on dashboards. - Keeps table row/header spacing stable after the settings table padding restoration. ## Validation - `npx nx lint:diff-with-main twenty-front` - `npx tsc -p packages/twenty-front/tsconfig.json --noEmit` - Manual Chrome pass on `apple.localhost:3001` for profile, app navigation, workspace switcher, AI overview/models/skills/tools/usage, community/lab, data model, new-field wizard, and dashboards. ## Visual QA ### Settings surface fixes <img width="1324" height="2668" alt="Settings surface fixes before/after board" src="https://github.com/user-attachments/assets/312131fa-3922-4724-9460-46fd373754d1" /> ### Navigation drawer fixes <img width="1324" height="1816" alt="Navigation drawer fixes before/after board" src="https://github.com/user-attachments/assets/ca0b29e5-e393-46c0-81f7-e6bed2557b59" /> ### Tables, wizards, gates and chips <img width="1324" height="2242" alt="Tables, wizards, gates and chips before/after board" src="https://github.com/user-attachments/assets/5f358240-c31c-4c15-8ca8-04ed761fbf85" /> |
||
|
|
869680a5a1 |
fix(deps): esbuild ^0.28.1 floors + vite 7→8 (rolldown) upgrade (#21517)
## What this does Resolves the remaining esbuild security alerts on packages we own, and upgrades the repo to **Vite 8** (which drops esbuild entirely in favour of rolldown/oxc). ### 1. esbuild → `^0.28.1` (security) - Raised the declared `esbuild` floor in `twenty-sdk` and the logic-function common-layer (both were `^0.25.0`, which can only resolve to a vulnerable version). These are our packages, so this is just declaring the patched version — clears Dependabot **#1467** and **#1468**. ### 2. Vite 7 → 8 - Bumped `vite` to `^8` in the 5 packages that declare it, and `@vitejs/plugin-react-swc` to `^4.3.1` (the only plugin that needed a bump for Vite 8; everything else already supports it). - `twenty-front` keeps esbuild minification, so esbuild is now an explicit (patched) devDependency there — Vite 8 no longer ships it. ### Two Vite-8 fallout fixes (bundler internals changed) - **Storybook tests:** added React to `optimizeDeps.include` so Vite's dep optimizer doesn't re-bundle React mid-run and break in-flight imports in browser-mode tests. - **`hex-rgb`:** it's ESM-only and broke rolldown's CJS interop (a default import resolved to the wrong thing under jest). Replaced its one use with a tiny inline hex→rgb parse and dropped the dependency. ## Verified Vite resolves to a single `8.0.16` with no esbuild in its tree. Builds pass on Vite 8/rolldown: `twenty-front` production build, the SDKs, and Storybook; the previously-failing front and storybook test jobs now pass; `yarn install --immutable` is clean. ## Note This doesn't close root alert **#1469** — esbuild is still pulled by other third-party tools (storybook, tsx, lingui, zapier, etc.) that haven't shipped a patched release. The vulnerable code path (esbuild's dev server) isn't used here, so that one is best dismissed as not-affected. |
||
|
|
4899f00bc7 |
fix: frontend build failing after code formatting library update (#21519)
Starting the frontend(`nx start twenty-front`) was failing because one of its dependencies - the client SDK - can not be built. A recent update made the sdk compatible with a newer version of Prettier. That update started using parts of prettier that the build setup did not recognize, so the build stopped with an error about a missing module. This PR updated the SDK’s build configuration, so it correctly handles those prettier imports. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21519?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Signed-off-by: Parship Chowdhury <parshipchowdhury@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
050f7dcf85 |
fix(server): allow ordering operators on SELECT and RATING fields (#21506)
## Problem
On a record **show page**, prev/next navigation fails with toasts like:
```
Invalid filter : Operator "lt" is not valid for this "severity" SELECT field
```
…but only when the record is reached via in-app navigation from an index
view sorted by a SELECT field (a hard reload is clean).
## Root cause
The record show page paginates with **keyset (cursor) pagination**.
`useRecordShowPagePagination` builds `before`/`after` filters via
`computeCursorArgFilter`, which emits `{ field: { gt|lt: value } }` for
**every** field in the parent view's `orderBy`, regardless of type.
When a view is sorted by a **SELECT** field (e.g. the *All Bugs* view
sorts by `severity`), the keyset filter becomes `{ severity: { gt:
"HIGH" } }` / `{ severity: { lt: "HIGH" } }`. SELECT/RATING fields use
`ENUM_FILTER_OPERATORS` (`eq, neq, in, containsAny, is, isEmptyArray`) —
no ordering operators — so filter validation rejects them, breaking both
the neighbour queries and the rank-in-view ("X of Y") count query. A
hard reload has no parent-view `orderBy`, so neighbour queries are
skipped → no error.
This isn't a technical limitation: the column is comparable, `ORDER BY
severity` works, and the backend already emits the same comparison for
its own cursor path (`buildCursorWhereCondition`) — that path just
bypasses the user-filter allowlist. Ordering operators were omitted from
`ENUM_FILTER_OPERATORS` because they aren't meaningful *user* filters
for categorical fields, but keyset pagination legitimately needs them.
## Fix
Add `gt/gte/lt/lte` to `ENUM_FILTER_OPERATORS`, so SELECT/RATING keyset
filters are accepted — exactly as `UUID_FILTER_OPERATORS` already
carries these operators for the `id` cursor tiebreaker. The filter UI
never offers these operands for SELECT, so this only enables the
keyset/cursor use case.
## Tests
- `get-operators-for-field-type.util.spec.ts`: SELECT/RATING now include
`gt/gte/lt/lte`.
- `validate-operator-for-field-type-or-throw.util.spec.ts`: regression —
ordering operators on a SELECT field no longer throw.
|