From d45bfbee2a174e811e212482c094e929b6cdd3d5 Mon Sep 17 00:00:00 2001 From: git_alhan Date: Fri, 26 Jun 2026 02:30:42 +0300 Subject: [PATCH] feat: auto-create default config on register + resume via session_id --- __init__.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/__init__.py b/__init__.py index 2e24fb1..df27bb4 100644 --- a/__init__.py +++ b/__init__.py @@ -144,6 +144,49 @@ def _build_row(columns: list, session: dict, index: int = 0) -> str: return " ".join(parts) +# ── Default config bootstrapping ───────────────────────────────────── + +def _ensure_default_config() -> None: + """Create session_list_config.yaml with sensible defaults if missing.""" + config_path = _hermes_home() / "session_list_config.yaml" + if config_path.exists(): + return + + default_config = """\ +# Hermes Session List — Column Configuration +# +# columns: ordered list of columns to display. +# field: session row key — available fields: +# # (row index), id, source, model, title, started_at, +# ended_at, message_count, preview, last_active, +# input_tokens, output_tokens, total_tokens, net_input, net_total, +# cache_read_tokens, cache_write_tokens, reasoning_tokens +# width: column width in characters +# (0 = free-form for the LAST column — can overflow) +# label: header text +# +# NOTE: input_tokens = cache miss (Hermes already deducts cache hits). +# net_input = max(0, input - cache) — would double-deduct. +# +# Used by /sl slash command. Survives `hermes update`. + +columns: + - {field: last_active, width: 10, label: Active} + - {field: title, width: 42, label: Title} + - {field: message_count, width: 4, label: Msgs} + - {field: cache_read_tokens, width: 6, label: Hit} + - {field: input_tokens, width: 6, label: Miss} + - {field: output_tokens, width: 6, label: Out} + - {field: id, width: 34, label: Session ID} +""" + + try: + config_path.parent.mkdir(parents=True, exist_ok=True) + config_path.write_text(default_config, encoding="utf-8") + except Exception: + pass # Silent fail — handler falls back to hardcoded defaults + + # ── Slash command handler ──────────────────────────────────────────── def _handle_sl(raw_args: str) -> Optional[str]: @@ -164,11 +207,13 @@ def _handle_sl(raw_args: str) -> Optional[str]: if not columns: columns = [ - {"field": "#", "width": 3, "label": "#"}, - {"field": "title", "width": 32, "label": "Title"}, - {"field": "preview", "width": 40, "label": "Preview"}, - {"field": "last_active", "width": 13, "label": "Last Active"}, - {"field": "id", "width": 0, "label": "ID"}, + {"field": "last_active", "width": 10, "label": "Active"}, + {"field": "title", "width": 42, "label": "Title"}, + {"field": "message_count", "width": 4, "label": "Msgs"}, + {"field": "cache_read_tokens", "width": 6, "label": "Hit"}, + {"field": "input_tokens", "width": 6, "label": "Miss"}, + {"field": "output_tokens", "width": 6, "label": "Out"}, + {"field": "id", "width": 34, "label": "Session ID"}, ] # Parse limit from args @@ -197,7 +242,7 @@ def _handle_sl(raw_args: str) -> Optional[str]: # Add hint for /resume lines.append("") - lines.append("Use /resume <#> to continue a session. Example: /resume 2") + lines.append("Use /resume to continue. Example: /resume 20260612_222504_8a868b") return "\n".join(lines) @@ -205,6 +250,9 @@ def _handle_sl(raw_args: str) -> Optional[str]: # ── Plugin registration ────────────────────────────────────────────── def register(ctx) -> None: + # Ensure default config file exists on first load + _ensure_default_config() + ctx.register_command( "sl", handler=_handle_sl,