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,20 @@
1
+ ---
2
+ layout: default
3
+ title: Understanding
4
+ nav_order: 5
5
+ has_children: true
6
+ ---
7
+
8
+ = Understanding
9
+
10
+ Deep dive into Ukiryu's architecture, design decisions, and internal mechanisms.
11
+
12
+ // Overview
13
+ == Overview
14
+
15
+ This section covers the technical internals of Ukiryu:
16
+
17
+ * link:/understanding/architecture[Architecture] - System design and components
18
+ * link:/understanding/register[Register] - Profile loading and caching
19
+ * link:/understanding/shell-layer[Shell Layer] - Platform and shell adaptation
20
+ * link:/understanding/command-builder[Command Builder] - Argument construction
data/lib/ukiryu/cli.rb CHANGED
@@ -15,6 +15,10 @@ require_relative 'cli_commands/version_command'
15
15
  require_relative 'cli_commands/system_command'
16
16
  require_relative 'cli_commands/validate_command'
17
17
  require_relative 'cli_commands/extract_command'
18
+ require_relative 'cli_commands/definitions_command'
19
+ require_relative 'cli_commands/cache_command'
20
+ require_relative 'cli_commands/resolve_command'
21
+ require_relative 'cli_commands/register_command'
18
22
  require_relative 'thor_ext'
19
23
  require_relative 'version'
20
24
 
@@ -29,74 +33,77 @@ module Ukiryu
29
33
  # Extend FriendlyCLI for better Thor behavior
30
34
  extend FriendlyCLI
31
35
 
32
- # Set default registry path if not configured
36
+ # Set default register path if not configured
33
37
  def self.exit_on_failure?
34
38
  false
35
39
  end
36
40
 
37
41
  desc 'run-file REQUEST_FILE', 'Execute a Ukiryu Structured Execution Request from a YAML file'
38
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
42
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
39
43
  method_option :output, aliases: :o, desc: 'Output file for response (default: stdout)', type: :string
40
44
  method_option :format, aliases: :f, desc: 'Response format (yaml, json, table, raw)', type: :string, default: 'yaml'
41
45
  method_option :dry_run, aliases: :d, desc: 'Show execution request without executing', type: :boolean,
42
46
  default: false
43
- method_option :shell, desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)', type: :string
47
+ method_option :shell, desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)',
48
+ type: :string
44
49
  def run_file(request_file)
45
50
  CliCommands::RunFileCommand.new(options).run(request_file)
46
51
  end
47
52
 
48
53
  desc 'exec TOOL [COMMAND] [KEY=VALUE ...]', 'Execute a tool command inline'
49
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
54
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
55
+ method_option :definition, aliases: :d, desc: 'Path to tool definition file', type: :string
50
56
  method_option :format, aliases: :f, desc: 'Response format (yaml, json, table, raw)', type: :string, default: 'yaml'
51
57
  method_option :output, aliases: :o, desc: 'Output file for response (default: stdout)', type: :string
52
- method_option :dry_run, aliases: :d, desc: 'Show execution request without executing', type: :boolean,
58
+ method_option :dry_run, aliases: :D, desc: 'Show execution request without executing', type: :boolean,
53
59
  default: false
54
- method_option :shell, desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)', type: :string
60
+ method_option :shell, aliases: :s,
61
+ desc: 'Shell to use for command execution (bash, zsh, fish, sh, powershell, cmd)', type: :string
55
62
  method_option :stdin, desc: 'Read input from stdin (pass to command)', type: :boolean, default: false
56
63
  method_option :raw, desc: 'Output raw stdout/stderr (for pipe composition)', type: :boolean, default: false
57
64
  def exec(tool_name, command_name = nil, *params)
58
65
  CliCommands::RunCommand.new(options).run(tool_name, command_name, *params)
59
66
  end
60
67
 
61
- desc 'list', 'List all available tools in the registry'
62
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
68
+ desc 'list', 'List all available tools in the register'
69
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
63
70
  def list
64
71
  CliCommands::ListCommand.new(options).run
65
72
  end
66
73
 
67
- desc 'info [TOOL]', 'Show detailed information about a tool (or general info if no tool specified)'
68
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
74
+ desc 'info [TOOL]', 'Show detailed information about a tool'
75
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
69
76
  method_option :all, desc: 'Show all implementations for interfaces', type: :boolean, default: false
70
77
  def info(tool_name = nil)
71
78
  if tool_name.nil?
72
- # Show general info when no tool specified
73
- show_general_info
79
+ # No tool specified - show help
80
+ help
74
81
  else
75
82
  CliCommands::InfoCommand.new(options).run(tool_name)
76
83
  end
77
84
  end
78
85
 
79
86
  desc 'commands TOOL', 'List all commands available for a tool'
80
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
87
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
81
88
  def commands(tool_name)
82
89
  CliCommands::CommandsCommand.new(options).run(tool_name)
83
90
  end
84
91
 
85
92
  desc 'opts TOOL [COMMAND]', 'Show options for a tool or specific command'
86
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
93
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
87
94
  def opts(tool_name, command_name = nil)
88
95
  CliCommands::OptsCommand.new(options).run(tool_name, command_name)
89
96
  end
90
97
 
91
98
  desc 'describe TOOL [COMMAND]', 'Show comprehensive documentation for a tool or specific command'
92
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
99
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
93
100
  method_option :format, aliases: :f, desc: 'Output format (text, yaml, json)', type: :string, default: 'text'
94
101
  def describe(tool_name, command_name = nil)
95
102
  CliCommands::DescribeCommand.new(options).run(tool_name, command_name)
96
103
  end
97
104
 
98
105
  desc 'system [SUBCOMMAND]', 'Show system information (shells, etc.)'
99
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
106
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
100
107
  def system(subcommand = nil)
101
108
  CliCommands::SystemCommand.new(options).run(subcommand)
102
109
  end
@@ -107,7 +114,7 @@ module Ukiryu
107
114
  end
108
115
 
109
116
  desc 'which IDENTIFIER', 'Show which tool implementation would be selected'
110
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
117
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
111
118
  method_option :platform, desc: 'Platform to check (macos, linux, windows)', type: :string
112
119
  method_option :shell, desc: 'Shell to check (bash, zsh, fish, sh, powershell, cmd)', type: :string
113
120
  def which(identifier)
@@ -115,16 +122,13 @@ module Ukiryu
115
122
  end
116
123
 
117
124
  desc 'config [ACTION] [KEY] [VALUE]', 'Manage configuration (list, get, set, unset)'
118
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
125
+ method_option :register, aliases: :r, desc: 'Path to tool register', type: :string
119
126
  def config(action = 'list', key = nil, value = nil)
120
127
  CliCommands::ConfigCommand.new(options).run(action, key, value)
121
128
  end
122
129
 
123
- desc 'validate [TOOL]', 'Validate tool profile(s) against schema'
124
- method_option :registry, aliases: :r, desc: 'Path to tool registry', type: :string
125
- def validate(tool_name = nil)
126
- CliCommands::ValidateCommand.new(options).run(tool_name)
127
- end
130
+ desc 'validate [COMMAND]', 'Validate tool definitions'
131
+ subcommand 'validate', CliCommands::ValidateCommand
128
132
 
129
133
  desc 'extract TOOL', 'Extract tool definition from an installed CLI tool'
130
134
  method_option :output, aliases: :o, desc: 'Output file for extracted definition', type: :string
@@ -134,41 +138,22 @@ module Ukiryu
134
138
  CliCommands::ExtractCommand.new(options).run(tool_name)
135
139
  end
136
140
 
