## What
`SettingsAiMCP` is dead code — nothing imports or renders it. The
redesign moved MCP setup to the **APIs & Webhooks** page
(`SettingsMcpSetup`, on the MCP tab), and the AI settings page now
**deep-links** there (`ApiWebhooks#mcp`) instead of rendering this
component.
Removes the orphaned component and its two cover SVGs:
- `src/pages/settings/ai/components/SettingsAiMCP.tsx`
- `public/images/ai/ai-mcp-cover-{light,dark}.svg`
## Notes
- Verified nothing references the component or the SVGs in source (only
stale `.po` source-reference comments remain, which `lingui` extraction
reconciles separately — not hand-edited here).
- The hero on the APIs & Webhooks page (incl. its MCP tab) is
unaffected; that's the `playground/cover` image.
## What
The settings discovery hero images (AI, Applications, Page Layouts,
Members, Data Model, APIs & Webhooks) baked the rounded border into the
pixels — transparent rounded corners plus a 1px edge stroke. Rendered
inside `Card rounded` — which already draws a 1px border + border-radius
and clips children with `overflow: hidden` — this produced a doubled,
slightly misaligned border.
This replaces all 12 files (light + dark per section) with clean
full-bleed exports (opaque square corners), so the border and rounding
come entirely from CSS.
## Notes
- Pure asset swap, no component changes.
- The MCP section's `.svg` cover is untouched (no new export provided).
Billing's unused cover is left as-is.
## Verification
- Each new image confirmed 1388×300, opaque square corners (no baked
border), correct light/dark variant.
- `Card` (twenty-ui) provides `border` + `border-radius` + `overflow:
hidden`, so the square images are clipped to the rounded card.
## Summary
Round through bosiraphael's 31 review threads on the merged PR #21072
(discovery hero + ephemeral playground token). The user asked to apply
each suggestion only where it adds value, so this PR is split into three
buckets.
### Comments (~17 threads)
- Tightened security-rationale / CSS-gotcha / API-doc comments to one or
two factual lines
- Kept (shortened) the comments above `RequireAccessTokenGuard` call
sites — without them a future reader could remove the guard and silently
reopen the escalation hole
- Kept (shortened) the in-memory-only rationale on
`playgroundApiKeyState` for the same reason
- Kept `flex: 1 + min-height: 0` CSS gotcha on `SubMenuTopBarContainer`
— non-obvious and easy to break
### Structure / extraction
- Move `WEBHOOK_TABLE_ROW_GRID_TEMPLATE_COLUMNS` to its own constants
file (one-export-per-file)
- Split `SettingsAgentToolsTab` and `SettingsAgentToolsTable` across
queries/, hooks/, types/, utils/:
- `graphql/queries/findManyApplicationsForToolTable.ts`
- `graphql/queries/findManyMarketplaceAppsForToolTable.ts`
- `hooks/useSettingsAgentToolsTable.ts` (data loading + index merging)
- `types/SettingsAgentToolItem|Application|MarketplaceApp`
- `utils/getToolApplicationId|getToolLink`
- Extract `SettingsAiModelsTab` optimistic mutations into
`hooks/useSettingsAiModelsActions` (handleModelFieldChange,
handleUseRecommendedToggle, handleModelToggle,
handleToggleAllVisibleModels)
- Extract `SettingsAI.handleCreateTool` into `hooks/useCreateTool`
- Drop unnecessary `useMemo` wrappers on `heroTabs` arrays
(SettingsObjects, SettingsLayout)
- Simplify `MenuItemToggle` handler in SettingsAgentSkillsTab:
`onToggleChange={setShowDeactivated}` (no longer wrapping with arrow +
read of stale `!showDeactivated`)
### Hero assets
- Replace placeholder `customize-illustration` with per-page exports
- Rename `layout/customize-illustration-{light,dark}.png` →
`layout/cover-{light,dark}.png`
- Add `cover-{light,dark}.png` for **applications** and **members**
(they were both pointing at the layout placeholder as a TODO)
- Overwrite `data-model/cover-*.png`, `playground/cover-*.png`,
`ai/ai-tools-cover-*.png` with the new exports
## Test plan
- [ ] `npx nx typecheck twenty-front` ✅
- [ ] `npx nx typecheck twenty-server` ✅
- [ ] `npx nx lint twenty-front` ✅ (oxlint + oxfmt, 0 warnings/errors)
- [ ] `/settings/layout`, `/settings/data-model`,
`/settings/applications`, `/settings/ai`, `/settings/api-webhooks`,
`/settings/members` each render the new hero illustration (light + dark)
- [ ] AI tab: tool list still loads, search + Custom/Managed/Standard
filters still work, "New Tool" still navigates to detail
- [ ] AI tab: Models tab — smart/fast model select, "Use best models
only" toggle, per-model checkboxes, toggle-all all still
optimistic+revert on error
- [ ] Skills tab: "Deactivated" toggle still flips show/hide
- [ ] Webhooks table still uses the 1fr 28px grid
## Summary
Updates the OAuth consent screen to match the provided modal treatment,
including the header artwork, app-to-Twenty logo layout, scope icons,
and a content-hugging title that stays on one line until its max width.
Also preserves `returnToPath` through Google and Microsoft social SSO so
users who sign in from `/authorize` return to the OAuth consent flow
with the original OAuth query parameters intact.
## Reference

## Validation
- `yarn nx test twenty-front
--testFile=src/modules/auth/hooks/__tests__/useAuth.test.tsx
--coverage=false`
- `yarn nx test twenty-server
--testFile=src/engine/core-modules/auth/services/auth.service.spec.ts
--coverage=false`
- `yarn nx typecheck twenty-front`
- `yarn nx typecheck twenty-server`
- `git diff --check`
## Notes
The reference screenshot is linked from a separate branch-hosted image
commit so it renders in the PR body without adding that screenshot to
the product diff.
Co-authored-by: Charles Bochet <charles@twenty.com>
## Setup
This PR can be tested only if some feature flags have specific values:
- `IsWorkflowEnabled` equals `true`
- `IsQueryRunnerTwentyORMEnabled` equals `false`
These feature flags weren't committed to don't break other branches.
## What this PR brings
- Display buttons to activate and deactivate a workflow version and a
button to discard the current draft version. I also scaffolded a "Test"
button, which doesn't do anything for now.
- Wired the activate, deactivate and discard draft buttons to the
backend.
- Made it possible to "edit" active and deactivated versions by
automatically creating a new draft version when the user tries to edit
the version.
- Hide the "Discard Draft", button if the current version is not a draft
or is the first version ever created.
- On the backend, don't consider discarded drafts when checking if a new
draft version can be created.
- On the backend, disallow deleting the first created workflow version.
Otherwise, we will end up with a blank canvas in the front end, and it
will be impossible to recover from it.
- On the backend, disallow running deactivation steps if the workflow
version is not currently active. Previously, we were throwing, which is
unnecessary as it's a valid case.
## Spotted bugs that we must dive into
### Duplicate workflow versions in Apollo cache
https://github.com/user-attachments/assets/7cfffd06-11e0-417a-8da0-f9a5f43b84e2
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
Split from https://github.com/twentyhq/twenty/pull/4518
Related to #4766
Mutualizes eslint config between projects.
I didn't include `twenty-server` in this PR as this was causing too many
lint errors.