wexample-cli 2.1.0__tar.gz → 2.1.1__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 (43) hide show
  1. wexample_cli-2.1.1/PKG-INFO +294 -0
  2. wexample_cli-2.1.1/README.md +274 -0
  3. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/pyproject.toml +5 -5
  4. wexample_cli-2.1.0/tests/__init__.py → wexample_cli-2.1.1/tests/.gitkeep +0 -0
  5. {wexample_cli-2.1.0/tests/helper → wexample_cli-2.1.1/tests}/__init__.py +0 -0
  6. wexample_cli-2.1.1/tests/unit/helper/__init__.py +0 -0
  7. wexample_cli-2.1.0/PKG-INFO +0 -169
  8. wexample_cli-2.1.0/README.md +0 -149
  9. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/__init__.py +0 -0
  10. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/command/__init__.py +0 -0
  11. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/command/extended_command.py +0 -0
  12. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/common/__init__.py +0 -0
  13. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/common/command_method_wrapper.py +0 -0
  14. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/const/__init__.py +0 -0
  15. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/const/middleware.py +0 -0
  16. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/const/tags.py +0 -0
  17. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/const/types.py +0 -0
  18. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/context/__init__.py +0 -0
  19. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/context/execution_context.py +0 -0
  20. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/__init__.py +0 -0
  21. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/alias.py +0 -0
  22. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/as_sudo.py +0 -0
  23. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/command.py +0 -0
  24. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/middleware.py +0 -0
  25. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/option.py +0 -0
  26. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/option_stop_on_failure.py +0 -0
  27. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/screenable.py +0 -0
  28. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/decorator/webhook.py +0 -0
  29. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/exception/__init__.py +0 -0
  30. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/exception/abstract_command_option_exception.py +0 -0
  31. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/exception/command_option_missing_exception.py +0 -0
  32. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/exception/command_option_validation_exception.py +0 -0
  33. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/helper/__init__.py +0 -0
  34. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/helper/extra_args.py +0 -0
  35. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/middleware/__init__.py +0 -0
  36. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/middleware/abstract_middleware.py +0 -0
  37. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/py.typed +0 -0
  38. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/testing/__init__.py +0 -0
  39. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/src/wexample_cli/testing/kernel.py +0 -0
  40. {wexample_cli-2.1.0/tests/unit → wexample_cli-2.1.1/tests/helper}/__init__.py +0 -0
  41. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/tests/helper/test_extra_args.py +0 -0
  42. {wexample_cli-2.1.0/tests/unit/helper → wexample_cli-2.1.1/tests/unit}/__init__.py +0 -0
  43. {wexample_cli-2.1.0 → wexample_cli-2.1.1}/tests/unit/helper/test_extra_args.py +0 -0
