methodproof 0.7.21__tar.gz → 0.7.23__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.21 → methodproof-0.7.23}/CHANGELOG.md +13 -0
  2. {methodproof-0.7.21 → methodproof-0.7.23}/PKG-INFO +1 -1
  3. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/cli.py +41 -7
  4. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/config.py +2 -1
  5. {methodproof-0.7.21 → methodproof-0.7.23}/pyproject.toml +1 -1
  6. {methodproof-0.7.21 → methodproof-0.7.23}/tests/conftest.py +1 -1
  7. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_start.py +7 -5
  8. methodproof-0.7.21/.code-review-graph/.gitignore +0 -3
  9. methodproof-0.7.21/.code-review-graph/graph.db +0 -0
  10. {methodproof-0.7.21 → methodproof-0.7.23}/.github/workflows/ci.yml +0 -0
  11. {methodproof-0.7.21 → methodproof-0.7.23}/.gitignore +0 -0
  12. {methodproof-0.7.21 → methodproof-0.7.23}/LICENSE +0 -0
  13. {methodproof-0.7.21 → methodproof-0.7.23}/README.md +0 -0
  14. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/__init__.py +0 -0
  15. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/__main__.py +0 -0
  16. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/_daemon.py +0 -0
  17. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/agents/__init__.py +0 -0
  18. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/agents/base.py +0 -0
  19. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/agents/music.py +0 -0
  20. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/agents/terminal.py +0 -0
  21. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/agents/watcher.py +0 -0
  22. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/analysis.py +0 -0
  23. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/binding.py +0 -0
  24. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/bip39.py +0 -0
  25. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/bridge.py +0 -0
  26. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/crypto.py +0 -0
  27. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/e2e.py +0 -0
  28. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/graph.py +0 -0
  29. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hook.py +0 -0
  30. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/__init__.py +0 -0
  31. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/claude_code.py +0 -0
  32. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/claude_code.sh +0 -0
  33. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/cline_hook.sh +0 -0
  34. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/codex_hook.sh +0 -0
  35. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/gemini_hook.sh +0 -0
  36. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/install.py +0 -0
  37. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/kiro_hook.sh +0 -0
  38. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/mcp_register.py +0 -0
  39. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/openclaw/HOOK.md +0 -0
  40. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/openclaw/handler.ts +0 -0
  41. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/openclaw_install.py +0 -0
  42. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/opencode_plugin.js +0 -0
  43. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/hooks/wrappers.py +0 -0
  44. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/integrity.py +0 -0
  45. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/kdf.py +0 -0
  46. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/keychain.py +0 -0
  47. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/live.py +0 -0
  48. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/lock.py +0 -0
  49. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/mcp.py +0 -0
  50. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/migrate_db.py +0 -0
  51. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/proxy.py +0 -0
  52. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/proxy_daemon.py +0 -0
  53. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/repos.py +0 -0
  54. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/skills/methodproof/SKILL.md +0 -0
  55. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/store.py +0 -0
  56. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/sync.py +0 -0
  57. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/__init__.py +0 -0
  58. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/consent.py +0 -0
  59. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/init.py +0 -0
  60. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/log.py +0 -0
  61. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/login_success.py +0 -0
  62. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/review.py +0 -0
  63. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/start.py +0 -0
  64. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/status.py +0 -0
  65. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/tui/theme.py +0 -0
  66. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/viewer.py +0 -0
  67. {methodproof-0.7.21 → methodproof-0.7.23}/methodproof/wordlist.py +0 -0
  68. {methodproof-0.7.21 → methodproof-0.7.23}/test_windows_compat.py +0 -0
  69. {methodproof-0.7.21 → methodproof-0.7.23}/tests/__init__.py +0 -0
  70. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_analysis.py +0 -0
  71. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_auth.py +0 -0
  72. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_config.py +0 -0
  73. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_helpers.py +0 -0
  74. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_session.py +0 -0
  75. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_share.py +0 -0
  76. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_cli_update.py +0 -0
  77. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_e2e_integration.py +0 -0
  78. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_graph.py +0 -0
  79. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_hooks.py +0 -0
  80. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_live.py +0 -0
  81. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_openclaw_hooks.py +0 -0
  82. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_profiles.py +0 -0
  83. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_security.py +0 -0
  84. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_store.py +0 -0
  85. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_sync.py +0 -0
  86. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_viewer.py +0 -0
  87. {methodproof-0.7.21 → methodproof-0.7.23}/tests/test_wrappers.py +0 -0
  88. {methodproof-0.7.21 → methodproof-0.7.23}/uv.lock +0 -0
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.23] — 2026-04-12
4
+
5
+ ### Fixed
6
+ - **`mp` alias works immediately after `init`** — `_install_alias` now creates a real symlink (`mp → methodproof`) in the same bin directory instead of writing an rc alias. No shell restart or eval needed. Falls back to rc alias if symlinking fails (e.g. read-only bin dir).
7
+
8
+ ## [0.7.22] — 2026-04-11
9
+
10
+ ### Added
11
+ - **Username in session output** — `mp start` banner shows `Account: @username` (falls back to email). `mp stop` summary shows the same. Username fetched from `/auth/me` on login and stored in config profile.
12
+
13
+ ### Fixed
14
+ - **`eval "$(methodproof shell-hook)"` missing `mp` alias** — `shell-hook` now emits both the command-logging hooks and `alias mp="methodproof"`, so eval fully activates the CLI without a shell restart.
15
+
3
16
  ## [0.7.20] — 2026-04-11
4
17
 
5
18
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: methodproof
3
- Version: 0.7.21
3
+ Version: 0.7.23
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
@@ -131,7 +131,21 @@ _ALIAS_MARKER = "# methodproof-alias"
131
131
 
132
132
 
133
133
  def _install_alias() -> None:
134
- """Add `alias mp=methodproof` to the user's shell rc file."""
134
+ """Install `mp` as an executable symlink next to `methodproof` in PATH.
135
+ Falls back to writing an alias in the shell rc if symlinking fails."""
136
+ import shutil
137
+ mp_exe = shutil.which("mp")
138
+ methodproof_exe = shutil.which("methodproof")
139
+ if mp_exe:
140
+ return # already exists
141
+ if methodproof_exe and sys.platform != "win32":
142
+ mp_path = Path(methodproof_exe).parent / "mp"
143
+ try:
144
+ mp_path.symlink_to(methodproof_exe)
145
+ return
146
+ except OSError:
147
+ pass # fall through to rc alias
148
+ # Fallback: write alias to shell rc (requires shell restart / eval)
135
149
  rc, _ = hook.get_shell_rc()
136
150
  if rc.exists() and _ALIAS_MARKER in rc.read_text():
137
151
  return
@@ -484,14 +498,19 @@ def cmd_init(args: argparse.Namespace) -> None:
484
498
  print("Signing key: exists")
485
499
 
486
500
  _print_intro()
487
- print(" Restart your shell or run this to activate now:\n")
488
- print(" eval \"$(methodproof shell-hook)\"\n")
501
+ import shutil
502
+ if shutil.which("mp"):
503
+ print(" Run `mp start` to begin recording.\n")
504
+ else:
505
+ print(" Restart your shell or run this to activate `mp`:\n")
506
+ print(" eval \"$(methodproof shell-hook)\"\n")
489
507
 
490
508
 
491
509
  def cmd_shell_hook(_args: argparse.Namespace) -> None:
492
510
  """Print the shell hook text for the current shell (for eval)."""
493
511
  _, hook_text = hook.get_shell_rc()
494
- print(hook_text.strip())
512
+ alias = 'Set-Alias mp methodproof' if sys.platform == "win32" else 'alias mp="methodproof"'
513
+ print(hook_text.strip() + "\n" + alias)
495
514
 
496
515
 
497
516
  # ── TUI mode helpers ──────────────────────────────────────────────────────────
@@ -1203,8 +1222,11 @@ def cmd_start(args: argparse.Namespace) -> None:
1203
1222
  config.save(cfg)
1204
1223
 
1205
1224
  active = [k for k, v in capture.items() if v]
1225
+ username = cfg.get("username")
1226
+ account_label = f"@{username}" if username else (cfg.get("email") or cfg.get("account_id", "")[:8])
1206
1227
  print(f"\n{_banner()}")
1207
1228
  print(f"Recording: {sid[:8]}")
1229
+ print(f"Account: {account_label}")
1208
1230
  print(f"Watching: {watch_dir}")
1209
1231
  if repo_url:
1210
1232
  print(f"Repo: {repo_url}")
@@ -1397,7 +1419,7 @@ def cmd_stop(args: argparse.Namespace) -> None:
1397
1419
  session = store.get_session(sid)
1398
1420
  cfg["active_session"] = None
1399
1421
  config.save(cfg)
1400
- _print_summary(session, stats)
1422
+ _print_summary(session, stats, cfg)
1401
1423
 
1402
1424
 
1403
1425
  def cmd_view(args: argparse.Namespace) -> None:
@@ -1705,6 +1727,13 @@ def cmd_login(args: argparse.Namespace) -> None:
1705
1727
  cfg["account_id"] = claims.get("user_id", "")
1706
1728
  cfg["last_auth_at"] = time.time()
1707
1729
  cfg["master_key_fingerprint"] = "" # clear stale fingerprint from previous account
