Development Environment
This repository combines shared Claude Code configuration with a Python CLI package named myk-claude-tools. If you are contributing locally, the most important things to understand are the uv-first Python workflow, the single tests dependency group, the hook-driven local guardrails, and the whitelist-style .gitignore.
If you are orienting yourself, these are the paths you will touch most often:
myk_claude_tools/for the Python package and CLI commandstests/for the pytest suitescripts/for hook scripts such asrule-enforcer.pyandgit-protection.pysettings.jsonfor Claude Code hook wiring and tool permissionsagents/,rules/, andplugins/for shared configuration content
Python Package Setup
pyproject.toml defines a small Python package: Python 3.10+, Hatchling for builds, a console script named myk-claude-tools, and only two runtime dependencies.
[project]
name = "myk-claude-tools"
version = "1.7.2"
description = "CLI utilities for Claude Code plugins"
readme = "README.md"
license = "MIT"
requires-python = ">=3.10"
authors = [{ name = "myk-org" }]
keywords = ["claude", "cli", "github", "code-review"]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = ["click>=8.0.0", "tomli>=2.0.0; python_version < '3.11'"]
[project.scripts]
myk-claude-tools = "myk_claude_tools.cli:main"
The CLI itself is a Click command group. At the top level, it exposes subcommands for CodeRabbit workflows, review database queries, PR helpers, release tasks, and review operations.
@click.group()
@click.version_option()
def cli() -> None:
"""CLI utilities for Claude Code plugins."""
cli.add_command(coderabbit_commands.coderabbit, name="coderabbit")
cli.add_command(db_commands.db, name="db")
cli.add_command(pr_commands.pr, name="pr")
cli.add_command(release_commands.release, name="release")
cli.add_command(reviews_commands.reviews, name="reviews")
def main() -> None:
"""Entry point."""
cli()
Note: The package version is stored in both
pyproject.tomlandmyk_claude_tools/__init__.py. If you update release metadata manually, keep both in sync.
Dependency Groups
The repository currently defines a single dependency group: tests.
[dependency-groups]
tests = ["pytest>=9.0.2"]
There is no separate dev, lint, or docs dependency group in pyproject.toml today. In practice, that means the project keeps development dependencies intentionally lean and routes test installation through uv.
Note:
uv.lockis tracked in the repository. If you change dependencies, plan to update bothpyproject.tomlanduv.lock.
Prerequisites
Minimum setup:
- Python 3.10 or newer
uv- Git
Useful extras:
prekif you want to run the pre-commit stack locallyghif you work on GitHub-related commands or review flowsjq,gawk, andmcplfor review and MCP-oriented workflows
scripts/session-start-check.sh is the repo's built-in environment check. It treats uv as critical and reports optional tools when they are relevant to the current repo or workflow. If you use the full Claude Code setup, it also checks for required review plugins such as pr-review-toolkit, superpowers, and feature-dev.
Tip: If you want the packaged CLI on your
PATH, the repository's own plugin command docs checkmyk-claude-tools --versionand recommenduv tool install myk-claude-toolswhen it is missing.
Local Development Flow
The simplest way to work in this repository is:
- Use
uvoruvxfor Python-related commands. - Run the unit test suite through the
testsdependency group. - Run the hook stack through
prekwhen you want the same checks the repository is configured to use. - If you are testing the full Claude Code configuration, expect local hooks from
settings.jsonto shape the experience.
tox.toml keeps the test flow deliberately simple. There is one environment, unittests, and it runs the working tree directly instead of building a source distribution first.
skipsdist = true
envlist = ["unittests"]
[env.unittests]
description = "Run pytest tests"
deps = ["uv"]
commands = [["uv", "run", "--group", "tests", "pytest", "tests"]]
That uv-first approach is enforced, not just suggested. scripts/rule-enforcer.py actively blocks direct python, python3, pip, pip3, and direct pre-commit usage in hook-managed Bash flows, and points contributors toward uv, uvx, and prek instead.
if is_forbidden_python_command(command):
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Direct python/pip commands are forbidden.",
"additionalContext": (
"You attempted to run python/pip directly. Instead:\n"
"1. Delegate Python tasks to the python-expert agent\n"
"2. Use 'uv run script.py' to run Python scripts\n"
"3. Use 'uvx package-name' to run package CLIs\n"
"See: https://docs.astral.sh/uv/"
),
}
}
print(json.dumps(output))
sys.exit(0)
if is_forbidden_precommit_command(command):
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Direct pre-commit commands are forbidden.",
"additionalContext": (
In practice, the commands you will see repeated across this repository are uv run --group tests pytest tests, uvx ruff check ., prek run --all-files, and myk-claude-tools --version.
Warning: If you are used to generic Python repositories, these guardrails can feel strict at first. That is intentional. The behavior is covered by
tests/test_rule_enforcer.pyandtests/test_git_protection.py, so those are the first tests to revisit when you change hook behavior.
If you are exercising the full Claude Code configuration rather than only editing Python code, settings.json also wires in session-start-check.sh, rule-injector.py, rule-enforcer.py, and git-protection.py. That makes hook behavior part of the normal local development loop.
Note:
settings.jsonincludes a_scriptsNotereminding contributors that new script entries must be added in bothpermissions.allowandallowedTools.
Quality Checks
Ruff is the main lint and formatting tool here, and Mypy handles type checking. Ruff configuration lives in pyproject.toml and uses a 120-character line length with auto-fix enabled. Mypy is configured with stricter-than-default settings such as disallow_untyped_defs, no_implicit_optional, and strict_equality.
Flake8 is present too, but only for M511 via flake8-mutable; it is not the primary style checker for the project.
The configured pre-commit stack covers file hygiene, secret scanning, Ruff, Mypy, Flake8, Gitleaks, and Markdown linting.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-symlinks
- id: detect-private-key
- id: mixed-line-ending
- id: debug-statements
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md] # Do not process Markdown files.
- id: end-of-file-fixer
- id: check-ast
- id: check-builtin-literals
- id: check-toml
- repo: https://github.com/PyCQA/flake8
rev: 7.3.0
hooks:
- id: flake8
args: [--config=.flake8]
additional_dependencies:
[flake8-mutable]
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.14
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.19.1
hooks:
- id: mypy
additional_dependencies:
- pytest
- repo: https://github.com/igorshubovych/markdownlint-cli
That split is worth remembering when you debug a failed check:
- Look in
pyproject.tomlfor Ruff and Mypy behavior. - Look in
.flake8for the narrow Flake8 rule set. - Look in
.pre-commit-config.yamlfor the full local hook chain.
Tip: Installing
prekmakes it easier to run the repository's hook stack locally without invokingpre-commitdirectly, which matches the repo's own guardrails.
Repository Conventions
The root .gitignore uses a whitelist model. It starts by ignoring everything, then selectively re-enables the files and directories that are meant to be shared.
# Ignore everything by default
# This config integrates into ~/.claude so we must be explicit about what we track
*
# Core config files
!.coderabbit.yaml
!.gitignore
!.markdownlint.yaml
!LICENSE
!AI_REVIEW.md
!README.md
!settings.json
!statusline.sh
!uv.lock
This is unusual in a Python project, but it fits this repository. The configuration is designed to live inside ~/.claude, so the default is "ignore unless explicitly shared."
In practice, that means directories such as agents/, rules/, scripts/, tests/, plugins/, and myk_claude_tools/ are only tracked because individual paths are explicitly whitelisted later in the file.
Warning: If you add a new file under one of those trees and forget the matching
!path/to/fileentry in.gitignore, Git will behave as if the file does not exist. Update the correct section and keep the entries alphabetized.
The same "explicit over implicit" convention shows up elsewhere too. Hook scripts are registered intentionally, allowed tools are listed explicitly, and tracked files are opt-in rather than assumed.
CI And Automation
There is no checked-in CI pipeline in this repository. There is no .github/workflows/ directory, no Jenkinsfile, and no GitLab or Azure pipeline file in the tree.
What the repository does include is local and external automation configuration:
.pre-commit-config.yamlfor local checks.coderabbit.yamlfor review automationsettings.jsonplusscripts/for Claude Code hook behavior
Note: The
ci:block inside.pre-commit-config.yamlis pre-commit metadata, not a full repository CI pipeline.Tip: Treat local
toxandprekruns as the primary way to validate changes before opening a pull request unless you add a dedicated CI workflow later.