libtmux-mcp 0.1.0.alpha.3 → 0.1.1

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: af3b345cc9efd2ed4fcb1c384d8ee9a0e8f14b0da9052eedafb5e88b285a2501
4
- data.tar.gz: f6c4f2647b58a02730b17ab57190f7cfc5ef2927c923961608d2a192d9f1b077
3
+ metadata.gz: 892583808fe4a27248b270071193932a4f7b36fb5eb592358c4ceb2ac24f296c
4
+ data.tar.gz: b45a1a838d2831cc34a1fab2c9a4d36780cae5594050dd9a3063dbb2f5e79067
5
5
  SHA512:
6
- metadata.gz: 62dddd73fc6080af123ef9b4b5aeb5dca20c72d8798232d69df61777f3e1aaa9b44db30d1853949e2e5d266d063b6827ed2b3f4feb4950072418d2283739bba2
7
- data.tar.gz: 37bffa621af62f041a08dffa029d2f060874686983982e70a1906343fd2755bfc6b81daefeb1e2914f99a53a38ba7d88c1b90edb1982f3f48349396bdb1a91e9
6
+ metadata.gz: 3d0d730cb95acf640cbaf2ddf1702c917558662a9427fc0c5b9d17bca81321998563efa7eed740140e7813d779f0cfc777b3ec6977528c59562fae957e6d17f1
7
+ data.tar.gz: 05eb4ecc928723328ee886877821e89ea5f05654dfe31c1f0652825dd582c4978e4442e7876fd37d265681aa3a92b1facd14210b62860d9d1088895feeb87f6d
data/README.md CHANGED
@@ -20,6 +20,9 @@ tool at a time.
20
20
  [Guides](https://libtmux.org/en/ruby/latest/mcp/guides/) ·
21
21
  [RubyGems](https://rubygems.org/gems/libtmux-mcp)
22
22
 
23
+ [![libtmux.org](https://img.shields.io/badge/docs-libtmux.org-0b7285)](https://libtmux.org/en/ruby/latest/mcp/)
24
+ [![libtmux-mcp](https://img.shields.io/gem/v/libtmux-mcp?label=libtmux-mcp)](https://rubygems.org/gems/libtmux-mcp)
25
+
23
26
  </div>
24
27
 
25
28
  Part of [libtmux for Ruby](https://github.com/libtmux/libtmux-ruby#readme).
@@ -40,11 +43,11 @@ transport.
40
43
 
41
44
  ## Quick start
42
45
 
43
- Install the alpha and its `libtmux-mcp` executable. It needs Ruby 3.3 or newer
46
+ Install the gem and its `libtmux-mcp` executable. It needs Ruby 3.3 or newer
44
47
  and tmux 3.3a or newer:
45
48
 
46
49
  ```console
47
- $ gem install libtmux-mcp --pre
50
+ $ gem install libtmux-mcp
48
51
  ```
49
52
 
50
53
  The server borrows a tmux server that is already running. Start one on a
@@ -122,6 +125,15 @@ $ libtmux-mcp \
122
125
  --socket-name agent
123
126
  ```
124
127
 
128
+ - With neither flag, the server borrows the socket in `LIBTMUX_SOCKET_PATH`,
129
+ else the name in `LIBTMUX_SOCKET`, else the server `TMUX` names when it runs
130
+ inside tmux, else tmux's default socket. When both variables are set, the
131
+ path wins, and an empty variable counts as unset. A flag ignores both
132
+ variables, and the two flags are refused together.
133
+ - The server never starts a tmux server. When none answers at the socket it
134
+ chose, it exits with status 1.
135
+ - Started from a tmux pane with no flag or variable, the server drives that
136
+ pane's server. Pass `--socket-name` to give an agent a server of its own.
125
137
  - EOF retires the clients the server owns and leaves the daemon running.
126
138
  - `--endpoint` sets the public alias in discovery and resource URIs, and
127
139
  defaults to `local`.
@@ -334,7 +346,9 @@ pass the invitation to [`accept_shell`][mcp-application-accept_shell].
334
346
 
335
347
  ## Support and status
336
348
 
337
- **Alpha.** APIs may change between releases.
349
+ Releases are numbered `0.1.N`, and each release increments `N`. The API is not
350
+ settled: any release may change or remove exported identifiers, and the
351
+ changelog marks each break. Pin an exact version to avoid one.
338
352
 
339
353
  - **Ruby 3.3 or newer.** The gem depends on `libtmux` and `libtmux-async` at
340
354
  the same version, the `mcp` SDK 1.5, `digest` and `optparse`.
@@ -348,8 +362,10 @@ pass the invitation to [`accept_shell`][mcp-application-accept_shell].
348
362
  client.
349
363
  - **Linux, including WSL, and macOS.** The core
350
364
  [compatibility workflow][compat] runs Ruby 3.3, 3.4 and 4.0 with tmux 3.3a
351
- through 3.8 on Ubuntu 24.04. macOS is supported on a best-effort basis, and
352
- CI coverage for it is highly limited.
365
+ through 3.8 on Ubuntu 24.04. A push and a pull request run the oldest and
366
+ newest of those releases, 3.3a and 3.8, and a release runs all of them. macOS
367
+ is supported on a best-effort basis, and CI coverage for it is highly
368
+ limited.
353
369
 
354
370
  ## Documentation
355
371
 
@@ -6,12 +6,12 @@ require "optparse"
6
6
  module LibTmux
7
7
  module MCP
8
8
  class CLI
9
- def self.run(arguments, input: $stdin, out: $stdout, err: $stderr)
10
- new(arguments, input, out, err).run
9
+ def self.run(arguments, input: $stdin, out: $stdout, err: $stderr, environment: ENV)
10
+ new(arguments, input, out, err, environment).run
11
11
  end
12
12
 
13
- def initialize(arguments, input, output, error)
14
- @arguments, @input, @output, @error = arguments.dup, input, output, error
13
+ def initialize(arguments, input, output, error, environment = ENV)
14
+ @arguments, @input, @output, @error, @environment = arguments.dup, input, output, error, environment
15
15
  @options = {endpoint_name: "local", executable: "tmux", tools: Catalog::READ_ONLY.dup,
16
16
  timeout: 5.0, concurrency: 4, max_requests: 32, max_frame_bytes: 1 << 20,
17
17
  max_output_bytes: 1 << 22, max_response_bytes: 1 << 20,
@@ -27,8 +27,7 @@ module LibTmux
27
27
  return 0
28
28
  end
29
29
  validate_arguments
30
- endpoint = Endpoint.new(socket_path: @options[:socket_path], socket_name: @options[:socket_name],
31
- executable: @options.fetch(:executable))
30
+ endpoint = build_endpoint
32
31
  Async do |task|
33
32
  begin
34
33
  serve(endpoint, task)
@@ -44,7 +43,7 @@ module LibTmux
44
43
  end
45
44
  end.wait
46
45
  rescue OptionParser::ParseError, ArgumentError => error
47
- report("Invalid arguments; use --help for supported options.", 2, failure: error)
46
+ report(@invalid_endpoint || "Invalid arguments; use --help for supported options.", 2, failure: error)
48
47
  rescue Interrupt, LibTmux::Cancelled => error
49
48
  report("MCP interrupted; dispatched effects may remain.", 130, failure: error)
50
49
  rescue StandardError => error
@@ -53,6 +52,25 @@ module LibTmux
53
52
 
54
53
  private
55
54
 
55
+ # --socket and --socket-name win; otherwise the core reads the variables,
56
+ # TMUX and tmux's default.
57
+ def build_endpoint
58
+ socket_path = @options[:socket_path]
59
+ socket_path = expand_socket(socket_path) unless socket_path.nil? || socket_path.empty?
60
+ Endpoint.new(socket_path: socket_path, socket_name: @options[:socket_name],
61
+ executable: @options.fetch(:executable), environment: @environment)
62
+ rescue ArgumentError => error
63
+ @invalid_endpoint = "Invalid arguments: #{error.message}."
64
+ raise
65
+ end
66
+
67
+ # File.expand_path puts the user it cannot find in its message.
68
+ def expand_socket(socket)
69
+ File.expand_path(socket)
70
+ rescue ArgumentError
71
+ raise ArgumentError, "--socket cannot be expanded to a path; its leading ~ names no home directory"
72
+ end
73
+
56
74
  def serve(endpoint, task)
57
75
  Server.open(endpoint: endpoint) do |server|
58
76
  LibTmux::Async.open(server: server, parent: task) do |scope|
@@ -185,9 +203,12 @@ module LibTmux
185
203
 
186
204
  def parser
187
205
  @parser ||= OptionParser.new do |options|
188
- options.banner = "Usage: libtmux-mcp (--socket PATH | --socket-name NAME) [options]"
189
- options.on("--socket PATH", "Borrow this existing tmux Unix socket") { |value| @options[:socket_path] = value }
190
- options.on("--socket-name NAME", "Borrow this explicit tmux socket name") { |value| @options[:socket_name] = value }
206
+ options.banner = "Usage: libtmux-mcp [--socket PATH | --socket-name NAME] [options]"
207
+ options.on("--socket PATH", "Borrow the tmux server at this Unix socket",
208
+ "Default: LIBTMUX_SOCKET_PATH, then LIBTMUX_SOCKET, then the",
209
+ "server TMUX names, then tmux's default socket") { |value| @options[:socket_path] = value }
210
+ options.on("--socket-name NAME", "Borrow the tmux server with this socket name",
211
+ "Not with --socket") { |value| @options[:socket_name] = value }
191
212
  options.on("--endpoint NAME", "Public endpoint alias (default: local)") { |value| @options[:endpoint_name] = value }
192
213
  options.on("--tmux EXECUTABLE", "Resolve and pin this tmux executable at startup") { |value| @options[:executable] = value }
193
214
  options.on("--enable-tool NAME", "Enable one additional tool; repeat as needed") { |value| @options.fetch(:tools) << value }
@@ -211,7 +232,7 @@ module LibTmux
211
232
 
212
233
  def validate_arguments
213
234
  raise ArgumentError unless @arguments.empty?
214
- raise ArgumentError unless [@options[:socket_path], @options[:socket_name]].compact.length == 1
235
+ raise ArgumentError if @options[:socket_path] && @options[:socket_name]
215
236
  raise ArgumentError unless @options.fetch(:tools).all? { |name| Catalog::NAMES.include?(name) }
216
237
  raise ArgumentError unless /\A[A-Za-z0-9][A-Za-z0-9_.-]{0,127}\z/.match?(@options.fetch(:endpoint_name))
217
238
  raise ArgumentError unless @options.fetch(:timeout).finite? && @options.fetch(:timeout).positive?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module LibTmux
4
4
  module MCP
5
- VERSION = "0.1.0.alpha.3"
5
+ VERSION = "0.1.1"
6
6
  end
7
7
  end
data/sig/libtmux-mcp.rbs CHANGED
@@ -10,7 +10,7 @@ module LibTmux
10
10
  class CLI
11
11
  private def self.new: (*untyped, **untyped) -> instance
12
12
  def run: () -> Integer
13
- def self.run: (Array[String], ?input: IO, ?out: untyped, ?err: untyped) -> Integer
13
+ def self.run: (Array[String], ?input: IO, ?out: untyped, ?err: untyped, ?environment: untyped) -> Integer
14
14
  end
15
15
  class Application
16
16
  attr_reader tools: Array[untyped]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libtmux-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha.3
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - libtmux contributors
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.1.0.alpha.3
18
+ version: 0.1.1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.1.0.alpha.3
25
+ version: 0.1.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: libtmux-async
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.1.0.alpha.3
32
+ version: 0.1.1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.1.0.alpha.3
39
+ version: 0.1.1
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: mcp
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -118,7 +118,7 @@ licenses:
118
118
  - MIT
119
119
  metadata:
120
120
  source_code_uri: https://github.com/libtmux/libtmux-ruby
121
- documentation_uri: https://libtmux.org/en/ruby/v0.1.0.alpha.3/mcp/
121
+ documentation_uri: https://libtmux.org/en/ruby/v0.1.1/mcp/
122
122
  rdoc_options: []
123
123
  require_paths:
124
124
  - lib