137
- private
138
-
139
- # Show general information when no specific tool is requested
140
- def show_general_info
141
- require_relative 'shell'
142
- require_relative 'runtime'
143
- require_relative 'platform'
144
-
145
- puts "Ukiryu v#{VERSION}"
146
- puts ''
147
- puts 'System Information:'
148
- puts " Platform: #{Platform.detect}"
149
- puts " Shell: #{Runtime.instance.shell}"
150
- puts " Ruby: #{RUBY_VERSION}"
151
- puts ''
152
- puts 'Available Shells:'
153
- Shell.available_shells.each do |shell|
154
- puts " - #{shell}"
155
- end
156
- puts ''
157
- puts 'Available Commands:'
158
- puts ' list - List all available tools'
159
- puts ' info TOOL - Show detailed information about a tool'
160
- puts ' which IDENTIFIER - Show which tool implementation would be selected'
161
- puts ' commands TOOL - List all commands available for a tool'
162
- puts ' opts TOOL [COMMAND] - Show options for a tool or specific command'
163
- puts ' describe TOOL [COMMAND] - Show comprehensive documentation'
164
- puts ' config [ACTION] - Manage configuration (list, get, set, unset)'
165
- puts ' system [shells] - Show system information (shells, etc.)'
166
- puts ' exec ... - Execute a tool command inline'
167
- puts ' run-file ... - Execute from a YAML file'
168
- puts ' version - Show Ukiryu version'
169
- puts ''
170
- puts 'For more information on a specific command:'
171
- puts ' ukiryu help COMMAND'
141
+ desc 'definitions [COMMAND]', 'Manage tool definitions'
142
+ subcommand 'definitions', CliCommands::DefinitionsCommand
143
+
144
+ desc 'cache [ACTION]', 'Manage definition cache'
145
+ subcommand 'cache', CliCommands::CacheCommand
146
+
147
+ desc 'resolve TOOL [VERSION]', 'Resolve which definition would be used for a tool'
148
+ def resolve(tool_name, version_constraint = nil)
149
+ CliCommands::ResolveCommand.new(options).run(tool_name, version_constraint)
150
+ end
151
+
152
+ desc 'register [SUBCOMMAND]', 'Manage the tool register'
153
+ method_option :force, aliases: :f, desc: 'Force re-clone the register', type: :boolean, default: false
154
+ method_option :verbose, aliases: :v, desc: 'Show verbose output', type: :boolean, default: false
155
+ def register(subcommand = nil)
156
+ CliCommands::RegisterCommand.new(options).run(subcommand, options)
172
157
  end
173
158
  end
174
159
  end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../config'
4
+ require_relative '../register'
4
5
 
5
6
  module Ukiryu
6
7
  module CliCommands
7
8
  # Base class for CLI commands
8
9
  #
9
10
  # Provides shared functionality for all CLI commands including
10
- # registry setup, output formatting, and error handling.
11
+ # register setup, output formatting, and error handling.
11
12
  #
12
13
  # @abstract Subclasses must implement the `run` method
13
14
  class BaseCommand
@@ -31,14 +32,14 @@ module Ukiryu
31
32
  raise NotImplementedError, "#{self.class} must implement #run"
32
33
  end
33
34
 
34
- # Setup the registry path
35
+ # Setup the register path
35
36
  #
36
- # @param custom_path [String, nil] custom registry path
37
- def setup_registry(custom_path = nil)
38
- registry_path = custom_path || config.registry || default_registry_path
39
- return unless registry_path && Dir.exist?(registry_path)
37
+ # @param custom_path [String, nil] custom register path
38
+ def setup_register(custom_path = nil)
39
+ register_path = custom_path || config.register || default_register_path
40
+ return unless register_path && Dir.exist?(register_path)
40
41
 
41
- Registry.default_registry_path = registry_path
42
+ Register.default_register_path = register_path
42
43
  end
43
44
 
44
45
  # Apply CLI options to the Config instance
@@ -49,7 +50,7 @@ module Ukiryu
49
50
  cli_mappings = {
50
51
  format: 'yaml', # default format in Thor
51
52
  output: nil,
52
- registry: nil,
53
+ register: nil,
53
54
  timeout: nil,
54
55
  shell: nil
55
56
  }
@@ -80,26 +81,14 @@ module Ukiryu
80
81
  config.set_cli_option(:dry_run, options[:dry_run])
81
82
  end
82
83
 
