Files
twenty/package.json
T
Paul Rastoin 24067ec87a chore: remove twenty-companion dead code (#23310)
## What

Removes `packages/twenty-companion` (package name `twenty-desktop`), the
Electron "Twenty Desktop" proof of concept that landed with the
Recall.ai call-recording work in #18281.

## Why it's dead code

- **Not in the nx graph** — no `project.json`, so no target ever runs
against it.
- **Not in CI** — no workflow references it. #21327 said as much when
bumping its Electron: "there's no CI job that builds/tests
twenty-companion, so this isn't exercised by CI".
- **No code references** — nothing imports it, and the only path
references were the root `workspaces` array, `yarn.lock`, and
`.vscode/twenty.code-workspace`. It talks to Twenty over the public REST
API from a separate process, so there is no coupling to remove.
- **Self-declared POC** — its README opens with "This application is a
Proof of Concept (POC) and must NOT be used in production. [...]
Security, stability, and performance have not been validated for
production use."
- **No feature work since it landed** (March 2026). Every commit
touching it since has been a dependency or tooling sweep: React 19
migration, ESLint→OxLint, npm→yarn workspaces, and four CVE bumps.
- **Docs already stale** — its README points at
`packages/twenty-apps/internal/call-recording`, which no longer exists.
The shipped app lives at `packages/twenty-apps/public/call-recorder` and
does not reference the desktop companion.

Meanwhile it pulled a full Electron + electron-forge toolchain into
every root install, and kept generating Dependabot noise against a tree
nothing builds.

## Changes

- Delete `packages/twenty-companion`.
- Drop its entry from root `workspaces` and from
`.vscode/twenty.code-workspace`.
- Drop four root `resolutions` that existed only to evict CVEs from the
Electron tree, along with their entries in the `//resolutions` rationale
doc:
  - `@electron/rebuild/tar`, `@electron/node-gyp/tar`
  - `@electron-forge/plugin-webpack/webpack-dev-server`
- `make-fetch-happen` — its only sub-`^15` consumer was the Electron
`node-gyp` fork; the remaining consumers (`@sigstore/sign`,
`npm-registry-fetch`, `tuf-js`) already declare `^15.x`
- Regenerate `yarn.lock`.

## Lockfile impact

469 descriptors removed, **zero version changes for any surviving
descriptor** (verified with a descriptor-level diff of old vs new
resolutions). Two descriptors show up as new —
`make-fetch-happen@npm:^15.0.1` and `@npm:^15.0.4` — only because the
global resolution was previously rewriting them; both still resolve to
`15.0.6`. Re-running resolution produces a byte-identical lockfile.

## Test plan

- [x] Repo-wide grep confirms no remaining references to
`twenty-companion` / `twenty-desktop` / the Electron toolchain.
- [x] `yarn install --mode=update-lockfile` is stable and idempotent
under hardened mode.
- [x] Descriptor-level lockfile diff shows no resolution changes outside
the removed tree.
- [ ] CI green (nothing targets the removed package, so the risk surface
is the lockfile).


---
_Generated by [Claude
Code](https://claude.ai/code/session_019NttPZiJWSJz56RW8pZ5jN)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23310?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. -->
2026-07-26 16:52:52 +00:00

109 lines
15 KiB
JSON

{
"private": true,
"devDependencies": {
"@nx/jest": "22.7.5",
"@nx/js": "22.7.5",
"@nx/react": "22.7.5",
"@nx/storybook": "22.7.5",
"@nx/vite": "22.7.5",
"@nx/web": "22.7.5",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@yarnpkg/types": "^4.0.0",
"concurrently": "^8.2.2",
"http-server": "^14.1.1",
"nx": "22.7.5",
"oxfmt": "0.50.0",
"tsx": "^4.17.0",
"verdaccio": "^6.3.1"
},
"engines": {
"node": "^24.5.0",
"npm": "please-use-yarn",
"yarn": ">=4.0.2"
},
"license": "AGPL-3.0",
"name": "twenty",
"packageManager": "yarn@4.13.0",
"resolutions": {
"@module-federation/dts-plugin/undici": "^7.28.0",
"nx/form-data": "4.0.6",
"zapier-platform-core/form-data": "4.0.6",
"@nestjs/platform-express/multer": "2.2.0",
"@nestjs/graphql/ws": "8.21.0",
"@remote-dom/react/@types/react": "^19.2.0",
"graphql": "16.8.1",
"graphql-redis-subscriptions/ioredis": "5.10.1",
"@types/qs": "6.9.16",
"@opentelemetry/api": "1.9.1",
"chokidar": "^3.6.0",
"tmp": "^0.2.7",
"@mintlify/previewing/tar": "npm:^7.5.16",
"@angular-devkit/core": "19.2.24",
"yeoman-environment": "6.0.1",
"express/qs": "6.15.2",
"@cypress/request/qs": "6.15.2",
"body-parser/qs": "6.15.2",
"next/postcss": "8.5.15",
"sockjs/uuid": "11.1.1",
"@cypress/request/uuid": "11.1.1",
"@ptc-org/nestjs-query-typeorm/uuid": "11.1.1",
"googleapis-common/uuid": "11.1.1",
"googleapis/googleapis-common": "8.0.1",
"@cyntler/react-doc-viewer/ajv": "8.20.0",
"@mintlify/cli/js-yaml": "4.3.0",
"@mintlify/common/js-yaml": "4.3.0",
"@mintlify/prebuild/js-yaml": "4.3.0",
"@mintlify/previewing/js-yaml": "4.3.0",
"@mintlify/scraping/js-yaml": "4.3.0",
"@mintlify/validation/js-yaml": "4.3.0",
"@verdaccio/config/js-yaml": "4.3.0",
"front-matter/js-yaml": "4.3.0",
"@istanbuljs/load-nyc-config/js-yaml": "4.3.0",
"@react-email/ui/esbuild": "0.28.1",
"react-email/esbuild": "0.28.1",
"@lingui/cli/esbuild": "0.28.1",
"@opennextjs/aws/esbuild": "0.28.1",
"storybook/esbuild": "0.28.1",
"zapier-platform-cli/esbuild": "0.28.1",
"front-matter@npm:4.0.2": "patch:front-matter@npm%3A4.0.2#~/.yarn/patches/front-matter-npm-4.0.2-e1cc0efa69.patch"
},
"//resolutions": "Each entry is load-bearing: it forces a version OUTSIDE some parent's declared range where no fixed upstream release exists; remove each once its blocker ships. @module-federation/dts-plugin/undici ^7.28.0 -> six undici advisories all fixed in 7.28.0: GHSA-pr7r-676h-xcf6 (shared-cache cross-user disclosure), GHSA-35p6-xmwp-9g52 (keep-alive response-queue poisoning), GHSA-p88m-4jfj-68fv (Set-Cookie percent-decode header injection) and GHSA-g8m3-5g58-fq7m (Set-Cookie SameSite downgrade) all >=7.0.0 <7.28.0, plus GHSA-hm92-r4w5-c3mj (SOCKS5 proxy-pool cross-origin routing) and GHSA-vmh5-mc38-953g (SOCKS5 ProxyAgent TLS-validation bypass) >=7.23.0 <7.28.0; @module-federation/dts-plugin@2.5.1 pins undici 7.24.7 exact (no caret) and is itself transitive (pinned by @module-federation/cli + enhanced) so no parent upgrade carries the fix; scoped to @module-federation/dts-plugin as the sole 7.24.7 pinner -- ^7.28.0 dedupes onto the 7.28.0 every other 7.x consumer already resolves (via ^7.25.0), and undici 6.27.0 (^6.25.0) is outside the advisories and left untouched; drop once @module-federation/dts-plugin depends on undici >=7.28.0. nx/form-data + zapier-platform-core/form-data 4.0.6 -> CVE-2026-12143 / GHSA-hmw2-7cc7-3qxx (form-data CRLF injection via unescaped multipart field names and filenames, vulnerable >=4.0.0 <4.0.6); nx 22.7.5 and zapier-platform-core 19.0.0 each hard-pin form-data 4.0.5 exact (no caret, both still 4.0.5 in their latest) so no parent upgrade carries the fix; scoped to those two as the sole 4.0.5 pinners -- every other form-data consumer resolves 4.0.6 naturally via its ^4.0.x range, so both pins dedupe onto it; drop once nx and zapier-platform-core depend on form-data >=4.0.6. @nestjs/platform-express/multer 2.2.0 -> CVE-2026-5038 & CVE-2026-5079 (multer DoS); @nestjs/platform-express hard-pins multer 2.1.1 exact (no caret, still 2.1.1 in latest 11.1.27) so no parent upgrade carries the fix; scoped to nest as the sole multer consumer; drop once @nestjs/platform-express depends on multer >=2.2.0. @nestjs/graphql/ws 8.21.0 -> CVE-2026-48779; @nestjs/graphql (already latest 13.4.2, only newer is the 14.0.0-next prerelease) pins ws 8.20.1 exact (no caret) so no parent upgrade carries the fix; scoped to @nestjs/graphql as the sole pinner of the vulnerable ws -- the scoped key matches both its npm and patch: locator instances, and every other ws consumer resolves 8.21.0 naturally; drop once @nestjs/graphql depends on ws >=8.21.0. @remote-dom/react/@types/react ^19.2.0 -> React type-identity dedup, SCOPED to @remote-dom/react only (every other package resolves @types/react 19 naturally from the workspace ^19.2.0 ranges). @remote-dom/react (transitive via twenty-front-component-renderer) lists @types/react ^18 in its own dependencies and nests its own copy; React 18 and 19 declare ReactNode differently (19 adds bigint + Promise<AwaitedReactNode>, drops ReactFragment's {}), so the two copies are mutually non-assignable and break twenty-front's typecheck (~156 TS2322 errors). Range-aligning our own packages can't fix a third-party's transitive @types pin, hence this single scoped override (only @types/react splits; runtime react/react-dom are peer-deps that converge naturally, and @types/react-dom does not nest a copy). Drop once @remote-dom/react widens @types/react to ^19 (latest 1.2.2 still pins ^18; tracked upstream in Shopify/remote-dom#153). graphql 16.8.1 -> singleton pin held below msw's ^16.12.0 dep and @nestjs/graphql's ^16.11.0 peer; drop after a validated repo-wide bump to latest 16.x; graphql-redis-subscriptions/ioredis 5.10.1 -> TS type-identity dedup: twenty-server passes its ioredis client into RedisPubSub, so this must equal the exact ioredis version pinned by twenty-server and bullmq (bump in lockstep); @types/qs 6.9.16 -> holdback below the 6.9.17 ParsedQs typing break (node-saml wants ^6.9.18); @opentelemetry/api 1.9.1 -> singleton guard for the NoopMeterProvider bug (#20231): ai 6.0.x pins 1.9.0 exact vs @sentry/node ^1.9.1, drop when workspace ai >=6.0.178 AND @scalar/agent-chat moves off ai 6.0.33; chokidar ^3 -> NestJS CLI watch needs fsevents on macOS, removed in chokidar 4/5 (#20316); tmp ^0.2.7 -> CVE, zapier-platform-cli 19 (latest) pins 0.2.5 and inquirer 7/8's external-editor wants ^0.0.33; @mintlify/previewing/tar ^7.5.16 -> tar PAX-header file-smuggling CVE GHSA-vmf3-w455-68vh (node-tar <=7.5.15, fixed 7.5.16); @mintlify/previewing exact-pins tar 7.5.15 with no fixed upstream release (latest 4.0.1163 still pins it), pulled via mintlify in twenty-docs; scoped as the sole tar holdout below 7.5.16 (every other tar parent permits 7.5.16 within its declared range and resolves there naturally), drop once @mintlify/previewing ships tar >=7.5.16; @angular-devkit/core 19.2.24 -> picomatch CVE, blocked on @nestjs/cli >11.0.23 fixing the dist/src output regression (repo held at 11.0.16); yeoman-environment 6.0.1 -> CVE, zapier-platform-cli 19 (latest) pins 4.4.3; express/qs + @cypress/request/qs + body-parser/qs 6.15.2 -> qs CVE-2026-8723 / GHSA-q8mj-m7cp-5q26 (>=6.11.1 <=6.15.1, fixed 6.15.2) for old express 4.22.x pinned by @mintlify/previewing and verdaccio: express's direct qs (express/qs), verdaccio's @cypress/request 3.0.10 qs (@cypress/request/qs), and express 4.x's bundled body-parser 1.20.4 which pins qs ~6.14.0 (body-parser/qs); the caret-range qs consumers all dedupe to 6.15.2 naturally; drop once @mintlify/previewing + verdaccio move off express 4.x; next/postcss 8.5.15 -> postcss CVE, every stable next pins 8.4.31 exact (fix only in 16.3.0 canaries; @react-email/ui also pins next 16.2.6); <pkg>/uuid 11.1.1 -> uuid CVE for parents pinning uuid <11 with no fixed release (sockjs dormant since 2021; @cypress/request 3.0.10 via verdaccio; @ptc-org/nestjs-query-typeorm at latest; googleapis 105 -> common 8 drops uuid but needs the googleapis >=152 migration). Preserves the intentional uuid 13.x; @cyntler/react-doc-viewer/ajv 8.20.0 -> CVE, upstream (latest 1.17.1) pins ajv ^7 but never imports it, forcing v8 is safe; */esbuild 0.28.1 -> two esbuild advisories both fixed in 0.28.1: the Deno-module binary-integrity RCE GHSA-gv7w-rqvm-qjhr (vulnerable >=0.17.0 <0.28.1) and the earlier dev-server path-traversal GHSA-g7r4-m6w7-qqqr (Windows, >=0.27.3 <0.28.1). The Deno advisory's range covers every esbuild <0.28.1, so it re-exposed older transitive copies too. Preference is to fix by upgrading the parent, not by resolution -- done where it works: @size-limit/preset-small-lib+size-limit (now ^12.1.0, pin esbuild ^0.28.0) and wrangler (bumped within ^4.0.0 to 4.102.0, which pins esbuild 0.28.1) were bumped and resolve to 0.28.1 on their own, NO resolution needed. The six resolutions below are for parents that cannot be cleanly upgraded. Five pin a vulnerable esbuild OUTSIDE the 0.28.1 range in their latest release: @react-email/ui exact-pins 0.28.0 (still 0.28.0 in latest 6.6.0); @opennextjs/aws exact-pins 0.25.4 (still 0.25.4 in latest 4.0.3); zapier-platform-cli exact-pins 0.25.8 (latest 19.0.0); @lingui/cli pins ^0.25.1 -> caps <0.26 (still ^0.25.1 in latest 6.3.0); storybook pins a range topping out at ^0.27.0 -> caps <0.28 (still capped in latest 10.4.4). react-email allows ^0.28.0 but the npmMinimalAgeGate down-selects it to the still-vulnerable 0.28.0 until 0.28.1 ages past the gate (published 2026-06-11). tsx needs NO resolution: its ^4.x ranges resolve to 4.22.x which pins esbuild ~0.28.0 -> 0.28.1 on its own. (tsx had briefly been pinned to 4.21.0 because tsx 4.22's --import tsx/esm loader feeds esbuild-downleveled enums into jest's type-checking ts-node config compiler, yielding a spurious TS7022 in server-integration-test; that is now fixed at the source by dropping --import tsx/esm from the integration jest invocation in twenty-server project.json (it had been swept in by the Storybook 10 upgrade and is not needed there): ts-node alone now compiles the config + globalSetup, so there is no esbuild enum downleveling to trip TS7022 and decorator metadata is still emitted. tsx version is now irrelevant to the tests, so the pin was dropped.) Drop each entry once its parent ships a range that resolves to >=0.28.1 on its own (react-email drops once 0.28.1 clears the age gate). Our own twenty-client-sdk raises its esbuild floor to ^0.28.1 directly in its package.json instead of via a resolution. googleapis/googleapis-common 8.0.1 -> singleton dedup for the googleapis 173 upgrade. googleapis-common 8.0.2 (published 2026-06-04, AFTER googleapis 173 on 2026-05-28) regressed its google-auth-library dep from a range to exact 10.5.0 (and gaxios to exact 7.1.3), while googleapis itself pulls google-auth-library ^10.2.0 (10.7.0); the two mismatched copies make OAuth2Client's type-identity diverge between the client our provider builds (via googleapis -> 10.7.0) and the one gmail/calendar method options expect (via googleapis-common -> 10.5.0), breaking every gmail/calendar service typecheck (TS2322/TS2769). The parents are already at latest (googleapis 173.0.0, googleapis-common 8.0.2) so we cannot fix by upgrading; instead we pin googleapis' googleapis-common back to 8.0.1, the last version with RANGE deps (google-auth-library ^10.1.0, gaxios ^7.0.0-rc.4) -- and the version googleapis 173 originally shipped against. Ranges resolve to the same hoisted versions googleapis uses, so google-auth-library AND gaxios both collapse to a single copy with no further resolution (a global google-auth-library pin would only dedup one of the two). Scoped to googleapis since it is the sole googleapis-common 8.x consumer. Drop once googleapis-common 8.0.3+ restores range deps or googleapis bumps to a common that does. @mintlify/{cli,common,prebuild,previewing,scraping,validation}/js-yaml + @verdaccio/config/js-yaml 4.3.0 -> CVE-2026-53550 / GHSA-h67p-54hq-rp68 (js-yaml quadratic-complexity DoS in YAML merge-key handling via repeated aliases, vulnerable <=4.1.1, fixed 4.2.0) and its follow-up CVE-2026-59869 / GHSA-52cp-r559-cp3m (merge-key chains force quadratic CPU, vulnerable 4.x <4.3.0, fixed 4.3.0); these seven packages each hard-pin js-yaml 4.1.1 exact (no caret, still 4.1.1 in their latest) so no parent upgrade carries the fix; scoped to those seven as the sole 4.1.1 pinners -- the cosmiconfig-based caret consumers (@graphql-codegen/cli, @lingui/cli, @lingui/vite-plugin, @wyw-in-js/vite, vite-plugin-svgr, all via cosmiconfig ^4.1.0) shared that single 4.1.1 copy and dedupe onto 4.3.0 once it is lifted. Drop these seven once they ship js-yaml >=4.3.0. The remaining js-yaml 3.x holders -- front-matter@4.0.2 (via mintlify in twenty-docs) and @istanbuljs/load-nyc-config@1.1.0 (via babel-plugin-istanbul coverage), both declaring js-yaml ^3.13.1 -> 3.14.2 with no fixed upstream release -- are also forced to 4.3.0 via scoped pins (front-matter/js-yaml + @istanbuljs/load-nyc-config/js-yaml), evicting the last js-yaml 3.14.2 copy and closing alert #1504. load-nyc-config calls yaml.load (present and safe-by-default in 4.x) so its pin alone suffices. front-matter's default loader called the safeLoad API that 4.x removed, so it is also patched (front-matter@npm:4.0.2 -> .yarn/patches/front-matter-npm-4.0.2-e1cc0efa69.patch) to set loader = parser.load (safe-by-default in 4.x; safeLoad is gone and 4.x core has no unsafe/full schema, so the old allowUnsafe ternary is dead). The version move stays a separate resolution because a yarn patch only rewrites a package's files, not its resolved dependency graph -- patching front-matter's own js-yaml range does not change what yarn resolves. Drop the patch + both pins once front-matter/mintlify and load-nyc-config ship js-yaml >=4.",
"version": "0.2.1",
"nx": {},
"scripts": {
"docs:generate": "tsx packages/twenty-docs/scripts/generate-docs-json.ts",
"docs:generate-navigation-template": "tsx packages/twenty-docs/scripts/generate-navigation-template.ts",
"docs:generate-paths": "tsx packages/twenty-docs/scripts/generate-documentation-paths.ts",
"docs:prune-orphans": "tsx packages/twenty-docs/scripts/prune-orphan-translations.ts",
"start": "npx concurrently --kill-others 'npx nx run-many -t start -p twenty-server twenty-front' 'npx wait-on tcp:3000 && npx nx run twenty-server:worker'"
},
"workspaces": {
"packages": [
"packages/twenty-front",
"packages/twenty-server",
"packages/twenty-emails",
"packages/twenty-ui",
"packages/twenty-utils",
"packages/twenty-zapier",
"packages/twenty-website",
"packages/twenty-docs",
"packages/twenty-e2e-testing",
"packages/twenty-shared",
"packages/twenty-sdk",
"packages/twenty-front-component-renderer",
"packages/twenty-client-sdk",
"packages/twenty-cli",
"packages/create-twenty-app",
"packages/twenty-codex-plugin",
"packages/twenty-oxlint-rules",
"packages/twenty-claude-skills"
]
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "lf"
}
}