Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

skillenv

English | 简体中文

像 pyenv / nvm 管理语言版本一样,管理 AI Agent 的全局 skill 与仓库选择。

skillenv install 默认把 skill 安装到 ~/.agents/skills 全局 canonical store,再为 Claude Code、Codex、OpenCode 建立兼容链接。仓库用 .skillsrc 记录需要同步的 skill;merge 模式直接复用全局副本,strict 模式把选中的 skill 物化到 .agents/skills.claude/skillsskillenv 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 + projectCodex 的用户级目录是 ~/.agents/skills,仓库目录是 .agents/skillsClaude 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

安装(推荐:交给你的 Agent)

把下面这句话发给你的 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 安装下即时生效)。

Agent 安装指引

本节写给执行安装的 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 initskillenv add 只自动信任自身生成的变更,并只自动授权内容完全匹配固定模板的 .envrc。仓库自带或经其他方式修改的 .skillsrc 需要先向用户展示完整内容,再执行 skillenv allow。自定义 .envrc 继续由 direnv 的审阅流程管理。

Agent 接管指引:盘点并管理已有 skill

本节写给 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 — 迁移(硬性规则)

  • mvrm:skill 进入 ~/.agents/skills/;重复副本、被淘汰的目录一律移到 ~/.skillenv/backup/,永不删除;
  • 含公司内部信息的 skill 绝不能提交/推送到公开仓库。

步骤 4 — 铺仓库配置:在每个目标仓库运行 skillenv init,再用 skillenv add <name> 把已安装的全局 skill 写入 .skillsrcadd 优先记录原始 github: / git: 来源,团队成员可从同一来源恢复;手工全局 skill 使用 skill global:<name>disable 过滤指定继承项,isolation strict 过滤 skillenv 能识别的顶层用户级 skill,并保留仓库声明项。两者都是便利性过滤,不是安全边界。

步骤 5 — 自动信任与激活skillenv initskillenv 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_HOMECODEX_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 shadow 迁移

迁移不需要搬动 Codex 数据:.skillsrc.envrc 格式不变,config、auth、sessions、logs 和 SQLite 继续使用真实或用户自定义的 Codex home。需要迁移的只是旧终端继承的进程级环境。

  1. 更新 skillenv:

    skillenv update

    curl 单文件安装需要重新下载最新版。

  2. 退出已运行的 Codex。最简单的迁移方式是关闭旧终端,重新打开后进入仓库;新 shell 不会继承旧 shadow 环境。

  3. 若要在当前 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 应保留;新版本不会改写它们。

  4. 验证:

    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 不会自动处理它。

进入仓库时迁移项目 skill

加载 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>

.skillsrc 参考

# 管理哪些 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);
  • 本仓库已屏蔽的全局 skilldisable 指令)——enable 恢复继承,或 uninstall 整机卸载;
  • 其余继承中的全局 skill——disable 只在本仓库屏蔽,或 uninstall 整机卸载。

remove/enable/disable 只改本仓库的 .skillsrcuninstall 影响整机所有仓库(移入 ~/.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.tomlformat 中加入 ${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 precmdRPROMPT、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 的对策:

  1. 来源感知的双重信任门skillenv init/add 产生的 manifest 变更会立即记录内容哈希;外部变更会恢复待审阅状态。内容完全匹配固定模板的 .envrc 由 skillenv 调用 direnv 授权;自定义 .envrc 继续使用 direnv 的独立审阅流程。
  2. Claude shadow 只生成在 ~/.skillenv/ 下,绝不使用仓库内路径。Codex 不重定向配置根目录,只在可信 manifest 需要过滤时通过 PATH shim 注入单次 skills.config 参数。
  3. 物化的 skill 目录带 .managed-by-skillenv 标记,自动同步只删除或覆盖 skillenv 管理的目录。显式执行 uninstall <name> 会把选中的 canonical entry 移入备份;宿主兼容目录中的手工 skill 保持原位。
  4. cd-check 只有收到 y 才写入全局目录。拒绝决定保存在 ~/.skillenv/migration-decisions/,并绑定当前 SKILL.md 内容哈希。
  5. strictdisable 只用于减少上下文和避免同名 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 在进程启动时确定——这也是符合预期的语义)。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages