lex-detect 0.1.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac8b336bd2c34b58a559c0f4b664c728b2c61991d9f88f4a4bc83014ff5fe45f
4
- data.tar.gz: 8d6b78909cf1e3c405f6251099f686882bab688496a66588681ad6646e7b2455
3
+ metadata.gz: 119e238ddb0711af3bb4d23c5c65bb85c910420aa4ce79c1fe28c81950a38d0c
4
+ data.tar.gz: da4f50f6e3b1653c18d70617ab81630f3f9db6aa01cf6271205882f34df312f6
5
5
  SHA512:
6
- metadata.gz: e0f94a3e7c7f3ab15a9f27c5646423d98a9c275c203911a8c6d3a44c1c17830c3de2cd1cad4e5d769e5d1662ab54e03daedfb3f885cd579d47ab62ef67c83031
7
- data.tar.gz: ac6498c5166dc7cbf6b077be7476b8911c979fe3eb911703840bb87f7944f35a5262581d6918ba4a142c98d37f4373816ac0eb68e7dae9b114f82979e4dd6afe
6
+ metadata.gz: 1f38552069181a4198433a821b64744f6bdf4cd42be0285c22eccfb4ef219f09f5d5d8a5825ac53c95ded7adb45278d5ca9ef20018c96f2dcac1ad61389da296
7
+ data.tar.gz: ecb32f15376b6079a1810c161a726f447e1aa6b07a3a187d894fe6393b31d608cc4c0a09227d52aefe88110e6f51ff3f3d9ba1e9e61772463587557600142896
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.3] - 2026-03-20
4
+
5
+ ### Added
6
+ - `Runners::TaskObserver` for monitoring task failure patterns
7
+ - `check_and_publish_failure_patterns` publishes failure pattern events to AMQP for self-healing pipeline integration
8
+ - `extract_gem_name` helper derives gem name from runner class string
9
+ - `build_failure_pattern` creates structured failure pattern hash
10
+
3
11
  ## [0.1.2] - 2026-03-19
4
12
 
5
13
  ### Added
data/CLAUDE.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # lex-detect: Environment-Aware Extension Discovery
2
2
 
3
3
  **Repository Level 3 Documentation**
4
- - **Parent (Level 2)**: `/Users/miverso2/rubymine/legion/extensions-core/CLAUDE.md`
5
- - **Parent (Level 1)**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-core/CLAUDE.md`
5
+ - **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
6
 
7
7
  ## Purpose
8
8
 
@@ -10,7 +10,7 @@ Legion Extension that scans the local environment and recommends which `lex-*` e
10
10
 
11
11
  **GitHub**: https://github.com/LegionIO/lex-detect
12
12
  **License**: MIT
13
- **Version**: 0.1.1
13
+ **Version**: 0.1.2
14
14
 
15
15
  ## Architecture
16
16
 
@@ -19,10 +19,13 @@ Legion::Extensions::Detect
19
19
  ├── CATALOG (constant) # Frozen array of 20 detection rules
20
20
  ├── Scanner # Probes environment, matches against catalog
21
21
  ├── Installer # Gem.install wrapper with dry_run support
22
+ ├── Actors/
23
+ │ ├── FullScan (Once) # Full environment scan at startup
24
+ │ └── DeltaScan (Every) # Periodic delta scan every 6 hours
22
25
  └── Entry Point # Public API: scan, missing, install_missing!, catalog
23
26
  ```
24
27
 
25
- This is NOT a typical LEX no runners, no actors, no AMQP transport, no Faraday client. It is a local-only utility gem with zero runtime dependencies.
28
+ Local-only utility gem. Actors run scans but do not create AMQP queues.
26
29
 
27
30
  - `data_required? false` — no database needed
28
31
  - `remote_invocable? false` — no AMQP queue creation
@@ -49,12 +52,12 @@ Legion::Extensions::Detect.catalog # raw CATALOG constant
49
52
 
50
53
  ## Design Docs
51
54
 
52
- - Design: `docs/plans/2026-03-18-lex-detect-design.md`
53
- - Implementation: `docs/plans/2026-03-18-lex-detect-implementation.md`
55
+ - Design: `docs/work/completed/2026-03-18-lex-detect-design.md`
56
+ - Implementation: `docs/work/completed/2026-03-18-lex-detect-implementation.md`
54
57
 
55
58
  ## Testing
56
59
 
57
- 37 specs across 4 spec files.
60
+ 40 specs across 6 spec files.
58
61
 
59
62
  ```bash
60
63
  bundle install
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Detect
6
+ module Runners
7
+ module TaskObserver
8
+ extend self
9
+
10
+ def observe(tasks:, **)
11
+ return { success: true, alerts: [] } unless tasks.is_a?(Array)
12
+
13
+ alerts = generate_alerts(tasks)
14
+ check_and_publish_failure_patterns(tasks)
15
+ { success: true, alerts: alerts, task_count: tasks.size }
16
+ rescue StandardError => e
17
+ { success: false, reason: :error, message: e.message }
18
+ end
19
+
20
+ private
21
+
22
+ def generate_alerts(tasks)
23
+ failed = tasks.select { |t| t[:status] == 'failed' }
24
+ return [] if failed.empty?
25
+
26
+ failed.group_by { |t| t[:runner_class] }.filter_map do |runner_class, failures|
27
+ next unless failures.size >= 3
28
+
29
+ { runner_class: runner_class, failure_count: failures.size, level: :warning }
30
+ end
31
+ end
32
+
33
+ def check_and_publish_failure_patterns(tasks)
34
+ return unless defined?(Legion::Data) && defined?(Legion::Transport)
35
+
36
+ runner_failures = tasks.select { |t| t[:status] == 'failed' }
37
+ .group_by { |t| t[:runner_class] }
38
+
39
+ runner_failures.each do |runner_class, failures|
40
+ next unless failures.size >= 3
41
+
42
+ gem_name = extract_gem_name(runner_class)
43
+ backtraces = failures.filter_map { |f| f[:error_backtrace] }.first(5)
44
+ error_class = failures.first[:error_class] || 'StandardError'
45
+
46
+ pattern = build_failure_pattern(gem_name, runner_class, error_class, backtraces, failures.size)
47
+ publish_failure_pattern(pattern)
48
+ end
49
+ rescue StandardError
50
+ nil
51
+ end
52
+
53
+ def build_failure_pattern(gem_name, runner_class, error_class, backtraces, count)
54
+ {
55
+ gem_name: gem_name,
56
+ runner_class: runner_class,
57
+ error_class: error_class,
58
+ backtraces: backtraces,
59
+ failure_count: count,
60
+ window_minutes: 60
61
+ }
62
+ end
63
+
64
+ def publish_failure_pattern(pattern)
65
+ return unless defined?(Legion::Transport::Messages::Dynamic)
66
+
67
+ Legion::Transport::Messages::Dynamic.new(
68
+ function: 'auto_fix',
69
+ payload: pattern
70
+ ).publish
71
+ rescue StandardError
72
+ nil
73
+ end
74
+
75
+ def extract_gem_name(runner_class)
76
+ return nil unless runner_class
77
+
78
+ parts = runner_class.to_s.split('::')
79
+ ext_idx = parts.index('Extensions')
80
+ return nil unless ext_idx && parts[ext_idx + 1]
81
+
82
+ "lex-#{parts[ext_idx + 1].gsub(/([a-z])([A-Z])/, '\1_\2').downcase}"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Detect
6
- VERSION = '0.1.2'
6
+ VERSION = '0.1.3'
7
7
  end
8
8
  end
9
9
  end
@@ -4,6 +4,7 @@ require 'legion/extensions/detect/version'
4
4
  require 'legion/extensions/detect/catalog'
5
5
  require 'legion/extensions/detect/scanner'
6
6
  require 'legion/extensions/detect/installer'
7
+ require_relative 'detect/runners/task_observer'
7
8
 
8
9
  module Legion
9
10
  module Extensions
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-detect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -32,6 +32,7 @@ files:
32
32
  - lib/legion/extensions/detect/catalog.rb
33
33
  - lib/legion/extensions/detect/installer.rb
34
34
  - lib/legion/extensions/detect/local_migrations/20260319000001_create_detect_results.rb
35
+ - lib/legion/extensions/detect/runners/task_observer.rb
35
36
  - lib/legion/extensions/detect/scanner.rb
36
37
  - lib/legion/extensions/detect/version.rb
37
38
  homepage: https://github.com/LegionIO/lex-detect