tony-cli 0.3.0__tar.gz → 0.3.2__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 (29) hide show
  1. {tony_cli-0.3.0/src/tony_cli.egg-info → tony_cli-0.3.2}/PKG-INFO +64 -15
  2. {tony_cli-0.3.0 → tony_cli-0.3.2}/README.md +63 -14
  3. {tony_cli-0.3.0 → tony_cli-0.3.2}/pyproject.toml +1 -1
  4. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/install.py +51 -8
  5. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/uninstall.py +19 -9
  6. {tony_cli-0.3.0 → tony_cli-0.3.2/src/tony_cli.egg-info}/PKG-INFO +64 -15
  7. {tony_cli-0.3.0 → tony_cli-0.3.2}/LICENSE +0 -0
  8. {tony_cli-0.3.0 → tony_cli-0.3.2}/setup.cfg +0 -0
  9. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/__init__.py +0 -0
  10. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/agent.py +0 -0
  11. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/fonts/Favorit-Bold.woff2 +0 -0
  12. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/fonts/Favorit-Book.woff2 +0 -0
  13. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/fonts/Favorit-Regular.woff2 +0 -0
  14. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/fonts/FavoritMono-Medium.woff2 +0 -0
  15. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/fonts/FavoritMono-Regular.woff2 +0 -0
  16. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/viewer.css +0 -0
  17. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/assets/viewer.js +0 -0
  18. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/fonts.py +0 -0
  19. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/hosted.py +0 -0
  20. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/layout.py +0 -0
  21. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/page.py +0 -0
  22. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/payload.py +0 -0
  23. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/source/__init__.py +0 -0
  24. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli/source/local.py +0 -0
  25. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli.egg-info/SOURCES.txt +0 -0
  26. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli.egg-info/dependency_links.txt +0 -0
  27. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli.egg-info/entry_points.txt +0 -0
  28. {tony_cli-0.3.0 → tony_cli-0.3.2}/src/tony_cli.egg-info/requires.txt +0 -0
  29. {tony_cli-0.3.0 → tony_cli-0.3.2}/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.0
3
+ Version: 0.3.2
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
@@ -104,9 +104,62 @@ first run tells you exactly where to get one and where to put it. tony reviews
104
104
  **committed** work: it shows code straight from disk, so the working tree must
105
105
  match the revision under review.
106
106
 
107
- Useful flags: `--replay` rebuilds the page from the last run without calling
108
- the API, `--json` prints the raw review, `-v` logs every file the model
109
- actually read, `--stale` overrides the clean-tree check.
107
+ Every command and flag is listed under [Commands](#commands).
108
+
109
+ ## Commands
110
+
111
+ `tony --help` prints this list. Everything below works from anywhere inside a
112
+ git repo unless noted.
113
+
114
+ ### Reviewing
115
+
116
+ ```sh
117
+ tony # default branch...HEAD, in the current repo
118
+ tony main...my-branch # an explicit range
119
+ tony my-branch # shorthand for my-branch...HEAD
120
+ tony ../other-repo main...x # any path inside another repo
121
+ ```
122
+
123
+ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
124
+ `origin/HEAD` — what the remote calls its default branch — falling back to
125
+ `main`, then `master`.
126
+
127
+ | Flag | What it does |
128
+ |---|---|
129
+ | `--local` | Keep the review on this machine. No account needed, nothing uploaded; you get the self-contained page in `.tony/` instead of a link. |
130
+ | `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
131
+ | `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
132
+ | `--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
+ | `--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. |
134
+ | `-v`, `--verbose` | Log every tool call to stderr, so you can see which files the review actually read before it drew conclusions. |
135
+ | `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
136
+ | `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
137
+
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
+ ### Managing tony
150
+
151
+ | Command | What it does |
152
+ |---|---|
153
+ | `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. |
154
+ | `tony uninstall` | Delete tony and everything it wrote — see [Uninstall](#uninstall). |
155
+ | `tony --version` | The installed version. |
156
+ | `tony --help` | Every command and flag. |
157
+
158
+ `tony uninstall` takes `--yes` (`-y`) to skip the confirmation and `--no-scan` to
159
+ limit it to the current repo instead of searching your home directory.
160
+
161
+ Both `tony update` and the installer resolve from PyPI explicitly, so a machine
162
+ pointed at an internal mirror can't decide what `tony-cli` is.
110
163
 
111
164
  ## Share a review
112
165
 
@@ -131,17 +184,6 @@ server to be able to open a review.
131
184
 
132
185
  Local review needs no account and never leaves the machine: `tony --local`.
133
186
 
134
- ## Update
135
-
136
- ```sh
137
- tony update
138
- ```
139
-
140
- Uses whichever of uv, pipx, or pip installed tony, and resolves from PyPI
141
- explicitly so a machine pointed at an internal mirror cannot decide what
142
- `tony-cli` is. `tony --version` says what you have; `tony --help` lists every
143
- command.
144
-
145
187
  ## Uninstall
146
188
 
147
189
  ```sh
@@ -170,6 +212,13 @@ npm run build:viewer # rebuild the renderer bundle the CLI embeds
170
212
  npm run dev # the site; /dev renders src/fixtures/review.json
171
213
  ```
172
214
 
215
+ Two flags exist only for this loop, and only work from a source checkout:
216
+
217
+ | Flag | What it does |
218
+ |---|---|
219
+ | `--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. |
220
+ | `--payload [PATH]` | Write the upload payload — windowed source, no absolute paths — next to the page, or to `PATH`. |
221
+
173
222
  There is exactly one renderer — `web/src/renderer/render.ts` — used by both
174
223
  the local page and the hosted site. The Python side decides all layout facts
175
224
  (line numbers, spans, added/changed tags) in `src/tony_cli/layout.py` and ships
@@ -50,9 +50,62 @@ first run tells you exactly where to get one and where to put it. tony reviews
50
50
  **committed** work: it shows code straight from disk, so the working tree must
51
51
  match the revision under review.
52
52
 
53
- Useful flags: `--replay` rebuilds the page from the last run without calling
54
- the API, `--json` prints the raw review, `-v` logs every file the model
55
- actually read, `--stale` overrides the clean-tree check.
53
+ Every command and flag is listed under [Commands](#commands).
54
+
55
+ ## Commands
56
+
57
+ `tony --help` prints this list. Everything below works from anywhere inside a
58
+ git repo unless noted.
59
+
60
+ ### Reviewing
61
+
62
+ ```sh
63
+ tony # default branch...HEAD, in the current repo
64
+ tony main...my-branch # an explicit range
65
+ tony my-branch # shorthand for my-branch...HEAD
66
+ tony ../other-repo main...x # any path inside another repo
67
+ ```
68
+
69
+ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
70
+ `origin/HEAD` — what the remote calls its default branch — falling back to
71
+ `main`, then `master`.
72
+
73
+ | Flag | What it does |
74
+ |---|---|
75
+ | `--local` | Keep the review on this machine. No account needed, nothing uploaded; you get the self-contained page in `.tony/` instead of a link. |
76
+ | `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
77
+ | `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
78
+ | `--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
+ | `--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. |
80
+ | `-v`, `--verbose` | Log every tool call to stderr, so you can see which files the review actually read before it drew conclusions. |
81
+ | `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
82
+ | `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
83
+
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
+ ### Managing tony
96
+
97
+ | Command | What it does |
98
+ |---|---|
99
+ | `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. |
100
+ | `tony uninstall` | Delete tony and everything it wrote — see [Uninstall](#uninstall). |
101
+ | `tony --version` | The installed version. |
102
+ | `tony --help` | Every command and flag. |
103
+
104
+ `tony uninstall` takes `--yes` (`-y`) to skip the confirmation and `--no-scan` to
105
+ limit it to the current repo instead of searching your home directory.
106
+
107
+ Both `tony update` and the installer resolve from PyPI explicitly, so a machine
108
+ pointed at an internal mirror can't decide what `tony-cli` is.
56
109
 
57
110
  ## Share a review
58
111
 
@@ -77,17 +130,6 @@ server to be able to open a review.
77
130
 
78
131
  Local review needs no account and never leaves the machine: `tony --local`.
79
132
 
80
- ## Update
81
-
82
- ```sh
83
- tony update
84
- ```
85
-
86
- Uses whichever of uv, pipx, or pip installed tony, and resolves from PyPI
87
- explicitly so a machine pointed at an internal mirror cannot decide what
88
- `tony-cli` is. `tony --version` says what you have; `tony --help` lists every
89
- command.
90
-
91
133
  ## Uninstall
92
134
 
93
135
  ```sh
@@ -116,6 +158,13 @@ npm run build:viewer # rebuild the renderer bundle the CLI embeds
116
158
  npm run dev # the site; /dev renders src/fixtures/review.json
117
159
  ```
118
160
 
161
+ Two flags exist only for this loop, and only work from a source checkout:
162
+
163
+ | Flag | What it does |
164
+ |---|---|
165
+ | `--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. |
166
+ | `--payload [PATH]` | Write the upload payload — windowed source, no absolute paths — next to the page, or to `PATH`. |
167
+
119
168
  There is exactly one renderer — `web/src/renderer/render.ts` — used by both
120
169
  the local page and the hosted site. The Python side decides all layout facts
121
170
  (line numbers, spans, added/changed tags) in `src/tony_cli/layout.py` and ships
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tony-cli"
3
- version = "0.3.0"
3
+ version = "0.3.2"
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" }
@@ -57,11 +57,18 @@ def uninstallCommand(kind):
57
57
 
58
58
 
59
59
  def updateCommand(kind):
60
+ """The upgrade, told to ignore its own cache.
61
+
62
+ Every one of these caches the index, and a cache that is minutes stale
63
+ resolves to the version before the one just released — then reports
64
+ "already at latest" and exits 0. An update that runs once a month should
65
+ pay for a fresh lookup rather than confidently do nothing.
66
+ """
60
67
  if kind == "uv":
61
- return ["uv", "tool", "upgrade", PKG]
68
+ return ["uv", "tool", "upgrade", "--refresh", PKG]
62
69
  if kind == "pipx":
63
- return ["pipx", "upgrade", PKG]
64
- return [sys.executable, "-m", "pip", "install", "--upgrade", PKG]
70
+ return ["pipx", "upgrade", PKG, "--pip-args=--no-cache-dir"]
71
+ return [sys.executable, "-m", "pip", "install", "--upgrade", "--no-cache-dir", PKG]
65
72
 
66
73
 
67
74
  def installedVersion():
@@ -73,6 +80,27 @@ def installedVersion():
73
80
  return None
74
81
 
75
82
 
83
+ def installedOnDisk():
84
+ """The version the environment's metadata records, re-read from disk.
85
+
86
+ `installedVersion` answers from what this interpreter imported at startup,
87
+ which is precisely the version an upgrade just replaced. The dist-info
88
+ directory on disk is the only thing in this process that knows what is
89
+ actually installed now.
90
+ """
91
+ import glob
92
+ import sysconfig
93
+
94
+ purelib = sysconfig.get_paths().get("purelib")
95
+ if not purelib:
96
+ return None
97
+ found = glob.glob(os.path.join(purelib, "tony_cli-*.dist-info"))
98
+ if not found:
99
+ return None
100
+ name = os.path.basename(sorted(found)[-1])
101
+ return name[len("tony_cli-"):-len(".dist-info")] or None
102
+
103
+
76
104
  def latestVersion(timeout=10):
77
105
  """The newest version PyPI serves, or None if it cannot be asked.
78
106
 
@@ -128,11 +156,26 @@ def update(argv=()):
128
156
  print(f"tony: {kind} could not update tony.", file=sys.stderr)
129
157
  return result.returncode
130
158
 
131
- # This interpreter still has the old version loaded, so it cannot read the
132
- # new one back. PyPI's answer is the honest thing to report; without it,
133
- # say what happened rather than asserting an outcome.
134
- if latest:
135
- print(f"\ntony: updated {before or '?'} -> {latest}.")
159
+ # What PyPI calls newest is not what just landed on this machine. An
160
+ # installer resolving against a stale index cache prints "already at latest"
161
+ # for a version that is not the latest, and exits 0 — reporting the upgrade
162
+ # from PyPI's answer turns that into a confident lie.
163
+ after = installedOnDisk()
164
+
165
+ if after and before and after == before:
166
+ print(
167
+ f"\ntony: still {after} — {kind} did not install a newer version, "
168
+ f"though PyPI offers {latest or 'a newer one'}.\n"
169
+ f" Try again in a minute; a release takes a moment to reach "
170
+ f"every mirror.\n",
171
+ file=sys.stderr,
172
+ )
173
+ return 1
174
+
175
+ if after and before:
176
+ print(f"\ntony: updated {before} -> {after}.")
177
+ elif after:
178
+ print(f"\ntony: now on {after}.")
136
179
  else:
137
180
  print("\ntony: the installer finished. Check it with `tony --version`.")
138
181
  return 0
@@ -115,6 +115,24 @@ def uninstall(argv):
115
115
  print("usage: tony uninstall [--yes] [--no-scan]", file=sys.stderr)
116
116
  return 2
117
117
 
118
+ # A source checkout cannot be uninstalled — deleting someone's working tree
119
+ # is not on the table — so this command cannot keep its promise here. Doing
120
+ # the half it can do anyway is the worst outcome available: the API key and
121
+ # every saved review are gone, the tool is still installed and still on
122
+ # PATH, and `tony --version` reports the same number as before. Refuse
123
+ # instead, and say exactly what to run.
124
+ if isSourceCheckout():
125
+ print(
126
+ f"tony: this is a source checkout at {sys.prefix} — an editable\n"
127
+ f" install, not something to uninstall. Nothing was deleted.\n\n"
128
+ f" To remove it, from the checkout:\n\n"
129
+ f" pip uninstall tony-cli\n\n"
130
+ f" To clear the key and saved reviews without touching the code:\n\n"
131
+ f" rm -rf {configDir()}\n",
132
+ file=sys.stderr,
133
+ )
134
+ return 2
135
+
118
136
  config = configDir()
119
137
  hasConfig = os.path.isdir(config)
120
138
  if scan:
@@ -123,7 +141,6 @@ def uninstall(argv):
123
141
 
124
142
  kind = installer()
125
143
  command = uninstallCommand(kind)
126
- source = isSourceCheckout()
127
144
 
128
145
  print("\nThis will delete:\n")
129
146
  if hasConfig:
@@ -134,10 +151,7 @@ def uninstall(argv):
134
151
  if not hasConfig and not reports:
135
152
  print(" (nothing — tony has written nothing to this machine)")
136
153
  print()
137
- if source:
138
- print(f"Then: nothing. This is a source checkout at {sys.prefix};")
139
- print(" removing the package would delete your working tree, so it stays.")
140
- elif os.name == "nt":
154
+ if os.name == "nt":
141
155
  print(f"Then: {' '.join(command)}")
142
156
  print(" Windows cannot delete a running program, so run that yourself after.")
143
157
  else:
@@ -177,10 +191,6 @@ def uninstall(argv):
177
191
  file=sys.stderr)
178
192
  return 1
179
193
 
180
- if source:
181
- print("tony: local data removed. The checkout itself is yours to delete.")
182
- return 0
183
-
184
194
  if os.name == "nt":
185
195
  print("tony: local data removed. Finish with:")
186
196
  print(f" {' '.join(command)}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tony-cli
3
- Version: 0.3.0
3
+ Version: 0.3.2
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
@@ -104,9 +104,62 @@ first run tells you exactly where to get one and where to put it. tony reviews
104
104
  **committed** work: it shows code straight from disk, so the working tree must
105
105
  match the revision under review.
106
106
 
107
- Useful flags: `--replay` rebuilds the page from the last run without calling
108
- the API, `--json` prints the raw review, `-v` logs every file the model
109
- actually read, `--stale` overrides the clean-tree check.
107
+ Every command and flag is listed under [Commands](#commands).
108
+
109
+ ## Commands
110
+
111
+ `tony --help` prints this list. Everything below works from anywhere inside a
112
+ git repo unless noted.
113
+
114
+ ### Reviewing
115
+
116
+ ```sh
117
+ tony # default branch...HEAD, in the current repo
118
+ tony main...my-branch # an explicit range
119
+ tony my-branch # shorthand for my-branch...HEAD
120
+ tony ../other-repo main...x # any path inside another repo
121
+ ```
122
+
123
+ The range is git's own `BASE...HEAD` syntax. With no range, tony diffs against
124
+ `origin/HEAD` — what the remote calls its default branch — falling back to
125
+ `main`, then `master`.
126
+
127
+ | Flag | What it does |
128
+ |---|---|
129
+ | `--local` | Keep the review on this machine. No account needed, nothing uploaded; you get the self-contained page in `.tony/` instead of a link. |
130
+ | `--json` | Print the raw review JSON to stdout and exit. Writes no page, uploads nothing, needs no account. |
131
+ | `--no-open` | Write the page but don't open a browser. For CI, or over SSH. |
132
+ | `--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
+ | `--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. |
134
+ | `-v`, `--verbose` | Log every tool call to stderr, so you can see which files the review actually read before it drew conclusions. |
135
+ | `-m`, `--model` | Model to review with. Defaults to `claude-opus-5`. |
136
+ | `--max-tokens` | Response ceiling, default `64000`. Raise it if a review comes back cut off. |
137
+
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
+ ### Managing tony
150
+
151
+ | Command | What it does |
152
+ |---|---|
153
+ | `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. |
154
+ | `tony uninstall` | Delete tony and everything it wrote — see [Uninstall](#uninstall). |
155
+ | `tony --version` | The installed version. |
156
+ | `tony --help` | Every command and flag. |
157
+
158
+ `tony uninstall` takes `--yes` (`-y`) to skip the confirmation and `--no-scan` to
159
+ limit it to the current repo instead of searching your home directory.
160
+
161
+ Both `tony update` and the installer resolve from PyPI explicitly, so a machine
162
+ pointed at an internal mirror can't decide what `tony-cli` is.
110
163
 
111
164
  ## Share a review
112
165
 
@@ -131,17 +184,6 @@ server to be able to open a review.
131
184
 
132
185
  Local review needs no account and never leaves the machine: `tony --local`.
133
186
 
134
- ## Update
135
-
136
- ```sh
137
- tony update
138
- ```
139
-
140
- Uses whichever of uv, pipx, or pip installed tony, and resolves from PyPI
141
- explicitly so a machine pointed at an internal mirror cannot decide what
142
- `tony-cli` is. `tony --version` says what you have; `tony --help` lists every
143
- command.
144
-
145
187
  ## Uninstall
146
188
 
147
189
  ```sh
@@ -170,6 +212,13 @@ npm run build:viewer # rebuild the renderer bundle the CLI embeds
170
212
  npm run dev # the site; /dev renders src/fixtures/review.json
171
213
  ```
172
214
 
215
+ Two flags exist only for this loop, and only work from a source checkout:
216
+
217
+ | Flag | What it does |
218
+ |---|---|
219
+ | `--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. |
220
+ | `--payload [PATH]` | Write the upload payload — windowed source, no absolute paths — next to the page, or to `PATH`. |
221
+
173
222
  There is exactly one renderer — `web/src/renderer/render.ts` — used by both
174
223
  the local page and the hosted site. The Python side decides all layout facts
175
224
  (line numbers, spans, added/changed tags) in `src/tony_cli/layout.py` and ships
File without changes
File without changes
File without changes
File without changes
File without changes