Database CLI Reference
The database CLI lets you inspect the local review history stored in the review database. Use it to answer practical questions like:
- Which review sources produce the most actionable comments?
- Which skipped or not-addressed comments keep repeating?
- Has this comment already been dismissed before?
- What does the raw review data look like?
You can run these queries in two ways:
myk-claude-tools db stats --by-source
/myk-review:query-db stats --by-source
All command examples on this page come from the project’s actual CLI definitions, plugin command, or tests.
At a glance
| Command | Best for |
|---|---|
stats |
Addressed-rate reports by source or reviewer |
patterns |
Recurring skipped or not-addressed comment patterns |
dismissed |
Repo-specific dismissed history and reasons |
query |
One-off read-only SQL queries |
find-similar |
Comparing a new comment to previously dismissed comments |
Before you start
If you want to run the CLI directly, install the myk-claude-tools console script:
uv tool install myk-claude-tools
myk-claude-tools --version
Note: By default, the CLI looks for the database at
<git-root>/.claude/data/reviews.db, where<git-root>is the Git repository root of your current working directory.Tip: Every
dbsubcommand accepts--db-path, so you can point at a different database file when needed.
These analytics commands query an existing database. Review data is stored separately after a completed review flow is written to disk.
A minimal stored review payload looks like this:
{
"metadata": {
"owner": "test-owner",
"repo": "test-repo",
"pr_number": 123
},
"human": [{"body": "human comment"}],
"qodo": [{"body": "qodo comment"}],
"coderabbit": [{"body": "coderabbit comment"}]
}
The database is append-only: each stored review run creates a new row in reviews, then inserts its comments into comments.
Note: If the same PR is stored more than once, the database keeps multiple
reviewsrows for that PR. That is useful for history, but it also means custom queries may needDISTINCT, grouping, or a “latest review” filter.
Common options
| Option | Available on | What it does |
|---|---|---|
--json |
All db subcommands |
Returns JSON instead of a formatted table |
--db-path |
All db subcommands |
Uses a specific database file |
--owner, --repo |
dismissed, find-similar |
Scopes the command to one repository |
--min |
patterns |
Sets the minimum number of repeated matches to report |
--threshold |
find-similar |
Sets the minimum similarity score from 0.0 to 1.0 |
Tip: Table output truncates long values for readability. Use
--jsonif you need the full comment body or want to pipe the result into another tool.
Command reference
stats
Use stats to measure how often comments are addressed, skipped, or left unaddressed.
myk-claude-tools db stats
myk-claude-tools db stats --by-reviewer
myk-claude-tools db stats --by-source --json
What it does:
--by-sourcegroups by comment source such ashuman,qodo, andcoderabbit--by-reviewergroups by the individualauthor- Source-based output includes an
addressed_ratepercentage
Note: If you do not pass either
--by-sourceor--by-reviewer,statsdefaults to source-based output.Warning:
--by-sourceand--by-reviewerare mutually exclusive. Passing both returns an error.
patterns
Use patterns to find repeated comment clusters that may be worth turning into reviewer guidance or skip rules.
myk-claude-tools db patterns
myk-claude-tools db patterns --min 3
myk-claude-tools db patterns --json
What it returns:
path: the file path where the pattern appearsoccurrences: how many similar comments were foundreason: the most commonreplyorskip_reasonin that clusterbody_sample: the first comment body in the cluster
How matching works:
- The command only looks at comments with status
not_addressedorskipped - Comments are grouped by exact
path - Within a path, comments are clustered when their body similarity is at least
0.6
Note:
patternsworks across the whole database. It is not scoped to oneownerorrepo.
dismissed
Use dismissed to list comments for a specific repository that were skipped, not addressed, or otherwise recorded as reusable dismissals.
myk-claude-tools db dismissed --owner myk-org --repo claude-code-config
myk-claude-tools db dismissed --owner myk-org --repo claude-code-config --json
In JSON mode, the command returns fields such as:
pathlinebodystatusreplyskip_reasonauthortypecomment_id
In table mode, the CLI shows a smaller set of columns:
pathlinestatusreplyauthor
Note: You may see some rows with status
addressed. That is intentional foroutside_diff_comment,nitpick_comment, andduplicate_comment, because those body-comment types do not rely on a normal GitHub review thread for later skipping.
query
Use query when you want raw SQL access to the database.
myk-claude-tools db query "SELECT * FROM comments WHERE status = 'skipped'"
myk-claude-tools db query "SELECT status, COUNT(*) as cnt FROM comments GROUP BY status"
myk-claude-tools db query "SELECT * FROM comments LIMIT 5" --json
myk-claude-tools db query "SELECT COUNT(*) as count FROM comments" --json
A practical example from the plugin command is:
myk-claude-tools db query "SELECT * FROM comments WHERE status = 'skipped' ORDER BY id DESC LIMIT 10"
This command is useful when you want exact control over:
- filtering by status, source, author, or path
- counting rows
- grouping and sorting
- inspecting raw rows behind
stats,patterns, ordismissed
Warning: The query interface is read-only. Only
SELECTandWITHstatements are allowed. Multiple statements are blocked, and mutating keywords such asINSERT,UPDATE,DELETE,DROP,ALTER,CREATE,ATTACH,DETACH, andPRAGMAare rejected.
find-similar
Use find-similar to compare a new comment against previously dismissed comments in the same repository and file path.
echo '{"path": "foo.py", "body": "Add error handling..."}' | \
myk-claude-tools db find-similar --owner myk-org --repo claude-code-config --json
The CLI reads JSON from standard input. The input must be a single JSON object with both path and body.
Actual input shape used by the test suite:
{"path": "path/to/file.py", "body": "Add skip option"}
How matching works:
- Repository must match
--ownerand--repo - File path must match exactly
- Only comments with status
not_addressedorskippedare considered - Similarity is based on case-insensitive word overlap, not semantic meaning
- The default threshold is
0.6 - Valid threshold values are
0.0through1.0
If a match is found, JSON output includes the matched row plus a similarity score. In text mode, the CLI prints:
- the similarity score
- the matched
path:line - the matched status
- the matched reason
- the first 100 characters of the original body
Warning: Pass a single JSON object, not a JSON array. The CLI reads
pathandbodydirectly from the top-level input object.
Slash command wrapper
Inside Claude Code, the myk-review plugin exposes the same database queries through /myk-review:query-db.
/myk-review:query-db stats --by-source
/myk-review:query-db stats --by-reviewer
/myk-review:query-db patterns --min 2
/myk-review:query-db dismissed --owner X --repo Y
/myk-review:query-db query "SELECT * FROM comments WHERE status='skipped' LIMIT 10"
/myk-review:query-db find-similar < comments.json
Use the slash command when you are already working inside Claude Code and want the same analytics without leaving the chat.
Database schema
The review database has two main tables:
reviews: one row per stored review runcomments: one row per stored comment fromhuman,qodo, orcoderabbit
Actual schema snippet:
CREATE TABLE IF NOT EXISTS reviews (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pr_number INTEGER NOT NULL,
owner TEXT NOT NULL,
repo TEXT NOT NULL,
commit_sha TEXT NOT NULL,
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
review_id INTEGER NOT NULL REFERENCES reviews(id),
source TEXT NOT NULL,
thread_id TEXT,
node_id TEXT,
comment_id INTEGER,
author TEXT,
path TEXT,
line INTEGER,
body TEXT,
priority TEXT,
status TEXT,
reply TEXT,
skip_reason TEXT,
posted_at TEXT,
resolved_at TEXT,
type TEXT DEFAULT NULL
);
Relevant indexes from the same schema:
CREATE INDEX IF NOT EXISTS idx_comments_review_id ON comments(review_id);
CREATE INDEX IF NOT EXISTS idx_comments_source ON comments(source);
CREATE INDEX IF NOT EXISTS idx_comments_status ON comments(status);
CREATE INDEX IF NOT EXISTS idx_reviews_pr ON reviews(owner, repo, pr_number);
CREATE INDEX IF NOT EXISTS idx_reviews_commit ON reviews(commit_sha);
The most useful fields for day-to-day analytics are:
source: where the comment came fromauthor: who wrote itpathandline: where it appliesstatus:pending,addressed,skipped, ornot_addressedreplyandskip_reason: why it was resolved, skipped, or not addressedtype: special body-comment categories such asoutside_diff_comment,nitpick_comment, andduplicate_comment
Practical query recipes
See which sources are most actionable
myk-claude-tools db stats --by-source
Use this when you want a quick view of how often comments from each review source get addressed.
Compare reviewers
myk-claude-tools db stats --by-reviewer
This is useful when your database contains multiple human or AI reviewers and you want author-level totals.
Find repeated skipped guidance
myk-claude-tools db patterns --min 2
Use this to surface repeated comment clusters that may be good candidates for future auto-skip rules or reviewer guidance.
Pull recent skipped rows directly
myk-claude-tools db query "SELECT * FROM comments WHERE status = 'skipped' ORDER BY id DESC LIMIT 10"
This is the quickest way to inspect recent skipped rows without writing a separate script.
Check whether a comment has already been dismissed
echo '{"path": "foo.py", "body": "Add error handling..."}' | \
myk-claude-tools db find-similar --owner myk-org --repo claude-code-config --json
Use this when you want to answer, “Have we seen and skipped something like this before?”
Troubleshooting
Note: If the database file does not exist, the commands return no results rather than creating a new database.
Warning: Default database discovery depends on Git. If you run the CLI outside the repository you want to inspect, the default path may point at the wrong place or fail entirely.
Tip: If the table output looks cut off, rerun the same command with
--json. The built-in formatter truncates long cell values for readability.