ace-tmux 0.11.2 → 0.14.3

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: 9ea74f6180f273e9190b38ec92b90c59b7c6ea379e849ce1294b93ae25a6cee4
4
- data.tar.gz: fea5f9376872d9ab0cf9f9d4504ab1866931131c320e0678491467dffde577e7
3
+ metadata.gz: 42e752d75968cab4e3af63e513247dd29b626e28f1ac0c88847c7fe036726df4
4
+ data.tar.gz: 9b4aad5052e103fe757001d03d487cb221d4af0c989af41097c11d3db4cad1ea
5
5
  SHA512:
6
- metadata.gz: 75a941be03f8588a5710f12e6d457ce204d1c80a6b538687855391dbd4501429d3b2087a0236740e661c21cf87c436c5d33d22d40b9bc2cc33a47c7a0782f0d5
7
- data.tar.gz: 782c0f5ecf18f99317a180756190bff21511c3e619d403620452b0b360832ba0c89aca3e8634732df553e28f01e77e3211455228cf784a29c3406056cdbf4e57
6
+ metadata.gz: 2f5de2adedeccbc4acb9cb1d876ececc32be10255b967daf764888b484d4af5fe02f26662f5979fc8978f0766f62f24faf0c32bb6915aeee3b42094235a3b001
7
+ data.tar.gz: d1b4c69d036364e760299cde7ac47a3540d7889e51b4e053683d4b18e75afe39813bfdda22fbb30e5c4294153200006899b8f6e141fe58f3bbc2d1dc35e3a7a0
data/CHANGELOG.md CHANGED
@@ -7,6 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.3] - 2026-04-16
11
+
12
+ ### Technical
13
+ - Hardened retained tmux preset and existing-session E2E verification to avoid false missing-artifact requirements and to accept stable session continuity evidence across lifecycle commands.
14
+
15
+ ## [0.14.2] - 2026-04-16
16
+
17
+ ### Technical
18
+ - Relaxed existing-session E2E verification to judge session reuse from lifecycle continuity and captured state instead of brittle wording differences in tmux output.
19
+
20
+ ## [0.14.1] - 2026-04-16
21
+
22
+ ### Fixed
23
+ - Routed tmux commands through an explicit sandbox socket path and enforced safe socket-directory permissions so isolated E2E sessions can be reused reliably.
24
+
25
+ ## [0.14.0] - 2026-04-15
26
+
27
+ ### Added
28
+ - Added `TS-TMUX-002` to validate the outside-tmux `ace-tmux window --session` public workflow with explicit success and constrained-execution branches.
29
+
30
+ ### Changed
31
+ - Expanded `TS-TMUX-001` with an existing-session lifecycle goal and tightened goal-style verifier contracts for preset/start/window evidence continuity.
32
+ - Clarified outside-tmux session-targeting usage in command help and usage documentation.
33
+
34
+ ## [0.13.0] - 2026-04-13
35
+
36
+ ### Added
37
+ - Added `ace-tmux start --name` so one preset can launch multiple concurrent tmux sessions with explicit runtime names.
38
+
39
+ ### Changed
40
+ - Tightened the tmux management E2E contract to require isolated run-scoped sessions and explicit cleanup instead of mutating the current tmux session.
41
+
42
+ ## [0.12.1] - 2026-04-13
43
+
44
+ ### Changed
45
+ - Completed the batch i05 migration follow-through for this package and aligned it with the restarted `fast` / `feat` / `e2e` verification model.
46
+
47
+ ### Technical
48
+ - Included in the coordinated assignment-driven patch release for batch i05 package updates.
49
+
50
+
51
+ ## [0.12.0] - 2026-04-12
52
+
53
+ ### Changed
54
+ - Migrated deterministic tests to the restarted layout under `test/fast/` and updated E2E scenario metadata to reference the new deterministic paths.
55
+ - Added explicit package testing contract guidance for `ace-test ace-tmux`, `ace-test ace-tmux feat`, `ace-test ace-tmux all`, and `ace-test-e2e ace-tmux` in README and docs.
56
+
57
+ ## [0.11.3] - 2026-03-29
58
+
59
+ ### Technical
60
+ - Normalized published gem metadata so RubyGems and Ruby Toolbox use current release information instead of the 1980 fallback date.
61
+
10
62
 
11
63
  ## [0.11.2] - 2026-03-29
12
64
 
data/README.md CHANGED
@@ -21,12 +21,12 @@
21
21
  ## How It Works
22
22
 
23
23
  1. Define session and window layouts in YAML presets stored in `.ace/tmux/` (project), `~/.ace/tmux/` (user), or gem defaults.
24
- 2. Run `ace-tmux start [PRESET]` to create a full session or `ace-tmux window [PRESET]` to inject a window into the current session.
24
+ 2. Run `ace-tmux start [PRESET]` to create a full session or `ace-tmux window [PRESET]` to inject a window into the current session. Use `ace-tmux start ... --name <session>` when you need multiple concurrent sessions from the same preset.
25
25
  3. Presets are deep-merged through the config cascade, so project-level overrides layer cleanly on top of shared defaults.
26
26
 
27
27
  ## Use Cases
28
28
 
29
- **Start or attach to a preset-backed session** - run `ace-tmux start [PRESET]` to create a session from YAML presets, or attach to an existing session with the same name, integrating panes for [ace-task](../ace-task) status, [ace-git](../ace-git) info, and editor windows.
29
+ **Start or attach to a preset-backed session** - run `ace-tmux start [PRESET]` to create a session from YAML presets, or attach to an existing session with the same name, integrating panes for [ace-task](../ace-task) status, [ace-git](../ace-git) info, and editor windows. Add `--name` to reuse the preset under a different runtime session name.
30
30
 
31
31
  **Inject windows into running sessions** - run `ace-tmux window [PRESET]` to add a new window from presets without recreating the current session, useful for spinning up focused tool or test panes on the fly.
32
32
 
@@ -36,5 +36,12 @@
36
36
 
37
37
  **Orchestrate task-focused workspaces** - pair with [ace-overseer](../ace-overseer) and [ace-assign](../ace-assign) for assignment-driven worktree and tmux orchestration that spins up isolated workspaces per task.
38
38
 
39
+ ## Testing
40
+
41
+ - `ace-test ace-tmux` runs deterministic fast-layer tests under `test/fast/`.
42
+ - `ace-test ace-tmux feat` runs deterministic feature tests when `test/feat/` coverage exists.
43
+ - `ace-test ace-tmux all` runs full package deterministic coverage.
44
+ - `ace-test-e2e ace-tmux` runs retained workflow scenarios under `test/e2e/`.
45
+
39
46
  ---
40
47
  [Getting Started](docs/getting-started.md) | [Usage Guide](docs/usage.md) | [Handbook - Skills, Agents, Templates](docs/handbook.md) | Part of [ACE](https://github.com/cs3b/ace)
@@ -26,6 +26,9 @@ Run: `ace-tmux start`.
26
26
 
27
27
  `ace-tmux` resolves the default session preset from `defaults.session` in config.
28
28
 
29
+ For parallel workspaces from the same preset, use a custom runtime session name:
30
+ `ace-tmux start default --detach --name review-sandbox`.
31
+
29
32
  ## Add a Window to a Running Session
30
33
 
31
34
  From inside tmux, run: `ace-tmux window`.
@@ -83,4 +86,5 @@ Use it in a session or add it directly with `ace-tmux window cc`.
83
86
 
84
87
  - Define project-level presets in `.ace/tmux/`.
85
88
  - Override personal defaults in `~/.ace/tmux/`.
89
+ - Validate package tests with `ace-test ace-tmux` and `ace-test-e2e ace-tmux`.
86
90
  - See [Usage Guide](usage.md) for full command and config reference.
data/docs/usage.md CHANGED
@@ -26,12 +26,14 @@ Examples:
26
26
  - `ace-tmux start` uses `defaults.session`
27
27
  - `ace-tmux start dev`
28
28
  - `ace-tmux start dev --detach`
29
+ - `ace-tmux start dev --detach --name qa-dev`
29
30
  - `ace-tmux start dev --force`
30
31
 
31
32
  Options:
32
33
 
33
34
  - `--detach`, `-D`: do not attach after creation
34
35
  - `--force`: kill existing session and recreate it
36
+ - `--name`, `-n`: override the runtime tmux session name
35
37
  - `--root`, `-r`: override session working directory
36
38
  - `--verbose`, `-v`: verbose output
37
39
  - `--quiet`, `-q`: suppress non-essential output
@@ -40,6 +42,7 @@ Behavior notes:
40
42
 
41
43
  - If session exists, `--force` is not set, and `--detach` is not set, `start` attaches to the existing session.
42
44
  - If session exists, `--force` is not set, and `--detach` is set, `start` returns without attaching.
45
+ - `--name` changes the tmux session name used at runtime without changing which preset is loaded.
43
46
  - If no preset is provided, `defaults.session` is used.
44
47
 
45
48
  ## `ace-tmux window`
@@ -51,6 +54,7 @@ Examples:
51
54
  - `ace-tmux window` uses `defaults.window`
52
55
  - `ace-tmux window cc`
53
56
  - `ace-tmux window cc --session dev`
57
+ - `ace-tmux window cc --session dev` (outside tmux path)
54
58
  - `ace-tmux window cc --root ~/work/repo`
55
59
 
56
60
  Options:
@@ -195,3 +199,10 @@ Chained preset references are supported (depth-limited).
195
199
 
196
200
  - [Getting Started](getting-started.md)
197
201
  - [Handbook Reference](handbook.md)
202
+
203
+ ## Testing Contract
204
+
205
+ - `ace-test ace-tmux` validates deterministic fast coverage in `test/fast/`.
206
+ - `ace-test ace-tmux feat` validates deterministic feature coverage in `test/feat/` when present.
207
+ - `ace-test ace-tmux all` validates full deterministic package coverage.
208
+ - `ace-test-e2e ace-tmux` runs workflow scenarios in `test/e2e/`.
@@ -33,6 +33,7 @@ module Ace
33
33
  "default # Start default session",
34
34
  "dev # Start dev session",
35
35
  "dev --detach # Create without attaching",
36
+ "dev --detach --name qa # Create under a custom session name",
36
37
  "dev --force # Kill existing and recreate"
37
38
  ]
38
39
 
@@ -40,6 +41,7 @@ module Ace
40
41
 
41
42
  option :detach, type: :boolean, aliases: %w[-D], desc: "Don't attach after creating session"
42
43
  option :force, type: :boolean, desc: "Kill existing session and recreate"
44
+ option :name, type: :string, aliases: %w[-n], desc: "Override the tmux session name"
43
45
  option :root, type: :string, aliases: %w[-r], desc: "Working directory for the session"
44
46
  option :verbose, type: :boolean, aliases: %w[-v], desc: "Show verbose output"
45
47
  option :quiet, type: :boolean, aliases: %w[-q], desc: "Suppress non-essential output"
@@ -64,14 +66,16 @@ module Ace
64
66
  tmux: tmux_bin
65
67
  )
66
68
 
67
- puts "Starting session '#{preset}'..." unless options[:quiet]
69
+ session_name = options[:name] || preset
70
+ puts "Starting session '#{session_name}'..." unless options[:quiet]
68
71
  manager.start(
69
72
  preset,
70
73
  detach: options[:detach] || false,
71
74
  force: options[:force] || false,
75
+ name: options[:name],
72
76
  root: options[:root]
73
77
  )
74
- puts "Session '#{preset}' created." if options[:detach] && !options[:quiet]
78
+ puts "Session '#{session_name}' created." if options[:detach] && !options[:quiet]
75
79
  rescue Ace::Tmux::PresetNotFoundError => e
76
80
  raise Ace::Support::Cli::Error.new(e.message)
77
81
  end
@@ -22,13 +22,13 @@ module Ace
22
22
  # Add code-editor window to current session
23
23
  $ ace-tmux window code-editor
24
24
 
25
- # Add to a specific session
25
+ # Outside tmux, target a specific session explicitly
26
26
  $ ace-tmux window code-editor --session dev
27
27
  DESC
28
28
 
29
29
  example [
30
30
  "code-editor # Add to current session",
31
- "code-editor -s dev # Add to specific session"
31
+ "code-editor -s dev # Outside tmux path: add to specific session"
32
32
  ]
33
33
 
34
34
  argument :preset, required: false, desc: "Window preset name (default: from config)"
@@ -7,7 +7,7 @@ module Ace
7
7
  class Session
8
8
  attr_reader :name, :root, :windows, :pre_window, :startup_window,
9
9
  :on_project_start, :on_project_exit, :attach, :tmux_options
10
- attr_writer :root
10
+ attr_writer :name, :root
11
11
 
12
12
  # @param name [String] Session name
13
13
  # @param root [String, nil] Base working directory
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "fileutils"
3
4
  require "open3"
4
-
5
5
  module Ace
6
6
  module Tmux
7
7
  module Molecules
@@ -17,7 +17,7 @@ module Ace
17
17
  # @param cmd [Array<String>] Command array
18
18
  # @return [ExecutionResult] Result with stdout, stderr, success?
19
19
  def capture(cmd)
20
- stdout, stderr, status = Open3.capture3(*cmd)
20
+ stdout, stderr, status = Open3.capture3(*with_socket_target(cmd))
21
21
  ExecutionResult.new(
22
22
  stdout: stdout.strip,
23
23
  stderr: stderr.strip,
@@ -31,7 +31,7 @@ module Ace
31
31
  # @param cmd [Array<String>] Command array
32
32
  # @return [Boolean] true if command succeeded
33
33
  def run(cmd)
34
- system(*cmd)
34
+ system(*with_socket_target(cmd))
35
35
  end
36
36
 
37
37
  # Replace current process with command (for tmux attach)
@@ -39,7 +39,7 @@ module Ace
39
39
  # @param cmd [Array<String>] Command array
40
40
  # @return [void] Never returns (replaces process)
41
41
  def exec(cmd)
42
- Kernel.exec(*cmd)
42
+ Kernel.exec(*with_socket_target(cmd))
43
43
  end
44
44
 
45
45
  # Check if tmux is available
@@ -52,6 +52,33 @@ module Ace
52
52
  rescue Errno::ENOENT
53
53
  false
54
54
  end
55
+
56
+ private
57
+
58
+ def with_socket_target(cmd)
59
+ return cmd unless tmux_command?(cmd)
60
+
61
+ socket = explicit_socket_path
62
+ return cmd unless socket
63
+
64
+ socket_dir = File.dirname(socket)
65
+ FileUtils.mkdir_p(socket_dir)
66
+ FileUtils.chmod(0o700, socket_dir)
67
+ executable, *rest = cmd
68
+ [executable, "-S", socket, *rest]
69
+ end
70
+
71
+ def tmux_command?(cmd)
72
+ Array(cmd).first == "tmux"
73
+ end
74
+
75
+ def explicit_socket_path
76
+ base = ENV["TMUX_TMPDIR"].to_s.strip
77
+ base = ENV["XDG_RUNTIME_DIR"].to_s.strip if base.empty?
78
+ return nil if base.empty?
79
+
80
+ File.join(base, "tmux-#{Process.uid}", "default")
81
+ end
55
82
  end
56
83
 
57
84
  # Immutable result of a tmux command execution
@@ -30,10 +30,12 @@ module Ace
30
30
  # @param preset_name [String] Session preset name
31
31
  # @param detach [Boolean] Skip attach after creation
32
32
  # @param force [Boolean] Kill existing session and recreate
33
+ # @param name [String, nil] Override runtime tmux session name
33
34
  # @param root [String, nil] Override working directory for the session
34
35
  # @return [void]
35
- def start(preset_name, detach: false, force: false, root: nil)
36
+ def start(preset_name, detach: false, force: false, name: nil, root: nil)
36
37
  session = @session_builder.build(preset_name)
38
+ session.name = name if name
37
39
  session.root = root if root
38
40
 
39
41
  if session_exists?(session.name)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ace
4
4
  module Tmux
5
- VERSION = '0.11.2'
5
+ VERSION = '0.14.3'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-tmux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.14.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2026-04-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-support-cli