hiiro 0.1.105 → 0.1.107
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/lib/hiiro/queue.rb +88 -19
- data/lib/hiiro/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: '00583cf6d27d5bf15012a0fcb366f5f89b57b68e02963de6ea1462d696f95712'
|
|
4
|
+
data.tar.gz: 6283dabff0534fc659f4a7fb23019881c5ce55b25697da23b445b02caa562cbc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3f9ee12a59e91c458186e14a040e19700e282251ec33fe585a8aea21198bb7c38da0a2fcd2a2c561d74ed0a684644c1b6436e8fb159f9f9008a140dac6f5521a
|
|
7
|
+
data.tar.gz: f17af6e37572b53a322b660db8d59e400456d60461212da54d72863327ee02ff20ef107ec169c44955ac814e61ce51078d7257940e6c232972ae595da80aab8f
|
data/lib/hiiro/queue.rb
CHANGED
|
@@ -50,6 +50,22 @@ class Hiiro
|
|
|
50
50
|
File.exist?(path) ? YAML.safe_load_file(path) : nil
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
def task_preview(name, status)
|
|
54
|
+
path = File.join(queue_dirs[status], "#{name}.md")
|
|
55
|
+
return nil unless File.exist?(path)
|
|
56
|
+
|
|
57
|
+
lines = File.readlines(path, chomp: true)
|
|
58
|
+
# Skip frontmatter
|
|
59
|
+
if lines.first == '---'
|
|
60
|
+
end_idx = lines[1..].index('---')
|
|
61
|
+
lines = lines[(end_idx + 2)..] if end_idx
|
|
62
|
+
end
|
|
63
|
+
first = lines&.find { |l| !l.strip.empty? }&.strip
|
|
64
|
+
return nil unless first
|
|
65
|
+
|
|
66
|
+
first.length > 60 ? "| #{first[0, 57]}..." : "| #{first}"
|
|
67
|
+
end
|
|
68
|
+
|
|
53
69
|
def find_task(name)
|
|
54
70
|
STATUSES.each do |status|
|
|
55
71
|
md = File.join(queue_dirs[status.to_sym], "#{name}.md")
|
|
@@ -73,7 +89,6 @@ class Hiiro
|
|
|
73
89
|
FileUtils.mv(md_file, running_md)
|
|
74
90
|
|
|
75
91
|
prompt_obj = Prompt.from_file(running_md, hiiro: hiiro)
|
|
76
|
-
prompt_text = File.read(running_md).strip
|
|
77
92
|
|
|
78
93
|
# Determine target tmux session and working directory from frontmatter
|
|
79
94
|
target_session = TMUX_SESSION
|
|
@@ -98,24 +113,44 @@ class Hiiro
|
|
|
98
113
|
system('tmux', 'new-session', '-d', '-s', target_session, '-c', working_dir)
|
|
99
114
|
end
|
|
100
115
|
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
# Write a clean prompt file (no frontmatter) for claude
|
|
117
|
+
raw = File.read(running_md).strip
|
|
118
|
+
prompt_body = prompt_obj ? prompt_obj.doc.content.strip : strip_frontmatter(raw)
|
|
119
|
+
prompt_file = File.join(dirs[:running], "#{name}.prompt")
|
|
120
|
+
File.write(prompt_file, prompt_body + "\n")
|
|
121
|
+
|
|
122
|
+
# Write a launcher script
|
|
123
|
+
script_path = File.join(dirs[:running], "#{name}.sh")
|
|
124
|
+
File.write(script_path, <<~SH)
|
|
125
|
+
#!/usr/bin/env bash
|
|
126
|
+
|
|
127
|
+
cd #{Shellwords.shellescape(working_dir)}
|
|
128
|
+
cat #{Shellwords.shellescape(prompt_file)} | claude -p
|
|
129
|
+
HQ_EXIT=$?
|
|
130
|
+
|
|
131
|
+
# Move task files to done/failed based on exit code
|
|
132
|
+
ruby -e '
|
|
133
|
+
require "fileutils"
|
|
134
|
+
name = #{name.inspect}
|
|
135
|
+
qdir = #{DIR.inspect}
|
|
136
|
+
exit_code = ENV["HQ_EXIT"].to_i
|
|
137
|
+
dst_dir = exit_code == 0 ? "done" : "failed"
|
|
138
|
+
%w[.md .meta .prompt .sh].each do |ext|
|
|
139
|
+
src = File.join(qdir, "running", name + ext)
|
|
140
|
+
if ext == ".prompt" || ext == ".sh"
|
|
141
|
+
FileUtils.rm_f(src)
|
|
142
|
+
elsif File.exist?(src)
|
|
143
|
+
FileUtils.mv(src, File.join(qdir, dst_dir, name + ext))
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
'
|
|
147
|
+
|
|
148
|
+
exec #{Shellwords.shellescape(ENV['SHELL'] || 'zsh')}
|
|
149
|
+
SH
|
|
150
|
+
FileUtils.chmod(0755, script_path)
|
|
116
151
|
|
|
117
152
|
win_name = short_window_name(name)
|
|
118
|
-
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir,
|
|
153
|
+
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir, script_path)
|
|
119
154
|
|
|
120
155
|
# Write meta sidecar
|
|
121
156
|
meta = {
|
|
@@ -134,6 +169,14 @@ class Hiiro
|
|
|
134
169
|
puts "Launched: #{name} [#{target_session}:#{win_name}]"
|
|
135
170
|
end
|
|
136
171
|
|
|
172
|
+
def strip_frontmatter(text)
|
|
173
|
+
lines = text.lines
|
|
174
|
+
return text unless lines.first&.strip == '---'
|
|
175
|
+
end_idx = lines[1..].index { |l| l.strip == '---' }
|
|
176
|
+
return text unless end_idx
|
|
177
|
+
lines[(end_idx + 2)..].join.strip
|
|
178
|
+
end
|
|
179
|
+
|
|
137
180
|
def short_window_name(name)
|
|
138
181
|
base = name[0, 8]
|
|
139
182
|
return base unless existing_window_name?(base)
|
|
@@ -228,7 +271,20 @@ class Hiiro
|
|
|
228
271
|
next
|
|
229
272
|
end
|
|
230
273
|
tasks.each do |t|
|
|
231
|
-
|
|
274
|
+
line = "%-10s %s" % [t[:status], t[:name]]
|
|
275
|
+
meta = q.meta_for(t[:name], t[:status].to_sym)
|
|
276
|
+
if meta && t[:status] == 'running'
|
|
277
|
+
started = meta['started_at']
|
|
278
|
+
if started
|
|
279
|
+
elapsed = Time.now - Time.parse(started)
|
|
280
|
+
mins = (elapsed / 60).to_i
|
|
281
|
+
line += " (#{mins}m)"
|
|
282
|
+
end
|
|
283
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
|
|
284
|
+
end
|
|
285
|
+
preview = q.task_preview(t[:name], t[:status].to_sym)
|
|
286
|
+
line += " #{preview}" if preview
|
|
287
|
+
puts line
|
|
232
288
|
end
|
|
233
289
|
}
|
|
234
290
|
|
|
@@ -239,7 +295,20 @@ class Hiiro
|
|
|
239
295
|
next
|
|
240
296
|
end
|
|
241
297
|
tasks.each do |t|
|
|
242
|
-
|
|
298
|
+
line = "%-10s %s" % [t[:status], t[:name]]
|
|
299
|
+
meta = q.meta_for(t[:name], t[:status].to_sym)
|
|
300
|
+
if meta && t[:status] == 'running'
|
|
301
|
+
started = meta['started_at']
|
|
302
|
+
if started
|
|
303
|
+
elapsed = Time.now - Time.parse(started)
|
|
304
|
+
mins = (elapsed / 60).to_i
|
|
305
|
+
line += " (#{mins}m)"
|
|
306
|
+
end
|
|
307
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
|
|
308
|
+
end
|
|
309
|
+
preview = q.task_preview(t[:name], t[:status].to_sym)
|
|
310
|
+
line += " #{preview}" if preview
|
|
311
|
+
puts line
|
|
243
312
|
end
|
|
244
313
|
}
|
|
245
314
|
|
data/lib/hiiro/version.rb
CHANGED