feat: poker session history — browse, delete, and Lyra lookup

Answers three gaps: no way to delete a single poker session (only clear_all),
no way to browse past sessions, and Lyra could only see aggregate stats.

- poker.list_sessions() (per-session summary + hand count + recap flag) and
  poker.delete_session() (removes a session + its hands/reads/observations/
  stacks/rituals; keeps the persistent villain file).
- /history page (date, stakes, venue, net, hours, recap link, per-row delete with
  confirm) + /history/data + DELETE /history/{id}. Nav links from chat + HUD.
- recent_sessions read tool, added to the shared lookups so Lyra can answer
  "how'd my last few sessions go?" in either mode.
- Delete is UI/CLI only — deliberately not a Lyra tool.
- test_modes.py +2 (list/delete, recent_sessions); 44 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-20 00:21:48 +00:00
parent 35c973df05
commit e1e89c07e4
8 changed files with 223 additions and 3 deletions
+28
View File
@@ -221,6 +221,27 @@ def _session_stats(args: dict, ctx: dict) -> str:
f"{st['hands_logged']} hands logged (tags: {tags}).")
def _recent_sessions(args: dict, ctx: dict) -> str:
try:
n = int(args.get("limit") or 8)
except (TypeError, ValueError):
n = 8
rows = poker.list_sessions(limit=n)
if not rows:
return "No sessions logged yet."
out = []
for s in rows:
net = s.get("net")
netstr = (f"{net:+.0f}" if net is not None
else "live" if s.get("status") == "live" else "")
hrs = f", {s['hours']:g}h" if s.get("hours") else ""
recap = " · recap" if s.get("has_recap") else ""
out.append(f"#{s['id']} {(s.get('started_at') or '')[:10]} "
f"{s.get('stakes') or '?'} {s.get('game') or ''} @ {s.get('venue') or '?'} "
f"— net {netstr}{hrs} ({s.get('hands', 0)} hands){recap}")
return "\n".join(out)
def _running_stats(args: dict, ctx: dict) -> str:
rs = poker.running_stats(stakes=args.get("stakes"), venue=args.get("venue"),
game=args.get("game"), since=args.get("since"))
@@ -432,6 +453,13 @@ TOOLS.update({
"confidence-bank entries so far. Use whenever he asks where he's at, what's in "
"the bank, his stack or net, or if gator mode is on — answer from THIS, not memory.",
{}, [])},
"recent_sessions": {"handler": _recent_sessions, "spec": _f(
"recent_sessions",
"List Brian's recent poker sessions — date, stakes, venue, net, hours, hand "
"count. Use when he asks about past sessions, how recent ones went, or to find "
"a session to review. Answer from this, not memory.",
{"limit": {**_N, "description": "How many recent sessions (default 8)"}},
[])},
"running_stats": {"handler": _running_stats, "spec": _f(
"running_stats",
"Cumulative results across closed sessions (net, $/hr, by stake). Optionally filter.",