mirror of
https://github.com/github/spec-kit.git
synced 2026-03-19 11:53:08 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36d97235ad | ||
|
|
4afbd87abb | ||
|
|
b562438df9 | ||
|
|
9111699cd2 | ||
|
|
0049b1cdc2 | ||
|
|
3e883fa32c | ||
|
|
baeb829ed4 | ||
|
|
236bcb3987 | ||
|
|
6c3d698959 | ||
|
|
dadda123f0 | ||
|
|
b4e1c07817 | ||
|
|
f65bf6ccb7 | ||
|
|
a0ca101aa4 | ||
|
|
bf5ae42085 | ||
|
|
33df8976ca |
@@ -34,7 +34,8 @@ rewrite_paths() {
|
|||||||
sed -E \
|
sed -E \
|
||||||
-e 's@(/?)memory/@.specify/memory/@g' \
|
-e 's@(/?)memory/@.specify/memory/@g' \
|
||||||
-e 's@(/?)scripts/@.specify/scripts/@g' \
|
-e 's@(/?)scripts/@.specify/scripts/@g' \
|
||||||
-e 's@(/?)templates/@.specify/templates/@g'
|
-e 's@(/?)templates/@.specify/templates/@g' \
|
||||||
|
-e 's@\.specify\.specify/@.specify/@g'
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_commands() {
|
generate_commands() {
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
},
|
},
|
||||||
"MD050": {
|
"MD050": {
|
||||||
"style": "asterisk"
|
"style": "asterisk"
|
||||||
}
|
},
|
||||||
|
"MD036": false,
|
||||||
|
"MD060": false
|
||||||
},
|
},
|
||||||
"ignores": [
|
"ignores": [
|
||||||
".genreleases/"
|
".genreleases/"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Specify supports multiple AI agents by generating agent-specific command files a
|
|||||||
### Current Supported Agents
|
### Current Supported Agents
|
||||||
|
|
||||||
| Agent | Directory | Format | CLI Tool | Description |
|
| Agent | Directory | Format | CLI Tool | Description |
|
||||||
|-------|-----------|---------|----------|-------------|
|
| -------------------------- | ---------------------- | -------- | --------------- | --------------------------- |
|
||||||
| **Claude Code** | `.claude/commands/` | Markdown | `claude` | Anthropic's Claude Code CLI |
|
| **Claude Code** | `.claude/commands/` | Markdown | `claude` | Anthropic's Claude Code CLI |
|
||||||
| **Gemini CLI** | `.gemini/commands/` | TOML | `gemini` | Google's Gemini CLI |
|
| **Gemini CLI** | `.gemini/commands/` | TOML | `gemini` | Google's Gemini CLI |
|
||||||
| **GitHub Copilot** | `.github/agents/` | Markdown | N/A (IDE-based) | GitHub Copilot in VS Code |
|
| **GitHub Copilot** | `.github/agents/` | Markdown | N/A (IDE-based) | GitHub Copilot in VS Code |
|
||||||
|
|||||||
@@ -71,13 +71,13 @@ To test your templates, commands, and other changes locally, follow these steps:
|
|||||||
|
|
||||||
Run the following command to generate the local packages:
|
Run the following command to generate the local packages:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
./.github/workflows/scripts/create-release-packages.sh v1.0.0
|
./.github/workflows/scripts/create-release-packages.sh v1.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Copy the relevant package to your test project**
|
2. **Copy the relevant package to your test project**
|
||||||
|
|
||||||
```
|
```bash
|
||||||
cp -r .genreleases/sdd-copilot-package-sh/. <path-to-test-project>/
|
cp -r .genreleases/sdd-copilot-package-sh/. <path-to-test-project>/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -57,7 +57,15 @@ uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
|
|||||||
Then use the tool directly:
|
Then use the tool directly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Create new project
|
||||||
specify init <PROJECT_NAME>
|
specify init <PROJECT_NAME>
|
||||||
|
|
||||||
|
# Or initialize in existing project
|
||||||
|
specify init . --ai claude
|
||||||
|
# or
|
||||||
|
specify init --here --ai claude
|
||||||
|
|
||||||
|
# Check installed tools
|
||||||
specify check
|
specify check
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -135,7 +143,7 @@ Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.c
|
|||||||
## 🤖 Supported AI Agents
|
## 🤖 Supported AI Agents
|
||||||
|
|
||||||
| Agent | Support | Notes |
|
| Agent | Support | Notes |
|
||||||
|-----------------------------------------------------------|---------|---------------------------------------------------|
|
| ------------------------------------------------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [Qoder CLI](https://qoder.com/cli) | ✅ | |
|
| [Qoder CLI](https://qoder.com/cli) | ✅ | |
|
||||||
| [Amazon Q Developer CLI](https://aws.amazon.com/developer/learning/q-developer-cli/) | ⚠️ | Amazon Q Developer CLI [does not support](https://github.com/aws/amazon-q-developer-cli/issues/3064) custom arguments for slash commands. |
|
| [Amazon Q Developer CLI](https://aws.amazon.com/developer/learning/q-developer-cli/) | ⚠️ | Amazon Q Developer CLI [does not support](https://github.com/aws/amazon-q-developer-cli/issues/3064) custom arguments for slash commands. |
|
||||||
| [Amp](https://ampcode.com/) | ✅ | |
|
| [Amp](https://ampcode.com/) | ✅ | |
|
||||||
@@ -162,14 +170,14 @@ The `specify` command supports the following options:
|
|||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|-------------|----------------------------------------------------------------|
|
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `init` | Initialize a new Specify project from the latest template |
|
| `init` | Initialize a new Specify project from the latest template |
|
||||||
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `cursor-agent`, `windsurf`, `qwen`, `opencode`, `codex`, `shai`, `qoder`) |
|
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `cursor-agent`, `windsurf`, `qwen`, `opencode`, `codex`, `shai`, `qoder`) |
|
||||||
|
|
||||||
### `specify init` Arguments & Options
|
### `specify init` Arguments & Options
|
||||||
|
|
||||||
| Argument/Option | Type | Description |
|
| Argument/Option | Type | Description |
|
||||||
|------------------------|----------|------------------------------------------------------------------------------|
|
| ---------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`, or use `.` for current directory) |
|
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`, or use `.` for current directory) |
|
||||||
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor-agent`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, `amp`, `shai`, `q`, `bob`, or `qoder` |
|
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor-agent`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, `amp`, `shai`, `q`, `bob`, or `qoder` |
|
||||||
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) |
|
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) |
|
||||||
@@ -243,7 +251,7 @@ After running `specify init`, your AI coding agent will have access to these sla
|
|||||||
Essential commands for the Spec-Driven Development workflow:
|
Essential commands for the Spec-Driven Development workflow:
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|--------------------------|-----------------------------------------------------------------------|
|
| ----------------------- | ------------------------------------------------------------------------ |
|
||||||
| `/speckit.constitution` | Create or update project governing principles and development guidelines |
|
| `/speckit.constitution` | Create or update project governing principles and development guidelines |
|
||||||
| `/speckit.specify` | Define what you want to build (requirements and user stories) |
|
| `/speckit.specify` | Define what you want to build (requirements and user stories) |
|
||||||
| `/speckit.plan` | Create technical implementation plans with your chosen tech stack |
|
| `/speckit.plan` | Create technical implementation plans with your chosen tech stack |
|
||||||
@@ -255,7 +263,7 @@ Essential commands for the Spec-Driven Development workflow:
|
|||||||
Additional commands for enhanced quality and validation:
|
Additional commands for enhanced quality and validation:
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|----------------------|-----------------------------------------------------------------------|
|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `/speckit.clarify` | Clarify underspecified areas (recommended before `/speckit.plan`; formerly `/quizme`) |
|
| `/speckit.clarify` | Clarify underspecified areas (recommended before `/speckit.plan`; formerly `/quizme`) |
|
||||||
| `/speckit.analyze` | Cross-artifact consistency & coverage analysis (run after `/speckit.tasks`, before `/speckit.implement`) |
|
| `/speckit.analyze` | Cross-artifact consistency & coverage analysis (run after `/speckit.tasks`, before `/speckit.implement`) |
|
||||||
| `/speckit.checklist` | Generate custom quality checklists that validate requirements completeness, clarity, and consistency (like "unit tests for English") |
|
| `/speckit.checklist` | Generate custom quality checklists that validate requirements completeness, clarity, and consistency (like "unit tests for English") |
|
||||||
@@ -263,8 +271,8 @@ Additional commands for enhanced quality and validation:
|
|||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|------------------|------------------------------------------------------------------------------------------------|
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `SPECIFY_FEATURE` | Override feature detection for non-Git repositories. Set to the feature directory name (e.g., `001-photo-albums`) to work on a specific feature when not using Git branches.<br/>**Must be set in the context of the agent you're working with prior to using `/speckit.plan` or follow-up commands. |
|
| `SPECIFY_FEATURE` | Override feature detection for non-Git repositories. Set to the feature directory name (e.g., `001-photo-albums`) to work on a specific feature when not using Git branches.<br/>\*\*Must be set in the context of the agent you're working with prior to using `/speckit.plan` or follow-up commands. |
|
||||||
|
|
||||||
## 📚 Core Philosophy
|
## 📚 Core Philosophy
|
||||||
|
|
||||||
@@ -278,7 +286,7 @@ Spec-Driven Development is a structured process that emphasizes:
|
|||||||
## 🌟 Development Phases
|
## 🌟 Development Phases
|
||||||
|
|
||||||
| Phase | Focus | Key Activities |
|
| Phase | Focus | Key Activities |
|
||||||
|-------|-------|----------------|
|
| ---------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| **0-to-1 Development** ("Greenfield") | Generate from scratch | <ul><li>Start with high-level requirements</li><li>Generate specifications</li><li>Plan implementation steps</li><li>Build production-ready applications</li></ul> |
|
| **0-to-1 Development** ("Greenfield") | Generate from scratch | <ul><li>Start with high-level requirements</li><li>Generate specifications</li><li>Plan implementation steps</li><li>Build production-ready applications</li></ul> |
|
||||||
| **Creative Exploration** | Parallel implementations | <ul><li>Explore diverse solutions</li><li>Support multiple technology stacks & architectures</li><li>Experiment with UX patterns</li></ul> |
|
| **Creative Exploration** | Parallel implementations | <ul><li>Explore diverse solutions</li><li>Support multiple technology stacks & architectures</li><li>Experiment with UX patterns</li></ul> |
|
||||||
| **Iterative Enhancement** ("Brownfield") | Brownfield modernization | <ul><li>Add features iteratively</li><li>Modernize legacy systems</li><li>Adapt processes</li></ul> |
|
| **Iterative Enhancement** ("Brownfield") | Brownfield modernization | <ul><li>Add features iteratively</li><li>Modernize legacy systems</li><li>Adapt processes</li></ul> |
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ specify init --here --force --ai copilot
|
|||||||
|
|
||||||
Without `--force`, the CLI warns you and asks for confirmation:
|
Without `--force`, the CLI warns you and asks for confirmation:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Warning: Current directory is not empty (25 items)
|
Warning: Current directory is not empty (25 items)
|
||||||
Template files will be merged with existing content and may overwrite existing files
|
Template files will be merged with existing content and may overwrite existing files
|
||||||
Proceed? [y/N]
|
Proceed? [y/N]
|
||||||
@@ -286,11 +286,13 @@ This tells Spec Kit which feature directory to use when creating specs, plans, a
|
|||||||
|
|
||||||
1. **Restart your IDE/editor** completely (not just reload window)
|
1. **Restart your IDE/editor** completely (not just reload window)
|
||||||
2. **For CLI-based agents**, verify files exist:
|
2. **For CLI-based agents**, verify files exist:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ls -la .claude/commands/ # Claude Code
|
ls -la .claude/commands/ # Claude Code
|
||||||
ls -la .gemini/commands/ # Gemini
|
ls -la .gemini/commands/ # Gemini
|
||||||
ls -la .cursor/commands/ # Cursor
|
ls -la .cursor/commands/ # Cursor
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Check agent-specific setup:**
|
3. **Check agent-specific setup:**
|
||||||
- Codex requires `CODEX_HOME` environment variable
|
- Codex requires `CODEX_HOME` environment variable
|
||||||
- Some agents need workspace restart or cache clearing
|
- Some agents need workspace restart or cache clearing
|
||||||
@@ -312,7 +314,8 @@ cp /tmp/constitution-backup.md .specify/memory/constitution.md
|
|||||||
### "Warning: Current directory is not empty"
|
### "Warning: Current directory is not empty"
|
||||||
|
|
||||||
**Full warning message:**
|
**Full warning message:**
|
||||||
```
|
|
||||||
|
```text
|
||||||
Warning: Current directory is not empty (25 items)
|
Warning: Current directory is not empty (25 items)
|
||||||
Template files will be merged with existing content and may overwrite existing files
|
Template files will be merged with existing content and may overwrite existing files
|
||||||
Do you want to continue? [y/N]
|
Do you want to continue? [y/N]
|
||||||
@@ -329,6 +332,7 @@ This warning appears when you run `specify init --here` (or `specify init .`) in
|
|||||||
**What gets overwritten:**
|
**What gets overwritten:**
|
||||||
|
|
||||||
Only Spec Kit infrastructure files:
|
Only Spec Kit infrastructure files:
|
||||||
|
|
||||||
- Agent command files (`.claude/commands/`, `.github/prompts/`, etc.)
|
- Agent command files (`.claude/commands/`, `.github/prompts/`, etc.)
|
||||||
- Scripts in `.specify/scripts/`
|
- Scripts in `.specify/scripts/`
|
||||||
- Templates in `.specify/templates/`
|
- Templates in `.specify/templates/`
|
||||||
@@ -346,6 +350,7 @@ Only Spec Kit infrastructure files:
|
|||||||
- **Type `y` and press Enter** - Proceed with the merge (recommended if upgrading)
|
- **Type `y` and press Enter** - Proceed with the merge (recommended if upgrading)
|
||||||
- **Type `n` and press Enter** - Cancel the operation
|
- **Type `n` and press Enter** - Cancel the operation
|
||||||
- **Use `--force` flag** - Skip this confirmation entirely:
|
- **Use `--force` flag** - Skip this confirmation entirely:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
specify init --here --force --ai copilot
|
specify init --here --force --ai copilot
|
||||||
```
|
```
|
||||||
@@ -388,6 +393,7 @@ uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
|
|||||||
**Explanation:**
|
**Explanation:**
|
||||||
|
|
||||||
The `specify` CLI tool is used for:
|
The `specify` CLI tool is used for:
|
||||||
|
|
||||||
- **Initial setup:** `specify init` to bootstrap Spec Kit in your project
|
- **Initial setup:** `specify init` to bootstrap Spec Kit in your project
|
||||||
- **Upgrades:** `specify init --here --force` to update templates and commands
|
- **Upgrades:** `specify init --here --force` to update templates and commands
|
||||||
- **Diagnostics:** `specify check` to verify tool installation
|
- **Diagnostics:** `specify check` to verify tool installation
|
||||||
@@ -397,6 +403,7 @@ Once you've run `specify init`, the slash commands (like `/speckit.specify`, `/s
|
|||||||
**If your agent isn't recognizing slash commands:**
|
**If your agent isn't recognizing slash commands:**
|
||||||
|
|
||||||
1. **Verify command files exist:**
|
1. **Verify command files exist:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# For GitHub Copilot
|
# For GitHub Copilot
|
||||||
ls -la .github/prompts/
|
ls -la .github/prompts/
|
||||||
@@ -412,6 +419,7 @@ Once you've run `specify init`, the slash commands (like `/speckit.specify`, `/s
|
|||||||
4. **For some agents**, you may need to reload the workspace or clear cache
|
4. **For some agents**, you may need to reload the workspace or clear cache
|
||||||
|
|
||||||
**Related issue:** If Copilot can't open local files or uses PowerShell commands unexpectedly, this is typically an IDE context issue, not related to `specify`. Try:
|
**Related issue:** If Copilot can't open local files or uses PowerShell commands unexpectedly, this is typically an IDE context issue, not related to `specify`. Try:
|
||||||
|
|
||||||
- Restarting VS Code
|
- Restarting VS Code
|
||||||
- Checking file permissions
|
- Checking file permissions
|
||||||
- Ensuring the workspace folder is properly opened
|
- Ensuring the workspace folder is properly opened
|
||||||
|
|||||||
@@ -128,32 +128,23 @@ get_highest_from_branches() {
|
|||||||
|
|
||||||
# Function to check existing branches (local and remote) and return next available number
|
# Function to check existing branches (local and remote) and return next available number
|
||||||
check_existing_branches() {
|
check_existing_branches() {
|
||||||
local short_name="$1"
|
local specs_dir="$1"
|
||||||
local specs_dir="$2"
|
|
||||||
|
|
||||||
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
||||||
git fetch --all --prune 2>/dev/null || true
|
git fetch --all --prune 2>/dev/null || true
|
||||||
|
|
||||||
# Find all branches matching the pattern using git ls-remote (more reliable)
|
# Get highest number from ALL branches (not just matching short name)
|
||||||
local remote_branches=$(git ls-remote --heads origin 2>/dev/null | grep -E "refs/heads/[0-9]+-${short_name}$" | sed 's/.*\/\([0-9]*\)-.*/\1/' | sort -n)
|
local highest_branch=$(get_highest_from_branches)
|
||||||
|
|
||||||
# Also check local branches
|
# Get highest number from ALL specs (not just matching short name)
|
||||||
local local_branches=$(git branch 2>/dev/null | grep -E "^[* ]*[0-9]+-${short_name}$" | sed 's/^[* ]*//' | sed 's/-.*//' | sort -n)
|
local highest_spec=$(get_highest_from_specs "$specs_dir")
|
||||||
|
|
||||||
# Check specs directory as well
|
# Take the maximum of both
|
||||||
local spec_dirs=""
|
local max_num=$highest_branch
|
||||||
if [ -d "$specs_dir" ]; then
|
if [ "$highest_spec" -gt "$max_num" ]; then
|
||||||
spec_dirs=$(find "$specs_dir" -maxdepth 1 -type d -name "[0-9]*-${short_name}" 2>/dev/null | xargs -n1 basename 2>/dev/null | sed 's/-.*//' | sort -n)
|
max_num=$highest_spec
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Combine all sources and get the highest number
|
|
||||||
local max_num=0
|
|
||||||
for num in $remote_branches $local_branches $spec_dirs; do
|
|
||||||
if [ "$num" -gt "$max_num" ]; then
|
|
||||||
max_num=$num
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Return next number
|
# Return next number
|
||||||
echo $((max_num + 1))
|
echo $((max_num + 1))
|
||||||
}
|
}
|
||||||
@@ -247,7 +238,7 @@ fi
|
|||||||
if [ -z "$BRANCH_NUMBER" ]; then
|
if [ -z "$BRANCH_NUMBER" ]; then
|
||||||
if [ "$HAS_GIT" = true ]; then
|
if [ "$HAS_GIT" = true ]; then
|
||||||
# Check existing branches on remotes
|
# Check existing branches on remotes
|
||||||
BRANCH_NUMBER=$(check_existing_branches "$BRANCH_SUFFIX" "$SPECS_DIR")
|
BRANCH_NUMBER=$(check_existing_branches "$SPECS_DIR")
|
||||||
else
|
else
|
||||||
# Fall back to local directory check
|
# Fall back to local directory check
|
||||||
HIGHEST=$(get_highest_from_specs "$SPECS_DIR")
|
HIGHEST=$(get_highest_from_specs "$SPECS_DIR")
|
||||||
@@ -255,7 +246,8 @@ if [ -z "$BRANCH_NUMBER" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FEATURE_NUM=$(printf "%03d" "$BRANCH_NUMBER")
|
# Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal)
|
||||||
|
FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))")
|
||||||
BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
|
BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
|
||||||
|
|
||||||
# GitHub enforces a 244-byte limit on branch names
|
# GitHub enforces a 244-byte limit on branch names
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ function Get-HighestNumberFromBranches {
|
|||||||
|
|
||||||
function Get-NextBranchNumber {
|
function Get-NextBranchNumber {
|
||||||
param(
|
param(
|
||||||
[string]$ShortName,
|
|
||||||
[string]$SpecsDir
|
[string]$SpecsDir
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -112,57 +111,14 @@ function Get-NextBranchNumber {
|
|||||||
# Ignore fetch errors
|
# Ignore fetch errors
|
||||||
}
|
}
|
||||||
|
|
||||||
# Find remote branches matching the pattern using git ls-remote
|
# Get highest number from ALL branches (not just matching short name)
|
||||||
$remoteBranches = @()
|
$highestBranch = Get-HighestNumberFromBranches
|
||||||
try {
|
|
||||||
$remoteRefs = git ls-remote --heads origin 2>$null
|
|
||||||
if ($remoteRefs) {
|
|
||||||
$remoteBranches = $remoteRefs | Where-Object { $_ -match "refs/heads/(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
|
||||||
if ($_ -match "refs/heads/(\d+)-") {
|
|
||||||
[int]$matches[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
# Ignore errors
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check local branches
|
# Get highest number from ALL specs (not just matching short name)
|
||||||
$localBranches = @()
|
$highestSpec = Get-HighestNumberFromSpecs -SpecsDir $SpecsDir
|
||||||
try {
|
|
||||||
$allBranches = git branch 2>$null
|
|
||||||
if ($allBranches) {
|
|
||||||
$localBranches = $allBranches | Where-Object { $_ -match "^\*?\s*(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
|
||||||
if ($_ -match "(\d+)-") {
|
|
||||||
[int]$matches[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
# Ignore errors
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check specs directory
|
# Take the maximum of both
|
||||||
$specDirs = @()
|
$maxNum = [Math]::Max($highestBranch, $highestSpec)
|
||||||
if (Test-Path $SpecsDir) {
|
|
||||||
try {
|
|
||||||
$specDirs = Get-ChildItem -Path $SpecsDir -Directory | Where-Object { $_.Name -match "^(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
|
||||||
if ($_.Name -match "^(\d+)-") {
|
|
||||||
[int]$matches[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
# Ignore errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Combine all sources and get the highest number
|
|
||||||
$maxNum = 0
|
|
||||||
foreach ($num in ($remoteBranches + $localBranches + $specDirs)) {
|
|
||||||
if ($num -gt $maxNum) {
|
|
||||||
$maxNum = $num
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Return next number
|
# Return next number
|
||||||
return $maxNum + 1
|
return $maxNum + 1
|
||||||
@@ -254,7 +210,7 @@ if ($ShortName) {
|
|||||||
if ($Number -eq 0) {
|
if ($Number -eq 0) {
|
||||||
if ($hasGit) {
|
if ($hasGit) {
|
||||||
# Check existing branches on remotes
|
# Check existing branches on remotes
|
||||||
$Number = Get-NextBranchNumber -ShortName $branchSuffix -SpecsDir $specsDir
|
$Number = Get-NextBranchNumber -SpecsDir $specsDir
|
||||||
} else {
|
} else {
|
||||||
# Fall back to local directory check
|
# Fall back to local directory check
|
||||||
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
|
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ The templates include comprehensive checklists that act as "unit tests" for the
|
|||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
### Requirement Completeness
|
### Requirement Completeness
|
||||||
|
|
||||||
- [ ] No [NEEDS CLARIFICATION] markers remain
|
- [ ] No [NEEDS CLARIFICATION] markers remain
|
||||||
- [ ] Requirements are testable and unambiguous
|
- [ ] Requirements are testable and unambiguous
|
||||||
- [ ] Success criteria are measurable
|
- [ ] Success criteria are measurable
|
||||||
@@ -208,10 +209,14 @@ The implementation plan template enforces architectural principles through phase
|
|||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
### Phase -1: Pre-Implementation Gates
|
### Phase -1: Pre-Implementation Gates
|
||||||
|
|
||||||
#### Simplicity Gate (Article VII)
|
#### Simplicity Gate (Article VII)
|
||||||
|
|
||||||
- [ ] Using ≤3 projects?
|
- [ ] Using ≤3 projects?
|
||||||
- [ ] No future-proofing?
|
- [ ] No future-proofing?
|
||||||
|
|
||||||
#### Anti-Abstraction Gate (Article VIII)
|
#### Anti-Abstraction Gate (Article VIII)
|
||||||
|
|
||||||
- [ ] Using framework directly?
|
- [ ] Using framework directly?
|
||||||
- [ ] Single model representation?
|
- [ ] Single model representation?
|
||||||
```
|
```
|
||||||
@@ -347,15 +352,19 @@ The implementation plan template operationalizes these articles through concrete
|
|||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
### Phase -1: Pre-Implementation Gates
|
### Phase -1: Pre-Implementation Gates
|
||||||
|
|
||||||
#### Simplicity Gate (Article VII)
|
#### Simplicity Gate (Article VII)
|
||||||
|
|
||||||
- [ ] Using ≤3 projects?
|
- [ ] Using ≤3 projects?
|
||||||
- [ ] No future-proofing?
|
- [ ] No future-proofing?
|
||||||
|
|
||||||
#### Anti-Abstraction Gate (Article VIII)
|
#### Anti-Abstraction Gate (Article VIII)
|
||||||
|
|
||||||
- [ ] Using framework directly?
|
- [ ] Using framework directly?
|
||||||
- [ ] Single model representation?
|
- [ ] Single model representation?
|
||||||
|
|
||||||
#### Integration-First Gate (Article IX)
|
#### Integration-First Gate (Article IX)
|
||||||
|
|
||||||
- [ ] Contracts defined?
|
- [ ] Contracts defined?
|
||||||
- [ ] Contract tests written?
|
- [ ] Contract tests written?
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -942,6 +942,41 @@ def ensure_executable_scripts(project_path: Path, tracker: StepTracker | None =
|
|||||||
for f in failures:
|
for f in failures:
|
||||||
console.print(f" - {f}")
|
console.print(f" - {f}")
|
||||||
|
|
||||||
|
def ensure_constitution_from_template(project_path: Path, tracker: StepTracker | None = None) -> None:
|
||||||
|
"""Copy constitution template to memory if it doesn't exist (preserves existing constitution on reinitialization)."""
|
||||||
|
memory_constitution = project_path / ".specify" / "memory" / "constitution.md"
|
||||||
|
template_constitution = project_path / ".specify" / "templates" / "constitution-template.md"
|
||||||
|
|
||||||
|
# If constitution already exists in memory, preserve it
|
||||||
|
if memory_constitution.exists():
|
||||||
|
if tracker:
|
||||||
|
tracker.add("constitution", "Constitution setup")
|
||||||
|
tracker.skip("constitution", "existing file preserved")
|
||||||
|
return
|
||||||
|
|
||||||
|
# If template doesn't exist, something went wrong with extraction
|
||||||
|
if not template_constitution.exists():
|
||||||
|
if tracker:
|
||||||
|
tracker.add("constitution", "Constitution setup")
|
||||||
|
tracker.error("constitution", "template not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Copy template to memory directory
|
||||||
|
try:
|
||||||
|
memory_constitution.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copy2(template_constitution, memory_constitution)
|
||||||
|
if tracker:
|
||||||
|
tracker.add("constitution", "Constitution setup")
|
||||||
|
tracker.complete("constitution", "copied from template")
|
||||||
|
else:
|
||||||
|
console.print(f"[cyan]Initialized constitution from template[/cyan]")
|
||||||
|
except Exception as e:
|
||||||
|
if tracker:
|
||||||
|
tracker.add("constitution", "Constitution setup")
|
||||||
|
tracker.error("constitution", str(e))
|
||||||
|
else:
|
||||||
|
console.print(f"[yellow]Warning: Could not initialize constitution: {e}[/yellow]")
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def init(
|
def init(
|
||||||
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here, or use '.' for current directory)"),
|
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here, or use '.' for current directory)"),
|
||||||
@@ -1108,6 +1143,7 @@ def init(
|
|||||||
("zip-list", "Archive contents"),
|
("zip-list", "Archive contents"),
|
||||||
("extracted-summary", "Extraction summary"),
|
("extracted-summary", "Extraction summary"),
|
||||||
("chmod", "Ensure scripts executable"),
|
("chmod", "Ensure scripts executable"),
|
||||||
|
("constitution", "Constitution setup"),
|
||||||
("cleanup", "Cleanup"),
|
("cleanup", "Cleanup"),
|
||||||
("git", "Initialize git repository"),
|
("git", "Initialize git repository"),
|
||||||
("final", "Finalize")
|
("final", "Finalize")
|
||||||
@@ -1128,6 +1164,8 @@ def init(
|
|||||||
|
|
||||||
ensure_executable_scripts(project_path, tracker=tracker)
|
ensure_executable_scripts(project_path, tracker=tracker)
|
||||||
|
|
||||||
|
ensure_constitution_from_template(project_path, tracker=tracker)
|
||||||
|
|
||||||
if not no_git:
|
if not no_git:
|
||||||
tracker.start("git")
|
tracker.start("git")
|
||||||
if is_git_repo(project_path):
|
if is_git_repo(project_path):
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ You **MUST** consider the user input before proceeding (if not empty).
|
|||||||
|
|
||||||
## Outline
|
## Outline
|
||||||
|
|
||||||
You are updating the project constitution at `/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
|
You are updating the project constitution at `.specify/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
|
||||||
|
|
||||||
|
**Note**: If `.specify/memory/constitution.md` does not exist yet, it should have been initialized from `.specify/templates/constitution-template.md` during project setup. If it's missing, copy the template first.
|
||||||
|
|
||||||
Follow this execution flow:
|
Follow this execution flow:
|
||||||
|
|
||||||
1. Load the existing constitution template at `/memory/constitution.md`.
|
1. Load the existing constitution at `.specify/memory/constitution.md`.
|
||||||
- Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`.
|
- Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`.
|
||||||
**IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly.
|
**IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly.
|
||||||
|
|
||||||
@@ -41,10 +43,10 @@ Follow this execution flow:
|
|||||||
- Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations.
|
- Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations.
|
||||||
|
|
||||||
4. Consistency propagation checklist (convert prior checklist into active validations):
|
4. Consistency propagation checklist (convert prior checklist into active validations):
|
||||||
- Read `/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
|
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
|
||||||
- Read `/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
|
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
|
||||||
- Read `/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
|
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
|
||||||
- Read each command file in `/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
|
- Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
|
||||||
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
|
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
|
||||||
|
|
||||||
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
|
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
|
||||||
@@ -61,7 +63,7 @@ Follow this execution flow:
|
|||||||
- Dates ISO format YYYY-MM-DD.
|
- Dates ISO format YYYY-MM-DD.
|
||||||
- Principles are declarative, testable, and free of vague language ("should" → replace with MUST/SHOULD rationale where appropriate).
|
- Principles are declarative, testable, and free of vague language ("should" → replace with MUST/SHOULD rationale where appropriate).
|
||||||
|
|
||||||
7. Write the completed constitution back to `/memory/constitution.md` (overwrite).
|
7. Write the completed constitution back to `.specify/memory/constitution.md` (overwrite).
|
||||||
|
|
||||||
8. Output a final summary to the user with:
|
8. Output a final summary to the user with:
|
||||||
- New version and bump rationale.
|
- New version and bump rationale.
|
||||||
@@ -79,4 +81,4 @@ If the user supplies partial updates (e.g., only one principle revision), still
|
|||||||
|
|
||||||
If critical info missing (e.g., ratification date truly unknown), insert `TODO(<FIELD_NAME>): explanation` and include in the Sync Impact Report under deferred items.
|
If critical info missing (e.g., ratification date truly unknown), insert `TODO(<FIELD_NAME>): explanation` and include in the Sync Impact Report under deferred items.
|
||||||
|
|
||||||
Do not create a new template; always operate on the existing `/memory/constitution.md` file.
|
Do not create a new template; always operate on the existing `.specify/memory/constitution.md` file.
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ Given that feature description, do this:
|
|||||||
2. **Check for existing branches before creating new one**:
|
2. **Check for existing branches before creating new one**:
|
||||||
|
|
||||||
a. First, fetch all remote branches to ensure we have the latest information:
|
a. First, fetch all remote branches to ensure we have the latest information:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fetch --all --prune
|
git fetch --all --prune
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ You **MUST** consider the user input before proceeding (if not empty).
|
|||||||
git config --get remote.origin.url
|
git config --get remote.origin.url
|
||||||
```
|
```
|
||||||
|
|
||||||
**ONLY PROCEED TO NEXT STEPS IF THE REMOTE IS A GITHUB URL**
|
> [!CAUTION]
|
||||||
|
> ONLY PROCEED TO NEXT STEPS IF THE REMOTE IS A GITHUB URL
|
||||||
|
|
||||||
1. For each task in the list, use the GitHub MCP server to create a new issue in the repository that is representative of the Git remote.
|
1. For each task in the list, use the GitHub MCP server to create a new issue in the repository that is representative of the Git remote.
|
||||||
|
|
||||||
**UNDER NO CIRCUMSTANCES EVER CREATE ISSUES IN REPOSITORIES THAT DO NOT MATCH THE REMOTE URL**
|
> [!CAUTION]
|
||||||
|
> UNDER NO CIRCUMSTANCES EVER CREATE ISSUES IN REPOSITORIES THAT DO NOT MATCH THE REMOTE URL
|
||||||
|
|||||||
Reference in New Issue
Block a user