iterm2_ruby 0.2.0 → 0.3.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: e7e477efa0c27e00e1cb34267975a48402332821b9ae336c55425ad3733e0bab
4
- data.tar.gz: fbb8e0de6adce1dcf2fdca490c36bde11f1b652755d49d2520d18d33468b5be1
3
+ metadata.gz: 7ea8b3aab793d0294a0cb9f726e8cc01123b0da6a22b02034a7f64c3e4744959
4
+ data.tar.gz: 3773d06e8c6969221bb52049ff3a11131a786f8280d36e3f5a889174c3a56d17
5
5
  SHA512:
6
- metadata.gz: 9ce8e36e0bc21000133f8d6fa0cc037aed5902812a298e5732e7865452a7f7b10fe1917882cf94d861bf55be6d83dc1bb39dce826d0bbf50d6f194b768fbe1f6
7
- data.tar.gz: b2bbc939e3c51138ff675655f2a9ba421fdba58ae0e2250c64640d91f5096315c3ef0f9283f07b53269fe5c9d555f587e9b16203d26df469f620756cd792fbd2
6
+ metadata.gz: ecff09efcb6229d0079eff7f8cc324fb0da17287c762f39fb1e99ada8c2476283373ed6ef48c097c3c36f6fe87346485c3b311133f0ca45be22e5f60940da729
7
+ data.tar.gz: 143e8af32d29624720bb35719eb399e620364c0e632bc5613ea710190acd0c8a5b8c3112a150db5794ff8da1968a6c39d38d1288626366ee9231ddf9810c63f5
data/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project are documented here. Format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## [0.3.1] - 2026-09-04
7
+
8
+ ### Fixed
9
+ - `client.get_window_frame(window_id)` restored under its documented name. A local
10
+ amend of the 0.3.0 commit (made before publish, after this method had already been
11
+ verified) silently renamed it to `client.window_frame`; the published 0.3.0 gem on
12
+ rubygems only exposes `window_frame` and lacks `get_window_frame`. Source is fixed
13
+ here; the published artifact is fixed by the next release.
14
+
15
+ ## [0.3.0] - 2026-09-03
16
+
17
+ ### Added
18
+ - `client.set_property`/`get_property` counterpart -- `client.set_property(name, value, session_id:, window_id:)`
19
+ - `client.window_frame(window_id)` / `client.set_window_frame(window_id, x:, y:, width:, height:)` --
20
+ windows created via `create_tab`/`split_pane` open at the profile's default size regardless of content;
21
+ this is the only way to move/resize one afterward.
22
+ - `client.set_session_grid_size(session_id, columns:, rows:)` -- resize a session's character grid
23
+ - CLI: `set-window-frame WINDOW_ID X Y WIDTH HEIGHT`, `get-window-frame WINDOW_ID [--json]`
24
+
6
25
  ## [0.2.0] - 2026-07-02
7
26
 
8
27
  ### Added
data/README.md CHANGED
@@ -156,6 +156,8 @@ end
156
156
  | `raise --cwd PATH` | Raise tab by working directory |
157
157
  | `activate-session ID` | Activate a session directly by ID |
158
158
  | `create [window\|tab]` | Create a new window or tab |
159
+ | `set-window-frame ID X Y W H` | Move/resize a window (pixels) |
160
+ | `get-window-frame ID` | Read a window's frame (pixels) |
159
161
  | `split` | Split the current pane |
160
162
  | `close` | Close a session |
161
163
  | `move --tab ID --to-window ID` | Move a tab to another window |
@@ -215,6 +217,9 @@ Most commands accept `--session ID`, `--tab ID`, or `--window ID` to target a sp
215
217
  | `close_session(session_id)` | Close a session |
216
218
  | `close_tab(tab_id)` | Close a tab |
217
219
  | `reorder_tabs(window_id => [tab_ids])` | Move/reorder tabs across windows |
220
+ | `window_frame(window_id)` | Get a window's frame (position + size, pixels) |
221
+ | `set_window_frame(window_id, x:, y:, width:, height:)` | Move/resize a window (pixels) |
222
+ | `set_session_grid_size(session_id, columns:, rows:)` | Set a session's grid size (columns/rows) |
218
223
 
219
224
  ### Profile & Properties
220
225
 
@@ -224,6 +229,7 @@ Most commands accept `--session ID`, `--tab ID`, or `--window ID` to target a sp
224
229
  | `get_profile_property(session_id, *keys)` | Get profile properties |
225
230
  | `list_profiles(properties:, guids:)` | List all profiles |
226
231
  | `get_property(name, session_id:)` | Get a session/window property |
232
+ | `set_property(name, value, session_id:)` | Set a session/window property |
227
233
  | `get_variables(*names, session_id:)` | Get variables |
228
234
  | `set_variables(vars, session_id:)` | Set user variables |
229
235
  | `focus` | Get current focus state |
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bundler/gem_tasks"
3
4
  require "rspec/core/rake_task"
4
5
 
5
6
  RSpec::Core::RakeTask.new(:spec)
data/bin/iterm2ctl CHANGED
@@ -21,20 +21,22 @@ module ITerm2CTL
21
21
  when "read-screen" then cmd_read_screen(args)
22
22
  when "raise" then cmd_raise(args)
23
23
  when "activate-session" then cmd_activate_session(args)
24
- when "create" then cmd_create(args)
25
- when "split" then cmd_split(args)
26
- when "close" then cmd_close(args)
27
- when "move" then cmd_move(args)
28
- when "var" then cmd_var(args)
29
- when "info" then cmd_info(args)
30
- when "focus" then cmd_focus(args)
31
- when "prompt" then cmd_prompt(args)
32
- when "watch" then cmd_watch(args)
33
- when "profile" then cmd_profile(args)
34
- when "inject" then cmd_inject(args)
35
- when "profiles" then cmd_profiles(args)
36
- when "version" then puts "iterm2ctl #{ITerm2::VERSION}"
37
- when "help", nil then usage
24
+ when "create" then cmd_create(args)
25
+ when "set-window-frame" then cmd_set_window_frame(args)
26
+ when "get-window-frame" then cmd_get_window_frame(args)
27
+ when "split" then cmd_split(args)
28
+ when "close" then cmd_close(args)
29
+ when "move" then cmd_move(args)
30
+ when "var" then cmd_var(args)
31
+ when "info" then cmd_info(args)
32
+ when "focus" then cmd_focus(args)
33
+ when "prompt" then cmd_prompt(args)
34
+ when "watch" then cmd_watch(args)
35
+ when "profile" then cmd_profile(args)
36
+ when "inject" then cmd_inject(args)
37
+ when "profiles" then cmd_profiles(args)
38
+ when "version" then puts "iterm2ctl #{ITerm2::VERSION}"
39
+ when "help", nil then usage
38
40
  else
39
41
  $stderr.puts "Unknown command: #{command}"
40
42
  usage
@@ -73,6 +75,8 @@ module ITerm2CTL
73
75
  activate-session ID Activate a session directly
74
76
  raise --cwd PATH Raise tab by working directory
75
77
  create [window|tab] Create a new window or tab
78
+ set-window-frame ID X Y W H Move/resize a window (pixels)
79
+ get-window-frame ID Read a window's frame (pixels)
76
80
  split [--session ID] Split the current pane
77
81
  close [--session ID] Close a session
78
82
  move --tab ID --to-window ID Move a tab to another window
@@ -310,6 +314,40 @@ module ITerm2CTL
310
314
  end
311
315
  end
312
316
 
317
+ def cmd_set_window_frame(args)
318
+ window_id, *numbers = args
319
+ x, y, w, h = numbers.map { |n| Integer(n, exception: false) }
320
+
321
+ if window_id.nil? || numbers.size != 4 || [x, y, w, h].any?(&:nil?)
322
+ $stderr.puts "Usage: iterm2ctl set-window-frame WINDOW_ID X Y WIDTH HEIGHT"
323
+ exit 1
324
+ end
325
+
326
+ ITerm2.connect do |client|
327
+ client.set_window_frame(window_id, x: x, y: y, width: w, height: h)
328
+ puts "Set frame for window #{window_id}: #{w}x#{h} at (#{x}, #{y})"
329
+ end
330
+ end
331
+
332
+ def cmd_get_window_frame(args)
333
+ window_id = args.shift
334
+ json_mode = args.delete("--json")
335
+
336
+ if window_id.nil?
337
+ $stderr.puts "Usage: iterm2ctl get-window-frame WINDOW_ID [--json]"
338
+ exit 1
339
+ end
340
+
341
+ ITerm2.connect do |client|
342
+ frame = client.get_window_frame(window_id)
343
+ if json_mode
344
+ puts JSON.pretty_generate(frame)
345
+ else
346
+ puts "x=#{frame[:x]} y=#{frame[:y]} width=#{frame[:width]} height=#{frame[:height]}"
347
+ end
348
+ end
349
+ end
350
+
313
351
  def cmd_split(args)
