hook 模板变量 ${ZCODE_PROJECT_DIR} 解析为会话实时 cwd 而非项目根,cd 后 hook 全部失效并死锁
Open
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
使用环境
- Windows 10(10.0.22631 x64),ZCode CLI 0.16.5(桌面壳内嵌运行)
- hook 配置位置:工作区
.zcode/config.json,command 型 hook(SessionStart / UserPromptSubmit / PreToolUse×2) - 模型通道:GLM-5.3-Flash
问题一句话
模板变量 ${ZCODE_PROJECT_DIR} 解析的是会话实时 cwd(会被 Bash 工具的 cd 改写),而不是项目根/会话启动目录;cd 一次之后所有 hook 全部失效,且 hook 失败会拦截工具调用,连 cd 回项目根的命令也被拦截,形成会话内死锁,无法自救。
复现步骤
- 工作区
.zcode/config.json配置任意使用占位符的 command hook,例如:{ "type": "command", "command": "python \"${ZCODE_PROJECT_DIR}/.zcode/hooks/x.py\"", "timeout": 30 } - 在项目根启动会话,任意 Bash 命令正常(此时占位符恰好等于项目根);
- 执行
cd sub-dir; - 再执行任意 Bash 命令 → hook 以漂移后的 cwd 展开,报错(真实案例):
工具调用被拦截;此时尝试python: can't open file '<workspace>\<sub-dir>\.zcode\hooks\x.py': [Errno 2] No such file or directorycd ..自救,cd本身也是被 PreToolUse hook 拦截的 Bash 调用 → 死锁。
期望表现 vs 实际表现
- 期望:
ZCODE_PROJECT_DIR锚定会话启动时的工作目录(项目根),会话生命周期内不随 Bash 的cd漂移。ZCode 同时设置CLAUDE_PROJECT_DIR作为兼容别名,Claude Code 对该变量的契约即"项目根绝对路径",两者的语义应保持一致。 - 实际:随会话实时 cwd 漂移(从插件内嵌的 hook 展开实现观察到取值为
input.cwd || workingDirectory)。两条消费通道同时失效:- hook 命令/参数中的
${ZCODE_PROJECT_DIR}占位符展开错位; - 注入 hook 子进程的
ZCODE_PROJECT_DIR环境变量同样漂移——依赖它定位项目资源的脚本(如 Trellis 工作流的 hook 找.trellis/、按*_PROJECT_DIR识别宿主平台)在cd后静默退化。
- hook 命令/参数中的
影响面
- 任何按官方推荐用占位符保持 hook 配置可移植的工作区,
cd一次即全体 hook 失效并死锁;新手几乎不可能在不重启会话的情况下恢复。 - 生态工具(Trellis 等)按该变量解析项目根/生成 context key 的逻辑在
cd后产生错误状态。
建议修复
- 会话启动时快照项目根(或以
.zcode/config.json所在目录为准),hook 的模板展开与环境变量注入一律使用该快照值; - 若需要把工具调用的实时 cwd 暴露给 hook,请另用独立变量(如
ZCODE_CWD)表达,不要与*_PROJECT_DIR混用。
临时规避(供其他用户参考)
- hook 命令写绝对路径,不用占位符;
- hook 脚本不信任该环境变量,从
cwd向上回溯定位项目根(找.trellis/.git等标志目录)。
如需日志,可提供 %USERPROFILE%\.zcode\cli\log\zcode-2026-09-05.jsonl 相关片段。
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 with the workspace .zcode/config.json and reproduce the issue using SessionStart, UserPromptSubmit, and PreToolUse command hooks, then inspect the hook expansion implementation described in the report. Done means ZCODE_PROJECT_DIR and its CLAUDE_PROJECT_DIR alias remain anchored to the session’s project root after Bash cd commands, while hook calls continue to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, shell
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100