squad upgrade reports success but the version stamp never persists. Running upgrade repeatedly always shows 0.0.0-source → 0.8.18 — it never reaches "Already up to date."
Repro
squad upgrade # says "0.0.0-source → 0.8.18"
squad upgrade # says "0.0.0-source → 0.8.18" again (should say "Already up to date")
grep "version:" .github/agents/squad.agent.md # still shows 0.0.0-source
Root Cause
In upgrade.js, stampVersion() correctly writes the version into squad.agent.md (line ~342), but the TEMPLATE_MANIFEST loop (line ~347) includes squad.agent.md with overwriteOnUpgrade: true, which copies the unstamped template back over the stamped file.
In templates.js:
export const TEMPLATE_MANIFEST = [
{
source: 'squad.agent.md',
destination: '../.github/agents/squad.agent.md',
overwriteOnUpgrade: true, // <-- this causes the overwrite
},
// ...
];
In upgrade.js:
// Step 1: Copy + stamp (works correctly)
fs.copyFileSync(agentSrc, agentDest);
stampVersion(agentDest, cliVersion);
// Step 2: Template manifest loop (overwrites the stamp)
const filesToUpgrade = TEMPLATE_MANIFEST.filter(f => f.overwriteOnUpgrade);
for (const file of filesToUpgrade) {
fs.copyFileSync(srcPath, destPath); // squad.agent.md gets overwritten here
}
Impact
Fix (verified locally)
Exclude squad.agent.md from the manifest loop — it is already handled explicitly with stampVersion():
const filesToUpgrade = TEMPLATE_MANIFEST.filter(f => f.overwriteOnUpgrade && f.source !== 'squad.agent.md');
After this one-line change, squad upgrade correctly stamps 0.8.18 and subsequent runs report "Already up to date (v0.8.18)."
Environment
squad --version: 0.8.18
- Node.js: v25.7.0
- npm: 11.10.1
- OS: Linux
- Install method:
npm install -g @bradygaster/squad-cli@0.8.18
squad upgradereports success but the version stamp never persists. Running upgrade repeatedly always shows0.0.0-source → 0.8.18— it never reaches "Already up to date."Repro
Root Cause
In
upgrade.js,stampVersion()correctly writes the version intosquad.agent.md(line ~342), but theTEMPLATE_MANIFESTloop (line ~347) includessquad.agent.mdwithoverwriteOnUpgrade: true, which copies the unstamped template back over the stamped file.In
templates.js:In
upgrade.js:Impact
isAlreadyCurrentcheck never passes (compares0.0.0-sourcevs0.8.18), so it re-copies all 30 files on every runFix (verified locally)
Exclude
squad.agent.mdfrom the manifest loop — it is already handled explicitly withstampVersion():After this one-line change,
squad upgradecorrectly stamps0.8.18and subsequent runs report "Already up to date (v0.8.18)."Environment
squad --version: 0.8.18npm install -g @bradygaster/squad-cli@0.8.18