rsmp 0.35.2 → 0.37.0

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: e5c0f93062b73555dd67edda6564054299c1df0240c4ce55f0b854abc7e94931
4
- data.tar.gz: 2659660e29f1ba7b50533b3e89bb80c81ae69f81768cbc4012db6da6776ccebc
3
+ metadata.gz: 9f2687b5748524376a9316cadcf6776a6d9a9ccddbb8b763ea222246f7efb602
4
+ data.tar.gz: 942347899e8f26aae13eb6ead6dce7c2b2d17020c0e11b04af530a5e91904ed5
5
5
  SHA512:
6
- metadata.gz: c48367c147156f5adb8cdabfd5fc81cde4cbb3e842f05c982307b6400f6fb33deb583cc57737faa2e7a1fe2a87f7e629dde7b335f063e126a403e45f49774c2f
7
- data.tar.gz: 77c5e1343d7106bd9a60ff55e666d69cb4589655e7ad9bcbcf84cb95101e3b7c004bf373943f018d24b38d5cb6f6cccc97f7a0202fe2c8f5dc6ad7e687134c1b
6
+ metadata.gz: 77ba8af9b9be03e22bef3fa9a83c28f407c2371f7b6c3064e00396f8f9e2a1e088d52afb9c06270352c602cea91b88468e8674a5555b6a7383cd8b389f5a2567
7
+ data.tar.gz: 1f17f3055a0c88a2848fc5ef0b1fe93fd7ad02e321cdfbe90824f418c61054c6085940e5c3c87a186ab46ed7e6c5e8bceb0dc905e0109d055d484519cb030659
@@ -0,0 +1,33 @@
1
+ # rsmp gem
2
+ This is a Ruby based repository contaning an implementation of RSMP (RoadSide Message Protocol), including:
3
+
4
+ - Ruby classes that can be used to build tests or other RSMP tools.
5
+ - Command-line tools for quickly running RSMP supervisors or sites and view messages exchanged.
6
+
7
+ It relies on the gem `rsmp_schema` to validate RSMP message using JSON schema.
8
+
9
+ Always reference these instructions first, and fall back to search or bash commands only when you encounter unexpected information that does not match the info here.
10
+
11
+ ## Development Flow
12
+ - Ruby and required gems are already installed by the action .github/copilot-setup-steps.yml, do not install them again.
13
+ - All gem executables must be run from the bundle environment using `bundle exec ...`
14
+ - Before any commit, run `bundle exec rspec` to verify that all tests pass.
15
+
16
+ ## Repository Structure
17
+ - `bin/`: Main service entry points and executables
18
+ - `lib/`: Ruby source code
19
+ - `spec/`: RSpec test files for validating Ruby code
20
+ - `features/`: Cucumber test files for validating the CLI component
21
+ - `config/`: Configuration files used when running the 'rsmp' command line
22
+ - `documentation/`: Documentation
23
+
24
+ ## Guidelines
25
+ - Follow Ruby best practices and idiomatic patterns.
26
+ - Maintain existing code structure and organization.
27
+ - Always use existing async patterns to handle concurrency, also in tests.
28
+ - Code behaviour should adhere to the RSMP specifications defined at https://github.com/rsmp-nordic/rsmp_core.
29
+ - Write and verify rspec tests for new functionality.
30
+ - Document public APIs and complex logic. Suggest changes to the `documentation/` folder when appropriate.
31
+ - Don't commit example scripts.
32
+ - Prefer real classes over test doubles or mocks in tests and use async contexts to run sites and supervisors.
33
+ - When reporting on progress, claims should be supported by tests or other data.
@@ -0,0 +1,35 @@
1
+ name: "Copilot Setup Steps"
2
+
3
+ # Automatically run the setup steps when they are changed to allow for easy validation, and
4
+ # allow manual testing through the repository's "Actions" tab
5
+ on:
6
+ workflow_dispatch:
7
+ push:
8
+ paths:
9
+ - .github/workflows/copilot-setup-steps.yml
10
+ pull_request:
11
+ paths:
12
+ - .github/workflows/copilot-setup-steps.yml
13
+
14
+ jobs:
15
+ # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
16
+ copilot-setup-steps:
17
+ runs-on: ubuntu-latest
18
+
19
+ # Set the permissions to the lowest permissions possible needed for your steps.
20
+ # Copilot will be given its own token for its operations.
21
+ permissions:
22
+ # If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
23
+ contents: read
24
+
25
+ # You can define any steps you want, and they will run before the agent starts.
26
+ # If you do not check out your code, Copilot will do this for you.
27
+ steps:
28
+ - name: Checkout code
29
+ uses: actions/checkout@v4
30
+
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: 3.4
34
+ bundler-cache: true
35
+
@@ -14,6 +14,7 @@ jobs:
14
14
  - uses: actions/checkout@v4
