github / github/spec-kit

specify init does not copy templates/commands/ to .specify/templates/commands/ — wrap composition strategy fails

Abierto
#3,086 3 comentarios 0 reacciones 0 asignados Ver en GitHub
bug-assess severity-medium stale
Lenguaje dominante
Python
Estrellas
137k
Forks
12.3k
Merge medio
2 d 12 h
PR fusionados (30 d)
159

Descripción

## `specify init` does not copy `templates/commands/` to `.specify/templates/commands/`

### Problem

During `specify init`, the `install_shared_infra` function in `shared_infra.py` copies template files from the bundled `templates/` directory to `.specify/templates/`. However, it only processes **files** at the top level (`src.is_file()` check), skipping subdirectories — specifically `templates/commands/`.

This means the core command templates (e.g., `implement.md`, `specify.md`, `plan.md`, etc.) are installed directly to the agent directory (e.g., `.opencode/commands/speckit.implement.md`) via the integration system, but they are **not** kept in `.specify/templates/commands/` for the preset resolver to find.

### Impact

Preset authors who use the `wrap` composition strategy for command overrides (e.g., wrapping `speckit.implement` with a preamble) cannot resolve the core command as a base layer. The `PresetResolver.collect_all_layers()` method looks for core commands at:

```python
c = self.templates_dir / "commands" / f"{template_name}.md" # or stem fallback
```

Since `.specify/templates/commands/` doesn't exist after `specify init`, the resolver finds no base layer, composition fails, and the command is silently not registered (`registered_commands` stays empty `{}`).

### Reproduction

```bash
specify init --here --integration opencode --script sh --ignore-agent-tools
# .specify/templates/commands/ does NOT exist
# .opencode/commands/speckit.implement.md exists (installed by integration)

# Create a preset with a wrap strategy for speckit.implement
specify preset add --dev /path/to/my-preset
# registered_commands is {} — the wrap composition failed silently
```

### Workaround

Manually copy command templates after init:

```bash
mkdir -p .specify/templates/commands
cp /templates/commands/*.md .specify/templates/commands/
```

### Suggested fix

In `shared_infra.py`, the `install_shared_infra` function should also copy the `templates/commands/` subdirectory (with the same overwrite/manifest logic). Something like:

```python
# After the top-level template files loop:
commands_src = templates_src / "commands"
if commands_src.is_dir():
dest_commands = dest_templates / "commands"
if _ensure_or_bucket_dir(dest_commands):
for src_path in commands_src.iterdir():
if not src_path.is_file() or src_path.name.startswith("."):
continue
dst = dest_commands / src_path.name
rel = dst.relative_to(project_path).as_posix()
# ... same overwrite/manifest logic as above ...
```

Alternatively, the `PresetResolver` could fall back to reading core commands from the agent directory (e.g., `.opencode/commands/speckit.implement.md`) when `.specify/templates/commands/` doesn't have them.

### Environment

- Spec Kit v0.11.3
- macOS Darwin arm64
- Integration: opencode

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Start in shared_infra.py at install_shared_infra and inspect how top-level templates are copied, then compare that with PresetResolver.collect_all_layers() and its templates/commands lookup. Reproduce with the provided specify init and preset commands; done means command templates are available under .specify/templates/commands/ and a wrap preset registers its composed command.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
cli, tooling
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Activo
Claridad
Bien especificado
Aptitud para principiantes
74/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.