methodproof 0.7.20__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.20 → methodproof-0.7.22}/CHANGELOG.md +8 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/PKG-INFO +1 -1
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/__init__.py +1 -1
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/cli.py +77 -44
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/config.py +2 -1
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/init.py +21 -11
- {methodproof-0.7.20 → methodproof-0.7.22}/pyproject.toml +1 -1
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/conftest.py +1 -1
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_start.py +7 -5
- {methodproof-0.7.20 → methodproof-0.7.22}/.github/workflows/ci.yml +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/.gitignore +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/LICENSE +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/README.md +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/__main__.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/_daemon.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/agents/__init__.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/agents/base.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/agents/music.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/agents/terminal.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/agents/watcher.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/analysis.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/binding.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/bip39.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/bridge.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/crypto.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/e2e.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/graph.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hook.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/__init__.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/claude_code.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/claude_code.sh +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/cline_hook.sh +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/codex_hook.sh +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/gemini_hook.sh +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/install.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/kiro_hook.sh +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/mcp_register.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/openclaw/HOOK.md +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/openclaw/handler.ts +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/openclaw_install.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/opencode_plugin.js +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/hooks/wrappers.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/integrity.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/kdf.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/keychain.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/live.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/lock.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/mcp.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/migrate_db.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/proxy.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/proxy_daemon.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/repos.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/skills/methodproof/SKILL.md +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/store.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/sync.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/__init__.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/consent.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/log.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/login_success.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/review.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/start.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/status.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/tui/theme.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/viewer.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/methodproof/wordlist.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/test_windows_compat.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/__init__.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_analysis.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_auth.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_config.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_helpers.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_session.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_share.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_cli_update.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_e2e_integration.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_graph.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_hooks.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_live.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_openclaw_hooks.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_profiles.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_security.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_store.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_sync.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_viewer.py +0 -0
- {methodproof-0.7.20 → methodproof-0.7.22}/tests/test_wrappers.py +0 -0
- {methodproof-0.7.20 → 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
|
|
@@ -334,62 +334,74 @@ def _run_consent_detailed(cfg: dict) -> dict:
|
|
|
334
334
|
def cmd_init(args: argparse.Namespace) -> None:
|
|
335
335
|
config.ensure_dirs()
|
|
336
336
|
cfg = config.load()
|
|
337
|
+
yes = getattr(args, "yes", False)
|
|
337
338
|
if getattr(args, "force", False):
|
|
338
339
|
for key in ("consent_acknowledged", "auto_update_offered", "alias_offered", "local_ai_ports_offered", "ui_mode_offered"):
|
|
339
340
|
cfg.pop(key, None)
|
|
340
341
|
config.save(cfg)
|
|
341
342
|
|
|
342
|
-
# TUI wizard — runs when nothing is set up yet, or on --force, or when ui_mode is on
|
|
343
|
-
needs_setup = not cfg.get("consent_acknowledged")
|
|
344
|
-
use_ui = needs_setup or _resolve_ui(args, cfg)
|
|
345
|
-
if use_ui:
|
|
346
|
-
from methodproof.tui.init import run as tui_init
|
|
347
|
-
tui_init(cfg)
|
|
348
|
-
return
|
|
349
|
-
|
|
350
343
|
if not cfg.get("consent_acknowledged"):
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
cfg["
|
|
344
|
+
if yes:
|
|
345
|
+
from methodproof import config as cfg_mod
|
|
346
|
+
cfg["capture"] = dict(cfg_mod._DEFAULTS["capture"])
|
|
347
|
+
cfg["publish_redact"] = dict(cfg_mod._DEFAULTS["publish_redact"])
|
|
348
|
+
cfg["consent_acknowledged"] = True
|
|
355
349
|
config.save(cfg)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
350
|
+
print("Capture: all defaults accepted")
|
|
351
|
+
else:
|
|
352
|
+
cfg = _run_consent(cfg)
|
|
353
|
+
config.save(cfg)
|
|
354
|
+
if cfg.get("token"):
|
|
355
|
+
cfg["_pending_research_sync"] = True
|
|
356
|
+
config.save(cfg)
|
|
357
|
+
from methodproof.sync import sync_research_consent
|
|
358
|
+
sync_research_consent(cfg["token"], cfg["api_url"])
|
|
359
|
+
print()
|
|
359
360
|
|
|
360
361
|
capture = cfg.get("capture", {})
|
|
361
362
|
store.init_db()
|
|
362
363
|
|
|
363
364
|
# Offer auto-update (recommended)
|
|
364
365
|
if not cfg.get("auto_update_offered"):
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
366
|
+
if yes:
|
|
367
|
+
cfg["auto_update_offered"] = True
|
|
368
|
+
cfg["auto_update"] = True
|
|
369
|
+
print("Auto-update: ON")
|
|
370
|
+
else:
|
|
371
|
+
answer = input("Enable auto-update (recommended)? [Y/n]: ").strip().lower()
|
|
372
|
+
cfg["auto_update_offered"] = True
|
|
373
|
+
cfg["auto_update"] = answer != "n"
|
|
374
|
+
print(f"Auto-update: {'ON — updates install before each session' if cfg['auto_update'] else 'OFF — toggle with: mp update --auto'}")
|
|
369
375
|
config.save(cfg)
|
|
370
376
|
|
|
371
377
|
# Offer mp alias
|
|
372
378
|
if not cfg.get("alias_offered"):
|
|
373
|
-
|
|
374
|
-
cfg["alias_offered"] = True
|
|
375
|
-
if answer != "n":
|
|
379
|
+
if yes:
|
|
376
380
|
_install_alias()
|
|
381
|
+
cfg["alias_offered"] = True
|
|
377
382
|
cfg["alias_installed"] = True
|
|
378
383
|
print("Alias: mp -> methodproof")
|
|
379
384
|
else:
|
|
380
|
-
|
|
385
|
+
answer = input("Install `mp` as a shorthand alias? [Y/n]: ").strip().lower()
|
|
386
|
+
cfg["alias_offered"] = True
|
|
387
|
+
if answer != "n":
|
|
388
|
+
_install_alias()
|
|
389
|
+
cfg["alias_installed"] = True
|
|
390
|
+
print("Alias: mp -> methodproof")
|
|
391
|
+
else:
|
|
392
|
+
print("Alias: skipped")
|
|
381
393
|
config.save(cfg)
|
|
382
394
|
|
|
383
395
|
# Offer classic CLI mode (TUI is default)
|
|
384
396
|
if not cfg.get("ui_mode_offered"):
|
|
385
397
|
cfg["ui_mode_offered"] = True
|
|
386
|
-
|
|
387
|
-
if answer == "y":
|
|
388
|
-
cfg["ui_mode"] = False
|
|
389
|
-
print("Output mode: classic (toggle anytime with: mp ui on/off)")
|
|
390
|
-
else:
|
|
398
|
+
if yes:
|
|
391
399
|
cfg["ui_mode"] = True
|
|
392
|
-
print("Output mode: rich TUI
|
|
400
|
+
print("Output mode: rich TUI")
|
|
401
|
+
else:
|
|
402
|
+
answer = input("Prefer classic terminal output instead of the rich TUI? [y/N]: ").strip().lower()
|
|
403
|
+
cfg["ui_mode"] = answer != "y"
|
|
404
|
+
print(f"Output mode: {'classic (toggle anytime with: mp ui on/off)' if not cfg['ui_mode'] else 'rich TUI (toggle anytime with: mp ui off)'}")
|
|
393
405
|
config.save(cfg)
|
|
394
406
|
|
|
395
407
|
# Shell hook — needed for terminal commands
|
|
@@ -440,19 +452,23 @@ def cmd_init(args: argparse.Namespace) -> None:
|
|
|
440
452
|
|
|
441
453
|
# Local AI ports — capture traffic from local LLM servers
|
|
442
454
|
if ai_enabled and not cfg.get("local_ai_ports_offered"):
|
|
443
|
-
answer = input("Run any local AI models (Ollama, LM Studio, vLLM, etc.)? [y/N]: ").strip().lower()
|
|
444
455
|
cfg["local_ai_ports_offered"] = True
|
|
445
|
-
if
|
|
446
|
-
raw = input("Enter ports (comma-separated, e.g. 8080,5000,7860): ").strip()
|
|
447
|
-
ports = [int(p.strip()) for p in raw.split(",") if p.strip().isdigit()]
|
|
448
|
-
cfg["local_ai_ports"] = ports
|
|
449
|
-
if ports:
|
|
450
|
-
print(f"Local AI ports: {', '.join(str(p) for p in ports)} (proxy will decode these)")
|
|
451
|
-
else:
|
|
452
|
-
print("Local AI ports: none added")
|
|
453
|
-
else:
|
|
456
|
+
if yes:
|
|
454
457
|
cfg["local_ai_ports"] = []
|
|
455
|
-
print("Local AI ports:
|
|
458
|
+
print("Local AI ports: using defaults (Ollama 11434, Jan 1234)")
|
|
459
|
+
else:
|
|
460
|
+
answer = input("Run any local AI models (Ollama, LM Studio, vLLM, etc.)? [y/N]: ").strip().lower()
|
|
461
|
+
if answer == "y":
|
|
462
|
+
raw = input("Enter ports (comma-separated, e.g. 8080,5000,7860): ").strip()
|
|
463
|
+
ports = [int(p.strip()) for p in raw.split(",") if p.strip().isdigit()]
|
|
464
|
+
cfg["local_ai_ports"] = ports
|
|
465
|
+
if ports:
|
|
466
|
+
print(f"Local AI ports: {', '.join(str(p) for p in ports)} (proxy will decode these)")
|
|
467
|
+
else:
|
|
468
|
+
print("Local AI ports: none added")
|
|
469
|
+
else:
|
|
470
|
+
cfg["local_ai_ports"] = []
|
|
471
|
+
print("Local AI ports: skipped (built-in: Ollama 11434, Jan 1234)")
|
|
456
472
|
config.save(cfg)
|
|
457
473
|
|
|
458
474
|
# Signing keypair for attestation
|
|
@@ -475,7 +491,8 @@ def cmd_init(args: argparse.Namespace) -> None:
|
|
|
475
491
|
def cmd_shell_hook(_args: argparse.Namespace) -> None:
|
|
476
492
|
"""Print the shell hook text for the current shell (for eval)."""
|
|
477
493
|
_, hook_text = hook.get_shell_rc()
|
|
478
|
-
|
|
494
|
+
alias = 'Set-Alias mp methodproof' if sys.platform == "win32" else 'alias mp="methodproof"'
|
|
495
|
+
print(hook_text.strip() + "\n" + alias)
|
|
479
496
|
|
|
480
497
|
|
|
481
498
|
# ── TUI mode helpers ──────────────────────────────────────────────────────────
|
|
@@ -1187,8 +1204,11 @@ def cmd_start(args: argparse.Namespace) -> None:
|
|
|
1187
1204
|
config.save(cfg)
|
|
1188
1205
|
|
|
1189
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])
|
|
1190
1209
|
print(f"\n{_banner()}")
|
|
1191
1210
|
print(f"Recording: {sid[:8]}")
|
|
1211
|
+
print(f"Account: {account_label}")
|
|
1192
1212
|
print(f"Watching: {watch_dir}")
|
|
1193
1213
|
if repo_url:
|
|
1194
1214
|
print(f"Repo: {repo_url}")
|
|
@@ -1381,7 +1401,7 @@ def cmd_stop(args: argparse.Namespace) -> None:
|
|
|
1381
1401
|
session = store.get_session(sid)
|
|
1382
1402
|
cfg["active_session"] = None
|
|
1383
1403
|
config.save(cfg)
|
|
1384
|
-
_print_summary(session, stats)
|
|
1404
|
+
_print_summary(session, stats, cfg)
|
|
1385
1405
|
|
|
1386
1406
|
|
|
1387
1407
|
def cmd_view(args: argparse.Namespace) -> None:
|
|
@@ -1689,6 +1709,13 @@ def cmd_login(args: argparse.Namespace) -> None:
|
|
|
1689
1709
|
cfg["account_id"] = claims.get("user_id", "")
|
|
1690
1710
|
cfg["last_auth_at"] = time.time()
|
|
1691
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))
|
|
1692
1719
|
config.save(cfg)
|
|
1693
1720
|
config.save_active_profile(cfg)
|
|
1694
1721
|
print(" done.\n")
|
|
@@ -1698,7 +1725,7 @@ def cmd_login(args: argparse.Namespace) -> None:
|
|
|
1698
1725
|
sync_research_consent(cfg["token"], cfg["api_url"])
|
|
1699
1726
|
from methodproof.tui.login_success import run as show_success
|
|
1700
1727
|
show_success(
|
|
1701
|
-
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],
|
|
1702
1729
|
email=cfg.get("email", ""),
|
|
1703
1730
|
account_count=len(cfg.get("profiles", {})),
|
|
1704
1731
|
added=getattr(args, "add", False),
|
|
@@ -1995,11 +2022,16 @@ def _duration(s: dict) -> str:
|
|
|
1995
2022
|
return f"{secs // 60}:{secs % 60:02d}"
|
|
1996
2023
|
|
|
1997
2024
|
|
|
1998
|
-
def _print_summary(session: dict | None, stats: dict) -> None:
|
|
2025
|
+
def _print_summary(session: dict | None, stats: dict, cfg: dict | None = None) -> None:
|
|
1999
2026
|
if not session:
|
|
2000
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])
|
|
2001
2031
|
print(f"\n{_banner()}")
|
|
2002
2032
|
print(f"Session: {session['id'][:8]}")
|
|
2033
|
+
if account_label:
|
|
2034
|
+
print(f" Account: {account_label}")
|
|
2003
2035
|
print(f" Events: {session['total_events']}")
|
|
2004
2036
|
print(f" Duration: {_duration(session)}")
|
|
2005
2037
|
print(f" Graph: {stats['next']} links, {stats['causal']} causal")
|
|
@@ -2115,6 +2147,7 @@ def main() -> None:
|
|
|
2115
2147
|
|
|
2116
2148
|
s = sub.add_parser("init", help="Install shell hook")
|
|
2117
2149
|
s.add_argument("--force", action="store_true", help="Re-run all setup prompts from scratch")
|
|
2150
|
+
s.add_argument("-y", "--yes", action="store_true", help="Accept all defaults, no prompts")
|
|
2118
2151
|
_add_ui_flags(s)
|
|
2119
2152
|
sub.add_parser("shell-hook", help="Print shell hook for eval (activates without restart)")
|
|
2120
2153
|
s = sub.add_parser("start", help="Start recording")
|
|
@@ -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",
|
|
@@ -8,7 +8,7 @@ from textual.screen import Screen
|
|
|
8
8
|
from textual.widgets import Button, Footer, Header, Label, RichLog, Rule, Static, Switch
|
|
9
9
|
|
|
10
10
|
from methodproof import config as cfg_mod
|
|
11
|
-
from methodproof.tui.theme import BASE_CSS, BORDER, DIM, GOLD, GREEN, PURPLE, RED, TEXT
|
|
11
|
+
from methodproof.tui.theme import BASE_CSS, BG, BORDER, DIM, GOLD, GREEN, PURPLE, RED, TEXT
|
|
12
12
|
|
|
13
13
|
_REDACTABLE = [
|
|
14
14
|
("command_output", "Terminal output"),
|
|
@@ -33,15 +33,29 @@ PrefsScreen {{
|
|
|
33
33
|
color: {DIM};
|
|
34
34
|
margin: 0 0 1 0;
|
|
35
35
|
}}
|
|
36
|
+
Switch {{
|
|
37
|
+
border: none;
|
|
38
|
+
height: 1;
|
|
39
|
+
width: 10;
|
|
40
|
+
background: {BORDER};
|
|
41
|
+
padding: 0 1;
|
|
42
|
+
}}
|
|
43
|
+
Switch.-on {{
|
|
44
|
+
background: {GREEN};
|
|
45
|
+
}}
|
|
46
|
+
Switch .switch--slider {{
|
|
47
|
+
color: {TEXT};
|
|
48
|
+
background: {DIM};
|
|
49
|
+
}}
|
|
50
|
+
Switch.-on .switch--slider {{
|
|
51
|
+
color: {BG};
|
|
52
|
+
background: {TEXT};
|
|
53
|
+
}}
|
|
36
54
|
.toggle-row {{
|
|
37
|
-
height:
|
|
55
|
+
height: 1;
|
|
38
56
|
align: left middle;
|
|
39
57
|
margin: 0 0 1 0;
|
|
40
58
|
}}
|
|
41
|
-
.toggle-row Switch {{
|
|
42
|
-
margin: 0 1 0 0;
|
|
43
|
-
width: 6;
|
|
44
|
-
}}
|
|
45
59
|
.row-label {{
|
|
46
60
|
width: 1fr;
|
|
47
61
|
color: {TEXT};
|
|
@@ -57,14 +71,10 @@ PrefsScreen {{
|
|
|
57
71
|
width: 5;
|
|
58
72
|
}}
|
|
59
73
|
.opt-row {{
|
|
60
|
-
height:
|
|
74
|
+
height: 1;
|
|
61
75
|
align: left middle;
|
|
62
76
|
margin: 0 0 1 0;
|
|
63
77
|
}}
|
|
64
|
-
.opt-row Switch {{
|
|
65
|
-
margin: 0 1 0 0;
|
|
66
|
-
width: 6;
|
|
67
|
-
}}
|
|
68
78
|
#fs-status {{
|
|
69
79
|
color: {DIM};
|
|
70
80
|
height: auto;
|
|
@@ -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)
|
|
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
|