hexastack-cli 0.1.0__tar.gz → 0.2.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 (20) hide show
  1. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/PKG-INFO +1 -1
  2. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/pyproject.toml +22 -1
  3. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/pyproject.toml.orig +26 -1
  4. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/adapters/app.py +1 -1
  5. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/infra/decorators.py +6 -3
  6. hexastack_cli-0.2.0/src/hexastack_cli/testing/__init__.py +9 -0
  7. hexastack_cli-0.2.0/src/hexastack_cli/testing/events.py +16 -0
  8. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/testing/narrator.py +1 -9
  9. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/testing/terminal.py +1 -1
  10. hexastack_cli-0.1.0/src/hexastack_cli/testing/__init__.py +0 -7
  11. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/README.md +0 -0
  12. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/__init__.py +0 -0
  13. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/adapters/__init__.py +0 -0
  14. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/adapters/presenter.py +0 -0
  15. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/adapters/routing.py +0 -0
  16. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/infra/__init__.py +0 -0
  17. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/infra/autodiscovery.py +0 -0
  18. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/infra/bootstrap.py +0 -0
  19. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/infra/config.py +0 -0
  20. {hexastack_cli-0.1.0 → hexastack_cli-0.2.0}/src/hexastack_cli/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexastack-cli
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Hexastack CLI presentation adapter with Typer and Rich
5
5
  Author: Richard West
6
6
  Author-email: Richard West <dopplereffect.us@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hexastack-cli"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  description = "Hexastack CLI presentation adapter with Typer and Rich"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -34,3 +34,24 @@ workspace = true
34
34
 
35
35
  [tool.importlinter]
36
36
  root_packages = ["hexastack_cli"]
37
+
38
+ [[tool.importlinter.contracts]]
39
+ name = "Hexagonal architecture layer hierarchy"
40
+ type = "layers"
41
+ containers = ["hexastack_cli"]
42
+ layers = [
43
+ "adapters",
44
+ "infra",
45
+ ]
46
+
47
+ [[tool.importlinter.contracts]]
48
+ name = "Forbidden imports for adapters"
49
+ type = "forbidden"
50
+ source_modules = ["hexastack_cli.adapters"]
51
+ forbidden_modules = ["hexastack_cli.testing"]
52
+
53
+ [[tool.importlinter.contracts]]
54
+ name = "Forbidden imports for infra"
55
+ type = "forbidden"
56
+ source_modules = ["hexastack_cli.infra"]
57
+ forbidden_modules = ["hexastack_cli.testing"]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hexastack-cli"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  description = "Hexastack CLI presentation adapter with Typer and Rich"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -33,3 +33,28 @@ hexastack-cqrs = { workspace = true }
33
33
 
34
34
  [tool.importlinter]
35
35
  root_packages = ["hexastack_cli"]
36
+
37
+ [[tool.importlinter.contracts]]
38
+ name = "Hexagonal architecture layer hierarchy"
39
+ type = "layers"
40
+ containers = ["hexastack_cli"]
41
+ layers = [
42
+ "adapters",
43
+ "infra",
44
+ ]
45
+
46
+ [[tool.importlinter.contracts]]
47
+ name = "Forbidden imports for adapters"
48
+ type = "forbidden"
49
+ source_modules = ["hexastack_cli.adapters"]
50
+ forbidden_modules = [
51
+ "hexastack_cli.testing",
52
+ ]
53
+
54
+ [[tool.importlinter.contracts]]
55
+ name = "Forbidden imports for infra"
56
+ type = "forbidden"
57
+ source_modules = ["hexastack_cli.infra"]
58
+ forbidden_modules = [
59
+ "hexastack_cli.testing",
60
+ ]
@@ -51,7 +51,7 @@ def create_cli_app(
51
51
  def _version_callback(value: bool) -> None:
52
52
  if value:
53
53
  active_console.print(f"{cfg.app_name} {cfg.version}")
54
- raise typer.Exit()
54
+ raise typer.Exit
55
55
 
56
56
  # Establish root callback to enforce multi-command structure and handle --version
57
57
  @app.callback()
@@ -1,9 +1,12 @@
1
1
  from collections.abc import Callable, Sequence
2
2
  from dataclasses import dataclass, field
3
- from typing import Any, Literal
3
+ from typing import Any, Literal, TypeVar
4
4
 
5
5
  from hexastack_core.domain import Command, Query
6
6
 
7
+ TCommand = TypeVar("TCommand", bound=Command)
8
+ TQuery = TypeVar("TQuery", bound=Query)
9
+
7
10
  _CLI_METADATA_ATTR = "__hexastack_cli__"
8
11
  _CLI_GROUP_ATTR = "__hexastack_cli_group__"
9
12
 
@@ -58,7 +61,7 @@ def _normalize_tokens(tokens: Sequence[str] | str | None) -> tuple[str, ...]:
58
61
  return tuple(str(t).strip() for t in tokens if str(t).strip())
59
62
 
60
63
 
61
- def cli_command[TCommand: Command](
64
+ def cli_command(
62
65
  name: str | None = None,
63
66
  *,
64
67
  positional: Sequence[str] | str | None = None,
@@ -129,7 +132,7 @@ def cli_group(
129
132
  return decorator
130
133
 
131
134
 
132
- def cli_query[TQuery: Query](
135
+ def cli_query(
133
136
  name: str | None = None,
134
137
  *,
135
138
  positional: Sequence[str] | str | None = None,
@@ -0,0 +1,9 @@
1
+ from hexastack_cli.testing.events import TerminalEvent
2
+ from hexastack_cli.testing.narrator import CliNarrator
3
+ from hexastack_cli.testing.terminal import render_cli_demo_video
4
+
5
+ __all__ = [
6
+ "CliNarrator",
7
+ "render_cli_demo_video",
8
+ "TerminalEvent",
9
+ ]
@@ -0,0 +1,16 @@
1
+ """Domain models and data contracts for CLI testing and narrative demonstration."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ __all__ = [
6
+ "TerminalEvent",
7
+ ]
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class TerminalEvent:
12
+ """A discrete timestamped event within a CLI demo recording session."""
13
+
14
+ event_type: str # "step" | "input" | "output"
15
+ payload: str
16
+ timestamp: float
@@ -4,20 +4,12 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
  import time
7
- from dataclasses import dataclass
8
7
  from pathlib import Path
9
8
  from typing import Any
10
9
 
11
10
  from typer.testing import CliRunner, Result
12
11
 
13
-
14
- @dataclass(frozen=True)
15
- class TerminalEvent:
16
- """A discrete timestamped event within a CLI demo recording session."""
17
-
18
- event_type: str # "step" | "input" | "output"
19
- payload: str
20
- timestamp: float
12
+ from hexastack_cli.testing.events import TerminalEvent
21
13
 
22
14
 
23
15
  class CliNarrator:
@@ -9,7 +9,7 @@ import re
9
9
  import shutil
10
10
  from pathlib import Path
11
11
 
12
- from hexastack_cli.testing.narrator import TerminalEvent
12
+ from hexastack_cli.testing.events import TerminalEvent
13
13
  from hexastack_core.domain.exceptions import MissingDependencyError
14
14
 
15
15
  TERMINAL_HTML_TEMPLATE = """<!DOCTYPE html>
@@ -1,7 +0,0 @@
1
- """Testing utilities and demo recording engine for CLI applications."""
2
-
3
- from hexastack_cli.testing.narrator import CliNarrator
4
-
5
- __all__ = [
6
- "CliNarrator",
7
- ]
File without changes