Module: Legion::CLI::Chat::MemoryStore
- Defined in:
- lib/legion/cli/chat/memory_store.rb
Constant Summary collapse
- DEFAULT_PROJECT_FILE =
'.legion/memory.md'- DEFAULT_GLOBAL_DIR =
File.join(Dir.home, '.legion', 'memory')
- DEFAULT_GLOBAL_FILE =
File.join(DEFAULT_GLOBAL_DIR, 'global.md')
Class Method Summary collapse
- .add(text, scope: :project, base_dir: Dir.pwd) ⇒ Object
- .clear(scope: :project, base_dir: Dir.pwd) ⇒ Object
- .forget(pattern, scope: :project, base_dir: Dir.pwd) ⇒ Object
- .global_path ⇒ Object
- .list(scope: :project, base_dir: Dir.pwd) ⇒ Object
- .load_all(base_dir = Dir.pwd) ⇒ Object
- .load_context(base_dir = Dir.pwd) ⇒ Object
- .project_path(base_dir = Dir.pwd) ⇒ Object
- .search(query, base_dir: Dir.pwd) ⇒ Object
Class Method Details
.add(text, scope: :project, base_dir: Dir.pwd) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/legion/cli/chat/memory_store.rb', line 44 def add(text, scope: :project, base_dir: Dir.pwd) path = scope == :global ? global_path : project_path(base_dir) ensure_dir(path) = Time.now.strftime('%Y-%m-%d %H:%M') entry = "\n- #{text} _(#{})_\n" if File.exist?(path) File.open(path, 'a', encoding: 'utf-8') { |f| f.write(entry) } else header = scope == :global ? "# Global Memory\n" : "# Project Memory\n" File.write(path, "#{header}#{entry}", encoding: 'utf-8') end sync_to_team(text) path end |
.clear(scope: :project, base_dir: Dir.pwd) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/legion/cli/chat/memory_store.rb', line 83 def clear(scope: :project, base_dir: Dir.pwd) path = scope == :global ? global_path : project_path(base_dir) return false unless File.exist?(path) File.delete(path) true end |
.forget(pattern, scope: :project, base_dir: Dir.pwd) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/legion/cli/chat/memory_store.rb', line 62 def forget(pattern, scope: :project, base_dir: Dir.pwd) path = scope == :global ? global_path : project_path(base_dir) return 0 unless File.exist?(path) lines = File.readlines(path, encoding: 'utf-8') original_count = lines.length lines.reject! { |line| line.include?(pattern) } removed = original_count - lines.length File.write(path, lines.join, encoding: 'utf-8') removed end |
.global_path ⇒ Object
20 21 22 |
# File 'lib/legion/cli/chat/memory_store.rb', line 20 def global_path DEFAULT_GLOBAL_FILE end |
.list(scope: :project, base_dir: Dir.pwd) ⇒ Object
74 75 76 77 78 79 80 81 |
# File 'lib/legion/cli/chat/memory_store.rb', line 74 def list(scope: :project, base_dir: Dir.pwd) path = scope == :global ? global_path : project_path(base_dir) return [] unless File.exist?(path) File.readlines(path, encoding: 'utf-8') .select { |line| line.start_with?('- ') } .map { |line| line.sub(/\A- /, '').strip } end |
.load_all(base_dir = Dir.pwd) ⇒ Object
24 25 26 27 28 29 30 31 32 |
# File 'lib/legion/cli/chat/memory_store.rb', line 24 def load_all(base_dir = Dir.pwd) memories = [] [global_path, project_path(base_dir)].each do |path| next unless File.exist?(path) memories << { source: path, content: File.read(path, encoding: 'utf-8') } end memories end |
.load_context(base_dir = Dir.pwd) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/legion/cli/chat/memory_store.rb', line 34 def load_context(base_dir = Dir.pwd) parts = load_all(base_dir).map do |m| label = m[:source].include?('global') ? 'Global Memory' : 'Project Memory' "## #{label}\n\n#{m[:content]}" end return nil if parts.empty? parts.join("\n\n---\n\n") end |
.project_path(base_dir = Dir.pwd) ⇒ Object
16 17 18 |
# File 'lib/legion/cli/chat/memory_store.rb', line 16 def project_path(base_dir = Dir.pwd) File.join(base_dir, DEFAULT_PROJECT_FILE) end |
.search(query, base_dir: Dir.pwd) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/legion/cli/chat/memory_store.rb', line 91 def search(query, base_dir: Dir.pwd) results = [] load_all(base_dir).each do |m| m[:content].lines.each_with_index do |line, idx| next unless line.downcase.include?(query.downcase) results << { source: m[:source], line: idx + 1, text: line.strip } end end results end |