mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-08 06:26:45 +02:00
feat: skill prefix is now a persistent user choice (v0.12.11.0) (#571)
* feat: make skill prefix a persistent, interactive user setting - Add --prefix flag alongside --no-prefix - Read/write skill_prefix from ~/.gstack/config.yaml (true/false) - Interactive prompt on first setup when no preference saved - Non-TTY environments default to flat names (no prefix) - Add cleanup_prefixed_claude_symlinks() for reverse direction - Fix gstack-config sed portability (mktemp+mv instead of BSD sed -i '') - Add SKILL_PREFIX to preamble output with namespace-aware instruction * test: add prefix config tests + README switching instructions 8 structural tests for persistent prefix setting: config reading, --prefix flag, config persistence, interactive prompt, TTY fallback, reverse cleanup, cleanup ordering, welcome. * chore: regenerate SKILL.md files with SKILL_PREFIX preamble * chore: bump version and changelog (v0.12.11.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: reframe changelog as feature, not mea culpa * docs: update CONTRIBUTING + CLAUDE.md for prefix-aware vendoring - CONTRIBUTING: vendoring now includes ./setup step for per-skill symlinks - CONTRIBUTING: prefix choice documented in contributor workflow + dev diagram - CONTRIBUTING: switching prefix mode section added - CLAUDE.md: vendored symlink awareness section covers prefix setting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1746,6 +1746,56 @@ describe('setup script validation', () => {
|
||||
);
|
||||
expect(claudeInstallSection).toContain('cleanup_old_claude_symlinks');
|
||||
});
|
||||
|
||||
// --- Persistent config + interactive prompt tests ---
|
||||
|
||||
test('setup reads skill_prefix from config', () => {
|
||||
expect(setupContent).toContain('get skill_prefix');
|
||||
expect(setupContent).toContain('GSTACK_CONFIG');
|
||||
});
|
||||
|
||||
test('setup supports --prefix flag', () => {
|
||||
expect(setupContent).toContain('--prefix)');
|
||||
expect(setupContent).toContain('SKILL_PREFIX=1; SKILL_PREFIX_FLAG=1');
|
||||
});
|
||||
|
||||
test('--prefix and --no-prefix persist to config', () => {
|
||||
expect(setupContent).toContain('set skill_prefix');
|
||||
});
|
||||
|
||||
test('interactive prompt shows when no config', () => {
|
||||
expect(setupContent).toContain('Short names');
|
||||
expect(setupContent).toContain('Namespaced');
|
||||
expect(setupContent).toContain('Choice [1/2]');
|
||||
});
|
||||
|
||||
test('non-TTY defaults to flat names', () => {
|
||||
// Should check if stdin is a TTY before prompting
|
||||
expect(setupContent).toContain('-t 0');
|
||||
});
|
||||
|
||||
test('cleanup_prefixed_claude_symlinks exists and uses readlink', () => {
|
||||
expect(setupContent).toContain('cleanup_prefixed_claude_symlinks');
|
||||
const fnStart = setupContent.indexOf('cleanup_prefixed_claude_symlinks()');
|
||||
const fnEnd = setupContent.indexOf('}', setupContent.indexOf('removed[@]}', fnStart));
|
||||
const fnBody = setupContent.slice(fnStart, fnEnd);
|
||||
expect(fnBody).toContain('readlink');
|
||||
expect(fnBody).toContain('gstack-$skill_name');
|
||||
});
|
||||
|
||||
test('reverse cleanup runs before link when prefix is disabled', () => {
|
||||
const claudeInstallSection = setupContent.slice(
|
||||
setupContent.indexOf('INSTALL_CLAUDE'),
|
||||
setupContent.lastIndexOf('link_claude_skill_dirs')
|
||||
);
|
||||
expect(claudeInstallSection).toContain('cleanup_prefixed_claude_symlinks');
|
||||
});
|
||||
|
||||
test('welcome message references SKILL_PREFIX', () => {
|
||||
// gstack-upgrade is always called gstack-upgrade (it's the actual dir name)
|
||||
// but the welcome section should exist near the prefix logic
|
||||
expect(setupContent).toContain('Run /gstack-upgrade anytime');
|
||||
});
|
||||
});
|
||||
|
||||
describe('discover-skills hidden directory filtering', () => {
|
||||
|
||||
Reference in New Issue
Block a user