Skip to main content

ixt

ixt — Universal CLI Tool Isolator

Release Build: GitLab CI PyPI PyPI Downloads License: MIT Python 3.10+

Work in Progress

One CLI for Python, Node, and binary tools — each in its own isolated env.

Zero third-party deps. Zero system pollution. One command, any ecosystem.

  • Day-one GitHub releases — install a tool the day it ships, without waiting for a formula, registry entry, or plugin.
  • No system runtime needed — ixt is pure Python stdlib; uv and bun are bootstrapped on first use, so the host does not need Node, npm, or a package manager pre-installed.
ixt tool install ruff                      # Python (PyPI)
ixt tool install @anthropic-ai/claude-code # npm package via bun
ixt tool install ripgrep                   # Binary (GitHub — via built-in registry)

Each tool gets its own isolated environment. Only the binaries you choose are exposed to your PATH.

📥 Install

From PyPI. The published package is ixt-cli; it installs the ixt command.

# One-shot via uvx (requires uv)
uvx --from ixt-cli ixt --help

# Persistent install via uv tool
uv tool install ixt-cli

Or from source:

git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
uv tool install -e .

Then add $IXT_HOME/installed/bin to your PATH:

ixt setup path

Integrity verification

Release tags are SSH-signed. Installing from PyPI does not verify the Git tag signature locally. Use the clone flow when you want to verify a signed release before installing:

# Verify the signed tag (requires the maintainer's SSH public key in git's allowed_signers)
git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
git fetch --tags
git verify-tag vX.Y.Z
git checkout --detach vX.Y.Z
uv tool install .

A valid tag signature means the checked-out source matches the maintainer-signed release tag.

🚀 Quick Start

# Install tools from 3 ecosystems
ixt tool install ruff                        # Python linter
ixt tool install @google/gemini-cli          # Node CLI
ixt tool install sharkdp/fd                  # GitHub binary

# List installed tools
ixt tool list
#  ruff          0.5.0   pypi     [ruff]
#  gemini-cli    0.1.12  npm      [gemini]
#  fd            10.2.0  github   [fd]

# Upgrade
ixt tool upgrade ruff
ixt tool upgrade --all

# Uninstall
ixt tool uninstall fd

⚙️ How It Works

ixt auto-detects the backend from the package name:

Format Backend Example
name PyPI (Python) ruff, mypy, httpie
@scope/name npm (Node) @google/gemini-cli
owner/repo GitHub Releases BurntSushi/ripgrep

Each tool is installed in its own isolated environment ($IXT_HOME/installed/envs/<tool>/), and only the requested binaries are exposed in $IXT_HOME/installed/bin/.

For GitHub Releases, ixt learns each tool's asset-URL template on the first install and caches it in $IXT_CACHE_HOME/metadata/asset_patterns.json. Subsequent installs and upgrades resolve the latest tag via a plain 302 on github.com/.../releases/latest and download directly from the CDN — zero calls to api.github.com, no rate limit, no token required. If a maintainer ever renames their release assets, the cache entry is auto-invalidated and ixt falls back to the full release API to relearn.

Force a backend

Use namespace prefixes:

ixt tool install @pypi:ruff
ixt tool install @npm:prettier
ixt tool install @gh:BurntSushi/ripgrep

📚 Built-in Registry

ixt ships with a built-in registry that maps common tool names to their source. No need to remember the GitHub path:

ixt tool install ripgrep    # resolves to @gh:BurntSushi/ripgrep
ixt tool install fd         # resolves to @gh:sharkdp/fd
ixt tool install bat        # resolves to @gh:sharkdp/bat
ixt tool install lazygit    # resolves to @gh:jesseduffield/lazygit

The registry currently includes 50+ popular tools (ripgrep, fd, bat, fzf, jq, delta, starship, zellij, helix, nushell, etc.). For a simple name, ixt checks the registry first and falls back to PyPI when no registry entry matches.

You can add your own entries in $IXT_HOME/config/registry.toml:

[tools]
mytool = "@gh:owner/repo"

For team/project overlays, point IXT_REGISTRY at one or more local registry files separated by ;:

export IXT_REGISTRY="/org/registry.toml;/project/registry.toml"

📌 Version pinning

ixt tool install sharkdp/fd@10.2.0          # exact version
ixt tool install sharkdp/fd@10              # latest 10.x.x
ixt tool install ruff>=0.5.0                # PEP 508 (Python)

🔒 Declarative locks

ixt.toml is the human-edited intent: which tools you want, with optional version bounds, exposure rules, and injections. ixt.lock is generated from that intent and records the exact resolved versions and binary release assets.

For teams and CI, commit both files:

ixt lock write
ixt lock check
ixt tool apply --locked --strict

--locked replays the exact lock instead of resolving newer versions. --strict fails before changing the machine if ixt.toml and ixt.lock diverge. The strict preflight is local: it checks the manifest fingerprint, declared policy, version constraints, and locked binary metadata without contacting PyPI, npm, GitHub, or GitLab. Run ixt lock write when you want to resolve upstream again and refresh the lock.

🧰 Commands

