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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66d96c81c6ee85c0bc75c616571fd4a8184bdec03117d48424898a6bc5ca7513
4
- data.tar.gz: f6677029749a5f5d3eeeea3e1df64a3f78d44243917d1192007de6db8ae2157a
3
+ metadata.gz: 81a6e6bcb2e2b40052ea69a7ac812919bc40c061eff86d8f1ed24d74db1bdd89
4
+ data.tar.gz: bed554f76a48119e57294fa4199479ce7d9ce1e9864d9a3189224daa11979be7
5
5
  SHA512:
6
- metadata.gz: 741f07d62607be8fc81a90c88ff66f69addad12bb7dcbd196059563e4635d629f326048b878ff21d298fb1e00f3b0ef8b862a2c7a5cad88ce054be0727251598
7
- data.tar.gz: 470f30b5b38a41c8dc4922b59d205c8ef88119838d0f68eedaba1157b1187b14d81fb45cef815afb15305b1cb23f56e67585ffb8b7e7ad90788ee71bed770144
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
+ [![libtmux.org](https://img.shields.io/badge/docs-libtmux.org-0b7285)](https://libtmux.org/en/ruby/latest/workspace/)
24
+ [![libtmux-workspace](https://img.shields.io/gem/v/libtmux-workspace?label=libtmux-workspace)](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
- LibTmux::Server.start do |server|
193
- workspace = LibTmux::Workspace.load(File.expand_path("../workspace.yaml", __dir__))
194
- plan = workspace.plan(snapshot: server.snapshot)
195
- puts "planned steps: #{plan.steps.length}"
196
- result = plan.apply(server: server)
197
- puts "applied: #{result.success?}"
198
- puts "sessions: #{server.list_sessions.map { |session| session.snapshot.name }.join(', ')}"
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 next to the `workspace.yaml` above, on a private server, and
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` require `--socket` for an existing
318
- server. This detached creation example uses an explicitly supplied
319
- `TMUX_SOCKET` value:
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
- changelog marks each break. Pin an exact version to avoid one.
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. macOS is supported on
386
- a best-effort basis, and CI coverage for it is highly limited.
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", "Explicit existing tmux socket for load or plan --live") { |value| @options[:socket] = value }
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 live && (!@options[:socket].is_a?(String) || @options[:socket].empty?)
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(socket_path: File.expand_path(@options.fetch(:socket), @directory), &block)
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)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module LibTmux
4
4
  class Workspace
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  end
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.0
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.0
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.0
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
- documentation_uri: https://libtmux.org/en/ruby/v0.1.0/workspace/
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