codex-manager 5.0.0__tar.gz → 7.0.0__tar.gz

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 (87) hide show
  1. {codex_manager-5.0.0 → codex_manager-7.0.0}/PKG-INFO +1 -1
  2. {codex_manager-5.0.0 → codex_manager-7.0.0}/pyproject.toml +1 -1
  3. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/__init__.py +1 -1
  4. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/args.py +8 -1
  5. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cli.py +9 -2
  6. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/PKG-INFO +1 -1
  7. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/SOURCES.txt +1 -0
  8. codex_manager-7.0.0/tests/test_backup_ux.py +36 -0
  9. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_more.py +1 -0
  10. {codex_manager-5.0.0 → codex_manager-7.0.0}/README.md +0 -0
  11. {codex_manager-5.0.0 → codex_manager-7.0.0}/setup.cfg +0 -0
  12. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/account_status.py +0 -0
  13. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/backup.py +0 -0
  14. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cloud.py +0 -0
  15. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/config.py +0 -0
  16. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cooldown.py +0 -0
  17. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/credentials.py +0 -0
  18. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/doctor.py +0 -0
  19. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/list_backups.py +0 -0
  20. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/profile.py +0 -0
  21. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/prune.py +0 -0
  22. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/prune_backups.py +0 -0
  23. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/purge.py +0 -0
  24. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/recommend.py +0 -0
  25. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/registry.py +0 -0
  26. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/remove.py +0 -0
  27. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/restore.py +0 -0
  28. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/status.py +0 -0
  29. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/sync.py +0 -0
  30. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/ui.py +0 -0
  31. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/use_account.py +0 -0
  32. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/utils.py +0 -0
  33. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/dependency_links.txt +0 -0
  34. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/entry_points.txt +0 -0
  35. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/requires.txt +0 -0
  36. {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/top_level.txt +0 -0
  37. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_account_status_coverage.py +0 -0
  38. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_account_status_more2.py +0 -0
  39. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli.py +0 -0
  40. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli_3.py +0 -0
  41. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli_extra.py +0 -0
  42. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_backup.py +0 -0
  43. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_backup2.py +0 -0
  44. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli2.py +0 -0
  45. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage.py +0 -0
  46. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_2.py +0 -0
  47. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_3.py +0 -0
  48. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_4.py +0 -0
  49. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_5.py +0 -0
  50. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_6.py +0 -0
  51. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_7.py +0 -0
  52. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_8.py +0 -0
  53. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_extra.py +0 -0
  54. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cloud.py +0 -0
  55. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_config.py +0 -0
  56. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cooldown.py +0 -0
  57. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cooldown2.py +0 -0
  58. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_credentials2.py +0 -0
  59. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_doctor.py +0 -0
  60. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_doctor2.py +0 -0
  61. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_dry_run_coverage.py +0 -0
  62. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups.py +0 -0
  63. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups2.py +0 -0
  64. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups3.py +0 -0
  65. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups_coverage.py +0 -0
  66. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_next_gen_upgrade.py +0 -0
  67. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_profile.py +0 -0
  68. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune.py +0 -0
  69. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune_backups.py +0 -0
  70. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune_backups2.py +0 -0
  71. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_purge.py +0 -0
  72. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_recommend.py +0 -0
  73. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_recommend2.py +0 -0
  74. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_registry_coverage_more.py +0 -0
  75. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_registry_dry_run_coverage.py +0 -0
  76. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_remove.py +0 -0
  77. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_restore.py +0 -0
  78. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_restore2.py +0 -0
  79. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status.py +0 -0
  80. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status2.py +0 -0
  81. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status3.py +0 -0
  82. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_sync.py +0 -0
  83. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_sync2.py +0 -0
  84. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_ui.py +0 -0
  85. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_ui_2.py +0 -0
  86. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_use.py +0 -0
  87. {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_use2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-manager
3
- Version: 5.0.0
3
+ Version: 7.0.0
4
4
  Summary: Codex account snapshot manager
5
5
  Author-email: Dhruv <dhruv13x@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codex-manager"
3
- version = "5.0.0"
3
+ version = "7.0.0"
4
4
  description = "Codex account snapshot manager"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  __all__ = ["__version__"]
2
2
 
3
- __version__ = "5.0.0"
3
+ __version__ = "7.0.0"
@@ -507,7 +507,14 @@ def get_parser() -> argparse.ArgumentParser:
507
507
  list_backups_parser.add_argument(
508
508
  "--latest-per-email",
509
509
  action="store_true",
510
- help="Only show the latest backup for each email.",
510
+ default=True,
511
+ help="Only show the latest backup for each email (Default).",
512
+ )
513
+ list_backups_parser.add_argument(
514
+ "--all",
515
+ action="store_false",
516
+ dest="latest_per_email",
517
+ help="Show all backups, including historical and duplicate entries.",
511
518
  )
512
519
  list_backups_parser.add_argument(
513
520
  "--ready",
@@ -31,7 +31,8 @@ from .use_account import perform_use, use_result_to_text
31
31
 
32
32
  def list_entries_from_args(args: Any) -> list[BackupEntry]:
33
33
  force_latest = args.command in ["cooldown", "recommend"]
34
- latest_per_email = getattr(args, "latest_per_email", False) or force_latest
34
+ # For list-backups, it now defaults to True in args.py, but we ensure it here
35
+ latest_per_email = getattr(args, "latest_per_email", True) or force_latest
35
36
  all_entries: list[BackupEntry] = []
36
37
 
37
38
  backup_dir = Path(args.backup_dir).expanduser()
@@ -283,7 +284,13 @@ def handle_status(args: Any) -> None:
283
284
 
284
285
 
285
286
  def handle_backup(args: Any) -> None:
286
- archive_path, metadata_path, metadata = perform_backup(args)
287
+ try:
288
+ archive_path, metadata_path, metadata = perform_backup(args)
289
+ except FileExistsError as exc:
290
+ console.print(f"[bold red]Stop:[/] {exc}")
291
+ console.print(f"[dim]Note: Backups are named after the account's weekly reset time.[/]")
292
+ console.print(f"[dim]If you want to update your current snapshot, run with: [bold white]--force[/][/]")
293
+ sys.exit(1)
287
294
 
288
295
  if getattr(args, "cloud", False):
289
296
  cp = get_cloud_provider(args)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-manager
3
- Version: 5.0.0
3
+ Version: 7.0.0
4
4
  Summary: Codex account snapshot manager
5
5
  Author-email: Dhruv <dhruv13x@gmail.com>
6
6
  License: MIT
@@ -37,6 +37,7 @@ tests/test_args_cli_3.py
37
37
  tests/test_args_cli_extra.py
38
38
  tests/test_backup.py
39
39
  tests/test_backup2.py
40
+ tests/test_backup_ux.py
40
41
  tests/test_cli2.py
41
42
  tests/test_cli_coverage.py
42
43
  tests/test_cli_coverage_2.py
@@ -0,0 +1,36 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from types import SimpleNamespace
4
+ from codex_manager.cli import handle_backup
5
+ import pytest
6
+
7
+ def test_handle_backup_file_exists_clean_error(tmp_path, capsys, mocker):
8
+ # Setup
9
+ backup_dir = tmp_path / "backups"
10
+ backup_dir.mkdir()
11
+ archive_name = "2026-01-01-test@example.com-codex.tar.gz"
12
+ (backup_dir / archive_name).write_text("existing")
13
+
14
+ args = SimpleNamespace(
15
+ command="backup",
16
+ backup_dir=str(backup_dir),
17
+ force=False,
18
+ cloud=False,
19
+ dry_run=False
20
+ )
21
+
22
+ # Mock perform_backup to raise the error like it does in real life
23
+ mocker.patch("codex_manager.cli.perform_backup", side_effect=FileExistsError(f"Archive already exists: {archive_name}. Use --force to overwrite."))
24
+
25
+ with pytest.raises(SystemExit) as exc:
26
+ handle_backup(args)
27
+
28
+ assert exc.value.code == 1
29
+ captured = capsys.readouterr()
30
+ assert "Stop:" in captured.out
31
+ assert "--force" in captured.out
32
+ assert "weekly reset time" in captured.out
33
+
34
+ if __name__ == "__main__":
35
+ # Just a simple run to see it visually if needed
36
+ pass
@@ -44,6 +44,7 @@ def test_list_entries_from_args_cooldown_no_cloud(mocker, tmp_path):
44
44
  backup_dir = str(tmp_path)
45
45
  cloud = False
46
46
  args = Args()
47
+ mocker.patch("codex_manager.cli.get_cloud_provider", return_value=None)
47
48
  entries = list_entries_from_args(args)
48
49
  assert entries == []
49
50
 
File without changes
File without changes