Skip to content

window: everything in the window's language - refusals, list values, format names, time, licence and the toolkit's words - #163

Merged
donislawdev merged 8 commits into
mainfrom
gui/said
Oct 6, 2026
Merged

donislawdev merged 8 commits into
mainfrom
gui/said

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

What changes for somebody using the window

A window set to Polish said part of what it said in English: the reason a run was refused, the values picked from a list (portrait, a4), the names of the formats, the time left, the licence on About and the words of the toolkit's own menus and dialogs. Now all of it follows the window's language.

  • A list shows its values under their names (pionowo for portrait) and still hands the value to the recipe, so a recipe written from the window says portrait.
  • The reason a run or a box is refused is said in the window's language, with what was typed shown as it was typed.
  • Format names, preset titles beside their ids, the time left, the licence (the English notice stays the one that binds) and the toolkit's words (Copy, Paste, Cancel, the folder dialog) follow the language chosen in Preferences.
  • A fault in the program itself is said in Polish with its English detail under it, for whoever reports it.

The command line, --json, recipes and manifests are unchanged, byte for byte.

How

  • Every sentence the engine says is kept as data (core.Said): an id, the printf layout the command line prints, and the values by name. The window looks the id up in locale/said/<tag>.json, which fills named fields. 622 sentences, all in Polish.
  • Typed values (core.Choice, core.Bytes, core.Term, lists of sentences) are said in the window's language too.
  • parts.Chooser.ShownAs draws a value under a name. Selected, OnChanged and SetSelected still speak values.
  • The toolkit is given its words in the chosen language (locale/toolkit/<tag>.json) under the system's locale tag.
  • Every entry of the window's catalogue carries the hash of the English it translates, so a stale translation turns a guard red.
  • Adding a language is adding files.

Checked

  • The command line: the refusal corpora of the old and the new binary are identical (350, 96 and 48 cases, and 2952 lines of the registry-derived sweep after the last change).
  • Every stored screen of the English window is unchanged, except the preset menu (titles beside ids) and the component catalogue (a list drawn under names, closed and open).
  • Guards: every sentence has a translatable shape and wraps one error at most, the English copy matches the code, every language says every sentence with the same fields, no engine refusal is bare errors.New, every engine refusal reaches the Polish window in Polish, the closed box draws the name, no Polish description names a list value in English, the toolkit gets every word it asks for, and preset titles match the site's.
  • Keystroke cost with every box refused: no measurable difference (A/B with main). Loading the Polish catalogue at start: about 2.5 ms more, once.
  • The toolkit on a system whose language it does not know (ko-KR, sw-KE in Docker): our words replace its English ones.

Not checked yet: the real window driven by hand. The screen was not drawing at the time, and the build from main drew the same blank window, so it is to be repeated.

🤖 Generated with Claude Code

donislawdev and others added 7 commits October 5, 2026 23:33
Every refusal and note of core, engine, recipe, format, preset and damage
is core.Says: an id, the fmt layout the command line has always printed,
and named values. The command line renders the layout with the same values,
so its bytes do not move - 350 cases of a corpus derived from the
registries, 96 recipes and 48 commands of the older corpora are identical
between the binary before and after.

The window looks the id up in locale/said and fills named fields, the
English window says exactly what it said before. Wrapped system errors are
said in our words with the number (O251), and an error only a fault in the
program can produce is framed as one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…as sentences

The tool and checksum refusals, the manifest and recipe limits and the
preset parameter refusals are core.Says now, and an error only a fault in
the program can produce is core.Defect. A refusal with no setting of its own
answers for the setting of the error it wraps, as fmt.Errorf let it.

A guard holds the engine to it: no fmt.Errorf or errors.New outside
core.Defect, with the one signal between two publishing functions named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es, preset titles and the licence as registry words

622 sentences of the engine in locale/said/pl.json, each with the hash of
the English it translates. Values of closed lists, the outcomes and rules of
the manifest notes, format names, preset titles and the paragraphs of the
licence notice are registry words, translated in locale/registry/pl.json.
The punctuation and typeface guards read the new folder as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…low the chosen language, time and licence translated

A menu of a declared setting shows each value under its name in the window's
language and still holds and hands back the value, so a recipe, the command
line and the manifest are unchanged. Preset menus show titles beside ids,
format lists the translated names of the three that describe a file.

The toolkit's own words - the menu of a text box, the folder and file
dialogs - are given to it in the window's language under the system's tag.
Time left, the empty-menu placeholder and the licence notice on About are
the window's words too. Every entry of the window's catalogue now records
the hash of the English it translates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…that named list values in English

Unique names in every list, no translated description naming a list value
the list calls otherwise, preset titles equal to the site's, the engine's
refusals through the Polish and the pseudo window, and time and the licence
in the English window equal to the command line's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…their names in the catalogue

A refusal kept as a sentence unwrapped to the list of errors it wrapped,
empty for most, and the window spreads an error that unwraps to several
into one refusal per box - so a size typed wrong marked no box at all.
It unwraps to one error now, the way fmt.Errorf with one %w does, and a
sentence may wrap one error at most.

Four Polish descriptions named a list value in English at the start of a
sentence, which the guard missed by matching lower case only. The guard
for the closed box read the menu's value rather than the drawn words.

The component catalogue shows a list whose values are drawn under longer
names, closed and open. JointLimit moves to its own file, the window's
note said as the manifest holds it moves to the manifest package, and
the engine's and the toolkit's word files are accounted for as our own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 167 files, which is 67 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Repository UI (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2b22c979-c805-4b9e-a683-73a4329d4d15
📥 Commits

Reviewing files that changed from the base of the PR and between 3e919e8 and b4ab591.

⛔ Files ignored due to path filters (2)
  • internal/guard/testdata/screens/catalogue.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset-menu.png is excluded by !**/*.png, !**/*.png
📒 Files selected for processing (167)
  • CHANGELOG.md
  • internal/cli/errors.go
  • internal/cli/recipecmd.go
  • internal/core/humanise.go
  • internal/core/limits.go
  • internal/core/records.go
  • internal/core/refusal.go
  • internal/core/said.go
  • internal/core/setting.go
  • internal/core/size.go
  • internal/core/system.go
  • internal/damage/apply.go
  • internal/damage/refusals.go
  • internal/engine/crash.go
  • internal/engine/engine.go
  • internal/engine/errors.go
  • internal/engine/filename.go
  • internal/engine/names.go
  • internal/engine/parallel.go
  • internal/engine/planmemory.go
  • internal/engine/plantarget.go
  • internal/engine/preflight.go
  • internal/engine/record.go
  • internal/format/archive/archive.go
  • internal/format/archive/compression.go
  • internal/format/archive/layout.go
  • internal/format/archive/lock.go
  • internal/format/archive/ownership.go
  • internal/format/avif/avif.go
  • internal/format/avif/codec.go
  • internal/format/bmp/bmp.go
  • internal/format/csvfile/csv.go
  • internal/format/csvfile/dialect.go
  • internal/format/docx/docx.go
  • internal/format/format.go
  • internal/format/gif/animation.go
  • internal/format/gif/gif.go
  • internal/format/htmlfile/html.go
  • internal/format/ico/ico.go
  • internal/format/imagedim/imagedim.go
  • internal/format/jointlimit.go
  • internal/format/jpg/jpg.go
  • internal/format/jsonfile/json.go
  • internal/format/jsonfile/style.go
  • internal/format/jxl/codec.go
  • internal/format/jxl/jxl.go
  • internal/format/logfile/log.go
  • internal/format/logfile/options.go
  • internal/format/md/md.go
  • internal/format/opc/opc.go
  • internal/format/pdf/info.go
  • internal/format/pdf/minimum.go
  • internal/format/pdf/padding.go
  • internal/format/pdf/pdf.go
  • internal/format/pdf/settings.go
  • internal/format/png/png.go
  • internal/format/pptx/pptx.go
  • internal/format/refusals.go
  • internal/format/stated.go
  • internal/format/svgfile/svg.go
  • internal/format/targz/compress.go
  • internal/format/targz/framing.go
  • internal/format/targz/size.go
  • internal/format/targz/targz.go
  • internal/format/textenc/textenc.go
  • internal/format/tiff/tiff.go
  • internal/format/tomlfile/toml.go
  • internal/format/txt/txt.go
  • internal/format/wav/wav.go
  • internal/format/webp/webp.go
  • internal/format/xlsx/xlsx.go
  • internal/format/xmlfile/xml.go
  • internal/format/yamlfile/yaml.go
  • internal/format/zip/children.go
  • internal/format/zip/compress.go
  • internal/format/zip/directories.go
  • internal/format/zip/filler.go
  • internal/format/zip/zip.go
  • internal/guard/archivecompression_test.go
  • internal/guard/archivedepth_test.go
  • internal/guard/archivewording_test.go
  • internal/guard/catalogue_test.go
  • internal/guard/containerentries_test.go
  • internal/guard/embeddedassets_test.go
  • internal/guard/extends_test.go
  • internal/guard/jointlimit_test.go
  • internal/guard/jsonlayout_test.go
  • internal/guard/planmemory_test.go
  • internal/guard/properties_test.go
  • internal/guard/refusaladdress_test.go
  • internal/guard/refusalwords_test.go
  • internal/guard/registrywords_test.go
  • internal/guard/said_test.go
  • internal/guard/settingslot_test.go
  • internal/guard/tableheader_test.go
  • internal/guard/testdata/screens/catalogue.xml
  • internal/guard/testdata/screens/preset-menu.xml
  • internal/guard/textencoding_test.go
  • internal/guard/toolkitwords_test.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/windowwords_test.go
  • internal/gui/catalogue/controls.go
  • internal/gui/catalogue/lists.go
  • internal/gui/parts/fields.go
  • internal/gui/parts/filekind.go
  • internal/gui/parts/listcontents.go
  • internal/gui/parts/menulook.go
  • internal/gui/parts/narrow.go
  • internal/gui/parts/openlist.go
  • internal/gui/parts/property.go
  • internal/gui/parts/ring.go
  • internal/gui/run_cgo.go
  • internal/gui/text/catalogue.go
  • internal/gui/text/locale/en.json
  • internal/gui/text/locale/pl.json
  • internal/gui/text/locale/registry/en.json
  • internal/gui/text/locale/registry/pl.json
  • internal/gui/text/locale/said/en.json
  • internal/gui/text/locale/said/pl.json
  • internal/gui/text/locale/toolkit/en.json
  • internal/gui/text/locale/toolkit/pl.json
  • internal/gui/text/registry.go
  • internal/gui/text/registrywords.go
  • internal/gui/text/said.go
  • internal/gui/text/screens.go
  • internal/gui/text/text.go
  • internal/gui/window/about.go
  • internal/gui/window/generate.go
  • internal/gui/window/preset.go
  • internal/gui/window/recipebase.go
  • internal/gui/window/recipefolds.go
  • internal/gui/window/run.go
  • internal/gui/window/runoutcome.go
  • internal/gui/window/runrefuse.go
  • internal/gui/window/runreport.go
  • internal/gui/window/tools.go
  • internal/gui/window/toolstext.go
  • internal/manifest/manifest.go
  • internal/manifest/reservation.go
  • internal/preset/build.go
  • internal/preset/emptyandminimal.go
  • internal/preset/expansion.go
  • internal/preset/filenamehandling.go
  • internal/preset/limitset.go
  • internal/preset/preset.go
  • internal/preset/read.go
  • internal/preset/sizeboundaries.go
  • internal/preset/tabularimport.go
  • internal/preset/textencoding.go
  • internal/preset/uploadset.go
  • internal/preset/uploadvalidation.go
  • internal/recipe/canonical.go
  • internal/recipe/compose.go
  • internal/recipe/contains.go
  • internal/recipe/damage.go
  • internal/recipe/errors.go
  • internal/recipe/extends.go
  • internal/recipe/limits.go
  • internal/recipe/recipe.go
  • internal/recipe/shape.go
  • internal/recipe/target.go
  • internal/tool/checksum/check.go
  • internal/tool/checksum/refusals.go
  • internal/tool/checksum/sums.go
  • internal/tool/checksum/write.go
  • internal/tool/refusals.go
  • internal/tool/tool.go

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

  • Autopilot · 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

Comment @coderabbitai help to get the list of available commands.

…, a menu born with its placeholder

The parsed-layout cache was a sync.Map, concurrency in a package that has
none. A parse is 141 ns against 16 ns kept, about a tenth of a second on
a million files, so the cache goes.

The name of a list's value agrees with its setting in a language with
grammatical gender (orientacja mieszana, rozmiar mieszany), and its key
already names the setting, so names of values are no longer compared
across settings.

Every menu is made with the window's own placeholder, so the toolkit puts
none in when it is first drawn. The guard for one width before and after
drawing now asserts that, rather than waiting for a placeholder that no
longer arrives.

Switches over a closed set say what happens to the rest, and four helpers
the sentences replaced are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 16911b1 into main Oct 6, 2026
25 checks passed
@donislawdev
donislawdev deleted the gui/said branch October 6, 2026 06:43
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.

1 participant