specify-cli 0.0.20__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/lint.yml +2 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/create-github-release.sh +6 -0
- specify_cli-1.0.0/.github/workflows/scripts/create-release-packages.ps1 +424 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/create-release-packages.sh +41 -10
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.gitignore +1 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.markdownlint-cli2.jsonc +4 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/AGENTS.md +39 -20
- {specify_cli-0.0.20 → specify_cli-1.0.0}/CHANGELOG.md +16 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/CODE_OF_CONDUCT.md +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/CONTRIBUTING.md +6 -5
- {specify_cli-0.0.20 → specify_cli-1.0.0}/PKG-INFO +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/README.md +84 -63
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/index.md +1 -0
- specify_cli-1.0.0/docs/quickstart.md +164 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/toc.yml +2 -1
- specify_cli-1.0.0/docs/upgrade.md +444 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/pyproject.toml +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/check-prerequisites.sh +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/common.sh +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/create-new-feature.sh +73 -36
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/setup-plan.sh +1 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/update-agent-context.sh +33 -6
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/create-new-feature.ps1 +59 -66
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/setup-plan.ps1 +0 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/update-agent-context.ps1 +14 -5
- {specify_cli-0.0.20 → specify_cli-1.0.0}/spec-driven.md +9 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/src/specify_cli/__init__.py +165 -6
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/clarify.md +4 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/constitution.md +5 -1
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/implement.md +2 -2
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/plan.md +8 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/specify.md +14 -5
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/tasks.md +10 -1
- specify_cli-1.0.0/templates/commands/taskstoissues.md +33 -0
- specify_cli-0.0.20/docs/quickstart.md +0 -123
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.devcontainer/devcontainer.json +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.devcontainer/post-create.sh +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.gitattributes +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/CODEOWNERS +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/docs.yml +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/pypi.yml +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/release.yml +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/check-release-exists.sh +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/generate-release-notes.sh +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/get-next-version.sh +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/update-version.sh +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/LICENSE +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/SECURITY.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/SUPPORT.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/.gitignore +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/README.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/docfx.json +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/installation.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/local-development.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/media/bootstrap-claude-code.gif +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/media/logo_large.webp +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/media/logo_small.webp +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/media/spec-kit-video-header.jpg +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/media/specify_cli.gif +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/memory/constitution.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/common.ps1 +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/agent-file-template.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/checklist-template.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/analyze.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/checklist.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/plan-template.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/spec-template.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/tasks-template.md +0 -0
- {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/vscode-settings.json +0 -0
|
@@ -40,9 +40,15 @@ gh release create "$VERSION" \
|
|
|
40
40
|
.genreleases/spec-kit-template-roo-ps-"$VERSION".zip \
|
|
41
41
|
.genreleases/spec-kit-template-codebuddy-sh-"$VERSION".zip \
|
|
42
42
|
.genreleases/spec-kit-template-codebuddy-ps-"$VERSION".zip \
|
|
43
|
+
.genreleases/spec-kit-template-qoder-sh-"$VERSION".zip \
|
|
44
|
+
.genreleases/spec-kit-template-qoder-ps-"$VERSION".zip \
|
|
43
45
|
.genreleases/spec-kit-template-amp-sh-"$VERSION".zip \
|
|
44
46
|
.genreleases/spec-kit-template-amp-ps-"$VERSION".zip \
|
|
47
|
+
.genreleases/spec-kit-template-shai-sh-"$VERSION".zip \
|
|
48
|
+
.genreleases/spec-kit-template-shai-ps-"$VERSION".zip \
|
|
45
49
|
.genreleases/spec-kit-template-q-sh-"$VERSION".zip \
|
|
46
50
|
.genreleases/spec-kit-template-q-ps-"$VERSION".zip \
|
|
51
|
+
.genreleases/spec-kit-template-bob-sh-"$VERSION".zip \
|
|
52
|
+
.genreleases/spec-kit-template-bob-ps-"$VERSION".zip \
|
|
47
53
|
--title "Spec Kit Templates - $VERSION_NO_V" \
|
|
48
54
|
--notes-file release_notes.md
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
#requires -Version 7.0
|
|
3
|
+
|
|
4
|
+
<#
|
|
5
|
+
.SYNOPSIS
|
|
6
|
+
Build Spec Kit template release archives for each supported AI assistant and script type.
|
|
7
|
+
|
|
8
|
+
.DESCRIPTION
|
|
9
|
+
create-release-packages.ps1 (workflow-local)
|
|
10
|
+
Build Spec Kit template release archives for each supported AI assistant and script type.
|
|
11
|
+
|
|
12
|
+
.PARAMETER Version
|
|
13
|
+
Version string with leading 'v' (e.g., v0.2.0)
|
|
14
|
+
|
|
15
|
+
.PARAMETER Agents
|
|
16
|
+
Comma or space separated subset of agents to build (default: all)
|
|
17
|
+
Valid agents: claude, gemini, copilot, cursor-agent, qwen, opencode, windsurf, codex, kilocode, auggie, roo, codebuddy, amp, q, bob, qoder
|
|
18
|
+
|
|
19
|
+
.PARAMETER Scripts
|
|
20
|
+
Comma or space separated subset of script types to build (default: both)
|
|
21
|
+
Valid scripts: sh, ps
|
|
22
|
+
|
|
23
|
+
.EXAMPLE
|
|
24
|
+
.\create-release-packages.ps1 -Version v0.2.0
|
|
25
|
+
|
|
26
|
+
.EXAMPLE
|
|
27
|
+
.\create-release-packages.ps1 -Version v0.2.0 -Agents claude,copilot -Scripts sh
|
|
28
|
+
|
|
29
|
+
.EXAMPLE
|
|
30
|
+
.\create-release-packages.ps1 -Version v0.2.0 -Agents claude -Scripts ps
|
|
31
|
+
#>
|
|
32
|
+
|
|
33
|
+
param(
|
|
34
|
+
[Parameter(Mandatory=$true, Position=0)]
|
|
35
|
+
[string]$Version,
|
|
36
|
+
|
|
37
|
+
[Parameter(Mandatory=$false)]
|
|
38
|
+
[string]$Agents = "",
|
|
39
|
+
|
|
40
|
+
[Parameter(Mandatory=$false)]
|
|
41
|
+
[string]$Scripts = ""
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
$ErrorActionPreference = "Stop"
|
|
45
|
+
|
|
46
|
+
# Validate version format
|
|
47
|
+
if ($Version -notmatch '^v\d+\.\d+\.\d+$') {
|
|
48
|
+
Write-Error "Version must look like v0.0.0"
|
|
49
|
+
exit 1
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Write-Host "Building release packages for $Version"
|
|
53
|
+
|
|
54
|
+
# Create and use .genreleases directory for all build artifacts
|
|
55
|
+
$GenReleasesDir = ".genreleases"
|
|
56
|
+
if (Test-Path $GenReleasesDir) {
|
|
57
|
+
Remove-Item -Path $GenReleasesDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
58
|
+
}
|
|
59
|
+
New-Item -ItemType Directory -Path $GenReleasesDir -Force | Out-Null
|
|
60
|
+
|
|
61
|
+
function Rewrite-Paths {
|
|
62
|
+
param([string]$Content)
|
|
63
|
+
|
|
64
|
+
$Content = $Content -replace '(/?)\bmemory/', '.specify/memory/'
|
|
65
|
+
$Content = $Content -replace '(/?)\bscripts/', '.specify/scripts/'
|
|
66
|
+
$Content = $Content -replace '(/?)\btemplates/', '.specify/templates/'
|
|
67
|
+
return $Content
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function Generate-Commands {
|
|
71
|
+
param(
|
|
72
|
+
[string]$Agent,
|
|
73
|
+
[string]$Extension,
|
|
74
|
+
[string]$ArgFormat,
|
|
75
|
+
[string]$OutputDir,
|
|
76
|
+
[string]$ScriptVariant
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
|
|
80
|
+
|
|
81
|
+
$templates = Get-ChildItem -Path "templates/commands/*.md" -File -ErrorAction SilentlyContinue
|
|
82
|
+
|
|
83
|
+
foreach ($template in $templates) {
|
|
84
|
+
$name = [System.IO.Path]::GetFileNameWithoutExtension($template.Name)
|
|
85
|
+
|
|
86
|
+
# Read file content and normalize line endings
|
|
87
|
+
$fileContent = (Get-Content -Path $template.FullName -Raw) -replace "`r`n", "`n"
|
|
88
|
+
|
|
89
|
+
# Extract description from YAML frontmatter
|
|
90
|
+
$description = ""
|
|
91
|
+
if ($fileContent -match '(?m)^description:\s*(.+)$') {
|
|
92
|
+
$description = $matches[1]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Extract script command from YAML frontmatter
|
|
96
|
+
$scriptCommand = ""
|
|
97
|
+
if ($fileContent -match "(?m)^\s*${ScriptVariant}:\s*(.+)$") {
|
|
98
|
+
$scriptCommand = $matches[1]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if ([string]::IsNullOrEmpty($scriptCommand)) {
|
|
102
|
+
Write-Warning "No script command found for $ScriptVariant in $($template.Name)"
|
|
103
|
+
$scriptCommand = "(Missing script command for $ScriptVariant)"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# Extract agent_script command from YAML frontmatter if present
|
|
107
|
+
$agentScriptCommand = ""
|
|
108
|
+
if ($fileContent -match "(?ms)agent_scripts:.*?^\s*${ScriptVariant}:\s*(.+?)$") {
|
|
109
|
+
$agentScriptCommand = $matches[1].Trim()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Replace {SCRIPT} placeholder with the script command
|
|
113
|
+
$body = $fileContent -replace '\{SCRIPT\}', $scriptCommand
|
|
114
|
+
|
|
115
|
+
# Replace {AGENT_SCRIPT} placeholder with the agent script command if found
|
|
116
|
+
if (-not [string]::IsNullOrEmpty($agentScriptCommand)) {
|
|
117
|
+
$body = $body -replace '\{AGENT_SCRIPT\}', $agentScriptCommand
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# Remove the scripts: and agent_scripts: sections from frontmatter
|
|
121
|
+
$lines = $body -split "`n"
|
|
122
|
+
$outputLines = @()
|
|
123
|
+
$inFrontmatter = $false
|
|
124
|
+
$skipScripts = $false
|
|
125
|
+
$dashCount = 0
|
|
126
|
+
|
|
127
|
+
foreach ($line in $lines) {
|
|
128
|
+
if ($line -match '^---$') {
|
|
129
|
+
$outputLines += $line
|
|
130
|
+
$dashCount++
|
|
131
|
+
if ($dashCount -eq 1) {
|
|
132
|
+
$inFrontmatter = $true
|
|
133
|
+
} else {
|
|
134
|
+
$inFrontmatter = $false
|
|
135
|
+
}
|
|
136
|
+
continue
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if ($inFrontmatter) {
|
|
140
|
+
if ($line -match '^(scripts|agent_scripts):$') {
|
|
141
|
+
$skipScripts = $true
|
|
142
|
+
continue
|
|
143
|
+
}
|
|
144
|
+
if ($line -match '^[a-zA-Z].*:' -and $skipScripts) {
|
|
145
|
+
$skipScripts = $false
|
|
146
|
+
}
|
|
147
|
+
if ($skipScripts -and $line -match '^\s+') {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
$outputLines += $line
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
$body = $outputLines -join "`n"
|
|
156
|
+
|
|
157
|
+
# Apply other substitutions
|
|
158
|
+
$body = $body -replace '\{ARGS\}', $ArgFormat
|
|
159
|
+
$body = $body -replace '__AGENT__', $Agent
|
|
160
|
+
$body = Rewrite-Paths -Content $body
|
|
161
|
+
|
|
162
|
+
# Generate output file based on extension
|
|
163
|
+
$outputFile = Join-Path $OutputDir "speckit.$name.$Extension"
|
|
164
|
+
|
|
165
|
+
switch ($Extension) {
|
|
166
|
+
'toml' {
|
|
167
|
+
$body = $body -replace '\\', '\\'
|
|
168
|
+
$output = "description = `"$description`"`n`nprompt = `"`"`"`n$body`n`"`"`""
|
|
169
|
+
Set-Content -Path $outputFile -Value $output -NoNewline
|
|
170
|
+
}
|
|
171
|
+
'md' {
|
|
172
|
+
Set-Content -Path $outputFile -Value $body -NoNewline
|
|
173
|
+
}
|
|
174
|
+
'agent.md' {
|
|
175
|
+
Set-Content -Path $outputFile -Value $body -NoNewline
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function Generate-CopilotPrompts {
|
|
182
|
+
param(
|
|
183
|
+
[string]$AgentsDir,
|
|
184
|
+
[string]$PromptsDir
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
New-Item -ItemType Directory -Path $PromptsDir -Force | Out-Null
|
|
188
|
+
|
|
189
|
+
$agentFiles = Get-ChildItem -Path "$AgentsDir/speckit.*.agent.md" -File -ErrorAction SilentlyContinue
|
|
190
|
+
|
|
191
|
+
foreach ($agentFile in $agentFiles) {
|
|
192
|
+
$basename = $agentFile.Name -replace '\.agent\.md$', ''
|
|
193
|
+
$promptFile = Join-Path $PromptsDir "$basename.prompt.md"
|
|
194
|
+
|
|
195
|
+
$content = @"
|
|
196
|
+
---
|
|
197
|
+
agent: $basename
|
|
198
|
+
---
|
|
199
|
+
"@
|
|
200
|
+
Set-Content -Path $promptFile -Value $content
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function Build-Variant {
|
|
205
|
+
param(
|
|
206
|
+
[string]$Agent,
|
|
207
|
+
[string]$Script
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
$baseDir = Join-Path $GenReleasesDir "sdd-${Agent}-package-${Script}"
|
|
211
|
+
Write-Host "Building $Agent ($Script) package..."
|
|
212
|
+
New-Item -ItemType Directory -Path $baseDir -Force | Out-Null
|
|
213
|
+
|
|
214
|
+
# Copy base structure but filter scripts by variant
|
|
215
|
+
$specDir = Join-Path $baseDir ".specify"
|
|
216
|
+
New-Item -ItemType Directory -Path $specDir -Force | Out-Null
|
|
217
|
+
|
|
218
|
+
# Copy memory directory
|
|
219
|
+
if (Test-Path "memory") {
|
|
220
|
+
Copy-Item -Path "memory" -Destination $specDir -Recurse -Force
|
|
221
|
+
Write-Host "Copied memory -> .specify"
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# Only copy the relevant script variant directory
|
|
225
|
+
if (Test-Path "scripts") {
|
|
226
|
+
$scriptsDestDir = Join-Path $specDir "scripts"
|
|
227
|
+
New-Item -ItemType Directory -Path $scriptsDestDir -Force | Out-Null
|
|
228
|
+
|
|
229
|
+
switch ($Script) {
|
|
230
|
+
'sh' {
|
|
231
|
+
if (Test-Path "scripts/bash") {
|
|
232
|
+
Copy-Item -Path "scripts/bash" -Destination $scriptsDestDir -Recurse -Force
|
|
233
|
+
Write-Host "Copied scripts/bash -> .specify/scripts"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
'ps' {
|
|
237
|
+
if (Test-Path "scripts/powershell") {
|
|
238
|
+
Copy-Item -Path "scripts/powershell" -Destination $scriptsDestDir -Recurse -Force
|
|
239
|
+
Write-Host "Copied scripts/powershell -> .specify/scripts"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# Copy any script files that aren't in variant-specific directories
|
|
245
|
+
Get-ChildItem -Path "scripts" -File -ErrorAction SilentlyContinue | ForEach-Object {
|
|
246
|
+
Copy-Item -Path $_.FullName -Destination $scriptsDestDir -Force
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# Copy templates (excluding commands directory and vscode-settings.json)
|
|
251
|
+
if (Test-Path "templates") {
|
|
252
|
+
$templatesDestDir = Join-Path $specDir "templates"
|
|
253
|
+
New-Item -ItemType Directory -Path $templatesDestDir -Force | Out-Null
|
|
254
|
+
|
|
255
|
+
Get-ChildItem -Path "templates" -Recurse -File | Where-Object {
|
|
256
|
+
$_.FullName -notmatch 'templates[/\\]commands[/\\]' -and $_.Name -ne 'vscode-settings.json'
|
|
257
|
+
} | ForEach-Object {
|
|
258
|
+
$relativePath = $_.FullName.Substring((Resolve-Path "templates").Path.Length + 1)
|
|
259
|
+
$destFile = Join-Path $templatesDestDir $relativePath
|
|
260
|
+
$destFileDir = Split-Path $destFile -Parent
|
|
261
|
+
New-Item -ItemType Directory -Path $destFileDir -Force | Out-Null
|
|
262
|
+
Copy-Item -Path $_.FullName -Destination $destFile -Force
|
|
263
|
+
}
|
|
264
|
+
Write-Host "Copied templates -> .specify/templates"
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# Generate agent-specific command files
|
|
268
|
+
switch ($Agent) {
|
|
269
|
+
'claude' {
|
|
270
|
+
$cmdDir = Join-Path $baseDir ".claude/commands"
|
|
271
|
+
Generate-Commands -Agent 'claude' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
272
|
+
}
|
|
273
|
+
'gemini' {
|
|
274
|
+
$cmdDir = Join-Path $baseDir ".gemini/commands"
|
|
275
|
+
Generate-Commands -Agent 'gemini' -Extension 'toml' -ArgFormat '{{args}}' -OutputDir $cmdDir -ScriptVariant $Script
|
|
276
|
+
if (Test-Path "agent_templates/gemini/GEMINI.md") {
|
|
277
|
+
Copy-Item -Path "agent_templates/gemini/GEMINI.md" -Destination (Join-Path $baseDir "GEMINI.md")
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
'copilot' {
|
|
281
|
+
$agentsDir = Join-Path $baseDir ".github/agents"
|
|
282
|
+
Generate-Commands -Agent 'copilot' -Extension 'agent.md' -ArgFormat '$ARGUMENTS' -OutputDir $agentsDir -ScriptVariant $Script
|
|
283
|
+
|
|
284
|
+
# Generate companion prompt files
|
|
285
|
+
$promptsDir = Join-Path $baseDir ".github/prompts"
|
|
286
|
+
Generate-CopilotPrompts -AgentsDir $agentsDir -PromptsDir $promptsDir
|
|
287
|
+
|
|
288
|
+
# Create VS Code workspace settings
|
|
289
|
+
$vscodeDir = Join-Path $baseDir ".vscode"
|
|
290
|
+
New-Item -ItemType Directory -Path $vscodeDir -Force | Out-Null
|
|
291
|
+
if (Test-Path "templates/vscode-settings.json") {
|
|
292
|
+
Copy-Item -Path "templates/vscode-settings.json" -Destination (Join-Path $vscodeDir "settings.json")
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
'cursor-agent' {
|
|
296
|
+
$cmdDir = Join-Path $baseDir ".cursor/commands"
|
|
297
|
+
Generate-Commands -Agent 'cursor-agent' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
298
|
+
}
|
|
299
|
+
'qwen' {
|
|
300
|
+
$cmdDir = Join-Path $baseDir ".qwen/commands"
|
|
301
|
+
Generate-Commands -Agent 'qwen' -Extension 'toml' -ArgFormat '{{args}}' -OutputDir $cmdDir -ScriptVariant $Script
|
|
302
|
+
if (Test-Path "agent_templates/qwen/QWEN.md") {
|
|
303
|
+
Copy-Item -Path "agent_templates/qwen/QWEN.md" -Destination (Join-Path $baseDir "QWEN.md")
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
'opencode' {
|
|
307
|
+
$cmdDir = Join-Path $baseDir ".opencode/command"
|
|
308
|
+
Generate-Commands -Agent 'opencode' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
309
|
+
}
|
|
310
|
+
'windsurf' {
|
|
311
|
+
$cmdDir = Join-Path $baseDir ".windsurf/workflows"
|
|
312
|
+
Generate-Commands -Agent 'windsurf' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
313
|
+
}
|
|
314
|
+
'codex' {
|
|
315
|
+
$cmdDir = Join-Path $baseDir ".codex/prompts"
|
|
316
|
+
Generate-Commands -Agent 'codex' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
317
|
+
}
|
|
318
|
+
'kilocode' {
|
|
319
|
+
$cmdDir = Join-Path $baseDir ".kilocode/workflows"
|
|
320
|
+
Generate-Commands -Agent 'kilocode' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
321
|
+
}
|
|
322
|
+
'auggie' {
|
|
323
|
+
$cmdDir = Join-Path $baseDir ".augment/commands"
|
|
324
|
+
Generate-Commands -Agent 'auggie' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
325
|
+
}
|
|
326
|
+
'roo' {
|
|
327
|
+
$cmdDir = Join-Path $baseDir ".roo/commands"
|
|
328
|
+
Generate-Commands -Agent 'roo' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
329
|
+
}
|
|
330
|
+
'codebuddy' {
|
|
331
|
+
$cmdDir = Join-Path $baseDir ".codebuddy/commands"
|
|
332
|
+
Generate-Commands -Agent 'codebuddy' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
333
|
+
}
|
|
334
|
+
'amp' {
|
|
335
|
+
$cmdDir = Join-Path $baseDir ".agents/commands"
|
|
336
|
+
Generate-Commands -Agent 'amp' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
337
|
+
}
|
|
338
|
+
'q' {
|
|
339
|
+
$cmdDir = Join-Path $baseDir ".amazonq/prompts"
|
|
340
|
+
Generate-Commands -Agent 'q' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
341
|
+
}
|
|
342
|
+
'bob' {
|
|
343
|
+
$cmdDir = Join-Path $baseDir ".bob/commands"
|
|
344
|
+
Generate-Commands -Agent 'bob' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
345
|
+
}
|
|
346
|
+
'qoder' {
|
|
347
|
+
$cmdDir = Join-Path $baseDir ".qoder/commands"
|
|
348
|
+
Generate-Commands -Agent 'qoder' -Extension 'md' -ArgFormat '$ARGUMENTS' -OutputDir $cmdDir -ScriptVariant $Script
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
# Create zip archive
|
|
353
|
+
$zipFile = Join-Path $GenReleasesDir "spec-kit-template-${Agent}-${Script}-${Version}.zip"
|
|
354
|
+
Compress-Archive -Path "$baseDir/*" -DestinationPath $zipFile -Force
|
|
355
|
+
Write-Host "Created $zipFile"
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
# Define all agents and scripts
|
|
359
|
+
$AllAgents = @('claude', 'gemini', 'copilot', 'cursor-agent', 'qwen', 'opencode', 'windsurf', 'codex', 'kilocode', 'auggie', 'roo', 'codebuddy', 'amp', 'q', 'bob', 'qoder')
|
|
360
|
+
$AllScripts = @('sh', 'ps')
|
|
361
|
+
|
|
362
|
+
function Normalize-List {
|
|
363
|
+
param([string]$Input)
|
|
364
|
+
|
|
365
|
+
if ([string]::IsNullOrEmpty($Input)) {
|
|
366
|
+
return @()
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
# Split by comma or space and remove duplicates while preserving order
|
|
370
|
+
$items = $Input -split '[,\s]+' | Where-Object { $_ } | Select-Object -Unique
|
|
371
|
+
return $items
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function Validate-Subset {
|
|
375
|
+
param(
|
|
376
|
+
[string]$Type,
|
|
377
|
+
[string[]]$Allowed,
|
|
378
|
+
[string[]]$Items
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
$ok = $true
|
|
382
|
+
foreach ($item in $Items) {
|
|
383
|
+
if ($item -notin $Allowed) {
|
|
384
|
+
Write-Error "Unknown $Type '$item' (allowed: $($Allowed -join ', '))"
|
|
385
|
+
$ok = $false
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return $ok
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
# Determine agent list
|
|
392
|
+
if (-not [string]::IsNullOrEmpty($Agents)) {
|
|
393
|
+
$AgentList = Normalize-List -Input $Agents
|
|
394
|
+
if (-not (Validate-Subset -Type 'agent' -Allowed $AllAgents -Items $AgentList)) {
|
|
395
|
+
exit 1
|
|
396
|
+
}
|
|
397
|
+
} else {
|
|
398
|
+
$AgentList = $AllAgents
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
# Determine script list
|
|
402
|
+
if (-not [string]::IsNullOrEmpty($Scripts)) {
|
|
403
|
+
$ScriptList = Normalize-List -Input $Scripts
|
|
404
|
+
if (-not (Validate-Subset -Type 'script' -Allowed $AllScripts -Items $ScriptList)) {
|
|
405
|
+
exit 1
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
$ScriptList = $AllScripts
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
Write-Host "Agents: $($AgentList -join ', ')"
|
|
412
|
+
Write-Host "Scripts: $($ScriptList -join ', ')"
|
|
413
|
+
|
|
414
|
+
# Build all variants
|
|
415
|
+
foreach ($agent in $AgentList) {
|
|
416
|
+
foreach ($script in $ScriptList) {
|
|
417
|
+
Build-Variant -Agent $agent -Script $script
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
Write-Host "`nArchives in ${GenReleasesDir}:"
|
|
422
|
+
Get-ChildItem -Path $GenReleasesDir -Filter "spec-kit-template-*-${Version}.zip" | ForEach-Object {
|
|
423
|
+
Write-Host " $($_.Name)"
|
|
424
|
+
}
|
{specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/create-release-packages.sh
RENAMED
|
@@ -6,7 +6,7 @@ set -euo pipefail
|
|
|
6
6
|
# Usage: .github/workflows/scripts/create-release-packages.sh <version>
|
|
7
7
|
# Version argument should include leading 'v'.
|
|
8
8
|
# Optionally set AGENTS and/or SCRIPTS env vars to limit what gets built.
|
|
9
|
-
# AGENTS : space or comma separated subset of: claude gemini copilot cursor-agent qwen opencode windsurf codex amp (default: all)
|
|
9
|
+
# AGENTS : space or comma separated subset of: claude gemini copilot cursor-agent qwen opencode windsurf codex amp shai bob (default: all)
|
|
10
10
|
# SCRIPTS : space or comma separated subset of: sh ps (default: both)
|
|
11
11
|
# Examples:
|
|
12
12
|
# AGENTS=claude SCRIPTS=sh $0 v0.2.0
|
|
@@ -95,12 +95,32 @@ generate_commands() {
|
|
|
95
95
|
{ echo "description = \"$description\""; echo; echo "prompt = \"\"\""; echo "$body"; echo "\"\"\""; } > "$output_dir/speckit.$name.$ext" ;;
|
|
96
96
|
md)
|
|
97
97
|
echo "$body" > "$output_dir/speckit.$name.$ext" ;;
|
|
98
|
-
|
|
98
|
+
agent.md)
|
|
99
99
|
echo "$body" > "$output_dir/speckit.$name.$ext" ;;
|
|
100
100
|
esac
|
|
101
101
|
done
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
generate_copilot_prompts() {
|
|
105
|
+
local agents_dir=$1 prompts_dir=$2
|
|
106
|
+
mkdir -p "$prompts_dir"
|
|
107
|
+
|
|
108
|
+
# Generate a .prompt.md file for each .agent.md file
|
|
109
|
+
for agent_file in "$agents_dir"/speckit.*.agent.md; do
|
|
110
|
+
[[ -f "$agent_file" ]] || continue
|
|
111
|
+
|
|
112
|
+
local basename=$(basename "$agent_file" .agent.md)
|
|
113
|
+
local prompt_file="$prompts_dir/${basename}.prompt.md"
|
|
114
|
+
|
|
115
|
+
# Create prompt file with agent frontmatter
|
|
116
|
+
cat > "$prompt_file" <<EOF
|
|
117
|
+
---
|
|
118
|
+
agent: ${basename}
|
|
119
|
+
---
|
|
120
|
+
EOF
|
|
121
|
+
done
|
|
122
|
+
}
|
|
123
|
+
|
|
104
124
|
build_variant() {
|
|
105
125
|
local agent=$1 script=$2
|
|
106
126
|
local base_dir="$GENRELEASES_DIR/sdd-${agent}-package-${script}"
|
|
@@ -146,8 +166,10 @@ build_variant() {
|
|
|
146
166
|
generate_commands gemini toml "{{args}}" "$base_dir/.gemini/commands" "$script"
|
|
147
167
|
[[ -f agent_templates/gemini/GEMINI.md ]] && cp agent_templates/gemini/GEMINI.md "$base_dir/GEMINI.md" ;;
|
|
148
168
|
copilot)
|
|
149
|
-
mkdir -p "$base_dir/.github/
|
|
150
|
-
generate_commands copilot
|
|
169
|
+
mkdir -p "$base_dir/.github/agents"
|
|
170
|
+
generate_commands copilot agent.md "\$ARGUMENTS" "$base_dir/.github/agents" "$script"
|
|
171
|
+
# Generate companion prompt files
|
|
172
|
+
generate_copilot_prompts "$base_dir/.github/agents" "$base_dir/.github/prompts"
|
|
151
173
|
# Create VS Code workspace settings
|
|
152
174
|
mkdir -p "$base_dir/.vscode"
|
|
153
175
|
[[ -f templates/vscode-settings.json ]] && cp templates/vscode-settings.json "$base_dir/.vscode/settings.json"
|
|
@@ -180,38 +202,47 @@ build_variant() {
|
|
|
180
202
|
codebuddy)
|
|
181
203
|
mkdir -p "$base_dir/.codebuddy/commands"
|
|
182
204
|
generate_commands codebuddy md "\$ARGUMENTS" "$base_dir/.codebuddy/commands" "$script" ;;
|
|
205
|
+
qoder)
|
|
206
|
+
mkdir -p "$base_dir/.qoder/commands"
|
|
207
|
+
generate_commands qoder md "\$ARGUMENTS" "$base_dir/.qoder/commands" "$script" ;;
|
|
183
208
|
amp)
|
|
184
209
|
mkdir -p "$base_dir/.agents/commands"
|
|
185
210
|
generate_commands amp md "\$ARGUMENTS" "$base_dir/.agents/commands" "$script" ;;
|
|
211
|
+
shai)
|
|
212
|
+
mkdir -p "$base_dir/.shai/commands"
|
|
213
|
+
generate_commands shai md "\$ARGUMENTS" "$base_dir/.shai/commands" "$script" ;;
|
|
186
214
|
q)
|
|
187
215
|
mkdir -p "$base_dir/.amazonq/prompts"
|
|
188
216
|
generate_commands q md "\$ARGUMENTS" "$base_dir/.amazonq/prompts" "$script" ;;
|
|
217
|
+
bob)
|
|
218
|
+
mkdir -p "$base_dir/.bob/commands"
|
|
219
|
+
generate_commands bob md "\$ARGUMENTS" "$base_dir/.bob/commands" "$script" ;;
|
|
189
220
|
esac
|
|
190
221
|
( cd "$base_dir" && zip -r "../spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" . )
|
|
191
222
|
echo "Created $GENRELEASES_DIR/spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
|
|
192
223
|
}
|
|
193
224
|
|
|
194
225
|
# Determine agent list
|
|
195
|
-
ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo codebuddy amp q)
|
|
226
|
+
ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo codebuddy amp shai q bob qoder)
|
|
196
227
|
ALL_SCRIPTS=(sh ps)
|
|
197
228
|
|
|
198
229
|
norm_list() {
|
|
199
|
-
# convert comma+space separated ->
|
|
200
|
-
tr ',\n' ' ' | awk '{for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?"
|
|
230
|
+
# convert comma+space separated -> line separated unique while preserving order of first occurrence
|
|
231
|
+
tr ',\n' ' ' | awk '{for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?"\n":"") $i);out=1}}}END{printf("\n")}'
|
|
201
232
|
}
|
|
202
233
|
|
|
203
234
|
validate_subset() {
|
|
204
235
|
local type=$1; shift; local -n allowed=$1; shift; local items=("$@")
|
|
205
|
-
local
|
|
236
|
+
local invalid=0
|
|
206
237
|
for it in "${items[@]}"; do
|
|
207
238
|
local found=0
|
|
208
239
|
for a in "${allowed[@]}"; do [[ $it == "$a" ]] && { found=1; break; }; done
|
|
209
240
|
if [[ $found -eq 0 ]]; then
|
|
210
241
|
echo "Error: unknown $type '$it' (allowed: ${allowed[*]})" >&2
|
|
211
|
-
|
|
242
|
+
invalid=1
|
|
212
243
|
fi
|
|
213
244
|
done
|
|
214
|
-
return $
|
|
245
|
+
return $invalid
|
|
215
246
|
}
|
|
216
247
|
|
|
217
248
|
if [[ -n ${AGENTS:-} ]]; then
|