mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
feat(cli): modern Rich terminal styling across all modules
## Summary
Overhaul the CLI and all library modules to produce polished, modern
terminal output comparable to tools like uv, gh, and cargo. Rich was
already a declared dependency but barely used — this commit wires it
throughout every layer.
## Changes by layer
### semantica/cli.py — visual overhaul
- Add imports: `box`, `Panel`, `Rule`, `Syntax`, `Text` from Rich
- Add 7 style constants (`_BRAND`, `_KEY`, `_VAL`, `_DIM`, `_SUCCESS`,
`_WARN_STY`, `_TABLE_BOX`) for a consistent colour palette
- `_ok()` now prefixes output with a green ✓ checkmark
- New `_info()` helper (neutral · bullet, respects --quiet)
- New `_warn()` helper (yellow ⚠ prefix, never suppressed)
- New `_pprint()` helper: renders dicts/lists as syntax-highlighted JSON
(Rich Syntax, monokai theme) instead of raw Python repr; strings
pass through unchanged; respects --quiet
- `info` command: banner replaced with a rounded Rich Panel showing
version + tagline; component table uses SIMPLE_HEAD box
- All 7 table sites updated: `box=SIMPLE_HEAD`, `show_edge=False`,
consistent `_KEY`/`_VAL` column styles (KG Stats, Reasoning Engines,
Recent Decisions, Configured Backends, Backup Info, MCP Tools)
- `_run_build()`: `console.status(spinner="dots")` wraps the blocking
build call; skipped under --quiet / --json
- `parse`, `extract`, `embed generate`, `reason run`, `reason explain`,
`deduplicate`: each wraps its long-running operation in a status
spinner, guarded by --quiet / --json
- All 30+ `console.print(result)` calls replaced with `_pprint()`
- All raw `[yellow]Warning:[/yellow]` and "not running" patterns
replaced with the new `_warn()` / `_WARN_STY` style
### semantica/explorer/__init__.py
- Error messages use `Console(stderr=True)` with `[bold red]Error:[/bold red]`
- Graph loading wrapped in `console.status()` spinner
- Startup info replaced with a cyan-bordered Rich Panel showing URL,
API docs, and health endpoint
### Library internals — replace print() with structured logger calls
All modules below had active `print()` calls that bypassed the logging
framework, corrupted spinners, and polluted stdout in piped/programmatic
use. All replaced with appropriate `self.logger.*` calls:
- `semantica/kg/graph_builder.py` — 23 calls: entity resolution
progress, graph structure steps, GraphStore persistence timing, and
the two `='*60` completion banners → `self.logger.info/debug()`
- `semantica/semantic_extract/methods.py` — 4 verbose-mode debug
prints → `logger.debug()`
- `semantica/semantic_extract/relation_extractor.py` — progress +
error prints → `self.logger.debug/warning()` with `exc_info`
- `semantica/semantic_extract/triplet_extractor.py` — same pattern
- `semantica/semantic_extract/semantic_network_extractor.py` — batch
error prints → `self.logger.warning/error()`
- `semantica/semantic_extract/coreference_resolver.py` — error print
→ `self.logger.error()`
- `semantica/semantic_extract/providers.py` — debug print →
`self.logger.debug()`
### Tooling
- `benchmarks/benchmarks_runner.py`: Rule banner, ✓/✗/⚠ status lines,
Rule separators around regression alert
- `benchmarks/infrastructure/compare.py`: removed manual ANSI escape
codes; comparison output is now a Rich Table with SIMPLE_HEAD;
summary uses coloured Rule + styled SUCCESS/FAILURE messages
- `cookbook/advanced/snowflake_ingestion_examples.py`: `_section()`
helper using Rule; tabular data rendered as Rich Table; result lines
use ✓/✗/⚠ prefixes; logger.error already present, retained
- `docs_check.py`: `pass`/`FAIL` lines use `[bold green]` /
`[bold red]`; summary uses styled output
## Tests
- `tests/test_cli_commands.py`: fix 3 pre-existing mock mismatches
- `test_kg_stats_json_with_mock`: mock now uses `compute_metrics()`
(the method the code actually calls) instead of `get_statistics()`
- `test_dry_run_not_needed_extract_is_read_only` and
`test_stdin_input`: mock now provides `NERExtractor`,
`RelationExtractor`, `TripletExtractor`, `EventDetector`
(the classes the code imports) instead of `SemanticAnalyzer`
Result: 230/230 tests pass (was 227/230)
- `tests/verify_rich_cli.py`: new verification script; exercises all
14 command groups (92 --help checks, table rendering, dry-run
formatting, --json mode, _pprint helper); 111 pass, 0 fail
This commit is contained in:
+9
-6
@@ -8,10 +8,13 @@ import re
|
||||
import sys
|
||||
from typing import Any, Callable, cast
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
DOCS = "docs"
|
||||
ALL_MD: list[str] = glob.glob(f"{DOCS}/**/*.md", recursive=True)
|
||||
|
||||
failures: list[str] = []
|
||||
console = Console()
|
||||
|
||||
|
||||
def check(label: str) -> Callable[[Callable[[], list[str]]], None]:
|
||||
@@ -19,12 +22,12 @@ def check(label: str) -> Callable[[Callable[[], list[str]]], None]:
|
||||
def decorator(fn: Callable[[], list[str]]) -> None:
|
||||
issues = fn()
|
||||
if issues:
|
||||
print(f"FAIL {label}")
|
||||
console.print(f"[bold red]FAIL[/bold red] {label}")
|
||||
for msg in issues:
|
||||
print(f" - {msg}")
|
||||
console.print(f"[dim] - {msg}[/dim]")
|
||||
failures.extend(issues)
|
||||
else:
|
||||
print(f"pass {label}")
|
||||
console.print(f"[bold green]pass[/bold green] {label}")
|
||||
return decorator
|
||||
|
||||
|
||||
@@ -162,9 +165,9 @@ def _() -> list[str]:
|
||||
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────────────────────────
|
||||
print()
|
||||
console.print()
|
||||
if failures:
|
||||
print(f"FAILED {len(failures)} issue(s) found")
|
||||
console.print(f"[bold red]FAILED[/bold red] {len(failures)} issue(s) found")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("All checks passed")
|
||||
console.print("[bold green]All checks passed[/bold green]")
|
||||
|
||||
Reference in New Issue
Block a user