hexastack-cli 0.1.0__tar.gz → 0.3.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.
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/PKG-INFO +3 -3
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/README.md +2 -2
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/pyproject.toml +22 -1
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/pyproject.toml.orig +26 -1
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/adapters/__init__.py +0 -2
- {hexastack_cli-0.1.0/src/hexastack_cli/infra → hexastack_cli-0.3.0/src/hexastack_cli/domain}/config.py +0 -20
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/infra/__init__.py +2 -0
- {hexastack_cli-0.1.0/src/hexastack_cli/adapters → hexastack_cli-0.3.0/src/hexastack_cli/infra}/app.py +1 -1
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/infra/bootstrap.py +1 -1
- hexastack_cli-0.3.0/src/hexastack_cli/infra/config.py +19 -0
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/infra/decorators.py +6 -3
- hexastack_cli-0.3.0/src/hexastack_cli/py.typed +0 -0
- hexastack_cli-0.3.0/src/hexastack_cli/testing/__init__.py +9 -0
- hexastack_cli-0.3.0/src/hexastack_cli/testing/events.py +16 -0
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/testing/narrator.py +1 -9
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/testing/terminal.py +1 -1
- hexastack_cli-0.1.0/src/hexastack_cli/testing/__init__.py +0 -7
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/__init__.py +0 -0
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/adapters/presenter.py +0 -0
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/adapters/routing.py +0 -0
- /hexastack_cli-0.1.0/src/hexastack_cli/py.typed → /hexastack_cli-0.3.0/src/hexastack_cli/domain/__init__.py +0 -0
- {hexastack_cli-0.1.0 → hexastack_cli-0.3.0}/src/hexastack_cli/infra/autodiscovery.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hexastack-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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>
|
|
@@ -43,8 +43,8 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
```
|
|
44
44
|
hexastack_cli/
|
|
45
45
|
├── domain/ # CliContext, OutputFormat enum
|
|
46
|
-
├── adapters/ #
|
|
47
|
-
└── infra/ # CliBootstrapper (order=
|
|
46
|
+
├── adapters/ # Rich presenters, Typer command runners
|
|
47
|
+
└── infra/ # create_cli_app, CliBootstrapper (order=40), @cli_command, @cli_query, @cli_group, @feature_flag_command
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### Key Exports
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
```
|
|
28
28
|
hexastack_cli/
|
|
29
29
|
├── domain/ # CliContext, OutputFormat enum
|
|
30
|
-
├── adapters/ #
|
|
31
|
-
└── infra/ # CliBootstrapper (order=
|
|
30
|
+
├── adapters/ # Rich presenters, Typer command runners
|
|
31
|
+
└── infra/ # create_cli_app, CliBootstrapper (order=40), @cli_command, @cli_query, @cli_group, @feature_flag_command
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
### Key Exports
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hexastack-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.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
|
+
"infra",
|
|
44
|
+
"adapters",
|
|
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.
|
|
3
|
+
version = "0.3.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
|
+
"infra",
|
|
43
|
+
"adapters",
|
|
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
|
+
]
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from hexastack_cli.adapters.app import create_cli_app
|
|
2
1
|
from hexastack_cli.adapters.presenter import RichTerminalPresenter
|
|
3
2
|
from hexastack_cli.adapters.routing import (
|
|
4
3
|
register_cqrs_command,
|
|
@@ -6,7 +5,6 @@ from hexastack_cli.adapters.routing import (
|
|
|
6
5
|
)
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
|
9
|
-
"create_cli_app",
|
|
10
8
|
"register_cqrs_command",
|
|
11
9
|
"register_cqrs_query",
|
|
12
10
|
"RichTerminalPresenter",
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
from pydantic import BaseModel, Field
|
|
2
2
|
|
|
3
|
-
from hexastack_core.infra.decorators import config_section
|
|
4
|
-
from hexastack_core.infra.registries.config import ConfigRegistry
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
@config_section("cli")
|
|
8
4
|
class HexastackCliConfig(BaseModel):
|
|
9
5
|
"""Configuration schema for Hexastack CLI presentation adapter.
|
|
10
6
|
|
|
@@ -24,20 +20,4 @@ class HexastackCliConfig(BaseModel):
|
|
|
24
20
|
|
|
25
21
|
__all__ = [
|
|
26
22
|
"HexastackCliConfig",
|
|
27
|
-
"register_cli_config",
|
|
28
23
|
]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def register_cli_config(registry: ConfigRegistry) -> None:
|
|
32
|
-
"""Register CLI configuration schema with a ConfigRegistry under 'cli'.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
registry: Target ConfigRegistry instance.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
None.
|
|
39
|
-
|
|
40
|
-
Raises:
|
|
41
|
-
None.
|
|
42
|
-
"""
|
|
43
|
-
registry.register_config_section("cli", HexastackCliConfig)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from hexastack_cli.infra.app import create_cli_app
|
|
1
2
|
from hexastack_cli.infra.autodiscovery import (
|
|
2
3
|
autodiscover_cli_commands,
|
|
3
4
|
create_cli_visitor,
|
|
@@ -22,6 +23,7 @@ __all__ = [
|
|
|
22
23
|
"cli_query",
|
|
23
24
|
"CliBootstrapper",
|
|
24
25
|
"CliMetadata",
|
|
26
|
+
"create_cli_app",
|
|
25
27
|
"create_cli_visitor",
|
|
26
28
|
"GroupMetadata",
|
|
27
29
|
"HexastackCliConfig",
|
|
@@ -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()
|
|
@@ -34,7 +34,7 @@ class CliBootstrapper(BootstrapperPort):
|
|
|
34
34
|
Raises:
|
|
35
35
|
None.
|
|
36
36
|
"""
|
|
37
|
-
from hexastack_cli.
|
|
37
|
+
from hexastack_cli.infra.app import create_cli_app
|
|
38
38
|
from hexastack_cli.infra.autodiscovery import create_cli_visitor
|
|
39
39
|
|
|
40
40
|
cfg = HexastackCliConfig()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from hexastack_cli.domain.config import HexastackCliConfig
|
|
2
|
+
from hexastack_core.infra.decorators import config_section
|
|
3
|
+
from hexastack_core.infra.registries.config import ConfigRegistry
|
|
4
|
+
|
|
5
|
+
config_section("cli")(HexastackCliConfig)
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"HexastackCliConfig",
|
|
9
|
+
"register_cli_config",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def register_cli_config(registry: ConfigRegistry) -> None:
|
|
14
|
+
"""Register CLI configuration schema with a ConfigRegistry under 'cli'.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
registry: Target ConfigRegistry instance.
|
|
18
|
+
"""
|
|
19
|
+
registry.register_config_section("cli", HexastackCliConfig)
|
|
@@ -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
|
|
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
|
|
135
|
+
def cli_query(
|
|
133
136
|
name: str | None = None,
|
|
134
137
|
*,
|
|
135
138
|
positional: Sequence[str] | str | None = None,
|
|
File without changes
|
|
@@ -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.
|
|
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>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|