ixt-cli 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. ixt_cli-0.8.0/.gitignore +152 -0
  2. ixt_cli-0.8.0/PKG-INFO +294 -0
  3. ixt_cli-0.8.0/README.md +266 -0
  4. ixt_cli-0.8.0/pyproject.toml +131 -0
  5. ixt_cli-0.8.0/src/ixt/__init__.py +8 -0
  6. ixt_cli-0.8.0/src/ixt/__main__.py +8 -0
  7. ixt_cli-0.8.0/src/ixt/backends/__init__.py +1 -0
  8. ixt_cli-0.8.0/src/ixt/backends/binary.py +935 -0
  9. ixt_cli-0.8.0/src/ixt/backends/binary_resolver.py +307 -0
  10. ixt_cli-0.8.0/src/ixt/backends/node.py +490 -0
  11. ixt_cli-0.8.0/src/ixt/backends/python.py +234 -0
  12. ixt_cli-0.8.0/src/ixt/cli/__init__.py +31 -0
  13. ixt_cli-0.8.0/src/ixt/cli/argparse_completion.py +557 -0
  14. ixt_cli-0.8.0/src/ixt/cli/cmd_apply.py +404 -0
  15. ixt_cli-0.8.0/src/ixt/cli/cmd_cache.py +86 -0
  16. ixt_cli-0.8.0/src/ixt/cli/cmd_config.py +295 -0
  17. ixt_cli-0.8.0/src/ixt/cli/cmd_info.py +116 -0
  18. ixt_cli-0.8.0/src/ixt/cli/cmd_install.py +508 -0
  19. ixt_cli-0.8.0/src/ixt/cli/cmd_misc.py +261 -0
  20. ixt_cli-0.8.0/src/ixt/cli/cmd_registry.py +35 -0
  21. ixt_cli-0.8.0/src/ixt/cli/cmd_upgrade.py +336 -0
  22. ixt_cli-0.8.0/src/ixt/cli/commands.py +70 -0
  23. ixt_cli-0.8.0/src/ixt/cli/parser.py +555 -0
  24. ixt_cli-0.8.0/src/ixt/cli/render.py +85 -0
  25. ixt_cli-0.8.0/src/ixt/config/__init__.py +5 -0
  26. ixt_cli-0.8.0/src/ixt/config/asset_index.py +305 -0
  27. ixt_cli-0.8.0/src/ixt/config/asset_pattern_cache.py +87 -0
  28. ixt_cli-0.8.0/src/ixt/config/env_policy.py +340 -0
  29. ixt_cli-0.8.0/src/ixt/config/flags.py +29 -0
  30. ixt_cli-0.8.0/src/ixt/config/fs_policy.py +17 -0
  31. ixt_cli-0.8.0/src/ixt/config/heuristics.py +465 -0
  32. ixt_cli-0.8.0/src/ixt/config/models.py +176 -0
  33. ixt_cli-0.8.0/src/ixt/config/registry.py +145 -0
  34. ixt_cli-0.8.0/src/ixt/config/settings.py +173 -0
  35. ixt_cli-0.8.0/src/ixt/config/setup_toml.py +179 -0
  36. ixt_cli-0.8.0/src/ixt/config/toml.py +416 -0
  37. ixt_cli-0.8.0/src/ixt/core/__init__.py +16 -0
  38. ixt_cli-0.8.0/src/ixt/core/apply.py +564 -0
  39. ixt_cli-0.8.0/src/ixt/core/apply_actions.py +106 -0
  40. ixt_cli-0.8.0/src/ixt/core/backend.py +187 -0
  41. ixt_cli-0.8.0/src/ixt/core/bootstrap.py +410 -0
  42. ixt_cli-0.8.0/src/ixt/core/cache.py +332 -0
  43. ixt_cli-0.8.0/src/ixt/core/discover.py +150 -0
  44. ixt_cli-0.8.0/src/ixt/core/doctor.py +591 -0
  45. ixt_cli-0.8.0/src/ixt/core/export.py +419 -0
  46. ixt_cli-0.8.0/src/ixt/core/expose.py +350 -0
  47. ixt_cli-0.8.0/src/ixt/core/extract.py +261 -0
  48. ixt_cli-0.8.0/src/ixt/core/hooks.py +182 -0
  49. ixt_cli-0.8.0/src/ixt/core/identity.py +148 -0
  50. ixt_cli-0.8.0/src/ixt/core/inject.py +143 -0
  51. ixt_cli-0.8.0/src/ixt/core/install.py +509 -0
  52. ixt_cli-0.8.0/src/ixt/core/install_local.py +229 -0
  53. ixt_cli-0.8.0/src/ixt/core/locks.py +54 -0
  54. ixt_cli-0.8.0/src/ixt/core/pathlink.py +86 -0
  55. ixt_cli-0.8.0/src/ixt/core/resolution_stats.py +191 -0
  56. ixt_cli-0.8.0/src/ixt/core/resolve.py +150 -0
  57. ixt_cli-0.8.0/src/ixt/core/resolve_cache.py +185 -0
  58. ixt_cli-0.8.0/src/ixt/core/runtimes.py +192 -0
  59. ixt_cli-0.8.0/src/ixt/core/save.py +237 -0
  60. ixt_cli-0.8.0/src/ixt/core/setup_completions.py +11 -0
  61. ixt_cli-0.8.0/src/ixt/core/setup_path.py +368 -0
  62. ixt_cli-0.8.0/src/ixt/core/upgrade.py +596 -0
  63. ixt_cli-0.8.0/src/ixt/data/__init__.py +10 -0
  64. ixt_cli-0.8.0/src/ixt/data/asset_index.json +574 -0
  65. ixt_cli-0.8.0/src/ixt/data/heuristics.toml +98 -0
  66. ixt_cli-0.8.0/src/ixt/data/registry.toml +71 -0
  67. ixt_cli-0.8.0/src/ixt/libs/__init__.py +3 -0
  68. ixt_cli-0.8.0/src/ixt/libs/constants.py +4 -0
  69. ixt_cli-0.8.0/src/ixt/libs/fmt.py +108 -0
  70. ixt_cli-0.8.0/src/ixt/libs/logger.py +109 -0
  71. ixt_cli-0.8.0/src/ixt/libs/output.py +25 -0
  72. ixt_cli-0.8.0/src/ixt/libs/req_spec.py +115 -0
  73. ixt_cli-0.8.0/src/ixt/libs/semver.py +149 -0
  74. ixt_cli-0.8.0/src/ixt/libs/shell.py +126 -0
  75. ixt_cli-0.8.0/src/ixt/libs/style.py +238 -0
  76. ixt_cli-0.8.0/src/ixt/net/__init__.py +1 -0
  77. ixt_cli-0.8.0/src/ixt/net/github_api.py +158 -0
  78. ixt_cli-0.8.0/src/ixt/net/gitlab_api.py +149 -0
  79. ixt_cli-0.8.0/src/ixt/net/http.py +194 -0
  80. ixt_cli-0.8.0/src/ixt/net/npm.py +24 -0
  81. ixt_cli-0.8.0/src/ixt/net/pypi.py +26 -0
  82. ixt_cli-0.8.0/src/ixt/net/source.py +163 -0
  83. ixt_cli-0.8.0/src/ixt/platform/__init__.py +131 -0
  84. ixt_cli-0.8.0/src/ixt/platform/win.py +68 -0
  85. ixt_cli-0.8.0/tests/__init__.py +1 -0
  86. ixt_cli-0.8.0/tests/conftest.py +294 -0
  87. ixt_cli-0.8.0/tests/e2e/README.md +182 -0
  88. ixt_cli-0.8.0/tests/e2e/conftest.py +18 -0
  89. ixt_cli-0.8.0/tests/e2e/docker/Dockerfile.alpine +19 -0
  90. ixt_cli-0.8.0/tests/e2e/docker/Dockerfile.fedora +20 -0
  91. ixt_cli-0.8.0/tests/e2e/docker/Dockerfile.ubuntu +22 -0
  92. ixt_cli-0.8.0/tests/e2e/playground_incus.sh +228 -0
  93. ixt_cli-0.8.0/tests/e2e/run_e2e_docker.sh +87 -0
  94. ixt_cli-0.8.0/tests/e2e/run_e2e_incus.sh +151 -0
  95. ixt_cli-0.8.0/tests/e2e/runtime_matrix.sh +373 -0
  96. ixt_cli-0.8.0/tests/e2e/test_e2e.py +975 -0
  97. ixt_cli-0.8.0/tests/integration/__init__.py +1 -0
  98. ixt_cli-0.8.0/tests/integration/test_lifecycle.py +323 -0
  99. ixt_cli-0.8.0/tests/integration/test_policy_runtime.py +486 -0
  100. ixt_cli-0.8.0/tests/unit/__init__.py +1 -0
  101. ixt_cli-0.8.0/tests/unit/test_apply.py +886 -0
  102. ixt_cli-0.8.0/tests/unit/test_argparse_completion.py +154 -0
  103. ixt_cli-0.8.0/tests/unit/test_asset_index.py +127 -0
  104. ixt_cli-0.8.0/tests/unit/test_asset_pattern_cache.py +90 -0
  105. ixt_cli-0.8.0/tests/unit/test_backend.py +178 -0
  106. ixt_cli-0.8.0/tests/unit/test_binary_backend.py +1980 -0
  107. ixt_cli-0.8.0/tests/unit/test_bootstrap.py +274 -0
  108. ixt_cli-0.8.0/tests/unit/test_cache.py +140 -0
  109. ixt_cli-0.8.0/tests/unit/test_cli.py +2446 -0
  110. ixt_cli-0.8.0/tests/unit/test_discover.py +300 -0
  111. ixt_cli-0.8.0/tests/unit/test_doctor.py +461 -0
  112. ixt_cli-0.8.0/tests/unit/test_env_policy.py +223 -0
  113. ixt_cli-0.8.0/tests/unit/test_export.py +627 -0
  114. ixt_cli-0.8.0/tests/unit/test_expose.py +484 -0
  115. ixt_cli-0.8.0/tests/unit/test_extract.py +402 -0
  116. ixt_cli-0.8.0/tests/unit/test_flags.py +33 -0
  117. ixt_cli-0.8.0/tests/unit/test_fs_policy.py +140 -0
  118. ixt_cli-0.8.0/tests/unit/test_github_api.py +141 -0
  119. ixt_cli-0.8.0/tests/unit/test_gitlab_api.py +126 -0
  120. ixt_cli-0.8.0/tests/unit/test_heuristics.py +392 -0
  121. ixt_cli-0.8.0/tests/unit/test_hooks.py +326 -0
  122. ixt_cli-0.8.0/tests/unit/test_http.py +163 -0
  123. ixt_cli-0.8.0/tests/unit/test_inject.py +155 -0
  124. ixt_cli-0.8.0/tests/unit/test_install.py +313 -0
  125. ixt_cli-0.8.0/tests/unit/test_install_local.py +242 -0
  126. ixt_cli-0.8.0/tests/unit/test_models.py +204 -0
  127. ixt_cli-0.8.0/tests/unit/test_namespacing.py +282 -0
  128. ixt_cli-0.8.0/tests/unit/test_node_backend.py +790 -0
  129. ixt_cli-0.8.0/tests/unit/test_output.py +58 -0
  130. ixt_cli-0.8.0/tests/unit/test_pathlink.py +62 -0
  131. ixt_cli-0.8.0/tests/unit/test_platform.py +75 -0
  132. ixt_cli-0.8.0/tests/unit/test_python_backend.py +239 -0
  133. ixt_cli-0.8.0/tests/unit/test_registry.py +181 -0
  134. ixt_cli-0.8.0/tests/unit/test_req_spec.py +149 -0
  135. ixt_cli-0.8.0/tests/unit/test_resolve.py +266 -0
  136. ixt_cli-0.8.0/tests/unit/test_resolve_cache.py +158 -0
  137. ixt_cli-0.8.0/tests/unit/test_runtimes.py +125 -0
  138. ixt_cli-0.8.0/tests/unit/test_save.py +318 -0
  139. ixt_cli-0.8.0/tests/unit/test_semver.py +139 -0
  140. ixt_cli-0.8.0/tests/unit/test_settings.py +148 -0
  141. ixt_cli-0.8.0/tests/unit/test_setup_path.py +502 -0
  142. ixt_cli-0.8.0/tests/unit/test_setup_toml.py +197 -0
  143. ixt_cli-0.8.0/tests/unit/test_source.py +105 -0
  144. ixt_cli-0.8.0/tests/unit/test_style.py +245 -0
  145. ixt_cli-0.8.0/tests/unit/test_toml.py +367 -0
  146. ixt_cli-0.8.0/tests/unit/test_upgrade.py +790 -0
@@ -0,0 +1,152 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ target/
74
+
75
+ # Jupyter Notebook
76
+ .ipynb_checkpoints
77
+
78
+ # IPython
79
+ profile_default/
80
+ ipython_config.py
81
+
82
+ # pyenv
83
+ .python-version
84
+
85
+ # pipenv
86
+ Pipfile.lock
87
+
88
+ # PEP 582
89
+ __pypackages__/
90
+
91
+ # Celery stuff
92
+ celerybeat-schedule
93
+ celerybeat.pid
94
+
95
+ # SageMath parsed files
96
+ *.sage.py
97
+
98
+ # Environments
99
+ .env
100
+ .venv
101
+ env/
102
+ venv/
103
+ ENV/
104
+ env.bak/
105
+ venv.bak/
106
+
107
+ # Spyder project settings
108
+ .spyderproject
109
+ .spyproject
110
+
111
+ # Rope project settings
112
+ .ropeproject
113
+
114
+ # mkdocs documentation
115
+ /site
116
+
117
+ # mypy
118
+ .mypy_cache/
119
+ .dmypy.json
120
+ dmypy.json
121
+
122
+ # Pyre type checker
123
+ .pyre/
124
+
125
+ # IDE
126
+ .vscode/
127
+ .idea/
128
+ *.swp
129
+ *.swo
130
+ *~
131
+
132
+ # OS
133
+ .DS_Store
134
+ Thumbs.db
135
+ *:Zone.Identifier
136
+
137
+ # astx cache
138
+ .astx/
139
+
140
+ # skylos cache
141
+ .skylos/
142
+
143
+ # Local development
144
+ .agents/
145
+ .claude
146
+
147
+ .env.local
148
+ ixt.egg-info
149
+ .hatch/
150
+
151
+ .memsearch/
152
+ .pyscn/
ixt_cli-0.8.0/PKG-INFO ADDED
@@ -0,0 +1,294 @@
1
+ Metadata-Version: 2.4
2
+ Name: ixt-cli
3
+ Version: 0.8.0
4
+ Summary: Universal CLI tool isolator - manage Python, Node, and binary tools with per-tool isolation
5
+ Project-URL: Homepage, https://gitlab.com/pytgaen-group/ixt
6
+ Project-URL: Repository, https://gitlab.com/pytgaen-group/ixt.git
7
+ Project-URL: Issues, https://gitlab.com/pytgaen-group/ixt/-/issues
8
+ Project-URL: Documentation, https://gitlab.com/pytgaen-group/ixt#readme
9
+ Author-email: Gaëtan Montury <10528250-pytgaen@users.noreply.gitlab.com>
10
+ License: MIT
11
+ Keywords: cli,github,isolation,npm,package-manager,pypi,tool
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Topic :: Software Development
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+
29
+ <p align="center">
30
+ <img src="assets/ixt.jpg" alt="ixt" width="600">
31
+ </p>
32
+
33
+ <h1 align="center">ixt — Universal CLI Tool Isolator</h1>
34
+
35
+ <p align="center">
36
+ <a href="https://gitlab.com/pytgaen-group/ixt/-/releases"><img src="https://img.shields.io/gitlab/v/release/pytgaen-group/ixt?label=release" alt="Release"></a>
37
+ <a href="https://gitlab.com/pytgaen-group/ixt/-/pipelines"><img src="https://img.shields.io/gitlab/pipeline-status/pytgaen-group/ixt?branch=main" alt="Pipeline"></a>
38
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
39
+ <img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+">
40
+ </p>
41
+
42
+ <p align="center">
43
+ <img src="assets/wip.jpg" alt="Work in Progress" width="300">
44
+ </p>
45
+
46
+ **One CLI for Python, Node, and binary tools — each in its own isolated env.**
47
+ **Optional Linux runtime policy can restrict env vars and filesystem access per tool.**
48
+
49
+ *Zero third-party deps. Zero system pollution. One command, any ecosystem.*
50
+
51
+ ```bash
52
+ ixt tool install ruff # Python (PyPI)
53
+ ixt tool install @anthropic-ai/claude-code # Node (npm)
54
+ ixt tool install ripgrep # Binary (GitHub — via built-in registry)
55
+ ```
56
+
57
+ Each tool gets its own isolated environment. Only the binaries you choose are exposed to your PATH.
58
+
59
+ ## 📥 Install
60
+
61
+ From PyPI. The published package is `ixt-cli`; it installs the `ixt` command.
62
+
63
+ ```bash
64
+ # One-shot via uvx (requires uv)
65
+ uvx --from ixt-cli==0.7.0 ixt --help
66
+
67
+ # Persistent install via uv tool
68
+ uv tool install ixt-cli==0.7.0
69
+ ```
70
+
71
+ Or from source:
72
+
73
+ ```bash
74
+ git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
75
+ uv tool install -e .
76
+ ```
77
+
78
+ Then add `$IXT_HOME/installed/bin` to your PATH:
79
+
80
+ ```bash
81
+ ixt setup path
82
+ ```
83
+
84
+ ### Integrity verification
85
+
86
+ Release tags are SSH-signed. Installing from PyPI pins the published package
87
+ version but does not verify the Git tag signature locally. Use the clone flow
88
+ when you want to verify the signed release before installing:
89
+
90
+ ```bash
91
+ # Verify the signed tag (requires the maintainer's SSH public key in git's allowed_signers)
92
+ git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
93
+ git fetch --tags
94
+ git verify-tag v0.7.0
95
+ git checkout --detach v0.7.0
96
+ uv tool install .
97
+ ```
98
+
99
+ A valid tag signature means the checked-out source matches the maintainer-signed release tag.
100
+
101
+ ## 🚀 Quick Start
102
+
103
+ ```bash
104
+ # Install tools from 3 ecosystems
105
+ ixt tool install ruff # Python linter
106
+ ixt tool install @google/gemini-cli # Node CLI
107
+ ixt tool install sharkdp/fd # GitHub binary
108
+
109
+ # List installed tools
110
+ ixt tool list
111
+ # ruff 0.5.0 pypi [ruff]
112
+ # gemini-cli 0.1.12 npm [gemini]
113
+ # fd 10.2.0 github [fd]
114
+
115
+ # Upgrade
116
+ ixt tool upgrade ruff
117
+ ixt tool upgrade --all
118
+
119
+ # Uninstall
120
+ ixt tool uninstall fd
121
+ ```
122
+
123
+ ## ⚙️ How It Works
124
+
125
+ ixt auto-detects the backend from the package name:
126
+
127
+ | Format | Backend | Example |
128
+ | ------------- | --------------- | ------------------------ |
129
+ | `name` | PyPI (Python) | `ruff`, `mypy`, `httpie` |
130
+ | `@scope/name` | npm (Node) | `@google/gemini-cli` |
131
+ | `owner/repo` | GitHub Releases | `BurntSushi/ripgrep` |
132
+
133
+ 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/`.
134
+
135
+ 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.
136
+
137
+ ### Force a backend
138
+
139
+ Use namespace prefixes:
140
+
141
+ ```bash
142
+ ixt tool install @pypi:ruff
143
+ ixt tool install @npm:prettier
144
+ ixt tool install @gh:BurntSushi/ripgrep
145
+ ```
146
+
147
+ ## 🛡️ Runtime policy
148
+
149
+ Dependency isolation is the baseline — but ixt also lets you control **what each tool can see at runtime**: which environment variables it receives, which filesystem paths it can read or write. This is a runtime policy for commands launched through ixt shims, not a sandbox for install-time package-manager scripts. If the install step itself is untrusted, use a disposable VM/container/user.
150
+
151
+ ```bash
152
+ # Avoid passing secrets in the runtime environment
153
+ ixt tool config some-cli env base os-common
154
+ ixt tool config some-cli env allow '*RUFF*'
155
+
156
+ # Restrict filesystem at runtime: read-only host, hide ~/.aws and ~/.ssh
157
+ ixt tool config some-cli fs base app-common
158
+ ixt tool config some-cli fs scratch ~/.aws ~/.ssh
159
+ ```
160
+
161
+ When a policy is active, the PATH shim becomes a small Python wrapper that — when [bubblewrap](https://github.com/containers/bubblewrap) is installed — runs the tool with PID isolation and a private `/proc`. The filtered env reaches the tool, and `/proc/$PPID/environ` reads from inside cannot recover the host secrets. Filesystem policy also requires bwrap. Without bwrap, env policy still cleans the env reaching the tool but `/proc` reads remain exfiltrable — the shim warns once per session in this **degraded "hygiene-only" mode**. Reset the policy and you're back to a direct symlink with zero overhead.
162
+
163
+ The policy is replayable: declare `env_base`, `env_allow`, `fs_scratch`, etc. inside `ixt.toml` and `ixt tool apply` reproduces it on any machine. Use `IXT_SHIM_DEBUG=1` to dump the effective env, `IXT_POLICY_QUIET=1` to silence the degraded-mode warning, `IXT_DISABLE_BWRAP=1` to force degraded mode for debugging.
164
+
165
+ > ⚠️ **Linux only for now.** Enforcement relies on POSIX `execve` and Linux namespaces. On macOS/Windows the policy is saved to `ixt.json` but **not enforced at runtime** — the tool runs with the full environment.
166
+ > Install [bubblewrap](https://github.com/containers/bubblewrap) for **effective env/fs enforcement**: `sudo apt install bubblewrap` / `sudo dnf install bubblewrap` / `sudo pacman -S bubblewrap` / `sudo apk add bubblewrap`. The env axis runs without it but only as a hygiene measure (cleans logs/traces); the fs axis requires it and errors out otherwise. Network isolation is not implemented yet.
167
+ > This is not a general malware sandbox.
168
+
169
+ [Full policy reference →](https://gitlab.com/pytgaen-group/ixt/-/blob/main/docs/policy/index.md)
170
+
171
+ ## 📚 Built-in Registry
172
+
173
+ ixt ships with a built-in registry that maps common tool names to their source. No need to remember the GitHub path:
174
+
175
+ ```bash
176
+ ixt tool install ripgrep # resolves to @gh:BurntSushi/ripgrep
177
+ ixt tool install fd # resolves to @gh:sharkdp/fd
178
+ ixt tool install bat # resolves to @gh:sharkdp/bat
179
+ ixt tool install lazygit # resolves to @gh:jesseduffield/lazygit
180
+ ```
181
+
182
+ 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.
183
+
184
+ You can add your own entries in `$IXT_HOME/config/registry.toml`:
185
+
186
+ ```toml
187
+ [tools]
188
+ mytool = "@gh:owner/repo"
189
+ ```
190
+
191
+ For team/project overlays, point `IXT_REGISTRY` at one or more local registry files separated by `;`:
192
+
193
+ ```bash
194
+ export IXT_REGISTRY="/org/registry.toml;/project/registry.toml"
195
+ ```
196
+
197
+ ## 📌 Version pinning
198
+
199
+ ```bash
200
+ ixt tool install sharkdp/fd@10.2.0 # exact version
201
+ ixt tool install sharkdp/fd@10 # latest 10.x.x
202
+ ixt tool install ruff>=0.5.0 # PEP 508 (Python)
203
+ ```
204
+
205
+ ## 🧰 Commands
206
+
207
+ | Command | Description |
208
+ | ---------------------------------------------- | --------------------------------------------------------------------- |
209
+ | `ixt tool add <pkg>` | Add a tool to ixt.toml without installing |
210
+ | `ixt tool install <pkg>` | Install a tool in isolation |
211
+ | `ixt tool install <pkg> --bare` | Install the env without exposing any binary |
212
+ | `ixt tool uninstall <pkg>` | Remove a tool |
213
+ | `ixt tool list` | List installed tools |
214
+ | `ixt tool info <pkg>` | Show tool details |
215
+ | `ixt tool upgrade <pkg>` | Upgrade a tool |
216
+ | `ixt tool upgrade --all` | Upgrade all tools |
217
+ | `ixt tool apply` | Sync tools from declarative config |
218
+ | `ixt tool export` | Export installed tools as ixt.toml (stdout), preserves install intent |
219
+ | `ixt asset-index export` | Export portable binary-resolution metadata as JSON |
220
+ | `ixt tool config <pkg> expose <rules...>` | Change exposed binaries |
221
+ | `ixt tool config <pkg> inject <dep>` | Inject a package into the tool's env |
222
+ | `ixt tool config <pkg> uninject <dep>` | Remove an injected package |
223
+ | `ixt tool config __all__ expose <rules...>` | Re-expose every installed tool |
224
+ | `ixt tool shell <pkg>` | Open a subshell in tool's env |
225
+ | `ixt tool where <pkg>` | Print the tool env path |
226
+ | `ixt environment [--sizes]` | Show ixt configuration, paths, and optional storage sizes |
227
+ | `ixt doctor` | Check ixt health (runtimes, PATH, caches) |
228
+ | `ixt cache info` | Show cache paths and sizes |
229
+ | `ixt cache prune` | Keep current + previous indexed download artifacts per repository |
230
+ | `ixt cache clear {downloads,metadata,tmp,all}` | Wipe cache(s); never touches installed tools |
231
+ | `ixt runtime info` | Show ixt-managed runtime state |
232
+ | `ixt runtime prune [--all]` | Remove unused or all ixt-managed runtimes |
233
+ | `ixt setup path` | Add `$IXT_HOME/installed/bin` to PATH |
234
+ | `ixt setup completions --shell zsh` | Print shell completion code for ixt |
235
+
236
+ ## 🏗️ Architecture
237
+
238
+ ```
239
+ $IXT_HOME/ # default ~/.local/share/ixt (respects $XDG_DATA_HOME)
240
+ ├── config/
241
+ │ ├── ixt.toml
242
+ │ ├── registry.toml
243
+ │ └── heuristics.toml
244
+ └── installed/
245
+ ├── bin/ # PATH-exposed shims
246
+ ├── envs/ # isolated environments
247
+ │ ├── ruff/ # Python venv
248
+ │ ├── gemini-cli/ # Node node_modules
249
+ │ └── ripgrep/ # extracted binary
250
+ └── runtimes/ # auto-bootstrapped: uv, bun
251
+
252
+ $IXT_CACHE_HOME/ # default ~/.cache/ixt (respects $XDG_CACHE_HOME)
253
+ ├── downloads/ # downloaded archives and runtime payloads
254
+ ├── metadata/ # resolve cache, asset templates, downloads index
255
+ └── tmp/ # ixt-owned temporary files
256
+ ```
257
+
258
+ **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.
259
+
260
+ ## 📊 How ixt compares
261
+
262
+ | | uv tool | pipx | npm -g | aqua | mise | proto | **ixt** |
263
+ | ------------------------ | ------- | ---- | ------ | ---- | --------- | ----- | ------- |
264
+ | Python tools (PyPI) | ✅ | ✅ | — | — | ✅ (pipx) | — | ✅ |
265
+ | Node tools (npm) | — | — | ✅ | — | ✅ (npm) | — | ✅ |
266
+ | GitHub Releases binaries | — | — | — | ✅ | ✅ (ubi) | ~ | ✅ |
267
+ | Dependency isolation | ✅ | ✅ | ❌ | — | partial | — | ✅ |
268
+ | Fine-grained exposure | — | — | — | — | — | — | ✅ |
269
+ | Runtime policy (env+fs) | — | — | — | — | — | — | ✅ |
270
+ | Bootstrap from scratch | — | — | — | — | curl | curl | ✅ |
271
+ | Declarative config | — | — | — | YAML | TOML | TOML | TOML |
272
+
273
+ 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.
274
+
275
+ ## 🛠️ Development
276
+
277
+ ```bash
278
+ git clone https://gitlab.com/pytgaen-group/ixt.git && cd ixt
279
+ uv sync --group dev
280
+
281
+ uv run pytest # test suite
282
+ uv run ruff check src/ tests/ # lint
283
+ uv run ruff format src/ tests/ # format
284
+ ```
285
+
286
+ ## 🤝 Contributing
287
+
288
+ Development happens on **GitLab**: <https://gitlab.com/pytgaen-group/ixt>. The GitHub repository (if present) is a **read-only mirror** — please open issues and merge requests on GitLab.
289
+
290
+ Bug reports and reproduction recipes are welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details, or open an issue to start a discussion.
291
+
292
+ ## 📄 License
293
+
294
+ MIT