# CLAUDE.md

Guidance for Claude Code when working in the styrene-tui project.

## Overview

Styrene TUI is a Python terminal user interface for Reticulum mesh network and MANET management. Built with [Textual](https://textual.textualize.io/), it provides an interface for managing edge devices over Reticulum mesh networks.

## Operational Commands

**The Makefile is the source of truth for all operational commands.**

```bash
make run          # Launch the TUI
make dev          # Launch with hot reload (textual --dev)
make test         # Run all tests in container (canonical)
make test-local   # Run tests locally (skips RNS singleton tests)
make lint         # Run ruff linter
make format       # Format code with ruff
make typecheck    # Run mypy
make validate     # Run lint + typecheck + test (pre-commit check)
make clean        # Remove cache directories
make install      # Install package with dev dependencies
```

If a task is repeatable and deterministic, it belongs in the Makefile.

## Theming

All colors derive from a single **phosphex** root color. Change the phosphex, the entire UI shifts cohesively. 32 forge world presets available.

- Use `HighlightedPanel` for sectioned content (corner-highlighted borders)
- Use semantic symbols (`●○◐◓`) + text-styles for status differentiation
- CSS uses `$variables` (never hardcode hex colors)
- See `examples/widget_gallery.py` for reference implementation

Full details in `.claude/skills/styrene-theming/SKILL.md`.

## Development Workflow

1. **Write Tests First** - Tests define the contract before implementation
2. **Validate Tests Fail** - Run `make test` to confirm tests fail correctly
3. **Implement Functionality** - Write minimal code to pass tests
4. **Validate** - Run `make validate` (lint + typecheck + test)
5. **Visual QA** - Use tmux harness for rendered output verification

### RNS Singleton Tests

RNS (Reticulum Network Stack) is a true singleton that cannot be reset within a single process. Tests marked `@pytest.mark.rns_singleton` are always skipped in normal test runs because they require process isolation.

**`make test`** runs all tests in a Docker container. Singleton tests are skipped but each container run starts with fresh global state.

**`make test-local`** runs tests directly on the host with the same skip behavior.

To test RNS initialization behavior, run tests individually:
```bash
python -m pytest tests/services/test_rns_service.py::TestRNSServiceInitialization::test_initialize_creates_reticulum_instance -v
```

## Visual Testing with tmux

tmux enables visual verification by launching the TUI in a controlled terminal environment.

| Capability | Benefit |
|------------|---------|
| Fixed terminal size | Reproducible layouts (80x24) |
| Detached sessions | Run TUI without interactive terminal |
| ANSI capture | Get actual rendered output with colors |
| Key injection | Simulate user input programmatically |

Quick test:

```bash
tmux new-session -d -s styrene_test -x 80 -y 24
tmux send-keys -t styrene_test 'source .venv/bin/activate && python -m styrene' Enter
sleep 2
tmux capture-pane -t styrene_test -e -p > /tmp/capture.txt
tmux kill-session -t styrene_test
```

For programmatic testing, see `TmuxTestHarness` in `.claude/skills/textual-tui-testing/SKILL.md`.

## Complex Tasks: Cleave

For multi-system changes, use `/cleave "directive"` to recursively decompose tasks into independent subtasks with automatic reunification.

**When to use**: Multi-file features, cross-layer changes, anything touching 3+ systems.

**Invocation**: `/cleave "Add feature X with Y constraints"`

Cleave assesses complexity, splits along domain boundaries, executes children (possibly recursively), and reunifies results with conflict detection.

## Skills Reference

| Skill | Purpose |
|-------|---------|
| `/cleave` | Recursive task decomposition for complex multi-system changes |
| `.claude/skills/styrene-theming/` | Theming system, color cascade, semantic differentiation |
| `.claude/skills/textual-tui-testing/` | TUI testing patterns, tmux harness, visual validation |

## Test Hardware

| Device | Hostname | User | SSH Key |
|--------|----------|------|---------|
| ASUS Q502L tablet-book | styrene-node.vanderlyn.local | styrene | ~/.ssh/styrene-admin |

## PyPI Distribution

- **PyPI package name**: `styrene-tui` (`pip install styrene-tui`)
- **Python module name**: `styrene` (import path unchanged)
- **CLI command**: `styrene` (unchanged)
- **Meta-package**: `pip install styrene` installs the full stack (styrened + styrene-tui) via the `styrene-pypi` meta-package
