misscat 1.0.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.
- misscat-1.0.0/LICENSE +21 -0
- misscat-1.0.0/PKG-INFO +350 -0
- misscat-1.0.0/README.md +323 -0
- misscat-1.0.0/pyproject.toml +45 -0
- misscat-1.0.0/setup.cfg +4 -0
- misscat-1.0.0/src/misscat/__init__.py +786 -0
- misscat-1.0.0/src/misscat/__main__.py +4 -0
- misscat-1.0.0/src/misscat/default.yml +50 -0
- misscat-1.0.0/src/misscat/py.typed +0 -0
- misscat-1.0.0/src/misscat.egg-info/PKG-INFO +350 -0
- misscat-1.0.0/src/misscat.egg-info/SOURCES.txt +13 -0
- misscat-1.0.0/src/misscat.egg-info/dependency_links.txt +1 -0
- misscat-1.0.0/src/misscat.egg-info/entry_points.txt +2 -0
- misscat-1.0.0/src/misscat.egg-info/requires.txt +1 -0
- misscat-1.0.0/src/misscat.egg-info/top_level.txt +1 -0
misscat-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 KJ Kim
|
|
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.
|
misscat-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: misscat
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Watch a GitHub repository and run an AI review on every new PR HEAD
|
|
5
|
+
Author: KJ Kim
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/genonfire/misscat
|
|
8
|
+
Project-URL: Repository, https://github.com/genonfire/misscat
|
|
9
|
+
Project-URL: Issues, https://github.com/genonfire/misscat/issues
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: PyYAML>=6.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# MissCat
|
|
29
|
+
|
|
30
|
+
**Never miss a single commit.**
|
|
31
|
+
|
|
32
|
+
> *I’ll catch ’em all, meow.*
|
|
33
|
+
|
|
34
|
+
MissCat is a small CLI that watches a GitHub repository and automatically runs an AI code review whenever a new pull request or commit appears.
|
|
35
|
+
|
|
36
|
+
It watches the **repository**, not a single PR.
|
|
37
|
+
|
|
38
|
+
## Why MissCat?
|
|
39
|
+
|
|
40
|
+
AI reviewers are useful, but somebody still has to notice that a PR changed and ask them to review it again.
|
|
41
|
+
|
|
42
|
+
MissCat does that part.
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
new PR
|
|
46
|
+
→ review
|
|
47
|
+
|
|
48
|
+
new commit
|
|
49
|
+
→ review again
|
|
50
|
+
|
|
51
|
+
nothing changed
|
|
52
|
+
→ do nothing
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
No webhook server.
|
|
56
|
+
No API keys stored by MissCat.
|
|
57
|
+
No repeated review of the same commit with the same profile.
|
|
58
|
+
|
|
59
|
+
## Prerequisites
|
|
60
|
+
|
|
61
|
+
Before running MissCat, ensure you have:
|
|
62
|
+
|
|
63
|
+
- **Python**: Python 3.9 or newer
|
|
64
|
+
- **Git**: Configured with credentials to clone and fetch the target repository (HTTPS users using GitHub CLI can run `gh auth setup-git`)
|
|
65
|
+
- **GitHub CLI (`gh`)**: Installed and authenticated (`gh auth login`)
|
|
66
|
+
- **At least one AI reviewer CLI**: Installed and authenticated:
|
|
67
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code) (`claude`)
|
|
68
|
+
- [Codex CLI](https://github.com/openai/codex) (`codex`)
|
|
69
|
+
- [Antigravity CLI](https://github.com/google/antigravity) (`agy`) for Gemini
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
Install MissCat with [pipx](https://pypa.github.io/pipx/):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pipx install misscat
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
To upgrade MissCat to the latest version:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pipx upgrade misscat
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Releasing (maintainers)
|
|
86
|
+
|
|
87
|
+
Releases are published to PyPI by `.github/workflows/publish.yml` when a `vMAJOR.MINOR.PATCH` tag is pushed. It uses PyPI [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC), so no PyPI token is stored in GitHub secrets.
|
|
88
|
+
|
|
89
|
+
### One-time setup
|
|
90
|
+
|
|
91
|
+
1. On PyPI, add a trusted publisher for the `misscat` project (Project → Publishing; for a first release use "Add a pending publisher"):
|
|
92
|
+
- Owner: `genonfire`
|
|
93
|
+
- Repository: `misscat`
|
|
94
|
+
- Workflow name: `publish.yml`
|
|
95
|
+
- Environment name: `pypi`
|
|
96
|
+
2. In the GitHub repository, create an environment named `pypi` (Settings → Environments). Recommended: add required reviewers so every release needs a manual approval, and add a tag ruleset (Settings → Rules) so only maintainers can create `v*` tags. A deployment tag rule alone is not enough, since it matches the tag name, not the commit.
|
|
97
|
+
|
|
98
|
+
### Release procedure
|
|
99
|
+
|
|
100
|
+
1. Check that the version is not already on PyPI (versions are immutable and cannot be re-uploaded): <https://pypi.org/project/misscat/#history>
|
|
101
|
+
2. Bump `version` in `pyproject.toml` **and** `__version__` in `src/misscat/__init__.py` (the workflow fails if they differ), then merge to `master`.
|
|
102
|
+
3. Tag the merge commit and push the tag (the tag must equal `v` + the `pyproject.toml` version):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git tag v1.0.1
|
|
106
|
+
git push origin v1.0.1
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
4. The workflow fails before publishing if the tagged commit is not on `master`, the tag is malformed, the tag does not match `pyproject.toml` or `__version__`, or `python -m build` / `twine check` fails.
|
|
110
|
+
5. Confirm the release:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pipx upgrade misscat
|
|
114
|
+
misscat --version
|
|
115
|
+
pip index versions misscat
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Quick Start / First Run
|
|
119
|
+
|
|
120
|
+
Watch a repository and review new PRs using the default profile:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
misscat <owner/repo>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
misscat genonfire/misscat
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use a specific reviewer profile:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
misscat genonfire/misscat luna
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
MissCat resolves `luna` as:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
~/.config/misscat/luna.yml
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Running `misscat` with no arguments (or `misscat --help`) shows usage help:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
misscat --help
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Repository names are canonicalized to lowercase, so `Genonfire/MissCat` and `genonfire/misscat` refer to the same local workspace and state.
|
|
151
|
+
|
|
152
|
+
## Configuration
|
|
153
|
+
|
|
154
|
+
MissCat ships with a bundled `default.yml` inside the package, so installed copies do not depend on the source checkout or current working directory.
|
|
155
|
+
|
|
156
|
+
User configuration and persistent data are kept entirely outside the package:
|
|
157
|
+
|
|
158
|
+
- **Profiles**: `~/.config/misscat/<profile>.yml`
|
|
159
|
+
- **Per-repository state**: `~/.config/misscat/<owner>__<repo>.json`
|
|
160
|
+
- **Persistent workspace**: `~/.cache/misscat/repos/<owner>/<repo>/`
|
|
161
|
+
|
|
162
|
+
Directory layout:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
~/.config/misscat/
|
|
166
|
+
├── luna.yml
|
|
167
|
+
├── sonnet.yml
|
|
168
|
+
├── genonfire__typewriter.json
|
|
169
|
+
└── genonfire__misscat.json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Example `default.yml`:
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
reviewer:
|
|
176
|
+
# provider: claude
|
|
177
|
+
# model: claude-sonnet-5-5
|
|
178
|
+
# args:
|
|
179
|
+
# - --allowedTools
|
|
180
|
+
# - "Bash(gh *)"
|
|
181
|
+
|
|
182
|
+
provider: codex
|
|
183
|
+
model: gpt-6.1-sol
|
|
184
|
+
args:
|
|
185
|
+
- --sandbox
|
|
186
|
+
- workspace-write
|
|
187
|
+
- -c
|
|
188
|
+
- sandbox_workspace_write.network_access=true
|
|
189
|
+
- -c
|
|
190
|
+
- apps._default.enabled=false
|
|
191
|
+
- -c
|
|
192
|
+
- model_reasoning_effort=medium
|
|
193
|
+
|
|
194
|
+
prompt: |
|
|
195
|
+
Read REVIEW.md if exist and act as the 1st reviewer.
|
|
196
|
+
Use the gh CLI for GitHub operations, including posting the review.
|
|
197
|
+
|
|
198
|
+
watch:
|
|
199
|
+
idle: [60, 120, 180, 240, 300]
|
|
200
|
+
active: [300, 240, 180, 120, 60]
|
|
201
|
+
|
|
202
|
+
review:
|
|
203
|
+
include_drafts: true
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Example `~/.config/misscat/luna.yml`:
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
reviewer:
|
|
210
|
+
provider: codex
|
|
211
|
+
model: gpt-6-luna
|
|
212
|
+
args:
|
|
213
|
+
- --sandbox
|
|
214
|
+
- workspace-write
|
|
215
|
+
- -c
|
|
216
|
+
- sandbox_workspace_write.network_access=true
|
|
217
|
+
- -c
|
|
218
|
+
- apps._default.enabled=false
|
|
219
|
+
- -c
|
|
220
|
+
- model_reasoning_effort=max
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The selected local profile overrides the bundled defaults.
|
|
224
|
+
|
|
225
|
+
When creating a local profile, use `default.yml` as the reference and specify `provider`, `model`, and `args` explicitly for that reviewer CLI. Do not rely on `args` inherited from a different provider.
|
|
226
|
+
|
|
227
|
+
The `args` field under `reviewer` is passed to the selected reviewer CLI unchanged.
|
|
228
|
+
|
|
229
|
+
Reviewed state is stored per repository and keyed by PR, HEAD SHA, and profile. The same HEAD can therefore be reviewed again with a different profile.
|
|
230
|
+
|
|
231
|
+
### Gemini (Antigravity CLI)
|
|
232
|
+
|
|
233
|
+
Gemini reviews use the Antigravity CLI (`agy`). Configure authentication and permissions before running MissCat.
|
|
234
|
+
|
|
235
|
+
For headless reviews, configure the Antigravity CLI settings file:
|
|
236
|
+
|
|
237
|
+
`~/.gemini/antigravity-cli/settings.json`
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"toolPermission": "proceed-in-sandbox",
|
|
242
|
+
"enableTerminalSandbox": true,
|
|
243
|
+
"permissions": {
|
|
244
|
+
"allow": [
|
|
245
|
+
"command(gh)",
|
|
246
|
+
"command(git)"
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Preserve any existing settings when adding these fields. Ensure the repository workspace is trusted as appropriate.
|
|
253
|
+
|
|
254
|
+
Example reviewer profile (`~/.config/misscat/gemini.yml`):
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
reviewer:
|
|
258
|
+
provider: gemini
|
|
259
|
+
model: gemini-3.8-flash-low
|
|
260
|
+
args:
|
|
261
|
+
- --print-timeout
|
|
262
|
+
- 30m
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Important:** In headless mode, commands requiring interactive permission approval may be automatically denied. Antigravity can still exit successfully without posting a GitHub review.
|
|
266
|
+
|
|
267
|
+
If a review finishes without appearing on GitHub, run MissCat with `--loud` to inspect reviewer activity and permission errors.
|
|
268
|
+
|
|
269
|
+
Avoid `--dangerously-skip-permissions` for routine unattended operation, as it broadly bypasses tool approval checks.
|
|
270
|
+
|
|
271
|
+
## Review workspace
|
|
272
|
+
|
|
273
|
+
MissCat reviews each repository in its own persistent workspace:
|
|
274
|
+
|
|
275
|
+
```text
|
|
276
|
+
~/.cache/misscat/repos/<owner>/<repo>/
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The repository is cloned on first use and reused for later reviews. Before each review, MissCat prepares a clean checkout of the exact PR HEAD.
|
|
280
|
+
|
|
281
|
+
Your normal development checkout is never touched.
|
|
282
|
+
|
|
283
|
+
## Requirements and limits
|
|
284
|
+
|
|
285
|
+
- **Authentication expectations**:
|
|
286
|
+
- Git must be able to authenticate to the target repository for clone and fetch. Existing SSH keys or Git credentials work seamlessly. If using HTTPS with GitHub CLI, configure Git helper via `gh auth setup-git`. MissCat never stores Git credentials.
|
|
287
|
+
- GitHub CLI (`gh`) must be authenticated (`gh auth login`) with permissions to query pull requests.
|
|
288
|
+
- Reviewer CLIs (`claude`, `codex`, `agy`) must be logged in and configured with their respective provider accounts or API keys. MissCat uses their existing credentials.
|
|
289
|
+
- **Trusted repository and PR warning**:
|
|
290
|
+
- Reviewer CLIs execute within a MissCat-managed checkout of PR-controlled files.
|
|
291
|
+
- MissCat should only be used with repositories and pull requests whose code and contributors you trust.
|
|
292
|
+
- **One process per repository**:
|
|
293
|
+
- Run at most one MissCat process per repository at any given time.
|
|
294
|
+
- Multiple MissCat instances or profiles pointing to the same repository would share and conflict over the same persistent workspace (`~/.cache/misscat/repos/<owner>/<repo>/`).
|
|
295
|
+
|
|
296
|
+
## Reviewer backends
|
|
297
|
+
|
|
298
|
+
MissCat is not tied to a specific AI reviewer.
|
|
299
|
+
|
|
300
|
+
Initial backends:
|
|
301
|
+
|
|
302
|
+
- Claude Code CLI
|
|
303
|
+
- Codex CLI
|
|
304
|
+
- Gemini via agy(Google Antigravity CLI)
|
|
305
|
+
|
|
306
|
+
MissCat runs the selected reviewer CLI from the root of the prepared PR checkout. The CLI can therefore discover and apply its own repository instructions, such as `CLAUDE.md` or `AGENTS.md`, while `REVIEW.md` defines the review behavior requested by MissCat.
|
|
307
|
+
|
|
308
|
+
MissCat does not parse or translate those instruction files.
|
|
309
|
+
|
|
310
|
+
MissCat uses the authentication already configured in the reviewer CLI.
|
|
311
|
+
The `args` field under `reviewer` can be used for CLI-specific execution options such as tool permissions, sandbox settings, or network access.
|
|
312
|
+
|
|
313
|
+
GitHub repository and pull request access is handled through the authenticated GitHub CLI (`gh`).
|
|
314
|
+
|
|
315
|
+
MissCat does not manage GitHub tokens, Git credentials, or AI API keys itself.
|
|
316
|
+
|
|
317
|
+
## Adaptive polling
|
|
318
|
+
|
|
319
|
+
When there are no open PRs, MissCat gradually becomes lazy:
|
|
320
|
+
|
|
321
|
+
```text
|
|
322
|
+
1m → 2m → 3m → 4m → 5m → 5m ...
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
After review work is complete, MissCat gives the author some time to make changes, then gets increasingly impatient:
|
|
326
|
+
|
|
327
|
+
```text
|
|
328
|
+
5m → 4m → 3m → 2m → 1m → 1m ...
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
MissCat runs one review at a time.
|
|
332
|
+
|
|
333
|
+
When a review finishes successfully, it immediately checks the repository again before sleeping. If another PR or new HEAD is waiting, it reviews that next.
|
|
334
|
+
|
|
335
|
+
If a review or workspace preparation fails, that HEAD is not marked reviewed and MissCat waits 5 minutes before checking again.
|
|
336
|
+
|
|
337
|
+
## What MissCat does
|
|
338
|
+
|
|
339
|
+
- Watches all open PRs in a repository
|
|
340
|
+
- Discovers PRs created after MissCat starts
|
|
341
|
+
- Detects changes by PR HEAD SHA
|
|
342
|
+
- Reviews every new PR HEAD once per profile
|
|
343
|
+
- Avoids duplicate reviews
|
|
344
|
+
- Remembers reviewed commits across restarts
|
|
345
|
+
- Uses an isolated persistent review workspace
|
|
346
|
+
- Supports multiple reviewer backends
|
|
347
|
+
|
|
348
|
+
MissCat does **not** modify code, push commits, or merge PRs.
|
|
349
|
+
|
|
350
|
+
It watches. It catches. It reviews.
|
misscat-1.0.0/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# MissCat
|
|
2
|
+
|
|
3
|
+
**Never miss a single commit.**
|
|
4
|
+
|
|
5
|
+
> *I’ll catch ’em all, meow.*
|
|
6
|
+
|
|
7
|
+
MissCat is a small CLI that watches a GitHub repository and automatically runs an AI code review whenever a new pull request or commit appears.
|
|
8
|
+
|
|
9
|
+
It watches the **repository**, not a single PR.
|
|
10
|
+
|
|
11
|
+
## Why MissCat?
|
|
12
|
+
|
|
13
|
+
AI reviewers are useful, but somebody still has to notice that a PR changed and ask them to review it again.
|
|
14
|
+
|
|
15
|
+
MissCat does that part.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
new PR
|
|
19
|
+
→ review
|
|
20
|
+
|
|
21
|
+
new commit
|
|
22
|
+
→ review again
|
|
23
|
+
|
|
24
|
+
nothing changed
|
|
25
|
+
→ do nothing
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
No webhook server.
|
|
29
|
+
No API keys stored by MissCat.
|
|
30
|
+
No repeated review of the same commit with the same profile.
|
|
31
|
+
|
|
32
|
+
## Prerequisites
|
|
33
|
+
|
|
34
|
+
Before running MissCat, ensure you have:
|
|
35
|
+
|
|
36
|
+
- **Python**: Python 3.9 or newer
|
|
37
|
+
- **Git**: Configured with credentials to clone and fetch the target repository (HTTPS users using GitHub CLI can run `gh auth setup-git`)
|
|
38
|
+
- **GitHub CLI (`gh`)**: Installed and authenticated (`gh auth login`)
|
|
39
|
+
- **At least one AI reviewer CLI**: Installed and authenticated:
|
|
40
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code) (`claude`)
|
|
41
|
+
- [Codex CLI](https://github.com/openai/codex) (`codex`)
|
|
42
|
+
- [Antigravity CLI](https://github.com/google/antigravity) (`agy`) for Gemini
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Install MissCat with [pipx](https://pypa.github.io/pipx/):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pipx install misscat
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To upgrade MissCat to the latest version:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pipx upgrade misscat
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Releasing (maintainers)
|
|
59
|
+
|
|
60
|
+
Releases are published to PyPI by `.github/workflows/publish.yml` when a `vMAJOR.MINOR.PATCH` tag is pushed. It uses PyPI [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC), so no PyPI token is stored in GitHub secrets.
|
|
61
|
+
|
|
62
|
+
### One-time setup
|
|
63
|
+
|
|
64
|
+
1. On PyPI, add a trusted publisher for the `misscat` project (Project → Publishing; for a first release use "Add a pending publisher"):
|
|
65
|
+
- Owner: `genonfire`
|
|
66
|
+
- Repository: `misscat`
|
|
67
|
+
- Workflow name: `publish.yml`
|
|
68
|
+
- Environment name: `pypi`
|
|
69
|
+
2. In the GitHub repository, create an environment named `pypi` (Settings → Environments). Recommended: add required reviewers so every release needs a manual approval, and add a tag ruleset (Settings → Rules) so only maintainers can create `v*` tags. A deployment tag rule alone is not enough, since it matches the tag name, not the commit.
|
|
70
|
+
|
|
71
|
+
### Release procedure
|
|
72
|
+
|
|
73
|
+
1. Check that the version is not already on PyPI (versions are immutable and cannot be re-uploaded): <https://pypi.org/project/misscat/#history>
|
|
74
|
+
2. Bump `version` in `pyproject.toml` **and** `__version__` in `src/misscat/__init__.py` (the workflow fails if they differ), then merge to `master`.
|
|
75
|
+
3. Tag the merge commit and push the tag (the tag must equal `v` + the `pyproject.toml` version):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git tag v1.0.1
|
|
79
|
+
git push origin v1.0.1
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. The workflow fails before publishing if the tagged commit is not on `master`, the tag is malformed, the tag does not match `pyproject.toml` or `__version__`, or `python -m build` / `twine check` fails.
|
|
83
|
+
5. Confirm the release:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pipx upgrade misscat
|
|
87
|
+
misscat --version
|
|
88
|
+
pip index versions misscat
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Quick Start / First Run
|
|
92
|
+
|
|
93
|
+
Watch a repository and review new PRs using the default profile:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
misscat <owner/repo>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Example:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
misscat genonfire/misscat
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Use a specific reviewer profile:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
misscat genonfire/misscat luna
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
MissCat resolves `luna` as:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
~/.config/misscat/luna.yml
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Running `misscat` with no arguments (or `misscat --help`) shows usage help:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
misscat --help
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Repository names are canonicalized to lowercase, so `Genonfire/MissCat` and `genonfire/misscat` refer to the same local workspace and state.
|
|
124
|
+
|
|
125
|
+
## Configuration
|
|
126
|
+
|
|
127
|
+
MissCat ships with a bundled `default.yml` inside the package, so installed copies do not depend on the source checkout or current working directory.
|
|
128
|
+
|
|
129
|
+
User configuration and persistent data are kept entirely outside the package:
|
|
130
|
+
|
|
131
|
+
- **Profiles**: `~/.config/misscat/<profile>.yml`
|
|
132
|
+
- **Per-repository state**: `~/.config/misscat/<owner>__<repo>.json`
|
|
133
|
+
- **Persistent workspace**: `~/.cache/misscat/repos/<owner>/<repo>/`
|
|
134
|
+
|
|
135
|
+
Directory layout:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
~/.config/misscat/
|
|
139
|
+
├── luna.yml
|
|
140
|
+
├── sonnet.yml
|
|
141
|
+
├── genonfire__typewriter.json
|
|
142
|
+
└── genonfire__misscat.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Example `default.yml`:
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
reviewer:
|
|
149
|
+
# provider: claude
|
|
150
|
+
# model: claude-sonnet-5-5
|
|
151
|
+
# args:
|
|
152
|
+
# - --allowedTools
|
|
153
|
+
# - "Bash(gh *)"
|
|
154
|
+
|
|
155
|
+
provider: codex
|
|
156
|
+
model: gpt-6.1-sol
|
|
157
|
+
args:
|
|
158
|
+
- --sandbox
|
|
159
|
+
- workspace-write
|
|
160
|
+
- -c
|
|
161
|
+
- sandbox_workspace_write.network_access=true
|
|
162
|
+
- -c
|
|
163
|
+
- apps._default.enabled=false
|
|
164
|
+
- -c
|
|
165
|
+
- model_reasoning_effort=medium
|
|
166
|
+
|
|
167
|
+
prompt: |
|
|
168
|
+
Read REVIEW.md if exist and act as the 1st reviewer.
|
|
169
|
+
Use the gh CLI for GitHub operations, including posting the review.
|
|
170
|
+
|
|
171
|
+
watch:
|
|
172
|
+
idle: [60, 120, 180, 240, 300]
|
|
173
|
+
active: [300, 240, 180, 120, 60]
|
|
174
|
+
|
|
175
|
+
review:
|
|
176
|
+
include_drafts: true
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Example `~/.config/misscat/luna.yml`:
|
|
180
|
+
|
|
181
|
+
```yaml
|
|
182
|
+
reviewer:
|
|
183
|
+
provider: codex
|
|
184
|
+
model: gpt-6-luna
|
|
185
|
+
args:
|
|
186
|
+
- --sandbox
|
|
187
|
+
- workspace-write
|
|
188
|
+
- -c
|
|
189
|
+
- sandbox_workspace_write.network_access=true
|
|
190
|
+
- -c
|
|
191
|
+
- apps._default.enabled=false
|
|
192
|
+
- -c
|
|
193
|
+
- model_reasoning_effort=max
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The selected local profile overrides the bundled defaults.
|
|
197
|
+
|
|
198
|
+
When creating a local profile, use `default.yml` as the reference and specify `provider`, `model`, and `args` explicitly for that reviewer CLI. Do not rely on `args` inherited from a different provider.
|
|
199
|
+
|
|
200
|
+
The `args` field under `reviewer` is passed to the selected reviewer CLI unchanged.
|
|
201
|
+
|
|
202
|
+
Reviewed state is stored per repository and keyed by PR, HEAD SHA, and profile. The same HEAD can therefore be reviewed again with a different profile.
|
|
203
|
+
|
|
204
|
+
### Gemini (Antigravity CLI)
|
|
205
|
+
|
|
206
|
+
Gemini reviews use the Antigravity CLI (`agy`). Configure authentication and permissions before running MissCat.
|
|
207
|
+
|
|
208
|
+
For headless reviews, configure the Antigravity CLI settings file:
|
|
209
|
+
|
|
210
|
+
`~/.gemini/antigravity-cli/settings.json`
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"toolPermission": "proceed-in-sandbox",
|
|
215
|
+
"enableTerminalSandbox": true,
|
|
216
|
+
"permissions": {
|
|
217
|
+
"allow": [
|
|
218
|
+
"command(gh)",
|
|
219
|
+
"command(git)"
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Preserve any existing settings when adding these fields. Ensure the repository workspace is trusted as appropriate.
|
|
226
|
+
|
|
227
|
+
Example reviewer profile (`~/.config/misscat/gemini.yml`):
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
reviewer:
|
|
231
|
+
provider: gemini
|
|
232
|
+
model: gemini-3.8-flash-low
|
|
233
|
+
args:
|
|
234
|
+
- --print-timeout
|
|
235
|
+
- 30m
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Important:** In headless mode, commands requiring interactive permission approval may be automatically denied. Antigravity can still exit successfully without posting a GitHub review.
|
|
239
|
+
|
|
240
|
+
If a review finishes without appearing on GitHub, run MissCat with `--loud` to inspect reviewer activity and permission errors.
|
|
241
|
+
|
|
242
|
+
Avoid `--dangerously-skip-permissions` for routine unattended operation, as it broadly bypasses tool approval checks.
|
|
243
|
+
|
|
244
|
+
## Review workspace
|
|
245
|
+
|
|
246
|
+
MissCat reviews each repository in its own persistent workspace:
|
|
247
|
+
|
|
248
|
+
```text
|
|
249
|
+
~/.cache/misscat/repos/<owner>/<repo>/
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The repository is cloned on first use and reused for later reviews. Before each review, MissCat prepares a clean checkout of the exact PR HEAD.
|
|
253
|
+
|
|
254
|
+
Your normal development checkout is never touched.
|
|
255
|
+
|
|
256
|
+
## Requirements and limits
|
|
257
|
+
|
|
258
|
+
- **Authentication expectations**:
|
|
259
|
+
- Git must be able to authenticate to the target repository for clone and fetch. Existing SSH keys or Git credentials work seamlessly. If using HTTPS with GitHub CLI, configure Git helper via `gh auth setup-git`. MissCat never stores Git credentials.
|
|
260
|
+
- GitHub CLI (`gh`) must be authenticated (`gh auth login`) with permissions to query pull requests.
|
|
261
|
+
- Reviewer CLIs (`claude`, `codex`, `agy`) must be logged in and configured with their respective provider accounts or API keys. MissCat uses their existing credentials.
|
|
262
|
+
- **Trusted repository and PR warning**:
|
|
263
|
+
- Reviewer CLIs execute within a MissCat-managed checkout of PR-controlled files.
|
|
264
|
+
- MissCat should only be used with repositories and pull requests whose code and contributors you trust.
|
|
265
|
+
- **One process per repository**:
|
|
266
|
+
- Run at most one MissCat process per repository at any given time.
|
|
267
|
+
- Multiple MissCat instances or profiles pointing to the same repository would share and conflict over the same persistent workspace (`~/.cache/misscat/repos/<owner>/<repo>/`).
|
|
268
|
+
|
|
269
|
+
## Reviewer backends
|
|
270
|
+
|
|
271
|
+
MissCat is not tied to a specific AI reviewer.
|
|
272
|
+
|
|
273
|
+
Initial backends:
|
|
274
|
+
|
|
275
|
+
- Claude Code CLI
|
|
276
|
+
- Codex CLI
|
|
277
|
+
- Gemini via agy(Google Antigravity CLI)
|
|
278
|
+
|
|
279
|
+
MissCat runs the selected reviewer CLI from the root of the prepared PR checkout. The CLI can therefore discover and apply its own repository instructions, such as `CLAUDE.md` or `AGENTS.md`, while `REVIEW.md` defines the review behavior requested by MissCat.
|
|
280
|
+
|
|
281
|
+
MissCat does not parse or translate those instruction files.
|
|
282
|
+
|
|
283
|
+
MissCat uses the authentication already configured in the reviewer CLI.
|
|
284
|
+
The `args` field under `reviewer` can be used for CLI-specific execution options such as tool permissions, sandbox settings, or network access.
|
|
285
|
+
|
|
286
|
+
GitHub repository and pull request access is handled through the authenticated GitHub CLI (`gh`).
|
|
287
|
+
|
|
288
|
+
MissCat does not manage GitHub tokens, Git credentials, or AI API keys itself.
|
|
289
|
+
|
|
290
|
+
## Adaptive polling
|
|
291
|
+
|
|
292
|
+
When there are no open PRs, MissCat gradually becomes lazy:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
1m → 2m → 3m → 4m → 5m → 5m ...
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
After review work is complete, MissCat gives the author some time to make changes, then gets increasingly impatient:
|
|
299
|
+
|
|
300
|
+
```text
|
|
301
|
+
5m → 4m → 3m → 2m → 1m → 1m ...
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
MissCat runs one review at a time.
|
|
305
|
+
|
|
306
|
+
When a review finishes successfully, it immediately checks the repository again before sleeping. If another PR or new HEAD is waiting, it reviews that next.
|
|
307
|
+
|
|
308
|
+
If a review or workspace preparation fails, that HEAD is not marked reviewed and MissCat waits 5 minutes before checking again.
|
|
309
|
+
|
|
310
|
+
## What MissCat does
|
|
311
|
+
|
|
312
|
+
- Watches all open PRs in a repository
|
|
313
|
+
- Discovers PRs created after MissCat starts
|
|
314
|
+
- Detects changes by PR HEAD SHA
|
|
315
|
+
- Reviews every new PR HEAD once per profile
|
|
316
|
+
- Avoids duplicate reviews
|
|
317
|
+
- Remembers reviewed commits across restarts
|
|
318
|
+
- Uses an isolated persistent review workspace
|
|
319
|
+
- Supports multiple reviewer backends
|
|
320
|
+
|
|
321
|
+
MissCat does **not** modify code, push commits, or merge PRs.
|
|
322
|
+
|
|
323
|
+
It watches. It catches. It reviews.
|