mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-18 19:02:18 +02:00
fix(setup): render the gbrain :user variant to an out-dir — global installs stay git-clean
On a global-git install with gbrain, ./setup and 'gstack-config gbrain-refresh' ran gen:skill-docs:user IN PLACE inside the install checkout, rewriting ~16 TRACKED SKILL.md files. The checkout stayed permanently dirty, every /gstack-upgrade 'git stash' saved a redundant snapshot of generated content, and the growing stash list invited a 'git stash pop' that would lay stale instruction markdown from an older gstack over the current version — a quiet wrong-rules failure mode. Fix, wired through machinery that already existed (gen-skill-docs --out-dir + the symlink install layer): brain-aware SKILL.md now renders into the untracked ~/.gstack/render/claude, and both Claude installers serve the render when present — setup's link_claude_skill_dirs prefers $GSTACK_HOME/render/claude/<skill>/SKILL.md, and bin/gstack-relink does the same so a later config change can't silently flip skills back to the blockless canonical source. setup wipes and rebuilds the render each run, repoints installed skills after a successful render, and removes a stale render (re-linking canonical) when gbrain is gone. gbrain-refresh renders to the out-dir and repoints via relink; its 'this dirties the install's git tree' caveat is retired because it no longer does. A one-time upgrade migration (gstack-upgrade/migrations/v1.67.0.0.sh, F12) restores the legacy dirt: unstaged modifications to SKILL.md / sections/ *.md files in the install checkout are git-checkout'd back to canonical; anything outside that footprint (user edits, untracked files, staged work) is left alone and reported. Idempotent, non-fatal, symlinked installs skipped. Tests: render-preference behavior for both installers, static pins that every executable :user invocation carries --out-dir and the caveat text is gone, migration fixture (restore/leave/idempotent/no-op matrix), and the existing out-dir render test now asserts 'git status --porcelain' gains zero new entries across a full :user render. Fixes #2569 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1dbed2c01f
commit
9af589bb73
@@ -266,6 +266,38 @@ describe('gstack-relink (#578)', () => {
|
||||
expect(new Set(names).size).toBe(names.length);
|
||||
});
|
||||
|
||||
// #2569: rendered :user variants live in ${GSTACK_HOME}/render/claude.
|
||||
// relink must serve the render when present — otherwise any config change
|
||||
// silently flips every skill back to the canonical (blockless) source.
|
||||
test('prefers a rendered SKILL.md from GSTACK_HOME/render/claude (#2569)', () => {
|
||||
setupMockInstall(['qa', 'ship']);
|
||||
const renderDir = path.join(tmpDir, 'render', 'claude', 'qa');
|
||||
fs.mkdirSync(renderDir, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(renderDir, 'SKILL.md'),
|
||||
'---\nname: qa\ndescription: test\n---\nrendered brain-aware qa',
|
||||
);
|
||||
|
||||
run(`${path.join(installDir, 'bin', 'gstack-config')} set skill_prefix false`, {
|
||||
GSTACK_INSTALL_DIR: installDir,
|
||||
GSTACK_SKILLS_DIR: skillsDir,
|
||||
GSTACK_HOME: tmpDir,
|
||||
});
|
||||
run(`${path.join(installDir, 'bin', 'gstack-relink')}`, {
|
||||
GSTACK_INSTALL_DIR: installDir,
|
||||
GSTACK_SKILLS_DIR: skillsDir,
|
||||
GSTACK_HOME: tmpDir,
|
||||
});
|
||||
|
||||
const qaLink = path.join(skillsDir, 'qa', 'SKILL.md');
|
||||
expect(fs.readlinkSync(qaLink)).toBe(path.join(renderDir, 'SKILL.md'));
|
||||
expect(fs.readFileSync(qaLink, 'utf-8')).toContain('rendered brain-aware qa');
|
||||
// ship has no render — canonical source link.
|
||||
expect(fs.readlinkSync(path.join(skillsDir, 'ship', 'SKILL.md'))).toBe(
|
||||
path.join(installDir, 'ship', 'SKILL.md'),
|
||||
);
|
||||
});
|
||||
|
||||
// FIRST INSTALL: --no-prefix must create ONLY flat names, zero gstack-* pollution
|
||||
test('first install --no-prefix: only flat names exist, zero gstack-* entries', () => {
|
||||
setupMockInstall(['qa', 'ship', 'review', 'plan-ceo-review', 'gstack-upgrade']);
|
||||
|
||||
Reference in New Issue
Block a user