314
352
  opts = parse_target_opts(args)
315
353
  vertical = !args.delete("--horizontal")
data/docs/api.md CHANGED
@@ -211,6 +211,39 @@ client.reorder_tabs("window_1" => ["tab_a", "tab_b"])
211
211
 
212
212
  ---
213
213
 
214
+ ## Window Frame
215
+
216
+ iTerm2 opens windows created via `create_tab`/`split_pane` at the profile's default
217
+ size, regardless of what's inside them. These wrap the `"frame"`/`"grid_size"`
218
+ `SetProperty`/`GetProperty` conventions so callers can size a window explicitly.
219
+
220
+ ### `client.get_window_frame(window_id)` -> Hash
221
+
222
+ ```ruby
223
+ { x: Numeric, y: Numeric, width: Numeric, height: Numeric } # pixels
224
+ ```
225
+
226
+ **Raises:** `RPCError` on failure (e.g. bogus `window_id`).
227
+
228
+ ### `client.set_window_frame(window_id, x:, y:, width:, height:)` -> true
229
+
230
+ Moves and resizes a window. All values are pixels.
231
+
232
+ ```ruby
233
+ client.set_window_frame(window_id, x: 0, y: 0, width: 1200, height: 800)
234
+ ```
235
+
236
+ **Raises:** `RPCError` on failure.
237
+
238
+ ### `client.set_session_grid_size(session_id, columns:, rows:)` -> true
239
+
240
+ Resizes a session's character grid (columns x rows), distinct from `set_window_frame`
241
+ which sizes the window in pixels.
242
+
243
+ **Raises:** `RPCError` on failure.
244
+
245
+ ---
246
+
214
247
  ## Profile & Properties
215
248
 
216
249
  ### `client.set_profile_property(session_id, key, value)` -> true | false
@@ -250,8 +283,18 @@ client.list_profiles(properties: ["Name", "Guid"])
250
283
  Gets a named property from a session or window. Returns the JSON-decoded value.
251
284
 
252
285
  ```ruby
253
- client.get_property("columns", session_id: sid) # => 120
254
- client.get_property("frame", window_id: wid) # => {"origin" => {...}, "size" => {...}}
286
+ client.get_property("grid_size", session_id: sid) # => {"width" => 80, "height" => 25}
287
+ client.get_property("frame", window_id: wid) # => {"origin" => {...}, "size" => {...}}
288
+ ```
289
+
290
+ **Raises:** `RPCError` on failure.
291
+
292
+ ### `client.set_property(name, value, session_id: nil, window_id: nil)` -> true
293
+
294
+ Sets a named property on a session or window. `value` is JSON-encoded before sending.
295
+
296
+ ```ruby
297
+ client.set_property("frame", {origin: {x: 0, y: 0}, size: {width: 800, height: 600}}, window_id: wid)
255
298
  ```
256
299
 
257
300
  **Raises:** `RPCError` on failure.
data/docs/cli.md CHANGED
@@ -111,6 +111,28 @@ iterm2ctl create tab --window W123... # new tab in specific window
111
111
  iterm2ctl create tab --profile "Custom" # new tab with profile
112
112
  ```
113
113
 
114
+ ### `set-window-frame`
115
+
116
+ Move and resize a window. Values are pixels.
117
+
118
+ ```bash
119
+ iterm2ctl set-window-frame W123... 0 0 1200 800
120
+ ```
121
+
122
+ ### `get-window-frame`
123
+
124
+ Read a window's current frame.
125
+
126
+ ```bash
127
+ iterm2ctl get-window-frame W123... # x=0 y=0 width=1200 height=800
128
+ iterm2ctl get-window-frame W123... --json # {
129
+ # "x": 0,
130
+ # "y": 0,
131
+ # "width": 1200,
132
+ # "height": 800
133
+ # }
134
+ ```
135
+
114
136
  ### `split`
115
137
 
116
138
  Split the current pane.
data/lib/iterm2/client.rb CHANGED
@@ -383,7 +383,7 @@ module ITerm2
383
383
  end
384
384
  end
385
385
 
386
- # --- GetProperty ---
386
+ # --- GetProperty / SetProperty ---
387
387
 
388
388
  def get_property(name, session_id: nil, window_id: nil)
389
389
  req = Proto::GetPropertyRequest.new(name: name)
@@ -396,6 +396,42 @@ module ITerm2
396
396
  JSON.parse(resp.json_value)
397
397
  end
398
398
 
399
+ def set_property(name, value, session_id: nil, window_id: nil)
400
+ req = Proto::SetPropertyRequest.new(name: name, json_value: JSON.dump(value))
401
+ req.session_id = session_id if session_id
402
+ req.window_id = window_id if window_id
403
+
404
+ resp = request(:set_property_request, req).set_property_response
405
+ raise RPCError, "SetProperty failed: #{resp.status}" unless resp.status == :OK
406
+
407
+ true
408
+ end
409
+
410
+ # --- Window Frame ---
411
+ # Windows open at the profile's default size regardless of content; these
412
+ # size one explicitly via the "frame"/"grid_size" SetProperty/GetProperty
413
+ # conventions (see proto/api.proto).
414
+
415
+ def get_window_frame(window_id)
416
+ origin, size = get_property("frame", window_id: window_id).values_at("origin", "size")
417
+ { x: origin["x"], y: origin["y"], width: size["width"], height: size["height"] }
418
+ end
419
+
420
+ def set_window_frame(window_id, x:, y:, width:, height:)
421
+ set_property(
422
+ "frame",
423
+ { "origin" => { "x" => x, "y" => y }, "size" => { "width" => width, "height" => height } },
424
+ window_id: window_id
425
+ )
426
+ end
427
+
428
+ # Resizes a session's character grid (columns x rows). Distinct from
429
+ # set_window_frame -- this sizes the text grid a session renders, in
430
+ # cells rather than points.
431
+ def set_session_grid_size(session_id, columns:, rows:)
432
+ set_property("grid_size", { "width" => columns, "height" => rows }, session_id: session_id)
433
+ end
434
+
399
435
  # --- Notifications ---
400
436
 
401
437
  def subscribe(notification_type, session_id: nil, &callback)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ITerm2
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.1"
5
5
  end
data/llms.txt CHANGED
@@ -66,6 +66,7 @@ States: `:editing`, `:running`, `:at_prompt`, `:unavailable`.
66
66
  `topology_enriched`, `list_sessions`, `activate_tab`, `activate_window`,
67
67
  `raise_by_cwd`, `create_tab`, `split_pane`, `close_session`, `close_tab`,
68
68
  `set_profile_property`, `get_profile_property`, `list_profiles`, `get_property`,
69
+ `set_property`, `window_frame`, `set_window_frame`, `set_session_grid_size`,
69
70
  `get_variables`, `set_variables`, `inject`, `reorder_tabs`, `topology_for_aggregator`.
70
71
 
71
72
  ## Notifications
@@ -90,6 +91,8 @@ iterm2ctl focus # show focus state
90
91
  iterm2ctl info # show session details
91
92
  iterm2ctl move --tab ID --to-window ID # move tab between windows
92
93
  iterm2ctl watch # stream events as JSON
94
+ iterm2ctl set-window-frame ID X Y W H # move/resize a window (pixels)
95
+ iterm2ctl get-window-frame ID # read a window's frame (pixels)
93
96
  ```
94
97
 
95
98
  Most commands accept `--session ID`, `--tab ID`, `--window ID`, `--json`.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iterm2_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Forrest Chang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-02 00:00:00.000000000 Z
11
+ date: 2026-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf