Skip to main content
Hotfix: SessionStart hook crashed at module-import time on PEP 604 union annotations when the AI CLI host spawned python3 as macOS system 3.9 — even though the user’s shell python3 was 3.11. Not breaking; no --migrate required. Also relaxes the declared Python floor from 3.10 to 3.9 so the macOS system python3 is supported out of the box.

Bug Fixes

Hook PEP 604 annotation crash

packages/cli/src/templates/shared-hooks/session-start.py and inject-subagent-context.py did not declare from __future__ import annotations, so PEP 604 union annotations (str | None, dict | None) were evaluated eagerly when Python processed the def statement. On any python3 < 3.10 the module aborted with:
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
Observed in the wild on macOS: the user’s shell python3 --version reported 3.11.12 (homebrew), but the AI CLI host spawned the hook subprocess with a minimal PATH that did not include /opt/homebrew/bin. env python3 resolved to /usr/bin/python3 → macOS system 3.9, which does not implement PEP 604 at expression-eval time. packages/cli/src/templates/shared-hooks/statusline.py plus the copilot/codex copies of session-start.py already carried the future import; the two canonical shared-hooks/*.py files were the outliers. Fix — add one line immediately after the module docstring:
"""Session Start Hook - Inject structured context"""
from __future__ import annotations                   # added
FileChange
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) makes all annotations lazy strings, so PEP 604 syntax in annotations is safe on Python 3.7+. Runtime union expressions — e.g. isinstance(x, int | str) — are not rescued and still require 3.10+; neither hook uses them.

Improvements

Python floor relaxed from 3.10 to 3.9

packages/cli/src/commands/init.ts now sets MIN_MINOR = 9. Rationale: macOS Ventura / Sonoma / Sequoia all ship /usr/bin/python3 at 3.9.6, and Trellis’s distributed templates (both shared-hooks/*.py and trellis/scripts/**/*.py) were empirically verified against CPython 3.8–3.13 via a full package-import matrix — 30/30 files load cleanly on every tested version.
ChangeLocation
MIN_MINOR = 109packages/cli/src/commands/init.ts
Warning text Python ≥ 3.10Python ≥ 3.9packages/cli/src/commands/init.ts (2 occurrences)
Python ≥ 3.10Python ≥ 3.9README.md
Quickstart Prerequisites tabledocs-site/quickstart.mdx + docs-site/zh/quickstart.mdx (new section)
No CI matrix change yet; the empirical test harness lives in /tmp/trellis-py-compat/ during development (not committed). Python 3.8 is not supported — EOL 2024-10, and declaring support would incur backport obligations whenever an unmaintained-Python CVE surfaces.

Init now follows the same OS-aware Python command policy as templates

The template layer already rendered {{PYTHON_CMD}} as python on Windows and python3 on macOS/Linux, but packages/cli/src/commands/init.ts still probed python3 first everywhere and only fell back to python. That meant the Windows status message, generated hook commands, and init’s own init_developer.py bootstrap path were talking about different interpreters. trellis init now uses the same platform rule in both places:
PlatformGenerated commandInit probe / bootstrap command
Windowspythonpython --version, python .trellis/scripts/init_developer.py ...
macOS / Linuxpython3python3 --version, python3 .trellis/scripts/init_developer.py ...
If the selected platform command resolves to Python < 3.9, init prints a warning but still completes. Missing Python still does not block file generation; the follow-up failure mode remains the same manual bootstrap hint.
FileChange
packages/cli/src/configurators/shared.tsExport shared OS → Python command helper used by template rendering
packages/cli/src/commands/init.tsReuse shared helper for version probe, Windows notice, and init_developer.py invocation
packages/cli/test/commands/init.integration.test.tsRegression coverage for init bootstrap command + soft warning path
packages/cli/test/commands/init-internals.test.tsUnit coverage for Python version floor warning behavior

Upgrade

Existing projects:
trellis update
Picks up the two patched hook files plus the updated cross-platform-thinking-guide.md template. Pristine installs apply silently; locally-modified copies land on the standard confirm prompt. Fresh install:
npm i -g @mindfoldhq/[email protected]