claude-multiacc 2.0.51 → 2.0.52

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.
Files changed (66) hide show
  1. package/bin/codex +1 -1
  2. package/bin/codex-accounts +28 -41
  3. package/docs/CODEX.md +43 -15
  4. package/lib/__pycache__/audit.cpython-312.pyc +0 -0
  5. package/lib/__pycache__/autoresume.cpython-312.pyc +0 -0
  6. package/lib/__pycache__/autoresume_probe.cpython-312.pyc +0 -0
  7. package/lib/__pycache__/claude_client_error.cpython-312.pyc +0 -0
  8. package/lib/__pycache__/claude_reset.cpython-312.pyc +0 -0
  9. package/lib/__pycache__/claude_token_identity.cpython-312.pyc +0 -0
  10. package/lib/__pycache__/codex_config_edit.cpython-312.pyc +0 -0
  11. package/lib/__pycache__/codex_credit_controls.cpython-312.pyc +0 -0
  12. package/lib/__pycache__/codex_credit_local_scope.cpython-312.pyc +0 -0
  13. package/lib/__pycache__/codex_credit_selection.cpython-312.pyc +0 -0
  14. package/lib/__pycache__/codex_credits.cpython-312.pyc +0 -0
  15. package/lib/__pycache__/codex_limits_lock.cpython-312.pyc +0 -0
  16. package/lib/__pycache__/codex_python.cpython-312.pyc +0 -0
  17. package/lib/__pycache__/codex_usage_fetch.cpython-312.pyc +0 -0
  18. package/lib/__pycache__/keychain.cpython-312.pyc +0 -0
  19. package/lib/__pycache__/mcp_registry.cpython-312.pyc +0 -0
  20. package/lib/__pycache__/report.cpython-312.pyc +0 -0
  21. package/lib/__pycache__/selector_credit_scope.cpython-312.pyc +0 -0
  22. package/lib/__pycache__/selector_credits.cpython-312.pyc +0 -0
  23. package/lib/__pycache__/selector_funding.cpython-312.pyc +0 -0
  24. package/lib/__pycache__/selector_policy.cpython-312.pyc +0 -0
  25. package/lib/__pycache__/selector_primitives.cpython-312.pyc +0 -0
  26. package/lib/__pycache__/shim_path.cpython-312.pyc +0 -0
  27. package/lib/codex_credit_controls.py +27 -0
  28. package/lib/codex_credit_selection.py +10 -4
  29. package/lib/codex_credits.py +28 -32
  30. package/lib/codex_limits_lock.py +56 -0
  31. package/lib/codex_usage_fetch.py +85 -0
  32. package/lib/selector_credit_scope.py +33 -3
  33. package/lib/selector_credits.py +10 -4
  34. package/lib/selector_funding.py +16 -14
  35. package/package.json +1 -1
  36. package/tests/__pycache__/packaged_command_support.cpython-312.pyc +0 -0
  37. package/tests/__pycache__/test_autoresume.cpython-312.pyc +0 -0
  38. package/tests/__pycache__/test_autoresume_fallback.cpython-312.pyc +0 -0
  39. package/tests/__pycache__/test_autoresume_probe.cpython-312.pyc +0 -0
  40. package/tests/__pycache__/test_claude_reset.cpython-312.pyc +0 -0
  41. package/tests/__pycache__/test_claude_token_identity.cpython-312.pyc +0 -0
  42. package/tests/__pycache__/test_codex_reset.cpython-312.pyc +0 -0
  43. package/tests/__pycache__/test_codex_reset_credits.cpython-312.pyc +0 -0
  44. package/tests/__pycache__/test_codex_reset_credits_polling.cpython-312.pyc +0 -0
  45. package/tests/__pycache__/test_codex_reset_credits_report.cpython-312.pyc +0 -0
  46. package/tests/__pycache__/test_codex_reset_fetch.cpython-312.pyc +0 -0
  47. package/tests/__pycache__/test_codex_reset_polling.cpython-312.pyc +0 -0
  48. package/tests/__pycache__/test_codex_reset_reporting.cpython-312.pyc +0 -0
  49. package/tests/__pycache__/test_codex_reset_windows.cpython-312.pyc +0 -0
  50. package/tests/__pycache__/test_selector.cpython-312.pyc +0 -0
  51. package/tests/__pycache__/test_selector_cached_credits.cpython-312.pyc +0 -0
  52. package/tests/__pycache__/test_selector_credit_scope.cpython-312.pyc +0 -0
  53. package/tests/__pycache__/test_selector_credit_shim.cpython-312.pyc +0 -0
  54. package/tests/__pycache__/test_selector_credits.cpython-312.pyc +0 -0
  55. package/tests/__pycache__/test_selector_spread.cpython-312.pyc +0 -0
  56. package/tests/__pycache__/test_token_identity_ceremony.cpython-312.pyc +0 -0
  57. package/tests/__pycache__/test_token_identity_integration.cpython-312.pyc +0 -0
  58. package/tests/__pycache__/test_token_identity_retry.cpython-312.pyc +0 -0
  59. package/tests/__pycache__/test_token_identity_sync.cpython-312.pyc +0 -0
  60. package/tests/test_codex_reset_credits.py +42 -0
  61. package/tests/test_codex_reset_credits_polling.py +58 -1
  62. package/tests/test_codex_reset_fetch.py +123 -0
  63. package/tests/test_selector_cached_credits.py +135 -0
  64. package/tests/test_selector_credit_scope.py +5 -5
  65. package/tests/test_selector_credit_shim.py +3 -3
  66. package/tests/test_selector_credits.py +3 -2
