claude-dev-env 8.47.0 → 8.47.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.47.0",
3
+ "version": "8.47.1",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import subprocess
4
4
  import sys
5
+ import threading
5
6
  import time
6
7
  from pathlib import Path
7
8
  from typing import cast
@@ -50,6 +51,7 @@ RESULT_WAIT_SECONDS = 5
50
51
  PROCESS_WAIT_SECONDS = 10
51
52
  POLL_INTERVAL_SECONDS = 0.01
52
53
  LEGACY_LOCK_CONTENT = "legacy owner metadata"
54
+ DELAYED_OUTCOME_WRITE_SECONDS = 0.2
53
55
  BASE_PYTHON_EXECUTABLE = cast(str, getattr(sys, "_base_executable", sys.executable))
54
56
 
55
57
 
@@ -72,13 +74,20 @@ def _start_lock_contender(
72
74
  )
73
75
 
74
76
 
77
+ def _read_reported_outcome(result_path: Path) -> str:
78
+ if not result_path.is_file():
79
+ return ""
80
+ return result_path.read_text(encoding="utf-8")
81
+
82
+
75
83
  def _wait_for_lock_outcomes(all_result_paths: list[Path]) -> list[str]:
76
84
  deadline = time.monotonic() + RESULT_WAIT_SECONDS
77
85
  while time.monotonic() < deadline:
78
- if all(each_path.is_file() for each_path in all_result_paths):
79
- return [
80
- each_path.read_text(encoding="utf-8") for each_path in all_result_paths
81
- ]
86
+ all_outcomes = [
87
+ _read_reported_outcome(each_path) for each_path in all_result_paths
88
+ ]
89
+ if all(all_outcomes):
90
+ return all_outcomes
82
91
  time.sleep(POLL_INTERVAL_SECONDS)
83
92
  raise AssertionError("lock contenders did not report within five seconds")
84
93
 
@@ -146,6 +155,22 @@ def test_process_lock_survives_contention_and_owner_termination(
146
155
  _terminate_owned_child(each_child_process)
147
156
 
148
157
 
158
+ def test_wait_for_lock_outcomes_waits_for_written_content(tmp_path: Path) -> None:
159
+ result_path = tmp_path / "delayed.result"
160
+ result_path.touch()
161
+ delayed_writer = threading.Timer(
162
+ DELAYED_OUTCOME_WRITE_SECONDS,
163
+ result_path.write_text,
164
+ args=("acquired",),
165
+ kwargs={"encoding": "utf-8"},
166
+ )
167
+ delayed_writer.start()
168
+ try:
169
+ assert _wait_for_lock_outcomes([result_path]) == ["acquired"]
170
+ finally:
171
+ delayed_writer.join()
172
+
173
+
149
174
  def test_lock_io_error_is_presented_as_supervisor_lock_error(
150
175
  tmp_path: Path,
151
176
  ) -> None: