11 KiB
Gap Analysis — i18n-frontend-ui-strings
1. Scope and current state
The five files in scope are at very different stages of i18n adoption. The audit drilled into each one and uncovered substantially more flagged sites than the ticket body enumerated; the spec is broader in practice than its evidence list suggests.
| File | i18n adoption today | Touch surface |
|---|---|---|
views/Process.vue |
None. No useI18n() import, no $t calls. ~40 user-visible Chinese literals across template + JS. |
All template headers, status badges, modal/info labels, error strings, fallback names. |
components/Step2EnvSetup.vue |
High (~70%). Templates already use $t. Remaining: 3 backend-stage equality checks (lines 680/682/689) and a few console.warn strings (not user-visible). |
Stage-watcher logic only. |
components/Step3Simulation.vue |
Sparse (1 $t call). The template is mostly English already, but the JS has startError.value = res.error || '启动失败' (line 423/427). |
A single fallback string. |
components/Step4Report.vue |
Sparse (2 $t calls). The bulk of the file is 29 regex patterns matching Chinese section markers emitted by report_agent.py, plus three string-equality checks for the no-reply marker, plus a log-severity classifier. |
Parser/regex layer + a small set of UI literals (e.g. line 1464 '选择理由', line 1774 '等待开始'). |
components/Step5Interaction.vue |
Extensive (~35 $t calls). Two literals remain: lines 725 and 727 — both prompt strings sent to the backend LLM, not user-visible UI. |
Prompt construction in the chat-history feature. |
createI18n lives at frontend/src/i18n/index.js. Default locale is 'zh' (read from localStorage), fallback 'zh'. Locales come from repo-root /locales/*.json via import.meta.glob. Both en.json and zh.json are aligned at 1031 lines after issue #20's backfill.
The audit script the original ticket refers to (.kiro/specs/i18n-e2e-english-verification/audit/scripts/run_audit.sh) does not exist — only the empty directory shell remains. Verification has to be done by direct grep over the five files (Requirement 6).
2. Requirement-to-asset map
| Req | Need | Existing asset (file) | Gap label |
|---|---|---|---|
| R1 | Wire useI18n() into Process.vue; route ~40 strings through new process.* keys |
No i18n import; no process.* namespace yet |
Missing — both wiring and namespace |
| R2 | Externalize remaining UI literals in Step3/Step4/Step5 | useI18n() already imported in all three; namespaces step3/4/5.* exist |
Constraint — match existing namespace structure |
| R3 | en.json/zh.json parity for new keys | Issue #20 / spec i18n-backfill-zh-json already aligned them |
Constraint — must not regress; checker exists informally |
| R4 | Stage-name comparator that survives backend translation | Step2EnvSetup.vue:679-692 watcher; backend emits both Chinese display strings and snake_case ids |
Missing — small lookup map needed |
| R5 | Bilingual (Chinese + English) tolerance for 29 regex parsers + 3 marker checks + log classifier | Step4Report.vue:557-943 regex block; :1334, :2014-2015 checks |
Missing — backend-coupled; depends on what translated prompts emit |
| R6 | Local verification check | Audit script gone; vanilla grep available |
Missing — small script or documented one-liner |
Research-needed flags
- Backend-emitted English strings (R5) — issues #25 (LLM prompt assembly translation) and the open
i18n-report-agent-promptsspec dictate what English markersreport_agent.pywill eventually emit (e.g., will it becomeAnalysis question:,Analyze question:, or stay as a stable分析问题:?). The frontend can't pin its English regexes to specific wording until that backend spec is settled. Mitigation strategy: keep the existing Chinese regexes intact (for backwards compat with current backend) and add deliberately permissive English alternates that match a documented set of likely renderings, plus keep an explicit allowlist of "deliberate Chinese tokens for backend compatibility" so the audit doesn't re-flag them. - Step5Interaction.vue prompt strings (lines 725, 727) — these are not UI; they are prompt content sent to the LLM. If the user is on
zhlocale and chats with a Chinese-trained agent, the Chinese phrasing is intentional. Two viable strategies: (a) localize to active locale viat()(correct linguistically; assumes the agent handles both), or (b) keep Chinese literally because the agent is currently Chinese-tuned. The wider initiative is moving the backend to English, so option (a) aligns better — but coordinating with the report agent's actual prompt translation (separate spec) would be ideal. For this spec, route through i18n keys and let the active locale dictate; document the assumption.
3. Implementation approach options
Option A — Pure extension (recommended)
Treat this as a localized cleanup of five existing files plus locale-file additions. All work is "match the surrounding file's style," no new abstractions.
- Files extended: 5 Vue files + 2 locale files. No new files (or 1 new file: a small grep-based verifier).
- Compatibility: The new i18n keys layer onto an existing pattern (
step2.*,step4.*, etc.). No public surface changes. - Complexity: Low to medium. The big number is the count of strings, not their individual difficulty. The two genuinely tricky pieces are (i) the bilingual regex strategy in
Step4Report.vue, (ii) the stage-comparator refactor inStep2EnvSetup.vue.
Trade-offs:
- ✅ Least architectural change; matches the steering principle "match the surrounding file's style."
- ✅ Each file's edits are independent; reviewable in isolation.
- ❌ Adds size to
Process.vue(already ~50KB) — but the additions are mostlyt()substitutions, not new logic.
Option B — Extract a useStageMatcher() composable + a parseReportSection() utility
Make new files for the two backend-coupled responsibilities (R4 and R5):
frontend/src/composables/useStageMatcher.js— owns the legacy-Chinese ↔ snake_case ↔ future-English equivalence map.frontend/src/utils/reportParsers.js— owns the bilingual regex set and exposes typed extractors.
Trade-offs:
- ✅ Cleaner separation; future backend-output changes localize into one parser file.
- ❌ Moves regexes out of
Step4Report.vuewhere today they sit alongside the consumer; the steering doc favors keeping pipeline-stage logic in the matching Step component unless responsibilities truly diverge. Arguably they don't yet. - ❌ Larger PR, more files for reviewers to navigate.
Option C — Hybrid
Apply Option A everywhere, but extract useStageMatcher() (Option B's smaller half) because the stage equality check is duplicated three times in one watcher and obviously benefits from a single source of truth. Leave the Step4Report.vue parsers in place and add the bilingual alternates inline; this avoids designing an extraction boundary against a backend that's still being translated.
4. Recommendation
Hybrid (Option C).
- R1, R2, R3: pure extension — substitute
t('…')and add keys to both locale files. - R4: introduce a tiny in-file lookup (or, if it earns its keep, a small composable) so that future stage strings only need adding in one place.
- R5: extend the existing regexes inline. Each parser becomes
chineseRegex.test(...) ? extract(chineseRegex) : englishRegex.exec(...)(or an explicitly bilingual single regex like/(?:分析问题|Analysis question):/). Document the deliberate Chinese tokens at the top of the parser block so the verifier in R6 can allowlist them. - R6: a
frontend/scripts/audit-i18n-strings.{sh,js}(the existing repo has no equivalent yet) that greps the five files for unicode CJK literals minus an allowlist; runnable locally in seconds, no backend required. Keep it tiny — this is verification, not a new test framework.
Effort: M (3–7 days of focused work). The volume in Process.vue is significant (~40 keys), but each substitution is mechanical. R5 is the only piece with real design content.
Risk: Medium. Risk concentration:
- R5 (parsers) — Medium. If the backend prompt translations land between this PR's merge and a release, and the actual English wording doesn't match the alternates we encoded, reports degrade silently. Mitigation: write the alternates against the actual prompts in
backend/app/services/report_agent.pyrather than guessing, and keep all Chinese regexes alive as fallbacks for as long as the backend is partially-translated. - R3 (locale parity) — Low. Tooling-aided; #20 just established the discipline.
- R1 (Process.vue) — Low individually, but the volume means review fatigue is a real risk. Recommend the PR call out logical chunks (header / progress / errors / fallback labels) so the reviewer can sign off section by section.
5. Research items to carry into design
- Read
backend/app/services/report_agent.py(and any prompt template referenced by it) to enumerate the actual English strings it emits today, not what we assume it will emit. The R5 regex alternates must be grounded in real backend output. Cross-reference the open speci18n-report-agent-promptsfor the planned English wording. - Confirm whether
Step2EnvSetup.vue:680-689ever sees backend-emitted English display strings now, or only the snake_case identifiers. If only snake_case, the comparator can prefer those and treat the Chinese as backwards-compat-only. - Confirm that
Step5Interaction.vue:725-727(chat history templating) is acceptable to localize viat()— i.e., that the report agent handles bothQuestion: …and提问者:…framings of chat history. If not, leave Chinese in for now and open a separate ticket to migrate alongside the backend agent prompt translation. - Decide naming for the new
process.*namespace: align with adjacent step namespaces (step1.*etc.) or use a fresher grouping. The existinggraph.*namespace already covers some of the graph-panel headers and may absorb several ofProcess.vue's strings rather than duplicating them.
Output checklist
- ✅ Requirement-to-asset map with gaps tagged
- ✅ Options A/B/C with trade-offs
- ✅ Effort M, Risk Medium with justification
- ✅ Recommendation: Option C (hybrid)
- ✅ Research items carried forward