zai-org / zai-org/feedback

hook 模板变量 ${ZCODE_PROJECT_DIR} 解析为会话实时 cwd 而非项目根,cd 后 hook 全部失效并死锁

Open
#528 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

使用环境

  • 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 回项目根的命令也被拦截,形成会话内死锁,无法自救。

复现步骤

  1. 工作区 .zcode/config.json 配置任意使用占位符的 command hook,例如:
    { "type": "command", "command": "python \"${ZCODE_PROJECT_DIR}/.zcode/hooks/x.py\"", "timeout": 30 }
    
  2. 在项目根启动会话,任意 Bash 命令正常(此时占位符恰好等于项目根);
  3. 执行 cd sub-dir
  4. 再执行任意 Bash 命令 → hook 以漂移后的 cwd 展开,报错(真实案例):
    python: can't open file '<workspace>\<sub-dir>\.zcode\hooks\x.py': [Errno 2] No such file or directory
    
    工具调用被拦截;此时尝试 cd .. 自救,cd 本身也是被 PreToolUse hook 拦截的 Bash 调用 → 死锁。

期望表现 vs 实际表现

  • 期望ZCODE_PROJECT_DIR 锚定会话启动时的工作目录(项目根),会话生命周期内不随 Bash 的 cd 漂移。ZCode 同时设置 CLAUDE_PROJECT_DIR 作为兼容别名,Claude Code 对该变量的契约即"项目根绝对路径",两者的语义应保持一致。
  • 实际:随会话实时 cwd 漂移(从插件内嵌的 hook 展开实现观察到取值为 input.cwd || workingDirectory)。两条消费通道同时失效
    1. hook 命令/参数中的 ${ZCODE_PROJECT_DIR} 占位符展开错位;
    2. 注入 hook 子进程的 ZCODE_PROJECT_DIR 环境变量同样漂移——依赖它定位项目资源的脚本(如 Trellis 工作流的 hook 找 .trellis/、按 *_PROJECT_DIR 识别宿主平台)在 cd 后静默退化。

影响面

  • 任何按官方推荐用占位符保持 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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.