fix(windsurf): remove trailing slash from .windsurf/rules path

Node v25 preserves trailing slashes in path.join, causing
writeFileSync to fail with ENOENT when the converted path
ends in '/'. Affects all Windsurf users on Node v25+.

Fixes gsd-build/get-shit-done#1392

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox
2026-03-26 01:13:46 -07:00
parent 604a78b30b
commit 69e104dffc
2 changed files with 8 additions and 7 deletions

View File

@@ -919,10 +919,10 @@ function convertClaudeToWindsurfMarkdown(content) {
converted = converted.replace(/subagent_type="general-purpose"/g, 'subagent_type="generalPurpose"');
converted = converted.replace(/\$ARGUMENTS\b/g, '{{GSD_ARGS}}');
// Replace project-level Claude conventions with Windsurf equivalents
converted = converted.replace(/`\.\/CLAUDE\.md`/g, '`.windsurf/rules/`');
converted = converted.replace(/\.\/CLAUDE\.md/g, '.windsurf/rules/');
converted = converted.replace(/`CLAUDE\.md`/g, '`.windsurf/rules/`');
converted = converted.replace(/\bCLAUDE\.md\b/g, '.windsurf/rules/');
converted = converted.replace(/`\.\/CLAUDE\.md`/g, '`.windsurf/rules`');
converted = converted.replace(/\.\/CLAUDE\.md/g, '.windsurf/rules');
converted = converted.replace(/`CLAUDE\.md`/g, '`.windsurf/rules`');
converted = converted.replace(/\bCLAUDE\.md\b/g, '.windsurf/rules');
converted = converted.replace(/\.claude\/skills\//g, '.windsurf/skills/');
// Remove Claude Code-specific bug workarounds before brand replacement
converted = converted.replace(/\*\*Known Claude Code bug \(classifyHandoffIfNeeded\):\*\*[^\n]*\n/g, '');
@@ -3127,7 +3127,7 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix, runtime, isCommand
let jsContent = fs.readFileSync(srcPath, 'utf8');
jsContent = jsContent.replace(/gsd:/gi, 'gsd-');
jsContent = jsContent.replace(/\.claude\/skills\//g, '.windsurf/skills/');
jsContent = jsContent.replace(/CLAUDE\.md/g, '.windsurf/rules/');
jsContent = jsContent.replace(/CLAUDE\.md/g, '.windsurf/rules');
jsContent = jsContent.replace(/\bClaude Code\b/g, 'Windsurf');
fs.writeFileSync(destPath, jsContent);
} else {

View File

@@ -105,10 +105,11 @@ describe('convertClaudeToWindsurfMarkdown', () => {
assert.ok(!result.includes('Claude Code'), 'original brand removed');
});
test('replaces CLAUDE.md with .windsurf/rules/', () => {
test('replaces CLAUDE.md with .windsurf/rules (no trailing slash)', () => {
const input = 'See `CLAUDE.md` for configuration. Also check ./CLAUDE.md file.';
const result = convertClaudeToWindsurfMarkdown(input);
assert.ok(result.includes('.windsurf/rules/'), 'CLAUDE.md replaced');
assert.ok(result.includes('.windsurf/rules'), 'CLAUDE.md replaced');
assert.ok(!result.includes('.windsurf/rules/'), 'no trailing slash (Node v25 compat)');
});
test('replaces .claude/skills/ with .windsurf/skills/', () => {