Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ This repo **is** a CLI tool manager, so the word "upgrade" is overloaded:
**AI CLI Preparation v2.0** — Tool version auditing and installation management for AI coding agents.

- **Modules:** 21 Python modules under `cli_audit/` (see [`cli_audit/AGENTS.md`](./cli_audit/AGENTS.md))
- **Catalog:** 98 JSON tool definitions under `catalog/`
- **Catalog:** 107 JSON tool definitions under `catalog/`
- **Installers:** 34 Bash scripts under `scripts/` (see [`scripts/AGENTS.md`](./scripts/AGENTS.md))
- **Phase 1:** Detection & auditing (complete)
- **Phase 2:** Installation & upgrade management (complete)
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
## [Unreleased]

### Added
- `pi` catalog entry: the pi coding agent, installed from npm as `@earendil-works/pi-coding-agent` (the earlier `@mariozechner/pi-coding-agent` package is deprecated); upstream version from GitHub `earendil-works/pi`.
- `jules` catalog entry: the Google Jules CLI (`@google/jules`), Google's asynchronous coding agent, with bash completion from `jules completion bash`.
- `herdr` catalog entry (`catalog/herdr.json`): terminal multiplexer for coding agents, installed as a raw linux binary from GitHub releases (x86_64, aarch64) with bash completion.
- `wslu`/`wslview` catalog entry (`catalog/wslu.json` + `scripts/install_wslu.sh`), gated by a new `requires_wsl` catalog flag so it is only surfaced and installed under WSL. Its installer also points the xdg default browser at `wslview` (so links open in the Windows browser); opt out with `WSLU_SET_DEFAULT_BROWSER=0`.
- Governance files: PR template, `CHANGELOG.md`. Security reporting is covered by the [org-level SECURITY.md](https://github.com/netresearch/.github/blob/main/SECURITY.md).
Expand All @@ -20,6 +22,7 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
- Binary-probe fallback in `guide.sh` when the post-install snapshot refresh is stale.

### Fixed
- `make uninstall-<tool>` removed an npm global package by the tool name. For `pi` (package `@earendil-works/pi-coding-agent`) that ran `npm uninstall -g pi`, which leaves the agent installed and names an unrelated npm package `pi`. The package name is now read from the binary's symlink into `node_modules`.
- The network-free refresh that `make upgrade` runs first (`audit.py --update-local`) skipped every multi-version row, so `python@3.14`, `node@26` and the other cycles kept the version they were last written with. After a successful upgrade the guide still offered the same upgrade until an install ran again. The refresh re-detects the cycle rows, the same way the post-install merge refresh already did.
- Audit detection skips virtualenv/conda bin dirs, like reconcile already did. An activated `~/.venv` made the audit report its own copy (`~/.venv/bin/black` 25.11.0) instead of the installation (`uv tool` black 26.5.1), so every upgrade of black, isort and python@3.14 looked like a no-op. Catalog `version_command`s run with the same filtered PATH. Reconcile no longer drops uv-tool and pipx installations, whose per-tool directories also carry a `pyvenv.cfg`. A tool that exists only inside a virtualenv or conda environment is now reported as not installed; the bulk missing-tool check and the post-install validation use the same lookup.
- `make upgrade` hid every pinned tool, whatever the pin. A release skipped with `s` ("ask again when newer patch available") hid the tool for good. A pin now hides a tool only while it is `never`, equals the target release (`s`), equals the installed version (`p`), or equals the cycle.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ make test-parallel # Parallel via pytest-xdist

## Installation scripts

All 97 cataloged tools can be installed, upgraded, uninstalled, or reconciled via generic Make targets:
All 107 cataloged tools can be installed, upgraded, uninstalled, or reconciled via generic Make targets:

```bash
# Generic pattern targets - work for ANY cataloged tool
Expand Down Expand Up @@ -539,7 +539,7 @@ When ambiguous, the audit may report a generic bucket (e.g., `~/.local/bin`). Th

### Actions: install, upgrade, uninstall, reconcile

All pattern targets (`install-%`, `upgrade-%`, `uninstall-%`, `reconcile-%`) work for any of the 97 cataloged tools. They use a three-step fallback: dedicated script, then generic installer, then error.
All pattern targets (`install-%`, `upgrade-%`, `uninstall-%`, `reconcile-%`) work for any of the 107 cataloged tools. They use a three-step fallback: dedicated script, then generic installer, then error.

```bash
# Upgrade any tool
Expand Down
103 changes: 32 additions & 71 deletions catalog/COVERAGE.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,42 @@
# Catalog Coverage

This file documents which tools have catalog entries and which use dedicated install scripts.

## Tools with Catalog Entries (57)

These tools use the catalog-based installation system with generic installers:

- ansible, ast-grep, aws, bandit, bat, black, codex, composer, curlie, dasel
- delta, direnv, dive, entr, fd, flake8, fx, fzf, gem, gemini, gh, git-absorb
- git-branchless, git-lfs, gitleaks, glab, golangci-lint, httpie, isort, just
- kubectl, ninja, npm, opengrep, parallel, pip, pipx, pnpm, poetry, pre-commit
- prettier, rga, ripgrep, ruff, sd, semgrep, shellcheck, shfmt, sponge, terraform
- tfsec, trivy, vault, watchexec, xsv, yarn, yq

## Tools with Dedicated Install Scripts

### Runtime Environments
These have their own complex installers in `scripts/`:
- **go** - `install_go.sh`
- **rust** - `install_rust.sh`
- **python** - `install_python.sh`
- **node** - `install_node.sh`

### Package Managers
Most now in catalog, one dedicated script:
- **uv** - `install_uv.sh` (special bootstrap installer)
- All others (pip, pipx, npm, pnpm, yarn, gem, composer, poetry, sponge) - Now in catalog!

### Docker Tools
- **docker** - `install_docker.sh` (uses official Docker install script)
- **docker-compose** - Typically installed with Docker

### System Tools
- **git** - System package (apt/dnf/brew)
- **ctags** - System package
- **sponge** - Part of moreutils package
- **prename** - System package (Perl rename)
- **rename.ul** - System package (util-linux rename)

### Other
- **gam** - Google Apps Manager (special installation)
- **claude** - Claude CLI (special installation)
- **ansible-core** - Subset of ansible package
- **eslint** - Node.js package (installed via npm)

## Installation Method Distribution

- **github_release_binary**: 32 tools
- **uv_tool**: 8 tools (Python CLI tools)
- **package_manager**: 10 tools (pip, pipx, poetry, npm, pnpm, yarn, gem, composer, sponge, entr)
- **hashicorp_zip**: 2 tools (terraform, vault)
- **aws_installer**: 1 tool (aws)
- **npm_global**: 1 tool (prettier)
- **script**: 1 tool (parallel)
- **dedicated_script**: 10 tools (runtimes: go, rust, python, node; special: uv, docker, git, ctags, gam)
- **system_package**: 2 tools (cscope, rename variants)

## Total: 72 tools tracked

- **57 tools** have catalog entries
- **10 tools** use dedicated scripts (runtimes + special cases)
- **5 tools** are system packages only

All installable tools either have catalog entries or use appropriate dedicated scripts.
This file documents which tools have catalog entries and how each one is installed.

## Catalog entries (107)

Counted from `catalog/*.json` on 2026-09-22. Every tool the audit tracks has a catalog entry; its `install_method` selects the installer (`scripts/installers/<method>.sh`). `dedicated_script` runs the script named in the entry's `script` field. `auto` goes through the reconciliation system (`reconcile_tool` in `scripts/lib/reconcile.sh`).

| install_method | Count | Tools |
|---|---|---|
| `github_release_binary` | 38 | ast-grep, curlie, dasel, direnv, dive, fx, fzf, gh, gh-aw, gh-aw-firewall, git-absorb, git-branchless, git-lfs, gitleaks, glab, golangci-lint, google-workspace-cli, gosec, herdr, jq, just, kubectl, mlr, ninja, opengrep, qsv, rga, sd, shellcheck, shfmt, symfony, tfsec, trivy, vhs, watchexec, xsv, yq, zellij |
| `dedicated_script` | 18 | blesh, byobu, claude, composer, docker, gem, go, node, parallel, pip, python, ruby, rust, tmux, tree, uv, wslu, yarn |
| `auto` | 13 | actionlint, bat, delta, difftastic, dust, fd, gup, hyperfine, jj, pnpm, ripgrep, scc, tokei |
| `uv_tool` | 12 | ansible-core, bandit, black, flake8, gam, git-filter-repo, httpie, isort, pre-commit, ruff, semgrep, trustmux |
| `package_manager` | 10 | bwrap, ctags, entr, git, php, pipx, poetry, prename, rename.ul, sponge |
| `npm_global` | 7 | bw, codex, eslint, gemini, jules, pi, prettier |
| `github_clone` | 2 | rbenv, ruby-build |
| `hashicorp_zip` | 2 | terraform, vault |
| `aws_installer` | 1 | aws |
| `docker_plugin` | 1 | compose |
| `gcloud_installer` | 1 | gcloud |
| `go_install` | 1 | templ |
| `npm_self_update` | 1 | npm |

## Bash completion coverage

Every catalog entry was audited for a bash-completion generator (sweep of
2026-07-22; each generator was executed and its output validated against
`complete -…` / `compgen ` / `COMPREPLY`, then checked to confirm it registers
the entry's own `binary_name`).
A sweep on 2026-07-22 (commit 9b6c053) audited the entries present in that
commit for a bash-completion generator: each generator was executed and its
output validated against `complete -…` / `compgen ` / `COMPREPLY`, then
checked to confirm it registers the entry's own `binary_name`. codex, pip and
pipx were not installed then; see the end of this section. herdr, jules, pi
and vault were checked when they were added. Five entries are not audited:
blesh, bw, bwrap, byobu, trustmux.

**40 entries declare `bash_completion`** — 39 `command`, 1 `source_path` (rbenv).
**42 entries declare `bash_completion`** — 41 `command`, 1 `source_path` (rbenv).

Declared (`command`): ast-grep, bat, black, codex, composer, dasel, delta, dive,
docker, fd, fx, gh, git-absorb, git-lfs, gitleaks, glab, golangci-lint, gup, jj,
just, kubectl, mlr, node, npm, parallel, pip, pipx, pnpm, poetry, ripgrep, ruff,
docker, fd, fx, gh, git-absorb, git-lfs, gitleaks, glab, golangci-lint, gup, herdr, jj,
jules, just, kubectl, mlr, node, npm, parallel, pip, pipx, pnpm, poetry, ripgrep, ruff,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
scc, symfony, trivy, uv, vhs, watchexec, yq, zellij

Declared (`source_path`): rbenv (`completions/rbenv.bash`, under its `clone_path`)
Expand All @@ -99,7 +60,7 @@ The completion file is named after `binary_name`, so a script that registers a
actionlint, ansible-core, aws, bandit, claude, ctags, curlie, difftastic,
direnv, dust, entr, eslint, flake8, gam, gem, gemini, gh-aw-firewall, git,
git-branchless, git-filter-repo, go, google-workspace-cli, gosec, httpie,
hyperfine, isort, jq, ninja, opengrep, php, pre-commit, prename, prettier,
hyperfine, isort, jq, ninja, opengrep, php, pi, pre-commit, prename, prettier,
python, qsv, rename.ul, ruby, ruby-build, sd, semgrep, shellcheck, shfmt,
sponge, templ, terraform, tfsec, tmux, tokei, tree, vault, wslu, xsv, yarn

Expand Down
4 changes: 2 additions & 2 deletions catalog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Install tools via system package managers (apt, brew, dnf, pacman).
2. The tool will automatically be available via `make install-<tool>`, `make upgrade-<tool>`, `make uninstall-<tool>`, and `make reconcile-<tool>`
3. No need to create a custom install script!

Currently **103 tools** are cataloged.
Currently **107 tools** are cataloged.

## Environment Variables

Expand All @@ -96,6 +96,6 @@ make upgrade

## Architecture

All 103 tools have catalog entries. The generic installer (`scripts/install_tool.sh`) reads a tool's catalog JSON and delegates to the appropriate method-specific installer under `scripts/installers/`. Tools with complex installation needs (python, node, docker, rust, etc.) use `install_method: "dedicated_script"` to route to their existing bespoke scripts.
All 107 tools have catalog entries. The generic installer (`scripts/install_tool.sh`) reads a tool's catalog JSON and delegates to the appropriate method-specific installer under `scripts/installers/`. Tools with complex installation needs (python, node, docker, rust, etc.) use `install_method: "dedicated_script"` to route to their existing bespoke scripts.

See [ADR-007](../docs/adr/ADR-007-generic-tool-installation-architecture.md) for the full architectural decision record.
22 changes: 22 additions & 0 deletions catalog/jules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "jules",
"category": "ai",
"install_method": "npm_global",
"description": "Google Jules CLI - terminal client for Jules, Google's asynchronous coding agent",
"homepage": "https://jules.google",
"package_name": "@google/jules",
"binary_name": "jules",
"requires": [
"node"
],
"version_command": "jules version 2>/dev/null | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1",
"guide": {
"display_name": "Google Jules CLI",
"install_action": "upgrade",
"order": 405
},
"notes": "Sessions run remotely (`jules remote`); `jules teleport` applies a session's changes locally. Sign in with `jules login`. Requires Node.js >= 18.",
"bash_completion": {
"command": "jules completion bash"
}
}
20 changes: 20 additions & 0 deletions catalog/pi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "pi",
"category": "ai",
"install_method": "npm_global",
"description": "pi - coding agent CLI with read, bash, edit and write tools and session management",
"homepage": "https://github.com/earendil-works/pi",
"github_repo": "earendil-works/pi",
"package_name": "@earendil-works/pi-coding-agent",
"binary_name": "pi",
"requires": [
"node"
],
"version_command": "pi --version 2>/dev/null | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1",
"guide": {
"display_name": "pi coding agent",
"install_action": "upgrade",
"order": 404
},
"notes": "Published as @earendil-works/pi-coding-agent; the earlier @mariozechner/pi-coding-agent package is deprecated. Requires Node.js >= 22.19."
}
4 changes: 2 additions & 2 deletions docs/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class ToolCatalog:
```python
from cli_audit import ToolCatalog

# Load catalog (97 tools)
# Load catalog (107 tools)
catalog = ToolCatalog()
entries = catalog.load_all()

Expand All @@ -137,7 +137,7 @@ if catalog.has("fzf"):
fzf = catalog.get("fzf")

# List all tools
all_tools = catalog.list_all() # Returns list of 97 tool names
all_tools = catalog.list_all() # Returns list of 107 tool names
```

#### `cli_audit.collectors` - Upstream Version Collection
Expand Down
2 changes: 1 addition & 1 deletion docs/CATALOG_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The catalog system allows tool definitions to be managed as JSON files instead o
- **Clear Separation**: Data (JSON) vs Logic (Python)

**Location**: `catalog/` directory at project root
**Current Size**: 97 JSON tool definitions
**Current Size**: 107 JSON tool definitions

## Quick Start

Expand Down
4 changes: 2 additions & 2 deletions docs/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

AI CLI Preparation is a specialized environment audit tool designed to ensure AI coding agents (like Claude Code) have access to all necessary developer tools. This documentation provides comprehensive technical details for developers, contributors, and integrators.

**Architecture:** Modular design with 21 specialized Python modules and 97 JSON tool catalog entries, evolved from a 3,387-line monolith to a maintainable, extensible system.
**Architecture:** Modular design with 21 specialized Python modules and 107 JSON tool catalog entries, evolved from a 3,387-line monolith to a maintainable, extensible system.

**Project Status:**
- **Phase 1 (Detection & Auditing):** ✅ Complete - Modular refactoring complete (v2.0.0)
Expand All @@ -34,7 +34,7 @@ AI CLI Preparation is a specialized environment audit tool designed to ensure AI

2. **[CATALOG_GUIDE.md](CATALOG_GUIDE.md)** - JSON Catalog System ⭐ **NEW**
- Tool definition schema and structure
- 97 JSON catalog entries
- 107 JSON catalog entries
- Creating and managing catalog entries
- ToolCatalog API and usage patterns
- Community contribution workflows
Expand Down
16 changes: 16 additions & 0 deletions docs/TOOL_ECOSYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,22 @@ make audit-offline-data-core
- **Install:** `npm install -g @google/gemini-cli`
- **Upgrade:** `npm update -g @google/gemini-cli`

