heinzel-example 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ .venv/
2
+ .tools/
3
+ __pycache__/
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .pyright/
7
+ .coverage*
8
+ htmlcov/
9
+ node_modules/
10
+ dist/
11
+ release-dist/
12
+ *.egg-info/
13
+ .acceptance/
14
+ .preview/
15
+ .candidates/
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.4.0
4
+
5
+ Move this plugin to its independent repository project for the Heinzel 0.9 plugin contract.
6
+ Own its dependencies, tests and artifacts; consume public contracts without concrete provider dependencies.
7
+
8
+ Earlier history is preserved in the source repository named in README.md.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Helmut Hoffer von Ankershoffen
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.
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.5
2
+ Name: heinzel-example
3
+ Version: 0.4.0
4
+ Summary: Show how a Heinzelmännchen plugin is built.
5
+ Project-URL: Source, https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/tree/main/plugins/heinzel-example
6
+ Project-URL: Changelog, https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/blob/main/plugins/heinzel-example/CHANGELOG.md
7
+ Project-URL: Issues, https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/issues
8
+ Author-email: Helmut Hoffer von Ankershoffen <helmuthva@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: heinzel,heinzel-plugin,heinzelmaennchen
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: heinzel<0.10,>=0.9.1
20
+ Description-Content-Type: text/markdown
21
+
22
+ # heinzel-example
23
+
24
+ Show how a Heinzelmännchen plugin is built: one module with an operation, settings, a health check and a submodule.
25
+
26
+ A plugin for [Heinzelmännchen](https://github.com/helmut-hoffer-von-ankershoffen/heinzel), the open-source, AI-driven
27
+ operating system for product development teams. It lives in
28
+ [heinzel-plugins](https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins). Its earlier history is preserved
29
+ in heinzel-contrib and the archived heinzel-example repository.
30
+
31
+ ## Install
32
+
33
+ With Heinzelmännchen installed (`uv tool install git+https://github.com/helmut-hoffer-von-ankershoffen/heinzel`):
34
+
35
+ ```bash
36
+ hz system plugin add "heinzel-example @ git+https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins#subdirectory=plugins/heinzel-example"
37
+ ```
38
+
39
+ Running `hz system plugin add` again upgrades; `hz system plugin remove heinzel-example` removes it.
40
+
41
+ ## Use
42
+
43
+ ```bash
44
+ hz example info # this plugin, its version and the Heinzelmännchen it runs on
45
+ hz example hello --name Ada # a submodule collapsed into a command
46
+ hz example info --json # every command speaks JSON, for scripts and agents
47
+ hz system info # includes a section contributed by this plugin
48
+ ```
49
+
50
+ ## Develop
51
+
52
+ From the repository root: `make check-fast NAME=example` runs this plugin's edit loop; `make check NAME=example`
53
+ runs its full checks. `make build NAME=example` and `make acceptance NAME=example` verify its installed artifact.
54
+ The modules live in
55
+ `src/heinzel_example/`; read the root [AGENTS.md](../../AGENTS.md) before changing them.
56
+
57
+ Development and release commands: [repository guide](../../README.md).
58
+
59
+ Migration provenance: heinzel-contrib, before the 0.9 plugin-boundary migration.
@@ -0,0 +1,38 @@
1
+ # heinzel-example
2
+
3
+ Show how a Heinzelmännchen plugin is built: one module with an operation, settings, a health check and a submodule.
4
+
5
+ A plugin for [Heinzelmännchen](https://github.com/helmut-hoffer-von-ankershoffen/heinzel), the open-source, AI-driven
6
+ operating system for product development teams. It lives in
7
+ [heinzel-plugins](https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins). Its earlier history is preserved
8
+ in heinzel-contrib and the archived heinzel-example repository.
9
+
10
+ ## Install
11
+
12
+ With Heinzelmännchen installed (`uv tool install git+https://github.com/helmut-hoffer-von-ankershoffen/heinzel`):
13
+
14
+ ```bash
15
+ hz system plugin add "heinzel-example @ git+https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins#subdirectory=plugins/heinzel-example"
16
+ ```
17
+
18
+ Running `hz system plugin add` again upgrades; `hz system plugin remove heinzel-example` removes it.
19
+
20
+ ## Use
21
+
22
+ ```bash
23
+ hz example info # this plugin, its version and the Heinzelmännchen it runs on
24
+ hz example hello --name Ada # a submodule collapsed into a command
25
+ hz example info --json # every command speaks JSON, for scripts and agents
26
+ hz system info # includes a section contributed by this plugin
27
+ ```
28
+
29
+ ## Develop
30
+
31
+ From the repository root: `make check-fast NAME=example` runs this plugin's edit loop; `make check NAME=example`
32
+ runs its full checks. `make build NAME=example` and `make acceptance NAME=example` verify its installed artifact.
33
+ The modules live in
34
+ `src/heinzel_example/`; read the root [AGENTS.md](../../AGENTS.md) before changing them.
35
+
36
+ Development and release commands: [repository guide](../../README.md).
37
+
38
+ Migration provenance: heinzel-contrib, before the 0.9 plugin-boundary migration.
@@ -0,0 +1,40 @@
1
+ {
2
+ "format": 1,
3
+ "sdk": 1,
4
+ "inputs": [
5
+ "coverage>=7.12",
6
+ "editables>=0.5",
7
+ "hatchling>=1.29.0",
8
+ "heinzel>=0.9.1,<0.10",
9
+ "mypy>=1.19.0,<3",
10
+ "pyright[nodejs]==1.1.414",
11
+ "pytest-timeout>=2.4.0,<3",
12
+ "pytest-xdist>=3.8",
13
+ "pytest>=9.0.3,<10",
14
+ "ruff==0.17.2"
15
+ ],
16
+ "core": {
17
+ "version": "0.9.1",
18
+ "dependencies": [
19
+ "croniter>=6.2.4",
20
+ "fastapi>=0.161",
21
+ "keyring>=25.6",
22
+ "mcp>=2.3",
23
+ "packaging>=25.0",
24
+ "platformdirs>=4.5",
25
+ "pluggy<2,>=1.6.0",
26
+ "psutil==7.2.2",
27
+ "pydantic-ai-slim==2.61.0",
28
+ "pydantic-ai-slim[anthropic]==2.61.0; extra == \"anthropic\"",
29
+ "pydantic-ai-slim[openai]==2.61.0; extra == \"openai\"",
30
+ "pydantic-settings<3,>=2.11.0",
31
+ "pydantic<3,>=2.12.0",
32
+ "pyyaml<7,>=6.0.2",
33
+ "rich>=14.2.0",
34
+ "tomlkit>=0.13",
35
+ "typer>=0.23.0",
36
+ "uvicorn>=0.54",
37
+ "wsproto>=1.3"
38
+ ]
39
+ }
40
+ }
@@ -0,0 +1,143 @@
1
+ [project]
2
+ name = "heinzel-example"
3
+ version = "0.4.0"
4
+ description = "Show how a Heinzelmännchen plugin is built."
5
+ readme = "README.md"
6
+ authors = [{ name = "Helmut Hoffer von Ankershoffen", email = "helmuthva@gmail.com" }]
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ requires-python = ">=3.12"
10
+ keywords = ["heinzel", "heinzel-plugin", "heinzelmaennchen"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Environment :: Console",
14
+ "Operating System :: MacOS",
15
+ "Operating System :: POSIX :: Linux",
16
+ "Programming Language :: Python :: 3",
17
+ "Typing :: Typed",
18
+ ]
19
+ # Heinzelmännchen resolves to the installed Heinzelmännchen when the plugin is added with `hz system plugin add`.
20
+ dependencies = ["heinzel>=0.9.1,<0.10"]
21
+
22
+ [project.entry-points."heinzel.modules"]
23
+ example = "heinzel_example"
24
+
25
+ [project.urls]
26
+ Source = "https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/tree/main/plugins/heinzel-example"
27
+ Changelog = "https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/blob/main/plugins/heinzel-example/CHANGELOG.md"
28
+ Issues = "https://github.com/helmut-hoffer-von-ankershoffen/heinzel-plugins/issues"
29
+
30
+ [build-system]
31
+ requires = ["hatchling>=1.29.0"]
32
+ build-backend = "hatchling.build"
33
+
34
+ [tool.hatch.build.targets.wheel]
35
+ packages = ["src/heinzel_example"]
36
+
37
+ [tool.ruff]
38
+ line-length = 120
39
+ fix = true
40
+ extend-exclude = ["template"] # rendered and checked by `make template-test`
41
+
42
+ [tool.ruff.lint]
43
+ select = ["ALL"]
44
+ # pydoclint (DOC): docstring sections must match what the code raises, returns and yields. Preview rules, opted into
45
+ # one by one so no other preview rule sneaks in.
46
+ preview = true
47
+ explicit-preview-rules = true
48
+ extend-select = ["DOC201", "DOC202", "DOC402", "DOC403", "DOC501", "DOC502"]
49
+ ignore = [
50
+ "COM812", # conflicts with the ruff formatter
51
+ "CPY001", # no copyright header in OSS files
52
+ "D203", # incompatible with D211
53
+ "DOC201", # a return value is documented by the type and the summary line; Returns: only when it adds meaning
54
+ "DOC502", # documenting exceptions raised by callees is useful for callers
55
+ "D213", # incompatible with D212
56
+ "FBT001", # boolean positional arguments are idiomatic for Typer options
57
+ "FBT002", # same as FBT001
58
+ "ISC001", # conflicts with the ruff formatter
59
+ "TD003", # todos don't need an issue link
60
+ "FIX002", # todos are allowed
61
+ ]
62
+
63
+ [tool.ruff.lint.per-file-ignores]
64
+ ".claude/hooks/*.py" = [
65
+ "D103", # hook entry points are documented by the module docstring
66
+ "INP001", # hooks are scripts, not a package
67
+ "S603", # subprocess calls with fixed argument lists
68
+ "S607", # tools (uv, git, make) are resolved from PATH on purpose
69
+ "T201", # hooks talk to the agent through stdout/stderr
70
+ ]
71
+ "fuzz/*.py" = [
72
+ "INP001", # fuzz targets are scripts, not a package
73
+ ]
74
+ "hatch_build.py" = [
75
+ "INP001", # the build hook hatch loads by path, not a package
76
+ ]
77
+ "scripts/*.py" = [
78
+ "INP001", # scripts are not a package
79
+ "T201", # scripts report on stdout/stderr
80
+ ]
81
+ "**/tests/**/*.py" = [
82
+ "ANN", # fixtures and tests don't need full annotations
83
+ "DOC", # test docstrings describe behaviour, not interfaces
84
+ "ARG", # fixtures are used for their side effects
85
+ "D", # test names are the documentation
86
+ "INP001", # tests are not a package
87
+ "PLC0415", # local imports keep fixtures isolated
88
+ "PLR2004", # magic values are fine in assertions
89
+ "S101", # asserts are what tests do
90
+ "S105", # fake tokens and passwords are test data (credentials, adapters for tracker and document services)
91
+ "S106", # same as S105, passed as arguments
92
+ "S603", # subprocess calls with trusted input
93
+ "S607", # partial executable paths (uv, hz) are resolved from PATH on purpose
94
+ "SLF001", # private access is needed for solitary unit tests
95
+ ]
96
+
97
+ [tool.ruff.lint.pydocstyle]
98
+ convention = "google"
99
+
100
+ [tool.ruff.format]
101
+ docstring-code-format = true
102
+
103
+ [tool.mypy]
104
+ strict = true
105
+ mypy_path = ["src"]
106
+ files = ["src"]
107
+ plugins = ["pydantic.mypy"]
108
+
109
+ [tool.pydantic-mypy]
110
+ init_forbid_extra = true
111
+ init_typed = true
112
+ warn_required_dynamic_aliases = true
113
+
114
+ [tool.pytest]
115
+ minversion = "9.0"
116
+ strict = true
117
+ testpaths = ["tests"]
118
+ addopts = ["-ra", "--import-mode=importlib"]
119
+ filterwarnings = ["error"]
120
+ markers = ["unit: Offline isolated behavior.", "integration: Offline public-contract integration.", "e2e: Installed artifacts or real external services.", "perf: Explicit timing tests.", "long_running: Extended end-to-end budget."]
121
+
122
+ [tool.heinzel.plugin]
123
+ profiles = []
124
+ requires = ["core:plugin-api@1"]
125
+ provides = []
126
+
127
+ [tool.coverage.run]
128
+ source = ["heinzel_example"]
129
+ branch = true
130
+
131
+ [tool.coverage.report]
132
+ fail_under = 90
133
+ show_missing = true
134
+ [dependency-groups]
135
+ test = ["editables>=0.5", "pytest>=9.0.3,<10", "pytest-timeout>=2.4.0,<3", "pytest-xdist>=3.8", "ruff==0.17.2", "mypy>=1.19.0,<3", "coverage>=7.12", "pyright[nodejs]==1.1.414"]
136
+
137
+ [tool.pyright]
138
+ typeCheckingMode = "strict"
139
+ include = ["src"]
140
+ pythonVersion = "3.12"
141
+
142
+ [tool.hatch.build.targets.sdist]
143
+ exclude = [".venv", ".acceptance", ".preview", "dist", "web/node_modules", "**/__pycache__", ".pytest_cache", ".mypy_cache", ".coverage*"]