Class: RailsAiBridge::Serializers::Providers::WindsurfRulesSerializer

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_ai_bridge/serializers/providers/windsurf_rules_serializer.rb

Overview

Generates .windsurf/rules/*.md files for Windsurf rule discovery. Each file is hard-capped at MAX_CHARS_PER_FILE characters (under Windsurf's 6K limit).

Constant Summary collapse

MAX_CHARS_PER_FILE =

Per-file character cap before truncation.

5_800

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context) ⇒ WindsurfRulesSerializer

Returns a new instance of WindsurfRulesSerializer.

Parameters:



16
17
18
# File 'lib/rails_ai_bridge/serializers/providers/windsurf_rules_serializer.rb', line 16

def initialize(context)
  @context = context
end

Instance Attribute Details

#contextHash (readonly)

Returns Introspection context passed to serializers.

Returns:

  • (Hash)

    Introspection context passed to serializers.



13
14
15
# File 'lib/rails_ai_bridge/serializers/providers/windsurf_rules_serializer.rb', line 13

def context
  @context
end

Instance Method Details

#call(output_dir) ⇒ Hash<Symbol, Array<String>>

Writes rule markdown files under .windsurf/rules/ when content changes.

Parameters:

  • output_dir (String)

    Root directory (typically the Rails app root) where .windsurf/rules is created.

Returns:

  • (Hash<Symbol, Array<String>>)

    +:written+ and +:skipped+ arrays of absolute file paths.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails_ai_bridge/serializers/providers/windsurf_rules_serializer.rb', line 24

def call(output_dir)
  rules_dir = File.join(output_dir, '.windsurf', 'rules')
  FileUtils.mkdir_p(rules_dir)

  written = []
  skipped = []

  files = {
    'rails-context.md' => render_context_rule,
    'rails-mcp-tools.md' => render_mcp_tools_rule
  }

  files.each do |filename, content|
    next unless content

    # Enforce Windsurf's 6K limit
    content = content[0...MAX_CHARS_PER_FILE] if content.length > MAX_CHARS_PER_FILE

    filepath = File.join(rules_dir, filename)
    if File.exist?(filepath) && File.read(filepath) == content
      skipped << filepath
    else
      File.write(filepath, content)
      written << filepath
    end
  end

  { written: written, skipped: skipped }
end