github / github/spec-kit

[Bug] Preset composition fails under isolated installs: scripts run on system python3 but PyYAML lives in the CLI venv

Offen
#4,443 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug-assess severity-medium triage-nice-to-have
Vorherrschende Sprache
Python
Sterne
137k
Forks
12.3k
Ø Merge
2 T. 12 Std.
Gemergte PRs (30 T.)
159

Beschreibung

## Summary

Preset template composition fails with `PyYAML is required to resolve preset template composition` whenever the CLI is installed the recommended way (`uv tool install` or `pipx`), because the automation scripts run under the system `python3` while `pyyaml` lives in the CLI's isolated venv.

The better the installation isolation, the more reliably the bug shows up.

## The chain

1. Command skills instruct the agent to run the **script**, not the CLI. From `speckit-plan`:
```
Run `python3 .specify/scripts/python/setup_plan.py --json` from repo root
```
2. That script reaches `common.py`, which does `import yaml` (line 391 in v1.0.4) and raises `TemplateResolutionError("PyYAML is required to resolve preset template composition")` when a `preset.yml` manifest exists.
3. `pyyaml>=6.0` is declared in `pyproject.toml` and is correctly installed — but inside the tool venv created by `uv tool install` / `pipx`.
4. The script is invoked as bare `python3`, which resolves to the system interpreter that cannot see that venv.

## Reproduction

```bash
uv tool install specify-cli
specify init myproj --integration claude --script py
cd myproj
specify preset add

# CLI path — works (runs inside the tool venv):
specify preset resolve plan-template

# Script path — fails (runs under system python3):
python3 .specify/scripts/python/resolve_template.py plan-template --json
# ERROR: PyYAML is required to resolve preset template composition
```

Same failure with the bash variant (`.specify/scripts/bash/resolve-template.sh`), since `_python3_command()` in `common.sh` only probes `python3` on PATH.

## Environment

- spec-kit `1.0.4`
- macOS 15 (arm64), Homebrew Python 3.14.6
- Reproduced with both `uv tool install specify-cli` and `pipx install specify-cli`

## Why the usual workarounds don't apply

- `--script py` doesn't help: the Python variant is invoked by the same bare `python3`.
- There is no environment variable to point at another interpreter; `_python3_command()` only checks PATH.
- Installing `pyyaml` into the system interpreter is refused on Homebrew/Debian Python under [PEP 668](https://peps.python.org/pep-0668/) (`externally-managed-environment`). `uv pip install --python "$(which python3)" pyyaml` is refused for the same reason and suggests a venv — but a venv doesn't help, because the skills invoke bare `python3` with no activation.

The only way out today is bypassing PEP 668 (`pip install --user --break-system-packages pyyaml`), which asks users to disable a safety mechanism to run a documented feature.

## Impact

Any project using a preset with a manifest — i.e. any preset that needs `append`, `prepend` or `wrap`, since the manifest-less path is hardcoded to `replace`:

```python
except ImportError as exc:
if manifest_path.is_file():
raise TemplateResolutionError("PyYAML is required ...")
return (conventional, "replace") if conventional is not None else None
```

So composition strategies are unavailable precisely for users who installed the CLI in an isolated environment, which is what the docs recommend.

## Suggested fixes

Any one of these would close it:

1. Have the scripts resolve the interpreter that ships with spec-kit (record its path at `init` time, similar to how some tools pin the interpreter into generated hooks) instead of assuming bare `python3`.
2. Honor an override such as `SPECIFY_PYTHON` in `_python3_command()`.
3. Vendor a minimal YAML parser for manifest reading, or parse the small, well-known `preset.yml` schema without the dependency.
4. If none of the above, document the requirement explicitly in the installation guide, since today it surfaces only as a runtime error.

Happy to send a PR for option 2 if that's the direction you'd prefer.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Start with .specify/scripts/python/common.py and .specify/scripts/bash/common.sh, especially the interpreter-selection path in _python3_command(), then compare it with the CLI entry point and the dependency declaration in pyproject.toml. Reproduce preset manifest composition after a uv tool install or pipx install. Done means both script variants resolve PyYAML in isolated installs without requiring it in the system interpreter.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
bash, python
Bereich
cli, tooling
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
55/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.