legion-tty 0.4.24 → 0.4.25
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 +13 -0
- data/lib/legion/tty/screens/chat/model_commands.rb +26 -0
- data/lib/legion/tty/screens/chat/ui_commands.rb +145 -0
- data/lib/legion/tty/screens/chat.rb +10 -1
- 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: c2baad187737411e10cb975111c2e766cd5b1b1c20bc27b7731cc990672597a0
|
|
4
|
+
data.tar.gz: e2d8eaabf4459beba0805f830025321c11fa70ea572aba05640b005e20dbd12a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 53b05dc182ec33a56c75c58a3936c9753b018c8a78ac3ae83f2fac588bafdf5ecb09026a9f70120b86d7685ce75d484bd993ef83efabf84ee0f63c4d81daefb8
|
|
7
|
+
data.tar.gz: 6f6849814bba37b3ebee42a88be6a927efaa913437d1c050586902aa4850cbf334df571e310818b6ddc711ff5d0828ef89e12cb8e249d9b704248e73898e200c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.25] - 2026-03-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `/ask <question>` command: quick concise Q&A mode (instructs LLM to answer in one paragraph)
|
|
7
|
+
- `/define <term>` command: ask LLM for a concise definition
|
|
8
|
+
- `/status` command: comprehensive view of all 18 toggleable modes and settings
|
|
9
|
+
- `/prefs [key] [value]` command: persistent user preferences in `~/.legionio/prefs.json`
|
|
10
|
+
- `/about` command: show legion-tty name, version, author, license, GitHub URL
|
|
11
|
+
- `/commands [pattern]` command: list all slash commands with optional pattern filter and count
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Total slash commands: 103 (milestone)
|
|
15
|
+
|
|
3
16
|
## [0.4.24] - 2026-03-19
|
|
4
17
|
|
|
5
18
|
### Added
|
|
@@ -154,6 +154,32 @@ module Legion
|
|
|
154
154
|
end
|
|
155
155
|
:handled
|
|
156
156
|
end
|
|
157
|
+
|
|
158
|
+
def handle_ask(input)
|
|
159
|
+
question = input.split(nil, 2)[1]&.strip
|
|
160
|
+
unless question && !question.empty?
|
|
161
|
+
@message_stream.add_message(role: :system, content: 'Usage: /ask <question>')
|
|
162
|
+
return :handled
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
@message_stream.add_message(role: :user, content: question)
|
|
166
|
+
@message_stream.add_message(role: :assistant, content: '')
|
|
167
|
+
send_to_llm("Answer the following question concisely in one paragraph: #{question}")
|
|
168
|
+
:handled
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def handle_define(input)
|
|
172
|
+
term = input.split(nil, 2)[1]&.strip
|
|
173
|
+
unless term && !term.empty?
|
|
174
|
+
@message_stream.add_message(role: :system, content: 'Usage: /define <term>')
|
|
175
|
+
return :handled
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
@message_stream.add_message(role: :user, content: term)
|
|
179
|
+
@message_stream.add_message(role: :assistant, content: '')
|
|
180
|
+
send_to_llm("Define the following term concisely: #{term}")
|
|
181
|
+
:handled
|
|
182
|
+
end
|
|
157
183
|
end
|
|
158
184
|
end
|
|
159
185
|
end
|
|
@@ -680,6 +680,49 @@ module Legion
|
|
|
680
680
|
:handled
|
|
681
681
|
end
|
|
682
682
|
|
|
683
|
+
def handle_about
|
|
684
|
+
lines = [
|
|
685
|
+
'legion-tty',
|
|
686
|
+
'Description : Rich terminal UI for the LegionIO async cognition engine',
|
|
687
|
+
"Version : #{Legion::TTY::VERSION}",
|
|
688
|
+
'Author : Matthew Iverson (@Esity)',
|
|
689
|
+
'License : Apache-2.0',
|
|
690
|
+
'GitHub : https://github.com/LegionIO/legion-tty'
|
|
691
|
+
]
|
|
692
|
+
@message_stream.add_message(role: :system, content: lines.join("\n"))
|
|
693
|
+
:handled
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def handle_commands(input)
|
|
697
|
+
pattern = input.split(nil, 2)[1]&.strip&.downcase
|
|
698
|
+
cmds = filter_commands(pattern)
|
|
699
|
+
header = commands_header(pattern, cmds)
|
|
700
|
+
rows = format_command_columns(cmds)
|
|
701
|
+
@message_stream.add_message(role: :system, content: "#{header}\n#{rows.join("\n")}")
|
|
702
|
+
:handled
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
def filter_commands(pattern)
|
|
706
|
+
cmds = SLASH_COMMANDS.sort
|
|
707
|
+
return cmds unless pattern && !pattern.empty?
|
|
708
|
+
|
|
709
|
+
cmds.select { |c| c.include?(pattern) }
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
def commands_header(pattern, cmds)
|
|
713
|
+
if pattern && !pattern.empty?
|
|
714
|
+
"Commands matching '#{pattern}' (#{cmds.size}):"
|
|
715
|
+
else
|
|
716
|
+
"All commands (#{cmds.size}):"
|
|
717
|
+
end
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
def format_command_columns(cmds)
|
|
721
|
+
col_width = cmds.map(&:length).max.to_i + 2
|
|
722
|
+
cols = [terminal_width / [col_width, 1].max, 1].max
|
|
723
|
+
cmds.each_slice(cols).map { |row| row.map { |c| c.ljust(col_width) }.join.rstrip }
|
|
724
|
+
end
|
|
725
|
+
|
|
683
726
|
def handle_freq
|
|
684
727
|
words = collect_freq_words
|
|
685
728
|
if words.empty?
|
|
@@ -707,6 +750,108 @@ module Legion
|
|
|
707
750
|
format(FREQ_ROW_FMT, rank: rank, word: word, count: count, pct: pct)
|
|
708
751
|
end
|
|
709
752
|
end
|
|
753
|
+
|
|
754
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
755
|
+
def handle_status
|
|
756
|
+
autosave_val = @autosave_enabled ? "on (every #{@autosave_interval}s)" : 'off'
|
|
757
|
+
filter_val = @message_stream.filter ? @message_stream.filter[:type].to_s : 'none'
|
|
758
|
+
wrap_val = @message_stream.wrap_width ? @message_stream.wrap_width.to_s : 'off'
|
|
759
|
+
truncate_val = @message_stream.truncate_limit ? @message_stream.truncate_limit.to_s : 'off'
|
|
760
|
+
tee_val = @tee_path || 'off'
|
|
761
|
+
lines = [
|
|
762
|
+
'Mode Status:',
|
|
763
|
+
" Plan mode : #{@plan_mode ? 'on' : 'off'}",
|
|
764
|
+
" Focus mode : #{@focus_mode ? 'on' : 'off'}",
|
|
765
|
+
" Debug mode : #{@debug_mode ? 'on' : 'off'}",
|
|
766
|
+
" Silent mode: #{@silent_mode ? 'on' : 'off'}",
|
|
767
|
+
" Mute system: #{@muted_system ? 'on' : 'off'}",
|
|
768
|
+
" Multi-line : #{@multiline_mode ? 'on' : 'off'}",
|
|
769
|
+
" Speak mode : #{defined?(@speak_mode) && @speak_mode ? 'on' : 'off'}",
|
|
770
|
+
" Autosave : #{autosave_val}",
|
|
771
|
+
" Color : #{@message_stream.colorize ? 'on' : 'off'}",
|
|
772
|
+
" Timestamps : #{@message_stream.show_timestamps ? 'on' : 'off'}",
|
|
773
|
+
" Numbers : #{@message_stream.show_numbers ? 'on' : 'off'}",
|
|
774
|
+
" Wrap : #{wrap_val}",
|
|
775
|
+
" Truncate : #{truncate_val}",
|
|
776
|
+
" Filter : #{filter_val}",
|
|
777
|
+
" Tee : #{tee_val}",
|
|
778
|
+
" Theme : #{Theme.current_theme}",
|
|
779
|
+
" Personality: #{@personality || 'default'}"
|
|
780
|
+
]
|
|
781
|
+
@message_stream.add_message(role: :system, content: lines.join("\n"))
|
|
782
|
+
:handled
|
|
783
|
+
end
|
|
784
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
785
|
+
|
|
786
|
+
def handle_prefs(input)
|
|
787
|
+
parts = input.split(nil, 3)
|
|
788
|
+
key = parts[1]
|
|
789
|
+
value = parts[2]
|
|
790
|
+
if key.nil?
|
|
791
|
+
show_all_prefs
|
|
792
|
+
elsif value.nil?
|
|
793
|
+
show_one_pref(key)
|
|
794
|
+
else
|
|
795
|
+
set_pref(key, value)
|
|
796
|
+
end
|
|
797
|
+
:handled
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
def prefs_path
|
|
801
|
+
File.expand_path('~/.legionio/prefs.json')
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
def load_prefs
|
|
805
|
+
return {} unless File.exist?(prefs_path)
|
|
806
|
+
|
|
807
|
+
require 'json'
|
|
808
|
+
::JSON.parse(File.read(prefs_path))
|
|
809
|
+
rescue ::JSON::ParserError
|
|
810
|
+
{}
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def save_prefs(prefs)
|
|
814
|
+
require 'fileutils'
|
|
815
|
+
require 'json'
|
|
816
|
+
FileUtils.mkdir_p(File.dirname(prefs_path))
|
|
817
|
+
File.write(prefs_path, ::JSON.pretty_generate(prefs))
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
def show_all_prefs
|
|
821
|
+
prefs = load_prefs
|
|
822
|
+
if prefs.empty?
|
|
823
|
+
@message_stream.add_message(role: :system, content: 'No preferences saved.')
|
|
824
|
+
else
|
|
825
|
+
lines = prefs.map { |k, v| " #{k}: #{v}" }
|
|
826
|
+
@message_stream.add_message(role: :system, content: "Preferences:\n#{lines.join("\n")}")
|
|
827
|
+
end
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
def show_one_pref(key)
|
|
831
|
+
val = load_prefs[key]
|
|
832
|
+
if val.nil?
|
|
833
|
+
@message_stream.add_message(role: :system, content: "No preference set for '#{key}'.")
|
|
834
|
+
else
|
|
835
|
+
@message_stream.add_message(role: :system, content: "#{key}: #{val}")
|
|
836
|
+
end
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
def set_pref(key, value)
|
|
840
|
+
prefs = load_prefs
|
|
841
|
+
prefs[key] = value
|
|
842
|
+
save_prefs(prefs)
|
|
843
|
+
apply_pref(key, value)
|
|
844
|
+
@message_stream.add_message(role: :system, content: "Preference set: #{key} = #{value}")
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
def apply_pref(key, value)
|
|
848
|
+
case key
|
|
849
|
+
when 'theme' then handle_theme("/theme #{value}")
|
|
850
|
+
when 'personality' then handle_personality("/personality #{value}")
|
|
851
|
+
when 'color' then handle_color("/color #{value}")
|
|
852
|
+
when 'timestamps' then handle_timestamps("/timestamps #{value}")
|
|
853
|
+
end
|
|
854
|
+
end
|
|
710
855
|
end
|
|
711
856
|
end
|
|
712
857
|
end
|
|
@@ -45,7 +45,10 @@ module Legion
|
|
|
45
45
|
/color /timestamps
|
|
46
46
|
/top /bottom /head /tail
|
|
47
47
|
/draft /revise
|
|
48
|
-
/mark /freq
|
|
48
|
+
/mark /freq
|
|
49
|
+
/about /commands
|
|
50
|
+
/ask /define
|
|
51
|
+
/status /prefs].freeze
|
|
49
52
|
|
|
50
53
|
PERSONALITIES = {
|
|
51
54
|
'default' => 'You are Legion, an async cognition engine and AI assistant. Be helpful and concise.',
|
|
@@ -492,6 +495,12 @@ module Legion
|
|
|
492
495
|
when '/revise' then handle_revise(input)
|
|
493
496
|
when '/mark' then handle_mark(input)
|
|
494
497
|
when '/freq' then handle_freq
|
|
498
|
+
when '/about' then handle_about
|
|
499
|
+
when '/commands' then handle_commands(input)
|
|
500
|
+
when '/ask' then handle_ask(input)
|
|
501
|
+
when '/define' then handle_define(input)
|
|
502
|
+
when '/status' then handle_status
|
|
503
|
+
when '/prefs' then handle_prefs(input)
|
|
495
504
|
else :handled
|
|
496
505
|
end
|
|
497
506
|
end
|
data/lib/legion/tty/version.rb
CHANGED