Class: Legion::TTY::App

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/tty/app.rb

Overview

rubocop:disable Metrics/ClassLength

Constant Summary collapse

CONFIG_DIR =
File.expand_path('~/.legionio/settings')
PROVIDER_MAP =
{
  claude: :anthropic,
  azure: :openai
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_dir: CONFIG_DIR) ⇒ App

Returns a new instance of App.



30
31
32
33
34
35
36
37
# File 'lib/legion/tty/app.rb', line 30

def initialize(config_dir: CONFIG_DIR)
  @config_dir = config_dir
  @config = load_config
  @credentials = load_credentials
  @screen_manager = ScreenManager.new
  @hotkeys = Hotkeys.new
  @llm_chat = nil
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



16
17
18
# File 'lib/legion/tty/app.rb', line 16

def config
  @config
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



16
17
18
# File 'lib/legion/tty/app.rb', line 16

def credentials
  @credentials
end

#hotkeysObject (readonly)

Returns the value of attribute hotkeys.



16
17
18
# File 'lib/legion/tty/app.rb', line 16

def hotkeys
  @hotkeys
end

#llm_chatObject (readonly)

Returns the value of attribute llm_chat.



16
17
18
# File 'lib/legion/tty/app.rb', line 16

def llm_chat
  @llm_chat
end

#screen_managerObject (readonly)

Returns the value of attribute screen_manager.



16
17
18
# File 'lib/legion/tty/app.rb', line 16

def screen_manager
  @screen_manager
end

Class Method Details

.first_run?(config_dir: CONFIG_DIR) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/legion/tty/app.rb', line 26

def self.first_run?(config_dir: CONFIG_DIR)
  !File.exist?(File.join(config_dir, 'identity.json'))
end

.run(argv = []) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/legion/tty/app.rb', line 18

def self.run(argv = [])
  _ = argv
  app = new
  app.start
rescue Interrupt
  app&.shutdown
end

Instance Method Details

#rescan_environmentObject

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/legion/tty/app.rb', line 102

def rescan_environment
  identity_path = File.join(@config_dir, 'identity.json')
  return unless File.exist?(identity_path)

  Thread.new do
    scanner = Background::Scanner.new
    scan = scanner.scan_all
    identity = deep_symbolize(::JSON.parse(File.read(identity_path)))
    services = scan[:services]&.values&.select { |s| s[:running] }&.map { |s| s[:name] } || []
    repos = scan[:repos]&.map { |r| { name: r[:name], language: r[:language] } } || []
    identity[:environment] = {
      running_services: services,
      repos_count: repos.size,
      top_languages: repos.filter_map { |r| r[:language] }.tally.sort_by { |_, v| -v }.first(5).to_h
    }.compact
    File.write(identity_path, ::JSON.generate(identity))
    @config = load_config
  rescue StandardError
    nil
  end
end

#run_chatObject



87
88
89
90
91
92
93
# File 'lib/legion/tty/app.rb', line 87

def run_chat
  rescan_environment
  setup_llm
  chat = Screens::Chat.new(self)
  @screen_manager.push(chat)
  chat.run
end

#run_onboardingObject



78
79
80
81
82
83
84
85
# File 'lib/legion/tty/app.rb', line 78

def run_onboarding
  onboarding = Screens::Onboarding.new(self)
  data = onboarding.activate
  save_config(data)
  @config = load_config
  @credentials = load_credentials
  run_chat
end

#save_config(data) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



126
127
128
129
130
# File 'lib/legion/tty/app.rb', line 126

def save_config(data)
  FileUtils.mkdir_p(@config_dir)
  save_identity(data)
  save_credentials(data)
end

#setup_hotkeysObject



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/legion/tty/app.rb', line 48

def setup_hotkeys
  @hotkeys.register("\x04", 'Toggle dashboard (Ctrl+D)') do
    toggle_dashboard
  end
  @hotkeys.register("\x0C", 'Refresh screen (Ctrl+L)') do
    :refresh
  end
  @hotkeys.register('?', 'Show help overlay') do
    show_help_overlay
  end
end

#setup_llmObject



95
96
97
98
99
# File 'lib/legion/tty/app.rb', line 95

def setup_llm
  @llm_chat = try_settings_llm || try_credentials_llm
rescue StandardError
  @llm_chat = nil
end

#show_help_overlayObject



71
72
73
74
75
76
# File 'lib/legion/tty/app.rb', line 71

def show_help_overlay
  bindings = @hotkeys.list
  lines = bindings.map { |b| "  #{b[:key].inspect} - #{b[:description]}" }
  text = "Hotkeys:\n#{lines.join("\n")}"
  @screen_manager.show_overlay(text)
end

#shutdownObject



132
133
134
# File 'lib/legion/tty/app.rb', line 132

def shutdown
  @screen_manager.teardown_all
end

#startObject



39
40
41
42
43
44
45
46
# File 'lib/legion/tty/app.rb', line 39

def start
  setup_hotkeys
  if self.class.first_run?(config_dir: @config_dir)
    run_onboarding
  else
    run_chat
  end
end

#toggle_dashboardObject



60
61
62
63
64
65
66
67
68
69
# File 'lib/legion/tty/app.rb', line 60

def toggle_dashboard
  active = @screen_manager.active_screen
  if active.is_a?(Screens::Dashboard)
    @screen_manager.pop
  else
    require_relative 'screens/dashboard'
    dashboard = Screens::Dashboard.new(self)
    @screen_manager.push(dashboard)
  end
end