PTE Practice: Collocations + Vocabulary (Leitner spaced repetition)
This skill renders a self-contained HTML artifact that runs a Leitner-box
flashcard review across two decks — 300 PTE collocations and 300 PTE
vocabulary words — with a mode picker so the user chooses which to
practice each session. It is meant to be invoked repeatedly (ideally daily)
via the trigger phrase /practice. Progress persists across sessions using
the artifact persistent storage API (window.storage) — NOT localStorage.
What to do when this skill triggers
- Read the two datasets in this skill folder:
assets/collocations.json — 300 objects:
{id, collocation, category, meaning, example}. Categories: Verb +
Noun, Adjective + Noun, Noun + Noun, Adverb + Adjective, Phrasal /
Prepositional.
assets/vocabulary.json — 300 objects:
{id, word, pos, meaning, example, synonym}. pos is the part of
speech (v., n., adj., adv.). Each word includes a synonym, matching
PTE's synonym-matching question style.
- A working reference implementation already exists at
assets/review-template.html. It embeds both datasets (normalized into
a common card shape internally), implements the mode picker, per-deck
Leitner logic, mixed-mode session composition, flashcard UI, and
window.storage persistence described below. Prefer reusing/adapting
this file directly (view it, copy its logic) over writing it from
scratch — it's already been simulated end-to-end and verified to keep
the two decks' progress fully isolated even in mixed mode. Only diverge
from it if the user asks for a change.
- Build (or reuse) a single HTML artifact that:
- Loads saved progress from
window.storage.get('practice-progress', false).
If it doesn't exist yet, initialize both decks fresh (see "Progress
schema" below).
- Shows a mode picker first: Collocations / Vocabulary / Mixed.
- After a mode is chosen, computes due items for that mode (see "Session
composition") and shows a dashboard (new / in-progress / mastered
counts) before starting.
- Presents up to a per-mode daily cap (default 15) of cards, in the same
flip-and-self-rate flow used for both decks: Again / Hard / Good / Easy.
- Persists updates back to the same
practice-progress key with a
single window.storage.set call per rating.
- Call
show_widget (or create the artifact per the platform's normal
artifact flow) with this HTML. Do not ask the user for confirmation
first — just build and show the session.
- After presenting it, briefly tell the user in chat which mode they're
in and how many cards are due, in one or two sentences. Do not dump the
full card list into the chat text itself — the artifact is the
interface.
If the user asks to reset progress, change daily volume, or inspect stats
in detail, handle it via the artifact's own UI controls — build those in
rather than trying to do it conversationally.
Progress schema
Single storage key practice-progress (personal, non-shared):
{
collocation: { items: { <id>: {box, due, lapses, streakFrom5, retired, introduced} }, dailyCap: 15 },
vocabulary: { items: { <id>: {box, due, lapses, streakFrom5, retired, introduced} }, dailyCap: 15 },
mixed: { dailyCap: 15 },
lastMode: "collocation" | "vocabulary" | "mixed" | null,
totalSessions: 0
}
Keeping both decks under one key means a single get/set covers
everything, per the storage API's batching guidance — don't split this
into two separate keys.
Leitner logic (applies identically to both decks)
5 boxes with fixed review intervals:
| Box |
Interval before next review |
| 1 |
1 day |
| 2 |
3 days |
| 3 |
7 days |
| 4 |
16 days |
| 5 |
35 days |
- New item: starts in Box 1, due immediately,
introduced:false until
it's actually pulled into a session.
- Again: box → 1, due tomorrow,
lapses += 1, resets the retirement
streak.
- Hard: same box, due date = today + that box's interval, resets the
retirement streak.
- Good: box up by 1 (max 5), due date = today + new box's interval.
- Easy: box up by 2 (max 5), due date = today + new box's interval.
- Retiring: after two consecutive Good/Easy ratings from Box 5, mark
retired:true. Retired items stop appearing in sessions for that deck.
Give the user a way to un-retire an item via the UI if they want extra
practice.
Session composition (10–15 items/day default per mode)
Single-deck mode (Collocations or Vocabulary):
- Gather non-retired, introduced items where
due <= today, sorted most
overdue first.
- Fill up to the deck's
dailyCap (default 15).
- If room remains, add never-seen items in dataset order, capped at 8 new
items per session regardless of remaining room.
Mixed mode:
- Gather due items from both decks, combine and sort by due date.
- Fill up to
mixed.dailyCap (default 15).
- If room remains, alternate pulling new items from collocations and
vocabulary (one from each in turn) until the combined new-item count
hits 8 or both pools run out.
- Each card in a mixed session still updates its own deck's progress —
never write vocabulary updates into the collocation deck or vice versa.
If there are zero due items and everything's introduced, show "All caught
up" for that mode rather than forcing extra reviews.
Card format (flashcard, self-rated)
Each card shows:
- Front: for collocations, the phrase (e.g. "raise awareness") with its
category tag (e.g. "Verb + Noun"). For vocabulary, the word (e.g.
"mitigate") with its part-of-speech tag (e.g. "v.").
- User taps "Show answer" to flip.
- Back: the meaning, then (for vocabulary only) a synonym line, then the
example sentence with the target word/phrase bolded.
- Below that: Again / Hard / Good / Easy buttons, color-coded (red / orange
/ green / blue).
Keep the visual design calm and uncluttered — this is a daily study tool,
not a game. Show "Card X of N" and the current deck label during review,
and a short completion summary at the end (reviewed / promoted / needs
work counts).
Artifact requirements
- Single HTML file, inline CSS/JS, no external network calls.
- Use
window.storage.get('practice-progress', false) /
.set('practice-progress', ..., false), always wrapped in try/catch. This
is personal, non-shared data (shared = false).
- Batch writes: one
set call per rating, not more.
- Handle first-run gracefully: if storage is empty or throws, initialize
fresh state from the embedded datasets instead of erroring out.
- No localStorage/sessionStorage anywhere.
Notes for future sessions of this skill
- Datasets are fixed at 300 + 300 items and shouldn't need to change often.
To add/edit/remove an entry, edit the relevant JSON file directly (find
by
id or the word/collocation field) rather than regenerating the whole
set.
- If the user wants to grow the vocabulary set toward a larger target
(e.g. 1000 words), extend
assets/vocabulary.json in additional batches,
keeping the same schema (id, word, pos, meaning, example, synonym),
continuing id numbering from the current max, and re-running the
duplicate check before saving. Don't regenerate the whole file from
scratch — append.
- If the user wants a different daily volume, that's a per-mode setting in
the artifact's own UI — don't regenerate the skill for this.
1---2name: collocation-vocab-practice-claude-skill3description: PTE Practice: Collocations + Vocabulary (Leitner spaced repetition)4---56# PTE Practice: Collocations + Vocabulary (Leitner spaced repetition)78This skill renders a self-contained HTML artifact that runs a Leitner-box9flashcard review across two decks — 300 PTE collocations and 300 PTE10vocabulary words — with a mode picker so the user chooses which to11practice each session. It is meant to be invoked repeatedly (ideally daily)12via the trigger phrase `/practice`. Progress persists across sessions using13the artifact persistent storage API (`window.storage`) — NOT localStorage.1415## What to do when this skill triggers16171. Read the two datasets in this skill folder:18 - `assets/collocations.json` — 300 objects:19 `{id, collocation, category, meaning, example}`. Categories: Verb +20 Noun, Adjective + Noun, Noun + Noun, Adverb + Adjective, Phrasal /21 Prepositional.22 - `assets/vocabulary.json` — 300 objects:23 `{id, word, pos, meaning, example, synonym}`. `pos` is the part of24 speech (v., n., adj., adv.). Each word includes a synonym, matching25 PTE's synonym-matching question style.262. A working reference implementation already exists at27 `assets/review-template.html`. It embeds both datasets (normalized into28 a common card shape internally), implements the mode picker, per-deck29 Leitner logic, mixed-mode session composition, flashcard UI, and30 `window.storage` persistence described below. Prefer reusing/adapting31 this file directly (view it, copy its logic) over writing it from32 scratch — it's already been simulated end-to-end and verified to keep33 the two decks' progress fully isolated even in mixed mode. Only diverge34 from it if the user asks for a change.353. Build (or reuse) a single HTML artifact that:36 - Loads saved progress from `window.storage.get('practice-progress', false)`.37 If it doesn't exist yet, initialize both decks fresh (see "Progress38 schema" below).39 - Shows a **mode picker** first: Collocations / Vocabulary / Mixed.40 - After a mode is chosen, computes due items for that mode (see "Session41 composition") and shows a dashboard (new / in-progress / mastered42 counts) before starting.43 - Presents up to a per-mode daily cap (default 15) of cards, in the same44 flip-and-self-rate flow used for both decks: Again / Hard / Good / Easy.45 - Persists updates back to the same `practice-progress` key with a46 single `window.storage.set` call per rating.474. Call `show_widget` (or create the artifact per the platform's normal48 artifact flow) with this HTML. Do not ask the user for confirmation49 first — just build and show the session.505. After presenting it, briefly tell the user in chat which mode they're51 in and how many cards are due, in one or two sentences. Do not dump the52 full card list into the chat text itself — the artifact is the53 interface.5455If the user asks to reset progress, change daily volume, or inspect stats56in detail, handle it via the artifact's own UI controls — build those in57rather than trying to do it conversationally.5859## Progress schema6061Single storage key `practice-progress` (personal, non-shared):6263```64{65 collocation: { items: { <id>: {box, due, lapses, streakFrom5, retired, introduced} }, dailyCap: 15 },66 vocabulary: { items: { <id>: {box, due, lapses, streakFrom5, retired, introduced} }, dailyCap: 15 },67 mixed: { dailyCap: 15 },68 lastMode: "collocation" | "vocabulary" | "mixed" | null,69 totalSessions: 070}71```7273Keeping both decks under one key means a single `get`/`set` covers74everything, per the storage API's batching guidance — don't split this75into two separate keys.7677## Leitner logic (applies identically to both decks)78795 boxes with fixed review intervals:8081| Box | Interval before next review |82|-----|------------------------------|83| 1 | 1 day |84| 2 | 3 days |85| 3 | 7 days |86| 4 | 16 days |87| 5 | 35 days |8889- **New item**: starts in Box 1, due immediately, `introduced:false` until90 it's actually pulled into a session.91- **Again**: box → 1, due tomorrow, `lapses += 1`, resets the retirement92 streak.93- **Hard**: same box, due date = today + that box's interval, resets the94 retirement streak.95- **Good**: box up by 1 (max 5), due date = today + new box's interval.96- **Easy**: box up by 2 (max 5), due date = today + new box's interval.97- **Retiring**: after two consecutive Good/Easy ratings *from Box 5*, mark98 `retired:true`. Retired items stop appearing in sessions for that deck.99 Give the user a way to un-retire an item via the UI if they want extra100 practice.101102## Session composition (10–15 items/day default per mode)103104**Single-deck mode (Collocations or Vocabulary):**1051. Gather non-retired, introduced items where `due <= today`, sorted most106 overdue first.1072. Fill up to the deck's `dailyCap` (default 15).1083. If room remains, add never-seen items in dataset order, capped at 8 new109 items per session regardless of remaining room.110111**Mixed mode:**1121. Gather due items from *both* decks, combine and sort by due date.1132. Fill up to `mixed.dailyCap` (default 15).1143. If room remains, alternate pulling new items from collocations and115 vocabulary (one from each in turn) until the combined new-item count116 hits 8 or both pools run out.1174. Each card in a mixed session still updates its *own* deck's progress —118 never write vocabulary updates into the collocation deck or vice versa.119120If there are zero due items and everything's introduced, show "All caught121up" for that mode rather than forcing extra reviews.122123## Card format (flashcard, self-rated)124125Each card shows:126- Front: for collocations, the phrase (e.g. "raise awareness") with its127 category tag (e.g. "Verb + Noun"). For vocabulary, the word (e.g.128 "mitigate") with its part-of-speech tag (e.g. "v.").129- User taps "Show answer" to flip.130- Back: the meaning, then (for vocabulary only) a synonym line, then the131 example sentence with the target word/phrase bolded.132- Below that: Again / Hard / Good / Easy buttons, color-coded (red / orange133 / green / blue).134135Keep the visual design calm and uncluttered — this is a daily study tool,136not a game. Show "Card X of N" and the current deck label during review,137and a short completion summary at the end (reviewed / promoted / needs138work counts).139140## Artifact requirements141142- Single HTML file, inline CSS/JS, no external network calls.143- Use `window.storage.get('practice-progress', false)` /144 `.set('practice-progress', ..., false)`, always wrapped in try/catch. This145 is personal, non-shared data (`shared = false`).146- Batch writes: one `set` call per rating, not more.147- Handle first-run gracefully: if storage is empty or throws, initialize148 fresh state from the embedded datasets instead of erroring out.149- No localStorage/sessionStorage anywhere.150151## Notes for future sessions of this skill152153- Datasets are fixed at 300 + 300 items and shouldn't need to change often.154 To add/edit/remove an entry, edit the relevant JSON file directly (find155 by `id` or the word/collocation field) rather than regenerating the whole156 set.157- If the user wants to grow the vocabulary set toward a larger target158 (e.g. 1000 words), extend `assets/vocabulary.json` in additional batches,159 keeping the same schema (`id, word, pos, meaning, example, synonym`),160 continuing `id` numbering from the current max, and re-running the161 duplicate check before saving. Don't regenerate the whole file from162 scratch — append.163- If the user wants a different daily volume, that's a per-mode setting in164 the artifact's own UI — don't regenerate the skill for this.