Metadata-Version: 2.3
Name: uv-router
Version: 0.1.0
Summary: Immediate Python command startup with atomic background updates through uv
Requires-Python: >=3.11
Project-URL: Repository, https://github.com/nimashoghi/uv-router
Description-Content-Type: text/markdown

# uv-router

Install Python commands that start immediately and update in the background. The foreground shell shim executes an already installed environment. It does not invoke uv or wait for network access.

Requires macOS or Linux, Python 3.11+, and [uv](https://docs.astral.sh/uv/). Install this tool into a stable environment with `uv tool install uv-router` from [PyPI](https://pypi.org/project/uv-router/). `uvx uv-router --help` also runs the CLI without a tool installation; use the stable tool installation for long-lived managed commands because their background updater uses its Python environment. Then install commands:

```sh
uv-router install ruff ruff
uv-router install my-command 'package-name @ git+https://github.com/owner/project.git@main' \
  --entrypoint actual-console-script --with another-package --python 3.13
my-command --help
uv-router update my-command
uv-router status my-command
```

`--bin-dir` defaults to `~/.local/bin`. Use a separate directory for evaluation. The installer refuses to overwrite commands it does not own. `UV_ROUTER_HOME` selects the installation-state directory; its default is `~/.local/share/uv-router`.

Each invocation captures the current immutable generation and starts a detached update check. Concurrent checks for the same tool coalesce under a process lock. A check resolves all requested packages together, pinning Git dependencies to concrete revisions. If the resolved installation is unchanged, it keeps the existing environment. Otherwise it creates a new environment at its final path, checks dependencies and loads the Python entrypoint (or verifies ownership of a wheel-provided executable), then atomically switches the generation used by future launches. Virtual environments are never moved after creation, because their scripts contain absolute paths.

The launched command retains its arguments, working directory, environment and exit status. Updates never mutate its environment. An offline or failed update leaves the installed version usable. `status` reports the current generation and the last completed update result; background diagnostics are in `<UV_ROUTER_HOME>/<command>/update.log`. Checks use the existing uv/Git authentication configuration and do not change it.

An initial installation requires dependency access. Automatic updates have a 600-second timeout per subprocess by default; configure it with `install --timeout`. Validation checks installation and entrypoint integrity, not application-specific behavior. Keep old generations while processes may still use them; this release deliberately does not automatically delete them. Reinstalling this launcher itself is explicit, using `uv tool upgrade uv-router`.

## Codex-router example

All five packages are resolved in one operation, so a moving Git ref produces one consistent suite revision:

```sh
uv-router install codexr \
  'codex-router @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-router' \
  --with 'codex-router-sdk @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-router-sdk' \
  --with 'codex-monitor @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-monitor' \
  --with 'codex-recovery @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-recovery' \
  --with 'codex-accounts @ git+https://github.com/nimashoghi/codex-router.git@main#subdirectory=packages/codex-accounts' \
  --bin-dir ~/.local/share/codexr-evaluation/bin
```

Use that isolated command before choosing to replace an existing launcher. Updating the local codexr suite and preparing that exact suite on an SSH host remain separate responsibilities; uv-router contains no Codex or SSH runtime logic.

## Development

```sh
uv sync
uv run pytest -q
uv run ruff check .
uv run ruff format --check .
```

Integration tests create local Git packages and exercise installation, immutable revisions, background publication, failed updates, concurrent checks, offline launches, and preservation of unrelated commands.
