cli-error 0.1.1__tar.gz → 0.1.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 (69) hide show
  1. {cli_error-0.1.1 → cli_error-0.1.2}/.github/workflows/ci.yml +2 -2
  2. {cli_error-0.1.1 → cli_error-0.1.2}/.github/workflows/release.yml +2 -2
  3. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/README.md +2 -0
  4. cli_error-0.1.2/.tasker/s01-extract-repo-skills-error-reporting/s01t21-reconsider-debug-output-layout-evaluate.md +33 -0
  5. cli_error-0.1.2/.tasker/s01-extract-repo-skills-error-reporting/s01t22-unify-debug-helper-label-idiom.md +61 -0
  6. {cli_error-0.1.1 → cli_error-0.1.2}/PKG-INFO +1 -1
  7. {cli_error-0.1.1 → cli_error-0.1.2}/README.md +3 -0
  8. {cli_error-0.1.1 → cli_error-0.1.2}/pyproject.toml +1 -1
  9. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/_reporter.py +10 -23
  10. {cli_error-0.1.1 → cli_error-0.1.2}/tests/test_reporter.py +33 -11
  11. {cli_error-0.1.1 → cli_error-0.1.2}/uv.lock +59 -58
  12. {cli_error-0.1.1 → cli_error-0.1.2}/.flake8 +0 -0
  13. {cli_error-0.1.1 → cli_error-0.1.2}/.gitignore +0 -0
  14. {cli_error-0.1.1 → cli_error-0.1.2}/.mcp.json +0 -0
  15. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/.env.example +0 -0
  16. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/README.md +0 -0
  17. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/base/Dockerfile +0 -0
  18. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/base/tmux.conf +0 -0
  19. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/base/zshrc +0 -0
  20. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/docker-compose.yml +0 -0
  21. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/run.sh +0 -0
  22. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/scripts/_lib.sh +0 -0
  23. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/scripts/attach.sh +0 -0
  24. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/scripts/build.sh +0 -0
  25. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/scripts/claude.sh +0 -0
  26. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/scripts/shell.sh +0 -0
  27. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/variants/python/Dockerfile +0 -0
  28. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/variants/python/compose.override.yml +0 -0
  29. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/worktree_run.sh +0 -0
  30. {cli_error-0.1.1 → cli_error-0.1.2}/.sandbox/worktree_shell.sh +0 -0
  31. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/.gitignore +0 -0
  32. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/archive/.gitkeep +0 -0
  33. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t01-rename-package-structure-clierror-cliexit.md +0 -0
  34. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t02-fluent-builder-for-clierror-context.md +0 -0
  35. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t03-render-formatted-error.md +0 -0
  36. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t04-error-handler-errorreporter-context-manager.md +0 -0
  37. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t05-cause-chain-rendering.md +0 -0
  38. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t06-debug-traceback.md +0 -0
  39. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t07-console-creation-with-style-overrides.md +0 -0
  40. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t08-library-documentation-readme.md +0 -0
  41. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t09-deployment-setup-ci-release-workflows.md +0 -0
  42. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t10-unify-markup-construction-template-args.md +0 -0
  43. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t11-refine-detail-single-last-wins.md +0 -0
  44. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t12-revisit-props-markup-first-prop.md +0 -0
  45. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t13-store-detail-as-ready-to.md +0 -0
  46. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t14-handle-empty-message-cause-in.md +0 -0
  47. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t15-reconsider-derive-debug-stderr-console.md +0 -0
  48. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t16-optionally-show-locals-in-debug.md +0 -0
  49. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t17-test-debug-traceback-includes-the.md +0 -0
  50. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t18-add-debug-gated-diagnostic-helpers.md +0 -0
  51. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t19-consolidate-shared-test-helpers-across.md +0 -0
  52. {cli_error-0.1.1 → cli_error-0.1.2}/.tasker/s01-extract-repo-skills-error-reporting/s01t20-add-a-safe-post-construction.md +0 -0
  53. {cli_error-0.1.1 → cli_error-0.1.2}/CLAUDE.md +0 -0
  54. {cli_error-0.1.1 → cli_error-0.1.2}/CONTEXT.md +0 -0
  55. {cli_error-0.1.1 → cli_error-0.1.2}/docs/adr/0001-error-formatting-and-theming.md +0 -0
  56. {cli_error-0.1.1 → cli_error-0.1.2}/docs/adr/0002-cli-reporter-output-facade.md +0 -0
  57. {cli_error-0.1.1 → cli_error-0.1.2}/docs/agents/dev-loop.md +0 -0
  58. {cli_error-0.1.1 → cli_error-0.1.2}/docs/agents/task-tracker.md +0 -0
  59. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/__init__.py +0 -0
  60. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/_console.py +0 -0
  61. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/_errors.py +0 -0
  62. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/_render.py +0 -0
  63. {cli_error-0.1.1 → cli_error-0.1.2}/src/cli_error/py.typed +0 -0
  64. {cli_error-0.1.1 → cli_error-0.1.2}/tests/__init__.py +0 -0
  65. {cli_error-0.1.1 → cli_error-0.1.2}/tests/helpers.py +0 -0
  66. {cli_error-0.1.1 → cli_error-0.1.2}/tests/test_console.py +0 -0
  67. {cli_error-0.1.1 → cli_error-0.1.2}/tests/test_errors.py +0 -0
  68. {cli_error-0.1.1 → cli_error-0.1.2}/tests/test_render.py +0 -0
  69. {cli_error-0.1.1 → cli_error-0.1.2}/tox.ini +0 -0
@@ -20,10 +20,10 @@ jobs:
20
20
  python-version: ["3.12", "3.13", "3.14"]
21
21
 
22
22
  steps:
23
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v5
24
24
 
25
25
  - name: Set up uv
26
- uses: astral-sh/setup-uv@v5
26
+ uses: astral-sh/setup-uv@v6
27
27
  with:
28
28
  enable-cache: true
29
29
  cache-dependency-glob: uv.lock
@@ -13,10 +13,10 @@ jobs:
13
13
  id-token: write
14
14
  contents: read
15
15
  steps:
16
- - uses: actions/checkout@v4
16
+ - uses: actions/checkout@v5
17
17
 
18
18
  - name: Set up uv
19
- uses: astral-sh/setup-uv@v5
19
+ uses: astral-sh/setup-uv@v6
20
20
  with:
21
21
  enable-cache: true
22
22
  cache-dependency-glob: uv.lock
@@ -59,3 +59,5 @@ status: done
59
59
  - [x] [s01t18](s01t18-add-debug-gated-diagnostic-helpers.md): Rename ErrorReporter to CliReporter and grow it into the CLI output façade
60
60
  - [x] [s01t19](s01t19-consolidate-shared-test-helpers-across.md): Consolidate shared test helpers into tests/_helpers.py
61
61
  - [x] [s01t20](s01t20-add-a-safe-post-construction.md): Add a safe post-construction debug toggle to CliReporter
62
+ - [x] [s01t21](s01t21-reconsider-debug-output-layout-evaluate.md): Reconsider debug_output layout — rule/divider delimiters
63
+ - [x] [s01t22](s01t22-unify-debug-helper-label-idiom.md): Unify debug-helper label idiom (debug_cmd vs debug_output)
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: s01t21
3
+ slug: reconsider-debug-output-layout-evaluate
4
+ status: done
5
+ ---
6
+
7
+ # Reconsider debug_output layout — rule/divider delimiters
8
+
9
+ **Superseded by s01t22:** the `─── stdout ───` rule layout below is replaced by the uppercase `LABEL:` header idiom (`STDOUT:` / `STDERR:` header line followed by the captured block).
10
+
11
+ `src/cli_error/_reporter.py` · `debug_output()`:
12
+ > TODO: this layout is ugly, lets prepend each line 'stdout: ' prefix
13
+
14
+ The current layout emits a ` stdout:` / ` stderr:` header line followed by the captured text as one escaped `misc` block. The body sits flush at column 0, so it has no visual boundary and merges with surrounding debug output.
15
+
16
+ **Decision:** Adopt the **rule/divider** layout (variant B). Each non-empty stream is delimited by a labeled `misc`-styled rule above the captured block:
17
+
18
+ ```
19
+ ─── stdout ───
20
+ line1
21
+ line2
22
+ ─── stderr ───
23
+ err1
24
+ ```
25
+
26
+ This labels each stream once (no per-line prefix), so it does not reopen the objection s01t18 named when it **rejected** per-line prefixing: *"bloats multi-line logs"*.
27
+
28
+ **Requirements:**
29
+ - A stream's rule is emitted **only when that stream is non-empty** — the existing empty/whitespace-only skip (`rstrip` → `continue`) must still apply, so an empty `stderr` produces no `stderr` rule at all.
30
+ - Keep the captured text as one escaped `misc` block (internal newlines preserved, trailing whitespace `rstrip`ped) — same escaped-arg contract as today.
31
+ - The rule/label styling routes through the existing `misc` role like the rest of the debug helpers.
32
+
33
+ Remove the TODO in `debug_output` once implemented.
@@ -0,0 +1,61 @@
1
+ ---
2
+ id: s01t22
3
+ slug: unify-debug-helper-label-idiom
4
+ status: done
5
+ ---
6
+
7
+ # Unify debug-helper label idiom (debug_cmd vs debug_output)
8
+
9
+ ## Context
10
+
11
+ After s01t21 adopted a labeled rule/divider for `debug_output` (`─── stdout ───`), the two subprocess debug helpers in the reporter presented labels in two different visual idioms: `debug_output` used rule headings while `debug_cmd` used an indented `COMMAND:` / ` cwd:` header. A `--debug` dump commonly interleaves both helpers (a command followed by its captured output), so the two grammars sat side by side in one stderr stream. This task unifies them onto a single label grammar.
12
+
13
+ ## Decisions
14
+
15
+ - **Unify on one uppercase `LABEL:` grammar (variant c)** — abandon the rule/divider entirely; every field is introduced by an all-uppercase, flush-left `LABEL:`. Scalars put the value inline (`RUN: git commit -m 'a b'`, `CWD: /tmp/x`); blocks put a bare header then the value on following lines (`STDOUT:` then the block). One grammar for the whole debug stream; each helper reads fine alone or back-to-back. *Rejected: (a) unifying toward the rule idiom `─── command ───` — a rule above a single-line command is visual noise, and a lonely `─── cwd ───` for one path is heavy; (b) keeping the two idioms distinct — the scalar-vs-block distinction is real but not worth making the reader parse two label grammars in one stream.*
16
+
17
+ - **Label set: `RUN:` / `CWD:` / `STDOUT:` / `STDERR:`** — all-uppercase, column 0, no indentation (drops the old ` cwd:` two-space indent). `RUN` over `COMMAND` (shorter; reads as "the command we ran"). Every line stays wrapped in `[misc]…[/misc]`; the `LABEL:` chars live in the trusted template and values (`cmd`, `cwd`, `text`) pass as escaped args — escaped-arg contract (ADR 0001) unchanged.
18
+
19
+ - **`debug_cmd`: two independent prints** — `RUN: {cmd}` always (via `shlex.join`), then `CWD: {cwd}` only when `cwd is not None`. Two separate `debug_print` calls because `CWD` is conditional. The helpers stay two fully independent methods — `debug_cmd` alone emits just `RUN:`/`CWD:`, `debug_output` alone emits just the stream blocks, and together they compose; no merging.
20
+
21
+ - **`debug_output`: header + block as one `[misc]` unit** — emit each non-empty stream as a single markup string `"[misc]STDOUT:\n{text}[/misc]"` (label and block coupled as one styled unit) rather than two prints. Empty-stream skip preserved unchanged: a stream's header is emitted only when non-empty (`rstrip()` → `continue`); body keeps internal newlines, `rstrip`s trailing whitespace, one escaped `misc` block.
22
+
23
+ - **s01t21 superseded on layout** — this task lands the final unified idiom across both helpers and replaces s01t21's `─── stdout ───` rule; s01t21 (in-review) gets a one-line supersede note pointing here rather than being reopened. *Note: this does NOT reopen the s01t18 objection that rejected per-line `stdout: ` prefixing for bloating multi-line logs — the format is a single header per stream, not a per-line prefix.*
24
+
25
+ ## Edge cases
26
+
27
+ - `debug_cmd` with no `cwd` → only the `RUN:` line, no `CWD:` line.
28
+ - `debug_output` with one empty stream → only the non-empty stream's header+block; an empty/whitespace-only stream produces no header at all (existing `rstrip` → `continue`).
29
+ - Both streams empty/whitespace-only → nothing emitted.
30
+ - All helpers are silent no-ops when `debug` is unset.
31
+ - Markup in values (`[red]…[/red]`, brackets in a command arg) must render literally — escaped-arg contract holds for `cmd`, `cwd`, and `text`.
32
+ - `misc` styling must actually apply: with color forced on, the `[misc]` (=dim) ANSI escape must wrap `RUN:` and the `STDOUT:` header.
33
+ - Multi-line stdout with trailing blank lines → internal newlines preserved, trailing whitespace `rstrip`ped.
34
+
35
+ ## Key files
36
+
37
+ - `src/cli_error/_reporter.py` — `debug_cmd()` (`COMMAND:`/` cwd:` → `RUN:`/`CWD:`) and `debug_output()` (rule → `STDOUT:`/`STDERR:` header block); update `debug_output`'s docstring.
38
+ - `tests/test_reporter.py` — update assertions: `COMMAND:`→`RUN:`, `cwd:`→`CWD:`, `─── stdout ───`→`STDOUT:` (incl. the ordering assertions and the `misc`-style ANSI-escape tests).
39
+ - `.tasker/s01-extract-repo-skills-error-reporting/s01t21-reconsider-debug-output-layout-evaluate.md` — one-line supersede note.
40
+
41
+ ## Acceptance criteria
42
+
43
+ - `debug_cmd(["git","commit","-m","a b"], cwd=Path("/tmp/x"))` under debug emits `RUN: git commit -m 'a b'` and `CWD: /tmp/x`; no `COMMAND:` or lowercase `cwd:`.
44
+ - `debug_cmd(["ls"])` emits `RUN: ls` and no `CWD:` line.
45
+ - `debug_output("out1\nout2 \n", "err1")` emits a `STDOUT:` header before `out1\nout2` and a `STDERR:` header before `err1`; no `─── … ───` rule, no lowercase `stdout:`/`stderr:`.
46
+ - `debug_output("kept", " ")` emits `STDOUT:` + `kept` and no `STDERR:`.
47
+ - Markup-bearing values render literally (`[red]…[/red]` preserved) for both helpers.
48
+ - With color forced on, the dim `misc` ANSI escape wraps both `RUN:` and the `STDOUT:` header.
49
+ - All helpers stay silent when `debug` is unset.
50
+ - s01t21 file carries a supersede note pointing to s01t22.
51
+ - `uv run tox` green across all environments, including any pre-existing issues.
52
+
53
+ ## Open questions
54
+
55
+ - None outstanding — all grill questions resolved.
56
+
57
+ ## Out of scope
58
+
59
+ - No CONTEXT.md change — the "Debug diagnostic" glossary entry never pinned an idiom.
60
+ - No new ADR and no ADR 0002 edit — the idiom is cosmetic and trivially reversible (fails the "hard to reverse" bar), and ADR 0002 already describes these helpers as `misc`-styled escaped-arg wrappers without pinning a label style.
61
+ - Reworking `debug_output`'s empty-skip / escaping behavior — carried over unchanged from s01t21.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-error
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Error handling and reporting utilities for CLI applications.
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: rich
@@ -293,6 +293,9 @@ uv run tox
293
293
 
294
294
  ## Release Notes
295
295
 
296
+ ### v0.1.2
297
+ - Debug diagnostics now share a consistent uppercase `LABEL:` grammar — `debug_cmd` emits flush-left `RUN:`/`CWD:` lines, and `debug_output` couples a single `STDOUT:`/`STDERR:` header to its output block.
298
+
296
299
  ### v0.1.1
297
300
  - `debug_traceback` can now render per-frame locals — opt in with `CliReporter(show_locals=True)` or a per-call `debug_traceback(show_locals=True)` override (locals may expose secrets, so keep it developer-only).
298
301
  - The auto-built stderr console now inherits the injected console's `no_color` and theme intent, so debug output matches your main console's styling.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cli-error"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "Error handling and reporting utilities for CLI applications."
5
5
  requires-python = ">=3.12"
6
6
  dependencies = ["rich"]
@@ -72,39 +72,26 @@ class CliReporter:
72
72
  if not self.debug:
73
73
  return
74
74
 
75
- self.debug_print("[misc]COMMAND: {cmd}[/misc]", cmd=shlex.join(cmd))
75
+ self.debug_print("[misc]RUN: {cmd}[/misc]", cmd=shlex.join(cmd))
76
76
  if cwd is not None:
77
- self.debug_print("[misc] cwd: {cwd}[/misc]", cwd=cwd)
77
+ self.debug_print("[misc]CWD: {cwd}[/misc]", cwd=cwd)
78
78
 
79
79
  def debug_output(self, stdout: str, stderr: str) -> None:
80
- """Emit captured subprocess output as debug diagnostics.
81
-
82
- Each non-empty stream is emitted as a header line followed by the
83
- captured text as one escaped ``misc`` block; empty streams are skipped.
84
- """
80
+ """Emit captured subprocess output as debug diagnostics."""
85
81
  if not self.debug:
86
82
  return
87
83
 
88
- for label, text in (("stdout", stdout), ("stderr", stderr)):
89
- trimmed = text.rstrip()
90
- if not trimmed:
91
- continue
84
+ trimmed = stdout.rstrip()
85
+ if trimmed:
86
+ self.debug_print("[misc]STDOUT:\n{text}[/misc]", text=trimmed)
92
87
 
93
- # TODO: this layout is ugly, lets prepend each line 'stdout: ' prefix
94
- self.debug_print("[misc] {label}:[/misc]", label=label)
95
- self.debug_print("[misc]{text}[/misc]", text=trimmed)
88
+ trimmed = stderr.rstrip()
89
+ if trimmed:
90
+ self.debug_print("[misc]STDERR:\n{text}[/misc]", text=trimmed)
96
91
 
97
92
  @contextmanager
98
93
  def handler(self) -> Generator[None]:
99
- """Report errors and translate them into process exit codes.
100
-
101
- * ``CliExit`` prints its message and exits 0;
102
- * any other ``Exception`` is rendered via ``print_error`` and exits 1,
103
- additionally emitting a full traceback to the ``stderr`` console when
104
- ``debug`` is set.
105
- * ``KeyboardInterrupt``, ``SystemExit`` and any other ``BaseException``
106
- propagate untouched.
107
- """
94
+ """Report errors and translate them into process exit codes."""
108
95
  try:
109
96
  yield
110
97
  except CliExit as ex:
@@ -299,8 +299,8 @@ def test_debug_cmd_emits_command_and_cwd(
299
299
  ) -> None:
300
300
  debug_reporter.debug_cmd(["git", "commit", "-m", "a b"], cwd=Path("/tmp/x"))
301
301
  err = capsys.readouterr().err
302
- assert "COMMAND: git commit -m 'a b'" in err
303
- assert "cwd: /tmp/x" in err
302
+ assert "RUN: git commit -m 'a b'" in err
303
+ assert "CWD: /tmp/x" in err
304
304
 
305
305
 
306
306
  def test_debug_cmd_omits_cwd_when_none(
@@ -308,8 +308,8 @@ def test_debug_cmd_omits_cwd_when_none(
308
308
  ) -> None:
309
309
  debug_reporter.debug_cmd(["ls"])
310
310
  err = capsys.readouterr().err
311
- assert "COMMAND: ls" in err
312
- assert "cwd:" not in err
311
+ assert "RUN: ls" in err
312
+ assert "CWD:" not in err
313
313
 
314
314
 
315
315
  def test_debug_cmd_silent_when_disabled(
@@ -327,15 +327,23 @@ def test_debug_cmd_escapes_markup(
327
327
  assert "[red]hi[/red]" in err
328
328
 
329
329
 
330
+ def test_debug_cmd_escapes_markup_in_cwd(
331
+ debug_reporter: CliReporter, capsys: pytest.CaptureFixture[str]
332
+ ) -> None:
333
+ debug_reporter.debug_cmd(["ls"], cwd=Path("/tmp/[red]x[/red]"))
334
+ err = capsys.readouterr().err
335
+ assert "[red]x[/red]" in err
336
+
337
+
330
338
  def test_debug_output_emits_both_streams(
331
339
  debug_reporter: CliReporter, capsys: pytest.CaptureFixture[str]
332
340
  ) -> None:
333
341
  debug_reporter.debug_output("out1\nout2 \n", "err1")
334
342
  err = capsys.readouterr().err
335
- assert "stdout:" in err
336
- assert "out1\nout2" in err
337
- assert "stderr:" in err
338
- assert "err1" in err
343
+ # Pin label-on-its-own-line + the ``\n`` separator + the trailing ``rstrip``
344
+ # as one contiguous unit, so swapping the newline for a space would fail.
345
+ assert "STDOUT:\nout1\nout2" in err
346
+ assert "STDERR:\nerr1" in err
339
347
 
340
348
 
341
349
  def test_debug_output_skips_empty_streams(
@@ -350,9 +358,9 @@ def test_debug_output_skips_only_the_empty_stream(
350
358
  ) -> None:
351
359
  debug_reporter.debug_output("kept", " ")
352
360
  err = capsys.readouterr().err
353
- assert "stdout:" in err
361
+ assert "STDOUT:" in err
354
362
  assert "kept" in err
355
- assert "stderr:" not in err
363
+ assert "STDERR:" not in err
356
364
 
357
365
 
358
366
  def test_debug_output_escapes_markup(
@@ -381,7 +389,21 @@ def test_debug_cmd_wraps_payload_in_dim_misc_style(
381
389
  reporter.debug_cmd(["ls"])
382
390
  output = capture.get()
383
391
  assert "\x1b[2m" in output
384
- assert "COMMAND: ls" in output
392
+ assert "RUN: ls" in output
393
+
394
+
395
+ def test_debug_output_wraps_header_in_dim_misc_style(
396
+ color_reporter: tuple[Console, CliReporter],
397
+ ) -> None:
398
+ # With color forced on, the ``misc`` role (=dim) must render its ANSI
399
+ # escape around the ``STDOUT:`` header, proving the ``[misc]…[/misc]``
400
+ # wrapper is applied rather than dropped.
401
+ color_console, reporter = color_reporter
402
+ with color_console.capture() as capture:
403
+ reporter.debug_output("out", "")
404
+ output = capture.get()
405
+ assert "\x1b[2m" in output
406
+ assert "STDOUT:" in output
385
407
 
386
408
 
387
409
  def test_debug_honors_trusted_markup_but_escapes_args(
@@ -90,7 +90,7 @@ wheels = [
90
90
 
91
91
  [[package]]
92
92
  name = "cli-error"
93
- version = "0.1.1"
93
+ version = "0.1.2"
94
94
  source = { editable = "." }
95
95
  dependencies = [
96
96
  { name = "rich" },
@@ -153,11 +153,11 @@ wheels = [
153
153
 
154
154
  [[package]]
155
155
  name = "filelock"
156
- version = "3.29.6"
156
+ version = "3.29.7"
157
157
  source = { registry = "https://pypi.org/simple" }
158
- sdist = { url = "https://files.pythonhosted.org/packages/e0/c8/35bdf04fb30755e2ed758f877edf3eb4a243c2463d3a258cc28b18b7a6e2/filelock-3.29.6.tar.gz", hash = "sha256:895c532ef3f4ef04972b9446a8c4e2931a5c399ff3c4be4c9369f2639b80f793", size = 70301, upload-time = "2026-07-06T23:08:08.577Z" }
158
+ sdist = { url = "https://files.pythonhosted.org/packages/35/94/00f2059e4835eace3ae8fde680b932c496f8ec7bdc99168dfa53fb2e6b79/filelock-3.29.7.tar.gz", hash = "sha256:5b481979797ae69e72f0b389d89a80bdd585c260c5b3f1fb9c0a5ba9bb3f195d", size = 71521, upload-time = "2026-07-08T05:46:58.716Z" }
159
159
  wheels = [
160
- { url = "https://files.pythonhosted.org/packages/bb/49/7467c2946ccd9617f7da38187071bdc45bb9a95df51f4d63d6622432ce4e/filelock-3.29.6-py3-none-any.whl", hash = "sha256:14d5f5597d2e0c4dbd774cfb6d8132da1db44da83732aab679d54f7dcf97ab65", size = 45478, upload-time = "2026-07-06T23:08:07.197Z" },
160
+ { url = "https://files.pythonhosted.org/packages/60/02/be4a57b60c7149b55b9e3b3c13f609cd8eb5307c751f22bd8fb8d262e75b/filelock-3.29.7-py3-none-any.whl", hash = "sha256:987db6f789a3a2a59f55081801b2b3697cb97e2a736b5f1a9e99b559285fbc51", size = 46036, upload-time = "2026-07-08T05:46:57.53Z" },
161
161
  ]
162
162
 
163
163
  [[package]]
@@ -286,7 +286,7 @@ wheels = [
286
286
 
287
287
  [[package]]
288
288
  name = "mypy"
289
- version = "2.1.0"
289
+ version = "2.2.0"
290
290
  source = { registry = "https://pypi.org/simple" }
291
291
  dependencies = [
292
292
  { name = "ast-serialize" },
@@ -295,37 +295,38 @@ dependencies = [
295
295
  { name = "pathspec" },
296
296
  { name = "typing-extensions" },
297
297
  ]
298
- sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359, upload-time = "2026-05-11T18:37:36.237Z" }
299
- wheels = [
300
- { url = "https://files.pythonhosted.org/packages/95/b1/55861beb5c339b44f9a2ba92df9e2cb1eeb4ae1eee674cdf7772c797778b/mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af", size = 14874381, upload-time = "2026-05-11T18:37:31.784Z" },
301
- { url = "https://files.pythonhosted.org/packages/0b/b3/b7f770114b7d0ac92d0f76e8d93c2780844a70488a90e91821927850da86/mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6", size = 13665501, upload-time = "2026-05-11T18:34:23.063Z" },
302
- { url = "https://files.pythonhosted.org/packages/b6/f3/8ae2037967e2126689a0c11d99e2b707134a565191e92c60ca2572aec60a/mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211", size = 14045750, upload-time = "2026-05-11T18:31:48.151Z" },
303
- { url = "https://files.pythonhosted.org/packages/a0/32/615eb5911859e43d054941b0d0a7d06cfa2870eba86529cf385b052b111c/mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b", size = 15061630, upload-time = "2026-05-11T18:37:06.898Z" },
304
- { url = "https://files.pythonhosted.org/packages/d4/03/4eafbfff8bfab1b87082741eae6e6a624028c984e6708b73bce2a8570c9d/mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22", size = 15288831, upload-time = "2026-05-11T18:31:18.07Z" },
305
- { url = "https://files.pythonhosted.org/packages/99/ee/919661478e5891a3c96e549c036e467e64563ab85995b10c53c8358e16a3/mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b", size = 11135228, upload-time = "2026-05-11T18:34:31.23Z" },
306
- { url = "https://files.pythonhosted.org/packages/24/0a/6a12b9782ca0831a553192f351679f4548abc9d19a7cc93bb7feb02084c7/mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8", size = 10040684, upload-time = "2026-05-11T18:36:48.199Z" },
307
- { url = "https://files.pythonhosted.org/packages/6e/dd/c7191469c777f07689c032a8f7326e393ea34c92d6d76eb7ce5ba57ea66d/mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5", size = 14852174, upload-time = "2026-05-11T18:31:38.929Z" },
308
- { url = "https://files.pythonhosted.org/packages/55/8c/aed55408879043d72bb9135f4d0d19a02b886dd569631e113e3d2706cb8d/mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e", size = 13651542, upload-time = "2026-05-11T18:36:04.636Z" },
309
- { url = "https://files.pythonhosted.org/packages/3a/8e/f371a824b1f1fa8ea6e3dbb8703d232977d572be2329554a3bc4d960302f/mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e", size = 14033929, upload-time = "2026-05-11T18:35:55.742Z" },
310
- { url = "https://files.pythonhosted.org/packages/94/21/f54be870d6dd53a82c674407e0f8eed7174b05ec78d42e5abd7b42e84fd5/mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285", size = 15039200, upload-time = "2026-05-11T18:33:10.281Z" },
311
- { url = "https://files.pythonhosted.org/packages/17/99/bf21748626a40ce59fd29a39386ab46afec88b7bd2f0fa6c3a97c995523f/mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5", size = 15272690, upload-time = "2026-05-11T18:32:07.205Z" },
312
- { url = "https://files.pythonhosted.org/packages/d6/d7/9e90d2cf47100bea550ed2bc7b0d4de3a62181d84d5e37da0003e8462637/mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65", size = 11147435, upload-time = "2026-05-11T18:33:56.477Z" },
313
- { url = "https://files.pythonhosted.org/packages/ec/46/e5c449e858798e35ffc90946282a27c62a77be743fe17480e4977374eb91/mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d", size = 10035052, upload-time = "2026-05-11T18:32:30.049Z" },
314
- { url = "https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2", size = 14848422, upload-time = "2026-05-11T18:35:45.984Z" },
315
- { url = "https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f", size = 13677374, upload-time = "2026-05-11T18:36:57.188Z" },
316
- { url = "https://files.pythonhosted.org/packages/84/7f/8107ea87a44fd1f1b59882442f033c9c3488c127201b1d1d15f1cbd6022e/mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4", size = 14055743, upload-time = "2026-05-11T18:35:18.361Z" },
317
- { url = "https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef", size = 15020937, upload-time = "2026-05-11T18:34:59.618Z" },
318
- { url = "https://files.pythonhosted.org/packages/ff/d7/f08360c691d758acb02f45022c34d98b92892f4ea756644e1000d4b9f3d8/mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135", size = 15253371, upload-time = "2026-05-11T18:36:41.081Z" },
319
- { url = "https://files.pythonhosted.org/packages/67/1b/09460a13719530a19bce27bd3bc8449e83569dd2ba7faf51c9c3c30c0b61/mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21", size = 11326429, upload-time = "2026-05-11T18:34:13.526Z" },
320
- { url = "https://files.pythonhosted.org/packages/40/62/75dbf0f82f7b6680340efc614af29dd0b3c17b8a4f1cd09b8bd2fd6bc814/mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57", size = 10218799, upload-time = "2026-05-11T18:32:23.491Z" },
321
- { url = "https://files.pythonhosted.org/packages/b2/66/caca04ed7d972fb6eb6dd1ccd6df1de5c38fae8c5b3dc1c4e8e0d85ee6b9/mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e", size = 15923458, upload-time = "2026-05-11T18:35:28.64Z" },
322
- { url = "https://files.pythonhosted.org/packages/ed/52/2d90cbe49d014b13ed7ff337930c30bad35893fe38a1e4641e756bb62191/mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780", size = 14757697, upload-time = "2026-05-11T18:36:14.208Z" },
323
- { url = "https://files.pythonhosted.org/packages/ac/37/d98f4a14e081b238992d0ed96b6d39c7cc0148c9699eb71eaa68629665ea/mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd", size = 15405638, upload-time = "2026-05-11T18:33:48.249Z" },
324
- { url = "https://files.pythonhosted.org/packages/a3/c2/15c46613b24a84fad2aea1248bf9619b99c2767ae9071fe224c179a0b7d4/mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08", size = 16215852, upload-time = "2026-05-11T18:32:50.296Z" },
325
- { url = "https://files.pythonhosted.org/packages/5c/90/9c16a57f482c76d25f6379762b56bbf65c711d8158cf271fb2802cfb0640/mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081", size = 16452695, upload-time = "2026-05-11T18:33:38.182Z" },
326
- { url = "https://files.pythonhosted.org/packages/0f/4c/215a4eeb63cacc5f17f516691ea7285d11e249802b942476bff15922a314/mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7", size = 12866622, upload-time = "2026-05-11T18:34:39.945Z" },
327
- { url = "https://files.pythonhosted.org/packages/4b/50/1043e1db5f455ffe4c9ab22747cd8ca2bc492b1e4f4e21b130a44ee2b217/mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6", size = 10610798, upload-time = "2026-05-11T18:36:31.444Z" },
328
- { url = "https://files.pythonhosted.org/packages/0d/2a/13ca1f292f6db1b98ff495ef3467736b331621c5917cad984b7043e7348d/mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289", size = 2693302, upload-time = "2026-05-11T18:31:29.246Z" },
298
+ sdist = { url = "https://files.pythonhosted.org/packages/e9/7e/be536678c6ae49ef058aba4b483d8c7bc104f471479016066f345bc1f5f8/mypy-2.2.0.tar.gz", hash = "sha256:2cdd99d48590dce6f6b7f1961eda75386364398fcdaad86923bc0f0231bf9baf", size = 3950939, upload-time = "2026-07-08T01:37:27.335Z" }
299
+ wheels = [
300
+ { url = "https://files.pythonhosted.org/packages/d1/be/fbaba7b0ee89874fb11668416dec9e5585c190b676b0796cff26a9290fe8/mypy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:484a2be712b245ac6e89847141f1f50c612b0a924aa25917e63e6cfcf4da07cd", size = 14928025, upload-time = "2026-07-08T01:37:24.376Z" },
301
+ { url = "https://files.pythonhosted.org/packages/c5/8f/f79a7c5a76671b0f563d4beaa7d99fe90df4500d2c1d2ba1be0432121bcf/mypy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb0a020dc68480d40e484675558ed637140df1ccbf896a81ba68bca85f2b50a0", size = 13793027, upload-time = "2026-07-08T01:34:33.937Z" },
302
+ { url = "https://files.pythonhosted.org/packages/b2/b9/3db0086bab611d34e26061b86189e6f71de6d22a9b81699a93b006eabcf6/mypy-2.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc361340732ce7108fa0308812caf02bb6868f16112f1efd35bcad88badf3327", size = 14108322, upload-time = "2026-07-08T01:36:08.316Z" },
303
+ { url = "https://files.pythonhosted.org/packages/58/29/4f1e13979a848de2a0fd385462354b58358b6e8b3d9661663e308f6e3d5d/mypy-2.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0179a3a0b833f724a65f22613607cf7ea941ab17ec34fa283f8d6dfe21d9fa9", size = 15190198, upload-time = "2026-07-08T01:36:20.168Z" },
304
+ { url = "https://files.pythonhosted.org/packages/14/f7/7759f6294d9d25d86671957d0974a215a2a24d429526e26a2f603de951c5/mypy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e0899b13da1e4ba44b880550f247402ce90ffecc71c54b220bcbe7ecb34f394", size = 15424222, upload-time = "2026-07-08T01:33:39.398Z" },
305
+ { url = "https://files.pythonhosted.org/packages/d7/1b/05b212bef4d2234b5f0b551ea53ce0680d8075b2e79861c765f70b590945/mypy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:511320b17467402e2906130e185abffffa3d7648aff1444fc2abb61f4c8a087d", size = 11135191, upload-time = "2026-07-08T01:35:03.019Z" },
306
+ { url = "https://files.pythonhosted.org/packages/92/51/495e7122f6589948b36d3820a046461906756a0eb1b6dedc13ebfec7815e/mypy-2.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:7589f370b33dcdd95708f5340f13a67c2c49140957f934b42ef63064d343cca0", size = 10132502, upload-time = "2026-07-08T01:34:04.508Z" },
307
+ { url = "https://files.pythonhosted.org/packages/a3/5f/2d7a9ac5646274cd6e77ce3abcc2a9ece760c2b21f4c4b9f301711e07855/mypy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6968f27347ef539c443ddfd6897e79db525ddb8c856aa8fbf14c34f310ca5193", size = 14931618, upload-time = "2026-07-08T01:33:51.702Z" },
308
+ { url = "https://files.pythonhosted.org/packages/b2/8a/1adaa7caaa104f87021b1ac71252d62e646e9b623d77900ac7a0ae252bf3/mypy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3df226d2a0ae2c3b03845af217800a68e2965d4b14914c99b78d3a2c8ae23299", size = 13857718, upload-time = "2026-07-08T01:35:27.555Z" },
309
+ { url = "https://files.pythonhosted.org/packages/1d/15/b11586b5aebbb82213e297fc30a6fcf3bed6a9deea3739cd8dd87621f3fd/mypy-2.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc53553996aca2094216ad9306a6f06c5265d206c1bcb54dd367560bd3557825", size = 14059704, upload-time = "2026-07-08T01:33:57.363Z" },
310
+ { url = "https://files.pythonhosted.org/packages/03/db/071e05ab442596bdf7a845e830d5ef7128a0175281038245b171a6b16873/mypy-2.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:996abf2f0bebf572556c60720e8dc0cf5292b64060fa68d7f2bc9caa48e01b6f", size = 15128719, upload-time = "2026-07-08T01:33:33.855Z" },
311
+ { url = "https://files.pythonhosted.org/packages/f3/1c/c4b84eafb85ee315da72471523cc1bf7d7c42164085c42333601da7a8817/mypy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ec287c2381898c652bf8ff79448627fe1a9ee76d22005181fac7315a485c7108", size = 15378692, upload-time = "2026-07-08T01:34:10.468Z" },
312
+ { url = "https://files.pythonhosted.org/packages/68/a4/59a0ee94877fdfe2958cec9b6add72a75393063c79cb60ab4026dd5e10c2/mypy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c2c967a7685fa93fcf1a778b3ebe76e756b28ba14655f539d7b61ff3da69352a", size = 11150911, upload-time = "2026-07-08T01:35:21.603Z" },
313
+ { url = "https://files.pythonhosted.org/packages/90/e4/6a9144be50180ed43d8c92de9b03dff504daa92b5bcc0353e8960799a23b/mypy-2.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:d59a4b80351ec92e5f7415fcdd008bd77fcbefc7adf9cbc7ffe4eb9f71617734", size = 10125389, upload-time = "2026-07-08T01:36:36.164Z" },
314
+ { url = "https://files.pythonhosted.org/packages/73/32/0aa8d8d197023ca6040f7b25a486cb47037b6350b0d3bae657c8f85fb43f/mypy-2.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1f6c3d76853071409ac58fc0aadfb276a22af5f190fdaa02152a858088a39ebd", size = 14926083, upload-time = "2026-07-08T01:36:02.365Z" },
315
+ { url = "https://files.pythonhosted.org/packages/e2/7c/35bbe0cb10e6699f90e988e537aaf4282a6c16e37f58848a242eb0a98bde/mypy-2.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bdaa177e80cc3292824d4ef3670b5b58771ee8d57c290e0c9c89e7968212332c", size = 13879985, upload-time = "2026-07-08T01:36:31.093Z" },
316
+ { url = "https://files.pythonhosted.org/packages/f9/0c/1597fbebd873e9b63452317740ae3dd32692cec5da180cc65acd96cd28cf/mypy-2.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80923e6d6e7878291f537ee11052f974954c20cb569798429a5dc265eb780b47", size = 14076883, upload-time = "2026-07-08T01:34:21.789Z" },
317
+ { url = "https://files.pythonhosted.org/packages/68/35/2ec021a83ec01b5d522639f78d8b36adade7fa4821db0f48fd6d82e861f3/mypy-2.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f24bd465a09077c8d64be8f19a6646db467a55490fd315fe7871afe6bb9645", size = 15103567, upload-time = "2026-07-08T01:36:47.717Z" },
318
+ { url = "https://files.pythonhosted.org/packages/53/3a/8cb3529f6d6800c7d069935e5c83a05d80263847b8a947cf6b0b16a9e958/mypy-2.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:db34595464869f474708e769413d1d739fc33a69850f253757b9a4cc20bc1fec", size = 15354641, upload-time = "2026-07-08T01:36:41.592Z" },
319
+ { url = "https://files.pythonhosted.org/packages/d6/4d/320bc9a9553f8a9db5e847ec5ded762ef7ed7403c76c4ba2e8181c80e2f0/mypy-2.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b48092132c7b0ef4322773fecae62fc5b0bc339be348badeec8af502122a4a51", size = 7694355, upload-time = "2026-07-08T01:37:03.291Z" },
320
+ { url = "https://files.pythonhosted.org/packages/90/05/bf3b349e2f885cd3aab488111bb9049439c28bc028dac5073350d3df8fbe/mypy-2.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:6fc0e98b95e31755ca06d89f75fafa7820fbb3ea2caace6d83cba17625cd0acb", size = 11329146, upload-time = "2026-07-08T01:35:38.318Z" },
321
+ { url = "https://files.pythonhosted.org/packages/41/a5/558b06e6cfe17ab88bb38f7b370b6bc68a74ba177c9e138db9748e422d2d/mypy-2.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:bc73a5b4d40e8a3e6b12ef82eb0c90430964e34016a36c2aff4e3bfe37ba41f0", size = 10316586, upload-time = "2026-07-08T01:36:25.458Z" },
322
+ { url = "https://files.pythonhosted.org/packages/0b/21/f0b96f19a9b8ba111a45ffbe9508e818b7f6990469b38f6888943f7bfd3a/mypy-2.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6257bd4b4c0ae2148548b869a1ff3758e38645b92c8fe65eca401866c3c551c1", size = 15922565, upload-time = "2026-07-08T01:35:56.282Z" },
323
+ { url = "https://files.pythonhosted.org/packages/18/f2/1dbcb20b0865d5e992541450a8c73f2fcc90f8bd7d8a4b81313e16934870/mypy-2.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:dfa22b3ae862ac1ce76f5976ddd402651b5f090bcfd49c6d0484b8983a29eaf8", size = 14816515, upload-time = "2026-07-08T01:34:58.167Z" },
324
+ { url = "https://files.pythonhosted.org/packages/84/a2/18cce9c7d5b4d14010d1f13836da11b234dda917b17ca8671fc32c136997/mypy-2.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30a430bf26fe8cf372f3933fbd83e633d6561868803645a20e4e6d4523f52a3b", size = 15272246, upload-time = "2026-07-08T01:37:08.72Z" },
325
+ { url = "https://files.pythonhosted.org/packages/ce/71/24d720c7924829bd675cbde2d0fa779f50abf676ca617f53d6a8bfef5fa7/mypy-2.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d58655a60e823b1a4c9ebcda072897fb0193c2f3e6f8e7c433e152aa4cb00233", size = 16226295, upload-time = "2026-07-08T01:34:51.861Z" },
326
+ { url = "https://files.pythonhosted.org/packages/b7/5e/785730990fc863ad8340b4ab44ac4ca23270aecff92c180ccdf27f9f5869/mypy-2.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d4452c955caf14e28bb046cbd0c3671272e6381630a8b81b0da9713558148890", size = 16493275, upload-time = "2026-07-08T01:35:09.337Z" },
327
+ { url = "https://files.pythonhosted.org/packages/93/33/55b1edf16f639f153972380d6977b81f65509c5b8f9c86b58b94b7990b03/mypy-2.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:68f5b7f7f755200f68c7181e3dfb28be9858162257690e539759c9f57721e388", size = 11749038, upload-time = "2026-07-08T01:35:50.071Z" },
328
+ { url = "https://files.pythonhosted.org/packages/61/36/67424748a4e65e97f0e05bf00df379dfb6c2d817f82cc3a4ce5c96d99beb/mypy-2.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:78d201accfafce3801d978f2b8dbbd473a9ce364cc0a0dfd9192fe47d977e129", size = 10704254, upload-time = "2026-07-08T01:37:17.971Z" },
329
+ { url = "https://files.pythonhosted.org/packages/28/cb/142c2097ca02c0d295b00625ff946808bdda65acda17d163c680d8a6a474/mypy-2.2.0-py3-none-any.whl", hash = "sha256:ecc138da861e932d1344214da4bae866b21900a9c2778824b51fe2fb47f5180e", size = 2726094, upload-time = "2026-07-08T01:34:00.075Z" },
329
330
  ]
330
331
 
331
332
  [[package]]
@@ -549,28 +550,28 @@ wheels = [
549
550
 
550
551
  [[package]]
551
552
  name = "uv"
552
- version = "0.11.27"
553
- source = { registry = "https://pypi.org/simple" }
554
- sdist = { url = "https://files.pythonhosted.org/packages/8f/ed/b8bb8bf2044561e3349ebe75be0d8abdeb19577886753b49200ec6caea0d/uv-0.11.27.tar.gz", hash = "sha256:3469204521869f0e6bdea17b02c1d86db2d0150820895653a6152cab206fb00b", size = 5978029, upload-time = "2026-07-06T21:00:29.995Z" }
555
- wheels = [
556
- { url = "https://files.pythonhosted.org/packages/b2/fe/8a080fb603f276ceb2d960454b2b5998cc6e5c0c6d5dbbbeb48b141de4f2/uv-0.11.27-py3-none-linux_armv6l.whl", hash = "sha256:6cedad2185b16bd5da77096d4813159c9c3c572897537256eecdb4092941adc0", size = 25490659, upload-time = "2026-07-06T20:59:29.003Z" },
557
- { url = "https://files.pythonhosted.org/packages/d1/15/886a2ef7b00c1a4fcf706e7a6b946b3f7485a55f42d0aa9b5572caed58b6/uv-0.11.27-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:42b273459864c67f3736ae2a63929df463975d885bbc1afd8f53f7e0fb1f2269", size = 24498434, upload-time = "2026-07-06T20:59:33.042Z" },
558
- { url = "https://files.pythonhosted.org/packages/2d/6e/45335717c4372bf955c87bc05c6462dd4c0c6087ed12c3991b14cbba77cd/uv-0.11.27-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b316464a1028a43478b74424b4b78925c463758baec93cb754fb2392ba175138", size = 23248727, upload-time = "2026-07-06T20:59:36.201Z" },
559
- { url = "https://files.pythonhosted.org/packages/0a/fa/41dde1e350c5a277b797371faf96fb013c2c13ed18df6efc51ed8ec9bb5b/uv-0.11.27-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:3ca478883d78270ceed57f229d1b480dbcadf5d79b2ce9624574807d6ec48554", size = 25208126, upload-time = "2026-07-06T20:59:39.984Z" },
560
- { url = "https://files.pythonhosted.org/packages/00/e3/bc6d4af24ab533db4c741cebade3a58b91fc0563059d39e838161dd210c8/uv-0.11.27-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:232dfb7549c8a4217ab1970dea0de731926b8ca21769ed89951ad8f8c3bce8b6", size = 25030974, upload-time = "2026-07-06T20:59:43.378Z" },
561
- { url = "https://files.pythonhosted.org/packages/c3/0c/82e736930d3f78ca6c3286ef31627d7155e20191af88afc40ec29486f400/uv-0.11.27-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c0cf7c7960587a231252cbe4d7a032b5a02c29cfab3fcc4e75a915b1c5cacee", size = 25015115, upload-time = "2026-07-06T20:59:46.694Z" },
562
- { url = "https://files.pythonhosted.org/packages/a0/5b/512ebf3b24b708ea2adda4ec4d4bd23b2404d7a7ea3bd24d2b92210ab680/uv-0.11.27-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47b5863ef715ffe4c29e792c9884a4e8b8016b0628d3613ac84c696acc128a78", size = 26487914, upload-time = "2026-07-06T20:59:50.414Z" },
563
- { url = "https://files.pythonhosted.org/packages/98/d5/3871185331266156fbd09ab0ad7ddc69ca759b3a28ece5488bdb64f152d9/uv-0.11.27-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5764155d2a578a41d2827f464d4ce5b7788632e732cb304e2025fb3d043b46f", size = 27393306, upload-time = "2026-07-06T20:59:53.852Z" },
564
- { url = "https://files.pythonhosted.org/packages/24/0f/9fe3cc9b8d498f2e426b3cda90d337b076d64f19c2d55cb0b7d091c4bfe9/uv-0.11.27-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d806e1067c8eb9f8ba5dbdca46484512d224070e8473442319d4c1fbc3246f4d", size = 26563495, upload-time = "2026-07-06T20:59:56.945Z" },
565
- { url = "https://files.pythonhosted.org/packages/e7/be/18393c15ac0c982fefa34944135ead3adc565da5023d973eff5081a95a62/uv-0.11.27-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cb783b9db3868e51e8da1956aaa7e800262ad1af03dfc8b024f3b04ecb447c2", size = 26652374, upload-time = "2026-07-06T21:00:00.256Z" },
566
- { url = "https://files.pythonhosted.org/packages/b8/93/1bb8bee2b0bcc6e9655518ecaa9a792b1952dd99ae7366fe4f6c82754361/uv-0.11.27-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8e2b86d3dee515eeba6ea001d8b3eac20b204db07d39b04187c755a490a4fba6", size = 25341573, upload-time = "2026-07-06T21:00:03.789Z" },
567
- { url = "https://files.pythonhosted.org/packages/e6/e0/fae0d1c972b25ac192ac807c1b1baf0f12070c40c8af2eb8e22310ea8846/uv-0.11.27-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:d325b8bd2665ce3ac58d33f977683cfb2cb8eb951effab06fad8518426bc0a90", size = 26051363, upload-time = "2026-07-06T21:00:07.281Z" },
568
- { url = "https://files.pythonhosted.org/packages/e5/a2/4c0c103ea431f5d70cd33f10c754b5b1de9687fea982ca1a20a4eee0a4a7/uv-0.11.27-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:3d5c9036b558a323f254e3d16038183c22c55e0d06b921f1ed9706953311e52f", size = 26148896, upload-time = "2026-07-06T21:00:10.56Z" },
569
- { url = "https://files.pythonhosted.org/packages/bb/b7/a514307a90ca9f1cb59efd0898958dea6c1092ad5e4e6b6f2eb4d55109db/uv-0.11.27-py3-none-musllinux_1_1_i686.whl", hash = "sha256:4cc04e625e7bfac6975fd384d6598169cea0030995ff3b557950ec3077974a4d", size = 25701138, upload-time = "2026-07-06T21:00:13.772Z" },
570
- { url = "https://files.pythonhosted.org/packages/bf/46/c6cfa675d727a199cfce32f7a30350ce6e47f699c3cd7f0433a619c671d4/uv-0.11.27-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:109d8e145b390d0e14f2aefd9708a7522a4236d6bee20361a7558e77a14c0531", size = 26913232, upload-time = "2026-07-06T21:00:17.233Z" },
571
- { url = "https://files.pythonhosted.org/packages/a4/04/0070ecdea37baa9d38187abedc78eed9a52a2e6cb1d4f175c580640f3456/uv-0.11.27-py3-none-win32.whl", hash = "sha256:b330d2ab6af0f79396fb350a9fed8ed1aa92516310f7533de9a8dfebc4e147cd", size = 24374672, upload-time = "2026-07-06T21:00:20.399Z" },
572
- { url = "https://files.pythonhosted.org/packages/d0/b9/f3df522d2e609fe511e5bee24b34c91ce281ce472594121fa1d5fa159d9d/uv-0.11.27-py3-none-win_amd64.whl", hash = "sha256:e20f25921ed4c46d32ac18a9b2e610c0384439fd367f647f2b68e0e1d90e9885", size = 27275452, upload-time = "2026-07-06T21:00:23.903Z" },
573
- { url = "https://files.pythonhosted.org/packages/8d/2e/4ea9c3bbf95a21c627a3dfa359f5a3266e648cd103c5ade374a6e4265c5f/uv-0.11.27-py3-none-win_arm64.whl", hash = "sha256:a41da27667e95c0df939e99e77a4d9169fb895df0f6788b2ab65ed5efdc1395f", size = 25561477, upload-time = "2026-07-06T21:00:27.333Z" },
553
+ version = "0.11.28"
554
+ source = { registry = "https://pypi.org/simple" }
555
+ sdist = { url = "https://files.pythonhosted.org/packages/a2/a2/bfd6755b40682ef7e775ddb9d52823dea6551352f4244106da4bad37cd3c/uv-0.11.28.tar.gz", hash = "sha256:df86cfd135542a833e9f84708b3b8dbaa987a3b9db85b267062db49ab639d242", size = 5985690, upload-time = "2026-07-07T23:12:47.095Z" }
556
+ wheels = [
557
+ { url = "https://files.pythonhosted.org/packages/06/5d/507b829e79353fe3dcb2779cde8f64497d9c99f9b08b18b8f55ee3bf1786/uv-0.11.28-py3-none-linux_armv6l.whl", hash = "sha256:ae5bbdb6150adcd625f5fa720b04abf2014247d878d1035f19751bb0e7274543", size = 25893158, upload-time = "2026-07-07T23:11:55.77Z" },
558
+ { url = "https://files.pythonhosted.org/packages/10/54/50c85a663ce723e061523ab4ac8b01b650077584e80950f9c93fd073979f/uv-0.11.28-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bb11d94cb848ff58af79e0bb5e4037cd324d27dbe2dabb7746db698b724a9a20", size = 25041511, upload-time = "2026-07-07T23:11:58.885Z" },
559
+ { url = "https://files.pythonhosted.org/packages/32/e1/49968cab72f16a7d6c45d095d319f9efbe8ce05f3f15c5f7104493694289/uv-0.11.28-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e9eb317b1cdb249887df77ac232d8a9448f26858b2399f9f2949c6a7b9bedf88", size = 23570471, upload-time = "2026-07-07T23:12:01.832Z" },
560
+ { url = "https://files.pythonhosted.org/packages/b8/4d/c9fe448dcd5cf65a5f054517aa42551b7f0920710a6891d98af321a06b22/uv-0.11.28-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:041e4b80bebc58d7142ac9394370cacd73185fd8d066d6675d14707d83408f6d", size = 25594677, upload-time = "2026-07-07T23:12:04.597Z" },
561
+ { url = "https://files.pythonhosted.org/packages/07/aa/4c0c71075ba66cc594f856cbd98844058fcb53cb4dd8a6fccda8419562bb/uv-0.11.28-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:185416a5316df8c5442b47178349f1f27fc1034468670ac1fb499eae3b25bd68", size = 25427944, upload-time = "2026-07-07T23:12:07.226Z" },
562
+ { url = "https://files.pythonhosted.org/packages/6c/77/50fef66f4e26bf771429e1d88f849476d8ed21f0fb0708acaa53dc5772a5/uv-0.11.28-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4a9fe246cb2882532277f5d5e5bd8a59462981462a2f98426f35ecfca82460e", size = 25448458, upload-time = "2026-07-07T23:12:10.894Z" },
563
+ { url = "https://files.pythonhosted.org/packages/d0/93/720f45af65ebda460166dc64f3318acd65f7bd3a8e326fbd21810fd920ee/uv-0.11.28-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f7ce6f6015a3e857bc6a663514afa62856b669ee5c1bd120e4c58ac2ef5513d", size = 26917218, upload-time = "2026-07-07T23:12:13.802Z" },
564
+ { url = "https://files.pythonhosted.org/packages/cd/27/a9b68a15a5fe8db7103bea514c2adb79e9b1114fc8dc96fb39dbd7a5b898/uv-0.11.28-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b3d0ea11e83b373a2166b82dd0864f5677fbadf98db64541ab2e59c42968905", size = 27771542, upload-time = "2026-07-07T23:12:16.519Z" },
565
+ { url = "https://files.pythonhosted.org/packages/d4/fd/208607a7f5f86188775387fe0839ef97cf8d013e8d0e909140b7fdb7d0d1/uv-0.11.28-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c60294e3be4fa203a04015fc02ac8a31d936e86fde06dcb43c7f8f22661dfff", size = 26972190, upload-time = "2026-07-07T23:12:19.191Z" },
566
+ { url = "https://files.pythonhosted.org/packages/75/2e/62273ee6c9fbebccd8248c153b44870f81ebf5267c31edf4c095d78537fb/uv-0.11.28-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fe42df9f42056037473f3876adec1615709b57d3470ed39178ff420f3afb9f", size = 27127688, upload-time = "2026-07-07T23:12:22.43Z" },
567
+ { url = "https://files.pythonhosted.org/packages/dd/8c/b15212904e6f0aa4a3709dc86838c6fa070fe97c7e96b3f10174a26b16e3/uv-0.11.28-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:fab3c31007a611866475824a666f5a721bf0c9335db806355a97fcfba2a6bbb7", size = 25715221, upload-time = "2026-07-07T23:12:25.144Z" },
568
+ { url = "https://files.pythonhosted.org/packages/64/35/b83b7c599474aaf1277c2224c09679640c2320562155c4b6ece1c6f014c1/uv-0.11.28-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:2e91eb8a0b00d5f4427195fc818bcaa4d8bb4fccb79f4e973e74802419ab06ca", size = 26392793, upload-time = "2026-07-07T23:12:27.848Z" },
569
+ { url = "https://files.pythonhosted.org/packages/81/49/8093318206dee51b5cfcabbf110892ff63cfd897a5df002e2d8b61350fe6/uv-0.11.28-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:47e3f12fe6f5c80a01639d8df36efde7bdddfc3bbc52250df623547d8d393105", size = 26522809, upload-time = "2026-07-07T23:12:30.757Z" },
570
+ { url = "https://files.pythonhosted.org/packages/cf/c5/b26d82e9297c29c201f61698ee56bba956f94953b23089532d026a97d93f/uv-0.11.28-py3-none-musllinux_1_1_i686.whl", hash = "sha256:d01c7c665511c047f350e587b8b6557c96b61b2eddafbcd8964f0cc2f5b9afbe", size = 26156793, upload-time = "2026-07-07T23:12:33.449Z" },
571
+ { url = "https://files.pythonhosted.org/packages/d0/c2/163e89424668d6c01499efbe85a854ad38f07834bde3f2b16df159eab1d5/uv-0.11.28-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:3fcfda468448093f4d5961ca8c068b0aeec2d02f7226d58ee8513321a929fe4f", size = 27327614, upload-time = "2026-07-07T23:12:36.252Z" },
572
+ { url = "https://files.pythonhosted.org/packages/f0/c9/db4cb824777d013272ccfa77db07a4d12bf1584899458c1917a4b5a4069d/uv-0.11.28-py3-none-win32.whl", hash = "sha256:692edef9cf1d2dd69bb9d9fc01f281a82610547900ce227a3cb269cdf988b5ce", size = 24665179, upload-time = "2026-07-07T23:12:38.803Z" },
573
+ { url = "https://files.pythonhosted.org/packages/40/bc/d67b18cddd54c503c7bad2b189a47fd7a1d07ea10b9212624f892b985498/uv-0.11.28-py3-none-win_amd64.whl", hash = "sha256:f4fcf2c8d9f1444b900e6b8dbbb828825fb76eca01acd18aeaa5c90240408cda", size = 27603677, upload-time = "2026-07-07T23:12:41.985Z" },
574
+ { url = "https://files.pythonhosted.org/packages/57/94/dc31a771eac989973219c730552dbcf5bf7ea6652dba4ba89b1bbdc75a80/uv-0.11.28-py3-none-win_arm64.whl", hash = "sha256:e94560995737c50525d586da553521fbafe9ef06641e7d885db4b270f53ee84d", size = 25839294, upload-time = "2026-07-07T23:12:44.893Z" },
574
575
  ]
575
576
 
576
577
  [[package]]
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