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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c0ebae864202a90016b7b7df7f65a32836cc11c144ea85638a9c75b22279b72
4
- data.tar.gz: 9a5e414ec3dc428f932acdaf47f989c80d2ca50a1fd19fe4d2d7fa9e4c634a76
3
+ metadata.gz: 1beafe3505bb704e88e7352d6f92c42023c0b6682574eafd5775f365bd7dc444
4
+ data.tar.gz: d3074244aabc4c9c64c880688ae45628137fa58d0babd960f3a8fd5bdb7aeaf6
5
5
  SHA512:
6
- metadata.gz: 4cbdc7c7029c4acfbf6720c47d63d330bb71c270ba1546d76e743a6c05fef40f98229458a39d981627fb49767fac3c63e745b681e12ddde30e180b251ac94087
7
- data.tar.gz: 3a95e13a5ebc85325d8426d398812499924bc8605f7e5e0e785cbb16b3ffafa6161ec7d04d1ff72387286779f8142bcff3f338348c35791192b1d97c72e5f780
6
+ metadata.gz: f7a5bbd8919dc92f5209112abdf6a2997890408bbdf3c71dda6e6adf662350a3b6c2502f4fe2d4dbaf24f02ec50ac4a591ec2c574d1e55856d743946c17d8150
7
+ data.tar.gz: 7cfa0e4c81959f8db363dfefa29e27faed97941dd72b8c83ef6b2f0a21bac65ca7caf5c06ec19ecaba6d978912a6c7c0e565ef92db1e5eabc24fa4cbd6bcfeb1
data/CHANGELOG.md CHANGED
@@ -1,6 +1 @@
1
- Done. Updated CHANGELOG.md:
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
- line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
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
- win_name = short_window_name(name)
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'] = prompt_obj.task_name if prompt_obj.task_name
233
- meta['tree_name'] = prompt_obj.tree_name if prompt_obj.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
- puts "Launched: #{name} [#{target_session}:#{win_name}]"
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
- line += " [#{meta['tmux_session']}:#{meta['tmux_window']}]" if meta['tmux_session']
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
- h.add_subcmd(:add) { |*args|
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
- if result
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
- session = meta&.[]('tmux_session') || TMUX_SESSION
639
- win = meta&.[]('tmux_window') || name
640
- system('tmux', 'kill-window', '-t', "#{session}:#{win}")
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
@@ -1,3 +1,3 @@
1
1
  class Hiiro
2
- VERSION = "0.1.277"
2
+ VERSION = "0.1.278"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiiro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.277
4
+ version: 0.1.278
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Toyota