15
15
  - uses: ruby/setup-ruby@v1
16
16
  with:
17
- ruby-version: 3.3
17
+ ruby-version: 3.4
18
18
  bundler-cache: true
19
19
  - run: bundle exec rspec -f d
20
+
data/.gitignore CHANGED
@@ -9,8 +9,9 @@ log
9
9
  /coverage/
10
10
  /doc/
11
11
  /pkg/
12
- /spec/reports/
13
12
  /tmp/
13
+ /vendor/
14
+ /spec/reports/
14
15
  /config/private/
15
16
 
16
17
 
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.35.2)
5
- async (~> 2.21)
6
- async-io (~> 1.43)
4
+ rsmp (0.37.0)
5
+ async (~> 2.32)
7
6
  colorize (~> 1.1)
7
+ io-endpoint (~> 0.15)
8
+ io-stream (~> 0.10)
8
9
  logger (~> 1.6)
9
10
  ostruct (~> 0.6)
10
11
  rsmp_schema (~> 0.8)
@@ -12,24 +13,22 @@ PATH
12
13
  GEM
13
14
  remote: https://rubygems.org/
14
15
  specs:
15
- aruba (2.3.0)
16
+ aruba (2.3.1)
16
17
  bundler (>= 1.17, < 3.0)
17
18
  contracts (>= 0.16.0, < 0.18.0)
18
- cucumber (>= 8.0, < 10.0)
19
+ cucumber (>= 8.0, < 11.0)
19
20
  rspec-expectations (~> 3.4)
20
21
  thor (~> 1.0)
21
- async (2.23.0)
22
+ async (2.32.0)
22
23
  console (~> 1.29)
23
24
  fiber-annotation
24
- io-event (~> 1.9)
25
+ io-event (~> 1.11)
25
26
  metrics (~> 0.12)
26
- traces (~> 0.15)
27
- async-io (1.43.2)
28
- async
29
- bigdecimal (3.1.9)
27
+ traces (~> 0.18)
28
+ bigdecimal (3.2.3)
30
29
  builder (3.3.0)
31
30
  colorize (1.1.0)
32
- console (1.29.3)
31
+ console (1.34.0)
33
32
  fiber-annotation
34
33
  fiber-local (~> 1.1)
35
34
  json
@@ -55,57 +54,63 @@ GEM
55
54
  bigdecimal
56
55
  cucumber-gherkin (27.0.0)
57
56
  cucumber-messages (>= 19.1.4, < 23)
58
- cucumber-html-formatter (21.9.0)
57
+ cucumber-html-formatter (21.14.0)
59
58
  cucumber-messages (> 19, < 28)
60
59
  cucumber-messages (22.0.0)
61
60
  cucumber-tag-expressions (6.1.2)
62
- diff-lcs (1.6.0)
63
- ffi (1.17.1)
61
+ diff-lcs (1.6.2)
62
+ ffi (1.17.2)
63
+ ffi (1.17.2-arm64-darwin)
64
64
  fiber-annotation (0.2.0)
65
65
  fiber-local (1.1.0)
66
66
  fiber-storage
