legion-tty 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c760495a859fdc2a4bf7fd578a07a1d5fda5502959a032d97b123bd2567f6fe
4
- data.tar.gz: e0338b1750ee30726575319555ce2e57011d2c503843433ef4a5282fba0b3101
3
+ metadata.gz: 65caf994766a2f1031423310b3ccb27998e8132e4d15973f2cf0e0e5b10fa60a
4
+ data.tar.gz: d3029f10a4a8cc27f930961dffc67f7314ec3e2d326ae7aac15f6266ff598d99
5
5
  SHA512:
6
- metadata.gz: 651364d8929e747cbaa2aa06b76a0e9da6f81ff581778f4061bbc8a0ae0befd7de2590ceb2e0cc139cdc30cb5341f9f66420c37be7d5a368661f9f2b2077fa50
7
- data.tar.gz: 457b264da15403f4b0c7605fe8db84171c4fade505cc0cda2399f23314a944f3826c0ad6ac79be7c4b18d0257e68ebf8254e1daa7426434b3a9ff79453b4a0fc
6
+ metadata.gz: 89d35f0381e976760f62c11bb6f4101546a409b311571b816c2b44c4b12382fe07964041325ac405fa8863b3701635e172f63e5d8a4e4c98518fd3e445e90ef2
7
+ data.tar.gz: 3dda102b9d1262ee74355120f8d682e198f06af5f820ad074c896ba598e53e10f54bd3825f66018e0485cbf5094ce01db4eb55c5249ab35c3b4627789d877fbd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.9] - 2026-03-18
4
+
5
+ ### Fixed
6
+ - Chat LLM not configured: setup_llm now reads from Legion::Settings llm.json first, falls back to legacy credentials.json
7
+
8
+ ## [0.2.8] - 2026-03-18
9
+
10
+ ### Added
11
+ - Extension detection in onboarding: background scan via lex-detect during digital rain
12
+ - "hooking into X..." typed output for each discovered service
13
+ - Offers to install missing extensions when uninstalled gems are detected
14
+ - Graceful skip when lex-detect gem is not installed
15
+ - 7 new specs for extension detection and gem availability (381 total)
16
+
3
17
  ## [0.2.7] - 2026-03-18
4
18
 
5
19
  ### Added
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Rich terminal UI for the LegionIO async cognition engine.
4
4
 
5
+ **Version**: 0.2.9
6
+
5
7
  Think Claude Code meets Codex CLI, but for LegionIO: onboarding wizard with identity detection, streaming AI chat shell, operational dashboard, and session persistence - all rendered with the [tty-ruby](https://ttytoolkit.org/) gem ecosystem.
6
8
 
7
9
  ## Features
@@ -93,12 +93,7 @@ module Legion
93
93
  end
94
94
 
95
95
  def setup_llm
96
- return unless @credentials[:provider] && @credentials[:api_key]
97
-
98
- provider = @credentials[:provider].to_sym
99
- api_key = @credentials[:api_key]
100
- configure_llm_provider(provider, api_key)
101
- @llm_chat = create_llm_chat(provider)
96
+ @llm_chat = try_settings_llm || try_credentials_llm
102
97
  rescue StandardError
103
98
  @llm_chat = nil
104
99
  end
@@ -145,6 +140,31 @@ module Legion
145
140
 
146
141
  private
147
142
 
143
+ def try_settings_llm
144
+ require 'legion/llm'
145
+ require 'legion/settings'
146
+ Legion::LLM.start unless Legion::LLM.started?
147
+ return nil unless Legion::LLM.started?
148
+
149
+ provider = Legion::LLM.settings[:default_provider]
150
+ return nil unless provider
151
+
152
+ Legion::LLM.chat(provider: provider)
153
+ rescue LoadError, StandardError
154
+ nil
155
+ end
156
+
157
+ def try_credentials_llm
158
+ return nil unless @credentials[:provider] && @credentials[:api_key]
159
+
160
+ provider = @credentials[:provider].to_sym
161
+ api_key = @credentials[:api_key]
162
+ configure_llm_provider(provider, api_key)
163
+ create_llm_chat(provider)
164
+ rescue StandardError
165
+ nil
166
+ end
167
+
148
168
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
149
169
  def save_identity(data)
150
170
  identity = {
@@ -22,12 +22,7 @@ module Legion
22
22
  @wizard = wizard || Components::WizardPrompt.new
23
23
  @output = output
24
24
  @skip_rain = skip_rain
25
- @scan_queue = Queue.new
26
- @github_queue = Queue.new
27
- @github_quick_queue = Queue.new
28
- @kerberos_queue = Queue.new
29
- @llm_queue = Queue.new
30
- @bootstrap_queue = Queue.new
25
+ initialize_queues
31
26
  @kerberos_identity = nil
32
27
  @github_quick = nil
33
28
  @vault_results = nil
@@ -48,6 +43,7 @@ module Legion
48
43
  scan_data, github_data = collect_background_results
49
44
  run_cache_awakening(scan_data)
50
45
  run_gaia_awakening
46
+ run_extension_detection
51
47
  run_reveal(name: config[:name], scan_data: scan_data, github_data: github_data)
52
48
  @log.log('onboarding', 'activate complete')
53
49
  build_onboarding_result(config, scan_data, github_data)
@@ -146,6 +142,20 @@ module Legion
146
142
  @llm_probe.run_async(@llm_queue)
147
143
  @bootstrap_probe = Background::BootstrapConfig.new(logger: @log)
148
144
  @bootstrap_probe.run_async(@bootstrap_queue)
145
+ start_detect_probe
146
+ end
147
+
148
+ def start_detect_probe
149
+ return unless detect_gem_available?
150
+
151
+ @log.log('detect', 'launching environment scan')
152
+ Thread.new do
153
+ results = Legion::Extensions::Detect.scan
154
+ @detect_queue.push({ type: :detect_complete, data: results })
155
+ rescue StandardError => e
156
+ @log.log('detect', "ERROR: #{e.message}")
157
+ @detect_queue.push({ type: :detect_error, error: e.message })
158
+ end
149
159
  end
150
160
 
151
161
  def run_cache_awakening(scan_data)
@@ -268,6 +278,63 @@ module Legion
268
278
 
269
279
  private
270
280
 
281
+ def initialize_queues
282
+ @scan_queue = Queue.new
283
+ @github_queue = Queue.new
284
+ @github_quick_queue = Queue.new
285
+ @kerberos_queue = Queue.new
286
+ @llm_queue = Queue.new
287
+ @bootstrap_queue = Queue.new
288
+ @detect_queue = Queue.new
289
+ end
290
+
291
+ def run_extension_detection
292
+ return unless detect_gem_available?
293
+
294
+ result = drain_with_timeout(@detect_queue, timeout: 3)
295
+ results = result&.dig(:data) || []
296
+ return if results.empty?
297
+
298
+ @log.log('detect', "detected #{results.size} services")
299
+ display_detected_extensions(results)
300
+ offer_missing_extensions(results)
301
+ @output.puts
302
+ end
303
+
304
+ def display_detected_extensions(results)
305
+ results.each do |detection|
306
+ sleep 0.4
307
+ typed_output(" hooking into #{detection[:name]}...")
308
+ @output.puts
309
+ end
310
+ end
311
+
312
+ # rubocop:disable Metrics/AbcSize
313
+ def offer_missing_extensions(results)
314
+ missing = results.select { |r| r[:installed].values.any?(false) }
315
+ if missing.any?
316
+ missing_gems = missing.flat_map { |r| r[:extensions].reject { |e| r[:installed][e] } }.uniq
317
+ @output.puts
318
+ typed_output("#{missing_gems.size} new connection#{'s' if missing_gems.size != 1} available.")
319
+ @output.puts
320
+ if @wizard.confirm('Install them now?')
321
+ Legion::Extensions::Detect.install_missing!
322
+ typed_output('Extensions installed. Neural pathways expanded.')
323
+ end
324
+ else
325
+ typed_output('All connections established.')
326
+ end
327
+ end
328
+ # rubocop:enable Metrics/AbcSize
329
+
330
+ def detect_gem_available?
331
+ require 'legion/extensions/detect'
332
+ true
333
+ rescue LoadError
334
+ @log.log('detect', 'lex-detect gem not available, skipping')
335
+ false
336
+ end
337
+
271
338
  def collect_bootstrap_result
272
339
  result = drain_with_timeout(@bootstrap_queue, timeout: 5)
273
340
  @bootstrap_data = result&.dig(:data)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module TTY
5
- VERSION = '0.2.7'
5
+ VERSION = '0.2.9'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-tty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  - !ruby/object:Gem::Version
244
244
  version: '0'
245
245
  requirements: []
246
- rubygems_version: 3.6.9
246
+ rubygems_version: 4.0.8
247
247
  specification_version: 4
248
248
  summary: Interactive terminal UI for the LegionIO framework
249
249
  test_files: []