claude-multiacc 2.0.40 → 2.0.41
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/lib/__pycache__/audit.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_reset.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_config_edit.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_python.cpython-312.pyc +0 -0
- package/lib/__pycache__/keychain.cpython-312.pyc +0 -0
- package/lib/__pycache__/mcp_registry.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_policy.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_primitives.cpython-312.pyc +0 -0
- package/lib/__pycache__/shim_path.cpython-312.pyc +0 -0
- package/lib/report.py +16 -1
- package/package.json +1 -1
- package/tests/__pycache__/packaged_command_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_claude_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_polling.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_reporting.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_windows.cpython-312.pyc +0 -0
- package/tests/test_claude_reset.py +30 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/report.py
CHANGED
|
@@ -46,7 +46,7 @@ import time
|
|
|
46
46
|
|
|
47
47
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
48
48
|
import keychain # noqa: E402
|
|
49
|
-
from audit import token_verified # noqa: E402
|
|
49
|
+
from audit import creds_doc_state, token_verified # noqa: E402
|
|
50
50
|
from claude_reset import marker_superseded, record_from # noqa: E402
|
|
51
51
|
|
|
52
52
|
SCHEMA = 'claude-multiacc/pool.v1'
|
|
@@ -194,6 +194,21 @@ def _claude_credentials(d):
|
|
|
194
194
|
if isinstance(o, dict):
|
|
195
195
|
detail['oauth_expires_at'] = _iso_ms(o.get('expiresAt'))
|
|
196
196
|
detail['oauth_refresh_expires_at'] = _iso_ms(o.get('refreshTokenExpiresAt'))
|
|
197
|
+
# `oauth` says a sign-in EXISTS here; `oauth_alive` says whether it can still work —
|
|
198
|
+
# the limits writer's own rule (audit.creds_doc_state). A dead one (refresh token
|
|
199
|
+
# expired) keeps inference running on the portable token but can never read usage
|
|
200
|
+
# or limit resets again, so the panel must ask for a sign-in (2026-09-22: acct-02 and
|
|
201
|
+
# acct-07 sat dark for days behind `oauth: true`). None = could not be read here (a
|
|
202
|
+
# Keychain this session cannot open) or no sign-in at all.
|
|
203
|
+
detail['oauth_alive'] = None
|
|
204
|
+
if has_oauth and isinstance(o, dict):
|
|
205
|
+
try:
|
|
206
|
+
state, reason = creds_doc_state({'claudeAiOauth': o}, time.time())
|
|
207
|
+
detail['oauth_alive'] = state == 'ok'
|
|
208
|
+
if state != 'ok':
|
|
209
|
+
detail['oauth_problem'] = reason
|
|
210
|
+
except Exception:
|
|
211
|
+
pass
|
|
197
212
|
if has_token:
|
|
198
213
|
mt = _mtime(tpath)
|
|
199
214
|
detail['token_minted_at'] = _iso(mt)
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -660,6 +660,36 @@ class ClaudeResetFleetRecordTest(ClaudePoolSandbox, unittest.TestCase):
|
|
|
660
660
|
self.assertIn("written before a confirmed limit reset", self.log())
|
|
661
661
|
|
|
662
662
|
|
|
663
|
+
class ClaudeDeadSignInReportTest(ClaudePoolSandbox, unittest.TestCase):
|
|
664
|
+
"""A sign-in that EXISTS but can no longer work must say so (2026-09-22: acct-02 and
|
|
665
|
+
acct-07 read `oauth: true` with a refresh token expired days before, so the panel
|
|
666
|
+
never offered the sign-in that restores their telemetry and limit resets)."""
|
|
667
|
+
|
|
668
|
+
def listed(self) -> dict:
|
|
669
|
+
result = subprocess.run([REPO / "bin/claude-accounts", "list", "--json"],
|
|
670
|
+
capture_output=True, text=True, env=self.env(), timeout=60,
|
|
671
|
+
check=False)
|
|
672
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
673
|
+
return json.loads(result.stdout)["accounts"][0]["credentials"]
|
|
674
|
+
|
|
675
|
+
def test_a_live_sign_in_is_alive(self) -> None:
|
|
676
|
+
creds = self.listed()
|
|
677
|
+
self.assertTrue(creds["oauth"])
|
|
678
|
+
self.assertTrue(creds["oauth_alive"])
|
|
679
|
+
self.assertNotIn("oauth_problem", creds)
|
|
680
|
+
|
|
681
|
+
def test_an_expired_refresh_token_is_a_dead_sign_in(self) -> None:
|
|
682
|
+
(self.account / "server.token").write_text("sk-ant-oat01-portable\n", encoding="utf-8")
|
|
683
|
+
dead = {"claudeAiOauth": {"accessToken": "old", "refreshToken": "r",
|
|
684
|
+
"expiresAt": int(time.time() - 7 * 86400) * 1000,
|
|
685
|
+
"refreshTokenExpiresAt": int(time.time() - 3 * 86400) * 1000}}
|
|
686
|
+
(self.account / ".credentials.json").write_text(json.dumps(dead), encoding="utf-8")
|
|
687
|
+
creds = self.listed()
|
|
688
|
+
self.assertTrue(creds["oauth"]) # it exists...
|
|
689
|
+
self.assertFalse(creds["oauth_alive"]) # ...but cannot work
|
|
690
|
+
self.assertIn("refresh token expired", creds["oauth_problem"])
|
|
691
|
+
|
|
692
|
+
|
|
663
693
|
class ClaudeResetReportingTest(ClaudePoolSandbox, unittest.TestCase):
|
|
664
694
|
def report(self, **overrides) -> dict:
|
|
665
695
|
result = self.run_limits("--json", **overrides)
|