claude-dev-env 8.54.7 → 8.54.8

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.54.7",
3
+ "version": "8.54.8",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,6 +48,7 @@ from dev_env_scripts_constants.account_broker_constants import (
48
48
  ALL_PARENT_CLAUDE_SESSION_VARIABLES,
49
49
  COMMAND_MISSING_EXIT_CODE,
50
50
  REPORT_INDENT_SPACES,
51
+ TIMEOUT_EXIT_CODE,
51
52
  WAIT_EXIT_CODE,
52
53
  utc_time_text as _time_text,
53
54
  )
@@ -287,13 +288,16 @@ def _attempt_once(context: _RunContext, decision: Decision) -> JobOutcome | None
287
288
  account = decision.account
288
289
  try:
289
290
  completion = _invoke(context, account)
290
- except (OSError, subprocess.TimeoutExpired) as error:
291
- status = "timeout" if isinstance(error, subprocess.TimeoutExpired) else "start_failed"
292
- _record_spent_attempt(context, account, status, COMMAND_MISSING_EXIT_CODE)
291
+ except subprocess.TimeoutExpired as error:
292
+ _record_spent_attempt(context, account, "timeout", TIMEOUT_EXIT_CODE)
293
+ context.report.final_decision = decision
294
+ return JobOutcome(TIMEOUT_EXIT_CODE, "", str(error), account.name, tuple(context.all_attempts), "timeout", None, None)
295
+ except OSError as error:
296
+ _record_spent_attempt(context, account, "start_failed", COMMAND_MISSING_EXIT_CODE)
293
297
  context.start_failure_text = str(error)
294
- if isinstance(error, subprocess.TimeoutExpired) or not context.all_readings:
298
+ if not context.all_readings:
295
299
  context.report.final_decision = decision
296
- final_status = "advisor_blocked" if context.product is Product.CLAUDE else status
300
+ final_status = "advisor_blocked" if context.product is Product.CLAUDE else "start_failed"
297
301
  return JobOutcome(COMMAND_MISSING_EXIT_CODE, "", str(error), account.name, tuple(context.all_attempts), final_status, None, None)
298
302
  return None
299
303
  combined = f"{completion.stdout}{completion.stderr}".casefold()
@@ -27,8 +27,6 @@ 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,
32
30
  TIMEOUT_MINUTES_FLAG,
33
31
  UTF8_ENCODING,
34
32
  )
@@ -104,11 +102,10 @@ def run_worker(
104
102
  if outcome.status in {"wait", "exhausted"}:
105
103
  report = wait_report("wait", _wait_reason(outcome), outcome.wait_reset_at)
106
104
  return finalize_report(report_file, report)
107
- is_timed_out = bool(outcome.attempts) and outcome.attempts[-1][1] == TIMEOUT_ATTEMPT_STATUS
108
105
  report = make_report(
109
106
  outcome.account_name or "none",
110
- TIMEOUT_ATTEMPT_STATUS if is_timed_out else outcome.status,
111
- exit_code=TIMEOUT_EXIT_CODE if is_timed_out else outcome.returncode,
107
+ outcome.status,
108
+ exit_code=outcome.returncode,
112
109
  duration_seconds=duration_seconds,
113
110
  stdout_text=outcome.stdout,
114
111
  )
@@ -50,6 +50,7 @@ ALL_CODEX_FLOORS = {
50
50
 
51
51
  WAIT_EXIT_CODE = 3
52
52
  COMMAND_MISSING_EXIT_CODE = 127
53
+ TIMEOUT_EXIT_CODE = 124
53
54
  REPORT_INDENT_SPACES = 2
54
55
  BROKER_STATE_DIRECTORY_NAME = "account-broker"
55
56
  BROKER_STATE_FILE_NAME = "state.json"
@@ -13,10 +13,6 @@ 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
-
20
16
  CONFIGURATION_FAILURE_EXIT_CODE: int = 2
21
17
 
22
18
  WAIT_DURATION_SECONDS: float = 0.0
@@ -104,8 +100,6 @@ __all__ = [
104
100
  "SINGLE_PROMPT_FLAG",
105
101
  "STDOUT_TAIL_CHARACTER_LIMIT",
106
102
  "SUMMARY_LINE_TEMPLATE",
107
- "TIMEOUT_ATTEMPT_STATUS",
108
- "TIMEOUT_EXIT_CODE",
109
103
  "TIMEOUT_MINUTES_FLAG",
110
104
  "UTF8_ENCODING",
111
105
  "WAIT_DURATION_SECONDS",
@@ -687,6 +687,7 @@ def test_should_stop_after_timeout_without_running_job_again(
687
687
  assert invoked_homes == ["first"]
688
688
  assert outcome.attempts == (("first", "timeout"),)
689
689
  assert outcome.status == "timeout"
690
+ assert outcome.returncode == 124
690
691
  assert outcome.account_name == "first"
691
692
  assert report.final_decision.account.name == "first"
692
693
  assert account_broker.main(("choose", "--product", "codex")) == 0
@@ -696,12 +697,12 @@ def test_should_stop_after_timeout_without_running_job_again(
696
697
  @pytest.mark.parametrize(
697
698
  ("product", "roster_names", "start_error", "expected_code"),
698
699
  (
699
- (Product.CLAUDE, ("first",), subprocess.TimeoutExpired("job", 1), 4),
700
- (Product.CODEX, ("first",), subprocess.TimeoutExpired("job", 1), 127),
700
+ (Product.CLAUDE, ("first",), subprocess.TimeoutExpired("job", 1), 124),
701
+ (Product.CODEX, ("first",), subprocess.TimeoutExpired("job", 1), 124),
701
702
  (Product.CODEX, (), OSError("missing command"), 127),
702
703
  ),
703
704
  )
704
- def test_should_exit_four_only_for_a_blocked_claude_job(
705
+ def test_should_exit_with_job_failure_code(
705
706
  monkeypatch: pytest.MonkeyPatch,
706
707
  tmp_path: Path,
707
708
  product: Product,
@@ -165,7 +165,7 @@ def test_should_preserve_served_failure_code(
165
165
  def test_should_exit_124_with_timeout_reason_when_the_broker_attempt_timed_out(
166
166
  monkeypatch: pytest.MonkeyPatch, tmp_path: Path
167
167
  ) -> None:
168
- timed_out = JobOutcome(127, "", "timed out", "extra_2", (("extra_2", "timeout"),), "advisor_blocked", None, None)
168
+ timed_out = JobOutcome(124, "", "timed out", "extra_2", (("extra_2", "timeout"),), "timeout", None, None)
169
169
 
170
170
  exit_code, report, _ = _run_worker(monkeypatch, tmp_path, timed_out)
171
171