@@ -33,10 +33,10 @@ class CreditScopeTests(unittest.TestCase):
33
33
  peer.update(runner_id=4, account_id="blocked")
34
34
  self.assertEqual(select(_request([blocked, peer], credit_fallback=True))["runner_id"], 4)
35
35
 
36
- def test_peer_wallet_cannot_erase_local_auth_identity_or_read_failure(self):
36
+ def test_peer_wallet_cannot_erase_local_auth_identity_or_refusal_read_failure(self):
37
37
  failed, busy = _paid(account_id="failed"), _paid(account_id="busy")
38
38
  busy["reservation_history"]["active_expires_at"] = "2026-08-25T09:05:00Z"
39
- for error in ("account_mismatch", "unauthenticated", "http_401", "usage_read_failed"):
39
+ for error in ("account_mismatch", "unauthenticated", "refusal_read_failed"):
40
40
  with self.subTest(error=error):
41
41
  failed["credits"].update(last_error=error, fetched_at="2026-08-25T08:59:00Z")
42
42
  self.assertFalse(select(_request([failed, busy], credit_fallback=True))["ok"])
@@ -59,14 +59,14 @@ class CreditScopeTests(unittest.TestCase):
59
59
  busy["reservation_history"]["active_expires_at"] = "2026-08-25T09:05:00Z"
60
60
  self.assertFalse(select(_request([blocked, busy], credit_fallback=True))["ok"])
61
61
 
62
- def test_latest_failed_financial_observation_does_not_revive_old_positive_balance(self):
62
+ def test_failed_refresh_does_not_replace_latest_confirmed_monetary_observation(self):
63
63
  old, failed = _paid(account_id="old"), _paid(account_id="failed")
64
64
  old["credits"]["fetched_at"] = "2026-08-25T08:59:00Z"
65
65
  failed["credits"].update(fetched_at="2026-08-25T08:58:00Z", last_error="usage_read_failed",
66
66
  last_error_at="2026-08-25T09:00:00Z")
67
- self.assertFalse(select(_request([old, failed], credit_fallback=True))["ok"])
68
- old["credits"]["fetched_at"] = "2026-08-25T09:00:01Z"
69
67
  self.assertTrue(select(_request([old, failed], credit_fallback=True))["ok"])
68
+ old["credits"]["balance"] = "0"
69
+ self.assertFalse(select(_request([old, failed], credit_fallback=True))["ok"])
70
70
 
71
71
  def test_standalone_refusal_is_shared_only_for_same_manifest_actor(self):
72
72
  case = shim_fixtures.CreditShimTests()
@@ -74,9 +74,9 @@ class CreditShimTests(unittest.TestCase):
74
74
  (self.pool / "acct-03" / "auth.json").unlink()
75
75
  self.assertIn("tier=hard", self.run_shim(CODEX_MULTIACC_CREDITS="0").stdout)
76
76
 
77
- def test_zero_unknown_stale_spend_control_and_auth_never_paid(self):
78
- for patch in ({"balance": "0"}, {"balance": None}, {"last_error": "usage_read_failed"},
79
- {"fetched_at": "2020-01-01T00:00:00Z"}, {"spend_control_reached": True},
77
+ def test_zero_unknown_future_spend_control_and_auth_never_paid(self):
78
+ for patch in ({"balance": "0"}, {"balance": None}, {"last_error": "unauthenticated"},
79
+ {"fetched_at": "2099-01-01T00:00:00Z"}, {"spend_control_reached": True},
80
80
  {"account_id": None}, {"limit_reached_type": "workspace_owner_credits_depleted"}):
81
81
  with self.subTest(patch=patch):
82
82
  self.account("acct-01", **patch)
@@ -52,8 +52,9 @@ class FundingSelectionTests(unittest.TestCase):
52
52
  def test_credits_fail_closed_for_all_restrictions(self):
53
53
  bad_credits = ({"balance": "0"}, {"balance": None}, {"balance": "NaN"},
54
54
  {"balance": "-1"}, {"has_credits": False}, {"account_id": None},
55
- {"fetched_at": "2026-08-25T08:44:59Z"}, {"fetched_at": "2026-08-25T09:00:31Z"},
56
- {"last_error": "usage_read_failed"}, {"spend_control_reached": True},
55
+ {"fetched_at": None}, {"fetched_at": "2026-08-25T09:00:31Z"},
56
+ {"last_error": "unauthenticated"}, {"last_error": "refusal_read_failed"},
57
+ {"spend_control_reached": True},
57
58
  {"limit_reached_type": "workspace_owner_usage_limit_reached"},
58
59
  {"limit_reached_type": "unknown"})
59
60
  for patch in bad_credits: