Skip to content

[Maintainer] i18n: migrate the vent, fence and MEP inspectors - #1185

Merged
Aymericr merged 5 commits into
mainfrom
cursor/i18n-vent-fence-mep-inspectors-8160
Oct 27, 2026
Merged

Aymericr merged 5 commits into
mainfrom
cursor/i18n-vent-fence-mep-inspectors-8160

Conversation

@Aymericr

@Aymericr Aymericr commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

What does this PR do?

Localizes the last of the inspectors still in English: the five roof vents, fences and gates, and the MEP panels and tool HUDs. Part of #621. main (20d6497, with #1180–#1183, #1186 and #1187) is merged in with a normal merge commit. The compiled en and en-XA catalogs and the literal baseline were regenerated with i18n:extract, i18n:literals update and i18n:compile. i18n/pseudo-surfaces.ts keeps all 46 surfaces once, and its three imports from ../packages/core/src/schema are now one (Tooling's nit, as a separate commit). Reviewed entries stay at 85 per locale, and release-check finds no draft compiled in. Stored scene data is unchanged.

  • Vents. Box, ridge, turbine and eyebrow vents, and the cupola.
  • Fences.
    • The path, surface-behaviour and pattern editors.
    • The gate and opening inspector (hinges and latch, swing, leaf proportion, remove), including its option values (Single/Double gate, Left/Right, Inward/Outward, None/Diagonal/Cross). The blocked-opening warning is stored as a flag and worded while rendering, so it follows a locale switch.
    • The endpoint tool labels.
    • The path summary is now one ICU plural ("{number} points · {length} m"). Its count is ungrouped and its length uses formatFixed.
    • "Span to point {number}".
    • The pattern note is one ICU select on the fence style. Before, an English fragment was slotted into the sentence.
  • MEP.
    • Run hangers: "Hanger {number} · segment {segment}", plus the position and support field names.
    • Downspouts ("Downspout {number}").
    • Duct fitting "Swap W/H".
    • The duct-terminal, duct-fitting, pipe-fitting, pipe-trap, liquid-line and HVAC tool HUDs. The mount is an ICU select rather than a capitalised enum.
  • Overflow (editor). SegmentedControl labels may now break inside a word ([overflow-wrap:anywhere]). Before, a long one-word translation in a six-option control, such as the fence styles, spilled into the next segment. The en-XA screenshot below shows the fix.
  • Audit. New surfaces box-vent-panel, ridge-vent-panel, turbine-vent-panel, eyebrow-vent-panel, cupola-panel and fence-panel. They run on the furnished project with the five vents on its roof segment and a fence on the ground floor. The turbine's "rad/s" unit is listed as data.
  • Catalogs. 194 new messages. zh-CN, fr, es and ja drafts are fuzzy with Review: required, so they show English until reviewed. The literal baseline drops by 186, from 858 on main to 672.

Display changes from main

  • Riser diagram fittings now read "Sanitary tee" instead of sanitary-tee. They use the shared inspector option names, and other fitting types read the same way (for example "End cap").

How to test

  1. bun run i18n:check passes after the merge, with 3,289 entries per locale awaiting review. bun scripts/i18n.ts release-check --base origin/main passes too.
  2. Run bun dev with ?lang=en-XA. Select each vent, a fence, and a gate on it: the inspectors, including the gate's option values, are bracketed and accented, and the fence style segments wrap inside their own boxes.
  3. Run bunx turbo run build --filter=@pascal-app/nodes (the app loads nodes from dist), then bun run i18n:pseudo-audit -- box-vent-panel ridge-vent-panel turbine-vent-panel eyebrow-vent-panel cupola-panel fence-panel: all six pass. I ran this.
  4. Tests I ran after the merge, with core and nodes rebuilt first:
    • packages/nodes: 5,028 pass, 1 skip.
    • packages/editor bun test src: 2,704 pass.
    • apps/editor bun test lib: 74 pass.
    • bun test scripts/: 131 pass.
    • The editor, nodes and app type checks are clean, and bun run check reports no errors.

Still English after this PR

  • Fence and gate placement messages (fence/feature-tool.tsx). This is tool copy for the toasts and errors pass.
  • 3D labels that render inside drei Html in these packages. They can switch to [Maintainer] i18n: editor-side inspector panels and 3D overlay scope #1180's LocalizedHtml, now on main, in a follow-up.
  • Not audited: the MEP and gate inspectors have no audit surface, because seeding duct and pipe runs with hangers is a larger fixture. Their copy is converted.
  • Also still English: construction dimension and block, external plugin copy, command messages, material names and unit suffixes.

Screenshots / screen recording

en-XA, captured by i18n:pseudo-audit (UTC, metric). The images are served from the image-only branch cursor/i18n-audit-screenshots-8160, which is never merged.

Fence (style segments wrap in their own boxes):
Fence panel en-XA

Box vent:
Box vent panel en-XA

Ridge vent:
Ridge vent panel en-XA

Turbine vent:
Turbine vent panel en-XA

Eyebrow vent:
Eyebrow vent panel en-XA

Cupola:
Cupola panel en-XA

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch
Open in Web Open in Cursor 

Note

Low Risk
Copy and catalog changes with a small CSS wrap fix; no auth, persistence, or core logic changes. Residual risk is missing or incorrect ICU/plural strings in non-English locales until review clears fuzzy entries.

Reviewed by Cursor Bugbot for commit 728ebbf. Bugbot is set up for automated code reviews on this repo. Configure here.

Box, ridge, turbine and eyebrow vents and the cupola; fence path, surface and
pattern editors and the gate/opening inspector; run hangers, downspouts, and
the MEP tool HUDs. Split sentences, the fence path summary, the hanger and
downspout names and the mount label are whole ICU messages; the path length
uses formatFixed and counts stay ungrouped. Segmented control labels may break
inside a word, so a long translation wraps in its segment instead of spilling
into the next. New audit surfaces for the five vents and the fence.
@Aymericr Aymericr added the bot:maintainer label Oct 27, 2026 — with Cursor
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T17:41:17.046325Z 153edb3 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 153edb3ffc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

{
key: 'leafType',
label: 'Leaves',
label: i18n._({ id: 'node.fenceFeature.inspector.leaves', message: 'Leaves' }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Translate the gate option values

When the gate inspector is rendered in a non-English locale, the field labels now use the catalog but the corresponding option arrays still contain raw English values (Single gate, Double gate, Left, Right, Inward, Outward, None, Diagonal, and Cross). This leaves the migrated inspector partially untranslated and also bypasses the pseudo-locale audit; pass these option labels through i18n._ as well.

Useful? React with 👍 / 👎.

Comment on lines +58 to +63
setError(
i18n._({
id: 'node.fenceFeature.inspector.keepTheOpeningInsideTheFence',
message: 'Keep the opening inside the fence and clear of other gates or passages.',
}),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Derive the validation message from the current locale

If this validation error is visible while the editor locale changes at runtime, usePascalI18n rerenders the component but error retains the already-formatted string from the old locale, so the message remains stale until another edit clears or recreates it. Store an error state/key and call i18n._ while rendering the status instead.

Useful? React with 👍 / 👎.

… render time

The gate's leaf, hinge, swing and bracing options are messages, and the
blocked-opening warning is a flag translated while rendering, so it follows a
locale switch.

Copy link
Copy Markdown
Member Author

Tooling cross-review at 31f92e9: APPROVE

No P0/P1/P2.

  • Stored data: gate leaf, hinge, swing and bracing options keep their values, and only the labels are messages. The blocked-placement warning is now a flag, translated at render time. Vent, fence and MEP copy is display only. Nothing translated reaches updateNode or MCP.
  • 3D overlays: the seven nodes tools that draw drei Html (duct fitting/terminal, fence endpoint, HVAC, liquid line, pipe fitting, pipe trap) call usePascalI18n() in the outer tool component and pass translated strings into the Html, so they use the editor scope without LocalizedHtml. They re-render on a locale switch.
  • Numbers: the fence length moves from toFixed(2) to formatFixed(..., 2, locale), which doesn't group, so English output is unchanged. Trap diameter is a plain {diameter} placeholder, unformatted as on main. No # plurals.
  • segmented-control.tsx only adds [overflow-wrap:anywhere] so longer translated labels wrap.
  • Catalogs: +194 entries per locale, all fuzzy with Review: required. Reviewed stays at 85 per locale and drafts are 2720 for each locale.
  • No Security areas are touched.

Findings

Checks run locally (Node 22; core and nodes dist rebuilt at this head):

  • Tests: editor 2704 pass; nodes 5026 run, 0 fail; scripts/i18n*.test.ts 56 pass.
  • tsc clean for editor and nodes. Biome clean.
  • i18n:check PASS, catalogs in sync. release-check --base origin/main shows no reviewed regression and no draft compiled in. i18n-literals check reports no new literals.

CI at this SHA: Changed paths, quality, cli-smoke and Cursor Bugbot all succeeded.

Conflicts in the compiled en and en-XA catalogs and the literal baseline are
regenerated with i18n:extract, i18n:literals update and i18n:compile.
i18n/pseudo-surfaces.ts merged cleanly and keeps every surface once.

Copy link
Copy Markdown
Member Author

Tooling cross-review at 728ebbf: APPROVE

Delta review since the 31f92e9 approval:

  • Parents check out with no rebase: a003115 = 31f92e9 + 20d6497 (main, [Maintainer] i18n: migrate the dormer, skylight and solar panel inspectors #1183), and 728ebbf has the single parent a003115. 31f92e9 is an ancestor of the head.
  • A clean local merge of 31f92e9 with 20d6497 conflicts only in i18n/literal-baseline.json and the compiled en and en-XA messages.ts. Once those are taken from a003115, my merge equals a003115 exactly. The only remaining difference from 728ebbf is i18n/pseudo-surfaces.ts, which changes 9 lines in and 9 out.
  • 728ebbf is import-only: it folds three ../packages/core/src/schema imports into one sorted import, with no other change.
  • A fresh extract, compile and i18n-literals update leave git status clean, and i18n:check passes. That also confirms the resolved baseline and packs.
  • There are 46 surfaces with no duplicate names.
  • The literal baseline goes from 858 to 672. That drop of 186 is exactly this PR's 19 vent, cupola, fence, gutter, downspout and MEP files, all going to 0. The allowlist, scripts/ and .github are unchanged versus main, and the PR adds no i18n-ignore.
  • 85 strings are reviewed, the same as main (3374 messages, 3289 awaiting review per locale). release-check --base origin/main is clean (exit 0).
  • On Node 22, after rebuilding core and nodes: nodes 5,028 pass (1 skip, 0 fail), editor 2,704 pass (0 fail), and check-types passes (14/14).
  • quality, cli-smoke, Changed paths and Cursor Bugbot are all green at this head. The PR is mergeable/clean against main 20d6497.

No findings.

@Aymericr
Aymericr merged commit 3eb2737 into main Oct 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants