Skip to content

Commit 8051f29

Browse files
olivermeyerclaude
andcommitted
feat(console): add themed Rich console
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2b656bb commit 8051f29

6 files changed

Lines changed: 108 additions & 2 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ requires-python = ">=3.11, <3.15"
5151

5252
dependencies = [
5353
"pydantic>=2,<3",
54+
"rich>=14,<15",
5455
]
5556

5657
[dependency-groups]

src/aignostics_foundry_core/AGENTS.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,26 @@ This file provides an overview of all modules in `aignostics_foundry_core`, thei
88

99
| Module | Purpose | Description |
1010
|--------|---------|-------------|
11+
| **console** | Themed terminal output | Module-level `console` object (Rich `Console`) with colour theme and `_get_console()` factory |
1112
| **health** | Service health checks | `Health` model and `HealthStatus` enum for tree-structured health status |
1213

1314
## Module Descriptions
1415

1516
<!-- For each module, document its purpose, features, dependencies, and usage. -->
1617

18+
### console
19+
20+
**Themed Rich console for structured terminal output**
21+
22+
- **Purpose**: Provides a module-level `console` object pre-configured with a colour theme for consistent, styled terminal output across all Foundry components
23+
- **Key Features**:
24+
- `console` — module-level `Console` singleton, ready to use
25+
- Colour theme: `success` (green), `info` / `logging.level.info` (purple4), `warning` (yellow1), `error` (red1), `debug` (light_cyan3)
26+
- `AIGNOSTICS_CONSOLE_WIDTH` env var — overrides console width (defaults to Rich's auto-detect, 80 in non-TTY environments)
27+
- `legacy_windows=False` — modern Windows terminal support
28+
- **Location**: `aignostics_foundry_core/console.py`
29+
- **Dependencies**: `rich>=13`
30+
1731
### health
1832

1933
**Tree-structured health status for service health checks**
@@ -47,12 +61,22 @@ This file provides an overview of all modules in `aignostics_foundry_core`, thei
4761
┌──────────────┴──────────────┐
4862
│ aignostics_foundry_core │
4963
├─────────────────────────────┤
64+
│ console │
5065
│ health │
5166
└─────────────────────────────┘
5267
```
5368

5469
## Usage Examples
5570

71+
```python
72+
from aignostics_foundry_core import console
73+
74+
# Print with theme styles
75+
console.print("[success]Done![/success]")
76+
console.print("[warning]Caution: retrying...[/warning]")
77+
console.print("[error]Failed to connect.[/error]")
78+
```
79+
5680
```python
5781
from aignostics_foundry_core.health import Health, HealthStatus
5882

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
"""Foundational infrastructure for Foundry components."""
1+
"""Foundational infrastructure for Foundry components.
2+
3+
We do NOT export any of the public APIs of the Foundry components here; see docs/decisions/0002-module-structure.md.
4+
"""
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Themed rich console."""
2+
3+
import os
4+
5+
from rich.console import Console
6+
from rich.theme import Theme
7+
8+
9+
def _get_console() -> Console:
10+
"""Get a themed rich console.
11+
12+
The console width can be set via the AIGNOSTICS_CONSOLE_WIDTH environment variable.
13+
14+
Returns:
15+
Console: The themed rich console.
16+
"""
17+
return Console(
18+
theme=Theme({
19+
"logging.level.info": "purple4",
20+
"debug": "light_cyan3",
21+
"success": "green",
22+
"info": "purple4",
23+
"warning": "yellow1",
24+
"error": "red1",
25+
}),
26+
width=int(os.environ.get("AIGNOSTICS_CONSOLE_WIDTH", "0")) or None,
27+
legacy_windows=False, # Modern Windows (10+) doesn't need width adjustment
28+
)
29+
30+
31+
console = _get_console()
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""Tests for console module."""
2+
3+
import importlib
4+
import sys
5+
6+
import pytest
7+
from rich.console import Console
8+
9+
from aignostics_foundry_core.console import console
10+
11+
EXPECTED_THEME_KEYS = ["success", "info", "warning", "error", "debug", "logging.level.info"]
12+
13+
14+
class TestConsole:
15+
"""Tests for the themed rich console module."""
16+
17+
@pytest.mark.unit
18+
def test_console_is_console_instance(self) -> None:
19+
"""Module-level console is a rich.console.Console instance."""
20+
assert isinstance(console, Console)
21+
22+
@pytest.mark.unit
23+
@pytest.mark.sequential
24+
def test_console_default_width(self, monkeypatch: pytest.MonkeyPatch) -> None:
25+
"""Module-level console has Rich's default width (80) when env var is not set."""
26+
monkeypatch.delenv("AIGNOSTICS_CONSOLE_WIDTH", raising=False)
27+
reloaded = importlib.reload(sys.modules["aignostics_foundry_core.console"])
28+
assert reloaded.console.width == 80
29+
30+
@pytest.mark.unit
31+
@pytest.mark.sequential
32+
def test_console_custom_width(self, monkeypatch: pytest.MonkeyPatch) -> None:
33+
"""Module-level console uses width from AIGNOSTICS_CONSOLE_WIDTH env var."""
34+
monkeypatch.setenv("AIGNOSTICS_CONSOLE_WIDTH", "100")
35+
reloaded = importlib.reload(sys.modules["aignostics_foundry_core.console"])
36+
assert reloaded.console.width == 100
37+
38+
@pytest.mark.unit
39+
def test_console_theme_contains_expected_keys(self) -> None:
40+
"""Console can render text with all required theme style names without error."""
41+
for key in EXPECTED_THEME_KEYS:
42+
style = console.get_style(key)
43+
assert style is not None, f"Theme style '{key}' should be defined on the console."

uv.lock

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)