@@ -0,0 +1,294 @@
1
+ Metadata-Version: 2.1
2
+ Name: wexample-cli
3
+ Version: 2.1.1
4
+ Summary: Supplies command decorators, typed options, and a composable middleware pipeline for kernels built on wexample-app
5
+ Author-Email: weeger <contact@wexample.com>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Project-URL: homepage, https://github.com/wexample/python-cli
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: attrs>=23.1.0
13
+ Requires-Dist: wexample-app>=19.1.0
14
+ Requires-Dist: wexample-helpers>=19.1.0
15
+ Requires-Dist: wexample-prompt>=15.0.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest; extra == "dev"
18
+ Requires-Dist: pytest-cov; extra == "dev"
19
+ Description-Content-Type: text/markdown
20
+
21
+ # cli
22
+
23
+ Version: 2.1.1
24
+
25
+ `wexample-cli` supplies the decorator layer — `@command`, `@option`, and `@middleware` — that turns plain Python methods into typed, discoverable commands for kernels built on `wexample-app`. Options are declared with Python types, short names, defaults, required flags, and per-value validators; a composable middleware pipeline can fan a single invocation across multiple execution contexts, run them in parallel, and abort on the first failure. It is aimed at Python developers building or extending a `wexample-app` kernel with new CLI commands.
26
+
27
+ ## Table of Contents
28
+
29
+ - [Installation](#installation)
30
+ - [Quickstart](#quickstart)
31
+ - [Tests](#tests)
32
+ - [Architecture](#architecture)
33
+ - [Integration in the Suite](#integration-in-the-suite)
34
+ - [Dependencies](#dependencies)
35
+ - [Versioning & Compatibility Policy](#versioning--compatibility-policy)
36
+ - [License](#license)
37
+ - [About us](#about-us)
38
+ - [Known Limitations & Roadmap](#known-limitations--roadmap)
39
+ - [Status & Compatibility](#status--compatibility)
40
+ - [Useful Links](#useful-links)
41
+ - [Migration Notes](#migration-notes)
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install wexample-cli
47
+ ```
48
+
49
+ Requires Python >=3.10.
50
+
51
+ ## Quickstart
52
+
53
+ Install the package:
54
+
55
+ ```bash
56
+ pip install wexample-cli
57
+ ```
58
+
59
+ Declare a command inside your kernel class. `@command` wraps the method into a `CommandMethodWrapper`; each `@option` stacks on top in outer-to-inner order to append a typed option to it.
60
+
61
+ ```python
62
+ from wexample_cli.decorator.command import command
63
+ from wexample_cli.decorator.option import option
64
+
65
+ @option(name="name", type=str, description="Who to greet", required=True)
66
+ @command(type="demo", description="Print a greeting")
67
+ def demo__greet(context, name: str) -> None:
68
+ context.io.log(f"Hello, {name}!")
69
+ ```
70
+
71
+ The decorated object is a `CommandMethodWrapper`. You can inspect it immediately:
72
+
73
+ ```python
74
+ demo__greet.description # "Print a greeting"
75
+ demo__greet.options[0].name # "name"
76
+ ```
77
+
78
+ The kernel maps the function name `demo__greet` to the command path `demo/greet`. To exercise the full decorator and middleware pipeline in a test, use the helpers in src/wexample_cli/testing/kernel.py:
79
+
80
+ ```python
81
+ from wexample_cli.testing.kernel import boot_kernel, dispatch_command
82
+
83
+ kernel = boot_kernel(MyKernel, entrypoint_path="/path/to/__main__.py")
84
+ response = dispatch_command(kernel, "demo/greet", {"name": "world"})
85
+ ```
86
+
87
+ `dispatch_command` accepts pre-parsed kwargs (`{"name": "world"}`) or CLI-style strings (`["--name", "world"]`).
88
+
89
+ ## Tests
90
+
91
+ This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
92
+
93
+ ### Installation
94
+
95
+ First, install the required testing dependencies:
96
+ ```bash
97
+ .venv/bin/python -m pip install pytest pytest-cov
98
+ ```
99
+
100
+ ### Basic Usage
101
+
102
+ Run all tests with coverage:
103
+ ```bash
104
+ .venv/bin/python -m pytest --cov --cov-report=html
105
+ ```
106
+
107
+ ### Common Commands
108
+ ```bash
109
+ # Run tests with coverage for a specific module
110
+ .venv/bin/python -m pytest --cov=your_module
111
+
112
+ # Show which lines are not covered
113
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
114
+
115
+ # Generate an HTML coverage report
116
+ .venv/bin/python -m pytest --cov=your_module --cov-report=html
117
+
118
+ # Combine terminal and HTML reports
119
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
120
+
121
+ # Run specific test file with coverage
122
+ .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
123
+ ```
124
+
125
+ ### Viewing HTML Reports
126
+
127
+ After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
128
+
129
+ ### Coverage Threshold
130
+
131
+ To enforce a minimum coverage percentage:
132
+ ```bash
133
+ .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
134
+ ```
135
+
136
+ This will cause the test suite to fail if coverage drops below 80%.
137
+
138
+ ## Architecture
139
+
140
+ `wexample-cli` is a decorator and dispatch layer that sits between a `wexample-app` kernel and the Python functions that implement its commands. It has no entry-point of its own; downstream kernels import its decorators, wrap their methods, and pass the resulting objects to the kernel's registration machinery.
141
+
142
+ ### Parts
143
+
144
+ **Decorators** — `src/wexample_cli/decorator/`
145
+
146
+ The decorators are the only thing a command author touches directly. Applied bottom-to-top on a plain function, they produce a `CommandMethodWrapper`:
147
+
148
+ - `@command(type, description, tags)` — creates the wrapper; must be the innermost decorator.
149
+ - `@option(name, type, ...)` — calls `wrapper.set_option(Option(...))` to append a typed option.
150
+ - `@middleware(name, **kwargs)` — calls `wrapper.register_middleware(name, kwargs)` to schedule a middleware class at runtime.
151
+ - `@alias(*names)` — extends `wrapper.aliases`.
152
+ - `@screenable(interval, height)` — adds `--screen` and `--screen-interval` options and pushes a pipeline wrapper that drives a refresh loop.
153
+ - `@as_sudo()` — sets `wrapper.sudo = True`.
154
+ - `@webhook()` — sets `wrapper.webhook = True`.
155
+ - `@option_stop_on_failure()` — adds a `--stop-on-failure` flag option.
156
+
157
+ **`CommandMethodWrapper`** — `src/wexample_cli/common/command_method_wrapper.py`
158
+
159
+ The data structure produced by decoration. It carries everything the runtime needs: `function`, `options`, `middlewares_attributes` (names → init-kwargs, resolved at call time), `pipeline_wrappers` (registered in outer-to-inner order), `aliases`, `tags`, and the boolean flags `sudo` and `webhook`. It owns no execution logic.
160
+
161
+ **`ExtendedCommand`** — `src/wexample_cli/command/extended_command.py`
162
+
163
+ The runtime command object registered with the kernel; extends `wexample_app.common.command.Command`. It owns the full execution path for one `CommandRequest`.
164
+
165
+ **`AbstractMiddleware`** — `src/wexample_cli/middleware/abstract_middleware.py`
166
+
167
+ Base class for middleware. A middleware can add options dynamically (`append_options`), produce multiple `ExecutionContext` objects from a single request (`build_execution_contexts`), and declare whether execution should be parallel, show a progress bar, or abort on the first failure. The values `"allways"` and `"optional"` (defined in `src/wexample_cli/const/middleware.py`) allow a middleware to make a behaviour mandatory or user-selectable.
168
+
169
+ **`ExecutionContext`** — `src/wexample_cli/context/execution_context.py`
170
+
171
+ A single unit of work inside one dispatch. Holds `function_kwargs`, `request`, `kernel`, `middleware`, and an optional `function` override. Its `__attrs_post_init__` injects `context=self` into `function_kwargs` so every command function receives it. Also provides progress-tracking helpers (`create_progress_range`, `finish_progress`, `get_or_create_progress`).
172
+
173
+ **Exceptions** — `src/wexample_cli/exception/`
174
+
175
+ `CommandOptionMissingException` and `CommandOptionValidationException` both extend `AbstractCommandOptionException`. The first is raised when a required option is absent; the second when an `AbstractValidator` rejects a value.
176
+
177
+ **Constants** — `src/wexample_cli/const/`
178
+
179
+ - `types.py` — `ParsedArgs = dict[str, Any]`.
180
+ - `middleware.py` — the `"allways"` / `"optional"` sentinel strings.
181
+ - `tags.py` — `EffectTag`, `AudienceTag`, and `ScopeTag` class-level string constants for `@command(tags=[...])`.
182
+
183
+ **Testing helpers** — `src/wexample_cli/testing/kernel.py`
184
+
185
+ `boot_kernel(KernelClass, entrypoint_path)` and `dispatch_command(kernel, name, arguments)` exercise the full decorator and dispatch pipeline from a test, identical to a real invocation.
186
+
187
+ **Helper** — `src/wexample_cli/helper/extra_args.py`
188
+
189
+ `resolve_shell_command(context, command, extra_args)` — resolves a shell command string from either a `--command "..."` option or positional `-- args`, preferring the positional form.
190
+
191
+ ### Call path
192
+
193
+ **At import time** (decorators run):
194
+
195
+ ```
196
+ @alias / @as_sudo / @webhook
197
+ @screenable → set_option(screen, screen_interval) + register_pipeline_wrapper(screen_wrapper)
198
+ @middleware(name) → register_middleware(name, kwargs)
199
+ @option(...) → set_option(Option(...))
200
+ @command(type, ...) → CommandMethodWrapper(function=fn, ...)
201
+ ```
202
+
203
+ The resulting `CommandMethodWrapper` is what the kernel stores; `ExtendedCommand` wraps it.
204
+
205
+ **At invocation** (`ExtendedCommand.execute_request`):
206
+
207
+ 1. Instantiate each middleware from the kernel's `"middlewares"` registry using `middlewares_attributes`; attach it with `set_middleware` (which also extends `wrapper.options` with the middleware's own options).
208
+ 2. If `--help` or `-h` is in the raw arguments, render help via `_render_help` and return.
209
+ 3. `_build_function_kwargs`:
210
+ - Each middleware calls `append_options` to inject any dynamic options (e.g. `--parallel`, `--progress`).
211
+ - Raw arguments (list or dict) are parsed by `_parse_arguments` into `ParsedArgs`.
212
+ - Each declared option is resolved from parsed args, then its default, then `CommandOptionMissingException` if required.
213
+ - Each non-`None` value is run through its validators; failure raises `CommandOptionValidationException`.
214
+ - If `--` passthrough tokens are present, they land in `parsed_args["__extra_args__"]` and are forwarded as `extra_args` if the function declares that parameter, otherwise `CommandUnexpectedArgumentException`.
215
+ 4. Build the pipeline: `_make_dispatch` produces the innermost callable; each entry in `pipeline_wrappers` is composed around it with `_wrap_dispatch`.
216
+ 5. Call `dispatch(function_kwargs)`.
217
+
218
+ **Inside `_execute_dispatch`:**
219
+
220
+ - With middlewares: each middleware calls `build_execution_contexts` (base returns one context; subclasses may fan out). Contexts are executed sequentially or in parallel (`asyncio` + `ThreadPoolExecutor`). Parallel runs each context with a `PromptBufferOutputHandler` so output is buffered per-context. Results accumulate in a `MultipleResponse`; a single result is unwrapped. `stop_on_failure` halts the loop early on `FailureResponse`.
221
+ - Without middlewares: a single `ExecutionContext` is built by `request.resolver.build_execution_context`, and the function is called directly.
222
+
223
+ In both paths, `ExecutionContext.__attrs_post_init__` injects `context=self` so the function can access `context.io`, `context.kernel`, progress handles, and the resolved `function_kwargs`.
224
+
225
+ ## Integration in the Suite
226
+
227
+ This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
228
+
229
+ ### Related Packages
230
+
231
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
232
+
233
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
234
+
235
+ ## Dependencies
236
+
237
+ - attrs: >=23.1.0
238
+ - wexample-app: >=19.1.0
239
+ - wexample-helpers: >=19.1.0
240
+ - wexample-prompt: >=15.0.0
241
+
242
+ ## Versioning & Compatibility Policy
243
+
244
+ Wexample packages follow **Semantic Versioning** (SemVer):
245
+
246
+ - **MAJOR**: Breaking changes
247
+ - **MINOR**: New features, backward compatible
248
+ - **PATCH**: Bug fixes, backward compatible
249
+
250
+ We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
251
+
252
+ ## License
253
+
254
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
255
+
256
+ Free to use in both personal and commercial projects.
257
+
258
+ ## About us
259
+
260
+ [Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
261
+
262
+ This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
263
+
264
+ Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
265
+
266
+ ## Known Limitations & Roadmap
267
+
268
+ Current limitations and planned features are tracked in the GitHub issues.
269
+
270
+ See the [project roadmap](https://github.com/wexample/python-cli/issues) for upcoming features and improvements.
271
+
272
+ ## Status & Compatibility
273
+
274
+ **Maturity**: Production-ready
275
+
276
+ **Python Support**: >=3.10
277
+
278
+ **OS Support**: Linux, macOS, Windows
279
+
280
+ **Status**: Actively maintained
281
+
282
+ ## Useful Links
283
+
284
+ - **Homepage**: https://github.com/wexample/python-cli
285
+ - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
286
+ - **Issue Tracker**: https://github.com/wexample/python-cli/issues
287
+ - **Discussions**: https://github.com/wexample/python-cli/discussions
288
+ - **PyPI**: [pypi.org/project/wexample-cli](https://pypi.org/project/wexample-cli/)
289
+
290
+ ## Migration Notes
291
+
292
+ When upgrading between major versions, refer to the migration guides in the documentation.
293
+
294
+ Breaking changes are clearly documented with upgrade paths and examples.
@@ -0,0 +1,274 @@
1
+ # cli
2
+
3
+ Version: 2.1.1
4
+
5
+ `wexample-cli` supplies the decorator layer — `@command`, `@option`, and `@middleware` — that turns plain Python methods into typed, discoverable commands for kernels built on `wexample-app`. Options are declared with Python types, short names, defaults, required flags, and per-value validators; a composable middleware pipeline can fan a single invocation across multiple execution contexts, run them in parallel, and abort on the first failure. It is aimed at Python developers building or extending a `wexample-app` kernel with new CLI commands.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Installation](#installation)
10
+ - [Quickstart](#quickstart)
11
+ - [Tests](#tests)
12
+ - [Architecture](#architecture)
13
+ - [Integration in the Suite](#integration-in-the-suite)
14
+ - [Dependencies](#dependencies)
15
+ - [Versioning & Compatibility Policy](#versioning--compatibility-policy)
16
+ - [License](#license)
17
+ - [About us](#about-us)
18
+ - [Known Limitations & Roadmap](#known-limitations--roadmap)
19
+ - [Status & Compatibility](#status--compatibility)
20
+ - [Useful Links](#useful-links)
21
+ - [Migration Notes](#migration-notes)
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install wexample-cli
27
+ ```
28
+
29
+ Requires Python >=3.10.
30
+
31
+ ## Quickstart
32
+
33
+ Install the package:
34
+
35
+ ```bash
36
+ pip install wexample-cli
37
+ ```
38
+
39
+ Declare a command inside your kernel class. `@command` wraps the method into a `CommandMethodWrapper`; each `@option` stacks on top in outer-to-inner order to append a typed option to it.
40
+
41
+ ```python
42
+ from wexample_cli.decorator.command import command
43
+ from wexample_cli.decorator.option import option
44
+
45
+ @option(name="name", type=str, description="Who to greet", required=True)
46
+ @command(type="demo", description="Print a greeting")
47
+ def demo__greet(context, name: str) -> None:
48
+ context.io.log(f"Hello, {name}!")
49
+ ```
50
+
51
+ The decorated object is a `CommandMethodWrapper`. You can inspect it immediately:
52
+
53
+ ```python
54
+ demo__greet.description # "Print a greeting"
55
+ demo__greet.options[0].name # "name"
56
+ ```
57
+
58
+ The kernel maps the function name `demo__greet` to the command path `demo/greet`. To exercise the full decorator and middleware pipeline in a test, use the helpers in src/wexample_cli/testing/kernel.py:
59
+
60
+ ```python
61
+ from wexample_cli.testing.kernel import boot_kernel, dispatch_command
62
+
63
+ kernel = boot_kernel(MyKernel, entrypoint_path="/path/to/__main__.py")
64
+ response = dispatch_command(kernel, "demo/greet", {"name": "world"})
65
+ ```
66
+
67
+ `dispatch_command` accepts pre-parsed kwargs (`{"name": "world"}`) or CLI-style strings (`["--name", "world"]`).
68
+
69
+ ## Tests
70
+
71
+ This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
72
+
73
+ ### Installation
74
+
75
+ First, install the required testing dependencies:
76
+ ```bash
77
+ .venv/bin/python -m pip install pytest pytest-cov
78
+ ```
79
+
80
+ ### Basic Usage
81
+
82
+ Run all tests with coverage:
83
+ ```bash
84
+ .venv/bin/python -m pytest --cov --cov-report=html
85
+ ```
86
+
87
+ ### Common Commands
88
+ ```bash
89
+ # Run tests with coverage for a specific module
90
+ .venv/bin/python -m pytest --cov=your_module
91
+
92
+ # Show which lines are not covered
93
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
94
+
95
+ # Generate an HTML coverage report
96
+ .venv/bin/python -m pytest --cov=your_module --cov-report=html
97
+
98
+ # Combine terminal and HTML reports
99
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
100
+
101
+ # Run specific test file with coverage
102
+ .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
103
+ ```
104
+
105
+ ### Viewing HTML Reports
106
+
107
+ After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
108
+
109
+ ### Coverage Threshold
110
+
111
+ To enforce a minimum coverage percentage:
112
+ ```bash
113
+ .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
114
+ ```
115
+
116
+ This will cause the test suite to fail if coverage drops below 80%.
117
+
118
+ ## Architecture
119
+
120
+ `wexample-cli` is a decorator and dispatch layer that sits between a `wexample-app` kernel and the Python functions that implement its commands. It has no entry-point of its own; downstream kernels import its decorators, wrap their methods, and pass the resulting objects to the kernel's registration machinery.
121
+
122
+ ### Parts
123
+
124
+ **Decorators** — `src/wexample_cli/decorator/`
125
+
126
+ The decorators are the only thing a command author touches directly. Applied bottom-to-top on a plain function, they produce a `CommandMethodWrapper`:
127
+
128
+ - `@command(type, description, tags)` — creates the wrapper; must be the innermost decorator.
129
+ - `@option(name, type, ...)` — calls `wrapper.set_option(Option(...))` to append a typed option.
130
+ - `@middleware(name, **kwargs)` — calls `wrapper.register_middleware(name, kwargs)` to schedule a middleware class at runtime.
131
+ - `@alias(*names)` — extends `wrapper.aliases`.
132
+ - `@screenable(interval, height)` — adds `--screen` and `--screen-interval` options and pushes a pipeline wrapper that drives a refresh loop.
133
+ - `@as_sudo()` — sets `wrapper.sudo = True`.
134
+ - `@webhook()` — sets `wrapper.webhook = True`.
135
+ - `@option_stop_on_failure()` — adds a `--stop-on-failure` flag option.
136
+
137
+ **`CommandMethodWrapper`** — `src/wexample_cli/common/command_method_wrapper.py`
138
+
139
+ The data structure produced by decoration. It carries everything the runtime needs: `function`, `options`, `middlewares_attributes` (names → init-kwargs, resolved at call time), `pipeline_wrappers` (registered in outer-to-inner order), `aliases`, `tags`, and the boolean flags `sudo` and `webhook`. It owns no execution logic.
140
+
141
+ **`ExtendedCommand`** — `src/wexample_cli/command/extended_command.py`
142
+
143
+ The runtime command object registered with the kernel; extends `wexample_app.common.command.Command`. It owns the full execution path for one `CommandRequest`.
144
+
145
+ **`AbstractMiddleware`** — `src/wexample_cli/middleware/abstract_middleware.py`
146
+
147
+ Base class for middleware. A middleware can add options dynamically (`append_options`), produce multiple `ExecutionContext` objects from a single request (`build_execution_contexts`), and declare whether execution should be parallel, show a progress bar, or abort on the first failure. The values `"allways"` and `"optional"` (defined in `src/wexample_cli/const/middleware.py`) allow a middleware to make a behaviour mandatory or user-selectable.
148
+
149
+ **`ExecutionContext`** — `src/wexample_cli/context/execution_context.py`
150
+
151
+ A single unit of work inside one dispatch. Holds `function_kwargs`, `request`, `kernel`, `middleware`, and an optional `function` override. Its `__attrs_post_init__` injects `context=self` into `function_kwargs` so every command function receives it. Also provides progress-tracking helpers (`create_progress_range`, `finish_progress`, `get_or_create_progress`).
152
+
153
+ **Exceptions** — `src/wexample_cli/exception/`
154
+
155
+ `CommandOptionMissingException` and `CommandOptionValidationException` both extend `AbstractCommandOptionException`. The first is raised when a required option is absent; the second when an `AbstractValidator` rejects a value.
156
+
157
+ **Constants** — `src/wexample_cli/const/`
158
+
159
+ - `types.py` — `ParsedArgs = dict[str, Any]`.
160
+ - `middleware.py` — the `"allways"` / `"optional"` sentinel strings.
161
+ - `tags.py` — `EffectTag`, `AudienceTag`, and `ScopeTag` class-level string constants for `@command(tags=[...])`.
162
+
163
+ **Testing helpers** — `src/wexample_cli/testing/kernel.py`
164
+
165
+ `boot_kernel(KernelClass, entrypoint_path)` and `dispatch_command(kernel, name, arguments)` exercise the full decorator and dispatch pipeline from a test, identical to a real invocation.
166
+
167
+ **Helper** — `src/wexample_cli/helper/extra_args.py`
168
+
169
+ `resolve_shell_command(context, command, extra_args)` — resolves a shell command string from either a `--command "..."` option or positional `-- args`, preferring the positional form.
170
+
171
+ ### Call path
172
+
173
+ **At import time** (decorators run):
174
+
175
+ ```
176
+ @alias / @as_sudo / @webhook
177
+ @screenable → set_option(screen, screen_interval) + register_pipeline_wrapper(screen_wrapper)
178
+ @middleware(name) → register_middleware(name, kwargs)
179
+ @option(...) → set_option(Option(...))
180
+ @command(type, ...) → CommandMethodWrapper(function=fn, ...)
181
+ ```
182
+
183
+ The resulting `CommandMethodWrapper` is what the kernel stores; `ExtendedCommand` wraps it.
184
+
185
+ **At invocation** (`ExtendedCommand.execute_request`):
186
+
187
+ 1. Instantiate each middleware from the kernel's `"middlewares"` registry using `middlewares_attributes`; attach it with `set_middleware` (which also extends `wrapper.options` with the middleware's own options).
188
+ 2. If `--help` or `-h` is in the raw arguments, render help via `_render_help` and return.
189
+ 3. `_build_function_kwargs`:
190
+ - Each middleware calls `append_options` to inject any dynamic options (e.g. `--parallel`, `--progress`).
191
+ - Raw arguments (list or dict) are parsed by `_parse_arguments` into `ParsedArgs`.
192
+ - Each declared option is resolved from parsed args, then its default, then `CommandOptionMissingException` if required.
193
+ - Each non-`None` value is run through its validators; failure raises `CommandOptionValidationException`.
194
+ - If `--` passthrough tokens are present, they land in `parsed_args["__extra_args__"]` and are forwarded as `extra_args` if the function declares that parameter, otherwise `CommandUnexpectedArgumentException`.
195
+ 4. Build the pipeline: `_make_dispatch` produces the innermost callable; each entry in `pipeline_wrappers` is composed around it with `_wrap_dispatch`.
196
+ 5. Call `dispatch(function_kwargs)`.
197
+
198
+ **Inside `_execute_dispatch`:**
199
+
200
+ - With middlewares: each middleware calls `build_execution_contexts` (base returns one context; subclasses may fan out). Contexts are executed sequentially or in parallel (`asyncio` + `ThreadPoolExecutor`). Parallel runs each context with a `PromptBufferOutputHandler` so output is buffered per-context. Results accumulate in a `MultipleResponse`; a single result is unwrapped. `stop_on_failure` halts the loop early on `FailureResponse`.
201
+ - Without middlewares: a single `ExecutionContext` is built by `request.resolver.build_execution_context`, and the function is called directly.
202
+
203
+ In both paths, `ExecutionContext.__attrs_post_init__` injects `context=self` so the function can access `context.io`, `context.kernel`, progress handles, and the resolved `function_kwargs`.
204
+
205
+ ## Integration in the Suite
206
+
207
+ This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
208
+
209
+ ### Related Packages
210
+
211
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
212
+
213
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
214
+
215
+ ## Dependencies
216
+
217
+ - attrs: >=23.1.0
218
+ - wexample-app: >=19.1.0
219
+ - wexample-helpers: >=19.1.0
220
+ - wexample-prompt: >=15.0.0
221
+
222
+ ## Versioning & Compatibility Policy
223
+
224
+ Wexample packages follow **Semantic Versioning** (SemVer):
225
+
226
+ - **MAJOR**: Breaking changes
227
+ - **MINOR**: New features, backward compatible
228
+ - **PATCH**: Bug fixes, backward compatible
229
+
230
+ We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
231
+
232
+ ## License
233
+
234
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
235
+
236
+ Free to use in both personal and commercial projects.
237
+
238
+ ## About us
239
+
240
+ [Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
241
+
242
+ This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
243
+
244
+ Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
245
+
246
+ ## Known Limitations & Roadmap
247
+
248
+ Current limitations and planned features are tracked in the GitHub issues.
249
+
250
+ See the [project roadmap](https://github.com/wexample/python-cli/issues) for upcoming features and improvements.
251
+
252
+ ## Status & Compatibility
253
+
254
+ **Maturity**: Production-ready
255
+
256
+ **Python Support**: >=3.10
257
+
258
+ **OS Support**: Linux, macOS, Windows
259
+
260
+ **Status**: Actively maintained
261
+
262
+ ## Useful Links
263
+
264
+ - **Homepage**: https://github.com/wexample/python-cli
265
+ - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
266
+ - **Issue Tracker**: https://github.com/wexample/python-cli/issues
267
+ - **Discussions**: https://github.com/wexample/python-cli/discussions
268
+ - **PyPI**: [pypi.org/project/wexample-cli](https://pypi.org/project/wexample-cli/)
269
+
270
+ ## Migration Notes
271
+
272
+ When upgrading between major versions, refer to the migration guides in the documentation.
273
+
274
+ Breaking changes are clearly documented with upgrade paths and examples.
@@ -6,8 +6,8 @@ build-backend = "pdm.backend"
6
6
 
7
7
  [project]
8
8
  name = "wexample-cli"
9
- version = "2.1.0"
10
- description = "Reusable CLI primitives — command decorators, options, middlewares, and the enriched command runner — extracted from wex-core so any kernel built on wexample-app can opt in without depending on the full wex framework."
9
+ version = "2.1.1"
10
+ description = "Supplies command decorators, typed options, and a composable middleware pipeline for kernels built on wexample-app"
11
11
  authors = [
12
12
  { name = "weeger", email = "contact@wexample.com" },
13
13
  ]
@@ -19,9 +19,9 @@ classifiers = [
19
19
  ]
20
20
  dependencies = [
21
21
  "attrs>=23.1.0",
22
- "wexample-app>=19.0.0",
23
- "wexample-helpers>=19.0.0",
24
- "wexample-prompt>=14.1.0",
22
+ "wexample-app>=19.1.0",
23
+ "wexample-helpers>=19.1.0",
24
+ "wexample-prompt>=15.0.0",
25
25
  ]
26
26
 
27
27
  [project.readme]
File without changes
@@ -1,169 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: wexample-cli
3
- Version: 2.1.0
4
- Summary: Reusable CLI primitives — command decorators, options, middlewares, and the enriched command runner — extracted from wex-core so any kernel built on wexample-app can opt in without depending on the full wex framework.
5
- Author-Email: weeger <contact@wexample.com>
6
- License: MIT
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Operating System :: OS Independent
10
- Project-URL: homepage, https://github.com/wexample/python-cli
11
- Requires-Python: >=3.10
12
- Requires-Dist: attrs>=23.1.0
13
- Requires-Dist: wexample-app>=19.0.0
14
- Requires-Dist: wexample-helpers>=19.0.0
15
- Requires-Dist: wexample-prompt>=14.1.0
16
- Provides-Extra: dev
17
- Requires-Dist: pytest; extra == "dev"
18
- Requires-Dist: pytest-cov; extra == "dev"
19
- Description-Content-Type: text/markdown
20
-
21
- # cli
22
-
23
- Version: 2.1.0
24
-
25
- Reusable CLI primitives — command decorators, options, middlewares, and the enriched command runner — extracted from wex-core so any kernel built on wexample-app can opt in without depending on the full wex framework.
26
-
27
- ## Table of Contents
28
-
29
- - [Tests](#tests)
30
- - [Suite Integration](#suite-integration)
31
- - [Dependencies](#dependencies)
32
- - [Versioning](#versioning)
33
- - [License](#license)
34
- - [Suite Integration](#suite-integration)
35
- - [Suite Signature](#suite-signature)
36
- - [Roadmap](#roadmap)
37
- - [Status Compatibility](#status-compatibility)
38
- - [Useful Links](#useful-links)
39
- - [Migration Notes](#migration-notes)
40
-
41
- ## Tests
42
-
43
- This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
44
-
45
- ### Installation
46
-
47
- First, install the required testing dependencies:
48
- ```bash
49
- .venv/bin/python -m pip install pytest pytest-cov
50
- ```
51
-
52
- ### Basic Usage
53
-
54
- Run all tests with coverage:
55
- ```bash
56
- .venv/bin/python -m pytest --cov --cov-report=html
57
- ```
58
-
59
- ### Common Commands
60
- ```bash
61
- # Run tests with coverage for a specific module
62
- .venv/bin/python -m pytest --cov=your_module
63
-
64
- # Show which lines are not covered
65
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
66
-
67
- # Generate an HTML coverage report
68
- .venv/bin/python -m pytest --cov=your_module --cov-report=html
69
-
70
- # Combine terminal and HTML reports
71
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
72
-
73
- # Run specific test file with coverage
74
- .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
75
- ```
76
-
77
- ### Viewing HTML Reports
78
-
79
- After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
80
-
81
- ### Coverage Threshold
82
-
83
- To enforce a minimum coverage percentage:
84
- ```bash
85
- .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
86
- ```
87
-
88
- This will cause the test suite to fail if coverage drops below 80%.
89
-
90
- ## Integration in the Suite
91
-
92
- This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
93
-
94
- ### Related Packages
95
-
96
- The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
97
-
98
- Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
99
-
100
- ## Dependencies
101
-
102
- - attrs: >=23.1.0
103
- - wexample-app: >=19.0.0
104
- - wexample-helpers: >=19.0.0
105
- - wexample-prompt: >=14.1.0
106
-
107
- ## Versioning & Compatibility Policy
108
-
109
- Wexample packages follow **Semantic Versioning** (SemVer):
110
-
111
- - **MAJOR**: Breaking changes
112
- - **MINOR**: New features, backward compatible
113
- - **PATCH**: Bug fixes, backward compatible
114
-
115
- We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
116
-
117
- ## License
118
-
119
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
120
-
121
- Free to use in both personal and commercial projects.
122
-
123
- ## Integration in the Suite
124
-
125
- This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
126
-
127
- ### Related Packages
128
-
129
- The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
130
-
131
- Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
132
-
133
- # About us
134
-
135
- [Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
136
-
137
- This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
138
-
139
- Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
140
-
141
- ## Known Limitations & Roadmap
142
-
143
- Current limitations and planned features are tracked in the GitHub issues.
144
-
145
- See the [project roadmap](https://github.com/wexample/python-cli/issues) for upcoming features and improvements.
146
-
147
- ## Status & Compatibility
148
-
149
- **Maturity**: Production-ready
150
-
151
- **Python Support**: >=3.10
152
-
153
- **OS Support**: Linux, macOS, Windows
154
-
155
- **Status**: Actively maintained
156
-
157
- ## Useful Links
158
-
159
- - **Homepage**: https://github.com/wexample/python-cli
160
- - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
161
- - **Issue Tracker**: https://github.com/wexample/python-cli/issues
162
- - **Discussions**: https://github.com/wexample/python-cli/discussions
163
- - **PyPI**: [pypi.org/project/cli](https://pypi.org/project/cli/)
164
-
165
- ## Migration Notes
166
-
167
- When upgrading between major versions, refer to the migration guides in the documentation.
168
-
169
- Breaking changes are clearly documented with upgrade paths and examples.
@@ -1,149 +0,0 @@
1
- # cli
2
-
3
- Version: 2.1.0
4
-
5
- Reusable CLI primitives — command decorators, options, middlewares, and the enriched command runner — extracted from wex-core so any kernel built on wexample-app can opt in without depending on the full wex framework.
6
-
7
- ## Table of Contents
8
-
9
- - [Tests](#tests)
10
- - [Suite Integration](#suite-integration)
11
- - [Dependencies](#dependencies)
12
- - [Versioning](#versioning)
13
- - [License](#license)
14
- - [Suite Integration](#suite-integration)
15
- - [Suite Signature](#suite-signature)
16
- - [Roadmap](#roadmap)
17
- - [Status Compatibility](#status-compatibility)
18
- - [Useful Links](#useful-links)
19
- - [Migration Notes](#migration-notes)
20
-
21
- ## Tests
22
-
23
- This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
24
-
25
- ### Installation
26
-
27
- First, install the required testing dependencies:
28
- ```bash
29
- .venv/bin/python -m pip install pytest pytest-cov
30
- ```
31
-
32
- ### Basic Usage
33
-
34
- Run all tests with coverage:
35
- ```bash
36
- .venv/bin/python -m pytest --cov --cov-report=html
37
- ```
38
-
39
- ### Common Commands
40
- ```bash
41
- # Run tests with coverage for a specific module
42
- .venv/bin/python -m pytest --cov=your_module
43
-
44
- # Show which lines are not covered
45
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
46
-
47
- # Generate an HTML coverage report
48
- .venv/bin/python -m pytest --cov=your_module --cov-report=html
49
-
50
- # Combine terminal and HTML reports
51
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
52
-
53
- # Run specific test file with coverage
54
- .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
55
- ```
56
-
57
- ### Viewing HTML Reports
58
-
59
- After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
60
-
61
- ### Coverage Threshold
62
-
63
- To enforce a minimum coverage percentage:
64
- ```bash
65
- .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
66
- ```
67
-
68
- This will cause the test suite to fail if coverage drops below 80%.
69
-
70
- ## Integration in the Suite
71
-
72
- This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
73
-
74
- ### Related Packages
75
-
76
- The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
77
-
78
- Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
79
-
80
- ## Dependencies
81
-
82
- - attrs: >=23.1.0
83
- - wexample-app: >=19.0.0
84
- - wexample-helpers: >=19.0.0
85
- - wexample-prompt: >=14.1.0
86
-
87
- ## Versioning & Compatibility Policy
88
-
89
- Wexample packages follow **Semantic Versioning** (SemVer):
90
-
91
- - **MAJOR**: Breaking changes
92
- - **MINOR**: New features, backward compatible
93
- - **PATCH**: Bug fixes, backward compatible
94
-
95
- We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
96
-
97
- ## License
98
-
99
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
100
-
101
- Free to use in both personal and commercial projects.
102
-
103
- ## Integration in the Suite
104
-
105
- This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
106
-
107
- ### Related Packages
108
-
109
- The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
110
-
111
- Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
112
-
113
- # About us
114
-
115
- [Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
116
-
117
- This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
118
-
119
- Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
120
-
121
- ## Known Limitations & Roadmap
122
-
123
- Current limitations and planned features are tracked in the GitHub issues.
124
-
125
- See the [project roadmap](https://github.com/wexample/python-cli/issues) for upcoming features and improvements.
126
-
127
- ## Status & Compatibility
128
-
129
- **Maturity**: Production-ready
130
-
131
- **Python Support**: >=3.10
132
-
133
- **OS Support**: Linux, macOS, Windows
134
-
135
- **Status**: Actively maintained
136
-
137
- ## Useful Links
138
-
139
- - **Homepage**: https://github.com/wexample/python-cli
140
- - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
141
- - **Issue Tracker**: https://github.com/wexample/python-cli/issues
142
- - **Discussions**: https://github.com/wexample/python-cli/discussions
143
- - **PyPI**: [pypi.org/project/cli](https://pypi.org/project/cli/)
144
-
145
- ## Migration Notes
146
-
147
- When upgrading between major versions, refer to the migration guides in the documentation.
148
-
149
- Breaking changes are clearly documented with upgrade paths and examples.