Class: Ace::Review::Molecules::ContextComposer

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/review/molecules/context_composer.rb

Overview

Composes context.md files with YAML frontmatter for ace-bundle integration Follows the pattern from ace-docs DocumentAnalysisPrompt

Class Method Summary collapse

Class Method Details

.build_review_scope_section(subject_config) ⇒ String

Build review scope section explaining what will be reviewed

Parameters:

  • subject_config (Hash)

    Subject configuration

Returns:

  • (String)

    Review scope section



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ace/review/molecules/context_composer.rb', line 83

def self.build_review_scope_section(subject_config)
  return "" unless subject_config

  # Extract subject description
  subject_desc = extract_subject_description(subject_config)

  <<~SECTION
    ## Review Scope

    **Subject of review**:
    #{subject_desc}
  SECTION
end

.create_context_md(base_instructions, context_config, subject_config = nil) ⇒ String

Create context.md with YAML frontmatter for review context

Parameters:

  • base_instructions (String)

    Base instructions for the context

  • context_config (Hash)

    Context configuration (presets, files, diffs, commands)

  • subject_config (Hash, nil) (defaults to: nil)

    Optional subject configuration for scope section

Returns:

  • (String)

    Complete context.md content with YAML frontmatter



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/ace/review/molecules/context_composer.rb', line 16

def self.create_context_md(base_instructions, context_config, subject_config = nil)
  # Normalize context configuration following ace-docs pattern
  normalized_config = normalize_context_config(context_config)

  frontmatter = {"bundle" => normalized_config}

  # Build review scope section if subject config provided
  scope_section = build_review_scope_section(subject_config) if subject_config

  # context.md = frontmatter + base instructions + scope section
  # YAML.dump adds opening --- but not closing, we add closing ---
  "#{YAML.dump(frontmatter).strip}\n---\n\n#{base_instructions}\n\n#{scope_section}".strip
end

.extract_subject_description(subject_config) ⇒ String

Extract human-readable description from subject configuration

Parameters:

  • subject_config (Hash)

    Subject configuration

Returns:

  • (String)

    Description string



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/ace/review/molecules/context_composer.rb', line 100

def self.extract_subject_description(subject_config)
  if subject_config["diff"]
    "- Git diff changes"
  elsif subject_config["files"]
    files = subject_config["files"]
    if files.is_a?(Array)
      if files.length == 1
        "- File: `#{files.first}`"
      else
        "- Files: #{files.map { |f| "`#{f}`" }.join(", ")}"
      end
    else
      "- File: `#{files}`"
    end
  elsif subject_config["content"]
    "- Inline content"
  else
    "- Repository changes"
  end
end

.load_context_via_ace_bundle(context_file_path) ⇒ String

Load context.md via ace-bundle

Parameters:

  • context_file_path (String)

    Path to context.md file

Returns:

  • (String)

    Content with embedded files and context



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ace/review/molecules/context_composer.rb', line 43

def self.load_context_via_ace_bundle(context_file_path)
  require "ace/bundle"

  # Use ace-bundle to load context.md - processes presets and files from frontmatter
  result = Ace::Bundle.load_file(context_file_path)
  result.content
rescue LoadError
  raise Ace::Review::Errors::ContextComposerError, "ace-bundle not available - required for context.md pattern"
rescue => e
  raise Ace::Review::Errors::ContextComposerError, "ace-bundle loading failed: #{e.message}"
end

.normalize_context_config(config) ⇒ Hash

Normalize context configuration to match ace-docs pattern

Parameters:

  • config (Hash)

    Raw context configuration

Returns:

  • (Hash)

    Normalized configuration



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ace/review/molecules/context_composer.rb', line 60

def self.normalize_context_config(config)
  # Start with base context config following ace-docs pattern
  normalized = {
    "params" => {"format" => "markdown-xml"},
    "embed_document_source" => true
  }

  # Merge with provided config
  config ||= {}
  normalized.merge!(config)

  # Ensure arrays are properly initialized
  normalized["presets"] ||= []
  normalized["files"] ||= []
  normalized["diffs"] ||= []
  normalized["commands"] ||= []

  normalized
end

.save_context_md(context_md, cache_dir) ⇒ String

Save context.md to specified directory

Parameters:

  • context_md (String)

    The context.md content

  • cache_dir (String)

    Directory to save context.md

Returns:

  • (String)

    Path to saved context.md file



34
35
36
37
38
# File 'lib/ace/review/molecules/context_composer.rb', line 34

def self.save_context_md(context_md, cache_dir)
  context_file_path = File.join(cache_dir, "context.md")
  File.write(context_file_path, context_md)
  context_file_path
end