mirror of
https://github.com/rohitg00/ai-engineering-from-scratch.git
synced 2026-10-02 01:54:39 +08:00
* fix: dark-mode mermaid fills, Apple Silicon Docker build, fnm unzip, ROADMAP rows, site chrome translations - site/lesson.html: mermaidPreprocess handles 3-digit hex fills so fill:#dfd stays legible in dark mode (#433) - 07-docker-for-ai: pin FROM to linux/amd64 and document why the cu124 layer fails on Apple Silicon (#476) - 01-dev-environment: add unzip to the apt line, fnm's installer needs it (#473) - ROADMAP.md: add Phase 11 lessons 16 and 17, 521 rows to 523 - site: translate interface strings for the eight CI languages via ui-i18n.js + ui-strings.js, picker dispatches aifs:lang, drift guarded by test_ui_i18n.js in CI (#469, #404) * docs: describe fnm's unzip check and scope the CUDA image to x86_64 hosts - 01-dev-environment: the installer checks for unzip up front and exits with its own message; macOS goes through Homebrew - 07-docker-for-ai: the linux/amd64 pin means the image is for x86_64 Linux hosts with an NVIDIA GPU * feat(i18n): generate site chrome translations in the translate pipeline The hand dictionary becomes site/ui-strings.json: an English key list plus per-language overrides. scripts/translate_ui_strings.py fills every other key through the lesson translator's provider layer, reuses what is already published, protects file names, paths, and commands behind the same placeholders, and writes i18n/<lang>/ui.json. A new ui-strings job in translate.yml runs it per CI language and publishes to the translations branch with the same race-safe worktree loop, so a new label or a new language needs no translation written by hand. site/ui-i18n.js now fetches i18n/<lang>/ui.json from the translations branch at runtime, caches it per language, and falls back to English until a language is published. Tests cover source consistency, precedence, placeholder protection, the page drift guard, and the fetch path. * fix(i18n): retranslate keys whose override was removed and keep failed dictionary loads retryable - ui.json now carries {strings, pinned}; a key that was pinned in the last publication but has no override now is translated again instead of reusing the old pin - the runtime no longer caches a failed fetch, so a language published later is picked up on the next switch without a reload * fix(i18n): refresh flat ui.json values once when pin provenance is missing A flat published file predates the {strings, pinned} shape and cannot say which values came from overrides, so every value in it counts as pinned and is retranslated on the first run instead of being reused blindly.