Skip to content

window: a Preferences tab - the window's language, and what it keeps between runs - #155

Merged
donislawdev merged 4 commits into
mainfrom
gui/settings
Sep 29, 2026
Merged

donislawdev merged 4 commits into
mainfrom
gui/settings

Conversation

@donislawdev

@donislawdev donislawdev commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

The window gets a fifth tab, Preferences, and speaks Polish as well as English.

Language. The window speaks the language chosen on Preferences, or the system's language when nobody chose one, or English when the window does not have the system's language. On a system set to Polish it now opens in Polish. The choice takes effect the next time the window opens. Restart now closes the window the way the close button does (runs stopped, the output folder written down), and the program starts again only after the window's loop has ended, so the new window reads everything the old one wrote. The button is off while files are being made.

Why not switch in place: the screens ask for their words once, when they are built, and they are built once so a run in flight and everything typed survive moving between tabs. A switch in place would rebuild every screen around its state.

What this window remembers. It says what is kept (output folder, window size, language), shows the folder it is kept in, and Forget clears only this program's own values. After Forget the close writes nothing back. That promise lives in window.Forgetting, where a guard can reach it, not behind cgo.

Polish. All 171 entries of the window's catalogue, with the four plural forms Polish needs. Text that comes from the engine's registries (format settings, presets) stays English for now, since --json reads it too.

Tab identity. The window knew its screens by the translated word on each tab. A translation that called two screens by one word would have merged them for the output folder and the keyboard. parts.Tab now carries an ID.

--pseudo-language opens the window with every word accented and about two fifths longer, to see how a translation sits on each screen before one exists.

The tab is "Preferences" rather than "Settings", because Settings is already the section of the form holding a format's own settings.

Guards: the language rules (pl-PL finds pl, zh-TW does not take simplified Chinese), every catalogue complete in every plural form go-i18n asks for, every letter in both Inter faces (read from their cmap), the pseudo language keeping every value, two tabs with one word staying two screens, and the screen's behaviour: nothing written by opening it, Restart now off while busy and closing the way a person does, Forget writing nothing back. Two new stored screens, and the tab strip on every other one.

How it was checked on the real window (Windows 11, profile redirected so nothing touched a real preferences file): it opened in Polish, English chosen, "Uruchom ponownie" lit, pressed, and a new window opened in English at the same size, with "language":"en" and the output folder in the preferences file.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a Preferences tab where you can choose the window language, open the settings folder, or clear remembered settings.
    • The window follows your system language when available, with English as a fallback. Language changes apply the next time the window opens; you can restart immediately when no files are being made.
    • Added Polish-language support.
    • The app remembers your output folder, window size, and language between runs.
  • Documentation

    • Updated the changelog with details about language selection and remembered settings.

donislawdev and others added 3 commits September 29, 2026 18:17
…eir tab

The window carried the output directory and the keyboard between screens
through maps keyed by each tab's word. A translation may call two screens by
one word, and they would have become one screen to everything keyed that way.
parts.Tab carries an ID beside its text, and every map in open.go is keyed by
it.

TestTwoTabsCalledTheSameAreStillTwoScreens loads a catalogue that gives the
first two tabs one word and moves the directory between them both ways.

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

The window speaks the language chosen on the new Preferences tab, or the
system's language when nobody chose one, or English (docs D9 changed by the
owner on 2026-09-29). Polish is the first language beside English: all 171
entries of the window's catalogue.

The choice takes effect from the next start. The screens ask for their words
once, when they are built, so a switch in place would rebuild every screen
around its state. Restart now closes the window the way the close button
does - runs stopped, the output folder written down - and the program starts
again only after the window's loop has ended, so the new window reads
everything the old one wrote. It stands down while files are being made.

"What this window remembers" says what is kept, where, and offers Forget,
which removes only this program's own values and keeps nothing more at the
close that follows. The promise lives in window.Forgetting, where a guard can
reach it, rather than behind cgo.

--pseudo-language opens the window with every word accented and about two
fifths longer, to see how a translation will sit on each screen.

Tabs are "Preferences" rather than "Settings", because Settings is already
the section of the form holding a format's own settings.

Guards: the language rules, every catalogue complete with every plural form
go-i18n needs, every letter in the Inter faces (read from their cmap), the
pseudo language keeping values, and the screen's behaviour - nothing written
by opening it, Restart now off while busy and closing the way a person does,
Forget writing nothing back. Two new stored screens.

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

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 67a34034-bb1b-4165-940f-0cb497ca01e2

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. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Advanced

Run ID: eb35f233-5f51-4ab8-af0b-f3dd25a9300e

📥 Commits

Reviewing files that changed from the base of the PR and between 36a1dd5 and 1450788.

⛔ Files ignored due to path filters (31)
  • internal/guard/testdata/screens/about.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/catalogue.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-chosen-by-key.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-chosen.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-empty.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-focused.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-hovered.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-menu-hovered.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-menu-keyed.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-menu.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-pdf-settings.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-refused-both.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-refused-setting.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-refused.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-switch-by-key.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-typed.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate-unchecked.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/generate.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preferences-chosen.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preferences.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset-many-settings.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset-menu-setting.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset-menu.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset-refused.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/preset.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe-contents.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe-on-a-preset.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe-refused.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe-two-batches.png is excluded by !**/*.png, !**/*.png
  • internal/guard/testdata/screens/recipe.png is excluded by !**/*.png, !**/*.png
📒 Files selected for processing (54)
  • CHANGELOG.md
  • internal/guard/embeddedassets_test.go
  • internal/guard/notelemetry_test.go
  • internal/guard/preferences_test.go
  • internal/guard/screenpixels_test.go
  • internal/guard/tabidentity_test.go
  • internal/guard/testdata/screens/about.xml
  • internal/guard/testdata/screens/catalogue.xml
  • internal/guard/testdata/screens/generate-chosen-by-key.xml
  • internal/guard/testdata/screens/generate-chosen.xml
  • internal/guard/testdata/screens/generate-empty.xml
  • internal/guard/testdata/screens/generate-focused.xml
  • internal/guard/testdata/screens/generate-hovered.xml
  • internal/guard/testdata/screens/generate-menu-hovered.xml
  • internal/guard/testdata/screens/generate-menu-keyed.xml
  • internal/guard/testdata/screens/generate-menu.xml
  • internal/guard/testdata/screens/generate-pdf-settings.xml
  • internal/guard/testdata/screens/generate-refused-both.xml
  • internal/guard/testdata/screens/generate-refused-setting.xml
  • internal/guard/testdata/screens/generate-refused.xml
  • internal/guard/testdata/screens/generate-switch-by-key.xml
  • internal/guard/testdata/screens/generate-typed.xml
  • internal/guard/testdata/screens/generate-unchecked.xml
  • internal/guard/testdata/screens/generate.xml
  • internal/guard/testdata/screens/preferences-chosen.xml
  • internal/guard/testdata/screens/preferences.xml
  • internal/guard/testdata/screens/preset-many-settings.xml
  • internal/guard/testdata/screens/preset-menu-setting.xml
  • internal/guard/testdata/screens/preset-menu.xml
  • internal/guard/testdata/screens/preset-refused.xml
  • internal/guard/testdata/screens/preset.xml
  • internal/guard/testdata/screens/recipe-contents.xml
  • internal/guard/testdata/screens/recipe-on-a-preset.xml
  • internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
  • internal/guard/testdata/screens/recipe-refused.xml
  • internal/guard/testdata/screens/recipe-two-batches.xml
  • internal/guard/testdata/screens/recipe.xml
  • internal/guard/window_test.go
  • internal/guard/windowlanguage_test.go
  • internal/gui/again.go
  • internal/gui/catalogue/lists.go
  • internal/gui/gui.go
  • internal/gui/parts/tabs.go
  • internal/gui/run_cgo.go
  • internal/gui/text/catalogue.go
  • internal/gui/text/languages.go
  • internal/gui/text/locale/en.json
  • internal/gui/text/locale/pl.json
  • internal/gui/text/screens.go
  • internal/gui/window/generate.go
  • internal/gui/window/open.go
  • internal/gui/window/preferences.go
  • internal/gui/window/remembered.go
  • internal/gui/window/runbusy.go

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

📜 Recent review details
⏰ Context from checks skipped due to timeout. (20)
  • GitHub Check: race detector (part 2 of 4)
  • GitHub Check: race detector (part 3 of 4)
  • GitHub Check: race detector (part 1 of 4)
  • GitHub Check: race detector (part 0 of 4)
  • GitHub Check: coverage gate
  • GitHub Check: known vulnerabilities
  • GitHub Check: reference tools actually installed
  • GitHub Check: semgrep
  • GitHub Check: staticcheck
  • GitHub Check: the installer installs and leaves
  • GitHub Check: linters
  • GitHub Check: test on windows-latest
  • GitHub Check: bill of materials
  • GitHub Check: import table of the window binary
  • GitHub Check: test on ubuntu-latest
  • GitHub Check: test on macos-latest
  • GitHub Check: the Chocolatey packages install and leave
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (actions)
🧰 Additional context used
📓 Path-based instructions (14)
Applies to text shown to the user (labels, buttons, tooltips, placeholders, dialogs, errors, status messages, empty states, translations).

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/text/locale/pl.json
  • internal/gui/parts/tabs.go
  • internal/gui/text/locale/en.json
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Verify tests check real behavior and would fail if the implementation were broken.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/guard/preferences_test.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
These are end-user desktop applications.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Performance is a known weak spot of these projects.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Applies only to code that builds or styles a GUI.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
User-facing changelog.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
Domain: test file generator (Go; `tfg` CLI and `tfg-gui` Fyne window over one engine).

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/testdata/screens/generate-chosen-by-key.xml
  • internal/guard/notelemetry_test.go
  • internal/guard/testdata/screens/generate-empty.xml
  • internal/guard/testdata/screens/generate-focused.xml
  • internal/guard/testdata/screens/generate-refused-setting.xml
  • internal/guard/testdata/screens/recipe-refused.xml
  • internal/guard/testdata/screens/about.xml
  • internal/guard/testdata/screens/generate-chosen.xml
  • internal/guard/testdata/screens/preset-refused.xml
  • internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
  • internal/guard/testdata/screens/generate-pdf-settings.xml
  • internal/guard/testdata/screens/generate-menu.xml
  • internal/guard/testdata/screens/generate-refused.xml
  • internal/guard/testdata/screens/generate.xml
  • internal/guard/testdata/screens/generate-switch-by-key.xml
  • internal/guard/testdata/screens/recipe-two-batches.xml
  • internal/guard/testdata/screens/recipe.xml
  • internal/guard/testdata/screens/generate-menu-keyed.xml
  • internal/guard/screenpixels_test.go
  • internal/guard/testdata/screens/generate-unchecked.xml
  • internal/guard/testdata/screens/preset-menu-setting.xml
  • internal/guard/testdata/screens/generate-typed.xml
  • internal/guard/testdata/screens/recipe-contents.xml
  • internal/guard/testdata/screens/catalogue.xml
  • internal/guard/testdata/screens/preset-many-settings.xml
  • internal/guard/testdata/screens/generate-menu-hovered.xml
  • internal/guard/testdata/screens/generate-refused-both.xml
  • internal/guard/testdata/screens/preset-menu.xml
  • internal/gui/text/locale/pl.json
  • internal/guard/testdata/screens/recipe-on-a-preset.xml
  • internal/gui/parts/tabs.go
  • internal/guard/testdata/screens/generate-hovered.xml
  • internal/gui/text/locale/en.json
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/guard/testdata/screens/preset.xml
  • internal/guard/testdata/screens/preferences.xml
  • internal/guard/testdata/screens/preferences-chosen.xml
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
SECURITY, HIGH PRIORITY.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
These apps are QA/developer tools.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Go code.

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/notelemetry_test.go
  • internal/guard/screenpixels_test.go
  • internal/gui/parts/tabs.go
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Check that documentation matches the actual code in this PR: commands, flags, config keys, file paths, build steps and examples must exist.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
All code in this repository is written by an AI coding agent (Claude Code).

⚙️ CodeRabbit configuration file

Files:

  • internal/guard/testdata/screens/generate-chosen-by-key.xml
  • internal/guard/notelemetry_test.go
  • internal/guard/testdata/screens/generate-empty.xml
  • internal/guard/testdata/screens/generate-focused.xml
  • internal/guard/testdata/screens/generate-refused-setting.xml
  • internal/guard/testdata/screens/recipe-refused.xml
  • internal/guard/testdata/screens/about.xml
  • internal/guard/testdata/screens/generate-chosen.xml
  • internal/guard/testdata/screens/preset-refused.xml
  • internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
  • internal/guard/testdata/screens/generate-pdf-settings.xml
  • internal/guard/testdata/screens/generate-menu.xml
  • internal/guard/testdata/screens/generate-refused.xml
  • internal/guard/testdata/screens/generate.xml
  • internal/guard/testdata/screens/generate-switch-by-key.xml
  • internal/guard/testdata/screens/recipe-two-batches.xml
  • internal/guard/testdata/screens/recipe.xml
  • internal/guard/testdata/screens/generate-menu-keyed.xml
  • internal/guard/screenpixels_test.go
  • internal/guard/testdata/screens/generate-unchecked.xml
  • CHANGELOG.md
  • internal/guard/testdata/screens/preset-menu-setting.xml
  • internal/guard/testdata/screens/generate-typed.xml
  • internal/guard/testdata/screens/recipe-contents.xml
  • internal/guard/testdata/screens/catalogue.xml
  • internal/guard/testdata/screens/preset-many-settings.xml
  • internal/guard/testdata/screens/generate-menu-hovered.xml
  • internal/guard/testdata/screens/generate-refused-both.xml
  • internal/guard/testdata/screens/preset-menu.xml
  • internal/gui/text/locale/pl.json
  • internal/guard/testdata/screens/recipe-on-a-preset.xml
  • internal/gui/parts/tabs.go
  • internal/guard/testdata/screens/generate-hovered.xml
  • internal/gui/text/locale/en.json
  • internal/gui/window/generate.go
  • internal/gui/catalogue/lists.go
  • internal/guard/testdata/screens/preset.xml
  • internal/guard/testdata/screens/preferences.xml
  • internal/guard/testdata/screens/preferences-chosen.xml
  • internal/gui/window/runbusy.go
  • internal/guard/tabidentity_test.go
  • internal/guard/embeddedassets_test.go
  • internal/gui/again.go
  • internal/guard/preferences_test.go
  • internal/gui/window/remembered.go
  • internal/gui/gui.go
  • internal/gui/text/languages.go
  • internal/gui/run_cgo.go
  • internal/gui/text/screens.go
  • internal/gui/window/preferences.go
  • internal/gui/text/catalogue.go
  • internal/guard/windowlanguage_test.go
  • internal/guard/window_test.go
  • internal/gui/window/open.go
Safe file parsing: Warn if the PR reads, imports or exports files (XML, XAML, CSV, XLSX, JSON, YAML, translations, themes, settings, archives) in a way that could execute code or formulas, resolve external entities, deserialize arbitrary ty...

📄 CodeRabbit inference engine (Custom checks)

Files:

  • internal/gui/text/locale/en.json
Source excerpt: **Words a user reads are English, with a flat hyphen and no semicolons.**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • CHANGELOG.md
🔇 Additional comments (47)
internal/gui/text/locale/pl.json (1)

64-65: Fix the Polish other plural form.

For integer counts, Polish uses only one, few and many. go-i18n uses other only for fractional counts, so {{.Count}} pliku is correct for those. The form set is complete as written, so no change is needed.

internal/gui/window/preferences.go (1)

179-189: Two languages that share a Name overwrite each other in tagOf.

tagOf is keyed by the display name. Suppose two carried catalogues report the same name. This happens when both fall back to the tag, or when one catalogue name equals the "Same as the system (…)" string. Choosing either entry then saves the wrong tag. A guard already rejects duplicate catalogue names, so the only remaining case is a collision with the first option. The collision is unlikely, and no change is needed now.

internal/gui/gui.go (1)

48-64: LGTM!

Also applies to: 77-78

internal/gui/text/catalogue.go (1)

219-242: LGTM!

internal/gui/text/locale/en.json (1)

428-467: LGTM!

internal/gui/text/screens.go (1)

734-829: LGTM!

internal/guard/windowlanguage_test.go (1)

30-57: LGTM!

internal/guard/embeddedassets_test.go (1)

142-144: LGTM!

internal/gui/window/generate.go (1)

137-155: LGTM!

internal/gui/window/remembered.go (1)

64-92: LGTM!

internal/gui/again.go (1)

57-68: LGTM!

internal/gui/catalogue/lists.go (1)

104-128: LGTM!

internal/guard/window_test.go (1)

409-458: LGTM!

internal/guard/notelemetry_test.go (1)

318-318: LGTM!

internal/gui/parts/tabs.go (1)

15-22: LGTM!

internal/gui/window/open.go (1)

135-142: LGTM!

internal/gui/window/runbusy.go (1)

99-103: LGTM!

internal/guard/preferences_test.go (1)

95-131: LGTM!

internal/guard/tabidentity_test.go (1)

56-95: LGTM!

internal/guard/screenpixels_test.go (1)

315-321: LGTM!

internal/guard/testdata/screens/about.xml (1)

23-33: LGTM!

internal/guard/testdata/screens/catalogue.xml (1)

1736-1741: LGTM!

internal/guard/testdata/screens/generate-chosen-by-key.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-chosen.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-empty.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-focused.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-hovered.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-menu-hovered.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-menu-keyed.xml (1)

23-28: LGTM!

internal/gui/run_cgo.go (1)

449-455: 🩺 Stability & Availability

The comment is undecidable from the available source. The restart path calls startInstead after a.Run returns, but the inspected application code does not establish whether Fyne has flushed its preference writes at that point. The Fyne implementation or an applicable version-specific contract for a.Run and preferences is required before recommending a synchronization change.

internal/guard/testdata/screens/generate-typed.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate-unchecked.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/generate.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/preferences-chosen.xml (1)

1-169: LGTM!

internal/guard/testdata/screens/preferences.xml (1)

1-169: LGTM!

internal/guard/testdata/screens/preset-many-settings.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/preset-menu-setting.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/preset-menu.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/preset-refused.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/preset.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe-contents.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe-on-a-preset.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe-refused.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe-two-batches.xml (1)

23-28: LGTM!

internal/guard/testdata/screens/recipe.xml (1)

23-28: LGTM!

CHANGELOG.md (1)

19-28: LGTM!


📝 Walkthrough

Walkthrough

The window adds English and Polish language catalogues, language selection, pseudo-localization, and a Preferences tab. It persists language choices and remembered settings, supports clearing those settings, and can restart to apply a language change.

Changes

Window language and Preferences

Layer / File(s) Summary
Language catalogues and localization
internal/gui/text/*, internal/gui/gui.go, internal/guard/windowlanguage_test.go, internal/guard/embeddedassets_test.go
The window discovers and resolves supported languages, loads English and Polish text, and supports pseudo-localization through --pseudo-language. Tests check language resolution, catalogue coverage, plural forms, font glyphs, and pseudo-localized rendering.
Remembered settings and restart lifecycle
internal/gui/window/generate.go, internal/gui/window/remembered.go, internal/gui/run_cgo.go, internal/gui/again.go, internal/guard/window_test.go, internal/guard/notelemetry_test.go
The host persists language choices and exposes the settings folder and system language. Forget clears the application’s directory, size, and language settings. A scheduled restart runs after the window closes, using the original arguments.
Preferences screen and tab integration
internal/gui/window/preferences.go, internal/gui/window/open.go, internal/gui/window/runbusy.go, internal/gui/parts/tabs.go, internal/guard/preferences_test.go, internal/guard/tabidentity_test.go, internal/guard/screenpixels_test.go, internal/gui/catalogue/lists.go, internal/guard/testdata/screens/*, CHANGELOG.md
The new Preferences tab provides language selection, restart, settings-folder, and Forget controls. Stable tab IDs keep per-tab state distinct when translated labels match. Tests and screen fixtures cover the screen, tab behavior, restart availability, and forgetting settings.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  actor Person
  participant Preferences
  participant Remembered
  participant desktop
  participant startInstead
  Person->>Preferences: Select a language
  Preferences->>Remembered: Save language choice
  Person->>Preferences: Request restart
  Preferences->>desktop: Schedule restart after window closes
  Preferences->>Preferences: Leave window through close callback
  desktop->>startInstead: Relaunch with original arguments after event loop
Loading

Suggested labels: enhancement, ui, bug, security

Merge Risk: ⚪ Minimal · up to 14507

The shipped languages are valid, and the saved language is flushed before the window restarts on the inspected desktop path. No identified issue blocks merging after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 14507

The reviewed desktop flows clear only this program’s saved settings and wait for active work to stop before restarting. No introduced security issue was identified, but persistence failures and other platform paths remain less certain.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The inspected settings and restart controls operate within the local desktop process and its application preferences. The available evidence does not establish a new remote or cross-service entry path.

Trust Boundaries and Controls

  • observed — A user-selected language is written to application preferences. Restart does not rely solely on the button’s enabled state: its action rechecks whether work is busy and whether a language change is pending.

Resilience and Maintainability Implications

  • observed — The post-Forget write guard is run-scoped. A restarted process constructs a fresh wrapper, consistent with the stated contract rather than a permanent opt-out.
🚥 Pre-merge checks | ✅ 11 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Desktop Robustness ⚠️ Warning The PR adds a destructive Forget action without confirmation. The Forget button calls forgetNow directly, and forgetNow immediately removes the remembered directory, size, and language. The PR als… Add a confirmation dialog and call Forget only after confirmation. Move all application-owned preference writes, including the new language value, to an atomic persistence path that writes a temporary file, syncs it, and renames it into p…
Clear User-Facing Text ⚠️ Warning The PR adds a restart failure message that displays the raw process error. run_cgo.go passes err.Error() directly to PreferencesRestartFailed, which renders it in the dialog and terminal. This v… Replace the restart failure text with a user-facing message that states the failure and next action without inserting err.Error(), for example: “The window could not restart. Your language choice was saved. Start the program manually to a…
Scope, Duplication And Docs ⚠️ Warning The PR adds the fifth Preferences tab and the --pseudo-language CLI flag, but README.md is unchanged. Its desktop-window section still says “Four screens” and does not document Preferences or the … Update README.md to describe five screens, the Preferences behavior, and --pseudo-language. Add the pseudo-language option to the relevant CHANGELOG.md entry if the changelog is intended to document all user-facing CLI changes.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the Preferences tab, window language support, and persisted settings. It is specific, user-focused, and within the length limit.
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.
Tests For Changed Behavior ✅ Passed The PR adds and updates tests for its non-UI runtime behavior. preferences_test.go covers language persistence, missing-language handling, busy-state restart disabling, clean close behavior, and For…
No Secrets Or Debug Leftovers ✅ Passed No prohibited agent files or .env files were added. Scans found no credentials, tokens, private URLs, user names, internal hosts, IPs, or personal emails. The added fmt.Fprintln calls report catal…
No Hardcoded Ui Styling ✅ Passed The PR adds GUI code, but the new Preferences screen uses shared parts components and tokens: parts.NewButton, parts.Menu, parts.Section, parts.Grid, parts.Prose, parts.ButtonRow, and `p…
No Obvious Performance Problems ✅ Passed No clear performance problem is introduced. The new language discovery reads only the two small embedded locale files at startup, and the Preferences chooser contains the available language entries wi…
Safe File Parsing ✅ Passed No unsafe file parsing was introduced. The new translation discovery reads only the compiled-in embed.FS with fs.ReadDir/fs.ReadFile; encoding/json.Unmarshal targets json.RawMessage and a st…
System Changes Are Reversible ✅ Passed The changed code only persists application preferences and restarts the application itself. The diff adds no network filter, proxy, firewall, system-time, process-hook/injection, Windows-service, regi…
No Resource Leaks ✅ Passed No resource leak was introduced. The new asynchronous process path calls cmd.Process.Release() after cmd.Start(), while the existing synchronous path uses cmd.Run(). The new language catalogue u…
Full details: Desktop Robustness

Explanation

The PR adds a destructive Forget action without confirmation. The Forget button calls forgetNow directly, and forgetNow immediately removes the remembered directory, size, and language. The PR also adds new language persistence through Fyne SetString/RemoveValue; Fyne writes preferences.json with os.Create and direct JSON encoding, so these new settings writes are non-atomic. A corrupted file is handled by Fyne with logged defaults, so no crash condition was found. Embedded catalogues avoid working-directory asset loads, and no new network or unbounded background operation was found.

Resolution

Add a confirmation dialog and call Forget only after confirmation. Move all application-owned preference writes, including the new language value, to an atomic persistence path that writes a temporary file, syncs it, and renames it into place. Handle missing or invalid data by logging and using defaults.

Full details: Clear User-Facing Text

Explanation

The PR adds a restart failure message that displays the raw process error. run_cgo.go passes err.Error() directly to PreferencesRestartFailed, which renders it in the dialog and terminal. This violates the requirement that user-facing errors must not show raw exceptions. The new Preferences UI also names the output location as “the folder the files went to”, while existing user-facing text calls it “Output directory” and “output folder”.

Resolution

Replace the restart failure text with a user-facing message that states the failure and next action without inserting err.Error(), for example: “The window could not restart. Your language choice was saved. Start the program manually to apply it.” Use one consistent term, preferably “output directory”, for the remembered output location across the Preferences text, existing fields, and changelog.

Full details: Scope, Duplication And Docs

Explanation

The PR adds the fifth Preferences tab and the --pseudo-language CLI flag, but README.md is unchanged. Its desktop-window section still says “Four screens” and does not document Preferences or the new flag. CHANGELOG.md describes the Preferences feature but does not document --pseudo-language or correct the stale README claim.


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.

@coderabbitai coderabbitai Bot added bug Something isn't working enhancement New feature or request security ui labels Sep 29, 2026
The list of tabs the guards walk named four screens, so thirteen guards
passed without looking at the fifth. With Preferences on it, two
exemptions are named and held both ways: that screen carries no Donate
button, and its one menu stands beside no box to type in.

The tab ids, the language key and --pseudo-language are not words a
person reads. pseudoOf and run were split to stay under the ceilings on
depth and length.

From the review: the sentence after a failed restart asked to close a
window that is already gone, the remembered folder is called by the name
on its field, and the README names five screens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 1f800cc into main Sep 29, 2026
25 checks passed
@donislawdev
donislawdev deleted the gui/settings branch September 29, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request security ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant