libtmux-workspace 0.1.0 → 0.1.2
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/CHANGELOG.md +51 -0
- data/README.md +51 -18
- data/lib/libtmux/workspace/cli.rb +21 -3
- data/lib/libtmux/workspace/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81a6e6bcb2e2b40052ea69a7ac812919bc40c061eff86d8f1ed24d74db1bdd89
|
|
4
|
+
data.tar.gz: bed554f76a48119e57294fa4199479ce7d9ce1e9864d9a3189224daa11979be7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42b471a92bea5e05bfea43e6005c0373df57aa5606e00c1e72af64960e33b0de755edfb48d6b4f6b07b665b8d59c9ef45b71a0e62cca087bbe82b50d12117b02
|
|
7
|
+
data.tar.gz: 37069ac56ea23c718a2e1cf7029297151ca5672a96ca1d4420aeef4b3fbba99e6ead871aebe999e1dc0a828d3d75a9361549f52f20ca6b451c9d4f9300fbbe1e
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to `libtmux-workspace`.
|
|
4
|
+
|
|
5
|
+
Releases are numbered `0.1.N`, and each release increments `N`. The API is not
|
|
6
|
+
settled: pin an exact version to avoid a break.
|
|
7
|
+
|
|
8
|
+
The gems are released together at one version, so every release has a section
|
|
9
|
+
here. Changes that span gems, such as documentation, CI and release tooling, are
|
|
10
|
+
in the [main changelog](../../CHANGELOG.md).
|
|
11
|
+
|
|
12
|
+
## 0.1.3 (unreleased)
|
|
13
|
+
|
|
14
|
+
## 0.1.2 (2026-11-04)
|
|
15
|
+
|
|
16
|
+
No entries for `libtmux-workspace`.
|
|
17
|
+
|
|
18
|
+
## 0.1.1 (2026-10-31)
|
|
19
|
+
|
|
20
|
+
- **Behavior change:** `libtmux-workspace load` and `plan --live` no longer
|
|
21
|
+
need `--socket`. Without it they use the same choice as `Server.new`, so a
|
|
22
|
+
command that failed with status 2 for a missing socket now acts on the
|
|
23
|
+
server tmux would pick. (#71)
|
|
24
|
+
|
|
25
|
+
## 0.1.0 (2026-10-25)
|
|
26
|
+
|
|
27
|
+
No entries for `libtmux-workspace`.
|
|
28
|
+
|
|
29
|
+
## 0.1.0.alpha.3 (2026-10-24)
|
|
30
|
+
|
|
31
|
+
No entries for `libtmux-workspace`.
|
|
32
|
+
|
|
33
|
+
## 0.1.0.alpha.2 (2026-10-18)
|
|
34
|
+
|
|
35
|
+
No entries for `libtmux-workspace`.
|
|
36
|
+
|
|
37
|
+
## 0.1.0.alpha.1 (2026-09-20)
|
|
38
|
+
|
|
39
|
+
### libtmux-workspace
|
|
40
|
+
|
|
41
|
+
- Load YAML or JSON with `LibTmux::Workspace.load` or `.parse`, inspect a
|
|
42
|
+
creation plan, then apply it explicitly. Supports the documented subset of
|
|
43
|
+
tmuxp-style configuration. [Workspace example](../../examples/workspace_apply.rb).
|
|
44
|
+
- Validate, plan and load from the `libtmux-workspace` CLI; optionally attach
|
|
45
|
+
or switch an explicit client after creation. `--version` reports the
|
|
46
|
+
installed gem version without reading a configuration or contacting tmux.
|
|
47
|
+
[CLI guide](../../gems/libtmux-workspace/README.md#script-it).
|
|
48
|
+
- Inspect partial application through `ApplyError#result`. Optional
|
|
49
|
+
compensation removes only a positively identified new session after
|
|
50
|
+
checking that its windows and panes belong to the apply operation.
|
|
51
|
+
[Failure results](../../gems/libtmux-workspace/README.md#recover-from-a-failed-apply).
|
data/README.md
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
[Guides](https://libtmux.org/en/ruby/latest/workspace/guides/) ·
|
|
21
21
|
[RubyGems](https://rubygems.org/gems/libtmux-workspace)
|
|
22
22
|
|
|
23
|
+
[](https://libtmux.org/en/ruby/latest/workspace/)
|
|
24
|
+
[](https://rubygems.org/gems/libtmux-workspace)
|
|
25
|
+
|
|
23
26
|
</div>
|
|
24
27
|
|
|
25
28
|
Part of [libtmux for Ruby](https://github.com/libtmux/libtmux-ruby#readme).
|
|
@@ -182,26 +185,47 @@ and never reconciles an existing one.
|
|
|
182
185
|
[`Workspace.load`][workspace-load] reads the file,
|
|
183
186
|
[`workspace.plan`][workspace-plan-method] plans it against a snapshot, and
|
|
184
187
|
`apply` creates the session. Calling `apply` authorizes the configuration's
|
|
185
|
-
shell commands
|
|
188
|
+
shell commands.
|
|
189
|
+
|
|
190
|
+
[The example file](../../examples/api/workspace_apply.rb) writes the same
|
|
191
|
+
document to a temporary `workspace.yaml` before loading it, so it runs saved on
|
|
192
|
+
its own:
|
|
186
193
|
|
|
187
194
|
<!-- example: api_workspace_apply/main -->
|
|
188
195
|
```ruby
|
|
189
196
|
require "libtmux"
|
|
190
197
|
require "libtmux/workspace"
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
require "tmpdir"
|
|
199
|
+
|
|
200
|
+
document = <<~'YAML'
|
|
201
|
+
session_name: work
|
|
202
|
+
environment:
|
|
203
|
+
PROJECT_MODE: development
|
|
204
|
+
windows:
|
|
205
|
+
- window_name: editor
|
|
206
|
+
window_index: 1
|
|
207
|
+
layout: tiled
|
|
208
|
+
panes:
|
|
209
|
+
- shell_command: printf 'editor ready\n'
|
|
210
|
+
- {}
|
|
211
|
+
YAML
|
|
212
|
+
|
|
213
|
+
Dir.mktmpdir("workspace-") do |directory|
|
|
214
|
+
path = File.join(directory, "workspace.yaml")
|
|
215
|
+
File.write(path, document)
|
|
216
|
+
LibTmux::Server.start do |server|
|
|
217
|
+
workspace = LibTmux::Workspace.load(path)
|
|
218
|
+
plan = workspace.plan(snapshot: server.snapshot)
|
|
219
|
+
puts "planned steps: #{plan.steps.length}"
|
|
220
|
+
result = plan.apply(server: server)
|
|
221
|
+
puts "applied: #{result.success?}"
|
|
222
|
+
puts "sessions: #{server.list_sessions.map { |session| session.snapshot.name }.join(', ')}"
|
|
223
|
+
end
|
|
199
224
|
end
|
|
200
225
|
```
|
|
201
226
|
<!-- /example -->
|
|
202
227
|
|
|
203
|
-
The program runs
|
|
204
|
-
prints:
|
|
228
|
+
The program runs on a private server and prints:
|
|
205
229
|
|
|
206
230
|
```text
|
|
207
231
|
planned steps: 11
|
|
@@ -314,9 +338,13 @@ $ libtmux-workspace plan \
|
|
|
314
338
|
workspace.yaml
|
|
315
339
|
```
|
|
316
340
|
|
|
317
|
-
[`load`][cli-load] and `plan --live`
|
|
318
|
-
|
|
319
|
-
`
|
|
341
|
+
[`load`][cli-load] and `plan --live` act on an existing server. Without
|
|
342
|
+
`--socket`, they use the socket in `LIBTMUX_SOCKET_PATH`, else the name in
|
|
343
|
+
`LIBTMUX_SOCKET`, else the server `TMUX` names when run inside tmux, else
|
|
344
|
+
tmux's default socket. When both variables are set, the path wins, an empty
|
|
345
|
+
variable counts as unset, and `--socket` ignores both. A command run from a tmux
|
|
346
|
+
pane with none of these set acts on that pane's server. This detached creation
|
|
347
|
+
example names its socket with a `TMUX_SOCKET` value:
|
|
320
348
|
|
|
321
349
|
```console
|
|
322
350
|
$ libtmux-workspace load \
|
|
@@ -331,7 +359,7 @@ $ libtmux-workspace load \
|
|
|
331
359
|
| Option | Effect |
|
|
332
360
|
| --- | --- |
|
|
333
361
|
| `--json` | Write one structured result or error object to stdout |
|
|
334
|
-
| `--socket PATH` | Select the existing server's socket for `load` or `plan --live` |
|
|
362
|
+
| `--socket PATH` | Select the existing server's socket for `load` or `plan --live`; the default follows the socket variables, then `TMUX`, then tmux's default socket |
|
|
335
363
|
| `--live` | Capture a snapshot before planning |
|
|
336
364
|
| `--timeout SECONDS` | Bound each apply, live capture or switch operation; the default is 5 |
|
|
337
365
|
| `--compensate` | Run guarded cleanup after an apply failure |
|
|
@@ -372,7 +400,10 @@ values by design.
|
|
|
372
400
|
|
|
373
401
|
Releases are numbered `0.1.N`, and each release increments `N`. The API is not
|
|
374
402
|
settled: any release may change or remove exported identifiers, and the
|
|
375
|
-
|
|
403
|
+
changelogs mark each break. Pin an exact version to avoid one.
|
|
404
|
+
See the [changelog](CHANGELOG.md), and the [main
|
|
405
|
+
changelog](https://github.com/libtmux/libtmux-ruby/blob/master/CHANGELOG.md)
|
|
406
|
+
for changes that span gems.
|
|
376
407
|
|
|
377
408
|
- **Ruby 3.3 or newer.** The gem depends on the same version of `libtmux`,
|
|
378
409
|
JSON 3.0 and Psych 5.5.
|
|
@@ -382,8 +413,10 @@ changelog marks each break. Pin an exact version to avoid one.
|
|
|
382
413
|
`error.kind` is `tmux_unsupported`.
|
|
383
414
|
- **Linux, including WSL, and macOS.** The library and the command share the
|
|
384
415
|
core [compatibility workflow][compat]: Ruby 3.3, 3.4 and 4.0 with tmux 3.3a
|
|
385
|
-
through 3.8 on Ubuntu 24.04, with per-revision results.
|
|
386
|
-
|
|
416
|
+
through 3.8 on Ubuntu 24.04, with per-revision results. A push and a pull
|
|
417
|
+
request run the oldest and newest of those releases, 3.3a and 3.8, and a
|
|
418
|
+
release runs all of them. macOS is supported on a best-effort basis, and CI
|
|
419
|
+
coverage for it is highly limited.
|
|
387
420
|
- **History limit.** On tmux 3.3a to 3.6 the reused initial pane keeps the
|
|
388
421
|
global `history-limit`. Set the server's global value before you apply to
|
|
389
422
|
get one history size.
|
|
@@ -85,7 +85,9 @@ module LibTmux
|
|
|
85
85
|
@parser ||= OptionParser.new do |options|
|
|
86
86
|
options.banner = "Usage: libtmux-workspace validate|plan|load [options] [FILE]"
|
|
87
87
|
options.on("--json", "Write structured JSON to stdout") { @json = true }
|
|
88
|
-
options.on("--socket PATH", "
|
|
88
|
+
options.on("--socket PATH", "Socket of the existing tmux server for load or plan --live",
|
|
89
|
+
"Default: LIBTMUX_SOCKET_PATH, then LIBTMUX_SOCKET, then the",
|
|
90
|
+
"server TMUX names, then tmux's default socket") { |value| @options[:socket] = value }
|
|
89
91
|
options.on("--live", "Acquire a snapshot before planning") { @options[:live] = true }
|
|
90
92
|
options.on("--timeout SECONDS", Float, "Per-operation apply/capture/switch deadline (default: 5)") { |value| @options[:timeout] = value }
|
|
91
93
|
options.on("--compensate", "Attempt guarded cleanup of positively created resources on failure") { @options[:compensate] = true }
|
|
@@ -125,7 +127,7 @@ module LibTmux
|
|
|
125
127
|
raise ArgumentError if command != "load" && (@options[:attach] || @options[:switch] || @options[:compensate])
|
|
126
128
|
raise ArgumentError if @options[:live] && command != "plan"
|
|
127
129
|
live = command == "load" || @options[:live]
|
|
128
|
-
raise ArgumentError if
|
|
130
|
+
raise ArgumentError if @options.key?(:socket) && @options[:socket].empty?
|
|
129
131
|
raise ArgumentError if !live && @options[:socket]
|
|
130
132
|
if @options[:attach]
|
|
131
133
|
term = @environment["TERM"]
|
|
@@ -145,7 +147,23 @@ module LibTmux
|
|
|
145
147
|
end
|
|
146
148
|
|
|
147
149
|
def with_server(&block)
|
|
148
|
-
LibTmux::Server.open(
|
|
150
|
+
LibTmux::Server.open(endpoint: endpoint, &block)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# --socket wins; otherwise the core reads the variables, TMUX and tmux's default.
|
|
154
|
+
def endpoint
|
|
155
|
+
socket = @options[:socket]
|
|
156
|
+
LibTmux::Endpoint.new(socket_path: (expand_socket(socket) if socket), environment: @environment)
|
|
157
|
+
rescue ArgumentError => error
|
|
158
|
+
@argument_message = "Invalid arguments: #{error.message}."
|
|
159
|
+
raise
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# File.expand_path puts the user it cannot find in its message.
|
|
163
|
+
def expand_socket(socket)
|
|
164
|
+
File.expand_path(socket, @directory)
|
|
165
|
+
rescue ArgumentError
|
|
166
|
+
raise ArgumentError, "--socket cannot be expanded to a path; its leading ~ names no home directory"
|
|
149
167
|
end
|
|
150
168
|
|
|
151
169
|
def human_plan(plan)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libtmux-workspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- libtmux contributors
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.1.
|
|
18
|
+
version: 0.1.2
|
|
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.2
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: json
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,6 +58,7 @@ executables:
|
|
|
58
58
|
extensions: []
|
|
59
59
|
extra_rdoc_files: []
|
|
60
60
|
files:
|
|
61
|
+
- CHANGELOG.md
|
|
61
62
|
- LICENSE
|
|
62
63
|
- README.md
|
|
63
64
|
- assets/logo.png
|
|
@@ -76,7 +77,8 @@ licenses:
|
|
|
76
77
|
- MIT
|
|
77
78
|
metadata:
|
|
78
79
|
source_code_uri: https://github.com/libtmux/libtmux-ruby
|
|
79
|
-
|
|
80
|
+
changelog_uri: https://github.com/libtmux/libtmux-ruby/blob/master/gems/libtmux-workspace/CHANGELOG.md
|
|
81
|
+
documentation_uri: https://libtmux.org/en/ruby/v0.1.2/workspace/
|
|
80
82
|
rdoc_options: []
|
|
81
83
|
require_paths:
|
|
82
84
|
- lib
|