claude-dev-env 8.47.1 → 8.47.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.
@@ -55,7 +55,8 @@ When the command exits 3 and the report has `"account": "wait"`, no account is
55
55
  eligible. Report the picker's reason and reset time. Do not fall back to the
56
56
  Agent tool. Claude can also return exit 3 after a worker starts. When the
57
57
  report account is `main`, `second`, or `extra_2` and later, report the child's
58
- exit code and result.
58
+ exit code and result. Exit 124 with reason `timeout` means the worker ran past
59
+ `--timeout-minutes`.
59
60
 
60
61
  Workers never commit, push, or call `gh`. The calling session reviews each
61
62
  worktree diff and owns every Git step.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.47.1",
3
+ "version": "8.47.2",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,6 +27,8 @@ from dev_env_scripts_constants.claude_account_worker_constants import (
27
27
  PROMPT_FILE_FLAG,
28
28
  REPORT_FILE_FLAG,
29
29
  SINGLE_PROMPT_FLAG,
30
+ TIMEOUT_ATTEMPT_STATUS,
31
+ TIMEOUT_EXIT_CODE,
30
32
  TIMEOUT_MINUTES_FLAG,
31
33
  UTF8_ENCODING,
32
34
  )
@@ -102,10 +104,11 @@ def run_worker(
102
104
  if outcome.status in {"wait", "exhausted"}:
103
105
  report = wait_report("wait", _wait_reason(outcome), outcome.wait_reset_at)
104
106
  return finalize_report(report_file, report)
107
+ is_timed_out = bool(outcome.attempts) and outcome.attempts[-1][1] == TIMEOUT_ATTEMPT_STATUS
105
108
  report = make_report(
106
109
  outcome.account_name or "none",
107
- outcome.status,
108
- exit_code=outcome.returncode,
110
+ TIMEOUT_ATTEMPT_STATUS if is_timed_out else outcome.status,
111
+ exit_code=TIMEOUT_EXIT_CODE if is_timed_out else outcome.returncode,
109
112
  duration_seconds=duration_seconds,
110
113
  stdout_text=outcome.stdout,
111
114
  )
@@ -13,6 +13,10 @@ MINIMUM_TIMEOUT_MINUTES: int = 1
13
13
 
14
14
  LAUNCH_FAILURE_EXIT_CODE: int = 1
15
15
 
16
+ TIMEOUT_EXIT_CODE: int = 124
17
+
18
+ TIMEOUT_ATTEMPT_STATUS: str = "timeout"
19
+
16
20
  CONFIGURATION_FAILURE_EXIT_CODE: int = 2
17
21
 
18
22
  WAIT_DURATION_SECONDS: float = 0.0
@@ -100,6 +104,8 @@ __all__ = [
100
104
  "SINGLE_PROMPT_FLAG",
101
105
  "STDOUT_TAIL_CHARACTER_LIMIT",
102
106
  "SUMMARY_LINE_TEMPLATE",
107
+ "TIMEOUT_ATTEMPT_STATUS",
108
+ "TIMEOUT_EXIT_CODE",
103
109
  "TIMEOUT_MINUTES_FLAG",
104
110
  "UTF8_ENCODING",
105
111
  "WAIT_DURATION_SECONDS",
@@ -152,6 +152,20 @@ def test_should_preserve_served_failure_code(
152
152
  assert report["is_error"] is True
153
153
 
154
154
 
155
+ def test_should_exit_124_with_timeout_reason_when_the_broker_attempt_timed_out(
156
+ monkeypatch: pytest.MonkeyPatch, tmp_path: Path
157
+ ) -> None:
158
+ timed_out = JobOutcome(127, "", "timed out", "extra_2", (("extra_2", "timeout"),), "advisor_blocked", None, None)
159
+
160
+ exit_code, report, _ = _run_worker(monkeypatch, tmp_path, timed_out)
161
+
162
+ assert exit_code == 124
163
+ assert report["exit_code"] == 124
164
+ assert report["reason"] == "timeout"
165
+ assert report["account"] == "extra_2"
166
+ assert report["is_error"] is True
167
+
168
+
155
169
  def test_should_write_report_for_unreadable_prompt(
156
170
  monkeypatch: pytest.MonkeyPatch, tmp_path: Path
157
171
  ) -> None: