tony-cli 0.4.2__tar.gz → 0.6.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.
- {tony_cli-0.4.2 → tony_cli-0.6.0}/LICENSE +2 -2
- {tony_cli-0.4.2/src/tony_cli.egg-info → tony_cli-0.6.0}/PKG-INFO +47 -68
- tony_cli-0.6.0/README.md +120 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/pyproject.toml +2 -6
- tony_cli-0.6.0/src/tony_cli/agent.py +108 -0
- tony_cli-0.6.0/src/tony_cli/anchors.py +374 -0
- tony_cli-0.6.0/src/tony_cli/hosted.py +550 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/install.py +118 -1
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/layout.py +37 -24
- tony_cli-0.6.0/src/tony_cli/mcp_config.py +190 -0
- tony_cli-0.6.0/src/tony_cli/mcp_server.py +790 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/payload.py +18 -7
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/source/local.py +88 -87
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/uninstall.py +9 -8
- {tony_cli-0.4.2 → tony_cli-0.6.0/src/tony_cli.egg-info}/PKG-INFO +47 -68
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli.egg-info/SOURCES.txt +3 -9
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli.egg-info/requires.txt +1 -2
- tony_cli-0.4.2/README.md +0 -140
- tony_cli-0.4.2/src/tony_cli/agent.py +0 -766
- tony_cli-0.4.2/src/tony_cli/assets/fonts/Favorit-Bold.woff2 +0 -0
- tony_cli-0.4.2/src/tony_cli/assets/fonts/Favorit-Book.woff2 +0 -0
- tony_cli-0.4.2/src/tony_cli/assets/fonts/Favorit-Regular.woff2 +0 -0
- tony_cli-0.4.2/src/tony_cli/assets/fonts/FavoritMono-Medium.woff2 +0 -0
- tony_cli-0.4.2/src/tony_cli/assets/fonts/FavoritMono-Regular.woff2 +0 -0
- tony_cli-0.4.2/src/tony_cli/assets/viewer.css +0 -281
- tony_cli-0.4.2/src/tony_cli/assets/viewer.js +0 -98
- tony_cli-0.4.2/src/tony_cli/fonts.py +0 -38
- tony_cli-0.4.2/src/tony_cli/hosted.py +0 -324
- tony_cli-0.4.2/src/tony_cli/page.py +0 -54
- {tony_cli-0.4.2 → tony_cli-0.6.0}/setup.cfg +0 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/__init__.py +0 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli/source/__init__.py +0 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli.egg-info/dependency_links.txt +0 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli.egg-info/entry_points.txt +0 -0
- {tony_cli-0.4.2 → tony_cli-0.6.0}/src/tony_cli.egg-info/top_level.txt +0 -0
|
@@ -12,8 +12,8 @@ furnished to do so, subject to the following conditions:
|
|
|
12
12
|
The above copyright notice and this permission notice shall be included in all
|
|
13
13
|
copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
|
-
The ABC Favorit and ABC Favorit Mono font files under
|
|
16
|
-
|
|
15
|
+
The ABC Favorit and ABC Favorit Mono font files under web/public/fonts are
|
|
16
|
+
commercial typefaces by Dinamo and are NOT covered by this license.
|
|
17
17
|
|
|
18
18
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
19
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tony-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Explains a git diff to whoever now owns it — annotated changes, blast radius, and steppable runtime walkthroughs.
|
|
5
5
|
Author: Fawwaz Abayomi
|
|
6
6
|
License: MIT License
|
|
@@ -17,8 +17,8 @@ License: MIT License
|
|
|
17
17
|
The above copyright notice and this permission notice shall be included in all
|
|
18
18
|
copies or substantial portions of the Software.
|
|
19
19
|
|
|
20
|
-
The ABC Favorit and ABC Favorit Mono font files under
|
|
21
|
-
|
|
20
|
+
The ABC Favorit and ABC Favorit Mono font files under web/public/fonts are
|
|
21
|
+
commercial typefaces by Dinamo and are NOT covered by this license.
|
|
22
22
|
|
|
23
23
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
24
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
@@ -44,10 +44,9 @@ Classifier: Topic :: Software Development :: Version Control :: Git
|
|
|
44
44
|
Requires-Python: >=3.10
|
|
45
45
|
Description-Content-Type: text/markdown
|
|
46
46
|
License-File: LICENSE
|
|
47
|
-
Requires-Dist: anthropic>=0.40
|
|
48
|
-
Requires-Dist: python-dotenv>=1.0
|
|
49
47
|
Requires-Dist: httpx>=0.27
|
|
50
48
|
Requires-Dist: cryptography>=42
|
|
49
|
+
Requires-Dist: mcp>=1.9
|
|
51
50
|
Provides-Extra: dev
|
|
52
51
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
53
52
|
Dynamic: license-file
|
|
@@ -56,9 +55,14 @@ Dynamic: license-file
|
|
|
56
55
|
|
|
57
56
|
**Your AI wrote the code. tony explains what now exists.**
|
|
58
57
|
|
|
59
|
-
tony
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
tony turns a git diff into a review page for the person who now owns the code —
|
|
59
|
+
often someone who didn't type a line of it. Not a linter, not a code-review
|
|
60
|
+
gate: it builds your mental model of the change, fast.
|
|
61
|
+
|
|
62
|
+
tony does not call a model. It runs inside the coding agent you already pay for:
|
|
63
|
+
you ask the agent to review a branch, it calls tony over MCP, tony hands it the
|
|
64
|
+
diff and the standard the review has to meet, checks the answer against the
|
|
65
|
+
diff, and publishes the page.
|
|
62
66
|
|
|
63
67
|
Every review page has three tabs:
|
|
64
68
|
|
|
@@ -87,63 +91,46 @@ uv tool install tony-cli # or: pipx install tony-cli
|
|
|
87
91
|
|
|
88
92
|
Either way you get a `tony` command on your PATH.
|
|
89
93
|
|
|
90
|
-
##
|
|
94
|
+
## Set up
|
|
95
|
+
|
|
96
|
+
Two commands, once per machine:
|
|
91
97
|
|
|
92
98
|
```sh
|
|
93
|
-
|
|
94
|
-
tony
|
|
95
|
-
tony # review the default branch...HEAD
|
|
99
|
+
tony connect # register tony with Claude Code, Codex, Cursor, Amp
|
|
100
|
+
tony login # sign in, so reviews have somewhere to publish
|
|
96
101
|
```
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
(gitignored automatically) and opens in your browser — one self-contained HTML
|
|
100
|
-
file, fonts and styles and data inlined, so it works offline and forever.
|
|
101
|
-
Nothing is uploaded; the only thing that leaves your machine is the diff tony
|
|
102
|
-
sends to Anthropic to write the review.
|
|
103
|
-
|
|
104
|
-
tony needs an Anthropic API key (`ANTHROPIC_API_KEY`, or `~/.tony/.env`). The
|
|
105
|
-
first run tells you exactly where to get one and where to put it. tony reviews
|
|
106
|
-
**committed** work: it shows code straight from disk, so the working tree must
|
|
107
|
-
match the revision under review.
|
|
108
|
-
|
|
109
|
-
Every command and flag is listed under [Commands](#commands).
|
|
103
|
+
Then restart your agent and ask it, in words:
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
`tony --help` prints this list. Everything below works from anywhere inside a
|
|
114
|
-
git repo unless noted.
|
|
105
|
+
> review this branch with tony
|
|
115
106
|
|
|
116
|
-
|
|
107
|
+
The agent calls `tony_start`, reads the diff and whatever files it needs,
|
|
108
|
+
writes the review, and calls `tony_publish`. What comes back is a URL. Reviews
|
|
109
|
+
are published to your account; the page is the deliverable, so the agent hands
|
|
110
|
+
you the link rather than pasting the review into the chat.
|
|
117
111
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
tony main...my-branch # an explicit range
|
|
121
|
-
tony my-branch # shorthand for my-branch...HEAD
|
|
122
|
-
tony ../other-repo main...x # any path inside another repo
|
|
123
|
-
```
|
|
112
|
+
tony reviews **committed** work: the page shows code straight from disk, so the
|
|
113
|
+
working tree has to match the revision under review.
|
|
124
114
|
|
|
125
|
-
|
|
126
|
-
`origin/HEAD` — what the remote calls its default branch — falling back to
|
|
127
|
-
`main`, then `master`.
|
|
128
|
-
|
|
129
|
-
| Flag | What it does |
|
|
130
|
-
|---|---|
|
|
131
|
-
| `--json` | Print the raw review JSON to stdout and exit. Writes no page instead. |
|
|
132
|
-
| `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
|
|
133
|
-
| `--stale` | Review a revision that isn't checked out, or with a dirty tree. Code is read from disk, so line numbers may not match the diff — tony refuses by default for that reason. |
|
|
134
|
-
| `--replay` | Rebuild the page from the last saved review for this range, without calling the API. Free; use it after a tony upgrade to re-render an old review. |
|
|
135
|
-
| `-v`, `--verbose` | Log every tool call to stderr, so you can see which files the review actually read before it drew conclusions. |
|
|
136
|
-
| `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
|
|
137
|
-
| `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
|
|
115
|
+
## Commands
|
|
138
116
|
|
|
139
|
-
|
|
117
|
+
`tony --help` prints this list.
|
|
140
118
|
|
|
141
119
|
| Command | What it does |
|
|
142
120
|
|---|---|
|
|
121
|
+
| `tony connect [host ...]` | Write the MCP config for Claude Code, Codex, Cursor, or Amp. Named hosts only, or all four it finds. |
|
|
122
|
+
| `tony login` / `tony logout` | Your account on the tony site. Publishing needs it; nothing else does. |
|
|
123
|
+
| `tony mcp` | Run the MCP server on stdio. Your agent runs this, not you. |
|
|
143
124
|
| `tony update` | Upgrade to the latest release, using whichever of uv, pipx or pip installed tony. Checks PyPI first and tells you if you're already current. |
|
|
125
|
+
|
|
126
|
+
Every command asks PyPI whether there is a newer release and says so on the way
|
|
127
|
+
out; the request runs alongside the command, so nothing waits on it, and a
|
|
128
|
+
review started through the MCP server tells the agent instead of a terminal
|
|
129
|
+
nobody is watching. It never installs anything by itself.
|
|
130
|
+
|
|
144
131
|
| `tony uninstall` | Delete tony and everything it wrote — see [Uninstall](#uninstall). |
|
|
145
132
|
| `tony --version` | The installed version. |
|
|
146
|
-
| `tony --help` |
|
|
133
|
+
| `tony --help` | This list. |
|
|
147
134
|
|
|
148
135
|
`tony uninstall` takes `--yes` (`-y`) to skip the confirmation and `--no-scan` to
|
|
149
136
|
limit it to the current repo instead of searching your home directory.
|
|
@@ -157,11 +144,12 @@ pointed at an internal mirror can't decide what `tony-cli` is.
|
|
|
157
144
|
tony uninstall
|
|
158
145
|
```
|
|
159
146
|
|
|
160
|
-
Removing the package by itself would leave the parts worth removing: your
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
147
|
+
Removing the package by itself would leave the parts worth removing: your login
|
|
148
|
+
token in `~/.tony`, and — from versions before tony went agent-native — an API
|
|
149
|
+
key beside it and a `.tony/` directory of past reviews inside every repository
|
|
150
|
+
you ran tony in, which hold source code. `tony uninstall` lists everything it
|
|
151
|
+
found, waits for you to type `yes`, deletes it, then removes the package with
|
|
152
|
+
whichever of uv, pipx, or pip installed it.
|
|
165
153
|
|
|
166
154
|
It searches your home directory for stray review directories; `--no-scan`
|
|
167
155
|
limits it to the current repository, and `--yes` skips the prompt.
|
|
@@ -172,22 +160,13 @@ limits it to the current repository, and `--yes` skips the prompt.
|
|
|
172
160
|
pip install -e ".[dev]" # the CLI, with pytest
|
|
173
161
|
python -m pytest # the deterministic layer's tests
|
|
174
162
|
cd web && npm install
|
|
175
|
-
npm run build:viewer # rebuild the renderer bundle the CLI embeds
|
|
176
163
|
npm run dev # the site; /dev renders src/fixtures/review.json
|
|
177
164
|
```
|
|
178
165
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
| `--viewer` | Write the payload straight into the local Astro viewer and reload it there, so you can iterate on the renderer against a real review. |
|
|
184
|
-
| `--payload [PATH]` | Write the upload payload — windowed source, no absolute paths — next to the page, or to `PATH`. |
|
|
185
|
-
|
|
186
|
-
There is exactly one renderer — `web/src/renderer/render.ts` — used by both
|
|
187
|
-
the local page and the hosted site. The Python side decides all layout facts
|
|
188
|
-
(line numbers, spans, added/changed tags) in `src/tony_cli/layout.py` and ships
|
|
189
|
-
them in the payload; the renderer never re-derives them. `DESIGN.md` is the
|
|
190
|
-
visual contract.
|
|
166
|
+
The renderer is `web/src/renderer/render.ts`, and the site is the only thing
|
|
167
|
+
that runs it. The Python side decides all layout facts (line numbers, spans,
|
|
168
|
+
added/changed tags) in `src/tony_cli/layout.py` and ships them in the payload;
|
|
169
|
+
the renderer never re-derives them. `DESIGN.md` is the visual contract.
|
|
191
170
|
|
|
192
171
|
The site deploys to Vercel and needs `DATABASE_URL` (Neon Postgres),
|
|
193
172
|
`BLOB_READ_WRITE_TOKEN` (Vercel Blob), and `GITHUB_CLIENT_ID` (an OAuth app
|
tony_cli-0.6.0/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# tony
|
|
2
|
+
|
|
3
|
+
**Your AI wrote the code. tony explains what now exists.**
|
|
4
|
+
|
|
5
|
+
tony turns a git diff into a review page for the person who now owns the code —
|
|
6
|
+
often someone who didn't type a line of it. Not a linter, not a code-review
|
|
7
|
+
gate: it builds your mental model of the change, fast.
|
|
8
|
+
|
|
9
|
+
tony does not call a model. It runs inside the coding agent you already pay for:
|
|
10
|
+
you ask the agent to review a branch, it calls tony over MCP, tony hands it the
|
|
11
|
+
diff and the standard the review has to meet, checks the answer against the
|
|
12
|
+
diff, and publishes the page.
|
|
13
|
+
|
|
14
|
+
Every review page has three tabs:
|
|
15
|
+
|
|
16
|
+
1. **File changes** — the diff per file, with plain-language annotations sitting
|
|
17
|
+
inline above the lines they explain. Modified code gets Prev / New / Changes
|
|
18
|
+
panes; line numbers are computed from the diff, never trusted to the model.
|
|
19
|
+
2. **Blast radius** — files the change reaches that are *not* in the diff, each
|
|
20
|
+
consumer classified breaks / behavior-change / compatible, shown at the
|
|
21
|
+
affected lines.
|
|
22
|
+
3. **How it works** — steppable runtime walkthroughs. One concrete scenario
|
|
23
|
+
("you run `export --resume` after a crash") traced step by step, showing the
|
|
24
|
+
real source lines read from your disk, a small state table, and one plain
|
|
25
|
+
sentence per step.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
curl -fsSL https://tony-cli.com/install.sh | sh
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
or, if you already use uv or pipx:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
uv tool install tony-cli # or: pipx install tony-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Either way you get a `tony` command on your PATH.
|
|
40
|
+
|
|
41
|
+
## Set up
|
|
42
|
+
|
|
43
|
+
Two commands, once per machine:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
tony connect # register tony with Claude Code, Codex, Cursor, Amp
|
|
47
|
+
tony login # sign in, so reviews have somewhere to publish
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then restart your agent and ask it, in words:
|
|
51
|
+
|
|
52
|
+
> review this branch with tony
|
|
53
|
+
|
|
54
|
+
The agent calls `tony_start`, reads the diff and whatever files it needs,
|
|
55
|
+
writes the review, and calls `tony_publish`. What comes back is a URL. Reviews
|
|
56
|
+
are published to your account; the page is the deliverable, so the agent hands
|
|
57
|
+
you the link rather than pasting the review into the chat.
|
|
58
|
+
|
|
59
|
+
tony reviews **committed** work: the page shows code straight from disk, so the
|
|
60
|
+
working tree has to match the revision under review.
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
`tony --help` prints this list.
|
|
65
|
+
|
|
66
|
+
| Command | What it does |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `tony connect [host ...]` | Write the MCP config for Claude Code, Codex, Cursor, or Amp. Named hosts only, or all four it finds. |
|
|
69
|
+
| `tony login` / `tony logout` | Your account on the tony site. Publishing needs it; nothing else does. |
|
|
70
|
+
| `tony mcp` | Run the MCP server on stdio. Your agent runs this, not you. |
|
|
71
|
+
| `tony update` | Upgrade to the latest release, using whichever of uv, pipx or pip installed tony. Checks PyPI first and tells you if you're already current. |
|
|
72
|
+
|
|
73
|
+
Every command asks PyPI whether there is a newer release and says so on the way
|
|
74
|
+
out; the request runs alongside the command, so nothing waits on it, and a
|
|
75
|
+
review started through the MCP server tells the agent instead of a terminal
|
|
76
|
+
nobody is watching. It never installs anything by itself.
|
|
77
|
+
|
|
78
|
+
| `tony uninstall` | Delete tony and everything it wrote — see [Uninstall](#uninstall). |
|
|
79
|
+
| `tony --version` | The installed version. |
|
|
80
|
+
| `tony --help` | This list. |
|
|
81
|
+
|
|
82
|
+
`tony uninstall` takes `--yes` (`-y`) to skip the confirmation and `--no-scan` to
|
|
83
|
+
limit it to the current repo instead of searching your home directory.
|
|
84
|
+
|
|
85
|
+
Both `tony update` and the installer resolve from PyPI explicitly, so a machine
|
|
86
|
+
pointed at an internal mirror can't decide what `tony-cli` is.
|
|
87
|
+
|
|
88
|
+
## Uninstall
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
tony uninstall
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Removing the package by itself would leave the parts worth removing: your login
|
|
95
|
+
token in `~/.tony`, and — from versions before tony went agent-native — an API
|
|
96
|
+
key beside it and a `.tony/` directory of past reviews inside every repository
|
|
97
|
+
you ran tony in, which hold source code. `tony uninstall` lists everything it
|
|
98
|
+
found, waits for you to type `yes`, deletes it, then removes the package with
|
|
99
|
+
whichever of uv, pipx, or pip installed it.
|
|
100
|
+
|
|
101
|
+
It searches your home directory for stray review directories; `--no-scan`
|
|
102
|
+
limits it to the current repository, and `--yes` skips the prompt.
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
pip install -e ".[dev]" # the CLI, with pytest
|
|
108
|
+
python -m pytest # the deterministic layer's tests
|
|
109
|
+
cd web && npm install
|
|
110
|
+
npm run dev # the site; /dev renders src/fixtures/review.json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The renderer is `web/src/renderer/render.ts`, and the site is the only thing
|
|
114
|
+
that runs it. The Python side decides all layout facts (line numbers, spans,
|
|
115
|
+
added/changed tags) in `src/tony_cli/layout.py` and ships them in the payload;
|
|
116
|
+
the renderer never re-derives them. `DESIGN.md` is the visual contract.
|
|
117
|
+
|
|
118
|
+
The site deploys to Vercel and needs `DATABASE_URL` (Neon Postgres),
|
|
119
|
+
`BLOB_READ_WRITE_TOKEN` (Vercel Blob), and `GITHUB_CLIENT_ID` (an OAuth app
|
|
120
|
+
with device flow enabled).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tony-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "Explains a git diff to whoever now owns it — annotated changes, blast radius, and steppable runtime walkthroughs."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -20,10 +20,9 @@ classifiers = [
|
|
|
20
20
|
"Topic :: Software Development :: Version Control :: Git",
|
|
21
21
|
]
|
|
22
22
|
dependencies = [
|
|
23
|
-
"anthropic>=0.40",
|
|
24
|
-
"python-dotenv>=1.0",
|
|
25
23
|
"httpx>=0.27",
|
|
26
24
|
"cryptography>=42",
|
|
25
|
+
"mcp>=1.9",
|
|
27
26
|
]
|
|
28
27
|
|
|
29
28
|
[project.optional-dependencies]
|
|
@@ -44,8 +43,5 @@ build-backend = "setuptools.build_meta"
|
|
|
44
43
|
where = ["src"]
|
|
45
44
|
include = ["tony_cli*"]
|
|
46
45
|
|
|
47
|
-
[tool.setuptools.package-data]
|
|
48
|
-
tony_cli = ["assets/fonts/*.woff2", "assets/viewer.js", "assets/viewer.css"]
|
|
49
|
-
|
|
50
46
|
[tool.pytest.ini_options]
|
|
51
47
|
testpaths = ["src/tests"]
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""The `tony` command.
|
|
2
|
+
|
|
3
|
+
tony does not review anything itself. The reviewing happens inside whatever
|
|
4
|
+
coding agent the developer already pays for, over the MCP server in
|
|
5
|
+
`mcp_server.py` — the agent reads the diff, writes the review, and hands it
|
|
6
|
+
back to be validated and published. So this module is a dispatcher: accounts,
|
|
7
|
+
agent wiring, and the installer. Everything a person types.
|
|
8
|
+
|
|
9
|
+
The old path — tony owning an Anthropic key and driving its own tool loop —
|
|
10
|
+
is gone. See `mcp_server.py` for what replaced it.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from tony_cli import hosted, install
|
|
16
|
+
|
|
17
|
+
USAGE = """\
|
|
18
|
+
tony — explains a git diff to whoever now owns it.
|
|
19
|
+
|
|
20
|
+
tony connect [host ...] connect tony to your coding agent
|
|
21
|
+
tony login sign in, so reviews have somewhere to publish
|
|
22
|
+
tony logout sign out on this machine
|
|
23
|
+
tony mcp run the MCP server on stdio (agents call this)
|
|
24
|
+
tony update update to the latest release
|
|
25
|
+
tony uninstall delete tony, its login, and every saved review
|
|
26
|
+
tony --version what is installed
|
|
27
|
+
|
|
28
|
+
To review something, ask your agent: "review this branch with tony".
|
|
29
|
+
|
|
30
|
+
https://tony-cli.com
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Commands that must not carry the notice. `update` and `uninstall` are about
|
|
35
|
+
# the installed version already and would be talking over themselves; `mcp`
|
|
36
|
+
# speaks a protocol on stdio and has no terminal to say anything to — it tells
|
|
37
|
+
# the agent instead, in `mcp_server.startReview`.
|
|
38
|
+
NO_NOTICE = ("update", "uninstall", "mcp")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def main(argv=None):
|
|
42
|
+
argv = sys.argv[1:] if argv is None else argv
|
|
43
|
+
command = argv[0] if argv else None
|
|
44
|
+
|
|
45
|
+
# Started before the command, collected after it: the round trip to PyPI
|
|
46
|
+
# overlaps whatever the command was going to do anyway, so the only run
|
|
47
|
+
# that ever waits on it is one that finishes in under half a second.
|
|
48
|
+
check = None if command in NO_NOTICE else install.startUpdateCheck()
|
|
49
|
+
code = dispatch(argv, command)
|
|
50
|
+
if check:
|
|
51
|
+
notice = install.updateNotice(check)
|
|
52
|
+
if notice:
|
|
53
|
+
# stderr, so it never lands in the middle of output being piped
|
|
54
|
+
# somewhere that expected only the command's own.
|
|
55
|
+
print(notice, file=sys.stderr)
|
|
56
|
+
return code
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def dispatch(argv, command):
|
|
60
|
+
"""Run one command and return its exit code. Everything a person types."""
|
|
61
|
+
if command in (None, "help", "-h", "--help"):
|
|
62
|
+
# No arguments is not an error: it is someone who just installed tony
|
|
63
|
+
# and wants to know what to type next. That is `tony connect`.
|
|
64
|
+
print(USAGE)
|
|
65
|
+
return 0
|
|
66
|
+
|
|
67
|
+
if command in ("--version", "-V", "version"):
|
|
68
|
+
print(f"tony {install.installedVersion() or 'unknown'}")
|
|
69
|
+
return 0
|
|
70
|
+
|
|
71
|
+
if command == "login":
|
|
72
|
+
return hosted.login(argv[1:])
|
|
73
|
+
if command == "logout":
|
|
74
|
+
return hosted.logout()
|
|
75
|
+
|
|
76
|
+
# Imported here, not at the top: it pulls in the MCP SDK, and `tony` as a
|
|
77
|
+
# CLI should not pay that import on every run to serve one subcommand.
|
|
78
|
+
if command == "mcp":
|
|
79
|
+
from tony_cli.mcp_server import serve
|
|
80
|
+
return serve(argv[1:])
|
|
81
|
+
if command == "connect":
|
|
82
|
+
from tony_cli import mcp_config
|
|
83
|
+
return mcp_config.connect(argv[1:])
|
|
84
|
+
|
|
85
|
+
# The obvious wrong guess, and one worth answering.
|
|
86
|
+
if command == "install":
|
|
87
|
+
print("tony: tony is already installed — you want `tony connect`, which\n"
|
|
88
|
+
" registers it with your coding agent.", file=sys.stderr)
|
|
89
|
+
return 2
|
|
90
|
+
if command == "update":
|
|
91
|
+
return install.update(argv[1:])
|
|
92
|
+
if command == "uninstall":
|
|
93
|
+
from tony_cli.uninstall import uninstall
|
|
94
|
+
return uninstall(argv[1:])
|
|
95
|
+
|
|
96
|
+
# A range or a repository path — what tony used to take directly. Someone
|
|
97
|
+
# typing it has an older tony's habits, so say where the reviewing went.
|
|
98
|
+
print(
|
|
99
|
+
f"tony: unknown command {command!r}.\n\n"
|
|
100
|
+
" tony no longer reviews on its own. Run `tony connect` once, then ask\n"
|
|
101
|
+
" your coding agent to review the branch and it will call tony for you.\n",
|
|
102
|
+
file=sys.stderr,
|
|
103
|
+
)
|
|
104
|
+
return 2
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
sys.exit(main())
|