From 1f3b6914112ab7c9ba6c08e66d6774801f1c25d9 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 17 Mar 2026 13:06:14 -0500 Subject: [PATCH] feat: /gstack-upgrade detects and syncs stale vendored copies (v0.5.4.1) (#137) When the global gstack is already up to date, standalone /gstack-upgrade now checks if the local vendored copy in the current project is at a different version and syncs it automatically. Also adds rollback on setup failure and update-check fallback matching the preamble pattern. Co-authored-by: Claude Opus 4.6 --- CHANGELOG.md | 10 ++++++++++ VERSION | 2 +- gstack-upgrade/SKILL.md | 28 ++++++++++++++++++++++++++-- gstack-upgrade/SKILL.md.tmpl | 28 ++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12fa243b8bbd943a4a07f0a49004c7e936796394..4593d3f1a538e9c6dbb5ecccaee8dd0395916e92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.6.0.1 — 2026-03-17 + +- **`/gstack-upgrade` now catches stale vendored copies automatically.** If your global gstack is up to date but the vendored copy in your project is behind, `/gstack-upgrade` detects the mismatch and syncs it. No more manually asking "did we vendor it?" — it just tells you and offers to update. +- **Upgrade sync is safer.** If `./setup` fails while syncing a vendored copy, gstack restores the previous version from backup instead of leaving a broken install. + +### For contributors + +- Standalone usage section in `gstack-upgrade/SKILL.md.tmpl` now references Steps 2 and 4.5 (DRY) instead of duplicating detection/sync bash blocks. Added one new version-comparison bash block. +- Update check fallback in standalone mode now matches the preamble pattern (global path → local path → `|| true`). + ## 0.6.0 — 2026-03-17 - **100% test coverage is the key to great vibe coding.** gstack now bootstraps test frameworks from scratch when your project doesn't have one. Detects your runtime, researches the best framework, asks you to pick, installs it, writes 3-5 real tests for your actual code, sets up CI/CD (GitHub Actions), creates TESTING.md, and adds test culture instructions to CLAUDE.md. Every Claude Code session after that writes tests naturally. diff --git a/VERSION b/VERSION index a918a2aa18d5bec6a8bb93891a7a63c243111796..758efdb4a76d911111b718b6df0c8eed6354bbb7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.0 +0.6.0.1 diff --git a/gstack-upgrade/SKILL.md b/gstack-upgrade/SKILL.md index 9d63565128fc2baeae54f9ebed28644ca40edf7b..50b67dfcc38c187be14152433c1f38bf26845774 100644 --- a/gstack-upgrade/SKILL.md +++ b/gstack-upgrade/SKILL.md @@ -156,6 +156,13 @@ rm -rf "$LOCAL_GSTACK.bak" ``` Tell user: "Also updated vendored copy at `$LOCAL_GSTACK` — commit `.claude/skills/gstack/` when you're ready." +If `./setup` fails, restore from backup and warn the user: +```bash +rm -rf "$LOCAL_GSTACK" +mv "$LOCAL_GSTACK.bak" "$LOCAL_GSTACK" +``` +Tell user: "Sync failed — restored previous version at `$LOCAL_GSTACK`. Run `/gstack-upgrade` manually to retry." + ### Step 5: Write marker + clear cache ```bash @@ -193,9 +200,26 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -~/.claude/skills/gstack/bin/gstack-update-check --force +~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. 2. If `UPGRADE_AVAILABLE `: follow Steps 2-6 above. -3. If no output (up to date): tell the user "You're already on the latest version (v{version})." + +3. If no output (primary is up to date): check for a stale local vendored copy. + +Run the Step 2 bash block above to detect the primary install type and directory (`INSTALL_TYPE` and `INSTALL_DIR`). Then run the Step 4.5 detection bash block above to check for a local vendored copy (`LOCAL_GSTACK`). + +**If `LOCAL_GSTACK` is empty** (no local vendored copy): tell the user "You're already on the latest version (v{version})." + +**If `LOCAL_GSTACK` is non-empty**, compare versions: +```bash +PRIMARY_VER=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown") +LOCAL_VER=$(cat "$LOCAL_GSTACK/VERSION" 2>/dev/null || echo "unknown") +echo "PRIMARY=$PRIMARY_VER LOCAL=$LOCAL_VER" +``` + +**If versions differ:** follow the Step 4.5 sync bash block above to update the local copy from the primary. Tell user: "Global v{PRIMARY_VER} is up to date. Updated local vendored copy from v{LOCAL_VER} → v{PRIMARY_VER}. Commit `.claude/skills/gstack/` when you're ready." + +**If versions match:** tell the user "You're on the latest version (v{PRIMARY_VER}). Global and local vendored copy are both up to date." diff --git a/gstack-upgrade/SKILL.md.tmpl b/gstack-upgrade/SKILL.md.tmpl index a441b8d664f5b9c29862f1d1b9d2d6689c659135..0acf16c200ebe38c0df3a9ce460b84dc2af7b152 100644 --- a/gstack-upgrade/SKILL.md.tmpl +++ b/gstack-upgrade/SKILL.md.tmpl @@ -154,6 +154,13 @@ rm -rf "$LOCAL_GSTACK.bak" ``` Tell user: "Also updated vendored copy at `$LOCAL_GSTACK` — commit `.claude/skills/gstack/` when you're ready." +If `./setup` fails, restore from backup and warn the user: +```bash +rm -rf "$LOCAL_GSTACK" +mv "$LOCAL_GSTACK.bak" "$LOCAL_GSTACK" +``` +Tell user: "Sync failed — restored previous version at `$LOCAL_GSTACK`. Run `/gstack-upgrade` manually to retry." + ### Step 5: Write marker + clear cache ```bash @@ -191,9 +198,26 @@ When invoked directly as `/gstack-upgrade` (not from a preamble): 1. Force a fresh update check (bypass cache): ```bash -~/.claude/skills/gstack/bin/gstack-update-check --force +~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \ +.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true ``` Use the output to determine if an upgrade is available. 2. If `UPGRADE_AVAILABLE `: follow Steps 2-6 above. -3. If no output (up to date): tell the user "You're already on the latest version (v{version})." + +3. If no output (primary is up to date): check for a stale local vendored copy. + +Run the Step 2 bash block above to detect the primary install type and directory (`INSTALL_TYPE` and `INSTALL_DIR`). Then run the Step 4.5 detection bash block above to check for a local vendored copy (`LOCAL_GSTACK`). + +**If `LOCAL_GSTACK` is empty** (no local vendored copy): tell the user "You're already on the latest version (v{version})." + +**If `LOCAL_GSTACK` is non-empty**, compare versions: +```bash +PRIMARY_VER=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null || echo "unknown") +LOCAL_VER=$(cat "$LOCAL_GSTACK/VERSION" 2>/dev/null || echo "unknown") +echo "PRIMARY=$PRIMARY_VER LOCAL=$LOCAL_VER" +``` + +**If versions differ:** follow the Step 4.5 sync bash block above to update the local copy from the primary. Tell user: "Global v{PRIMARY_VER} is up to date. Updated local vendored copy from v{LOCAL_VER} → v{PRIMARY_VER}. Commit `.claude/skills/gstack/` when you're ready." + +**If versions match:** tell the user "You're on the latest version (v{PRIMARY_VER}). Global and local vendored copy are both up to date."