feat(scripts): add SPECIFY_INIT_DIR to target a member project from the repo root#2892
feat(scripts): add SPECIFY_INIT_DIR to target a member project from the repo root#2892PascalThuet wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a SPECIFY_INIT_DIR environment variable to let Spec Kit Bash/PowerShell scripts explicitly target a specific member project (the directory containing .specify/) when invoked from outside that project (e.g., monorepo root or CI), with strict validation and no silent fallback behavior.
Changes:
- Added
SPECIFY_INIT_DIRresolvers to core Bash/PowerShell common scripts and threaded the resolved root through feature path/branch resolution. - Updated bundled extension scripts (git + agent-context) to honor
SPECIFY_INIT_DIR, including “legacy core scripts” fallback behavior in the git extension. - Added targeted tests and documented the new environment variable in core docs.
Show a summary per file
| File | Description |
|---|---|
tests/test_init_dir.py |
New end-to-end tests for SPECIFY_INIT_DIR resolution/validation across Bash, PowerShell, and extension entrypoints. |
tests/extensions/git/test_git_extension.py |
Adds compatibility tests ensuring the git extension can honor SPECIFY_INIT_DIR even with legacy core scripts. |
scripts/powershell/common.ps1 |
Introduces Resolve-SpecifyInitDir and makes Get-RepoRoot prefer SPECIFY_INIT_DIR. |
scripts/bash/create-new-feature.sh |
Ensures get_repo_root failures propagate (fail-fast) when resolving the repo root. |
scripts/bash/common.sh |
Adds resolve_specify_init_dir and ensures get_repo_root failures propagate through key call sites. |
extensions/git/scripts/powershell/git-common.ps1 |
Adds extension-local Resolve-SpecifyInitDir for legacy-core compatibility. |
extensions/git/scripts/powershell/create-new-feature.ps1 |
Uses SPECIFY_INIT_DIR as the highest-priority repo-root selector with legacy-core fallback. |
extensions/git/scripts/powershell/auto-commit.ps1 |
Honors SPECIFY_INIT_DIR for auto-commit repo root selection. |
extensions/git/scripts/bash/git-common.sh |
Adds extension-local resolve_specify_init_dir for legacy-core compatibility. |
extensions/git/scripts/bash/create-new-feature.sh |
Uses SPECIFY_INIT_DIR as highest-priority repo-root selector with legacy-core fallback. |
extensions/git/scripts/bash/auto-commit.sh |
Honors SPECIFY_INIT_DIR for auto-commit repo root selection. |
extensions/agent-context/scripts/powershell/update-agent-context.ps1 |
Resolves project root via SPECIFY_INIT_DIR when set. |
extensions/agent-context/scripts/bash/update-agent-context.sh |
Resolves project root via SPECIFY_INIT_DIR when set. |
docs/reference/core.md |
Documents SPECIFY_INIT_DIR behavior and its interaction with feature selection variables. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 14/14 changed files
- Comments generated: 3
Architectural feedbackThanks for the thorough work here — the strict contract (must exist + must contain However, the resolver duplication across 3 script families (core, git-common, agent-context) diverges from how other env var overrides work in Spec Kit. Compare with
This eliminates ~60 lines of duplicated validation and the drift risk across 3 independent copies, while keeping the strict fail-fast behavior you designed. |
|
@mnriem done — centralized on the core resolver and dropped the per-extension resolver copies.
One gap this exposed: if Updated on behalf of @PascalThuet by Codex (GPT-5). |
e933b4a to
69efb21
Compare
…he repo root Resolve an explicit SPECIFY_INIT_DIR project override once in the core get_repo_root / Get-RepoRoot, so a non-interactive / CI caller can target a member project (the directory containing .specify/) from a monorepo root without cd. Strict by design: the path must exist and contain .specify/, otherwise it hard-errors with no silent fallback. - Single resolver in core; the git feature-branch script inherits it by sourcing core, with no per-extension copies. - PS resolver verifies the resolved path is a directory (Resolve-Path also succeeds for files) so a file value errors as "not an existing directory". - get_feature_paths splits decl/assignment so a SPECIFY_INIT_DIR failure propagates instead of being masked by `local`. - create-new-feature-branch: when core is absent (only git-common loaded) and SPECIFY_INIT_DIR is set, hard-error rather than silently using the git root. - Document SPECIFY_INIT_DIR and SPECIFY_FEATURE_DIRECTORY in the core reference. - Tests for valid/relative/trailing-slash/file/missing/no-.specify targets, feature-axis composition, the no-core guard, and a PowerShell mirror.
69efb21 to
facd309
Compare
mnriem
left a comment
There was a problem hiding this comment.
Please resolve conflicts
Summary
Adds
SPECIFY_INIT_DIRas an explicit project-root override for Spec Kit scripts that may be invoked from outside the target project, such as a monorepo root or CI task.Behavior
SPECIFY_INIT_DIR=/path/to/projectmakes supported core scripts operate on that Spec Kit project..specify/.cwdor the git toplevel.SPECIFY_INIT_DIRis set but only minimal or stale core helpers are available, it errors instead of guessing a root.Changes
SPECIFY_INIT_DIRin the core common scripts.Validation
uv run pytest tests/test_init_dir.py tests/extensions/git/test_git_extension.py -quvx ruff check tests/extensions/git/test_git_extension.pybash -n extensions/git/scripts/bash/create-new-feature-branch.sh scripts/bash/common.sh scripts/bash/create-new-feature.shgit diff --checkpwshis not available in my local environment, so PowerShell runtime tests are included but skipped locally.