hiiro 0.1.351 → 0.1.353
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/AGENTS.md +1 -0
- data/CHANGELOG.md +13 -0
- data/README.md +7 -0
- data/bin/h-claude +21 -5
- data/bin/h-pane +2 -2
- data/docs/h-claude.md +4 -1
- data/lib/hiiro/config.rb +32 -0
- data/lib/hiiro/tui.rb +216 -0
- data/lib/hiiro/version.rb +1 -1
- data/lib/hiiro.rb +2 -1
- 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: bbd7598e65b8521905ec67a960f09700d7260c5329e066e6cfcbb4661c180c99
|
|
4
|
+
data.tar.gz: 189ca275fa4cc2af210c1d67c8976bc4b90343e68eb4a0fe86ebedea1421bb9f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 50b6f3d077471531303d04f9ef234ff4ade40dbea85b52f575e6c9e3c48088ba1318dd0798eaeef15acdeb4ce0ca8fcf13100d4963fb5174dccdefaf87de228f
|
|
7
|
+
data.tar.gz: 4c852f5cea47667811dd2dd461b5c1bdfe3935cc7fecad2c95c7d3d43f28d3c7aea0554ea415cfda812e776b047bf4dee9ef77b34fdb0ffc5b806170864e2705
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CLAUDE.md
|
data/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.1.353] - 2026-04-26
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `Hiiro::Tui::ListScreen` for building keyboard-driven full-screen list interfaces
|
|
9
|
+
- `Hiiro::Config.load_yaml` and `Hiiro::Config.yaml_dig` helpers for YAML file loading with nested key access
|
|
10
|
+
|
|
11
|
+
## [0.1.352] - 2026-04-24
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `h claude all|agents|commands|skills` now support `--absolute/-a` to print absolute tool paths; skill matches resolve to `SKILL.md`
|
|
15
|
+
|
|
5
16
|
### Fixed
|
|
6
17
|
- `h capture path <num>` now prints the path of the Nth most recent capture (was always printing the captures dir regardless of args)
|
|
7
18
|
- `h capture new` / `h capture file` now record to the DB even when interrupted (Ctrl-C, exception) so partial captures show up in `h capture ls`. Interrupted captures display with the existing `?` glyph and `(exit interrupted)` message.
|
|
19
|
+
- `h pane splitv/splith` subcommand mappings corrected
|
|
20
|
+
- Corrected `REPO_PATH` constant from `.bare` to `.git`
|
|
8
21
|
|
|
9
22
|
## [0.1.350] - 2026-04-18
|
|
10
23
|
|
data/README.md
CHANGED
|
@@ -8,6 +8,7 @@ A lightweight, extensible CLI framework for Ruby. Build your own multi-command t
|
|
|
8
8
|
- **Abbreviation matching** - Type `h ex hel` instead of `h example hello`
|
|
9
9
|
- **Plugin system** - Extend functionality with reusable modules
|
|
10
10
|
- **Per-command storage** - Each command gets its own pin/config namespace
|
|
11
|
+
- **TUI helpers** - Build keyboard-driven list screens with `Hiiro::Tui::ListScreen`
|
|
11
12
|
|
|
12
13
|
See [docs/](docs/) for detailed documentation on all subcommands.
|
|
13
14
|
|
|
@@ -93,6 +94,8 @@ h ping
|
|
|
93
94
|
| `h window` | Tmux window management |
|
|
94
95
|
| `h wtree` | Git worktree management |
|
|
95
96
|
|
|
97
|
+
`h claude agents|commands|skills -a` prints the absolute file path for each matching `.claude` tool, including `SKILL.md` for skills.
|
|
98
|
+
|
|
96
99
|
## Abbreviations
|
|
97
100
|
|
|
98
101
|
Any subcommand can be abbreviated as long as the prefix uniquely matches:
|
|
@@ -152,6 +155,10 @@ h example hello # => Hi!
|
|
|
152
155
|
h example bye # => Goodbye!
|
|
153
156
|
```
|
|
154
157
|
|
|
158
|
+
### Building TUIs
|
|
159
|
+
|
|
160
|
+
Use `Hiiro::Tui::ListScreen` for simple full-screen list interfaces. Subclass it, override `header_lines`, `format_row`, and `handle_key`, then run it from a normal `Hiiro.run` subcommand.
|
|
161
|
+
|
|
155
162
|
### Method 2: Inline Subcommands
|
|
156
163
|
|
|
157
164
|
Modify `exe/h` directly to add subcommands to the base `h` command:
|
data/bin/h-claude
CHANGED
|
@@ -17,11 +17,26 @@ opts = Hiiro::Options.setup {
|
|
|
17
17
|
|
|
18
18
|
tool_opts = Hiiro::Options.setup {
|
|
19
19
|
flag(:full, short: :f, default: false, desc: 'fulltext search - full grep file or dir')
|
|
20
|
+
flag(:absolute, short: :a, default: false, desc: 'print absolute path to matching tool file')
|
|
20
21
|
flag(:verbose, short: :v, default: false, desc: 'display claude dirs in stderr')
|
|
21
22
|
flag(:veryverbose, short: :V, default: false, desc: 'display all stderr messages')
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
def
|
|
25
|
+
def tool_file(path, skill: false)
|
|
26
|
+
return path unless skill
|
|
27
|
+
|
|
28
|
+
path / 'SKILL.md'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def display_tool_path(path, bname: nil, opts:, skill: false)
|
|
32
|
+
target = tool_file(path, skill: skill)
|
|
33
|
+
return target if opts.absolute
|
|
34
|
+
return path.basename if skill
|
|
35
|
+
|
|
36
|
+
target.basename(bname.to_s)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def glob_path(glob, bname=nil, opts:, skill: false)
|
|
25
40
|
filters = opts.args
|
|
26
41
|
fulltext = opts.full
|
|
27
42
|
bname ||= ''
|
|
@@ -46,6 +61,7 @@ def glob_path(glob, bname=nil, opts:)
|
|
|
46
61
|
cmd = ['egrep', *more_args, '-m1', re_s, f.to_s]
|
|
47
62
|
kwcmd = { out: File.open('/dev/null', 'w') }
|
|
48
63
|
base_f = f.basename(bname)
|
|
64
|
+
display_f = display_tool_path(f, bname: bname, opts: opts, skill: skill)
|
|
49
65
|
|
|
50
66
|
matches =
|
|
51
67
|
if fulltext
|
|
@@ -55,7 +71,7 @@ def glob_path(glob, bname=nil, opts:)
|
|
|
55
71
|
end
|
|
56
72
|
|
|
57
73
|
if matches
|
|
58
|
-
puts
|
|
74
|
+
puts display_f
|
|
59
75
|
else
|
|
60
76
|
$stderr.puts "SKIPPING #{base_f}" if opts.veryverbose
|
|
61
77
|
end
|
|
@@ -74,7 +90,7 @@ def collect_files(glob, bname=nil, opts:, skill: false)
|
|
|
74
90
|
claude_paths.flat_map { |path| path.glob(glob) }.filter_map do |f|
|
|
75
91
|
base_f = f.basename(bname.to_s)
|
|
76
92
|
next unless base_f.to_s.match?(re)
|
|
77
|
-
target =
|
|
93
|
+
target = tool_file(f, skill: skill)
|
|
78
94
|
target if target.exist?
|
|
79
95
|
end
|
|
80
96
|
end
|
|
@@ -171,7 +187,7 @@ add_subcmd(:env) { |*args|
|
|
|
171
187
|
opts = tool_opts.parse(args)
|
|
172
188
|
glob_path('agents/*.md', '.md', opts: opts)
|
|
173
189
|
glob_path('commands/*.md', '.md', opts: opts)
|
|
174
|
-
glob_path('skills/*/', opts: opts)
|
|
190
|
+
glob_path('skills/*/', opts: opts, skill: true)
|
|
175
191
|
}
|
|
176
192
|
|
|
177
193
|
add_subcmd(:agents) { |*args|
|
|
@@ -186,7 +202,7 @@ add_subcmd(:env) { |*args|
|
|
|
186
202
|
|
|
187
203
|
add_subcmd(:skills) { |*args|
|
|
188
204
|
opts = tool_opts.parse(args)
|
|
189
|
-
glob_path('skills/*/', opts: opts)
|
|
205
|
+
glob_path('skills/*/', opts: opts, skill: true)
|
|
190
206
|
}
|
|
191
207
|
|
|
192
208
|
add_subcmd(:vim) { |*args|
|
data/bin/h-pane
CHANGED
|
@@ -61,7 +61,7 @@ Hiiro.run(*ARGV, plugins: [Pins]) do
|
|
|
61
61
|
system('tmux', 'split-window', *args)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
add_subcmd(:
|
|
64
|
+
add_subcmd(:hsplit, :splith) { |*args|
|
|
65
65
|
if args.empty?
|
|
66
66
|
tmux.split_window(horizontal: false)
|
|
67
67
|
else
|
|
@@ -69,7 +69,7 @@ Hiiro.run(*ARGV, plugins: [Pins]) do
|
|
|
69
69
|
end
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
add_subcmd(:
|
|
72
|
+
add_subcmd(:vsplit, :splitv) { |*args|
|
|
73
73
|
if args.empty?
|
|
74
74
|
tmux.split_window(horizontal: true)
|
|
75
75
|
else
|
data/docs/h-claude.md
CHANGED
|
@@ -77,6 +77,7 @@ List agent, command, and skill files found in `.claude/` directories from the cu
|
|
|
77
77
|
| Flag | Short | Description |
|
|
78
78
|
|------|-------|-------------|
|
|
79
79
|
| `--full` | `-f` | Full text search (grep inside files) |
|
|
80
|
+
| `--absolute` | `-a` | Print the absolute path to each matching tool file (`SKILL.md` for skills) |
|
|
80
81
|
| `--verbose` | `-v` | Show `.claude` paths being searched |
|
|
81
82
|
| `--veryverbose` | `-V` | Show all paths including skipped |
|
|
82
83
|
|
|
@@ -85,7 +86,9 @@ List agent, command, and skill files found in `.claude/` directories from the cu
|
|
|
85
86
|
```bash
|
|
86
87
|
h claude all
|
|
87
88
|
h claude agents fetch
|
|
89
|
+
h claude agents -a fetch
|
|
88
90
|
h claude commands refactor
|
|
91
|
+
h claude skills -a review
|
|
89
92
|
h claude skills -f "pull request"
|
|
90
93
|
```
|
|
91
94
|
|
|
@@ -333,7 +336,7 @@ h claude vadd "Write tests for foo"
|
|
|
333
336
|
|
|
334
337
|
### vim
|
|
335
338
|
|
|
336
|
-
Open matching agent, command, and skill files in your editor. Uses the same filter logic as `all
|
|
339
|
+
Open matching agent, command, and skill files in your editor. Uses the same filter logic and search flags as `all`; matches are opened via their absolute file paths.
|
|
337
340
|
|
|
338
341
|
**Examples**
|
|
339
342
|
|
data/lib/hiiro/config.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
1
3
|
class Hiiro
|
|
2
4
|
class Config
|
|
3
5
|
BASE_DIR = File.join(Dir.home, '.config/hiiro')
|
|
@@ -15,6 +17,36 @@ class Hiiro
|
|
|
15
17
|
File.join(BASE_DIR, relpath)
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
def load_yaml(relpath = 'config.yml', default: {}, permitted_classes: [Symbol])
|
|
21
|
+
file = path(relpath)
|
|
22
|
+
return default unless File.exist?(file)
|
|
23
|
+
|
|
24
|
+
YAML.safe_load_file(file, permitted_classes: permitted_classes) || default
|
|
25
|
+
rescue StandardError
|
|
26
|
+
default
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def yaml_dig(relpath = 'config.yml', *keys, default: nil, permitted_classes: [Symbol])
|
|
30
|
+
value = load_yaml(relpath, default: {}, permitted_classes: permitted_classes)
|
|
31
|
+
|
|
32
|
+
keys.flatten.each do |key|
|
|
33
|
+
return default unless value.is_a?(Hash)
|
|
34
|
+
|
|
35
|
+
value =
|
|
36
|
+
if value.key?(key)
|
|
37
|
+
value[key]
|
|
38
|
+
elsif value.key?(key.to_s)
|
|
39
|
+
value[key.to_s]
|
|
40
|
+
elsif key.respond_to?(:to_sym) && value.key?(key.to_sym)
|
|
41
|
+
value[key.to_sym]
|
|
42
|
+
else
|
|
43
|
+
return default
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
value.nil? ? default : value
|
|
48
|
+
end
|
|
49
|
+
|
|
18
50
|
def data_path(relpath='')
|
|
19
51
|
File.join(DATA_DIR, relpath)
|
|
20
52
|
end
|
data/lib/hiiro/tui.rb
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
require 'io/console'
|
|
2
|
+
|
|
3
|
+
class Hiiro
|
|
4
|
+
module Tui
|
|
5
|
+
module Terminal
|
|
6
|
+
def with_screen
|
|
7
|
+
input = $stdin
|
|
8
|
+
$stdout.write("\e[?1049h\e[?25l")
|
|
9
|
+
$stdout.flush
|
|
10
|
+
|
|
11
|
+
input.raw do
|
|
12
|
+
yield input
|
|
13
|
+
end
|
|
14
|
+
ensure
|
|
15
|
+
$stdout.write("\r\e[0m\e[?25h\e[?1049l")
|
|
16
|
+
$stdout.flush
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def read_key(input)
|
|
20
|
+
char = input.getch
|
|
21
|
+
return :ctrl_c if char == "\u0003"
|
|
22
|
+
return :enter if char == "\r" || char == "\n"
|
|
23
|
+
|
|
24
|
+
if char == "\e"
|
|
25
|
+
first = read_escape_char(input)
|
|
26
|
+
return :escape if first.nil?
|
|
27
|
+
return :escape unless first == '['
|
|
28
|
+
|
|
29
|
+
case read_escape_char(input)
|
|
30
|
+
when 'A' then :up
|
|
31
|
+
when 'B' then :down
|
|
32
|
+
when 'C' then :right
|
|
33
|
+
when 'D' then :left
|
|
34
|
+
else :escape
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
char
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def read_escape_char(input)
|
|
42
|
+
return nil unless IO.select([input], nil, nil, 0.02)
|
|
43
|
+
|
|
44
|
+
input.getch
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def terminal_rows
|
|
48
|
+
env_dimension('LINES') || IO.console.winsize[0]
|
|
49
|
+
rescue StandardError
|
|
50
|
+
24
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def terminal_cols
|
|
54
|
+
env_dimension('COLUMNS') || IO.console.winsize[1]
|
|
55
|
+
rescue StandardError
|
|
56
|
+
80
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def terminal_line(text, cols)
|
|
60
|
+
truncate(text, cols) + "\e[K"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def center_text(text, cols)
|
|
64
|
+
truncated = truncate(text, cols)
|
|
65
|
+
return truncated if truncated.length >= cols
|
|
66
|
+
|
|
67
|
+
left_padding = [(cols - truncated.length) / 2, 0].max
|
|
68
|
+
(' ' * left_padding) + truncated
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def truncate(text, cols)
|
|
72
|
+
return text if text.length <= cols
|
|
73
|
+
return text[0, cols] if cols <= 1
|
|
74
|
+
|
|
75
|
+
text[0, cols - 1] + '…'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def visible_text(text, cols, offset = 0)
|
|
79
|
+
return truncate(text, cols) if offset <= 0
|
|
80
|
+
|
|
81
|
+
clipped = text[offset..] || ''
|
|
82
|
+
return truncate(clipped, cols) if cols <= 1
|
|
83
|
+
|
|
84
|
+
truncate("«#{clipped}", cols)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def env_dimension(name)
|
|
88
|
+
value = ENV[name].to_i
|
|
89
|
+
return nil unless value.positive?
|
|
90
|
+
|
|
91
|
+
value
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class ListScreen
|
|
96
|
+
include Terminal
|
|
97
|
+
|
|
98
|
+
attr_reader :items, :cursor, :top, :horizontal_offset
|
|
99
|
+
|
|
100
|
+
def initialize(items:, empty_message: 'No items.')
|
|
101
|
+
@items = items
|
|
102
|
+
@empty_message = empty_message
|
|
103
|
+
@cursor = 0
|
|
104
|
+
@top = 0
|
|
105
|
+
@horizontal_offset = 0
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def run
|
|
109
|
+
if items.empty?
|
|
110
|
+
puts @empty_message
|
|
111
|
+
return false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
with_screen do |input|
|
|
115
|
+
loop do
|
|
116
|
+
render
|
|
117
|
+
|
|
118
|
+
result = handle_key(read_key(input))
|
|
119
|
+
return result unless result == :continue
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def handle_key(key)
|
|
125
|
+
case key
|
|
126
|
+
when :up, 'k'
|
|
127
|
+
move(-1)
|
|
128
|
+
when :down, 'j'
|
|
129
|
+
move(1)
|
|
130
|
+
when :left, 'h'
|
|
131
|
+
scroll_horizontal(-4)
|
|
132
|
+
when :right, 'l'
|
|
133
|
+
scroll_horizontal(4)
|
|
134
|
+
when 'q', :escape, :ctrl_c
|
|
135
|
+
return false
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
:continue
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def render
|
|
142
|
+
rows = terminal_rows
|
|
143
|
+
cols = terminal_cols
|
|
144
|
+
line_cols = [cols - 1, 1].max
|
|
145
|
+
headers = header_lines
|
|
146
|
+
visible_rows = [rows - headers.length - footer_height, 1].max
|
|
147
|
+
visible = items[@top, visible_rows] || []
|
|
148
|
+
@horizontal_offset = [horizontal_offset, max_horizontal_offset(line_cols, visible)].min
|
|
149
|
+
|
|
150
|
+
lines = headers.map { |line| terminal_line(line, line_cols) }
|
|
151
|
+
visible.each_with_index do |item, idx|
|
|
152
|
+
lines << format_row(item, @top + idx == cursor, line_cols)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
(visible_rows - visible.length).times { lines << terminal_line('', line_cols) }
|
|
156
|
+
footer_lines.each { |line| lines << terminal_line(line, line_cols) }
|
|
157
|
+
|
|
158
|
+
$stdout.write("\e[H\e[2J")
|
|
159
|
+
$stdout.write(lines.join("\r\n"))
|
|
160
|
+
$stdout.write("\r")
|
|
161
|
+
$stdout.flush
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def header_lines
|
|
165
|
+
[]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def footer_lines
|
|
169
|
+
["Showing #{@top + 1}-#{@top + visible_items.length} of #{items.length}"]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def footer_height
|
|
173
|
+
1
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def format_row(item, current, line_cols)
|
|
177
|
+
prefix = current ? '> ' : ' '
|
|
178
|
+
style = current ? "\e[7m" : "\e[0m"
|
|
179
|
+
text = (prefix + visible_text(item.to_s, [line_cols - prefix.length, 1].max, horizontal_offset)).ljust(line_cols)
|
|
180
|
+
|
|
181
|
+
"#{style}#{text}\e[0m\e[K"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def move(delta)
|
|
185
|
+
@cursor = [[cursor + delta, 0].max, items.length - 1].min
|
|
186
|
+
visible_rows = body_rows_budget
|
|
187
|
+
@top = cursor if cursor < top
|
|
188
|
+
@top = cursor - visible_rows + 1 if cursor >= top + visible_rows
|
|
189
|
+
@horizontal_offset = [horizontal_offset, max_horizontal_offset].min
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def scroll_horizontal(delta)
|
|
193
|
+
@horizontal_offset = [[horizontal_offset + delta, 0].max, max_horizontal_offset].min
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def visible_items
|
|
197
|
+
items[top, body_rows_budget] || []
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def body_rows_budget
|
|
201
|
+
[terminal_rows - header_lines.length - footer_height, 1].max
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def max_horizontal_offset(line_cols = nil, visible = nil)
|
|
205
|
+
line_cols ||= [terminal_cols - 1, 1].max
|
|
206
|
+
visible ||= visible_items
|
|
207
|
+
return 0 if visible.empty?
|
|
208
|
+
|
|
209
|
+
longest_visible_item = visible.map { |item| item.to_s.length }.max || 0
|
|
210
|
+
min_visible_chars = [5, line_cols].min
|
|
211
|
+
|
|
212
|
+
[longest_visible_item - min_visible_chars, 0].max
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
data/lib/hiiro/version.rb
CHANGED
data/lib/hiiro.rb
CHANGED
|
@@ -47,6 +47,7 @@ require_relative "hiiro/pane_home"
|
|
|
47
47
|
require_relative "hiiro/pin_record"
|
|
48
48
|
require_relative "hiiro/reminder"
|
|
49
49
|
require_relative 'hiiro/registry'
|
|
50
|
+
require_relative 'hiiro/tui'
|
|
50
51
|
|
|
51
52
|
class String
|
|
52
53
|
def underscore(camel_cased_word=self)
|
|
@@ -63,7 +64,7 @@ end
|
|
|
63
64
|
|
|
64
65
|
class Hiiro
|
|
65
66
|
WORK_DIR = File.join(Dir.home, 'work')
|
|
66
|
-
REPO_PATH = File.join(WORK_DIR, '.
|
|
67
|
+
REPO_PATH = File.join(WORK_DIR, '.git')
|
|
67
68
|
|
|
68
69
|
def self.init(*oargs, plugins: [], logging: false, tasks: false, task_scope: nil, **values, &block)
|
|
69
70
|
load_env
|
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.353
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Toyota
|
|
@@ -119,6 +119,7 @@ extra_rdoc_files: []
|
|
|
119
119
|
files:
|
|
120
120
|
- ".DS_Store"
|
|
121
121
|
- ".config/.keep"
|
|
122
|
+
- AGENTS.md
|
|
122
123
|
- CHANGELOG.md
|
|
123
124
|
- CLAUDE.md
|
|
124
125
|
- LICENSE
|
|
@@ -376,6 +377,7 @@ files:
|
|
|
376
377
|
- lib/hiiro/tmux/window.rb
|
|
377
378
|
- lib/hiiro/tmux/windows.rb
|
|
378
379
|
- lib/hiiro/todo.rb
|
|
380
|
+
- lib/hiiro/tui.rb
|
|
379
381
|
- lib/hiiro/version.rb
|
|
380
382
|
- notes
|
|
381
383
|
- obsidian_slides.md
|