diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index 9f0f2f7ea..5248dc21d 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -131,6 +131,7 @@ cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main +find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + ./setup ``` If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them." @@ -180,8 +181,9 @@ Tell user: "Removed vendored copy at `$LOCAL_GSTACK` (team mode active — globa **If `LOCAL_GSTACK` is non-empty AND `TEAM_MODE` is NOT `true`:** Update it by copying from the freshly-upgraded primary install (same approach as README vendored install): ```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" -cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" -rm -rf "$LOCAL_GSTACK/.git" +mkdir -p "$LOCAL_GSTACK" +rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/" +find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ``` diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index 5402a1da3..c3b0be3bd 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -128,6 +128,7 @@ cd "$INSTALL_DIR" STASH_OUTPUT=$(git stash 2>&1) git fetch origin git reset --hard origin/main +find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + ./setup ``` If `$STASH_OUTPUT` contains "Saved working directory", warn the user: "Note: local changes were stashed. Run `git stash pop` in the skill directory to restore them." @@ -177,8 +178,9 @@ Tell user: "Removed vendored copy at `$LOCAL_GSTACK` (team mode active — globa **If `LOCAL_GSTACK` is non-empty AND `TEAM_MODE` is NOT `true`:** Update it by copying from the freshly-upgraded primary install (same approach as README vendored install): ```bash mv "$LOCAL_GSTACK" "$LOCAL_GSTACK.bak" -cp -Rf "$INSTALL_DIR" "$LOCAL_GSTACK" -rm -rf "$LOCAL_GSTACK/.git" +mkdir -p "$LOCAL_GSTACK" +rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/" +find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} + cd "$LOCAL_GSTACK" && ./setup rm -rf "$LOCAL_GSTACK.bak" ``` diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index 2fb783ffd..f6a4aa3e1 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -498,6 +498,13 @@ describe('gen-skill-docs', () => { expect(qaOnlyContent).toContain('Phase 6'); }); + test('gstack-upgrade generated skill excludes backup trees during upgrade sync', () => { + const content = fs.readFileSync(path.join(ROOT, 'gstack-upgrade', 'SKILL.md'), 'utf-8'); + expect(content).toContain(`find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} +`); + expect(content).toContain(`rsync -a --exclude='.git' --exclude='.bak*' "$INSTALL_DIR/" "$LOCAL_GSTACK/"`); + expect(content).toContain(`find "$LOCAL_GSTACK" -maxdepth 1 -mindepth 1 -name '.bak*' -exec rm -rf {} +`); + }); + test('qa-only has no-fix guardrails', () => { const qaOnlyContent = fs.readFileSync(path.join(ROOT, 'qa-only', 'SKILL.md'), 'utf-8'); expect(qaOnlyContent).toContain('Never fix bugs');