methodproof 0.7.21__tar.gz → 0.7.22__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.
- {methodproof-0.7.21 → methodproof-0.7.22}/CHANGELOG.md +8 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/PKG-INFO +1 -1
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/cli.py +20 -4
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/config.py +2 -1
- {methodproof-0.7.21 → methodproof-0.7.22}/pyproject.toml +1 -1
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/conftest.py +1 -1
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_start.py +7 -5
- methodproof-0.7.21/.code-review-graph/.gitignore +0 -3
- methodproof-0.7.21/.code-review-graph/graph.db +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/.github/workflows/ci.yml +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/.gitignore +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/LICENSE +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/README.md +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/__init__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/__main__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/_daemon.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/agents/__init__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/agents/base.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/agents/music.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/agents/terminal.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/agents/watcher.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/analysis.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/binding.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/bip39.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/bridge.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/crypto.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/e2e.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/graph.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hook.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/__init__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/claude_code.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/claude_code.sh +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/cline_hook.sh +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/codex_hook.sh +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/gemini_hook.sh +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/install.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/kiro_hook.sh +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/mcp_register.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/openclaw/HOOK.md +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/openclaw/handler.ts +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/openclaw_install.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/opencode_plugin.js +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/hooks/wrappers.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/integrity.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/kdf.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/keychain.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/live.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/lock.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/mcp.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/migrate_db.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/proxy.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/proxy_daemon.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/repos.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/skills/methodproof/SKILL.md +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/store.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/sync.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/__init__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/consent.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/init.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/log.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/login_success.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/review.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/start.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/status.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/tui/theme.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/viewer.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/methodproof/wordlist.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/test_windows_compat.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/__init__.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_analysis.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_auth.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_config.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_helpers.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_session.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_share.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_cli_update.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_e2e_integration.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_graph.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_hooks.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_live.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_openclaw_hooks.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_profiles.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_security.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_store.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_sync.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_viewer.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/tests/test_wrappers.py +0 -0
- {methodproof-0.7.21 → methodproof-0.7.22}/uv.lock +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.22] — 2026-04-11
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **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.
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- **`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.
|
|
10
|
+
|
|
3
11
|
## [0.7.20] — 2026-04-11
|
|
4
12
|
|
|
5
13
|
### Fixed
|
|
@@ -491,7 +491,8 @@ def cmd_init(args: argparse.Namespace) -> None:
|
|
|
491
491
|
def cmd_shell_hook(_args: argparse.Namespace) -> None:
|
|
492
492
|
"""Print the shell hook text for the current shell (for eval)."""
|
|
493
493
|
_, hook_text = hook.get_shell_rc()
|
|
494
|
-
|
|
494
|
+
alias = 'Set-Alias mp methodproof' if sys.platform == "win32" else 'alias mp="methodproof"'
|
|
495
|
+
print(hook_text.strip() + "\n" + alias)
|
|
495
496
|
|
|
496
497
|
|
|
497
498
|
# ── TUI mode helpers ──────────────────────────────────────────────────────────
|
|
@@ -1203,8 +1204,11 @@ def cmd_start(args: argparse.Namespace) -> None:
|
|
|
1203
1204
|
config.save(cfg)
|
|
1204
1205
|
|
|
1205
1206
|
active = [k for k, v in capture.items() if v]
|
|
1207
|
+
username = cfg.get("username")
|
|
1208
|
+
account_label = f"@{username}" if username else (cfg.get("email") or cfg.get("account_id", "")[:8])
|
|
1206
1209
|
print(f"\n{_banner()}")
|
|
1207
1210
|
print(f"Recording: {sid[:8]}")
|
|
1211
|
+
print(f"Account: {account_label}")
|
|
1208
1212
|
print(f"Watching: {watch_dir}")
|
|
1209
1213
|
if repo_url:
|
|
1210
1214
|
print(f"Repo: {repo_url}")
|
|
@@ -1397,7 +1401,7 @@ def cmd_stop(args: argparse.Namespace) -> None:
|
|
|
1397
1401
|
session = store.get_session(sid)
|
|
1398
1402
|
cfg["active_session"] = None
|
|
1399
1403
|
config.save(cfg)
|
|
1400
|
-
_print_summary(session, stats)
|
|
1404
|
+
_print_summary(session, stats, cfg)
|
|
1401
1405
|
|
|
1402
1406
|
|
|
1403
1407
|
def cmd_view(args: argparse.Namespace) -> None:
|
|
@@ -1705,6 +1709,13 @@ def cmd_login(args: argparse.Namespace) -> None:
|
|
|
1705
1709
|
cfg["account_id"] = claims.get("user_id", "")
|
|
1706
1710
|
cfg["last_auth_at"] = time.time()
|
|
1707
1711
|
cfg["master_key_fingerprint"] = "" # clear stale fingerprint from previous account
|
|
1712
|
+
# Fetch profile to store email and username
|
|
1713
|
+
try:
|
|
1714
|
+
profile = _request("GET", "/auth/me", api, poll["token"])
|
|
1715
|
+
cfg["email"] = profile.get("email", "")
|
|
1716
|
+
cfg["username"] = profile.get("username") or ""
|
|
1717
|
+
except Exception as exc:
|
|
1718
|
+
_log_debug("auth.profile_fetch_failed", error=str(exc))
|
|
1708
1719
|
config.save(cfg)
|
|
1709
1720
|
config.save_active_profile(cfg)
|
|
1710
1721
|
print(" done.\n")
|
|
@@ -1714,7 +1725,7 @@ def cmd_login(args: argparse.Namespace) -> None:
|
|
|
1714
1725
|
sync_research_consent(cfg["token"], cfg["api_url"])
|
|
1715
1726
|
from methodproof.tui.login_success import run as show_success
|
|
1716
1727
|
show_success(
|
|
1717
|
-
display_name=cfg.get("email") or cfg.get("account_id", "")[:8],
|
|
1728
|
+
display_name=cfg.get("username") or cfg.get("email") or cfg.get("account_id", "")[:8],
|
|
1718
1729
|
email=cfg.get("email", ""),
|
|
1719
1730
|
account_count=len(cfg.get("profiles", {})),
|
|
1720
1731
|
added=getattr(args, "add", False),
|
|
@@ -2011,11 +2022,16 @@ def _duration(s: dict) -> str:
|
|
|
2011
2022
|
return f"{secs // 60}:{secs % 60:02d}"
|
|
2012
2023
|
|
|
2013
2024
|
|
|
2014
|
-
def _print_summary(session: dict | None, stats: dict) -> None:
|
|
2025
|
+
def _print_summary(session: dict | None, stats: dict, cfg: dict | None = None) -> None:
|
|
2015
2026
|
if not session:
|
|
2016
2027
|
return
|
|
2028
|
+
cfg = cfg or {}
|
|
2029
|
+
username = cfg.get("username")
|
|
2030
|
+
account_label = f"@{username}" if username else (cfg.get("email") or cfg.get("account_id", "")[:8])
|
|
2017
2031
|
print(f"\n{_banner()}")
|
|
2018
2032
|
print(f"Session: {session['id'][:8]}")
|
|
2033
|
+
if account_label:
|
|
2034
|
+
print(f" Account: {account_label}")
|
|
2019
2035
|
print(f" Events: {session['total_events']}")
|
|
2020
2036
|
print(f" Duration: {_duration(session)}")
|
|
2021
2037
|
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.
|
|
3
|
+
version = "0.7.22"
|
|
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.
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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)
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|