Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
993f983
i18n: string-extraction codemod, literal ratchet and en-XA pseudo-loc…
cursoragent Oct 27, 2026
54ffbe8
i18n codemod: drop a path segment that repeats the package namespace
cursoragent Oct 27, 2026
a9350e5
i18n codemod: lazy descriptors for module data; scan detail copy
cursoragent Oct 27, 2026
12752d8
i18n audit: scope findings, full-viewport screenshots, label-based su…
cursoragent Oct 27, 2026
b4cc700
Remove a file that belongs to the navbar migration
cursoragent Oct 27, 2026
a165e1a
i18n:check: reviewed translations cannot regress; releases require re…
cursoragent Oct 27, 2026
184a2ae
Literal guard: per-text baseline that may only shrink, stricter scanner
cursoragent Oct 27, 2026
2e08651
Pseudo-locale: dev/test builds only; audit allowlist matches whole wo…
cursoragent Oct 27, 2026
5fa76da
i18n: migrate the viewer toolbar so the literal baseline only shrinks
cursoragent Oct 27, 2026
9c31599
i18n tooling: fast fixture tests; document the release review gate
cursoragent Oct 27, 2026
2ba90c0
i18n extract: never approve a newly filled translation
cursoragent Oct 27, 2026
13b6052
i18n: normalize draft comment order as extract writes it
cursoragent Oct 27, 2026
0134222
Merge main
cursoragent Oct 27, 2026
c1e3a73
Baseline the floor plan panel copy that main changed
cursoragent Oct 27, 2026
abbf51f
i18n codemod: leave app modules without 'use client' for a person
cursoragent Oct 27, 2026
0a80256
Literal guard: resolve rendered constants through lexical scope
cursoragent Oct 27, 2026
e37b746
i18n: releases ship drafts as English; gate on regressions and pack l…
cursoragent Oct 27, 2026
fee4995
Literal guard: measure baseline growth repo-wide; scan rendered text
cursoragent Oct 27, 2026
9ae7763
i18n codemod: ICU-exact encoding, entry-module and callback guards, i…
cursoragent Oct 27, 2026
acea493
i18n:check: catch renamed reviewed IDs; compare pushes with github.ev…
cursoragent Oct 27, 2026
444267a
i18n audit: report controls without an accessible name; tests and doc…
cursoragent Oct 27, 2026
285ce3c
i18n:check: a stale draft after a wording change is a draft, not an e…
cursoragent Oct 27, 2026
1032c0f
release-check: compare with the latest @pascal-app/editor release tag
cursoragent Oct 27, 2026
8776a6d
i18n: renames warn unless declared; codemod and scanner fidelity fixes
cursoragent Oct 27, 2026
53abaae
Literal guard: a trailing i18n-ignore exempts only its own line
cursoragent Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ jobs:
permissions:
contents: read
steps:
# Depth 2 keeps the pull request merge commit's first parent (the base
# tip), which i18n:check compares reviewed translations and the literal
# baseline against.
- uses: actions/checkout@v4
with:
fetch-depth: 2

# Read from `packageManager` in package.json, so CI runs the same bun as
# contributors and a bun release cannot change the gate on its own.
Expand All @@ -80,7 +85,20 @@ jobs:
- name: Lint & format check
run: bun run check

# A push compares with the commit before it (every commit of a
# multi-commit push); the shallow checkout lacks it, so fetch it.
- name: Fetch the pre-push commit for localization checks
if: github.event_name == 'push' && !startsWith(github.event.before, '0000000')
env:
BEFORE: ${{ github.event.before }}
run: git fetch --no-tags --depth=1 origin "$BEFORE"

# Includes the review-regression check against the PR base (or the
# pre-push commit) and the scan of the compiled packs for drafts; draft
# counts go to the job summary.
- name: Check localization catalogs
env:
I18N_BASE_REF: ${{ github.event_name == 'push' && github.event.before || '' }}
run: bun run i18n:check

- name: Validate agent skills and plugin packages
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

# Drafts ship as English until reviewed. A release fails only when an
# entry reviewed at the latest @pascal-app/editor@* tag (the package
# that ships the catalogs; tagged below) became a draft with the same
# English, or when a compiled pack contains a draft. The full-history
# checkout above makes the tags available.
- name: Check translation review regressions and shipped packs
run: bun scripts/i18n.ts release-check

- name: Configure git
run: |
git config user.name "github-actions[bot]"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ og-test
.claude/launch.json
.claude/settings.local.json
.vscode/launch.json
.i18n-audit/
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ and reports inflated counts. `bun run test` goes through Turborepo, which
builds workspace dependencies first (several packages import theirs from
`dist/`) and runs each package's own scoped test script.

### User-visible text

Every string a person reads in the editor (labels, tooltips, `aria-label`,
`title`, placeholders, menus, dialogs, errors) goes through the i18n catalog:

```tsx
const i18n = usePascalI18n()
<button title={i18n._({ id: 'app.editorNavbar.share', message: 'Share' })} />
```

`bun run i18n:check` (part of `bun run ci`) fails when a file gains a
hardcoded user-visible literal. Run `bun run i18n:extract` after changing copy.
Scene data, MCP/agent text and developer errors stay English. See
[`i18n/README.md`](i18n/README.md) for catalogs, translation review, the
migration codemod and the pseudo-locale screenshot audit.

### Project structure

| Package | What it does |
Expand Down
2 changes: 2 additions & 0 deletions apps/editor/app/client-bootstrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import '../lib/bootstrap'
import { createI18n, defaultI18n, PascalI18nProvider } from '@pascal-app/core'
import { registerBundledLocales } from '@pascal-app/editor/locales'
import { type ReactNode, useEffect, useMemo } from 'react'
import { registerDevLocales } from '@/lib/dev-locales'

registerBundledLocales()
registerDevLocales()

export function ClientBootstrap({
children,
Expand Down
2 changes: 2 additions & 0 deletions apps/editor/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { GeistPixelSquare } from 'geist/font/pixel'
import { Barlow } from 'next/font/google'
import localFont from 'next/font/local'
import { headers } from 'next/headers'
import { registerDevLocales } from '@/lib/dev-locales'
import { PASCAL_LOCALE_HEADER, resolveUiLocale } from '@/lib/ui-locale'
import { ClientBootstrap } from './client-bootstrap'
import './globals.css'

registerBundledLocales()
registerDevLocales()

const geistSans = localFont({
src: './fonts/GeistVF.woff',
Expand Down
Loading
Loading