grask

agent
Guvenlik Denetimi
Basarisiz
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Basarisiz
  • rm -rf — Recursive force deletion command in docs/demo/record.sh
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

One question about your own code, when you finish coding. A SessionEnd hook for Claude Code that asks you about the mechanism you just shipped.

README.md

grask

CI
Python 3.8+
License: MIT
Status: alpha

One question about your own code, when you finish coding.

You can't tell the difference between understanding something and having watched it happen.
Shipping code used to force the issue — you couldn't ship what you didn't understand,
because it wouldn't run. That forcing function is gone.

grask watches your Claude Code sessions end and usually asks nothing. When it does ask, it
asks exactly one multiple-choice question about the mechanism you shipped, the next time
you run /grask.

Most sessions produce no question. That silence is the feature — not a failure to
find something.

grask: I have code in production I couldn't explain — one multiple-choice question about the code you just shipped

Example

The same probe as text. /grask inside Claude Code asks it through the native question UI
instead.

$ grask
from 2026-07-21 · retry backoff in the webhook dispatcher

Your retry loop sleeps 2**attempt seconds between attempts. Why does adding random
jitter matter more as the number of clients grows?

  a) Jitter reduces the total number of retries each client makes.
  b) Clients knocked out together retry together; jitter spreads them back out.
  c) Exponential backoff overflows without a random term to bound it.
  d) Jitter is what makes the sleep interruptible by a signal.

pick   [a-d]   ·   enter = skip   ·   /wrong
> b
✓ Backoff decides how long each client waits. It does nothing about them all waiting
the same amount. Clients dropped by one outage come back in lockstep, so the recovering
service takes the same thundering herd on every cycle. Jitter decorrelates the schedules.

Grading is mechanical — the key was minted with the question, so there is no second model
call and no judge to argue with.

Install

Both paths need the Claude Code CLI already installed and
authenticated. grask has no runtime dependencies and needs no second API key — it shells
out to the claude binary you already use. They are two ways in, not two products: each
wires the same SessionEnd capture hook and the same /grask skill.

As a plugin (recommended)

Needs a python3 (≥ 3.8) on your PATH. Inside Claude Code:

/plugin marketplace add imkp1/grask
/plugin install grask

That is the whole setup — no settings.json editing, no separate pip install, no uv.
The plugin carries grask's source under src/ and runs it with plain python3; grask has no
third-party dependencies, so there is no virtualenv and no build step. A SessionStart step
writes a small shim so the /grask skill can find the plugin's copy of grask. If your python3
is older than 3.8, grask doctor will say so. The skill is namespaced by the runtime, so you
type /grask:grask.

Standalone

For the bare grask command line, or if you'd rather not run a plugin:

uv tool install grask --prerelease=allow
grask install

Only pre-release versions are published so far, hence the flag — plain
uv tool install grask will find nothing. pipx install --pip-args=--pre grask works the
same way, as does uv tool install . from a clone. Install as a tool, not with uv sync:
both surfaces invoke grask by name, so it has to resolve without a path.

grask install writes the /grask skill and merges the SessionEnd hook into your
~/.claude/settings.json — idempotently, and leaving anything else in that file alone.
grask uninstall reverses both (your captured data is left in place), and grask doctor
checks the wiring and the environment it needs.

Updating

Neither path updates itself, and both hold a copy of the /grask skill — so a new
release reaches you only when you refresh that copy.

Plugin:

/plugin marketplace update grask
/reload-plugins

Claude Code disables auto-update for third-party marketplaces by default, and only ships an
update when the plugin's version field changes — which every grask release bumps, so the
plugin cache path changes with it and you get a clean refetch rather than a silent no-op.

Standalone:

uv tool upgrade grask --prerelease=allow
grask install

Run grask install again after the upgrade. It is idempotent, and it is what rewrites
~/.claude/skills/grask/SKILL.md — upgrading the package alone leaves the previous skill
file sitting in your skills directory. grask doctor will tell you what is wired and what
is not.

The capture hook spawns a detached worker and returns immediately — it never blocks the end
of your session, and it never speaks. Failures go to ~/.claude/grask/grask.log, never to
your terminal. If capture ever seems off, grask doctor is the one place that will tell you
why.

Approving the two commands it runs

Optional, and only for the /grask skill inside Claude Code. The skill reaches
grask by running its shim, so the first /grask of a session asks you to approve a
Bash command. To approve the two calls once instead of every session, add them to
the allow list in ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "Bash(~/.claude/grask/grask serve --json)",
      "Bash(~/.claude/grask/grask record:*)"
    ]
  }
}

