Local-first LSAT practice analytics from LawHub — without storing official LSAT content.
lawhub-pp-cli syncs authenticated LawHub practice-test metadata into local SQLite, then provides score history, weakness reports, question lists, user-authored review notes, and safe links back into LawHub for official content review.
This is an unofficial tool. It is not affiliated with or endorsed by LSAC or LawHub.
Allowed/synced:
- attempt IDs and test/module IDs
- test names, dates, modes, scores
- raw/scored totals
- section IDs/types/counts
- chosen answer letters
- correctness
- question type/subtype
- difficulty
- per-question timing
- flag state
- links back to LawHub
- user-authored notes
Not stored:
- LSAT question stems
- passages
- answer-choice text
- official explanations
- bulk official LSAT content
Use review open to view official content in LawHub.
Created by @nolan (Nolan McCafferty).
The recommended path installs both the lawhub-pp-cli binary and the pp-lawhub agent skill (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, and other agents supported by the upstream skills CLI) in one shot:
npx -y @mvanhorn/printing-press-library install lawhubFor CLI only (no skill):
npx -y @mvanhorn/printing-press-library install lawhub --cli-onlyFor skill only — installs the skill into the same agents as the default command above, but skips the CLI binary (use this to update or reinstall just the skill):
npx -y @mvanhorn/printing-press-library install lawhub --skill-onlyTo constrain the skill install to one or more specific agents (repeatable — agent names match the skills CLI):
npx -y @mvanhorn/printing-press-library install lawhub --agent claude-code
npx -y @mvanhorn/printing-press-library install lawhub --agent claude-code --agent codexIf npx isn't available (no Node, offline), install the CLI directly via Go (requires Go 1.26.3 or newer):
go install github.com/mvanhorn/printing-press-library/library/education/lawhub/cmd/lawhub-pp-cli@latestThis installs the CLI only — no skill.
Download a pre-built binary for your platform from the latest release. On macOS, clear the Gatekeeper quarantine: xattr -d com.apple.quarantine <binary>. On Unix, mark it executable: chmod +x <binary>.
Install the CLI binary first. The installer writes binaries to a per-user managed bin directory by default: $HOME/.local/bin on macOS/Linux and %LOCALAPPDATA%\Programs\PrintingPress\bin on Windows.
npx -y @mvanhorn/printing-press-library install lawhub --cli-onlyThen install the focused Hermes skill.
From the Hermes CLI:
hermes skills install mvanhorn/printing-press-library/cli-skills/pp-lawhub --forceInside a Hermes chat session:
/skills install mvanhorn/printing-press-library/cli-skills/pp-lawhub --forceRestart the Hermes session or gateway if the newly installed skill is not visible immediately.
Install both the CLI binary and the focused OpenClaw skill. The installer defaults binaries to a per-user bin directory ($HOME/.local/bin on macOS/Linux, %LOCALAPPDATA%\Programs\PrintingPress\bin on Windows):
npx -y @mvanhorn/printing-press-library install lawhub --agent openclawRestart the OpenClaw session or gateway if the newly installed skill is not visible immediately.
Do not paste LSAC/LawHub credentials into chat.
LawHub/MSAL needs browser storage, not just cookies. The supported login flow imports storage from an already-running debuggable browser.
- Start a browser with Chrome DevTools Protocol enabled. Chrome is preferred; Brave/Chromium work too.
# Chrome, if installed:
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/lawhub-debug-profile https://app.lawhub.org/library/fulltests
# Or Brave:
brave-browser --remote-debugging-port=9222 --user-data-dir=/tmp/lawhub-debug-profile https://app.lawhub.org/library/fulltests-
Log into LawHub in that browser and confirm the library page loads.
-
In another terminal, import the active browser session:
lawhub-pp-cli auth login --cdp http://127.0.0.1:9222- Verify:
lawhub-pp-cli auth status --live --agentExpected live auth shape:
{"live":{"checked":true,"ok":true,"probe":"library-page","status":200}}Fallback import, if another tool produced Playwright/browser-use storage state:
lawhub-pp-cli auth import-file /path/to/storage-state.jsonOther auth helpers:
lawhub-pp-cli auth status --agent
lawhub-pp-cli auth path --agent
lawhub-pp-cli auth logout --agentIf LawHub user-id discovery fails, set:
export LAWHUB_USER_ID=<LAW_HUB_USER_ID>or pass:
--user-id <LAW_HUB_USER_ID>lawhub-pp-cli doctor --agent
lawhub-pp-cli auth status --live --agent
lawhub-pp-cli sync browser --agent
lawhub-pp-cli sync history --agent
lawhub-pp-cli sync report-metadata --agent
lawhub-pp-cli summary --agent
lawhub-pp-cli weakness report --agentUse explicit sync steps. There is intentionally no public sync all.
Health/version:
lawhub-pp-cli version --agent
lawhub-pp-cli doctor --agent
lawhub-pp-cli doctor --live --agentAuth:
lawhub-pp-cli auth login --cdp http://127.0.0.1:9222
lawhub-pp-cli auth import-file <storage-state.json>
lawhub-pp-cli auth status --live --agent
lawhub-pp-cli auth path --agent
lawhub-pp-cli auth logout --agentSync:
lawhub-pp-cli sync browser --agent
lawhub-pp-cli sync history --agent
lawhub-pp-cli sync history --module LSAC140 --agent
lawhub-pp-cli sync report-metadata --agent
lawhub-pp-cli sync report-metadata --attempt <testInstanceId> --agentAttempts/tests:
lawhub-pp-cli tests list --agent
lawhub-pp-cli attempts list --agent
lawhub-pp-cli attempts show <attempt-id> --agentQuestions and notes:
lawhub-pp-cli questions list --incorrect --agent
lawhub-pp-cli questions list --type "Matching Flaws" --agent
lawhub-pp-cli questions list --difficulty 4 --agent
lawhub-pp-cli questions list --min-time 120 --agent
lawhub-pp-cli questions show <question-id> --agent
lawhub-pp-cli questions note <question-id> --note "Misread conditional conclusion" --agent
lawhub-pp-cli questions note <question-id> --why-picked "..." --why-correct "..." --next-time "..." --agentAnalytics:
lawhub-pp-cli summary --agent
lawhub-pp-cli weakness report --agentReview in LawHub:
lawhub-pp-cli review open <attempt-id> --section 1 --question 17
lawhub-pp-cli review open <attempt-id> --section 1 --question 17 --print-url --agentLow-token output:
lawhub-pp-cli summary --select counts,recent_average,weakest_question_types --agent
lawhub-pp-cli questions list --incorrect --select id,question_type,chosen_answer,correct_answer,is_correct --agentauth
attempts
doctor
login # alias for auth login
questions
review
summary
sync
tests
version
weaknesssync exposes:
browser
history
report-metadataThese prototype commands are intentionally not public unless reimplemented Go-native:
lawhub-pp-cli sync all
lawhub-pp-cli sync questions
lawhub-pp-cli capture-har
lawhub-pp-cli export obsidian
lawhub-pp-cli attempts importDB: ~/.local/share/lawhub-pp-cli/lawhub.sqlite
Config dir: ~/.config/lawhub-pp-cli
Session dir: ~/.openclaw/secure/lawhub
Session: ~/.openclaw/secure/lawhub/storage-state.json
Account: ~/.openclaw/secure/lawhub/account.jsonOverride with --data-dir, --config-dir, and --secure-dir.
Start the browser with remote debugging first:
brave-browser --remote-debugging-port=9222 --user-data-dir=/tmp/lawhub-debug-profile https://app.lawhub.org/library/fulltests
curl http://127.0.0.1:9222/json/versionThe curl command should return JSON containing webSocketDebuggerUrl.
Re-import from the debuggable browser after confirming LawHub is logged in:
lawhub-pp-cli auth login --cdp http://127.0.0.1:9222
lawhub-pp-cli auth status --live --agentSet:
export LAWHUB_USER_ID=<LAW_HUB_USER_ID>Do not extract it. Open LawHub:
lawhub-pp-cli review open <attempt-id> --section <n> --question <q>make build VERSION=0.1.0-dev
make test
make vet
make smoke VERSION=0.1.0-devDesigned as a Printing Press package under:
library/education/lawhubwith .printing-press.json, SKILL.md, .manuscripts/, and Go source under cmd/ and internal/.