legionio 1.4.115 → 1.4.117

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abcb24b9f1dbcec868c68b5b66d203405896b38487f4197f352f2ad69e96b2b4
4
- data.tar.gz: 9a684aa568b3d19fcc9e19c186a4d2a9efdc7d5001776cceae9d33d9aa0cc7dd
3
+ metadata.gz: d03cb4a8c6be7dd7d726f3999ebf88826914163aa9c59ac3a7206f7975616892
4
+ data.tar.gz: 1002f6425389c201d397f07163ccc40101880d0f9dadce0fb4c4159078b531cb
5
5
  SHA512:
6
- metadata.gz: 41610c2dec55f16656d15356ffc29c7d0f76020623e662fa47dbd54ed67038962a02b1f4dfadfa9a3057d6fd3d124a24dc476f95ae14e3f5cb7510f71283fcbc
7
- data.tar.gz: 2cfbdefeb8d689545a5fb62b47255dcae967cc83087feaf950bc0169aedce32b5c89c24e7f9dc951d74c43b2ac45cd49e0100740dffd786d447dc2c11f71a94d
6
+ metadata.gz: 3f1679456170344d1ea966e7b08f5ba518f2f1957030b1cfa18c614516502bab2848861fd2c698f86ef72889cf4f79882ee1cafbf65a4bf8f3b00b23e8fb517c
7
+ data.tar.gz: 72c3d056636a57c41244a9483824d6eaa448feb3b970bff31dc79741ba884e89045d4cec22b32e716d350bdbbd72b67465d09ca91aade426c8b9596f7fb12e92
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Legion Changelog
2
2
 
3
+ ## [1.4.117] - 2026-03-22
4
+
5
+ ### Added
6
+ - `Legion::CLI::Error` gains `suggestions`, `code` attributes and `.actionable` factory method
7
+ - `Legion::CLI::ErrorHandler` module: 6-pattern matcher maps common exceptions (RabbitMQ, DB, extensions, permissions, data, Vault) to actionable errors with fix suggestions
8
+ - `ErrorHandler.wrap` wraps any `StandardError` into a `CLI::Error` with suggestions when a pattern matches
9
+ - `ErrorHandler.format_error` prints suggestions below the error line when the error is actionable
10
+ - `Legion::CLI::Main.start` overrides Thor's entry point to wrap unhandled exceptions through `ErrorHandler` before exiting
11
+
12
+ ## [1.4.116] - 2026-03-22
13
+
14
+ ### Added
15
+ - `legion detect scan --format sarif|markdown|json` option for CI-friendly output formats
16
+
17
+ ## [1.4.115] - 2026-03-22
18
+
19
+ ### Changed
20
+ - Extension parallel pool size now reads from `Legion::Settings[:extensions][:parallel_pool_size]` (default: 24) instead of hardcoded 4
21
+ - Significantly faster boot with many extensions: all load concurrently instead of in batches of 4
22
+
3
23
  ## [1.4.114] - 2026-03-22
4
24
 
5
25
  ### Changed
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
  require 'thor'
4
5
  require 'legion/cli/output'
5
6
 
@@ -20,13 +21,17 @@ module Legion
20
21
  desc 'scan', 'Scan environment and recommend extensions (default)'
21
22
  option :install, type: :boolean, default: false, desc: 'Install missing extensions after scan'
22
23
  option :dry_run, type: :boolean, default: false, desc: 'Show what would be installed without installing'
24
+ option :format, type: :string, enum: %w[sarif markdown json], desc: 'Output format (sarif, markdown, json)'
23
25
  def scan
24
26
  out = formatter
25
27
  require_detect_gem
26
28
 
27
29
  results = Legion::Extensions::Detect.scan
28
30
 
29
- if options[:json]
31
+ if options[:format]
32
+ output = Legion::Extensions::Detect.format_results(format: options[:format], detections: results)
33
+ puts output.is_a?(String) ? output : ::JSON.pretty_generate(output)
34
+ elsif options[:json]
30
35
  out.json(detections: results)
31
36
  else
32
37
  display_detections(out, results)
@@ -2,6 +2,19 @@
2
2
 
3
3
  module Legion
4
4
  module CLI
5
- class Error < StandardError; end
5
+ class Error < StandardError
6
+ attr_reader :suggestions, :code
7
+
8
+ def self.actionable(code:, message:, suggestions: [])
9
+ err = new(message)
10
+ err.instance_variable_set(:@code, code)
11
+ err.instance_variable_set(:@suggestions, suggestions)
12
+ err
13
+ end
14
+
15
+ def actionable?
16
+ !suggestions.nil? && !suggestions.empty?
17
+ end
18
+ end
6
19
  end
7
20
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module CLI
5
+ module ErrorHandler
6
+ PATTERNS = [
7
+ {
8
+ match: /connection refused.*5672|ECONNREFUSED.*5672|bunny.*not connected/i,
9
+ code: :transport_unavailable,
10
+ message: 'Cannot connect to RabbitMQ',
11
+ suggestions: [
12
+ "Run 'legion doctor' to diagnose connectivity",
13
+ "Check transport settings: 'legion config show -s transport'",
14
+ 'Verify RabbitMQ is running: brew services list | grep rabbitmq'
15
+ ]
16
+ },
17
+ {
18
+ match: /table.*not.*found|no such table|PG::UndefinedTable|Sequel::DatabaseError.*exist/i,
19
+ code: :database_missing,
20
+ message: 'Database table not found',
21
+ suggestions: [
22
+ "Run 'legion start' to apply pending migrations",
23
+ "Check database config: 'legion config show -s data'",
24
+ "Verify database is running: 'legion doctor'"
25
+ ]
26
+ },
27
+ {
28
+ match: /extension.*not.*found|no such extension|uninitialized constant.*Extensions/i,
29
+ code: :extension_missing,
30
+ message: 'Extension not found',
31
+ suggestions: [
32
+ "Search available extensions: 'legion marketplace search <name>'",
33
+ 'Install with: gem install lex-<name>',
34
+ "List installed: 'legion lex list'"
35
+ ]
36
+ },
37
+ {
38
+ match: /permission denied|EACCES/i,
39
+ code: :permission_denied,
40
+ message: 'Permission denied',
41
+ suggestions: [
42
+ 'Try running with sudo for system directories',
43
+ 'Set custom config dir: LEGIONIO_CONFIG_DIR=~/.legionio',
44
+ 'Check file permissions: ls -la ~/.legionio/'
45
+ ]
46
+ },
47
+ {
48
+ match: /legion-data.*not.*connected|data.*not.*available/i,
49
+ code: :data_unavailable,
50
+ message: 'Database not connected',
51
+ suggestions: [
52
+ "Check database config: 'legion config show -s data'",
53
+ "Run diagnostics: 'legion doctor'",
54
+ 'Some commands work without a database — try adding --no-data flag'
55
+ ]
56
+ },
57
+ {
58
+ match: /vault.*not.*connected|vault.*sealed|VAULT_ADDR/i,
59
+ code: :vault_unavailable,
60
+ message: 'Vault not connected',
61
+ suggestions: [
62
+ "Check Vault config: 'legion config show -s crypt'",
63
+ 'Verify VAULT_ADDR and VAULT_TOKEN environment variables',
64
+ "Run diagnostics: 'legion doctor'"
65
+ ]
66
+ }
67
+ ].freeze
68
+
69
+ module_function
70
+
71
+ def wrap(error)
72
+ pattern = PATTERNS.find { |p| error.message.match?(p[:match]) }
73
+ return error unless pattern
74
+
75
+ Error.actionable(
76
+ code: pattern[:code],
77
+ message: "#{pattern[:message]}: #{error.message}",
78
+ suggestions: pattern[:suggestions]
79
+ )
80
+ end
81
+
82
+ def format_error(error, formatter)
83
+ formatter.error(error.message)
84
+ return unless error.is_a?(Error) && error.actionable?
85
+
86
+ error.suggestions.each do |suggestion|
87
+ puts " #{formatter.colorize('>', :label)} #{suggestion}"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/legion/cli.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'thor'
4
4
  require 'legion/version'
5
5
  require 'legion/cli/error'
6
+ require 'legion/cli/error_handler'
6
7
  require 'legion/cli/output'
7
8
  require 'legion/cli/connection'
8
9
 
@@ -61,6 +62,19 @@ module Legion
61
62
  true
62
63
  end
63
64
 
65
+ def self.start(given_args = ARGV, config = {})
66
+ super
67
+ rescue Legion::CLI::Error => e
68
+ formatter = Output::Formatter.new(json: given_args.include?('--json'), color: !given_args.include?('--no-color'))
69
+ ErrorHandler.format_error(e, formatter)
70
+ exit(1)
71
+ rescue StandardError => e
72
+ wrapped = ErrorHandler.wrap(e)
73
+ formatter = Output::Formatter.new(json: given_args.include?('--json'), color: !given_args.include?('--no-color'))
74
+ ErrorHandler.format_error(wrapped, formatter)
75
+ exit(1)
76
+ end
77
+
64
78
  class_option :json, type: :boolean, default: false, desc: 'Output as JSON'
65
79
  class_option :no_color, type: :boolean, default: false, desc: 'Disable color output'
66
80
  class_option :verbose, type: :boolean, default: false, aliases: ['-V'], desc: 'Verbose logging'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Legion
4
- VERSION = '1.4.115'
4
+ VERSION = '1.4.117'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legionio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.115
4
+ version: 1.4.117
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -498,6 +498,7 @@ files:
498
498
  - lib/legion/cli/doctor/vault_check.rb
499
499
  - lib/legion/cli/doctor_command.rb
500
500
  - lib/legion/cli/error.rb
501
+ - lib/legion/cli/error_handler.rb
501
502
  - lib/legion/cli/eval_command.rb
502
503
  - lib/legion/cli/failover_command.rb
503
504
  - lib/legion/cli/function.rb