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.
Files changed (70) hide show
  1. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/lint.yml +2 -0
  2. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/create-github-release.sh +6 -0
  3. specify_cli-1.0.0/.github/workflows/scripts/create-release-packages.ps1 +424 -0
  4. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/create-release-packages.sh +41 -10
  5. {specify_cli-0.0.20 → specify_cli-1.0.0}/.gitignore +1 -0
  6. {specify_cli-0.0.20 → specify_cli-1.0.0}/.markdownlint-cli2.jsonc +4 -1
  7. {specify_cli-0.0.20 → specify_cli-1.0.0}/AGENTS.md +39 -20
  8. {specify_cli-0.0.20 → specify_cli-1.0.0}/CHANGELOG.md +16 -0
  9. {specify_cli-0.0.20 → specify_cli-1.0.0}/CODE_OF_CONDUCT.md +1 -1
  10. {specify_cli-0.0.20 → specify_cli-1.0.0}/CONTRIBUTING.md +6 -5
  11. {specify_cli-0.0.20 → specify_cli-1.0.0}/PKG-INFO +1 -1
  12. {specify_cli-0.0.20 → specify_cli-1.0.0}/README.md +84 -63
  13. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/index.md +1 -0
  14. specify_cli-1.0.0/docs/quickstart.md +164 -0
  15. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/toc.yml +2 -1
  16. specify_cli-1.0.0/docs/upgrade.md +444 -0
  17. {specify_cli-0.0.20 → specify_cli-1.0.0}/pyproject.toml +1 -1
  18. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/check-prerequisites.sh +1 -1
  19. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/common.sh +1 -1
  20. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/create-new-feature.sh +73 -36
  21. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/setup-plan.sh +1 -1
  22. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/bash/update-agent-context.sh +33 -6
  23. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/create-new-feature.ps1 +59 -66
  24. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/setup-plan.ps1 +0 -1
  25. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/update-agent-context.ps1 +14 -5
  26. {specify_cli-0.0.20 → specify_cli-1.0.0}/spec-driven.md +9 -0
  27. {specify_cli-0.0.20 → specify_cli-1.0.0}/src/specify_cli/__init__.py +165 -6
  28. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/clarify.md +4 -0
  29. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/constitution.md +5 -1
  30. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/implement.md +2 -2
  31. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/plan.md +8 -0
  32. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/specify.md +14 -5
  33. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/tasks.md +10 -1
  34. specify_cli-1.0.0/templates/commands/taskstoissues.md +33 -0
  35. specify_cli-0.0.20/docs/quickstart.md +0 -123
  36. {specify_cli-0.0.20 → specify_cli-1.0.0}/.devcontainer/devcontainer.json +0 -0
  37. {specify_cli-0.0.20 → specify_cli-1.0.0}/.devcontainer/post-create.sh +0 -0
  38. {specify_cli-0.0.20 → specify_cli-1.0.0}/.gitattributes +0 -0
  39. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/CODEOWNERS +0 -0
  40. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/docs.yml +0 -0
  41. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/pypi.yml +0 -0
  42. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/release.yml +0 -0
  43. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/check-release-exists.sh +0 -0
  44. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/generate-release-notes.sh +0 -0
  45. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/get-next-version.sh +0 -0
  46. {specify_cli-0.0.20 → specify_cli-1.0.0}/.github/workflows/scripts/update-version.sh +0 -0
  47. {specify_cli-0.0.20 → specify_cli-1.0.0}/LICENSE +0 -0
  48. {specify_cli-0.0.20 → specify_cli-1.0.0}/SECURITY.md +0 -0
  49. {specify_cli-0.0.20 → specify_cli-1.0.0}/SUPPORT.md +0 -0
  50. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/.gitignore +0 -0
  51. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/README.md +0 -0
  52. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/docfx.json +0 -0
  53. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/installation.md +0 -0
  54. {specify_cli-0.0.20 → specify_cli-1.0.0}/docs/local-development.md +0 -0
  55. {specify_cli-0.0.20 → specify_cli-1.0.0}/media/bootstrap-claude-code.gif +0 -0
  56. {specify_cli-0.0.20 → specify_cli-1.0.0}/media/logo_large.webp +0 -0
  57. {specify_cli-0.0.20 → specify_cli-1.0.0}/media/logo_small.webp +0 -0
  58. {specify_cli-0.0.20 → specify_cli-1.0.0}/media/spec-kit-video-header.jpg +0 -0
  59. {specify_cli-0.0.20 → specify_cli-1.0.0}/media/specify_cli.gif +0 -0
  60. {specify_cli-0.0.20 → specify_cli-1.0.0}/memory/constitution.md +0 -0
  61. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/check-prerequisites.ps1 +0 -0
  62. {specify_cli-0.0.20 → specify_cli-1.0.0}/scripts/powershell/common.ps1 +0 -0
  63. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/agent-file-template.md +0 -0
  64. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/checklist-template.md +0 -0
  65. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/analyze.md +0 -0
  66. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/commands/checklist.md +0 -0
  67. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/plan-template.md +0 -0
  68. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/spec-template.md +0 -0
  69. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/tasks-template.md +0 -0
  70. {specify_cli-0.0.20 → specify_cli-1.0.0}/templates/vscode-settings.json +0 -0
@@ -1,4 +1,6 @@
1
1
  name: Lint
2
+ permissions:
3
+ contents: read
2
4
 
3
5
  on:
4
6
  push:
@@ -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
+ }
@@ -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
- prompt.md)
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/prompts"
150
- generate_commands copilot prompt.md "\$ARGUMENTS" "$base_dir/.github/prompts" "$script"
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 -> space separated unique while preserving order of first occurrence
200
- tr ',\n' ' ' | awk '{for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?" ":"") $i)}}}END{printf("\n")}'
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 ok=1
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
- ok=0
242
+ invalid=1
212
243
  fi
213
244
  done
214
- return $ok
245
+ return $invalid
215
246
  }
216
247
 
217
248
  if [[ -n ${AGENTS:-} ]]; then
@@ -32,6 +32,7 @@ env/
32
32
  *.swp
33
33
  *.swo
34
34
  .DS_Store
35
+ *.tmp
35
36
 
36
37
  # Project specific
37
38
  *.log
@@ -20,5 +20,8 @@
20
20
  "MD050": {
21
21
  "style": "asterisk"
22
22
  }
23
- }
23
+ },
24
+ "ignores": [
25
+ ".genreleases/"
26
+ ]
24
27
  }