You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every specify init call commits the full Spec Kit tooling stack into the repository:
.specify/extensions/*/ — full extension source (commands, scripts, changelogs, READMEs)
.specify/scripts/bash/ — hundreds of lines of bash scripts
.specify/templates/ — spec/plan/tasks templates
.specify/integrations/ — integration manifests
.cursor/skills/speckit-* — SKILL.md files for every command
This is the right zero-setup default, but it conflates two fundamentally different concerns:
Tooling — the skills, scripts, templates, and extension source that make specify work. These are the same across every repo using the same version and extension set. They belong at the user/IDE level, not committed to each repo.
Project state — the constitution, extension config, and init options that are genuinely repo-specific. These belong committed.
The result is repos accumulating thousands of lines of Spec Kit infrastructure that agents (Claude Code, Cursor, Windsurf, etc.) index and treat as part of the codebase. This is the root cause behind #1401 — not just a context window issue, but a signal-to-noise problem: agents surface Spec Kit boilerplate when searching for product code, and LLMs pay token costs for content that carries no project-specific information.
Proposed Solution
A --global flag (or a dedicated specify install command) that installs the tooling layer to the user's IDE/agent config directory rather than the repo:
# Install tooling globally once (per developer machine)
specify install --global
# Init a repo — commits only project state
specify init --here
Global layer (~/.cursor/skills/, ~/.specify/, ~/.agents/skills/, etc.):
speckit-* SKILL.md files
Extension source (.specify/extensions/*/)
Bash/PowerShell scripts
Templates
Integration manifests
Repo layer (committed):
.specify/memory/constitution.md
.specify/extensions.yml (enabled/disabled per repo)
.specify/extensions/.registry (installed state)
.specify/init-options.json, integration.json
Why This Is the Right Architecture
The skills, scripts, and extension source are versioned tooling — identical across every repo on the same manifest. Committing them to each repo is analogous to committing node_modules or a virtualenv. The conventional solution is: install tooling once, commit only the lockfile.
The constitution and extension config are project-specific state — they vary per repo and carry meaningful context for agents. These should stay committed.
Complements the skills-based approach (already the right direction for Cursor) by extending the same principle to all agents and to the repo itself
Does not require changes to the default behavior — specify init without --global continues to work as today
Migration Path
For repos already fully committed:
specify migrate --global # moves tooling to global, gitignores it, commits only project state
A generated .gitignore patch would cover .specify/extensions/, .specify/scripts/, .specify/templates/, .cursor/skills/speckit-*, etc. A post-clone setup hook (e.g. postCreateCommand in devcontainer, or make setup) would run specify install to restore the tooling layer.
Additional Context
This pattern is how most modern developer tooling works: the tool itself lives outside the repo, only its configuration is committed. Spec Kit is mature enough that this separation makes sense.
Problem Statement
Every
specify initcall commits the full Spec Kit tooling stack into the repository:.specify/extensions/*/— full extension source (commands, scripts, changelogs, READMEs).specify/scripts/bash/— hundreds of lines of bash scripts.specify/templates/— spec/plan/tasks templates.specify/integrations/— integration manifests.cursor/skills/speckit-*— SKILL.md files for every commandThis is the right zero-setup default, but it conflates two fundamentally different concerns:
specifywork. These are the same across every repo using the same version and extension set. They belong at the user/IDE level, not committed to each repo.The result is repos accumulating thousands of lines of Spec Kit infrastructure that agents (Claude Code, Cursor, Windsurf, etc.) index and treat as part of the codebase. This is the root cause behind #1401 — not just a context window issue, but a signal-to-noise problem: agents surface Spec Kit boilerplate when searching for product code, and LLMs pay token costs for content that carries no project-specific information.
Proposed Solution
A
--globalflag (or a dedicatedspecify installcommand) that installs the tooling layer to the user's IDE/agent config directory rather than the repo:Global layer (
~/.cursor/skills/,~/.specify/,~/.agents/skills/, etc.):speckit-*SKILL.md files.specify/extensions/*/)Repo layer (committed):
.specify/memory/constitution.md.specify/extensions.yml(enabled/disabled per repo).specify/extensions/.registry(installed state).specify/init-options.json,integration.jsonWhy This Is the Right Architecture
The skills, scripts, and extension source are versioned tooling — identical across every repo on the same manifest. Committing them to each repo is analogous to committing
node_modulesor a virtualenv. The conventional solution is: install tooling once, commit only the lockfile.The constitution and extension config are project-specific state — they vary per repo and carry meaningful context for agents. These should stay committed.
Relationship to Existing Issues
specify initwithout--globalcontinues to work as todayMigration Path
For repos already fully committed:
specify migrate --global # moves tooling to global, gitignores it, commits only project stateA generated
.gitignorepatch would cover.specify/extensions/,.specify/scripts/,.specify/templates/,.cursor/skills/speckit-*, etc. A post-clone setup hook (e.g.postCreateCommandin devcontainer, ormake setup) would runspecify installto restore the tooling layer.Additional Context
This pattern is how most modern developer tooling works: the tool itself lives outside the repo, only its configuration is committed. Spec Kit is mature enough that this separation makes sense.