zai-org / zai-org/feedback

[Bug] git-subdir/url 类插件安装后产生指向临时目录的 symlink,macOS 清理 /var/folders 后全部死链,插件功能失效

Open
#211 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
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-subdirurl 来源的插件(已观察到 redis-developmentbuildkitesupabasesuperpowerscanva),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 '...' 警告刷屏
复现步骤
  1. macOS(已复现:macOS 15.5 darwin arm64)
  2. 在 zcode 插件市场安装 redis-development(git-subdir 来源:github.com/redis/agent-skills.git
  3. 安装后立即检查 cache 目录:
    ls -la ~/.zcode/cli/plugins/cache/claude-plugins-official/redis-development/*/skills/
    
    能看到 8 个 lrwxr-xr-x 符号链接,target 为 /var/folders/.../T/zcode-plugin-src-XXXXX/...
  4. 重启 Mac,或等待若干天,再次执行上述 ls——target 路径已不存在
  5. 启动 zcode,控制台输出:
    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'
    
    (8 个技能各报一次)
受影响插件(实测)
插件 死链数 失效内容
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 来源插件的处理流程似乎是:

  1. 把 git 仓库克隆/解压到临时目录 $TMPDIR/zcode-plugin-src-XXXXXX/
  2. 在正式 cache 目录 ~/.zcode/cli/plugins/cache/.../<plugin>/<ver>/ 下,创建 symlink 指向临时目录中的文件
  3. 没有把真实文件拷贝/移动到 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.