Those two are the skill's entire interface: serve prints the next question and
writes nothing, record grades one answer. Neither takes input from the model
beyond a probe id and your pick. Skipping this only costs you a keystroke per
session.

Use

grask          # ask the next pending question, or say there's nothing

You get one question, three or four options, and one line of orientation about which
session it came from. Pick a letter. enter skips. /wrong rejects the premise if the
question misreads what happened.

Questions expire after 7 days. A probe about work you did last week is a quiz.

Privacy — read this before installing

grask reads your Claude Code transcripts, and it is not scoped to one project:

  • It reads every transcript under ~/.claude/projects/, across all your repositories.
  • It sends transcript content to a model — your prompts, the agent's replies, and the
    before/after text of edits — by shelling out to claude -p. That call runs under your
    existing Claude Code authentication and is subject to whatever data policy your account
    already has. No data goes anywhere else, and grask adds no telemetry.
  • It stores what it extracts locally, in a SQLite database at ~/.claude/grask/,
    including verbatim quotes of things you typed.

Controls:

  • GRASK_HOME relocates the database and log.
  • The batch tools in CONTRIBUTING.md take --exclude to
    skip projects by name substring, and --root to point at a different transcript
    directory. The session-end hook has neither — it captures whatever session just ended.

If any of your repositories are covered by an agreement that prohibits sending source to a
model, do not install the hook.

Nothing derived from a real transcript belongs in this repository. The tools write
under GRASK_HOME by default for exactly that reason, and .gitignore is a second line of
defence. This project has made that mistake once already.

How it works

Four stages, cheapest first. Each one filters, so only what survives pays for the next.

Stage Module Cost Job
0 — extract transcript.py free Pull the developer's own turns out of a session log. Tool results, file snapshots, and injected skill text are not the developer thinking. Sessions with no human turns stop here.
1 — triage triage.py one call List every moment worth asking about, each anchored to a verbatim quote and the turn it came from. Sees turns and file paths, never file contents. Most sessions yield nothing.
— select select.py free Rank the moments and pick one. Deliberately code, not prompt: a model asked to both find and choose picks arbitrarily, and the topic changed run to run on an unchanged session.
2 — seed seed.py one call State, as a falsifiable claim, what the developer may have accepted without understanding. Stored, so a better stage-3 prompt can re-ask the whole corpus later.
3 — probe probe.py one call, up to 3 Write one multiple-choice question about the mechanism, with the answer key and an explanation. A structurally unusable question is regenerated.

Several rules are enforced in code rather than prompted for, because instruction is not a
control. Two matter most:

  • The evidence rule. A triaged moment whose quote does not appear in the turn it names
    is demoted to silence. Same for a seed quote that appears nowhere the developer typed.
  • The one-question rule. A stem with two questions in it cannot have one correct
    option, so it is rejected and regenerated, up to three attempts.

The question must also teach something portable. A question whose answer is "because this
file says so" is answerable only by whoever sat through the session and is worth nothing
once they close the file.

grask names no model: it calls claude -p with no --model flag, so every stage runs on
whatever you have selected and there is no second credential to manage. Its own prompts are
small, and stages 2 and 3 only run on the minority of sessions triage keeps. Measured costs
are in docs/design.md.

Status

Alpha, and honest about it. The capture pipeline, storage, both delivery surfaces, and
mechanical grading all work end to end.

Not built, in the order they matter: the one-keypress "was this worth asking?" vote, which
is the only planned measure of whether the questions are any good; cross-session dedup, so
two sessions can currently produce near-identical probes; and resurfacing a question you got
wrong, which is the half IDEA.md argues matters most.

docs/design.md has the reasoning behind each decision;
IDEA.md covers what this is and the ways it might not work.

Contributing

Issues and pull requests are welcome — CONTRIBUTING.md has the
development setup, the three checks CI runs, and the three rules that are easy to break by
accident. Also CODE_OF_CONDUCT.md.

A question grask asked that was bad — wrong premise, wrong key, or testing nothing
portable — is the single most useful thing you can report. There is an issue template
for exactly that.

For anything where grask leaked, over-collected, or wrote outside GRASK_HOME, see
SECURITY.md and report it privately rather than in a public issue.

License

MIT — see LICENSE.

Yorumlar (0)

Sonuc bulunamadi