dsh-word-learn: Word lookup, frequency-based grading, and FSRS review in DSH

Preface

Developers who use English as their working language read a vast amount of technical content. The problem is usually not “not knowing the vocabulary,” but rather “knowing only one meaning of a word in a specific context,” and uncertainty about the accuracy of reading. Highlight translation can solve “understanding this sentence,” but after checking, you forget it, and nothing is left to review. The dsh-word-learn introduced below reverses the goal to “remembering the word”: after highlighting, a learning card pops up, checked words go into the vocabulary book, and FSRS schedules reviews.

What is it

dsh-word-learn is a DSH plugin, maintained by guicaiyue, with an MIT license in the GitHub repository. The community directory categorizes it under the “Memory” category. It solves a specific problem: enabling developers to look up words, add them to the book, and schedule reviews while reading English in DSH conversations, rather than treating translation as the endpoint.

The version number in the repository’s package.json is 0.1.0, and engines.node requires >=22.5.0. The repository was created on 2026-11-04, and as of our fetch, it had 0 GitHub stars. It is a personal maintenance project with evolving functionality and schedule.

How is it different from highlight translation

The README directly provides a comparison:

Highlight Translation This Plugin
Goal Make you understand this sentence Make you remember this word
Result Translation, forgotten after reading Vocabulary book + review schedule
Common words Still translates Marks “This is a high-frequency word, you likely already know”
Data None Local SQLite, exportable

In other words, it focuses on whether a word will be encountered again in the future or remembered, rather than the semantics of the current sentence.

Highlight Card: Only applies to conversation body

The most basic action is: select an English word in a DSH conversation, pop up a learning card on the spot, containing IPA, definitions, inflections, word frequency rating, real pronunciation, examples, and synonyms. The overlay does not modify the page DOM.

Scope control is implemented strictly: both ends of the selection must fall within [data-chat-flow]. The left sidebar, right sidebar, Trajectory page, and English learning dashboard do not respond. If the anchor cannot be found, it will not pop up at all, and won’t degrade into “random popups all over the page.” If you want to change this logic, first run npx vitest run tests/features/scope.test.mjs. The single source of truth for scope determination and exclusion lists is in src/client/features/core.js.

Sentence Translation & Word Splitting

Behavior differs when the whole sentence is selected: first give the Chinese translation, then list splittable candidate words below. Translation prioritizes DSH’s own model because technical context is more accurate, for example, reviews translates to “review”, latent space to “latent space”. When the model is unavailable, it falls back to the MyMemory public interface. Translation failure does not affect word splitting; splitting takes a separate path.

Dictionary, Word Frequency, and Filtering

The dictionary is a streamlined SQLite library from ECDICT, 14.4 MB in size, containing 59,111 entries and 39,053 inflection indexes, searchable offline. This means lookup does not rely on the network; the dictionary file is <plugin directory>/data/ecdict.db, read-only.

Because ECDICT lists inflected forms as separate entries and the word frequency field is often wrong, the plugin implements inflection fallback: children → child, better → good, perceived → perceive, and inherits the frequency of the base form. Word frequency is divided into five tiers: Top 1000, High 3000, Common 8000, Low Frequency, and Professional. The learning card will tell you “This is a high-frequency word, you likely already know,” avoiding wasting time on words you already mastered.

Two types of filtering rules are worth noting: Code text is not passed through; src/lib/index.js, config_path, getElementById are not treated as words. Number suffixes are not passed through; ≈62.3M, ≈65.7k will not be treated as M or k. Both the frontend and host router have gates set up.

Pronunciation, Examples, and Autoplay

Examples come from dictionaryapi.dev, with disk caching, and fallback if unavailable, not affecting lookup. Pronunciation uses the browser’s built-in speechSynthesis, zero network, offline capable, prioritizing system natural/online English voices. The selected voice and speed are saved locally. Browsers do not allow recording synthesis results, so there is no audio file cache; it is synthesized in real-time every time.

Autoplay is on by default but can be turned off. The switch is in Settings → Pronunciation Preferences → Autoplay. It reads once when entering the learning page, when a word appears, when viewing the answer, and when the spelling result comes out, creating an “read while listening” environment. The speaker icon allows manual replay at any time; if autoplay fails, no prompt is shown.

Vocabulary Book & Capability Profile

Checked words automatically enter the vocabulary book, recording the original sentence and the number of times encountered, and generate a five-dimensional capability profile: Recognize, Meaning, Write, Listen, Read Accurate. You can bookmark and add notes.

Confusing words/synonyms in the learning page and AI analysis are dotted small tags. Hovering or clicking them pops up IPA and definitions; you can add the word to the vocabulary book with one click in the card. The hover is just a preview and will not shove every scanned word into the book.

The appearance follows the DSH theme, colors are taken from theme tokens --dsw-alias-*, automatically following light/dark mode switching without needing a restart.

AI Analysis Model & Failure Prompts

Which model is used for root decomposition, distractors, and mnemonics is selected from DSH’s existing text model list in the settings page. The default is the first one, not following the conversation’s default model; changes take effect on the next analysis. When analysis fails, reasons are distinguished: model service unavailable, no key configured, rate limit, output is not JSON, reported separately, no longer uniformly displaying “model might be unavailable.”

Learning Page & FSRS-6

