3333
3434NEW_VERSION=" $1 "
3535
36- if [[ ! $NEW_VERSION =~ ^v[0-9]+\. [0-9]+\. [0-9]+$ ]]; then
36+ if [[ ! $NEW_VERSION =~ ^v[0-9]+\. [0-9]+\. [0-9]+ (-. * ) ? $ ]]; then
3737
3838 echo " Version must look like v0.0.0" >&2
3939
@@ -46,8 +46,10 @@ PACKAGE_VERSION=${NEW_VERSION#v}
4646
4747echo " Building release packages for $NEW_VERSION (packages will use $PACKAGE_VERSION )"
4848
49- rm -rf sdd-package-base* sdd-* -package-* spec-kit-template-* -${NEW_VERSION} .zip || true
50- rm -rf sdd-package-base* sdd-* -package-* spec-kit-template-* -${PACKAGE_VERSION} .zip || true
49+ # Create and use .genreleases directory for all build artifacts
50+ GENRELEASES_DIR=" .genreleases"
51+ mkdir -p " $GENRELEASES_DIR "
52+ rm -rf " $GENRELEASES_DIR " /* || true
5153
5254rewrite_paths () {
5355 sed -E \
@@ -66,7 +68,7 @@ generate_commands() {
6668
6769 [[ -f " $template " ]] || continue
6870
69- local name description script_command body
71+ local name description script_command agent_script_command body
7072
7173 name=$( basename " $template " .md)
7274
@@ -88,18 +90,36 @@ generate_commands() {
8890
8991 fi
9092
93+ # Extract agent_script command from YAML frontmatter if present
94+ agent_script_command=$( printf ' %s\n' " $file_content " | awk '
95+ /^agent_scripts:$/ { in_agent_scripts=1; next }
96+ in_agent_scripts && /^[[:space:]]*' " $script_variant " ' :[[:space:]]*/ {
97+ sub(/^[[:space:]]*' " $script_variant " ' :[[:space:]]*/, "")
98+ print
99+ exit
100+ }
101+ in_agent_scripts && /^[a-zA-Z]/ { in_agent_scripts=0 }
102+ ' )
103+
91104 # Replace {SCRIPT} placeholder with the script command
92105
93106 body=$( printf ' %s\n' " $file_content " | sed " s|{SCRIPT}|${script_command} |g" )
94107
95- # Remove the scripts: section from frontmatter while preserving YAML structure
108+ # Replace {AGENT_SCRIPT} placeholder with the agent script command if found
109+ if [[ -n $agent_script_command ]]; then
110+ body=$( printf ' %s\n' " $body " | sed " s|{AGENT_SCRIPT}|${agent_script_command} |g" )
111+ fi
112+
113+ # Remove the scripts: and agent_scripts: sections from frontmatter while preserving YAML structure
96114
97115 body=$( printf ' %s\n' " $body " | awk '
98116
99117 /^---$/ { print; if (++dash_count == 1) in_frontmatter=1; else in_frontmatter=0; next }
100118
101119 in_frontmatter && /^scripts:$/ { skip_scripts=1; next }
102120
121+ in_frontmatter && /^agent_scripts:$/ { skip_scripts=1; next }
122+
103123 in_frontmatter && /^[a-zA-Z].*:/ && skip_scripts { skip_scripts=0 }
104124
105125 in_frontmatter && skip_scripts && /^[[:space:]]/ { next }
@@ -116,13 +136,15 @@ generate_commands() {
116136
117137 toml)
118138
139+ body=$( printf ' %s\n' " $body " | sed ' s/\\/\\\\/g' )
140+
119141 { echo " description = \" $description \" " ; echo ; echo " prompt = \"\"\" " ; echo " $body " ; echo " \"\"\" " ; } > " $output_dir /speckit.$name .$ext " ;;
120142
121143 md)
122144
123145 echo " $body " > " $output_dir /speckit.$name .$ext " ;;
124146
125- prompt .md)
147+ agent .md)
126148
127149 echo " $body " > " $output_dir /speckit.$name .$ext " ;;
128150
@@ -132,11 +154,31 @@ generate_commands() {
132154
133155}
134156
157+ generate_copilot_prompts () {
158+ local agents_dir=$1 prompts_dir=$2
159+ mkdir -p " $prompts_dir "
160+
161+ # Generate a .prompt.md file for each .agent.md file
162+ for agent_file in " $agents_dir " /speckit.* .agent.md; do
163+ [[ -f " $agent_file " ]] || continue
164+
165+ local basename=$( basename " $agent_file " .agent.md)
166+ local prompt_file=" $prompts_dir /${basename} .prompt.md"
167+
168+ # Create prompt file with agent frontmatter
169+ cat > " $prompt_file " << EOF
170+ ---
171+ agent: ${basename}
172+ ---
173+ EOF
174+ done
175+ }
176+
135177build_variant () {
136178
137179 local agent=$1 script=$2
138180
139- local base_dir=" sdd-${agent} -package-${script} "
181+ local base_dir=" $GENRELEASES_DIR / sdd-${agent} -package-${script} "
140182
141183 echo " Building $agent ($script ) package..."
142184
@@ -164,7 +206,9 @@ build_variant() {
164206
165207 # Copy any script files that aren't in variant-specific directories
166208
167- find scripts -maxdepth 1 -type f -exec cp {} " $SPEC_DIR /scripts/" \; 2> /dev/null || true
209+ for script_file in scripts/* ; do
210+ [[ -f " $script_file " ]] && cp " $script_file " " $SPEC_DIR /scripts/"
211+ done 2> /dev/null || true
168212
169213 ;;
170214
@@ -174,15 +218,17 @@ build_variant() {
174218
175219 # Copy any script files that aren't in variant-specific directories
176220
177- find scripts -maxdepth 1 -type f -exec cp {} " $SPEC_DIR /scripts/" \; 2> /dev/null || true
221+ for script_file in scripts/* ; do
222+ [[ -f " $script_file " ]] && cp " $script_file " " $SPEC_DIR /scripts/"
223+ done 2> /dev/null || true
178224
179225 ;;
180226
181227 esac
182228
183229 fi
184230
185- [[ -d templates ]] && { mkdir -p " $SPEC_DIR /templates" ; find templates -type f -not -path " templates/commands/*" -exec cp --parents {} " $SPEC_DIR " / \; ; echo " Copied templates -> .specify/templates" ; }
231+ [[ -d templates ]] && { mkdir -p " $SPEC_DIR /templates" ; find templates -type f -not -path " templates/commands/*" -not -name " vscode-settings.json " - exec cp --parents {} " $SPEC_DIR " / \; 2> /dev/null || true ; echo " Copied templates -> .specify/templates" ; }
186232
187233 # Inject variant into plan-template.md within .specify/templates if present
188234
@@ -240,9 +286,17 @@ build_variant() {
240286
241287 copilot)
242288
243- mkdir -p " $base_dir /.github/prompts"
289+ mkdir -p " $base_dir /.github/agents"
290+
291+ generate_commands copilot agent.md " \$ ARGUMENTS" " $base_dir /.github/agents" " $script "
244292
245- generate_commands copilot prompt.md " \$ ARGUMENTS" " $base_dir /.github/prompts" " $script " ;;
293+ # Generate companion prompt files
294+ generate_copilot_prompts " $base_dir /.github/agents" " $base_dir /.github/prompts"
295+
296+ # Create VS Code workspace settings
297+ mkdir -p " $base_dir /.vscode"
298+
299+ [[ -f templates/vscode-settings.json ]] && cp templates/vscode-settings.json " $base_dir /.vscode/settings.json" ;;
246300
247301 cursor-agent)
248302
@@ -306,51 +360,77 @@ build_variant() {
306360
307361 generate_commands codebuddy md " \$ ARGUMENTS" " $base_dir /.codebuddy/commands" " $script " ;;
308362
363+ amp)
364+
365+ mkdir -p " $base_dir /.agents/commands"
366+
367+ generate_commands amp md " \$ ARGUMENTS" " $base_dir /.agents/commands" " $script " ;;
368+
369+ shai)
370+
371+ mkdir -p " $base_dir /.shai/commands"
372+
373+ generate_commands shai md " \$ ARGUMENTS" " $base_dir /.shai/commands" " $script " ;;
374+
375+ q)
376+
377+ mkdir -p " $base_dir /.amazonq/prompts"
378+
379+ generate_commands q md " \$ ARGUMENTS" " $base_dir /.amazonq/prompts" " $script " ;;
380+
381+ bob)
382+
383+ mkdir -p " $base_dir /.bob/commands"
384+
385+ generate_commands bob md " \$ ARGUMENTS" " $base_dir /.bob/commands" " $script " ;;
386+
309387 esac
310388
311- ( cd " $base_dir " && zip -r " ../spec-kit-template-${agent} -${script} -${PACKAGE_VERSION } .zip" . )
389+ ( cd " $base_dir " && zip -r " ../spec-kit-template-${agent} -${script} -${NEW_VERSION } .zip" . )
312390
313- echo " Created spec-kit-template-${agent} -${script} -${PACKAGE_VERSION } .zip"
391+ echo " Created $GENRELEASES_DIR / spec-kit-template-${agent} -${script} -${NEW_VERSION } .zip"
314392
315393}
316394
317395# Determine agent list
318396
319- ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo q codebuddy )
397+ ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo codebuddy amp shai q bob )
320398
321399ALL_SCRIPTS=(sh ps)
322400
323401norm_list () {
324402
325- # convert comma+space separated -> space separated unique while preserving order of first occurrence
403+ # convert comma+space separated -> line separated unique while preserving order of first occurrence
326404
327- tr ' ,\n' ' ' | awk ' {for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?" ":"") $i)}}}END{printf("\n")}'
405+ tr ' ,\n' ' ' | awk ' {for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?"\n ":"") $i);out=1 }}}END{printf("\n")}'
328406
329407}
330408
331409validate_subset () {
332410
333- local type=$1 ; shift ; local -n allowed =$1 ; shift ; local items=($@ )
411+ local type=$1 ; shift ; local allowed_name =$1 ; shift ; local items=(" $@ " )
334412
335- local ok=1
413+ local invalid=0
336414
337415 for it in " ${items[@]} " ; do
338416
339417 local found=0
340418
341- for a in " ${allowed[@]} " ; do [[ $it == $a ]] && { found=1; break ; }; done
419+ eval " allowed=(\"\$ {${allowed_name} [@]}\" )"
420+
421+ for a in " ${allowed[@]} " ; do [[ $it == " $a " ]] && { found=1; break ; }; done
342422
343423 if [[ $found -eq 0 ]]; then
344424
345425 echo " Error: unknown $type '$it ' (allowed: ${allowed[*]} )" >&2
346426
347- ok=0
427+ invalid=1
348428
349429 fi
350430
351431 done
352432
353- return $ok
433+ return $invalid
354434
355435}
356436
@@ -362,7 +442,7 @@ if [[ -n ${AGENTS:-} ]]; then
362442
363443else
364444
365- AGENT_LIST=(${ALL_AGENTS[@]} )
445+ AGENT_LIST=(" ${ALL_AGENTS[@]} " )
366446
367447fi
368448
@@ -374,7 +454,7 @@ if [[ -n ${SCRIPTS:-} ]]; then
374454
375455else
376456
377- SCRIPT_LIST=(${ALL_SCRIPTS[@]} )
457+ SCRIPT_LIST=(" ${ALL_SCRIPTS[@]} " )
378458
379459fi
380460
@@ -392,6 +472,6 @@ for agent in "${AGENT_LIST[@]}"; do
392472
393473done
394474
395- echo " Archives:"
475+ echo " Archives in $GENRELEASES_DIR :"
396476
397- ls -1 spec-kit-template-* -${PACKAGE_VERSION} .zip
477+ ls -1 " $GENRELEASES_DIR " / spec-kit-template-* -" ${NEW_VERSION} " .zip
0 commit comments