Metadata-Version: 2.4
Name: rpr-cli
Version: 0.3.10
Requires-Dist: typer>=0.24.1
Requires-Dist: jinja2>=3.1.5
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: rich>=14.3.3
Requires-Dist: pathspec>=1.0.4
Requires-Dist: prompt-toolkit>=3.0.52
Requires-Dist: tomlkit>=0.15.0
Requires-Dist: packaging>=26.2
License-File: LICENSE
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
License-Expression: MIT
Requires-Python: >=3.14
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# RPR CLI

React Python Rust monorepo scaffolding orchestrator.

## Installation

Published package name: `rpr-cli`

Once published to PyPI, install by name with either:

```bash
uv add rpr-cli
uv tool install rpr-cli
```

Both install the `rpr` command.

For development, editable install is fine:

```bash
uv sync
uv run maturin develop
```

For an actual distributable install you can use in other projects, build the wheel first and install the built artifact:

```bash
uv build
uv tool install dist/rpr_cli-*.whl
```

From another local project you can also install the built artifact directly:

```bash
uv add ../project-getting-started/dist/rpr_cli-*.whl
```

The published wheels are mixed Python/Rust distributions. The `rpr._native`
binding used by `rpr rename` and accelerated `rpr map` is installed alongside
the Python package; no separate parser installation is required.

## Usage

### 🚀 Scaffolding & Generation

Create a new NX + UV monorepo, then add apps and packages as needed.

> NX monorepo uses integrated mode.

```bash
rpr init my-app              # Create/init my-app with root NX + UV tooling and AI instructions
cd my-app
rpr generate domain my-app   # Add a Python domain package
rpr generate api my-app      # Add a FastAPI application
rpr generate ui my-app       # Add a React UI library and web app
rpr generate engine my-app   # Add a Rust/PyO3 computation engine
rpr generate storybook       # Add Storybook for UI component development
rpr rename new-app           # Rename the workspace identity and references
```

Run `rpr rename <new-name>` from an initialized workspace root to update RPR
metadata, package and Nx project names, imports, commands, paths, lockfiles, and
matching references in user-added text files. The command shows its complete
change plan before asking for confirmation. Use `--dry-run` to preview without
writing or `--yes` to skip the prompt. On its first invocation, rename creates a
`.rename-ignore` file and stops so you can review the generated dependency,
environment, cache, and build-output exclusions before rerunning. The file uses
gitignore-style patterns and is independent of `.gitignore`, allowing ignored
source and experiments to remain in rename scope. Binary contents, VCS data, and
symlink targets are never changed. The outer workspace directory keeps its
existing name.

After applying the rename, RPR synchronizes Node and Python dependencies and
runs uncached Nx build, Rust-engine build, and typecheck targets with the Nx
daemon disabled. This verifies the renamed project graph and commands without
deleting the existing Nx cache. Pass `--skip-verify` to omit these checks; a
dry run previews them without executing anything. If verification fails, the
rename remains applied and RPR prints the command to retry.

The success output includes a guarded command for optionally renaming the outer
workspace directory. Git remotes and hosted repository names are never changed.
When a hosted repository still matches the old project name, rename it through
the hosting provider if desired and then update its local URL with
`git remote set-url`. Local and remote branch names are unaffected.

`rpr init <project-name>` creates the project directory when it does not exist. If the directory already exists and is not an NX workspace, RPR initializes Git and runs `nx init` inside that directory.

