hiiro 0.1.388 → 0.1.390
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 +5 -0
- data/README.md +44 -0
- data/bin/h-extract +61 -0
- data/bin/h-mcp +310 -272
- data/docs/README.md +1 -0
- data/docs/h.md +1 -0
- data/lib/hiiro/tuios.rb +629 -0
- data/lib/hiiro/version.rb +1 -1
- data/lib/hiiro.rb +3 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9c16c581ea6c758abd518a2f706d980cd7e7d4f2c0efad6fb8f99de4ba8fcdb
|
|
4
|
+
data.tar.gz: 85fbe331a3e3ddf3fd36adfb3864d5f4d131a17714be759a65eaf79940f423ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab5e23b6ebe2c5e0fbfb17000ce471c965efc3988777e346d15bbaeb54d1bc3ca1479f0ed21c98a52a0f959d1066f6c0c936a665e71ba29d3132c6f64c70062d
|
|
7
|
+
data.tar.gz: eb6a4353ae61c553c5f1cf524e18548161ff201a465cdf682ea04e897028b6b7df56ce356fd57259ddc7fd3951370b8ad65691453bbf6995c25a68869af2159b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -73,6 +73,49 @@ Saved files can be listed, printed, copied back to the clipboard, opened,
|
|
|
73
73
|
edited, or removed with `h save ls|show|copy|open|edit|rm`. See
|
|
74
74
|
[docs/h-save.md](docs/h-save.md).
|
|
75
75
|
|
|
76
|
+
### Extract files, directories, and links
|
|
77
|
+
|
|
78
|
+
`h extract files`, `h extract dirs`, and `h extract links` read text from stdin
|
|
79
|
+
or input files and print one unique match per line, in first-encounter order.
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
# Read text from stdin
|
|
83
|
+
printf '%s\n' 'README.md:12:3' 'README.md' | h extract files
|
|
84
|
+
printf '%s\n' 'docs/' './docs/' | h extract dirs
|
|
85
|
+
printf '%s\n' '(https://example.org/a_(b)).' | h extract links
|
|
86
|
+
|
|
87
|
+
# Read text from input files
|
|
88
|
+
h extract files build.log
|
|
89
|
+
h extract dirs build.log
|
|
90
|
+
h extract links notes.txt build.log
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Files and directories must exist and match the requested type. Relative paths
|
|
94
|
+
are checked against the current directory by default. Repeat `--base-dir DIR`
|
|
95
|
+
or `-b DIR` to replace that default with explicit bases. A match under any one
|
|
96
|
+
base is enough:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
h extract files --base-dir /path/to/project -b /path/to/other-project build.log
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Base directories affect path checks, not the locations of input files. Output
|
|
103
|
+
preserves the original path spelling rather than expanding or normalizing it.
|
|
104
|
+
Quotes and surrounding wrappers are removed, as are `:line` and `:line:column`
|
|
105
|
+
suffixes. Quoted paths can contain spaces, such as `"src/my file.rb:12:3"`.
|
|
106
|
+
Links must use HTTP or HTTPS. Trailing punctuation is removed, while balanced
|
|
107
|
+
parentheses in URLs are kept.
|
|
108
|
+
|
|
109
|
+
`--no-check` skips filesystem checks and uses text heuristics, not actual
|
|
110
|
+
existence or type. Files need a slash or a dotted filename and cannot end in a
|
|
111
|
+
slash. Directories need a slash and cannot have a dotted basename. These rules
|
|
112
|
+
can misclassify paths or omit real files and directories:
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
printf '%s\n' '"src/my file.rb:12:3"' | h extract files --no-check
|
|
116
|
+
printf '%s\n' 'missing/output/' | h extract dirs --no-check
|
|
117
|
+
```
|
|
118
|
+
|
|
76
119
|
### Task CLI
|
|
77
120
|
|
|
78
121
|
`t` and `tt` are gem executables in `exe/`, installed alongside `h`. They are thin
|
|
@@ -167,6 +210,7 @@ See the [task command reference](docs/t.md) for all commands and the [workflow i
|
|
|
167
210
|
| `h commit` | Select commits using fuzzy finder |
|
|
168
211
|
| `h config` | Open config files (vim, git, Herdr, zsh, starship, claude) |
|
|
169
212
|
| `h env` | Append safely quoted environment variables |
|
|
213
|
+
| [`h extract`](#extract-files-directories-and-links) | Extract file paths, directories, and HTTP(S) links from text |
|
|
170
214
|
| `h link` | Manage saved links with URL, description, and shorthand |
|
|
171
215
|
| `h pane` | Herdr pane management |
|
|
172
216
|
| `h plugin` | Manage hiiro plugins (list, edit, search) |
|
data/bin/h-extract
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'hiiro'
|
|
4
|
+
|
|
5
|
+
options = Hiiro::Options.setup do
|
|
6
|
+
option(:base_dir, short: :b, multi: true, desc: 'Base directory for relative path checks (repeatable; default: cwd)')
|
|
7
|
+
flag(:no_check, desc: 'Extract path-shaped text without checking the filesystem')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
clean_url = lambda do |url|
|
|
11
|
+
url = url.sub(/[.,;:!?]+\z/, '')
|
|
12
|
+
{ ')' => '(', ']' => '[', '}' => '{' }.each do |closing, opening|
|
|
13
|
+
url = url.chop while url.end_with?(closing) && url.count(closing) > url.count(opening)
|
|
14
|
+
end
|
|
15
|
+
url.sub(/[.,;:!?]+\z/, '')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Hiiro.run(*ARGV) do
|
|
19
|
+
%i[files dirs links].each do |kind|
|
|
20
|
+
add_subcmd(kind) do |*args|
|
|
21
|
+
vals = options.parse!(args)
|
|
22
|
+
if vals.help?
|
|
23
|
+
puts "Usage: h extract #{kind} [options] [input-file ...]"
|
|
24
|
+
puts options.help_text
|
|
25
|
+
next
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
abort("--base-dir requires a directory") if vals.base_dir.any? { |base| base.nil? || base.empty? }
|
|
29
|
+
bases = vals.base_dir.empty? ? [Dir.pwd] : vals.base_dir.map { |base| File.expand_path(base) }
|
|
30
|
+
input = Hiiro::Shell.read_input(*vals.args)
|
|
31
|
+
matches = if kind == :links
|
|
32
|
+
input.scan(%r{https?://[^\s<>"'`]+}i).map { |url| clean_url.call(url) }
|
|
33
|
+
else
|
|
34
|
+
# Consume URLs whole so their slash-separated pieces cannot become paths.
|
|
35
|
+
tokens = input.scan(%r{https?://[^\s<>"'`]+|(?<![[:alnum:]])(?:"[^"\n]+"|'[^'\n]+'|`[^`\n]+`)|[^\s<>"'`()\[\]{},;=]+}i)
|
|
36
|
+
tokens.filter_map do |token|
|
|
37
|
+
quoted = ['"', "'", '`'].include?(token[0])
|
|
38
|
+
original = quoted ? token[1...-1] : token
|
|
39
|
+
path = original.sub(/[.!?:]+\z/, '').sub(/:\d+(?::\d+)?\z/, '')
|
|
40
|
+
next if path.empty? || path.match?(%r{\A[a-z][a-z0-9+.-]*://}i)
|
|
41
|
+
|
|
42
|
+
if vals.no_check
|
|
43
|
+
next unless path.include?('/') || path.match?(/\A[^\s]+\.[^\s.]+\z/)
|
|
44
|
+
next if kind == :files && path.end_with?('/')
|
|
45
|
+
next if kind == :dirs && File.basename(path).match?(/\.[^.]+\z/)
|
|
46
|
+
else
|
|
47
|
+
path = [original, path].uniq.find do |candidate|
|
|
48
|
+
bases.any? do |base|
|
|
49
|
+
full_path = File.expand_path(candidate, base)
|
|
50
|
+
kind == :files ? File.file?(full_path) : File.directory?(full_path)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
next unless path
|
|
54
|
+
end
|
|
55
|
+
path
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
puts matches.uniq
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|