像 pyenv / nvm 管理语言版本一样,管理 AI Agent 的全局 skill 与仓库选择。
skillenv install 默认把 skill 安装到 ~/.agents/skills 全局 canonical store,再为 Claude Code、Codex、OpenCode 建立兼容链接。仓库用 .skillsrc 记录需要同步的 skill;merge 模式直接复用全局副本,strict 模式把选中的 skill 物化到 .agents/skills 与 .claude/skills。skillenv init/add 自动完成自身变更的信任、固定 .envrc 模板授权和同步。shell hook 会在 cd 后发现仅存在于仓库的 skill,并询问是否迁移到全局。skillenv 的管理对象是包含 SKILL.md 的 skill 目录、.skillsrc 和 skill 隔离配置。同一份声明对所有支持 Agent Skills 标准的工具生效。
单文件 bash 脚本,唯一依赖是 direnv。
Agent Skills 已统一 skill 的目录结构与 SKILL.md 格式。GitHub CLI gh skill install 提供跨 Agent 安装,支持 --scope user|project 和 Codex、Claude Code、OpenCode 等宿主,当前处于 preview,非交互默认值是 github-copilot + project。Codex 的用户级目录是 ~/.agents/skills,仓库目录是 .agents/skills;Claude Code 使用 ~/.claude/skills 与 .claude/skills。skillenv 采用相同的 skill 格式,并提供 global-first 默认值、私有 Git 源、仓库 manifest、隔离与备份能力。
# GitHub CLI 的用户级安装
gh skill install owner/repo skill-name --agent codex --scope user
# skillenv 的默认全局安装,再写入目标仓库声明
skillenv install github:owner/repo/skills/skill-name@main
cd <target-repo> && skillenv init && skillenv add skill-name把下面这句话发给你的 Claude Code / Codex:
请阅读 https://raw.githubusercontent.com/TsichiChang/skillenv/main/README.md,按其中「Agent 安装指引」一节在我的机器上安装 skillenv,完成后执行验证步骤并汇报结果。
安装完成后,若想让 Agent 把机器上已有的 skill 也管理起来,再发:
按照 skillenv README 中「Agent 接管指引」一节,盘点我本地已安装的所有 skill,给出分类建议,经我确认后完成迁移和各仓库配置。
或者手动安装:
git clone https://github.com/TsichiChang/skillenv.git ~/.skillenv/repo
ln -s ~/.skillenv/repo/skillenv /usr/local/bin/skillenv
brew install direnv
printf '%s\n' 'eval "$(direnv hook zsh)"' 'eval "$(skillenv hook zsh)"' >> ~/.zshrc
source ~/.zshrc之后升级只需 skillenv update(等价于在安装仓库里 git pull,symlink 安装下即时生效)。
本节写给执行安装的 AI Agent。按顺序执行,每步都有验证方式和失败分支。
步骤 1 — 选择 bin 目录:按顺序取第一个存在且可写的目录:/opt/homebrew/bin(Apple Silicon)→ /usr/local/bin → ~/.local/bin(若用此项,需确认其在 PATH 中,不在则追加到 shell rc)。下文称 $BIN。
步骤 2 — 安装 skillenv(git clone + symlink,保证后续可用 skillenv update 升级):
git clone https://github.com/TsichiChang/skillenv.git ~/.skillenv/repo
ln -s ~/.skillenv/repo/skillenv "$BIN/skillenv"
skillenv help # 应输出用法说明若 ~/.skillenv/repo 已存在,改为 git -C ~/.skillenv/repo pull 更新后重建 symlink。若环境无法 git clone GitHub,才退化为 curl 下载单文件(此方式升级需重新下载)。
步骤 3 — 安装 direnv:先 command -v direnv 检查,已有则跳过。首选 brew install direnv;若 brew 不可用、报错或卡住超过 2 分钟(公司网络访问 formulae.brew.sh 可能极慢),改用二进制直装:
# macOS Apple Silicon 用 darwin-arm64;Intel 用 darwin-amd64;Linux 用 linux-amd64
curl -fsSL -o "$BIN/direnv" https://github.com/direnv/direnv/releases/latest/download/direnv.darwin-arm64
chmod +x "$BIN/direnv"
direnv version # 应输出版本号步骤 4 — 挂 shell hook:检测用户 shell(echo $SHELL),检查对应 rc 文件中的 hook。按下面顺序加载,direnv 先同步仓库,skillenv 再检查项目 skill:
# zsh:~/.zshrc
eval "$(direnv hook zsh)"
eval "$(skillenv hook zsh)"
# bash:~/.bashrc
eval "$(direnv hook bash)"
eval "$(skillenv hook bash)"
# fish:~/.config/fish/config.fish
direnv hook fish | source
skillenv hook fish | source此步骤修改用户 shell 配置,执行前告知用户。已有 hook 保留一份即可。
步骤 5 — 验证安装:
command -v skillenv && command -v direnv
grep -c "direnv hook" ~/.zshrc && grep -c "skillenv hook" ~/.zshrc四项都有输出即安装完成。提醒用户:需要开新终端(或 source rc 文件)hook 才生效。
步骤 6 — 在仓库启用(可选,用户要求时执行):
cd <目标仓库>
skillenv init # 生成并自动授权固定模板
skillenv add <全局-skill-名> # 写入、信任并同步仓库自带的 .skillsrc 属于外部内容。先审阅完整文件,再运行一次 skillenv allow;该命令同时同步 skill,并自动授权固定模板 .envrc。
Agent 必须遵守的安全规则:skillenv init 与 skillenv add 只自动信任自身生成的变更,并只自动授权内容完全匹配固定模板的 .envrc。仓库自带或经其他方式修改的 .skillsrc 需要先向用户展示完整内容,再执行 skillenv allow。自定义 .envrc 继续由 direnv 的审阅流程管理。
本节写给 AI Agent:用户要求"把本地已安装的 skill 用 skillenv 管理起来"时,按以下流程执行。
步骤 1 — 盘点:在用户的常用仓库目录下运行 skillenv scan,得到全局(claude/codex/agents/opencode)与项目级 skill 的完整清单及各自的 description。对 description 缺失或截断的 skill,读它的 SKILL.md 补全理解。
步骤 2 — 分类并请用户确认:把每个 skill 归入三类,以表格形式向用户呈现建议,必须经用户确认后才能动手:
- 通用 → 全局安装:任何仓库都可能用到的(文档处理、通用工作流类);
- 领域性 → 全局安装并按仓库声明:绑定某业务域/某类项目的(判断依据:description 中出现特定业务、框架、团队名)。全局 canonical store 是
~/.agents/skills/; - 已就位 → 不动:已在各仓库
.claude/skills/等目录的手写项目级 skill。
步骤 3 — 迁移(硬性规则):
- 只
mv不rm:skill 进入~/.agents/skills/;重复副本、被淘汰的目录一律移到~/.skillenv/backup/,永不删除; - 含公司内部信息的 skill 绝不能提交/推送到公开仓库。
步骤 4 — 铺仓库配置:在每个目标仓库运行 skillenv init,再用 skillenv add <name> 把已安装的全局 skill 写入 .skillsrc。add 优先记录原始 github: / git: 来源,团队成员可从同一来源恢复;手工全局 skill 使用 skill global:<name>。disable 过滤指定继承项,isolation strict 过滤 skillenv 能识别的顶层用户级 skill,并保留仓库声明项。两者都是便利性过滤,不是安全边界。
步骤 5 — 自动信任与激活:skillenv init 和 skillenv add 会完成自身变更的信任、固定模板 .envrc 的授权与首次同步。外部修改会让 .skillsrc 回到待审阅状态;用户确认完整内容后执行一次 skillenv allow。
步骤 6 — 验证并汇报:检查 ~/.agents/skills/<name>/SKILL.md、各宿主兼容链接和仓库 .skillsrc。strict 仓库还要检查 .agents/skills/、.claude/skills/、Claude shadow,以及终端中的 command -v codex 是否指向 ~/.skillenv/shims/codex。最后汇报全局清单、仓库声明、过滤结果和备份位置。
skillenv install <source>
└─► ~/.agents/skills/<name>/ 全局 canonical copy
├─► ~/.claude/skills/<name> Claude 兼容链接
├─► ~/.codex/skills/<name> Codex 兼容链接
└─► ~/.config/opencode/skills/<name> OpenCode 兼容链接
.skillsrc(提交进 git,团队共享)
│ 进目录时 direnv 触发 skillenv activate
├─► merge:复用同源全局副本,避免同名 skill 重复出现
├─► strict:物化声明项到 .agents/skills/ 与 .claude/skills/
├─► Claude:构建 Claude-only shadow,导出 CLAUDE_CONFIG_DIR
└─► Codex:PATH 前置共享 shim,启动时注入 -c 'skills.config=[...]'
shell prompt(PWD 变化后)
└─► skillenv cd-check
├─► 扫描当前目录与 Git 根目录中的项目 skill
└─► 询问是否迁移缺失的全局副本
过滤是进程级的(只影响从该 shell 启动的 agent),不改动任何全局 skill——其他终端、其他仓库完全不受影响,离开目录时 direnv 自动恢复环境。Claude 继续使用 ~/.skillenv/shadow/<repo-hash>/claude,因为 Claude CLI 没有等价的单次启动 skill filter。
Codex 不再使用 shadow,也不会由 skillenv 设置 CODEX_HOME 或 CODEX_SQLITE_HOME。激活需要过滤时,skillenv 把共享 symlink ~/.skillenv/shims/codex 前置到 PATH,并通过 SKILLENV_CODEX_CONFIG_OVERRIDE 在真实 Codex 命令前追加一个根级参数:codex -c 'skills.config=[...]' ...。shim 从 PATH 删除自身目录后查找真实 codex,再用 exec 直接替换进程,因此 TTY、stdin/stdout/stderr、signal 与退出码保持不变。Codex 的 config、auth、sessions、logs、SQLite 与 plugins 全部留在真实或调用方自定义的 home;这也避免了 rollout canonical path 逃出 shadow home 导致的 /sidechat / thread/fork 错误。
Codex 的过滤列表是激活时快照。激活后新增或删除全局 skill、或切换 CODEX_HOME,需要运行 direnv reload(也可重新执行 eval "$(skillenv activate)")才能重建 override。需要过滤时,skillenv 要求 effective CODEX_HOME 是绝对路径;它只读取其中的顶层 skills/*/SKILL.md,不会改写该目录。
升级前版本创建的 Codex shadow 不会被复制、合并、移动或删除。若当前 shell 仍带着指向 ~/.skillenv/shadow/.../codex 的旧 CODEX_HOME,先 unset CODEX_HOME,再运行 direnv reload(或重开终端)。
迁移不需要搬动 Codex 数据:.skillsrc 与 .envrc 格式不变,config、auth、sessions、logs 和 SQLite 继续使用真实或用户自定义的 Codex home。需要迁移的只是旧终端继承的进程级环境。
-
更新 skillenv:
skillenv update
curl 单文件安装需要重新下载最新版。
-
退出已运行的 Codex。最简单的迁移方式是关闭旧终端,重新打开后进入仓库;新 shell 不会继承旧 shadow 环境。
-
若要在当前 shell 原地迁移,先检查变量:
printf 'CODEX_HOME=%s\n' "${CODEX_HOME-<unset>}" printf 'CODEX_SQLITE_HOME=%s\n' "${CODEX_SQLITE_HOME-<unset>}"
仅当
CODEX_HOME指向~/.skillenv/shadow/<repo-hash>/codex时清除它。若CODEX_SQLITE_HOME只是旧 skillenv 自动导出的默认值、而不是用户的显式配置,也一并清除:unset CODEX_HOME unset CODEX_SQLITE_HOME unset SKILLENV_CODEX_CONFIG_OVERRIDE hash -r direnv reload
没有使用 direnv 时,最后一行改为:
eval "$(skillenv activate)" hash -r
用户有意设置的绝对
CODEX_HOME/CODEX_SQLITE_HOME应保留;新版本不会改写它们。 -
验证:
skillenv status command -v codex codex --version在 strict 或 merge+disable 仓库中,
command -v codex应指向~/.skillenv/shims/codex;不需要过滤的普通 merge 仓库直接指向真实 Codex 是正常行为。每个仍继承旧环境的终端都需要 reload 或重开,从旧环境启动的 Codex 与 IDE 也需要重启。
旧 ~/.skillenv/shadow/<repo-hash>/codex 保留作审计和回退参考。若曾在 shadow 激活期间修改 Codex 配置,应比较真实 home 与 shadow 中的 config.toml,只手工迁移真实的用户配置;不要整体复制 shadow 文件,因为其中可能包含 skillenv 自动生成的 skills.config 过滤条目。确认所有终端和工具均已切换后,可自行归档旧 shadow,skillenv 不会自动处理它。
加载 skillenv hook <shell> 后,每次 PWD 变化都会运行一次 skillenv cd-check。hook 加载时会记录启动目录,让首个 prompt 直接复用当前状态。cd-check 扫描当前目录和 Git 根目录下的 .agents/skills、.claude/skills、.codex/skills、.opencode/skills。某个项目 skill 在 ~/.agents/skills 中缺失时,终端会显示:
skillenv: project skill 'globalpay-bi' is missing from the global store:
/path/to/repo/.agents/skills/globalpay-bi
skillenv: migrate it to ~/.agents/skills? The repository source stays available. [y/N]
- 输入
y:把 skill 复制到 canonical global store,并建立宿主兼容链接。手写项目目录继续保留;.skillsrc生成的重复副本按 merge 规则清理,来源声明继续保留。 - 回车或输入
n:保留项目 skill,并按“仓库路径 + skill 路径 +SKILL.md内容哈希”记录本次决定。同一内容后续保持静默;SKILL.md变化后重新询问。 - 之后主动迁移:执行
skillenv install /absolute/path/to/repo/.agents/skills/<name>。
# 管理哪些 agent:auto = 检测本机装了哪些(推荐——后续新装 agent 进目录即自动纳管)
# 也可显式指定:claude / codex / opencode / agents(通用 .agents/skills);默认 claude codex
agents auto
# merge(默认):全局 skill + 仓库 skill 叠加
# strict:过滤 skillenv 可识别的顶层用户级 skill,保留 manifest 声明项
# strict / disable 是便利性过滤,不是安全边界
isolation strict
# skill 来源:github 简写、任意 git URL(@ref 为分支或 tag),或本地路径
skill github:anthropics/skills/document-skills/pdf@main
skill git:ssh://git@dev.example.com/group/skills.git/my-skill@main # 内网/自建 git,.git 为仓库边界
skill ./skills/my-local-skill # 相对路径:相对仓库根,可随仓库提交
skill /Users/me/store/private-skill # 绝对路径:仅本机可用,勿提交进 git
skill global:my-installed-skill # 复用 ~/.agents/skills 中的手工全局 skill
# merge 模式下屏蔽某个全局 skill(按目录名)
disable some-global-skill从 marketplace 安装:skills.sh 等市场没有独立的包托管,条目背后就是 git 仓库,所以不需要专门的源类型——把 skill 页面 URL 翻译成 git 坐标即可。例如 https://skills.sh/vercel-labs/agent-skills/react-best-practices 对应 skill github:vercel-labs/agent-skills/skills/react-best-practices@main(skill 通常在仓库的 skills/ 容器目录下,装前可去仓库确认路径)。市场负责发现,清单里永远写精确的 git 坐标——间接的名字引用可能随时间易主,精确坐标才经得起 skillenv allow 的审阅。
源不可达时的行为:某个 skill 拿不到(私有仓库无权限、别人机器的绝对路径)时,activate 会警告并跳过它,其余 skill、disable 与隔离照常生效;之前已物化的拷贝保留不删。源恢复可达后,下次进目录自动补装,无需任何命令。另外两道针对绝对路径的提醒:.skillsrc 被 git 跟踪且含绝对路径源时,skillenv allow 会警告"这只在本机可解析";队友机器上解析失败的警告也会指明根因并建议改用 github: 源。
| 命令 | 作用 |
|---|---|
skillenv init |
在当前仓库生成 .skillsrc + .envrc,自动信任固定模板并调用 direnv 授权;每次运行都会刷新托管的全局 skill;有 TTY 时接着交互式复查本仓库配置 |
skillenv allow |
审阅外部修改后,信任并同步当前 .skillsrc;固定模板 .envrc 会同时自动授权 |
skillenv activate |
同步 skill 并输出 env export(由 .envrc 调用,也可手动跑) |
skillenv hook <zsh|bash|fish> |
输出目录切换 hook;记录启动目录,在 PWD 变化后的下一次 prompt 调用 cd-check |
skillenv cd-check |
扫描当前目录与 Git 根目录,询问是否把项目级 skill 迁移到全局;通常由 shell hook 调用 |
skillenv status |
查看信任状态、生效模式与当前环境 |
skillenv scan |
盘点本机所有已安装的 skill(全局 + 当前仓库项目级,含托管标记与描述) |
skillenv list |
canonical 全局清单与宿主兼容视图:来源、安装日期、描述,●=skillenv 托管 / ○=手工安装 |
skillenv install <源> [名字...] |
全局安装:写入 ~/.agents/skills canonical store,并为已检测宿主建立兼容链接。把现有宿主 skill 目录作为源时会安全接管该目录;容器源会递归发现其中所有 skill |
skillenv add <名> [...] |
把已安装的全局 skill 加入当前仓库 .skillsrc,自动更新信任并同步;托管 skill 记录原始来源,手工 skill 记录 global:<名> |
skillenv uninstall <名> |
全局卸载:移动 canonical copy 和受控兼容链接到 ~/.skillenv/backup/ |
skillenv prompt |
输出提示符用的紧凑状态(见下节),无 .skillsrc 时输出为空 |
skillenv update |
升级 skillenv 本体(git 安装则 git pull,curl 安装则重新下载) |
skillenv list 的输出形如:
◆ global ~/.agents/skills · 2 skills
├─ ● react-best-practices github:vercel-labs/agent-skills/skills/react-b… · 2026-07-11
│ React and Next.js performance optimization guidelines from Vercel…
└─ ○ pdf manual · 2026-03-06
Use when tasks involve reading, creating, or reviewing PDF files…
◆ codex compatibility ~/.codex/skills · 2 skills
init 每次运行:先刷新托管的全局 skill:跑 skillenv init 的第一步永远是遍历本机所有全局 skill 目录,对带 .managed-by-skillenv 标记的逐个按其记录的来源重新 fetch(github:/git: 来源会强制拉取远端最新提交,覆盖本地缓存)并覆盖安装;手工放置的 skill(没有标记)不受影响。不管 .skillsrc 是新建还是已存在、有没有 TTY 都会执行;单个来源刷新失败(离线、私有仓库无权限等)只警告跳过,不影响其余步骤和后续流程。这一步复用 skillenv install 同一套抓取/安装逻辑,区别只是强制刷新已有缓存——目前只有 init 会这样做,单独重跑 install 不会。
init 每次运行:交互式复查配置:刷新完成、脚手架就绪后,只要有 TTY,skillenv init 就会带你分段复查这个仓库的 skill 配置——不只首次,每次都跑(.skillsrc 已存在的团队仓库也一样,方便随时调整;无 TTY 的 agent 调用则整段跳过,不卡住等输入)。复查分四段,每段列出相关 skill、说明每个动作的影响,再让你按名字挑选(支持 all、回车跳过):
- 本仓库声明的 skill(
.skillsrc里的skill指令)——remove掉某条声明; - 隔离模式——显示当前是 merge 还是 strict,问要不要切到 strict(过滤已知顶层用户级 skill);
- 本仓库已屏蔽的全局 skill(
disable指令)——enable恢复继承,或uninstall整机卸载; - 其余继承中的全局 skill——
disable只在本仓库屏蔽,或uninstall整机卸载。
remove/enable/disable 只改本仓库的 .skillsrc;uninstall 影响整机所有仓库(移入 ~/.skillenv/backup/,永不真删)。从已信任配置启动的交互修改会自动更新信任并同步。列表里 ●=当前生效/继承中、⊘=本仓库已屏蔽;加 disable 显示为 +、移除声明/屏蔽显示为 -:
$ skillenv init
skillenv: created .skillsrc
skillenv: wrote .envrc
◆ isolation
merge (current) — inherit global skills, add repo-declared ones on top
› filter known user skills for this repo? (y/N) n
◆ other global skills on this machine
disable = hide in this repo · uninstall = remove from every repo
● bi-query-sql Use when: (1) 用户需要执行 SQL 或用自然语言描述查询…
● eden-dev Eden 开发环境向导…
› uninstall which? (names · all · ↵ skip)
› disable which? (names · all · ↵ skip) eden-dev
+ disable eden-dev
skillenv: trusted and synchronized the skillenv-managed manifest
skillenv: authorized the generated .envrc
skillenv: next: add an installed global skill with 'skillenv add <name>'
全局层与仓库层的分工:install / uninstall 管理 ~/.agents/skills;.skillsrc 管理仓库声明。merge 仓库继承全局 skill,同源声明直接复用 canonical copy;strict 仓库把声明项物化到仓库发现目录。Claude 通过 Claude-only shadow 过滤用户级 skill;Codex 通过共享 PATH shim 的单次 skills.config override 关闭匹配的 canonical 与 effective CODEX_HOME/skills 顶层副本。disable 使用同样机制控制单个仓库的指定继承项。宿主兼容目录中手工维护的同名 skill 保持原位;uninstall 把 canonical entry 与受控兼容链接移入备份。
接管现有宿主 skill:直接运行 skillenv install ~/.claude/skills/<name> 或 skillenv install ~/.codex/skills/<name>。skillenv 先生成 canonical copy,再把作为安装源的原目录移动到 ~/.skillenv/backup/,最后在原位置建立兼容链接。其他手工同名目录保持原位。
~/.agents/skills 中已有的手工 skill 可运行 skillenv install global:<name>,canonical 内容保持原样,skillenv 会补齐已检测宿主的兼容链接。
给一整个仓库而不是具体 skill 路径:install 的源如果自己没有 SKILL.md,会被当成仓库/容器目录,递归找出其中所有 skill:
$ skillenv install github:vercel-labs/agent-skills
skillenv: no SKILL.md at github:vercel-labs/agent-skills itself — found 2 skill(s) inside:
skills/react-best-practices React and Next.js performance optimization guidelines…
skills/vercel-deploy Deploy and manage projects on Vercel…
skillenv: install which? (names, 'all', or blank to cancel): react-best-practices
不带名字直接回车会取消;也可以一次性传 all 或具体名字跳过交互,例如 skillenv install github:vercel-labs/agent-skills react-best-practices。非 TTY 环境下(脚本、agent 调用)不带名字时只打印清单和可用的下一条命令,不会挂起等待输入。
默认 cd 时 direnv 会打印 loading / export +VAR 行。想完全静音、把状态改放进提示符:
1. 静音 direnv——写 ~/.config/direnv/direnv.toml:
[global]
hide_env_diff = true
log_filter = "^$"skillenv 的「.skillsrc 未信任」安全警告走 .envrc 的 stderr,不受此过滤影响,仍会正常显示。
2. 提示符显示状态——skillenv prompt 输出形如 merge -4(merge 模式、屏蔽 4 个全局 skill)、strict +2(strict 模式、声明 2 个 skill)、!untrusted(清单待确认)。starship 用户在 ~/.config/starship.toml 的 format 中加入 ${custom.skillenv},并追加:
[custom.skillenv]
command = "skillenv prompt"
when = "test -f .skillsrc"
symbol = "⛭"
style = "bold cyan"
format = "[$symbol $output]($style) "powerlevel10k 用户在 ~/.p10k.zsh 中加 custom segment:
function prompt_skillenv() {
local out
out=$(skillenv prompt 2>/dev/null) || return
[[ -n $out ]] || return
p10k segment -f cyan -i '⛭' -t "$out"
}
# 再把 skillenv 加进 POWERLEVEL9K_LEFT_PROMPT_ELEMENTS 或 RIGHT_PROMPT_ELEMENTS其他框架同理:任何能执行命令的 prompt 段(zsh precmd 拼 RPROMPT、oh-my-posh custom segment)调 skillenv prompt 即可,单次执行约 70ms。
输出状态一览:空(无 .skillsrc)、merge -4(merge 模式、屏蔽 4 个)、strict +2(strict 模式、声明 2 个)、!untrusted(外部清单变更待 skillenv allow 确认)。固定模板 .envrc 由 skillenv 自动授权;自定义 .envrc 保留 direnv 的独立审阅状态。
自动安装与仓库触发的配置注入都是标准供应链攻击面(Codex 曾因 .env 重定向 CODEX_HOME 出过 RCE)。skillenv 的对策:
- 来源感知的双重信任门:
skillenv init/add产生的 manifest 变更会立即记录内容哈希;外部变更会恢复待审阅状态。内容完全匹配固定模板的.envrc由 skillenv 调用 direnv 授权;自定义.envrc继续使用 direnv 的独立审阅流程。 - Claude shadow 只生成在
~/.skillenv/下,绝不使用仓库内路径。Codex 不重定向配置根目录,只在可信 manifest 需要过滤时通过 PATH shim 注入单次skills.config参数。 - 物化的 skill 目录带
.managed-by-skillenv标记,自动同步只删除或覆盖 skillenv 管理的目录。显式执行uninstall <name>会把选中的 canonical entry 移入备份;宿主兼容目录中的手工 skill 保持原位。 cd-check只有收到y才写入全局目录。拒绝决定保存在~/.skillenv/migration-decisions/,并绑定当前SKILL.md内容哈希。strict与disable只用于减少上下文和避免同名 skill 冲突,不是授权或沙箱机制。Codex 用户可以用更晚的-c覆盖 session rule;skill 文件本身也仍是普通本地文件。
- Codex 过滤依赖 PATH 命中 shim:绝对路径启动的
codex、固定二进制路径的 IDE/扩展、已运行进程、远程 server 或自行重写 PATH 的启动器不会经过~/.skillenv/shims/codex。这些场景继续使用真实 Codex 状态,但不会获得仓库级 strict/disable 过滤。 - Codex 后置参数可以覆盖过滤:shim 把 skillenv 的
-c放在用户 argv 前面;调用方追加更晚的-c 'skills.config=…'时,Codex 的后置配置优先。这符合“便利性过滤、非安全边界”的定位。 codex agents是最小兼容例外:Codex 不允许 shared-session attach 携带 invocation-specific override,因此当第一个参数精确为agents时,shim 不注入 skillenv 的-c。skillenv 不实现通用 Codex 子命令解析器;若在agents前放置全局参数,该形式不会命中此例外。- OpenCode 的全局 skill 无法屏蔽:它硬编码读取
~/.claude/skills和~/.agents/skills,配置目录重定向拦不住;仓库级 skill 不受影响。 - Claude Code 的 VS Code 扩展不读取
CLAUDE_CONFIG_DIR,过滤只对终端启动的 CLI 生效。 @ref仅支持分支/标签(git clone --branch),不支持 commit SHA;skill 路径不能含空格。- 已在运行的 agent session 不受进出目录影响(环境变量和 argv 在进程启动时确定——这也是符合预期的语义)。