tarazed 0.2.0 → 0.2.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: 9aca479c6fefe50cf31a19a4d9f2ee2e9ccda43c41737accfc7d4297fd68df34
4
- data.tar.gz: e877aa139fc517da68b0214e3b76e9f0b87d7d8277cc096370c451153a8463ca
3
+ metadata.gz: e7770f7ce8eac23698c2c294317d339ac24135b86b9f8203ee43f63229c1c4d4
4
+ data.tar.gz: d3aecd412f31417f961d10e07b683c07d2feeea3d5596b8d6218fde0a01e117d
5
5
  SHA512:
6
- metadata.gz: 264107d5d55ddb7f21f95c973c6211113eebe67e25b64c24c3c1b5810b31b93231b7e6297e9c5143fd39f3d3496f66e7539e8a43863e379cbdd0fefa4279fbf6
7
- data.tar.gz: b6af96ac20098f3b52aa9642be6550aa35a4c0a37cc0ab9cf5775f86d0e717e819e3dcbb9dbb509f63fb324761ae1b4e2b4019ac9c7fb7a3717b0859b3104dbf
6
+ metadata.gz: 5c6164054701b25e94dac45e3cd5359126f591d450a9ad1c817b9e2537c3117f77286c23354cc9a1b5585d7e991ca919f29085f5fcbab1d414305e97358f0e2a
7
+ data.tar.gz: 660218a61bf1017d59d90219d9beb040847ccaa8154b2f5dabdca23a0dff72d30a92e4537619a32808dec6d9ea65d64b5c67281e618f389d7978d3ab9c38d7d5
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.1 - 2026-09-16
6
+
7
+ - Report and cache natural Windows ConPTY process exit status through the cross-platform `PTY#status` API.
8
+
5
9
  ## 0.2.0 - 2026-09-16
6
10
 
7
11
  - Track OSC 133 command boundaries, input, output rows, exit status, and OSC 7 working directories in bounded history.
data/README.md CHANGED
@@ -1,9 +1,40 @@
1
- # Tarazed
1
+ <h1 align="center">Tarazed</h1>
2
+
3
+ <p align="center">
4
+ <strong>Pure Ruby terminal emulator core</strong>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://rubygems.org/gems/tarazed"><img src="https://img.shields.io/gem/v/tarazed.svg?colorB=319e8c" alt="Gem Version"></a>
9
+ <a href="https://rubygems.org/gems/tarazed"><img src="https://img.shields.io/gem/dt/tarazed.svg" alt="Downloads"></a>
10
+ <img src="https://img.shields.io/badge/ruby-%3E%3D%203.1-ruby.svg" alt="Ruby Version">
11
+ <a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
12
+ </p>
13
+
14
+ <p align="center">
15
+ <a href="#features">Features</a> ·
16
+ <a href="#installation">Installation</a> ·
17
+ <a href="#quick-start">Quick Start</a> ·
18
+ <a href="#pty-sessions">PTY Sessions</a> ·
19
+ <a href="#command-history">Command History</a> ·
20
+ <a href="#shell-integration">Shell Integration</a>
21
+ </p>
22
+
23
+ ---
2
24
 
3
25
  Tarazed is a pure Ruby terminal emulator core. It provides the
4
26
  terminal cell grid, scrollback, VT parser, keyboard/mouse encoding, and a
5
27
  POSIX or Windows ConPTY session without depending on an editor or UI toolkit.
6
28
 
29
+ ## Features
30
+
31
+ - Unicode-aware cell grid with bounded scrollback
32
+ - Chunk-safe VT parsing for terminal controls, input, links, and selection
33
+ - Keyboard, mouse, bracketed-paste, and terminal-reply encoding
34
+ - POSIX PTY and 64-bit Windows ConPTY sessions behind one API
35
+ - OSC 133 command history and OSC 7 working-directory tracking
36
+ - Packaged shell integration for bash, zsh, and fish
37
+
7
38
  ## Installation
8
39
 
9
40
  ```bash
@@ -12,7 +43,9 @@ bundle add tarazed
12
43
 
13
44
  Or run `gem install tarazed`.
14
45
 
15
- ## Usage
46
+ Tarazed supports Ruby 3.1 and later.
47
+
48
+ ## Quick Start
16
49
 
17
50
  Feed arbitrary byte chunks into a `VT`; incomplete UTF-8 and control sequences
18
51
  are retained until the next chunk.
@@ -26,6 +59,8 @@ terminal.feed("\e[32mready\e[0m\r\n")
26
59
  puts screen.text
27
60
  ```
28
61
 
62
+ ## PTY Sessions
63
+
29
64
  `Tarazed::PTY` owns a child process and feeds its output into the same grid.
30
65
  It uses a POSIX PTY on macOS and Linux and ConPTY on 64-bit Windows:
31
66
 
@@ -33,11 +68,15 @@ It uses a POSIX PTY on macOS and Linux and ConPTY on 64-bit Windows:
33
68
  terminal = Tarazed::PTY.new(command: ["/bin/sh"], columns: 80, rows: 24)
34
69
  terminal.write("printf 'hello\\n'\r")
35
70
  terminal.read(timeout: 0.1)
71
+ puts terminal.status.exitstatus if !terminal.alive? && terminal.status
36
72
  terminal.close
37
73
  ```
38
74
 
39
75
  ConPTY requires a supported 64-bit Windows release and does not fall back to a
40
- pipe-only console.
76
+ pipe-only console. After natural process exit, `status` provides `exited?`,
77
+ `exitstatus`, `success?`, and `termsig` on every platform.
78
+
79
+ ## Command History
41
80
 
42
81
  `Tarazed::Session` adds a pump-oriented API and bounded OSC 133 command
43
82
  history. Command rows and output ranges use stable absolute history rows, and
@@ -52,6 +91,8 @@ end
52
91
  session.close
53
92
  ```
54
93
 
94
+ ## Shell Integration
95
+
55
96
  Shell integration snippets for bash, zsh, and fish are packaged with the gem.
56
97
  An embedding application can inject one into a new interactive shell with
57
98
  `Tarazed::ShellIntegration.read(:bash)` (or `:zsh` / `:fish`). The snippets
@@ -60,9 +101,13 @@ visible prompt.
60
101
 
61
102
  ## Development
62
103
 
63
- Run `bundle install`, then `bundle exec rake test`. Validate the signatures with
64
- `bundle exec rbs -I sig validate` and run the benchmark with
65
- `BUDGET=1 bundle exec rake bench`.
104
+ ```bash
105
+ bundle install
106
+ bundle exec rake test
107
+ bundle exec rbs -I sig validate
108
+ BUDGET=1 bundle exec rake bench
109
+ gem build --strict tarazed.gemspec
110
+ ```
66
111
 
67
112
  ## Contributing
68
113
 
@@ -70,4 +115,4 @@ Bug reports and pull requests are welcome at https://github.com/noxdea/tarazed.
70
115
 
71
116
  ## License
72
117
 
73
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
118
+ Tarazed is available under the [MIT License](LICENSE.txt).
data/lib/tarazed/pty.rb CHANGED
@@ -5,7 +5,7 @@ require "shellwords"
5
5
 
6
6
  module Tarazed
7
7
  class PTY
8
- attr_reader :reader, :writer, :pid, :grid, :vt, :status, :initial_cwd, :command_name
8
+ attr_reader :reader, :writer, :pid, :grid, :vt, :initial_cwd, :command_name
9
9
 
10
10
  def initialize(command: ENV.fetch("SHELL", "/bin/sh"), cwd: Dir.pwd, columns: 80, rows: 24, env: {},
11
11
  scrollback: 10_000, queue_limit_bytes: 8_388_608, command_history_limit: 1_000, on_command: nil)
@@ -124,6 +124,8 @@ module Tarazed
124
124
  @foreground_name = nil
125
125
  end
126
126
 
127
+ def status = @native ? @native.status : @status
128
+
127
129
  def signal(name = "INT")
128
130
  return @native.write("\x03") if @native && name == "INT"
129
131
  if @native
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tarazed
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -21,8 +21,23 @@ module Tarazed
21
21
  class ConPTY
22
22
  P, I, U, N, V = Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_UINT, Fiddle::TYPE_SIZE_T,
23
23
  Fiddle::TYPE_VOID
24
+ STILL_ACTIVE = 259
24
25
  private_constant :P, :I, :U, :N, :V
25
26
 
27
+ class Status
28
+ attr_reader :exitstatus
29
+
30
+ def initialize(exitstatus)
31
+ @exitstatus = exitstatus
32
+ freeze
33
+ end
34
+
35
+ def exited? = true
36
+ def success? = exitstatus.zero?
37
+ def termsig = nil
38
+ end
39
+ private_constant :Status
40
+
26
41
  attr_reader :pid
27
42
 
28
43
  def initialize(command: nil, columns: 80, rows: 24, cwd: nil, env: {}, kernel: nil)
@@ -104,13 +119,17 @@ module Tarazed
104
119
  check_hresult(function(:ResizePseudoConsole, [P, I], I).call(@console, coordinate(columns, rows)))
105
120
  end
106
121
 
107
- def alive?
108
- !@closed && function(:WaitForSingleObject, [P, U], U).call(@process, 0) == 258
122
+ def status
123
+ refresh_status unless @closed
124
+ @status
109
125
  end
110
126
 
127
+ def alive? = !@closed && !status
128
+
111
129
  def close
112
130
  return self if @closed
113
131
 
132
+ safely { refresh_status }
114
133
  @closed = true
115
134
  close_handle(@input_write)
116
135
  @input_write = nil
@@ -128,6 +147,15 @@ module Tarazed
128
147
  @kernel.fn(name, arguments, result, need_gvl: need_gvl)
129
148
  end
130
149
 
150
+ def refresh_status
151
+ return @status if @status
152
+
153
+ code = [0].pack("I")
154
+ check(function(:GetExitCodeProcess, [P, P], I).call(@process, code), "GetExitCodeProcess")
155
+ value = code.unpack1("I")
156
+ @status = Status.new(value) unless value == STILL_ACTIVE
157
+ end
158
+
131
159
  def process_attributes(console)
132
160
  size = [0].pack("J")
133
161
  function(:InitializeProcThreadAttributeList, [P, U, U, P], I).call(0, 1, 0, size)
data/sig/tarazed.rbs CHANGED
@@ -132,13 +132,20 @@ module Tarazed
132
132
  def key: (String | Symbol name, ?shift: bool, ?alt: bool, ?control: bool) -> String
133
133
  end
134
134
 
135
+ interface _PTYStatus
136
+ def exited?: () -> bool
137
+ def exitstatus: () -> Integer?
138
+ def success?: () -> bool?
139
+ def termsig: () -> Integer?
140
+ end
141
+
135
142
  class PTY
136
143
  attr_reader reader: IO?
137
144
  attr_reader writer: IO?
138
145
  attr_reader pid: Integer
139
146
  attr_reader grid: Grid
140
147
  attr_reader vt: VT
141
- attr_reader status: Process::Status?
148
+ attr_reader status: _PTYStatus?
142
149
  attr_reader initial_cwd: String
143
150
  attr_reader command_name: String
144
151
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tarazed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada