hiiro 0.1.277 → 0.1.278
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 +1 -6
- data/lib/hiiro/git.rb +17 -0
- data/lib/hiiro/queue.rb +71 -26
- data/lib/hiiro/service_manager.rb +7 -0
- 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: 1beafe3505bb704e88e7352d6f92c42023c0b6682574eafd5775f365bd7dc444
|
|
4
|
+
data.tar.gz: d3074244aabc4c9c64c880688ae45628137fa58d0babd960f3a8fd5bdb7aeaf6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7a5bbd8919dc92f5209112abdf6a2997890408bbdf3c71dda6e6adf662350a3b6c2502f4fe2d4dbaf24f02ec50ac4a591ec2c574d1e55856d743946c17d8150
|
|
7
|
+
data.tar.gz: 7cfa0e4c81959f8db363dfefa29e27faed97941dd72b8c83ef6b2f0a21bac65ca7caf5c06ec19ecaba6d978912a6c7c0e565ef92db1e5eabc24fa4cbd6bcfeb1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
Done.
|
|
2
|
-
|
|
3
|
-
- Moved `Hiiro#add_resolver` and `Hiiro#resolve` from the Unreleased section to the new v0.1.277 release section (2026-03-24)
|
|
4
|
-
- Added them to the Added subsection of v0.1.277
|
|
5
|
-
- Added a Changed entry documenting the `h pr` refactoring that uses these new methods
|
|
6
|
-
- Updated the Unreleased section to remove these items and add a note in Changed about the `h pr` refactoring
|
|
1
|
+
Done. The CHANGELOG.md has been updated with v0.1.278 released on 2026-03-24. The pane-based queue launch modes (cadd, hadd, vadd) and related changes have been moved from Unreleased to the new v0.1.278 section, and the `add_resolvers` class methods have been added to the Added section based on commit 1bba9fd.
|
data/lib/hiiro/git.rb
CHANGED
|
@@ -7,6 +7,23 @@ require_relative 'git/pr'
|
|
|
7
7
|
|
|
8
8
|
class Hiiro
|
|
9
9
|
class Git
|
|
10
|
+
def self.add_resolvers(hiiro)
|
|
11
|
+
hiiro.add_resolver(:branch, -> { hiiro.fuzzyfind(Branches.local.names) }) do |name|
|
|
12
|
+
Branches.local.find_by_name(name)&.name || name
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
hiiro.add_resolver(:worktree,
|
|
16
|
+
-> {
|
|
17
|
+
wts = Worktrees.fetch.without_bare
|
|
18
|
+
map = wts.each_with_object({}) { |wt, h| h["#{wt.name} #{wt.path}"] = wt.path }
|
|
19
|
+
hiiro.fuzzyfind_from_map(map)
|
|
20
|
+
}
|
|
21
|
+
) do |ref|
|
|
22
|
+
wts = Worktrees.fetch
|
|
23
|
+
(wts.find_by_path(ref) || wts.find_by_name(ref) || wts.find_by_branch(ref))&.path || ref
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
10
27
|
attr_reader :hiiro, :pwd
|
|
11
28
|
|
|
12
29
|
def initialize(hiiro, pwd=Dir.pwd)
|
data/lib/hiiro/queue.rb
CHANGED
|
@@ -70,7 +70,11 @@ class Hiiro
|
|
|
70
70
|
mins = (elapsed / 60).to_i
|
|
71
71
|
line += " (#{mins}m)"
|
|
72
72
|
end
|
|
73
|
-
|
|
73
|
+
if meta['tmux_pane']
|
|
74
|
+
line += " [pane #{meta['tmux_pane']}]"
|
|
75
|
+
elsif meta['tmux_session']
|
|
76
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]"
|
|
77
|
+
end
|
|
74
78
|
end
|
|
75
79
|
preview = task_preview(t[:name], status.to_sym)
|
|
76
80
|
line += " #{preview}" if preview
|
|
@@ -126,6 +130,16 @@ class Hiiro
|
|
|
126
130
|
end
|
|
127
131
|
|
|
128
132
|
def launch_task(name)
|
|
133
|
+
launch_in_mode(name, mode: :window)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def launch_in_pane(name, split:)
|
|
137
|
+
launch_in_mode(name, mode: split)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
def launch_in_mode(name, mode:)
|
|
129
143
|
dirs = queue_dirs
|
|
130
144
|
md_file = File.join(dirs[:pending], "#{name}.md")
|
|
131
145
|
return unless File.exist?(md_file)
|
|
@@ -174,11 +188,6 @@ class Hiiro
|
|
|
174
188
|
end
|
|
175
189
|
end
|
|
176
190
|
|
|
177
|
-
# Ensure the target session exists
|
|
178
|
-
unless system('tmux', 'has-session', '-t', target_session, out: File::NULL, err: File::NULL)
|
|
179
|
-
system('tmux', 'new-session', '-d', '-s', target_session, '-c', working_dir)
|
|
180
|
-
end
|
|
181
|
-
|
|
182
191
|
# Write a clean prompt file (no frontmatter) for claude
|
|
183
192
|
raw = File.read(running_md).strip
|
|
184
193
|
prompt_body = prompt_obj ? strip_frontmatter(prompt_obj.doc.content.strip) : strip_frontmatter(raw)
|
|
@@ -218,26 +227,45 @@ class Hiiro
|
|
|
218
227
|
SH
|
|
219
228
|
FileUtils.chmod(0755, script_path)
|
|
220
229
|
|
|
221
|
-
|
|
222
|
-
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir, script_path)
|
|
223
|
-
|
|
224
|
-
# Write meta sidecar
|
|
230
|
+
# Build base meta (no tmux_window/pane yet)
|
|
225
231
|
meta = {
|
|
226
|
-
'tmux_session' => target_session,
|
|
227
|
-
'tmux_window' => win_name,
|
|
228
232
|
'started_at' => Time.now.iso8601,
|
|
229
233
|
'working_dir' => working_dir,
|
|
230
234
|
}
|
|
231
235
|
if prompt_obj
|
|
232
|
-
meta['task_name']
|
|
233
|
-
meta['tree_name']
|
|
236
|
+
meta['task_name'] = prompt_obj.task_name if prompt_obj.task_name
|
|
237
|
+
meta['tree_name'] = prompt_obj.tree_name if prompt_obj.tree_name
|
|
234
238
|
meta['session_name'] = prompt_obj.session_name if prompt_obj.session_name
|
|
235
239
|
end
|
|
236
|
-
File.write(File.join(dirs[:running], "#{name}.meta"), meta.to_yaml)
|
|
237
240
|
|
|
238
|
-
|
|
241
|
+
case mode
|
|
242
|
+
when :window
|
|
243
|
+
# Ensure the target session exists
|
|
244
|
+
unless system('tmux', 'has-session', '-t', target_session, out: File::NULL, err: File::NULL)
|
|
245
|
+
system('tmux', 'new-session', '-d', '-s', target_session, '-c', working_dir)
|
|
246
|
+
end
|
|
247
|
+
win_name = short_window_name(name)
|
|
248
|
+
system('tmux', 'new-window', '-d', '-t', target_session, '-n', win_name, '-c', working_dir, script_path)
|
|
249
|
+
meta['tmux_session'] = target_session
|
|
250
|
+
meta['tmux_window'] = win_name
|
|
251
|
+
File.write(File.join(dirs[:running], "#{name}.meta"), meta.to_yaml)
|
|
252
|
+
puts "Launched: #{name} [#{target_session}:#{win_name}]"
|
|
253
|
+
|
|
254
|
+
when :current
|
|
255
|
+
File.write(File.join(dirs[:running], "#{name}.meta"), meta.to_yaml)
|
|
256
|
+
exec(script_path)
|
|
257
|
+
|
|
258
|
+
when :hsplit, :vsplit
|
|
259
|
+
flag = mode == :hsplit ? '-v' : '-h'
|
|
260
|
+
pane_id = `tmux split-window #{flag} -P -F '\#{pane_id}' -c #{Shellwords.shellescape(working_dir)} #{Shellwords.shellescape(script_path)} 2>/dev/null`.strip
|
|
261
|
+
meta['tmux_pane'] = pane_id unless pane_id.empty?
|
|
262
|
+
File.write(File.join(dirs[:running], "#{name}.meta"), meta.to_yaml)
|
|
263
|
+
puts "Launched: #{name} [pane #{pane_id}]"
|
|
264
|
+
end
|
|
239
265
|
end
|
|
240
266
|
|
|
267
|
+
public
|
|
268
|
+
|
|
241
269
|
def task_info_for(task_name)
|
|
242
270
|
env = Environment.current rescue nil
|
|
243
271
|
return nil unless env
|
|
@@ -445,7 +473,11 @@ class Hiiro
|
|
|
445
473
|
mins = (elapsed / 60).to_i
|
|
446
474
|
line += " (#{mins}m elapsed)"
|
|
447
475
|
end
|
|
448
|
-
|
|
476
|
+
if meta['tmux_pane']
|
|
477
|
+
line += " [pane #{meta['tmux_pane']}]"
|
|
478
|
+
elsif meta['tmux_session']
|
|
479
|
+
line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]"
|
|
480
|
+
end
|
|
449
481
|
line += " dir:#{meta['working_dir']}" if meta['working_dir']
|
|
450
482
|
end
|
|
451
483
|
puts line
|
|
@@ -488,7 +520,7 @@ class Hiiro
|
|
|
488
520
|
Tmux.open_session(TMUX_SESSION, start_directory: work_dir)
|
|
489
521
|
}
|
|
490
522
|
|
|
491
|
-
|
|
523
|
+
do_add = lambda do |args, split: nil|
|
|
492
524
|
q.queue_dirs
|
|
493
525
|
opts = Hiiro::Options.parse(args) do
|
|
494
526
|
option(:task, short: :t, desc: 'Task name')
|
|
@@ -516,7 +548,6 @@ class Hiiro
|
|
|
516
548
|
elsif args.any?
|
|
517
549
|
content = args.join(' ')
|
|
518
550
|
else
|
|
519
|
-
# Pre-fill with frontmatter template
|
|
520
551
|
fm_lines = ["---"]
|
|
521
552
|
fm_lines << "task_name: #{ti[:task_name]}" if ti&.dig(:task_name)
|
|
522
553
|
fm_lines << "tree_name: #{ti[:tree_name]}" if ti&.dig(:tree_name)
|
|
@@ -539,12 +570,22 @@ class Hiiro
|
|
|
539
570
|
end
|
|
540
571
|
|
|
541
572
|
result = q.add_with_frontmatter(content, task_info: ti, ignore: opts.ignore, name: opts.name)
|
|
542
|
-
|
|
543
|
-
puts "Created: #{result[:path]}"
|
|
544
|
-
else
|
|
573
|
+
unless result
|
|
545
574
|
puts "Could not generate a task name"
|
|
575
|
+
next
|
|
546
576
|
end
|
|
547
|
-
|
|
577
|
+
|
|
578
|
+
if split
|
|
579
|
+
q.launch_in_pane(result[:name], split: split)
|
|
580
|
+
else
|
|
581
|
+
puts "Created: #{result[:path]}"
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
h.add_subcmd(:add) { |*args| do_add.call(args) }
|
|
586
|
+
h.add_subcmd(:cadd) { |*args| do_add.call(args, split: :current) }
|
|
587
|
+
h.add_subcmd(:hadd) { |*args| do_add.call(args, split: :hsplit) }
|
|
588
|
+
h.add_subcmd(:vadd) { |*args| do_add.call(args, split: :vsplit) }
|
|
548
589
|
|
|
549
590
|
h.add_subcmd(:wip) { |*args|
|
|
550
591
|
q.queue_dirs
|
|
@@ -635,9 +676,13 @@ class Hiiro
|
|
|
635
676
|
next unless name
|
|
636
677
|
|
|
637
678
|
meta = q.meta_for(name, :running)
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
679
|
+
if meta&.key?('tmux_pane')
|
|
680
|
+
system('tmux', 'kill-pane', '-t', meta['tmux_pane'])
|
|
681
|
+
else
|
|
682
|
+
session = meta&.[]('tmux_session') || TMUX_SESSION
|
|
683
|
+
win = meta&.[]('tmux_window') || name
|
|
684
|
+
system('tmux', 'kill-window', '-t', "#{session}:#{win}")
|
|
685
|
+
end
|
|
641
686
|
|
|
642
687
|
dirs = q.queue_dirs
|
|
643
688
|
md = File.join(dirs[:running], "#{name}.md")
|
|
@@ -12,6 +12,13 @@ class Hiiro
|
|
|
12
12
|
|
|
13
13
|
attr_reader :config_file, :state_file
|
|
14
14
|
|
|
15
|
+
def self.add_resolvers(hiiro)
|
|
16
|
+
sm = new
|
|
17
|
+
hiiro.add_resolver(:service, -> { hiiro.fuzzyfind(sm.services.keys) }) do |name|
|
|
18
|
+
sm.find_service(name)&.[](:name)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
15
22
|
def initialize(config_file: CONFIG_FILE, state_file: STATE_FILE)
|
|
16
23
|
@config_file = config_file
|
|
17
24
|
@state_file = state_file
|
data/lib/hiiro/version.rb
CHANGED