Class: Legion::TTY::Screens::Onboarding
- Inherits:
-
Base
- Object
- Base
- Legion::TTY::Screens::Onboarding
show all
- Includes:
- Logging::Helper
- Defined in:
- lib/legion/tty/screens/onboarding.rb
Overview
rubocop:disable Metrics/ClassLength
Constant Summary
collapse
- TYPED_DELAY =
0.05
- GAIA_GEMS =
%w[
lex-agentic-self lex-agentic-affect lex-agentic-attention
lex-agentic-defense lex-agentic-executive lex-agentic-homeostasis
lex-agentic-imagination lex-agentic-inference lex-agentic-integration
lex-agentic-language lex-agentic-learning lex-agentic-memory
lex-agentic-social
lex-tick lex-extinction lex-mind-growth lex-mesh
lex-synapse lex-react
legion-gaia legion-apollo
].freeze
Instance Attribute Summary
Attributes inherited from Base
#app
Instance Method Summary
collapse
Methods inherited from Base
#deactivate, #handle_input, #needs_input_bar?, #render, #teardown
Constructor Details
#initialize(app, wizard: nil, output: $stdout, skip_rain: false) ⇒ Onboarding
Returns a new instance of Onboarding.
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/legion/tty/screens/onboarding.rb', line 34
def initialize(app, wizard: nil, output: $stdout, skip_rain: false)
super(app)
@wizard = wizard || Components::WizardPrompt.new
@output = output
@skip_rain = skip_rain
initialize_queues
@kerberos_identity = nil
@github_quick = nil
@vault_results = nil
@bootstrap_data = nil
@boot_log = BootLogger.new
end
|
Instance Method Details
#activate ⇒ Object
rubocop:disable Metrics/AbcSize
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
# File 'lib/legion/tty/screens/onboarding.rb', line 48
def activate
@boot_log.log('onboarding', 'activate started')
start_background_threads
run_rain unless @skip_rain
run_intro
config = run_wizard
@boot_log.log('wizard', "name=#{config[:name]} provider=#{config[:provider]}")
collect_bootstrap_result
run_vault_auth
scan_data, github_data = collect_background_results
run_cache_awakening(scan_data)
run_gaia_awakening
run_extension_detection
run_service_auth
run_reveal(name: config[:name], scan_data: scan_data, github_data: github_data)
@boot_log.log('onboarding', 'activate complete')
build_onboarding_result(config, scan_data, github_data)
end
|
#build_summary(name:, scan_data:, github_data:) ⇒ Object
rubocop:disable Metrics/AbcSize
286
287
288
289
290
291
292
293
294
295
296
297
|
# File 'lib/legion/tty/screens/onboarding.rb', line 286
def build_summary(name:, scan_data:, github_data:)
lines = ["Hello, #{name}!", '', "Here's what I found:"]
lines.concat(bootstrap_summary_lines)
lines.concat(identity_summary_lines)
lines.concat(scan_summary_lines(scan_data))
lines.concat(dotfiles_summary_lines(scan_data))
lines.concat(github_summary_lines(github_data))
lines.concat(vault_summary_lines)
lines.concat(cache_summary_lines(scan_data))
lines.concat(gaia_summary_lines)
lines.join("\n")
end
|
#collect_background_results ⇒ Object
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
# File 'lib/legion/tty/screens/onboarding.rb', line 251
def collect_background_results
@boot_log.log('collect', 'waiting for scanner results (10s timeout)')
scan_result = drain_with_timeout(@scan_queue, timeout: 10)
scan_data = scan_result&.dig(:data) || { services: {}, repos: [], tools: {} }
log_scan_data(scan_data)
remotes = scan_data[:repos]&.filter_map { |r| r[:remote] } || []
@boot_log.log('collect', "launching github probe with #{remotes.size} remotes")
@github_probe.run_async(@github_queue, remotes: remotes, quick_profile: @github_quick)
github_result = drain_with_timeout(@github_queue, timeout: 8)
github_data = github_result&.dig(:data)
log_github_data(github_data)
[scan_data, github_data]
end
|
#detect_providers ⇒ Object
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/legion/tty/screens/onboarding.rb', line 123
def detect_providers
typed_output('Detecting AI providers...')
@output.puts
@output.puts
llm_data = drain_with_timeout(@llm_queue, timeout: 15)
providers = llm_data&.dig(:data, :providers) || []
@wizard.display_provider_results(providers)
@output.puts
providers
end
|
#run_cache_awakening(scan_data) ⇒ Object
177
178
179
180
181
182
183
184
185
186
187
188
189
|
# File 'lib/legion/tty/screens/onboarding.rb', line 177
def run_cache_awakening(scan_data)
services = scan_data.is_a?(Hash) ? scan_data[:services] : nil
return unless services.is_a?(Hash)
if services.dig(:memcached, :running) || services.dig(:redis, :running)
typed_output('... extending neural pathways...')
sleep 0.8
typed_output('Additional memory online.')
else
run_cache_offer
end
@output.puts
end
|
#run_cache_offer ⇒ Object
191
192
193
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/legion/tty/screens/onboarding.rb', line 191
def run_cache_offer
typed_output('No extended memory detected.')
sleep 0.8
@output.puts
return unless @wizard.confirm('Shall I activate a memory cache?')
binary = detect_cache_binary
if binary
run_cache_start(binary)
else
typed_output('No cache service found. Install with: brew install memcached')
end
end
|
#run_cache_start(binary) ⇒ Object
205
206
207
208
209
210
211
212
|
# File 'lib/legion/tty/screens/onboarding.rb', line 205
def run_cache_start(binary)
started = start_cache_service(binary.to_s)
if started
typed_output('Memory cache activated. Neural capacity expanded.')
else
typed_output("No cache service found. Install with: brew install #{binary}")
end
end
|
#run_gaia_awakening ⇒ Object
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/legion/tty/screens/onboarding.rb', line 214
def run_gaia_awakening
typed_output('Scanning for active cognition threads...')
sleep 1.2
@output.puts
gaia_active = if legionio_running?
typed_output('GAIA is awake.')
sleep 0.5
typed_output('Heuristic mesh: nominal.')
sleep 0.8
typed_output('Cognitive threads synchronized.')
true
else
wake_gaia_daemon
end
offer_gaia_gems if gaia_active
@output.puts
end
|
#run_intro ⇒ Object
rubocop:enable Metrics/AbcSize
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/legion/tty/screens/onboarding.rb', line 88
def run_intro
collect_kerberos_identity
collect_github_quick
sleep 2
typed_output('...')
sleep 1.2
@output.puts
@output.puts
typed_output("Hello. I'm Legion.")
@output.puts
sleep 1.5
if @kerberos_identity
run_intro_with_identity
else
typed_output("Let's get you set up.")
@output.puts
@output.puts
end
run_intro_with_github if @github_quick
end
|
#run_rain ⇒ Object
rubocop:disable Metrics/AbcSize
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/legion/tty/screens/onboarding.rb', line 69
def run_rain
require 'tty-cursor'
require 'tty-font'
width = terminal_width
height = terminal_height
rain = Components::DigitalRain.new(width: width, height: height)
rain.run(duration_seconds: 20, fps: 18, output: @output)
@output.print ::TTY::Cursor.clear_screen
font = ::TTY::Font.new(:standard)
title = font.write('LEGION')
title.each_line do |line|
@output.puts line.center(width)
end
@output.puts Theme.c(:muted, 'async cognition engine').center(width + 20)
sleep 5
@output.print ::TTY::Cursor.clear_screen
end
|
#run_reveal(name:, scan_data:, github_data:) ⇒ Object
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
# File 'lib/legion/tty/screens/onboarding.rb', line 267
def run_reveal(name:, scan_data:, github_data:)
require 'tty-box'
@output.puts
typed_output('One moment...')
@output.puts
sleep 1.5
summary = build_summary(name: name, scan_data: scan_data, github_data: github_data)
box = ::TTY::Box.frame(summary, padding: 1, border: :thick)
@output.puts box
@output.puts
@wizard.confirm('Does this look right?')
@output.puts
sleep 0.8
typed_output("Let's chat.")
@output.puts
sleep 1
end
|
#run_wizard ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/legion/tty/screens/onboarding.rb', line 111
def run_wizard
name = ask_for_name
sleep 0.8
typed_output(" Nice to meet you, #{name}.")
@output.puts
sleep 1
providers = detect_providers
default = select_provider_default(providers)
@output.puts
{ name: name, provider: default, providers: providers }
end
|
#select_provider_default(providers) ⇒ Object
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/legion/tty/screens/onboarding.rb', line 134
def select_provider_default(providers)
working = providers.select { |p| p[:status] == :ok }
working = providers.select { |p| p[:status] == :configured } if working.empty?
if working.any?
default = @wizard.select_default_provider(working)
sleep 0.5
typed_output("Connected. Let's chat.")
default
else
typed_output('No AI providers detected. Configure one in ~/.legionio/settings/llm.json')
nil
end
end
|
#start_background_threads ⇒ Object
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# File 'lib/legion/tty/screens/onboarding.rb', line 148
def start_background_threads
@boot_log.log('threads', 'launching scanner, kerberos probe, github quick probe')
@scanner = Background::Scanner.new(logger: @boot_log)
@github_probe = Background::GitHubProbe.new(logger: @boot_log)
@kerberos_probe = Background::KerberosProbe.new(logger: @boot_log)
@scanner.run_async(@scan_queue)
@kerberos_probe.run_async(@kerberos_queue)
@github_probe.run_quick_async(@github_quick_queue)
require_relative '../background/llm_probe'
@llm_probe = Background::LlmProbe.new(logger: @boot_log, wait_queue: @bootstrap_queue)
@llm_probe.run_async(@llm_queue)
@bootstrap_probe = Background::BootstrapConfig.new(logger: @boot_log)
@bootstrap_probe.run_async(@bootstrap_queue)
start_detect_probe
end
|
#start_detect_probe ⇒ Object
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/legion/tty/screens/onboarding.rb', line 164
def start_detect_probe
return unless detect_gem_available?
@boot_log.log('detect', 'launching environment scan')
Thread.new do
results = Legion::Extensions::Detect.scan
@detect_queue.push({ type: :detect_complete, data: results })
rescue StandardError => e
@boot_log.log('detect', "ERROR: #{e.message}")
@detect_queue.push({ type: :detect_error, error: e.message })
end
end
|
#wake_gaia_daemon ⇒ Object
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
# File 'lib/legion/tty/screens/onboarding.rb', line 234
def wake_gaia_daemon
typed_output('GAIA is dormant.')
sleep 1
@output.puts
return unless @wizard.confirm('Shall I wake her?')
started = start_legionio_daemon
if started
typed_output('... initializing cognitive substrate...')
sleep 1
typed_output('GAIA online. All systems nominal.')
else
typed_output("Could not start daemon. Run 'legionio start' manually.")
end
started
end
|