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 +4 -4
- data/README.md +21 -5
- data/lib/libtmux/mcp/cli.rb +32 -11
- data/lib/libtmux/mcp/version.rb +1 -1
- data/sig/libtmux-mcp.rbs +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 892583808fe4a27248b270071193932a4f7b36fb5eb592358c4ceb2ac24f296c
|
|
4
|
+
data.tar.gz: b45a1a838d2831cc34a1fab2c9a4d36780cae5594050dd9a3063dbb2f5e79067
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
+
[](https://libtmux.org/en/ruby/latest/mcp/)
|
|
24
|
+
[](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
|
|
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
|
|
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
|
-
|
|
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.
|
|
352
|
-
|
|
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
|
|
data/lib/libtmux/mcp/cli.rb
CHANGED
|
@@ -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 =
|
|
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
|
|
189
|
-
options.on("--socket PATH", "Borrow
|
|
190
|
-
|
|
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
|
|
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?
|
data/lib/libtmux/mcp/version.rb
CHANGED
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
121
|
+
documentation_uri: https://libtmux.org/en/ruby/v0.1.1/mcp/
|
|
122
122
|
rdoc_options: []
|
|
123
123
|
require_paths:
|
|
124
124
|
- lib
|