hiiro 0.1.366 → 0.1.367
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 +29 -0
- data/CLAUDE.md +1 -0
- data/README.md +47 -9
- data/bin/h-bin +20 -0
- data/bin/h-task +1 -0
- data/bin/t +1 -0
- data/bin/tt +1 -0
- data/docs/h-bin.md +49 -2
- data/docs/h-subtask.md +5 -44
- data/docs/h-task.md +20 -557
- data/docs/h.md +1 -2
- data/docs/t.md +17 -7
- data/docs/why-t.md +2 -2
- data/exe/h +1 -0
- data/exe/t +7 -0
- data/exe/tt +7 -0
- data/lib/hiiro/current_task.rb +92 -0
- data/lib/hiiro/error.rb +5 -0
- data/lib/hiiro/git/worktrees.rb +1 -1
- data/lib/hiiro/git.rb +8 -2
- data/lib/hiiro/task_cli.rb +671 -0
- data/lib/hiiro/task_scope.rb +2 -43
- data/lib/hiiro/task_sessions.rb +1 -1
- data/lib/hiiro/tasks.rb +40 -27
- data/lib/hiiro/version.rb +1 -1
- data/lib/hiiro.rb +23 -20
- metadata +9 -1
- data/bin/t +0 -526
- data/bin/tt +0 -20
data/lib/hiiro/task_scope.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Hiiro
|
|
2
2
|
class TaskScope
|
|
3
|
-
class Error <
|
|
3
|
+
class Error < Hiiro::Error; end
|
|
4
4
|
|
|
5
5
|
attr_reader :reference
|
|
6
6
|
|
|
@@ -45,48 +45,7 @@ class Hiiro
|
|
|
45
45
|
private
|
|
46
46
|
|
|
47
47
|
def current_task
|
|
48
|
-
|
|
49
|
-
if ENV['HERDR_WORKSPACE_ID'] || ENV['HERDR_PANE_ID'] || ENV['HERDR_ENV'] == '1'
|
|
50
|
-
herdr = @herdr.call
|
|
51
|
-
unless herdr.server_running?
|
|
52
|
-
raise Error, 'Herdr is not running; start Herdr for workspace/tab/pane commands, or supply a task name for task data'
|
|
53
|
-
end
|
|
54
|
-
pane = herdr.get_pane(ENV['HERDR_PANE_ID']) if ENV['HERDR_PANE_ID']
|
|
55
|
-
if ENV['HERDR_PANE_ID'] && !pane
|
|
56
|
-
raise Error, 'Cannot resolve the current Herdr pane; supply a task name'
|
|
57
|
-
end
|
|
58
|
-
workspace_id = ENV['HERDR_WORKSPACE_ID'] || pane&.workspace_id
|
|
59
|
-
if pane && workspace_id != pane.workspace_id
|
|
60
|
-
raise Error, 'Conflicting Herdr pane/workspace context; supply a task name'
|
|
61
|
-
end
|
|
62
|
-
workspace = workspace_id ? herdr.get_workspace(workspace_id) : herdr.current_workspace
|
|
63
|
-
raise Error, 'Cannot resolve the current Herdr workspace; supply a task name' unless workspace
|
|
64
|
-
|
|
65
|
-
matches = tasks.select { |task| (task.session || task.name).tr('.', '_') == workspace.name }
|
|
66
|
-
raise Error, "Ambiguous workspace task: #{matches.map(&:name).join(', ')}" if matches.length > 1
|
|
67
|
-
return matches.first if matches.one?
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
cwd = File.realpath(Dir.pwd)
|
|
71
|
-
matches = tasks.select do |task|
|
|
72
|
-
directory = task.primary_directory || (task.tree && (task.tree.start_with?('/') ? task.tree : File.join(Hiiro::WORK_DIR, task.tree)))
|
|
73
|
-
paths = [task.home, directory, *task.resources.where(kind: 'directory').select_map(:target)].compact
|
|
74
|
-
paths.any? { |path| inside?(cwd, path) }
|
|
75
|
-
end
|
|
76
|
-
raise Error, "Ambiguous directory task: #{matches.map(&:name).join(', ')}" if matches.length > 1
|
|
77
|
-
return matches.first if matches.one?
|
|
78
|
-
|
|
79
|
-
saved = PinRecord.find_key('t', 'current_task')
|
|
80
|
-
raise Error, 'No current task; supply a task name or run t TASK current' unless saved
|
|
81
|
-
|
|
82
|
-
TaskRecord[saved.value] || raise(Error, 'Saved task no longer exists; run t TASK current')
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def inside?(path, directory)
|
|
86
|
-
return false unless Dir.exist?(directory)
|
|
87
|
-
|
|
88
|
-
root = File.realpath(directory)
|
|
89
|
-
path == root || path.start_with?(root == File::SEPARATOR ? root : root + File::SEPARATOR)
|
|
48
|
+
CurrentTask.new(herdr: @herdr, pin: true).resolve!
|
|
90
49
|
end
|
|
91
50
|
end
|
|
92
51
|
end
|
data/lib/hiiro/task_sessions.rb
CHANGED
data/lib/hiiro/tasks.rb
CHANGED
|
@@ -175,6 +175,28 @@ class Hiiro
|
|
|
175
175
|
task_name = scope == :subtask ? "#{current_parent_task.name}/#{name}" : name
|
|
176
176
|
subtree_name = scope == :subtask ? "#{current_parent_task.name}/#{name}" : "#{name}/main"
|
|
177
177
|
|
|
178
|
+
target_path = create_tree(subtree_name, sparse_groups: sparse_groups)
|
|
179
|
+
return unless target_path
|
|
180
|
+
|
|
181
|
+
session_name = task_name
|
|
182
|
+
task = Task.new(name: task_name, tree: subtree_name, session: session_name)
|
|
183
|
+
config.save_task(task)
|
|
184
|
+
|
|
185
|
+
base_dir = target_path
|
|
186
|
+
if app_name
|
|
187
|
+
app = environment.find_app(app_name)
|
|
188
|
+
base_dir = app.resolve(target_path) if app
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
Dir.chdir(base_dir)
|
|
192
|
+
hiiro.start_herdr_workspace(session_name, start_directory: Dir.pwd)
|
|
193
|
+
|
|
194
|
+
puts "Started task '#{task_name}' in worktree '#{subtree_name}'"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Create (or reuse an unassigned) worktree under WORK_DIR and return its path,
|
|
198
|
+
# or nil on failure. Shared by `h task start` and `t TASK tree new`.
|
|
199
|
+
def create_tree(subtree_name, sparse_groups: [])
|
|
178
200
|
target_path = File.join(Hiiro::WORK_DIR, subtree_name)
|
|
179
201
|
|
|
180
202
|
git = Hiiro::Git.new(nil, Hiiro::REPO_PATH)
|
|
@@ -184,33 +206,19 @@ class Hiiro
|
|
|
184
206
|
FileUtils.mkdir_p(File.dirname(target_path))
|
|
185
207
|
unless git.move_worktree(available.path, target_path, repo_path: Hiiro::REPO_PATH)
|
|
186
208
|
puts "ERROR: Failed to rename worktree"
|
|
187
|
-
return
|
|
209
|
+
return nil
|
|
188
210
|
end
|
|
189
211
|
else
|
|
190
212
|
puts "Creating new worktree '#{subtree_name}'..."
|
|
191
213
|
FileUtils.mkdir_p(File.dirname(target_path))
|
|
192
214
|
unless git.add_worktree_detached(target_path, repo_path: Hiiro::REPO_PATH)
|
|
193
215
|
puts "ERROR: Failed to create worktree"
|
|
194
|
-
return
|
|
216
|
+
return nil
|
|
195
217
|
end
|
|
196
218
|
end
|
|
197
219
|
|
|
198
220
|
apply_sparse_checkout(target_path, sparse_groups) if sparse_groups.any?
|
|
199
|
-
|
|
200
|
-
session_name = task_name
|
|
201
|
-
task = Task.new(name: task_name, tree: subtree_name, session: session_name)
|
|
202
|
-
config.save_task(task)
|
|
203
|
-
|
|
204
|
-
base_dir = target_path
|
|
205
|
-
if app_name
|
|
206
|
-
app = environment.find_app(app_name)
|
|
207
|
-
base_dir = app.resolve(target_path) if app
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
Dir.chdir(base_dir)
|
|
211
|
-
hiiro.start_herdr_workspace(session_name, start_directory: Dir.pwd)
|
|
212
|
-
|
|
213
|
-
puts "Started task '#{task_name}' in worktree '#{subtree_name}'"
|
|
221
|
+
target_path
|
|
214
222
|
end
|
|
215
223
|
|
|
216
224
|
def switch_to_task(task, app_name: nil, force: false)
|
|
@@ -1463,10 +1471,11 @@ class Hiiro
|
|
|
1463
1471
|
end
|
|
1464
1472
|
|
|
1465
1473
|
def name
|
|
1466
|
-
@name ||=
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1474
|
+
@name ||= begin
|
|
1475
|
+
roots = [Hiiro::WORK_DIR]
|
|
1476
|
+
roots << File.realpath(Hiiro::WORK_DIR) if Dir.exist?(Hiiro::WORK_DIR)
|
|
1477
|
+
root = roots.uniq.find { |dir| path.start_with?(dir + '/') }
|
|
1478
|
+
root ? path.delete_prefix(root + '/') : File.basename(path)
|
|
1470
1479
|
end
|
|
1471
1480
|
end
|
|
1472
1481
|
|
|
@@ -1683,13 +1692,17 @@ class Hiiro
|
|
|
1683
1692
|
end
|
|
1684
1693
|
|
|
1685
1694
|
def task
|
|
1695
|
+
return @task if defined?(@task)
|
|
1696
|
+
|
|
1697
|
+
s = session
|
|
1698
|
+
t = tree
|
|
1699
|
+
@task = all_tasks.find { |task|
|
|
1700
|
+
(s && task.session_name == s.name) ||
|
|
1701
|
+
(t && (task.tree_name == t.name || task.tree_name == t.path))
|
|
1702
|
+
}
|
|
1686
1703
|
@task ||= begin
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
all_tasks.find { |task|
|
|
1690
|
-
(s && task.session_name == s.name) ||
|
|
1691
|
-
(t && (task.tree_name == t.name || task.tree_name == t.path))
|
|
1692
|
-
}
|
|
1704
|
+
record = CurrentTask.new(herdr: -> { Hiiro::Herdr.client }, cwd: path, pin: false).resolve
|
|
1705
|
+
record && all_tasks.find { |task| task.name == record.name }
|
|
1693
1706
|
end
|
|
1694
1707
|
end
|
|
1695
1708
|
|
data/lib/hiiro/version.rb
CHANGED
data/lib/hiiro.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "ostruct"
|
|
|
6
6
|
require 'awesome_print'
|
|
7
7
|
|
|
8
8
|
require_relative "hiiro/version"
|
|
9
|
+
require_relative "hiiro/error"
|
|
9
10
|
require_relative "hiiro/config"
|
|
10
11
|
require_relative "hiiro/effects"
|
|
11
12
|
require_relative "hiiro/db"
|
|
@@ -46,6 +47,10 @@ require_relative "hiiro/pane_home"
|
|
|
46
47
|
require_relative "hiiro/pin_record"
|
|
47
48
|
require_relative "hiiro/reminder"
|
|
48
49
|
require_relative 'hiiro/registry'
|
|
50
|
+
require_relative 'hiiro/current_task'
|
|
51
|
+
require_relative 'hiiro/task_scope'
|
|
52
|
+
require_relative 'hiiro/task_sessions'
|
|
53
|
+
require_relative 'hiiro/task_cli'
|
|
49
54
|
require_relative 'hiiro/tui'
|
|
50
55
|
|
|
51
56
|
class String
|
|
@@ -65,7 +70,7 @@ class Hiiro
|
|
|
65
70
|
WORK_DIR = File.join(Dir.home, 'work')
|
|
66
71
|
REPO_PATH = File.join(WORK_DIR, '.git')
|
|
67
72
|
|
|
68
|
-
def self.init(*oargs, plugins: [], logging: false, tasks: false, task_scope: nil, **values, &block)
|
|
73
|
+
def self.init(*oargs, plugins: [], logging: false, tasks: false, task_scope: nil, builtin_commands: true, **values, &block)
|
|
69
74
|
load_env
|
|
70
75
|
Hiiro::DB.setup!
|
|
71
76
|
|
|
@@ -98,24 +103,14 @@ class Hiiro
|
|
|
98
103
|
new(h_bin, *h_args, logging: logging, tasks: tasks, task_scope: task_scope, **values).tap do |hiiro|
|
|
99
104
|
hiiro.load_plugins(plugins)
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
hiiro.add_subcmd(:edit, **values) { |*args|
|
|
106
|
-
hiiro.edit_files(hiiro.bin)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if hiiro.tasks_enabled?
|
|
110
|
-
hiiro.add_subcmd(:task) do |*args|
|
|
111
|
-
tm = TaskManager.new(hiiro, scope: :task)
|
|
112
|
-
Tasks.build_hiiro(hiiro, tm).run
|
|
113
|
-
end
|
|
106
|
+
if builtin_commands
|
|
107
|
+
hiiro.add_subcommand(:pry) { |*args|
|
|
108
|
+
binding.pry
|
|
109
|
+
}
|
|
114
110
|
|
|
115
|
-
hiiro.add_subcmd(:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
end
|
|
111
|
+
hiiro.add_subcmd(:edit, **values) { |*args|
|
|
112
|
+
hiiro.edit_files(hiiro.bin)
|
|
113
|
+
}
|
|
119
114
|
end
|
|
120
115
|
|
|
121
116
|
if block
|
|
@@ -132,8 +127,8 @@ class Hiiro
|
|
|
132
127
|
Options.setup(&block)
|
|
133
128
|
end
|
|
134
129
|
|
|
135
|
-
def self.run(*args, plugins: [], logging: false, tasks: false, task_scope: nil, **values, &block)
|
|
136
|
-
hiiro = init(*args, plugins:, logging:, tasks:, task_scope:, **values, &block)
|
|
130
|
+
def self.run(*args, plugins: [], logging: false, tasks: false, task_scope: nil, builtin_commands: true, **values, &block)
|
|
131
|
+
hiiro = init(*args, plugins:, logging:, tasks:, task_scope:, builtin_commands:, **values, &block)
|
|
137
132
|
|
|
138
133
|
hiiro.run
|
|
139
134
|
end
|
|
@@ -227,6 +222,12 @@ class Hiiro
|
|
|
227
222
|
Hiiro::Config.open(file, dir: dir)
|
|
228
223
|
end
|
|
229
224
|
|
|
225
|
+
# Open a file, directory, or URL with the OS default handler.
|
|
226
|
+
def open_default(target)
|
|
227
|
+
executable = RUBY_PLATFORM.include?('darwin') ? 'open' : 'xdg-open'
|
|
228
|
+
system(executable, target)
|
|
229
|
+
end
|
|
230
|
+
|
|
230
231
|
def herdr_client
|
|
231
232
|
@herdr_client ||= Herdr.client!(self)
|
|
232
233
|
end
|
|
@@ -276,6 +277,8 @@ class Hiiro
|
|
|
276
277
|
handle_result(result)
|
|
277
278
|
|
|
278
279
|
exit 1
|
|
280
|
+
rescue Hiiro::Error => e
|
|
281
|
+
abort "ERROR: #{e.message}"
|
|
279
282
|
rescue => e
|
|
280
283
|
puts "ERROR: #{e.message}"
|
|
281
284
|
puts e.backtrace
|
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.367
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Toyota
|
|
@@ -129,6 +129,8 @@ email:
|
|
|
129
129
|
executables:
|
|
130
130
|
- h
|
|
131
131
|
- hiiro
|
|
132
|
+
- t
|
|
133
|
+
- tt
|
|
132
134
|
extensions: []
|
|
133
135
|
extra_rdoc_files: []
|
|
134
136
|
files:
|
|
@@ -170,6 +172,7 @@ files:
|
|
|
170
172
|
- bin/h-sha
|
|
171
173
|
- bin/h-sparse
|
|
172
174
|
- bin/h-tags
|
|
175
|
+
- bin/h-task
|
|
173
176
|
- bin/h-time
|
|
174
177
|
- bin/h-title
|
|
175
178
|
- bin/h-todo
|
|
@@ -336,6 +339,8 @@ files:
|
|
|
336
339
|
- examples/sparse_groups.yml
|
|
337
340
|
- exe/h
|
|
338
341
|
- exe/hiiro
|
|
342
|
+
- exe/t
|
|
343
|
+
- exe/tt
|
|
339
344
|
- h-tmux-plugins.tmux
|
|
340
345
|
- hiiro.gemspec
|
|
341
346
|
- lib/hiiro.rb
|
|
@@ -349,8 +354,10 @@ files:
|
|
|
349
354
|
- lib/hiiro/capture.rb
|
|
350
355
|
- lib/hiiro/check_run.rb
|
|
351
356
|
- lib/hiiro/config.rb
|
|
357
|
+
- lib/hiiro/current_task.rb
|
|
352
358
|
- lib/hiiro/db.rb
|
|
353
359
|
- lib/hiiro/effects.rb
|
|
360
|
+
- lib/hiiro/error.rb
|
|
354
361
|
- lib/hiiro/fuzzyfind.rb
|
|
355
362
|
- lib/hiiro/git.rb
|
|
356
363
|
- lib/hiiro/git/branch.rb
|
|
@@ -383,6 +390,7 @@ files:
|
|
|
383
390
|
- lib/hiiro/service_manager.rb
|
|
384
391
|
- lib/hiiro/shell.rb
|
|
385
392
|
- lib/hiiro/tags.rb
|
|
393
|
+
- lib/hiiro/task_cli.rb
|
|
386
394
|
- lib/hiiro/task_record.rb
|
|
387
395
|
- lib/hiiro/task_scope.rb
|
|
388
396
|
- lib/hiiro/task_sessions.rb
|