Command line¶
grip and git grip are the same program.
grip quiz¶
Run the quiz now, without a hook.
grip quiz # staged changes
grip quiz --unpushed # commits not on any remote
grip quiz --branch # the branch since it left main: its pull request
grip quiz --range main..HEAD # explicit range
grip quiz --passing-score 90 --difficulty hard
grip quiz --provider fake # offline dry run
grip quiz --report out.json # also write the report here
grip quiz --fresh # new questions, even for a diff quizzed recently
Trying again on the same diff reuses the questions from the last attempt (see
cache_hours), so only the grading calls the model. --fresh asks for
new ones. grip whiteboard reuses its board the same way.
--branch diffs from the merge base with the default branch: what origin/HEAD points
at, else origin/main or origin/master, else a local main or master. It is the
"quiz my PR" command, whatever has or has not been pushed yet.
Answer each question on one line and press Enter. To answer in paragraphs, paste them: a pasted answer keeps its line breaks and ends at the next empty line. (On Windows each pasted line still answers the next question.)
Exit codes: 0 passed or skipped, 1 failed the quiz, 2 error.
grip whiteboard¶
Draw the change as a whiteboard and defend it in the browser. The parts of the change, how
they connect and five questions pinned to them come from your diff. Answers are graded like
grip quiz, and a pass counts for the push hook. See the whiteboard.
grip whiteboard # staged changes
grip whiteboard --unpushed # commits not on any remote
grip whiteboard --branch # the whole branch since main
grip whiteboard --range main..HEAD # explicit range
grip whiteboard --interview # rubrics visible to the person asking; nothing recorded
grip whiteboard --export board.html # standalone page, no rubrics, nothing graded
grip whiteboard --no-open --port 8765 # print the address instead of opening a browser
It takes the same --provider, --model, --difficulty, --passing-score and --report
options as grip quiz. The page is served on 127.0.0.1 behind a random token and waits up
to twenty idle minutes. Exit codes: 0 defended, skipped or exported, 1 below the pass
mark, 2 error (including Ctrl-C or the idle timeout, which record nothing).
grip hook STAGE [ARGS...]¶
The entry point installed hooks and pre-commit call. STAGE is pre-commit or
pre-push; extra arguments are whatever git passes to the hook. You rarely run this
yourself, but it is handy for debugging:
printf 'refs/heads/main %s refs/heads/main %s\n' "$(git rev-parse HEAD)" "$(git rev-parse origin/main)" \
| grip hook pre-push origin
Accepts the same --passing-score, --provider, --model, --difficulty and
--report flags as grip quiz.
grip ask / grip grade / grip check¶
The quiz in three non-interactive steps, for coding agents. ask prints the questions as
JSON (rubrics stay in .git/grip/pending.json), grade scores a JSON list of answers and
remembers a pass, check exits 0 when the diff already passed. Same --staged,
--unpushed, --branch and --range selectors as grip quiz. Raw line breaks inside an
answer's JSON string are accepted and kept. See Coding agents.
grip ask --unpushed
grip grade --answers - <<'EOF'
["answer 1", "answer 2", "answer 3", "answer 4", "answer 5"]
EOF
grip check --unpushed && git push
grip agent-hook claude-code [--gate push|commit|both]¶
Claude Code PreToolUse hook. Reads the hook payload from stdin and denies git push
(and git commit with --gate both) until the diff has passed a quiz. Installed by the
plugin.
grip init¶
Sets a repository up in one go: writes a commented .grip.toml, installs the pre-push hook
(chaining after an existing hook rather than failing) and runs grip agents for the
coding agents it detects.
In a terminal it asks three questions, each with a default picked for this machine: which
model writes and grades the questions (an installed coding agent first, else
anthropic), the pass mark, and whether to quiz before pushes, commits or both. Press
Enter to keep a default. A flag answers its question up front, --yes takes every
default without asking, and outside a terminal (scripts, CI) nothing is asked. It then
says what is still missing for the chosen provider, such as ANTHROPIC_API_KEY.
grip init # ask, write, install
grip init --yes # every default, no questions
grip init --provider ollama --passing-score 80 --difficulty hard
grip init --stage pre-commit --stage pre-push
grip init --no-hook --no-agents # only .grip.toml
grip init --force # overwrite an existing .grip.toml
grip agents¶
Writes the file each installed coding agent reads so it runs the quiz before pushing:
AGENTS.md, CLAUDE.md and .claude/settings.json, GEMINI.md, .cursor/rules/grip.mdc,
.windsurf/rules/grip.md, .clinerules/grip.md, .github/copilot-instructions.md.
Detection looks for the agent's binary on PATH or its directory under your home.
grip agents --list # detected agents and what each would get
grip agents # write for the detected ones
grip agents --all # write for every known agent
grip agents --agent gemini --dry-run
grip agents --remove # strip the blocks, leave the rest of each file
See Coding agents.
grip install / grip uninstall¶
grip install # pre-push
grip install --stage pre-commit --stage pre-push
grip install --append # chain after an existing hook
grip install --force # replace an existing hook
grip uninstall # remove from every stage
Hooks go to .git/hooks/ or to core.hooksPath when it is set. Files grip wrote start
with a marker line so uninstall never touches a hook it does not own.
grip status¶
Shows which stages have grip installed, whether a foreign hook is in the way, the last quiz (score, pass or fail, how long ago), whether hooks are paused, the effective configuration, and for each of the staged changes, the unpushed commits and the branch against the default branch, where it stands:
passed 98/100 at 17:52, remembered, failed 40/100 at 17:40 and not quizzed read as
they say. A branch whose commits are all on the remote can still be unquizzed:
grip quiz --branch covers it.
grip skip / grip resume¶
GRIP_SKIP=1 is awkward from an IDE's push button. grip skip skips the next hook run
once; grip skip --hours 2 pauses every hook run for two hours; grip resume cancels.
Only the hooks and the agent push gate look at it, a manual grip quiz never does.
grip skip && git push # one push without the quiz
grip skip --hours 1 # a demo, a pairing session
grip resume
grip statusline¶
One short line for an editor or Claude Code status line: grip 92/100 pass, with
paused appended while grip skip is in effect. Outside a repository or before any quiz
it prints nothing and exits 0. It reads an optional JSON payload on stdin and uses its
cwd, which is what Claude Code sends:
grip statusline --json prints the score, pass mark, time and skip state for other tools.
grip config¶
Prints the effective configuration after merging files, environment and defaults.
grip last¶
Shows the last graded quiz in this repository: each question with its focus, your answer,
the points and the feedback, then the verdict. Rubrics are not shown. --json prints the
same payload as grip grade plus summary, questions, answers and at; the
/grip-explain skill builds a commit message from it.
grip forget¶
Clears remembered passes so the next commit or push is quizzed again.
grip study export / grip study status¶
Every graded quiz is appended to .git/grip/history.jsonl and the repository is noted in
~/.local/share/grip/repos.json ($XDG_DATA_HOME/grip, or GRIP_DATA_HOME). export
collects that history from every repository on the machine into one anonymised JSON file
you can upload to a study platform yourself; grip never uploads anything.
grip study status # how many repos and quizzes, and the exact field list
grip study export # last 45 days -> grip-export-<YYYYMMDD>.json
grip study export --since 0 --out ~/all-quizzes.json
The export carries, per quiz: an opaque id, an opaque per-repository hash, the time,
stage, provider, model, pass mark, score, pass/fail, and for each question its focus
label and points. It never contains the diff, file paths, repository names, question
text, rubrics, your answers, feedback or the verdict. grip study status prints both
lists so you can check before sharing.
grip login / grip solve SLUG / grip submit¶
The Keep A Grip commands. login TOKEN [--url URL] verifies and stores an
API token from your dashboard (logout forgets it, whoami shows the account).
problems [--category SLUG] lists the catalogue. solve SLUG [--dir PATH] sets up a
repository with PROBLEM.md and the problem's pass mark, and remembers the base commit.
submit [--no-tests] [--dry-run] runs the problem's test command, quizzes you on everything
since that base commit (uncommitted work included) and reports the score; --dry-run prints
the payload instead of sending it.