claude-multiacc 2.0.57 → 2.0.59
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/README.md +111 -3
- package/bin/claude +323 -84
- package/bin/claude-accounts +273 -42
- package/bin/codex +15 -0
- package/bin/codex-accounts +31 -4
- package/docs/ACCOUNT_OPERATIONS.md +62 -2
- package/docs/AUTORESUME-HANDOFF.md +30 -3
- package/docs/AUTORESUME.md +275 -18
- package/docs/CODEX.md +1 -0
- package/docs/INSTALLATION.md +7 -1
- package/docs/VERIFICATION.md +4 -0
- package/lib/__pycache__/audit.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross_dispatch.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross_receipt.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_handoff.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_probe.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_receipt.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_client_error.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_reset.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_token_identity.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_autoresume_mode.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_config_edit.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_controls.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_local_scope.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_selection.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credits.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_limits_lock.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_python.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_trust.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_usage_fetch.cpython-312.pyc +0 -0
- package/lib/__pycache__/keychain.cpython-312.pyc +0 -0
- package/lib/__pycache__/mcp_oauth.cpython-312.pyc +0 -0
- package/lib/__pycache__/mcp_registry.cpython-312.pyc +0 -0
- package/lib/__pycache__/model_catalog.cpython-312.pyc +0 -0
- package/lib/__pycache__/model_match.cpython-312.pyc +0 -0
- package/lib/__pycache__/report.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_credit_scope.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_credits.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_funding.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__/session_settings.cpython-312.pyc +0 -0
- package/lib/__pycache__/shim_path.cpython-312.pyc +0 -0
- package/lib/audit.py +88 -22
- package/lib/autoresume.py +1197 -82
- package/lib/autoresume_cross.py +3 -1
- package/lib/autoresume_handoff.py +82 -10
- package/lib/autoresume_probe.py +2 -2
- package/lib/claude_client_error.py +9 -4
- package/lib/codex_trust.py +263 -0
- package/lib/common.sh +131 -3
- package/lib/credential.py +5 -2
- package/lib/install_actions.sh +19 -0
- package/lib/keychain.py +180 -36
- package/lib/mcp_oauth.py +1748 -0
- package/lib/model_catalog.json +404 -0
- package/lib/model_catalog.py +201 -0
- package/lib/model_match.py +104 -0
- package/lib/report.py +8 -5
- package/lib/session_settings.py +123 -0
- package/package.json +2 -2
- package/tests/__pycache__/autoresume_cross_receipt_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_tmux_environment.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_tmux_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_unit_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_tmux_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/packaged_command_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_catalog.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_catalog_cli.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_codex_records.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_codex_trust.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_claude_holders.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_guards.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_holders.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_origin.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_policy.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_receipt.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tmux_races.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tokens.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cursor.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_fallback.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_argv.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_history.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_origins.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_memory.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_memory_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_mode.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_probe.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_receipt.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_relaunch_settings.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_settings.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_sidechain.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_sidechain_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_tmux_modes.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_trust_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_claude_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_claude_token_identity.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits_polling.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits_report.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_fetch.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/__pycache__/test_selector.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_cached_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credit_scope.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credit_shim.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_spread.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_ceremony.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_integration.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_retry.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_sync.cpython-312.pyc +0 -0
- package/tests/fake_codex_tui.py +25 -0
- package/tests/fake_security.sh +24 -2
- package/tests/fixtures/cross_provider_cli.py +111 -1
- package/tests/run-tests.sh +1028 -23
- package/tests/test_autoresume.py +215 -8
- package/tests/test_autoresume_catalog.py +226 -0
- package/tests/test_autoresume_catalog_cli.py +185 -0
- package/tests/test_autoresume_codex_records.py +16 -0
- package/tests/test_autoresume_codex_trust.py +247 -0
- package/tests/test_autoresume_cross_guards.py +28 -0
- package/tests/test_autoresume_cross_origin.py +70 -0
- package/tests/test_autoresume_cross_tmux.py +27 -2
- package/tests/test_autoresume_cross_tokens.py +32 -2
- package/tests/test_autoresume_handoff_argv.py +120 -16
- package/tests/test_autoresume_handoff_origins.py +67 -0
- package/tests/test_autoresume_memory.py +1141 -0
- package/tests/test_autoresume_memory_tmux.py +94 -0
- package/tests/test_autoresume_probe.py +2 -1
- package/tests/test_autoresume_relaunch_settings.py +317 -0
- package/tests/test_autoresume_settings.py +135 -0
- package/tests/test_autoresume_sidechain.py +1518 -0
- package/tests/test_autoresume_sidechain_tmux.py +79 -0
- package/tests/test_autoresume_trust_tmux.py +63 -0
- package/tests/test_claude_client_error.py +10 -7
- package/tests/test_claude_org_block.py +1 -0
- package/tests/test_claude_pool_prepare.py +4 -1
- package/tests/test_claude_reset.py +3 -0
- package/tests/test_keychain_nologin.py +340 -0
- package/tests/test_mcp_oauth.py +1414 -0
- package/tests/test_packaged_commands.py +41 -0
|
@@ -61,6 +61,13 @@ class PackagedCommandsTests(unittest.TestCase):
|
|
|
61
61
|
self.assertRegex(result.stdout, r"(?i)usage")
|
|
62
62
|
result = run([str(self.package / "install.sh"), "--help"], self.env, self.work)
|
|
63
63
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
64
|
+
# The catalog verb refreshes pools when it runs; asked for help it must write nothing.
|
|
65
|
+
for prefix in (["claude-accounts"], ["codex-accounts"], ["claude-multiacc"], ["claude-multiacc", "codex"]):
|
|
66
|
+
for args in (["model-catalog", "--help"], ["model-catalog", "refresh", "--help"]):
|
|
67
|
+
with self.subTest(prefix=prefix, args=args):
|
|
68
|
+
result = run(prefix + args, self.env, self.work)
|
|
69
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
70
|
+
self.assertIn("model-catalog [refresh|show]", result.stdout)
|
|
64
71
|
self.assertEqual(before, sorted(str(path) for path in self.home.rglob("*")))
|
|
65
72
|
|
|
66
73
|
def test_verify_and_json_reports_use_the_correct_pool(self):
|
|
@@ -140,6 +147,10 @@ class PackagedCommandsTests(unittest.TestCase):
|
|
|
140
147
|
self.assertEqual(text.count("_claude_multiacc_path_guard() {"), 1, rc)
|
|
141
148
|
self.assertTrue(text.rstrip().endswith("# <<< claude-multiacc <<<"), rc)
|
|
142
149
|
self.assertFalse((self.home / ".bash_profile").exists())
|
|
150
|
+
# Every install refreshes the model catalog into both pools (the stubbed CLIs exit 1
|
|
151
|
+
# and are never needed: the refresh reads files only).
|
|
152
|
+
for pool in (".claude-accounts", ".codex-accounts"):
|
|
153
|
+
self.assertEqual(json.loads((self.home / pool / "model-catalog.json").read_text())["schema"], 1)
|
|
143
154
|
# ...and fresh login shells of every flavour now resolve the package's shims,
|
|
144
155
|
# the real binaries in ~/.local/bin notwithstanding (lib/shim_path.py is the
|
|
145
156
|
# same probe `claude-accounts status` and `health` print).
|
|
@@ -185,6 +196,36 @@ class PackagedCommandsTests(unittest.TestCase):
|
|
|
185
196
|
uname.unlink()
|
|
186
197
|
identity.unlink()
|
|
187
198
|
|
|
199
|
+
def test_installer_refreshes_the_model_catalog_and_fails_open(self):
|
|
200
|
+
pools = [self.home / ".claude-accounts", self.home / ".codex-accounts"]
|
|
201
|
+
install = ["claude-multiacc", "install", "--no-server", "--no-schedule"]
|
|
202
|
+
for pool in pools:
|
|
203
|
+
if (pool / "model-catalog.json").exists():
|
|
204
|
+
(pool / "model-catalog.json").unlink()
|
|
205
|
+
result = run(install, self.env, self.work)
|
|
206
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
207
|
+
self.assertIn("model catalog: refreshed", result.stdout)
|
|
208
|
+
shipped = json.loads((self.package / "lib/model_catalog.json").read_text())
|
|
209
|
+
for pool in pools:
|
|
210
|
+
doc = json.loads((pool / "model-catalog.json").read_text())
|
|
211
|
+
self.assertEqual(doc["schema"], 1)
|
|
212
|
+
for provider in ("claude", "codex"): # no CLI cache in these pools: the shipped lineup
|
|
213
|
+
self.assertEqual(doc[provider]["models"], shipped[provider]["models"])
|
|
214
|
+
# A refresh that cannot run never fails the install: one note, nothing written.
|
|
215
|
+
module = self.package / "lib/model_catalog.py"
|
|
216
|
+
original = module.read_text()
|
|
217
|
+
for pool in pools:
|
|
218
|
+
(pool / "model-catalog.json").unlink()
|
|
219
|
+
module.write_text("raise SystemExit(1)\n")
|
|
220
|
+
try:
|
|
221
|
+
result = run(install, self.env, self.work)
|
|
222
|
+
finally:
|
|
223
|
+
module.write_text(original)
|
|
224
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
225
|
+
self.assertIn("model catalog could not be refreshed", result.stderr)
|
|
226
|
+
self.assertIn("install complete", result.stdout)
|
|
227
|
+
self.assertEqual([pool for pool in pools if (pool / "model-catalog.json").exists()], [])
|
|
228
|
+
|
|
188
229
|
def test_selector_transport_and_version_match_across_entrypoints(self):
|
|
189
230
|
expected = None
|
|
190
231
|
for prefix in (["multiacc-select"], ["claude-multiacc", "select"]):
|