-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Description
Summary
Embed the core template pack (templates, commands, and scripts) inside the specify-cli Python package so that specify init can scaffold projects entirely from local assets without calling the GitHub API. This eliminates the last hardcoded external network dependency and enables air-gapped deployment.
Problem Statement
After #1707 (multi-catalog) and #1708 (pluggable templates with scripts), every network touchpoint in Spec Kit becomes configurable — except one:
specify init always calls https://api.github.com/repos/github/spec-kit/releases/latest to fetch and download a release ZIP. This is hardcoded in download_template_from_github() (__init__.py L677) and cannot be redirected to an internal server.
On an air-gapped network where extension and template catalogs point at internal HTTPS servers (#1707, #1708), specify init still fails because it can't reach api.github.com.
Proposed Solution
1. Bundle core assets inside the pip package
Ship templates, commands, and scripts as package data within specify-cli:
src/specify_cli/
__init__.py
extensions.py
core_pack/ # NEW: shipped with pip install
template-pack.yml # Standard #1708 manifest
templates/
spec-template.md
plan-template.md
tasks-template.md
checklist-template.md
constitution-template.md
agent-file-template.md
commands/
specify.md
plan.md
tasks.md
implement.md
...
scripts/
bash/
create-new-feature.sh
setup-plan.sh
common.sh
check-prerequisites.sh
update-agent-context.sh
powershell/
create-new-feature.ps1
setup-plan.ps1
common.ps1
check-prerequisites.ps1
update-agent-context.ps1
2. Update pyproject.toml to include non-Python files
[tool.hatch.build.targets.wheel]
packages = ["src/specify_cli"]
[tool.hatch.build.targets.wheel.force-include]
"templates" = "specify_cli/core_pack/templates"
"templates/commands" = "specify_cli/core_pack/commands"
"scripts" = "specify_cli/core_pack/scripts"3. Add local scaffolding function
New scaffold_from_core_pack() function that replaces download_and_extract_template() as the default init path:
- Uses
importlib.resourcesto locate bundled assets - Copies templates →
.specify/templates/ - Copies scripts (bash or powershell) →
.specify/scripts/ - Generates agent-specific command files (the
{SCRIPT}substitution, TOML conversion for Gemini/Qwen, frontmatter transforms for Copilot, etc.)
4. Port agent command generation to Python
The generate_commands() function in create-release-packages.sh (frontmatter parsing, {SCRIPT} placeholder substitution, Markdown → TOML conversion, $ARGUMENTS vs {{args}}) needs a Python equivalent so specify init can generate agent-specific command files at runtime.
5. Keep download as optional fallback
Retain download_and_extract_template() behind a flag (e.g., specify init --from-github) for users who want the latest release without upgrading the CLI.
Acceptance Criteria
-
specify initscaffolds a complete project from embedded assets with no network calls - All supported agents produce correct command files (Markdown, TOML, agent.md) from embedded command templates
-
specify init --from-githubretains current behavior (download from GitHub API) -
pip install specify-cliincludes all core templates, commands, and scripts - Existing
create-release-packages.shcontinues to work (kept for manual ZIP distribution) - Air-gapped deployment works: install CLI via pip (from internal PyPI mirror), configure catalogs to internal URLs (feat(extensions): support multiple active catalogs simultaneously #1707),
specify initsucceeds without external network access
Dependencies
- feat(extensions): support multiple active catalogs simultaneously #1707 — Multi-catalog support (redirectable catalog URLs)
- feat(templates): Pluggable Template System with Template Catalog #1708 — Pluggable template system with
type: "script"support (template pack manifest design)
Out of Scope
- Removing release ZIPs entirely (kept as supplementary distribution for non-pip users)
- Private PyPI mirror setup documentation (org-specific)
- Catalog mirroring tooling
References
- Current GitHub API dependency:
src/specify_cli/__init__.pyL677, L1661 - Release build script:
.github/workflows/scripts/create-release-packages.sh generate_commands()shell function: ~60 lines of awk/sed for agent-specific transforms