# Collocation-Vocab-Practice-Claude-SKILL

> PTE Practice: Collocations + Vocabulary (Leitner spaced repetition)

- Skill: `ironking63/collocation-vocab-practice-claude-skill` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add ironking63/collocation-vocab-practice-claude-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ironking63/collocation-vocab-practice-claude-skill/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ironking63 (https://skillmd.com/u/ironking63)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ironking63/collocation-vocab-practice-claude-skill

---


# 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

1. 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.
2. 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.
3. 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.
4. 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.
5. 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):**
1. Gather non-retired, introduced items where `due <= today`, sorted most
   overdue first.
2. Fill up to the deck's `dailyCap` (default 15).
3. If room remains, add never-seen items in dataset order, capped at 8 new
   items per session regardless of remaining room.

**Mixed mode:**
1. Gather due items from *both* decks, combine and sort by due date.
2. Fill up to `mixed.dailyCap` (default 15).
3. 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.
4. 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.

