ace-llm-providers-cli 0.36.0 → 0.36.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: fd7b7ee1d350ec4ea77298f5ecd0f137537897291ce0ba1f13949357fb1a0d94
4
- data.tar.gz: 2ee0526ca547c242ec6346f7db4e1816a31b652ba8c06d8ba98ddff0cf6acfe0
3
+ metadata.gz: 31bd7e17459ce8d8e8c1bc358819d49fbd919fa5c5fefbfab977d1a4993983c6
4
+ data.tar.gz: 47a14679feaea4018e4a437a36ddfb176a9392909db2c4eb68a49e7773927348
5
5
  SHA512:
6
- metadata.gz: 60660511b2ef85e79054367ccb21560663cdca66714d6c3f501ad0d04e917f058330b4ba8e93c285133832e91edf949a1cd80c6bf348c93ec2657d4e5fd1b044
7
- data.tar.gz: 67f8baa381e615f7c53eba0df32db3fab86e417f0ef048f99929c8a12f3a9e83f93e9a31df8470e61a8fc35b6e8c7e17681f9c2c905f21dcccf2967ca0ceca59
6
+ metadata.gz: 8368b8e11eb5e0afa9e9e4fef56696bd16024b0ded23fca5e54689d86694a1aa045f6df1d701b1cadbe8281ccb04b992d861884bf5b4c1805da8d551979ecb48
7
+ data.tar.gz: e5353cb3b9734d28b9003d6017b3a31fbd61c8dd36d781c97b211f6e795323551b1ec0226ae527c4ca788df873983b001850afe0f159131605475700566901fe
data/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.36.2] - 2026-10-16
11
+
12
+ ### Fixed
13
+
14
+ - Terminate coding-agent subprocess groups when a caller interrupts a capture, before Open3 waits for the child.
15
+
16
+ - `SafeCapture`: repair the `readiness.nil.` typo (missing `?`) introduced in
17
+ 0.36.0 that raised `NoMethodError` on every successful supervised CLI
18
+ capture before any model call, breaking all CLI-delegating providers
19
+ (codex, agy, claude, pi). Regression tests pin readiness semantics
20
+ (String/nil/unsupervised); signal-classification tests now exercise an
21
+ unsupervised direct child, since the Linux supervisor converts child
22
+ signals to exit status by design.
23
+
24
+ ## [0.36.1] - 2026-10-01
25
+
26
+ ### Technical
27
+ - Observe descendant exit with a bounded monotonic wait in cleanup tests, retaining the process-absence predicate and adding a live-child negative control.
28
+
10
29
  ## [0.36.0] - 2026-09-29
11
30
 
12
31
  ### Added
@@ -97,7 +97,7 @@ module Ace
97
97
  # StandardError describing a supervisor-reported child spawn
98
98
  # failure, or nil when the child group started normally.
99
99
  def child_spawn_failure
100
- return nil if supervised != true || readiness.nil.
100
+ return nil if supervised != true || readiness.nil?
101
101
 
102
102
  message = readiness.to_s
103
103
  return nil unless message.start_with?("S")
@@ -203,6 +203,22 @@ module Ace
203
203
  deadline_seconds: normalized_timeout,
204
204
  elapsed_seconds: elapsed_since(started_at)
205
205
  )
206
+ ensure
207
+ # A caller may cancel a worker thread while it waits on a coding
208
+ # agent. Clean up before Open3's block unwinds (which otherwise
209
+ # waits for the still-running child). The capture boundary owns
210
+ # the process group, so consumers must not duplicate this policy.
211
+ if pid && (wait_thr.alive? || $!)
212
+ terminate_subprocess_tree(
213
+ pid: pid, pgid: pgid, provider_name: provider_name, supervised: spawn_result.supervised?
214
+ )
215
+ unless wait_thr.join(5)
216
+ terminate_group_or_pid("KILL", pid, pgid)
217
+ wait_thr.join(5)
218
+ end
219
+ end
220
+ [stdin, stdout, stderr].each { |stream| stream.close unless stream.closed? }
221
+ [out_reader, err_reader].compact.each { |reader| reader.join(1) }
206
222
  end
207
223
  end
208
224
 
@@ -243,7 +259,9 @@ module Ace
243
259
  io.close unless io.closed?
244
260
  reader.join(1)
245
261
  reader.kill if reader.alive?
246
- buffer.dup
262
+ # The reader may have been killed mid-chunk; finalize the
263
+ # partial buffer with the same UTF-8 scrubbing contract.
264
+ buffer.dup.force_encoding(Encoding::UTF_8).scrub!
247
265
  end
248
266
  end
249
267
 
@@ -261,6 +279,12 @@ module Ace
261
279
  end
262
280
  buffer << chunk
263
281
  end
282
+ # Pipes yield raw bytes; CLI output can contain non-UTF-8
283
+ # fragments. Finalize as valid UTF-8 (invalid bytes become
284
+ # replacement characters) so downstream prompt concatenation
285
+ # cannot raise Encoding::CompatibilityError.
286
+ buffer.force_encoding(Encoding::UTF_8)
287
+ buffer.scrub!
264
288
  buffer
265
289
  rescue IOError, SystemCallError
266
290
  buffer
@@ -288,7 +312,7 @@ module Ace
288
312
  end
289
313
 
290
314
  def terminate_subprocess_tree(pid:, pgid:, provider_name:, supervised: false)
291
- debug_log(provider_name, "timeout cleanup pid=#{pid} pgid=#{pgid || "n/a"}")
315
+ debug_log(provider_name, "capture cleanup pid=#{pid} pgid=#{pgid || "n/a"}")
292
316
  terminate_group_or_pid("TERM", pid, pgid)
293
317
  terminate_group_or_pid("KILL", pid, pgid) unless supervised
294
318
  end
@@ -4,7 +4,7 @@ module Ace
4
4
  module LLM
5
5
  module Providers
6
6
  module CLI
7
- VERSION = "0.36.0"
7
+ VERSION = "0.36.2"
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-llm-providers-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.36.0
4
+ version: 0.36.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-09-30 00:00:00.000000000 Z
10
+ date: 2026-10-16 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-llm