Agent skill
LC ZH Translate
a sparse overlay, not a second tree
The cheatsheets and FAQs are translated into 繁體中文 as an overlay —
translated prose keyed per section, composed with the English document at build time,
with every code fence stored exactly once. /lc-zh-translate works that
store — translating what is missing, and adapting the entries an English edit
parked rather than starting them from nothing.
1 status dp_loop_order 0/33 — one of four sheets untouched
patience_sorting 0/24 · math_logic_puzzles 0/14
memory_constrained_algorithms 0/14
2 sync nothing parked — the document had no overlay at all
3 todo 33 sections, each with its key
<!-- 4e9c8ca0cfb6 --> the H1 and its Scope line
4 write i18n/zh/<id>.md
> **範圍** — 為什麼自底向上 DP 的迴圈巢狀與方向…
⭐⭐⭐⭐⭐ kept on the heading, verbatim
dp.md#template-1b-... left as the ENGLISH anchor
every <!--CODE--> marker in place, in order
5 refresh sync clean · status --write → 5171/5318
6 gate compose accepted every marker · e2e 80/80
7 assumed 5 LC-titled headings: their Chinese IS the English title
A real run. Code is never stored twice, so it can never drift between the two languages.
Why an overlay and not a second tree
Three ways a translation rots
The storage design is the answer to the first one. The skill is the answer to the other two.
Roughly 70% of a cheatsheet is fenced code that must read identically in both languages, and it would be tracked per file — so a 45-line edit invalidates a 1,000-line translation.
Fix: prose only, keyed per section. Median 249 bytes.
<!--CODE--> marker
Every fence is lifted to a one-line marker before storage and spliced back at compose time. A section that drops one, adds one or reorders them makes compose throw.
Rule: count the markers before and after.
[見 §3](#two-pointers) keeps the English slug. The build pairs the two documents' headings by position, retargets every fragment, and then asserts nothing dangles.
Translate the anchor and the assertion fires.
sync → todo → write → sync → status
Seven steps, in order
Pick one to see what it does and the rule that step exists to enforce.
What lands in the store
How a translation is stored
One entry per section, keyed by a hash of its English text. Everything else is read off the English document, so the two can never disagree.
<!-- afb8deac2112 --> <- the key: a hash of the English
# 堆積與優先佇列 <- heading TEXT translated, position fixed
> **範圍** — 堆積(heap,這個資料結構)以及它所實作的優先佇列…
^ the Scope line, which becomes the card
<!--CODE--> <- a fence, stored once, in English only
一般來說,`heapq` 只實作 min-heap… <- API names stay English
<!--CODE-->
| Never in a translation | Why |
|---|---|
| a new or dropped heading | Structure is the English document's. The two cannot disagree about shape. |
| a translated anchor target | The build retargets fragments by heading position, then asserts nothing dangles. |
category / tier / kind | Read off the English document, so the two indexes can never disagree. |
| an API, class or command name | They are what you type, and what an interviewer will say. |
| an LC problem title | House rule — they stay English in both trees. |
| English tree | Overlay | Progress | |
|---|---|---|---|
| Cheatsheets | doc/cheatsheet/<slug>.md | i18n/zh/<slug>.md | 5138/5318 |
| FAQs | doc/faq/<path>.md | i18n/zh/faq/<path>.md | 902/902 |
CORPORA in site/i18n.js is the only place that table lives
— script/zh.js, build-site.js and
i18n.corpus.test.js all read it, so a third translated tree is an entry
there rather than three copies of a directory name. A document's id is its store
path minus the .md, which is also the address the CLI takes.
<!-- stale: 51e9781a0030 -->
這一段的英文改過了,但中文大部分還可以用…
When an English section changes, its translation simply goes missing from the store
— and sync parks it rather than deleting it, because the edit
is usually small and the Chinese usually still most of the way there.
compose ignores parked entries, so one can never reach a page. Reverting
the English revives it on the next sync, same text and same key.
sync --prune is the only thing that throws them away — so it
is never reached for as a tidy-up.
An id prefix stands for everything under it
How to call it
/lc-zh-translate heap # one cheatsheet
/lc-zh-translate faq # the whole FAQ tree
/lc-zh-translate faq/java # one directory
/lc-zh-translate faq/java/jvm # one document
work the zh backlog
what is still untranslated?
| Left out | What happens |
|---|---|
| Which document | It reports the backlog and asks. A campaign is your call about where to spend effort. |
| The keys | Taken from todo, never composed by hand. |
| Structure | Read off the English document. A translation cannot add or drop a section. |
| The progress docs | Regenerated by status --write, never hand-edited. |
The guardrails
What it will not do
- Drop, add or reorder a
<!--CODE-->marker.composethrows. The markers are how the code that is stored once gets back into both languages. - Add or remove a section.Structure is the English document's, which is why the two can never disagree about shape.
- Translate an anchor, an API name or an LC title.The first breaks the link assertion; the other two are what you type and what an interviewer says.
- Run
sync --pruneto tidy.It is the only thing that discards parked work, and parked work was kept on purpose. - Paste English prose to move the percentage.Coverage is a proxy. A page a Chinese reader can actually use is the thing.
- Start a campaign you did not ask for.180 sections is a lot of tokens. Which ones is a decision worth making deliberately.
One markdown file, no dependencies
Install
SKILL.md is the whole recipe — nothing to build and no network calls,
so the same source runs on any agent that takes a system prompt. Pick yours.
Drop the skill directory into your user-level skills folder and it loads in every repo:
git clone --depth 1 https://github.com/yennanliu/CS_basics.git /tmp/cs_basics
mkdir -p ~/.claude/skills
cp -r /tmp/cs_basics/.claude/skills/lc-zh-translate ~/.claude/skills/
Already installed inside this repo at .claude/skills/lc-zh-translate/.
The directory name is the command.
Zip the directory, then Customize → Skills → + → + Create skill → Upload a skill:
cd .claude/skills && zip -r lc-zh-translate.zip lc-zh-translate
Leave the YAML frontmatter intact — description is what Claude matches your request against.
Codex reads AGENTS.md at the repo root automatically. Point it at the skill:
## Translating into 繁體中文
When asked to translate a cheatsheet or FAQ, work the zh backlog, or
refresh the translation progress, follow
`.claude/skills/lc-zh-translate/SKILL.md`.
A pointer, not a copy — one source of truth means a fix reaches every agent at once.
Same shape in GEMINI.md, or point at it for a single session:
gemini -p "Follow the recipe in .claude/skills/lc-zh-translate/SKILL.md. \
Translate the dp_loop_order sheet."
Paste SKILL.md in as the system prompt. For Cursor or Windsurf, put the
Codex pointer above into a rule file
(.cursor/rules/lc-zh-translate.mdc or the editor's equivalent).
curl -sL https://raw.githubusercontent.com/yennanliu/CS_basics/master/.claude/skills/lc-zh-translate/SKILL.md
Away from this repo the transferable part is the storage idea: prose only, keyed per section, structure taken from the source document, and code stored exactly once.
Under the hood
What is inside
- SKILL.md The whole recipe — what an overlay is and why, the five prime directives, the sync → todo → write → sync → status loop, the seven steps, the do-not list, and a worked run.
Gated in CI by
check_skills.py,
and the store it writes is gated by the build itself — compose throws
on a marker mismatch, and the link retargeting asserts nothing dangles.
The rest of the loop
Where it fits
/lc-cheatsheet re-translates the sections an edit
parked; /lc-zh-translate is the one that drives the standing backlog, and
/lc-faq-add writes the Chinese for a new FAQ answer in the
same pass. The way in is the 中文 / EN button in the navbar, or
cheatsheets.zh and faqs.zh.