Metadata-Version: 2.5
Name: yanju
Version: 0.1.1
Summary: A local, disposable debugging harness for practical engineering skills
Project-URL: Homepage, https://yanju.dev/
Project-URL: Documentation, https://github.com/xyluz/yanju-scenarios/wiki
Project-URL: Issues, https://github.com/xyluz/yanju-scenarios/issues
Author: xyluz
License-Expression: MIT
License-File: LICENSE
Keywords: debugging,docker,education,harness,incident
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Education
Requires-Python: >=3.11
Requires-Dist: docker>=7
Requires-Dist: psutil>=6
Requires-Dist: pyyaml>=6
Requires-Dist: rich>=13
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: hatchling; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Description-Content-Type: text/markdown

# Yanjú

Yanjú (Yoruba for "to solve" / "bring order to chaos") is a local, disposable debugging harness. It drops engineers into containerized, intentionally broken apps so they can practice reading logs, fixing config, and shipping a working service — not trivia.

v0.1 points at **yanju-scenarios**: **broken-proxy** (Nginx → FastAPI under k6 load) and **broken-playbook** (Ansible deploys a Jinja nginx template onto a web host). The CLI does not ship scene files; it fetches a scene folder and copies only the editable surface into your working directory.

## Requirements

- Python 3.11+
- Docker Engine with Compose v2 (`docker compose`)

## Install

```bash
uv tool install yanju
# or: python3 -m pip install yanju
```

The wheel is the CLI engine only. Scene files come from [yanju-scenarios](https://github.com/xyluz/yanju-scenarios) at runtime (or a local checkout).

## Quick start

```bash
yanju check
yanju scene            # or: yanju scene --all   then   yanju init broken-proxy
yanju play
```

Edit the copied files in your IDE. Re-run `yanju play` after config changes so the stack recreates and hidden tests run. Use `--persist` to leave the stack up while you debug. Then:

```bash
yanju status
yanju verify
yanju reset
```

`init` copies the editable surface into the current directory (for broken-proxy: `app/`, `nginx/`, compose; for broken-playbook: `app/`, `ansible/`, compose) and writes a README from `brief.problem` / `brief.outcome`. Hidden `eval/` tests, the k6 overlay, and lab SSH keys stay in the scene checkout (cache or local `yanju-scenarios/`), not in your cwd.

## Commands

| Command | What it does |
| --- | --- |
| `yanju check` | Docker ping, RAM/CPU (warn below 2 GB / 2 CPUs). Pulls images for the current workspace scene if one is initialized |
| `yanju init <scenario>` | Copy workspace, `git init` + baseline commit. `--force` stops the previous stack, then replaces the workspace |
| `yanju scene` | List the catalog (`index.yaml`) and pick one to initialize. `--all` lists without initializing |
| `yanju play` | Start or recreate the stack, run hidden tests, stop containers if they fail. Logs stay at `.yanju/logs/stack.log`. `--persist` leaves the stack running (previous default). `--follow` streams logs after the stack stays up |
| `yanju help` | How to apply edits, logs, and verify |
| `yanju logs` | Tail captured logs (Ctrl+C detaches). `--no-follow` for a one-shot dump |
| `yanju status` | Container health, ports, CPU/memory, whether k6 is running |
| `yanju verify` | Hidden pytest against the scenario `verify.base_url` plus a git diff. PASS/FAIL is tests only; `app/` edits warn |
| `yanju stop` | `compose down -v`; keep workspace files and `.yanju/` logs |
| `yanju reset` | `compose down -v`, restore files to the init commit, keep `.yanju/` |

## Scenes

Scenes live in a separate **yanju-scenarios** catalog, not this package. Yanjú reads `index.yaml`, fetches that scene folder, and copies `workspace.copy` into cwd.

A source checkout of this repo uses `./yanju-scenarios` when present. Otherwise the CLI clones the remote in `yanju/catalog.yaml`. Overrides:

- `YANJU_SCENES_DIR` — path to a local checkout
- `YANJU_SCENES_REPO` / `YANJU_SCENES_REF` — git URL and branch/tag to clone into `~/.cache/yanju/scenes/` (or `YANJU_SCENES_CACHE`)

Default remote: `https://github.com/xyluz/yanju-scenarios.git`.

## Adding a scenario

Add a folder to **yanju-scenarios** (not this CLI) with:

- `scenario.yaml` — name, **brief.problem**, **brief.outcome**, images, `workspace.copy`, compose project, health service, verify URL, optional chaos command
- `docker-compose.yaml` — the whole stack (PHP-FPM, MySQL, Redis, … are fine)
- files listed in `workspace.copy`
- optional `docker-compose.k6.yaml` overlay (not copied to the candidate)
- optional `chaos/` hook
- `eval/` pytest files that read `YANJU_BASE_URL`
- a row in `index.yaml`

The harness never imports scenario Python and never assumes FastAPI or Nginx.

## Development

```bash
python3 -m pip install -e ".[dev]"
python3 -m pytest tests -v
```

The default suite does not need Docker.
