# adaptivegears-cli

CLI tools for data engineering workflows. Published to PyPI as `adaptivegears`.

Documentation: `adaptivegears/man/adaptivegears-cli.md` (KB article with usage examples)

## Structure

```
adaptivegears-cli/
├── src/adaptivegears/
│   ├── cli.py          # Main CLI entrypoint
│   ├── aws/            # AWS utilities (pricing, compute)
│   ├── lookup/         # Lookup tables and mappings
│   ├── pg/             # PostgreSQL introspection
│   ├── tags/           # Resource tagging utilities
│   └── util/           # Shared utilities (uuid, etc.)
├── tests/              # pytest tests with VCR cassettes
├── pyproject.toml      # Package config (hatchling build)
└── Makefile            # Development commands
```

## Development

```bash
uv sync                     # Install dependencies
uv run adaptivegears --help # Run CLI
make test                   # Run tests
make lint                   # Run ruff check
make fmt                    # Format code
```

## Adding Commands

1. Create module in `src/adaptivegears/<name>/`
2. Add CLI in `<name>/cli.py` using typer
3. Register in `cli.py`: `app.add_typer(<name>_app, name="<name>")`
4. Add tests in `tests/`

## Testing

- Use pytest with `uv run pytest tests/ -v`
- VCR cassettes in `tests/cassettes/` for AWS API mocking
- Run `make test` before commits

## Publishing

```bash
make publish  # Build and publish to PyPI
```

Version is in `src/adaptivegears/__init__.py`.

## Behavioral Instructions

- YAGNI: No speculative code. Every feature must have a concrete use case.
- KISS: Straightforward solutions. Simple code > clever code.
- Errors are expected (network, I/O) - catch specific exceptions.
- Bugs should crash with full stack traces.
- Ask vs Assume: Clarify ambiguous requirements.
- No default values: Function parameters must be explicit. Caller decides.

## Code Style

- Ruff for linting and formatting
- Type hints required
- `--json` flag on commands for machine-readable output
- Use typer for CLI, pydantic for data validation
- CLI command functions: `command_<module>_<action>` (e.g., `command_tags_get`)

## Refactoring Instructions

- Large data changes: Use programmatic scripts, not manual edits.
- Propose, don't ask: "Here's X" not "What direction are you thinking?"
- Step-by-step: One transformation at a time. Verify each step.

## Naming

- Short and direct.
- Bad: `ResourceTypeConfig`, `cost_relevant`, `get_resource_by_id`
- Good: `ResourceOptions`, `tracked`, `get`
- Drop redundant suffixes. Context already provides meaning.
- Local scope = short names: `r`, `rt`, `opts`, `df` are fine.
- Default to short. Verbose does not mean clear.
- NEVER use type-based suffixes: `_list`, `_dict`, `_str`, `_int`, etc. are for idiots. The type system exists for a reason. `names` not `name_list`, `by_id` not `id_to_value_dict`.
