Use this skill when the user asks to audit, dry-run, or upgrade local AI and developer CLIs in a repeatable way.
Do not use it when the user only asks how to install one known CLI and no version audit or batch workflow is needed.
Engine (v2.2.0): single-file pure Python standard library
scripts/upgrade_ai_clis.py. Ported line by line from the bash engine of the same name; the external contract (environment variables, table columns, status words, exit codes, log naming and rotation) was locked by repo-level contract tests on both engines before the switch was completed; a full real-machine dry-run line-by-line comparison found only oneintentional difference: newly added~/.opencode/binnative installation detection fallback (2026-08-08 real-machine run found a false "not installed" report when the old shell PATH was missing). Pure Python is also a hard prerequisite for the external skill marketplace file whitelist (which does not accept .sh).
Customer-readable description
What this skill can do
Audit and upgrade AI/developer CLIs (codex, claude, Antigravity/agy, Gemini's supported non-consumer lanes, kimi, qwen, opencode, cursor, deepcode, pi, etc.) with dry-run reports and logs.
Advanced maintenance tool: aimed at users who already have multiple AI CLIs installed; its positioning differs from the other single-tool installation skills in this repo that target beginners.
| What the customer wants | What the skill will do | What the customer can see |
|---|---|---|
| Complete the work covered by this skill | Read the user request, necessary context, and this skill's main workflow, and execute the minimal reliable steps | The customer will see the execution plan, command output summary, code/document changes, verification results, and risk notes. |
| Missing dependencies, permissions, configuration, or key | Stop actions that require external state, and clearly state what is missing | Installation command, application address, configuration path, or questions requiring customer confirmation |
| Execution complete | Summarize successes, skips, failures, file changes, and verification results | A completion receipt that can be copied into a ticket/log |
How the customer uses it
- Describe the goal in natural language and provide the necessary inputs: files, URLs, repos, workspaces, proposals, vaults, or platform account status.
- For actions that can be dry-run or previewed, give a preview first; for actions involving deletion, overwriting, sending, publishing, or writing remote state, ask for customer confirmation first.
Dependencies and installation
Installation (recommended: install the entire domain plugin, installing all skills in this repo at once):
claude plugin marketplace add soia-team/soia-open-skills
claude plugin install soia-env@soia
If you only want this one skill, you can use the npx route. Note that the skill will land in the shared source of truth ~/.agents/skills; if the plugin is also installed, the same skill will have two indexes and each will drift, so it is recommended to choose one of the two:
npx skills add soia-team/soia-open-env-skills -g -a '*' -s soia-env-ai-cli-upgrade -y
Note for domestic network environments: if npm channel installation or CLI upgrades time out or downloads fail, switch to the npmmirror domestic mirror source first and retry, then switch back to the official source as needed:
npm config set registry https://registry.npmmirror.com # 切国内镜像
npm config set registry https://registry.npmjs.org # 切回官方源
Configuration conventions:
~/.config/soia-skills/soia-env-ai-cli-upgrade/config.yml
SOIA_ENV_AI_CLI_UPGRADE_CONFIG_FILE=<custom-config-path>
- If this skill does not need private configuration, you can skip creating
config.yml。 - The configuration file uses
schema_version: 2; scripts prefer reading the new path, and only fall back to reading the old configuration location when the new path does not exist. - If an API key, cookie, session, provider home, or local path is needed, it can only go into a private
config.yml, the process environment, or the provider's own login state; it must not be written into the repo, vault body, or logs. - Log location and retention: upgrade logs are positioned asuse and discard—the report has no value once viewed, so by default it goes to the system temporary area
${TMPDIR:-/tmp}/soia-env-ai-cli-upgrade/logs/(on macOS $TMPDIR is automatically cleaned after about 3 days, /tmp is cleared on reboot), and multiple runs on the same day are handled byLOG_KEEP(default 10) rotations to prevent buildup. If audit traceability is genuinely needed (for example, to troubleshoot "which day's version upgrade caused a behavior change"), setLOG_DIRredirect to a persistent location (such as~/.local/state/...)。 - Third-party skills may only declare dependencies and installation methods; they must not directly modify third-party skill files.
WorkBuddy 's loading unit is role-based experts rather than plugins,npx skills add -a '*' cannot cover it; it requires separate installation, see docs/install/workbuddy.md。
Logging and completion receipts
Every execution must let the customer see the process and results. Minimum receipt format:
In the customer-visible results, the 更新时间 is recorded after final version verification is complete, using an RFC 3339 time with time zone.
完成:<一句话说明本次完成了什么>。
日志摘要:
- started: <检查到的输入/配置/依赖,不打印秘密值>
- processed: <数量或范围>
- created/updated: <数量或路径>
- skipped/failed: <数量和原因>
文件变化:
- <绝对路径或“未改动文件”>
验证:
- <运行过的检查、命令或人工核对点>
问题与下一步:
- <缺 key / 缺依赖 / 需要客户确认 / 建议下一条命令;没有则写“无”>
Tools Covered
| Tool | Command | Default upgrade method |
|---|---|---|
| Codex | codex |
codex update (auto-detects native/brew-cask/npm internally); installs via curl https://chatgpt.com/codex/install.sh, brew install --cask codex, or npm install -g @openai/codex; ⚑ npm path: NOTE column shows curl recommendation |
| Claude Code | claude |
auto-detected: native → claude update; Homebrew defaults to preserving the installed cask, while authorized CLAUDE_CHANNEL=latest safely migrates claude-code → claude-code@latest with prefetch and rollback; npm (legacy) → npm install -g @anthropic-ai/claude-code; Desktop-managed → skip (MANUAL) |
| Antigravity CLI (consumer Google accounts) | agy |
Official successor to Gemini CLI consumer Google login; native agy update; missing-command install is gated by AGY_INSTALL=1 |
| Gemini CLI (non-consumer lanes) | gemini |
auto-detected: brew formula (brew install gemini-cli) → brew upgrade <formula>; npm → npm install -g @google/gemini-cli; native → gemini update; explicit opt-in with TOOLS=gemini |
| Qwen Code | qwen |
auto-detected: brew formula (brew install qwen-code) → brew upgrade <formula>; npm → npm install -g @qwen-code/qwen-code; native (curl) → qwen update; ⚑ npm path: NOTE column shows curl recommendation |
| MiniMax CLI | mmx |
mmx update (wraps npm internally); npm-only: npm install -g mmx-cli |
| Kimi Code | kimi |
auto-detected: Homebrew formula, including relative bin symlinks, → brew upgrade <formula>; npm → npm install -g @moonshot-ai/kimi-code; native (curl) → kimi upgrade; Homebrew failures are reported instead of being treated as “already latest” |
| OpenCode | opencode |
auto-detected: brew formula (brew install opencode) → brew upgrade <formula>; npm → npm install -g opencode-ai; native (curl) → MANUAL (re-run curl -fsSL https://opencode.ai/install | bash); ⚑ npm path: NOTE column shows curl recommendation |
| Qoder CLI | qodercli |
qodercli update |
| DeepCode Agent CLI | deepcode |
npm → npm install -g deepcode(update package name when @vegamo/deepcode-cli is already installed) |
| Pi (pi-coding-agent) | pi |
pi update --self(npm package @earendil-works/pi-coding-agent) |
| Cursor | cursor |
version audit only unless CURSOR_UPGRADE_CMD is set |
Why both rows remain: agy is the replacement for Gemini CLI's consumer
Google-login path. gemini stays only so this skill can audit explicitly
supported Standard/Enterprise, API Key, and Vertex AI installations; it is no
longer part of the default batch.
Safety Model
- Start with
DRY_RUN=1unless the user explicitly asked to upgrade. - Preserve Claude's installed Homebrew cask by default. Set
CLAUDE_CHANNEL=latestonly after the user separately authorizes changing fromclaude-codetoclaude-code@latest; fetch the target before removing the stable cask and attempt restoration if installation fails. - Never edit shell profiles or PATH files automatically.
- Missing
agyis installed only whenAGY_INSTALL=1. The helper downloads Google's HTTPS installer to a temporary directory, syntax-checks it, and runs it with an isolated temporaryHOME;--dirplaces the native binary inAGY_INSTALL_DIRwithout letting vendor setup edit the user's real profiles. - Never write API keys, tokens, cookies, or login material to logs.
- Treat
CURSOR_UPGRADE_CMDas user-supplied code. Only run it when the user has explicitly provided or approved that command. - If an updater requires interactive login or privileged access, stop and report the blocker instead of guessing.
Configuration
The script uses environment variables. If persistent local configuration is
needed, keep it in the skill-specific private config.yml:
~/.config/soia-skills/soia-env-ai-cli-upgrade/config.yml
Example:
schema_version: 2
env:
LOG_DIR: "$HOME/.local/state/soia-env-ai-cli-upgrade/logs"
TOOLS: "codex,claude,agy"
NPM_PREFIX: "$HOME/.npm-global"
CLAUDE_CHANNEL: "preserve"
AGY_INSTALL: "0"
AGY_INSTALL_DIR: "$HOME/.local/bin"
Supported variables:
| Variable | Purpose | Default |
|---|---|---|
DRY_RUN=1 |
Print current versions without upgrading | 0 |
TOOLS="codex,claude,agy" |
Limit the tool list | consumer-safe default set; gemini is opt-in |
NPM_PACKAGES="codex,claude" |
Backward-compatible alias for TOOLS; ignored when TOOLS is set |
unset |
NPM_PREFIX=<path> |
npm global prefix for npm-based CLIs | $HOME/.npm-global |
| `CLAUDE_CHANNEL=preserve | latest` | Preserve the installed Claude Homebrew cask, or explicitly migrate the stable cask to claude-code@latest |
AGY_INSTALL=1 |
Allow a missing agy to be installed from Google's fixed official HTTPS endpoint |
0 |
AGY_INSTALL_DIR=<path> |
Native agy installation and fallback detection directory |
$HOME/.local/bin |
LOG_DIR=<path> |
Upgrade log directory | ${TMPDIR:-/tmp}/soia-env-ai-cli-upgrade/logs |
CURSOR_UPGRADE_CMD=<command> |
Optional Cursor updater command | unset |
Standard Workflow
From this repository:
# Version audit only
DRY_RUN=1 python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
# Upgrade all supported tools
python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
# Upgrade a consumer-safe subset
TOOLS="codex,claude,agy" \
python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
# After separate channel-switch authorization, migrate Homebrew Claude to @latest
CLAUDE_CHANNEL=latest TOOLS="claude" \
python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
# Upgrade Gemini CLI only after confirming a supported non-consumer lane
TOOLS="gemini" \
python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
# Explicitly install agy if it is missing; this does not perform login
AGY_INSTALL=1 TOOLS="agy" \
python3 skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
From an installed skill:
DRY_RUN=1 python3 ~/.agents/skills/soia-env-ai-cli-upgrade/scripts/upgrade_ai_clis.py
The script writes one timestamped log file and prints a table:
| Column | Meaning |
|---|---|
TOOL |
logical tool name |
COMMAND |
executable checked |
OLD |
version before upgrade or current version in dry-run |
NEW |
version after upgrade, or N/A in dry-run |
STATUS |
INSTALLED, UPDATED, ALREADY_LATEST, NOT_INSTALLED, SKIP_DRY_RUN, MANUAL, FAILED |
NOTE |
short reason or next action |
MANUAL for agy can mean installation or update succeeded but the resolved
binary directory is absent from PATH, or PATH resolves to a different binary.
The script reports the absolute resolved path and never edits PATH itself.
Example: a real dry-run audit
On 2026-08-08, on a real macOS (arm64) machine, running DRY_RUN=1 python3 scripts/upgrade_ai_clis.py
's actual output (the user's home directory has been anonymized as ~; data is preserved verbatim):
| TOOL | OLD | NEW | STATUS | NOTE |
|---|---|---|---|---|
| codex | 0.147.0 | N/A | SKIP_DRY_RUN | path=/opt/homebrew/bin/codex; no upgrade |
| claude | 2.1.224 | N/A | SKIP_DRY_RUN | path=/opt/homebrew/bin/claude; no upgrade; channel=claude-code@latest |
| agy | 1.1.11 | N/A | SKIP_DRY_RUN | path=~/.local/bin/agy; no upgrade |
| kimi | 0.34.0 | N/A | SKIP_DRY_RUN | path=/opt/homebrew/bin/kimi; no upgrade |
| mmx | 1.0.16 | N/A | SKIP_DRY_RUN | path=~/.npm-global/bin/mmx; no upgrade |
| qwen | 0.21.6 | N/A | SKIP_DRY_RUN | path=/opt/homebrew/bin/qwen; no upgrade |
| opencode | 1.18.15 | N/A | SKIP_DRY_RUN | path=~/.opencode/bin/opencode; no upgrade |
| qodercli | 1.1.17 | N/A | SKIP_DRY_RUN | path=~/.local/bin/qodercli; no upgrade |
| cursor | UNKNOWN | N/A | SKIP_DRY_RUN | path=~/.local/bin/cursor; no upgrade |
| deepcode | 0.1.34 | N/A | SKIP_DRY_RUN | path=~/.npm-global/bin/deepcode; no upgrade |
| pi | 0.84.1 | N/A | SKIP_DRY_RUN | path=~/.npm-global/bin/pi; no upgrade |
How to read: this machine has 11 AI CLIs installed; dry-run only audits and takes no action; theOLD column is the current version.
cursor is a desktop application; since the CLI has no version command, it displays UNKNOWN(this is expected, see capability boundaries).
opencode was detected via the ~/.opencode/bin native directory fallback probing newly added in v2.2.0—it will not be falsely reported as not installed even if it is not on the current
shell's PATH. When the installation channel is inconsistent with the official recommendation (such as npm-installed
codex), theNOTE column will include a directly copyable migration command; on this machine, all tools have already been migrated to the recommended channels, so there is no such prompt.
What it is not responsible for (capability boundaries)
- Does not install missing CLIs for the first time: tools that are not installed are only reported as
NOT_INSTALLED, not installed on the user's behalf (the only exception isagy, and explicitAGY_INSTALL=1authorization is required); for installation, use each tool's official channel or the corresponding installation skill - Does not modify shell profile, PATH, or login state: if re-login is required after an upgrade, report it truthfully and stop; does not complete any authentication process on the customer's behalf
- Does not upgrade desktop applications: Cursor is only version-audited, unless the customer provides
CURSOR_UPGRADE_CMD - Does not judge whether a new version is better: only performs version alignment and result verification; whether to roll back or lock a version is the customer's decision
- Does not touch secrets: API keys, tokens, and cookies are never read, recorded, or echoed
Private information and intermediate data
- The configuration stores only non-secret preferences and user-selected paths; API keys, tokens, cookies, sessions, and login credentials continue to be managed by each CLI's official login flow or the system credential store.
- By default, logs are located in the system temporary directory and rotate according to
LOG_KEEP; if the user explicitly chooses persistentLOG_DIR, only anonymized versions, statuses, and error summaries are recorded; accounts, credentials, authentication URLs, or private paths are not recorded. - A dry-run only performs read-only checks and does not create persistent state; a real upgrade's customer receipt must state the tool, old/new versions, result, and the time-zone-aware
更新时间。
Output Checklist
Before final response:
- Say whether the run was dry-run or live.
- Include the log file path.
- Summarize each tool status.
- Call out any
FAILED,MANUAL, or interactive-login blockers. - For Homebrew Claude, report the actual cask channel. Treat
ALREADY_LATESTas “latest in the preserved channel,” not proof that another authorized channel has no newer build. - Treat a non-zero script exit as at least one true
FAILEDrow; the script still processes the remaining selected tools before returning failure. - State that authentication was not checked unless an explicit PTY login flow
was completed by the user. Use
blocked_user_actionwhile waiting. - When model discovery was requested, report
model_source=runtime_account_scopedand the display names returned byagy models; do not invent stable model ids, aliases, a default, or plan eligibility from that output. - If live upgrades were run, report old and new versions where available.
Process-specific manuals
The following processes are mutually exclusive; a task will follow only one of them; simply read the corresponding file as needed.
- Gemini consumer migration and Antigravity authentication — antigravity-migration.md
- Antigravity diagnosis — antigravity-diagnosis.md