feat(twenty-sdk): extract & compile app translations into the manifest (#22236)

## Summary

**PR 2/4** of the app-metadata-translations stack. Gives app developers
the authoring side, as part of the normal manifest build — and it stays
out of the way of developers who don't translate.

- `twenty-sdk` CLI i18n pipeline: collect translatable strings from the
manifest, generate value-as-key message ids (`sha256(value)` truncated,
byte-identical to the server's `generateMessageId`), a `dev
i18n-extract` command to scaffold per-locale catalog files, and a
compile step folded into `build` that emits `manifest.translations`.
- Opt-in: no `locales/` dir → `compileApplicationTranslations` returns
`undefined` → manifest is unchanged.
- Adds an optional `locale` to the front-component execution context so
components can translate against the host locale.

## Stack
Stacks on #22235 (PR 1/4). Base branch:
`claude/app-translation-1-runtime-resolution`.

## Tests
Unit (vitest): extract/compile round-trip + message-id determinism.

## Verification note
`yarn install` could not complete in the remote dev environment, so
typecheck/lint/tests were not run locally — **CI is the source of
truth**.

https://claude.ai/code/session_01NiE7o3cd3zCLZarVkJa6UA

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

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22236?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. -->
This commit is contained in:
Félix Malfait
2026-06-28 07:36:48 +02:00
committed by GitHub
parent 41c10b9ee7
commit d81b3c3fa3
13 changed files with 407 additions and 2 deletions
@@ -80,7 +80,7 @@ export const useFrontComponentExecutionContext = ({
} = useSnackBar();
const { closeSidePanelMenu } = useSidePanelMenu();
const { copyToClipboard: copyToClipboardWithSnackbar } = useCopyToClipboard();
const { t } = useLingui();
const { t, i18n } = useLingui();
// oxlint-disable-next-line twenty/no-state-useref
const lastCopyToClipboardCallAtRef = useRef<number>(Number.NEGATIVE_INFINITY);
const setCommandMenuItemProgress = useSetAtomFamilyState(
@@ -252,6 +252,7 @@ export const useFrontComponentExecutionContext = ({
recordId: selectedRecordIds?.length === 1 ? selectedRecordIds[0] : null,
selectedRecordIds: selectedRecordIds ?? [],
colorScheme,
locale: i18n.locale,
};
const unmountFrontComponent: FrontComponentHostCommunicationApi['unmountFrontComponent'] =