By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold` or pass a comma-separated list:

```bash
rpr init todo-list --scaffold common
rpr init todo-list --scaffold domain
rpr init todo-list --scaffold api --domain-migrations
rpr init todo-list --scaffold api --scaffold web --domain-migrations
```

Available scaffolds are:

- `common`: Alias for `instructions`, `domain`, `api`, `ui`, `web`, and `storybook`; excludes `engine`.
- `instructions`: AI instruction files for Cursor, Copilot, Claude Code, Gemini, and Codex.
- `domain`: Python DDD package at `packages/python/domain`.
- `api`: FastAPI app at `apps/<name>-api`; also scaffolds `domain`.
- `ui`: React UI library at `packages/node/<name>-ui`.
- `web`: React web app at `apps/<name>-web`; also scaffolds `ui`.
- `storybook`: Storybook host package; requires or scaffolds `ui`.
- `engine`: Rust/PyO3 package at `packages/python/<name>-engine`.

### Dependency Placement

RPR keeps dependencies close to the package that uses them.

- Root Python tooling such as Ruff, pytest, pyright, pre-commit, and maturin lives in the root `pyproject.toml`.
- Domain runtime dependencies such as `sqlmodel`, `asyncpg`, `pydantic-settings`, and optional `alembic` are added to `packages/python/domain/pyproject.toml`.
- API runtime dependencies such as `fastapi`, `uvicorn`, and the workspace domain package are added to `apps/<name>-api/pyproject.toml`.
- Node dependencies are written to the relevant package-level `package.json` files, and `npm install` runs from the root workspace.

Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made through npm workspace package metadata and root `npm install`.

Update project-owned package manifests from upstream registries with `rpr update node` or `rpr update python`. Node updates target `package.json`; Python updates target `pyproject.toml` by default and fall back to `requirements.txt` when no `pyproject.toml` exists. Use `--file` to update a nested manifest, `--dry-run` to preview without changing files or running installers, and `--include-major` to opt into major-version updates.

The scaffold version manifest that powers generated dependency specs and the synced AI tech-stack overview lives in `src/rpr/dependency_manifest_data.py`. Refresh it from upstream registries with `rpr refresh manifest` when you want the repo-owned defaults to move forward.

### 🧠 AI Instructions & Code Templates

Sync project context to your favorite AI tools and add common code patterns.

```bash
rpr sync rules                         # Sync AI instructions to all supported coding agents
rpr sync rules --target claude         # Sync only Claude
rpr sync rules -t claude -t codex      # Sync Claude and Codex
rpr add template python mapper_util    # Add a Python code template to your project
rpr add template python camel_case_model
rpr add template node sticky_navigation --include-tests
rpr add template node -l               # List available Node/TSX templates
rpr add template --list                # List all available code templates
```

Use `--output-dir` to write generated files to a different directory while keeping the template filenames. Templates with test companions can use `--include-tests`; Node browser-test templates print the extra npm dev dependencies and any Playwright setup notes they need. Existing config files such as `vitest.config.ts` are not merged automatically; RPR leaves them unchanged unless you rerun with `--force` to replace them.

### 💬 Interactive Shell

`rpr chat` is the primary interactive shell for the product. It runs a Rich-based session with slash commands for both chat controls and existing CLI workflows.

```bash
rpr chat                                 # Start the interactive shell
rpr chat --approval-mode auto-readonly   # Override the session approval mode
```

Inside the shell:

```text
/help        List supported slash commands
/settings    Inspect and update persisted settings in-shell
/init        Run workspace bootstrap from chat
/generate    Run scaffolding commands from chat
/sync        Sync AI instructions from chat
/add         Add a registered template from chat
/check       Run workspace health checks from chat
/map         Generate a code map from chat
/exit        End the session
```

There is no separate `--tui` mode. The unified shell is the default chat experience.

### 🛠️ Maintenance & Insights

Keep your project healthy and explore its structure.

```bash
rpr refresh manifest         # Refresh the scaffold dependency manifest from npm, PyPI, and crates.io
rpr update node              # Update package.json dependencies and run npm install
rpr update python            # Update pyproject.toml or requirements.txt and sync Python dependencies
rpr check                    # Inspect project health and report setup status
rpr map                      # Generate a structured code map of your project
rpr settings                 # Inspect persisted shell settings
rpr settings set theme ocean # Update the terminal theme
rpr settings set approval_mode auto-all
rpr settings set startup_help false
```

Persisted settings currently include:

- `theme`: Rich console theme
- `approval_mode`: default chat approval mode (`ask`, `auto-readonly`, `auto-all`)
- `startup_help`: whether chat shows slash-command guidance on startup

`rpr refresh manifest` is a repo-maintenance command. It rewrites `src/rpr/dependency_manifest_data.py`, which feeds scaffold dependency versions in `rpr generate ...` and the versioned overview text produced by `rpr sync rules`. Use `--dry-run` to preview the manifest rewrite without writing the file.

`rpr update node` and `rpr update python` are project-maintenance commands. They update the selected package manifest, print applied and held-back dependency changes, and run the matching installer only when live changes are written. Without `--include-major`, RPR chooses the latest stable version inside the current major version and reports higher-major candidates as held back. Python updates cover `[project].dependencies`, `[dependency-groups].*`, and `requirements.txt`; build backend packages in `[build-system].requires` are left unchanged unless a future explicit build-system update option is added.

### ⚙️ Common Flags

Most commands support these global flags:

- `--dry-run`: Preview changes without writing any files.
- `--help`: Show detailed help for any command or subcommand.

Example:

```bash
rpr init my-app --scaffold domain --dry-run
rpr generate api my-app --dry-run
```

Dry runs print the commands RPR would execute, the files/directories it would create or update, and the package dependencies it would add with their target scope.

The `check` command also supports:

- `--json`: Output machine-readable JSON for CI/CD integration.

The `chat` command also supports:

- `--provider`: Override the AI provider. The mock provider is the only supported provider today.
- `--model`: Override the active model name.
- `--approval-mode`: Override the session approval mode without changing persisted settings.

### Project Development

#### Setup

```bash
# Install Python dependencies
uv sync

# Rebuild the bundled Rust extension after native code changes
uv run maturin develop
```

> **Note:** `uv tool install rpr-cli` installs the matching platform wheel with
> the Rust binding included. Building from a source checkout requires a Rust
> toolchain because Maturin compiles the same native module locally.

#### Running Tests

```bash
# Full test suite (Python)
uv run pytest

# Single test file
uv run pytest tests/test_map_extractor.py

# Single test
uv run pytest tests/test_map_extractor.py::test_fallback_returns_correct_shape

# Rust unit tests (bundled native crate)
cd rpr-parser && cargo test && cd ..

# Lint and format
uv run ruff check .
uv run ruff format .
```

The Rust-path tests in `tests/test_map_extractor.py` are automatically skipped if the bundled
extension has not been built yet — run `uv run maturin develop` first to enable them.

### Publishing To PyPI

This repo is set up to publish the package `rpr-cli` to PyPI from GitHub Actions.

One-time setup:

1. Create the PyPI project `rpr-cli`.
2. Create a PyPI Trusted Publisher for this repository using workflow `.github/workflows/publish-pypi.yml` and environment `pypi`.

No `PYPI_API_TOKEN` secret is required when publishing through GitHub Actions OIDC.

Release flow:

```bash
rpr version bump patch             # updates Python, Cargo.toml, and Cargo.lock
# Or repair/set an explicit version: rpr version set 0.3.9
git add src/rpr/__init__.py rpr-parser/Cargo.toml rpr-parser/Cargo.lock
git commit -m "Release 0.3.9"
git tag v0.3.9
git push origin main --tags
```

The workflow in `.github/workflows/publish-pypi.yml` checks both version declarations against the
tag, builds an sdist plus native wheels for Linux x86-64/AArch64, Windows x86-64, and macOS
x86-64/Apple Silicon, then publishes all artifacts to PyPI.

