zai-org / zai-org/feedback

[Bug] .zcode/agents 扫描静默跳过符号链接/junction(软链接的 subagent 定义不加载)

Open
#336 1 comment 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

提交前确认 · Pre-submission checklist
  • 我已搜索过现有 issue,确认这不是重复提议 / I searched existing issues and confirmed this isn't a duplicate.
  • 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category

缺陷 / Bug(子智能体配置发现)

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

问题描述 · Bug description

.zcode/agents/(项目级)与 ~/.zcode/agents/(用户级)目录扫描会静默跳过所有符号链接条目:软链接的 .md 定义文件不加载,软链接/junction 的子目录整棵子树丢失。用硬链接或真实文件则正常加载。

根因分析 · Root cause

zcode.cjs 中 subagent 目录扫描(反混淆后逻辑如下):

function scanAgents(dir) {
  if (!fs.existsSync(dir)) return [];
  if (!fs.statSync(dir).isDirectory()) return [];
  const out = [];
  for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
    const p = path.join(dir, ent.name);
    if (ent.isDirectory()) { out.push(...scanAgents(p)); continue; }
    ent.isFile() && /\.(md|markdown)$/i.test(ent.name) && out.push(p);
  }
  return out.sort();
}

readdirSync(..., { withFileTypes: true }) 返回的 Dirent 基于 lstat 语义:符号链接条目的 isFile()isDirectory() 均为 false(它是 isSymbolicLink()),于是既不进文件分支也不进目录分支,被静默丢弃。

同类扫描在本产品内处理不一致:skills 的目录扫描(skillFilesUnderRoot 等)过滤条件是 isDirectory() || isSymbolicLink(),明确处理了软链接;agents 的扫描没有。这应当是实现疏漏而非设计约定。(次要观察:commands 的 .md 列表过滤也是 isFile() 单条件,疑似同病,供一并核查。)

复现步骤 · Reproduce

Windows 11 + ZCode 桌面版 v3.7.x(自带 CLI 0.16.3):

  1. 在任意工作区建 .zcode/agents/,放一个正常的 real.md(frontmatter + 正文,可被加载);
  2. 再放一个软链接定义文件:mklink link.md <某个外部的合法 agent 定义.md>(或开发者模式下 ln -s);以及一个目录联接:mklink /J linkdir <外部目录>(内含合法 .md);
  3. 启动会话查看实际加载的 subagent profiles。

实测结果(直接用与 zcode.cjs 一字不差的扫描逻辑跑真实目录):

条目 Dirent 判定 是否被收集
real.md 普通文件 isFile=true
shared/sub.md 普通子目录 isDirectory=true
hardlink.mdmklink /H 硬链接) isFile=true
link.md 符号链接文件 isFile=false, isSymbolicLink=true ❌ 跳过
linkdir(junction / 符号链接目录) isDirectory=false, isSymbolicLink=true ❌ 整棵子树丢失

期望行为 · Expected behavior

扫描跟随符号链接:文件与目录分支都应兼容 isSymbolicLink() 条目,例如 ent.isFile() || ent.isSymbolicLink()(再配合 statSync(p) 判定目标类型与扩展名),目录分支同理——与 skills 扫描的既有做法对齐。若出于安全考虑决定不跟随软链接,至少应在 doctor / 日志中给出明确诊断,而不是静默丢弃。

影响 · Impact

  • 团队把 subagent 定义集中存放、按仓库软链引入的用法完全不可用(这是 #269 之后"项目级 subagent 共享"的一个常见延伸用法);
  • Windows 上 junction(mklink /J,无需管理员权限,最常用的目录链接手段)同样中招;
  • 用户级 ~/.zcode/agents/ 走同一扫描函数,一样受影响。

临时绕过 · Workaround

文件级共享可改用硬链接 cmd /c mklink /H <link.md> <target.md>(无需管理员权限,Dirent 表现为普通文件,实测可被加载);目录级共享暂时只能复制文件。

你认为的优先级 · Your perceived priority

中 · Medium(有硬链接绕过,但静默失败 + 与 skills 行为不一致,容易让人误以为项目级 subagent 不生效)

你使用的 ZCode 版本 / 环境 · ZCode version / environment
  • Windows 11 桌面版 v3.7.x,自带 CLI 0.16.3(F:\soft\ZCode\resources\glm\zcode.cjs
  • 复现为对 bundle 内实际扫描函数的等价执行,非猜测
补充材料 · Additional context
  • 相关:#269(项目级 subagent 已支持;本 bug 发生在其配置发现环节)
  • 对照证据:skills 扫描已处理 isSymbolicLink()zcode.cjsskillFilesUnderRoot 的过滤条件)

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 in zcode.cjs at scanAgents and compare its Dirent handling with the skillFilesUnderRoot scan, which already considers symbolic links. Reproduce the scan with a linked .md file and linked directory on Windows, then verify that both linked agent definitions are loaded without silently skipping them.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.