legion-tty 0.4.1 → 0.4.3
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 +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/legion/tty/components/input_bar.rb +7 -1
- data/lib/legion/tty/components/message_stream.rb +29 -0
- data/lib/legion/tty/screens/chat.rb +97 -14
- data/lib/legion/tty/theme.rb +102 -35
- data/lib/legion/tty/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 93f9cd78860072bfa0df27f33574552a7d5ac749fbb9440f61017ed76f7f9f4d
|
|
4
|
+
data.tar.gz: c590bb6fb1cbe8639b5df4e46e0aa255f5d23f01499c8d2b1137ad86700412b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8880c1013b5c36a3d9a7d378280b6a1212ba82f527a37dd7f5f81b5b0fc591435ea10fec4a565b5e95a714be1b6340b587214ce9ccde08ee1dfbc63572e0d2f9
|
|
7
|
+
data.tar.gz: d99de6e491d811a3e891833760c4f25fe45c4034494bd200322b41145fc39a16929b8ea3b5295c2044cc1e123e45f30022f310ca97aaf1643f842696a424db77
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.3] - 2026-03-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Daemon-first chat routing: chat screen routes through LegionIO daemon when available
|
|
7
|
+
- `send_via_daemon` and `send_via_direct` methods with automatic fallback
|
|
8
|
+
- `daemon_available?` guard for `Legion::LLM::DaemonClient` presence
|
|
9
|
+
|
|
10
|
+
## [0.4.2] - 2026-03-19
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Multi-provider model switching: `/model <provider>` creates new Legion::LLM.chat instance
|
|
14
|
+
- Model picker integration: `open_model_picker` for interactive provider/model selection
|
|
15
|
+
- ToolPanel wiring in MessageStream: `add_tool_call`, `update_tool_call` methods
|
|
16
|
+
- Tool call rendering in chat messages (`:tool` role with panel display)
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- Flaky table_view_spec: added explicit `require 'tty-table'` to prevent test ordering failures
|
|
20
|
+
|
|
3
21
|
## [0.4.1] - 2026-03-19
|
|
4
22
|
|
|
5
23
|
### Added
|
|
@@ -41,11 +41,17 @@ module Legion
|
|
|
41
41
|
@completions.select { |c| c.start_with?(partial) }.sort
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def history
|
|
45
|
+
return [] unless @reader.respond_to?(:history)
|
|
46
|
+
|
|
47
|
+
@reader.history.to_a
|
|
48
|
+
end
|
|
49
|
+
|
|
44
50
|
private
|
|
45
51
|
|
|
46
52
|
def build_default_reader
|
|
47
53
|
require 'tty-reader'
|
|
48
|
-
reader = ::TTY::Reader.new
|
|
54
|
+
reader = ::TTY::Reader.new(history_cycle: true)
|
|
49
55
|
register_tab_completion(reader)
|
|
50
56
|
reader
|
|
51
57
|
rescue LoadError
|
|
@@ -29,6 +29,21 @@ module Legion
|
|
|
29
29
|
@messages.last[:tool_panels] << panel
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
def add_tool_call(name:, args: {}, status: :running)
|
|
33
|
+
require_relative 'tool_panel'
|
|
34
|
+
panel = ToolPanel.new(name: name, args: args, status: status)
|
|
35
|
+
@messages << { role: :tool, content: panel, tool_panel: true }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def update_tool_call(name:, status:, duration: nil, result: nil, error: nil)
|
|
39
|
+
tool_msg = @messages.reverse.find do |m|
|
|
40
|
+
m[:tool_panel] && m[:content].is_a?(ToolPanel) && m[:content].instance_variable_get(:@name) == name
|
|
41
|
+
end
|
|
42
|
+
return unless tool_msg
|
|
43
|
+
|
|
44
|
+
apply_tool_panel_update(tool_msg[:content], status: status, duration: duration, result: result, error: error)
|
|
45
|
+
end
|
|
46
|
+
|
|
32
47
|
def scroll_up(lines = 1)
|
|
33
48
|
@scroll_offset += lines
|
|
34
49
|
end
|
|
@@ -60,6 +75,7 @@ module Legion
|
|
|
60
75
|
when :user then user_lines(msg)
|
|
61
76
|
when :assistant then assistant_lines(msg, width)
|
|
62
77
|
when :system then system_lines(msg)
|
|
78
|
+
when :tool then tool_call_lines(msg, width)
|
|
63
79
|
else []
|
|
64
80
|
end
|
|
65
81
|
end
|
|
@@ -85,9 +101,22 @@ module Legion
|
|
|
85
101
|
msg[:content].split("\n").map { |l| " #{Theme.c(:muted, l)}" }
|
|
86
102
|
end
|
|
87
103
|
|
|
104
|
+
def tool_call_lines(msg, width)
|
|
105
|
+
return [] unless msg[:tool_panel] && msg[:content].respond_to?(:render)
|
|
106
|
+
|
|
107
|
+
msg[:content].render(width: width).split("\n")
|
|
108
|
+
end
|
|
109
|
+
|
|
88
110
|
def panel_lines(msg, width)
|
|
89
111
|
msg[:tool_panels].flat_map { |panel| panel.render(width: width).split("\n") }
|
|
90
112
|
end
|
|
113
|
+
|
|
114
|
+
def apply_tool_panel_update(panel, status:, duration:, result:, error:)
|
|
115
|
+
panel.instance_variable_set(:@status, status)
|
|
116
|
+
panel.instance_variable_set(:@duration, duration) if duration
|
|
117
|
+
panel.instance_variable_set(:@result, result) if result
|
|
118
|
+
panel.instance_variable_set(:@error, error) if error
|
|
119
|
+
end
|
|
91
120
|
end
|
|
92
121
|
end
|
|
93
122
|
end
|
|
@@ -13,7 +13,7 @@ module Legion
|
|
|
13
13
|
# rubocop:disable Metrics/ClassLength
|
|
14
14
|
class Chat < Base
|
|
15
15
|
SLASH_COMMANDS = %w[/help /quit /clear /model /session /cost /export /tools /dashboard /hotkeys /save /load
|
|
16
|
-
/sessions /system /delete /plan /palette /extensions /config].freeze
|
|
16
|
+
/sessions /system /delete /plan /palette /extensions /config /theme].freeze
|
|
17
17
|
|
|
18
18
|
attr_reader :message_stream, :status_bar
|
|
19
19
|
|
|
@@ -92,20 +92,16 @@ module Legion
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def send_to_llm(message)
|
|
95
|
-
unless @llm_chat
|
|
95
|
+
unless @llm_chat || daemon_available?
|
|
96
96
|
@message_stream.append_streaming('LLM not configured. Use /help for commands.')
|
|
97
97
|
return
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@message_stream.append_streaming(chunk.content) if chunk.content
|
|
105
|
-
render_screen
|
|
100
|
+
if daemon_available?
|
|
101
|
+
send_via_daemon(message)
|
|
102
|
+
else
|
|
103
|
+
send_via_direct(message)
|
|
106
104
|
end
|
|
107
|
-
@status_bar.update(thinking: false)
|
|
108
|
-
track_response_tokens(response)
|
|
109
105
|
rescue StandardError => e
|
|
110
106
|
@status_bar.update(thinking: false)
|
|
111
107
|
@message_stream.append_streaming("\n[Error: #{e.message}]")
|
|
@@ -142,6 +138,40 @@ module Legion
|
|
|
142
138
|
@llm_chat.with_instructions(prompt) if @llm_chat.respond_to?(:with_instructions)
|
|
143
139
|
end
|
|
144
140
|
|
|
141
|
+
def send_via_daemon(message)
|
|
142
|
+
result = Legion::LLM.ask(message: message)
|
|
143
|
+
|
|
144
|
+
case result&.dig(:status)
|
|
145
|
+
when :done
|
|
146
|
+
@message_stream.append_streaming(result[:response])
|
|
147
|
+
when :error
|
|
148
|
+
err = result.dig(:error, :message) || 'Unknown error'
|
|
149
|
+
@message_stream.append_streaming("\n[Daemon error: #{err}]")
|
|
150
|
+
else
|
|
151
|
+
send_via_direct(message)
|
|
152
|
+
end
|
|
153
|
+
rescue StandardError
|
|
154
|
+
send_via_direct(message)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def send_via_direct(message)
|
|
158
|
+
return unless @llm_chat
|
|
159
|
+
|
|
160
|
+
@status_bar.update(thinking: true)
|
|
161
|
+
render_screen
|
|
162
|
+
response = @llm_chat.ask(message) do |chunk|
|
|
163
|
+
@status_bar.update(thinking: false)
|
|
164
|
+
@message_stream.append_streaming(chunk.content) if chunk.content
|
|
165
|
+
render_screen
|
|
166
|
+
end
|
|
167
|
+
@status_bar.update(thinking: false)
|
|
168
|
+
track_response_tokens(response)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def daemon_available?
|
|
172
|
+
!!(defined?(Legion::LLM::DaemonClient) && Legion::LLM::DaemonClient.available?)
|
|
173
|
+
end
|
|
174
|
+
|
|
145
175
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
146
176
|
def build_system_prompt(cfg)
|
|
147
177
|
lines = ['You are Legion, an async cognition engine and AI assistant.']
|
|
@@ -245,6 +275,7 @@ module Legion
|
|
|
245
275
|
when '/palette' then handle_palette
|
|
246
276
|
when '/extensions' then handle_extensions_screen
|
|
247
277
|
when '/config' then handle_config_screen
|
|
278
|
+
when '/theme' then handle_theme(input)
|
|
248
279
|
else :handled
|
|
249
280
|
end
|
|
250
281
|
end
|
|
@@ -255,7 +286,8 @@ module Legion
|
|
|
255
286
|
role: :system,
|
|
256
287
|
content: "Commands:\n /help /quit /clear /model <name> /session <name> /cost\n " \
|
|
257
288
|
"/export [md|json] /tools /dashboard /hotkeys /save /load /sessions\n " \
|
|
258
|
-
"/system <prompt> /delete <session> /plan /palette /extensions /config\n
|
|
289
|
+
"/system <prompt> /delete <session> /plan /palette /extensions /config\n " \
|
|
290
|
+
"/theme [name] -- switch color theme (purple, green, blue, amber)\n\n" \
|
|
259
291
|
'Hotkeys: Ctrl+D=dashboard Ctrl+K=palette Ctrl+S=sessions Esc=back'
|
|
260
292
|
)
|
|
261
293
|
:handled
|
|
@@ -282,16 +314,50 @@ module Legion
|
|
|
282
314
|
return
|
|
283
315
|
end
|
|
284
316
|
|
|
285
|
-
|
|
317
|
+
apply_model_switch(name)
|
|
318
|
+
rescue StandardError => e
|
|
319
|
+
@message_stream.add_message(role: :system, content: "Failed to switch model: #{e.message}")
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def apply_model_switch(name)
|
|
323
|
+
new_chat = try_provider_switch(name)
|
|
324
|
+
if new_chat
|
|
325
|
+
@llm_chat = new_chat
|
|
326
|
+
@status_bar.update(model: name)
|
|
327
|
+
@token_tracker.update_model(name)
|
|
328
|
+
@message_stream.add_message(role: :system, content: "Switched to provider: #{name}")
|
|
329
|
+
elsif @llm_chat.respond_to?(:with_model)
|
|
286
330
|
@llm_chat.with_model(name)
|
|
287
331
|
@status_bar.update(model: name)
|
|
332
|
+
@token_tracker.update_model(name)
|
|
288
333
|
@message_stream.add_message(role: :system, content: "Model switched to: #{name}")
|
|
289
334
|
else
|
|
290
335
|
@status_bar.update(model: name)
|
|
291
336
|
@message_stream.add_message(role: :system, content: "Model set to: #{name}")
|
|
292
337
|
end
|
|
293
|
-
|
|
294
|
-
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def try_provider_switch(name)
|
|
341
|
+
return nil unless defined?(Legion::LLM)
|
|
342
|
+
|
|
343
|
+
providers = Legion::LLM.settings[:providers]
|
|
344
|
+
return nil unless providers.is_a?(Hash) && providers.key?(name.to_sym)
|
|
345
|
+
|
|
346
|
+
Legion::LLM.chat(provider: name)
|
|
347
|
+
rescue StandardError
|
|
348
|
+
nil
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def open_model_picker
|
|
352
|
+
require_relative '../components/model_picker'
|
|
353
|
+
picker = Components::ModelPicker.new(
|
|
354
|
+
current_provider: safe_config[:provider],
|
|
355
|
+
current_model: @llm_chat.respond_to?(:model) ? @llm_chat.model.to_s : nil
|
|
356
|
+
)
|
|
357
|
+
selection = picker.select_with_prompt(output: @output)
|
|
358
|
+
return unless selection
|
|
359
|
+
|
|
360
|
+
switch_model(selection[:provider])
|
|
295
361
|
end
|
|
296
362
|
|
|
297
363
|
def show_current_model
|
|
@@ -506,6 +572,23 @@ module Legion
|
|
|
506
572
|
:handled
|
|
507
573
|
end
|
|
508
574
|
|
|
575
|
+
def handle_theme(input)
|
|
576
|
+
name = input.split(nil, 2)[1]
|
|
577
|
+
if name
|
|
578
|
+
if Theme.switch(name)
|
|
579
|
+
@message_stream.add_message(role: :system, content: "Theme switched to: #{name}")
|
|
580
|
+
else
|
|
581
|
+
available = Theme.available_themes.join(', ')
|
|
582
|
+
@message_stream.add_message(role: :system, content: "Unknown theme '#{name}'. Available: #{available}")
|
|
583
|
+
end
|
|
584
|
+
else
|
|
585
|
+
current = Theme.current_theme
|
|
586
|
+
available = Theme.available_themes.join(', ')
|
|
587
|
+
@message_stream.add_message(role: :system, content: "Current theme: #{current}\nAvailable: #{available}")
|
|
588
|
+
end
|
|
589
|
+
:handled
|
|
590
|
+
end
|
|
591
|
+
|
|
509
592
|
def detect_provider
|
|
510
593
|
cfg = safe_config
|
|
511
594
|
provider = cfg[:provider].to_s.downcase
|
data/lib/legion/tty/theme.rb
CHANGED
|
@@ -2,44 +2,100 @@
|
|
|
2
2
|
|
|
3
3
|
module Legion
|
|
4
4
|
module TTY
|
|
5
|
+
# rubocop:disable Metrics/ModuleLength
|
|
5
6
|
module Theme
|
|
6
7
|
# rubocop:disable Naming/VariableNumber
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
THEMES = {
|
|
9
|
+
purple: {
|
|
10
|
+
palette: {
|
|
11
|
+
shade_1: [30, 27, 46], shade_2: [41, 37, 63], shade_3: [52, 47, 80],
|
|
12
|
+
shade_4: [63, 57, 97], shade_5: [74, 67, 114], shade_6: [85, 77, 131],
|
|
13
|
+
shade_7: [96, 87, 148], shade_8: [107, 97, 165], shade_9: [118, 107, 182],
|
|
14
|
+
shade_10: [129, 119, 199], shade_11: [140, 131, 210], shade_12: [157, 148, 221],
|
|
15
|
+
shade_13: [174, 167, 230], shade_14: [191, 186, 239], shade_15: [208, 205, 245],
|
|
16
|
+
shade_16: [225, 224, 250], shade_17: [242, 243, 255]
|
|
17
|
+
},
|
|
18
|
+
semantic: {
|
|
19
|
+
primary: :shade_9, secondary: :shade_6, accent: :shade_12,
|
|
20
|
+
success: [0, 200, 83], warning: [255, 191, 0], error: [255, 69, 58],
|
|
21
|
+
info: :shade_7, surface: :shade_1, muted: :shade_4,
|
|
22
|
+
rain: :shade_11, rain_fade: :shade_3
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
green: {
|
|
26
|
+
palette: {
|
|
27
|
+
shade_1: [15, 30, 15], shade_2: [20, 45, 20], shade_3: [25, 60, 25],
|
|
28
|
+
shade_4: [30, 75, 30], shade_5: [35, 90, 35], shade_6: [40, 110, 40],
|
|
29
|
+
shade_7: [50, 130, 50], shade_8: [60, 150, 60], shade_9: [75, 170, 75],
|
|
30
|
+
shade_10: [90, 190, 90], shade_11: [110, 210, 110], shade_12: [140, 225, 140],
|
|
31
|
+
shade_13: [170, 235, 170], shade_14: [195, 242, 195], shade_15: [215, 248, 215],
|
|
32
|
+
shade_16: [230, 252, 230], shade_17: [245, 255, 245]
|
|
33
|
+
},
|
|
34
|
+
semantic: {
|
|
35
|
+
primary: :shade_9, secondary: :shade_6, accent: :shade_12,
|
|
36
|
+
success: [0, 200, 83], warning: [255, 191, 0], error: [255, 69, 58],
|
|
37
|
+
info: :shade_7, surface: :shade_1, muted: :shade_4,
|
|
38
|
+
rain: :shade_11, rain_fade: :shade_3
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
blue: {
|
|
42
|
+
palette: {
|
|
43
|
+
shade_1: [15, 20, 40], shade_2: [20, 30, 60], shade_3: [25, 40, 80],
|
|
44
|
+
shade_4: [30, 50, 100], shade_5: [40, 65, 120], shade_6: [50, 80, 140],
|
|
45
|
+
shade_7: [65, 100, 160], shade_8: [80, 120, 180], shade_9: [100, 140, 200],
|
|
46
|
+
shade_10: [120, 160, 215], shade_11: [145, 185, 225], shade_12: [170, 205, 235],
|
|
47
|
+
shade_13: [195, 220, 242], shade_14: [210, 230, 248], shade_15: [225, 240, 252],
|
|
48
|
+
shade_16: [238, 248, 255], shade_17: [248, 252, 255]
|
|
49
|
+
},
|
|
50
|
+
semantic: {
|
|
51
|
+
primary: :shade_9, secondary: :shade_6, accent: :shade_12,
|
|
52
|
+
success: [0, 200, 83], warning: [255, 191, 0], error: [255, 69, 58],
|
|
53
|
+
info: :shade_7, surface: :shade_1, muted: :shade_4,
|
|
54
|
+
rain: :shade_11, rain_fade: :shade_3
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
amber: {
|
|
58
|
+
palette: {
|
|
59
|
+
shade_1: [35, 25, 10], shade_2: [50, 35, 15], shade_3: [65, 45, 20],
|
|
60
|
+
shade_4: [80, 55, 25], shade_5: [100, 70, 30], shade_6: [120, 85, 35],
|
|
61
|
+
shade_7: [140, 100, 40], shade_8: [165, 120, 50], shade_9: [190, 140, 60],
|
|
62
|
+
shade_10: [210, 160, 70], shade_11: [225, 180, 85], shade_12: [235, 200, 110],
|
|
63
|
+
shade_13: [242, 215, 140], shade_14: [248, 230, 170], shade_15: [252, 240, 200],
|
|
64
|
+
shade_16: [255, 248, 225], shade_17: [255, 252, 245]
|
|
65
|
+
},
|
|
66
|
+
semantic: {
|
|
67
|
+
primary: :shade_9, secondary: :shade_6, accent: :shade_12,
|
|
68
|
+
success: [0, 200, 83], warning: [255, 191, 0], error: [255, 69, 58],
|
|
69
|
+
info: :shade_7, surface: :shade_1, muted: :shade_4,
|
|
70
|
+
rain: :shade_11, rain_fade: :shade_3
|
|
71
|
+
}
|
|
72
|
+
}
|
|
25
73
|
}.freeze
|
|
26
74
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
accent: :purple_12,
|
|
31
|
-
success: [0, 200, 83],
|
|
32
|
-
warning: [255, 191, 0],
|
|
33
|
-
error: [255, 69, 58],
|
|
34
|
-
info: :purple_7,
|
|
35
|
-
surface: :purple_1,
|
|
36
|
-
muted: :purple_4,
|
|
37
|
-
rain: :purple_11,
|
|
38
|
-
rain_fade: :purple_3
|
|
39
|
-
}.freeze
|
|
75
|
+
# Legacy aliases for backward compatibility
|
|
76
|
+
PALETTE = THEMES[:purple][:palette].transform_keys { |k| k.to_s.sub('shade_', 'purple_').to_sym }.freeze
|
|
77
|
+
SEMANTIC = THEMES[:purple][:semantic].freeze
|
|
40
78
|
# rubocop:enable Naming/VariableNumber
|
|
41
79
|
|
|
42
80
|
class << self
|
|
81
|
+
def current_theme
|
|
82
|
+
@current_theme || :purple
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# rubocop:disable Naming/PredicateMethod
|
|
86
|
+
def switch(name)
|
|
87
|
+
name = name.to_sym
|
|
88
|
+
return false unless THEMES.key?(name)
|
|
89
|
+
|
|
90
|
+
@current_theme = name
|
|
91
|
+
true
|
|
92
|
+
end
|
|
93
|
+
# rubocop:enable Naming/PredicateMethod
|
|
94
|
+
|
|
95
|
+
def available_themes
|
|
96
|
+
THEMES.keys
|
|
97
|
+
end
|
|
98
|
+
|
|
43
99
|
def c(name, text)
|
|
44
100
|
rgb = resolve_rgb(name)
|
|
45
101
|
return text unless rgb
|
|
@@ -47,17 +103,28 @@ module Legion
|
|
|
47
103
|
"\e[38;2;#{rgb[0]};#{rgb[1]};#{rgb[2]}m#{text}\e[0m"
|
|
48
104
|
end
|
|
49
105
|
|
|
106
|
+
def reset_theme
|
|
107
|
+
@current_theme = :purple
|
|
108
|
+
end
|
|
109
|
+
|
|
50
110
|
private
|
|
51
111
|
|
|
52
112
|
def resolve_rgb(name)
|
|
53
|
-
|
|
113
|
+
theme = THEMES[current_theme]
|
|
114
|
+
palette = theme[:palette]
|
|
115
|
+
semantic = theme[:semantic]
|
|
116
|
+
|
|
117
|
+
if palette.key?(name)
|
|
118
|
+
palette[name]
|
|
119
|
+
elsif semantic.key?(name)
|
|
120
|
+
ref = semantic[name]
|
|
121
|
+
ref.is_a?(Symbol) ? palette[ref] : ref
|
|
122
|
+
elsif PALETTE.key?(name)
|
|
54
123
|
PALETTE[name]
|
|
55
|
-
elsif SEMANTIC.key?(name)
|
|
56
|
-
ref = SEMANTIC[name]
|
|
57
|
-
ref.is_a?(Symbol) ? PALETTE[ref] : ref
|
|
58
124
|
end
|
|
59
125
|
end
|
|
60
126
|
end
|
|
61
127
|
end
|
|
128
|
+
# rubocop:enable Metrics/ModuleLength
|
|
62
129
|
end
|
|
63
130
|
end
|
data/lib/legion/tty/version.rb
CHANGED