### jules
- **Purpose:** Google Jules CLI - terminal client for Jules, Google's asynchronous coding agent
- **Executable:** `jules`
- **Upstream:** npm (@google/jules)
- **Use Case:** Assign coding sessions that run remotely and apply their changes locally (`jules teleport`)
- **Install:** `npm install -g @google/jules`
- **Upgrade:** `npm update -g @google/jules`

### pi
- **Purpose:** pi - coding agent CLI with read, bash, edit and write tools and session management
- **Executable:** `pi`
- **Upstream:** GitHub (earendil-works/pi), published on npm as @earendil-works/pi-coding-agent
- **Use Case:** Minimal terminal coding agent
- **Install:** `npm install -g @earendil-works/pi-coding-agent`
- **Upgrade:** `npm update -g @earendil-works/pi-coding-agent`

### claude
- **Purpose:** Anthropic Claude Code CLI
- **Executable:** `claude`
Expand Down
2 changes: 1 addition & 1 deletion scripts/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ make scripts-perms # Ensure all scripts are executable
./scripts/install_node.sh reconcile
```

**Via Make (works for all 98 cataloged tools):**
**Via Make (works for all 107 cataloged tools):**
```bash
make install-python # Install Python toolchain (dedicated script)
make upgrade-python # Upgrade Python toolchain
Expand Down
23 changes: 21 additions & 2 deletions scripts/lib/reconcile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,27 @@ remove_installation() {
;;
npm)
if command -v npm >/dev/null 2>&1; then
echo "[$tool] Uninstalling npm global package: $tool" >&2
npm uninstall -g "$tool" 2>/dev/null || true
# The package name can differ from the tool name (pi is
# @earendil-works/pi-coding-agent, and an unrelated package `pi`
# exists), so read it from the bin symlink: node_modules/<pkg>/...
# One level only: `npm link` and folder installs make the package
# directory a symlink too, and readlink -f would resolve past it.
local npm_pkg="$tool" npm_path npm_target npm_rest
npm_path="${known_path:-$(command -v "$binary" 2>/dev/null || echo "")}"
npm_target="$(readlink "$npm_path" 2>/dev/null || echo "")"
case "$npm_target" in
*/node_modules/*|node_modules/*)
# First node_modules = the global prefix; a later one would be
# a bundled dependency of the package
npm_rest="${npm_target#*node_modules/}"
case "$npm_rest" in
@*/*) npm_pkg="$(echo "$npm_rest" | cut -d/ -f1-2)" ;;
*) npm_pkg="${npm_rest%%/*}" ;;
esac
;;
esac
echo "[$tool] Uninstalling npm global package: $npm_pkg" >&2
npm uninstall -g "$npm_pkg" 2>/dev/null || true
fi
;;
nvm)
Expand Down
Loading
Loading