[Bug] git-subdir/url 类插件安装后产生指向临时目录的 symlink,macOS 清理 /var/folders 后全部死链,插件功能失效
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
标题(建议)
[Bug] git-subdir/url 类插件安装后产生指向临时目录的 symlink,macOS 清理 /var/folders 后全部死链,插件功能失效
正文
现象
在 macOS 上安装任何 git-subdir 或 url 来源的插件(已观察到 redis-development、buildkite、supabase、superpowers、canva),cache 目录里出现的不是真实文件,而是符号链接,target 指向系统临时目录:
/Users/trista/.zcode/cli/plugins/cache/claude-plugins-official/<plugin>/<ver>/skills/<skill>
→ /var/folders/<id>/T/zcode-plugin-src-XXXXXX/skills/<skill>
/var/folders/<id>/T/ 是 macOS 用户级临时目录,会被系统周期性清理(重启、或数日内自动)。一旦清理,全部 symlink 变成死链(dangling symlink),导致:
- 插件的技能完全不加载(如
redis-development的 8 个技能全部失效,等于插件没装) - 插件的指引文档读不到(
AGENT.md/CLAUDE.md/AGENTS.md/references/目录) - zcode 启动时报
ENOENT: no such file or directory, stat '...'警告刷屏
复现步骤
- macOS(已复现:macOS 15.5 darwin arm64)
- 在 zcode 插件市场安装
redis-development(git-subdir 来源:github.com/redis/agent-skills.git) - 安装后立即检查 cache 目录:
能看到 8 个ls -la ~/.zcode/cli/plugins/cache/claude-plugins-official/redis-development/*/skills/lrwxr-xr-x符号链接,target 为/var/folders/.../T/zcode-plugin-src-XXXXX/... - 重启 Mac,或等待若干天,再次执行上述
ls——target路径已不存在 - 启动 zcode,控制台输出:
(8 个技能各报一次)warning 扫描技能目录失败 ENOENT: no such file or directory, stat '/Users/<user>/.zcode/cli/plugins/cache/claude-plugins-official/redis-development/0.0.0/skills/redis-core'
受影响插件(实测)
| 插件 | 死链数 | 失效内容 |
|---|---|---|
| redis-development | 8 | 8 个技能全部失效 |
| buildkite | 7 | AGENT.md/CLAUDE.md + 4 个 references 目录 |
| supabase | 1 | CLAUDE.md |
| superpowers | 1 | AGENTS.md |
| canva | 1 | .cursor/skills |
根因分析
zcode 的插件安装器对 git-subdir / url 来源插件的处理流程似乎是:
- 把 git 仓库克隆/解压到临时目录
$TMPDIR/zcode-plugin-src-XXXXXX/ - 在正式 cache 目录
~/.zcode/cli/plugins/cache/.../<plugin>/<ver>/下,创建 symlink 指向临时目录中的文件 - 没有把真实文件拷贝/移动到 cache 目录
而 $TMPDIR(即 /var/folders/<id>/T/)是 macOS 周期性清理的临时位置,不适合持久化插件文件。任何这样安装的插件都注定失效。
期望行为
安装完成后,cache 目录里应该是真实文件(-rw-r--r-- / drwxr-xr-x),而不是指向临时目录的符号链接。
建议修复
在解压/克隆后,用 cp -RL(follow symlink)或 rsync -aL 把临时目录的内容真正拷贝到 cache 目录,而不是创建 symlink。例如:
# 伪代码:当前(有 bug)
ln -s "$TMPDIR/zcode-plugin-src-XXX/skills/redis-core" "$CACHE/skills/redis-core"
# 修复后
cp -RL "$TMPDIR/zcode-plugin-src-XXX/skills/redis-core" "$CACHE/skills/redis-core"
环境信息
- OS: macOS 15.5(darwin 25.5.0 arm64)
- zcode 版本: 3.6.5 (build 4145) —
CFBundleShortVersionString=3.6.5,CFBundleVersion=3.6.5.4145 - 受影响插件均为 git-subdir / url 来源;本地路径来源(
./plugins/...)的插件不受影响
临时绕过方法(已验证有效)
用户可手动从官方 git 仓库克隆,用真实文件替换 cache 里的死 symlink:
# 以 redis-development 为例
PLUGIN=redis-development
VER=0.0.0
CACHE=~/.zcode/cli/plugins/cache/claude-plugins-official/$PLUGIN/$VER
# 备份原死链目录
mv "$CACHE/skills" "$CACHE/skills.dead"
# 克隆官方仓库(depth 1 即可)
TMP=$(mktemp -d)
git clone --depth 1 https://github.com/redis/agent-skills.git "$TMP/repo"
# 拷贝真实文件到 cache
mkdir -p "$CACHE/skills"
cp -RL "$TMP/repo/plugins/$PLUGIN/skills/." "$CACHE/skills/"
# 验证:应是 drwxr-xr-x 而非 lrwxr-xr-x
ls -la "$CACHE/skills/"
但这是用户侧的繁琐绕过,希望 zcode 在安装器层面根治。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the plugin installer path that handles git-subdir and url sources, using the cache path under ~/.zcode/cli/plugins/cache and the temporary zcode-plugin-src directories described in the report. Confirm where symlinks are created and verify that installation leaves real files in the cache after the source directory is removed; no specific source file or test is named in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, macos
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100