The upper half of the left column has an “English Learning” entry; clicking opens a full-page dashboard, including today’s review, tomorrow’s due, future 14-day forecast, review volume in the last 14 days, learning progress, capability profile, and reports. The schedule uses FSRS-6 (ts-fsrs@6.0.0, MIT), with two independent lines for each word: Recognize (receptive) and Write (productive).

Here are a few implementation rules worth noting:

  1. Writing must wait for Recognizing to stabilize. Only when Receptive enters review state (state>=2) and has been rated at least twice is Productive queued; when creating the card for lookup, Productive just builds the structure but doesn’t enter the queue.
  2. A word appears only once per round. If both lines are due on the same day, do the one due earlier first (if due is same, do Receptive first), leave the other for the next round; the dashboard’s today/tomorrow/forecast also deduplicates by word. Otherwise, it would become massed practice of the same word repeatedly, instead of spaced repetition—README mentioned the earlier implementation missed these two points, resulting in “just finished memorizing a word, the next card is still it.”
  3. The two lines train different things. Recognize gives English, selects meaning; Write gives Chinese meaning, requires spelling the word. Correct/Typo/Wrong are rated as Too Easy/Remembered/Forgetting.
  4. If forgotten repeatedly 8 times, it will be automatically suspended (leech), no longer entering the queue.

How “Forgot” is Handled

When rating “Forgot,” the answer is not given directly. Instead, you write the meaning yourself first, compare with the definition and original sentence, then spell the word correctly again before rating Again(1). The word is hidden during the spelling stage, and the speaker and skip are also hidden. This step only adds retrieval and production, it does not change the rating: successful recall still rates “Forgot” to avoid tricking FSRS into extending intervals.

When material with definitions is available, it first does a multiple-choice. After AI generates definition material based on “this word + the sentence you encountered it in,” “Forgot” will first ask you to choose which of the four definitions is in this sentence, then give the contrast “You chose X / This sentence is Y,” and then enter spelling; if analysis hasn’t finished, it automatically reverts to free recall.

There are also two layers: Recall at the end of the session, re-spelling words rated “Forgot” today before the end of the round, clearing that “recall debt” only if spelled correctly; Next-day revisit, going to the learning page the next day to do a one-minute “Did you forget these words yesterday, do these two sentences have the same meaning?”, clearing debt on correct, restarting debt on wrong, only logging, not touching FSRS, can be skipped.

Inline Annotation in Conversation

In the English read, words being learned or having cards will have a dotted underline. Hovering or focusing pops up a small card showing the definition of this word in the sentence and “Add to review.” The original text is not changed or translated. Code blocks, inline code, filenames, URLs, links, popups, and other plugin interfaces are not marked; collapsed content only marks the title, filled in after expanding; text during streaming generation is not touched. To turn it off, execute localStorage['dwl-annotate'] = 'off' in the console and refresh.

Data Location & Backup

File Location Description
Dictionary <plugin directory>/data/ecdict.db Read-only, can be regenerated
Vocabulary Book $DSH_HOME/dsh-word-learn/user.db Not regenerable, please backup
External Cache $DSH_HOME/dsh-word-learn/cache/ Can be deleted

The vocabulary book is not regenerable, please backup this file before upgrading or migrating.

Interface & Security Boundaries

The frontend (highlight card, annotation, learning page) is all compiled into a single artifact dist/client.js, loaded by the host via package.json’s exports["./client"]. There is no frontend script routing and no page injection. The host entry is package.json’s exports["."] → lib/host/index.js.

On the data side, there are 22 interfaces, with src/host/routes/paths.ts as the unique exit point. For example, GET|POST /dsh-word-learn/lookup, POST /dsh-word-learn/grade, GET /dsh-word-learn/dashboard. Write operations only accept methods declared in the table; others return 405 with Allow header; cross-site requests are all 403. This fence applies to third-party scripts as well.

When regenerating the dictionary is needed, the process given in the README is to download ECDICT and build:

# 1) Download ECDICT (63 MB)
curl -L -o D:\dsh-cache\tmp\ecdict.csv https://raw.githubusercontent.com/skywind3000/ECDICT/master/ecdict.csv

# 2) Build
python scripts\build_dict.py

Installation & Usage Prerequisites

The README does not give a unified dsh plugin add ... command. Before installing, confirm the entry point on the community directory page and the repository, do not concatenate the installation command based on the repository name. Before getting started, it is recommended to read AGENTS.md and CONVENTIONS.md in the repository: the former is hard constraints before changing code and a “where to go to change X” locator table, the latter is directory boundaries, route contracts, data access, and testing discipline. Run pnpm verify before submitting changes; it chains build, artifact check, type/lint/format/dependency check, and tests.

The plugin runs with the current DSH process permissions, able to read/write host files and initiate HTTP requests. Before installing, you should check the source code and license to confirm it does not touch data you don’t want it to access.

Conclusion

The value of dsh-word-learn lies in connecting “reading a word” with “remembering the word”: the local dictionary guarantees offline lookup availability, word frequency ratings avoid repeatedly consuming time on mastered words, and FSRS-6 guarantees review scheduling instead of one-time lookup. The project is in its early stages, with few stars and community feedback, suitable for developers willing to read the source code and modify code according to AGENTS.md constraints. Directory page and repository are below.

  • Community Directory: https://www.skillhub.cn/plugins/guicaiyue/dsh-word-learn
  • GitHub: https://github.com/guicaiyue/dsh-word-learn
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye