hiiro 0.1.271 → 0.1.273
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 -1
- data/bin/h-bg +79 -0
- data/bin/h-sparse +30 -0
- data/exe/h +1 -1
- data/lib/hiiro/background.rb +29 -0
- data/lib/hiiro/notification.rb +2 -2
- data/lib/hiiro/task_colors.rb +2 -2
- data/lib/hiiro/version.rb +1 -1
- data/lib/hiiro.rb +19 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b55682a1256d90688f6471b9fd2ae9cd6d0c6ee716692d04d9c52123cc9f2ad
|
|
4
|
+
data.tar.gz: ac10d9d826855e8eeb43ae48e33eff5b7f1af43fad6e12184334f8dff845d8eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2846d4b518bdeca084f38090a422e965f027c9df5bc90e8f39984781733227bcf7647ee9cfbba0213892ab406d90bf20f8f1155ee2d06195ddd325cb8278c611
|
|
7
|
+
data.tar.gz: 5a35953c04c0f089d30b061835cc445b130801aaef4f4dcd28227376811dcb0bce7e4ead0bc8844da16f064d6bed4800873350a409c7ac50c73f7dc4daea2a4a
|
data/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Done. CHANGELOG.md
|
|
1
|
+
Done. CHANGELOG.md updated for v0.1.273 with today's date (2026-03-23). Changes grouped into Added and Changed sections based on the recent commits.
|
data/bin/h-bg
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'hiiro'
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
|
|
5
|
+
HISTORY_FILE = File.expand_path('~/.config/hiiro/bg-history.txt')
|
|
6
|
+
HISTORY_MAX = 50
|
|
7
|
+
|
|
8
|
+
def load_history
|
|
9
|
+
return [] unless File.exist?(HISTORY_FILE)
|
|
10
|
+
File.readlines(HISTORY_FILE, chomp: true).last(HISTORY_MAX)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def append_history(cmd)
|
|
14
|
+
FileUtils.mkdir_p(File.dirname(HISTORY_FILE))
|
|
15
|
+
File.open(HISTORY_FILE, 'a') { |f| f.puts(cmd) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run_in_bg(cmd)
|
|
19
|
+
Hiiro::Background.ensure_session
|
|
20
|
+
name = cmd.split.first.to_s
|
|
21
|
+
system('tmux', 'new-window', '-d', '-t', "#{Hiiro::Background::SESSION}:", '-n', name, cmd)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Hiiro.run(*ARGV) do
|
|
25
|
+
add_subcmd(:popup) do
|
|
26
|
+
history = load_history
|
|
27
|
+
|
|
28
|
+
tf = Tempfile.new(['h-bg-', '.sh'])
|
|
29
|
+
unless history.empty?
|
|
30
|
+
tf.puts("# --- history (uncomment or rewrite below) ---")
|
|
31
|
+
history.reverse.each { |h| tf.puts("# #{h}") }
|
|
32
|
+
tf.puts("# ---")
|
|
33
|
+
tf.puts
|
|
34
|
+
end
|
|
35
|
+
tf.flush
|
|
36
|
+
tf.close
|
|
37
|
+
|
|
38
|
+
system(ENV['EDITOR'] || 'nvim', tf.path)
|
|
39
|
+
|
|
40
|
+
cmd = File.readlines(tf.path, chomp: true)
|
|
41
|
+
.reject { |l| l.strip.start_with?('#') || l.strip.empty? }
|
|
42
|
+
.join("\n")
|
|
43
|
+
.strip
|
|
44
|
+
tf.unlink
|
|
45
|
+
|
|
46
|
+
unless cmd.empty?
|
|
47
|
+
append_history(cmd)
|
|
48
|
+
run_in_bg(cmd)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
add_subcmd(:run) do |*cmd_args|
|
|
53
|
+
cmd = cmd_args.shelljoin
|
|
54
|
+
next puts("Usage: h bg run <command>") if cmd.empty?
|
|
55
|
+
append_history(cmd)
|
|
56
|
+
run_in_bg(cmd)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
add_subcmd(:attach, :a) do
|
|
60
|
+
system('tmux', 'switch-client', '-t', Hiiro::Background::SESSION)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
add_subcmd(:history, :hist) do
|
|
64
|
+
history = load_history
|
|
65
|
+
if history.empty?
|
|
66
|
+
puts "No background command history yet."
|
|
67
|
+
else
|
|
68
|
+
history.each_with_index { |cmd, i| puts "#{i + 1} #{cmd}" }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
add_subcmd(:setup) do
|
|
73
|
+
puts 'Add this to your tmux.conf:'
|
|
74
|
+
puts
|
|
75
|
+
puts " bind-key b display-popup -E -w 80% -h 40% \"h bg popup\""
|
|
76
|
+
puts
|
|
77
|
+
puts "Then reload tmux: tmux source-file ~/.tmux.conf"
|
|
78
|
+
end
|
|
79
|
+
end
|
data/bin/h-sparse
CHANGED
|
@@ -54,6 +54,36 @@ Hiiro.run(*ARGV) {
|
|
|
54
54
|
|
|
55
55
|
add_subcmd(:list) { |*args| run_subcmd(:ls, *args) }
|
|
56
56
|
|
|
57
|
+
add_subcmd(:set) { |group_name=nil|
|
|
58
|
+
if group_name.nil?
|
|
59
|
+
puts "Usage: h sparse set <group>"
|
|
60
|
+
next
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
groups = load_groups
|
|
64
|
+
|
|
65
|
+
match = groups.keys.find { |k| k == group_name } ||
|
|
66
|
+
groups.keys.find { |k| k.start_with?(group_name) } ||
|
|
67
|
+
groups.keys.find { |k| k.include?(group_name) }
|
|
68
|
+
|
|
69
|
+
unless match
|
|
70
|
+
puts "Group '#{group_name}' not found."
|
|
71
|
+
puts
|
|
72
|
+
puts "Available groups: #{groups.keys.join(', ')}"
|
|
73
|
+
next
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
paths = Array(groups[match]).map { |p| p.sub(/^\//, '') }
|
|
77
|
+
git_root = `git rev-parse --show-toplevel`.strip
|
|
78
|
+
|
|
79
|
+
if git_root.empty?
|
|
80
|
+
puts "Not inside a git repository."
|
|
81
|
+
next
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
system("git", "-C", git_root, "sparse-checkout", "set", "--cone", "--skip-checks", *paths)
|
|
85
|
+
}
|
|
86
|
+
|
|
57
87
|
add_subcmd(:add) { |group_name=nil, *paths|
|
|
58
88
|
if group_name.nil? || paths.empty?
|
|
59
89
|
puts "Usage: h sparse add <group> <path> [path...]"
|
data/exe/h
CHANGED
|
@@ -76,7 +76,7 @@ Hiiro.run(*ARGV, cwd: Dir.pwd, tasks: true) do
|
|
|
76
76
|
'github' => %w[pr],
|
|
77
77
|
'claude' => %w[claude],
|
|
78
78
|
'hiiro' => %w[bin plugin],
|
|
79
|
-
'other' => %w[app config link misc project todo],
|
|
79
|
+
'other' => %w[app bg config link misc project todo],
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
bin_files = Dir["#{source_bins}/h-*"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Hiiro
|
|
2
|
+
module Background
|
|
3
|
+
SESSION = 'h-bg'
|
|
4
|
+
|
|
5
|
+
# Run cmd asynchronously. Inside tmux, spins up a hidden window in the
|
|
6
|
+
# h-bg session so you can attach and inspect if needed. Outside tmux,
|
|
7
|
+
# falls back to a detached spawn.
|
|
8
|
+
def self.run(*cmd)
|
|
9
|
+
if inside_tmux?
|
|
10
|
+
ensure_session
|
|
11
|
+
system('tmux', 'new-window', '-d', '-t', "#{SESSION}:", '-n', cmd.first.to_s, cmd.shelljoin)
|
|
12
|
+
else
|
|
13
|
+
Process.detach(spawn(*cmd))
|
|
14
|
+
end
|
|
15
|
+
rescue
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.inside_tmux?
|
|
20
|
+
ENV['TMUX'] && !ENV['TMUX'].empty?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.ensure_session
|
|
24
|
+
unless system('tmux', 'has-session', '-t', SESSION, out: File::NULL, err: File::NULL)
|
|
25
|
+
system('tmux', 'new-session', '-d', '-s', SESSION, out: File::NULL, err: File::NULL)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/hiiro/notification.rb
CHANGED
|
@@ -42,14 +42,14 @@ class Hiiro
|
|
|
42
42
|
cmd += ['-title', options.title.tr('()[]', '')] if options.title
|
|
43
43
|
cmd += ['-open', options.link] if options.link
|
|
44
44
|
cmd += ['-execute', options.command] if options.command
|
|
45
|
-
|
|
45
|
+
Background.run(*cmd)
|
|
46
46
|
|
|
47
47
|
play_sound
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def play_sound
|
|
51
51
|
if options.sound && sounds[options.sound]
|
|
52
|
-
|
|
52
|
+
Background.run('afplay', sounds[options.sound.downcase])
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
data/lib/hiiro/task_colors.rb
CHANGED
|
@@ -24,8 +24,8 @@ class Hiiro
|
|
|
24
24
|
# Apply status-bg / status-fg to the named tmux session.
|
|
25
25
|
def self.apply(session_name, color_index)
|
|
26
26
|
colors = for_index(color_index)
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
Background.run('tmux', 'set-option', '-t', session_name, 'status-bg', colors[:bg])
|
|
28
|
+
Background.run('tmux', 'set-option', '-t', session_name, 'status-fg', colors[:fg])
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Return the first palette index not already used by existing_indices,
|
data/lib/hiiro/version.rb
CHANGED
data/lib/hiiro.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "ostruct"
|
|
|
6
6
|
|
|
7
7
|
require_relative "hiiro/version"
|
|
8
8
|
require_relative "hiiro/config"
|
|
9
|
+
require_relative "hiiro/background"
|
|
9
10
|
require_relative "hiiro/bins"
|
|
10
11
|
require_relative "hiiro/fuzzyfind"
|
|
11
12
|
require_relative "hiiro/git"
|
|
@@ -214,6 +215,8 @@ class Hiiro
|
|
|
214
215
|
end
|
|
215
216
|
|
|
216
217
|
def run
|
|
218
|
+
auto_tag_branch_with_task if tasks_enabled?
|
|
219
|
+
|
|
217
220
|
run_args = runners.using_default? ? [subcmd, *args].compact : args
|
|
218
221
|
result = runner.run(*run_args)
|
|
219
222
|
|
|
@@ -232,6 +235,22 @@ class Hiiro
|
|
|
232
235
|
exit 1
|
|
233
236
|
end
|
|
234
237
|
|
|
238
|
+
def auto_tag_branch_with_task
|
|
239
|
+
task = environment.task
|
|
240
|
+
return unless task
|
|
241
|
+
|
|
242
|
+
branch = environment.tree&.branch
|
|
243
|
+
return if branch.nil? || branch.empty?
|
|
244
|
+
return if %w[master main].include?(branch)
|
|
245
|
+
|
|
246
|
+
tag_store = Tags.new(:branch)
|
|
247
|
+
return if tag_store.get(branch).include?(task.name)
|
|
248
|
+
|
|
249
|
+
tag_store.add(branch, task.name)
|
|
250
|
+
rescue
|
|
251
|
+
# never let auto-tagging break a command
|
|
252
|
+
end
|
|
253
|
+
|
|
235
254
|
def runnable?
|
|
236
255
|
runner
|
|
237
256
|
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.
|
|
4
|
+
version: 0.1.273
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Toyota
|
|
@@ -98,6 +98,7 @@ files:
|
|
|
98
98
|
- TODO.md
|
|
99
99
|
- bin/h
|
|
100
100
|
- bin/h-app
|
|
101
|
+
- bin/h-bg
|
|
101
102
|
- bin/h-bin
|
|
102
103
|
- bin/h-branch
|
|
103
104
|
- bin/h-buffer
|
|
@@ -252,6 +253,7 @@ files:
|
|
|
252
253
|
- lib/hiiro.rb
|
|
253
254
|
- lib/hiiro/any_struct.rb
|
|
254
255
|
- lib/hiiro/app_files.rb
|
|
256
|
+
- lib/hiiro/background.rb
|
|
255
257
|
- lib/hiiro/bins.rb
|
|
256
258
|
- lib/hiiro/config.rb
|
|
257
259
|
- lib/hiiro/fuzzyfind.rb
|