CLI 工具的配置目录别乱放——从 Claude Code 的做法说起

2026-06-02 22 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

装完一个命令行工具,想改下配置,结果 find ~ -name settings.json 跑了半分钟才定位到文件——这种体验你一定遇到过。前两天我装了个朋友写的 AI 编辑器 CLI,npm 全局安装,跑起来没问题,顺手翻配置才发现它把文件写到了 ~/Library/Application Support/vibecoding/settings.json。一个命令行工具,配置藏在 macOS GUI 应用的专属目录里,ls ~ 根本看不见。

反观 Claude Code,配置一目了然:~/.claude/,干净、直观、符合 CLI 工具的惯例。这看似是个小细节,但对日常使用和自动化脚本的影响很大。

配置放哪,不是随便决定的

CLI 工具的配置路径选择,背后有三条主流惯例:

惯例 路径示例 适用场景
Unix 传统 ~/.claude/ 简单直接,一个目录搞定
XDG 规范 ~/.config/claude/ 与其他工具统一管理,支持 $XDG_CONFIG_HOME
macOS GUI 惯例 ~/Library/Application Support/Claude/ macOS 图形应用,CLI 不该用

Claude Code 选了第一条,~/.claude/。好处很明显:

  • ls -a ~ 一眼就能看到
  • rm -rf ~/.claude 一条命令清干净
  • shell 脚本里 ~/.claude/config.json 直接拼路径,不需要处理空格和特殊字符

~/Library/Application Support/ 的问题恰好相反:路径带空格,shell 里必须加引号;目录层级深,ls ~ 看不到;更关键的是——这是 Apple 给 GUI 应用划的地盘,Finder 和系统工具会管理这个目录,CLI 工具混进去既不合规矩也不方便。

XDG 规范:更"正确"但更复杂的选择

XDG Base Directory Specification 定义了 ~/.config/ 作为配置集中存放的位置。理论上,所有 CLI 工具都应该尊重 $XDG_CONFIG_HOME,把配置放到 ~/.config/<appname>/ 下。Git、Neovim、bat 等工具已经跟进。

但现实是:大量经典工具(如 .ssh/.bashrc)仍住在 ~ 根目录,用户也习惯了 ~/.appname 的模式。Claude Code 选 ~/.claude/ 而不是 ~/.config/claude/,牺牲了一点规范一致性,换来的是更低的心智负担和更好的可发现性。

对大多数 CLI 工具来说,两种选择都合理,但有一条底线:别用平台专属的 GUI 目录

写一个靠谱的配置路径解析函数

如果你在写 Node.js CLI 工具,配置路径的解析逻辑应该考虑优先级:环境变量 > XDG 规范 > 传统路径。下面是一个可以直接用的实现:

// config-path.js — CLI 工具配置目录解析
import { homedir } from 'node:os';
import { join } from 'node:path';
import { mkdirSync } from 'node:fs';

const APP_NAME = 'mycli'; // 替换成你的工具名

/**
 * 按优先级解析配置目录:
 * 1. MYCLI_CONFIG_DIR 环境变量(允许用户强制指定)
 * 2. XDG_CONFIG_HOME/mycli(遵循 XDG 规范)
 * 3. ~/.mycli(Unix 传统,兜底方案)
 *
 * 不使用 ~/Library/Application Support,这是 macOS GUI 应用的地盘。
 */
function resolveConfigDir() {
  // 优先级 1:用户通过环境变量显式指定
  const envDir = process.env[`${APP_NAME.toUpperCase()}_CONFIG_DIR`];
  if (envDir) return envDir;

  // 优先级 2:XDG 规范
  const xdgDir = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
  const xdgAppDir = join(xdgDir, APP_NAME);
  // 如果 XDG 目录已存在,优先使用它
  try {
    mkdirSync(xdgAppDir, { recursive: true });
    return xdgAppDir;
  } catch {
    // XDG 目录不可写,降级到传统路径
  }

  // 优先级 3:传统 ~/.mycli
  const traditionalDir = join(homedir(), `.${APP_NAME}`);
  mkdirSync(traditionalDir, { recursive: true });
  return traditionalDir;
}

// 使用示例
const configDir = resolveConfigDir();
console.log(`配置目录: ${configDir}`);
// Linux/Mac 默认输出: 配置目录: /home/you/.config/mycli
// 设置环境变量后: MYCLI_CONFIG_DIR=/tmp/mycli_test node config-path.js
// 输出: 配置目录: /tmp/mycli_test

运行方式:

# 默认行为,配置落到 ~/.config/mycli
node config-path.js

# 强制指定配置目录(测试或特殊部署时有用)
MYCLI_CONFIG_DIR=/tmp/mycli_test node config-path.js

# 清理配置,一条命令搞定——不管走哪条路径都好删
rm -rf ~/.config/mycli   # XDG 路径
rm -rf ~/.mycli          # 传统路径
# 对比:如果放在 ~/Library/Application Support/mycli/
# rm -rf "$HOME/Library/Application Support/mycli"  # 空格必须加引号

关键设计点:

  • 环境变量覆盖让测试和 CI 场景干净,不用污染真实配置。
  • XDG 优先但可降级,尊重规范但不强迫用户。
  • 绝不写入 ~/Library/Application Support,CLI 工具就该走 CLI 的路。

几条实用的检查清单

下次写 CLI 工具或者审查别人的项目,可以对照这几条:

  1. 配置路径不含空格和特殊字符——~/.mycli 可以,~/Library/Application Support/mycli 不行。
  2. 支持环境变量覆盖——至少提供 APP_CONFIG_DIR 一类的变量,方便测试和临时切换。
  3. 一条 rm -rf 能清干净——用户卸载或重置时不需要到处找文件。
  4. 尊重 XDG 但不强迫——如果 ~/.config/ 已存在就用它,否则 ~/.appname 也完全可以。
  5. 跨平台一致——Linux 和 macOS 用同一套路径逻辑,Windows 上才考虑 %APPDATA%

Claude Code 的 ~/.claude/ 不是什么惊天设计,但它做到了该做到的事:用户找得到、删得掉、脚本拼路径不用处理空格。CLI 工具的配置目录不需要花哨,需要的是不给用户添麻烦


相关推荐