chore: auto-commit (799 archivos)

- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 00:28:20 +02:00
parent d110aa40f9
commit cfdf515228
805 changed files with 5515 additions and 810 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "add_header_logo(fig: Figure, image: np.ndarray, x: float = 0.88, y: float = 0.905, width: float = 0.08, height: float = 0.08) -> None"
description: "Añade un logo como axes inset en la esquina superior derecha de una figura matplotlib. Usa fig.add_axes + imshow + axis off. Útil para branding en páginas de informe PDF."
tags: [pdf, matplotlib, logo, report, infra]
tags: [pdf, matplotlib, logo, report, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "compress_pdf_ghostscript(pdf_path: str | Path, quality: str = 'screen') -> bool"
description: "Comprime un PDF en disco usando Ghostscript con downsampling 96/200 dpi. Reemplaza el archivo solo si el comprimido es menor. Retorna True si comprimió, False si gs no disponible o no hubo mejora."
tags: [pdf, ghostscript, compression, infra]
tags: [pdf, ghostscript, compression, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "config_from_env(target_class: type) -> object"
description: "Crea una instancia de un dataclass poblada desde variables de entorno usando field metadata (env, required, default, secret). Soporta str, int, float, bool, list. Acumula todos los errores antes de lanzar ValueError."
tags: [config, env, dataclass, infra, python]
tags: [config, env, dataclass, infra, python, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "dotenv_load(path: str) -> None"
description: "Parsea un archivo .env (KEY=VALUE) e inyecta pares en os.environ. Ignora comentarios # y lineas vacias. No sobreescribe variables ya presentes. Soporta valores con comillas simples o dobles."
tags: [dotenv, env, config, os, infra, python]
tags: [dotenv, env, config, os, infra, python, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: pure
signature: "email_build_html(from_addr: str, to: list[str], subject: str, body_html: str) -> EmailMessagePy"
description: "Construye un EmailMessagePy inmutable con cuerpo HTML. El campo body_text queda vacio. Funcion pura sin efectos secundarios."
tags: [email, html, builder, pure, python, dataclass]
tags: [email, html, builder, pure, python, dataclass, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def get_logger(name: str = 'app') -> logging.Logger"
description: "Devuelve un logger existente si ya tiene handlers, o lo crea con setup_logger. Util en modulos internos que no controlan la inicializacion del logger."
tags: [logging, logger, infra, utility]
tags: [logging, logger, infra, utility, pendiente-usar]
uses_functions: [setup_logger_py_infra]
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "http_download_file(url: str, dest_path: str, headers: dict[str, str] | None = None, timeout: float = 120.0, chunk_size: int = 8192) -> dict"
description: "Descarga un archivo por HTTP en streaming (sin cargar todo en memoria). Crea directorios intermedios si no existen. Retorna dict con path, size_bytes y content_type."
tags: [http, download, file, streaming, network, stdlib, infra]
tags: [http, download, file, streaming, network, stdlib, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "http_get_json(url: str, headers: dict[str, str] | None = None, params: dict[str, str] | None = None, timeout: float = 30.0) -> dict"
description: "GET request que espera JSON. Agrega Accept: application/json automaticamente. Lanza RuntimeError si status >= 400 con status code, url truncada y primeros 200 chars del body."
tags: [http, json, get, client, network, stdlib, infra]
tags: [http, json, get, client, network, stdlib, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "http_post_json(url: str, body: dict, headers: dict[str, str] | None = None, timeout: float = 30.0) -> dict"
description: "POST request con body JSON. Agrega Content-Type: application/json y Accept: application/json. Lanza RuntimeError si status >= 400 con status code, url truncada y primeros 200 chars del body."
tags: [http, json, post, client, network, stdlib, infra]
tags: [http, json, post, client, network, stdlib, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def nominatim_reverse_geocode(lat: float, lon: float, lang: str = 'es') -> dict"
description: "Reverse geocoding usando Nominatim (OpenStreetMap). Convierte coordenadas lat/lon a una dirección estructurada con calle, ciudad, país y otros campos normalizados."
tags: [geocoding, nominatim, openstreetmap, osm, reverse-geocoding, geo, location, address]
tags: [geocoding, nominatim, openstreetmap, osm, reverse-geocoding, geo, location, address, pendiente-usar]
params:
- name: lat
desc: "Latitud en grados decimales (rango -90 a 90)."
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def ollama_chat(messages: list[dict], model: str = 'llama3.1:8b', base_url: str = 'http://localhost:11434', temperature: float = 0.7, max_tokens: int = 1024) -> dict"
description: "Envía una solicitud de chat completion a Ollama (API local compatible con OpenAI). Retorna el contenido generado junto a métricas de duración y tokens."
tags: [ollama, llm, chat, inference, local-ai, http]
tags: [ollama, llm, chat, inference, local-ai, http, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "osm2pgsql_ingest(osm_pbf_path: str | Path, host: str = 'localhost', port: int = 5432, dbname: str = 'gis', user: str = 'geoserver', password: str = 'geoserver', style: str | None = None, ensure_hstore: bool = True) -> dict"
description: "Ingesta un archivo .osm.pbf en PostGIS usando osm2pgsql con --create --slim --hstore --multi-geometry. Verifica osm2pgsql en PATH, opcionalmente crea extensión hstore. Retorna dict {ok, rows_loaded, stderr}."
tags: [osm, postgis, gis, osm2pgsql, infra]
tags: [osm, postgis, gis, osm2pgsql, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "overpass_nearby_pois(lat: float, lon: float, radius_m: int = 500, categories: list[str] | None = None) -> list[dict]"
description: "Consulta la Overpass API (OpenStreetMap) para obtener POIs cercanos a una coordenada. Soporta 16 categorias mapeadas a tags OSM (amenity, tourism, historic, leisure, shop). Sin dependencias externas, solo stdlib."
tags: [osm, openstreetmap, overpass, poi, geolocation, nearby, geocoding, infra, http, stdlib]
tags: [osm, openstreetmap, overpass, poi, geolocation, nearby, geocoding, infra, http, stdlib, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_add_header_footer(doc, header_text, footer_text, page_numbers) -> PDFDoc"
description: "Configura header y/o footer recurrente para todas las paginas del documento. Debe llamarse antes de pdf_add_page. El footer acepta {n} y {total} como placeholders para numeracion automatica."
tags: [pdf, header, footer, pagination, builder, infra]
tags: [pdf, header, footer, pagination, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_add_image(doc, image, x, y, width, height, keep_aspect) -> PDFDoc"
description: "Añade una imagen PNG o JPEG al documento PDF desde un path de archivo o bytes. Calcula automaticamente la dimension faltante si solo se especifica width o height para mantener la relacion de aspecto."
tags: [pdf, image, embed, builder, infra]
tags: [pdf, image, embed, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_add_page(doc, orientation, width, height) -> PDFDoc"
description: "Añade una pagina nueva al documento PDF con orientacion y tamaño configurables. Sin dimensiones personalizadas usa A4 con la orientacion indicada."
tags: [pdf, page, layout, builder, infra]
tags: [pdf, page, layout, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_add_table(doc, headers, rows, col_widths, header_style, row_style, border, row_height, alternate_bg) -> PDFDoc"
description: "Añade una tabla con fila de headers y filas de datos al documento PDF. Soporta anchos de columna personalizados, estilos diferenciados para headers/datos, bordes y colores alternados en filas."
tags: [pdf, table, data, builder, infra]
tags: [pdf, table, data, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra, pdf_style_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_add_text(doc, text, style, x, y, width) -> PDFDoc"
description: "Escribe un bloque de texto en el documento PDF con fuente, tamaño, color y alineacion del PDFStyle dado. Soporta saltos de linea y word wrap automatico."
tags: [pdf, text, typography, builder, infra]
tags: [pdf, text, typography, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra, pdf_style_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_create(title, author, subject, default_font, margin_left, margin_right, margin_top, margin_bottom) -> PDFDoc"
description: "Inicializa un documento PDF nuevo usando fpdf2. Crea un objeto FPDF configurado con metadatos y margenes. Retorna un PDFDoc listo para añadir paginas con pdf_add_page."
tags: [pdf, create, fpdf2, builder, infra]
tags: [pdf, create, fpdf2, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra]
returns: [pdf_doc_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_from_markdown(markdown_string, output_path, css, page_size) -> str"
description: "Convierte un string Markdown a PDF via HTML + weasyprint. Incluye CSS por defecto para tipografia legible. Soporta tablas, codigo y headers. Requiere weasyprint y markdown instalados."
tags: [pdf, markdown, conversion, weasyprint, infra]
tags: [pdf, markdown, conversion, weasyprint, infra, pendiente-usar]
uses_functions: [pdf_from_html_py_infra]
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_merge(pdf_paths, output_path) -> str"
description: "Fusiona una lista de archivos PDF en un unico PDF combinado usando pypdf. Mantiene el orden de la lista. Lanza FileNotFoundError si alguno de los archivos no existe."
tags: [pdf, merge, combine, pypdf, infra]
tags: [pdf, merge, combine, pypdf, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def pdf_save(doc, output_path) -> str | bytes"
description: "Serializa el documento PDF a disco o retorna los bytes en memoria. Si output_path es None retorna bytes para transmision directa (HTTP response, almacenamiento en BD). Si se especifica, escribe el archivo y retorna el path."
tags: [pdf, save, output, builder, infra]
tags: [pdf, save, output, builder, infra, pendiente-usar]
uses_functions: []
uses_types: [pdf_doc_py_infra]
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: pure
signature: "def powertoys_config_path(user: str | None = None) -> str"
description: "Devuelve el path al default.json de PowerToys Keyboard Manager. Soporta WSL, Windows nativo y override via env var POWERTOYS_CONFIG."
tags: [powertoys, keyboard, windows, wsl, config, path]
tags: [powertoys, keyboard, windows, wsl, config, path, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def powertoys_restart() -> None"
description: "Mata los procesos de PowerToys y los relanza para que recargue la configuracion del Keyboard Manager. Compatible con WSL via taskkill.exe y cmd.exe."
tags: [powertoys, keyboard, windows, wsl, restart, process, taskkill]
tags: [powertoys, keyboard, windows, wsl, restart, process, taskkill, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def powertoys_shortcut_add(keys: list[str], target_path: str, args: str = \"\", elevated: bool = False, exact_match: bool = False, start_in_dir: str = \"\", config_path: str | None = None) -> None"
description: "Añade o reemplaza un atajo global en el config de PowerToys Keyboard Manager. Convierte nombres legibles de teclas a VK codes y escribe JSON compacto (una linea) para mantener compatibilidad con el formato de PowerToys."
tags: [powertoys, keyboard, windows, wsl, shortcut, config, write, add]
tags: [powertoys, keyboard, windows, wsl, shortcut, config, write, add, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def powertoys_shortcut_list(config_path: str | None = None) -> list[dict]"
description: "Lee el default.json de PowerToys Keyboard Manager y devuelve los atajos globales con VK codes convertidos a nombres legibles."
tags: [powertoys, keyboard, windows, wsl, shortcut, config, read]
tags: [powertoys, keyboard, windows, wsl, shortcut, config, read, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def powertoys_shortcut_remove(keys: list[str], config_path: str | None = None) -> bool"
description: "Elimina un atajo global del config de PowerToys Keyboard Manager por combinacion de teclas. Devuelve True si se elimino, False si no existia."
tags: [powertoys, keyboard, windows, wsl, shortcut, config, write, remove, delete]
tags: [powertoys, keyboard, windows, wsl, shortcut, config, write, remove, delete, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "read_file_with_encoding(path: str, encodings: list[str] | None = None) -> str"
description: "Lee un archivo de texto intentando multiples encodings en orden hasta encontrar uno que funcione. Util para archivos de origen desconocido (Windows, Latin-1, con BOM, etc.)."
tags: [file, encoding, io, text, utf8, latin1, cp1252, decode]
tags: [file, encoding, io, text, utf8, latin1, cp1252, decode, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -0,0 +1,56 @@
---
name: registry_telemetry
lang: py
domain: infra
version: 0.1.0
purity: impure
kind: function
description: "Telemetria de invocaciones del registry desde Python. Patchea via sys.meta_path los paquetes del registry (core, finance, metabase, etc.) y registra cada llamada en call_monitor.operations.db. Activable con FN_TELEMETRY=1. Issue 0085c."
tags: [telemetry, monitoring, registry, import-hook, pendiente-usar]
signature: "install() -> bool"
error_type: "error_go_core"
returns_optional: false
params:
- name: FN_TELEMETRY (env)
desc: "Si vale '1', install() registra el meta_path finder y envuelve cada modulo del registry al importarse. Si no, no-op."
- name: FN_REGISTRY_ROOT (env)
desc: "Override de la raiz del registry. Si no se setea, se descubre walking up desde el archivo del modulo."
- name: CLAUDE_SESSION_ID (env)
desc: "ID de sesion Claude Code, persistido en cada fila de calls. Vacio si no se setea."
output: "True si el finder se instalo, False si FN_TELEMETRY != '1' o si ya estaba instalado."
uses_functions: []
uses_types: []
imports:
- functools
- importlib.abc
- importlib.util
- sqlite3
- sys
- time
example: |
# Activacion en heredoc o app
import os
os.environ["FN_TELEMETRY"] = "1"
import sys, os.path as p
sys.path.insert(0, p.join(os.environ["FN_REGISTRY_ROOT"], "python", "functions"))
import infra.registry_telemetry # auto-install al importarse
from core import filter_list, map_list # automaticamente envueltos
filter_list(lambda x: x > 0, [1, -2, 3]) # registrado en calls
file_path: "python/functions/infra/registry_telemetry.py"
tested: false
notes: |
Patron: meta_path importer (PEP 451). Cuando el agente importa `core`, `finance`, etc.,
el finder intercepta la carga del modulo, deja que el loader real ejecute, y luego
envuelve cada callable definido en el modulo con un decorator que mide duration
y registra en calls (con tool_used='python_wrapper').
Fail-safe: si la BD no existe, INSERT falla, o cualquier excepcion ocurre durante
el wrap, se ignora silenciosamente. NUNCA rompe el codigo cliente.
function_id heuristic: `{name}_py_{domain}` donde domain = nombre del paquete
top-level (`core`, `finance`, etc.). Coincide con convencion del registry
siempre que el paquete top-level se llame igual que el dominio.
Privacidad: solo function_id, duration_ms, success, error_class, type_name del error.
NUNCA args, kwargs, return values. error_snippet truncado a 240 chars.
---
@@ -0,0 +1,217 @@
"""Telemetria de invocaciones del registry desde Python (issue 0085c).
Activacion explicita: env var FN_TELEMETRY=1.
Mecanismo: sys.meta_path importer que detecta cuando se carga un modulo bajo
un paquete del registry (core, finance, metabase, ...) y envuelve cada
funcion publica con un wrapper que mide duration y registra en
projects/fn_monitoring/apps/call_monitor/operations.db.
Reglas:
- No-op silencioso si BD no existe o INSERT falla. NUNCA rompe codigo cliente.
- Solo guarda function_id, tool_used, duration_ms, success, error_class.
NUNCA guarda argumentos concretos.
- Idempotente: install() puede llamarse N veces sin duplicar el finder.
- Bypass: si FN_TELEMETRY != "1", install() es no-op. La funcion sigue siendo
importable para usos manuales (wrap_namespace).
"""
from __future__ import annotations
import functools
import importlib.abc
import importlib.util
import os
import sqlite3
import sys
import time
from pathlib import Path
from typing import Iterable, Optional
_ENABLED = os.environ.get("FN_TELEMETRY", "") == "1"
_SESSION_ID = os.environ.get("CLAUDE_SESSION_ID", "")
_DB_PATH: Optional[str] = None
_REGISTRY_ROOT: Optional[str] = None
def _resolve_root() -> Optional[str]:
global _REGISTRY_ROOT
if _REGISTRY_ROOT:
return _REGISTRY_ROOT
env = os.environ.get("FN_REGISTRY_ROOT")
if env and (Path(env) / "registry.db").exists():
_REGISTRY_ROOT = env
return env
here = Path(__file__).resolve()
for parent in here.parents:
if (parent / "registry.db").exists():
_REGISTRY_ROOT = str(parent)
return _REGISTRY_ROOT
return None
def _resolve_db() -> Optional[str]:
global _DB_PATH
if _DB_PATH:
return _DB_PATH
root = _resolve_root()
if not root:
return None
candidate = Path(root) / "projects" / "fn_monitoring" / "apps" / "call_monitor" / "operations.db"
if candidate.exists():
_DB_PATH = str(candidate)
return _DB_PATH
return None
def _registry_packages() -> set[str]:
root = _resolve_root()
if not root:
return set()
fns_dir = Path(root) / "python" / "functions"
if not fns_dir.is_dir():
return set()
return {p.name for p in fns_dir.iterdir() if p.is_dir() and not p.name.startswith("_") and not p.name.startswith(".")}
def _log_call(
function_id: str,
duration_ms: float,
success: bool,
error_class: str = "",
error_snippet: str = "",
) -> None:
db = _resolve_db()
if not db:
return
try:
conn = sqlite3.connect(db, timeout=0.1, isolation_level=None)
conn.execute(
"INSERT INTO calls "
"(session_id, function_id, tool_used, args_hash, duration_ms, success, error_class, error_snippet, ts) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, CAST(strftime('%s','now') AS INTEGER))",
(
_SESSION_ID,
function_id,
"python_wrapper",
"",
int(duration_ms),
1 if success else 0,
(error_class or "")[:64],
(error_snippet or "")[:240],
),
)
conn.close()
except Exception:
pass # never break user code
def _wrap_callable(fn, function_id: str):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
t0 = time.perf_counter()
try:
result = fn(*args, **kwargs)
_log_call(function_id, (time.perf_counter() - t0) * 1000, True)
return result
except Exception as e:
_log_call(
function_id,
(time.perf_counter() - t0) * 1000,
False,
type(e).__name__,
str(e),
)
raise
wrapper.__fn_telemetered__ = True # type: ignore[attr-defined]
return wrapper
def wrap_namespace(ns_globals: dict, domain: str) -> None:
"""Wrap public callables defined in ns_globals.
function_id pattern: {func_name}_py_{domain}
Only wraps callables defined in the same module (skips re-exports).
"""
if not _ENABLED:
return
module_name = ns_globals.get("__name__", "")
for name, obj in list(ns_globals.items()):
if name.startswith("_"):
continue
if getattr(obj, "__fn_telemetered__", False):
continue
if not callable(obj):
continue
# Skip classes / exceptions / non-functions
if isinstance(obj, type):
continue
obj_module = getattr(obj, "__module__", None)
if obj_module and module_name and obj_module != module_name and not obj_module.startswith(module_name.split(".")[0]):
continue
function_id = f"{name}_py_{domain}"
ns_globals[name] = _wrap_callable(obj, function_id)
class _RegistryTelemetryLoader(importlib.abc.Loader):
def __init__(self, real_loader, domain: str):
self.real_loader = real_loader
self.domain = domain
def create_module(self, spec):
if hasattr(self.real_loader, "create_module"):
return self.real_loader.create_module(spec)
return None
def exec_module(self, module):
self.real_loader.exec_module(module)
try:
wrap_namespace(vars(module), self.domain)
except Exception:
pass
class _RegistryTelemetryFinder(importlib.abc.MetaPathFinder):
def __init__(self, packages: Iterable[str]):
self._packages = set(packages)
def find_spec(self, fullname, path, target=None):
top = fullname.split(".")[0]
if top not in self._packages:
return None
if fullname == __name__:
return None
# ask the other finders for the real spec; do not recurse on self
for finder in sys.meta_path:
if finder is self:
continue
if not hasattr(finder, "find_spec"):
continue
try:
spec = finder.find_spec(fullname, path, target)
except Exception:
continue
if spec is None or spec.loader is None:
continue
spec.loader = _RegistryTelemetryLoader(spec.loader, top)
return spec
return None
def install() -> bool:
"""Install meta_path finder. Idempotent. Returns True if installed."""
if not _ENABLED:
return False
packages = _registry_packages()
if not packages:
return False
for f in sys.meta_path:
if isinstance(f, _RegistryTelemetryFinder):
return False
sys.meta_path.insert(0, _RegistryTelemetryFinder(packages))
return True
if _ENABLED:
install()
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "render_table_page_pdfpages(pdf: PdfPages, title: str, rows: list[list[str]], col_labels: list[str], max_rows: int = 28, figsize: tuple[float, float] = (11.69, 8.27), fontsize: int = 8, dpi: int = 300) -> None"
description: "Renderiza filas como páginas de tabla paginadas en un PdfPages abierto. Usa matplotlib.pyplot.table con paginación automática por max_rows. Una página A4 landscape por chunk."
tags: [pdf, matplotlib, table, report, infra]
tags: [pdf, matplotlib, table, report, infra, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def safe_extract_zip(zip_path: str, dest_dir: str) -> None"
description: "Extrae un archivo ZIP con proteccion contra Zip Slip (path traversal attack). Valida que cada archivo extraido quede dentro del directorio destino antes de extraerlo. Normaliza nombres de archivo UTF-8 antes de extraer."
tags: [zip, extract, security, zip-slip, path-traversal, infra, io]
tags: [zip, extract, security, zip-slip, path-traversal, infra, io, pendiente-usar]
uses_functions: [normalize_zip_filenames_py_infra]
uses_types: []
returns: []
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def scan_directory(root: str, supported_extensions: set[str] | None = None, ignore_dirs: set[str] | None = None, include: str | None = None, exclude: str | None = None, strict: bool = False) -> DirectoryScanResult"
description: "Recorre un arbol de directorios y clasifica cada archivo como procesable o no soportado. Util para validacion pre-importacion de directorios. Ignora dot files, symlinks, archivos vacios y directorios de build/venv/cache predefinidos. Soporta filtros include/exclude con globs."
tags: [directory, scan, filesystem, classification, infra, walk, files]
tags: [directory, scan, filesystem, classification, infra, walk, files, pendiente-usar]
uses_functions: []
uses_types: [classified_file_py_infra, directory_scan_result_py_infra]
returns: [directory_scan_result_py_infra]
+1 -1
View File
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "smtp_send(cfg: SMTPConfigPy, from_addr: str, to: list[str], subject: str, body_html: str = '', body_text: str = '', cc: list[str] | None = None, bcc: list[str] | None = None, attachments: list[EmailAttachmentPy] | None = None, headers: dict[str, str] | None = None) -> None"
description: "Conecta al servidor SMTP, construye el mensaje MIME y envia el email en un solo paso. Soporta TLS directo (port 465), STARTTLS (port 587) y sin cifrado (port 25). Cierra la conexion automaticamente."
tags: [email, smtp, send, python, smtplib, mime, tls]
tags: [email, smtp, send, python, smtplib, mime, tls, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
@@ -7,7 +7,7 @@ version: "1.0.0"
purity: impure
signature: "def vault_profile_dispatch(vault_path: str, rel_path: str, kind: str, db_path: str | None = None) -> dict"
description: "CLI dispatcher que enruta un archivo del vault al profiler correcto segun su tipo (csv/pdf/md). Thin wrapper sobre vault_csv_profile, vault_pdf_extract y vault_knowledge_parse. Usable desde Go via os/exec para procesar archivos en bulk."
tags: [vault, profile, dispatch, profiler, csv, pdf, md, infra]
tags: [vault, profile, dispatch, profiler, csv, pdf, md, infra, pendiente-usar]
uses_functions:
- vault_csv_profile_py_datascience
- vault_pdf_extract_py_datascience