methodproof 0.7.17__tar.gz → 0.7.19__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 (88) hide show
  1. {methodproof-0.7.17 → methodproof-0.7.19}/PKG-INFO +1 -1
  2. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/__init__.py +1 -1
  3. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/cli.py +40 -12
  4. methodproof-0.7.19/methodproof/tui/login_success.py +41 -0
  5. {methodproof-0.7.17 → methodproof-0.7.19}/pyproject.toml +1 -1
  6. {methodproof-0.7.17 → methodproof-0.7.19}/.code-review-graph/.gitignore +0 -0
  7. {methodproof-0.7.17 → methodproof-0.7.19}/.code-review-graph/graph.db +0 -0
  8. {methodproof-0.7.17 → methodproof-0.7.19}/.github/workflows/ci.yml +0 -0
  9. {methodproof-0.7.17 → methodproof-0.7.19}/.gitignore +0 -0
  10. {methodproof-0.7.17 → methodproof-0.7.19}/CHANGELOG.md +0 -0
  11. {methodproof-0.7.17 → methodproof-0.7.19}/LICENSE +0 -0
  12. {methodproof-0.7.17 → methodproof-0.7.19}/README.md +0 -0
  13. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/__main__.py +0 -0
  14. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/_daemon.py +0 -0
  15. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/agents/__init__.py +0 -0
  16. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/agents/base.py +0 -0
  17. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/agents/music.py +0 -0
  18. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/agents/terminal.py +0 -0
  19. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/agents/watcher.py +0 -0
  20. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/analysis.py +0 -0
  21. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/binding.py +0 -0
  22. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/bip39.py +0 -0
  23. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/bridge.py +0 -0
  24. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/config.py +0 -0
  25. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/crypto.py +0 -0
  26. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/e2e.py +0 -0
  27. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/graph.py +0 -0
  28. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hook.py +0 -0
  29. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/__init__.py +0 -0
  30. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/claude_code.py +0 -0
  31. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/claude_code.sh +0 -0
  32. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/cline_hook.sh +0 -0
  33. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/codex_hook.sh +0 -0
  34. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/gemini_hook.sh +0 -0
  35. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/install.py +0 -0
  36. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/kiro_hook.sh +0 -0
  37. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/mcp_register.py +0 -0
  38. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/openclaw/HOOK.md +0 -0
  39. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/openclaw/handler.ts +0 -0
  40. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/openclaw_install.py +0 -0
  41. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/opencode_plugin.js +0 -0
  42. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/hooks/wrappers.py +0 -0
  43. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/integrity.py +0 -0
  44. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/kdf.py +0 -0
  45. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/keychain.py +0 -0
  46. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/live.py +0 -0
  47. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/lock.py +0 -0
  48. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/mcp.py +0 -0
  49. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/migrate_db.py +0 -0
  50. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/proxy.py +0 -0
  51. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/proxy_daemon.py +0 -0
  52. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/repos.py +0 -0
  53. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/skills/methodproof/SKILL.md +0 -0
  54. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/store.py +0 -0
  55. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/sync.py +0 -0
  56. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/__init__.py +0 -0
  57. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/consent.py +0 -0
  58. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/init.py +0 -0
  59. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/log.py +0 -0
  60. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/review.py +0 -0
  61. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/start.py +0 -0
  62. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/status.py +0 -0
  63. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/tui/theme.py +0 -0
  64. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/viewer.py +0 -0
  65. {methodproof-0.7.17 → methodproof-0.7.19}/methodproof/wordlist.py +0 -0
  66. {methodproof-0.7.17 → methodproof-0.7.19}/test_windows_compat.py +0 -0
  67. {methodproof-0.7.17 → methodproof-0.7.19}/tests/__init__.py +0 -0
  68. {methodproof-0.7.17 → methodproof-0.7.19}/tests/conftest.py +0 -0
  69. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_analysis.py +0 -0
  70. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_auth.py +0 -0
  71. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_config.py +0 -0
  72. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_helpers.py +0 -0
  73. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_session.py +0 -0
  74. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_share.py +0 -0
  75. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_start.py +0 -0
  76. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_cli_update.py +0 -0
  77. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_e2e_integration.py +0 -0
  78. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_graph.py +0 -0
  79. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_hooks.py +0 -0
  80. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_live.py +0 -0
  81. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_openclaw_hooks.py +0 -0
  82. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_profiles.py +0 -0
  83. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_security.py +0 -0
  84. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_store.py +0 -0
  85. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_sync.py +0 -0
  86. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_viewer.py +0 -0
  87. {methodproof-0.7.17 → methodproof-0.7.19}/tests/test_wrappers.py +0 -0
  88. {methodproof-0.7.17 → methodproof-0.7.19}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: methodproof
3
- Version: 0.7.17
3
+ Version: 0.7.19
4
4
  Summary: See how you code. Capture and visualize your engineering process.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,3 +1,3 @@
1
1
  """MethodProof — see how you code."""
2
2
 
3
- __version__ = "0.7.17"
3
+ __version__ = "0.7.19"
@@ -1391,6 +1391,25 @@ def cmd_view(args: argparse.Namespace) -> None:
1391
1391
 
1392
1392
 
1393
1393
  def cmd_log(args: argparse.Namespace) -> None:
1394
+ if getattr(args, "purge_empty", False):
1395
+ empty = [s for s in store.list_sessions() if s["total_events"] == 0]
1396
+ if not empty:
1397
+ print("No empty sessions.")
1398
+ return
1399
+ print(f"Found {len(empty)} empty session{'s' if len(empty) != 1 else ''}:")
1400
+ for s in empty:
1401
+ from datetime import datetime, UTC
1402
+ dt = datetime.fromtimestamp(s["created_at"], tz=UTC).strftime("%Y-%m-%d %H:%M")
1403
+ print(f" {s['id'][:8]} {dt} {s.get('watch_dir', '?')}")
1404
+ answer = input(f"\nDelete {len(empty)} empty session{'s' if len(empty) != 1 else ''}? [y/N]: ").strip().lower()
1405
+ if answer != "y":
1406
+ print("Cancelled.")
1407
+ return
1408
+ for s in empty:
1409
+ store.delete_session(s["id"])
1410
+ print(f"Deleted {len(empty)} empty session{'s' if len(empty) != 1 else ''}.")
1411
+ return
1412
+
1394
1413
  cfg = config.load()
1395
1414
  if _resolve_ui(args, cfg):
1396
1415
  _tui_guard()
@@ -1627,13 +1646,15 @@ def cmd_login(args: argparse.Namespace) -> None:
1627
1646
  api = args.api_url or cfg["api_url"]
1628
1647
 
1629
1648
  if cfg.get("token") and not getattr(args, "force", False):
1630
- current = cfg.get("email") or cfg.get("account_id", "")[:8] or "an account"
1631
- print(f"Already logged in as {current}.")
1632
- answer = input(" Switch accounts? [y/N]: ").strip().lower()
1633
- if answer not in ("y", "yes"):
1634
- return
1635
- # Stash current profile before switching
1636
- config.save_active_profile(cfg)
1649
+ if getattr(args, "add", False):
1650
+ config.save_active_profile(cfg)
1651
+ else:
1652
+ current = cfg.get("email") or cfg.get("account_id", "")[:8] or "an account"
1653
+ print(f"Already logged in as {current}.")
1654
+ answer = input(" Switch accounts? [y/N]: ").strip().lower()
1655
+ if answer not in ("y", "yes"):
1656
+ return
1657
+ config.save_active_profile(cfg)
1637
1658
 
1638
1659
  # Start device auth flow
1639
1660
  result = _request("POST", "/auth/cli/start", api, "")
@@ -1642,6 +1663,9 @@ def cmd_login(args: argparse.Namespace) -> None:
1642
1663
  user_code = result.get("user_code", "")
1643
1664
  verification_url = result.get("verification_url", "")
1644
1665
 
1666
+ if getattr(args, "add", False):
1667
+ auth_url += ("&" if "?" in auth_url else "?") + "mode=add"
1668
+
1645
1669
  print(f"\nOpening browser to sign in...\n")
1646
1670
  print(f" {auth_url}\n")
1647
1671
  if user_code and verification_url:
@@ -1673,11 +1697,13 @@ def cmd_login(args: argparse.Namespace) -> None:
1673
1697
  _setup_master_key(cfg)
1674
1698
  from methodproof.sync import sync_research_consent
1675
1699
  sync_research_consent(cfg["token"], cfg["api_url"])
1676
- label = cfg.get("email") or cfg.get("account_id", "")[:8]
1677
- profiles = cfg.get("profiles", {})
1678
- n = len(profiles)
1679
- print(f"Logged in as {label}. {n} account{'s' if n != 1 else ''} on this device.")
1680
- print(" Quick-swap: `mp switch`")
1700
+ from methodproof.tui.login_success import run as show_success
1701
+ show_success(
1702
+ display_name=cfg.get("email") or cfg.get("account_id", "")[:8],
1703
+ email=cfg.get("email", ""),
1704
+ account_count=len(cfg.get("profiles", {})),
1705
+ added=getattr(args, "add", False),
1706
+ )
1681
1707
  return
1682
1708
  except Exception:
1683
1709
  pass
@@ -2109,11 +2135,13 @@ def main() -> None:
2109
2135
  v = sub.add_parser("view", help="Inspect captured session data")
2110
2136
  v.add_argument("session_id", nargs="?")
2111
2137
  l_log = sub.add_parser("log", help="List sessions")
2138
+ l_log.add_argument("--purge-empty", action="store_true", help="Delete all sessions with 0 events")
2112
2139
  _add_ui_flags(l_log)
2113
2140
  s_status = sub.add_parser("status", help="Auth, session, and config status")
2114
2141
  _add_ui_flags(s_status)
2115
2142
  l = sub.add_parser("login", help="Connect to platform")
2116
2143
  l.add_argument("--api-url")
2144
+ l.add_argument("--add", action="store_true", help="Add another account to this device")
2117
2145
  l.add_argument("--force", "-f", action="store_true", help="Skip switch-account prompt")
2118
2146
  l.add_argument("--no-key", action="store_true", help="Skip master key generation (test accounts)")
2119
2147
  sub.add_parser("logout", help="Clear login credentials (keeps consent and sessions)")
@@ -0,0 +1,41 @@
1
+ """Rich success panel shown after mp login / mp login --add."""
2
+ from __future__ import annotations
3
+
4
+ from rich.console import Console
5
+ from rich.panel import Panel
6
+ from rich.text import Text
7
+
8
+ from methodproof.tui.theme import BORDER, DIM, GOLD, GREEN, TEXT
9
+
10
+ _CONSOLE = Console()
11
+
12
+
13
+ def run(display_name: str, email: str, account_count: int, added: bool) -> None:
14
+ """Render post-login success panel. Always shown regardless of ui_mode."""
15
+ body = Text()
16
+ body.append("✓ ", style=f"bold {GREEN}")
17
+
18
+ if added:
19
+ body.append("You have successfully added ", style=TEXT)
20
+ body.append(display_name, style=f"bold {TEXT}")
21
+ body.append(" authentication to your CLI.", style=TEXT)
22
+ else:
23
+ body.append("Signed in as ", style=TEXT)
24
+ body.append(display_name, style=f"bold {TEXT}")
25
+ body.append(".", style=TEXT)
26
+
27
+ if email and email != display_name:
28
+ body.append(f"\n {email}", style=DIM)
29
+
30
+ n = account_count
31
+ body.append(
32
+ f"\n\n {n} account{'s' if n != 1 else ''} on this device · ",
33
+ style=DIM,
34
+ )
35
+ body.append("mp switch", style=f"bold {GOLD}")
36
+ body.append(" to swap", style=DIM)
37
+
38
+ title = f"[{GOLD}] {'Added to CLI' if added else 'Logged In'} [/{GOLD}]"
39
+ _CONSOLE.print()
40
+ _CONSOLE.print(Panel(body, title=title, border_style=BORDER, padding=(0, 1)))
41
+ _CONSOLE.print()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "methodproof"
3
- version = "0.7.17"
3
+ version = "0.7.19"
4
4
  description = "See how you code. Capture and visualize your engineering process."
5
5
  requires-python = ">=3.11"
6
6
  dependencies = ["watchdog>=4.0", "websocket-client>=1.7", "cryptography>=43.0", "keyring>=25.0", "textual>=0.59", "rich>=13.7"]
File without changes
File without changes
File without changes
File without changes
File without changes