feat: session naming, username/persona rename, help page, contrast fixes

- Session name field: PATCH /sessions/{id} endpoint, inline rename button in UI
- Persona rename: inline ✏ toggle form in settings, POST /settings/persona/rename
- Username rename: inline form in settings, POST /settings/username (renames home dir, forces re-login)
- Help page: dedicated /help route replacing modal, collapsible sections
- Per-persona isolation: files.py and session_store.py now scope to correct user/persona
- Contrast/visibility: muted text bumped to slate-400+, session rename btn at 0.4 opacity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-23 23:10:12 -04:00
parent 1b425a539f
commit 0cf0d65e9e
10 changed files with 351 additions and 33 deletions

View File

@@ -62,12 +62,29 @@ def save(session_id: str, messages: list[dict]) -> None:
# Enforce rolling window
windowed = messages[-settings.max_history_messages:]
path.write_text(json.dumps({
data = {
"session_id": session_id,
"created": existing.get("created", datetime.now().isoformat()),
"updated": datetime.now().isoformat(),
"messages": windowed,
}, indent=2))
}
if "name" in existing:
data["name"] = existing["name"]
path.write_text(json.dumps(data, indent=2))
def rename(session_id: str, name: str) -> bool:
"""Set (or clear) the friendly name on a session. Returns False if not found."""
path = _path(session_id)
if not path.exists():
return False
data = json.loads(path.read_text())
if name:
data["name"] = name
else:
data.pop("name", None)
path.write_text(json.dumps(data, indent=2))
return True
def delete(session_id: str) -> bool:
@@ -87,11 +104,13 @@ def list_all() -> list[dict]:
for f in sorted(d.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True):
try:
data = json.loads(f.read_text())
results.append({
entry = {
"session_id": data["session_id"],
"name": data.get("name", ""),
"updated": data.get("updated"),
"message_count": len(data.get("messages", [])),
})
}
results.append(entry)
except Exception:
pass
return results