Skip to content

fix(windsurf): include YAML frontmatter when generating rule files#1470

Merged
dyoshikawa merged 1 commit intomainfrom
codex/investigate-issue-1438
Apr 13, 2026
Merged

fix(windsurf): include YAML frontmatter when generating rule files#1470
dyoshikawa merged 1 commit intomainfrom
codex/investigate-issue-1438

Conversation

@dyoshikawa
Copy link
Copy Markdown
Owner

Motivation

  • Windsurf requires YAML frontmatter (title, trigger, globs) in .windsurf/rules/*.md files, but generated files previously contained only the rule body.
  • Ensure generated Windsurf rule files include the required frontmatter so they work correctly in the Windsurf toolchain.

Description

  • Serialize Windsurf frontmatter by importing stringifyFrontmatter and adding a WindsurfRuleFrontmatter shape.
  • Implement buildWindsurfFrontmatter() to derive title from rulesync description (fallback to filename), set trigger to glob when specific globs exist otherwise always_on, and include globs only for glob triggers.
  • Update WindsurfRule.fromRulesyncRule() to build tool params, compose Windsurf frontmatter, and set fileContent to stringifyFrontmatter(body, windsurfFrontmatter).
  • Update src/features/rules/windsurf-rule.test.ts to assert the new frontmatter output and add coverage for glob-triggered rules.

Testing

  • Ran the Windsurf unit tests with pnpm vitest run src/features/rules/windsurf-rule.test.ts and they passed (38 passed).
  • Ran full project checks with pnpm cicheck, which completed formatting, linting, typechecks and the full test suite successfully (all automated checks passed; full test run completed without failures).

Codex Task

Copilot AI review requested due to automatic review settings April 13, 2026 11:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Windsurf-required YAML frontmatter to generated .windsurf/rules/*.md files so Windsurf can correctly interpret rule metadata during its rule loading pipeline.

Changes:

  • Generate Windsurf rule file content via stringifyFrontmatter(), emitting title, trigger, and optional globs.
  • Introduce buildWindsurfFrontmatter() to derive Windsurf frontmatter from Rulesync rule metadata.
  • Update unit tests to assert the new frontmatter output, including a glob-triggered example.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/features/rules/windsurf-rule.ts Builds and serializes Windsurf YAML frontmatter into generated rule file content.
src/features/rules/windsurf-rule.test.ts Updates assertions to match the new frontmatter-bearing output and adds a glob-trigger test.

Comment on lines +122 to +127
const hasSpecificGlobs = Boolean(globs && globs.length > 0 && !globs.includes("**/*"));

return {
title: description ?? relativeFilePath.replace(/\.md$/, ""),
trigger: hasSpecificGlobs ? "glob" : "always_on",
...(hasSpecificGlobs && { globs }),
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasSpecificGlobs treats any occurrence of "/*" as meaning "no specific globs". That misclassifies cases like ["**/*", "src/**/*.ts"] (should still be trigger: glob) and also treats "*" as specific even though it’s a wildcard used elsewhere in the codebase. Consider computing specificity as “at least one glob that isn’t "/" or ""” (and treat mixed wildcard+specific as specific).

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +81
const windsurfFrontmatter = this.buildWindsurfFrontmatter({
relativeFilePath: rulesyncRule.getRelativeFilePath(),
description: rulesyncRule.getFrontmatter().description,
globs: rulesyncRule.getFrontmatter().globs,
});

return new WindsurfRule({
...toolRuleParams,
fileContent: stringifyFrontmatter(rulesyncRule.getBody(), windsurfFrontmatter),
});
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromRulesyncRule() now writes Windsurf YAML frontmatter into fileContent, but WindsurfRule.fromFile() doesn’t parse/strip that frontmatter. As a result, reading a generated .windsurf/rules/*.md file will keep the frontmatter in the body and toRulesyncRuleDefault() will round-trip it into the Rulesync rule body (and you also lose the ability to map title/trigger/globs back into Rulesync metadata). Consider updating fromFile() to parseFrontmatter() and populate description/globs from the parsed Windsurf frontmatter, storing only the markdown body as fileContent.

Copilot uses AI. Check for mistakes.
@dyoshikawa dyoshikawa merged commit 21e43d0 into main Apr 13, 2026
14 checks passed
@dyoshikawa dyoshikawa deleted the codex/investigate-issue-1438 branch April 13, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants