A modern, blazingly fast Python client and Command Line Interface (CLI) for managing vocabulary in the Phase-6 web application.
This tool reverse-engineers the private Phase-6 Single Page Application API, combining robust browser automation (via Playwright) for complex authentication with lightning-fast native REST API calls for vocabulary CRUD operations.
This repo is packaged as an agent skill (opencode / Claude Code compatible). The entire project lives in .agents/skills/phase6/:
.agents/skills/phase6/
├── SKILL.md # Skill definition: triggers, invocation, gotchas
├── scripts/pyphase6/ # The Python package (CLI, client, models)
└── tests/ # Pytest suite (fully offline, Playwright mocked)
Skill-aware agents discover it via SKILL.md; the wheel is built from the skill's scripts/ dir by hatchling.
- Automated Login: Uses a headless Playwright instance to perform the login flow and extract the required
x-jauthtokensession tokens. - Fast CRUD API: Direct JSON requests to the Phase-6 backend, skipping slow browser UI navigation entirely.
- Bulk Import: Quickly upload hundreds of vocabulary cards from CSV or JSON files.
- Rich Terminal UI: Beautiful console output and progress bars built with
typerandrich.
Ensure you have Python 3.14.7 installed. We use uv to manage the environment and dependencies.
# Clone the repository
git clone https://github.com/timhls/phase6-cli.git
cd phase6-cli
# Install dependencies using uv
uv sync
# Install Playwright browsers (needed for the login flow)
uv run playwright install chromiumBefore doing anything, you need to log in to generate your session token. This opens a headless Chromium browser in the background.
uv run pyphase6 loginYou will be prompted securely for your Phase-6 email and password.
List all the subjects (vocabulary books or lists) you currently own:
uv run pyphase6 subjectsTake note of the Subject ID from the output, as you will need it to manage cards within that subject. Add --json for agent-parseable output with full IDs.
View all vocabulary items inside a specific subject:
uv run pyphase6 vocab <SUBJECT_ID>(Use --limit <N> to change the number of items fetched).
Add, update, or delete a single vocabulary card:
# Add a new card
uv run pyphase6 add <SUBJECT_ID> "Your Question" "Your Answer"
# Update an existing card
uv run pyphase6 update <SUBJECT_ID> <CARD_ID> "New Question" "New Answer"
# Delete a card
uv run pyphase6 delete <CARD_ID>You can bulk import many cards at once using a CSV or JSON file.
CSV Format (import.csv)
question,answer
"Hello","Hallo"
"Goodbye","Auf Wiedersehen"JSON Format (import.json)
[
{"question": "Dog", "answer": "Hund"},
{"question": "Cat", "answer": "Katze"}
]Run the import command:
uv run pyphase6 import <SUBJECT_ID> import.csvThis project uses ruff for linting/formatting, mypy for static type checking, and pytest for unit testing.
# Run all tests
uv run pytest
# Format and lint code
uv run ruff format .
uv run ruff check .
# Run type checks (scoped to the skill package)
uv run mypy .agents/skills/phase6/scripts/pyphase6MIT License