From 0a65edfa46c710df9b08c646138d8a0786c07dac Mon Sep 17 00:00:00 2001 From: Dominik Seemann Date: Thu, 7 May 2026 15:32:30 +0000 Subject: [PATCH] fix(i18n): backfill english-only entries in zh.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit translate nine user-facing english values (step3/step4/step5 waiting states, step5 interactive tools and report-agent chat panel, graph panel labels) plus the user-visible step 2 log line `log.prepareTaskId` to natural chinese, so chinese-locale users no longer see english text mixed into the chinese ui. `home.heroDescBrand` is intentionally left as the literal `MiroFish` because it is a brand name. `log.prepareTaskId` was translated rather than kept english because it is rendered into the in-ui log panel via `Step2EnvSetup.vue:801` and every surrounding `log.*` value in zh.json is already translated; the leading two-space indent, the `└─` continuation glyph, and the `{taskId}` placeholder are preserved. en.json and zh.json key sets remain identical (`paths(scalars)` diff is empty); no frontend code is changed. Closes #8 --- .kiro/specs/i18n-backfill-zh-json/design.md | 221 ++++++++++++++++++ .../i18n-backfill-zh-json/gap-analysis.md | 116 +++++++++ .../i18n-backfill-zh-json/requirements.md | 63 +++++ .kiro/specs/i18n-backfill-zh-json/research.md | 115 +++++++++ .kiro/specs/i18n-backfill-zh-json/spec.json | 27 +++ .kiro/specs/i18n-backfill-zh-json/tasks.md | 29 +++ locales/zh.json | 18 +- 7 files changed, 580 insertions(+), 9 deletions(-) create mode 100644 .kiro/specs/i18n-backfill-zh-json/design.md create mode 100644 .kiro/specs/i18n-backfill-zh-json/gap-analysis.md create mode 100644 .kiro/specs/i18n-backfill-zh-json/requirements.md create mode 100644 .kiro/specs/i18n-backfill-zh-json/research.md create mode 100644 .kiro/specs/i18n-backfill-zh-json/spec.json create mode 100644 .kiro/specs/i18n-backfill-zh-json/tasks.md diff --git a/.kiro/specs/i18n-backfill-zh-json/design.md b/.kiro/specs/i18n-backfill-zh-json/design.md new file mode 100644 index 00000000..d3a6c5b0 --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/design.md @@ -0,0 +1,221 @@ +# Design Document — i18n-backfill-zh-json + +## Overview + +**Purpose**: Backfill ten English-only values in `locales/zh.json` with +natural Chinese translations so the Chinese UI renders fully Chinese +labels on Step 3, Step 4, Step 5, and the graph panel, plus the Step 2 +log line that prints a task ID. + +**Users**: Chinese-locale UI users; secondarily, frontend engineers and +i18n reviewers who depend on `en.json` and `zh.json` being structurally +aligned. + +**Impact**: Pure data change — modifies values for ten keys in +`locales/zh.json`. No code, no schema, no contract changes. Tracks +GitHub issue #8. + +### Goals + +- Translate the nine user-facing English values into natural Chinese. +- Translate `log.prepareTaskId` to Chinese (gap analysis confirmed it is + user-facing) while preserving the leading two-space indent, the `└─` + glyph, and the `{taskId}` placeholder. +- Keep `home.heroDescBrand` literally as `MiroFish` (proper noun). +- Keep `locales/en.json` and `locales/zh.json` structurally aligned + (same scalar key paths, same key order in unchanged objects). + +### Non-Goals + +- Translating `en.json` (covered by other epic tickets). +- Restructuring the locale files or the i18n loader. +- Adding new keys for currently-untranslated UI elements. +- Any frontend code change (`*.vue` / `*.js` / `*.ts`). + +## Boundary Commitments + +### This Spec Owns + +- The values of exactly ten scalar keys in `locales/zh.json`: + `home.heroDescBrand`, `step3.waitingForActions`, + `step4.waitingForReportAgent`, `step5.interactiveTools`, + `step5.agentsAvailable`, `step5.reportAgentChat`, + `graph.panelTitle`, `graph.nodeDetails`, `graph.relationship`, + `log.prepareTaskId`. +- The decision and rationale for `log.prepareTaskId` (translate, see + research.md). + +### Out of Boundary + +- Any other value in `locales/zh.json` (must remain byte-identical). +- Any value in `locales/en.json` or `locales/languages.json`. +- The i18n loader, the Vue components that consume these keys, and any + backend code. + +### Allowed Dependencies + +- The existing structural contract: `locales/en.json` and + `locales/zh.json` MUST contain the same set of scalar key paths + (verified by the `jq paths(scalars)` diff). +- The existing placeholder syntax used by `vue-i18n` + (`{count}`, `{taskId}`, …). + +### Revalidation Triggers + +- A change to `vue-i18n` placeholder syntax (none expected). +- Any new English key added to `en.json` after this spec lands — that is + a separate ticket (out of scope) and would invalidate the alignment + diff if not mirrored to `zh.json`. + +## Architecture + +### Existing Architecture Analysis + +- Locale files are flat JSON trees grouped by feature + (`home`, `step3`, `step5`, `graph`, `log`, …) and consumed by + `vue-i18n` via `frontend/src/i18n/`. +- `locales/en.json` and `locales/zh.json` are kept structurally aligned + by convention; the alignment is verified by the `jq paths(scalars)` + diff cited in the requirements doc and is currently empty. +- Translation convention in `zh.json`: surrounding `step*`, `graph.*`, + and `log.*` values are direct natural-Chinese renderings of their + English siblings, preserving placeholders and any leading/trailing + glyphs. + +### Architecture Pattern & Boundary Map + +This change has no architectural surface area — it is a value-only edit +inside a configuration data file. No diagram needed. + +- Selected pattern: **In-place data edit** of `locales/zh.json`. +- Domain boundary: locale data only. +- Existing patterns preserved: `vue-i18n` key/value contract; placeholder + syntax; key order; key set. +- New components: none. +- Steering compliance: matches `tech.md`'s i18n setup + (`vue-i18n` + JSON files in `/locales/`); no new dependency. + +### Technology Stack + +| Layer | Choice / Version | Role in Feature | Notes | +|-------|------------------|-----------------|-------| +| Frontend | `vue-i18n` | Consumes the translated keys at runtime | Unchanged | +| Data | `locales/zh.json` (UTF-8 JSON) | Storage of the translated values | Only file edited | +| Tooling | `jq`, `python -c "import json"` | Validation of JSON parseability and key alignment | No new tool | + +## File Structure Plan + +### Modified Files + +- `locales/zh.json` — replace the value of ten specific keys (see the + table in *Translation Contract* below). No keys are added, removed, + reordered, or restructured. + +No other file is touched. + +## Requirements Traceability + +| Requirement | Summary | Realized by | +|-------------|---------|-------------| +| 1.1 | Step 3 waiting label is Chinese | Edit value of `step3.waitingForActions` | +| 1.2 | Step 4 waiting label is Chinese | Edit value of `step4.waitingForReportAgent` | +| 1.3 | Step 5 labels are Chinese | Edit values of `step5.interactiveTools`, `step5.agentsAvailable`, `step5.reportAgentChat` | +| 1.4 | Graph panel labels are Chinese | Edit values of `graph.panelTitle`, `graph.nodeDetails`, `graph.relationship` | +| 1.5 | `step5.agentsAvailable` keeps `{count}` once, naturally placed | Translation contract row | +| 1.6 | `home.heroDescBrand` stays `MiroFish` | No edit (verified by spot check) | +| 2.1 | Decision recorded if scaffold kept English | N/A — decision is to translate (R2.2) | +| 2.2 | Translate scaffold preserving indent / `└─` / `{taskId}` | Edit value of `log.prepareTaskId` | +| 2.3 | PR description lists English-by-design keys | Done at /done time (PR description) | +| 3.1 | `en.json` ↔ `zh.json` key sets identical | Validated by alignment diff in *Validation Strategy* | +| 3.2 | Key order preserved in unchanged objects | Enforced by using `Edit` (string replace) only | +| 3.3 | Placeholders preserved byte-for-byte | Enforced by translation contract + parse check | +| 3.4 | Reject change if placeholder drifts | Enforced by review + grep check in *Validation Strategy* | +| 3.5 | `zh.json` remains valid JSON | Enforced by `jq empty` check | +| 4.1 | Only `locales/zh.json` changes | Enforced at /done time (`git status` review) | +| 4.2 | No add/rename/delete of keys | Enforced by using `Edit` only on values | +| 4.3 | If a value is already Chinese (upstream change), skip and note | Enforced by pre-edit re-read of current values | + +## Components and Interfaces + +There is no software component to design. The "interface" is the set of +exact value strings that `locales/zh.json` will contain after the +change. + +## Translation Contract + +The implementation MUST replace each listed value with exactly the +target string below, using `Edit` (string replace) on the JSON value +only. Leading/trailing whitespace inside the JSON value, all +placeholders, and the surrounding double quotes / commas are preserved +because the Edit operates only on the value bytes. + +| Key | Current value (English) | Target value (Chinese) | +|-----|--------------------------|------------------------| +| `home.heroDescBrand` | `MiroFish` | `MiroFish` (unchanged — brand) | +| `step3.waitingForActions` | `Waiting for agent actions...` | `等待智能体执行动作...` | +| `step4.waitingForReportAgent` | `Waiting for Report Agent...` | `等待报告智能体...` | +| `step5.interactiveTools` | `Interactive Tools` | `交互工具` | +| `step5.agentsAvailable` | `{count} agents available` | `{count} 个智能体可用` | +| `step5.reportAgentChat` | `Report Agent - Chat` | `报告智能体 - 对话` | +| `graph.panelTitle` | `Graph Relationship Visualization` | `图谱关系可视化` | +| `graph.nodeDetails` | `Node Details` | `节点详情` | +| `graph.relationship` | `Relationship` | `关系` | +| `log.prepareTaskId` | ` └─ Task ID: {taskId}` | ` └─ 任务 ID: {taskId}` | + +Translation rationale (matches existing `zh.json` conventions): + +- "Agent" → "智能体" (e.g. existing `agent.title: "🤖 智能体详情"`). +- "Report Agent" → "报告智能体" (e.g. existing + `step4.reportAgentReady: "报告智能体就绪"`). +- "Task ID" → "任务 ID" (Chinese tech UI keeps "ID" as a loanword; + preserves the two-space indent and the `└─` continuation glyph used + across the surrounding `log.*` lines). +- The trailing `...` is preserved on `waitingForActions` and + `waitingForReportAgent` because it is a meaningful UI cue ("in + progress") and the English source uses it. +- The ` - ` separator in `step5.reportAgentChat` is kept literally so the + Chinese label keeps the same visual structure as the English one. + +## Data Models + +Not applicable. No schema or domain model is defined or changed. + +## Error Handling + +The only failure modes are (a) invalid JSON after edit and +(b) accidental key-set drift. Both are caught by the validation script +in the next section before the change is committed. + +## Testing Strategy + +### Static checks (mandatory before commit) + +1. `jq empty locales/zh.json` — file remains valid JSON. +2. `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) + <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` — + produces no output (key sets identical). +3. `jq -r '' locales/zh.json` for each of the ten keys — output + matches the *Target value* column of the Translation Contract. +4. `git diff --stat` shows exactly one file changed: `locales/zh.json`. +5. `git diff locales/zh.json` shows only value changes (no key adds, + removes, or reorders) — visually confirm via `grep -nE + '^[+-]' <(git diff locales/zh.json)` that every `+` line has a + matching `-` line for the same key. + +### Manual smoke test (recommended, optional) + +- Run `npm run dev`, switch UI to Chinese (`zh`), and visit: + - Step 2 (look for the translated `└─ 任务 ID: …` log line), + - Step 3 (waiting state placeholder), + - Step 4 (waiting state placeholder), + - Step 5 (Interactive Tools heading, agent count, Report Agent chat + panel title), + - Graph panel (title, node details, relationship label). +- Confirm no English text remains for the targeted UI elements. + +## Supporting References + +- `.kiro/specs/i18n-backfill-zh-json/gap-analysis.md` — current-state + inventory, `log.prepareTaskId` usage analysis, and the rationale for + Option A (single targeted edit). +- `.ticket/8.md` — original GitHub issue snapshot. diff --git a/.kiro/specs/i18n-backfill-zh-json/gap-analysis.md b/.kiro/specs/i18n-backfill-zh-json/gap-analysis.md new file mode 100644 index 00000000..82c2f0f7 --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/gap-analysis.md @@ -0,0 +1,116 @@ +# Gap Analysis — i18n-backfill-zh-json + +## Scope + +Translate ten English-only values in `locales/zh.json` to natural Chinese, +preserving structural alignment with `locales/en.json`. Data-only change. + +## Current State Investigation + +- **Locale files** live at the repo root: `locales/en.json`, `locales/zh.json`, + `locales/languages.json`. The frontend loader is `frontend/src/i18n/` + (vue-i18n). +- **Key alignment**: `diff <(jq -r 'paths(scalars) | join(".")' + locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")' + locales/zh.json | sort)` is currently empty — same key set, no drift. +- **Confirmed English-only values in `zh.json`** (verified via `jq`): + - `home.heroDescBrand` → `"MiroFish"` (brand, keep as-is) + - `step3.waitingForActions` → `"Waiting for agent actions..."` + - `step4.waitingForReportAgent` → `"Waiting for Report Agent..."` + - `step5.interactiveTools` → `"Interactive Tools"` + - `step5.agentsAvailable` → `"{count} agents available"` + - `step5.reportAgentChat` → `"Report Agent - Chat"` + - `graph.panelTitle` → `"Graph Relationship Visualization"` + - `graph.nodeDetails` → `"Node Details"` + - `graph.relationship` → `"Relationship"` + - `log.prepareTaskId` → `" └─ Task ID: {taskId}"` +- `en.json` contains the same English values for these keys (as expected). + +### `log.prepareTaskId` usage + +Confirmed via `Grep`: this key is consumed by +`frontend/src/components/Step2EnvSetup.vue:801` — +`addLog(t('log.prepareTaskId', { taskId: res.data.task_id }))` — i.e. it is +rendered into the in-UI log panel that the user reads. The surrounding +`log.*` keys in `zh.json` are all translated to natural Chinese (e.g. +`prepareTaskStarted: "准备任务已启动"`, `simEnvClosed: "✓ 模拟环境已关闭"`). +**Conclusion**: this is a user-facing log line, not a locale-neutral +scaffold; it should be translated, with the leading two-space indent, the +`└─` continuation glyph, and the `{taskId}` placeholder preserved. + +## Implementation Approach + +### Option A — Single targeted edit to `locales/zh.json` (recommended) + +Open `locales/zh.json`, locate each of the ten keys, and replace the value +with its Chinese translation. Re-run the `jq` alignment diff and parse-check +afterward. + +- ✅ Minimal blast radius, single file changed. +- ✅ Matches the surrounding convention (other `log.*`, `step3.*`, `step5.*` + Chinese values are already direct translations of their English siblings). +- ✅ No risk of key reorder or shape change if edits are value-only. +- ❌ None — this is the only sensible approach for a 10-value backfill. + +### Option B — Script-driven rewrite + +Write a one-off `jq` or Node script to set the ten values. Overkill for ten +values and increases the chance of accidental key reorder (`jq` does not +guarantee key-order preservation in older versions). + +**Decision**: Option A. + +## Translation Plan (proposed values) + +| Key | Proposed Chinese value | +| --- | --- | +| `home.heroDescBrand` | `MiroFish` (unchanged — brand) | +| `step3.waitingForActions` | `等待智能体执行动作...` | +| `step4.waitingForReportAgent` | `等待报告智能体...` | +| `step5.interactiveTools` | `交互工具` | +| `step5.agentsAvailable` | `{count} 个智能体可用` | +| `step5.reportAgentChat` | `报告智能体 - 对话` | +| `graph.panelTitle` | `图谱关系可视化` | +| `graph.nodeDetails` | `节点详情` | +| `graph.relationship` | `关系` | +| `log.prepareTaskId` | ` └─ 任务 ID: {taskId}` | + +Notes: +- "Agent" is rendered as "智能体" — consistent with existing `zh.json` usage + (e.g. `step3.recentActions: "最近行为"`, `agent.title: "🤖 智能体详情"`). +- "Report Agent" → "报告智能体" — matches existing translations such as + `step4.reportAgentReady: "报告智能体就绪"`. +- `step5.reportAgentChat` keeps the ` - ` separator literally to match the + English style in the same key family. +- `log.prepareTaskId` keeps the two leading spaces and `└─` glyph because + surrounding log lines (e.g. `simEnvClosed: "✓ 模拟环境已关闭"`) preserve + their leading glyph; the indent is meaningful in the log panel. + +These are proposals to be finalized at design time; minor wording polish +(e.g. "对话" vs "聊天") can be revisited during /kiro:spec-design. + +## Validation Strategy + +1. `jq empty locales/zh.json` — file remains valid JSON. +2. `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) + <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` — empty. +3. Spot-check via `jq -r ''` that the ten target values now match the + translation table (or the brand/scaffold exception, where applicable). +4. Manual: launch the dev server, switch UI to Chinese, walk through Step 2 + logs (look for translated `log.prepareTaskId` line), Step 3 / Step 4 + waiting states, Step 5 interactive tools, and the graph panel. + +## Risks / Unknowns + +- **Wording quality**: My proposed translations follow the conventions used + elsewhere in `zh.json`; a native reviewer may prefer alternatives. The PR + description should call this out so reviewers can suggest edits. +- **Key order preservation**: `Edit` (string-replace) is safe; `jq`-based + rewrites would not be. We will use `Edit` exclusively. +- **No additional research needed** — this is a well-bounded data change. + +## Recommendation + +Proceed to `/kiro:spec-design` with Option A and the translation table +above. Design phase will only need to specify the exact `Edit` operations +and the validation script — no architecture work. diff --git a/.kiro/specs/i18n-backfill-zh-json/requirements.md b/.kiro/specs/i18n-backfill-zh-json/requirements.md new file mode 100644 index 00000000..f5e9ee5d --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/requirements.md @@ -0,0 +1,63 @@ +# Requirements Document + +## Project Description (Input) +Backfill 10 keys in `locales/zh.json` that still hold English values, so Chinese UI users see Chinese strings everywhere. The `locales/en.json` and `locales/zh.json` files are structurally aligned (629 keys each) and `en.json` contains zero Chinese — this is the inverse problem (zh.json with English values), bundled into the i18n epic for symmetry. + +## Introduction + +This spec covers the work to translate ten remaining English-only natural-language values in `locales/zh.json` into natural Chinese, so that Chinese UI users see Chinese labels across the affected workflow steps and the graph panel. The change is data-only (locale JSON edits) and must keep `locales/en.json` and `locales/zh.json` structurally aligned (same key set, same key order). Tracks GitHub issue #8. + +## Boundary Context + +- **In scope**: + - Translation of nine user-facing English values in `locales/zh.json` (the keys listed in the project description, excluding the brand string). + - A documented decision for `log.prepareTaskId` — translate or keep English, recorded in the PR description with rationale. + - Preservation of all interpolation placeholders (`{count}`, `{taskId}`, etc.) verbatim. + - Preservation of the existing key set and key order in `locales/zh.json` so it remains structurally aligned with `locales/en.json`. +- **Out of scope**: + - Any English-side translation work in `locales/en.json` (covered by other tickets in the i18n epic). + - Restructuring locale files, moving keys between sections, or changing the i18n loader. + - Adding new keys for currently-untranslated UI elements (file a separate issue if any are discovered). + - Frontend code changes (`*.vue`, `*.js`, `*.ts`). +- **Adjacent expectations**: + - The frontend i18n loader (`vue-i18n` + `frontend/src/i18n/`) reads `locales/en.json` and `locales/zh.json` directly; it expects identical key trees in both files. + - The acceptance check `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` must remain empty after the change. + +## Requirements + +### Requirement 1: Backfill English-only values in `locales/zh.json` with natural Chinese +**Objective:** As a Chinese-locale UI user, I want all user-facing labels on Step 3, Step 4, Step 5, and the graph panel to be displayed in Chinese, so that I do not see English text mixed into a Chinese UI. + +#### Acceptance Criteria +1. When the Chinese locale is active and a user views the Step 3 simulation screen, the MiroFish frontend shall render `step3.waitingForActions` as a natural Chinese translation of "Waiting for agent actions..." (preserving the trailing ellipsis). +2. When the Chinese locale is active and a user views the Step 4 report screen, the MiroFish frontend shall render `step4.waitingForReportAgent` as a natural Chinese translation of "Waiting for Report Agent...". +3. When the Chinese locale is active and a user views the Step 5 interaction screen, the MiroFish frontend shall render `step5.interactiveTools`, `step5.agentsAvailable`, and `step5.reportAgentChat` as natural Chinese strings. +4. When the Chinese locale is active and a user opens the graph panel, the MiroFish frontend shall render `graph.panelTitle`, `graph.nodeDetails`, and `graph.relationship` as natural Chinese strings. +5. The translated value for `step5.agentsAvailable` shall contain the placeholder `{count}` exactly once and at a position that produces grammatically natural Chinese when interpolated. +6. The MiroFish locale data shall keep `home.heroDescBrand` set to the literal string `"MiroFish"` because it is a proper noun. + +### Requirement 2: Documented decision for `log.prepareTaskId` +**Objective:** As a maintainer, I want a recorded, justified decision about whether `log.prepareTaskId` should be translated, so that future contributors understand why this value differs from the surrounding policy. + +#### Acceptance Criteria +1. Where `log.prepareTaskId` is intentionally retained as a locale-neutral English log scaffold, the MiroFish PR description shall document that decision and the reason (log scaffold convention). +2. Where `log.prepareTaskId` is treated as a user-facing string, the MiroFish locale data shall translate it to natural Chinese while preserving the leading whitespace, the `└─` glyph, and the `{taskId}` placeholder verbatim. +3. The MiroFish PR description shall list any keys that remain English on purpose (brand strings and any retained log scaffolds) so reviewers can see they were not overlooked. + +### Requirement 3: Preserve structural alignment and placeholders +**Objective:** As a frontend developer relying on `vue-i18n`, I want `locales/en.json` and `locales/zh.json` to keep the same key set and the same key order, so that fallbacks and tooling continue to work and diffs stay reviewable. + +#### Acceptance Criteria +1. The MiroFish locale data shall keep the set of scalar key paths in `locales/zh.json` identical to the set in `locales/en.json` (the diff command in the boundary context shall produce no output). +2. The MiroFish locale data shall preserve the existing order of keys in `locales/zh.json` for every object that is not modified by this change. +3. For every translated value, the MiroFish locale data shall preserve interpolation placeholders (`{count}`, `{taskId}`, …) byte-for-byte. +4. If a translation requires inserting or removing a placeholder, then the MiroFish change shall be rejected and the translation revised, because placeholder drift breaks runtime interpolation. +5. The MiroFish locale data shall remain valid JSON (parseable by `JSON.parse` / `jq`) after the change. + +### Requirement 4: No frontend code changes +**Objective:** As a reviewer, I want the diff to be limited to `locales/zh.json`, so that the change is easy to verify and unrelated risk is excluded. + +#### Acceptance Criteria +1. The MiroFish change shall modify only `locales/zh.json`; no `*.vue`, `*.js`, `*.ts`, `*.py`, or other source files shall be edited. +2. The MiroFish change shall not add, rename, or delete keys in `locales/zh.json`; only the values of the listed keys may change. +3. If a listed value in `locales/zh.json` already contains natural Chinese (an upstream change landed first), then the MiroFish change shall leave that value untouched and note the skip in the PR description. diff --git a/.kiro/specs/i18n-backfill-zh-json/research.md b/.kiro/specs/i18n-backfill-zh-json/research.md new file mode 100644 index 00000000..b137d555 --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/research.md @@ -0,0 +1,115 @@ +# Research & Design Decisions — i18n-backfill-zh-json + +## Summary + +- **Feature**: `i18n-backfill-zh-json` +- **Discovery Scope**: Simple Addition (data-only edits to one JSON file). +- **Key Findings**: + - All ten flagged keys in `locales/zh.json` currently hold the exact + English value listed in issue #8 (verified via `jq`). + - `en.json` and `zh.json` key sets are currently identical + (`paths(scalars)` diff is empty), so we must preserve that + invariant. + - `log.prepareTaskId` is consumed by `Step2EnvSetup.vue:801` via + `addLog(t('log.prepareTaskId', { taskId: ... }))` — it IS + user-facing, and surrounding `log.*` keys are translated; therefore + we translate it. + +## Research Log + +### Current values of the targeted keys +- **Context**: Confirm the issue's claim that ten specific values are + English-only. +- **Sources Consulted**: `locales/zh.json`, `locales/en.json` (via `jq`). +- **Findings**: + - Each of the ten target keys in `zh.json` matches the English value + in `en.json` byte-for-byte today. + - `home.heroDescBrand` is the brand name `MiroFish` and should stay + English. +- **Implications**: Direct value replacement is safe; no upstream + changes have already translated any of them. + +### `log.prepareTaskId` usage classification +- **Context**: Issue requires a documented decision on whether this + value is locale-neutral scaffold or a user-facing string. +- **Sources Consulted**: `Grep` for `prepareTaskId` across the repo; + inspection of `frontend/src/components/Step2EnvSetup.vue:801`; + inspection of sibling `log.*` values in `zh.json`. +- **Findings**: + - The key is rendered into the in-UI log panel via `addLog(t(...))`. + - All sibling `log.*` values in `zh.json` are translated to natural + Chinese while preserving placeholders and continuation glyphs. +- **Implications**: Translate the value; preserve the leading two-space + indent, the `└─` glyph, and the `{taskId}` placeholder. + +### Translation conventions in `zh.json` +- **Context**: Choose Chinese wordings consistent with the existing + vocabulary so reviewers don't need to debate terminology. +- **Sources Consulted**: `jq` dumps of `home.*`, `step3.*`, `step4.*`, + `step5.*`, `graph.*`, `agent.*`, `log.*` in `zh.json`. +- **Findings**: + - "Agent" → "智能体" (e.g. `agent.title: "🤖 智能体详情"`). + - "Report Agent" → "报告智能体" + (e.g. `step4.reportAgentReady: "报告智能体就绪"`). + - "Graph" → "图谱" (e.g. existing `graphLoadFailed: "图谱加载失败"`). + - "Task ID" → "任务 ID" — keeps "ID" as a loanword, which is the + standard rendering in Chinese tech UIs and matches surrounding + log-line tone. +- **Implications**: Wording table in `design.md` follows these + conventions; a native reviewer can still suggest polish but no + reviewer should be surprised by the chosen vocabulary. + +## Architecture Pattern Evaluation + +| Option | Description | Strengths | Risks / Limitations | Notes | +|--------|-------------|-----------|---------------------|-------| +| In-place value `Edit` (selected) | Use the `Edit` tool for each of the ten lines in `zh.json` | No risk of key reorder; minimal blast radius; reviewable diff | Requires care that `old_string` is unique per edit | Matches surrounding convention | +| `jq` script rewrite | One-off `jq --arg ... '.x = $v'` script | Mechanizable | Older `jq` versions may reorder object keys, breaking structural alignment | Rejected | +| Manual full-file rewrite via `Write` | Rewrite the file with new values | Fewer edits | Highest risk of accidental whitespace/key-order drift | Rejected | + +## Design Decisions + +### Decision: Translate `log.prepareTaskId` rather than leave it English +- **Context**: Issue allows either choice, conditional on a documented + rationale. +- **Alternatives Considered**: + 1. Leave English on the grounds that it is a "log scaffold". + 2. Translate, matching the surrounding `log.*` translations. +- **Selected Approach**: Translate to ` └─ 任务 ID: {taskId}`. +- **Rationale**: The key is consumed by a user-visible log panel + (`Step2EnvSetup.vue:801`), and every other `log.*` key in `zh.json` + is already translated. Leaving this one in English would be the + inconsistent choice. +- **Trade-offs**: None material; the indent and `└─` glyph carry the + scaffold semantics and are preserved. +- **Follow-up**: Document the decision in the PR description so a + reviewer can override if they prefer to keep "Task ID" as a literal + technical identifier. + +### Decision: Use `Edit` (string replace) rather than a `jq` rewrite +- **Context**: Need to change ten values without disturbing key order + or the file's whitespace. +- **Selected Approach**: One `Edit` per key, matching the value with + enough surrounding context to be unique. +- **Rationale**: `Edit` operates on raw bytes — it cannot reorder keys + or drop comments/whitespace. `jq` rewrites are not safe across all + versions for object key order. +- **Trade-offs**: Slightly more tool calls; offset by safety. +- **Follow-up**: After the edits, run the alignment diff and the + `jq empty` check before committing. + +## Risks & Mitigations +- **Translation polish disagreements** — Reviewer may prefer different + wording. *Mitigation*: PR description lists the chosen renderings and + invites suggestions; copy changes are cheap. +- **Accidental placeholder drift** — `{count}` or `{taskId}` lost during + edit. *Mitigation*: post-edit `grep` check that each placeholder + still appears exactly once in its key's value. +- **Accidental key reorder** — JSON tooling sometimes reorders keys. + *Mitigation*: use `Edit` only; do not run `jq` write-back. + +## References +- `.kiro/specs/i18n-backfill-zh-json/gap-analysis.md` +- `.ticket/8.md` +- `frontend/src/components/Step2EnvSetup.vue:801` — usage of + `log.prepareTaskId`. diff --git a/.kiro/specs/i18n-backfill-zh-json/spec.json b/.kiro/specs/i18n-backfill-zh-json/spec.json new file mode 100644 index 00000000..5d18535e --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/spec.json @@ -0,0 +1,27 @@ +{ + "feature_name": "i18n-backfill-zh-json", + "created_at": "2026-05-07T15:24:17Z", + "updated_at": "2026-05-07T15:24:17Z", + "language": "en", + "phase": "tasks-generated", + "approvals": { + "requirements": { + "generated": true, + "approved": true + }, + "design": { + "generated": true, + "approved": true + }, + "tasks": { + "generated": true, + "approved": true + } + }, + "ready_for_implementation": true, + "ticket": { + "number": 8, + "url": "https://github.com/salestech-group/MiroFish/issues/8", + "snapshot": ".ticket/8.md" + } +} diff --git a/.kiro/specs/i18n-backfill-zh-json/tasks.md b/.kiro/specs/i18n-backfill-zh-json/tasks.md new file mode 100644 index 00000000..af47a2fe --- /dev/null +++ b/.kiro/specs/i18n-backfill-zh-json/tasks.md @@ -0,0 +1,29 @@ +# Implementation Plan + +- [x] 1. Backfill English-only values in `locales/zh.json` with the natural Chinese translations from the design's Translation Contract + - Edit `step3.waitingForActions` → `等待智能体执行动作...` + - Edit `step4.waitingForReportAgent` → `等待报告智能体...` + - Edit `step5.interactiveTools` → `交互工具` + - Edit `step5.agentsAvailable` → `{count} 个智能体可用` (placeholder `{count}` preserved exactly once) + - Edit `step5.reportAgentChat` → `报告智能体 - 对话` + - Edit `graph.panelTitle` → `图谱关系可视化` + - Edit `graph.nodeDetails` → `节点详情` + - Edit `graph.relationship` → `关系` + - Edit `log.prepareTaskId` → ` └─ 任务 ID: {taskId}` (preserves the two-space indent, the `└─` glyph, and the `{taskId}` placeholder verbatim) + - Leave `home.heroDescBrand` as the literal string `MiroFish` (brand) + - Use the `Edit` tool only (do not run any `jq` write-back); do not add, remove, or reorder any keys + - Observable completion: `git diff --stat` shows exactly one file changed (`locales/zh.json`); `git diff locales/zh.json` shows only value changes for the listed keys (no key adds/removes/reorders) + - _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.2, 3.2, 3.3, 4.1, 4.2, 4.3_ + +- [x] 2. Validate JSON parseability, key alignment, and placeholder preservation after the backfill + - Run `jq empty locales/zh.json` and confirm exit code 0 (file is valid JSON) + - Run `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` and confirm output is empty (key sets identical) + - Run `jq -r ''` for each of the ten keys and confirm the value matches the design's Translation Contract row (or `MiroFish` for `home.heroDescBrand`) + - Confirm `{count}` appears exactly once inside the new value of `step5.agentsAvailable`, and `{taskId}` appears exactly once inside the new value of `log.prepareTaskId` + - Observable completion: all five checks above pass; if any fails, return to task 1 and revise the offending edit before re-running validation + - _Requirements: 3.1, 3.3, 3.4, 3.5_ + +- [x] 3. Capture the `log.prepareTaskId` decision and any English-by-design exceptions for the PR description + - Record in a short note (in `.kiro/specs/i18n-backfill-zh-json/HANDOFF.md` if needed, or directly in the PR body at /done time) that: (a) `home.heroDescBrand` is intentionally kept as `MiroFish` because it is a brand; (b) `log.prepareTaskId` was translated to ` └─ 任务 ID: {taskId}` because it is rendered into the user-visible log panel by `Step2EnvSetup.vue:801` and surrounding `log.*` keys are translated. + - Observable completion: the rationale text is ready for inclusion in the PR description so reviewers can see the decisions at a glance + - _Requirements: 2.1, 2.3_ diff --git a/locales/zh.json b/locales/zh.json index b283cf0b..961d66ef 100644 --- a/locales/zh.json +++ b/locales/zh.json @@ -185,7 +185,7 @@ "step3": { "startGenerateReport": "开始生成结果报告", "generatingReport": "启动中...", - "waitingForActions": "Waiting for agent actions...", + "waitingForActions": "等待智能体执行动作...", "errorMissingSimId": "错误:缺少 simulationId", "startingDualSim": "正在启动双平台并行模拟...", "graphMemoryUpdateEnabled": "已开启动态图谱更新模式", @@ -216,7 +216,7 @@ "step4": { "generatingSection": "正在生成{title}...", "goToInteraction": "进入深度互动", - "waitingForReportAgent": "Waiting for Report Agent...", + "waitingForReportAgent": "等待报告智能体...", "collapse": "收起 ▲", "expandAll": "展开全部 {count} 条 ▼", "expandAllEntities": "展开全部 {count} 个 ▼", @@ -256,13 +256,13 @@ "world2": "世界2" }, "step5": { - "interactiveTools": "Interactive Tools", - "agentsAvailable": "{count} agents available", + "interactiveTools": "交互工具", + "agentsAvailable": "{count} 个智能体可用", "chatWithReportAgent": "与Report Agent对话", "chatWithAgent": "与世界中任意个体对话", "selectChatTarget": "选择对话对象", "sendSurvey": "发送问卷调查到世界中", - "reportAgentChat": "Report Agent - Chat", + "reportAgentChat": "报告智能体 - 对话", "reportAgentDesc": "报告生成智能体的快速对话版本,可调用 4 种专业工具,拥有MiroFish的完整记忆", "toolInsightForge": "InsightForge 深度归因", "toolInsightForgeDesc": "对齐现实世界种子数据与模拟环境状态,结合Global/Local Memory机制,提供跨时空的深度归因分析", @@ -291,13 +291,13 @@ "selectAgentFirst": "请先选择一个模拟个体" }, "graph": { - "panelTitle": "Graph Relationship Visualization", + "panelTitle": "图谱关系可视化", "refreshGraph": "刷新图谱", "graphMemoryRealtime": "GraphRAG长短期记忆实时更新中", "realtimeUpdating": "实时更新中...", "pendingContentHint": "还有少量内容处理中,建议稍后手动刷新图谱", - "nodeDetails": "Node Details", - "relationship": "Relationship", + "nodeDetails": "节点详情", + "relationship": "关系", "graphDataLoading": "图谱数据加载中...", "waitingOntology": "等待本体生成...", "toggleMaximize": "最大化/还原", @@ -578,7 +578,7 @@ "preparingSimEnv": "正在准备模拟环境...", "detectedExistingPrep": "检测到已有完成的准备工作,直接使用", "prepareTaskStarted": "准备任务已启动", - "prepareTaskId": " └─ Task ID: {taskId}", + "prepareTaskId": " └─ 任务 ID: {taskId}", "zepEntitiesFound": "从Zep图谱读取到 {count} 个实体", "entityTypes": " └─ 实体类型: {types}", "startPollingProgress": "开始轮询准备进度...",