6351c6c1c666d00a1702eacb28b271bca15e529a
10542 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6351c6c1c6 |
feat: remember original URL and redirect after login (#18308)
## Summary - Implement a return-to-path mechanism that preserves the user's intended destination across authentication flows (login, magic link, cross-domain redirects) - Uses layered persistence: Jotai atom (in-memory), sessionStorage with TTL (tab-switch resilience), URL query parameter (cross-domain propagation) - Includes path validation to prevent open redirects, automatic cleanup after successful login, and comprehensive test coverage - Replaces the unused `previousUrlState` with a robust `returnToPathState` system ## Test plan - [ ] Visit a deep link (e.g. `/objects/tasks`) while logged out — should redirect to login, then back to `/objects/tasks` after logging in - [ ] Visit an OAuth authorize link while logged out — should redirect to login, then to the authorize page - [ ] Test magic link flow: click sign-in link that opens new tab — should still redirect to original destination - [ ] Test cross-domain: visit `app.twenty.com/objects/tasks` — should preserve path through workspace domain redirect - [ ] Verify auth/onboarding paths are excluded from being saved as return paths - [ ] Verify return-to-path is cleared after successful navigation - [ ] All 215 existing `usePageChangeEffectNavigateLocation` tests pass Made with [Cursor](https://cursor.com) |
||
|
|
20a2c3836e |
feat: introduce role selector when inviting members to a workspace (#18085)
This PR adds an explicit role selector to the "Invite by email" flow,
requires a role choice before sending, and stores the selected role with
each invitation. The backend now accepts and persists `roleId` on
invitations and applies it when the invite is accepted, while keeping it
optional to avoid breaking existing clients and legacy invites.
---
### Frontend
- **Settings → Members → Invite by email**
- New **Role** dropdown (same `Select` pattern as member/API key role
selectors) between the email input and Invite button.
- Roles are loaded via `SettingsRolesQueryEffect` and
`settingsAllRolesSelector`; only roles with `canBeAssignedToUsers` are
shown.
- Role is **required**: form validates `roleId` (e.g.
`z.string().min(1)`) and the Invite button is disabled until a role is
selected and emails are valid.
- `WorkspaceInviteTeam` receives `roles` as a prop from the parent;
layout is responsive (e.g. stacked on small viewports).
- **Pending invitations table**
- New **Role** column showing the invitation’s role label (or "Unknown
role" for legacy invites without `roleId`), using the same roles source
for lookup.
- **Onboarding invite step**
- When sending invites during onboarding, the workspace **default role**
is used when available (`currentWorkspace?.defaultRole?.id`), so no role
selector is added there.
- **GraphQL**
- `sendInvitations` mutation accepts optional `roleId`;
`findWorkspaceInvitations` and resend mutation responses include
`roleId` on `WorkspaceInvitation`. Frontend types (e.g.
`WorkspaceInvitation`, hook variables) updated accordingly.
---
### Backend
- **API**
- `SendInvitationsInput` has an **optional** `roleId` (UUID, nullable).
The resolver normalises `null` to `undefined` so existing callers and
legacy flows are not broken.
- **Validation (when `roleId` is provided)**
- Role checks are centralised in **RoleValidationService**
(`RoleValidationModule`, in `metadata-modules/role-validation/`). It
validates that the role exists in the workspace and has
`canBeAssignedToUsers`, and throws a permissions-style error otherwise.
This avoids circular dependencies (e.g. `RoleModule` imports
`UserWorkspaceModule`, so invite/accept flows cannot depend on
`RoleModule`).
- **Send flow:** `WorkspaceInvitationResolver` and
`WorkspaceInvitationService.sendInvitations` both call
`RoleValidationService.validateRoleAssignableToUsersOrThrow` when
`roleId` is present (resolver before calling the service; service again
before creating tokens so that **resend** also validates the stored role
and fails fast if the role was deleted or made unassignable).
- **Accept flow:**
`UserWorkspaceService.addUserToWorkspaceIfUserNotInWorkspace` uses the
same service in `resolveRoleIdForNewMember` when an invitation provides
a `roleId`, then falls back to `workspace.defaultRoleId` when not.
Role/default is resolved and validated before any user/workspace/member
creation.
- **Persistence**
- Invitation app tokens store `roleId` in `context` next to `email`
(`context: { email, roleId? }`). `generateInvitationToken` and
`createWorkspaceInvitation` accept an optional `roleId` and only add it
to `context` when defined.
- **Resend**
- Resend passes the existing invitation’s `context.roleId` into
`sendInvitations`. The service validates that role (when present) before
creating the new token, so if the role was deleted or made unassignable,
resend fails with a clear error instead of sending a broken link.
- **Response shape**
- `SendInvitationsOutput.result` remains `WorkspaceInvitation[]`. When
`usePersonalInvitation` is false we only push full invitation records
(from `castAppTokenToWorkspaceInvitationUtil`), so the result always
matches the GraphQL type (`id`, `email`, `roleId`, `expiresAt`).
- **Modules**
- `WorkspaceInvitationModule` and `UserWorkspaceModule` import
**RoleValidationModule** (not `RoleModule`) and inject
**RoleValidationService** for validation. `RoleModule` imports
`RoleValidationModule` and `RoleService` delegates to
`RoleValidationService` for the same validation where the module graph
allows.
---
### Backward compatibility
- **Optional `roleId`**: Clients that don’t send `roleId` (or send
`null`) are unchanged; invitations are created without a role and the
accept flow uses the workspace default role.
- **Legacy invitations**: App tokens with only `context.email` still
work; `context.roleId` is optional and the UI can show e.g. "Unknown
role" for those in the pending-invitations table.
|
||
|
|
1eb284c87f |
Fix command menu text/number inputs to commit on blur and cancel cleanly on Escape (#18283)
closes https://github.com/twentyhq/twenty/issues/18264 https://github.com/user-attachments/assets/7b576a00-78bc-46a2-9528-d8b3bcbdd530 https://github.com/user-attachments/assets/4102468e-e85f-46a0-8b23-e7abd77bfc95 ### PR description - This fixes flaky persistence in command menu text and number inputs. - moved commit logic to onBlur (single commit path) - Enter now blurs, so it uses the same commit path - Escape now cancels edit (restores draft + exits) without persisting - removed dependency on input click-outside commit timing ### Outcome - - clicking anywhere outside the input now reliably persists edits - Escape consistently discards edits |
||
|
|
c4140f85df |
chore(twenty-front): migrate small modules from Emotion to Linaria (PR 1/10) (#18314)
## Emotion → Linaria migration — PR 1 of 10
First batch of the `twenty-front` migration from Emotion (runtime
CSS-in-JS) to Linaria (zero-runtime, build-time extraction via
wyw-in-js). Covers **100 files** across 10 small standalone modules —
chosen as the lowest-risk starting point.
### Modules migrated
spreadsheet-import (28) · navigation-menu-item (17) · views (14) ·
billing (10) · blocknote-editor (7) · advanced-text-editor (7) ·
favorites (7) · navigation (4) · information-banner (3) ·
sign-in-background-mock (3)
### Migration pattern
Every file follows the same mechanical transformation:
| Emotion | Linaria |
|---|---|
| `import styled from '@emotion/styled'` | `import { styled } from
'@linaria/react'` |
| `${({ theme }) => theme.font.color.primary}` |
`${themeCssVariables.font.color.primary}` |
| `${({ theme }) => theme.spacing(4)}` |
`${themeCssVariables.spacing[4]}` |
| `const theme = useTheme()` | `const { theme } =
useContext(ThemeContext)` |
| `import { type Theme } from '@emotion/react'` | `import { type
ThemeType } from 'twenty-ui/theme'` |
`themeCssVariables` is a build-time object where every leaf is a
`var(--t-xxx)` CSS custom property reference, evaluated statically by
wyw-in-js. Runtime theme access (icon sizes, colors passed as props)
uses `useContext(ThemeContext)`.
### Gotchas encountered & fixed
- **Interpolation return types** — wyw-in-js requires `string | number`,
never `false`/`undefined`. Replaced `condition && 'css'` with `condition
? 'css' : ''`.
- **`css` tag inside `styled` templates** — Linaria `css` returns a
class name, not CSS text. Replaced with plain template strings.
- **`styled(Component)` needs `className`** — added `className` prop to
`NavigationDrawerSection`, `DropdownMenuItemsContainer`, and `Heading`.
- **`shouldForwardProp` not supported** — Linaria filters invalid DOM
props automatically for HTML elements. For custom components, used
wrapper divs where needed.
- **`FormFieldPlaceholderStyles`** — converted from Emotion `css`
function to a static string using `themeCssVariables`.
|
||
|
|
9c4b0f526c |
Refactor chip component hierarchy: AvatarChip → AvatarOrIcon (#18313)
## Summary Cleans up the chip component hierarchy in `twenty-ui`: - **Fix twenty-ui Storybook** — The `wyw-in-js` Vite plugin crashed on `/@react-refresh` virtual module. Fixed by setting `enforce: 'pre'` so it runs before the React refresh plugin injects virtual imports. - **Rename `AvatarChip` → `AvatarOrIcon`** — The old name was misleading. This component is not a chip — it's a polymorphic renderer that displays either an `Avatar` (image/initials) or an `Icon` (plain or with colored background). It's typically slotted into `Chip`/`LinkChip` as `leftComponent`. - **Move `rightComponentDivider` to `Chip`/`LinkChip`** — The vertical separator between chip content and a right action (e.g. a close button) is a chip layout concern, not an avatar concern. Added `rightComponentDivider` boolean prop to `Chip` and `LinkChip`. - **Remove `MultipleAvatarChip`** — Zero consumers in the codebase. The command menu implements its own overlapping avatar layout. - **Migrate raw icon usages** — `CalendarEventDetails` and `FileIcon` (small size) now use `AvatarOrIcon` for consistent Chip icon rendering. - **Enhance stories** — Full `CatalogDecorator` coverage for `Chip` and `LinkChip` showing all variants, sizes, accents, and states. ## Component hierarchy ``` AvatarOrIcon (twenty-ui) ├── No Icon → renders Avatar (image or initials) ├── Icon + background → renders icon in colored square └── Icon only → renders plain icon Used as leftComponent/rightComponent in Chip or standalone Chip (twenty-ui) ├── leftComponent (typically AvatarOrIcon) ├── label (with overflow tooltip) ├── rightComponentDivider (optional vertical separator) └── rightComponent (e.g. close icon via AvatarOrIcon) LinkChip (twenty-ui) └── Wraps Chip inside a react-router <Link> RecordChip (twenty-front) └── Composes Chip/LinkChip + AvatarOrIcon with record data ``` ## `Chip` API additions | Prop | Type | Description | |------|------|-------------| | `rightComponentDivider` | `boolean` | Renders a vertical separator before `rightComponent` | ## Stories <img width="1032" height="576" alt="image" src="https://github.com/user-attachments/assets/fe7c7666-9b16-4545-b87e-1b53e22d462d" /> |
||
|
|
37bcb35391 |
Migrate pagelayout position frontend (#18229)
## Context Part 1 of migrating gridPosition in favor of typed position FE should now always send both values to the BE and use both. Next steps: - Update the backend to enforce and validate the new position field + DB migrations gridPositon -> position (type: GRID) - Cleanup frontend usage - Cleanup backend |
||
|
|
78a0197643 |
Prevent deletion of il-else branches (#18294)
If-else branches cannot be recreated once deleted. Only else-if branches can. On if-else branches removal, we now remplace the node by an empty node instead of only deleting Also fixing nested if-else. |
||
|
|
ff3326a53b |
i18n - translations (#18323)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
5e92fb4fc6 |
Do not console.log while consoleListener (#18322)
It can occur infinite loops see https://twenty-v7.sentry.io/issues/7269592888/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20!issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=issue-stream&sort=freq |
||
|
|
1a8be234de |
OAuth security hardening: RFC compliance, PKCE binding, rate limiting (#18305)
## Summary Follow-up to #18267. Hardens the OAuth implementation with security fixes identified during audit: **P0 — Critical:** - Bind authorization codes to `client_id` in context to prevent auth code injection (RFC 6749 §4.1.3) - Store PKCE `code_challenge` directly in auth code context instead of a separate `CodeChallenge` token — cryptographically binds the challenge to its code - Enforce `code_verifier` when `code_challenge` was used during authorization - Hash authorization codes (SHA-256) before storage to prevent exposure if DB is compromised - Add `Cache-Control: no-store` + `Pragma: no-cache` headers on token responses (RFC 6749 §5.1) - Add rate limiting on `/oauth/token` endpoint (20 req/min per client via existing `ThrottlerService`) **P1 — High:** - Return HTTP 401 for `invalid_client` errors instead of 400 (RFC 6749 §5.2) - Verify refresh tokens belong to the presenting client (cross-client token theft prevention) - Limit fields exposed by public `findApplicationRegistrationByClientId` query to only what the frontend needs (`id`, `name`, `logoUrl`, `websiteUrl`, `oAuthScopes`) - Require `API_KEYS_AND_WEBHOOKS` permission for `createApplicationRegistration` mutation **P2/P3 — Medium/Low:** - Add error handling and loading states to frontend Authorize page - Rename redirect URL param from `authorizationCode` to `code` (RFC standard) - Add unit tests for `validateRedirectUri` utility (8 test cases) ## Test plan - [ ] Existing OAuth integration tests updated for all changes (hashed codes, context-based PKCE, client binding, 401 status codes, cache headers) - [ ] New test: auth code rejected when presented by a different client - [ ] New test: refresh token rejected when presented by a different client - [ ] New test: `code_verifier` required when PKCE was used in authorization - [ ] New test: `Cache-Control: no-store` header present on responses - [ ] New unit tests for `validateRedirectUri` (HTTPS, localhost, fragments, invalid URIs) - [ ] Verify frontend authorize page shows errors gracefully Made with [Cursor](https://cursor.com) |
||
|
|
d021f7e369 |
Fix self host application (#18292)
- Fixes self host application - add new telemetry information - add serverId to identify a server instance - remove .twenty from git tracking - tree-shake "twenty-sdk" usage in built logic functions and front components - fix "twenty-sdk" version usage - fix twenty-zapier cli --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> |
||
|
|
1b67ba6a75 |
Draft emails fix onblur on text input and callout banner component overflow (#18310)
Before <img width="396" height="759" alt="SCR-20260301-daft" src="https://github.com/user-attachments/assets/c3fb3a19-3456-424d-9fd2-dd13ed0d2ad5" /> After <img width="391" height="752" alt="SCR-20260301-daio" src="https://github.com/user-attachments/assets/80a64991-6e69-4ddf-b968-bdc788af02cd" /> |
||
|
|
5afc46ebd3 |
i18n - translations (#18321)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
a06abb1d60 |
Fields widget rename group (#18169)
## Rename https://github.com/user-attachments/assets/b151683a-d1ae-447f-9d9f-95a14b50608b ## Delete https://github.com/user-attachments/assets/8da73a33-1c57-4771-b712-527b8080117d --------- Co-authored-by: Weiko <corentin@twenty.com> |
||
|
|
2a5b2746c9 |
Fix preview-env-dispatch: repository_dispatch requires contents:write
The `repository_dispatch` API endpoint requires `contents: write` permission on the GITHUB_TOKEN, not `actions: write`. Our security hardening PR inadvertently changed this to `contents: read`, breaking the self-dispatch to the keepalive workflow. Made-with: Cursor |
||
|
|
0223975bbd |
Harden GitHub Actions: fix injections, isolate privileged operations to ci-privileged repo (#18318)
## Summary - Fix expression injection vulnerabilities in composite actions (`restore-cache`, `nx-affected`) and workflow files (`claude.yml`) - Reduce overly broad permissions in `ci-utils.yaml` (Danger.js) and `ci-breaking-changes.yaml` - Restructure `preview-env-dispatch.yaml`: auto-trigger for members, opt-in for contributor PRs via `preview-app` label (safe because keepalive has no write tokens) - Isolate all write-access operations (PR comments, cross-repo posting) to a new dedicated [`twentyhq/ci-privileged`](https://github.com/twentyhq/ci-privileged) repo via `repository_dispatch`, so that workflows in twenty that execute contributor code never have write tokens - Create `post-ci-comments.yaml` (`workflow_run` bridge) to dispatch breaking changes results to ci-privileged, solving the [fork PR comment issue](https://github.com/twentyhq/twenty/pull/13713#issuecomment-3168999083) - Delete 5 unused secrets and broken `i18n-qa-report` workflow - Remove `TWENTY_DISPATCH_TOKEN` from twenty (moved to ci-privileged as `CORE_TEAM_ISSUES_COMMENT_TOKEN`) - Use `toJSON()` for all `client-payload` values to prevent JSON injection ## Security model after this PR | Workflow | Executes fork code? | Write tokens available? | |----------|---------------------|------------------------| | preview-env-keepalive | Yes | None (contents: read only) | | preview-env-dispatch | No (base branch) | CI_PRIVILEGED_DISPATCH_TOKEN only | | ci-breaking-changes | Yes | None (contents: read only) | | post-ci-comments (workflow_run) | No (default branch) | CI_PRIVILEGED_DISPATCH_TOKEN only | | claude.yml | No (base branch) | CI_PRIVILEGED_DISPATCH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN | | ci-utils (Danger.js) | No (base branch) | GITHUB_TOKEN (scoped) | All actual write tokens (`TWENTY_PR_COMMENT_TOKEN`, `CORE_TEAM_ISSUES_COMMENT_TOKEN`) live in `twentyhq/ci-privileged` with strict CODEOWNERS review and branch protection. ## Test plan - [ ] Verify preview environment comments still appear on member PRs - [ ] Verify adding `preview-app` label triggers preview for contributor PRs - [ ] Verify breaking changes reports still post on PRs (including fork PRs) - [ ] Verify Claude cross-repo responses still post on core-team-issues - [ ] Confirm ci-privileged branch protection is enforced |
||
|
|
8d47d8ae38 |
Fix E2E tests broken by redesigned navigation menu (#18315)
## Summary
- **Settings selector**: The Settings navigation item is now rendered as
a `<button>` (via `NavigationDrawerItem` with `onClick`) instead of an
`<a>` link (with `to`). Updated `leftMenu.ts` POM and
`create-kanban-view.spec.ts` to use `getByRole('button', { name:
'Settings' })`.
- **create-record URL field**: The Linkedin field interaction was
missing an initial label click to trigger the hover portal rendering.
Added `recordFieldList.getByText('Linkedin').first().click()` before the
value click, matching the pattern used by the working Emails field.
## Test plan
- [ ] E2E `signup_invite_email.spec.ts` passes (uses
`leftMenu.goToSettings()`)
- [ ] E2E `create-kanban-view.spec.ts` passes (uses Settings click
directly)
- [ ] E2E `create-record.spec.ts` passes (Linkedin URL field
interaction)
- [ ] Existing passing E2E tests remain green
Made with [Cursor](https://cursor.com)
|
||
|
|
68d2297338 |
Fix expression injection in cross-repo GitHub Actions workflow (#18316)
## Summary
- Fixes a script injection vulnerability in the `claude-cross-repo`
job's `actions/github-script` step where `${{ steps.prompt.outputs.repo
}}` and `${{ steps.prompt.outputs.issue_number }}` were interpolated
directly into JavaScript string literals. A crafted dispatch payload
could inject arbitrary JavaScript with access to
`secrets.TWENTY_DISPATCH_TOKEN`.
- Values are now passed via `env:` and accessed through `process.env`,
which treats them as data rather than code.
## Context
Motivated by the [hackerbot-claw
campaign](https://www.stepsecurity.io/blog/hackerbot-claw-github-actions-exploitation)
which exploited similar `${{ }}` expression injection patterns in
workflows at Microsoft, DataDog, and CNCF projects.
The broader analysis found that our workflow is **not vulnerable** to
the primary attack vector (Pwn Request via `pull_request_target` +
untrusted checkout), and `claude-code-action` already gates on write
access internally. This expression injection in the cross-repo dispatch
job was the only concrete vulnerability identified.
## Test plan
- [ ] Verify the `claude-cross-repo` job still posts comments back to
the source issue after a dispatch run
- [ ] Confirm `TARGET_REPO` and `TARGET_ISSUE` env vars are correctly
resolved from step outputs
Made with [Cursor](https://cursor.com)
|
||
|
|
1db2a40961 |
Migrate twenty ui to linaria (#18307)
## Migrate twenty-ui from Emotion to Linaria
Completes the migration of all `twenty-ui` components from Emotion
(runtime CSS-in-JS) to Linaria (zero-runtime, CSS extracted at build
time).
- Replaced `@emotion/styled` with `@linaria/react` across ~170 files
- Removed all Emotion dependencies from `twenty-ui`
- Introduced a CSS custom properties-based theme system:
`themeCssVariables` where every leaf is a `var(--t-xxx)` reference,
injected onto `document.documentElement` by
`ThemeCssVariableInjectorEffect`
- No more `theme` prop threading — styled components reference
`themeCssVariables.x.y` directly at build time
- Updated `twenty-front` consumers to remove `theme={theme}` prop
passing
**Before / After:**
```tsx
// Emotion
color: ${({ theme }) => theme.font.color.primary};
padding: ${({ theme }) => theme.spacing(4)};
// Linaria
color: ${themeCssVariables.font.color.primary};
padding: ${themeCssVariables.spacing[4]};
```
### Theme architecture
Two build-time utilities produce the theme system:
- **`buildThemeReferencingRootCssVariables`** — walks the theme object
and builds a nested mirror where every leaf is a `var(--t-xxx)` string
(evaluated at build time by wyw-in-js)
- **`prepareThemeForRootCssVariableInjection`** — walks the runtime
theme and collects flat `[--css-variable-name, value]` pairs, injected
onto `document.documentElement` by `ThemeCssVariableInjectorEffect`
Both share naming conventions (`camelToKebab`, `SPACING_VALUES`,
`formatSpacingKey`) and are unit tested.
### Spacing cleanup
Spacing scale now uses integers 0–32 (generated via loop), with `0.5`
and `1.5` as the only fractional exceptions. All other fractional
spacing usages (`0.25`, `0.75`, `1.25`, `2.5`, `3.5`) were replaced with
literal pixel values across ~20 twenty-front files.
### Framer Motion integration
Linaria doesn't support `styled(motion.div)` — wrapping a motion element
with `styled()` causes the component body to be stripped at build time.
Instead, we define the styled component first, then wrap it with
`motion.create()`:
```tsx
const StyledBarBase = styled.div`
background-color: ${themeCssVariables.font.color.primary};
height: 100%;
`;
const StyledBar = motion.create(StyledBarBase);
```
### Block interpolations
Linaria doesn't support interpolations that return multiple CSS
declarations (Linaria wraps the entire block in a single `var()`,
producing invalid CSS). These were split into individual property
interpolations:
```tsx
// Emotion — single interpolation returning multiple declarations
border-left: ${({ divider, theme }) => {
const border = `1px solid ${theme.border.color.light}`;
return divider ? `border-${divider}: ${border}` : '';
}}
// Linaria — one interpolation per property
border-left: ${({ divider }) =>
divider === 'left' ? `1px solid ${themeCssVariables.border.color.light}` : 'none'};
border-right: ${({ divider }) =>
divider === 'right' ? `1px solid ${themeCssVariables.border.color.light}` : 'none'};
```
### Dynamic styles via CSS variables
When a component needs to compute styles from multiple props with
complex branching logic (e.g. `Button` combining `variant`, `accent`,
`inverted`, `disabled`, `focus`, `position`), Linaria's prop
interpolations become unwieldy. In those cases we use a
`computeDynamicStyles` function that returns a `CSSProperties` object
injected via `style={}`, referenced from the static CSS with `var()`:
```tsx
const StyledButton = styled.button`
background: var(--btn-bg);
border-color: var(--btn-border-color);
&:hover { background: var(--btn-hover-bg); }
`;
const dynamicStyles = useMemo(() => {
const s = computeButtonDynamicStyles(variant, accent, ...);
return { '--btn-bg': s.background, '--btn-hover-bg': s.hoverBackground } as CSSProperties;
}, [variant, accent, ...]);
return <StyledButton style={dynamicStyles} />;
```
### CSS var + unit concatenation
CSS custom properties can't be concatenated with unit suffixes directly
(`var(--x)px` is invalid). Values that need units use `calc()`:
```tsx
// Broken
transition: background ${themeCssVariables.animation.duration.instant}s ease;
// Fixed
transition: background calc(${themeCssVariables.animation.duration.instant} * 1s) ease;
```
|
||
|
|
159bb9d70a |
A few fixes on table performance (#18304)
## RecordTable Performance Investigation & Optimization (WIP) Investigates what makes the RecordTable slow (14 components, ~12 hooks per cell) and starts applying fixes. ### Key Findings (2,000 cells benchmark)   - **Jotai atoms are the dominant cost**: 10 atom reads/cell = +312%. Full sim with atoms = +476%. - **Derived atoms are 3x cheaper** than individual reads (12 sources: +93% vs +294%). - **Component depth is expensive**: 4-level nesting = +82%, 14 wrappers = +109%. - **Styling engines are comparable**: Linaria vs Emotion is within noise. - **Context reads and useState are nearly free** vs baseline. ### Optimizations Applied 1. **Static focus providers** — replaced per-cell `useState(false)` with static context. Eliminates 400 useState instances. 2. **Delegated onMouseMove** — single handler on table body instead of 400 per-cell handlers. 3. **Hoisted `useObjectMetadataItems()`** — moved from per-cell to table-level context. Eliminates 400 global atom reads. ### Tooling - Perf page at `/__perf__/table`: 17 cell render + 13 state access benchmarks - Render profiler: `window.__RECORD_TABLE_PROFILE = true` - Full plan in `__perf__/PERFORMANCE_PLAN.md` ### Remaining Phases (not high priority to-be-honest) | Phase | What | Status | |-------|------|--------| | 1 | Separate display from interaction | Partial | | 2 | Flatten hierarchy (14 → ~5 components/cell) | TODO | | 3 | Reduce atom reads per cell | Partial | | 4 | CSS-only hover/focus | TODO | | 5 | Event delegation, lazy Draggable | TODO | |
||
|
|
b341704a0e |
i18n - translations (#18306)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
d5d0f5d994 |
i18n - translations (#18302)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
012d819557 |
OAuth Client — Unified ApplicationRegistration, OAuth server, and frontend (#18267)
## Summary Consolidates three separate PRs (#18260, #18261, #18262) into a single unified branch with all review feedback addressed: ### New features - **ApplicationRegistration entity** — server-level registration for OAuth apps with encrypted server variables - **OAuth 2.0 server** — authorization code, client credentials, refresh token grants with PKCE support - **OAuth discovery endpoint** — `.well-known/oauth-authorization-server` metadata - **Frontend UI** — app registration details page with credential management, redirect URI editing, and server variable configuration - **CLI integration** — `twenty dev` auto-registers apps and stores OAuth credentials locally - **Authorize consent screen** — OAuth consent page at `/authorize` showing requested scopes ### Review feedback addressed **Renames (PR #18260):** - `appRegistration` → `applicationRegistration` (entity, tables, files, imports, GraphQL types) - `appRegistrationVariable` → `applicationRegistrationVariable` - `clientId` → `oAuthClientId`, `clientSecretHash` → `oAuthClientSecretHash`, `redirectUris` → `oAuthRedirectUris`, `scopes` → `oAuthScopes` **Security fixes (PR #18261):** - Fixed redirect URI validation bypass when `oAuthRedirectUris` is an empty array - Fixed workspace isolation in `clientCredentialsGrant` — now uses `find()` with explicit handling for multiple installations - Added error logging in refresh token `catch` block instead of silently swallowing **Code quality (PR #18262):** - Split `VersionDistributionEntry` into its own file (one export per file) - Split GraphQL queries and mutations into individual files with a shared fragment - Removed unused `OAuth` entry from `AuthProviderEnum` - Added loading state to `handleRotateSecret` - Removed 27 narration-style comments from test files - Added proper guards (`PublicEndpointGuard`, `NoPermissionGuard`) to controllers and resolvers ## Test plan - [ ] Verify `twenty dev` registers an app and stores OAuth credentials - [ ] Test OAuth authorization code flow end-to-end (authorize → token → API call) - [ ] Test client credentials grant - [ ] Verify redirect URI validation rejects requests when no URIs are registered - [ ] Verify app registration detail page renders correctly - [ ] Test secret rotation with loading state - [ ] Verify server variable editing and saving - [ ] Run `npx nx database:reset twenty-server` to validate migration Closes #18260, #18261, #18262 Made with [Cursor](https://cursor.com) --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> |
||
|
|
9fe2a07c55 |
Navbar customization v2 (#18026)
Adds color support for navigation menu items. --------- 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: Charles Bochet <charles@twenty.com> |
||
|
|
63f17eec2c |
i18n - translations (#18300)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
e806d36099 |
Navbar with AI chats (#18161)
## Summary Add Home/Chat tabs and a dedicated threads list in the navigation drawer. ## Changes - **Navbar tabs:** Tabs in the drawer to switch between Home and Chat (with “New chat” button). Shown on desktop when expanded and on mobile below the workspace selector. - **Navbar threads list:** New `NavigationDrawerAIChatThreadsList` for the Chat tab with date groups (Today / Yesterday / Older), thread rows as `NavigationDrawerItem` (IconComment, title, timestamp). Shared `useAIChatThreadClick` hook used by navbar and command menu; navbar passes `resetNavigationStack: true`. - **NavigationDrawerItem:** New `alwaysShowRightOptions` prop so the timestamp is always visible (no hover-only). --------- Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com> Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
9f5a8735c9 |
i18n - docs translations (#18280)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
c0e6aa1c0b |
i18n - translations (#18295)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
9342b16aad |
Fix more tests 2 (#18293)
## Summary - Migrate more hand-written test mocks to auto-generated data from a real Twenty instance - Add generators for views, billing plans, API keys; extend record generator for workspace members, favorites, connected accounts, calendar events - Remove 9 hand-written mock files replaced by generated equivalents - Update 16 test/story files to use generated data - Fix WorkflowEditActionEmailBase story assertion to match configured recipient email ## Test plan - [x] Lint, typecheck, unit tests pass - [ ] Storybook tests pass in CI |
||
|
|
cfad24da48 |
Fix empty user id clickhouse (#18238)
- Fixes: - Make Workspace User select work; previously, it didn't work as we were not fetching the workspace users correctly - Send Object Events with valid record id and object id ## Audit logs demo https://github.com/user-attachments/assets/92437037-d253-4810-a138-7c709550755d |
||
|
|
86fbf69e95 |
Fix more tests (#18287)
Improve mock in front tests |
||
|
|
9667b3f369 |
i18n - translations (#18291)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
76c7639eb3 |
fix: upgrade storybook to latest to resolve dependabot alert (#18285)
Resolves [Dependabot Alert 509](https://github.com/twentyhq/twenty/security/dependabot/509). Upgraded storybook and related packages to latest, also fixed a failing test to match what the DOM really contains. |
||
|
|
4ed09a3feb |
Upgrade blocknote dependencies from 0.31.1 to 0.47.0. (#18207)
This PR pgrades all BlockNote packages (@blocknote/core, @blocknote/react, @blocknote/mantine, @blocknote/server-util, @blocknote/xl-docx-exporter, @blocknote/xl-pdf-exporter) to 0.47.0 and adapts the codebase to the new API. ### Changes - Dependency upgrades: Bumped all BlockNote packages to 0.47.0, added required Mantine v8 peer dependencies, removed unnecessary prosemirror resolutions - Formatting toolbar: Replaced the manual reimplementation of FormattingToolbarController (which handled visibility, positioning, portal rendering, text-alignment-based placement, and a dangerouslySetInnerHTML transition trick) with BlockNote's built-in FormattingToolbarController. The toolbar buttons themselves are unchanged. - Side menu: Replaced manual drag handle menu positioning and rendering (DashboardBlockDragHandleMenu, DashboardBlockColorPicker, and their floating configs) with BlockNote's built-in SideMenuController, DragHandleButton, and DragHandleMenu components. Deleted 4 files that became dead code. - Extension API migration: Replaced deprecated editor.suggestionMenus and editor.formattingToolbar APIs with the new extension system (SuggestionMenu, useExtensionState, editor.getExtension()) - Slash menu fixes: Filtered out BlockNote's new default "File" item (added in 0.47) to avoid duplicates with our custom one; added icon mappings for new block types (Toggle List, Divider, Toggle Headings, Headings 4-6) - Server-side: Switched @blocknote/server-util to dynamic import() to handle ESM-only transitive dependencies in CJS context |
||
|
|
def5ea5764 |
Fix ai agent node prompt and variables (#18275)
- prompt stored on workflow lvl so input variables can be resolved and it can evolves with versions - make ai agent node output available as variables |
||
|
|
81698ff32c |
i18n - docs translations (#18274)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
c0c51f2ef5 |
i18n - translations (#18278)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
3bbaff801a |
Add Twenty app settings custom app (#18273)
## Context
This PR adds the ability to define a front-component as a custom tab for
the application settings, allowing app creators to inject some
logic/rendering the their app settings.
## Example
```typescript
// packages/twenty-apps/my-test-app/src/front-components/settings-custom-tab.tsx
import { defineFrontComponent } from 'twenty-sdk';
export const SETTINGS_CUSTOM_TAB_UNIVERSAL_IDENTIFIER =
'a42a88a8-21ce-4d22-bc44-d5146da64726';
export const SettingsCustomTab = () => {
return (
<div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
<h2>My Test App Settings</h2>
<p>This is a custom settings tab provided by My Test App.</p>
<p>Application creators can customize this component freely.</p>
</div>
);
};
export default defineFrontComponent({
universalIdentifier: SETTINGS_CUSTOM_TAB_UNIVERSAL_IDENTIFIER,
name: 'settings-custom-tab',
description: 'Custom settings tab for the application',
component: SettingsCustomTab,
});
```
```typescript
// packages/twenty-apps/my-test-app/src/application-config.ts
export default defineApplication({
universalIdentifier: '52870ce6-e584-4bd4-bc1a-6c63c508982e',
displayName: 'My test app',
description: '',
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
settingsCustomTabFrontComponentUniversalIdentifier:
SETTINGS_CUSTOM_TAB_UNIVERSAL_IDENTIFIER,
});
```
<img width="786" height="757" alt="Screenshot 2026-02-26 at 14 54 09"
src="https://github.com/user-attachments/assets/fcba70db-35da-48f1-bd65-359e894a691d"
/>
|
||
|
|
2d2fc06265 |
fix: basic-ftp related dependabot alert (#18269)
Resolves [Dependabot Alert 507](https://github.com/twentyhq/twenty/security/dependabot/507). Fixes critical SLA breach in 6 days. |
||
|
|
8a7a19f312 |
Improve test tooling (#18259)
## Summary Unifies test mocking tooling across Jest and Storybook, replaces handcrafted mock data with auto-generated server-fetched data, and restructures the mock data generation script for maintainability. ### Mock data generation - Split `generate-mock-data.ts` into three focused modules under `scripts/mock-data/`: - `utils.ts` — shared authentication, GraphQL client, and file writer - `generate-metadata.ts` — fetches object metadata from `/metadata` - `generate-record-data.ts` — fetches record data from `/graphql` using metadata-driven dynamic queries - The orchestrator (`generate-mock-data.ts`) authenticates once and passes the token to both generators - Company records are now fetched from the actual server (limited to 10 records) instead of being handcrafted - Generated files are organized under `generated/metadata/objects/` and `generated/data/companies/` ### Unified test utilities - Consolidated Jest and MSW mocking into shared utilities that compose production code (`prefillRecord`, `getRecordNodeFromRecord`, `getRecordConnectionFromRecords`) with mock metadata - Renamed `generateEmptyJestRecordNode` → `generateMockRecordNode` and moved to `testing/utils/` - Extracted `generateMockRecordConnection` into its own file - Removed `sanitizeInputForPrefill` workaround (no longer needed with correctly shaped generated data) |
||
|
|
2f0103faa5 |
OAuth Client - Add OAuth propagator (#18266)
For OAuth Server without wildcard redirect URL https://www.benanderson.co.uk/2023/07/28/dynamic-redirect-uris-oauth/ |
||
|
|
08bfbfda45 |
Bump @emotion/styled from 11.13.0 to 11.14.1 (#18253)
Bumps [@emotion/styled](https://github.com/emotion-js/emotion) from 11.13.0 to 11.14.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/emotion-js/emotion/releases"><code>@emotion/styled</code>'s releases</a>.</em></p> <blockquote> <h2><code>@emotion/styled</code><a href="https://github.com/11"><code>@11</code></a>.14.1</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/emotion-js/emotion/pull/3334">#3334</a> <a href="https://github.com/emotion-js/emotion/commit/0facbe47bd9099ae4ed22dc201822d910ac3dec5"><code>0facbe4</code></a> Thanks <a href="https://github.com/ZachRiegel"><code>@ZachRiegel</code></a>! - Renamed default-exported variable in <code>@emotion/styled</code> to aid inferred import names in auto-import completions in IDEs</li> </ul> <h2><code>@emotion/styled</code><a href="https://github.com/11"><code>@11</code></a>.14.0</h2> <h3>Minor Changes</h3> <ul> <li><a href="https://redirect.github.com/emotion-js/emotion/pull/3284">#3284</a> <a href="https://github.com/emotion-js/emotion/commit/a19d019bd418ebc3b9cba0e58f58b36ac2862a42"><code>a19d019</code></a> Thanks <a href="https://github.com/Andarist"><code>@Andarist</code></a>! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.</li> </ul> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/emotion-js/emotion/commit/e1bf17ee87ec51da1412eb5291460ea95a39d27a"><code>e1bf17e</code></a>]: <ul> <li><code>@emotion/use-insertion-effect-with-fallbacks</code><a href="https://github.com/1"><code>@1</code></a>.2.0</li> </ul> </li> </ul> <h2><code>@emotion/styled</code><a href="https://github.com/11"><code>@11</code></a>.13.5</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/emotion-js/emotion/pull/3270">#3270</a> <a href="https://github.com/emotion-js/emotion/commit/77d930dc708015ff6fd34a1084bb343b02d732fa"><code>77d930d</code></a> Thanks <a href="https://github.com/emmatown"><code>@emmatown</code></a>! - Fix inconsistent hashes using development vs production bundles/<code>exports</code> conditions when using <code>@emotion/babel-plugin</code> with <code>sourceMap: true</code> (the default). This is particularly visible when using Emotion with the Next.js Pages router where the <code>development</code> condition is used when bundling code but not when importing external code with Node.js.</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/emotion-js/emotion/commit/77d930dc708015ff6fd34a1084bb343b02d732fa"><code>77d930d</code></a>]:</p> <ul> <li><code>@emotion/serialize</code><a href="https://github.com/1"><code>@1</code></a>.3.3</li> <li><code>@emotion/utils</code><a href="https://github.com/1"><code>@1</code></a>.4.2</li> <li><code>@emotion/babel-plugin</code><a href="https://github.com/11"><code>@11</code></a>.13.5</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/emotion-js/emotion/commit/49229553967b6050c92d9602eb577bdc48167e91"><code>4922955</code></a> Version Packages (<a href="https://redirect.github.com/emotion-js/emotion/issues/3335">#3335</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/0facbe47bd9099ae4ed22dc201822d910ac3dec5"><code>0facbe4</code></a> Renamed default-exported variable in <code>@emotion/styled</code> to aid inferred import...</li> <li><a href="https://github.com/emotion-js/emotion/commit/cce67ec6b2fc94261028b4f4778aae8c3d6c5fd6"><code>cce67ec</code></a> Bump parcel (<a href="https://redirect.github.com/emotion-js/emotion/issues/3258">#3258</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/3c19ce5997f73960679e546af47801205631dfde"><code>3c19ce5</code></a> Version Packages (<a href="https://redirect.github.com/emotion-js/emotion/issues/3280">#3280</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/a19d019bd418ebc3b9cba0e58f58b36ac2862a42"><code>a19d019</code></a> Convert <code>@emotion/styled</code>'s source code to TypeScript (<a href="https://redirect.github.com/emotion-js/emotion/issues/3284">#3284</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/5974e33fcb5e7aee177408684ac6fe8b38b3e353"><code>5974e33</code></a> Fix JSX namespace <a href="https://github.com/ts-ignores"><code>@ts-ignores</code></a> (<a href="https://redirect.github.com/emotion-js/emotion/issues/3282">#3282</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/fc4d7bd744c205f55513dcd4e4e5134198c219de"><code>fc4d7bd</code></a> Convert <code>@emotion/react</code>'s source code to TypeScript (<a href="https://redirect.github.com/emotion-js/emotion/issues/3281">#3281</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/8dc1a6dd19d2dc9ce435ef0aff85ccf5647f5d2e"><code>8dc1a6d</code></a> Convert <code>@emotion/cache</code>'s source code to TypeScript (<a href="https://redirect.github.com/emotion-js/emotion/issues/3277">#3277</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/282b61d2ad4e39ea65af88351a894a903c2d42c4"><code>282b61d</code></a> Convert <code>@emotion/css-prettifier</code>'s source code to TypeScript (<a href="https://redirect.github.com/emotion-js/emotion/issues/3278">#3278</a>)</li> <li><a href="https://github.com/emotion-js/emotion/commit/e1bf17ee87ec51da1412eb5291460ea95a39d27a"><code>e1bf17e</code></a> Convert <code>@emotion/use-insertion-effect-with-fallbacks</code>'s source code to TypeS...</li> <li>Additional commits viewable in <a href="https://github.com/emotion-js/emotion/compare/@emotion/styled@11.13.0...@emotion/styled@11.14.1">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
c025a0c2b8 |
Add events and properties to video, audio and iFrame (#18257)
- Add media-specific events - Extend `iFrame` with missing properties - Enrich `SerializedEventData` with media-related target fields so serialized events carry the media element state. - Refactor the `remote-elements` code generator to support per-element custom events |
||
|
|
5e19361494 |
Allow uuidv5 for universal identifier (#18265)
Twenty apps are using v5 |
||
|
|
f11d76d6cf |
Bump @babel/preset-react from 7.26.3 to 7.28.5 (#18254)
Bumps [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) from 7.26.3 to 7.28.5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/babel/babel/releases"><code>@babel/preset-react</code>'s releases</a>.</em></p> <blockquote> <h2>v7.28.5 (2025-10-23)</h2> <p>Thank you <a href="https://github.com/CO0Ki3"><code>@CO0Ki3</code></a>, <a href="https://github.com/Olexandr88"><code>@Olexandr88</code></a>, and <a href="https://github.com/youthfulhps"><code>@youthfulhps</code></a> for your first PRs!</p> <h4>👓 Spec Compliance</h4> <ul> <li><code>babel-parser</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17446">#17446</a> Allow <code>Runtime Errors for Function Call Assignment Targets</code> (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> <li><code>babel-helper-validator-identifier</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17501">#17501</a> fix: update identifier to unicode 17 (<a href="https://github.com/fisker"><code>@fisker</code></a>)</li> </ul> </li> </ul> <h4>🐛 Bug Fix</h4> <ul> <li><code>babel-plugin-proposal-destructuring-private</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17534">#17534</a> Allow mixing private destructuring and rest (<a href="https://github.com/CO0Ki3"><code>@CO0Ki3</code></a>)</li> </ul> </li> <li><code>babel-parser</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17521">#17521</a> Improve <code>@babel/parser</code> error typing (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> <li><a href="https://redirect.github.com/babel/babel/pull/17491">#17491</a> fix: improve ts-only declaration parsing (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> <li><code>babel-plugin-proposal-discard-binding</code>, <code>babel-plugin-transform-destructuring</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17519">#17519</a> fix: <code>rest</code> correctly returns plain array (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> <li><code>babel-helper-create-class-features-plugin</code>, <code>babel-helper-member-expression-to-functions</code>, <code>babel-plugin-transform-block-scoping</code>, <code>babel-plugin-transform-optional-chaining</code>, <code>babel-traverse</code>, <code>babel-types</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17503">#17503</a> Fix <code>JSXIdentifier</code> handling in <code>isReferencedIdentifier</code> (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> <li><code>babel-traverse</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17504">#17504</a> fix: ensure scope.push register in anonymous fn (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> </ul> <h4>🏠 Internal</h4> <ul> <li><code>babel-types</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17494">#17494</a> Type checking babel-types scripts (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> </ul> <h4>🏃♀️ Performance</h4> <ul> <li><code>babel-core</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17490">#17490</a> Faster finding of locations in <code>buildCodeFrameError</code> (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> </ul> <h4>Committers: 8</h4> <ul> <li>Babel Bot (<a href="https://github.com/babel-bot"><code>@babel-bot</code></a>)</li> <li>Byeongho Yoo (<a href="https://github.com/youthfulhps"><code>@youthfulhps</code></a>)</li> <li>Huáng Jùnliàng (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> <li>Hyeon Dokko (<a href="https://github.com/CO0Ki3"><code>@CO0Ki3</code></a>)</li> <li>Nicolò Ribaudo (<a href="https://github.com/nicolo-ribaudo"><code>@nicolo-ribaudo</code></a>)</li> <li><a href="https://github.com/Olexandr88"><code>@Olexandr88</code></a></li> <li><a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a></li> <li>fisker Cheung (<a href="https://github.com/fisker"><code>@fisker</code></a>)</li> </ul> <h2>v7.28.4 (2025-09-05)</h2> <p>Thanks <a href="https://github.com/gwillen"><code>@gwillen</code></a> and <a href="https://github.com/mrginglymus"><code>@mrginglymus</code></a> for your first PRs!</p> <h4>🏠 Internal</h4> <ul> <li><code>babel-core</code>, <code>babel-helper-check-duplicate-nodes</code>, <code>babel-traverse</code>, <code>babel-types</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17493">#17493</a> Update Jest to v30.1.1 (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> <li><code>babel-plugin-transform-regenerator</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17455">#17455</a> chore: Clean up <code>transform-regenerator</code> (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/babel/babel/blob/main/CHANGELOG.md"><code>@babel/preset-react</code>'s changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <blockquote> <p><strong>Tags:</strong></p> <ul> <li>💥 [Breaking Change]</li> <li>👓 [Spec Compliance]</li> <li>🚀 [New Feature]</li> <li>🐛 [Bug Fix]</li> <li>📝 [Documentation]</li> <li>🏠 [Internal]</li> <li>💅 [Polish]</li> </ul> </blockquote> <p><em>Note: Gaps between patch versions are faulty, broken or test releases.</em></p> <p>This file contains the changelog starting from v8.0.0-alpha.0.</p> <ul> <li>See <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v7.15.0-v7.28.5.md">CHANGELOG - v7.15.0 to v7.28.5</a> for v7.15.0 to v7.28.5 changes (the last common release between the v8 and v7 release lines was v7.28.5).</li> <li>See <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v7.0.0-v7.14.9.md">CHANGELOG - v7.0.0 to v7.14.9</a> for v7.0.0 to v7.14.9 changes.</li> <li>See <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v7-prereleases.md">CHANGELOG - v7 prereleases</a> for v7.0.0-alpha.1 to v7.0.0-rc.4 changes.</li> <li>See <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v4.md">CHANGELOG - v4</a>, <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v5.md">CHANGELOG - v5</a>, and <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-v6.md">CHANGELOG - v6</a> for v4.x-v6.x changes.</li> <li>See <a href="https://github.com/babel/babel/blob/main/.github/CHANGELOG-6to5.md">CHANGELOG - 6to5</a> for the pre-4.0.0 version changelog.</li> <li>See <a href="https://github.com/babel/babel/blob/main/packages/babel-parser/CHANGELOG.md">Babylon's CHANGELOG</a> for the Babylon pre-7.0.0-beta.29 version changelog.</li> <li>See <a href="https://github.com/babel/babel-eslint/releases"><code>babel-eslint</code>'s releases</a> for the changelog before <code>@babel/eslint-parser</code> 7.8.0.</li> <li>See <a href="https://github.com/babel/eslint-plugin-babel/releases"><code>eslint-plugin-babel</code>'s releases</a> for the changelog before <code>@babel/eslint-plugin</code> 7.8.0.</li> </ul> <!-- raw HTML omitted --> <!-- raw HTML omitted --> <h2>v8.0.0-rc.2 (2026-02-15)</h2> <h4>💥 Breaking Change</h4> <ul> <li>Other <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17766">#17766</a> Remove unused code for old ESLint versions (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> <li><code>babel-code-frame</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17772">#17772</a> Remove deprecated default export from <code>@babel/code-frame</code> (<a href="https://github.com/fisker"><code>@fisker</code></a>)</li> </ul> </li> </ul> <h4>🐛 Bug Fix</h4> <ul> <li><code>babel-helpers</code>, <code>babel-plugin-transform-async-generator-functions</code>, <code>babel-runtime-corejs3</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17797">#17797</a> fix: Properly handle <code>await</code> in <code>finally</code> (<a href="https://github.com/liuxingbaoyu"><code>@liuxingbaoyu</code></a>)</li> </ul> </li> <li><code>babel-parser</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17796">#17796</a> Support ESLint 10 (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> <li><code>babel-preset-env</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17787">#17787</a> Fix: preset-env include/exclude should accept bugfix plugins (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> <li><code>babel-generator</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17781">#17781</a> fix: preserve trailing comma in optional call args (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> <li><a href="https://redirect.github.com/babel/babel/pull/17774">#17774</a> Fix <code>undefined</code> indentation when exactly 64 indents (<a href="https://github.com/YoussefHenna"><code>@YoussefHenna</code></a>)</li> </ul> </li> <li><code>babel-standalone</code> <ul> <li><a href="https://redirect.github.com/babel/babel/pull/17770">#17770</a> fix: ensure <code>targets.esmodules</code> is validated (<a href="https://github.com/JLHwung"><code>@JLHwung</code></a>)</li> </ul> </li> </ul> <h4>💅 Polish</h4> <ul> <li><code>babel-core</code></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/babel/babel/commit/61647ae2397c82c3c71f077b5ab109106a5cac0f"><code>61647ae</code></a> v7.28.5</li> <li><a href="https://github.com/babel/babel/commit/42cb285b59fc99a8102d69bef6223b75617e9f46"><code>42cb285</code></a> Improve <code>@babel/core</code> types (<a href="https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react/issues/17404">#17404</a>)</li> <li><a href="https://github.com/babel/babel/commit/eebd3a06021c13d335b5b0bd79734df3abbea678"><code>eebd3a0</code></a> v7.27.1</li> <li><a href="https://github.com/babel/babel/commit/fdc0fb59e119ee0b38bced63867a344a5b4bc2f3"><code>fdc0fb5</code></a> [Babel 8] Bump nodejs requirements to <code>^20.19.0 || >= 22.12.0</code> (<a href="https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react/issues/17204">#17204</a>)</li> <li><a href="https://github.com/babel/babel/commit/cd24cc07ef6558b7f6510f9177f6393c91b0549f"><code>cd24cc0</code></a> chore: Update TS 5.7 (<a href="https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react/issues/17053">#17053</a>)</li> <li>See full diff in <a href="https://github.com/babel/babel/commits/v7.28.5/packages/babel-preset-react">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by [GitHub Actions](<a href="https://www.npmjs.com/~GitHub">https://www.npmjs.com/~GitHub</a> Actions), a new releaser for <code>@babel/preset-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> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
3aedce9af7 | Fix remaining non v4 uuid universal identifier (#18263) | ||
|
|
8e8ecfb8a3 |
Bump @sentry/react from 10.27.0 to 10.40.0 (#18252)
Bumps [@sentry/react](https://github.com/getsentry/sentry-javascript) from 10.27.0 to 10.40.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/getsentry/sentry-javascript/releases"><code>@sentry/react</code>'s releases</a>.</em></p> <blockquote> <h2>10.40.0</h2> <h3>Important Changes</h3> <ul> <li> <p><strong>feat(tanstackstart-react): Add global sentry exception middlewares (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19330">#19330</a>)</strong></p> <p>The <code>sentryGlobalRequestMiddleware</code> and <code>sentryGlobalFunctionMiddleware</code> global middlewares capture unhandled exceptions thrown in TanStack Start API routes and server functions. Add them as the first entries in the <code>requestMiddleware</code> and <code>functionMiddleware</code> arrays of <code>createStart()</code>:</p> <pre lang="ts"><code>import { createStart } from '@tanstack/react-start/server'; import { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from '@sentry/tanstackstart-react'; <p>export default createStart({ requestMiddleware: [sentryGlobalRequestMiddleware, myRequestMiddleware], functionMiddleware: [sentryGlobalFunctionMiddleware, myFunctionMiddleware], }); </code></pre></p> </li> <li> <p><strong>feat(tanstackstart-react)!: Export Vite plugin from <code>@sentry/tanstackstart-react/vite</code> subpath (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19182">#19182</a>)</strong></p> <p>The <code>sentryTanstackStart</code> Vite plugin is now exported from a dedicated subpath. Update your import:</p> <pre lang="diff"><code>- import { sentryTanstackStart } from '@sentry/tanstackstart-react'; + import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite'; </code></pre> </li> <li> <p><strong>fix(node-core): Reduce bundle size by removing apm-js-collab and requiring pino >= 9.10 (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/18631">#18631</a>)</strong></p> <p>In order to keep receiving pino logs, you need to update your pino version to >= 9.10, the reason for the support bump is to reduce the bundle size of the node-core SDK in frameworks that cannot tree-shake the apm-js-collab dependency.</p> </li> <li> <p><strong>fix(browser): Ensure user id is consistently added to sessions (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19341">#19341</a>)</strong></p> <p>Previously, the SDK inconsistently set the user id on sessions, meaning sessions were often lacking proper coupling to the user set for example via <code>Sentry.setUser()</code>. Additionally, the SDK incorrectly skipped starting a new session for the first soft navigation after the pageload. This patch fixes these issues. As a result, metrics around sessions, like "Crash Free Sessions" or "Crash Free Users" might change. This could also trigger alerts, depending on your set thresholds and conditions. We apologize for any inconvenience caused!</p> <p>While we're at it, if you're using Sentry in a Single Page App or meta framework, you might want to give the new <code>'page'</code> session lifecycle a try! This new mode no longer creates a session per soft navigation but continues the initial session until the next hard page refresh. Check out the <a href="https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/browsersession/">docs</a> to learn more!</p> </li> <li> <p><strong>ref!(gatsby): Drop Gatsby v2 support (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19467">#19467</a>)</strong></p> <p>We drop support for Gatsby v2 (which still relies on webpack 4) for a critical security update in <a href="https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0">https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0</a></p> </li> </ul> <h3>Other Changes</h3> <ul> <li>feat(astro): Add support for Astro on CF Workers (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19265">#19265</a>)</li> <li>feat(cloudflare): Instrument async KV API (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19404">#19404</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md"><code>@sentry/react</code>'s changelog</a>.</em></p> <blockquote> <h2>10.40.0</h2> <h3>Important Changes</h3> <ul> <li> <p><strong>feat(tanstackstart-react): Add global sentry exception middlewares (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19330">#19330</a>)</strong></p> <p>The <code>sentryGlobalRequestMiddleware</code> and <code>sentryGlobalFunctionMiddleware</code> global middlewares capture unhandled exceptions thrown in TanStack Start API routes and server functions. Add them as the first entries in the <code>requestMiddleware</code> and <code>functionMiddleware</code> arrays of <code>createStart()</code>:</p> <pre lang="ts"><code>import { createStart } from '@tanstack/react-start/server'; import { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from '@sentry/tanstackstart-react/server'; <p>export default createStart({ requestMiddleware: [sentryGlobalRequestMiddleware, myRequestMiddleware], functionMiddleware: [sentryGlobalFunctionMiddleware, myFunctionMiddleware], }); </code></pre></p> </li> <li> <p><strong>feat(tanstackstart-react)!: Export Vite plugin from <code>@sentry/tanstackstart-react/vite</code> subpath (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19182">#19182</a>)</strong></p> <p>The <code>sentryTanstackStart</code> Vite plugin is now exported from a dedicated subpath. Update your import:</p> <pre lang="diff"><code>- import { sentryTanstackStart } from '@sentry/tanstackstart-react'; + import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite'; </code></pre> </li> <li> <p><strong>fix(node-core): Reduce bundle size by removing apm-js-collab and requiring pino >= 9.10 (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/18631">#18631</a>)</strong></p> <p>In order to keep receiving pino logs, you need to update your pino version to >= 9.10, the reason for the support bump is to reduce the bundle size of the node-core SDK in frameworks that cannot tree-shake the apm-js-collab dependency.</p> </li> <li> <p><strong>fix(browser): Ensure user id is consistently added to sessions (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19341">#19341</a>)</strong></p> <p>Previously, the SDK inconsistently set the user id on sessions, meaning sessions were often lacking proper coupling to the user set for example via <code>Sentry.setUser()</code>. Additionally, the SDK incorrectly skipped starting a new session for the first soft navigation after the pageload. This patch fixes these issues. As a result, metrics around sessions, like "Crash Free Sessions" or "Crash Free Users" might change. This could also trigger alerts, depending on your set thresholds and conditions. We apologize for any inconvenience caused!</p> <p>While we're at it, if you're using Sentry in a Single Page App or meta framework, you might want to give the new <code>'page'</code> session lifecycle a try! This new mode no longer creates a session per soft navigation but continues the initial session until the next hard page refresh. Check out the <a href="https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/browsersession/">docs</a> to learn more!</p> </li> <li> <p><strong>ref!(gatsby): Drop Gatsby v2 support (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19467">#19467</a>)</strong></p> <p>We drop support for Gatsby v2 (which still relies on webpack 4) for a critical security update in <a href="https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0">https://github.com/getsentry/sentry-javascript-bundler-plugins/releases/tag/5.0.0</a></p> </li> </ul> <h3>Other Changes</h3> <ul> <li>feat(astro): Add support for Astro on CF Workers (<a href="https://redirect.github.com/getsentry/sentry-javascript/pull/19265">#19265</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/getsentry/sentry-javascript/commit/663fd5e7e3c1808d4a636f001d768845f167668e"><code>663fd5e</code></a> Increase bundler-tests timeout to 30s</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/8033ea380f0526cc863c6d50347fd5747ae5df32"><code>8033ea3</code></a> release: 10.40.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/eb3c4d2489a77753377f7e3a320f18cd853ebf6a"><code>eb3c4d2</code></a> Merge pull request <a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19488">#19488</a> from getsentry/prepare-release/10.40.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/9a10630c6b7524d053b96cfaafa14751b0611f33"><code>9a10630</code></a> meta(changelog): Update changelog for 10.40.0</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/39d1ef77849223f7742999c808f7f23da0c42adf"><code>39d1ef7</code></a> fix(deps): Bump to latest version of each minimatch major (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19486">#19486</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/e8ed6d262f7f43cef8b04265794db83ab013f95c"><code>e8ed6d2</code></a> test(nextjs): Deactivate canary test for cf-workers (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19483">#19483</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/6eb320eb3e01985720238c8f08e3ac114502059b"><code>6eb320e</code></a> chore(deps): Bump Sentry CLI to latest v2 (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19477">#19477</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/8fc81d2cd4048fb41b49e773d4829d9fb799f16c"><code>8fc81d2</code></a> fix: Bump bundler plugins to v5 (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19468">#19468</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/365f7fab4e33d69363d4eb6d99e5f87e48672fba"><code>365f7fa</code></a> chore(ci): Adapt max turns of triage issue agent (<a href="https://redirect.github.com/getsentry/sentry-javascript/issues/19473">#19473</a>)</li> <li><a href="https://github.com/getsentry/sentry-javascript/commit/11e5412d42f6126e5415d67d1418ffdb17f5caa6"><code>11e5412</code></a> feat(tanstackstart-react)!: Export Vite plugin from <code>@sentry/tanstackstart-rea</code>...</li> <li>Additional commits viewable in <a href="https://github.com/getsentry/sentry-javascript/compare/10.27.0...10.40.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
120096346a |
Add define post isntall logic function (#18248)
As title |
||
|
|
fde8168a85 | Centralized universal identifier validation on create (#18258) | ||
|
|
2674589b44 |
Remove any recoil reference from project (#18250)
## Remove all Recoil references and replace with Jotai ### Summary - Removed every occurrence of Recoil from the entire codebase, replacing with Jotai equivalents where applicable - Updated `README.md` tech stack: `Recoil` → `Jotai` - Rewrote documentation code examples to use `createAtomState`/`useAtomState` instead of `atom`/`useRecoilState`, and removed `RecoilRoot` wrappers - Cleaned up source code comment and Cursor rules that referenced Recoil - Applied changes across all 13 locale translations (ar, cs, de, es, fr, it, ja, ko, pt, ro, ru, tr, zh) |