67
- fiber-storage (1.0.0)
67
+ fiber-storage (1.0.1)
68
68
  hana (1.3.7)
69
- io-event (1.9.0)
70
- json (2.10.1)
71
- json_schemer (2.3.0)
69
+ io-endpoint (0.15.2)
70
+ io-event (1.14.0)
71
+ io-stream (0.10.0)
72
+ json (2.14.1)
73
+ json_schemer (2.4.0)
72
74
  bigdecimal
73
75
  hana (~> 1.3)
74
76
  regexp_parser (~> 2.0)
75
77
  simpleidn (~> 0.2)
76
- logger (1.6.6)
77
- metrics (0.12.1)
78
+ logger (1.7.0)
79
+ memoist3 (1.0.0)
80
+ metrics (0.15.0)
78
81
  mini_mime (1.1.5)
79
82
  multi_test (1.1.0)
80
- ostruct (0.6.1)
81
- rake (13.2.1)
82
- regexp_parser (2.10.0)
83
- rsmp_schema (0.8.7)
84
- json_schemer (~> 2.3.0)
85
- thor (~> 1.3.1)
86
- rspec (3.13.0)
83
+ ostruct (0.6.3)
84
+ rake (13.3.0)
85
+ regexp_parser (2.11.2)
86
+ rsmp_schema (0.8.9)
87
+ json_schemer (~> 2.4.0)
88
+ thor (~> 1.4.0)
89
+ rspec (3.13.1)
87
90
  rspec-core (~> 3.13.0)
88
91
  rspec-expectations (~> 3.13.0)
89
92
  rspec-mocks (~> 3.13.0)
90
- rspec-core (3.13.3)
93
+ rspec-core (3.13.5)
91
94
  rspec-support (~> 3.13.0)
92
- rspec-expectations (3.13.3)
95
+ rspec-expectations (3.13.5)
93
96
  diff-lcs (>= 1.2.0, < 2.0)
94
97
  rspec-support (~> 3.13.0)
95
- rspec-mocks (3.13.2)
98
+ rspec-mocks (3.13.5)
96
99
  diff-lcs (>= 1.2.0, < 2.0)
97
100
  rspec-support (~> 3.13.0)
98
- rspec-support (3.13.2)
101
+ rspec-support (3.13.5)
99
102
  simpleidn (0.2.3)
100
- sys-uname (1.3.1)
103
+ sys-uname (1.4.1)
101
104
  ffi (~> 1.1)
102
- thor (1.3.2)
105
+ memoist3 (~> 1.0.0)
106
+ thor (1.4.0)
103
107
  timecop (0.9.10)
104
- traces (0.15.2)
108
+ traces (0.18.2)
105
109
 
106
110
  PLATFORMS
107
111
  arm64-darwin-22
108
112
  arm64-darwin-23
113
+ arm64-darwin-24
109
114
  x64-mingw-ucrt
110
115
  x64-mingw32
111
116
  x86_64-darwin-19
data/bin/console CHANGED
@@ -14,10 +14,8 @@ module IRB
14
14
  class MyInputMethod < StdioInputMethod
15
15
  def initialize
16
16
  super
