Content
# bilingual-content-sync-agent
**English** | [中文](README.zh-CN.md)
> Solo Founder OS agent #4 — keep `en.json` and `zh.json` (or any locale pair) in sync. Diffs, translates missing keys via Claude, queues them in a markdown HITL review file, applies approved edits back to your locale JSON. Never auto-writes without human approval.
[](LICENSE)
[](https://pypi.org/project/bilingual-content-sync-agent/)
[](#)
[](https://anthropic.com)
Built by [Alex Ji](https://github.com/alex-jb) for [VibeXForge](https://github.com/alex-jb/vibex)'s 925 EN/ZH i18n strings. Born from this thought:
> *Every feature ships English first. ZH catches up days or weeks later. Tracking which keys are stale is manual labor I do at 1 AM. Same for the next 11 makers I know.*
## What it does
```
en.json + zh.json
↓
diff (find keys present in EN, missing/empty/echo'd in ZH)
↓
translate via Claude Sonnet (vibex-tone glossary baked in)
↓
queue/pending/<timestamp>-review.md
↓
founder edits in Obsidian, moves to queue/approved/
↓
apply → writes back to zh.json (preserves nesting + key order)
```
## CLI
```bash
# Coverage report
bilingual-sync stats --en locales/en.json --zh locales/zh.json
# Show what's missing (no LLM call)
bilingual-sync diff --en locales/en.json --zh locales/zh.json
# Translate + write review file (LLM call)
bilingual-sync draft \
--en locales/en.json \
--zh locales/zh.json \
--glossary glossary.json \
--tone "indie SaaS, gamified, neon-pixel, peer-to-peer"
# After human review → move file to queue/approved/, then:
bilingual-sync apply --en locales/en.json --zh locales/zh.json
```
## Glossary file
Glossary keys force consistent translation of brand terms. Without it, Claude picks reasonable defaults but those drift across runs.
```json
{
"Forge": "锻造",
"Dojo": "道场",
"Vibe": "氛围",
"Login": "登录",
"Sign up": "注册"
}
```
## What gets flagged as "missing"
A key is missing in ZH when ANY of:
- key absent from `zh.json`
- ZH value is empty string
- ZH value byte-equals the EN value (a common copy-paste mistake — easy to miss without tooling)
## Design choices
- **HITL is non-negotiable.** UI strings are seen by every user every session. One bad translation that ships globally is worse than five days of catch-up. The agent never writes to `zh.json` without an explicit approve-and-apply step.
- **Sonnet by default, not Haiku.** Cold UI translations are exactly the task where naïve Haiku output gets too literal ("Login" → "登入" instead of "登录"). Sonnet's nuance is worth the 3× cost for 925 strings (~$0.50 total).
- **Batched calls.** 50 keys per call is the token-budget sweet spot. Full vibex catalog = ~20 calls = ~$0.50.
- **Preserves placeholders + HTML.** The system prompt explicitly forbids translating `{name}`, `<span>`, ICU patterns. If Claude breaks this it gets flagged in the review file.
- **Built on solo-founder-os.** AnthropicClient handles graceful degrade + auto-logs token usage to `~/.bilingual-content-sync-agent/usage.jsonl` (cost-audit-agent picks it up monthly).
## Roadmap
- [x] **v0.1** — diff/draft/apply/stats CLI · HITL queue · Sonnet drafting · 43 tests · graceful degrade
- [ ] **v0.2** — Multi-language support (EN→ES, EN→JA, etc.) — same code path, different glossaries
- [ ] **v0.3** — Watch mode: re-run on commit, post-flagging stale keys to GitHub PR
- [ ] **v0.4** — In-context preview: show the React component a key appears in
- [ ] **v0.5** — Reverse sync: detect ZH-only orphan keys (features that got removed but ZH was forgotten)
## MCP server (Claude Desktop / Cursor / Zed)
Translate missing i18n keys inline from your AI assistant.
```bash
pip install 'bilingual-content-sync-agent[mcp]'
```
```json
{
"mcpServers": {
"bilingual-sync": {
"command": "bilingual-sync-mcp",
"env": { "ANTHROPIC_API_KEY": "..." }
}
}
}
```
Tools: `diff_locales(en, zh)` · `translate_missing(en, zh, ...)` · `apply_approved(en, zh)`
## License
MIT.
---
## 🧩 Part of the [Solo Founder OS](https://github.com/alex-jb/solo-founder-os) stack
A growing collection of MIT-licensed agents that share `solo-founder-os` as their base — cron, eval, reflexion, AnthropicClient, HITL queue, notifiers. Each agent is independently useful; together they cover the full one-person company workflow.
🌐 The whole stack is live in production at [vibexforge.com](https://vibexforge.com).
| Agent | What it does |
|---|---|
| [solo-founder-os](https://github.com/alex-jb/solo-founder-os) | The shared base lib (cron · eval · reflexion · skill library · DGM-lite). Every other agent depends on it. |
| [build-quality-agent](https://github.com/alex-jb/build-quality-agent) | Pre-push Claude diff reviewer + local build runner — catches CI-killing changes before they ship. |
| [customer-discovery-agent](https://github.com/alex-jb/customer-discovery-agent) | Reddit pain-point scraper + Claude clustering for product validation. |
| [funnel-analytics-agent](https://github.com/alex-jb/funnel-analytics-agent) | Daily founder brief + real-time PH-day alerts across 9 sources. |
| [orallexa-marketing-agent](https://github.com/alex-jb/orallexa-marketing-agent) | AI marketing agent — submit project once, get platform-native posts for X / Reddit / HN / Dev.to / 小红书 + 7 more. Powers [vibexforge.com](https://vibexforge.com). |
| [vc-outreach-agent](https://github.com/alex-jb/vc-outreach-agent) | Cold email drafter — investors (vc mode) or paying customers (customer mode, merged from customer-outreach in v0.9.0). HITL queue + SMTP sender. |
| [cost-audit-agent](https://github.com/alex-jb/cost-audit-agent) | Monthly bill audit across 6 providers (Vercel / Anthropic / OpenPanel / HyperDX / Supabase / GitHub Actions) with dollar-tagged waste findings. |
| [customer-support-agent](https://github.com/alex-jb/customer-support-agent) | Triage user messages → auto-draft replies → HITL queue. Closes the L5 customer-support layer. |
| [payments-agent](https://github.com/alex-jb/payments-agent) | Overdue-invoice reminder drafter. Stripe-shaped types + MockProvider fallback + hard money-safety prompt rules. |
*Each agent's own row is omitted from its README. Install whichever solve real problems for you — `pip install <agent-name>`.*