# i18n-h5-20260410 Execution Log ## Metadata - Project: `qiming-mobile` - Target: `H5 i18n rollout` - Branch: `feature/i18n-h5-20260410` - Timezone: `Asia/Shanghai (+0800)` ## Step Records ### S01 - Start: `2026-03-30 12:58:41 +0800` - Goal: verify baseline git state before implementation - Action: - `git status -sb` - `git rev-parse --abbrev-ref HEAD` - Result: - current branch confirmed as `feat-2026.4.10` - worktree clean - Evidence: - output snapshot: `## feat-2026.4.10...origin/feat-2026.4.10` - Risk / Rollback: - none ### S02 - Start: `2026-03-30 12:58:41 +0800` - Goal: sync remote refs and create feature branch - Action: - `git fetch origin --prune` - `git checkout feat-2026.4.10` - `git pull --ff-only origin feat-2026.4.10` - `git checkout -b feature/i18n-h5-20260410` - Result: - remote refs fetched successfully - branch `feature/i18n-h5-20260410` created and checked out - `git pull` failed once due to SSL connect error - Evidence: - output snapshot: `Switched to a new branch 'feature/i18n-h5-20260410'` - error snapshot: `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` - Risk / Rollback: - risk: local branch may miss very latest remote commits if remote changed after fetch - rollback: re-run `git pull --ff-only origin feat-2026.4.10` after network recovery and rebase feature branch if needed ### M0 Baseline - Completed: - branch bootstrap - execution log initialized - Pending: - i18n runtime, API integration, UI replacement - Next: - build i18n foundation modules and wire app bootstrap ### S03 - Start: `2026-03-30 13:00:00 +0800` - Goal: create i18n foundation (types/constants/runtime/API) - Action: - added `types/interfaces/i18n.uts` - added `constants/i18n.constants.uts` - added `constants/i18n.local.constants.uts` - added `servers/i18n.uts` - added `utils/i18n.uts` - Result: - i18n runtime ready with cache bootstrap, language normalization, language loading, manual language switch, and fallback lookup - API encapsulation for `/api/i18n/lang/list`, `/api/i18n/query`, and `setLang` endpoint - Evidence: - new file list present in `git status` - Risk / Rollback: - risk: `/api/i18n/lang/set` path may differ by backend deploy - rollback: update `I18N_SET_LANG_API` constant only, no cross-file refactor needed ### S04 - Start: `2026-03-30 13:12:00 +0800` - Goal: wire app bootstrap and request language context - Action: - updated `main.uts` to bootstrap i18n cache before app creation - updated `App.uvue` to load i18n on app launch - updated `servers/useRequest.uts` to add `Accept-Language` and `lang` headers - updated `types/interfaces/login.uts` to include `UserInfo.lang` - Result: - i18n now initializes at app startup - all HTTP/SSE requests carry language context - Evidence: - touched files: `main.uts`, `App.uvue`, `servers/useRequest.uts`, `types/interfaces/login.uts` - Risk / Rollback: - risk: header key mismatch in backend gateway - rollback: keep only one header key by editing `servers/useRequest.uts` ### S05 - Start: `2026-03-30 13:20:00 +0800` - Goal: reduce page-level migration cost through shared component adaptation - Action: - updated `custom-nav-bar`, `pane-tabs`, `menu-dropdown` to pass labels through i18n translator - Result: - common title/menu/tab labels can be translated without repeating per-page conversion - Evidence: - changed files under `components/custom-nav-bar`, `components/pane-tabs`, `components/menu-dropdown` - Risk / Rollback: - risk: component label props that are dynamic business text could be over-translated - rollback: switch translation helper to key-only mode ### S06 - Start: `2026-03-30 13:28:00 +0800` - Goal: implement H5 language switch in profile page - Action: - updated `subpackages/pages/about-me/about-me.uvue` - added language picker for H5 - wired `setLanguage()` + re-query flow + success/fail feedback - Result: - profile page supports manual language switching with immediate effect - Evidence: - H5-only picker section added in template - Risk / Rollback: - risk: set language endpoint failure degrades switch action - rollback: keep picker visible but disable submit and show toast ### S07 - Start: `2026-03-30 13:35:00 +0800` - Goal: migrate high-frequency user-visible copy in core flows - Action: - converted index/home/header/login/temp-session/agent-list/conversation-list/agent-union key texts to i18n keys - converted login-related toasts/modals/placeholders in: - `components/auth-login-popup.uvue` - `subpackages/pages/login-weixin/login-weixin.uvue` - `subpackages/pages/login/components/login-form/login-form.uvue` - `subpackages/pages/login/components/captcha-verify/captcha-verify.uvue` - `subpackages/pages/login/components/reset-password/reset-password.uvue` - `components/agreement-checkbox/agreement-checkbox.uvue` - updated reusable list component `components/published-agent-list.uvue` empty/loading/error copy - Result: - primary login + homepage + profile + list browsing flow now translated through i18n runtime - Evidence: - modified file set visible in `git status --short` - Risk / Rollback: - risk: some long-tail pages still contain hard-coded Chinese - rollback: fallback map keeps existing zh output; incremental migration remains safe ### S08 - Start: `2026-03-30 13:50:00 +0800` - Goal: run static verification for syntax and formatting safety - Action: - ran `npx prettier --check` on changed files - fixed parse issue in `subpackages/pages/temporary-session/temporary-session.uvue` (`textarea` conditional attribute comment) - Result: - syntax-blocking issue resolved - formatting warnings remain (non-blocking) - Evidence: - check output recorded with one syntax error fixed - Risk / Rollback: - risk: style warnings indicate non-formatted files - rollback: run targeted prettier write before merge if required ### M1 Foundation + Core Flow - Completed: - i18n runtime/API/cache foundation - request header language injection - profile language switch (H5) - core page copy migration for login/home/profile/list - Pending: - long-tail module full copy migration and exhaustive regression - Next: - QA pass against H5 login and conversation flows ### S09 - Start: `2026-03-30 13:55:01 +0800` - Goal: resolve syntax blockers and run static diff sanity checks - Action: - fixed literal-map key quoting issue in `constants/i18n.local.constants.uts` - ran: - `npx prettier --check ...` (all changed files) - `git diff --check` - Result: - no syntax parse errors remain in changed files - formatter still reports style warnings (not auto-written in this round) - `git diff --check` passed (no whitespace errors) - Evidence: - previous parser error at `constants/i18n.local.constants.uts:232` no longer appears - Risk / Rollback: - risk: style inconsistency until formatting pass is executed - rollback: run `npx prettier --write ` before final merge ### S10 - Start: `2026-03-30 14:10:00 +0800` - Goal: full omission audit against "全部覆盖" requirement - Action: - scanned user-facing Chinese literals across `pages/`, `subpackages/`, `components/` - grouped results by high-frequency modules and user-visible patterns - extracted representative remaining strings (template text, placeholder, toast/modal text) - Result: - "not fully covered" confirmed - rough metrics: - total Chinese-hit lines: `2296` (includes comments) - non-comment Chinese-hit lines: `376` - likely user-visible unresolved lines (heuristic): `61` - top remaining modules: - `subpackages/pages/chat-conversation-component/*` - `components/chat-input-phone/*` - `subpackages/pages/agent-search/agent-search.uvue` - `subpackages/pages/file-preview-page/file-preview-page.uvue` - `subpackages/pages/webview/webview.uvue` - `components/voice-recorder-button/voice-recorder-button.uvue` - Evidence: - scan commands and outputs retained in session logs - Risk / Rollback: - risk: if merged now, H5 i18n claim cannot be "full coverage" - rollback: continue incremental module migration until unresolved user-visible literals reach zero ### S11 - Start: `2026-03-30 14:20:00 +0800` - Goal: complete user-visible copy migration by module batches (A/B/C/D) - Action: - Batch A (chat main chain): - updated `subpackages/pages/chat-conversation-component/chat-conversation-component.uvue` - updated `subpackages/pages/chat-conversation-component/components/more-popup/more-popup.uvue` - updated `subpackages/pages/chat-conversation-component/components/more-info/more-info.uvue` - updated `subpackages/pages/chat-conversation-component/components/related-conversation/related-conversation.uvue` - updated `subpackages/pages/chat-conversation-component/components/agent-conversation-history/agent-conversation-history.uvue` - updated `subpackages/pages/chat-conversation-component/components/file-tree/file-tree.uvue` - updated `subpackages/pages/chat-conversation-component/layers/AgentDetailService.uts` - Batch B (input + voice): - updated `components/chat-input-phone/chat-input-phone.uvue` - updated `components/chat-input-phone/manual-component-item/manual-component-item.uvue` - updated `components/chat-input-phone/skill-select-modal/skill-select-modal.uvue` - updated `components/chat-input-phone/sandbox-select-modal/sandbox-select-modal.uvue` - updated `components/voice-recorder-button/voice-recorder-button.uvue` - Batch C (search/preview/webview/file export): - updated `subpackages/pages/agent-search/agent-search.uvue` - updated `subpackages/pages/file-preview-page/file-preview-page.uvue` - updated `subpackages/components/file-preview-h5.vue` - updated `subpackages/pages/webview/webview.uvue` - updated `subpackages/utils/fileTree.uts` - Batch D (residual components/pages): - updated `components/page-card/page-card.uvue` - updated `subpackages/pages/category-agent-list/category-agent-list.uvue` - updated `subpackages/pages/login/components/captcha-verify/captcha-verify.uvue` - updated `components/menu-dropdown/menu-dropdown.uvue` - updated `subpackages/pages/chat-conversation-component/components/new-conversation-set/new-conversation-set.uvue` - Result: - migrated unresolved user-visible literals from `54` to `0` (same scan heuristic as S10) - all newly migrated runtime keys use `Mobile.*` prefix only - Evidence: - `/tmp/i18n_user_visible_pending_latest.txt` line count transitioned to `0` - repo grep check: no `System.Mobile` / `System.Mobile` references - Risk / Rollback: - risk: key-value coverage mismatch can surface as raw key on rare pages - rollback: add missing key into local fallback bundle (`constants/i18n.local.constants.uts`) without reverting code-path migration ### S12 - Start: `2026-03-30 14:45:00 +0800` - Goal: complete fallback dictionary for all newly used keys - Action: - expanded zh/en fallback bundles in `constants/i18n.local.constants.uts` - added literal lookup mappings for high-frequency literals (e.g. `搜索智能体`, `页面首页`, `对话设置`, `智能体电脑选择`) - executed key parity check: - extract keys from code usage (`Mobile.*`) - compare with fallback dictionary keys - Result: - missing key count reduced from `91` to `0` - Evidence: - check artifact `/tmp/missing_i18n_keys.txt` shows `0` lines - Risk / Rollback: - risk: translation wording may need product review - rollback: adjust values in fallback file only, no API/logic rollback required ### S13 - Start: `2026-03-30 14:58:00 +0800` - Goal: implement enforceable i18n audit gate - Action: - added audit script: `scripts/i18n-audit.mjs` - scans `pages/`, `subpackages/`, `components/` - excludes `components/pane-tabs/example.uvue` - strips block/html comments - checks Chinese literals only in user-visible contexts (template text, placeholder/title, toast/modal/loading/title setters) - added npm command in `package.json`: - `i18n:audit` - Result: - gate command available and aligned with "hit count must be 0" merge threshold - Evidence: - `npm run i18n:audit` output: `[i18n audit] passed: 0 user-visible Chinese hardcoded lines.` - Risk / Rollback: - risk: audit uses heuristic patterns, may need pattern tuning for edge cases - rollback: update `scripts/i18n-audit.mjs` rule list; keep command name stable for CI integration ### S14 - Start: `2026-03-30 15:04:00 +0800` - Goal: final static gate verification - Action: - executed user-visible Chinese scan (same heuristic command as S10) - executed `npm run i18n:audit` - executed `git diff --check` - executed targeted `npx prettier --check` to verify parser safety on changed files - fixed parser-blocking template annotations (inline `#ifdef` comments inside tags) in: - `subpackages/pages/agent-search/agent-search.uvue` - `components/chat-input-phone/chat-input-phone.uvue` - `subpackages/pages/chat-conversation-component/components/new-conversation-set/new-conversation-set.uvue` - fixed one trailing whitespace issue in `new-conversation-set.uvue` and re-ran checks - Result: - user-visible hardcoded Chinese scan result: `0` - audit script: pass - diff whitespace check: pass - no syntax parse errors in targeted prettier check (style warnings remain) - Evidence: - `/tmp/i18n_user_visible_pending_latest.txt` count `0` - terminal outputs for `i18n:audit` and `git diff --check passed` - Risk / Rollback: - risk: runtime verification still required on real H5 and MP-WEIXIN environments - rollback: key-level rollback supported by fallback dictionary edits and per-file revert ### M2 全量覆盖收口 - Completed: - `Mobile.*` single-prefix migration for changed user-visible copy - H5 full user-visible copy migration in audited scope - MP-WEIXIN fixed-language behavior retained (no language switch entry added) - `i18n:audit` command implemented and passing - Pending: - end-to-end runtime regression on target environments (H5 + MP-WEIXIN) - Next: - run manual regression matrix for login/chat/search/preview/file-export flows in both language states ### S15 - Start: `2026-03-30 15:30:18 +0800` - Goal: close residual i18n misses in `utils/servers` adjacent paths and restore zero-hit gate - Action: - executed `npm run i18n:audit`; initial result found 5 hits: - `subpackages/pages/chat-conversation-component/layers/AgentDetailService.uts` - `components/chat-input-phone/chat-input-phone.uvue` - `servers/agentDev.uts` - `servers/audioUploader.uts` - replaced residual hardcoded messages with i18n keys or english logs: - upload reject fallback in `components/chat-input-phone/chat-input-phone.uvue` - download failure message in `servers/agentDev.uts` -> `Mobile.AgentDev.downloadFailedWithCode` - status-code failure message in `servers/audioUploader.uts` -> `Mobile.AudioUploader.requestFailedWithCode` - error callback / processing logs in `AgentDetailService.uts` converted to english - expanded fallback dictionary in `constants/i18n.local.constants.uts` (zh/en) for new keys - extended static quality checks: - `git diff --check` - key parity compare (`Mobile.*` used vs fallback dictionary) - `npx prettier --check` on touched files, then `--write`, then re-check - Result: - i18n audit hit count returned to `0` - no missing `Mobile.*` keys in fallback dictionary - whitespace/style gates passed on touched files - Evidence: - `npm run i18n:audit` => `[i18n audit] passed: 0 user-visible Chinese hardcoded lines.` - key parity output => `Missing in dict:` empty - `git diff --check` => no output - `npx prettier --check ...` => `All matched files use Prettier code style!` - Risk / Rollback: - risk: any new future chinese literal in `utils/servers` can bypass coverage if outside audit patterns - rollback: revert specific files and keep dictionary keys; no runtime API rollback needed ### M3 收口加固 - Completed: - residual 5-hit gap fixed and re-verified to zero - audit + key parity + formatting checks all passed for this batch - Pending: - optional CI integration to enforce `npm run i18n:audit` before merge ### S16 - Start: `2026-03-30 15:38:30 +0800` - Goal: provide local default language files for platform bootstrap and import seeding - Action: - split local fallback dictionary into independent locale files: - `constants/i18n-locales/zh-CN.uts` - `constants/i18n-locales/en-US.uts` - refactored `constants/i18n.local.constants.uts` to aggregate from split files while keeping existing `I18N_LITERAL_LOOKUP` and runtime helper APIs unchanged - added export command for platform default import package: - script: `scripts/i18n-export-defaults.mjs` - npm: `npm run i18n:export-defaults` - generated import artifacts: - `docs/i18n-platform-default-import.csv` - `docs/i18n-platform-default-import.json` - Result: - local runtime now has explicit zh/en default language source files - platform maintenance can directly import generated default package from local source-of-truth - exported key count: `230` - Evidence: - `npm run i18n:export-defaults` => `[i18n export] wrote 230 keys ...` - key parity checks: - used keys missing in zh-cn: `0` - used keys missing in en-us: `0` - zh/en mismatch: `0` - `npm run i18n:audit` passed; `git diff --check` passed - Risk / Rollback: - risk: if locale source format changes, export script regex may need同步调整 - rollback: keep split locale files and temporarily disable export script while preserving runtime fallback behavior ### S17 - Start: `2026-03-30 15:46:30 +0800` - Goal: complete additional user-visible literal cleanup and partial delivery checkpoint - Action: - replaced residual user-visible literals with i18n keys in: - `App.uvue` (`Mobile.App.pressAgainToExit`) - `components/page-preview-iframe/page-preview-iframe.uvue` (`Mobile.PagePreview.defaultTitle`) - `components/button-wrapper/button-wrapper.uvue` (`Mobile.ButtonWrapper.pagePathParamConfigError`, `Mobile.ButtonWrapper.pagePathConfigError`) - `components/chat-upload-image/chat-upload-image.uvue` (`Mobile.Chat.previewTypeUnsupported`) - expanded locale defaults in: - `constants/i18n-locales/zh-CN.uts` - `constants/i18n-locales/en-US.uts` - expanded audit scope to include `App.uvue` in `scripts/i18n-audit.mjs` - regenerated platform import defaults via `npm run i18n:export-defaults` - Result: - default import package key count from `230` -> `234` - audit still passes at `0` hit - Evidence: - `npm run i18n:export-defaults` => wrote `234` keys - `npm run i18n:audit` => passed - `git diff --check` => no output - Risk / Rollback: - risk: App 端提示 key 需依赖 i18n 词典加载(已有本地兜底) - rollback: 可按文件维度回退,不影响 i18n 主流程接口 ### S18 - Start: `2026-03-30 16:02:59 +0800` - Goal: align initialization behavior with backend language-hit logic - Action: - updated `utils/i18n.uts` init path: - H5 init now calls `/api/i18n/query` without `lang` - MP-WEIXIN still enforces fixed `zh-cn` via explicit query target - kept manual switch behavior unchanged (`setLanguage` uses save-lang + explicit query) - Result: - initialization semantics now match requirement: "page-load prefetch uses backend-hit language logic" - Evidence: - code path in `loadI18n` calls `fetchLangMap("")` on H5 - `npm run i18n:audit` passed; `git diff --check` passed - Risk / Rollback: - risk: when local cache is empty, `currentLang` may differ from backend-hit language label until explicit switch/save - rollback: revert `utils/i18n.uts` only, no API contract rollback required ### S19 - Start: `2026-03-30 16:07:51 +0800` - Goal: close remaining accessibility/visible literal gaps after review - Action: - localized `alt` accessibility text: - `components/page-card/page-card.uvue` (`cover image`, `avatar`) - `components/agent-component/agent-component.uvue` (`avatar`) - localized image-choose failure toast in `components/chat-input-phone/chat-input-phone.uvue` - replaced hardcoded english with `Mobile.Chat.chooseImageFailed` - expanded locale dictionaries: - `Mobile.Common.coverImageAlt` - `Mobile.Common.avatarAlt` - `Mobile.Chat.chooseImageFailed` - strengthened audit rule to include `alt=` in visible-line patterns (`scripts/i18n-audit.mjs`) - regenerated platform default import artifacts (`npm run i18n:export-defaults`) - Result: - static `alt` hardcoded literals removed from business components - fallback/export dictionary key count increased to `237` - review-raised missing points are closed for this batch - Evidence: - `rg '\balt="[^"]+"'` now returns only `:alt="t(...)"` bindings in relevant components - `npm run i18n:audit` => pass (0 hit) - `git diff --check` => no output - Risk / Rollback: - risk: audit still focuses on chinese hardcoded detection and visible patterns; non-standard literal paths may need rule extension - rollback: per-file revert for component-level changes; dictionary additions are backward compatible ### S20 - Start: `2026-03-30 16:10:59 +0800` - Goal: verify residual omissions and harden multilingual behavior in mixed-language names - Action: - executed residual scans: - hardcoded `alt` attribute scan - hardcoded `title:` literal scan in toast/modal contexts - locale key parity checks (used keys vs zh/en bundles) - updated `components/chat-input-phone/manual-component-item/manual-component-item.uvue` icon mapping logic: - from Chinese-only keyword matching to Chinese + English keyword matching (`search/internet/research/deep`) - Result: - no remaining business `alt` hardcoded literal found (all switched to `:alt="t(...)"`) - no remaining business `title:` hardcoded visible literal (excluding commented lines / empty placeholder) - key parity remains complete - multilingual display no longer causes icon match fallback in english keyword cases - Evidence: - `npm run i18n:audit` => pass - `git diff --check` => pass - parity output: `Missing in zh-cn:` empty, `Missing in en-us:` empty - Risk / Rollback: - risk: keyword-based icon mapping still heuristic; future locale text variants may require type-based mapping - rollback: revert `manual-component-item` logic only ### S21 - Start: `2026-03-30 16:16:48 +0800` - Goal: continue omission closure and strengthen gate for non-Chinese hardcoded visible literals - Action: - fixed residual visible literals: - `components/page-card/page-card.uvue`: `alt` switched to i18n keys - `components/agent-component/agent-component.uvue`: `alt` switched to i18n key - `components/chat-input-phone/chat-input-phone.uvue`: image choose failure toast switched to i18n key - `subpackages/pages/chat-conversation-component/components/more-info/more-info.uvue`: removed hardcoded author initial (`A`) -> dynamic initial derivation - expanded zh/en locale dictionaries with: - `Mobile.Common.coverImageAlt` - `Mobile.Common.avatarAlt` - `Mobile.Chat.chooseImageFailed` - hardened audit script `scripts/i18n-audit.mjs`: - keeps chinese visible literal detection - adds non-chinese hardcoded visible literal detection for `title/content/confirmText/cancelText/placeholder/alt` - excludes i18n-key form (`Mobile.*`) and avoids dynamic binding false positives - regenerated platform default import artifacts via `npm run i18n:export-defaults` - Result: - no remaining business static `alt` literal - no remaining direct toast `title` hardcoded visible literal in active code paths - audit gate now can block english hardcoded visible literals in key scenes - default import key count increased to `237` - Evidence: - `npm run i18n:audit` => pass - `git diff --check` => pass - `rg '\\balt="[^\\"]+"'` returns only `:alt="t(...)"` in business components - Risk / Rollback: - risk: regex-based audit still heuristic and may need incremental rule tuning for edge syntax - rollback: rule rollback limited to `scripts/i18n-audit.mjs`, does not affect runtime behavior ### S22 - Start: `2026-03-30 16:24:56 +0800` - Goal: close tabBar multilingual omission for H5 runtime - Action: - implemented tabBar runtime i18n sync in `utils/i18n.uts`: - added `TAB_BAR_I18N_ITEMS` mapping (home/unionRecord/agent/app) - added `applyTabBarI18n()` using `uni.setTabBarItem` - trigger points: - `bootstrapI18nCache` - `loadI18n` success path - `setLanguage` success path - maintained platform isolation: - only applies on H5/WEB - MP-WEIXIN remains fixed `zh-cn` - Result: - H5 tabBar text now follows active language instead of static `pages.json` defaults only - Evidence: - code added in `utils/i18n.uts` - `npm run i18n:audit` passed - `git diff --check` passed - Risk / Rollback: - risk: on non-tab pages, `setTabBarItem` may throw; protected with try/catch - rollback: remove `applyTabBarI18n()` calls only ### S23 - Start: `2026-03-30 16:33:17 +0800` - Goal: continue final omission closure for hardcoded fallback app titles - Action: - replaced hardcoded fallback app title `Qiming` with i18n key `Mobile.Common.appName` in: - `utils/commonBusiness.uts` - `subpackages/pages/webview/webview.uvue` - `subpackages/pages/category-agent-list/category-agent-list.uvue` - added locale key in zh/en bundles: - `Mobile.Common.appName` - regenerated platform import artifacts via `npm run i18n:export-defaults` - Result: - business runtime no longer contains direct `Qiming` fallback literal; all app-name fallback now goes through i18n layer - default import key count increased to `238` - Evidence: - `rg -n 'Qiming' ...` now only hits locale dictionary values - `npm run i18n:audit` passed - `git diff --check` passed - Risk / Rollback: - risk: none functionally; key missing would fallback to local dictionary immediately - rollback: revert three usage files while keeping key definitions ### S24 - Start: `2026-03-30 17:01:42 +0800` - Goal: continue final omission closure for residual visible text edge-cases - Action: - replaced static agreement separator in `components/agreement-checkbox/agreement-checkbox.uvue` with i18n key: - `Mobile.Auth.agreementSeparator` - normalized published-agent-list default title to translated default instead of raw key literal: - `components/published-agent-list/published-agent-list.uvue` - updated locale defaults (zh/en) with: - `Mobile.Auth.agreementSeparator` - adjusted audit output wording in `scripts/i18n-audit.mjs` to align with “hardcoded user-visible text” gate scope - regenerated platform default import artifacts via `npm run i18n:export-defaults` - Result: - agreement line punctuation now language-aware - no raw i18n-key fallback title leak when published-agent-list is reused without explicit title prop - platform import default key count increased to `239` - Evidence: - `npm run i18n:audit` => pass (`0 user-visible hardcoded lines`) - `git diff --check` => pass - `docs/i18n-platform-default-import.json` => `totalKeys: 239` - Risk / Rollback: - risk: minimal; only text rendering defaults changed - rollback: revert S24 touched files without impacting i18n runtime core ### S25 - Start: `2026-03-30 16:45:19 +0800` - Goal: close review concern on accessibility `alt` internationalization and prevent regression - Action: - re-checked business `alt` usage: - `components/page-card/page-card.uvue` - `components/agent-component/agent-component.uvue` - confirmed all existing `alt=` in business code are `t(...)` based and use: - `Mobile.Common.coverImageAlt` - `Mobile.Common.avatarAlt` - hardened `scripts/i18n-audit.mjs` to detect bound-literal hardcoding patterns, including: - `:alt="'...'"`, `:placeholder="'...'"`, `:title="'...'"`, `:content="'...'"`, `:confirmText="'...'"`, `:cancelText="'...'"` - Result: - review-mentioned `alt` hardcoding risk is closed in current branch - audit gate now can block both static and bound-literal forms for key user-visible fields - Evidence: - `rg -n "alt=" components pages subpackages --glob '*.uvue'` shows only `:alt="t(...)"` usages - `npm run i18n:audit` => pass (`0 user-visible hardcoded lines`) - `git diff --check` => pass - Risk / Rollback: - risk: low; regex expansion may introduce rare false positives in future complex expressions - rollback: revert only new bound-literal regex lines in `scripts/i18n-audit.mjs` ### S26 - Start: `2026-03-30 16:51:00 +0800` - Goal: expand accessibility alt coverage beyond card components - Action: - added i18n-based avatar `alt` to additional user-visible avatar scenes: - `pages/index/header-menu/header-menu.uvue` - `subpackages/pages/about-me/about-me.uvue` - `subpackages/pages/chat-conversation-component/components/more-info/more-info.uvue` - all above use existing key: - `Mobile.Common.avatarAlt` - Result: - avatar alt text coverage expanded from card components to header/profile/conversation-more-info scenes - no new dictionary key needed, keeps import set stable - Evidence: - `rg -n "alt=" components pages subpackages --glob '*.uvue'` shows all current `alt` bindings use `t(...)` - `npm run i18n:audit` => pass (`0 user-visible hardcoded lines`) - `git diff --check` => pass - Risk / Rollback: - risk: very low, template attribute-only change - rollback: revert the three S26 view files only ### S27 - Start: `2026-03-30 17:09:03 +0800` - Goal: continue full-coverage i18n closure for image accessibility text and enforce gate - Action: - performed repo-wide business scan for `` tags in `pages/components/subpackages` and closed all missing `alt` cases (non-comment code). - completed alt coverage in key scenes: - list empty states (`agent-list-content`, `conversation-list-content`, `published-agent-list`, `agent-search`) - agent/card icons (`agent-component`, `recent-used-agent-item`, `category-agent-list`, `agent-union-record`) - chat/attachment chain (`chat-upload-image`, `chat-conversation-component`, `file-tree`, `file-tree-node`) - common UI (`custom-nav-bar`, `login-layout`, `empty-state`, `button-wrapper`, `skill-select-modal`, `voice-recorder-button`) - semantics strategy: - meaningful images use i18n alt (`t(...)`) - decorative icons use empty alt (`alt=""`) - enhanced `scripts/i18n-audit.mjs`: - added hard gate for `` without `alt`/`:alt` - expanded locale defaults (zh/en): - `Mobile.Common.noDataImageAlt` - `Mobile.Common.agentIconAlt` - `Mobile.Common.skillIconAlt` - `Mobile.Common.appLogoAlt` - `Mobile.Common.deleteIconAlt` - `Mobile.Chat.uploadImageAlt` - `Mobile.Chat.uploadFileAlt` - regenerated platform default import artifacts via `npm run i18n:export-defaults` - Result: - business code now has zero missing `alt` for image tags in `pages/components/subpackages` - i18n gate upgraded to prevent future missing-alt regression - platform import key count increased to `246` - Evidence: - `npm run i18n:audit` => pass (`0 user-visible hardcoded lines`) - `git diff --check` => pass - repo scan script output => `TOTAL_MISSING_ALT=0` (comments excluded) - `docs/i18n-platform-default-import.json` => `totalKeys: 246` - Risk / Rollback: - risk: low, broad template attribute updates may expose minor rendering differences on niche devices - rollback: revert S27 touched files in batches (components/pages/subpackages/audit/locales) without changing i18n runtime core ### S28 - Start: `2026-03-30 17:18:39 +0800` - Goal: improve runtime language-switch consistency for dynamic UI labels - Action: - replaced static-at-init translation patterns with dynamic evaluation: - `components/chat-input-phone/skill-select-modal/skill-select-modal.uvue` - `tabs` switched from static array to computed array to follow language switch - `subpackages/pages/webview/webview.uvue` - `pageTitle` fallback switched to computed (`displayPageTitle`) instead of init-time `t(...)` - `pages/index/index.uvue` - share title fallback changed to computed (`fallbackShareTitle`) to avoid stale language text when tenant title absent - `utils/commonBusiness.uts` - function default params no longer evaluate `t(...)` at module-load time - fallback appName moved to call-time resolution - improved generic empty-state component i18n behavior: - `components/empty-state/empty-state.uvue` - default `text` changed to i18n key - render switched to `translateText(...)` for runtime language responsiveness - adjusted `components/published-agent-list/published-agent-list.uvue` default title back to key form for dynamic translation path - Result: - reduced stale-text risk after language switching without page reload - component defaults align with key-driven translation flow - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - `git diff --check` => pass - Risk / Rollback: - risk: low; mostly fallback and computed wiring changes - rollback: revert S28 touched files only (`skill-select-modal`, `webview`, `index`, `commonBusiness`, `empty-state`, `published-agent-list`) ### S29 - Start: `2026-03-30 17:22:01 +0800` - Goal: continue full-coverage key management for remaining visible login literal - Action: - replaced login area-code visible literal in: - `subpackages/pages/login/components/login-form/login-form.uvue` - `+86` -> `t("Mobile.Auth.defaultAreaCode")` - added locale keys (zh/en): - `Mobile.Auth.defaultAreaCode` - regenerated platform import artifacts via `npm run i18n:export-defaults` - Result: - login area-code text now managed in i18n dictionary and can be imported/maintained on platform uniformly - platform default import key count increased to `247` - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - `git diff --check` => pass - `docs/i18n-platform-default-import.json` => contains `Mobile.Auth.defaultAreaCode` - Risk / Rollback: - risk: very low, text source replacement only - rollback: revert login-form + locale key entries + regenerated import artifacts ### S30 - Start: `2026-03-30 17:32:21 +0800` - Goal: improve placeholder language-switch consistency between union-record and search page - Action: - changed union-record search handoff to pass i18n key instead of translated text: - `pages/agent-union-record/agent-union-record.uvue` - `app.globalData.searchPlaceholder = "Mobile.AgentUnion.searchPlaceholder"` - refactored agent-search placeholder rendering to key-driven runtime translation: - `subpackages/pages/agent-search/agent-search.uvue` - introduced `searchPlaceholderSource` (key source) - `searchPlaceholder` switched to computed + `translateText(...)` - local-search handoff now writes source key directly, not one-time translated literal - Result: - placeholder can follow current language at runtime more consistently - avoids stale translated string handoff across page jump boundary - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - `git diff --check` => pass - code references confirm key-driven flow in both pages - Risk / Rollback: - risk: low; affects only search placeholder source plumbing - rollback: revert S30 two files to prior string-handoff behavior ### S31 - Start: `2026-03-30 17:35:43 +0800` - Goal: strengthen i18n audit gate for key completeness and prefix policy - Action: - enhanced `scripts/i18n-audit.mjs` with key-level checks: - collect all used `Mobile.*` keys from business code - validate keys exist in both locale defaults: - `constants/i18n-locales/zh-CN.uts` - `constants/i18n-locales/en-US.uts` - enforce zh/en locale key-set parity - block legacy key prefix usage: - code-side `System.*` - locale-side `System.*` - preserved existing visible-text/alt gate checks - Result: - audit now catches missing dictionary definitions and bilingual key drift early - key-prefix policy (`Mobile.*` only) is enforced by gate - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - Risk / Rollback: - risk: low; stricter gate may expose pre-existing key debt in future branches - rollback: revert S31 delta in `scripts/i18n-audit.mjs` ### S32 - Start: `2026-03-30 17:39:58 +0800` - Goal: remove residual literal symbols from form UI to approach strict key-only visible text policy - Action: - converted two visible literals in new-conversation-set to i18n keys: - required marker: `*` -> `Mobile.Common.requiredMark` - single-select separator: `/` -> `Mobile.Common.optionSeparator` - added locale entries in zh/en defaults: - `Mobile.Common.requiredMark` - `Mobile.Common.optionSeparator` - regenerated platform import artifacts via `npm run i18n:export-defaults` - Result: - form visible symbols are now key-managed and platform-importable - platform default import key count increased to `249` - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - `git diff --check` => pass - export artifacts contain both new keys - Risk / Rollback: - risk: very low; symbol rendering source only - rollback: revert `new-conversation-set` and locale/export artifact updates ### S33 - Start: `2026-03-30 18:18:57 +0800` - Goal: improve language-switch behavior for published-agent category tab labels - Action: - refactored category label render path in: - `components/published-agent-list/published-agent-list.uvue` - changes: - template label render switched to `translateText(category.label)` - default "all" category label source changed from translated literal to key: - `t("Mobile.Common.all")` -> `"Mobile.Common.all"` - imported `translateText` alongside `useI18n` - Result: - "all" tab label can follow runtime language changes through key-driven rendering path - backend-provided category labels remain compatible (non-key labels pass through unchanged) - Evidence: - `npm run i18n:audit` => pass (`0 i18n coverage issues`) - `git diff --check` => pass - Risk / Rollback: - risk: low; label render path adjusted but category key/value behavior unchanged - rollback: revert S33 file only ### S34 - Start: `2026-03-30 18:28:28 +0800` - Goal: strengthen i18n audit gate for non-Chinese hardcoded visible text coverage - Action: - updated `scripts/i18n-audit.mjs` - added hardcoded visible literal detection for object field `text: "..."` - added `/