83
- # Get the default registry path
84
+ # Get the default register path
84
85
  #
85
- # @return [String, nil] the default registry path
86
- def default_registry_path
87
- # Try multiple approaches to find the registry
88
- # Note: ENV and Config.registry are already checked by setup_registry
89
-
90
- # 1. Try relative to gem location
91
- gem_root = File.dirname(File.dirname(File.dirname(__FILE__)))
92
- registry_path = File.join(gem_root, '..', 'register')
93
- return File.expand_path(registry_path) if Dir.exist?(registry_path)
94
-
95
- # 2. Try from current directory (development setup)
96
- current = File.expand_path('../register', Dir.pwd)
97
- return current if Dir.exist?(current)
98
-
99
- # 3. Try from parent directory
100
- parent = File.expand_path('../../register', Dir.pwd)
101
- return parent if Dir.exist?(parent)
102
-
86
+ # @return [String, nil] the default register path from RegisterAutoManager
87
+ def default_register_path
88
+ # Use RegisterAutoManager to find or create the register
89
+ require_relative '../register_auto_manager'
90
+ RegisterAutoManager.register_path
91
+ rescue StandardError
103
92
  nil
104
93
  end
105
94
 
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+ require_relative '../definition/definition_cache'
5
+
6
+ module Ukiryu
7
+ module CliCommands
8
+ # Manage definition cache
9
+ #
10
+ # The cache command allows users to view and manage the definition cache.
11
+ class CacheCommand < Thor
12
+ class_option :verbose, type: :boolean, default: false
13
+ class_option :dry_run, type: :boolean, default: false
14
+
15
+ desc 'info', 'Show cache information'
16
+ def info
17
+ show_cache_info
18
+ end
19
+
20
+ desc 'stats', 'Show detailed cache statistics'
21
+ def stats
22
+ show_cache_stats
23
+ end
24
+
25
+ desc 'clear', 'Clear all cached definitions'
26
+ def clear
27
+ clear_cache
28
+ end
29
+
30
+ private
31
+
32
+ # Show cache information
33
+ def show_cache_info
34
+ cache = Ukiryu::Definition::DefinitionCache.instance
35
+ stats = cache.stats
36
+
37
+ say 'Definition Cache:', :cyan
38
+ say '', :clear
39
+
40
+ say "Status: #{stats[:size].positive? ? 'Active' : 'Empty'}", stats[:size].positive? ? :green : :dim
41
+ say "Entries: #{stats[:size]}", :white
42
+ say "TTL: #{stats[:ttl]} seconds", :white
43
+ say "Refresh Strategy: #{stats[:refresh_strategy]}", :white
44
+
45
+ return unless stats[:entries] && !stats[:entries].empty?
46
+
47
+ say '', :clear
48
+ say 'Cached Definitions:', :white
49
+ stats[:entries].each do |key|
50
+ say " - #{key}", :dim
51
+ end
52
+ end
53
+
54
+ # Clear the cache
55
+ def clear_cache
56
+ cache = Ukiryu::Definition::DefinitionCache.instance
57
+
58
+ if options[:dry_run]
59
+ say 'Dry run: Would clear cache', :cyan
60
+ count = cache.stats[:size]
61
+ say "Entries to be cleared: #{count}", :white
62
+ return
63
+ end
64
+
65
+ count = cache.clear
66
+
67
+ say "✓ Cache cleared (#{count} entries)", :green
68
+ end
69
+
70
+ # Show cache statistics
71
+ def show_cache_stats
72
+ cache = Ukiryu::Definition::DefinitionCache.instance
73
+ stats = cache.stats
74
+
75
+ say 'Cache Statistics:', :cyan
76
+ say '', :clear
77
+
78
+ say "Total Entries: #{stats[:size]}", :white
79
+ say "TTL: #{stats[:ttl]} seconds (#{(stats[:ttl] / 60).round(1)} minutes)", :white
80
+ say "Refresh Strategy: #{stats[:refresh_strategy]}", :white
81
+ say '', :clear
82
+
83
+ return unless stats[:entries] && !stats[:entries].empty?
84
+
85
+ say 'Cached Keys:', :white
86
+ stats[:entries].each do |key|
87
+ entry = cache.get(key)
88
+ if entry
89
+ age = Time.now - entry.loaded_at
90
+ stale = entry.stale? ? ' (stale)' : ''
91
+ say " - #{key}#{stale}", :white
92
+ say " Age: #{age.round}s", :dim
93
+ else
94
+ say " - #{key} (empty)", :dim
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -11,11 +11,11 @@ module Ukiryu
11
11
  #
12
12
  # @param tool_name [String] the tool name
13
13
  def run(tool_name)
14
- setup_registry
14
+ setup_register
15
15
 
16
16
  # Use find_by for interface-based discovery (ping -> ping_bsd/ping_gnu)
17
17
  tool = Tool.find_by(tool_name.to_sym)
18
- error!("Tool not found: #{tool_name}\nAvailable tools: #{Registry.tools.sort.join(', ')}") unless tool
18
+ error!("Tool not found: #{tool_name}\nAvailable tools: #{Register.tools.sort.join(', ')}") unless tool
19
19
 
20
20
  tool_commands = tool.commands
21
21
  error! "No commands defined for #{tool_name}" unless tool_commands
@@ -73,9 +73,9 @@ module Ukiryu
73
73
  end
74
74
 
75
75
  # Show cli_flag if this is a flag-based action
76
- if cmd.flag_action?
77
- say " Action flag: #{cmd.cli_flag}", :dim
78
- end
76
+ return unless cmd.flag_action?
77
+
78
+ say " Action flag: #{cmd.cli_flag}", :dim
79
79
  end
80
80
 
81
81
  # Display hierarchical commands with routing information
@@ -86,8 +86,8 @@ module Ukiryu
86
86
  def display_hierarchical_commands(tool, grouped)
87
87
  # Show routing table first
88
88
  if tool.routing?
89
- say " Routing table:", :dim
90
- tool.routing.keys.each do |key|
89
+ say ' Routing table:', :dim
90
+ tool.routing.each_key do |key|
91
91
  target = tool.routing.resolve(key)
92
92
  say " #{key} => #{target}", :dim
93
93
  end
@@ -96,7 +96,7 @@ module Ukiryu
96
96
 
97
97
  # Show top-level commands (no belongs_to)
98
98
  if grouped.key?(nil) && !grouped[nil].empty?
99
- say " Top-level commands:", :cyan
99
+ say ' Top-level commands:', :cyan
100
100
  grouped[nil].each do |cmd|
101
101
  display_command(cmd)
102
102
  end
@@ -11,7 +11,7 @@ module Ukiryu
11
11
  #
12
12
  # @param tool_name [String] the tool name
13
13
  def run(tool_name)
14
- setup_registry
14
+ setup_register
15
15
 
16
16
  tool = Tool.get(tool_name)
17
17
  tool_commands = tool.commands
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'base_command'
4
4
  require_relative '../config'
5
+ require_relative '../register_auto_manager'
5
6
  require 'yaml'
6
7
  require 'fileutils'
7
8
 
@@ -18,7 +19,7 @@ module Ukiryu
18
19
  # @param key [String, nil] the config key
19
20
  # @param value [String, nil] the config value
20
21
  def run(action = 'list', key = nil, value = nil)
21
- setup_registry
22
+ setup_register
22
23
 
23
24
  case action
24
25
  when 'list'
@@ -41,8 +42,11 @@ module Ukiryu
41
42
  say 'Current configuration:', :cyan
42
43
  say '', :clear
43
44
 
45
+ # Get actual register info for better display
46
+ register_display = format_register_display
47
+
44
48
  config_data = {
45
- 'Registry' => config.registry || '(not set)',
49
+ 'Register' => register_display,
46
50
  'Timeout' => format_config_value(config.timeout, '(no timeout)'),
47
51
  'Debug' => format_config_value(config.debug),
48
52
  'Dry run' => format_config_value(config.dry_run),
@@ -51,7 +55,7 @@ module Ukiryu
51
55
  'Format' => format_config_value(config.format),
52
56
  'Output' => format_config_value(config.output, '(stdout)'),
53
57
  'Search paths' => format_config_value(config.search_paths, '(not set)'),
54
- 'Use color' => format_config_value(config.use_color, '(auto-detect)')
58
+ 'Use color' => format_config_value(config.use_color)
55
59
  }