Command Description
ixt tool add <pkg> Add a tool to ixt.toml without installing
ixt tool install <pkg> Install a tool in isolation
ixt tool install <pkg> --bare Install the env without exposing any binary
ixt tool uninstall <pkg> Remove a tool
ixt tool list List installed tools
ixt tool info <pkg> Show tool details
ixt tool upgrade <pkg> Upgrade a tool
ixt tool upgrade --all Upgrade all tools
ixt tool apply Sync tools from declarative config
ixt tool apply --locked --strict Sync using exact versions and assets from ixt.lock
ixt tool export Export installed tools as ixt.toml (stdout), preserves install intent
ixt lock write Resolve ixt.toml and write ixt.lock
ixt lock check Validate ixt.lock against ixt.toml locally
ixt lock diff Show semantic differences between ixt.toml and ixt.lock
ixt asset-index export Export portable binary-resolution metadata as JSON
ixt tool config <pkg> expose <rules...> Change exposed binaries
ixt tool config <pkg> inject <dep> Inject a package into the tool's env
ixt tool config <pkg> uninject <dep> Remove an injected package
ixt tool config __all__ expose <rules...> Re-expose every installed tool
ixt tool shell <pkg> Open a subshell in tool's env
ixt tool where <pkg> Print the tool env path
ixt exec [--sudo] <tool> -- <args...> Run an exposed tool by name, without relying on PATH
ixt environment [--sizes] Show ixt configuration, paths, and optional storage sizes
ixt doctor Check ixt health (runtimes, PATH, caches)
ixt cache info Show cache paths and sizes
ixt cache prune Keep current + previous indexed download artifacts per repository
ixt cache clear {downloads,metadata,tmp,all} Wipe cache(s); never touches installed tools
ixt runtime info Show ixt-managed runtime state
ixt runtime prune [--all] Remove unused or all ixt-managed runtimes
ixt setup path Add $IXT_HOME/installed/bin to PATH
ixt setup completions --shell zsh Print shell completion code for ixt

🏗️ Architecture

$IXT_HOME/                # default ~/.local/share/ixt (respects $XDG_DATA_HOME)
├── config/
│   ├── ixt.toml          # global declarative manifest fallback
│   ├── ixt.lock          # global lock when using the global ixt.toml
│   ├── registry.toml
│   └── heuristics.toml
└── installed/
    ├── bin/              # PATH-exposed shims
    ├── envs/             # isolated environments
    │   ├── ruff/         #   Python venv
    │   ├── gemini-cli/   #   Node node_modules
    │   └── ripgrep/      #   extracted binary
    └── runtimes/         # auto-bootstrapped: uv, bun

$IXT_CACHE_HOME/          # default ~/.cache/ixt (respects $XDG_CACHE_HOME)
├── downloads/            # downloaded archives and runtime payloads
├── metadata/             # resolve cache, asset templates, downloads index
└── tmp/                  # ixt-owned temporary files

Zero dependencies. ixt uses Python stdlib only — no PyPI packages. bun is auto-downloaded on first Node install. uv is typically already on your PATH (you used it to install ixt), with an auto-download fallback to $IXT_HOME/installed/runtimes/uv if missing.

📊 How ixt compares

uv tool pipx npm -g aqua mise proto ixt
Python tools (PyPI) ✅ (pipx)
npm packages ✅ (npm)
GitHub Releases binaries ✅ (ubi) ~
Day-one GitHub releases ~
Dependency isolation partial
Fine-grained exposure
No system runtime needed
Declarative config YAML TOML TOML TOML

ixt is not a runtime version manager (mise, proto, asdf cover that). It manages the last mile: install, isolate, expose and group CLI tools across three ecosystems.

🛠️ Development

git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
uv sync --group dev

uv run pytest                 # hermetic unit suite
uv run ruff check src/ tests/ # lint
uv run ruff format src/ tests/ # format

🤝 Contributing

Development happens on GitLab: https://gitlab.com/pytgaen-group/ixt. Any GitHub repository for this project is a read-only mirror of GitLab; it is not the review or issue tracker. Please open issues and merge requests on GitLab.

Bug reports and reproduction recipes are welcome. See CONTRIBUTING.md for details, or open an issue to start a discussion.

📄 License

MIT. See LICENSE.

Release files for ixt-cli 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ixt-cli 0.10.1
File Size Uploaded
ixt_cli-0.10.1.tar.gz 317.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ixt-cli 0.10.1
File Interpreter ABI Platform
ixt_cli-0.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 532.4 kB

Release files / ixt_cli-0.10.1.tar.gz

Download URL ixt_cli-0.10.1.tar.gz
Size 317.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c9d1175a75729faa64ff717effd84f9338ba4639accd46388bc25caff0b82d68
BLAKE2b-256 checksum
How to use checksums
74ecb10362e0d9f9b1e3e1e62332eec4912df8cf1cde4cb7d12654b16ec645be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / ixt_cli-0.10.1-py3-none-any.whl

Download URL ixt_cli-0.10.1-py3-none-any.whl
Size 215.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76a8f0601f09b8c01bc4fa5cec67100e1a1263040a2392d50e1478220dbb577a
BLAKE2b-256 checksum
How to use checksums
0c0519f8ad7b61e605f7f8d2d0f896c9025cc12489d4d17ccb12e688946d1c6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

0.10.1 This release

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page