1730
+ # Fetch profile to store email and username
1731
+ try:
1732
+ profile = _request("GET", "/auth/me", api, poll["token"])
1733
+ cfg["email"] = profile.get("email", "")
1734
+ cfg["username"] = profile.get("username") or ""
1735
+ except Exception as exc:
1736
+ _log_debug("auth.profile_fetch_failed", error=str(exc))
1708
1737
  config.save(cfg)
1709
1738
  config.save_active_profile(cfg)
1710
1739
  print(" done.\n")
@@ -1714,7 +1743,7 @@ def cmd_login(args: argparse.Namespace) -> None:
1714
1743
  sync_research_consent(cfg["token"], cfg["api_url"])
1715
1744
  from methodproof.tui.login_success import run as show_success
1716
1745
  show_success(
1717
- display_name=cfg.get("email") or cfg.get("account_id", "")[:8],
1746
+ display_name=cfg.get("username") or cfg.get("email") or cfg.get("account_id", "")[:8],
1718
1747
  email=cfg.get("email", ""),
1719
1748
  account_count=len(cfg.get("profiles", {})),
1720
1749
  added=getattr(args, "add", False),
@@ -2011,11 +2040,16 @@ def _duration(s: dict) -> str:
2011
2040
  return f"{secs // 60}:{secs % 60:02d}"
2012
2041
 
2013
2042
 
2014
- def _print_summary(session: dict | None, stats: dict) -> None:
2043
+ def _print_summary(session: dict | None, stats: dict, cfg: dict | None = None) -> None:
2015
2044
  if not session:
2016
2045
  return
2046
+ cfg = cfg or {}
2047
+ username = cfg.get("username")
2048
+ account_label = f"@{username}" if username else (cfg.get("email") or cfg.get("account_id", "")[:8])
2017
2049
  print(f"\n{_banner()}")
2018
2050
  print(f"Session: {session['id'][:8]}")
2051
+ if account_label:
2052
+ print(f" Account: {account_label}")
2019
2053
  print(f" Events: {session['total_events']}")
2020
2054
  print(f" Duration: {_duration(session)}")
2021
2055
  print(f" Graph: {stats['next']} links, {stats['causal']} causal")
@@ -42,6 +42,7 @@ _DEFAULTS: dict[str, Any] = {
42
42
  "e2e_fingerprint": "",
43
43
  "auto_update": False,
44
44
  "account_id": "",
45
+ "username": "",
45
46
  "last_auth_at": 0,
46
47
  "local_ai_ports": [], # user-configured localhost ports for local LLM capture
47
48
  "publish_redact": {
@@ -161,7 +162,7 @@ def save(cfg: dict[str, Any]) -> None:
161
162
  # --- Multi-account profiles ---
162
163
 
163
164
  _PROFILE_KEYS = [
164
- "token", "refresh_token", "email", "account_id",
165
+ "token", "refresh_token", "email", "account_id", "username",
165
166
  "last_auth_at", "master_key_fingerprint",
166
167
  "e2e_mode", "e2e_fingerprint",
167
168
  "journal_mode", "journal_credits",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "methodproof"
3
- version = "0.7.21"
3
+ version = "0.7.23"
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"]
@@ -125,7 +125,7 @@ def cli_args():
125
125
  "verbose": False, "streaming": False, "force": False,
126
126
  "local": False, "api_url": None, "no_key": False, "auto": None,
127
127
  "account": None, "purge": False, "keep_sessions": False,
128
- "anonymous": False,
128
+ "anonymous": False, "yes": False,
129
129
  }
130
130
  defaults.update(kwargs)
131
131
  return argparse.Namespace(**defaults)
@@ -427,11 +427,13 @@ def test_consent_detailed_redaction_toggle():
427
427
  # ── cmd_init ──
428
428
 
429
429
 
430
- @patch("methodproof.tui.init.run")
431
- def test_init_first_run(mock_tui_init, cli_args):
432
- # First run: consent_acknowledged=False forces TUI regardless of ui_mode
433
- cli.cmd_init(cli_args())
434
- mock_tui_init.assert_called_once()
430
+ @patch("methodproof.hook.install", return_value="hook installed")
431
+ @patch("methodproof.integrity.has_keypair", return_value=True)
432
+ def test_init_first_run(mock_keypair, mock_hook, cli_args, capsys):
433
+ # First run with --yes: all prompts auto-accepted, no stdin required
434
+ cli.cmd_init(cli_args(yes=True))
435
+ out = capsys.readouterr().out
436
+ assert "METHODPROOF" in out or "Recording" in out or "mp start" in out
435
437
 
436
438
 
437
439
  @patch("methodproof.integrity.has_keypair", return_value=True)
@@ -1,3 +0,0 @@
1
- # Auto-generated by code-review-graph — do not commit database files.
2
- # The graph.db contains absolute paths and code structure metadata.
3
- *
File without changes
File without changes
File without changes
File without changes