diff options
| author | Elvis Claros Castro <elvis@claros.ar> | 2026-08-17 15:14:11 -0300 |
|---|---|---|
| committer | Elvis Claros Castro <elvis@claros.ar> | 2026-08-17 15:14:11 -0300 |
| commit | ffe36e782b064a31b7a695ac1372f1329ac79153 (patch) | |
| tree | 0a40ea9ade098e8e9ff21028d4a6442c133cba15 /claude_sesiones/webpage.py | |
| parent | 0d1fe286ac6ea30b91c15b44c0872b57a864ea7f (diff) | |
| download | claude-logbook-ffe36e782b064a31b7a695ac1372f1329ac79153.tar.gz claude-logbook-ffe36e782b064a31b7a695ac1372f1329ac79153.zip | |
Renombrar el proyecto a claude-logbook
El nombre en español no se encontraba, y la zona de "claude + sessions" ya
está poblada por cosas distintas con las que se confundía:
gapmiss/claude-sessions plugin de Obsidian
kyupid/claude-sessions monitor de sesiones en curso (PyPI)
claude-session-manager wrapper que preserva contexto (PyPI)
LearnedGeek/claude-recall búsqueda con SQLite FTS5 (PyPI)
"logbook" cubre las dos mitades — las conversaciones y las memorias — sin
caer en "session manager", y encaja con lo que el proyecto produce: una
bitácora que se abre en cualquier lado.
claude_sesiones/ → claude_logbook/ y todas las referencias
~/.cache/claude-sesiones → ~/.cache/claude-logbook
el resumen de PyPI pasa a inglés, como el README principal
El comando viejo sigue funcionando: pyproject declara claude-sesiones como
segundo entry point del mismo main, para no rehacer la memoria muscular.
La interfaz sigue en español; solo cambia cómo se llama e instala el paquete.
De paso, memory.py faltaba en la tabla de módulos de los dos READMEs.
Claude-Session: https://claude.ai/code/session_01RmtZ9qBemrc9TncwVTG6ED
Diffstat (limited to 'claude_sesiones/webpage.py')
| -rw-r--r-- | claude_sesiones/webpage.py | 74 |
1 files changed, 0 insertions, 74 deletions
diff --git a/claude_sesiones/webpage.py b/claude_sesiones/webpage.py deleted file mode 100644 index c8550fe..0000000 --- a/claude_sesiones/webpage.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Genera la página HTML autocontenida a partir de las sesiones. - -El resultado no necesita red ni servidor: los datos y las transcripciones van -embebidos adentro y se abre con doble clic. -""" - -import json -from importlib import resources - -MARKER = "__DATA__" - -TEMPLATE_NAME = "template.html" - - -class TemplateError(Exception): - """El template no tiene la forma que espera el generador.""" - - -def template_text(path=None): - if path: - with open(path, encoding="utf-8") as f: - return f.read() - return (resources.files(__package__) / TEMPLATE_NAME).read_text(encoding="utf-8") - - -def build_payload(sessions, memories=None): - """Estructura que viaja embebida en la página. - - Un objeto y no una lista porque la página muestra dos cosas distintas: - sesiones y memorias de proyecto. - """ - return {"s": list(sessions), "m": list(memories or ())} - - -def encode_payload(payload): - """Serializa el payload para meterlo en un <script type=application/json>. - - El parser de HTML corta ese bloque en el primer "</script", y las - transcripciones tienen HTML adentro. Escapamos "</" como "<\\/", que es un - escape válido de JSON: JSON.parse lo devuelve intacto. - """ - raw = json.dumps(payload, ensure_ascii=False, separators=(",", ":")) - return raw.replace("</", "<\\/") - - -def render(records, memories=None, template=None): - """Devuelve el HTML completo con los datos ya embebidos.""" - html = template if template is not None else template_text() - # No se puede verificar el resultado buscando el marcador: estas mismas - # sesiones incluyen conversaciones sobre este script, así que el payload lo - # contiene como texto. Validamos el template antes de sustituir. - if html.count(MARKER) != 1: - raise TemplateError( - f"el template debe tener exactamente un {MARKER} " - f"(encontrados: {html.count(MARKER)})") - return html.replace(MARKER, encode_payload(build_payload(records, memories))) - - -def write(records, out_path, memories=None, template=None): - """Escribe la página y devuelve un resumen de lo que quedó adentro.""" - html = render(records, memories=memories, template=template) - with open(out_path, "w", encoding="utf-8") as f: - f.write(html) - return summary(records, memories) - - -def summary(records, memories=None): - return { - "sesiones": len(records), - "proyectos": len({r["p"] for r in records}), - "mensajes": sum(r["u"] for r in records), - "bloques": sum(len(r["c"]) for r in records), - "memorias": len(memories or ()), - } |