tony-cli 0.3.2__tar.gz → 0.4.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.3.2/src/tony_cli.egg-info → tony_cli-0.4.0}/PKG-INFO +12 -48
- {tony_cli-0.3.2 → tony_cli-0.4.0}/README.md +11 -47
- {tony_cli-0.3.2 → tony_cli-0.4.0}/pyproject.toml +1 -1
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/agent.py +17 -18
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/install.py +29 -4
- {tony_cli-0.3.2 → tony_cli-0.4.0/src/tony_cli.egg-info}/PKG-INFO +12 -48
- {tony_cli-0.3.2 → tony_cli-0.4.0}/LICENSE +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/setup.cfg +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/__init__.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/fonts/Favorit-Bold.woff2 +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/fonts/Favorit-Book.woff2 +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/fonts/Favorit-Regular.woff2 +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/fonts/FavoritMono-Medium.woff2 +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/fonts/FavoritMono-Regular.woff2 +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/viewer.css +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/assets/viewer.js +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/fonts.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/hosted.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/layout.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/page.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/payload.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/source/__init__.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/source/local.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli/uninstall.py +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli.egg-info/SOURCES.txt +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli.egg-info/dependency_links.txt +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli.egg-info/entry_points.txt +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli.egg-info/requires.txt +0 -0
- {tony_cli-0.3.2 → tony_cli-0.4.0}/src/tony_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tony-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -95,9 +95,11 @@ tony main...my-branch # review a branch against main
|
|
|
95
95
|
tony # review the default branch...HEAD
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
The page is written to `.tony/` inside the repo
|
|
99
|
-
opens in your browser
|
|
100
|
-
data inlined
|
|
98
|
+
Reviews stay on your machine. The page is written to `.tony/` inside the repo
|
|
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.
|
|
101
103
|
|
|
102
104
|
tony needs an Anthropic API key (`ANTHROPIC_API_KEY`, or `~/.tony/.env`). The
|
|
103
105
|
first run tells you exactly where to get one and where to put it. tony reviews
|
|
@@ -126,8 +128,7 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
126
128
|
|
|
127
129
|
| Flag | What it does |
|
|
128
130
|
|---|---|
|
|
129
|
-
| `--
|
|
130
|
-
| `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
|
|
131
|
+
| `--json` | Print the raw review JSON to stdout and exit. Writes no page instead. |
|
|
131
132
|
| `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
|
|
132
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. |
|
|
133
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,17 +136,6 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
135
136
|
| `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
|
|
136
137
|
| `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
|
|
137
138
|
|
|
138
|
-
### Sharing
|
|
139
|
-
|
|
140
|
-
| Command | What it does |
|
|
141
|
-
|---|---|
|
|
142
|
-
| `tony login` | Sign in to tony-cli.com with GitHub's device flow. Once per machine. |
|
|
143
|
-
| `tony logout` | Revoke this machine's token server-side, then delete it locally. |
|
|
144
|
-
| `tony whoami` | Which GitHub account this machine is signed in as. |
|
|
145
|
-
| `tony unpublish <id>` | Take one published review down. The id is the last part of its URL. |
|
|
146
|
-
|
|
147
|
-
Publishing is the default when you're signed in. `--local` opts out per run.
|
|
148
|
-
|
|
149
139
|
### Managing tony
|
|
150
140
|
|
|
151
141
|
| Command | What it does |
|
|
@@ -161,29 +151,6 @@ limit it to the current repo instead of searching your home directory.
|
|
|
161
151
|
Both `tony update` and the installer resolve from PyPI explicitly, so a machine
|
|
162
152
|
pointed at an internal mirror can't decide what `tony-cli` is.
|
|
163
153
|
|
|
164
|
-
## Share a review
|
|
165
|
-
|
|
166
|
-
```sh
|
|
167
|
-
tony login # once — GitHub device flow
|
|
168
|
-
tony main...my-branch # publishing is the default
|
|
169
|
-
tony: https://tony-cli.com/r/8f3ka92m
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Who can read a published review:** anyone signed in who has the link. Review
|
|
173
|
-
ids are random, so the link is what grants access — treat it like a password.
|
|
174
|
-
`tony unpublish <id>` removes a review at any time.
|
|
175
|
-
|
|
176
|
-
**What the site can read:** everything in the review. The payload is uploaded
|
|
177
|
-
over TLS and encrypted at rest under a key the server holds, so a leak of the
|
|
178
|
-
stored blobs yields nothing — but we can open a review, and so can any lawful
|
|
179
|
-
demand made to us. Do not publish from a repository you could not share with
|
|
180
|
-
us. An earlier design encrypted on your machine and kept the key in the link's
|
|
181
|
-
fragment; that was dropped deliberately when reading moved behind an account
|
|
182
|
-
and a history of past reviews became part of the product, since both need the
|
|
183
|
-
server to be able to open a review.
|
|
184
|
-
|
|
185
|
-
Local review needs no account and never leaves the machine: `tony --local`.
|
|
186
|
-
|
|
187
154
|
## Uninstall
|
|
188
155
|
|
|
189
156
|
```sh
|
|
@@ -191,16 +158,13 @@ tony uninstall
|
|
|
191
158
|
```
|
|
192
159
|
|
|
193
160
|
Removing the package by itself would leave the parts worth removing: your
|
|
194
|
-
`ANTHROPIC_API_KEY`
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
uv, pipx, or pip installed it.
|
|
161
|
+
`ANTHROPIC_API_KEY` in `~/.tony`, and a `.tony/` directory of past reviews
|
|
162
|
+
inside every repository you ran tony in — those hold source code. `tony
|
|
163
|
+
uninstall` lists everything it found, waits for you to type `yes`, deletes it,
|
|
164
|
+
then removes the package with whichever of uv, pipx, or pip installed it.
|
|
199
165
|
|
|
200
166
|
It searches your home directory for stray review directories; `--no-scan`
|
|
201
|
-
limits it to the current repository, and `--yes` skips the prompt.
|
|
202
|
-
published to the site are separate — take those down with `tony unpublish <id>`
|
|
203
|
-
before uninstalling, or they stay up.
|
|
167
|
+
limits it to the current repository, and `--yes` skips the prompt.
|
|
204
168
|
|
|
205
169
|
## Development
|
|
206
170
|
|
|
@@ -41,9 +41,11 @@ tony main...my-branch # review a branch against main
|
|
|
41
41
|
tony # review the default branch...HEAD
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
The page is written to `.tony/` inside the repo
|
|
45
|
-
opens in your browser
|
|
46
|
-
data inlined
|
|
44
|
+
Reviews stay on your machine. The page is written to `.tony/` inside the repo
|
|
45
|
+
(gitignored automatically) and opens in your browser — one self-contained HTML
|
|
46
|
+
file, fonts and styles and data inlined, so it works offline and forever.
|
|
47
|
+
Nothing is uploaded; the only thing that leaves your machine is the diff tony
|
|
48
|
+
sends to Anthropic to write the review.
|
|
47
49
|
|
|
48
50
|
tony needs an Anthropic API key (`ANTHROPIC_API_KEY`, or `~/.tony/.env`). The
|
|
49
51
|
first run tells you exactly where to get one and where to put it. tony reviews
|
|
@@ -72,8 +74,7 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
72
74
|
|
|
73
75
|
| Flag | What it does |
|
|
74
76
|
|---|---|
|
|
75
|
-
| `--
|
|
76
|
-
| `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
|
|
77
|
+
| `--json` | Print the raw review JSON to stdout and exit. Writes no page instead. |
|
|
77
78
|
| `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
|
|
78
79
|
| `--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. |
|
|
79
80
|
| `--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. |
|
|
@@ -81,17 +82,6 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
81
82
|
| `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
|
|
82
83
|
| `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
|
|
83
84
|
|
|
84
|
-
### Sharing
|
|
85
|
-
|
|
86
|
-
| Command | What it does |
|
|
87
|
-
|---|---|
|
|
88
|
-
| `tony login` | Sign in to tony-cli.com with GitHub's device flow. Once per machine. |
|
|
89
|
-
| `tony logout` | Revoke this machine's token server-side, then delete it locally. |
|
|
90
|
-
| `tony whoami` | Which GitHub account this machine is signed in as. |
|
|
91
|
-
| `tony unpublish <id>` | Take one published review down. The id is the last part of its URL. |
|
|
92
|
-
|
|
93
|
-
Publishing is the default when you're signed in. `--local` opts out per run.
|
|
94
|
-
|
|
95
85
|
### Managing tony
|
|
96
86
|
|
|
97
87
|
| Command | What it does |
|
|
@@ -107,29 +97,6 @@ limit it to the current repo instead of searching your home directory.
|
|
|
107
97
|
Both `tony update` and the installer resolve from PyPI explicitly, so a machine
|
|
108
98
|
pointed at an internal mirror can't decide what `tony-cli` is.
|
|
109
99
|
|
|
110
|
-
## Share a review
|
|
111
|
-
|
|
112
|
-
```sh
|
|
113
|
-
tony login # once — GitHub device flow
|
|
114
|
-
tony main...my-branch # publishing is the default
|
|
115
|
-
tony: https://tony-cli.com/r/8f3ka92m
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Who can read a published review:** anyone signed in who has the link. Review
|
|
119
|
-
ids are random, so the link is what grants access — treat it like a password.
|
|
120
|
-
`tony unpublish <id>` removes a review at any time.
|
|
121
|
-
|
|
122
|
-
**What the site can read:** everything in the review. The payload is uploaded
|
|
123
|
-
over TLS and encrypted at rest under a key the server holds, so a leak of the
|
|
124
|
-
stored blobs yields nothing — but we can open a review, and so can any lawful
|
|
125
|
-
demand made to us. Do not publish from a repository you could not share with
|
|
126
|
-
us. An earlier design encrypted on your machine and kept the key in the link's
|
|
127
|
-
fragment; that was dropped deliberately when reading moved behind an account
|
|
128
|
-
and a history of past reviews became part of the product, since both need the
|
|
129
|
-
server to be able to open a review.
|
|
130
|
-
|
|
131
|
-
Local review needs no account and never leaves the machine: `tony --local`.
|
|
132
|
-
|
|
133
100
|
## Uninstall
|
|
134
101
|
|
|
135
102
|
```sh
|
|
@@ -137,16 +104,13 @@ tony uninstall
|
|
|
137
104
|
```
|
|
138
105
|
|
|
139
106
|
Removing the package by itself would leave the parts worth removing: your
|
|
140
|
-
`ANTHROPIC_API_KEY`
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
uv, pipx, or pip installed it.
|
|
107
|
+
`ANTHROPIC_API_KEY` in `~/.tony`, and a `.tony/` directory of past reviews
|
|
108
|
+
inside every repository you ran tony in — those hold source code. `tony
|
|
109
|
+
uninstall` lists everything it found, waits for you to type `yes`, deletes it,
|
|
110
|
+
then removes the package with whichever of uv, pipx, or pip installed it.
|
|
145
111
|
|
|
146
112
|
It searches your home directory for stray review directories; `--no-scan`
|
|
147
|
-
limits it to the current repository, and `--yes` skips the prompt.
|
|
148
|
-
published to the site are separate — take those down with `tony unpublish <id>`
|
|
149
|
-
before uninstalling, or they stay up.
|
|
113
|
+
limits it to the current repository, and `--yes` skips the prompt.
|
|
150
114
|
|
|
151
115
|
## Development
|
|
152
116
|
|
|
@@ -523,10 +523,6 @@ def main(argv=None):
|
|
|
523
523
|
epilog=(
|
|
524
524
|
"commands:\n"
|
|
525
525
|
" tony <path> [BASE...HEAD] review a diff — the default\n"
|
|
526
|
-
" tony login sign in to the tony site\n"
|
|
527
|
-
" tony logout revoke this machine's token\n"
|
|
528
|
-
" tony whoami who this machine is signed in as\n"
|
|
529
|
-
" tony unpublish <id> take one published review down\n"
|
|
530
526
|
" tony update update to the latest release\n"
|
|
531
527
|
" tony uninstall delete tony, its key, and every saved review\n"
|
|
532
528
|
" tony --version what is installed\n"
|
|
@@ -566,10 +562,17 @@ def main(argv=None):
|
|
|
566
562
|
"--no-open", action="store_false", dest="openPage",
|
|
567
563
|
help="Write the page but do not open it in a browser.",
|
|
568
564
|
)
|
|
565
|
+
# Reviews stay on this machine unless asked otherwise. Publishing used to be
|
|
566
|
+
# the default, which put a GitHub account in front of a first run: `tony`
|
|
567
|
+
# with no account printed an error and never reviewed anything. Sharing is a
|
|
568
|
+
# separate act, and it is opt-in until it can be relied on end to end.
|
|
569
|
+
parser.add_argument(
|
|
570
|
+
"--publish", action="store_true",
|
|
571
|
+
help=argparse.SUPPRESS,
|
|
572
|
+
)
|
|
569
573
|
parser.add_argument(
|
|
570
574
|
"--local", action="store_true",
|
|
571
|
-
help=
|
|
572
|
-
"and opens the self-contained page in .tony/ instead of a link.",
|
|
575
|
+
help=argparse.SUPPRESS, # now the default; accepted so it never breaks
|
|
573
576
|
)
|
|
574
577
|
parser.add_argument(
|
|
575
578
|
"--payload", nargs="?", const=True, default=False, metavar="PATH",
|
|
@@ -636,17 +639,14 @@ def main(argv=None):
|
|
|
636
639
|
print(f"tony: {problem}", file=sys.stderr)
|
|
637
640
|
return 2
|
|
638
641
|
|
|
639
|
-
#
|
|
640
|
-
#
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
offline = args.local or args.asJson
|
|
644
|
-
if not offline and not hosted.savedToken():
|
|
642
|
+
# Checked before the review runs — discovering it afterwards would waste an
|
|
643
|
+
# API call the user already paid for.
|
|
644
|
+
publishing = args.publish and not args.asJson
|
|
645
|
+
if publishing and not hosted.savedToken():
|
|
645
646
|
print(
|
|
646
|
-
"tony:
|
|
647
|
+
"tony: publishing needs an account.\n\n"
|
|
647
648
|
" tony login # once, with GitHub\n\n"
|
|
648
|
-
" Or keep this
|
|
649
|
-
f" tony {args.path} {args.range or ''} --local".rstrip() + "\n",
|
|
649
|
+
" Or drop --publish to keep this review on your machine.\n",
|
|
650
650
|
file=sys.stderr,
|
|
651
651
|
)
|
|
652
652
|
return 2
|
|
@@ -745,7 +745,7 @@ def main(argv=None):
|
|
|
745
745
|
# is the fallback when publishing fails so a paid-for review is never lost.
|
|
746
746
|
target = f"file://{path}"
|
|
747
747
|
|
|
748
|
-
if
|
|
748
|
+
if publishing:
|
|
749
749
|
url, problem = hosted.publish(
|
|
750
750
|
payloadJson, repo=os.path.basename(root), rangeLabel=rangeLabel,
|
|
751
751
|
)
|
|
@@ -755,8 +755,7 @@ def main(argv=None):
|
|
|
755
755
|
else:
|
|
756
756
|
print(url)
|
|
757
757
|
target = url
|
|
758
|
-
|
|
759
|
-
if args.local:
|
|
758
|
+
else:
|
|
760
759
|
print(f"tony: {path}")
|
|
761
760
|
if args.openPage:
|
|
762
761
|
webbrowser.open(target)
|
|
@@ -7,6 +7,7 @@ the root of the environment tony is actually running from.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
import os
|
|
10
|
+
import re
|
|
10
11
|
import subprocess
|
|
11
12
|
import sys
|
|
12
13
|
|
|
@@ -18,7 +19,13 @@ PKG = "tony-cli"
|
|
|
18
19
|
# an ambient index setting, so on a machine pointed at an internal mirror an
|
|
19
20
|
# update would pull whatever that mirror serves under the name `tony-cli`.
|
|
20
21
|
INDEX = "https://pypi.org/simple"
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
# The project's page on that same index, asked for as JSON (PEP 691). Not
|
|
24
|
+
# pypi.org/pypi/<name>/json — that one is CDN-cached and runs minutes behind a
|
|
25
|
+
# release, so it will call a version "latest" that an installer has already
|
|
26
|
+
# moved past, and report "already on the latest version" to someone who is not.
|
|
27
|
+
PROJECT = f"{INDEX}/{PKG}/"
|
|
28
|
+
SIMPLE_JSON = "application/vnd.pypi.simple.v1+json"
|
|
22
29
|
|
|
23
30
|
|
|
24
31
|
def indexEnv():
|
|
@@ -101,21 +108,39 @@ def installedOnDisk():
|
|
|
101
108
|
return name[len("tony_cli-"):-len(".dist-info")] or None
|
|
102
109
|
|
|
103
110
|
|
|
111
|
+
def _release(version):
|
|
112
|
+
"""A sortable key for a plain release, or None for anything else.
|
|
113
|
+
|
|
114
|
+
Pre-releases and dev builds sort unpredictably as digit tuples — "1.0.0rc1"
|
|
115
|
+
would read as (1, 0, 0, 1) and outrank 1.0.0 — and `tony update` should not
|
|
116
|
+
move anyone onto one.
|
|
117
|
+
"""
|
|
118
|
+
if not re.fullmatch(r"\d+(?:\.\d+)*", version or ""):
|
|
119
|
+
return None
|
|
120
|
+
return tuple(int(n) for n in version.split("."))
|
|
121
|
+
|
|
122
|
+
|
|
104
123
|
def latestVersion(timeout=10):
|
|
105
|
-
"""The newest
|
|
124
|
+
"""The newest release the index offers, or None if it cannot be asked.
|
|
106
125
|
|
|
107
126
|
Worth one request: without it there is nothing to check the upgrade
|
|
108
127
|
against, and every installer exits 0 for "already at latest" — which is
|
|
109
128
|
indistinguishable from "upgraded" unless you knew the target beforehand.
|
|
110
129
|
"""
|
|
111
130
|
try:
|
|
112
|
-
response = httpx.get(
|
|
131
|
+
response = httpx.get(
|
|
132
|
+
PROJECT, timeout=timeout, headers={"Accept": SIMPLE_JSON},
|
|
133
|
+
follow_redirects=True,
|
|
134
|
+
)
|
|
113
135
|
if response.status_code != 200:
|
|
114
136
|
return None
|
|
115
|
-
|
|
137
|
+
versions = (response.json() or {}).get("versions") or []
|
|
116
138
|
except Exception:
|
|
117
139
|
return None
|
|
118
140
|
|
|
141
|
+
ranked = [(key, v) for v in versions if (key := _release(v))]
|
|
142
|
+
return max(ranked)[1] if ranked else None
|
|
143
|
+
|
|
119
144
|
|
|
120
145
|
def update(argv=()):
|
|
121
146
|
"""`tony update`. Returns an exit code, prints its own messages."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tony-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -95,9 +95,11 @@ tony main...my-branch # review a branch against main
|
|
|
95
95
|
tony # review the default branch...HEAD
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
The page is written to `.tony/` inside the repo
|
|
99
|
-
opens in your browser
|
|
100
|
-
data inlined
|
|
98
|
+
Reviews stay on your machine. The page is written to `.tony/` inside the repo
|
|
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.
|
|
101
103
|
|
|
102
104
|
tony needs an Anthropic API key (`ANTHROPIC_API_KEY`, or `~/.tony/.env`). The
|
|
103
105
|
first run tells you exactly where to get one and where to put it. tony reviews
|
|
@@ -126,8 +128,7 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
126
128
|
|
|
127
129
|
| Flag | What it does |
|
|
128
130
|
|---|---|
|
|
129
|
-
| `--
|
|
130
|
-
| `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
|
|
131
|
+
| `--json` | Print the raw review JSON to stdout and exit. Writes no page instead. |
|
|
131
132
|
| `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
|
|
132
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. |
|
|
133
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,17 +136,6 @@ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
|
|
|
135
136
|
| `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
|
|
136
137
|
| `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
|
|
137
138
|
|
|
138
|
-
### Sharing
|
|
139
|
-
|
|
140
|
-
| Command | What it does |
|
|
141
|
-
|---|---|
|
|
142
|
-
| `tony login` | Sign in to tony-cli.com with GitHub's device flow. Once per machine. |
|
|
143
|
-
| `tony logout` | Revoke this machine's token server-side, then delete it locally. |
|
|
144
|
-
| `tony whoami` | Which GitHub account this machine is signed in as. |
|
|
145
|
-
| `tony unpublish <id>` | Take one published review down. The id is the last part of its URL. |
|
|
146
|
-
|
|
147
|
-
Publishing is the default when you're signed in. `--local` opts out per run.
|
|
148
|
-
|
|
149
139
|
### Managing tony
|
|
150
140
|
|
|
151
141
|
| Command | What it does |
|
|
@@ -161,29 +151,6 @@ limit it to the current repo instead of searching your home directory.
|
|
|
161
151
|
Both `tony update` and the installer resolve from PyPI explicitly, so a machine
|
|
162
152
|
pointed at an internal mirror can't decide what `tony-cli` is.
|
|
163
153
|
|
|
164
|
-
## Share a review
|
|
165
|
-
|
|
166
|
-
```sh
|
|
167
|
-
tony login # once — GitHub device flow
|
|
168
|
-
tony main...my-branch # publishing is the default
|
|
169
|
-
tony: https://tony-cli.com/r/8f3ka92m
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Who can read a published review:** anyone signed in who has the link. Review
|
|
173
|
-
ids are random, so the link is what grants access — treat it like a password.
|
|
174
|
-
`tony unpublish <id>` removes a review at any time.
|
|
175
|
-
|
|
176
|
-
**What the site can read:** everything in the review. The payload is uploaded
|
|
177
|
-
over TLS and encrypted at rest under a key the server holds, so a leak of the
|
|
178
|
-
stored blobs yields nothing — but we can open a review, and so can any lawful
|
|
179
|
-
demand made to us. Do not publish from a repository you could not share with
|
|
180
|
-
us. An earlier design encrypted on your machine and kept the key in the link's
|
|
181
|
-
fragment; that was dropped deliberately when reading moved behind an account
|
|
182
|
-
and a history of past reviews became part of the product, since both need the
|
|
183
|
-
server to be able to open a review.
|
|
184
|
-
|
|
185
|
-
Local review needs no account and never leaves the machine: `tony --local`.
|
|
186
|
-
|
|
187
154
|
## Uninstall
|
|
188
155
|
|
|
189
156
|
```sh
|
|
@@ -191,16 +158,13 @@ tony uninstall
|
|
|
191
158
|
```
|
|
192
159
|
|
|
193
160
|
Removing the package by itself would leave the parts worth removing: your
|
|
194
|
-
`ANTHROPIC_API_KEY`
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
uv, pipx, or pip installed it.
|
|
161
|
+
`ANTHROPIC_API_KEY` in `~/.tony`, and a `.tony/` directory of past reviews
|
|
162
|
+
inside every repository you ran tony in — those hold source code. `tony
|
|
163
|
+
uninstall` lists everything it found, waits for you to type `yes`, deletes it,
|
|
164
|
+
then removes the package with whichever of uv, pipx, or pip installed it.
|
|
199
165
|
|
|
200
166
|
It searches your home directory for stray review directories; `--no-scan`
|
|
201
|
-
limits it to the current repository, and `--yes` skips the prompt.
|
|
202
|
-
published to the site are separate — take those down with `tony unpublish <id>`
|
|
203
|
-
before uninstalling, or they stay up.
|
|
167
|
+
limits it to the current repository, and `--yes` skips the prompt.
|
|
204
168
|
|
|
205
169
|
## Development
|
|
206
170
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|