⚠️ Breaking changes
- Relabel the app permissions as Workspace Apps and User Apps and enforce User Apps on the server (#28083) by @ehconitin
💅 Improvements & UX
- feat(billing): add workspace credits per seat (#28207) by @etiennejouan
- feat(roles): prepare custom roles gating (Member identity, self-host grant, atomic role deletion) (#28291) by @etiennejouan
- Show installed apps' user settings on App preferences (#27753) by @ehconitin
- Let lone widgets fill standalone pages (#27863) by @Bonapara
- Add fallback values to campaign variables (#27915) by @neo773
- Edit campaign variable fallbacks from the chip (#27916) by @neo773
- Add the Teams activities route (#28000) by @abdulrahmancodes
- Regroup Communication settings under channel tabs (#28001) by @neo773
- Capture Slider drags on the host in front components (#28061) by @bosiraphael
- Keep workspace-shared app connections off App preferences (#28088) by @ehconitin
- Require CONNECTED_ACCOUNTS to add or reconnect a personal app connection (#28089) by @ehconitin
- Stop radio labels shifting when the selection changes (#28090) by @Bonapara
- App preferences: reset on empty value, error state, missing configuration warning (#28091) by @ehconitin
- Show the sender and clearer choices on the unsubscribe page (#28135) by @Bonapara
- Write an AI summary on Call Recordings imported from Microsoft Teams (#28226) by @ehconitin
- Make transcript summaries the only Teams setting for V1 (#28227) by @ehconitin
- Add a Generate call summary command for Teams Call Recordings and calendar events (#28228) by @ehconitin
- Keep the native account app tab bar stable while accounts load (#28244) by @ehconitin
- Make twenty-ui Skeleton a block clamped to its container (#28260) by @bosiraphael
- Let render-composed Autocomplete inputs own their look (#28261) by @bosiraphael
- Remove the no-op rounded prop from Card.Root (#28263) by @bosiraphael
- Give the gray soft Banner a visible tint (#28264) by @bosiraphael
- Stack SkeletonLine placeholders in a flex column (#28268) by @bosiraphael
- Remove the IS_RECORD_SHARE_VISIBILITY_GATING_ENABLED feature flag (#28271) by @charlesBochet
- Load the global reset in the twenty-ui Storybook (#28272) by @bosiraphael
- Narrow the call recorder summary parser to the fields it reads (#28273) by @ehconitin
- Make Cmd+J toggle the logs mode instead of collapsing the console (#28274) by @martmull
- Align Dropdown search activation (#28275) by @bosiraphael
- Only sweep workspaces with an emailing domain for stale campaigns (#28276) by @charlesBochet
- Index timeline activity linked record id and skip unchanged happensAt updates (#28277) by @neo773
- Fix the call recorder custom hex input border (#28279) by @ehconitin
- Fix core client JSON scalar types (#28281) by @Weiko
- Retire MenuItem and MenuItemAvatar (#28285) by @bosiraphael
- Stop reporting revoked accounts to Sentry (#28287) by @neo773
- Retire specialized menu rows (#28290) by @bosiraphael
- Render the virtualized record table from row slots (#28294) by @charlesBochet
- Give Breadcrumb a consistent medium weight (#28297) by @bosiraphael
- Unify Tooltip width defaults (#28298) by @bosiraphael
- Keep Skeleton corners round (#28299) by @bosiraphael
- Keep full Tag labels at their natural width (#28300) by @bosiraphael
- Add plain Chips with exact width limits (#28301) by @bosiraphael
- Remove the IS_JSON_FILTER_ENABLED feature flag (#28302) by @charlesBochet
- Stabilize frontend and twenty-ui stories (#28303) by @bosiraphael
- Stop requiring workspace SECURITY permission on admin panel resolvers (#28305) by @charlesBochet
- Agent engine: release a conversation's claim in one place (#28306) by @FelixMalfait
- Skip istanbul and cache the Vite optimizer in Storybook test runs (#28307) by @bosiraphael
- Agent engine: read a conversation's wait in one query (#28308) by @FelixMalfait
- Fix inert edit button on field widgets in editor mode (#28310) by @Weiko
- Expose Tooltip body composition (#28311) by @bosiraphael
- Style Button popup triggers while open (#28312) by @bosiraphael
- Add soft accent badges (#28313) by @bosiraphael
- Add larger Heading sizes (#28314) by @bosiraphael
- Let InlineBanner fill its container (#28315) by @bosiraphael
- Replace gray dropdown section bands with quiet labels (#28320) by @Bonapara
- Match additional emails, phones and secondary links in optimistic filters (#28327) by @charlesBochet
- Agent engine: never drop a run outcome its caller is not ready for (#28328) by @FelixMalfait
- Remove FelixMalfait from CODEOWNERS (#28330) by @FelixMalfait
- Cover SVG shape sizes in the worker ResizeObserver (#28331) by @bosiraphael
- Share the remote element command queue (#28332) by @bosiraphael
- Bump the call recorder app to Twenty 2.49 (#28336) by @ehconitin
- Agent engine: park a run behind a busy conversation instead of polling (#28338) by @FelixMalfait
- Reject bare select filter values and rewrite stored ones (#28339) by @charlesBochet
- Run prebuilt warm-ups on a rate-limited lambda-management-queue (#28343) by @charlesBochet
- Rename transient-postgres-error-codes.constants.ts to transient-postgres-error-codes.constant.ts (#28345) by @twenty-pr-author
- Rename the Teams feature flags to release flags (#28347) by @ehconitin
- Give every field a default icon (#28349) by @Bonapara
- Save nested new filter groups on dashboard widgets in one call (#28353) by @ehconitin
- Split the campaign send checks from the send preparation (#28357) by @neo773
- Add a query that previews a campaign send with its blocker (#28358) by @neo773
- Cover the campaign send preview with integration tests (#28359) by @neo773
- Show the server's send blocker in the campaign send panel (#28360) by @neo773
- Remove the
as anycasts in 2 files of modules/object-record/record-filter/utils (#28363) by @twenty-pr-author - Keep grouped table rows from re-rendering when their group changes (#28365) by @charlesBochet
- Fix grouped table rows disappearing after a relation edit (#28367) by @charlesBochet
- Subscribe grouped table views to SSE record events (#28369) by @charlesBochet
- Fix currency display crash on a code missing from the currency labels (#28370) by @charlesBochet
- Fix stale selectors in create-record and create-kanban-view e2e tests (#28380) by @charlesBochet
- Remove the
as anycasts in cache-storage.service.ts (#28382) by @twenty-pr-author - Offer pending invitations in the workspace picker only once the email is verified (#28383) by @charlesBochet
- Rename 2 server files to the singular suffix in src/engine/core-modules/admin-panel/constants (#28384) by @twenty-pr-author
- Improve Standard and Custom app marketplace pages (#28387) by @martmull
- Show built-in account apps in the Installed tab (#28388) by @ehconitin
- Add visual RadioGroup orientation (#28392) by @bosiraphael
- Add outlined Chips for rounded links (#28393) by @bosiraphael
- Add 32px Avatars and move 40px to xxl (#28394) by @bosiraphael
- Add compact Tabs for tool call details (#28395) by @bosiraphael
- Open the calendar event from the Call Recordings widget (#28398) by @ehconitin
- Fix transcript status placement in the call recording transcript widget (#28401) by @ehconitin
- Drop db spans from AI agent transactions sent to Sentry (#28402) by @etiennejouan
- Rename native account apps to built-in account apps (#28403) by @ehconitin
- Search help center through the docs.twenty.com MCP server (#28405) by @etiennejouan
- Wait for the signed-in app in the postcard e2e auth setup (#28406) by @charlesBochet
- Remove IS_TRANSCRIPT_IMPORT_RELEASED feature flag (#28409) by @ehconitin
- Remove the remaining placeholders from the call recorder widgets (#28410) by @ehconitin
- Add inherited Button colors (#28413) by @bosiraphael
- Use Twenty UI by default in app agent guidance (#28419) by @bosiraphael
- Fix flaky SavedSecretCanBeCleared story (#28423) by @ehconitin
- Cover the empty currency code in getCurrencyLabel tests (#28424) by @charlesBochet
- Wait for the auth UI before choosing email login in e2e tests (#28426) by @charlesBochet
- Clean up call recordings left behind by call recorder integration tests (#28428) by @ehconitin
- Apply loaded metadata when one stale query fails (#28429) by @charlesBochet
- Accept the self-signed local TLS proxy in the postcard e2e config (#28431) by @charlesBochet
- Use shared settings dialog layouts (#28436) by @bosiraphael
- Use shared confirmation dialog layouts (#28437) by @bosiraphael
- Always show unmatched attendees in the call participants widget (#28438) by @ehconitin
- Remove the main CI failure ping to a route that does not exist (#28440) by @charlesBochet
- Expose host location to front components (#28444) by @bosiraphael
🐛 Bug fixes
- fix(server): reject oversized app tarballs without crashing the process (#27471) by @devjotaduo
- fix(roles): explain a role deletion refused because the default role cannot take its API keys or agents (#28348) by @etiennejouan
- fix(front): resize record table columns in the right direction in RTL (#28378) by @almoghazaz-cell
- fix(shared): keep trailing slashes inside the query or hash in normalizeUrlOrigin (#28421) by @charlesBochet
- fix(billing): drop billingPrice.stripeMeterId before dropping billingMeter (#28435) by @etiennejouan
🔧 Developer & API
- Self-host Extra Smart: replace dominated grok-4.6@xhigh with grok-4.7 (#28053) by @twenty-pr-author
- Let workspace admins switch to the new REST metadata API format from the Lab (#28282) by @charlesBochet
- Rename 5 server files to the singular suffix in src/engine/api/mcp/constants (#28346) by @twenty-pr-author
- Give SDK runtime values their own twenty-shared entry (#28351) by @ehconitin
- Rename 7 server files to the singular suffix in src/engine/api/utils (#28364) by @twenty-pr-author
- Parse quoted REST filter values and sibling root groups correctly (#28368) by @charlesBochet
🏗️ Internal changes (1)
- chore(billing): remove unused billingMeter table (#28381) by @etiennejouan
Full changelog (131 PRs)
- fix(server): reject oversized app tarballs without crashing the process (#27471) by @devjotaduo
- Show installed apps' user settings on App preferences (#27753) by @ehconitin
- i18n - website translations (#27821) by @github-actions
- Let lone widgets fill standalone pages (#27863) by @Bonapara
- chore: sync AI model catalog (#27887) by @github-actions
- Add fallback values to campaign variables (#27915) by @neo773
- Edit campaign variable fallbacks from the chip (#27916) by @neo773
- Add the Teams activities route (#28000) by @abdulrahmancodes
- Regroup Communication settings under channel tabs (#28001) by @neo773
- Self-host Extra Smart: replace dominated grok-4.6@xhigh with grok-4.7 (#28053) by @twenty-pr-author
- Capture Slider drags on the host in front components (#28061) by @bosiraphael
- Relabel the app permissions as Workspace Apps and User Apps and enforce User Apps on the server (#28083) by @ehconitin
- Keep workspace-shared app connections off App preferences (#28088) by @ehconitin
- Require CONNECTED_ACCOUNTS to add or reconnect a personal app connection (#28089) by @ehconitin
- Stop radio labels shifting when the selection changes (#28090) by @Bonapara
- App preferences: reset on empty value, error state, missing configuration warning (#28091) by @ehconitin
- Show the sender and clearer choices on the unsubscribe page (#28135) by @Bonapara
- feat(billing): add workspace credits per seat (#28207) by @etiennejouan
- Write an AI summary on Call Recordings imported from Microsoft Teams (#28226) by @ehconitin
- Make transcript summaries the only Teams setting for V1 (#28227) by @ehconitin
- Add a Generate call summary command for Teams Call Recordings and calendar events (#28228) by @ehconitin
- i18n - translations (#28239) by @github-actions
- Keep the native account app tab bar stable while accounts load (#28244) by @ehconitin
- chore: sync DPA sub-processors from trust center (#28253) by @github-actions
- Make twenty-ui Skeleton a block clamped to its container (#28260) by @bosiraphael
- Let render-composed Autocomplete inputs own their look (#28261) by @bosiraphael
- Remove the no-op rounded prop from Card.Root (#28263) by @bosiraphael
- Give the gray soft Banner a visible tint (#28264) by @bosiraphael
- chore: bump version to 2.50.0 (#28267) by @twenty-pr
- Stack SkeletonLine placeholders in a flex column (#28268) by @bosiraphael
- Remove the IS_RECORD_SHARE_VISIBILITY_GATING_ENABLED feature flag (#28271) by @charlesBochet
- Load the global reset in the twenty-ui Storybook (#28272) by @bosiraphael
- Narrow the call recorder summary parser to the fields it reads (#28273) by @ehconitin
- Make Cmd+J toggle the logs mode instead of collapsing the console (#28274) by @martmull
- Align Dropdown search activation (#28275) by @bosiraphael
- Only sweep workspaces with an emailing domain for stale campaigns (#28276) by @charlesBochet
- Index timeline activity linked record id and skip unchanged happensAt updates (#28277) by @neo773
- Fix the call recorder custom hex input border (#28279) by @ehconitin
- Fix core client JSON scalar types (#28281) by @Weiko
- Let workspace admins switch to the new REST metadata API format from the Lab (#28282) by @charlesBochet
- Retire MenuItem and MenuItemAvatar (#28285) by @bosiraphael
- Stop reporting revoked accounts to Sentry (#28287) by @neo773
- Retire specialized menu rows (#28290) by @bosiraphael
- feat(roles): prepare custom roles gating (Member identity, self-host grant, atomic role deletion) (#28291) by @etiennejouan
- Render the virtualized record table from row slots (#28294) by @charlesBochet
- Give Breadcrumb a consistent medium weight (#28297) by @bosiraphael
- Unify Tooltip width defaults (#28298) by @bosiraphael
- Keep Skeleton corners round (#28299) by @bosiraphael
- Keep full Tag labels at their natural width (#28300) by @bosiraphael
- Add plain Chips with exact width limits (#28301) by @bosiraphael
- Remove the IS_JSON_FILTER_ENABLED feature flag (#28302) by @charlesBochet
- Stabilize frontend and twenty-ui stories (#28303) by @bosiraphael
- Stop requiring workspace SECURITY permission on admin panel resolvers (#28305) by @charlesBochet
- Agent engine: release a conversation's claim in one place (#28306) by @FelixMalfait
- Skip istanbul and cache the Vite optimizer in Storybook test runs (#28307) by @bosiraphael
- Agent engine: read a conversation's wait in one query (#28308) by @FelixMalfait
- Fix inert edit button on field widgets in editor mode (#28310) by @Weiko
- Expose Tooltip body composition (#28311) by @bosiraphael
- Style Button popup triggers while open (#28312) by @bosiraphael
- Add soft accent badges (#28313) by @bosiraphael
- Add larger Heading sizes (#28314) by @bosiraphael
- Let InlineBanner fill its container (#28315) by @bosiraphael
- Replace gray dropdown section bands with quiet labels (#28320) by @Bonapara
- Match additional emails, phones and secondary links in optimistic filters (#28327) by @charlesBochet
- Agent engine: never drop a run outcome its caller is not ready for (#28328) by @FelixMalfait
- Remove FelixMalfait from CODEOWNERS (#28330) by @FelixMalfait
- Cover SVG shape sizes in the worker ResizeObserver (#28331) by @bosiraphael
- Share the remote element command queue (#28332) by @bosiraphael
- Bump the call recorder app to Twenty 2.49 (#28336) by @ehconitin
- Agent engine: park a run behind a busy conversation instead of polling (#28338) by @FelixMalfait
- Reject bare select filter values and rewrite stored ones (#28339) by @charlesBochet
- Run prebuilt warm-ups on a rate-limited lambda-management-queue (#28343) by @charlesBochet
- Rename transient-postgres-error-codes.constants.ts to transient-postgres-error-codes.constant.ts (#28345) by @twenty-pr-author
- Rename 5 server files to the singular suffix in src/engine/api/mcp/constants (#28346) by @twenty-pr-author
- Rename the Teams feature flags to release flags (#28347) by @ehconitin
- fix(roles): explain a role deletion refused because the default role cannot take its API keys or agents (#28348) by @etiennejouan
- Give every field a default icon (#28349) by @Bonapara
- i18n - translations (#28350) by @github-actions
- Give SDK runtime values their own twenty-shared entry (#28351) by @ehconitin
- Save nested new filter groups on dashboard widgets in one call (#28353) by @ehconitin
- i18n - translations (#28354) by @github-actions
- i18n - website translations (#28355) by @github-actions
- Split the campaign send checks from the send preparation (#28357) by @neo773
- Add a query that previews a campaign send with its blocker (#28358) by @neo773
- Cover the campaign send preview with integration tests (#28359) by @neo773
- Show the server's send blocker in the campaign send panel (#28360) by @neo773
- Remove the
as anycasts in 2 files of modules/object-record/record-filter/utils (#28363) by @twenty-pr-author - Rename 7 server files to the singular suffix in src/engine/api/utils (#28364) by @twenty-pr-author
- Keep grouped table rows from re-rendering when their group changes (#28365) by @charlesBochet
- i18n - translations (#28366) by @github-actions
- Fix grouped table rows disappearing after a relation edit (#28367) by @charlesBochet
- Parse quoted REST filter values and sibling root groups correctly (#28368) by @charlesBochet
- Subscribe grouped table views to SSE record events (#28369) by @charlesBochet
- Fix currency display crash on a code missing from the currency labels (#28370) by @charlesBochet
- i18n - translations (#28372) by @github-actions
- chore: sync AI model catalog (#28376) by @github-actions
- fix(front): resize record table columns in the right direction in RTL (#28378) by @almoghazaz-cell
- Fix stale selectors in create-record and create-kanban-view e2e tests (#28380) by @charlesBochet
- chore(billing): remove unused billingMeter table (#28381) by @etiennejouan
- Remove the
as anycasts in cache-storage.service.ts (#28382) by @twenty-pr-author - Offer pending invitations in the workspace picker only once the email is verified (#28383) by @charlesBochet
- Rename 2 server files to the singular suffix in src/engine/core-modules/admin-panel/constants (#28384) by @twenty-pr-author
- Improve Standard and Custom app marketplace pages (#28387) by @martmull
- Show built-in account apps in the Installed tab (#28388) by @ehconitin
- Add visual RadioGroup orientation (#28392) by @bosiraphael
- Add outlined Chips for rounded links (#28393) by @bosiraphael
- Add 32px Avatars and move 40px to xxl (#28394) by @bosiraphael
- Add compact Tabs for tool call details (#28395) by @bosiraphael
- Open the calendar event from the Call Recordings widget (#28398) by @ehconitin
- Fix transcript status placement in the call recording transcript widget (#28401) by @ehconitin
- Drop db spans from AI agent transactions sent to Sentry (#28402) by @etiennejouan
- Rename native account apps to built-in account apps (#28403) by @ehconitin
- Search help center through the docs.twenty.com MCP server (#28405) by @etiennejouan
- Wait for the signed-in app in the postcard e2e auth setup (#28406) by @charlesBochet
- Remove IS_TRANSCRIPT_IMPORT_RELEASED feature flag (#28409) by @ehconitin
- Remove the remaining placeholders from the call recorder widgets (#28410) by @ehconitin
- Add inherited Button colors (#28413) by @bosiraphael
- Use Twenty UI by default in app agent guidance (#28419) by @bosiraphael
- fix(shared): keep trailing slashes inside the query or hash in normalizeUrlOrigin (#28421) by @charlesBochet
- Fix flaky SavedSecretCanBeCleared story (#28423) by @ehconitin
- Cover the empty currency code in getCurrencyLabel tests (#28424) by @charlesBochet
- Wait for the auth UI before choosing email login in e2e tests (#28426) by @charlesBochet
- Clean up call recordings left behind by call recorder integration tests (#28428) by @ehconitin
- Apply loaded metadata when one stale query fails (#28429) by @charlesBochet
- Accept the self-signed local TLS proxy in the postcard e2e config (#28431) by @charlesBochet
- fix(billing): drop billingPrice.stripeMeterId before dropping billingMeter (#28435) by @etiennejouan
- Use shared settings dialog layouts (#28436) by @bosiraphael
- Use shared confirmation dialog layouts (#28437) by @bosiraphael
- Always show unmatched attendees in the call participants widget (#28438) by @ehconitin
- Remove the main CI failure ping to a route that does not exist (#28440) by @charlesBochet
- Expose host location to front components (#28444) by @bosiraphael
Full Changelog: twenty/v2.49.0...twenty/v2.50.0