codemop 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. codemop-0.1.0/.gitignore +32 -0
  2. codemop-0.1.0/LICENSE +21 -0
  3. codemop-0.1.0/PKG-INFO +351 -0
  4. codemop-0.1.0/README.md +329 -0
  5. codemop-0.1.0/pyproject.toml +59 -0
  6. codemop-0.1.0/src/codemop/__init__.py +3 -0
  7. codemop-0.1.0/src/codemop/cli.py +233 -0
  8. codemop-0.1.0/src/codemop/config.py +66 -0
  9. codemop-0.1.0/src/codemop/github/__init__.py +1 -0
  10. codemop-0.1.0/src/codemop/github/client.py +106 -0
  11. codemop-0.1.0/src/codemop/providers/__init__.py +59 -0
  12. codemop-0.1.0/src/codemop/providers/anthropic.py +114 -0
  13. codemop-0.1.0/src/codemop/providers/base.py +84 -0
  14. codemop-0.1.0/src/codemop/providers/openai_compatible.py +187 -0
  15. codemop-0.1.0/src/codemop/providers/pricing.py +45 -0
  16. codemop-0.1.0/src/codemop/review/__init__.py +1 -0
  17. codemop-0.1.0/src/codemop/review/chunks.py +131 -0
  18. codemop-0.1.0/src/codemop/review/diff.py +123 -0
  19. codemop-0.1.0/src/codemop/review/pipeline.py +86 -0
  20. codemop-0.1.0/src/codemop/review/placement.py +44 -0
  21. codemop-0.1.0/src/codemop/review/prompt.py +54 -0
  22. codemop-0.1.0/src/codemop/review/schema.py +39 -0
  23. codemop-0.1.0/tests/github/test_client.py +99 -0
  24. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/diff.diff +144 -0
  25. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/report.json +51 -0
  26. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/report.txt +34 -0
  27. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/requests.txt +161 -0
  28. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/responses.json +50 -0
  29. codemop-0.1.0/tests/golden/cases/claude-suggestions-endpoint/settings.json +1 -0
  30. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/diff.diff +122 -0
  31. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/report.json +51 -0
  32. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/report.txt +27 -0
  33. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/requests.txt +137 -0
  34. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/responses.json +76 -0
  35. codemop-0.1.0/tests/golden/cases/ollama-pr-storage-chunked/settings.json +3 -0
  36. codemop-0.1.0/tests/golden/record.py +80 -0
  37. codemop-0.1.0/tests/golden/test_golden.py +88 -0
  38. codemop-0.1.0/tests/providers/test_anthropic.py +150 -0
  39. codemop-0.1.0/tests/providers/test_create_model.py +63 -0
  40. codemop-0.1.0/tests/providers/test_openai_compatible.py +200 -0
  41. codemop-0.1.0/tests/providers/test_pricing.py +29 -0
  42. codemop-0.1.0/tests/review/conftest.py +62 -0
  43. codemop-0.1.0/tests/review/test_chunks.py +76 -0
  44. codemop-0.1.0/tests/review/test_diff.py +74 -0
  45. codemop-0.1.0/tests/review/test_pipeline.py +150 -0
  46. codemop-0.1.0/tests/review/test_placement.py +37 -0
  47. codemop-0.1.0/tests/review/test_prompt.py +24 -0
  48. codemop-0.1.0/tests/test_cli.py +276 -0
  49. codemop-0.1.0/tests/test_config.py +48 -0
@@ -0,0 +1,32 @@
1
+ __pycache__/
2
+ .env
3
+ .env.production
4
+ *.pyc
5
+ *.pyo
6
+ *.pyd
7
+ .Python
8
+ env/
9
+ venv/
10
+ node_modules/
11
+ .DS_Store
12
+ *.log
13
+ *.sqlite
14
+ *.db
15
+ coverage/
16
+ htmlcov/
17
+ .coverage
18
+ coverage.xml
19
+ .pytest_cache/
20
+ .mypy_cache/
21
+ dist/
22
+ build/
23
+ *.egg-info/
24
+ .vscode/
25
+ .idea/
26
+ *.swp
27
+ *.swo
28
+ .DS_Store
29
+ .Trashes
30
+ .Spotlight-V100
31
+ .Spotlight-V100
32
+ .fuse_hidden*
codemop-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gregory Kemp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
codemop-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,351 @@
1
+ Metadata-Version: 2.5
2
+ Name: codemop
3
+ Version: 0.1.0
4
+ Summary: AI code review for pull requests, with the model of your choice
5
+ Project-URL: Homepage, https://github.com/sgtwickool/codemop
6
+ Author: Gregory Kemp
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: ai,code review,github,llm,pull requests
10
+ Classifier: Development Status :: 2 - Pre-Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Software Development :: Quality Assurance
16
+ Requires-Python: >=3.12
17
+ Requires-Dist: anthropic<2,>=1.11
18
+ Requires-Dist: httpx<1,>=0.28
19
+ Requires-Dist: pydantic<3,>=2.13
20
+ Requires-Dist: pyyaml<7,>=6
21
+ Description-Content-Type: text/markdown
22
+
23
+ # CodeMop
24
+
25
+ AI code review for pull requests, with the model of your choice.
26
+
27
+ ## 🚀 CI/CD Status
28
+
29
+ [![CI Status](https://github.com/sgtwickool/codemop/actions/workflows/ci.yml/badge.svg)](https://github.com/sgtwickool/codemop/actions/workflows/ci.yml)
30
+ [![Docker Build](https://github.com/sgtwickool/codemop/actions/workflows/docker.yml/badge.svg)](https://github.com/sgtwickool/codemop/actions/workflows/docker.yml)
31
+ [![Security Scan](https://github.com/sgtwickool/codemop/actions/workflows/security.yml/badge.svg)](https://github.com/sgtwickool/codemop/actions/workflows/security.yml)
32
+ [![Codecov](https://codecov.io/gh/sgtwickool/codemop/branch/master/graph/badge.svg)](https://codecov.io/gh/sgtwickool/codemop)
33
+
34
+ ## Quick start
35
+
36
+ ```bash
37
+ pipx install codemop # or: uv tool install codemop
38
+ export ANTHROPIC_API_KEY=sk-ant-... # or use another provider (see "Choosing a model")
39
+
40
+ codemop review owner/repo#123 # a pull request (GITHUB_TOKEN or `gh auth login` for private repos)
41
+ git diff main | codemop review - # your local changes
42
+ ```
43
+
44
+ It prints each suggestion with the file and line, the reason, and a fix where it has one,
45
+ then the tokens used and an estimated cost (about two cents a review with the default
46
+ model). `--json` prints the report for scripts. Posting reviews on pull requests comes
47
+ with the GitHub Action (see the [roadmap](https://github.com/sgtwickool/codemop/blob/master/ROADMAP.md)).
48
+
49
+ The rest of this README covers configuring reviews, choosing a model, and running the
50
+ webhook server.
51
+
52
+ ## 🏗️ Development Setup
53
+
54
+ ### Prerequisites
55
+ - Python 3.12+ (Python 3.14 recommended)
56
+ - PostgreSQL 13+ (or any recent version)
57
+ - Docker (optional, for containerized development)
58
+ - ngrok (for webhook testing) - [Download ngrok](https://ngrok.com/download)
59
+
60
+ #### Fedora/Linux Installation Notes
61
+ ```bash
62
+ # Install Python and PostgreSQL on Fedora
63
+ sudo dnf install python3 python3-pip postgresql-server postgresql-contrib
64
+
65
+ # Initialize and start PostgreSQL
66
+ sudo postgresql-setup --initdb
67
+ sudo systemctl enable postgresql
68
+ sudo systemctl start postgresql
69
+
70
+ # Install ngrok (download from ngrok.com and follow their instructions)
71
+ # Or use their official Fedora package if available
72
+ ```
73
+
74
+ ### Installation
75
+ 1. Clone the repository
76
+ 2. Copy `.env.example` to `.env` and configure your settings:
77
+ ```bash
78
+ cp .env.example .env
79
+ ```
80
+ `GITHUB_WEBHOOK_SECRET` and `API_KEY` are required: the server refuses to start without
81
+ them unless `APP_ENV=development` (which `.env.example` sets). `APP_ENV` defaults to
82
+ `production` when unset.
83
+ 3. Install dependencies and set up the database (creates `venv/` and, if missing, `.env`):
84
+ ```bash
85
+ ./scripts/setup_dev.sh
86
+ ```
87
+ 4. Start the development server:
88
+ ```bash
89
+ ./scripts/run_dev.sh
90
+ ```
91
+
92
+ ### GitHub Webhook Setup
93
+ 1. **Install ngrok**: Download and install ngrok for your platform from [ngrok.com/download](https://ngrok.com/download)
94
+ 2. **Start ngrok tunnel**:
95
+ ```bash
96
+ ngrok http 8000
97
+ ```
98
+ 3. **Configure GitHub Webhook**:
99
+ - Go to your GitHub repository → Settings → Webhooks
100
+ - Add webhook with the ngrok URL (e.g., `https://abc123.ngrok.io/api/v1/github/webhook`)
101
+ - Set content type to `application/json`
102
+ - Add your webhook secret (same as in `.env` file)
103
+ - Select "Let me select individual events" and check "Pull requests"
104
+ 4. **Private repositories**: set `GITHUB_TOKEN` in `.env` so CodeMop can fetch PR diffs through the GitHub API. Create a [fine-grained token](https://github.com/settings/personal-access-tokens/new) limited to the repos you want reviewed, with read-only **Pull requests** and **Contents** permissions. Public repos work without one, but a token raises the API rate limit from 60 to 5,000 requests an hour.
105
+ 5. **Test the webhook**: GitHub sends a `ping` when the webhook is created; its delivery log should show `"status": "pong"`. Then open a test pull request and check that delivery too
106
+
107
+ ### Testing
108
+
109
+ The tests need no database, network or `.env`: they use a temporary SQLite database and
110
+ fixed test settings (see `server/tests/conftest.py`).
111
+
112
+ **Run all tests:**
113
+ ```bash
114
+ cd server
115
+ pytest
116
+ ```
117
+
118
+ **Run specific tests:**
119
+ ```bash
120
+ cd server
121
+ pytest tests/integration/test_webhook_integration.py -k health
122
+ ```
123
+
124
+ **Try a service function interactively:**
125
+ ```bash
126
+ cd server
127
+ PYTHONPATH=src python -c "
128
+ from app.services.github import extract_pr_data
129
+ payload = {'action': 'opened', 'number': 123, 'pull_request': {'title': 'Test'}, 'repository': {'full_name': 'test/repo'}}
130
+ print(extract_pr_data(payload))
131
+ "
132
+ ```
133
+
134
+ ### Configuring reviews
135
+ A repository can include a `.codemop.yml` to say how its pull requests are reviewed:
136
+ ```yaml
137
+ ignore: # paths not to review, added to the defaults (lock files, minified files...)
138
+ - "docs/*"
139
+ - "*.snap"
140
+ min_confidence: 0.6 # drop suggestions the model is less sure of (default: 0.5)
141
+ chunk_tokens: 20000 # largest piece of diff sent in one request (default: the model's own)
142
+ ```
143
+ CodeMop reads it from the repository's **default branch**, so a pull request can't change how it's
144
+ reviewed (for `codemop review -`, from the current directory; `--config PATH` uses another file).
145
+ Command-line flags override it.
146
+
147
+ It can't choose the provider or model, or where requests go: whoever runs CodeMop decides that, with
148
+ `--provider` / `--model` / `--base-url` or `CODEMOP_PROVIDER` / `CODEMOP_MODEL` / `CODEMOP_BASE_URL`
149
+ (and the server's `AI_*` settings). Otherwise reviewing someone else's pull request could send your API
150
+ key to their server.
151
+
152
+ Each review ends with the tokens used and, where the model's list price is known, an estimated cost.
153
+
154
+ ### Choosing a model
155
+ The default is Claude Opus 5.5 (`claude-opus-5-5`) at high effort, chosen by the
156
+ [review eval](https://github.com/sgtwickool/codemop/blob/master/evals/review/README.md): it found the most known issues, with almost no false alarms,
157
+ for about two cents a review. `--effort` (or `CODEMOP_EFFORT`) sets Claude's effort level. For less
158
+ cost, `--model claude-sonnet-5-5 --effort low` was as good on simple changes and missed a little more
159
+ on complex ones. Claude Haiku 4.5 isn't recommended: half its comments were wrong.
160
+
161
+ ### Reviewing with a local model (Ollama)
162
+ The `codemop` command can review with a model running on your own machine: no API key, no cost per
163
+ review, and the code never leaves your computer. It's slower, and small models review less well.
164
+ ```bash
165
+ ollama pull qwen2.5-coder:7b
166
+ codemop review owner/repo#123 --provider ollama --model qwen2.5-coder:7b
167
+ ```
168
+ Ollama runs models with a 4,096-token context window by default, which has to hold the instructions,
169
+ a chunk of the diff and the review, so raise it. On Linux, where Ollama runs as a systemd service:
170
+ ```bash
171
+ sudo mkdir -p /etc/systemd/system/ollama.service.d
172
+ printf '[Service]\nEnvironment="OLLAMA_CONTEXT_LENGTH=16384"\n' | sudo tee /etc/systemd/system/ollama.service.d/context.conf
173
+ sudo systemctl daemon-reload && sudo systemctl restart ollama
174
+ ```
175
+ CodeMop sends Ollama 8,000-token chunks and checks the token count Ollama reports back: if part of the
176
+ input was dropped, it stops with an error instead of reviewing a fragment.
177
+
178
+ ### Database migrations
179
+ The server applies any pending migrations when it starts (and `setup_dev.sh` runs them too),
180
+ so there's nothing to run by hand. After changing a model in `server/src/app/models/`,
181
+ generate a migration, review it, and commit it:
182
+ ```bash
183
+ cd server
184
+ alembic revision --autogenerate -m "describe the change" # creates src/app/migrations/versions/<rev>_....py
185
+ alembic upgrade head # apply it to the database in DATABASE_URL
186
+ ```
187
+
188
+ ### Troubleshooting
189
+
190
+ #### Database Connection Issues
191
+ If you get database connection errors:
192
+ 1. Make sure PostgreSQL is running: `sudo systemctl status postgresql`
193
+ 2. Try creating the database as postgres user: `sudo -u postgres createdb codemop`
194
+ 3. Check your `.env` file has the correct DATABASE_URL
195
+
196
+ #### Port Already in Use
197
+ If port 8000 is in use:
198
+ 1. Find the process: `lsof -i :8000`
199
+ 2. Kill it: `kill -9 <PID>` or use a different port
200
+
201
+ #### Python Virtual Environment Issues
202
+ If you have virtual environment issues:
203
+ 1. Remove existing venv: `rm -rf venv`
204
+ 2. Recreate it: `python -m venv venv`
205
+ 3. Activate and install: `source venv/bin/activate && pip install -r server/requirements-dev.txt`
206
+
207
+ ### API Endpoints
208
+ - `POST /api/v1/github/webhook` - GitHub webhook endpoint (versioned)
209
+ - `GET /api/v1/health` - Health check endpoint (versioned)
210
+ - `GET /api/v1/repos/{owner}/{repo}/pulls/{number}/suggestions` - Get suggestions for a PR by repo and PR number (needs `Authorization: Bearer <API_KEY>`)
211
+ - `GET /api/v1/pr/{pr_id}/suggestions` - The same, by CodeMop's database ID (the webhook response's `database_id`)
212
+
213
+ **Note**: All endpoints are versioned under the `/api/v1/` prefix. Interactive API docs are at `/api/v1/docs`.
214
+
215
+ ### Project Structure
216
+ ```
217
+ codemop/
218
+ ├── server/ # FastAPI server
219
+ │ ├── src/ # Source code (modern structure)
220
+ │ │ ├── app/ # Main application package
221
+ │ │ │ ├── main.py # FastAPI app setup
222
+ │ │ │ ├── config.py # Configuration management
223
+ │ │ │ ├── api/ # Versioned API endpoints
224
+ │ │ │ │ └── v1/ # API version 1
225
+ │ │ │ │ ├── endpoints/ # Individual endpoints
226
+ │ │ │ │ └── api.py # API router
227
+ │ │ │ ├── core/ # Core utilities
228
+ │ │ │ ├── services/ # Business logic
229
+ │ │ │ ├── models/ # Database models
230
+ │ │ │ ├── db/ # Database layer
231
+ │ │ │ ├── utils/ # Utilities
232
+ │ │ │ └── migrations/ # Alembic database migrations
233
+ │ ├── tests/ # Test files
234
+ │ ├── requirements.txt # Runtime dependencies (pinned)
235
+ │ ├── requirements-dev.txt # Test and security tooling
236
+ │ ├── Dockerfile # Docker configuration
237
+ │ ├── pytest.ini # Pytest configuration
238
+ │ └── .bandit # Bandit security config
239
+ ├── .github/ # GitHub Actions workflows
240
+ │ └── workflows/ # CI/CD pipelines
241
+ │ ├── ci.yml # Continuous Integration
242
+ │ ├── docker.yml # Docker builds
243
+ │ ├── security.yml # Security scanning
244
+ │ └── README.md # Workflow documentation
245
+ ├── ROADMAP.md # Plan and decisions
246
+ ├── docs/ # Documentation
247
+ ├── scripts/ # Development scripts
248
+ ├── .gitignore
249
+ ├── .env.example
250
+ ├── docker-compose.yml
251
+ └── README.md
252
+ ```
253
+
254
+ ## User Story 1: GitHub Webhook Integration
255
+
256
+ This implementation provides:
257
+ - FastAPI server with GitHub webhook endpoint
258
+ - Webhook signature validation for security
259
+ - PR data extraction and logging
260
+ - Database schema for PR storage
261
+ - Docker setup for local development
262
+ - Comprehensive testing framework
263
+
264
+ ### Features Implemented
265
+ ✅ GitHub webhook endpoint with signature validation
266
+ ✅ PR event handling and data extraction
267
+ ✅ Database models for PRs and suggestions
268
+ ✅ Docker and docker-compose configuration
269
+ ✅ Development scripts for easy setup
270
+ ✅ Test suite with pytest
271
+
272
+ ### Next Steps
273
+ See [ROADMAP.md](https://github.com/sgtwickool/codemop/blob/master/ROADMAP.md).
274
+
275
+ ## 🚀 CI/CD Pipeline
276
+
277
+ CodeMop uses GitHub Actions for Continuous Integration and Deployment with the following workflows:
278
+
279
+ ### Continuous Integration (CI)
280
+ - **Trigger**: Push to `master`/`develop`, Pull Requests
281
+ - **Features**:
282
+ - Python 3.12, 3.13, 3.14 test matrix
283
+ - Automated test execution with pytest
284
+ - Code coverage reporting via Codecov
285
+
286
+ ### Docker Build & Push
287
+ - **Trigger**: Push to `master`, version tags
288
+ - **Features**:
289
+ - Multi-stage Docker builds
290
+ - Automatic image tagging
291
+ - GitHub Container Registry integration
292
+ - Docker layer caching for faster builds
293
+
294
+ ### Security Scanning
295
+ - **Trigger**: Push to `master`/`develop`, Pull Requests, Weekly schedule
296
+ - **Features**:
297
+ - **pip-audit**: Dependency vulnerability scanning
298
+ - **Bandit**: Python security linting using configuration file
299
+ - **Trivy**: Container vulnerability scanning
300
+ - Scheduled weekly scans
301
+
302
+ ### Local Development with CI/CD
303
+
304
+ #### Running Tests Locally
305
+ ```bash
306
+ # Install test and security tooling
307
+ pip install -r server/requirements-dev.txt
308
+
309
+ # Run tests (coverage is reported by default)
310
+ cd server
311
+ pytest
312
+
313
+ # Run security scanning
314
+ pip-audit -r requirements.txt
315
+ bandit -c .bandit -r src/
316
+ ```
317
+
318
+ #### Building Docker Images Locally
319
+ ```bash
320
+ # Build production image
321
+ docker build -f server/Dockerfile.prod -t codemop:latest server/
322
+
323
+ # Run the container
324
+ docker run -p 8000:8000 --env-file .env codemop:latest
325
+ ```
326
+
327
+ ### CI/CD Best Practices
328
+
329
+ 1. **Small, Focused Commits**: Keep changes small for easier testing
330
+ 2. **Test Locally First**: Run tests before pushing to CI
331
+ 3. **Monitor Workflows**: Check GitHub Actions tab regularly
332
+ 4. **Fix Failures Promptly**: Address CI failures immediately
333
+ 5. **Use Feature Branches**: Create branches for new features
334
+ 6. **Pull Request Workflow**: All changes go through PR review
335
+
336
+ ### Troubleshooting CI/CD
337
+
338
+ #### Test Failures
339
+ - Check the specific test that failed
340
+ - Run tests locally to reproduce
341
+ - Fix the issue and push the correction
342
+
343
+ #### Docker Build Failures
344
+ - Verify `Dockerfile.prod` syntax
345
+ - Check for missing files in build context
346
+ - Ensure proper permissions
347
+
348
+ #### Security Scan Failures
349
+ - Review vulnerability reports
350
+ - Update vulnerable dependencies
351
+ - Add exceptions for false positives if necessary