claude-dev-env 8.46.22 → 8.46.24

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.46.22",
3
+ "version": "8.46.24",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -333,7 +333,8 @@ def _parser() -> argparse.ArgumentParser:
333
333
  commands = parser.add_subparsers(dest="action", required=True)
334
334
  for each_action in ("choose", "check", "accounts", "limits", "run"):
335
335
  command = commands.add_parser(each_action)
336
- command.add_argument("--product", choices=[each_product.value for each_product in Product], required=True)
336
+ all_product_choices = [Product.CODEX.value] if each_action == "limits" else [each_product.value for each_product in Product]
337
+ command.add_argument("--product", choices=all_product_choices, required=True)
337
338
  if each_action == "choose":
338
339
  command.add_argument("--spent", action="append", default=[])
339
340
  if each_action == "limits":
@@ -373,9 +374,7 @@ def _accounts_cli(product: Product) -> int:
373
374
  return 0
374
375
 
375
376
 
376
- def _limits_cli(product: Product, parsed: argparse.Namespace) -> int:
377
- if product is not Product.CODEX:
378
- raise BrokerConfigurationError("limits reads Codex accounts only")
377
+ def _limits_cli(parsed: argparse.Namespace) -> int:
379
378
  try:
380
379
  rate_limit_records = codex_account_meters.read_rate_limit_records(
381
380
  codex_account_meters.resolve_codex_path(parsed.codex), parsed.home
@@ -430,7 +429,7 @@ def main(all_arguments: Sequence[str]) -> int:
430
429
  if parsed.action == "accounts":
431
430
  return _accounts_cli(product)
432
431
  if parsed.action == "limits":
433
- return _limits_cli(product, parsed)
432
+ return _limits_cli(parsed)
434
433
  if parsed.action == "run":
435
434
  return _run_cli(product, parsed, parser)
436
435
  return _choose_cli(product, parsed)
@@ -10,5 +10,5 @@ ALL_USAGE_LIMIT_SIGNATURES: tuple[str, ...] = (
10
10
  )
11
11
  """Case-insensitive substrings that mark a non-zero exit as a usage-limit refusal."""
12
12
 
13
- CHAIN_CONFIG_ERROR_EXIT_CODE: int = 3
13
+ CHAIN_CONFIG_ERROR_EXIT_CODE: int = 5
14
14
  """CLI exit code when the chain configuration is missing or invalid."""
@@ -493,7 +493,7 @@ SPAWN_SERVED_EXIT_CODE: int = 0
493
493
  SPAWN_EXHAUSTED_EXIT_CODE: int = 2
494
494
  """CLI exit code when no dispatcher tier served the call."""
495
495
 
496
- SPAWN_CONFIG_ERROR_EXIT_CODE: int = 3
496
+ SPAWN_CONFIG_ERROR_EXIT_CODE: int = 5
497
497
  """CLI exit code when the claude chain configuration is missing or invalid."""
498
498
 
499
499
  RESULT_KEY_TIER_USED: str = "tier_used"
@@ -607,7 +607,7 @@ def main(all_command_arguments: list[str]) -> int:
607
607
 
608
608
  A timeout outside the accepted bounds is a config fault: the run prints a
609
609
  structured outcome whose attempt reason is ``timeout_out_of_bounds`` and
610
- exits ``3``, rather than raising out of the CLI. A broker configuration error,
610
+ exits ``5``, rather than raising out of the CLI. A broker configuration error,
611
611
  or an unknown host profile refused by ``detect_host_profile``, prints the
612
612
  same exit code with the refusal text as its output.
613
613
 
@@ -805,5 +805,7 @@ def test_should_exit_two_when_the_limits_read_fails(
805
805
 
806
806
 
807
807
  def test_should_refuse_limits_for_claude(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
808
- assert account_broker.main(("limits", "--product", "claude", "--home", str(tmp_path))) == 2
809
- assert "Codex accounts only" in capsys.readouterr().err
808
+ with pytest.raises(SystemExit) as exit_info:
809
+ account_broker.main(("limits", "--product", "claude", "--home", str(tmp_path)))
810
+ assert exit_info.value.code == 2
811
+ assert "invalid choice: 'claude'" in capsys.readouterr().err
@@ -164,7 +164,6 @@ class TestReadCodexMeters:
164
164
  read_codex_meters(Path("codex"), Path("/h"), broken_exchange)
165
165
 
166
166
 
167
-
168
167
  class TestReadRateLimitRecords:
169
168
  def should_return_every_limit_record_the_reply_carries(self) -> None:
170
169
  rate_limit_records = {
@@ -196,6 +195,7 @@ class TestReadRateLimitRecords:
196
195
  with pytest.raises(CodexMeterUnreadError, match="no rate-limit reply"):
197
196
  read_rate_limit_records(Path("codex"), Path("/h"), lambda *_: [])
198
197
 
198
+
199
199
  FAKE_APP_SERVER = """#!/usr/bin/env python3
200
200
  import json, os, sys
201
201
  for line in sys.stdin:
@@ -19,7 +19,7 @@ from _code_review_test_support import (
19
19
  install_seams,
20
20
  run_review_cli,
21
21
  )
22
- from dev_env_scripts_constants.account_broker_constants import BrokerConfigurationError
22
+ from dev_env_scripts_constants.account_broker_constants import BrokerConfigurationError, WAIT_EXIT_CODE
23
23
  from dev_env_scripts_constants.claude_chain_constants import (
24
24
  CHAIN_CONFIG_ERROR_EXIT_CODE,
25
25
  )
@@ -82,6 +82,7 @@ def test_cli_emits_json_on_chain_configuration_error(
82
82
  exit_code = run_review_cli(working_directory, session_model=FIXTURE_SESSION_OPUS)
83
83
 
84
84
  assert exit_code == CHAIN_CONFIG_ERROR_EXIT_CODE
85
+ assert exit_code != WAIT_EXIT_CODE
85
86
  captured = capsys.readouterr()
86
87
  parsed_payload = json.loads(captured.out)
87
88
  assert parsed_payload == {
@@ -299,12 +299,12 @@ def test_grok_usage_limited_on_claude_host_requires_agent(
299
299
  def test_out_of_bounds_timeout_is_reported_as_config_not_worker_failure(
300
300
  monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str]
301
301
  ) -> None:
302
- """A refused timeout prints a structured outcome and exits 3, never a traceback.
302
+ """A refused timeout prints a structured outcome and exits 5, never a traceback.
303
303
 
304
304
  ::
305
305
 
306
- --timeout-seconds 0 ok: reason timeout_out_of_bounds, exit 3
307
- --timeout-seconds 5401 ok: reason timeout_out_of_bounds, exit 3
306
+ --timeout-seconds 0 ok: reason timeout_out_of_bounds, exit 5
307
+ --timeout-seconds 5401 ok: reason timeout_out_of_bounds, exit 5
308
308
  """
309
309
  prompt_file, working_directory, run_state_directory = _paths(tmp_path)
310
310
  _install_seams(monkeypatch, grok_outcome=_grok_ok())
@@ -350,7 +350,7 @@ def test_out_of_bounds_timeout_is_refused_when_the_grok_tier_is_unreachable(
350
350
  ::
351
351
 
352
352
  preflight unusable, --timeout-seconds 5401
353
- ok: reason timeout_out_of_bounds, exit 3, no tier invoked
353
+ ok: reason timeout_out_of_bounds, exit 5, no tier invoked
354
354
  """
355
355
  prompt_file, working_directory, run_state_directory = _paths(tmp_path)
356
356
  call_log = _install_seams(
@@ -496,7 +496,7 @@ def test_tier_three_wait_reports_reset_and_stops(
496
496
  assert call_log.claude_calls == 1
497
497
 
498
498
 
499
- def test_config_error_returns_exit_three(
499
+ def test_config_error_exit_code_differs_from_the_wait_exit_code(
500
500
  monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str]
501
501
  ) -> None:
502
502
  prompt_file, working_directory, run_state_directory = _paths(tmp_path)
@@ -523,6 +523,7 @@ def test_config_error_returns_exit_three(
523
523
  )
524
524
 
525
525
  assert exit_code == SPAWN_CONFIG_ERROR_EXIT_CODE
526
+ assert exit_code != WAIT_EXIT_CODE
526
527
  captured = capsys.readouterr()
527
528
  parsed_payload = json.loads(captured.out)
528
529
  assert parsed_payload[RESULT_KEY_OK] is False