lux-hammer 0.3.21 → 0.3.23
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/.version +1 -1
- data/lib/hammer/shell.rb +33 -12
- data/recipes/lib/llm/plan.rb +660 -0
- data/recipes/lib/llm/wrap.rb +558 -87
- data/recipes/llm.rb +445 -17
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74dd44bca6cf689dcfe0396d90e05e51b0605821314fb6d5b742502662f4e8e8
|
|
4
|
+
data.tar.gz: a84eaa4fcce83f951905bab3419d18adfcce409cd0f9d2f23db910569443a2ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 044a31c525aba212012888f39d938fa37dc2e69e59097fa10f1dda53723b0a267dae2dad0e77887c19ad801a64fcb47e03b8aa95d916b04474d5239628a9b8f0
|
|
7
|
+
data.tar.gz: 3ec9940429c06e4bfb00669184fe3d4f78fff0ed693f857fcd37c682bf89b70a214f3a7e92e24826a1ab5889c62de26f05e0f9b78fe22c1c65b12227d4a18681
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.23
|
data/lib/hammer/shell.rb
CHANGED
|
@@ -88,26 +88,43 @@ class Hammer
|
|
|
88
88
|
#
|
|
89
89
|
# idx = choose 'Pick env', %w[dev staging prod]
|
|
90
90
|
# say.green "chose #{ %w[dev staging prod][idx] }" if idx
|
|
91
|
-
|
|
91
|
+
#
|
|
92
|
+
# `skip` marks rows that are shown but never landed on, so a list can
|
|
93
|
+
# carry its own headings and rules. They are drawn in gray, the cursor
|
|
94
|
+
# steps over them, and the returned index still counts every row:
|
|
95
|
+
#
|
|
96
|
+
# choose 'Pick', ['-- fast --', 'dev', '-- slow --', 'prod'],
|
|
97
|
+
# skip: ->(item) { item.start_with?('--') }
|
|
98
|
+
def choose(prompt, items, skip: nil)
|
|
92
99
|
items = items.to_a
|
|
93
100
|
error 'choose needs at least one item' if items.empty?
|
|
94
101
|
|
|
102
|
+
live = items.each_index.reject { |i| skip&.call(items[i]) }
|
|
103
|
+
error 'choose needs at least one selectable item' if live.empty?
|
|
104
|
+
|
|
95
105
|
say.cyan prompt
|
|
96
106
|
|
|
97
|
-
return choose_numbered(items) unless $stdin.tty? && $stdin.respond_to?(:raw)
|
|
107
|
+
return choose_numbered(items, live) unless $stdin.tty? && $stdin.respond_to?(:raw)
|
|
98
108
|
|
|
99
|
-
selected =
|
|
109
|
+
selected = live.first
|
|
100
110
|
# In raw mode \n is not translated to \r\n, so the picker uses \r\n
|
|
101
111
|
# explicitly. The initial draw happens in cooked mode but \r\n is
|
|
102
112
|
# harmless there.
|
|
103
113
|
redraw = lambda do |highlight = :cyan|
|
|
104
114
|
items.each_with_index do |item, i|
|
|
105
|
-
line = i
|
|
115
|
+
line = if !live.include?(i) then paint(" #{item}", :gray)
|
|
116
|
+
elsif i == selected then paint("> #{item}", highlight)
|
|
117
|
+
else " #{item}"
|
|
118
|
+
end
|
|
106
119
|
$stdout.print "#{line}\r\n"
|
|
107
120
|
end
|
|
108
121
|
end
|
|
109
122
|
redraw.call
|
|
110
123
|
|
|
124
|
+
# Move by position among the selectable rows, so skipped ones are
|
|
125
|
+
# stepped over in both directions and the wrap-around still works.
|
|
126
|
+
step = ->(dir) { live[(live.index(selected) + dir) % live.size] }
|
|
127
|
+
|
|
111
128
|
$stdout.print "\e[?25l" # hide cursor
|
|
112
129
|
begin
|
|
113
130
|
$stdin.raw do |io|
|
|
@@ -126,15 +143,15 @@ class Hammer
|
|
|
126
143
|
# ESC may stand alone or start an arrow sequence \e[A / \e[B.
|
|
127
144
|
if IO.select([io], nil, nil, 0.01) && io.getch == '['
|
|
128
145
|
case io.getch
|
|
129
|
-
when 'A' then selected = (
|
|
130
|
-
when 'B' then selected = (
|
|
146
|
+
when 'A' then selected = step.call(-1)
|
|
147
|
+
when 'B' then selected = step.call(1)
|
|
131
148
|
end
|
|
132
149
|
else
|
|
133
150
|
$stdout.print "\e[#{items.size}A\r\e[J"
|
|
134
151
|
return nil
|
|
135
152
|
end
|
|
136
|
-
when 'k' then selected = (
|
|
137
|
-
when 'j' then selected = (
|
|
153
|
+
when 'k' then selected = step.call(-1)
|
|
154
|
+
when 'j' then selected = step.call(1)
|
|
138
155
|
end
|
|
139
156
|
$stdout.print "\e[#{items.size}A\r\e[J"
|
|
140
157
|
redraw.call
|
|
@@ -146,13 +163,17 @@ class Hammer
|
|
|
146
163
|
end
|
|
147
164
|
|
|
148
165
|
# Fallback for non-TTY stdin (pipes, tests). Returns the index or nil.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
166
|
+
# Skipped rows are still printed, just without a number to type.
|
|
167
|
+
def choose_numbered(items, live = items.each_index.to_a)
|
|
168
|
+
items.each_with_index do |item, i|
|
|
169
|
+
n = live.index(i)
|
|
170
|
+
puts n ? " #{n + 1}) #{item}" : " #{item}"
|
|
171
|
+
end
|
|
172
|
+
print paint("select [1-#{live.size}]: ", :cyan)
|
|
152
173
|
line = $stdin.gets
|
|
153
174
|
return nil if line.nil?
|
|
154
175
|
idx = line.strip.to_i - 1
|
|
155
|
-
idx.between?(0,
|
|
176
|
+
idx.between?(0, live.size - 1) ? live[idx] : nil
|
|
156
177
|
end
|
|
157
178
|
|
|
158
179
|
# Run a shell command. Echoes the command in gray, raises
|