diff --git a/bin/gstack-patch-names b/bin/gstack-patch-names new file mode 100755 index 00000000..bef02aae --- /dev/null +++ b/bin/gstack-patch-names @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# gstack-patch-names — patch name: field in SKILL.md frontmatter for prefix mode +# Usage: gstack-patch-names +set -euo pipefail + +GSTACK_DIR="$1" +DO_PREFIX="$2" + +# Normalize prefix arg +case "$DO_PREFIX" in true|1) DO_PREFIX=1 ;; *) DO_PREFIX=0 ;; esac + +PATCHED=0 +for skill_dir in "$GSTACK_DIR"/*/; do + [ -f "$skill_dir/SKILL.md" ] || continue + dir_name="$(basename "$skill_dir")" + [ "$dir_name" = "node_modules" ] && continue + cur=$(grep -m1 '^name:' "$skill_dir/SKILL.md" 2>/dev/null | sed 's/^name:[[:space:]]*//' | tr -d '[:space:]' || true) + [ -z "$cur" ] && continue + [ "$cur" = "gstack" ] && continue # never prefix root skill + if [ "$DO_PREFIX" -eq 1 ]; then + case "$cur" in gstack-*) continue ;; esac + new="gstack-$cur" + else + case "$cur" in gstack-*) ;; *) continue ;; esac + [ "$dir_name" = "$cur" ] && continue # inherently prefixed (gstack-upgrade) + new="${cur#gstack-}" + fi + tmp="$(mktemp "${skill_dir}/SKILL.md.XXXXXX")" + sed "1,/^---$/s/^name:[[:space:]]*${cur}/name: ${new}/" "$skill_dir/SKILL.md" > "$tmp" && mv "$tmp" "$skill_dir/SKILL.md" + PATCHED=$((PATCHED + 1)) +done +if [ "$PATCHED" -gt 0 ]; then + echo " patched name: field in $PATCHED skills" +fi diff --git a/bin/gstack-relink b/bin/gstack-relink index 49d0ccac..4647f6df 100755 --- a/bin/gstack-relink +++ b/bin/gstack-relink @@ -66,6 +66,9 @@ for skill_dir in "$INSTALL_DIR"/*/; do SKILL_COUNT=$((SKILL_COUNT + 1)) done +# Patch SKILL.md name: fields to match prefix setting +"$INSTALL_DIR/bin/gstack-patch-names" "$INSTALL_DIR" "$PREFIX" + if [ "$PREFIX" = "true" ]; then echo "Relinked $SKILL_COUNT skills as gstack-*" else diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 94f39101..ec495189 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -472,3 +472,16 @@ if (failures.length > 0 && HOST_ARG_VAL === 'all') { if (failures.some(f => f.host === 'claude')) process.exit(1); } // Single host dry-run failure already handled above + +// After all hosts processed, warn if prefix patches may need re-applying +if (!DRY_RUN) { + try { + const configPath = path.join(process.env.HOME || '', '.gstack', 'config.yaml'); + if (fs.existsSync(configPath)) { + const config = fs.readFileSync(configPath, 'utf-8'); + if (/^skill_prefix:\s*true/m.test(config)) { + console.log('\nNote: skill_prefix is true. Run gstack-relink to re-apply name: patches.'); + } + } + } catch { /* non-fatal */ } +} diff --git a/setup b/setup index d2836245..609311d5 100755 --- a/setup +++ b/setup @@ -567,6 +567,7 @@ if [ "$INSTALL_CLAUDE" -eq 1 ]; then cleanup_prefixed_claude_symlinks "$SOURCE_GSTACK_DIR" "$INSTALL_SKILLS_DIR" fi link_claude_skill_dirs "$SOURCE_GSTACK_DIR" "$INSTALL_SKILLS_DIR" + "$SOURCE_GSTACK_DIR/bin/gstack-patch-names" "$SOURCE_GSTACK_DIR" "$SKILL_PREFIX" if [ "$LOCAL_INSTALL" -eq 1 ]; then echo "gstack ready (project-local)." echo " skills: $INSTALL_SKILLS_DIR"