fix(i18n): backfill english-only entries in zh.json
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
This commit is contained in:
parent
b15dc2ea2c
commit
0a65edfa46
|
|
@ -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 '<key>' 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.
|
||||
|
|
@ -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 '<key>'` 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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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 '<key>'` 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_
|
||||
|
|
@ -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": "开始轮询准备进度...",
|
||||
|
|
|
|||
Loading…
Reference in New Issue