> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trytrellis.app/llms.txt
> Use this file to discover all available pages before exploring further.

# v0.5.0-beta.11

> 2026-04-22

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:

```python theme={null}
"""Session Start Hook - Inject structured context"""
from __future__ import annotations                   # added
```

| File                                                                 | Change                                |
| -------------------------------------------------------------------- | ------------------------------------- |
| `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.

| Change                                        | Location                                                                 |
| --------------------------------------------- | ------------------------------------------------------------------------ |
| `MIN_MINOR = 10` → `9`                        | `packages/cli/src/commands/init.ts`                                      |
| Warning text `Python ≥ 3.10` → `Python ≥ 3.9` | `packages/cli/src/commands/init.ts` (2 occurrences)                      |
| `Python ≥ 3.10` → `Python ≥ 3.9`              | `README.md`                                                              |
| Quickstart Prerequisites table                | `docs-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:

| Platform      | Generated command | Init probe / bootstrap command                                        |
| ------------- | ----------------- | --------------------------------------------------------------------- |
| Windows       | `python`          | `python --version`, `python .trellis/scripts/init_developer.py ...`   |
| macOS / Linux | `python3`         | `python3 --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.

| File                                                  | Change                                                                                    |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `packages/cli/src/configurators/shared.ts`            | Export shared OS → Python command helper used by template rendering                       |
| `packages/cli/src/commands/init.ts`                   | Reuse shared helper for version probe, Windows notice, and `init_developer.py` invocation |
| `packages/cli/test/commands/init.integration.test.ts` | Regression coverage for init bootstrap command + soft warning path                        |
| `packages/cli/test/commands/init-internals.test.ts`   | Unit coverage for Python version floor warning behavior                                   |

## Upgrade

Existing projects:

```bash theme={null}
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:

```bash theme={null}
npm i -g @mindfoldhq/trellis@0.5.0-beta.11
```
