Skip to content

i18n: script.run answers errors are translated in every complete-message catalog - #7532

Merged
bflatastic merged 14 commits into
storytold:mainfrom
dotCooCoo:fix/script-answers-errors-translated
Nov 15, 2026
Merged

bflatastic merged 14 commits into
storytold:mainfrom
dotCooCoo:fix/script-answers-errors-translated

Conversation

@dotCooCoo

@dotCooCoo dotCooCoo commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

What and why

When script.run refused its answers parameter, the status bar showed the error in English in several interface languages. 11 of the 24 languages that translate every message (ca, da, el, es, fi, hi, ka, ru, sv, tr, vi) had no rows for the list errors and the reasons, and six of them (da, el, hi, ka, sv, vi) had no row for the indexed wrapper `answers[{i}]` {e} either. Hungarian and Ukrainian had the list errors and the reasons but no wrapper, and showed an indexed error in English or half translated. Simplified Chinese had both, and showed the confirm reason half translated. No language had a row for the refusal of answers in a run in the app.

  • Every complete-message catalog now has @msg rows for the three list errors (not a list, more than 10,000 answers, larger than 1 MiB), the indexed wrapper `answers[{i}]` {e}, the seven reasons an answer at an index is refused, and `answers` is only for a run with nobody to ask: in the app, the person answers each dialog. Catalogs that already had some of these rows (all but da, el, hi, ka, sv and vi) get only the missing ones. The rows keep the code names (answers, kind, value, alert, confirm, prompt), the values "ok", true, false and null, the index and the counts as written. Size units follow each catalog's existing script rows.
  • Catalog::parse (crates/ui-egui/src/i18n/catalog.rs) orders templates that start with text by the length of the text before the first placeholder, then by all their literal text. Before, `{key}` must be true or false took `answers[3]` is a confirm's answer, whose `value` must be true or false with the key answers[3] is a confirm's answer, whose value, and the line was shown half translated. `answers[{i}]` {e} now matches it first. This changes which row matches when two rows that start with text both fit a message; a quoted name can still hold a backtick.
  • The untranslated-strings report also reads the refusals script.run's param(...) helper gives (crates/engine/src/cmd/scripts.rs), and skips a type's own function of that name, such as Grays::param(C, p).
  • This branch does not change the engine, so the error script.run returns to MCP and other callers is still the English text, as for other messages that are translated only when the status bar shows them. Which words are translated and which stay as written is VectorCraft's own rule.
  • docs/target-app-parity.md has one line for it.

How it was tested

New tests in crates/ui-egui/src/i18n/tests.rs, each failing without the change:

  • script_answers_errors_are_translated: runs script.run through Session::execute with each of the seven bad answers at index 3 and at index 9999, a value that is not a list, 10,001 answers, 70 prompt answers of 16 KiB (more than 1 MiB), and a nonempty answers in a run in the app. It checks the English BadParams message, then, in every complete-message language, that the outer line, the indexed wrapper and the reason are translated and that the code names and numbers are kept.
  • the_longer_leading_text_matches_first: `answers[{i}]` {e} takes the confirm message before `{key}` must be true or false, and a name holding a backtick still matches `{key}` must be true or false and no brush named `{name}` .
  • message_scan_reads_script_run_param_refusals: the scan reads param("...") and skips Grays::param(C, p) and Pick::param(p, C).

Checks on the final tree, on main at 67f6d3a:

  • cargo fmt --all -- --check
  • cargo clippy -p vectorcraft-ui-egui --all-targets -- -D warnings
  • cargo check --workspace --tests
  • cargo test -p vectorcraft-ui-egui --lib: 4,655 passed, 2 ignored (the i18n tests: 125 passed)
  • cargo xtask brands, layers (30 crates) and assets (337 files)
  • cargo xtask ci runs in this pull request's CI.

After merging main at 8f8956f (Danish became a complete-message language) and adding the Danish rows: cargo fmt --all -- --check, cargo check --workspace --tests and cargo test -p vectorcraft-ui-egui --lib i18n (127 passed).

Checklist

  • cargo xtask ci passes (fmt, clippy, tests, assets, brands, layers, wasm).
  • No panics in shipped code: no unwrap(), expect(), panic!, unreachable!, todo! or
    unimplemented! outside tests, and no unchecked indexing on data from files, parameters or
    messages. Errors are returned as Result and shown to the user
    (why and how).
  • Clean-room: nothing copied from Adobe products or GPL/AGPL code (AGENTS.md).
  • Every new asset has a row in ASSETS.md.

Summary by CodeRabbit

  • Bug Fixes

    • Improved message-template matching so templates with longer leading text are prioritized, including templates containing backticks.
  • Documentation

    • Clarified the documented handling of script-run answer validation refusals, including which details remain unchanged and that these messages appear in the untranslated-strings report.

…age catalog

script.run refuses an answers value that is not a list, that has more
than 10000 answers or that is larger than 1 MiB, an answer at an index
that is not an object, does not have exactly kind and value, has a
value its kind of dialog does not take, holds a prompt text longer than
16 KiB or has an unknown kind, and answers given to a run in the app.
Seventeen complete-message catalogs had no rows for these errors, and
none had the `answers[{i}]` {e} row or the in-app refusal, so the status
bar showed them in English. The command's own error stays in English.

- Every complete-message catalog has a row for each of these errors.
  The index, the counts and the names answers, kind, value, true, false
  and null are kept.
- Of two message templates that start with text, the one with the
  longer text before its first placeholder is tried first. Before,
  "`{key}` must be true or false" took "`answers[3]` is a confirm's
  answer, whose `value` must be true or false" (its key then held
  "answers[3]` is a confirm's answer, whose `value"), and the line was
  shown half translated.
- The untranslated-strings report lists the refusals of script.run's
  parameters (the param helper in cmd/scripts.rs), and the message scan
  skips a type's own function of a helper's name (Grays::param).

Tests: i18n::tests::script_answers_errors_are_translated,
the_longer_leading_text_matches_first,
message_scan_reads_script_run_param_refusals.
Main now has Czech and Traditional Chinese rows for the answers list and
reason messages. The duplicates this branch added are removed; the
indexed wrapper and the app refusal rows stay.
Main added the script.run answers list and reason rows to fr and ko, and the
`answers[{i}]` wrapper to ru and zh-hans. This branch's copies of those rows
were duplicates, which bundled_catalogs_are_consistent rejects. Main's rows
stay; the wrapper and app-run refusal rows this branch adds are kept.
@coderabbitai

coderabbitai Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters: 1

  • crates/ui-egui/src/i18n/tr.tsv is excluded by !**/*.tsv

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

The changes adjust message-template matching order and expand script.run refusal-scanning tests, answer-validation translation tests, and parity documentation.

Changes: Internationalized Messages

Layer / File(s) Summary
Message template matching precedence
crates/ui-egui/src/i18n/catalog.rs, crates/ui-egui/src/i18n/tests.rs
Catalog parsing now sorts templates by whether they begin with a placeholder, then by descending leading literal-text length, and then by descending total literal-text length. Tests cover matching precedence and backticks in captured values.
Script refusal scanning and translation coverage
crates/ui-egui/src/i18n/tests.rs, docs/target-app-parity.md
The helper scan includes free-function param( calls and excludes calls owned by uppercase-named types. Tests cover translated script.run answer-validation refusals and retained details. The parity document lists the translated refusals and details that remain untranslated.

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix

Suggested reviewers: bflatastic, ruchirguitar, mockydevs

Merge Risk: Minimal · up to 3281b

Merge Risk: ⚪ Minimal · up to 3281b

This change adds translations for script answer-parameter errors in the status bar and refines how matching message templates are chosen. No concrete merge-blocking risk was found, and the reported tests cover the changed behavior.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: script.run answers error messages are translated in every complete-message catalog. The changeset adds @msg rows for those errors across catalogs, and it also changes …
Description check Passed The description follows the template sections 'What and why' and 'How it was tested', and it includes the Checklist. It explains the problem, lists the catalog and ordering changes, and names the new …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main change: script.run answers error messages are translated in every complete-message catalog. The changeset adds @msg rows for those errors across catalogs, and it also changes template ordering and the param() scan. The title covers the primary change and matches the PR objectives. It is 80 characters, which is within a reasonable length, and it uses the repository's i18n prefix convention.

Full details: Description check

Explanation

The description follows the template sections 'What and why' and 'How it was tested', and it includes the Checklist. It explains the problem, lists the catalog and ordering changes, and names the new tests with their purpose. It also gives the final-tree check results and the post-merge checks. Two checklist items are checked, and the cargo xtask ci item stays unchecked, which is consistent with the author's note that CI runs on the PR. The description is mostly complete.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 557b6f3 and d95cc39.

Files ignored due to path filters: 24

  • crates/ui-egui/src/i18n/ca.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/cs.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/da.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/de.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/el.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/es.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/fi.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/fr.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/hi.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/hu.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/it.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/ja.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/ka.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/ko.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/nl.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/pl.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/pt-br.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/ru.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/sv.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/tr.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/uk.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/vi.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/zh-hans.tsv is excluded by !**/*.tsv
  • crates/ui-egui/src/i18n/zh-hant.tsv is excluded by !**/*.tsv
Files selected for processing: 2

  • crates/ui-egui/src/i18n/tests.rs
  • docs/target-app-parity.md
Files skipped from review as they are similar to previous changes: 1

  • docs/target-app-parity.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

bflatastic pushed a commit that referenced this pull request Nov 14, 2026
…wers change

#7532 adds a Hungarian row for `answers[{i}]` {e}. Two rows with the same source would fail the catalog's duplicate check once both merge.
Danish joined the complete-message languages on main, so the script.run answers errors and reasons now need da rows. The merge of main also left the indexed wrapper twice in uk and vi; the duplicate rows from this branch are removed.
main already translates ten of the answers errors in tr.tsv, so the rows this branch added for them repeated those keys and bundled_catalogs_are_consistent failed. The repeated rows are removed; the row for the app's refusal of `answers` stays.
@bflatastic
bflatastic merged commit 8f339ee into storytold:main Nov 15, 2026
7 checks passed
@bflatastic

Copy link
Copy Markdown
Member

Merged, thanks @dotCooCoo! It passed its CI checks.

bflatastic added a commit that referenced this pull request Nov 15, 2026
#7532's script.run answers rows and the Russian message rows landed in the same batch with
the same ten messages, so bundled_catalogs_are_consistent fails on a duplicate. The first
of each pair stays.
dotCooCoo pushed a commit to dotCooCoo/vectorcraft that referenced this pull request Nov 15, 2026
storytold#7774's Georgian catalog and storytold#7532's script.run answers rows landed in the same batch with
twelve of the same messages, so bundled_catalogs_are_consistent fails on a duplicate. The
first of each pair stays.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants