hatchsvg 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. hatchsvg-2.0.0/.github/workflows/ci.yml +50 -0
  2. hatchsvg-2.0.0/.github/workflows/workflow.yml +75 -0
  3. hatchsvg-2.0.0/.gitignore +100 -0
  4. hatchsvg-2.0.0/Bluey-orig.png +0 -0
  5. hatchsvg-2.0.0/Bluey.png +0 -0
  6. hatchsvg-2.0.0/CHANGELOG.md +198 -0
  7. hatchsvg-2.0.0/LICENSE +21 -0
  8. hatchsvg-2.0.0/PKG-INFO +310 -0
  9. hatchsvg-2.0.0/README.md +274 -0
  10. hatchsvg-2.0.0/color_palettes/crayola_10ct_fine_line_classic.json +17 -0
  11. hatchsvg-2.0.0/color_palettes/jot_20ct_washable_fineline.json +27 -0
  12. hatchsvg-2.0.0/examples/README.md +50 -0
  13. hatchsvg-2.0.0/examples/scene.png +0 -0
  14. hatchsvg-2.0.0/examples/scene_fast.svg +6 -0
  15. hatchsvg-2.0.0/examples/scene_logo.svg +10 -0
  16. hatchsvg-2.0.0/examples/scene_portrait.svg +6 -0
  17. hatchsvg-2.0.0/examples/scene_sketch.svg +6 -0
  18. hatchsvg-2.0.0/notebooks/README.md +125 -0
  19. hatchsvg-2.0.0/notebooks/craft.ipynb +560 -0
  20. hatchsvg-2.0.0/notebooks/craft_executed.ipynb +835 -0
  21. hatchsvg-2.0.0/notebooks/explore.ipynb +345 -0
  22. hatchsvg-2.0.0/notebooks/explore_executed.ipynb +667 -0
  23. hatchsvg-2.0.0/notebooks/notebook_helpers.py +756 -0
  24. hatchsvg-2.0.0/notebooks/quickstart.ipynb +205 -0
  25. hatchsvg-2.0.0/notebooks/quickstart_executed.ipynb +406 -0
  26. hatchsvg-2.0.0/pyproject.toml +103 -0
  27. hatchsvg-2.0.0/scripts/build_notebooks.py +711 -0
  28. hatchsvg-2.0.0/scripts/png2svg_legacy.py +1328 -0
  29. hatchsvg-2.0.0/scripts/verify_notebooks.sh +90 -0
  30. hatchsvg-2.0.0/scripts/verify_notebooks_helpers.py +115 -0
  31. hatchsvg-2.0.0/src/hatchsvg/__init__.py +15 -0
  32. hatchsvg-2.0.0/src/hatchsvg/__main__.py +6 -0
  33. hatchsvg-2.0.0/src/hatchsvg/cli.py +411 -0
  34. hatchsvg-2.0.0/src/hatchsvg/core.py +1662 -0
  35. hatchsvg-2.0.0/src/hatchsvg/presets.py +114 -0
  36. hatchsvg-2.0.0/tests/__init__.py +0 -0
  37. hatchsvg-2.0.0/tests/conftest.py +59 -0
  38. hatchsvg-2.0.0/tests/fixtures/bluey_golden.svg +5 -0
  39. hatchsvg-2.0.0/tests/integration/__init__.py +0 -0
  40. hatchsvg-2.0.0/tests/integration/test_cli.py +387 -0
  41. hatchsvg-2.0.0/tests/integration/test_e2e.py +130 -0
  42. hatchsvg-2.0.0/tests/integration/test_notebook_helpers.py +190 -0
  43. hatchsvg-2.0.0/tests/integration/test_verify_notebook_helpers.py +272 -0
  44. hatchsvg-2.0.0/tests/unit/__init__.py +0 -0
  45. hatchsvg-2.0.0/tests/unit/test_color.py +54 -0
  46. hatchsvg-2.0.0/tests/unit/test_hatch.py +57 -0
  47. hatchsvg-2.0.0/tests/unit/test_input_formats.py +49 -0
  48. hatchsvg-2.0.0/tests/unit/test_optimize_layer_order.py +77 -0
  49. hatchsvg-2.0.0/tests/unit/test_palette.py +33 -0
  50. hatchsvg-2.0.0/tests/unit/test_preset_config.py +148 -0
  51. hatchsvg-2.0.0/tests/unit/test_presets.py +104 -0
  52. hatchsvg-2.0.0/tests/unit/test_render_layer.py +110 -0
  53. hatchsvg-2.0.0/tests/unit/test_sanitize_filename.py +47 -0
  54. hatchsvg-2.0.0/tests/unit/test_segments.py +31 -0
  55. hatchsvg-2.0.0/tests/unit/test_session.py +45 -0
@@ -0,0 +1,50 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: test (${{ matrix.os }}, Python ${{ matrix.python-version }})
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, macos-latest]
17
+ python-version: ["3.11", "3.12", "3.13"]
18
+
19
+ steps:
20
+ - name: Check out repository
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Set up Python ${{ matrix.python-version }}
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ cache: pip
28
+ cache-dependency-path: pyproject.toml
29
+
30
+ - name: Install package with dev and plot extras
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ pip install -e ".[dev,plot]"
34
+
35
+ - name: Lint with ruff
36
+ run: |
37
+ ruff check src tests
38
+ ruff format --check src tests
39
+
40
+ - name: Run tests with coverage
41
+ run: |
42
+ pytest --cov=png2svg --cov-report=xml --cov-report=term-missing
43
+
44
+ - name: Upload coverage to Codecov
45
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
46
+ uses: codecov/codecov-action@v4
47
+ with:
48
+ file: coverage.xml
49
+ flags: unittests
50
+ fail_ci_if_error: false
@@ -0,0 +1,75 @@
1
+ name: Publish to PyPI
2
+
3
+ # Trusted publishing workflow for hatchsvg.
4
+ # PyPI was configured to trust this workflow via:
5
+ # Project: hatchsvg
6
+ # Repository: Veedubin/hatchsvg
7
+ # Workflow: workflow.yml
8
+ # Environment: pypi
9
+ #
10
+ # Trigger options:
11
+ # 1. workflow_dispatch: manual run from the Actions tab (useful for re-publishing
12
+ # a tag or publishing from a non-tag commit)
13
+ # 2. push tag v*: automatic publish on every v*.*.* tag push
14
+ #
15
+ # To publish a new release:
16
+ # - Update __version__ in src/hatchsvg/__init__.py
17
+ # - Commit, tag: git tag -a v2.1.0 -m "..." && git push origin v2.1.0
18
+ # - The tag push triggers this workflow automatically
19
+ # - Or trigger manually via the Actions tab for ad-hoc publishes
20
+
21
+ on:
22
+ workflow_dispatch:
23
+ push:
24
+ tags:
25
+ - "v*.*.*"
26
+
27
+ jobs:
28
+ build:
29
+ name: Build sdist + wheel
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Check out repository
33
+ uses: actions/checkout@v4
34
+
35
+ - name: Set up Python
36
+ uses: actions/setup-python@v5
37
+ with:
38
+ python-version: "3.12"
39
+
40
+ - name: Install build tooling
41
+ run: python -m pip install --upgrade build
42
+
43
+ - name: Build distributions
44
+ run: python -m build
45
+
46
+ - name: Check distributions
47
+ run: python -m pip install twine && twine check dist/*
48
+
49
+ - name: Upload build artifacts
50
+ uses: actions/upload-artifact@v4
51
+ with:
52
+ name: dist
53
+ path: dist/
54
+
55
+ publish:
56
+ name: Publish to PyPI
57
+ runs-on: ubuntu-latest
58
+ needs: build
59
+ environment:
60
+ name: pypi
61
+ url: https://pypi.org/p/hatchsvg
62
+ permissions:
63
+ # OIDC token for PyPI trusted publishing
64
+ id-token: write
65
+ steps:
66
+ - name: Download build artifacts
67
+ uses: actions/download-artifact@v4
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+
72
+ - name: Publish to PyPI
73
+ uses: pypa/gh-action-pypi-publish@release/v1
74
+ # No environment, no token — PyPI trusted publishing handles auth
75
+ # automatically via the GitHub OIDC token exchange.
@@ -0,0 +1,100 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ build/
9
+ develop-eggs/
10
+ dist/
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ wheels/
20
+ *.egg-info/
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Installer logs
25
+ pip-log.txt
26
+ pip-delete-this-directory.txt
27
+
28
+ # Unit test / coverage reports
29
+ htmlcov/
30
+ .tox/
31
+ .nox/
32
+ .coverage
33
+ .coverage.*
34
+ .cache
35
+ .pytest_cache/
36
+ coverage.xml
37
+ *.cover
38
+
39
+ # uv lockfile (dev environment)
40
+ uv.lock
41
+
42
+ # ruff / mypy
43
+ .ruff_cache/
44
+ .mypy_cache/
45
+
46
+ # Environments
47
+ .env
48
+ .venv
49
+ env/
50
+ venv/
51
+ ENV/
52
+ env.bak/
53
+ venv.bak/
54
+
55
+ # IDEs
56
+ .idea/
57
+ .vscode/
58
+ *.swp
59
+ *.swo
60
+ .DS_Store
61
+
62
+ # png2svg-specific
63
+ *.session.json
64
+ !color_palettes/
65
+ memory_data/
66
+
67
+ # Boomerang plugin / session artifacts — these are tooling for the
68
+ # development environment that lives alongside this repo, NOT part
69
+ # of the png2svg project itself. They should never be committed to
70
+ # this repo. (If you want to track plugin behavior, use a separate
71
+ # repo for the plugin.)
72
+ .opencode/
73
+ AGENTS.md
74
+ PLAN.md
75
+ REVIEW.md
76
+
77
+ # AI assistant session documents — internal development notes that
78
+ # were committed in error before .gitignore patterns were added.
79
+ # The package, tests, and user-facing docs (README, CHANGELOG, LICENSE)
80
+ # are the only public artifacts that should ever ship on GitHub.
81
+ CONTEXT_png2svg.md
82
+ GUI_ARCHITECTURE.md
83
+ HANDOFF.md
84
+ ROADMAP.md
85
+ SETUP.md
86
+ TASKS.md
87
+
88
+ # AI session memory backup (when memini-ai MCP transport is down)
89
+ .session-memory/
90
+
91
+ # Notebook runtime outputs (created when users run the notebooks)
92
+ # Keep the *_executed.ipynb files (committed for reviewers) but
93
+ # exclude user-generated outputs that appear in the working tree
94
+ notebooks/my_*.svg
95
+ notebooks/my_*.json
96
+ notebooks/explore_output.svg
97
+ notebooks/explore_session.json
98
+ notebooks/craft_session.json
99
+ notebooks/batch_output/
100
+ notebooks/__pycache__/
Binary file
Binary file
@@ -0,0 +1,198 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.0.0] - 2026-06-17
9
+
10
+ ### ⚠️ BREAKING CHANGE: rename `png2svg` → `hatchsvg`
11
+
12
+ The package has been renamed from `png2svg` to `hatchsvg` to match
13
+ the GitHub repository name (`github.com/Veedubin/hatchsvg`) and to
14
+ better describe the algorithm. **The repo was renamed to `hatchsvg`
15
+ in v1.1.1; this release brings the package in line.**
16
+
17
+ ### Migration guide
18
+
19
+ | Old (v1.2.0) | New (v2.0.0) |
20
+ |--------------|--------------|
21
+ | `pip install png2svg` | `pip install hatchsvg` |
22
+ | `import png2svg` | `import hatchsvg` |
23
+ | `png2svg photo.jpg out.svg` | `hatchsvg photo.jpg out.svg` |
24
+ | `python -m png2svg` | `python -m hatchsvg` |
25
+ | `from png2svg.core import ...` | `from hatchsvg.core import ...` |
26
+ | `from png2svg.presets import ...` | `from hatchsvg.presets import ...` |
27
+ | `src/png2svg/` directory | `src/hatchsvg/` directory |
28
+ | Internal attribute `_png2svg_parser` | `_hatchsvg_parser` |
29
+
30
+ ### Why a major bump (v2.0.0)?
31
+
32
+ Per [SemVer](https://semver.org/), any backward-incompatible change
33
+ to the public API requires a major version bump. The rename touches:
34
+
35
+ - **PyPI package name** (`pip install` no longer finds `png2svg`)
36
+ - **Import name** (`import png2svg` raises `ModuleNotFoundError`)
37
+ - **CLI command** (`png2svg` command no longer exists)
38
+ - **Module path** (`python -m png2svg` fails)
39
+
40
+ The CLI flags, file output, session JSON schema, palette JSON
41
+ schema, and Python API function signatures are unchanged.
42
+
43
+ ### What did NOT change
44
+
45
+ - 114 tests still pass
46
+ - Golden file is byte-identical
47
+ - All v1.2.0 CLI flags work the same
48
+ - Output SVG format unchanged
49
+
50
+ ### Migration shim
51
+
52
+ A compatibility shim is **not** shipped in v2.0.0. If you need to
53
+ keep `png2svg` working for existing scripts, add this to your
54
+ project's `requirements.txt`:
55
+
56
+ ```
57
+ hatchsvg>=2.0.0
58
+ ```
59
+
60
+ Then in your code, change `import png2svg` to `import hatchsvg as png2svg`.
61
+ A standalone `png2svg` PyPI shim package that depends on `hatchsvg`
62
+ may be added in v2.1.0 if user demand warrants it.
63
+
64
+ ## [1.2.0] - 2026-06-17
65
+
66
+ ### Added
67
+ - **`--preview`** — opens the output SVG in the default system viewer after render (uses stdlib `webbrowser`)
68
+ - **`--split-layers`** — writes one SVG file per color layer alongside the main output (`<stem>_<NN>_<color>.svg`)
69
+ - **`--optimize-travel`** — reorders layers using greedy nearest-neighbor to minimize pen-up travel distance
70
+ - **`--hatch-angles`** — comma-separated hatch rotation per layer in degrees (e.g. `--hatch-angles=0,45,90,135`)
71
+ - **`--help` examples** — 5 inline examples below the presets block in `hatchsvg --help` output
72
+ - **ViewBox normalization** — viewBox values are now always integer strings (no floats) for Cricut Design Space compatibility
73
+ - **`render_single_layer_svg()`** — new public function in `core.py` for per-layer SVG rendering (used by `--split-layers`)
74
+ - **`optimize_layer_order()`** — new public function in `core.py` for nearest-neighbor layer reordering (used by `--optimize-travel`)
75
+ - **Test count** — 88 → 98 (new tests for all 6 features)
76
+
77
+ ### Changed
78
+ - `RenderParams` gained two additive fields: `hatch_angles: Optional[List[float]]` and `hatch_angle: float` (both backward-compatible defaults)
79
+ - `process_image_to_hatched_svg()` gained an `optimize_travel: bool = False` parameter (backward-compatible)
80
+
81
+ ## [1.1.1] - 2026-06-16
82
+
83
+ ### Fixed
84
+ - **`save_session` JSON serialization bug** (`src/hatchsvg/core.py:484`) — when
85
+ `--save-session` was used, the color_map contained numpy `uint32` scalars
86
+ from the quantization path and `json.dump` raised
87
+ `TypeError: Object of type uint32 is not JSON serializable`. The bug
88
+ was in the codebase since v1.0.0 but only ever triggered for users
89
+ who ran `--save-session`. The fix coerces each RGB value to a plain
90
+ Python `int` at the serialization boundary (RGB is conceptually 8-bit
91
+ so no precision is lost). Caught by a new test, not by a linter or
92
+ type-checker — see [Discipline note](#discipline-note).
93
+ - **Notebook byte-stability** (`scripts/build_notebooks.py`,
94
+ `scripts/verify_notebooks_helpers.py`) — three non-determinism sources
95
+ in the executed notebooks: (1) random `cell.id` values assigned by
96
+ `nbformat.v4.new_code_cell` — fixed with `_assign_stable_ids(nb, prefix)`
97
+ producing `f"{prefix}-cell-{i:02d}"` IDs; (2) wall-clock timing
98
+ prints (`print(f'Render took ...s')`) and timing fields in
99
+ `format_quantize_report` / `format_render_report` — removed; (3)
100
+ Jupyter kernel execution timestamps in
101
+ `cell.metadata.execution` (note: nested, not in
102
+ `output.metadata.execution`) — stripped post-execution. Three
103
+ consecutive `verify_notebooks.sh` runs now produce identical `sha256`.
104
+
105
+ ### Removed
106
+ - **Duplicate `main()` in `src/hatchsvg/core.py`** (54 lines, lines
107
+ 1405-1458 prior to removal) — never called, dead code. The real CLI
108
+ entry point is `hatchsvg.cli:main` per the `[project.scripts]`
109
+ table in `pyproject.toml`. Removed along with an unused
110
+ `import argparse` that was the only consumer.
111
+ - **Untracked planning/session documents** — `AGENTS.md`, `PLAN.md`,
112
+ `REVIEW.md`, `CONTEXT_hatchsvg.md`, `GUI_ARCHITECTURE.md`, `HANDOFF.md`,
113
+ `ROADMAP.md`, `SETUP.md`, `TASKS.md`, and `.opencode/` are now in
114
+ `.gitignore` and removed from tracking. These are internal AI
115
+ development notes that should never have been in a public repo.
116
+ The package, tests, and user-facing docs (`README`, `CHANGELOG`,
117
+ `LICENSE`) are the only public artifacts that ship on GitHub.
118
+
119
+ ### Changed
120
+ - **Per-file ruff ignores** in `pyproject.toml` — added `notebooks/*.ipynb`
121
+ (ignores `I001`/`E402`/`F811` for Jupyter cell architecture) and
122
+ `notebooks/*_executed.ipynb` (ignores all rules for generated output).
123
+ `scripts/hatchsvg_legacy.py` now ignores `I001` in addition to its
124
+ existing rule groups. Resolves 50 lint errors without restructuring
125
+ notebook sources.
126
+ - **`scripts/verify_notebooks_helpers.py`** (new) — Python module
127
+ extracted from inline `python - <<PY` heredocs in
128
+ `verify_notebooks.sh`. Two functions, `check_for_errors(nb_path)`
129
+ and `strip_execution_timestamps(nb_path)`, plus a `__main__` CLI
130
+ (`check` and `strip` subcommands). Enables 15 new unit tests
131
+ for previously-untestable inline code.
132
+ - **Test count** — 70 → 88 tests; coverage 58% → 60%.
133
+
134
+ ### Discipline note
135
+
136
+ The `save_session` JSON bug had been in the codebase since v1.0.0
137
+ and was *only* caught by writing a new test
138
+ (`test_cli_save_session_roundtrip`). Neither `ruff`, `ruff format`,
139
+ nor static type analysis flagged it. A linter will never find a
140
+ type that survives the boundary between numpy and stdlib. **Always
141
+ include a "test quality" agent in any code review pass, and always
142
+ run the new tests before declaring the review done.** The same
143
+ session also caught — and shipped the fix for — a subtle Jupyter
144
+ internals issue: kernel execution timestamps live in
145
+ `cell.metadata.execution` (a *nested* dict), not in
146
+ `output.metadata.execution`. The wrong-tree-level bug took two
147
+ debug iterations to diagnose.
148
+
149
+ ## [1.1.0] - 2026-06-16
150
+
151
+ ### Added
152
+ - **Three tutorial notebooks** in `notebooks/`:
153
+ - `quickstart.ipynb` — 5 cells, ~5 minutes, copy-paste-done path
154
+ - `explore.ipynb` — 6 cells, 4-stage walkthrough with explanations and 2a/2b/2c branches for color matching
155
+ - `craft.ipynb` — 5 cells, advanced usage: custom palettes, per-color remap, session save/load, batch processing, parameter deep-dive, comparison with adjacent tools
156
+ - **Shared `notebooks/notebook_helpers.py`** — thin wrappers around `hatchsvg.core` (load_image, quantize_image, match_to_palette, render_svg, snapshot_session, etc.). No magic — every function is a one-liner around a `core` call.
157
+ - **`notebooks/README.md`** — entry point that says "start with quickstart, then explore, then craft"
158
+ - **`scripts/build_notebooks.py`** — programmatic notebook builder (notebooks are reviewable as Python in PRs, not as JSON)
159
+ - **`scripts/verify_notebooks.sh`** — CI script that runs all 3 notebooks end-to-end via `nbconvert --execute` and checks for errors
160
+ - **10 smoke tests** in `tests/integration/test_notebook_helpers.py` covering helper imports, palette loading, quantization, session save/load
161
+ - **`[notebook]` extra** in `pyproject.toml`: `jupyter`, `ipykernel`, `matplotlib`, `nbformat`
162
+ - **Per-file ruff ignores** for `scripts/hatchsvg_legacy.py` (pre-existing bugs in the preserved legacy file)
163
+ - **Named presets** — `--preset portrait|logo|line-art|photo|sketch|fast` for common use cases; explicit CLI flags override preset values
164
+ - **Multi-format input** — CLI now accepts `.png`, `.jpg`, `.jpeg`, `.webp`, `.bmp`, `.gif`, `.tiff`, `.tif` (Pillow decodes; CLI validates extension with a friendly error)
165
+ - **New module `hatchsvg.presets`** — typed `PRESETS` dict with 6 hand-tuned presets, `list_presets()`, `get_preset()`, `apply_preset()`; ships with 6 hand-tuned presets
166
+ - **`get_run_configuration(args, preset_name=...)`** — preset-aware variant of the CLI config loader; explicit CLI flags still win over preset defaults
167
+ - **21 new tests** in `test_presets.py` (13 tests) and `test_preset_config.py` (8 tests); all preset fields validated against `RenderParams` dataclass
168
+ - **8 new CLI integration tests** in `tests/integration/test_cli.py` — full subprocess coverage of `--version`, `--help`, presets, multi-format input, error handling
169
+ - **`examples/` directory** with `scene.png` (procedural 200×200 input) and 4 output SVGs demonstrating each preset (fast/portrait/logo/sketch)
170
+
171
+ ### Changed
172
+ - **README rewrite** — new quickstart, comparison table vs potrace/vtracer/Inkscape, full CLI flag table, 5+ Cookbook recipes, expanded project structure
173
+ - **Test count** — 27 → 70 tests; coverage 49% → 58%; `presets.py` 100% covered, `notebook_helpers.py` ~60% covered
174
+
175
+ ## [1.0.0] - 2026-06-15
176
+
177
+ ### Added
178
+ - MIT license
179
+ - `pyproject.toml` with hatchling build system
180
+ - `--version` flag (`hatchsvg --version` → `hatchsvg 1.0.0`)
181
+ - Friendly error messages for `SystemExit` and palette loading failures
182
+ - Test suite: 8 unit tests + 1 end-to-end integration test with golden-file comparison
183
+ - GitHub Actions CI matrix (Linux + macOS, Python 3.11 / 3.12 / 3.13)
184
+ - `CHANGELOG.md` (this file)
185
+ - `.gitignore` with standard Python exclusions
186
+
187
+ ### Changed
188
+ - Project restructured into `src/hatchsvg/` package layout
189
+ - `core.py` extracted from `hatchsvg.py` (algorithm preserved verbatim)
190
+ - CLI entry point moved to `hatchsvg.cli:main` (script `hatchsvg.py` retained as reference)
191
+ - Python requirement raised to 3.11+
192
+
193
+ ### Fixed
194
+ - Cryptic `SystemExit` errors now show actionable advice
195
+ - Missing `--version` flag
196
+
197
+ [1.0.0]: https://github.com/Veedubin/hatchsvg/releases/tag/v1.0.0
198
+ [1.1.0]: https://github.com/Veedubin/hatchsvg/compare/v1.0.0...v1.1.0
hatchsvg-2.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 png2svg contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.