SessionStart hook 在模块 import 阶段被 PEP 604 联合类型标注炸掉——AI CLI host 拉起的 python3 解析到 macOS 系统 3.9,哪怕用户 shell 里 python3 是 3.11。非 breaking,不用加 --migrate。同时把声明的 Python 版本底线从 3.10 下调到 3.9,让 macOS 系统自带的 python3 开箱可用。
Bug 修复
Hook PEP 604 标注崩溃
packages/cli/src/templates/shared-hooks/session-start.py 和 inject-subagent-context.py 顶部没写 from __future__ import annotations,于是 PEP 604 联合类型标注(str | None、dict | None)在 Python 处理 def 语句时就被立即求值。任何 python3 < 3.10 都会让模块直接抛:
python3 --version 返回 3.11.12(homebrew),但 AI CLI host 拉起 hook 子进程时 PATH 是被裁剪过的,里面没有 /opt/homebrew/bin。env python3 落到 /usr/bin/python3 → macOS 系统自带的 3.9,没实现 PEP 604 的表达式求值。
packages/cli/src/templates/shared-hooks/statusline.py 和 copilot/codex 两份 session-start.py 早就加上了这个 future import;只有 shared-hooks/*.py 这两个主文件漏了。
修复 —— 在模块 docstring 后面加一行:
| 文件 | 变更 |
|---|---|
packages/cli/src/templates/shared-hooks/session-start.py | +from __future__ import annotations |
packages/cli/src/templates/shared-hooks/inject-subagent-context.py | +from __future__ import annotations |
from __future__ import annotations(PEP 563)会把所有标注变成惰性字符串,所以标注里的 PEP 604 语法在 Python 3.7+ 都能跑。运行时的联合表达式——比如 isinstance(x, int | str)——不受这个 import 影响,仍然需要 3.10+;这两个 hook 都没用到。
改进
Python 版本底线从 3.10 下调到 3.9
packages/cli/src/commands/init.ts 里的 MIN_MINOR 改成 9。原因:macOS Ventura / Sonoma / Sequoia 系统自带的 /usr/bin/python3 都是 3.9.6;另外 Trellis 分发的模板文件(shared-hooks/*.py 和 trellis/scripts/**/*.py)经过完整 package-import 矩阵实测,30 个文件在 CPython 3.8–3.13 全部导入通过。
| 改动 | 位置 |
|---|---|
MIN_MINOR = 10 → 9 | packages/cli/src/commands/init.ts |
Warning 文案 Python ≥ 3.10 → Python ≥ 3.9 | packages/cli/src/commands/init.ts(2 处) |
Python ≥ 3.10 → Python ≥ 3.9 | README.md |
| Quickstart 前置要求表 | docs-site/quickstart.mdx + docs-site/zh/quickstart.mdx(新增段) |
/tmp/trellis-py-compat/ 下、没提交到仓库。不支持 Python 3.8:2024-10 已 EOL,声明支持会背上 CVE backport 的维护责任。
init 现在和模板层共用同一套按 OS 选 Python 命令的规则
模板层早就把{{PYTHON_CMD}} 渲染成 Windows 用 python、macOS / Linux
用 python3,但 packages/cli/src/commands/init.ts 之前还是所有平台都先探测
python3,失败后才回退到 python。结果就是 Windows 提示文案、生成出来的
hook 命令、以及 init 自己执行 init_developer.py 时实际用的解释器并不一致。
现在 trellis init 两边统一成同一条平台规则:
| 平台 | 生成到文件里的命令 | init 探测 / bootstrap 使用的命令 |
|---|---|---|
| Windows | python | python --version、python .trellis/scripts/init_developer.py ... |
| macOS / Linux | python3 | python3 --version、python3 .trellis/scripts/init_developer.py ... |
| 文件 | 变更 |
|---|---|
packages/cli/src/configurators/shared.ts | 导出共享的 OS → Python 命令 helper,模板渲染直接复用 |
packages/cli/src/commands/init.ts | 复用同一个 helper 做版本探测、Windows 提示和 init_developer.py 调用 |
packages/cli/test/commands/init.integration.test.ts | 给 init bootstrap 命令和 soft warning 路径补回归测试 |
packages/cli/test/commands/init-internals.test.ts | 给 Python 版本 warning 行为补单测 |
升级
老项目:cross-platform-thinking-guide.md 模板。文件是 pristine 的会静默应用;本地改过的会走标准的 confirm 提示。
新装: