Class: ClaudeMemory::Core::SnippetExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/claude_memory/core/snippet_extractor.rb

Overview

Extracts relevant snippets from raw content based on query terms. Finds the line with the most query term matches and returns surrounding context (1 line before + 2 lines after). Follows Functional Core pattern - pure transformations, no I/O.

Constant Summary collapse

CONTEXT_BEFORE =
1
CONTEXT_AFTER =
2
MAX_SNIPPET_LENGTH =
500

Class Method Summary collapse

Class Method Details

.build_snippet(lines, center_idx) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



90
91
92
93
94
# File 'lib/claude_memory/core/snippet_extractor.rb', line 90

def self.build_snippet(lines, center_idx)
  start_idx, end_idx = snippet_range(lines, center_idx)
  snippet = lines[start_idx..end_idx].join("\n")
  truncate(snippet)
end

.extract(content, query) ⇒ String?

Extract the best snippet from content matching the query

Parameters:

  • content (String)

    Raw text content

  • query (String)

    Search query

Returns:

  • (String, nil)

    Best matching snippet or nil if no content



18
19
20
21
22
23
# File 'lib/claude_memory/core/snippet_extractor.rb', line 18

def self.extract(content, query)
  parsed = parse_and_find(content, query)
  return nil unless parsed

  build_snippet(parsed[:lines], parsed[:best_line_idx])
end

.extract_with_lines(content, query) ⇒ Hash?

Extract snippet and return line range information

Parameters:

  • content (String)

    Raw text content

  • query (String)

    Search query

Returns:

  • (Hash, nil)

    Hash with :snippet, :line_start, :line_end or nil



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/claude_memory/core/snippet_extractor.rb', line 29

def self.extract_with_lines(content, query)
  parsed = parse_and_find(content, query)
  return nil unless parsed

  lines = parsed[:lines]
  best_line_idx = parsed[:best_line_idx]
  start_idx, end_idx = snippet_range(lines, best_line_idx)

  {
    snippet: build_snippet(lines, best_line_idx),
    line_start: start_idx + 1, # 1-indexed
    line_end: end_idx + 1       # 1-indexed
  }
end

.find_best_line(lines, terms) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/claude_memory/core/snippet_extractor.rb', line 66

def self.find_best_line(lines, terms)
  best_idx = nil
  best_score = 0

  lines.each_with_index do |line, idx|
    downcased = line.downcase
    score = terms.count { |term| downcased.include?(term) }
    if score > best_score
      best_score = score
      best_idx = idx
    end
  end

  best_idx
end

.parse_and_find(content, query) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/claude_memory/core/snippet_extractor.rb', line 45

def self.parse_and_find(content, query)
  return nil if content.nil? || content.empty? || query.nil? || query.empty?

  lines = content.lines.map(&:chomp)
  return nil if lines.empty?

  terms = tokenize_query(query)
  return nil if terms.empty?

  best_line_idx = find_best_line(lines, terms)
  return nil unless best_line_idx

  {lines: lines, best_line_idx: best_line_idx}
end

.snippet_range(lines, center_idx) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



83
84
85
86
87
# File 'lib/claude_memory/core/snippet_extractor.rb', line 83

def self.snippet_range(lines, center_idx)
  start_idx = [center_idx - CONTEXT_BEFORE, 0].max
  end_idx = [center_idx + CONTEXT_AFTER, lines.size - 1].min
  [start_idx, end_idx]
end

.tokenize_query(query) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



61
62
63
# File 'lib/claude_memory/core/snippet_extractor.rb', line 61

def self.tokenize_query(query)
  query.downcase.split(/\s+/).reject { |t| t.length < 2 }
end

.truncate(text) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



97
98
99
100
# File 'lib/claude_memory/core/snippet_extractor.rb', line 97

def self.truncate(text)
  return text if text.length <= MAX_SNIPPET_LENGTH
  text[0, MAX_SNIPPET_LENGTH - 3] + "..."
end