## What
Upgrades the internal `self-hosting` app to the latest Twenty CLI
tooling, bringing it in line with the other actively-maintained apps in
the monorepo.
- `twenty-sdk`: `2.19.0-alpha.1` → `2.23.0-alpha.2` (dependency +
devDependency)
- `twenty-client-sdk`: `2.19.0-alpha.1` → `2.23.0-alpha.2` (dependency +
devDependency)
- `engines.twenty`: `>=2.19.0` → `>=2.23.0`
- Regenerated `yarn.lock` to match.
The `twenty` CLI ships inside `twenty-sdk`, so this pulls the app onto
the same CLI version every other recently-updated app (call-recorder,
people-data-labs, twenty-partners, real-estate, last-contact, postcard)
already uses.
## Verification
- `yarn typecheck` passes
- `yarn lint` passes (0 warnings, 0 errors)
- `yarn test:unit` passes (3/3)
Integration tests (`yarn test`) require a running Twenty server and were
not run in this environment.
## Notes
Scope is limited to the CLI/SDK tooling. Framework deps (React 18) were
left untouched since they are not tied to the CLI version and vary
across apps.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01HUPkxerLhethaP9Lw6qDyd)_
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23279?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## Summary
- Bumps `twenty-sdk` / `twenty-client-sdk` to the exact `2.19.0-alpha.1`
prerelease for the apps under `packages/twenty-apps` that actually
target a mutated standard identifier, and refreshes their lockfiles.
- Declares `"engines": { "twenty": ">=2.19.0" }` in those apps so
pre-2.19 servers refuse to install or upgrade to the rebuilt packages.
Only apps that reference a standard object's **system-field** universal
identifier, define a **relation into** a standard object, or call the
field-UID derivation helper need 2.19 (the identifiers those touch
changed from hardcoded UUIDs to deterministic hashes). Apps that only
define their own custom objects, or add plain scalar fields to a
standard object via its stable object-level id, were left on their prior
SDK pins. Currently bumped: `postcard`, `self-hosting`,
`twenty-partners`, `call-recorder`, `people-data-labs`,
`twenty-last-contact`.
## Context
Follow-up to #22565 (deterministic system field universal identifiers)
and #22599 (SDK prerelease bump).
Packages built with SDK ≤ 2.18 carry legacy system field identifiers and
are rejected by servers running `main`. Rebuilding with the 2.19 SDK
fixes that — but a rebuilt package must not be *upgraded into* by a 2.18
server, since 2.18 has no deterministic-identifier validation and would
diff the changed system field identifiers as a destructive delete +
create (the 2.19 backfill has not run there yet).
The `engines.twenty` constraint closes that gap: `doInstallApplication`
validates it via `validateServerCompatibility` before any mutation, and
this check has shipped since ~2.10, so every 2.18 server enforces it.
Resulting matrix:
- 2.18 fresh install of a rebuilt app: works, converges as a no-op once
the 2.19 backfill runs
- 2.18 upgrade of an existing install: rejected with
`SERVER_VERSION_INCOMPATIBLE` before any mutation
- 2.19 (post-backfill) install/upgrade: syncs cleanly
## Expected CI failures
**The `CI Twenty Apps` integration-test jobs are expected to fail on
this PR** (e.g. `people-data-labs`, `twenty-partners`). This is a
server-version mismatch, not an app bug — lint, typecheck and unit tests
all pass:
- The integration step spawns a real Twenty server from Docker Hub
`twentycrm/twenty-app-dev:latest` and runs `twenty dev` to sync each
app's metadata into it.
- `latest` currently resolves to **v2.18.5** — no `2.19` image is
published to Docker Hub yet.
- These apps now reference 2.19's **deterministic system-field universal
identifiers** (e.g. `company.createdBy`, `opportunity.createdAt`). A
2.18 server still carries the legacy identifiers, so the sync rejects
every 2.19-derived reference with `INVALID_VIEW_DATA` /
`FIELD_METADATA_NOT_FOUND` ("Field metadata not found").
- The failure surfaces as low-level field errors rather than a clean
`SERVER_VERSION_INCOMPATIBLE` because the `engines.twenty` gate
(`validateServerCompatibility`) only runs on the `app:install` / publish
paths — **not** on the `twenty dev` dev-sync path the integration tests
use.
These jobs will go green automatically once `twenty-app-dev:2.19` is
published to Docker Hub (or once CI pins the spawn action's
`twenty-version` to a 2.19 tag).
## Intentionally not included
- App `version` fields are untouched; they'll be bumped at publish time.
## Test plan
- [x] Refresh each bumped app's `yarn.lock` (`2.19.0-alpha.1` is now on
npm)
- [ ] Rebuild one app manifest and verify default field identifiers
match `getFieldUniversalIdentifier`
- [ ] Verify a 2.18 server rejects an upgrade to a rebuilt package with
`SERVER_VERSION_INCOMPATIBLE`
- [ ] Re-run `CI Twenty Apps` integration jobs once a
`twenty-app-dev:2.19` image is available
Made with [Cursor](https://cursor.com)
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22601?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## What
Bumps **all 14 `twenty-apps`** (internal, examples, community) to the
freshly published SDK **2.13.0**, and upgrades `vitest` 3 → 4 so `vite`
resolves to 8 (rolldown).
- `twenty-sdk` / `twenty-client-sdk`: `2.10.1` → `2.13.0` (each app's
original spec format preserved — plain, `^`, and `npm:…@`).
- `vitest`: `^3.x` → `^4.0.0` in the 13 apps that use it
(`call-recording` has no vitest).
## Why
Each app's `yarn.lock` had open Dependabot esbuild alerts — high
`GHSA-gv7w-rqvm-qjhr` and low `GHSA-g7r4-m6w7-qqqr`, both fixed in
esbuild `0.28.1`.
The SDK bump alone does **not** clear them: the advisories fire on *any*
esbuild `< 0.28.1`, and each app pulled a vulnerable `esbuild@0.27.7`
transitively via **vite** (through the `vitest` devDependency),
independent of the SDK. Bumping `vitest` to 4 resolves `vite@8`
(rolldown), which drops the esbuild dependency entirely.
`twenty-partners` additionally needed a recursive esbuild re-resolution
(its `tsx` dep had `esbuild@~0.28.0` pinned at the still-vulnerable
`0.28.0`).
After this change, **all 14 lockfiles resolve esbuild `0.28.1` only** —
zero copies `< 0.28.1`.
## Test
- All 14 lockfiles verified free of esbuild `< 0.28.1`.
- vitest 4 + vite 8 confirmed working: `people-data-labs` runs **334
tests across 83 files, all passing**.
- `twenty-for-twenty`'s suite fails only because its global setup
requires a live Twenty server (`/healthz`) — environmental, would fail
identically under vitest 3.
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21553?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
The match-telemetry-event-with-people logic function triggers on
selfHostingUser.* (both created and updated) and unconditionally wrote
personId back to the record on every run. Since the handler's own write
produces an updated event — and the telemetry webhook also updates
unrelated fields (name, serverUrl, etc.) on returning signups — the
matching logic re-ran unnecessarily, querying people and writing on each
pass.
This adds an early-return guard so the handler only does work when
there's actually something to match:
Skip when the selfHostingUser is already linked (personId set) and the
primary email hasn't changed.
Still (re)match on first link and on genuine email changes — the
legitimate reasons for listening on updated.
The guard reads before.email.primaryEmail via an 'before' in properties
narrowing so it stays type-safe across the create/update event union.
Resolves the **vitest Critical** Dependabot alerts
(`GHSA-5xrq-8626-4rwp`, vitest `< 3.2.6`) — #1422–#1433.
Each `packages/twenty-apps/*` project is an **independent yarn project**
with its own `package.json` + `yarn.lock` (not part of the root
workspace). 12 of them declared `vitest: ^3.1.1` and locked an older
3.2.x. This bumps the range to `^3.2.6` and refreshes each lockfile to
**3.2.6** (latest 3.x, published 2026-06-01).
Projects updated: `community/github-connector`,
`examples/{hello-world,postcard}`,
`internal/{exa,people-data-labs,self-hosting,twenty-discord,twenty-fireflies,twenty-for-twenty,twenty-linear,twenty-partners,twenty-slack}`.
- Dev-scope only (test runner); no runtime impact.
- The **root workspace already uses vitest 4.x** (≥ the fix) and is
intentionally untouched.
- Verified: no `vitest < 3.2.6` remains in any `twenty-apps` lockfile.
## What
The standalone apps under `packages/twenty-apps/*` each ship **their own
`yarn.lock`** (they're not part of the root workspace), and those
lockfiles still pulled vulnerable transitive versions of `axios`,
`undici`, `tmp`, `qs`, `ws`, `brace-expansion`, `uuid` (via `twenty-sdk`
/ `twenty-client-sdk`). This was ~130 of the open Dependabot alerts —
none of them reachable from the root-lockfile PRs.
Ran `yarn up -R` per app to re-resolve the vulnerable transitives within
their existing ranges, across all 13 flagged apps:
- **`axios` → 1.17.0** — clears the entire proxy-auth-leak / ReDoS /
config-merge MITM advisory set (the 56 axios alerts)
- **`qs`, `brace-expansion`, `uuid`** → patched
- **`undici`, `ws`** → patched on the in-range majors (older majors that
parents pin exactly remain, same situation as the root lockfile)
## Scope
- **Lockfile-only**, 13 apps. No `package.json` changes.
- Test **fixtures** (`packages/twenty-apps/fixtures/*`) intentionally
left untouched — Dependabot didn't flag them and they back snapshot
tests.
- 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>
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline
### Why
The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.
### How
- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.