Commit Graph
5110 Commits
Author SHA1 Message Date
Charles BochetandGitHub 530f74e28c Migrate more to Jotai (#18087)
Continue jotai migration
2026-02-19 13:50:21 +01:00
Charles BochetandGitHub 1a13258302 Keep migrating to jotai (#18064)
And we continue!
2026-02-19 12:10:02 +01:00
Paul RastoinandGitHub 88424611ec Refactor and standardize isSystem field and object (#17992)
# Introduction

## Centralize system field definitions
- Extract a single `PARTIAL_SYSTEM_FLAT_FIELD_METADATAS` constant as the
source of truth for all 8 system fields (`id`, `createdAt`, `updatedAt`,
`deletedAt`, `createdBy`, `updatedBy`, `position`, `searchVector`),
eliminating duplication across custom object and standard app field
builders
- Refactor `buildDefaultFlatFieldMetadatasForCustomObject` to use the
shared constant via a new `buildObjectSystemFlatFieldMetadatas` helper

## Mark system fields as `isSystem: true`
- Fields `id`, `createdAt`, `updatedAt`, `deletedAt`, `createdBy`,
`updatedBy`, `position`, `searchVector` are now properly flagged as
system fields across all standard objects and custom object creation
- Standard app field builders for all ~30 standard objects updated to
set `isSystem: true` on `createdAt`, `updatedAt`, `deletedAt`,
`createdBy`, `updatedBy`
- System-only standard objects (blocklist, calendar channels, message
threads, etc.) now also include `createdBy`, `updatedBy`, `position`,
`searchVector` field definitions that were previously missing

## Validate system fields on object creation
- New transversal validation (`crossEntityTransversalValidation`) runs
after all atomic entity validations in the build orchestrator, ensuring
all 8 system fields are present with correct `type` and `isSystem: true`
when an object is created
- New `buildUniversalFlatObjectFieldByNameAndJoinColumnMaps` utility to
resolve field names to universal identifiers for a given object
- New exception codes: `MISSING_SYSTEM_FIELD` and `INVALID_SYSTEM_FIELD`
on `ObjectMetadataExceptionCode`

## Protect system fields and objects from mutation
- Field validators now block update/delete of `isSystem` fields by
non-system callers (`FIELD_MUTATION_NOT_ALLOWED`)
- Object validators now block update/delete of `isSystem` objects by
non-system callers
- `POSITION` and `TS_VECTOR` field type validators replaced: instead of
rejecting creation outright, they now validate that the field is named
correctly (`position` / `searchVector`) and has `isSystem: true`

## Distinguish `isSystemBuild` from `isCallerTwentyStandardApp`
- New `isCallerTwentyStandardApp` utility checks whether the caller's
`applicationUniversalIdentifier` matches the twenty standard app
- Name-sync logic (`isFlatFieldMetadataNameSyncedWithLabel`,
`areFlatObjectMetadataNamesSyncedWithLabels`) refactored to use
`isCallerTwentyStandardApp` for custom suffix decisions, keeping
`isSystemBuild` for mutation permission checks
- `WorkspaceMigrationBuilderOptions` type updated to include
`applicationUniversalIdentifier`

## Adapt frontend filtering
- New `HIDDEN_SYSTEM_FIELD_NAMES` constant (`id`, `position`,
`searchVector`) and `isHiddenSystemField` utility to only hide truly
internal fields while keeping user-facing system fields (`createdAt`,
`updatedAt`, `deletedAt`, `createdBy`, `updatedBy`) visible in the UI
- ~20 frontend files updated to replace `!field.isSystem` checks with
`!isHiddenSystemField(field)` across record index, settings, data model,
charts, workflows, spreadsheet import, aggregations, and role
permissions

## Add 1.19 upgrade commands
- **`backfill-system-fields-is-system`**: Raw SQL command to set
`isSystem = true` on existing workspace fields matching system field
names, and fix `position` field type from `NUMBER` to `POSITION` for
`favorite`/`favoriteFolder` objects. Includes proper cache invalidation.
- **`add-missing-system-fields-to-standard-objects`**: Codegen'd
workspace migration to create missing `position`, `searchVector`,
`createdBy`, `updatedBy` fields on standard objects that didn't
previously have them. Runs via `WorkspaceMigrationRunnerService` in a
single transaction with idempotency check. **Known limitation**: assumes
all standard objects exist and are valid in the target workspace.

## Add `universalIdentifier` for system fields in standard object
constants
- `standard-object.constant.ts` updated to include `universalIdentifier`
for `createdBy`, `updatedBy`, `position`, and `searchVector` across all
standard objects
- `fieldManifestType.ts` updated to support the new field manifest shape

## System relation
Completely removed and backfilled all `isSystem` relation to be false
false
As we won't require an object to have any relation system fields

## Add integration tests
- New test suite `failing-sync-application-object-system-fields`
covering: missing system fields, wrong field types (`id` as TEXT,
`createdAt` as TEXT, `position` as TEXT), system field deletion
attempts, and system field update attempts
- New test utilities: `buildDefaultObjectManifest` (builds an object
manifest with all 8 system fields) and `setupApplicationForSync`
(centralizes application setup)
- Existing successful sync test updated to verify system fields are
created with correct properties

## Next step
Make the builder scope the compared entity to be the currently built app
+ nor twenty standard app
2026-02-19 10:13:50 +00:00
082400f751 Add objectRecordCounts query to /metadata endpoint (#18054)
## Summary

- Adds an `objectRecordCounts` query on the `/metadata` GraphQL endpoint
that returns approximate record counts for all objects in the workspace
- Uses PostgreSQL's `pg_class.reltuples` catalog stats — a single
instant query instead of N `COUNT(*)` table scans
- Replaces the previous `CombinedFindManyRecords` approach which hit the
server's 20 root resolver limit and silently showed 0 for all counts on
the settings Data Model page

### Server
- `ObjectRecordCountDTO` — GraphQL type with `objectNamePlural` and
`totalCount`
- `ObjectRecordCountService` — reads `pg_class` catalog for the
workspace schema
- Query added to `ObjectMetadataResolver` with `@MetadataResolver()` +
`NoPermissionGuard`

### Frontend
- `OBJECT_RECORD_COUNTS` query added to
`object-metadata/graphql/queries.ts`
- `useCombinedGetTotalCount` simplified to a zero-argument hook using
the new query
- `SettingsObjectTable` simplified to a single hook call

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 09:02:31 +00:00
EtienneandGitHub a14b0ab6ca FILES field - Attachment name display fix (#18073)
with new 'file' FILES field on attachment, UI should display attachment
name from file field value.
Issue with API users updating only 'file' FILES field (and not name
field anymore)
2026-02-19 10:04:05 +01:00
Charles BochetandGitHub 36c2b0e23b Migrate dropdown to jotai (#18063)
Here we go again
2026-02-19 00:58:26 +01:00
743b733e70 i18n - translations (#18056)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 22:40:10 +01:00
Thomas des FrancsGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Charles BochetCharles Bochet
612f7c37a5 Improve security settings card grouping and description overflow (#17928)
# After

- Added a separtor between the two audit logs cards
- Rename the audit log card to avoid repetition
- Grouped "Invite by link" and "2 factor auth" in one group
- Changed the card component description to always be one line max with
truncation & tooltips

<img width="777" height="1278" alt="CleanShot 2026-02-13 at 17 02 36"
src="https://github.com/user-attachments/assets/685c792a-c85b-4521-8c1b-bd9adedc75d9"
/>

<img width="976" height="690"
alt="b49f2eb043b6712d013618bb0a4ef7f011cf2316e1163fbdee4c293bed036ac9"
src="https://github.com/user-attachments/assets/6e17aa11-ecdb-4f98-ba50-5cd9b9c5def6"
/>

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-18 22:33:37 +01:00
Félix MalfaitGitHubCursorclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
67074a7581 Harden server-side input validation and auth defaults (#18018)
## Summary

- **File storage (LocalDriver):** Add realpath resolution and symlink
rejection to `writeFile`, `downloadFile`, and `downloadFolder` — brings
them in line with the existing `readFile` protections. Includes unit
tests.
- **JWT:** Pin signing/verification to HS256 explicitly.
- **Auth:** Revoke active refresh tokens when a user changes their
password.
- **Logic functions:** Validate `handlerName` as a safe JS identifier at
both DTO and runtime level, preventing injection into the generated
runner script.
- **User entity:** Remove `passwordHash` from the GraphQL schema
(`@Field` decorator removed, column stays).
- **Query params:** Use `crypto.randomBytes` instead of `Math.random`
for SQL parameter name generation.
- **Exception filter:** Mirror the request `Origin` header instead of
sending `Access-Control-Allow-Origin: *`.

## Test plan

- [x] `local.driver.spec.ts` — writeFile rejects symlinks, downloadFile
rejects paths outside storage
- [ ] Verify JWT auth flow still works (login, token refresh)
- [ ] Verify password change invalidates existing sessions
- [ ] Verify logic function creation with valid/invalid handler names
- [ ] Verify file upload/download in dev environment


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-18 21:41:01 +01:00
4cb64c6aa5 Restore old favorite design (#18049)
Issue : With IS_NAVIGATION_MENU_ITEM_ENABLED:true +
IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED:false, nav menu design is
changed after 1.18.0 release : views expansion removed, system object
displayed, position re-ordered

We prefer keeping the same "old" favorite behaviour and design state

- After 1.18.0 all workspaces have up-to-date navigation menu items
(migrated)
- IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED becomes the FF for nav menu
new design

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-18 21:35:17 +01:00
6aaafb76b6 fix: show "Not shared" for junction relation fields when target or intermediate object is not readable (#18025)
When a user's role lacks read permission on the target object (e.g.,
Company) or the intermediate junction object (e.g., EmploymentHistory),
junction relation fields like "Previous Companies" displayed as blank
instead of showing "Not shared."

- In RecordFieldList, junction fields now check the junction object's
read permission and set isForbidden on the field context so FieldDisplay
renders "Not shared" instead of an empty field.
- In RelationFromManyFieldDisplay, if junction records exist but all
nested target records are null (permission-denied by the API), the
component renders "Not shared" instead of an empty list.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2026-02-18 21:05:45 +01:00
Thomas des FrancsandGitHub 7ec4508d5f Add currency hover tooltip in CurrencyDisplay (#18045)
https://github.com/user-attachments/assets/af768ecb-b5e9-4e8d-a9f9-fee1a08ea9a0

Fixes https://github.com/twentyhq/twenty/issues/17756
2026-02-18 20:25:34 +01:00
Thomas des FrancsandGitHub a05a9c8f79 refactor workflow action messaging with callout (#18038)
## Summary
- remove the dedicated `WorkflowMessage` component and story
- update workflow action editor components to use the shared callout
patterns
- adjust `Callout` and its stories to support the new usage in workflow
actions

## Before/After

<img width="525" height="548" alt="image"
src="https://github.com/user-attachments/assets/ce57a84f-f070-4149-85ef-a4d162b2d878"
/>


<img width="518" height="593" alt="image"
src="https://github.com/user-attachments/assets/f7249cd0-221f-496d-9deb-d9966ee43382"
/>
2026-02-18 20:23:38 +01:00
8e6b267ff3 Allow DATE_TIME IS operand to filter on a whole day (#17529)
Fixes:  https://github.com/twentyhq/core-team-issues/issues/2027

We've replaced the DATE_TIME picker with DATE picker, and changed the
logic to filter for complete day period.



https://github.com/user-attachments/assets/ba7e1078-bab3-4c62-a803-d6a851f14b7d

---------

Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-18 13:44:05 +00:00
Raphaël BosiandGitHub 2455c859b4 Add SSE for metadata and plug front components (#17998)
Create the necessary tooling to listen to metadata events and plug it to
the front components. Now we have a hot reload like experience when we
edit a component in an app.

## Backend

- Split `EventWithQueryIds` into `ObjectRecordEventWithQueryIds` and
`MetadataEventWithQueryIds`
- Publish metadata event batches to active SSE streams in
`MetadataEventsToDbListener`

## Frontend

- Create a metadata event dispatching pipeline: SSE metadata events are
grouped by metadata name, transformed into
`MetadataOperationBrowserEventDetail` objects, and dispatched as browser
`CustomEvents`
- Add `useListenToMetadataOperationBrowserEvent` hook for consuming
metadata operation events filtered by metadata name and operation type
- Rename `useListenToObjectRecordEventsForQuery` to
`useListenToEventsForQuery`, now accepting both
`RecordGqlOperationSignature` and `MetadataGqlOperationSignature`
- Implement `useOnFrontComponentUpdated` which subscribes to front
component metadata events and updates the Apollo cache when the
component is modified
- Add `builtComponentChecksum` to the front component query and appends
it to the component URL for browser cache invalidation
2026-02-18 11:26:20 +00:00
WeikoandGitHub f3faa11dd2 New field creates fields widget field (#18022)
## Context
Introducing "NewFieldDefaultConfiguration" to FIELDS widget
configurations
```typescript
{
  isVisible: boolean;
  viewFieldGroupId: string | null;
}
```

This configuration will define where a new field should be added (which
section) and its default visibility inside FIELDS widget views.
The new field position should always be at the end (meaning the last
position for the view fields OR the last position of a viewFieldGroup)

See "New fields" on this screenshot
<img width="401" height="724" alt="Layout V1"
src="https://github.com/user-attachments/assets/4969bcaa-f244-4504-8947-778a02c24c47"
/>
2026-02-18 11:03:27 +00:00
nitinandGitHub 477fbc0865 fixes: loosen up front validation, add resolveEntityRelationUniversalIdentifiers to update and restore (#18015)
closes https://github.com/twentyhq/private-issues/issues/419
2026-02-18 10:35:08 +00:00
EtienneGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
08a3d983cb Date & DateTime validation fixes / improvements (#18009)
Fixes https://github.com/twentyhq/twenty/issues/17138

- Backend should have strict date/dateTime format validation
- FE in import csv is more permissive

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-18 10:13:18 +00:00
BOHEUSGitHubneo773neo773greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
5ae1d94f23 Fix connected account permissions (#17598)
Fixes #17411

---------

Co-authored-by: neo773 <neo773@protonmail.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-18 01:05:56 +01:00
Abdul RahmanGitHubCopilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>DevessierFélix Malfait
015ccbf0a7 Navbar customization improvements (#17863)
- Add folder icon editing support
- And other navbar customization fixes/improvements.

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 19:53:52 +00:00
Charles BochetGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
d7f025157b Migrate more to Jotai (#17968)
As per title

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-17 19:24:36 +01:00
98482f3a01 i18n - translations (#18013)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 19:18:53 +01:00
BOHEUSandGitHub 171efe2a19 New onboarding plan (#17776)
Fixes github.com/twentyhq/core-team-issues/issues/637
2026-02-17 19:11:47 +01:00
Charles BochetandGitHub c0cc0689d6 Add Client Api generation (#17961)
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline

### Why

The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.

### How

- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.
2026-02-17 18:45:52 +01:00
0891886aa0 i18n - translations (#18012)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 18:35:35 +01:00
Thomas TrompetteandGitHub f768bbe512 Replace country code by calling code in workflows (#18008)
Long overdue PR: replacing deprecated country code in workflows.
Will allow to use variables.

We keep storing the country code since it allows to display the right
flag in picker when there are multiple countries for one calling code.
But we do not store country for variables.

<img width="477" height="254" alt="Capture d’écran 2026-02-17 à 17 25
23"
src="https://github.com/user-attachments/assets/dc67c41c-33cf-4021-b7bb-490827b2aa3c"
/>
2026-02-17 17:06:09 +00:00
7c5a13852b i18n - translations (#18007)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 17:27:50 +01:00
EtienneandGitHub 163c1175cb File - Migrate core pictures (workspace and member logo) + workflow attachments (#17924)
- Create a common file-by-id download controller
- Create core picture module with resolver and logic to handle
workspaceLogo and workspaceMemberProfilePicture update
- Create workflow file module (same)
- Data migration
2026-02-17 15:42:50 +00:00
Baptiste DevessierandGitHub 963f2de864 Translate page layout tab title (#17975)
> [!NOTE]
> The improvement will only fully work once all tabs get translated. 

## When using the front-end mocks


https://github.com/user-attachments/assets/cf7dc0fb-9438-4e18-841e-47558ff71474

## When loading page layout information from database


https://github.com/user-attachments/assets/d2c9d98b-97e2-4629-aa6c-53f3f3713733

## When editing dashboard


https://github.com/user-attachments/assets/c6ae3a7a-f05f-48ea-8b33-8f689e3f71f7

Closes
https://github.com/twentyhq/twenty/issues/17950#issuecomment-3902782952
2026-02-17 15:26:28 +00:00
martmullandGitHub e3fcff00b0 Fix initial code step functionInput (#18002)
At code step creation

## before
<img width="623" height="816" alt="image"
src="https://github.com/user-attachments/assets/0aed5ed8-8d56-4988-9d31-fe80942191bb"
/>

## after
<img width="627" height="528" alt="image"
src="https://github.com/user-attachments/assets/9e2a5cb9-7480-4734-8e41-25b45edcec07"
/>
2026-02-17 16:45:00 +01:00
Thomas TrompetteandGitHub b4e924b671 Sync views and navigation items (#18003)
Both objects are necessary to fully enjoy objects within applications

<img width="770" height="311" alt="Capture d’écran 2026-02-17 à 15 19
43"
src="https://github.com/user-attachments/assets/48c51fa4-63f4-45b2-a40a-df73f3aa79be"
/>
2026-02-17 16:32:41 +01:00
Lucas BordeauandGitHub 8938dd637f Added relations to SSE events (#17683)
Fixes https://github.com/twentyhq/core-team-issues/issues/2192

This PR implements what is necessary to re-create the query that we
build on the frontend to obtain the returned object record from a
mutation, but on the backend, which was only partially implemented for
REST API.

Usually we want to have relations with only their id and label
identifier field to have lighter payloads.

In the event we only had depth 0 fields, with this PR we have all events
with depth 1 relations.

We have depth 2 for many-to-many cases, like updateOne or updateMany
result :
- Junction tables
- Activity target tables
2026-02-17 13:57:26 +00:00
5750c9be0c i18n - translations (#17997)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:36:47 +01:00
08feb6f651 i18n - translations (#17995)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:29:21 +01:00
Félix MalfaitGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Charles Bochet
c9c3b2b691 fix: improve clipboard copy for non-HTTPS self-hosted deployments (#17989)
Closes #8305

The Clipboard API (`navigator.clipboard`) requires a secure context
(HTTPS or localhost). Self-hosted deployments on plain HTTP silently
fail when copying.

This PR:
- Adds a `document.execCommand('copy')` fallback for insecure contexts
- Shows a descriptive error message explaining HTTPS is required when
the fallback also fails
- Consolidates 3 components that were using `navigator.clipboard`
directly (without error handling) to use the centralized
`useCopyToClipboard` hook

Generated with [Claude Code](https://claude.ai/code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Scoped to frontend clipboard UX with a defensive fallback and clearer
errors; minimal impact outside copy flows.
> 
> **Overview**
> Improves copy-to-clipboard behavior in non-HTTPS/self-hosted
deployments by enhancing `useCopyToClipboard` to use
`navigator.clipboard` only in secure contexts and otherwise fall back to
`document.execCommand('copy')`.
> 
> Updates 2FA setup screens and the view visibility dropdown to use the
centralized `copyToClipboard` helper (with consistent snackbars), and
shows a more descriptive error (longer duration) when copying fails due
to an insecure context.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
30944e63eb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2026-02-17 14:24:00 +01:00
09e1684300 feat: show auto-generated conversation title for AI chat. (#17922)
## Summary
Replaces the static "Ask AI" header in the command menu with the
conversation’s auto-generated title once it’s set after the first
message.

## Changes
- **Backend:** Title is generated after the first user message (existing
behavior).
- **Frontend:** After the first stream completes, we fetch the thread
title and sync it to:
- `currentAIChatThreadTitleState` (persists across command menu
close/reopen)
- Command menu page info and navigation stack (so the title survives
back navigation)
- **Entry points:** Opening Ask AI from the left nav or command center
uses the same title resolution (explicit `pageTitle` → current thread
title → "Ask AI" fallback).
- **Race fix:** Title sync only runs when the thread that finished
streaming is still the active thread, so switching threads mid-stream
doesn’t overwrite the current thread’s title.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 12:46:35 +00:00
nitinandGitHub e80e9a6a25 fix: on charts newly added multi split values toggle wasnt being saved (#17990)
:)
2026-02-17 14:01:11 +01:00
c2fe18af53 i18n - translations (#17993)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:00:47 +01:00
EtienneandGitHub dc167b2d3d File - Disable file upload in standalone rich text widget (#17934)
File's url are not signed, in standalone rich text. We choose to disable
file upload to prevent unauthorised file upload links.
2026-02-17 13:46:28 +01:00
3516be2cf4 i18n - translations (#17987)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 13:43:13 +01:00
9477bb3677 Improve AI chat UX (#17974)
## Summary
- update AI chat message typography and list line-height for readability
- apply richer markdown-section styling for headings, spacing,
separators, and inline code
- keep links non-underlined by default with underline on hover, using
accent11 for link color
- preserve previous AI chat table design while keeping other markdown
improvements

## Validation
- yarn eslint
packages/twenty-front/src/modules/ai/components/LazyMarkdownRenderer.tsx
packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 11:24:33 +01:00
8244610bdc i18n - translations (#17983)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 11:05:36 +01:00
nitinandGitHub cfc4e0e343 [DASHBOARDS] Add split multi-value fields setting for charts (#17907)
closes https://github.com/twentyhq/twenty/issues/17890



https://github.com/user-attachments/assets/dbf2ebe6-c2da-44d0-846e-d7fa9fac5f43
2026-02-17 09:29:17 +01:00
Paul RastoinandGitHub 2b7b05de2e [OBJECT_MANIFEST_BREAKING_CHANGE] Sync returns workspace migration (#17918)
# Introduction
In this PR we start returning a workspace migration post sync so it can
committed and provided within the tarball

## Universal aggregators utils
Created two utils
### deleteUniversalFlatEntityForeignKeyAggregators
Used when building a universal create action, a newly created actions
should not contain any aggregated foreign key so they won't be codegen
in the workspace migration but also they are overriden at uninversal to
flat transpilation anw

### resetUniversalFlatEntityForeignKeyAggregators
Used before validating a new flat entity creation, some validator will
consume the fk aggregator in order to validate integrity, but of
optimstically provided it can result to errors. To avoid caller
responsability we override them here

## create-field-action refactor
Refactored the universal and flat field create action to be following
the base actions in order to ease typing
Also it was tailored to handle unlimited amount of flat field metadata
in the same actions whereas in the reality we were always only sending
at max 2 ( for relation fields )

Note: relation field has to be provided at the same as if not optimistic
would fail to retrieve circular universal identifiers

## ObjectManifest
Now always expect a `labelIdentifierFieldMetadataUniversalIdentifier`

## Integration test
Created an integration test that creates an app, sync a first manifest
and a second implying update workspace migration action generation
2026-02-16 15:00:24 +01:00
5604cdbb4b i18n - translations (#17966)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-16 11:07:14 +01:00
martmullandGitHub da064d5e88 Support define is tool logic function (#17926)
- supports isTool and timeout settings in defineLogicFunction in apps
and in setting tabs definition
- compute for all toolInputSchema for logic funciton, in settings and in
code steps

<img width="991" height="802" alt="image"
src="https://github.com/user-attachments/assets/05dc1221-cac9-45a3-87b0-3b13161446fd"
/>
2026-02-16 10:43:29 +01:00
f694bb99b3 fix: restore customDomain field in getCurrentUser query fragment (#17949)
## Summary
- The `customDomain` field was accidentally removed from the
`currentWorkspace` GraphQL query fragment in #16016 (Nov 2025), when
`workspaceCustomApplication { id }` was added in its place rather than
alongside it.
- This caused the custom domain settings page to never display the
configured domain value, the reload/delete buttons, or the DNS records —
since `currentWorkspace.customDomain` was always `undefined`.
- Restores the missing field in the query fragment.

## Test plan
- [ ] Navigate to Settings > Domains on a workspace with a custom domain
configured
- [ ] Verify the custom domain value appears in the input field
- [ ] Verify the Reload and Delete buttons are visible
- [ ] Verify DNS records are displayed


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 06:58:22 +01:00
b901bdec40 i18n - translations (#17945)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-15 23:50:35 +01:00
6f251a6f8e Add @mention support in AI Chat input (#17943)
## Summary
- Add `@mention` support to the AI Chat text input by replacing the
plain textarea with a minimal Tiptap editor and building a shared
`mention` module with reusable Tiptap extensions (`MentionTag`,
`MentionSuggestion`), search hook (`useMentionSearch`), and suggestion
menu — all shared with the existing BlockNote-based Notes mentions to
avoid code duplication
- Mentions are serialized as
`[[record:objectName:recordId:displayName]]` markdown (the format
already understood by the backend and rendered in chat messages), and
displayed using the existing `RecordLink` chip component for visual
consistency
- Fix images in chat messages overflowing their container by
constraining to `max-width: 100%`
- Fix web_search tool display showing literal `{query}` instead of the
actual query (ICU single-quote escaping issue in Lingui `t` tagged
templates)

## Test plan
- [ ] Open AI Chat, type `@` and verify the suggestion menu appears with
searchable records
- [ ] Select a mention from the dropdown (via click or keyboard
Enter/ArrowUp/Down) and verify the record chip renders inline
- [ ] Send a message containing a mention and verify it appears
correctly in the conversation as a clickable `RecordLink`
- [ ] Verify Enter sends the message when the suggestion menu is closed,
and selects a mention when the menu is open
- [ ] Verify images in AI chat responses are constrained to the
container width
- [ ] Verify the web_search tool step shows the actual search query
(e.g. "Searched the web for Salesforce") instead of `{query}`
- [ ] Verify Notes @mentions still work as before


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 14:37:33 +01:00
0876197c8d i18n - translations (#17935)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-14 10:54:52 +01:00