comicforge 0.2.1__tar.gz → 0.2.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 (134) hide show
  1. {comicforge-0.2.1 → comicforge-0.2.2}/CLAUDE.md +50 -0
  2. {comicforge-0.2.1 → comicforge-0.2.2}/PKG-INFO +1 -1
  3. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/inspire.py +2 -1
  4. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/scene.py +1 -1
  5. comicforge-0.2.2/hooks/pre-commit +4 -0
  6. {comicforge-0.2.1 → comicforge-0.2.2}/pyproject.toml +24 -1
  7. {comicforge-0.2.1 → comicforge-0.2.2}/uv.lock +74 -6
  8. {comicforge-0.2.1 → comicforge-0.2.2}/.claude/skills/comicforge/SKILL.md +0 -0
  9. {comicforge-0.2.1 → comicforge-0.2.2}/.claude/skills/comicforge/reference.md +0 -0
  10. {comicforge-0.2.1 → comicforge-0.2.2}/.github/dependabot.yml +0 -0
  11. {comicforge-0.2.1 → comicforge-0.2.2}/.github/workflows/ci.yml +0 -0
  12. {comicforge-0.2.1 → comicforge-0.2.2}/.github/workflows/docs.yml +0 -0
  13. {comicforge-0.2.1 → comicforge-0.2.2}/.github/workflows/release.yml +0 -0
  14. {comicforge-0.2.1 → comicforge-0.2.2}/.gitignore +0 -0
  15. {comicforge-0.2.1 → comicforge-0.2.2}/.python-version +0 -0
  16. {comicforge-0.2.1 → comicforge-0.2.2}/README.md +0 -0
  17. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/__init__.py +0 -0
  18. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/__main__.py +0 -0
  19. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/bubbles.py +0 -0
  20. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/caption.py +0 -0
  21. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/cli.py +0 -0
  22. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/library.py +0 -0
  23. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/pixelart.py +0 -0
  24. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/raster.py +0 -0
  25. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/render.py +0 -0
  26. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/scaffold.py +0 -0
  27. {comicforge-0.2.1 → comicforge-0.2.2}/comicforge/validate.py +0 -0
  28. {comicforge-0.2.1 → comicforge-0.2.2}/docs/art/characters.md +0 -0
  29. {comicforge-0.2.1 → comicforge-0.2.2}/docs/art/inspire.md +0 -0
  30. {comicforge-0.2.1 → comicforge-0.2.2}/docs/art/pixel.md +0 -0
  31. {comicforge-0.2.1 → comicforge-0.2.2}/docs/art/scenes.md +0 -0
  32. {comicforge-0.2.1 → comicforge-0.2.2}/docs/assets/favicon.svg +0 -0
  33. {comicforge-0.2.1 → comicforge-0.2.2}/docs/assets/logo.svg +0 -0
  34. {comicforge-0.2.1 → comicforge-0.2.2}/docs/claude.md +0 -0
  35. {comicforge-0.2.1 → comicforge-0.2.2}/docs/concepts.md +0 -0
  36. {comicforge-0.2.1 → comicforge-0.2.2}/docs/contributing.md +0 -0
  37. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/arms.yaml +0 -0
  38. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/bubble-at.yaml +0 -0
  39. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/bubble-stack.yaml +0 -0
  40. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/bubbles.yaml +0 -0
  41. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/captions.yaml +0 -0
  42. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/coords.yaml +0 -0
  43. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/faces.yaml +0 -0
  44. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/frames.yaml +0 -0
  45. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/grid.yaml +0 -0
  46. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/illustration.yaml +0 -0
  47. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/images.yaml +0 -0
  48. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/lettering.yaml +0 -0
  49. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/pixel.yaml +0 -0
  50. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/poses.yaml +0 -0
  51. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/raster-art/backdrop.png +0 -0
  52. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/scenes.yaml +0 -0
  53. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/strip.yaml +0 -0
  54. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/characters/pip/base.svg +0 -0
  55. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/characters/pip/character.yaml +0 -0
  56. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/characters/pip/face-happy.svg +0 -0
  57. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/characters/pip/face-neutral.svg +0 -0
  58. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/pages/first.yaml +0 -0
  59. {comicforge-0.2.1 → comicforge-0.2.2}/docs/demos/tutorial-art/pixel/heart.yaml +0 -0
  60. {comicforge-0.2.1 → comicforge-0.2.2}/docs/gallery.md +0 -0
  61. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/actors.md +0 -0
  62. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/bubbles.md +0 -0
  63. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/captions-frames.md +0 -0
  64. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/illustrations.md +0 -0
  65. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/images.md +0 -0
  66. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/pages.md +0 -0
  67. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/pixel-art.md +0 -0
  68. {comicforge-0.2.1 → comicforge-0.2.2}/docs/guide/scenes.md +0 -0
  69. {comicforge-0.2.1 → comicforge-0.2.2}/docs/hooks/render_demos.py +0 -0
  70. {comicforge-0.2.1 → comicforge-0.2.2}/docs/index.md +0 -0
  71. {comicforge-0.2.1 → comicforge-0.2.2}/docs/install.md +0 -0
  72. {comicforge-0.2.1 → comicforge-0.2.2}/docs/quickstart.md +0 -0
  73. {comicforge-0.2.1 → comicforge-0.2.2}/docs/reference/cli.md +0 -0
  74. {comicforge-0.2.1 → comicforge-0.2.2}/docs/reference/python-api.md +0 -0
  75. {comicforge-0.2.1 → comicforge-0.2.2}/docs/reference/spec.md +0 -0
  76. {comicforge-0.2.1 → comicforge-0.2.2}/docs/reference/troubleshooting.md +0 -0
  77. {comicforge-0.2.1 → comicforge-0.2.2}/docs/starting-a-project.md +0 -0
  78. {comicforge-0.2.1 → comicforge-0.2.2}/docs/stylesheets/extra.css +0 -0
  79. {comicforge-0.2.1 → comicforge-0.2.2}/examples/README.md +0 -0
  80. {comicforge-0.2.1 → comicforge-0.2.2}/examples/README.md.old +0 -0
  81. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/character.yaml +0 -0
  82. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/face-happy.svg +0 -0
  83. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/face-neutral.svg +0 -0
  84. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/poses/sit/base.svg +0 -0
  85. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/poses/sit/pose.yaml +0 -0
  86. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/poses/walk/base.svg +0 -0
  87. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/bara/poses/walk/pose.yaml +0 -0
  88. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-crossed.svg +0 -0
  89. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-down.svg +0 -0
  90. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-hips.svg +0 -0
  91. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-point.svg +0 -0
  92. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-thumbsup.svg +0 -0
  93. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/arms-wave.svg +0 -0
  94. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/base.svg +0 -0
  95. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/character.yaml +0 -0
  96. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-angry.svg +0 -0
  97. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-happy.svg +0 -0
  98. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-laugh.svg +0 -0
  99. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-neutral.svg +0 -0
  100. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-sad.svg +0 -0
  101. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-surprised.svg +0 -0
  102. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/characters/tom/face-wink.svg +0 -0
  103. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pages/dvur-scene.yaml +0 -0
  104. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pages/kosticka.yaml +0 -0
  105. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pages/slepice.yaml +0 -0
  106. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pixel/bone.yaml +0 -0
  107. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pixel/heart.yaml +0 -0
  108. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pixel/star.yaml +0 -0
  109. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/pixel/sun.yaml +0 -0
  110. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/references.yaml +0 -0
  111. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/dvur/base.svg +0 -0
  112. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/dvur/scene.yaml +0 -0
  113. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/dvur/weather-clear.svg +0 -0
  114. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/dvur/weather-rain.svg +0 -0
  115. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/pokoj/base.svg +0 -0
  116. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/scenes/pokoj/scene.yaml +0 -0
  117. {comicforge-0.2.1 → comicforge-0.2.2}/examples/pes/theme.yaml +0 -0
  118. {comicforge-0.2.1 → comicforge-0.2.2}/mkdocs.yml +0 -0
  119. {comicforge-0.2.1 → comicforge-0.2.2}/poe_tasks.toml +0 -0
  120. {comicforge-0.2.1 → comicforge-0.2.2}/skills/comicforge/SKILL.md +0 -0
  121. {comicforge-0.2.1 → comicforge-0.2.2}/skills/comicforge/reference.md +0 -0
  122. {comicforge-0.2.1 → comicforge-0.2.2}/tests/__init__.py +0 -0
  123. {comicforge-0.2.1 → comicforge-0.2.2}/tests/conftest.py +0 -0
  124. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_bubbles.py +0 -0
  125. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_caption.py +0 -0
  126. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_cli.py +0 -0
  127. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_inspire.py +0 -0
  128. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_library.py +0 -0
  129. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_pixelart.py +0 -0
  130. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_raster.py +0 -0
  131. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_render.py +0 -0
  132. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_scaffold.py +0 -0
  133. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_scene.py +0 -0
  134. {comicforge-0.2.1 → comicforge-0.2.2}/tests/test_validate.py +0 -0
@@ -120,3 +120,53 @@ broken cross-reference, a dead anchor, a missing snippet or a missing render.
120
120
  - Demo art is hand/LLM-authored crisp SVG, edited directly in `examples/pes/`
121
121
  (there is no procedural generator). Use `comicforge inspire` for *reference*
122
122
  images only — never auto-vectorize them; it breaks overlay/anchor registration.
123
+
124
+ ## Toolbox (aesop)
125
+
126
+ The [aesop toolbox](https://mojzis.github.io/aesop/llms.txt) is wired in. Every
127
+ tool documents itself: run `uv run <tool> guide` before guessing at flags
128
+ (`madoqua`, `gerenuk`, `biston`, `zorilla`, `pycoati`, `tyf`).
129
+
130
+ **On every commit** — `hooks/pre-commit` runs `madoqua`, which acts on the
131
+ staged `.py` files only (a commit with no `.py` staged runs nothing, silently):
132
+
133
+ - fix phase: `ruff check --fix`, `ruff format` (re-staged)
134
+ - check phase, in parallel: `ruff check`, `ty check`, `biston scan --focus-args`
135
+ (clone pairs touching a staged file), `zorilla check` (test smells in the
136
+ staged test files), `gerenuk run -- -q -o addopts=` (only the tests the diff
137
+ can reach, whole suite when unsure; diffs the *working tree* against
138
+ `origin/main`, so unstaged edits count)
139
+
140
+ Typical timing: `uv run madoqua stats` (log in `.git/hook-timings.jsonl`).
141
+ Skip one check for one run: `MADOQUA_SKIP="ty check" git commit ...`.
142
+ Known baseline: `tests/test_inspire.py` and `tests/test_scaffold.py` carry
143
+ ZR004 assertion-roulette findings — the hook blocks the next commit that
144
+ touches them until those tests are split. Config: `[tool.madoqua]` and
145
+ `[tool.biston.scan]` in `pyproject.toml`.
146
+
147
+ `poe check` / CI are unchanged and remain the whole-tree run.
148
+
149
+ **On demand** (never in the hook):
150
+
151
+ - symbols — use `uv run tyf` instead of grep for definitions and references:
152
+ `uv run tyf find <name>`, `uv run tyf show <name> -r`, `uv run tyf refs <name>`.
153
+ Stale results after big edits: `uv run tyf daemon stop` (next query restarts it).
154
+ - `uv run gerenuk impacted-tests` — which tests the current diff reaches, and why.
155
+ - `uv run gerenuk audit <file>` — symbols in a module nothing references.
156
+ - `uv run pycoati . --format pretty` — periodic test-suite audit: ranks every
157
+ test by suspicion with a remediation ladder. Run before a test cleanup session.
158
+ Not a hook, not CI. Needs pytest-cov (installed) or coverage is silently null.
159
+ - `uv run biston scan .` / `uv run zorilla check .` — whole-tree clone / test-smell scan.
160
+
161
+ **Fresh clone:** `uv sync` (add `--group docs` / `--extra inspire` as needed),
162
+ then `uv run madoqua install` once — `core.hooksPath` is local git config, the
163
+ shim in `hooks/` is committed.
164
+
165
+ **Refresh the toolbox:**
166
+
167
+ ```bash
168
+ uv lock --refresh --upgrade-package madoqua --upgrade-package gerenuk --upgrade-package biston --upgrade-package zorilla --upgrade-package pycoati --upgrade-package ty-find && uv sync
169
+ ```
170
+
171
+ (`--refresh` matters: without it uv may serve a cached index and miss a release
172
+ published minutes ago.)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: comicforge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A tiny, scriptable comic-page engine — author comics as YAML, render to SVG / PNG / PDF
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: cairosvg>=2.7
@@ -76,7 +76,8 @@ def load_items(path: Path) -> list[Item]:
76
76
  Each entry needs an id (``id`` / ``name``) and a description
77
77
  (``prompt`` / ``description`` / ``desc``).
78
78
  """
79
- data = yaml.safe_load(path.read_text(encoding="utf-8"))
79
+ text = path.read_text(encoding="utf-8")
80
+ data = yaml.safe_load(text)
80
81
  raw = data.get("items", []) if isinstance(data, dict) else data
81
82
  if not isinstance(raw, list):
82
83
  # malformed config, not a type bug -> ValueError is the right contract
@@ -1,4 +1,4 @@
1
- """Load the scene library and compose a scene background.
1
+ """Load the scene library and compose a scene background (base + overlays).
2
2
 
3
3
  A scene is a directory mirroring a character:
4
4
  base.svg, <slot>-<variant>.svg, scene.yaml
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ root=$(git rev-parse --show-toplevel)
3
+ [ -x "$root/.venv/bin/madoqua" ] && exec "$root/.venv/bin/madoqua" run
4
+ exec madoqua run
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "comicforge"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "A tiny, scriptable comic-page engine — author comics as YAML, render to SVG / PNG / PDF"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -52,6 +52,11 @@ dev = [
52
52
  "deptry",
53
53
  "biston>=0.5.0",
54
54
  "poethepoet",
55
+ "madoqua>=0.2.2",
56
+ "gerenuk>=0.3.1",
57
+ "zorilla>=0.2.1",
58
+ "pycoati>=0.2.7",
59
+ "ty-find>=0.5.0",
55
60
  ]
56
61
 
57
62
  [tool.ruff]
@@ -96,3 +101,21 @@ min_confidence = 80
96
101
 
97
102
  [tool.poe]
98
103
  include = "poe_tasks.toml"
104
+
105
+ # --- aesop toolbox -----------------------------------------------------------
106
+ # madoqua is the commit hook (hooks/pre-commit shim; `uv run madoqua install`
107
+ # once per clone). Fix phase: ruff check --fix, ruff format. Check phase: ruff
108
+ # check, ty check, plus the siblings below. See CLAUDE.md "Toolbox".
109
+ [tool.madoqua]
110
+ extend_check = [
111
+ # madoqua appends the staged .py files. biston reads them as --focus-args focus
112
+ # files (only clone pairs touching a staged file); zorilla lints exactly those.
113
+ { name = "biston", cmd = "biston scan --focus-args", timeout_s = 60, max_output_lines = 80 },
114
+ { name = "zorilla", cmd = "zorilla check", timeout_s = 30, max_output_lines = 80 },
115
+ # gerenuk scopes itself from the git diff, so no file list. `-o addopts=`
116
+ # drops the --cov from [tool.pytest.ini_options] in the hook (same as `poe test`).
117
+ { name = "gerenuk", cmd = "gerenuk run -- -q -o addopts=", pass_files = false, timeout_s = 120, max_output_lines = 120 },
118
+ ]
119
+
120
+ [tool.biston.scan]
121
+ exclude = ["tests/**", "**/conftest.py"]
@@ -47,13 +47,13 @@ wheels = [
47
47
 
48
48
  [[package]]
49
49
  name = "biston"
50
- version = "0.5.0"
50
+ version = "0.7.2"
51
51
  source = { registry = "https://pypi.org/simple" }
52
- sdist = { url = "https://files.pythonhosted.org/packages/e1/35/ac5828c2744716da22aa52af700cd9521781b914045f264a9ab53654108d/biston-0.5.0.tar.gz", hash = "sha256:289b1a9a6d8811b04fb049ef01cc4834f2c37434e8235bad01892012d01b79ea", size = 882675, upload-time = "2026-04-16T21:39:38.738Z" }
52
+ sdist = { url = "https://files.pythonhosted.org/packages/88/42/08c323c5bd20b274aa6576192c1a07a089e70413a73e7da9cea0713ae029/biston-0.7.2.tar.gz", hash = "sha256:04d0245f75f535a726768866f97d60bbf7ad862ccd45345a84280a971ac063bf", size = 973137, upload-time = "2026-09-06T09:43:50.91Z" }
53
53
  wheels = [
54
- { url = "https://files.pythonhosted.org/packages/44/97/e255f980ba62ff27cd2d212a66562eb20d804c3d3a5779aadfc583dab59a/biston-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fb63fbca3d059c8bb750d79de016e1d606e577b83b5c513931679323c995756c", size = 1405240, upload-time = "2026-04-16T21:39:33.562Z" },
55
- { url = "https://files.pythonhosted.org/packages/ae/ae/c5b9bcbdbd7eafa4001169275b4d4f2f1f96ef12bc35140c95a5dc9b3a2d/biston-0.5.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:6836af938703d5a1248204729432f9c42115eb4123ae838a405ac8e69e0897d8", size = 1623075, upload-time = "2026-04-16T21:39:35.316Z" },
56
- { url = "https://files.pythonhosted.org/packages/e2/62/0da884c32b256b56ee61d91ae55de4082dff5841984bf6644431eed9b1f1/biston-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e2cf9ebf029958eb1e78215df301cc6d5b8885e2d6b80f744ba47c9c0285c289", size = 1477973, upload-time = "2026-04-16T21:39:37.063Z" },
54
+ { url = "https://files.pythonhosted.org/packages/05/2a/f7549966fa83f73237c95f0e1c7c154197e3dac8d514ce74c07665c7e42d/biston-0.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8dd795b2f48bb60a9f8942187b9c0eb55fbe13d3f0f22ec2bde524a830c2d31b", size = 1515854, upload-time = "2026-09-06T09:43:45.099Z" },
55
+ { url = "https://files.pythonhosted.org/packages/b5/bb/ea8082d3234e5ab538d26f13fe65fe05cc153c5f92be07e2e03663515cc5/biston-0.7.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:e68b7d10c0c5359f75dc52630b1124d16f8af1794154dc3be873569de5cb1ffc", size = 1750729, upload-time = "2026-09-06T09:43:46.991Z" },
56
+ { url = "https://files.pythonhosted.org/packages/c0/ca/a09aea13c2cbfce4cef26f1a68594c1634b632bf645ddb578760fbbb9fc6/biston-0.7.2-py3-none-win_amd64.whl", hash = "sha256:490037b14cf366a53d49edc1ae10258de3a794f4b5742653ad17f9ce8b0afd7b", size = 1603046, upload-time = "2026-09-06T09:43:49.098Z" },
57
57
  ]
58
58
 
59
59
  [[package]]
@@ -276,7 +276,7 @@ wheels = [
276
276
 
277
277
  [[package]]
278
278
  name = "comicforge"
279
- version = "0.2.1"
279
+ version = "0.2.2"
280
280
  source = { editable = "." }
281
281
  dependencies = [
282
282
  { name = "cairosvg" },
@@ -294,12 +294,17 @@ inspire = [
294
294
  dev = [
295
295
  { name = "biston" },
296
296
  { name = "deptry" },
297
+ { name = "gerenuk" },
298
+ { name = "madoqua" },
297
299
  { name = "poethepoet" },
300
+ { name = "pycoati" },
298
301
  { name = "pytest" },
299
302
  { name = "pytest-cov" },
300
303
  { name = "ruff" },
301
304
  { name = "ty" },
305
+ { name = "ty-find" },
302
306
  { name = "vulture" },
307
+ { name = "zorilla" },
303
308
  ]
304
309
  docs = [
305
310
  { name = "mkdocs-material" },
@@ -319,12 +324,17 @@ provides-extras = ["inspire"]
319
324
  dev = [
320
325
  { name = "biston", specifier = ">=0.5.0" },
321
326
  { name = "deptry" },
327
+ { name = "gerenuk", specifier = ">=0.3.1" },
328
+ { name = "madoqua", specifier = ">=0.2.2" },
322
329
  { name = "poethepoet" },
330
+ { name = "pycoati", specifier = ">=0.2.7" },
323
331
  { name = "pytest" },
324
332
  { name = "pytest-cov" },
325
333
  { name = "ruff" },
326
334
  { name = "ty" },
335
+ { name = "ty-find", specifier = ">=0.5.0" },
327
336
  { name = "vulture" },
337
+ { name = "zorilla", specifier = ">=0.2.1" },
328
338
  ]
329
339
  docs = [{ name = "mkdocs-material", specifier = ">=9.5" }]
330
340
 
@@ -442,6 +452,20 @@ wheels = [
442
452
  { url = "https://files.pythonhosted.org/packages/c7/7f/cd6b3ac8cf95f2f1c5c7a74ff6452e9098af89a9b56607381f677880641e/deptry-0.25.1-cp310-abi3-win_arm64.whl", hash = "sha256:6efffd8116fb9d2c45a251382ce4ce1c38dbb17179f581ec9231ed5390f7fc12", size = 1647020, upload-time = "2026-03-18T23:22:23.311Z" },
443
453
  ]
444
454
 
455
+ [[package]]
456
+ name = "gerenuk"
457
+ version = "0.3.1"
458
+ source = { registry = "https://pypi.org/simple" }
459
+ dependencies = [
460
+ { name = "ty-find" },
461
+ ]
462
+ sdist = { url = "https://files.pythonhosted.org/packages/b6/d7/30c04740c694ebe0a6bfd17ecb90553ee41274033adeae787cfb369ce31d/gerenuk-0.3.1.tar.gz", hash = "sha256:0938a056fc46440f3b3a83c465526247f1815f05ed0aab26401cd8bdd8b3b727", size = 1057582, upload-time = "2026-09-06T10:17:40.989Z" }
463
+ wheels = [
464
+ { url = "https://files.pythonhosted.org/packages/1d/5a/97341a2ab50e0fd73b812878d459bceec2edd54359555ba0ee4e4ce7afc2/gerenuk-0.3.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e33289016c58ec81b1afbac0c1ae59ce2caddde2264a29f46d70bce7f7030af2", size = 1156041, upload-time = "2026-09-06T10:17:36.762Z" },
465
+ { url = "https://files.pythonhosted.org/packages/1b/b9/2644c11616691979f0025be61269f4be04442c79fbd7d814b26b1ac59f32/gerenuk-0.3.1-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:d80528e96c195133a9cc2c7f0470413c97dceab86afd1437a213e96e78479c55", size = 1321715, upload-time = "2026-09-06T10:17:38.138Z" },
466
+ { url = "https://files.pythonhosted.org/packages/e9/1e/8039f351bcbc75f4b648ac2a98c58e832a3b41bbf354751b64300820fa5b/gerenuk-0.3.1-py3-none-win_amd64.whl", hash = "sha256:82e47509c9f101298d2a3c865fa3a9c4977f7fa632b11be6e190c4dbb79d76e9", size = 1224539, upload-time = "2026-09-06T10:17:39.69Z" },
467
+ ]
468
+
445
469
  [[package]]
446
470
  name = "ghp-import"
447
471
  version = "2.1.0"
@@ -521,6 +545,17 @@ wheels = [
521
545
  { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
522
546
  ]
523
547
 
548
+ [[package]]
549
+ name = "madoqua"
550
+ version = "0.2.2"
551
+ source = { registry = "https://pypi.org/simple" }
552
+ sdist = { url = "https://files.pythonhosted.org/packages/9d/47/b638680853d3a3fd05678acb31c125b2ee73c083998f45118fd201f01623/madoqua-0.2.2.tar.gz", hash = "sha256:799f70ae2eebaf8e3d8e296a1bc6af96459aa5ad6d6f683d2d0e85d2ef186d92", size = 886386, upload-time = "2026-09-06T10:16:31.566Z" }
553
+ wheels = [
554
+ { url = "https://files.pythonhosted.org/packages/5c/c1/558f9dff51b20e30297dfe144564313ca5eec797372e91af46e19883f0fd/madoqua-0.2.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:465a237666d16fa3365b92cfa58750e5bb94f8a95f7c6a3c022ffd342c6ff0e6", size = 756092, upload-time = "2026-09-06T10:16:26.915Z" },
555
+ { url = "https://files.pythonhosted.org/packages/c4/e0/edffd6b495454d77ece7a0bf522f7028f0ec6db60a4554cdd2c96c1890f3/madoqua-0.2.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f56ee6598683e276dcf5a00fccec2960cd166a8c4aa1dda61c82c6ef5c2de31f", size = 867899, upload-time = "2026-09-06T10:16:28.644Z" },
556
+ { url = "https://files.pythonhosted.org/packages/f5/ab/16170ffe43b4b0a088cf29507fe8102533a68afa620fa8d696c3f4c2dddd/madoqua-0.2.2-py3-none-win_amd64.whl", hash = "sha256:8cde9b4a776a39c6b92d72379c9d72f0de77e4019967a5ed7c275e1793b39725", size = 775267, upload-time = "2026-09-06T10:16:30.077Z" },
557
+ ]
558
+
524
559
  [[package]]
525
560
  name = "markdown"
526
561
  version = "3.10.3"
@@ -810,6 +845,17 @@ wheels = [
810
845
  { url = "https://files.pythonhosted.org/packages/af/01/a9d6ea30351919298d3dc237172ae6a60ce0224ecaaee289b671ab979c13/poethepoet-0.46.0-py3-none-any.whl", hash = "sha256:dc6d770a14792d124abac9066c5a707876027d1878ac9ca26cf57e9b2a96dc89", size = 150581, upload-time = "2026-05-15T15:52:01.118Z" },
811
846
  ]
812
847
 
848
+ [[package]]
849
+ name = "pycoati"
850
+ version = "0.2.7"
851
+ source = { registry = "https://pypi.org/simple" }
852
+ sdist = { url = "https://files.pythonhosted.org/packages/73/48/32a8a15278bf6d9fd32ae649988196f80a3fe7713fc9a239e0defa284e3b/pycoati-0.2.7.tar.gz", hash = "sha256:8479936109209afdf897576fab87b0a09b6d426815853db5f443583ba0d29d19", size = 145027, upload-time = "2026-09-06T10:16:32.865Z" }
853
+ wheels = [
854
+ { url = "https://files.pythonhosted.org/packages/92/77/428eb4adaa1e975d81bca60b18b373ec867301a643e5cde76eef8364aa60/pycoati-0.2.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9599833af88090e77025131a9903abcec274aadfe445cb8ef27c29e50b32fa68", size = 1381423, upload-time = "2026-09-06T10:16:27.856Z" },
855
+ { url = "https://files.pythonhosted.org/packages/5f/56/a5ac29ba05decede07697cf016c3de438205a1223dae2df424f46d223745/pycoati-0.2.7-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:83dcf7fee42e6b57720e9866526798a4a5f33053584e712818f151e593d523d2", size = 1596183, upload-time = "2026-09-06T10:16:29.778Z" },
856
+ { url = "https://files.pythonhosted.org/packages/04/21/c1b336047dd795cac09c1f95d7d57d04c66bc30fe4fa5afc51fbbe1804f3/pycoati-0.2.7-py3-none-win_amd64.whl", hash = "sha256:55923c3450026564925b2cde9784aae9bcf7642281c9662368dcfc6f903bc01f", size = 1472390, upload-time = "2026-09-06T10:16:31.404Z" },
857
+ ]
858
+
813
859
  [[package]]
814
860
  name = "pycparser"
815
861
  version = "3.0"
@@ -1173,6 +1219,17 @@ wheels = [
1173
1219
  { url = "https://files.pythonhosted.org/packages/ef/a2/8959249da951ba3977fee20e688d28678b8a1d30a9ed4464228a85d45853/ty-0.0.49-py3-none-win_arm64.whl", hash = "sha256:75d5e2e7649765f31f4bed6c8adb149a75b18edd3fa6336dac4d0efc1a66466f", size = 11558965, upload-time = "2026-06-12T03:08:23.012Z" },
1174
1220
  ]
1175
1221
 
1222
+ [[package]]
1223
+ name = "ty-find"
1224
+ version = "0.5.0"
1225
+ source = { registry = "https://pypi.org/simple" }
1226
+ sdist = { url = "https://files.pythonhosted.org/packages/c0/01/e96f1bde06497386f9cb3a33225aa19b0a7aa07e2adef184ffe108d2468e/ty_find-0.5.0.tar.gz", hash = "sha256:bab7b8a107048271431853d02ac988ed65a9566cd19c3db8f801efe6ff5c1172", size = 1045795, upload-time = "2026-09-06T09:42:18.33Z" }
1227
+ wheels = [
1228
+ { url = "https://files.pythonhosted.org/packages/01/81/9b5d590d72393b7092b83ca575e35320295de61911e9448bba152c6fa021/ty_find-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:41b641f3c43421d1500b1c796b437772d7b49863229bfd3ce247506d9c9edd83", size = 1262109, upload-time = "2026-09-06T09:42:12.622Z" },
1229
+ { url = "https://files.pythonhosted.org/packages/95/9d/1f5f744ad14f3259a03737c03b7d9d4f936969f91314f77627e3d0c42adb/ty_find-0.5.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:fed1dca32166800d391eb681050145104795418b7ac1413eb0987f88e6c4e9b7", size = 1443249, upload-time = "2026-09-06T09:42:14.728Z" },
1230
+ { url = "https://files.pythonhosted.org/packages/3e/e6/40493d4edf785ed26220d7e0ce56b4e5fe27175ed728e683c72717667c67/ty_find-0.5.0-py3-none-win_amd64.whl", hash = "sha256:dd2aca8b306b415a1bae6cc075201b287b95e78dd40d655b8c448e9c264b4661", size = 924217, upload-time = "2026-09-06T09:42:16.563Z" },
1231
+ ]
1232
+
1176
1233
  [[package]]
1177
1234
  name = "typing-extensions"
1178
1235
  version = "4.15.0"
@@ -1241,3 +1298,14 @@ sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda5308
1241
1298
  wheels = [
1242
1299
  { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" },
1243
1300
  ]
1301
+
1302
+ [[package]]
1303
+ name = "zorilla"
1304
+ version = "0.2.1"
1305
+ source = { registry = "https://pypi.org/simple" }
1306
+ sdist = { url = "https://files.pythonhosted.org/packages/eb/5a/601682072eafda550b7441ff30af74bd729a6b1618221c8929efcefa6828/zorilla-0.2.1.tar.gz", hash = "sha256:565e57d75bd2cb05519e73ebdbe0fe821362329d1748b4443122db255f82519c", size = 146975, upload-time = "2026-09-06T09:44:02.027Z" }
1307
+ wheels = [
1308
+ { url = "https://files.pythonhosted.org/packages/0b/b0/e8da970248940cd0135b5dd119df4dd142f8b2eaea4f3b124fa9f5a03da0/zorilla-0.2.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d5022e7ecd35e9f82486ba51d54b1f128261ae6f067cd8c6c009017d2b3b1ca9", size = 1190635, upload-time = "2026-09-06T09:43:57.396Z" },
1309
+ { url = "https://files.pythonhosted.org/packages/6f/24/b1f7ed13b369a29b0277079192e88e6b5dc431004c0ef0ff61bf65117788/zorilla-0.2.1-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:74d68dc2ae4e681380e818a3aa9c032f904685d613249a9d8d3371c1eef61236", size = 1386039, upload-time = "2026-09-06T09:43:59.027Z" },
1310
+ { url = "https://files.pythonhosted.org/packages/9f/a1/9fcda70e96ca6eadad92a42ed93cd46b5aa63508d21554837791eafec370/zorilla-0.2.1-py3-none-win_amd64.whl", hash = "sha256:c1a6c1fb8e6ce0f6724eb782e41fb4eb607fc78e1346ee8027f2c165d0109727", size = 1261320, upload-time = "2026-09-06T09:44:00.554Z" },
1311
+ ]
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