56
60
 
57
61
  config_data.each do |k, v|
@@ -82,7 +86,7 @@ module Ukiryu
82
86
  say '', :clear
83
87
  say 'Environment variables:', :cyan
84
88
  env_vars = {
85
- 'UKIRYU_REGISTRY' => ENV['UKIRYU_REGISTRY'],
89
+ 'UKIRYU_REGISTER' => ENV['UKIRYU_REGISTER'],
86
90
  'UKIRYU_TIMEOUT' => ENV['UKIRYU_TIMEOUT'],
87
91
  'UKIRYU_DEBUG' => ENV['UKIRYU_DEBUG'],
88
92
  'UKIRYU_DRY_RUN' => ENV['UKIRYU_DRY_RUN'],
@@ -111,7 +115,7 @@ module Ukiryu
111
115
  normalized_key = normalize_key(key)
112
116
 
113
117
  value = case normalized_key
114
- when :registry then config.registry
118
+ when :register then config.register
115
119
  when :timeout then config.timeout
116
120
  when :debug then config.debug
117
121
  when :dry_run then config.dry_run
@@ -122,7 +126,7 @@ module Ukiryu
122
126
  when :search_paths then config.search_paths
123
127
  when :use_color then config.use_color
124
128
  else
125
- error! "Unknown config key: #{key}\nValid keys: registry, timeout, debug, dry_run, metrics, shell, format, output, search_paths, use_color"
129
+ error! "Unknown config key: #{key}\nValid keys: register, timeout, debug, dry_run, metrics, shell, format, output, search_paths, use_color"
126
130
  end
127
131
 
128
132
  say "#{key}: #{format_config_value(value, '(not set)')}", :white
@@ -206,7 +210,7 @@ module Ukiryu
206
210
  when :shell then config.shell = value
207
211
  when :format then config.format = value
208
212
  when :output then config.output = value
209
- when :registry then config.registry = value
213
+ when :register then config.register = value
210
214
  when :search_paths then config.search_paths = value
211
215
  when :use_color then config.use_color = value
212
216
  end
@@ -221,6 +225,44 @@ module Ukiryu
221
225
  value.nil? ? default : value
222
226
  end
223
227
 
228
+ # Format register display showing actual register being used
229
+ #
230
+ # @return [String] formatted register display
231
+ def format_register_display
232
+ info = RegisterAutoManager.register_info
233
+
234
+ case info[:status]
235
+ when :ok
236
+ # Register exists and is valid
237
+ source_label = format_source_label(info[:source])
238
+ tools_count = info[:tools_count] ? " (#{info[:tools_count]} tools)" : ''
239
+ "#{info[:path]} [#{source_label}]#{tools_count}"
240
+ when :not_cloned, :not_found
241
+ # Register not cloned yet
242
+ '~/.ukiryu/register (not found - run: ukiryu register update)'
243
+ when :invalid
244
+ # Register exists but is invalid
245
+ "#{info[:path]} (invalid - run: ukiryu register update --force)"
246
+ else
247
+ '(unknown)'
248
+ end
249
+ end
250
+
251
+ # Format source label for display
252
+ #
253
+ # @param source [Symbol] the source symbol
254
+ # @return [String] formatted source label
255
+ def format_source_label(source)
256
+ case source
257
+ when :env
258
+ 'env'
259
+ when :user
260
+ 'user'
261
+ else
262
+ source.to_s
263
+ end
264
+ end
265
+
224
266
  # Ensure config directory exists
225
267
  def ensure_config_dir
226
268
  FileUtils.mkdir_p(CONFIG_DIR) unless Dir.exist?(CONFIG_DIR)