hiiro 0.1.105 → 0.1.106
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 +80 -18
- 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: e8acd4525328ec989fc21c5cc4cc12b89cb6bb6f5f7a58cd26e8c4d9e314e47f
|
|
4
|
+
data.tar.gz: 767aab54f70478217a1884805be0536a69dc213696f989fe5d7f365e3016b3ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1105b1d12f8a88c6a31f056c024a02d1bdaf200e046dac69be7a3ac179d0413bbc8d90a0d9588f3655ebdb9f4ed912145fefe9197b09b34ff9d6dfa8c762b9dc
|
|
7
|
+
data.tar.gz: 4328502564e28fcbb11fef9da5b1e3e33caa7421820349c6290d0d2ec3ce2e2177f7341710233b49b84e398102045fc036df3c5992fd5514e2c10e30dc7d838d
|
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")
|
|
@@ -98,24 +114,44 @@ class Hiiro
|
|
|
98
114
|
system('tmux', 'new-session', '-d', '-s', target_session, '-c', working_dir)
|
|
99
115
|
end
|
|
100
116
|
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
# Write a clean prompt file (no frontmatter) for claude
|
|
118
|
+
prompt_body = prompt_obj ? prompt_obj.doc.content.strip : prompt_text
|
|
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
|
+
set -e
|
|
127
|
+
|
|
128
|
+
cd #{Shellwords.shellescape(working_dir)}
|
|
129
|
+
claude "run the prompt in the file @#{prompt_file}"
|
|
130
|
+
HQ_EXIT=$?
|
|
131
|
+
|
|
132
|
+
# Move task files to done/failed based on exit code
|
|
133
|
+
ruby -e '
|
|
134
|
+
require "fileutils"
|
|
135
|
+
name = #{name.inspect}
|
|
136
|
+
qdir = #{DIR.inspect}
|
|
137
|
+
exit_code = ENV["HQ_EXIT"].to_i
|
|
138
|
+
dst_dir = exit_code == 0 ? "done" : "failed"
|
|
139
|
+
%w[.md .meta .prompt .sh].each do |ext|
|
|
140
|
+
src = File.join(qdir, "running", name + ext)
|
|
141
|
+
if ext == ".prompt" || ext == ".sh"
|
|
142
|
+
FileUtils.rm_f(src)
|
|
143
|
+
elsif File.exist?(src)
|
|
144
|
+
FileUtils.mv(src, File.join(qdir, dst_dir, name + ext))
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
'
|
|
148
|
+
|
|
149
|
+
exec #{Shellwords.shellescape(ENV['SHELL'] || 'zsh')}
|
|
150
|
+
SH
|
|
151
|
+
FileUtils.chmod(0755, script_path)
|
|
116
152
|
|
|
117
153
|
win_name = short_window_name(name)
|
|
118
|
-
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir,
|
|
154
|
+
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir, script_path)
|
|
119
155
|
|
|
120
156
|
# Write meta sidecar
|
|
121
157
|
meta = {
|
|
@@ -228,7 +264,20 @@ class Hiiro
|
|
|
228
264
|
next
|
|
229
265
|
end
|
|
230
266
|
tasks.each do |t|
|
|
231
|
-
|
|
267
|
+
line = "%-10s %s" % [t[:status], t[:name]]
|
|
268
|
+
meta = q.meta_for(t[:name], t[:status].to_sym)
|
|
269
|
+
if meta && t[:status] == 'running'
|
|
270
|
+
started = meta['started_at']
|
|
271
|
+
if started
|
|
272
|
+
elapsed = Time.now - Time.parse(started)
|
|
273
|
+
mins = (elapsed / 60).to_i
|
|
274
|
+
line += " (#{mins}m)"
|
|
275
|
+
end
|
|
276
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
|
|
277
|
+
end
|
|
278
|
+
preview = q.task_preview(t[:name], t[:status].to_sym)
|
|
279
|
+
line += " #{preview}" if preview
|
|
280
|
+
puts line
|
|
232
281
|
end
|
|
233
282
|
}
|
|
234
283
|
|
|
@@ -239,7 +288,20 @@ class Hiiro
|
|
|
239
288
|
next
|
|
240
289
|
end
|
|
241
290
|
tasks.each do |t|
|
|
242
|
-
|
|
291
|
+
line = "%-10s %s" % [t[:status], t[:name]]
|
|
292
|
+
meta = q.meta_for(t[:name], t[:status].to_sym)
|
|
293
|
+
if meta && t[:status] == 'running'
|
|
294
|
+
started = meta['started_at']
|
|
295
|
+
if started
|
|
296
|
+
elapsed = Time.now - Time.parse(started)
|
|
297
|
+
mins = (elapsed / 60).to_i
|
|
298
|
+
line += " (#{mins}m)"
|
|
299
|
+
end
|
|
300
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
|
|
301
|
+
end
|
|
302
|
+
preview = q.task_preview(t[:name], t[:status].to_sym)
|
|
303
|
+
line += " #{preview}" if preview
|
|
304
|
+
puts line
|
|
243
305
|
end
|
|
244
306
|
}
|
|
245
307
|
|
data/lib/hiiro/version.rb
CHANGED