17
- @input = Async::IO::Protocol::Line.new(
18
- Async::IO::Stream.new(
19
- Async::IO::Generic.new($stdin)
20
- )
17
+ @input = RSMP::Protocol.new(
18
+ IO::Stream::Buffered.new($stdin)
21
19
  )
22
20
  end
23
21
 
@@ -74,16 +74,16 @@ SiteProxy and SupervisorProxy both inherit from Proxy and have a reader task and
74
74
  ## Task Hierachy
75
75
  When you start an Async task, the parent will be the currently running task, unless you specify a different parent task.
76
76
 
77
- The Async task hierarchy is similar to the object hierachy, with the difference that proxies have reader and timer tasks. And Async::IO which is used to handle TPC connections concurently, will create some intermediate tasks:
77
+ The Async task hierarchy is similar to the object hierachy, with the difference that proxies have reader and timer tasks. And IO::Endpoint which is used to handle TCP connections concurently, will create some intermediate tasks:
78
78
 
79
79
  ```
80
80
  Supervisor @task
81
- accepting connections # this task is created by Async::IO
82
- incoming connection 1 # this task is created by Async::IO
81
+ accepting connections # this task is created by IO::Endpoint
82
+ incoming connection 1 # this task is created by IO::Endpoint
83
83
  SiteProxy @task
84
84
  SiteProxy @reader
85
85
  SiteProxy @timer
86
- incoming connection 2 # this task is created by Async::IO
86
+ incoming connection 2 # this task is created by IO::Endpoint
87
87
  SiteProxy @task
88
88
  SiteProxy @reader
89
89
  SiteProxy @timer
@@ -0,0 +1,35 @@
1
+ module RSMP
2
+ class Protocol
3
+ def initialize(stream)
4
+ @stream = stream
5
+ @peeked = nil
6
+ end
7
+
8
+ def read_line
9
+ if @peeked
10
+ line = @peeked
11
+ @peeked = nil
12
+ line
13
+ else
14
+ read
15
+ end
16
+ end
17
+
18
+ def peek_line
19
+ @peeked = read unless @peeked
20
+ @peeked
21
+ end
22
+
23
+ def write_lines(data)
24
+ @stream.write(data + RSMP::Proxy::WRAPPING_DELIMITER)
25
+ @stream.flush unless @stream.closed?
26
+ end
27
+
28
+ protected
29
+ def read
30
+ line = @stream.gets(RSMP::Proxy::WRAPPING_DELIMITER)
31
+ return nil unless line
32
+ line.chomp(RSMP::Proxy::WRAPPING_DELIMITER)
33
+ end
34
+ end
35
+ end
data/lib/rsmp/proxy.rb CHANGED
@@ -169,16 +169,14 @@ module RSMP
169
169
  end
170
170
 
171
171
  def run_reader
172
- @stream ||= Async::IO::Stream.new(@socket)
173
- @protocol ||= Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
172
+ @stream ||= IO::Stream::Buffered.new(@socket)
173
+ @protocol ||= RSMP::Protocol.new(@stream) # rsmp messages are json terminated with a form-feed
174
174
  loop do
175
175
  read_line
176
176
  end
177
177
  rescue Restart
178
178
  log "Closing connection", level: :warning
179
179
  raise
180
- rescue Async::Wrapper::Cancelled
181
- # ignore exceptions raised when a wait is aborted because a task is stopped
182
180
  rescue EOFError, Async::Stop
183
181
  log "Connection closed", level: :warning
184
182
  rescue IOError => e
@@ -4,12 +4,15 @@
4
4
 
5
5
  module RSMP
6
6
  class Supervisor < Node
7
- attr_reader :core_version, :site_id, :supervisor_settings, :proxies, :logger
7
+ attr_reader :core_version, :site_id, :supervisor_settings, :proxies, :logger, :ready_condition
8
+
9
+ attr_accessor :site_id_condition
8
10
 
9
11
  def initialize options={}
10
12
  handle_supervisor_settings( options[:supervisor_settings] || {} )
11
13
  super options
12
14
  @proxies = []
15
+ @ready_condition = Async::Notification.new
13
16
  @site_id_condition = Async::Notification.new
14
17
  end
15
18
 
@@ -58,19 +61,26 @@ module RSMP
58
61
  end
59
62
 
60
63
  # listen for connections
61
- # Async::IO::Endpoint#accept createa an async task that we will wait for
62
64
  def run
63
65
  log "Starting supervisor on port #{@supervisor_settings["port"]}",
64
66
  level: :info,
65
67
  timestamp: @clock.now
66
68
 
67
- @endpoint = Async::IO::Endpoint.tcp('0.0.0.0', @supervisor_settings["port"])
68
- tasks = @endpoint.accept do |socket| # creates async tasks
69
- handle_connection(socket)
69
+ @endpoint = IO::Endpoint.tcp('0.0.0.0', @supervisor_settings["port"])
70
+ @accept_task = Async::Task.current.async do |task|
71
+ task.annotate "supervisor accept loop"
72
+ @endpoint.accept() do |socket| # creates fibers
73
+ handle_connection(socket)
74
+ rescue StandardError => e
75
+ distribute_error e, level: :internal
76
+ end
77
+ rescue Async::Stop # will happen at shutdown
70
78
  rescue StandardError => e
71
79
  distribute_error e, level: :internal
72
80
  end
73
- tasks.each { |task| task.wait }
81
+
82
+ @ready_condition.signal
83
+ @accept_task.wait
74
84
  rescue StandardError => e
75
85
  distribute_error e, level: :internal
76
86
  end
@@ -78,6 +88,11 @@ module RSMP
78
88
  # stop
79
89
  def stop
80
90
  log "Stopping supervisor #{@supervisor_settings["site_id"]}", level: :info
91
+
92
+ @accept_task.stop if @accept_task
93
+ @accept_task = nil
94
+
95
+ @endpoint = nil
81
96
  super
82
97
  end
83
98
 
@@ -150,8 +165,8 @@ module RSMP
150
165
 
151
166
  authorize_ip info[:ip]
152
167
 
153
- stream = Async::IO::Stream.new socket
154
- protocol = Async::IO::Protocol::Line.new stream, Proxy::WRAPPING_DELIMITER
168
+ stream = IO::Stream::Buffered.new(socket)
169
+ protocol = RSMP::Protocol.new stream
155
170
 
156
171
  settings = {
157
172
  supervisor: self,
@@ -65,28 +65,22 @@ module RSMP
65
65
  end
66
66
 
67
67
  def connect_tcp
68
- @endpoint = Async::IO::Endpoint.tcp(@ip, @port)
69
-
70
- error = nil
71
- # Async::IO::Endpoint#connect renames the current task. run in a subtask to avoid this see issue #22
72
- result = @task.async do |task|
73
- task.annotate 'socket task'
74
- # this timeout is a workaround for connect hanging on windows if the other side is not present yet
75
- timeout = @site_settings.dig('timeouts','connect') || 1.1
76
- task.with_timeout timeout do
77
- @socket = @endpoint.connect
78
- end
79
- delay = @site_settings.dig('intervals','after_connect')
80
- task.sleep delay if delay
81
- rescue Errno::ECONNREFUSED => e # rescue to avoid log output
82
- log "Connection refused", level: :warning
83
- error = e
84
- end.wait
85
- raise error if error # reraise any error outside task
86
-
87
- @stream = Async::IO::Stream.new(@socket)
88
- @protocol = Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
68
+ @endpoint = IO::Endpoint.tcp(@ip, @port)
69
+
70
+ # this timeout is a workaround for connect hanging on windows if the other side is not present yet
71
+ timeout = @site_settings.dig('timeouts','connect') || 1.1
72
+ task.with_timeout timeout do
73
+ @socket = @endpoint.connect
74
+ end
75
+ delay = @site_settings.dig('intervals','after_connect')
76
+ task.sleep delay if delay
77
+
78
+ @stream = IO::Stream::Buffered.new(@socket)
79
+ @protocol = RSMP::Protocol.new(@stream) # rsmp messages are json terminated with a form-feed
89
80
  set_state :connected
81
+ rescue Errno::ECONNREFUSED => e # rescue to avoid log output
82
+ log "Connection refused", level: :warning
83
+ raise e
90
84
  end
91
85
 
92
86
  def handshake_complete
data/lib/rsmp/task.rb CHANGED
@@ -13,12 +13,24 @@ module RSMP
13
13
  # run() will be called inside the task to perform actual long-running work
14
14
  def start
15
15
  return if @task
16
- Async do |task|
17
- task.annotate "#{self.class.name} main task"
18
- @task = task
19
- run
20
- stop_subtasks
21
- @task = nil
16
+
17
+ # Use current task context if available, otherwise create new reactor
18
+ if Async::Task.current?
19
+ Async::Task.current.async do |task|
20
+ task.annotate "#{self.class.name} main task"
21
+ @task = task
22
+ run
23
+ stop_subtasks
24
+ @task = nil
25
+ end
26
+ else
27
+ Async do |task|
28
+ task.annotate "#{self.class.name} main task"
29
+ @task = task
30
+ run
31
+ stop_subtasks
32
+ @task = nil
33
+ end
22
34
  end
23
35
  self
24
36
  end
@@ -141,7 +141,12 @@ module RSMP
141
141
  end
142
142
 
143
143
  def move_cycle_counter
144
- counter = Time.now.to_i % current_plan.cycle_time
144
+ plan = current_plan
145
+ if plan
146
+ counter = Time.now.to_i % plan.cycle_time
147
+ else
148
+ counter = 0
149
+ end
145
150
  changed = counter != @cycle_counter
146
151
  @cycle_counter = counter
147
152
  changed
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.35.2"
2
+ VERSION = "0.37.0"
3
3
  end
data/lib/rsmp.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'yaml'
2
2
  require 'socket'
3
3
  require 'time'
4
- require 'async/io'
5
- require 'async/io/protocol/line'
4
+ require 'async'
5
+ require 'io/endpoint'
6
+ require 'io/endpoint/host_endpoint'
7
+ require 'io/stream'
6
8
  require 'colorize'
7
9
  require 'json'
8
10
  require 'securerandom'
@@ -14,6 +16,7 @@ require 'rsmp/task'
14
16
  require 'rsmp/deep_merge'
15
17
  require 'rsmp/inspect'
16
18
  require 'rsmp/logging'
19
+ require 'rsmp/protocol'
17
20
  require 'rsmp/node'
18
21
  require 'rsmp/supervisor'
19
22
  require 'rsmp/components'
data/rsmp.gemspec CHANGED
@@ -32,8 +32,9 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_dependency "logger", "~> 1.6"
34
34
  spec.add_dependency "ostruct", "~> 0.6"
35
- spec.add_dependency "async", "~> 2.21"
36
- spec.add_dependency "async-io", "~> 1.43"
35
+ spec.add_dependency "async", "~> 2.32"
36
+ spec.add_dependency "io-stream", "~> 0.10"
37
+ spec.add_dependency "io-endpoint", "~> 0.15"
37
38
  spec.add_dependency "colorize", "~> 1.1"
38
39
  spec.add_dependency "rsmp_schema", "~> 0.8"
39
40
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.35.2
4
+ version: 0.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-04 00:00:00.000000000 Z
10
+ date: 2025-09-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: logger
@@ -43,28 +43,42 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '2.21'
46
+ version: '2.32'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '2.21'
53
+ version: '2.32'
54
54
  - !ruby/object:Gem::Dependency
55
- name: async-io
55
+ name: io-stream
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '1.43'
60
+ version: '0.10'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.43'
67
+ version: '0.10'
68
+ - !ruby/object:Gem::Dependency
69
+ name: io-endpoint
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.15'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.15'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: colorize
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -199,6 +213,8 @@ executables:
199
213
  extensions: []
200
214
  extra_rdoc_files: []
201
215
  files:
216
+ - ".github/copilot-instructions.md"
217
+ - ".github/workflows/copilot-setup-steps.yml"
202
218
  - ".github/workflows/rspec.yaml"
203
219
  - ".gitignore"
204
220
  - ".gitmodules"
@@ -253,6 +269,7 @@ files:
253
269
  - lib/rsmp/logging.rb
254
270
  - lib/rsmp/message.rb
255
271
  - lib/rsmp/node.rb
272
+ - lib/rsmp/protocol.rb
256
273
  - lib/rsmp/proxy.rb
257
274
  - lib/rsmp/rsmp.rb
258
275
  - lib/rsmp/site.rb