ukiryu 0.1.1 → 0.1.3

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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +58 -14
  3. data/.gitignore +3 -0
  4. data/.rubocop_todo.yml +170 -79
  5. data/Gemfile +1 -1
  6. data/README.adoc +1603 -576
  7. data/docs/.gitignore +1 -0
  8. data/docs/Gemfile +10 -0
  9. data/docs/INDEX.adoc +261 -0
  10. data/docs/_config.yml +180 -0
  11. data/docs/advanced/custom-tool-classes.adoc +581 -0
  12. data/docs/advanced/index.adoc +20 -0
  13. data/docs/features/configuration.adoc +657 -0
  14. data/docs/features/index.adoc +31 -0
  15. data/docs/features/platform-support.adoc +488 -0
  16. data/docs/getting-started/core-concepts.adoc +666 -0
  17. data/docs/getting-started/index.adoc +36 -0
  18. data/docs/getting-started/installation.adoc +216 -0
  19. data/docs/getting-started/quick-start.adoc +258 -0
  20. data/docs/guides/env-var-sets.adoc +388 -0
  21. data/docs/guides/index.adoc +20 -0
  22. data/docs/interfaces/cli.adoc +609 -0
  23. data/docs/interfaces/index.adoc +153 -0
  24. data/docs/interfaces/ruby-api.adoc +538 -0
  25. data/docs/lychee.toml +49 -0
  26. data/docs/reference/configuration-options.adoc +720 -0
  27. data/docs/reference/error-codes.adoc +634 -0
  28. data/docs/reference/index.adoc +20 -0
  29. data/docs/reference/ruby-api.adoc +1217 -0
  30. data/docs/understanding/index.adoc +20 -0
  31. data/lib/ukiryu/cli.rb +43 -58
  32. data/lib/ukiryu/cli_commands/base_command.rb +16 -27
  33. data/lib/ukiryu/cli_commands/cache_command.rb +100 -0
  34. data/lib/ukiryu/cli_commands/commands_command.rb +8 -8
  35. data/lib/ukiryu/cli_commands/commands_command.rb.fixed +1 -1
  36. data/lib/ukiryu/cli_commands/config_command.rb +49 -7
  37. data/lib/ukiryu/cli_commands/definitions_command.rb +254 -0
  38. data/lib/ukiryu/cli_commands/describe_command.rb +13 -7
  39. data/lib/ukiryu/cli_commands/describe_command.rb.fixed +1 -1
  40. data/lib/ukiryu/cli_commands/docs_command.rb +148 -0
  41. data/lib/ukiryu/cli_commands/exec_inline_command.rb.fixed +1 -1
  42. data/lib/ukiryu/cli_commands/extract_command.rb +2 -2
  43. data/lib/ukiryu/cli_commands/info_command.rb +7 -7
  44. data/lib/ukiryu/cli_commands/lint_command.rb +167 -0
  45. data/lib/ukiryu/cli_commands/list_command.rb +6 -6
  46. data/lib/ukiryu/cli_commands/opts_command.rb +2 -2
  47. data/lib/ukiryu/cli_commands/opts_command.rb.fixed +1 -1
  48. data/lib/ukiryu/cli_commands/register_command.rb +144 -0
  49. data/lib/ukiryu/cli_commands/resolve_command.rb +124 -0
  50. data/lib/ukiryu/cli_commands/run_command.rb +38 -14
  51. data/lib/ukiryu/cli_commands/run_file_command.rb +2 -2
  52. data/lib/ukiryu/cli_commands/system_command.rb +50 -32
  53. data/lib/ukiryu/cli_commands/validate_command.rb +452 -51
  54. data/lib/ukiryu/cli_commands/which_command.rb +5 -5
  55. data/lib/ukiryu/command_builder.rb +81 -23
  56. data/lib/ukiryu/config/env_provider.rb +3 -3
  57. data/lib/ukiryu/config/env_schema.rb +6 -6
  58. data/lib/ukiryu/config.rb +11 -11
  59. data/lib/ukiryu/definition/definition_cache.rb +238 -0
  60. data/lib/ukiryu/definition/definition_composer.rb +257 -0
  61. data/lib/ukiryu/definition/definition_linter.rb +460 -0
  62. data/lib/ukiryu/definition/definition_validator.rb +320 -0
  63. data/lib/ukiryu/definition/discovery.rb +239 -0
  64. data/lib/ukiryu/definition/documentation_generator.rb +429 -0
  65. data/lib/ukiryu/definition/lint_issue.rb +168 -0
  66. data/lib/ukiryu/definition/loader.rb +139 -0
  67. data/lib/ukiryu/definition/metadata.rb +159 -0
  68. data/lib/ukiryu/definition/source.rb +87 -0
  69. data/lib/ukiryu/definition/sources/file.rb +138 -0
  70. data/lib/ukiryu/definition/sources/string.rb +88 -0
  71. data/lib/ukiryu/definition/validation_result.rb +158 -0
  72. data/lib/ukiryu/definition/version_resolver.rb +194 -0
  73. data/lib/ukiryu/definition.rb +40 -0
  74. data/lib/ukiryu/errors.rb +6 -0
  75. data/lib/ukiryu/execution_context.rb +11 -11
  76. data/lib/ukiryu/executor.rb +6 -0
  77. data/lib/ukiryu/extractors/extractor.rb +6 -5
  78. data/lib/ukiryu/extractors/help_parser.rb +13 -19
  79. data/lib/ukiryu/logger.rb +3 -1
  80. data/lib/ukiryu/models/command_definition.rb +3 -3
  81. data/lib/ukiryu/models/command_info.rb +1 -1
  82. data/lib/ukiryu/models/components.rb +1 -3
  83. data/lib/ukiryu/models/env_var_definition.rb +11 -3
  84. data/lib/ukiryu/models/flag_definition.rb +15 -0
  85. data/lib/ukiryu/models/option_definition.rb +7 -7
  86. data/lib/ukiryu/models/platform_profile.rb +6 -3
  87. data/lib/ukiryu/models/routing.rb +1 -1
  88. data/lib/ukiryu/models/tool_definition.rb +2 -4
  89. data/lib/ukiryu/models/tool_metadata.rb +6 -6
  90. data/lib/ukiryu/models/validation_result.rb +1 -1
  91. data/lib/ukiryu/models/version_compatibility.rb +6 -3
  92. data/lib/ukiryu/models/version_detection.rb +10 -1
  93. data/lib/ukiryu/{registry.rb → register.rb} +54 -38
  94. data/lib/ukiryu/register_auto_manager.rb +268 -0
  95. data/lib/ukiryu/schema_validator.rb +31 -10
  96. data/lib/ukiryu/shell/base.rb +18 -0
  97. data/lib/ukiryu/shell/bash.rb +19 -1
  98. data/lib/ukiryu/shell/cmd.rb +11 -1
  99. data/lib/ukiryu/shell/powershell.rb +11 -1
  100. data/lib/ukiryu/shell.rb +1 -1
  101. data/lib/ukiryu/tool.rb +107 -95
  102. data/lib/ukiryu/tool_index.rb +22 -22
  103. data/lib/ukiryu/tools/base.rb +12 -25
  104. data/lib/ukiryu/tools/generator.rb +7 -7
  105. data/lib/ukiryu/tools.rb +3 -3
  106. data/lib/ukiryu/type.rb +20 -5
  107. data/lib/ukiryu/version.rb +1 -1
  108. data/lib/ukiryu/version_detector.rb +21 -2
  109. data/lib/ukiryu.rb +6 -3
  110. data/ukiryu-proposal.md +41 -41
  111. data/ukiryu.gemspec +1 -0
  112. metadata +64 -8
  113. data/.gitmodules +0 -3
@@ -0,0 +1,1217 @@
1
+ ---
2
+ layout: default
3
+ title: Ruby API Reference
4
+ parent: Reference
5
+ nav_order: 4
6
+ ---
7
+
8
+ == Ruby API Reference
9
+
10
+ Complete reference documentation for Ukiryu Ruby classes and methods.
11
+
12
+ // Module: Ukiryu
13
+ == Module: Ukiryu
14
+
15
+ The root module for the Ukiryu gem.
16
+
17
+ [source,ruby]
18
+ ----
19
+ require 'ukiryu'
20
+ ----
21
+
22
+ === Classes
23
+
24
+ * `Ukiryu::Tool` - Main tool interface
25
+ * `Ukiryu::Config` - Configuration management
26
+ * `Ukiryu::Register` - Tool register
27
+ * `Ukiryu::Executor` - Command execution
28
+ * `Ukiryu::Shell` - Shell abstraction
29
+ * `Ukiryu::Platform` - Platform detection
30
+ * `Ukiryu::Runtime` - Runtime state management
31
+
32
+ === Submodules
33
+
34
+ * `Ukiryu::Tools` - Tool-specific classes
35
+ * `Ukiryu::Definition` - Definition loading
36
+ * `Ukiryu::Execution` - Execution result classes
37
+ * `Ukiryu::Models` - Data models
38
+
39
+ // Class: Ukiryu::Tool
40
+ == Class: Ukiryu::Tool
41
+
42
+ Main interface for interacting with CLI tools defined in YAML profiles.
43
+
44
+ === Class Methods
45
+
46
+ ==== get
47
+
48
+ [source,ruby]
49
+ Tool.get(name, options = {}) -> Tool
50
+ ----
51
+
52
+ Get a tool by name from the register.
53
+
54
+ * **Parameters**:
55
+ * `name` (String, Symbol) - Tool name
56
+ * `options` (Hash) - Optional parameters
57
+ * `:register_path` (String) - Path to tool register
58
+ * `:platform` (Symbol) - Platform to use (`:macos`, `:linux`, `:windows`)
59
+ * `:shell` (Symbol) - Shell to use (`:bash`, `:zsh`, `:fish`, `:sh`, `:powershell`, `:cmd`)
60
+ * `:version` (String) - Specific version to use
61
+ * **Returns** (Tool) - Tool instance
62
+ * **Raises** (ToolNotFoundError) - If tool not found in register
63
+ * **Raises** (ProfileNotFoundError) - If no compatible profile for platform/shell
64
+
65
+ [source,ruby]
66
+ ----
67
+ # Get tool with auto-detected platform/shell
68
+ tool = Ukiryu::Tool.get(:imagemagick)
69
+
70
+ # Get tool for specific platform
71
+ tool = Ukiryu::Tool.get(:imagemagick, platform: :linux)
72
+
73
+ # Get specific version
74
+ tool = Ukiryu::Tool.get(:imagemagick, version: '7.1')
75
+ ----
76
+
77
+ ==== find_by
78
+
79
+ [source,ruby]
80
+ Tool.find_by(identifier, options = {}) -> Tool, nil
81
+ ----
82
+
83
+ Find a tool by name, alias, or interface.
84
+
85
+ * **Parameters**:
86
+ * `identifier` (String, Symbol) - Tool name, interface, or alias
87
+ * `options` (Hash) - Optional parameters (same as `get`)
88
+ * **Returns** (Tool, nil) - Tool instance or nil if not found
89
+
90
+ [source,ruby]
91
+ ----
92
+ # Find by exact name
93
+ tool = Ukiryu::Tool.find_by(:imagemagick)
94
+
95
+ # Find by interface
96
+ tool = Ukiryu::Tool.find_by(:convert)
97
+
98
+ # Find by alias
99
+ tool = Ukiryu::Tool.find_by(:magick)
100
+
101
+ # Returns nil if not found
102
+ tool = Ukiryu::Tool.find_by(:nonexistent) # => nil
103
+ ----
104
+
105
+ ==== get_class
106
+
107
+ [source,ruby]
108
+ Tool.get_class(tool_name) -> Class
109
+ ----
110
+
111
+ Get the tool-specific class (new OOP API).
112
+
113
+ * **Parameters**:
114
+ * `tool_name` (String, Symbol) - Tool name
115
+ * **Returns** (Class) - Tool class (e.g., `Ukiryu::Tools::Imagemagick`)
116
+
117
+ [source,ruby]
118
+ ----
119
+ # Get tool class
120
+ tool_class = Ukiryu::Tool.get_class(:imagemagick)
121
+ # => Ukiryu::Tools::Imagemagick
122
+
123
+ # Create instance
124
+ tool = tool_class.new
125
+ ----
126
+
127
+ ==== load
128
+
129
+ [source,ruby]
130
+ Tool.load(file_path, options = {}) -> Tool
131
+ Tool.from_file(file_path, options = {}) -> Tool
132
+ ----
133
+
134
+ Load a tool definition from a file path.
135
+
136
+ * **Parameters**:
137
+ * `file_path` (String) - Path to YAML file
138
+ * `options` (Hash) - Optional parameters
139
+ * `:validation` (Symbol) - Validation mode (`:strict`, `:lenient`, `:none`)
140
+ * `:version_check` (Symbol) - Version check mode (`:strict`, `:lenient`, `:probe`)
141
+ * **Returns** (Tool) - Tool instance
142
+ * **Raises** (DefinitionLoadError) - If file cannot be loaded
143
+ * **Raises** (DefinitionValidationError) - If validation fails
144
+
145
+ [source,ruby]
146
+ ----
147
+ # Load from file
148
+ tool = Ukiryu::Tool.load('/path/to/tool.yaml')
149
+
150
+ # With validation options
151
+ tool = Ukiryu::Tool.load('/path/to/tool.yaml',
152
+ validation: :strict,
153
+ version_check: :probe
154
+ )
155
+
156
+ # Alias method
157
+ tool = Ukiryu::Tool.from_file('/path/to/tool.yaml')
158
+ ----
159
+
160
+ ==== load_from_string
161
+
162
+ [source,ruby]
163
+ Tool.load_from_string(yaml_string, options = {}) -> Tool
164
+ Tool.from_definition(yaml_string, options = {}) -> Tool
165
+ ----
166
+
167
+ Load a tool definition from a YAML string.
168
+
169
+ * **Parameters**:
170
+ * `yaml_string` (String) - YAML content
171
+ * `options` (Hash) - Optional parameters
172
+ * `:file_path` (String) - Optional file path for error messages
173
+ * `:validation` (Symbol) - Validation mode
174
+ * `:version_check` (Symbol) - Version check mode
175
+ * **Returns** (Tool) - Tool instance
176
+ * **Raises** (DefinitionLoadError) - If YAML cannot be parsed
177
+
178
+ [source,ruby]
179
+ ----
180
+ # Load from string
181
+ yaml = <<-YAML
182
+ name: mytool
183
+ version: "1.0"
184
+ profiles:
185
+ - name: default
186
+ platforms: [linux, macos, windows]
187
+ shells: [bash, zsh, powershell, cmd]
188
+ YAML
189
+
190
+ tool = Ukiryu::Tool.load_from_string(yaml)
191
+
192
+ # Alias method
193
+ tool = Ukiryu::Tool.from_definition(yaml)
194
+ ----
195
+
196
+ ==== from_bundled
197
+
198
+ [source,ruby]
199
+ Tool.from_bundled(tool_name, options = {}) -> Tool, nil
200
+ ----
201
+
202
+ Load a tool from bundled system locations.
203
+
204
+ * **Parameters**:
205
+ * `tool_name` (String, Symbol) - Tool name
206
+ * `options` (Hash) - Optional parameters (same as `load`)
207
+ * **Returns** (Tool, nil) - Tool instance or nil if not found
208
+
209
+ [source,ruby]
210
+ ----
211
+ # Search bundled locations
212
+ tool = Ukiryu::Tool.from_bundled(:imagemagick)
213
+ ----
214
+
215
+ ==== extract_definition
216
+
217
+ [source,ruby]
218
+ Tool.extract_definition(tool_name, options = {}) -> Hash
219
+ ----
220
+
221
+ Extract tool definition from an installed CLI tool.
222
+
223
+ * **Parameters**:
224
+ * `tool_name` (String, Symbol) - Tool name
225
+ * `options` (Hash) - Extraction options
226
+ * `:output` (String) - Output file path
227
+ * `:method` (Symbol) - Extraction method (`:native`, `:help`, `:auto`)
228
+ * `:verbose` (Boolean) - Enable verbose output
229
+ * **Returns** (Hash) - Result with keys:
230
+ * `:success` (Boolean) - Success status
231
+ * `:yaml` (String) - Extracted YAML
232
+ * `:method` (Symbol) - Method used
233
+ * `:error` (String) - Error message if failed
234
+
235
+ [source,ruby]
236
+ ----
237
+ # Extract definition
238
+ result = Ukiryu::Tool.extract_definition(:git)
239
+ if result[:success]
240
+ puts result[:yaml]
241
+ end
242
+
243
+ # Extract and write to file
244
+ result = Ukiryu::Tool.extract_definition(:git,
245
+ output: './git.yaml',
246
+ method: :auto,
247
+ verbose: true
248
+ )
249
+ ----
250
+
251
+ ==== clear_cache
252
+
253
+ [source,ruby]
254
+ Tool.clear_cache -> nil
255
+ ----
256
+
257
+ Clear the tool cache.
258
+
259
+ [source,ruby]
260
+ ----
261
+ # Clear all cached tools
262
+ Ukiryu::Tool.clear_cache
263
+ ----
264
+
265
+ ==== clear_definition_cache
266
+
267
+ [source,ruby]
268
+ Tool.clear_definition_cache -> nil
269
+ ----
270
+
271
+ Clear the definition cache only.
272
+
273
+ [source,ruby]
274
+ ----
275
+ # Clear definition cache
276
+ Ukiryu::Tool.clear_definition_cache
277
+ ----
278
+
279
+ ==== configure
280
+
281
+ [source,ruby]
282
+ Tool.configure(options = {}) -> Hash
283
+ ----
284
+
285
+ Configure default options for Tool instances.
286
+
287
+ * **Parameters**:
288
+ * `options` (Hash) - Default options
289
+ * **Returns** (Hash) - Current default options
290
+
291
+ [source,ruby]
292
+ ----
293
+ # Configure defaults
294
+ Ukiryu::Tool.configure(
295
+ timeout: 120,
296
+ debug: true
297
+ )
298
+ ----
299
+
300
+ === Instance Methods
301
+
302
+ ==== name
303
+
304
+ [source,ruby]
305
+ tool.name -> String
306
+ ----
307
+
308
+ Get the tool name.
309
+
310
+ [source,ruby]
311
+ ----
312
+ tool = Ukiryu::Tool.get(:imagemagick)
313
+ tool.name # => "imagemagick"
314
+ ----
315
+
316
+ ==== version
317
+
318
+ [source,ruby]
319
+ tool.version -> String, nil
320
+ ----
321
+
322
+ Get the detected tool version.
323
+
324
+ [source,ruby]
325
+ ----
326
+ tool = Ukiryu::Tool.get(:imagemagick)
327
+ tool.version # => "7.1.1-32"
328
+ ----
329
+
330
+ ==== executable
331
+
332
+ [source,ruby]
333
+ tool.executable -> String
334
+ ----
335
+
336
+ Get the executable path.
337
+
338
+ [source,ruby]
339
+ ----
340
+ tool = Ukiryu::Tool.get(:imagemagick)
341
+ tool.executable # => "/usr/local/bin/magick"
342
+ ----
343
+
344
+ ==== available?
345
+
346
+ [source,ruby]
347
+ tool.available? -> Boolean
348
+ ----
349
+
350
+ Check if the tool is available (executable found).
351
+
352
+ [source,ruby]
353
+ ----
354
+ tool = Ukiryu::Tool.get(:imagemagick)
355
+ tool.available? # => true
356
+ ----
357
+
358
+ ==== commands
359
+
360
+ [source,ruby]
361
+ tool.commands -> Hash, nil
362
+ ----
363
+
364
+ Get the commands defined in the active profile.
365
+
366
+ [source,ruby]
367
+ ----
368
+ tool = Ukiryu::Tool.get(:imagemagick)
369
+ tool.commands.keys # => [:convert, :identify, :mogrify]
370
+ ----
371
+
372
+ ==== command?
373
+
374
+ [source,ruby]
375
+ tool.command?(command_name) -> Boolean
376
+ ----
377
+
378
+ Check if a command is available.
379
+
380
+ [source,ruby]
381
+ ----
382
+ tool = Ukiryu::Tool.get(:imagemagick)
383
+ tool.command?(:convert) # => true
384
+ tool.command?(:nonexistent) # => false
385
+ ----
386
+
387
+ ==== command_definition
388
+
389
+ [source,ruby]
390
+ tool.command_definition(command_name) -> CommandDefinition, nil
391
+ ----
392
+
393
+ Get a command definition by name.
394
+
395
+ [source,ruby]
396
+ ----
397
+ tool = Ukiryu::Tool.get(:imagemagick)
398
+ cmd = tool.command_definition(:convert)
399
+ cmd.name # => "convert"
400
+ cmd.arguments # => [...]
401
+ ----
402
+
403
+ ==== options_for
404
+
405
+ [source,ruby]
406
+ tool.options_for(command_name) -> Class
407
+ ----
408
+
409
+ Get the options class for a command.
410
+
411
+ [source,ruby]
412
+ ----
413
+ tool = Ukiryu::Tool.get(:imagemagick)
414
+ options_class = tool.options_for(:convert)
415
+ options = options_class.new
416
+ options.inputs = ['image.jpg']
417
+ options.output = 'output.png'
418
+ ----
419
+
420
+ ==== execute
421
+
422
+ [source,ruby]
423
+ tool.execute(command_name, params = {}) -> Execution::Result
424
+ ----
425
+
426
+ Execute a command.
427
+
428
+ * **Parameters**:
429
+ * `command_name` (String, Symbol) - Command name or root-path (e.g., `'remote:add'`)
430
+ * `params` (Hash) - Command parameters
431
+ * **Returns** (Execution::Result) - Execution result
432
+ * **Raises** (ExecutionError) - If command fails (non-zero exit)
433
+
434
+ [source,ruby]
435
+ ----
436
+ # Simple command
437
+ result = tool.execute(:convert, {
438
+ inputs: ['input.jpg'],
439
+ output: 'output.png',
440
+ resize: '50%'
441
+ })
442
+
443
+ # Root-path notation for hierarchical commands
444
+ result = git_tool.execute('remote:add', {
445
+ name: 'origin',
446
+ url: 'https://github.com/user/repo.git'
447
+ })
448
+ ----
449
+
450
+ ==== execute_action
451
+
452
+ [source,ruby]
453
+ tool.execute_action(path, params = {}) -> Execution::Result
454
+ ----
455
+
456
+ Execute a routed action (for tools with routing).
457
+
458
+ * **Parameters**:
459
+ * `path` (Array<String, Symbol>) - Action path (e.g., `['remote', 'add']`)
460
+ * `params` (Hash) - Action parameters
461
+ * **Returns** (Execution::Result) - Execution result
462
+
463
+ [source,ruby]
464
+ ----
465
+ result = git_tool.execute_action(['remote', 'add'], {
466
+ name: 'origin',
467
+ url: 'https://github.com/user/repo.git'
468
+ })
469
+ ----
470
+
471
+ ==== resolve_action_path
472
+
473
+ [source,ruby]
474
+ tool.resolve_action_path(path) -> Hash, nil
475
+ ----
476
+
477
+ Resolve a hierarchical action path.
478
+
479
+ * **Parameters**:
480
+ * `path` (Array<String, Symbol>) - Action path
481
+ * **Returns** (Hash, nil) - Resolution info with `:executable`, `:action`, `:path` keys
482
+
483
+ [source,ruby]
484
+ ----
485
+ resolution = git_tool.resolve_action_path(['remote', 'add'])
486
+ # => {
487
+ # executable: 'git-remote',
488
+ # action: <CommandDefinition>,
489
+ # path: ['remote', 'add']
490
+ # }
491
+ ----
492
+
493
+ ==== routing
494
+
495
+ [source,ruby]
496
+ tool.routing -> Models::Routing, nil
497
+ ----
498
+
499
+ Get the routing table from the active profile.
500
+
501
+ [source,ruby]
502
+ ----
503
+ git_tool = Ukiryu::Tool.get(:git)
504
+ git_tool.routing # => #<Models::Routing>
505
+ ----
506
+
507
+ ==== routing?
508
+
509
+ [source,ruby]
510
+ tool.routing? -> Boolean
511
+ ----
512
+
513
+ Check if this tool has routing defined.
514
+
515
+ [source,ruby]
516
+ ----
517
+ git_tool = Ukiryu::Tool.get(:git)
518
+ git_tool.routing? # => true
519
+
520
+ convert_tool = Ukiryu::Tool.get(:imagemagick)
521
+ convert_tool.routing? # => false
522
+ ----
523
+
524
+ ==== definition_source
525
+
526
+ [source,ruby]
527
+ tool.definition_source -> Definition::Source, nil
528
+ ----
529
+
530
+ Get the definition source if loaded from non-register source.
531
+
532
+ [source,ruby]
533
+ ----
534
+ tool = Ukiryu::Tool.load('/path/to/tool.yaml')
535
+ tool.definition_source # => #<Definition::Sources::FileSource>
536
+ tool.definition_source.path # => "/path/to/tool.yaml"
537
+ tool.definition_source.mtime # => 2024-01-15 10:30:00 UTC
538
+ ----
539
+
540
+ ==== probe_flag
541
+
542
+ [source,ruby]
543
+ tool.probe_flag(flag) -> Boolean
544
+ ----
545
+
546
+ Probe for a feature flag.
547
+
548
+ * **Parameters**:
549
+ * `flag` (String) - Feature flag to probe (e.g., `'--worktree'`)
550
+ * **Returns** (Boolean) - True if the feature is supported
551
+
552
+ [source,ruby]
553
+ ----
554
+ git_tool = Ukiryu::Tool.get(:git)
555
+ git_tool.probe_flag('--worktree') # => true
556
+ git_tool.probe_flag('--nonexistent') # => false
557
+ ----
558
+
559
+ // Class: Ukiryu::Config
560
+ == Class: Ukiryu::Config
561
+
562
+ Configuration management for Ukiryu.
563
+
564
+ === Class Methods
565
+
566
+ ==== configure
567
+
568
+ [source,ruby]
569
+ Config.configure { |config| block } -> Config
570
+ ----
571
+
572
+ Configure Ukiryu with a block.
573
+
574
+ [source,ruby]
575
+ ----
576
+ Ukiryu::Config.configure do |config|
577
+ config.timeout = 120
578
+ config.debug = true
579
+ config.format = :json
580
+ config.register = '/path/to/register'
581
+ end
582
+ ----
583
+
584
+ ==== reset!
585
+
586
+ [source,ruby]
587
+ Config.reset! -> Config
588
+ ----
589
+
590
+ Reset configuration to defaults.
591
+
592
+ [source,ruby]
593
+ ----
594
+ Ukiryu::Config.reset!
595
+ ----
596
+
597
+ === Instance Methods
598
+
599
+ ==== timeout
600
+
601
+ [source,ruby]
602
+ config.timeout -> Integer, nil
603
+ config.timeout = value -> Integer
604
+ ----
605
+
606
+ Execution timeout in seconds.
607
+
608
+ [source,ruby]
609
+ ----
610
+ Ukiryu::Config.timeout = 120
611
+ Ukiryu::Config.timeout # => 120
612
+ ----
613
+
614
+ ==== debug
615
+
616
+ [source,ruby]
617
+ config.debug -> Boolean
618
+ config.debug = value -> Boolean
619
+ ----
620
+
621
+ Debug mode flag.
622
+
623
+ [source,ruby]
624
+ ----
625
+ Ukiryu::Config.debug = true
626
+ Ukiryu::Config.debug # => true
627
+ ----
628
+
629
+ ==== dry_run
630
+
631
+ [source,ruby]
632
+ config.dry_run -> Boolean
633
+ config.dry_run = value -> Boolean
634
+ ----
635
+
636
+ Dry run flag.
637
+
638
+ [source,ruby]
639
+ ----
640
+ Ukiryu::Config.dry_run = true
641
+ Ukiryu::Config.dry_run # => true
642
+ ----
643
+
644
+ ==== format
645
+
646
+ [source,ruby]
647
+ config.format -> Symbol
648
+ config.format = value -> Symbol
649
+ ----
650
+
651
+ Output format (`:yaml`, `:json`, `:table`).
652
+
653
+ [source,ruby]
654
+ ----
655
+ Ukiryu::Config.format = :json
656
+ Ukiryu::Config.format # => :json
657
+ ----
658
+
659
+ ==== output
660
+
661
+ [source,ruby]
662
+ config.output -> String, nil
663
+ config.output = value -> String
664
+ ----
665
+
666
+ Output file path.
667
+
668
+ [source,ruby]
669
+ ----
670
+ Ukiryu::Config.output = '/tmp/result.yaml'
671
+ Ukiryu::Config.output # => "/tmp/result.yaml"
672
+ ----
673
+
674
+ ==== register
675
+
676
+ [source,ruby]
677
+ config.register -> String, nil
678
+ config.register = value -> String
679
+ ----
680
+
681
+ Register path.
682
+
683
+ [source,ruby]
684
+ ----
685
+ Ukiryu::Config.register = '/opt/ukiryu/register'
686
+ Ukiryu::Config.register # => "/opt/ukiryu/register"
687
+ ----
688
+
689
+ ==== search_paths
690
+
691
+ [source,ruby]
692
+ config.search_paths -> String, nil
693
+ config.search_paths = value -> String
694
+ ----
695
+
696
+ Search paths (comma-separated).
697
+
698
+ [source,ruby]
699
+ ----
700
+ Ukiryu::Config.search_paths = '/usr/local/bin,/opt/bin'
701
+ Ukiryu::Config.search_paths # => "/usr/local/bin,/opt/bin"
702
+ ----
703
+
704
+ ==== use_color
705
+
706
+ [source,ruby]
707
+ config.use_color -> Boolean, nil
708
+ config.use_color = value -> Boolean
709
+ ----
710
+
711
+ Color usage flag.
712
+
713
+ [source,ruby]
714
+ ----
715
+ Ukiryu::Config.use_color = false
716
+ Ukiryu::Config.use_color # => false
717
+ Ukiryu::Config.colors_disabled? # => true
718
+ ----
719
+
720
+ ==== metrics
721
+
722
+ [source,ruby]
723
+ config.metrics -> Boolean
724
+ config.metrics = value -> Boolean
725
+ ----
726
+
727
+ Metrics collection flag.
728
+
729
+ [source,ruby]
730
+ ----
731
+ Ukiryu::Config.metrics = true
732
+ Ukiryu::Config.metrics # => true
733
+ ----
734
+
735
+ ==== shell
736
+
737
+ [source,ruby]
738
+ config.shell -> Symbol, nil
739
+ config.shell = value -> Symbol, String
740
+ ----
741
+
742
+ Shell for command execution.
743
+
744
+ [source,ruby]
745
+ ----
746
+ Ukiryu::Config.shell = :zsh
747
+ Ukiryu::Config.shell # => :zsh
748
+ ----
749
+
750
+ ==== to_h
751
+
752
+ [source,ruby]
753
+ config.to_h -> Hash
754
+ ----
755
+
756
+ Get configuration as hash.
757
+
758
+ [source,ruby]
759
+ ----
760
+ config = Ukiryu::Config.to_h
761
+ # => {
762
+ # timeout: 120,
763
+ # debug: true,
764
+ # dry_run: false,
765
+ # metrics: false,
766
+ # shell: :zsh,
767
+ # format: :yaml,
768
+ # output: nil,
769
+ # register: "/path/to/register",
770
+ # search_paths: "/usr/local/bin,/opt/bin",
771
+ # use_color: false
772
+ # }
773
+ ----
774
+
775
+ // Class: Ukiryu::Register
776
+ == Class: Ukiryu::Register
777
+
778
+ Tool profile register management.
779
+
780
+ === Class Methods
781
+
782
+ ==== default_register_path
783
+
784
+ [source,ruby]
785
+ Register.default_register_path -> String, nil
786
+ ----
787
+
788
+ Get the default register path.
789
+
790
+ [source,ruby]
791
+ ----
792
+ path = Ukiryu::Register.default_register_path
793
+ # => "/path/to/register"
794
+ ----
795
+
796
+ ==== default_register_path=
797
+
798
+ [source,ruby]
799
+ Register.default_register_path = path -> String
800
+ ----
801
+
802
+ Set the default register path.
803
+
804
+ [source,ruby]
805
+ ----
806
+ Ukiryu::Register.default_register_path = '/opt/ukiryu/register'
807
+ ----
808
+
809
+ ==== tools
810
+
811
+ [source,ruby]
812
+ Register.tools -> Array<String>
813
+ ----
814
+
815
+ Get list of all available tools.
816
+
817
+ [source,ruby]
818
+ ----
819
+ tools = Ukiryu::Register.tools
820
+ # => ["imagemagick", "inkscape", "ghostscript", "jq", ...]
821
+ ----
822
+
823
+ ==== load_tool_yaml
824
+
825
+ [source,ruby]
826
+ Register.load_tool_yaml(tool_name) -> String, nil
827
+ ----
828
+
829
+ Load YAML content for a tool.
830
+
831
+ * **Parameters**:
832
+ * `tool_name` (String, Symbol) - Tool name
833
+ * **Returns** (String, nil) - YAML content or nil if not found
834
+
835
+ [source,ruby]
836
+ ----
837
+ yaml = Ukiryu::Register.load_tool_yaml(:imagemagick)
838
+ ----
839
+
840
+ // Module: Ukiryu::Executor
841
+ == Module: Ukiryu::Executor
842
+
843
+ Command execution module.
844
+
845
+ === Class Methods
846
+
847
+ ==== execute
848
+
849
+ [source,ruby]
850
+ Executor.execute(executable, args = [], options = {}) -> Execution::Result
851
+ ----
852
+
853
+ Execute a command.
854
+
855
+ * **Parameters**:
856
+ * `executable` (String) - Executable path
857
+ * `args` (Array<String>) - Command arguments
858
+ * `options` (Hash) - Execution options
859
+ * `:timeout` (Integer) - Maximum execution time in seconds
860
+ * `:env` (Hash) - Environment variables
861
+ * `:cwd` (String) - Working directory
862
+ * `:shell` (Symbol) - Shell to use
863
+ * `:stdin` (String, IO) - Stdin input
864
+ * `:allow_failure` (Boolean) - Don't raise on non-zero exit
865
+ * `:tool_name` (String) - Tool name for exit code lookups
866
+ * `:command_name` (String) - Command name for exit code lookups
867
+ * **Returns** (Execution::Result) - Execution result
868
+
869
+ [source,ruby]
870
+ ----
871
+ result = Ukiryu::Executor.execute(
872
+ '/usr/local/bin/convert',
873
+ ['input.jpg', 'output.png'],
874
+ timeout: 30,
875
+ env: { 'MAGICK_MEMORY_LIMIT' => '256MB' }
876
+ )
877
+ ----
878
+
879
+ ==== find_executable
880
+
881
+ [source,ruby]
882
+ Executor.find_executable(command, options = {}) -> String, nil
883
+ ----
884
+
885
+ Find an executable in system PATH.
886
+
887
+ * **Parameters**:
888
+ * `command` (String) - Command name
889
+ * `options` (Hash) - Search options
890
+ * `:additional_paths` (Array<String>) - Additional search paths
891
+ * **Returns** (String, nil) - Full path or nil
892
+
893
+ [source,ruby]
894
+ ----
895
+ path = Ukiryu::Executor.find_executable('magick')
896
+ # => "/usr/local/bin/magick"
897
+
898
+ path = Ukiryu::Executor.find_executable('magick',
899
+ additional_paths: ['/opt/bin']
900
+ )
901
+ ----
902
+
903
+ // Module: Ukiryu::Shell
904
+ == Module: Ukiryu::Shell
905
+
906
+ Shell abstraction module.
907
+
908
+ === Class Methods
909
+
910
+ ==== detect
911
+
912
+ [source,ruby]
913
+ Shell.detect -> Symbol
914
+ ----
915
+
916
+ Auto-detect current shell.
917
+
918
+ [source,ruby]
919
+ ----
920
+ shell = Ukiryu::Shell.detect # => :bash, :zsh, :powershell, etc.
921
+ ----
922
+
923
+ ==== class_for
924
+
925
+ [source,ruby]
926
+ Shell.class_for(shell_name) -> Class
927
+ ----
928
+
929
+ Get shell implementation class.
930
+
931
+ * **Parameters**:
932
+ * `shell_name` (Symbol) - Shell name
933
+ * **Returns** (Class) - Shell class
934
+
935
+ [source,ruby]
936
+ ----
937
+ klass = Ukiryu::Shell.class_for(:bash)
938
+ # => Ukiryu::Shell::Bash
939
+ ----
940
+
941
+ ==== available_shells
942
+
943
+ [source,ruby]
944
+ Shell.available_shells -> Array<Symbol>
945
+ ----
946
+
947
+ Get list of available shells.
948
+
949
+ [source,ruby]
950
+ ----
951
+ shells = Ukiryu::Shell.available_shells
952
+ # => [:bash, :zsh, :fish, :sh, :powershell, :cmd]
953
+ ----
954
+
955
+ // Class: Ukiryu::Platform
956
+ == Class: Ukiryu::Platform
957
+
958
+ Platform detection.
959
+
960
+ === Class Methods
961
+
962
+ ==== detect
963
+
964
+ [source,ruby]
965
+ Platform.detect -> Symbol
966
+ ----
967
+
968
+ Detect current platform.
969
+
970
+ [source,ruby]
971
+ ----
972
+ platform = Ukiryu::Platform.detect
973
+ # => :macos, :linux, or :windows
974
+ ----
975
+
976
+ ==== macos?
977
+
978
+ [source,ruby]
979
+ Platform.macos? -> Boolean
980
+ ----
981
+
982
+ Check if running on macOS.
983
+
984
+ [source,ruby]
985
+ ----
986
+ Ukiryu::Platform.macos? # => true or false
987
+ ----
988
+
989
+ ==== linux?
990
+
991
+ [source,ruby]
992
+ Platform.linux? -> Boolean
993
+ ----
994
+
995
+ Check if running on Linux.
996
+
997
+ [source,ruby]
998
+ ----
999
+ Ukiryu::Platform.linux? # => true or false
1000
+ ----
1001
+
1002
+ ==== windows?
1003
+
1004
+ [source,ruby]
1005
+ Platform.windows? -> Boolean
1006
+ ----
1007
+
1008
+ Check if running on Windows.
1009
+
1010
+ [source,ruby]
1011
+ ----
1012
+ Ukiryu::Platform.windows? # => true or false
1013
+ ----
1014
+
1015
+ // Module: Ukiryu::Runtime
1016
+ == Module: Ukiryu::Runtime
1017
+
1018
+ Runtime state management.
1019
+
1020
+ === Class Methods
1021
+
1022
+ ==== instance
1023
+
1024
+ [source,ruby]
1025
+ Runtime.instance -> Runtime
1026
+ ----
1027
+
1028
+ Get the runtime instance (singleton).
1029
+
1030
+ [source,ruby]
1031
+ ----
1032
+ runtime = Ukiryu::Runtime.instance
1033
+ ----
1034
+
1035
+ === Instance Methods
1036
+
1037
+ ==== platform
1038
+
1039
+ [source,ruby]
1040
+ runtime.platform -> Symbol
1041
+ ----
1042
+
1043
+ Get current platform.
1044
+
1045
+ [source,ruby]
1046
+ ----
1047
+ platform = Ukiryu::Runtime.instance.platform # => :macos
1048
+ ----
1049
+
1050
+ ==== shell
1051
+
1052
+ [source,ruby]
1053
+ runtime.shell -> Symbol
1054
+ ----
1055
+
1056
+ Get current shell.
1057
+
1058
+ [source,ruby]
1059
+ ----
1060
+ shell = Ukiryu::Runtime.instance.shell # => :bash
1061
+ ----
1062
+
1063
+ // Class: Ukiryu::Execution::Result
1064
+ == Class: Ukiryu::Execution::Result
1065
+
1066
+ Execution result object.
1067
+
1068
+ === Attributes
1069
+
1070
+ ==== command_info
1071
+
1072
+ [source,ruby]
1073
+ result.command_info -> Execution::CommandInfo
1074
+ ----
1075
+
1076
+ Command information.
1077
+
1078
+ [source,ruby]
1079
+ ----
1080
+ info = result.command_info
1081
+ info.executable # => "/usr/local/bin/convert"
1082
+ info.arguments # => ["input.jpg", "output.png"]
1083
+ info.full_command # => "convert 'input.jpg' 'output.png'"
1084
+ info.shell # => :bash
1085
+ ----
1086
+
1087
+ ==== output
1088
+
1089
+ [source,ruby]
1090
+ result.output -> Execution::Output
1091
+ ----
1092
+
1093
+ Command output.
1094
+
1095
+ [source,ruby]
1096
+ ----
1097
+ output = result.output
1098
+ output.stdout # => "Conversion complete"
1099
+ output.stderr # => ""
1100
+ output.exit_status # => 0
1101
+ output.success? # => true
1102
+ output.failure? # => false
1103
+ output.stdout_lines # => ["Conversion complete"]
1104
+ ----
1105
+
1106
+ ==== metadata
1107
+
1108
+ [source,ruby]
1109
+ result.metadata -> Execution::ExecutionMetadata
1110
+ ----
1111
+
1112
+ Execution metadata.
1113
+
1114
+ [source,ruby]
1115
+ ----
1116
+ meta = result.metadata
1117
+ meta.started_at # => 2024-01-15 10:30:00 UTC
1118
+ meta.finished_at # => 2024-01-15 10:30:01 UTC
1119
+ meta.duration_seconds # => 1.234
1120
+ meta.formatted_duration # => "1.2s"
1121
+ ----
1122
+
1123
+ === Convenience Methods
1124
+
1125
+ ==== success?
1126
+
1127
+ [source,ruby]
1128
+ result.success? -> Boolean
1129
+ ----
1130
+
1131
+ Check if command succeeded (exit code 0).
1132
+
1133
+ [source,ruby]
1134
+ ----
1135
+ if result.success?
1136
+ puts "Success!"
1137
+ end
1138
+ ----
1139
+
1140
+ ==== failure?
1141
+
1142
+ [source,ruby]
1143
+ result.failure? -> Boolean
1144
+ ----
1145
+
1146
+ Check if command failed (non-zero exit).
1147
+
1148
+ [source,ruby]
1149
+ ----
1150
+ if result.failure?
1151
+ puts "Failed!"
1152
+ end
1153
+ ----
1154
+
1155
+ ==== stdout
1156
+
1157
+ [source,ruby]
1158
+ result.stdout -> String
1159
+ ----
1160
+
1161
+ Get stdout (stripped).
1162
+
1163
+ [source,ruby]
1164
+ ----
1165
+ puts result.stdout
1166
+ ----
1167
+
1168
+ ==== stderr
1169
+
1170
+ [source,ruby]
1171
+ result.stderr -> String
1172
+ ----
1173
+
1174
+ Get stderr (stripped).
1175
+
1176
+ [source,ruby]
1177
+ ----
1178
+ puts result.stderr
1179
+ ----
1180
+
1181
+ ==== stdout_lines
1182
+
1183
+ [source,ruby]
1184
+ result.stdout_lines -> Array<String>
1185
+ ----
1186
+
1187
+ Get stdout as array of lines.
1188
+
1189
+ [source,ruby]
1190
+ ----
1191
+ result.stdout_lines.each do |line|
1192
+ puts line
1193
+ end
1194
+ ----
1195
+
1196
+ ==== stderr_lines
1197
+
1198
+ [source,ruby]
1199
+ result.stderr_lines -> Array<String>
1200
+ ----
1201
+
1202
+ Get stderr as array of lines.
1203
+
1204
+ [source,ruby]
1205
+ ----
1206
+ result.stderr_lines.each do |line|
1207
+ warn line
1208
+ end
1209
+ ----
1210
+
1211
+ // See Also
1212
+ == See Also
1213
+
1214
+ * link:/interfaces/ruby-api[Ruby API Guide] - Usage guide and examples
1215
+ * link:/reference/error-codes[Error Codes] - Error handling
1216
+ * link:/reference/configuration-options[Configuration Options] - All configuration methods
1217
+ * link:/reference/tool-profile-schema[Tool Profile Schema] - YAML definition reference