工具管理器 (tool managers) — 誰安裝什麼¶
Micro 隨 devtools 安裝:macOS 用 brew,Linux 用 apt/驗證 checksum 的 user-level release(no-root、RedHat)。Release 以 just upgrade-micro 升級。見 編輯器選擇。
Terminology rule (zh-TW pages)
技術名詞首次出現以「中文 (English original)」格式呈現,例:依賴注入
(dependency injection)。不自創翻譯——若無公認譯名直接保留英文
(如 embedding、tokenizer)。代碼、API 名、CLI flag、套件名、檔名一律不翻。
本 repo 安裝的每個工具的對照表,依照「擁有它的 manager」分類。是
upgrades.md 的姊妹文件——那份講升級面,這份講安裝面。
當你想知道:
| 問題 | 章節 |
|---|---|
| 「工具 X 從哪裡來?」 | § 工具索引 (A–Z) |
| 「Manager Y 安裝了哪些工具?」 | § 各 manager 目錄 |
| 「我要新增一個工具——該用哪個 manager?」 | § 新增工具決策樹 |
| 「為什麼 X 由 Z 而不是 W 管理?」 | § 多機制工具 + 原因說明 |
| 「X 怎麼升級?」 | upgrades.md |
慣例提醒:刻意採用 install-only 設計(見
upgrades.md§ 為什麼安裝與升級要分開)。 這裡的每個安裝路徑都使用state: present/creates:/[[ -d … ]]守衛 (guard);chezmoi apply不會默默升級任何工具的版本。唯一會刻意 推進工具版本的是scripts/upgrade_tools.sh(透過just upgrade-*)。
TL;DR — manager 全景¶
| Manager | 擁有什麼 | 列在哪 | 升級類別 |
|---|---|---|---|
Bootstrap (run_once_before_*.sh.tmpl) |
Homebrew 本身、uv、mise、ansible-core、apt 前置條件 | run_once_before_00_bootstrap.sh.tmpl |
n/a (一次性、冪等) |
| Homebrew formulae | macOS 共用 CLI (mas) + role 驅動的(在 base, devtools, coding_agents 等之中) |
dot_config/homebrew/Brewfile.tmpl + 散布在各處的 community.general.homebrew: task |
brew |
| Homebrew casks | macOS GUI 應用程式(~25 個;AI 類由 installAiDesktopApps 控管) |
Brewfile.darwin.tmpl |
brew (--cask --greedy) |
| Ansible roles | 主要部分——26 個 role,涵蓋 shells、devtools、agents、語言工具鏈、網路、安全 | dot_ansible/roles/*/tasks/main.yml |
間接(每個 role 呼叫 brew / apt / mise / uv / npm / cargo / gem / dotnet / curl-installer / github-release 之一) |
| mise | Runtime 版本:node、bun、rust、go、dotnet、ruby(oldEL:只有 ruby) |
dot_config/mise/config.toml.tmpl |
mise |
| uv | Python CLI 工具(python_uv_tools ~13 個 + llm_tools 1 個 + litellm) |
dot_ansible/roles/python_uv_tools/defaults/main.yml、dot_ansible/roles/llm_tools/defaults/main.yml、coding_agents 中的 ad-hoc uv tool install(specify-cli)+ security_tools(pre-commit) |
uv (uv tool upgrade --all) |
| npm (全域) | JS CLI(Pi、copilot-cli、codex、gemini-cli、openchamber、bitwarden、readability-cli)+ tldr + tree-sitter-cli |
js_cli_tools/defaults/main.yml、散布的 community.general.npm: + mise exec -- npm install -g |
npm (npm -g update) / Pi 另由 agents 處理穩定 prefix |
| cargo | Rust crates:recon、pueue(Linux)、tree-sitter-cli(fallback)、alacritty(Linux 編譯)、modelsdev(Linux fallback) |
rust_cargo_tools/defaults/main.yml(目前為 [])+ 在 task 中硬寫 |
cargo (cargo install-update -a) |
go (go install) |
Linux gopls;個人工具來源另由 personal role 管理 | go_tools/defaults/main.yml |
go |
| dotnet (全域工具) | azure-cost-cli(binary azure-cost) |
dotnet_tools/defaults/main.yml |
dotnet |
| gem | try-cli(binary try)、tmuxinator |
ruby_gem_tools/defaults/main.yml |
gem |
curl-installer (廠商 install.sh) |
自管 coding agents + 少數系統工具:claude、opencode、omp、cursor-agent、agy、rtk、ollama、atuin、docker、zoxide、direnv、just、llmfit、starship | dot_ansible/roles/coding_agents/、llm_tools/、devtools/、starship/、atuin/、docker/、bootstrap |
agents(其中具自我更新 (self-update) 子命令的子集) |
| GitHub-release 下載 | ~30 個 Linux 使用者層級 fallback:ripgrep/fd/jq/git-lfs/gh/glab/bat/eza/git-delta/diffnav/glow/gum/vhs/freeze/yazi/superfile/btop/zellij/sesh/worktrunk/workmux/tailspin/dasel/yq/jnv/doggo/gping/trippy/bandwhich/rustscan/cloudflared/ngrok/speedtest/gitleaks/lazygit/neovim + macOS specstory、lazygit 與 neovim 的 fallback | 每個 role 的 _release_fallback 區塊 |
無(明確的最低版本修復除外;見 覆蓋落差) |
| chezmoi externals | 每週刷新的 git checkout:oh-my-zsh + 插件、oh-my-bash、ble.sh、TPM、fzf(Linux)、pi-agents、toolkami.rb | .chezmoiexternal.toml.tmpl |
externals (chezmoi apply --refresh-externals) |
| apt / yum | 發行版套件(編譯依賴、ffmpeg、audit、fontconfig、libnotify-bin、系統 git/zsh/bash 等) | role 中散布的 ansible.builtin.apt: / ansible.builtin.yum: |
無(依賴 repo 流程外的 apt upgrade) |
| flatpak | Discord(Linux 上的預設頻道) | gui_apps_linux/tasks/main.yml |
flatpak (flatpak update -y) |
| personal tools | 十三件 CLI:macOS Homebrew/Linux verified release binaries | personal_tools/files/tools.json |
personal |
安裝順序¶
依照時間順序的五個階段。任何後一階段都必須等前一階段存在後才能執行。
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 0 — Bootstrap (run_once_before_*) │
│ curl-installer: Homebrew, uv, mise │
│ apt: build-essential, git, curl (Linux 用 Linuxbrew 的前置條件) │
│ apt: libffi-dev, libyaml-dev, python3-dev (僅 Linux 非 noRoot) │
│ uv: ansible-core (固定 Python 3.13) │
│ ansible-galaxy: community.general collection │
│ mise: 從 ~/.config/mise/config.toml 安裝 runtimes │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 1 — chezmoi apply (部署設定檔) │
│ 部署 dot_* 檔案;不直接安裝工具 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 2 — Ansible (run_onchange_after_20_ansible_roles) │
│ 執行全部 26 個 role;每個分派到其底層 manager │
│ (brew / apt / mise / uv / npm / cargo / gem / dotnet / curl / gh-rel) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 3 — Brew bundle (run_onchange_after_30_brew_bundle) │
│ 針對 ~/.config/homebrew/Brewfile* 執行 `brew bundle --no-upgrade` │
│ 主要是 GUI casks (macOS);installBrewApps=false 時略過 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 4 — 各應用 onchange 腳本 │
│ completion 重新生成 (run_after_50_generate_completions) │
│ bat theme cache (run_onchange_after_25_bat_theme) │
│ ble.sh 編譯 (run_onchange_after_26_install_blesh) │
│ 全域 skills 還原 (run_onchange_after_40_install_global_skills) │
└─────────────────────────────────────────────────────────────────────────┘
Bootstrap 是其他一切所依賴的基礎工具的唯一真實來源 (SSOT)。如果你
發現自己想在別處加入 mise / uv / Homebrew,答案幾乎一定是「擴充
bootstrap,然後在 role 中假設它存在」。Linux noRoot 路徑
(profile=ubuntu_server 或沒有 sudo 的 RHEL/CentOS) 跳過 apt 前置條件
與 Linuxbrew,改走「每個工具自己的 curl-installer + GitHub releases」
fallback——覆蓋面刻意縮窄(無 GUI、無系統範疇 (system-wide) 安裝)。
各 manager 目錄¶
下面每個小節涵蓋一個 manager。格式:
- 擁有什麼 (Owns) — 哪些工具落入這個 manager 的掌控
- 如何把工具加進去 (How a tool gets there) — 「我要透過這個 manager 加 X」的標準寫法
- OS 差異 (Per-OS notes) — 必要時的分歧
- 升級路徑 (Upgrade path) — 對應
upgrades.md類別的連結
Ansible roles 小節再依主題切分,因為 26 個 role 擠在同一個表格裡沒法讀。
1. Bootstrap 腳本 (pre-chezmoi)¶
檔案:run_once_before_00_bootstrap.sh.tmpl、
run_once_before_02_fix_intel_homebrew.sh.tmpl、
run_once_before_50_opencode_migrate.sh.tmpl
擁有什麼 — 其他一切都假設存在的四個基礎 manager:
| 工具 | 機制 | OS 差異 |
|---|---|---|
| Homebrew | Homebrew/install curl 腳本 |
macOS 永遠安裝;Linux 只在 installBrewApps=true 且非 noRoot 且 arch∈{amd64,arm64} 時安裝。useChineseMirror=true 時透過 HOMEBREW_BREW_GIT_REMOTE + bottle/API domain 走鏡像(BFSU 基準;brew-mirror 可切到 USTC/Aliyun/TUNA)。Aliyun 的 brew.git 壞掉(會卡住),HOMEBREW_CORE_GIT_REMOTE 保持 unset(API 模式)—— 見 mirrors.md |
| uv | curl -LsSf https://astral.sh/uv/install.sh \| sh |
全 OS,缺失時 |
| mise | curl https://mise.run \| sh,加上直接從 mise.jdx.dev/mise-latest-linux-${arch}[-musl] 下載的 fallback(glibc < 2.28 時強制 musl) |
全 OS;arch 自動偵測 (x64/arm64/armv7) |
| ansible-core | uv tool install --force --python 3.13 ansible-core |
全 OS;若現有 ansible 跑在 Python < 3.10 上會強制刷新 |
| ansible-galaxy: community.general | ansible-galaxy collection install --force-with-deps |
全 OS |
| mise runtimes | mise install --yes(讀 ~/.config/mise/config.toml) |
全 OS — 見 § mise |
Linux 前置條件 (apt) 用來讓 Linuxbrew + mise Ruby + ansible-cryptography
可編譯:build-essential、procps、curl、file、git(永遠);
libffi-dev、libyaml-dev、python3-dev(僅非 noRoot)。
僅 Intel Mac 的旁支腳本:run_once_before_02_fix_intel_homebrew.sh.tmpl
執行 softwareupdate -i 抓 Xcode CLT,接著 brew cleanup +
brew link --overwrite git。
一次性遷移:run_once_before_50_opencode_migrate.sh.tmpl 把舊版
設定檔搬家(~/.config/opencode/config.json → opencode.json)。
不是安裝。
新增到 bootstrap:只在「新工具必須在 ansible 跑之前就存在」時——
例如 ansible 本身、mise(因為 ansible role 會呼叫 mise exec)、uv
(因為某些 role 會呼叫 uv tool install)。否則優先用 ansible role。
2. Homebrew (formulae + casks)¶
三個 Brewfile 模板 + ansible role 中散布的
community.general.homebrew[_cask] task。切分是以 macOS 為中心:
Linux Brewfile 是空的,Linuxbrew 的使用是 role-by-role。
Linux glibc 下限:當 glibc < 2.28 時 bootstrap 直接跳過 Linuxbrew 安裝 (RHEL 8 / Debian 10 的下限——排除 CentOS/RHEL 7 的 2.17,不影響 Ubuntu 20.04 的 2.31)。低於此線時每個 bottle 都得從原始碼編譯,而且安裝程式通常會 先失敗。這與 mise 安裝程式強制改用 musl build 的門檻相同。
一律用「輸出」而非「離開碼」偵測 brew。 本 repo 所有「brew 在不在?」的
檢查都是驗證 brew --prefix 印出非空路徑:
假的 brew stub(#!/bin/sh + exit 0——README 早期建議用它阻止 bootstrap
在 CentOS 7 上安裝 Linuxbrew)會滿足 command -v brew / which brew,且對
每個子命令都回傳 0 並且不印任何東西。於是 brew list --formula <x> 會成功
(誤判安裝方式,見 §2.3)、brew bundle 會「成功」但什麼都沒裝、
community.general.homebrew 則會因空 JSON 而死於
Expecting value: line 1 column 1 (char 0)。詳見
pitfalls/ansible-homebrew-expecting-value-line-1-column-1.md。
2.1 Brewfiles¶
| 檔案 | 擁有什麼 |
|---|---|
Brewfile.tmpl(共用) |
macOS GUI 選項、personal tap 與 gopls;七個 personal formula 由 personal_tools 在 apply 管理,不放 Brewfile,避免 brew bundle 在 upgrade 補裝。 |
Brewfile.darwin.tmpl |
全部 GUI casks — 見下表 |
Brewfile.linux.tmpl |
空白(只有被註解掉的佔位) |
macOS casks(~25 個啟用,由 feature flag 控管):
| Cask | 控管條件 |
|---|---|
alacritty、warp、cmux、cursor、visual-studio-code |
永遠 |
claude、chatgpt、opencode-desktop、antigravity |
installAiDesktopApps |
codeisland(tap wxtsky/tap) |
installAiDesktopApps |
ollama-app |
installAiDesktopApps + installLlmTools |
nikitabobko/tap/aerospace、alt-tab、raycast、maccy、scroll-reverser、the-unarchiver、applite |
永遠(系統工具) |
discord |
永遠 |
arc |
永遠 |
obsidian、google-drive、grammarly-desktop、super-productivity |
永遠 |
spotify、anki |
永遠 |
tailscale-app |
永遠 |
tailscale (Linux) |
installTailscale |
dbeaver-community |
永遠 |
superset |
僅 arm64 |
還有更多被註解掉的條目(steam、telegram、openvpn-connect 等)——取消註解即可啟用。
2.2 Role 驅動的 brew(formulae + casks)¶
大多數 CLI formulae 透過 ansible role 而非 Brewfile 安裝。例:
base/tasks/main.yml:git、git-lfs、curl、wget、ripgrep、fd、jq、tree、justdevtools/tasks/main.yml:大量集合——bat、gh、glab、diffnav、git-delta、eza、tlrc、glow、gum、vhs、freeze、thefuck、zoxide、direnv、yazi、superfile、tmux、sesh、worktrunk、workmux、zellij、btop、htop、duckdb、rclone、coreutils、taplo、television、pandoc、tailspin、lnav、grc、dasel、yq、jnv、witr、figlet、toilet、lolcat、fastfetch、shellcheck、shfmt、bats-core、git-graph、moshcoding_agents/tasks/main.yml:claude-code(cask)、codex(cask)、gemini-cli(formula)、rtk(formula)、specstory、codexbar、td、sidecar(除codexbar外都有 tap 設定;它的 cask 在 homebrew-cask core)coding_agents/tasks/tasks.yml(由main.ymlimport):marcus/tap/tasks,一次安裝tasks、tasks-tui、tasks-apinetworking_tools/:nmap、arp-scan、mtr、iperf3、doggo、httpie、gping、trippy、bandwhich、rustscan、speedtest(tapteamookla/speedtest)、ngrok、cloudflaredmedia_tools/:ffmpeg、imagemagick、exiftool、vipsiac_tools/:azure-cli、hashicorp/tap/terraform、opentofullm_tools/:llmfit、models、ollamasecurity_tools/:gitleaksstarship/、atuin/、bash/(gawk)、zsh/— 每個都在 macOS 上透過 homebrew formula 安裝主要工具;neovim/在 Apple Silicon 使用 Homebrew,需要時改走官方 release fallbackpueue(來自rust_cargo_tools/):macOS 走 homebrew formula
OS 分派在 role 中是通用模式:macOS 分支用
community.general.homebrew / homebrew_cask;Linux 分支用 apt、
Linuxbrew(存在時)或 GitHub releases。每個 role 都有明確的
when: ansible_facts["os_family"] == "Darwin" 守衛。
Tap 清單(各 role 加進來的):nikitabobko/tap、wxtsky/tap
(CodeIsland)、hashicorp/tap(terraform)、teamookla/speedtest、
specstoryai/tap、steipete/tap(CodexBar 的 CLI formula——cask 在 homebrew-cask core,不需要 tap)、marcus/tap(td、sidecar、Tasks)、
dlvhdr/formulae、raine/workmux。
透過 homebrew 新增:只在「macOS 出貨且 Linux 對應品走 apt 或 release tarball」時優先選 brew formula/cask。Linux-first 的工具很少 應該寫進 Brewfile。
2.3 Homebrew prefix 分派輔助¶
scripts/upgrade_tools.sh::_uv_install_style(以及
python_uv_tools/tasks/main.yml 中的對應寫法)會檢查 binary 是不是
住在 brew --prefix 下,以決定走 brew upgrade <pkg> 還是工具的原生
self-update。這避免了「在 brew-uv host 上跑 uv self update 默默
no-op」的陷阱——見
pitfalls/uv-self-update-homebrew-noop.md。
3. Ansible roles¶
dot_ansible/roles/ 下的 26 個 role。由
.chezmoiscripts/global/run_onchange_after_20_ansible_roles.sh.tmpl
觸發(任何 role 的 tasks/main.yml 或 defaults/main.yml 變動時重跑
——SHA256 追蹤)。
通用模式:
state: present/creates:— install-only,不會默默升級- 透過
when: ansible_facts["os_family"] == "Darwin"(或["Debian", "RedHat"])做 OS 分支 - 任何
become: truetask 必加tags: [sudo](讓 noRoot 模式優雅跳過——見pitfalls/ansible-missing-sudo-tag.md) - 「工具裝了嗎?」探測用
failed_when: false+register: - 發行版套件不存在或太舊時退回使用者層級 fallback 到
~/.local/bin(處理 RHEL/CentOS + noRoot + Apple-Silicon-沒有-bottle 的情境)
Role feature flag(在 .chezmoi.toml.tmpl 透過 prompt 設定):
installBrewApps、installAiDesktopApps、installCodingAgents、
installLlmTools、installPythonUvTools、installJsCliTools、
installDotnetTools、installIacTools、installMediaTools、
installNetworkingTools、installTunnelTools、installBitwarden、
installInputMethod、installAuditd。Roles 依據對應 flag 自我控管;
bundle 腳本 scripts/init/dotfiles_init.py 定義 profile 預設
(minimal、規劃中的 cloud-vm、預設開發者等)。
3.1 基礎 / 共用 CLI¶
| Role | 擁有什麼 | OS 機制 |
|---|---|---|
atuin |
atuin shell history 同步 |
macOS:brew formula · Linux:curl https://setup.atuin.sh \| sh -s -- --non-interactive → ~/.atuin/bin/ |
homebrew |
(無安裝 — 只做刷新 + 清理,24h 節流) | n/a |
base |
git、git-lfs、curl、wget、ripgrep、fd、jq、tree、just、gcc/build-essential/make |
macOS:brew formulae · Debian:apt(fd-find + /usr/bin/fd symlink) · RedHat:yum · just 永遠走 curl https://just.systems/install.sh · Linux 使用者層級 GitHub-release fallback 到 ~/.local/bin:ripgrep/fd/jq/git-lfs |
nerdfonts |
font-hack-nerd-font |
macOS:brew cask · Linux:從 nerd-fonts/releases/latest 下載 Hack.zip → ~/.local/share/fonts + fc-cache -fv |
3.2 Shells (bash、zsh、starship)¶
| Role | 擁有什麼 | OS 機制 |
|---|---|---|
bash |
gawk(ble.sh 依賴,無條件);homebrew bash 5.x + /etc/shells + chsh(僅 macOS 且 primary_shell="bash") |
macOS:brew · Debian:apt · RedHat:yum |
zsh |
系統 zsh 套件;若系統 zsh < 5.3,在 RHEL/CentOS 7 上從原始碼編譯 zsh 5.9 到 ~/.local;primary_shell="zsh" 時 chsh(預設) |
macOS:brew · Debian:apt · RedHat:yum + ncurses-devel 原始碼編譯 fallback。oh-my-zsh + 插件以 externals 出貨(§12) |
starship |
starship prompt |
macOS:brew formula · Linux:curl https://starship.rs/install.sh \| sh -s -- --yes → sudo /usr/local/bin → 使用者 ~/.local/bin fallback |
primaryShell chezmoi prompt 只控管 chsh 呼叫——兩個 shell 的 config
不論如何都會部署。詳見 AGENTS.md → "primaryShell choice gates chsh
only" hard invariant。
3.3 DevTools (巨型 role)¶
單一 role,~50 個工具——終端機生活 CLI 的雜燴。有一個 backlog 條目
(backlog/devtools-role-split.md)
在考慮是否要拆開。
macOS(homebrew,taps:gh-dash 用 dlvhdr/formulae、
raine/workmux):bat、bats-core、gh、glab、diffnav、
git-delta、git-graph、eza、tlrc、glow、gum、vhs、
freeze、thefuck、zoxide、direnv、yazi、superfile、tmux、
sesh、worktrunk、workmux、zellij、btop、htop、duckdb、
rclone、coreutils、taplo、television、pandoc、tailspin、
lnav、grc、dasel、yq、jnv、witr、figlet、toilet、
lolcat、fastfetch、shellcheck、shfmt。
Linux — 每個工具分派。模式是apt/yum(系統)→ GitHub release tarball 或 installer(使用者):
| 工具 | Linux 機制(優先 → fallback) |
|---|---|
gh |
GitHub .deb → 使用者 tarball |
glab |
GitHub .deb → 使用者 tarball |
bat |
apt + /usr/bin/bat symlink → GitHub musl release |
bats |
apt → GitHub release install.sh |
zoxide |
curl install.sh |
eza |
gierens.de apt repo → 使用者 GitHub musl → brew aarch64 |
git-delta |
.deb(x86_64)→ brew aarch64 → 使用者 GitHub musl |
diffnav |
使用者 GitHub release |
gh-dash |
gh extension install dlvhdr/gh-dash |
gh-notify |
gh extension install meiji163/gh-notify |
gh-select |
gh extension install remcostoeten/gh-select |
git-graph |
使用者 GitHub release(僅 x86_64) |
tldr |
系統 npm 或 mise exec -- npm install -g tldr |
glow、gum、vhs、freeze、duckdb |
使用者 GitHub release tarball |
rclone |
官方 installer 或 GitHub release |
thefuck |
uv tool install thefuck(Python 3.11,distutils workaround) |
shellcheck、shfmt |
apt 或 release |
direnv |
apt 或 installer |
yazi、superfile、btop、zellij、sesh、worktrunk、workmux |
Linuxbrew 或 GitHub release |
tmux |
apt → 系統版本 < 3.3 時 nelsonenzo/tmux-appimage AppImage 到 ~/.local/share/tmux-appimage/(display-menu popup 必須) — 見 AGENTS.md "Tmux popup menu ≥ 3.3 required" |
htop、pandoc |
apt |
taplo、television (tv)、lnav、grc、tailspin (tspin)、dasel、yq、jnv、witr |
apt + release 混合 |
ccze |
僅 apt(Linux-only 工具,無 macOS 對應品) |
3.4 Coding agents¶
Role:dot_ansible/roles/coding_agents/tasks/main.yml。由
installCodingAgents 控管。最多元異質的 role — 每個 agent 上游
出貨機制都不同,role 就鏡像了那種多樣性。
| Agent | macOS | Linux | 備註 / 來源行號 |
|---|---|---|---|
terminal-notifier / libnotify-bin |
brew formula / apt(Debian) | 僅 apt(Debian) | 通知輔助,9–29 行 |
| Claude Code | brew cask claude-code |
curl https://claude.ai/install.sh \| bash → ~/.claude/local/bin/claude |
33–71 行;非 amd64/arm64 架構跳過 |
| OpenCode | curl https://opencode.ai/install \| bash -s -- --no-modify-path → ~/.opencode/bin/opencode |
同 | 73–107 行。跨平台統一安裝;--no-modify-path 阻止 installer 改寫 chezmoi 管理的 shell rc。容器映像 (container image) 變體見 pitfalls/opencode-docker-opentui-glibc-loader-missing.md |
Pi (pi) |
mise exec -- npm install -g --ignore-scripts --prefix ~/.local @earendil-works/pi-coding-agent |
同 | role 最後區段。需要 Node ≥ 22.19;先以 transaction 安裝並驗證 stable canonical copy,再從其他 npm prefix 移除精確的已棄用/重複 package |
Oh My Pi (omp) |
curl https://omp.sh/install \| sh -s -- --binary → ~/.local/bin/omp |
同 | role 最後區段。先 read-only 偵測 package copy,安裝/驗證 binary 後才移除精確的 @oh-my-pi/pi-coding-agent npm/Bun globals;失敗會還原舊 command,不支援主機不 migration |
| pia | chezmoi external → ~/.local/share/pi-agents/bin/pia |
同 | 由 installCodingAgents gate 的 CLI + combo checkout;08_pi_agents.sh 在 mise/Bun 後重申 canonical Pi/OMP/pia precedence,runtime/session state 不在 checkout 內 |
Cursor CLI(cursor-agent) |
curl https://cursor.com/install \| bash |
同 | 112–124 行;brew cask 因簽章 (code-signing) 問題棄用 |
| GitHub Copilot CLI | npm @githubnext/github-copilot-cli(全域) |
mise exec -- npm install -g |
134–168 行 |
| OpenAI Codex CLI | brew cask codex |
mise exec -- npm install -g @openai/codex |
172–236 行 |
| Gemini CLI | brew formula gemini-cli → npm @google/gemini-cli fallback |
mise exec -- npm install -g |
240–300 行 |
Antigravity CLI(agy + agyc symlink) |
curl https://antigravity.google/cli/install.sh,中途用 sed 改寫成 --skip-path --skip-aliases |
同 | 317–355 行。兩個雷區:(a) 與 Antigravity IDE 同名 — 無衝突的 agyc symlink 是 AICAP 堆疊的鑰匙;(b) installer 預設會改 shell profiles — 已 patch 掉。兩者皆有 in-source 文件 |
| RTK | brew formula rtk |
curl https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh \| sh → ~/.local/bin/rtk |
359–413 行 |
| SpecStory | brew tap specstoryai/tap + formula → GitHub release zip fallback |
GitHub release tarball | 417–595 行 |
| CodexBar | brew cask codexbar——homebrew-cask core(不需 tap)、universal binary、macOS 14+ |
glibc ≥ 2.38:Linuxbrew steipete/tap/codexbar → GitHub release;低於此:只走 static-musl GitHub release |
597–864 行。判斷依據是 /Applications/CodexBar.app 而非 which codexbar;會先移除衝突的 CLI formula(兩者連結同一個 binary 名稱);預編的 Linux CLI 需要 GLIBC_2.38,所以舊 glibc 主機會整個跳過 Linuxbrew。見 codexbar.md |
| td | brew tap marcus/tap + formula |
Linuxbrew → GitHub release marcus/td |
865–1078 行。包含「現有 td 是否與 Sidecar 相容?」版本檢查;不相容則移除衝突的 formula |
| sidecar | brew tap marcus/tap + formula |
Linuxbrew → GitHub release marcus/sidecar |
1080–1256 行 |
Tasks (tasks / tasks-tui / tasks-api) |
marcus/tap/tasks formula |
Linuxbrew → 經 checksum 驗證的 amd64/arm64 GitHub release | tasks.yml 由 main.yml import;三個執行檔完整時不升級,fallback 成組安裝到 ~/.local/bin。首次 XDG 設定見 tasks.md |
| Specify CLI | uv tool install specify-cli --from git+https://github.com/github/spec-kit.git |
同 | 1153–1184 行。目前唯一在 role 中直接用 uv tool install 而非透過 python_uv_tools defaults 的工具 |
| OpenChamber | npm @openchamber/web |
mise exec -- npm install -g |
1188–1222 行 |
| claude-hud 插件 | 執行 files/claude_hud_sync.py --only-if-missing |
同 | 1239–1247 行;install-only,顯式的 just upgrade-plugins 才會刷新 |
AICAP agent 堆疊的 SSOT:dot_config/shell/04_ai_agents.sh 定義
自動偵測順序 + AICAP_*_MODEL 預設值。四個 Python 消費者 regex parse
同一份檔案(見 AGENTS.md cross-file rule)。在此新增 agent 時要同時:
在本 role 安裝 + 加到 SSOT + 四個 Python AGENT_CONFIG dict。
Pi、OMP 與 pia 在本次變更中刻意不加入 AICAP:它們是 harness combo
研究/runtime surface,不是通用 one-shot AI shell helper 的新預設。
3.5 語言工具鏈 (python_uv_tools, ruby_gem_tools, rust_cargo_tools, dotnet_tools, js_cli_tools)¶
語言專用套件管理器的 wrapper。全部都讀取 defaults/main.yml 清單,
所以 role 的 tasks/main.yml 是個迴圈。工具清單見
§ uv、§ npm、
§ cargo、§ dotnet、
§ gem。
| Role | 底層 manager | 工具(數量) | Gate |
|---|---|---|---|
python_uv_tools |
uv tool install |
13 | installPythonUvTools |
llm_tools |
uv tool install + brew + cargo + curl-installer |
4(litellm、llmfit、models、ollama) | installLlmTools |
js_cli_tools |
mise exec -- npm install -g / 系統 npm |
1(readability-cli) |
installJsCliTools |
rust_cargo_tools |
cargo install(在 mise install rust@stable 之後) |
defaults 中 [] + 2 個 hard-code(recon、pueue) |
(無 gate;rust runtime 永遠透過 mise 安裝) |
ruby_gem_tools |
gem install(在 mise install ruby@3 之後) |
2(try-cli、tmuxinator) |
(無 gate;在 noRoot Linux 上由 mise install ruby 跳過來 gate) |
dotnet_tools |
dotnet tool install --global(在 mise use -g dotnet@latest 之後) |
1(azure-cost-cli) |
installDotnetTools |
關鍵 invariant(with_executables_from: 條目必須同時宣告
extra_binaries:):見 AGENTS.md "Install vs upgrade is split on
purpose" hard invariant 的稽核 one-liner 與相關 pitfall。
3.6 編輯器 + 插件 (neovim, lazyvim_deps, nerdfonts)¶
| Role | 擁有什麼 | OS 機制 |
|---|---|---|
neovim |
neovim ≥ 0.11.2(健康的既有安裝保持不動) |
macOS:Apple Silicon brew formula(state: present)→ 仍缺少/太舊時使用經 checksum 驗證的官方 macOS release 安裝到 ~/.local;Intel 直接使用官方 release · Linux:apt → 太舊則 GitHub release tarball(/opt/nvim + /usr/local/bin/nvim symlink)→ 使用者層級 tarball 到 ~/.local;oldEL 抓 neovim/neovim-releases(glibc 2.17 重建 repo)。不用 snap(2026-06 移除——見 linux-package-sources.zh-TW.md → 這個 repo 的 snap 使用現況)。見 pitfalls/centos7-neovim-apt-register-defined.md |
lazyvim_deps |
fzf、lazygit >= 0.64.0、tree-sitter、node |
macOS:brew 安裝四個套件;舊版 brew LazyGit 會只升級該 formula,若 active binary 仍太舊則以經 checksum 驗證的官方 release fallback 到 ~/.local/bin。另外跑 config-driven mise install --yes(Darwin 上唯一會安裝 dot_config/mise/config.toml.tmpl 裡 go/rust 的地方)· Linux:mise(一般 node@lts;armv7l 為 node@20 + rust@stable);fzf 由 chezmoi external clone 編譯;LazyGit 依序走 brew 偵測 → 經 checksum 驗證的 system release → user release fallback(舊 PPA 會移除);tree-sitter-cli 透過 mise exec -- npm install -g tree-sitter-cli(timeout 180)→ cargo fallback 並先裝 libclang-dev/clang-devel |
nerdfonts |
(見 § 3.1 基礎/共用) | — |
3.7 網路 + IaC + LLM + 媒體 (networking_tools, iac_tools, llm_tools, media_tools)¶
| Role | 擁有什麼 | OS 機制 |
|---|---|---|
networking_tools |
nmap、arp-scan、mtr、iperf3、doggo、httpie、gping、trippy、bandwhich、rustscan、speedtest(Ookla) |
macOS:brew(speedtest 用 tap teamookla/speedtest) · Linux:apt + GitHub-release fallback(musl)到 ~/.local/bin,給沒有 apt 套件的工具 |
networking_tools(tunnel 子集,installTunnelTools + tag tunnel_tools 控管) |
ngrok、cloudflared |
macOS:brew cask ngrok + brew formula cloudflared · Debian:ngrok apt repo + cloudflared .deb · RedHat:cloudflared .rpm · noRoot:使用者層級 tarball fallback |
iac_tools(installIacTools 控管;每工具皆有 toggle) |
azure-cli、terraform、opentofu |
macOS:brew(terraform 用 hashicorp/tap) · Linux:廠商 apt repo(Microsoft / HashiCorp / Cloudsmith)→ 使用者層級 zip / uv tool install azure-cli fallback |
llm_tools(installLlmTools 控管) |
litellm[proxy](透過 uv)、llmfit、models、ollama |
混合 — macOS 用 brew formula / Linux 用 curl-installer。Ollama:永遠 brew formula(CLI) + installBrewApps 時 Brewfile 的 cask ollama-app;Linux 用 curl https://ollama.com/install.sh(sudo,noRoot 跳過) |
media_tools(installMediaTools 控管) |
ffmpeg、imagemagick、exiftool、vips |
macOS:brew · Debian:apt(libimage-exiftool-perl、libvips-tools) |
3.8 系統 / GUI / 安全 (docker, gui_apps_linux, auditd, security_tools, bitwarden, input_method, atuin, homebrew)¶
| Role | 擁有什麼 | OS 機制 |
|---|---|---|
docker |
OrbStack(macOS)、Docker rootless(Linux) | macOS:brew cask orbstack(/Applications/Docker.app 存在則跳過) · Debian/Ubuntu:apt 前置條件(uidmap、dbus-user-session、fuse-overlayfs、slirp4netns、iptables)→ curl https://get.docker.com \| sh → docker-ce-rootless-extras → dockerd-rootless-setuptool.sh install 使用者 systemd unit |
gui_apps_linux(Linux Debian + ubuntu_desktop profile) |
Alacritty、libfuse2、AppImageLauncher、VSCode、Cursor、Google Chrome、Discord、Zen Browser、CopyQ、playerctl/wmctrl/xdotool、wl-clipboard/xclip/xsel | Alacritty:cargo 編譯(apt 依賴 cmake、pkg-config、字型/X 函式庫) · AppImageLauncher:PPA → GitHub .deb → Lite AppImage 到 ~/Applications/ · VSCode:Microsoft apt repo · Cursor:.deb 來自 cursor.com/api/download · Google Chrome:.deb 來自 dl.google.com(僅 x86_64) · Discord:flatpak(Flathub user-scope,預設)或 .deb,由 discordChannel 選擇 · Zen Browser:AppImage 到 ~/Applications/zen.AppImage |
auditd(Linux,installAuditd 控管) |
auditd + audispd-plugins(Debian)/ audit(RedHat);rule 檔 00-baseline.rules、05-privileged.rules、選用 10-execve.rules、99-finalize.rules |
apt / yum |
security_tools |
pre-commit、gitleaks |
macOS:brew(gitleaks)+ uv(pre-commit) · Linux:gitleaks 來自 GitHub release(系統 → /usr/local/bin;使用者 fallback → ~/.local/bin)+ uv pre-commit。Go 已不在此 — 移到 mise(go = "latest",gate 於 installExtraRuntimes)。 |
bitwarden(installBitwarden 控管) |
@bitwarden/cli + Bitwarden Desktop(bitwarden_install_desktop=true 時) |
CLI:mise exec -- npm install -g @bitwarden/cli(優先)/ 系統 npm fallback · Desktop:macOS brew cask · Linux:snap → .deb fallback |
input_method(installInputMethod 控管) |
mcbopomofo、squirrel(macOS)· ibus-rime(Debian) |
macOS:brew cask · Linux:apt。Rime 的 *.custom.yaml 由 chezmoi 納管並與 Windows repo 共用 — 見 input_methods。 |
atuin |
(見 § 3.1 基礎/共用) | — |
homebrew |
(見 § 2 Homebrew) | — |
4. mise (執行階段 (runtime) 版本)¶
設定檔:dot_config/mise/config.toml.tmpl
[settings]:ruby.compile = false。
現代主機(預設):
| Runtime | 版本 | gate 條件 |
|---|---|---|
node |
lts |
一律安裝 |
bun |
1 |
installExtraRuntimes |
rust |
stable |
installExtraRuntimes |
go |
latest |
installExtraRuntimes |
dotnet |
10 |
installDotnetTools |
ruby |
3 |
installExtraRuntimes(且非 noRoot) |
版本釘選理由:node=lts / rust=stable / go=latest 使用浮動
channel,因為它們各自承諾向後相容(Go 的
go1compat 讓 latest 如同 rust 的
stable 一樣安全)。bun=1 與 dotnet=10 改為釘住主版號 —
兩者都不保證跨主版號不破壞(bun 在 minor 就會有行為變更;.NET 主版號
會 bump TFM / SDK 行為),且 dotnet=10 也是目前的 LTS(8/9 在 2026
年中已到/接近 EOL)。下一個 LTS(12)推出時再刻意 bump dotnet。
ruby=3 追蹤 3.x 線。
go 取代了原本 security_tools role 中僅限 macOS 的 brew 安裝,因此
Linux 主機現在也有受管的 Go(先前是缺口)。
Ruby 在 noRoot 模式下會跳過(profile=ubuntu_server 無 sudo),
因為它需要 libffi-dev / libyaml-dev 才能編譯,而那需要 apt。
oldEL(CentOS/RHEL 7、glibc 2.17):只有 ruby = "3" — 其他
runtime 的 glibc/libstdc++ 需求對 EL7 來說太新。
升級:just upgrade-mise → mise self-update --yes + mise upgrade
(遵守設定檔中的版本約束;lts/latest 會往前移,釘住的版本不會)。
新增 runtime:直接編輯 dot_config/mise/config.toml.tmpl。跨機器
的 runtime 版本控管在 backlog。
為什麼選 mise(而不是 nvm/rbenv/pyenv/asdf/n):統一、語言無關、
尊重 .tool-versions、不與 shell 啟動順序打架。Python 刻意不用 mise
管理 — 那是 uv 的地盤(更快 + 不需要從原始碼編譯 CPython,而 noRoot
Linux 路徑無法編譯)。
backlog
追蹤更細粒度的跨主機控管。
5. uv (Python CLI 工具)¶
設定檔:dot_ansible/roles/python_uv_tools/defaults/main.yml
(+ llm_tools/defaults/main.yml 中的 litellm)。Role 層級分派:
dot_ansible/roles/python_uv_tools/tasks/main.yml。
檢查 uv 是否低於 min_uv_version(0.8.5),分派升級到對應通道——
Homebrew 安裝走 brew upgrade uv、curl-installer 安裝走
uv self update。scripts/upgrade_tools.sh::cat_uv() 中有鏡像邏輯。
詳見 docs/this_repo/uv-bootstrap.md 與
pitfalls/uv-self-update-homebrew-noop.md。
兩個完整性 guard 可修復既有 tool、但不會把 role 變成自動升級:extra_binaries
檢查 ~/.local/bin 的 entry-point shim;required_distributions(搭配
env_name)檢查 uv tool venv 內的 Python distribution。缺少時只執行一次
uv tool install --force,完整環境保持不變。yt-dlp[default] 用後者確保從前
安裝 bare yt-dlp 的主機也補上相容的 yt-dlp-ejs solver。
工具清單(python_uv_tools/defaults/main.yml):
| 工具 | --with / --with-executables-from |
needs_modern_gcc |
|---|---|---|
thefuck |
(python 3.11;distutils workaround) | — |
apprise |
— | — |
sqlit-tui[ssh] |
psycopg2-binary, pymysql, mssql-python, pyodbc, duckdb |
✓(gcc ≥ 9) |
python-dotenv[cli](dotenv) |
— | — |
git-filter-repo |
— | — |
mlflow |
— | ✓ |
tmuxp |
— | — |
visidata(vd) |
pandas, pyarrow |
✓ |
copyparty |
— | — |
trafilatura |
— | — |
marimo[recommended,mcp] |
httpx[socks] |
✓ |
jupyterlab(jupyter-lab) |
marimo[sandbox], marimo-jupyter-extension, ipykernel, ipywidgets;with_executables_from: notebook, jupyter-core;extra_binaries: jupyter, jupyter-notebook |
✓ |
xonsh |
xontrib-jedi, xontrib-zoxide, xontrib-pipeliner, xontrib-fzf-widgets |
— |
yt-dlp[default] |
required_distributions: yt-dlp-ejs(EJS solver;yth/ytmv 啟用 Node) |
— |
來自 llm_tools/defaults/main.yml:
| 工具 | 釘住 |
|---|---|
litellm[proxy](litellm) |
--python 3.13, --with httpx[socks] |
defaults YAML 之外的 ad-hoc uv tool install:
coding_agents/tasks/main.yml:1153-1184—specify-cli(從git+...)security_tools/tasks/main.yml—pre-commit(--python 3.13, 避開 Homebrew Python 3.14 pyexpat ABI 不相容)iac_tools/tasks/main.yml—azure-cli使用者 fallback(Linux noRoot)
升級:just upgrade-uv → uv self-update(已分派)+ uv tool upgrade --all。
新增 uv 工具:在 python_uv_tools/defaults/main.yml 附加。如果套件
會在入口點之外寫入伴隨 binary,必須同時宣告
with_executables_from: AND extra_binaries:——否則在主要 binary 已
存在的主機上 install guard 會短路而 shim 永遠不會寫入
(pitfalls/uv-tool-install-creates-guard-misses-executables-from.md)。
如果範圍內有 gcc < 9 的主機,設 needs_modern_gcc: true。
6. npm (全域 Node CLI)¶
設定檔:dot_ansible/roles/js_cli_tools/defaults/main.yml 是 JS
工具專屬清單。其他散布在各 role 的全域 npm 安裝在
(coding_agents、bitwarden、lazyvim_deps、devtools)。
安裝分派(跨 role 的通用模式):
# Linux 上:
mise exec -- npm install -g <package>
# 如果 mise 沒註冊 node 則退回系統 npm
# macOS 上:
community.general.npm: { name: <package>, global: true }
Linux 顯式用 mise exec -- npm 避開 Ubuntu apt 的 npm(太舊;系統
Node 12 連現代套件的 engine 檢查都過不了,而且 /usr/local/lib/node_modules
是 root-owned,讓非 root 使用者的 --global 安裝壞掉)。見
pitfalls/ansible-js-cli-tools-old-system-node.md。
Pi 在兩個 OS 都刻意優先使用 mise,並加上 --prefix ~/.local:它與
pia 共用 Node 22.19 的最低需求,而固定 prefix 能跨 mise Node 版本替換
保留 command。role 會先安裝並驗證 canonical copy,再從不同的 active
npm prefix 移除精確的 deprecated/duplicate Pi package,因此失敗的
migration 不會破壞原本可用的 command。
清單:
| 套件 | Binary | Role / 行號 |
|---|---|---|
readability-cli |
readable |
js_cli_tools/defaults/main.yml |
@bitwarden/cli |
bw |
bitwarden/tasks/main.yml |
@earendil-works/pi-coding-agent |
pi |
coding_agents/tasks/main.yml(--ignore-scripts --prefix ~/.local;移除已棄用的 @mariozechner/pi-coding-agent) |
@githubnext/github-copilot-cli |
github-copilot-cli |
coding_agents/tasks/main.yml:134-168 |
@openai/codex |
codex(僅 Linux — macOS 走 brew cask) |
coding_agents/tasks/main.yml:172-236 |
@google/gemini-cli |
gemini(Linux 永遠;macOS 在 brew formula 失敗時 fallback) |
coding_agents/tasks/main.yml:240-300 |
@openchamber/web |
openchamber |
coding_agents/tasks/main.yml:1188-1222 |
tldr |
tldr(僅 Linux — macOS 走 brew 的 tlrc) |
devtools/tasks/main.yml |
tree-sitter-cli |
tree-sitter |
lazyvim_deps/tasks/main.yml(優先於 cargo fallback) |
升級:just upgrade-npm → npm -g update,有 mise exec -- fallback。
Pi 使用固定的 ~/.local prefix,因此由 just upgrade-agents 先跑
pi update --self,失敗時以同一個 prefix 的 npm install fallback 更新。
新增 npm 工具:在 js_cli_tools/defaults/main.yml 附加(給一般工具);
若是 agent CLI,改在 coding_agents/tasks/main.yml 新增安裝 task,
按現有分派模式(通常 macOS 用系統 npm,Linux 用 mise exec -- npm install -g;
若 command 必須跨 runtime 升級保留,使用固定的 user prefix)。
7. cargo (Rust crates)¶
設定檔:dot_ansible/roles/rust_cargo_tools/defaults/main.yml
(目前 cargo_tools: [] — 沒有泛用條目)。
Rust 安裝:mise install rust@stable(優先——這個 spec 必須與
dot_config/mise/config.toml.tmpl 的 rust = "stable" 一致,見
pitfalls/mise-warn-missing-rust-stable-every-prompt.md),在 noRoot/oldEL 主機
上有兩層 fallback:直接 rustup-init、設定的 mirror manifest 過期
時退回 https://static.rust-lang.org。
清單(tasks/main.yml 中 hard-coded):
| Crate | 機制 | 備註 |
|---|---|---|
recon |
cargo install --git https://github.com/gavraz/recon --locked |
git source(尚未發到 crates.io) |
pueue |
macOS brew formula;Linux cargo install pueue --locked |
+ pueued.service systemd user unit;版本檢查 pueue_min_version=4.0.0(僅警示) |
tree-sitter-cli |
cargo install tree-sitter-cli(只當 fallback) |
優先路徑是 mise exec -- npm install -g tree-sitter-cli;cargo 路徑會先裝 libclang-dev/clang-devel |
alacritty |
cargo 編譯(gui_apps_linux) |
需要 apt 編譯依賴(cmake、pkg-config、libfontconfig1-dev、libxcb-xfixes0-dev、libxkbcommon-dev) |
modelsdev |
cargo fallback(llm_tools) |
只在 Linuxbrew 不存在 + brew formula models 也不可用時 |
cargo-update |
cargo install cargo-update(給升級用的 bootstrap) |
第一次跑 upgrade_tools.sh::cat_cargo 時安裝,之後 cargo install-update -a 就會用它 |
升級:just upgrade-cargo → cargo install-update -a(涵蓋所有
透過 cargo 安裝的東西,包括 Linux 上的 pueue)。
新增 cargo 工具:優先 cargo_tools: [<name>] 寫到 defaults YAML
(由 cargo install-update -a 涵蓋);只在安裝需要額外編譯依賴或非
crates.io 來源時才 hard-code 到 tasks/main.yml(見 recon、pueue)。
Go CLI 與個人工具套件¶
go_tools/defaults/main.yml 現只管理 Linux 的 gopls;macOS gopls 仍由
Homebrew 管理。它維持 installExtraRuntimes、mise Go、creates: 與
just upgrade-go 的既有 install-only/明確升級分工。
十三個個人工具由 personal_tools role 管理,單一來源是
dot_ansible/roles/personal_tools/files/tools.json。installPersonalTools=true
時,macOS 走 Homebrew formula,Linux amd64/arm64 走驗證 checksum 的 GitHub
release;這十三件不需 Go 或 sudo。just upgrade-personal 只升級已安裝且能辨識
owner 的選定工具,不補裝缺失工具,也不覆蓋未知同名程式。
舊機缺少新 key 時保留舊選擇:macOS 的 dev/translate 維持 Brew;Linux 的
這兩者與兩平台 lazyclash 仍受 extra runtimes 控制,使用既有 Go 安裝基線。
Go output/cache 維持 ~/.local/bin/~/.local/share/go;沒有 Go 就略過,
不默默安裝 SDK。套件其他工具不會自動加入。套件只安裝 CLI,不啟動後端或建立密鑰。
新增 lazyansible、lazycrontab、lazyfind、lazypkg、lazymermaid、lazyset 沿用 同樣的不可變 release 與 personal tap formula。沒有新增 SDK、首次呼叫下載或 backend 安裝。各工具版本基線與 runtime 前置條件見個人工具文件。
詳見 個人工具 的遷移、receipt、可回復 Brew 轉換與平台限制。安裝/升級成功後沿用 completion generator 更新對應的兩個 shell。
8. dotnet (全域 .NET 工具)¶
設定檔:dot_ansible/roles/dotnet_tools/defaults/main.yml
.NET SDK 透過 mise use -g dotnet@<version>(預設 latest)。
SDK 裝好後,role 對每個條目跑 dotnet tool install --global 迴圈 —
binary 放到 ~/.dotnet/tools/(已經由
dot_config/shell/00_exports.sh.tmpl 加到 PATH)。
清單:
| 套件 | Binary |
|---|---|
azure-cost-cli |
azure-cost |
升級:just upgrade-dotnet → 對每個工具重跑 dotnet tool update --global。
新增 dotnet 工具:在 dotnet_tools/defaults/main.yml 附加,提供
name(NuGet package id)與 binary(實際命令名)。
9. gem (Ruby gems)¶
設定檔:dot_ansible/roles/ruby_gem_tools/defaults/main.yml
Ruby 安裝:mise install ruby@3(noRoot Linux 跳過)。先裝編譯
依賴:libffi-dev、libyaml-dev(Debian)/ libffi-devel、
libyaml-devel(RedHat)。
清單:
| Gem | Binary |
|---|---|
try-cli |
try |
tmuxinator |
tmuxinator |
加上 toolkami.rb 由 chezmoi external 抓取(見 § 12 — 獨立執行,
不透過 gem install)。
升級:just upgrade-gem → gem update。
新增 gem:在 ruby_gem_tools/defaults/main.yml 附加(noRoot Linux
上會自動跳過,因為那邊 ruby 沒裝)。
10. curl-installer (自管 CLI)¶
透過廠商 install.sh 而非套件管理器出貨的工具。主要是 AI coding
agents(每個廠商自己維護 installer + self-update 子命令)。所有 landing
路徑都是使用者可寫,讓 in-binary self-update 不用 sudo 就能用。
清單:
| 工具 | 安裝 URL | 落地處 | 來源 role |
|---|---|---|---|
| Homebrew | https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh |
/usr/local/bin/brew(macOS)/ /home/linuxbrew/.linuxbrew/(Linux) |
bootstrap |
| uv | https://astral.sh/uv/install.sh |
~/.local/bin/uv(或 ~/.cargo/bin/uv) |
bootstrap |
| mise | https://mise.run |
~/.local/bin/mise |
bootstrap |
| just | https://just.systems/install.sh |
/usr/local/bin/just 或 ~/.local/bin/just |
base |
| starship | https://starship.rs/install.sh |
/usr/local/bin/starship 或 ~/.local/bin/starship |
starship |
| atuin | https://setup.atuin.sh |
~/.atuin/bin/atuin |
atuin |
| docker | https://get.docker.com |
系統 docker(rootless 變體) | docker(Linux) |
| zoxide | (廠商 installer) | ~/.local/bin/zoxide |
devtools(Linux fallback) |
| direnv | (廠商 installer) | ~/.local/bin/direnv |
devtools(Linux fallback) |
| Claude Code | https://claude.ai/install.sh |
~/.claude/local/bin/claude |
coding_agents(Linux) |
| OpenCode | https://opencode.ai/install(+ --no-modify-path) |
~/.opencode/bin/opencode |
coding_agents(macOS + Linux) |
| Oh My Pi | https://omp.sh/install(--binary) |
~/.local/bin/omp |
coding_agents(macOS + Linux x64/arm64) |
| Cursor CLI | https://cursor.com/install |
~/.local/bin/cursor-agent |
coding_agents |
| Antigravity CLI | https://antigravity.google/cli/install.sh(改寫成 --skip-path --skip-aliases) |
~/.local/bin/agy + agyc symlink |
coding_agents |
| RTK | https://raw.githubusercontent.com/rtk-ai/rtk/master/install.sh |
~/.local/bin/rtk |
coding_agents(Linux) |
| llmfit | https://llmfit.axjns.dev/install.sh |
~/.local/bin/llmfit(或系統) |
llm_tools(Linux) |
| Ollama | https://ollama.com/install.sh |
系統路徑(Linux,sudo) | llm_tools(Linux) |
| Ookla speedtest | https://install.speedtest.net/app/cli/install.<distro>.sh |
系統 | networking_tools(Linux) |
為什麼選 curl-installer 而非套件管理器:
- 快速迭代的 release — 廠商控制節奏(Claude、OpenCode、Cursor、 Antigravity 每天/每週推送)
- 存在 self-update 子命令 + installer 是標準重裝路徑 →
scripts/upgrade_tools.sh的cat_agents兩種都可呼叫 - 避開「brew formula 落後 3 週」的問題(見 OpenCode 從
anomalyco/tap搬到官方 installer 的 commit 歷史) - 不用維護 tap/PPA/repo
新增 curl-installer 工具:
- 選一個 role(agent 就放
coding_agents) - 用標準模式:
which檢查 → binary 路徑上的creates:守衛 →curl ... | bash [-s -- --no-modify-path]shell task - 如果 installer 會改 shell rc 檔,加
--no-modify-pathflag(或對等 ——見 OpenCode 與 Antigravity 區塊)。chezmoi 管理的 PATH 是 SSOT - 如果工具有 self-update 子命令(或 installer-as-upgrader 路徑),
更新
scripts/upgrade_tools.sh::cat_agents - 如果 binary 落在
~/.local/bin以外(例如~/.opencode/bin/opencode), 到dot_config/shell/00_exports.sh.tmpl加一個存在性守衛的 PATH 前置。 如果受管理路徑必須蓋過後面的 mise、Bun 或 package-manager PATH, 改在更後面的編號共用 fragment 再次前置(Pi/OMP/pia 的做法在dot_config/shell/08_pi_agents.sh.tmpl)
11. GitHub-release 下載 (使用者層級 fallback)¶
當 apt/yum 不能滿足版本需求(例如 Apple Silicon brew bottle 缺失、
RHEL/CentOS 套件太舊、無 sudo 的 noRoot 主機),role 退回下載最新
GitHub release tarball 並解壓到 ~/.local/bin(使用者可寫,已在 PATH)。
標準寫法:
- name: Get latest <tool> release
ansible.builtin.uri:
url: https://api.github.com/repos/<owner>/<repo>/releases/latest
return_content: true
register: <tool>_release
- name: Compute <tool> arch
ansible.builtin.set_fact:
<tool>_arch: "{{ 'amd64' if target_architecture in ['x86_64', 'amd64'] else 'arm64' if ... else 'unsupported' }}"
- name: Download / extract / copy into ~/.local/bin
block:
- get_url: { url: "https://github.com/.../{{ tag }}/{{ asset }}", dest: /tmp/..., retries: 3, delay: 5, timeout: 120 }
- unarchive: { src: ..., dest: /tmp/..., remote_src: true }
- find: { paths: /tmp/..., patterns: <binary>, file_type: file }
- copy: { src: ..., dest: "{{ ansible_facts['env']['HOME'] }}/.local/bin/<binary>", mode: '0755' }
rescue:
- debug: "<tool> installation failed (likely network timeout) - skipping"
使用此模式的工具(粗略清單 — 見各 role 的 tasks/main.yml):
base:ripgrep、fd、jq、git-lfsdevtools:gh、glab、bat、bats、eza、git-delta、diffnav、git-graph、glow、gum、vhs、freeze、duckdb、yazi、superfile、btop、zellij、sesh、worktrunk、workmux、taplo、tv(television)、lnav、tailspin、dasel、yq、jnv、witrnetworking_tools:doggo、gping、trippy、bandwhich、rustscan、cloudflaredneovim:nvim tarball(Linux fallback + macOS Intel/最低版本 fallback)lazyvim_deps:lazygitfallbackcoding_agents:specstory、codexbar、td、sidecar、agy(都同時有 brew formula / cask 當主要路徑)coding_agents/tasks/tasks.yml:Tasks 工具組;Linuxbrew 失敗後驗證官方 release checksum,成組安裝tasks、tasks-tui、tasks-api;完整安裝不重下。明確升級見 Tasks 升級。security_tools:gitleaksiac_tools:terraform、opentofu使用者 fallback(來自releases.hashicorp.com/ GitHub 的 zip)gui_apps_linux:AppImageLauncher Lite、Zen Browser AppImagebitwarden:Desktop.debfallback(Linux)
⚠️ 覆蓋落差:GitHub-release 下載用 binary 路徑上的 creates: 守衛,
所以一旦安裝就永遠不會被 chezmoi apply 刷新——而
scripts/upgrade_tools.sh 沒有對應類別。唯一刷新方式:rm binary
後重 apply。見下面的 § 覆蓋落差。
新增 GitHub-release 工具:從例如 devtools/tasks/main.yml 複製
標準區塊(找一個架構矩陣類似的現有工具),替換 owner/repo/asset-name。
永遠包在 block: / rescue: 裡(廠商端會出包),下載用
retries: 3, delay: 5, timeout: 120。
12. chezmoi externals (週期刷新 git/檔案抓取)¶
設定檔:.chezmoiexternal.toml.tmpl
chezmoi apply 依排程抓取這些。全部設 refreshPeriod = "168h"
(每週),--depth 1 淺 clone,--ff-only 拉取。
| 路徑 | 類型 | 來源 | 控管條件 |
|---|---|---|---|
.oh-my-zsh |
git-repo | ohmyzsh/ohmyzsh.git |
永遠 |
.oh-my-zsh/custom/plugins/zsh-autosuggestions |
git-repo | zsh-users/zsh-autosuggestions.git |
永遠 |
.oh-my-zsh/custom/plugins/zsh-syntax-highlighting |
git-repo | zsh-users/zsh-syntax-highlighting.git |
永遠 |
.oh-my-zsh/custom/plugins/zsh-completions |
git-repo | zsh-users/zsh-completions.git |
永遠 |
.oh-my-zsh/custom/plugins/zsh-vi-mode |
git-repo | jeffreytse/zsh-vi-mode.git |
enableVimMode |
.oh-my-bash |
git-repo | ohmybash/oh-my-bash.git |
永遠 |
.local/src/blesh |
git-repo(--recurse-submodules) |
akinomyoga/ble.sh.git |
永遠;由 run_onchange_after_26_install_blesh.sh.tmpl 編譯 → ~/.local/share/blesh/ble.sh |
.tmux/plugins/tpm |
git-repo | tmux-plugins/tpm.git |
永遠 |
.fzf |
git-repo | junegunn/fzf.git |
僅 Linux(ansible 跑 ~/.fzf/install --bin) |
.local/share/pi-agents |
git-repo | daviddwlee84/pi-agents.git |
installCodingAgents;提供 bin/pia,runtime state 留在 checkout 外 |
.local/share/toolkami/toolkami.rb |
file(executable) | https://raw.githubusercontent.com/aperoc/toolkami/refs/heads/main/toolkami.rb |
永遠 |
為什麼選 externals(而不是在 role 裡 git clone):
- 刷新節奏內建(chezmoi 自己照排程做
git pull;ansible role 沒有 「每 N 小時 re-pull」的基本元素) - 一個地方就能看到「這台機器上有哪些第三方原始碼」
chezmoi update --refresh-externals是明確的強制刷新
升級:just upgrade-externals → chezmoi apply --refresh-externals。
新增 external:在 .chezmoiexternal.toml.tmpl 前置條目。如果 clone
後需要編譯步驟(像 ble.sh),掛一個
run_onchange_after_NN_*.sh.tmpl 腳本在 external 的 commit 變動時
重跑。
過往 pitfall:
- ble.sh local-changes-overwritten (
pitfalls/chezmoi-update-blesh-local-changes-overwritten.md) — 原始碼 clone 已搬出 chezmoi external 路徑,以解耦make install
13. apt / yum (系統套件)¶
Linux 的務實後盾。對發行版打包良好的工具(夠新、可用、沒有顯著 的上下游分歧),role 使用 apt/yum。
使用 apt/yum 的 role(不完全列舉):
| Role | apt 套件 | yum 套件 |
|---|---|---|
base |
git、git-lfs、curl、wget、ripgrep、fd-find、jq、tree、build-essential |
git、git-lfs、curl、wget、jq、tree、gcc、gcc-c++、make |
bash |
(Linux 上只有 primary_shell=bash 時走 brew) |
— |
zsh |
zsh |
zsh(或 RHEL 7 上的 ncurses-devel + 原始碼編譯) |
devtools |
bat、gh、glab、eza、git-delta、htop、pandoc、tldr 等(很多) |
類似子集 |
media_tools |
ffmpeg、imagemagick、libimage-exiftool-perl、libvips-tools |
— |
networking_tools |
nmap、arp-scan、mtr、iperf3、httpie、tcpdump |
同(扣掉 httpie) |
coding_agents |
libnotify-bin(僅 Debian) |
— |
lazyvim_deps |
(主要靠 mise + GitHub releases) | — |
auditd |
auditd、audispd-plugins |
audit |
gui_apps_linux |
cmake、pkg-config、字型函式庫(Alacritty 編譯)、libfuse2、copyq、playerctl、wmctrl、xdotool、wl-clipboard、xclip、xsel |
— |
docker |
uidmap、dbus-user-session、fuse-overlayfs、slirp4netns、iptables(rootless 前置) |
— |
iac_tools |
azure-cli、terraform、opentofu(透過廠商 apt repo) |
— |
nerdfonts |
fontconfig |
fontconfig |
python_uv_tools |
libffi-dev、libyaml-dev、python3-dev(Ruby + ansible-cryptography 編譯依賴) |
libffi-devel、libyaml-devel、python3-devel |
管理中的廠商 apt repo(需要 GPG key + sources.list.d 條目):
| Repo | 用於什麼 |
|---|---|
apt.releases.hashicorp.com |
terraform |
packages.microsoft.com |
azure-cli、vscode |
cli.github.com/packages |
gh |
gitlab.com/api/v4/projects/.../packages/debian |
glab |
pkgs.gierens.de |
eza |
ngrok-agent.s3.amazonaws.com |
ngrok |
apt.releases.opentofu.org |
opentofu(Cloudsmith) |
PPA ppa:lazygit-team/release |
lazygit |
PPA ppa:appimagelauncher-team/stable |
AppImageLauncher |
升級:scripts/upgrade_tools.sh 不涵蓋。依賴 repo 流程外的
sudo apt upgrade / sudo yum update。這是刻意的落差——發行版升級是
系統管理員的決定,不是 dotfiles 的決定。
新增 apt/yum 套件:在相關 role 的 tasks/main.yml 加一個
ansible.builtin.apt / ansible.builtin.yum task,用 os_family 控管。
永遠 become: true + tags: [sudo](讓 noRoot 模式優雅跳過),
若工具有廣泛用途,考慮替 noRoot 路徑加一個使用者層級 fallback。
多機制工具 + 原因說明¶
安裝路徑因 OS / 架構 / role-feature-flag 而異的工具,以及原因說明。
| 工具 | 機制分派 | 為什麼 |
|---|---|---|
| uv | Bootstrap:curl。之後:依 binary 路徑分派 brew upgrade uv vs uv self update |
brew 安裝會釘住版本到 versioned Cellar — uv self update 在那裡 no-op。Role + upgrade script 中的鏡像邏輯讓兩條路徑都能用。見 pitfall |
| OpenCode | 兩個 OS 都走 curl-installer(2026-05 起) | 過去 macOS 是 brew tap(anomalyco/tap),但 formula 版本落後 + Cellar 釘版本讓 opencode upgrade 失效。統一到官方 installer + --no-modify-path。見 coding_agents/tasks/main.yml # === OpenCode 區塊 |
| OpenAI Codex CLI | macOS:brew cask;Linux:npm @openai/codex |
macOS 有 brew 的 .app(較豐富);Linux 只出 npm CLI |
| Gemini CLI | macOS:brew formula gemini-cli → npm fallback;Linux:npm |
brew formula 可用性不穩 |
| Specstory | macOS:brew tap → GitHub release fallback;Linux:GitHub release tarball | brew formula 可用性 + 版本新鮮度 |
| CodexBar | macOS:brew cask(homebrew-cask core、universal);Linux:Linuxbrew formula → GitHub release | macOS 裝的是選單列應用程式,本身就內含 CLI(formula 的超集);Linux 只有 CLI |
| td / sidecar | macOS:brew tap;Linux:Linuxbrew → GitHub release | 同維護者(marcus/tap);Linuxbrew 存在時走快路 |
| Tasks 工具組 | macOS:marcus/tap/tasks;Linux:Linuxbrew → checksum 驗證的 release |
與 td/Sidecar 同屬 marcus/tap;三個 binary 一起安裝,完整既有工具組維持 install-only |
| Ollama | 永遠 brew formula(CLI);installAiDesktopApps + installLlmTools 時 brew cask ollama-app;Linux:curl ollama.com/install.sh |
CLI vs GUI 切分;廠商 installer 是 Linux 標準路徑 |
| fzf | macOS:lazyvim_deps brew。Linux:chezmoi external + ~/.fzf/install --bin |
macOS 用 brew 沒問題;Linux 拿到最新的 git tip |
| bash | 永遠有系統 bash;macOS 上只有 primary_shell="bash" 時才裝 homebrew bash 5.x |
macOS 出貨 bash 3.2(GPL2 vintage);brew bash 5 只在使用者真的想當登入 shell 時才需要 |
| gh | macOS:brew(透過 devtools);Linux:廠商 apt repo → 使用者 tarball fallback |
brew 是 macOS 標準;廠商 apt repo 是 Linux 標準 |
| tmux | macOS:brew;Linux:apt → 系統版本 < 3.3 時 nelsonenzo/tmux-appimage |
display-menu popup 需要 3.3+ — 見 AGENTS.md tmux hard invariant |
| Discord | macOS:brew cask;Linux:flatpak(預設)或 .deb,由 discordChannel 選 |
apt 沒有 Discord;flatpak 沙箱化且最新,.deb 給討厭 flatpak 的人 |
| just、starship、zoxide、direnv | macOS:brew;Linux:廠商 curl-installer | Linux 發行版套件對這些快速迭代的工具太舊 |
| Neovim | macOS:健康安裝 → Apple Silicon brew(state: present)→ 經 checksum 驗證的官方 release;Intel 需要安裝時跳過 brew。Linux:apt → GitHub release tarball → 使用者 fallback → oldEL 上的 neovim/neovim-releases |
在不把 chezmoi apply 變成升級流程的前提下強制最低版本 0.11.2;政策上不用 snap |
| LazyGit | 既有版本 >= 0.64.0 → Homebrew 管理的舊 formula 定向升級 → 經 checksum 驗證的官方 release(Linux 先 /usr/local/bin,所有支援 OS 再以 ~/.local/bin fallback) |
0.64 前會靜默忽略託管的 git.diffRenderers schema,因此這是最低版本修復,不是一般升級 |
| tree-sitter-cli | npm 透過 mise(優先,timeout 180)→ cargo fallback | npm 比較快;cargo 需要 libclang 才能編譯。兩條路徑產生同一份 binary |
| bw (Bitwarden CLI) | npm 全域(優先)或系統 npm fallback | 永遠是 npm,分派是 mise-npm vs 系統-npm |
新增多機制分派工具:每個 OS 優先一個主要機制,最多一個 fallback。多層 fallback 會增加實際沒人會跑的測試組合(5 層 × 5 OS 變體 = 25 格)。猶豫時寫最簡單的版本,只在實際主機壞了才加 fallback。
Fallback 鏈¶
值得記住的串接式 fallback 模式:
| 工具 | 鏈 |
|---|---|
| mise binary | curl https://mise.run(優先)→ 直接從 mise.jdx.dev/mise-latest-linux-${arch} 下載 → musl 變體(glibc < 2.28 時強制) |
| Neovim (macOS) | 既有版本 ≥ 最低要求 → Apple Silicon Homebrew 安裝 → 經 checksum 驗證的官方 arm64 release fallback;Intel 需要安裝時直接使用官方 x86_64 release |
| Neovim (Linux) | apt → 太舊則 GitHub release tarball(/opt/nvim + symlink)→ 使用者 tarball 到 ~/.local → neovim-releases 分支(oldEL glibc 2.17 重建) |
| LazyGit | 既有版本 >= 0.64.0 → formula 管理時定向升級 Homebrew → Linux 經 checksum 驗證的官方 release 到 /usr/local/bin → 使用者 fallback 到 ~/.local/bin(同時處理 macOS 非 brew/PATH shadow) |
| base/devtools/networking_tools 中大多數 Linux CLI | apt/yum(sudo)→ 使用者層級 GitHub release musl tarball 到 ~/.local/bin。部分有架構專屬 brew-on-aarch64 分支(eza、git-delta) |
| Rust (mise) | 設定的 mirror → 官方 static.rust-lang.org → 在 oldEL 上:直接 rustup-init |
Cursor .deb (Linux) |
get_url 配 retries=4(大檔,GFW-prone)— 單一機制但重試多次 |
| Bitwarden Desktop (Linux) | snap → .deb fallback |
| CodexBar / td / sidecar / RTK / specstory / llmfit | Linuxbrew → GitHub release tarball |
| Tasks 工具組 (Linux) | 完整既有安裝 → Linuxbrew marcus/tap/tasks → checksum 驗證的 amd64/arm64 release,將三個 binary 安裝到 ~/.local/bin |
| uv (升級端) | 檢查 binary 路徑 → brew upgrade uv 或 uv self update |
| Discord (Linux) | flatpak(預設)→ .deb(由 discordChannel 選) |
| tree-sitter-cli (Linux) | mise exec -- npm install -g tree-sitter-cli(timeout 180)→ cargo install tree-sitter-cli(先裝 libclang-dev) |
| Antigravity installer | curl → 中途 sed patch 注入 --skip-path --skip-aliases → bash(避開 profile 改寫) |
| just | macOS brew → Linux:廠商 curl install.sh 配 sudo → 使用者層級 --bin-dir ~/.local/bin fallback |
為什麼要 fallback:noRoot Linux 主機、RHEL/CentOS 7(glibc 2.17、 沒現代 bottle、超老 zsh)、沒有合適 Homebrew bottle 的 macOS 組態、 中國鏡像中斷。
覆蓋落差 (install-only,沒有自動化升級)¶
chezmoi apply 會裝但沒有 upgrade_tools.sh 類別會刷新的工具。
這些工具一旦安裝就停在當時的版本,除非手動移除重裝。
| 類別 | 為什麼沒升級 | 如何刷新 |
|---|---|---|
| GitHub-release 使用者層級 fallback(~30 個工具 — 見 § 11) | creates: 守衛讓 ansible 永遠不重下 |
rm ~/.local/bin/<tool> 後 chezmoi apply |
| Tasks Linux release 工具組 | 完整工具組 guard 維持 install-only;沒有自動 release 升級 category | 驗證指定 release checksum,成組替換三個 binary;見 Tasks 升級。Brew 安裝仍走 just upgrade-brew |
| Debian 上的廠商 apt-repo 套件(terraform、azure-cli、vscode、opentofu、ngrok、PPA 的 lazygit) | 依賴本 repo 流程外的 sudo apt upgrade |
sudo apt update && sudo apt upgrade(非 chezmoi 的職責) |
| Docker 便利腳本安裝 | 沒有升級目標 | 重跑 curl get.docker.com \| sh |
| OrbStack | macOS brew cask | 由 cat_brew --cask --greedy 涵蓋 |
Cursor .deb / Discord .deb / VSCode (Microsoft apt) |
apt 端,不是 chezmoi 端 | apt 升級 |
| Zen Browser AppImage / AppImageLauncher Lite | 一次性下載;Zen 的守衛用 glob zen*.AppImage(AppImageLauncher 會把整合過的改名) |
刪掉所有 ~/Applications/zen*.AppImage 後重 apply |
| Hack Nerd Font | latest URL,沒追版本 |
刪字型目錄後重 apply |
| fontconfig / libfuse2 / libnotify-bin / playerctl / wmctrl / xdotool / wl-clipboard / xclip / xsel | 系統套件,沒升級自動化 | apt 升級 |
| auditd rules | 設定檔,不是有版本的「工具」 | 編輯 rule 模板後重 apply |
| claude-hud / LazyVim plugins / TPM plugins / pre-commit / tldr cache / gh extensions | 被 cat_plugins 涵蓋 |
just upgrade-plugins |
為什麼這很重要:在 Linux 主機上跑 just upgrade-all 的開發者拿到
brew + mise + uv + npm + cargo + dotnet + gem + flatpak + agents +
plugins 的推進。但 ~30 個 GitHub-release-installed CLI(其中很多廣泛
使用:ripgrep、fd、jq、git-delta、lazygit 等)永遠釘在安裝時間。
這部分被以下事實部分緩解:
- 這些工具在 macOS 上通常走 brew,而
cat_brew涵蓋;Neovim 與 LazyGit 有狹義的最低版本 release fallback - 非 noRoot Linux 上,發行版套件可以在 repo 流程外被 apt 升級
- 落差在 noRoot Linux 上最尖銳,因為 GitHub releases 是唯一安裝 路徑,而且沒有升級自動化
cat_agents 上的覆蓋落差:只有 claude / opencode / pi / omp /
cursor-agent / ollama / llmfit / rtk / specstory 有明確受 guard 的
agent-specific 升級路徑。
漏掉:agy(Antigravity)、codexbar、td、sidecar、
specify-cli、openchamber、codex — 這些依賴 brew / uv / npm
類別。
backlog 追蹤:還沒有正式條目,但在 scripts/upgrade_tools.sh
加一個 releases 類別(稽核已安裝 binary 對最新 GitHub tag,提示
是否刷新)會關閉這個落差。當前類別清單見
upgrades.md。
工具索引 (A–Z)¶
字母序查詢。對於有多條安裝路徑的工具,第一條為主要路徑;其餘以
/分隔列在同一格內。自動產生 — 請勿手動編輯此表。 單一真實來源是
dot_config/docs/tools/tool-catalog.toml(同時記錄每個工具的分類、一行說明與 init prompt gate)。修改後執行just gen-tool-index;表格內容與英文版相同(不另行翻譯,避免漂移)。 想互動瀏覽並看本機安裝狀態,用tv inventory。
| Tool | macOS | Linux | Role |
|---|---|---|---|
| actionlint | brew | Linuxbrew (best-effort) | devtools |
| aerospace | brew cask (nikitabobko/tap) |
n/a | Brewfile.darwin |
| agy / agyc (Antigravity CLI) | curl antigravity.google/cli/install.sh |
same | coding_agents |
| alacritty | brew cask | cargo build (apt deps) | Brewfile.darwin / gui_apps_linux |
| alt-tab | brew cask | n/a | Brewfile.darwin |
| anki | brew cask | n/a | Brewfile.darwin |
| ansible-core | uv tool install | uv tool install | bootstrap |
| antigravity (IDE) | brew cask | placeholder | Brewfile.darwin |
| AppImageLauncher | n/a | PPA → GitHub .deb → Lite AppImage |
gui_apps_linux |
| applite | brew cask | n/a | Brewfile.darwin |
| apprise | uv tool | uv tool | python_uv_tools |
| arc | brew cask | n/a | Brewfile.darwin |
| arp-scan | brew | apt/yum | networking_tools |
| atuin | brew | curl setup.atuin.sh |
atuin |
| azure-cli | brew | Microsoft apt repo → uv tool fallback | iac_tools |
azure-cost-cli (azure-cost) |
dotnet tool install --global |
same | dotnet_tools |
| bandwhich | brew | GitHub release musl | networking_tools |
| bash (5.x) | brew (when primary_shell="bash") |
system | bash |
| bat | brew | apt + /usr/bin/bat symlink → GitHub musl |
base/devtools |
| bats-core | brew | apt → GitHub install.sh |
devtools |
Bitwarden CLI (bw) |
mise exec -- npm install -g @bitwarden/cli |
same | bitwarden |
| Bitwarden Desktop | brew cask | snap → .deb |
bitwarden |
| btop | brew | apt → GitHub release | devtools |
| build-essential | n/a | apt | bootstrap (Linux) |
| bun | mise | mise | mise |
calibre (ebook-meta) |
brew cask — opt-in installCalibre |
apt (calibre) — opt-in |
devtools — backs Kindle .mobi/.azw/.azw3 metadata previews in yazi via view-ebook. See yazi-previews.md |
| cargo-update | cargo install (bootstrap for cat_cargo) |
same | rust_cargo_tools |
| chafa | brew | apt (chafa) |
devtools — yazi image-display fallback (unicode-art); backs all image/pdf/video/heic previews. Shadowed by a --probe off shim (dot_dotfiles/bin/executable_chafa) to stop the OSC-query→rename-popup leak. See yazi-previews.md |
| chatgpt | brew cask (Intel + Apple Silicon; includes Codex) | n/a | Brewfile.darwin |
| Claude (desktop) | brew cask claude |
n/a | Brewfile.darwin |
| Claude Code | brew cask claude-code |
curl claude.ai/install.sh → ~/.claude/local/bin/claude |
coding_agents |
| claude-hud | python helper run from role | same | coding_agents |
| cloudflared | brew | GitHub .deb/binary / .rpm |
networking_tools (tunnel) |
| CMux | brew cask | n/a | Brewfile.darwin |
| CodeIsland | brew cask (wxtsky/tap) |
n/a | Brewfile.darwin |
| codex (OpenAI Codex CLI) | brew cask codex |
mise exec -- npm install -g @openai/codex |
coding_agents |
| CodexBar | brew cask codexbar (homebrew-cask core) |
Linuxbrew steipete/tap/codexbar → GitHub release; static-musl asset (and no Linuxbrew) when glibc < 2.38 |
coding_agents |
| copyparty | uv tool | uv tool | python_uv_tools |
| CopyQ | n/a | apt | gui_apps_linux |
| coreutils | brew | (GNU coreutils via apt; macOS gets via brew) | devtools |
| curl | system | apt/yum | base + bootstrap |
| cursor (IDE) | brew cask | .deb from cursor.com/api/download |
Brewfile.darwin / gui_apps_linux |
| cursor-agent (CLI) | curl cursor.com/install |
same | coding_agents |
| dasel | brew | release | devtools |
| dbeaver-community | brew cask | n/a | Brewfile.darwin |
dev-cli (dev) |
brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Repository/task/worktree dashboard; binary dev. |
| dev-projects | chezmoi (dot_dotfiles/bin/executable_dev-projects, Python stdlib) |
same | in-house |
| diffnav | brew | GitHub release | devtools |
| direnv | brew | apt or curl-installer | devtools |
| discord | brew cask | flatpak (default) / .deb |
Brewfile.darwin / gui_apps_linux |
| docker | brew cask orbstack |
curl get.docker.com rootless |
docker |
| doggo | brew | GitHub release | networking_tools |
| dotenv (python-dotenv[cli]) | uv tool | uv tool | python_uv_tools |
| dotnet | mise (10, isolated) |
mise (10, isolated) |
mise |
| doxx | brew (homebrew-core) | GitHub release .tar.xz |
devtools |
| duckdb | brew | GitHub release | devtools |
| duckdb.yazi | ya pkg (Yazi plugin) |
ya pkg |
devtools (yazi) |
| ethtool | n/a | apt / yum (ethtool) |
wake_on_lan |
| exiftool | brew | apt (libimage-exiftool-perl) |
media_tools |
exp-cli (exp) |
brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Research workflow CLI and overview; binary exp. |
| eza | brew | gierens.de apt repo → GitHub musl → brew aarch64 | devtools |
| fastfetch | brew | (Linux release if added) | devtools |
| fd | brew | apt (fd-find + symlink) → GitHub release |
base |
| ffmpeg | brew | apt | media_tools |
| ffmpeg-full | brew (keg-only) | — (Debian ffmpeg already links libass) | media_tools |
| figlet | brew | (apt likely) | devtools |
| font-hack-nerd-font | brew cask | GitHub release Hack.zip → ~/.local/share/fonts |
nerdfonts |
| fontconfig | (system) | apt/yum | nerdfonts |
| freeze | brew | GitHub release | devtools |
| fzf | brew (via lazyvim_deps) |
chezmoi external + ~/.fzf/install --bin |
lazyvim_deps + externals |
| gawk | brew | apt/yum | bash |
| gcc / gcc-c++ / make | (Xcode CLT) | apt (build-essential) / yum |
base + bootstrap |
| gemini (Gemini CLI) | brew formula gemini-cli → npm fallback |
mise exec -- npm install -g @google/gemini-cli |
coding_agents |
| gh | brew | vendor apt (.deb) → GitHub tarball | base/devtools |
| gh-dash | gh extension install dlvhdr/gh-dash |
same | devtools |
| gh-notify | gh extension install meiji163/gh-notify |
same | devtools |
| gh-select | gh extension install remcostoeten/gh-select |
same | devtools |
| ghostty | brew cask (installBrewApps) |
native apt → Ubuntu 24.04 community PPA → classic Snap | GUI profile only; sudo + x64/arm64 on Linux. See Ghostty |
| git | brew | apt/yum | base |
| git-delta | brew | .deb (x86_64) → brew aarch64 → GitHub musl user |
devtools |
| git-filter-repo | uv tool | uv tool | python_uv_tools |
| git-graph | brew | GitHub release (x86_64 only) | devtools |
| git-lfs | brew | apt/yum → GitHub release | base |
| git.yazi | ya pkg (Yazi plugin) |
ya pkg |
devtools (yazi) |
github-copilot-cli (@githubnext/github-copilot-cli) |
npm global | mise exec -- npm install -g |
coding_agents |
| gitleaks | brew | GitHub release | security_tools |
| glab | brew | vendor apt (.deb) → GitHub tarball | devtools |
| glow | brew | GitHub release tarball | devtools |
| go | mise (go = "latest") |
same (mise) | mise (installExtraRuntimes) |
| google-chrome-stable | (Brewfile cask territory) | .deb from dl.google.com; postinst self-registers the apt repo, so apt upgrade maintains it. x86_64 only — no arm64 Linux build exists |
gui_apps_linux — a Chromium-engine backup browser; Ubuntu has no Chromium .deb, only a snap shim |
| google-drive | brew cask | n/a | Brewfile.darwin |
| gopls | brew | go install (go_tools) |
Go language server for Claude Code's official gopls-lsp plugin |
| gping | brew | GitHub release musl | networking_tools |
| grammarly-desktop | brew cask | n/a | Brewfile.darwin |
| grc | brew | apt | devtools |
| gum | brew | GitHub release | devtools |
| herdr | GitHub release single binary → ~/.local/bin/herdr (not brew — see note) |
GitHub release single binary → ~/.local/bin/herdr |
devtools · upgrade: just upgrade-herdr (herdr update --handoff, must run outside herdr) |
| herdr-gpui | penso/tap/herdr-gpui cask; macOS 14.2+ | SHA-256 verified stable .deb; glibc 2.39+, x64/arm64, sudo | GUI bundle; apply installs missing copies only |
| herdr-plus (herdr plugin) | herdr plugin install cloudmanic/herdr-plus (prebuilt binary when no Go; idempotent ansible task) |
same | devtools |
| Homebrew | curl installer | same (Linux, gated) | bootstrap |
| htop | brew | apt | devtools |
| httpie | brew | apt (Debian) | networking_tools |
| imagemagick | brew | apt | media_tools |
input methods (mcbopomofo, squirrel) |
brew cask | (Debian) apt ibus-rime |
input_method |
| iperf3 | brew | apt/yum | networking_tools |
| ipmitool | n/a | apt/yum (gated on BMC detected) | homelab_tools |
| jnv | brew | release | devtools |
| jq | brew | apt/yum → GitHub release | base |
jupyterlab (jupyter-lab) |
uv tool (with notebook, ipykernel, etc.) | uv tool | python_uv_tools |
| just | curl just.systems/install.sh (always) |
same | base |
| lazyansible | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Ansible inventory/playbook workspace; personal fork. |
| lazychezmoi | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Chezmoi state, diff, edit and apply TUI. |
| lazyclash | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Mihomo CLI/TUI and guarded proxy shell integration. |
| lazycrontab | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Local/SSH cron inspection, schedules and reviewed edits. |
| lazyfind | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Local/SSH file and text search with result actions. |
| lazygit | brew → official release fallback (minimum 0.64.0) | stale PPA purge → brew detection → official system/user release (minimum 0.64.0) | lazyvim_deps |
| lazymermaid | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Mermaid repository workbench with optional Neovim and renderers. |
| lazymlflow | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — MLflow experiments, runs and artifact inspection. |
| lazypkg | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Software inventory and reviewed package-manager operations. |
| lazypueue | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Pueue task/queue dashboard. |
| lazyset | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Local/SSH TUI catalog and retained-session workspace. |
| libfuse2 | n/a | apt | gui_apps_linux |
| libnotify-bin | n/a | apt (Debian) | coding_agents |
libreoffice (soffice) |
brew cask | apt (libreoffice-writer/calc/impress, no-recommends) |
devtools |
| liquidctl | n/a | apt/yum (gated on a USB cooler / telemetry PSU detected) | homelab_tools |
litellm[proxy] (litellm) |
uv tool (python 3.13) | uv tool | llm_tools |
| llmfit | brew formula | curl llmfit.axjns.dev/install.sh |
llm_tools |
lm-sensors (sensors) |
n/a | apt/yum (lm-sensors/lm_sensors) |
homelab_tools |
| lnav | brew | apt/release | devtools |
| lolcat | brew | (apt) | devtools |
| maccy | brew cask | n/a | Brewfile.darwin |
| marimo | uv tool ([recommended,mcp]) |
uv tool | python_uv_tools |
markitdown ([docx,xlsx,pptx]) |
uv tool | uv tool | python_uv_tools |
| mas | brew (shared Brewfile, macOS only) | n/a | Brewfile.tmpl |
| micro | brew | apt / verified user-level release (no-root, RedHat) | devtools; editorcfg, just upgrade-micro for release installs |
| mise | curl mise.run |
curl mise.run → direct binary → musl variant |
bootstrap |
| mlflow | uv tool | uv tool | python_uv_tools |
| models | brew formula | Linuxbrew → cargo modelsdev |
llm_tools |
mole (mo) |
brew formula, gated on installMole |
n/a — macOS-only upstream | Brewfile.tmpl |
| mosh | brew | apt | devtools |
| mtr | brew | apt/yum | networking_tools |
| neovim | healthy install → Apple Silicon brew (state: present) → official release; Intel official release when needed |
apt → GitHub release → user → oldEL fork | neovim |
| ngrok | brew cask | vendor apt repo → user tgz / RedHat tgz | networking_tools (tunnel) |
| nmap | brew | apt/yum | networking_tools |
| node | brew (via lazyvim_deps) |
mise | mise + lazyvim_deps |
| nowplaying-cli | brew (gated installMediaControl) |
n/a | media_control |
nvme-cli (nvme) |
n/a | apt/yum (gated on NVMe detected) | homelab_tools |
| obsidian | brew cask | n/a | Brewfile.darwin |
| ollama | brew formula ollama (CLI) + cask ollama-app (GUI) |
curl ollama.com/install.sh |
llm_tools |
| omp (Oh My Pi) | curl omp.sh/install --binary → ~/.local/bin/omp |
same | coding_agents |
openchamber (@openchamber/web) |
npm global | mise exec -- npm install -g |
coding_agents |
| opencode | curl opencode.ai/install (--no-modify-path) → ~/.opencode/bin/opencode |
same | coding_agents |
| opencode-desktop | brew cask | n/a | Brewfile.darwin |
opentofu (tofu) |
brew formula | Cloudsmith apt repo → GitHub release | iac_tools |
| OrbStack | brew cask | n/a | docker |
| pandoc | brew | apt | devtools |
peon-ping (peon) |
brew tap PeonPing/tap (needs brew trust, Homebrew 6 gate) |
install.sh --openpeon --no-rc |
coding_agents — agent completion sounds; never run peon-ping-setup (hooks are declared in dot_claude/modify_settings.json.tmpl). Gated by the agentSounds prompt. See agent-sounds.md |
| pi | mise exec -- npm install -g --ignore-scripts --prefix ~/.local @earendil-works/pi-coding-agent |
same | coding_agents |
| pia | chezmoi external ~/.local/share/pi-agents/bin/pia |
same | .chezmoiexternal.toml.tmpl (installCodingAgents) |
| piper.yazi | ya pkg (Yazi plugin) |
ya pkg |
devtools (yazi) |
| playerctl / wmctrl / xdotool | n/a (playerctl: brew via media_control) | apt | gui_apps_linux; playerctl also via media_control (gated installMediaControl, backs sysplay/sysnow) |
playwright-cli (@playwright/cli) |
mise npm | mise npm (supported Debian/Ubuntu x64/arm64) | devtools, installPlaywrightCli; package skills refreshed on apply / upgrade-npm, Chromium preloading opt-in. See browser-tools |
poppler (pdftoppm) |
brew | apt (poppler-utils) |
devtools — yazi PDF preview. See yazi-previews.md |
| pre-commit | uv tool install --python 3.13 |
same | security_tools |
| prettier | Mason (Neovim-local) | Mason (Neovim-local) | LazyVim ensure_installed; Conform prefers project-local node_modules/.bin/prettier |
| procps | (system) | apt | bootstrap (Linux) |
| pueue | brew formula | cargo install pueue --locked + systemd user unit |
rust_cargo_tools |
| raycast | brew cask | n/a | Brewfile.darwin |
| rclone | brew | official installer or GitHub | devtools — macOS rclone mount also needs macFUSE (5.x on macOS 26+), manual & not repo-managed (reboot + GUI approval); brew rclone ≥1.73 already ships mount so the binary isn't the blocker (pitfall) |
readability-cli (readable) |
npm global | mise exec -- npm install -g |
js_cli_tools |
| recon | cargo install (git source) | same | rust_cargo_tools |
| resilio-sync | brew cask (GUI app) | Resilio apt repo → headless daemon + WebUI (per-user systemd service) | resilio_sync |
| resvg | brew | Linuxbrew → cargo install resvg (no apt pkg; non-fatal if absent) |
devtools — yazi SVG preview. See yazi-previews.md |
| ripgrep | brew | apt/yum → GitHub release | base |
| rsync | brew | apt / yum (usually preinstalled) | base — replaces macOS's built-in openrsync 2.6.9 (no --info etc.); brew rsync 3.x lands in brew's bin (/opt/homebrew/bin Apple Silicon, /usr/local/bin Intel) ahead of /usr/bin on PATH |
| ruby | mise | mise (skipped in noRoot) | mise |
| rust | mise | mise → rustup-init → static.rust-lang.org fallback |
mise + rust_cargo_tools |
| rustscan | brew | GitHub release | networking_tools |
| scroll-reverser | brew cask | n/a | Brewfile.darwin |
| sesh | brew | GitHub release | devtools |
sevenzip (7-Zip; 7zz / 7z) |
brew (sevenzip) |
apt (p7zip-full) |
devtools — yazi archive + dmg listing. See yazi-previews.md |
| shellcheck / shfmt | brew | apt or release | devtools |
| sidecar | brew tap marcus/tap |
Linuxbrew → GitHub release | coding_agents |
| skopeo | brew | apt (universe) |
devtools — client-side registry copy; rung 3 of docker-net pull. See docker-net.md |
smartmontools (smartctl) |
n/a | apt/yum | homelab_tools |
| specify-cli | uv tool install from git |
same | coding_agents |
| specstory | brew tap specstoryai/tap → GitHub release |
GitHub release tarball | coding_agents |
| speedtest (Ookla) | brew (tap teamookla/speedtest) |
install.speedtest.net |
networking_tools |
| spotify | brew cask | n/a | Brewfile.darwin |
| sqlit-tui[ssh] | uv tool | uv tool | python_uv_tools |
| starship | brew | curl starship.rs/install.sh |
starship |
| steam | brew cask (gated by installGamingApps) |
Valve apt repo (steam-launcher, x86_64, gated by installGamingApps) |
Brewfile.darwin / gui_apps_linux |
| storcli | n/a | vendor/mirror download to ~/.local/bin (gated on RAID controller detected + homelab_storcli_url; not in distro repos) |
homelab_tools |
| summarize | brew (gated installSummarize) |
mise exec -- npm install -g @steipete/summarize (Node 24+; skipped on oldEL) |
summarize — see summarize.md |
| super-productivity | brew cask | n/a | Brewfile.darwin |
| superfile | brew | installer/release | devtools |
| superset | brew cask (arm64) | n/a | Brewfile.darwin |
switchaudio-osx (SwitchAudioSource) |
brew (gated installMediaControl) |
n/a | media_control |
| tailscale (CLI) | via the tailscale-app cask wrapper (/usr/local/bin/tailscale → app; no formula) |
apt/yum from pkgs.tailscale.com (networking_tools role, tailscale tag, gated on installTailscale) |
Brewfile.darwin / networking_tools |
| tailscale-app | brew cask (pkg also installs the /usr/local/bin/tailscale CLI wrapper) |
n/a | Brewfile.darwin |
tailspin (tspin) |
brew | release | devtools |
| taplo | brew | apt+release | devtools |
Tasks (tasks / tasks-tui / tasks-api) |
brew (marcus/tap/tasks) |
Linuxbrew → verified GitHub release | coding_agents — all three binaries; user-owned XDG data/config. See tasks.md |
| td | brew tap marcus/tap |
Linuxbrew → GitHub release | coding_agents |
television (tv) |
brew | apt+release | devtools |
| terminal-browser | brew cask | checksum-verified upstream stable release (supported Debian/Ubuntu x64/arm64) | devtools, installTerminalBrowser; package skills, upgrade-brew / upgrade-terminal-browser. See browser-tools |
| terminal-notifier | brew | n/a | coding_agents (macOS) |
| terraform | brew (hashicorp/tap) |
HashiCorp apt repo → user zip | iac_tools |
| the-unarchiver | brew cask | n/a | Brewfile.darwin |
| thefuck | brew | uv tool (python 3.11 distutils) | devtools |
| tldr | (macOS uses tlrc via brew) |
system npm or mise exec -- npm install -g tldr |
devtools |
| tlrc | brew | (Linux uses tldr npm instead) |
devtools |
| tmux | brew | apt → tmux-appimage when < 3.3 | devtools |
| tmuxinator | gem | gem | ruby_gem_tools |
| tmuxp | uv tool | uv tool | python_uv_tools |
| toilet | brew | (apt) | devtools |
| tokens | brew tap owo-network/brew (trusted) |
GitHub release → ~/.local/bin (no systemd unit) |
coding_agents |
| trafilatura | uv tool | uv tool | python_uv_tools |
| translate | brew (daviddwlee84/tap) |
Verified GitHub release; legacy Go preserved | personal_tools — Terminal translation CLI/TUI. |
| tree | brew | apt/yum | base |
| tree-sitter / tree-sitter-cli | brew | mise-npm → cargo fallback | lazyvim_deps |
trippy (trip) |
brew | apt/release | networking_tools |
try-cli (try) |
gem | gem | ruby_gem_tools |
| tsnet | chezmoi (dot_dotfiles/bin/executable_tsnet, uv PEP-723 script) |
same | in-house — tailnet → ssh config, tailnet-HTTPS serve |
| uv | curl astral.sh/uv/install.sh |
same | bootstrap; python_uv_tools self-upgrade dispatch |
| vhs | brew | GitHub release | devtools |
| vips | brew | apt (libvips-tools) |
media_tools |
visidata (vd) |
uv tool (with pandas, pyarrow) | uv tool | python_uv_tools |
| visual-studio-code | brew cask | Microsoft apt repo | Brewfile.darwin / gui_apps_linux |
| wakeonlan | brew | apt (wakeonlan) |
networking_tools |
| warp | brew cask | n/a | Brewfile.darwin |
| wget | brew | apt/yum | base |
| witr | brew | (release) | devtools |
wl-clipboard (wl-copy/wl-paste) |
n/a (pbcopy built-in) |
apt | gui_apps_linux — Wayland clipboard backend for Neovim yank, lazygit Ctrl+O, x copy. See clipboard.md |
| workmux | brew (tap raine/workmux) |
GitHub release .tar.gz |
devtools |
| worktrunk | brew | GitHub release | devtools |
| xclip | n/a (pbcopy built-in) |
apt | gui_apps_linux — X11/XWayland clipboard backend (same consumers as wl-clipboard) |
| xonsh | uv tool (with xontribs) | uv tool | python_uv_tools |
| xsel | n/a (pbcopy built-in) |
apt | gui_apps_linux — X11 clipboard backend; last non-OSC-52 fallback in x, named in lazygit's error text |
| yazi | brew | Linuxbrew/GitHub release | devtools |
| yq | brew | release | devtools |
| yt-dlp | uv tool ([default] + yt-dlp-ejs) |
uv tool ([default] + yt-dlp-ejs) |
python_uv_tools |
| zellij | brew | GitHub release | devtools |
| Zen Browser | n/a | GitHub release AppImage → ~/Applications/zen.AppImage, thereafter matched by glob zen*.AppImage |
gui_apps_linux |
| zoxide | brew | curl official installer | devtools |
| zsh | brew | apt/yum / source build (RHEL 7) | zsh |
未列出的工具:
oh-my-zsh、oh-my-bash、zsh-autosuggestions、zsh-syntax-highlighting、zsh-completions、zsh-vi-mode、ble.sh、TPM、pi-agents、toolkami.rb— 這些以 chezmoi externals 形式存在 (§ 12),不是「PATH 上的 binary」。
新增工具決策樹¶
工具需要在 ansible 跑之前就存在嗎?
├── 是 → Bootstrap 腳本(run_once_before_*)— 僅在絕對必要時
└── 否 → 繼續
它是 runtime / 語言直譯器(node、ruby、python、rust、go、dotnet)?
├── 是 → mise(dot_config/mise/config.toml.tmpl)— 除了 python(用 uv)
└── 否 → 繼續
是 Python CLI 工具嗎?
├── 是 → uv(附加到 python_uv_tools/defaults/main.yml)
│ · LLM 相關走 llm_tools/defaults/main.yml
│ · 需要 gcc ≥ 9?設 needs_modern_gcc: true
│ · 會寫伴隨 binary?同時設 with_executables_from 與 extra_binaries
└── 否 → 繼續
是 Node/JS CLI 工具嗎?
├── 是 → npm 透過 mise(附加到 js_cli_tools/defaults/main.yml)
│ · Agent CLI?改寫到 coding_agents/tasks/main.yml
└── 否 → 繼續
是 crates.io 上發佈良好的 Rust crate?
├── 是 → cargo(rust_cargo_tools/defaults/main.yml cargo_tools 條目)
│ · 需要編譯依賴或 git-source?在 tasks/main.yml 中 hard-code
└── 否 → 繼續
是 Ruby gem?
├── 是 → gem(ruby_gem_tools/defaults/main.yml)
│ · noRoot Linux 上自動跳過
└── 否 → 繼續
是 .NET 全域工具?
├── 是 → dotnet tool(dotnet_tools/defaults/main.yml)
└── 否 → 繼續
工具是 coding agent CLI(廠商出貨、有自己的 installer)?
├── 是 → curl-installer 寫進 coding_agents/tasks/main.yml
│ · 對齊現有模式(Claude / OpenCode / Cursor)
│ · 傳 --no-modify-path 或對等(別改 shell rc)
│ · 加進 scripts/upgrade_tools.sh 的 cat_agents
│ · 更新 AICAP SSOT(dot_config/shell/04_ai_agents.sh)+
│ 四個 Python AGENT_CONFIG dict(見 AGENTS.md hard invariant)
└── 否 → 繼續
是 macOS 出貨的 GUI app?
├── 是 → brew cask 寫進 Brewfile.darwin.tmpl
│ · AI 類用 installAiDesktopApps 控管
└── 否 → 繼續
是 macOS 出貨的 CLI?
├── 是 → brew formula 寫進相關 role 的 tasks/main.yml
│ · 在同 role 加 Linux fallback(apt 或 GitHub release)
│ · 考慮是否 macOS-only 就好(例如 terminal-notifier)
└── 否 → 繼續
是 Linux-only、發行版打包?
├── 是 → apt / yum 寫進相關 role 的 tasks/main.yml
│ · become: true + tags: [sudo]
│ · 為 noRoot 加使用者層級 GitHub-release fallback
└── 否 → 繼續
是 Linux-only、廠商出貨(有自己的 install.sh)?
├── 是 → curl-installer 寫進相關 role
│ · 用 creates: 守衛
│ · 如果 binary 落在 ~/.local/bin 以外,在
│ dot_config/shell/00_exports.sh.tmpl 加 PATH 前置;若必須蓋過
│ 後面的 mise/Bun/package-manager 路徑,則用更後面的編號共用
│ fragment(例如 08_pi_agents.sh.tmpl)
└── 否 → 繼續
GitHub release tarball(其他一切的最可靠路徑):
└── 從 devtools/tasks/main.yml 複製標準模式
· block: + rescue:(廠商會出包)
· 在 get_url 上 retries: 3, delay: 5, timeout: 120
· 透過 target_architecture 計算架構
· 解壓到 ~/.local/bin(使用者)或 /usr/local/bin(sudo + tags: [sudo])
· ⚠️ 這個 binary 不會被自動升級(見 § 覆蓋落差)
新增工具時其他要做的事:
- 工具若出貨 shell completion(
<tool> completion zsh|bash), 在scripts/generate_completions.sh加一條regenrow(按 AGENTS.md cross-file rule) - 若工具是新的自家 CLI(自製,在
dot_dotfiles/bin/),按docs/zsh/zsh-completions.mdSection F 的 completion 決策流程做 (兩份手寫 completion 檔 + Section F 表格的 row +docs/shells/aliases.md的 row) - 若工具有特殊的升級故事(self-update 子命令等),在
upgrades.md加類別或擴充既有類別 - 若工具取代了另一個工具,把舊路徑加到
.chezmoiremove - 若工具是新的 alias / shell function,在
docs/shells/aliases.md加一條 row (按 AGENTS.md cross-file rule)
交叉參考¶
其他相關文件:
upgrades.md— 升級面參考(本文是安裝面)architecture.md— Repo 布局 + 安裝流程階段bootstrap.md— Bootstrap 腳本深度說明uv-bootstrap.md— 為什麼 uv 很特別ansible_customization.md— 每主機 ansible 變數覆蓋config-conventions.md— 部署的設定檔住在哪testing.md— 如何驗證工具裝對了
相關的 AGENTS.md hard invariants:
- "Install vs upgrade is split on purpose" — 永遠不要
state: latest - "
with_executables_from:entries MUST also declareextra_binaries:" - "primaryShell choice gates
chshonly — both shells always deploy" - "AI agent autodetect order or AICAP_*_MODEL defaults" — 只編輯
04_ai_agents.sh - "Tmux ≥ 3.3 required" — 見 § 多機制工具 的
tmux條目
與安裝路徑相關的過往 pitfall:
uv-self-update-homebrew-noop.md— uv 為何需要 brew-vs-curl 分派uv-tool-install-creates-guard-misses-executables-from.md—extra_binaries:必要性ansible-js-cli-tools-old-system-node.md— Linux 上 npm 為何走 miseansible-missing-sudo-tag.md—tags: [sudo]慣例centos7-neovim-apt-register-defined.md— neovim user-fallback gate bugtmux-appimage-terminfo-not-found.md— tmux-appimage 注意事項opencode-docker-opentui-glibc-loader-missing.md— opencode 容器變體chezmoi-update-blesh-local-changes-overwritten.md— 後置 hook 改動工作樹時 externals 會漂移
與安裝路徑相關的 backlog 條目:
mise-runtime-gating.md— 細粒度的每主機 runtime 控管devtools-role-split.md— 拆開巨型 rolelean-bundle-init-ux.md— bundle 預設 + 決策樹 SSOTopencodebox-wrapper.md— 容器化 opencode wrapper