sesigram 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sesigram-0.1.0/PKG-INFO +58 -0
- sesigram-0.1.0/README.md +50 -0
- sesigram-0.1.0/pyproject.toml +16 -0
- sesigram-0.1.0/sesigram/__init__.py +4 -0
- sesigram-0.1.0/sesigram/cli.py +108 -0
- sesigram-0.1.0/sesigram/telegram_api.py +78 -0
- sesigram-0.1.0/sesigram/wrapper.py +122 -0
- sesigram-0.1.0/sesigram.egg-info/PKG-INFO +58 -0
- sesigram-0.1.0/sesigram.egg-info/SOURCES.txt +12 -0
- sesigram-0.1.0/sesigram.egg-info/dependency_links.txt +1 -0
- sesigram-0.1.0/sesigram.egg-info/entry_points.txt +2 -0
- sesigram-0.1.0/sesigram.egg-info/requires.txt +1 -0
- sesigram-0.1.0/sesigram.egg-info/top_level.txt +1 -0
- sesigram-0.1.0/setup.cfg +4 -0
sesigram-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sesigram
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal Telegram CLI Wrapper for AI Assistants and Terminals
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: requests
|
|
8
|
+
|
|
9
|
+
# Sesigram
|
|
10
|
+
|
|
11
|
+
**Sesigram** es un wrapper universal de terminal que te permite interactuar con cualquier asistente de IA de línea de comandos (como Claude Code, Aider, Antigravity, etc.) o cualquier programa interactivo desde Telegram.
|
|
12
|
+
|
|
13
|
+
Con Sesigram, puedes alejarte de tu computadora y seguir respondiendo o leyendo las salidas de la terminal en tiempo real desde tu celular.
|
|
14
|
+
|
|
15
|
+
## Instalación
|
|
16
|
+
|
|
17
|
+
Puedes instalar Sesigram globalmente usando `pipx` (recomendado) o `pip`:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install sesigram
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
*(O puedes instalarlo localmente desde el código fuente con `pip install -e .`)*
|
|
24
|
+
|
|
25
|
+
## Configuración
|
|
26
|
+
|
|
27
|
+
Una vez instalado, ejecuta el comando de configuración inicial:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
sesigram setup
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Sigue las instrucciones en pantalla para vincular tu bot de Telegram y tu chat ID.
|
|
34
|
+
|
|
35
|
+
## Uso
|
|
36
|
+
|
|
37
|
+
Para usar Sesigram, simplemente **envuelve** el comando que quieres ejecutar con `sesigram run`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Ejemplo con bash interactivo
|
|
41
|
+
sesigram run bash
|
|
42
|
+
|
|
43
|
+
# Ejemplo con Aider
|
|
44
|
+
sesigram run aider
|
|
45
|
+
|
|
46
|
+
# Ejemplo con Claude Code
|
|
47
|
+
sesigram run claude
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
A partir de ese momento, la terminal arrancará normalmente pero todo el texto que imprima te llegará a Telegram. Si respondes a tu bot de Telegram, el mensaje se inyectará como si lo hubieras escrito en la consola.
|
|
51
|
+
|
|
52
|
+
Para cerrar la sesión de forma remota, envía `/stop_sesigram` en Telegram.
|
|
53
|
+
|
|
54
|
+
## Características
|
|
55
|
+
|
|
56
|
+
- **Agnóstico**: No requiere plugins ni modificaciones en el programa subyacente. Utiliza Pseudo-Terminales (PTY) nativas de Python.
|
|
57
|
+
- **Sin Demonios**: No se queda corriendo en segundo plano. El puente hacia Telegram solo existe mientras dura el comando envuelto.
|
|
58
|
+
- **Smart Buffering**: Acumula las salidas rápidas para no hacer spam ni exceder el límite de mensajes de la API de Telegram.
|
sesigram-0.1.0/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Sesigram
|
|
2
|
+
|
|
3
|
+
**Sesigram** es un wrapper universal de terminal que te permite interactuar con cualquier asistente de IA de línea de comandos (como Claude Code, Aider, Antigravity, etc.) o cualquier programa interactivo desde Telegram.
|
|
4
|
+
|
|
5
|
+
Con Sesigram, puedes alejarte de tu computadora y seguir respondiendo o leyendo las salidas de la terminal en tiempo real desde tu celular.
|
|
6
|
+
|
|
7
|
+
## Instalación
|
|
8
|
+
|
|
9
|
+
Puedes instalar Sesigram globalmente usando `pipx` (recomendado) o `pip`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install sesigram
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
*(O puedes instalarlo localmente desde el código fuente con `pip install -e .`)*
|
|
16
|
+
|
|
17
|
+
## Configuración
|
|
18
|
+
|
|
19
|
+
Una vez instalado, ejecuta el comando de configuración inicial:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
sesigram setup
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Sigue las instrucciones en pantalla para vincular tu bot de Telegram y tu chat ID.
|
|
26
|
+
|
|
27
|
+
## Uso
|
|
28
|
+
|
|
29
|
+
Para usar Sesigram, simplemente **envuelve** el comando que quieres ejecutar con `sesigram run`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Ejemplo con bash interactivo
|
|
33
|
+
sesigram run bash
|
|
34
|
+
|
|
35
|
+
# Ejemplo con Aider
|
|
36
|
+
sesigram run aider
|
|
37
|
+
|
|
38
|
+
# Ejemplo con Claude Code
|
|
39
|
+
sesigram run claude
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A partir de ese momento, la terminal arrancará normalmente pero todo el texto que imprima te llegará a Telegram. Si respondes a tu bot de Telegram, el mensaje se inyectará como si lo hubieras escrito en la consola.
|
|
43
|
+
|
|
44
|
+
Para cerrar la sesión de forma remota, envía `/stop_sesigram` en Telegram.
|
|
45
|
+
|
|
46
|
+
## Características
|
|
47
|
+
|
|
48
|
+
- **Agnóstico**: No requiere plugins ni modificaciones en el programa subyacente. Utiliza Pseudo-Terminales (PTY) nativas de Python.
|
|
49
|
+
- **Sin Demonios**: No se queda corriendo en segundo plano. El puente hacia Telegram solo existe mientras dura el comando envuelto.
|
|
50
|
+
- **Smart Buffering**: Acumula las salidas rápidas para no hacer spam ni exceder el límite de mensajes de la API de Telegram.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sesigram"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Universal Telegram CLI Wrapper for AI Assistants and Terminals"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"requests",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.scripts]
|
|
16
|
+
sesigram = "sesigram.cli:main"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
from .telegram_api import get_updates, send_message, load_config, save_config
|
|
4
|
+
from .wrapper import TelegramWrapper
|
|
5
|
+
|
|
6
|
+
def print_step(text):
|
|
7
|
+
print(f"\n\033[1m> {text}\033[0m")
|
|
8
|
+
|
|
9
|
+
def print_ok(text):
|
|
10
|
+
print(f" \033[32m✓\033[0m {text}")
|
|
11
|
+
|
|
12
|
+
def print_err(text):
|
|
13
|
+
print(f" \033[31m✗\033[0m {text}")
|
|
14
|
+
|
|
15
|
+
def setup():
|
|
16
|
+
print("\n\033[1m🤖 Sesigram - Setup\033[0m")
|
|
17
|
+
print("=" * 45)
|
|
18
|
+
|
|
19
|
+
print("\nPaso 1: Crear tu bot de Telegram")
|
|
20
|
+
print("1. Abre Telegram y busca @BotFather")
|
|
21
|
+
print("2. Escribe /newbot")
|
|
22
|
+
print("3. Ponle un nombre y un username")
|
|
23
|
+
print("4. Copia el Token que te da al final")
|
|
24
|
+
|
|
25
|
+
token = input("\nPega aquí tu token: ").strip()
|
|
26
|
+
if not token:
|
|
27
|
+
print_err("Token inválido.")
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
|
|
30
|
+
print_step("Paso 2: Conectar tu cuenta de Telegram")
|
|
31
|
+
print("1. Abre Telegram en tu móvil o escritorio")
|
|
32
|
+
print("2. Busca el bot que acabas de crear")
|
|
33
|
+
print("3. Pulsa START o escribe /start")
|
|
34
|
+
print("4. Espera (detección automática en curso...)")
|
|
35
|
+
|
|
36
|
+
chat_id = None
|
|
37
|
+
sys.stdout.write("\n Esperando que escribas a tu bot...")
|
|
38
|
+
sys.stdout.flush()
|
|
39
|
+
|
|
40
|
+
# Poll for messages to find chat_id
|
|
41
|
+
for _ in range(30): # 30 seconds wait
|
|
42
|
+
updates = get_updates(token, timeout=1)
|
|
43
|
+
if updates:
|
|
44
|
+
for update in updates:
|
|
45
|
+
if "message" in update:
|
|
46
|
+
msg = update["message"]
|
|
47
|
+
if msg.get("text") == "/start":
|
|
48
|
+
chat_id = msg["chat"]["id"]
|
|
49
|
+
first_name = msg["from"].get("first_name", "Usuario")
|
|
50
|
+
print(f"\n ✓ Conectado con {first_name} (ID: {chat_id})")
|
|
51
|
+
break
|
|
52
|
+
if chat_id:
|
|
53
|
+
break
|
|
54
|
+
sys.stdout.write(".")
|
|
55
|
+
sys.stdout.flush()
|
|
56
|
+
time.sleep(1)
|
|
57
|
+
|
|
58
|
+
if not chat_id:
|
|
59
|
+
print("\n\n ⚠ Timeout. Introduce tu chat_id manualmente.")
|
|
60
|
+
try:
|
|
61
|
+
chat_id = int(input(" Chat ID: ").strip())
|
|
62
|
+
except ValueError:
|
|
63
|
+
print_err("ID inválido. Abortando.")
|
|
64
|
+
sys.exit(1)
|
|
65
|
+
|
|
66
|
+
save_config(token, chat_id)
|
|
67
|
+
print_ok("Config guardada")
|
|
68
|
+
|
|
69
|
+
send_message(token, chat_id, "🎉 Sesigram vinculado correctamente en esta máquina.")
|
|
70
|
+
print_ok("Mensaje de prueba enviado a Telegram")
|
|
71
|
+
|
|
72
|
+
print("\n🎉 Setup completo!")
|
|
73
|
+
print("\nPara usar Sesigram, simplemente envuelve cualquier comando:")
|
|
74
|
+
print(" sesigram run bash")
|
|
75
|
+
print(" sesigram run claude")
|
|
76
|
+
print(" sesigram run python\n")
|
|
77
|
+
|
|
78
|
+
def main():
|
|
79
|
+
if len(sys.argv) < 2 or sys.argv[1] in ["--help", "-h", "help"]:
|
|
80
|
+
print("Uso: sesigram <comando>")
|
|
81
|
+
print(" sesigram setup -> Configura tu Bot de Telegram")
|
|
82
|
+
print(" sesigram run <comando> -> Ejecuta un comando envolviéndolo con Telegram")
|
|
83
|
+
sys.exit(1 if len(sys.argv) < 2 else 0)
|
|
84
|
+
|
|
85
|
+
command = sys.argv[1]
|
|
86
|
+
|
|
87
|
+
if command == "setup":
|
|
88
|
+
setup()
|
|
89
|
+
elif command == "run":
|
|
90
|
+
if len(sys.argv) < 3:
|
|
91
|
+
print("Error: falta el comando a ejecutar.")
|
|
92
|
+
print("Uso: sesigram run <comando>")
|
|
93
|
+
sys.exit(1)
|
|
94
|
+
|
|
95
|
+
config = load_config()
|
|
96
|
+
if not config:
|
|
97
|
+
print("Error: Sesigram no está configurado. Ejecuta 'sesigram setup' primero.")
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
|
|
100
|
+
argv = sys.argv[2:]
|
|
101
|
+
wrapper = TelegramWrapper(config)
|
|
102
|
+
wrapper.run(argv)
|
|
103
|
+
else:
|
|
104
|
+
print(f"Comando desconocido: {command}")
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
main()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import socket
|
|
3
|
+
import requests
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
CONFIG_FILE = Path.home() / ".sesigram-config"
|
|
7
|
+
|
|
8
|
+
def load_config():
|
|
9
|
+
try:
|
|
10
|
+
if CONFIG_FILE.exists():
|
|
11
|
+
with open(CONFIG_FILE, 'r') as f:
|
|
12
|
+
return json.load(f)
|
|
13
|
+
except Exception:
|
|
14
|
+
pass
|
|
15
|
+
return None
|
|
16
|
+
|
|
17
|
+
def save_config(token, chat_id, machine_name=None):
|
|
18
|
+
if not machine_name:
|
|
19
|
+
machine_name = socket.gethostname()
|
|
20
|
+
config = {
|
|
21
|
+
"bot_token": token,
|
|
22
|
+
"chat_id": chat_id,
|
|
23
|
+
"machine_name": machine_name
|
|
24
|
+
}
|
|
25
|
+
with open(CONFIG_FILE, 'w') as f:
|
|
26
|
+
json.dump(config, f, indent=2)
|
|
27
|
+
|
|
28
|
+
def escape_md(text):
|
|
29
|
+
"""Escape MarkdownV2 special characters."""
|
|
30
|
+
special = r"_*[]()~`>#+-=|{}.!"
|
|
31
|
+
for c in special:
|
|
32
|
+
text = text.replace(c, f"\\{c}")
|
|
33
|
+
return text
|
|
34
|
+
|
|
35
|
+
def send_message(token, chat_id, text, machine_name=None, disable_notification=True):
|
|
36
|
+
if not text.strip():
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
if len(text) > 3800:
|
|
40
|
+
text = text[:3800] + "\n\n[... mensaje truncado ...]"
|
|
41
|
+
|
|
42
|
+
header = ""
|
|
43
|
+
if machine_name:
|
|
44
|
+
header = f"🖥️ *{escape_md(machine_name)}*\n\n"
|
|
45
|
+
|
|
46
|
+
full_msg = header + escape_md(text)
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
requests.post(
|
|
50
|
+
f"https://api.telegram.org/bot{token}/sendMessage",
|
|
51
|
+
json={
|
|
52
|
+
"chat_id": chat_id,
|
|
53
|
+
"text": full_msg,
|
|
54
|
+
"parse_mode": "MarkdownV2",
|
|
55
|
+
"disable_notification": disable_notification
|
|
56
|
+
},
|
|
57
|
+
timeout=10
|
|
58
|
+
)
|
|
59
|
+
except Exception:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def get_updates(token, offset=None, timeout=30):
|
|
63
|
+
"""Long polling for new messages."""
|
|
64
|
+
params = {"timeout": timeout}
|
|
65
|
+
if offset:
|
|
66
|
+
params["offset"] = offset
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
response = requests.get(
|
|
70
|
+
f"https://api.telegram.org/bot{token}/getUpdates",
|
|
71
|
+
params=params,
|
|
72
|
+
timeout=timeout + 5
|
|
73
|
+
)
|
|
74
|
+
if response.status_code == 200:
|
|
75
|
+
return response.json().get("result", [])
|
|
76
|
+
except Exception:
|
|
77
|
+
pass
|
|
78
|
+
return []
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pty
|
|
3
|
+
import sys
|
|
4
|
+
import threading
|
|
5
|
+
import time
|
|
6
|
+
import re
|
|
7
|
+
from .telegram_api import get_updates, send_message
|
|
8
|
+
|
|
9
|
+
ANSI_ESCAPE_RE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
|
10
|
+
|
|
11
|
+
class TelegramWrapper:
|
|
12
|
+
def __init__(self, config):
|
|
13
|
+
self.config = config
|
|
14
|
+
self.master_fd = None
|
|
15
|
+
self.output_buffer = ""
|
|
16
|
+
self.last_send_time = time.time()
|
|
17
|
+
self.buffer_lock = threading.Lock()
|
|
18
|
+
self.is_running = True
|
|
19
|
+
|
|
20
|
+
def _strip_ansi(self, text):
|
|
21
|
+
return ANSI_ESCAPE_RE.sub('', text)
|
|
22
|
+
|
|
23
|
+
def master_read(self, fd):
|
|
24
|
+
"""Called by pty.spawn when there is output from the child process."""
|
|
25
|
+
data = os.read(fd, 1024)
|
|
26
|
+
text = data.decode('utf-8', errors='replace')
|
|
27
|
+
|
|
28
|
+
with self.buffer_lock:
|
|
29
|
+
self.output_buffer += text
|
|
30
|
+
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
def telegram_sender_loop(self):
|
|
34
|
+
"""Periodically sends buffered output to Telegram."""
|
|
35
|
+
while self.is_running:
|
|
36
|
+
time.sleep(1.0) # Check every second
|
|
37
|
+
with self.buffer_lock:
|
|
38
|
+
if not self.output_buffer:
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
# Only send if there's a pause in output or buffer is large
|
|
42
|
+
current_time = time.time()
|
|
43
|
+
if current_time - self.last_send_time > 1.5 or len(self.output_buffer) > 2000:
|
|
44
|
+
text_to_send = self._strip_ansi(self.output_buffer).strip()
|
|
45
|
+
if text_to_send:
|
|
46
|
+
send_message(
|
|
47
|
+
self.config["bot_token"],
|
|
48
|
+
self.config["chat_id"],
|
|
49
|
+
text_to_send,
|
|
50
|
+
self.config["machine_name"],
|
|
51
|
+
disable_notification=True
|
|
52
|
+
)
|
|
53
|
+
self.output_buffer = ""
|
|
54
|
+
self.last_send_time = current_time
|
|
55
|
+
|
|
56
|
+
def telegram_polling_loop(self):
|
|
57
|
+
"""Polls Telegram for new messages and injects them into the PTY."""
|
|
58
|
+
offset = None
|
|
59
|
+
while self.is_running:
|
|
60
|
+
updates = get_updates(self.config["bot_token"], offset=offset, timeout=10)
|
|
61
|
+
for update in updates:
|
|
62
|
+
offset = update["update_id"] + 1
|
|
63
|
+
if "message" in update and "text" in update["message"]:
|
|
64
|
+
# Only accept messages from the authorized chat_id
|
|
65
|
+
if str(update["message"]["chat"]["id"]) == str(self.config["chat_id"]):
|
|
66
|
+
text = update["message"]["text"]
|
|
67
|
+
|
|
68
|
+
# System command check
|
|
69
|
+
if text.strip().lower() == "/stop_sesigram":
|
|
70
|
+
send_message(
|
|
71
|
+
self.config["bot_token"],
|
|
72
|
+
self.config["chat_id"],
|
|
73
|
+
"🛑 Cerrando sesión remota.",
|
|
74
|
+
self.config["machine_name"]
|
|
75
|
+
)
|
|
76
|
+
# Escribir Ctrl+C y Exit para intentar matar el child
|
|
77
|
+
if self.master_fd:
|
|
78
|
+
os.write(self.master_fd, b'\x03exit\n')
|
|
79
|
+
continue
|
|
80
|
+
|
|
81
|
+
# Inject into PTY
|
|
82
|
+
if self.master_fd:
|
|
83
|
+
# Escribir el texto seguido de un salto de línea
|
|
84
|
+
payload = (text + "\n").encode('utf-8')
|
|
85
|
+
os.write(self.master_fd, payload)
|
|
86
|
+
|
|
87
|
+
time.sleep(0.5)
|
|
88
|
+
|
|
89
|
+
def run(self, argv):
|
|
90
|
+
# Setup threads
|
|
91
|
+
sender_thread = threading.Thread(target=self.telegram_sender_loop, daemon=True)
|
|
92
|
+
polling_thread = threading.Thread(target=self.telegram_polling_loop, daemon=True)
|
|
93
|
+
|
|
94
|
+
sender_thread.start()
|
|
95
|
+
polling_thread.start()
|
|
96
|
+
|
|
97
|
+
def _spawn_read(fd):
|
|
98
|
+
if self.master_fd is None:
|
|
99
|
+
self.master_fd = fd
|
|
100
|
+
return self.master_read(fd)
|
|
101
|
+
|
|
102
|
+
print(f"🚀 Iniciando Sesigram en modo remoto para: {' '.join(argv)}")
|
|
103
|
+
send_message(
|
|
104
|
+
self.config["bot_token"],
|
|
105
|
+
self.config["chat_id"],
|
|
106
|
+
f"🚀 Sesión iniciada: `{' '.join(argv)}`",
|
|
107
|
+
self.config["machine_name"]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
# pty.spawn bloquea hasta que el subproceso termine
|
|
112
|
+
pty.spawn(argv, master_read=_spawn_read)
|
|
113
|
+
except Exception as e:
|
|
114
|
+
print(f"Error en pty.spawn: {e}")
|
|
115
|
+
finally:
|
|
116
|
+
self.is_running = False
|
|
117
|
+
send_message(
|
|
118
|
+
self.config["bot_token"],
|
|
119
|
+
self.config["chat_id"],
|
|
120
|
+
f"🛑 Sesión terminada: `{' '.join(argv)}`",
|
|
121
|
+
self.config["machine_name"]
|
|
122
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sesigram
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal Telegram CLI Wrapper for AI Assistants and Terminals
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: requests
|
|
8
|
+
|
|
9
|
+
# Sesigram
|
|
10
|
+
|
|
11
|
+
**Sesigram** es un wrapper universal de terminal que te permite interactuar con cualquier asistente de IA de línea de comandos (como Claude Code, Aider, Antigravity, etc.) o cualquier programa interactivo desde Telegram.
|
|
12
|
+
|
|
13
|
+
Con Sesigram, puedes alejarte de tu computadora y seguir respondiendo o leyendo las salidas de la terminal en tiempo real desde tu celular.
|
|
14
|
+
|
|
15
|
+
## Instalación
|
|
16
|
+
|
|
17
|
+
Puedes instalar Sesigram globalmente usando `pipx` (recomendado) o `pip`:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install sesigram
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
*(O puedes instalarlo localmente desde el código fuente con `pip install -e .`)*
|
|
24
|
+
|
|
25
|
+
## Configuración
|
|
26
|
+
|
|
27
|
+
Una vez instalado, ejecuta el comando de configuración inicial:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
sesigram setup
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Sigue las instrucciones en pantalla para vincular tu bot de Telegram y tu chat ID.
|
|
34
|
+
|
|
35
|
+
## Uso
|
|
36
|
+
|
|
37
|
+
Para usar Sesigram, simplemente **envuelve** el comando que quieres ejecutar con `sesigram run`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Ejemplo con bash interactivo
|
|
41
|
+
sesigram run bash
|
|
42
|
+
|
|
43
|
+
# Ejemplo con Aider
|
|
44
|
+
sesigram run aider
|
|
45
|
+
|
|
46
|
+
# Ejemplo con Claude Code
|
|
47
|
+
sesigram run claude
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
A partir de ese momento, la terminal arrancará normalmente pero todo el texto que imprima te llegará a Telegram. Si respondes a tu bot de Telegram, el mensaje se inyectará como si lo hubieras escrito en la consola.
|
|
51
|
+
|
|
52
|
+
Para cerrar la sesión de forma remota, envía `/stop_sesigram` en Telegram.
|
|
53
|
+
|
|
54
|
+
## Características
|
|
55
|
+
|
|
56
|
+
- **Agnóstico**: No requiere plugins ni modificaciones en el programa subyacente. Utiliza Pseudo-Terminales (PTY) nativas de Python.
|
|
57
|
+
- **Sin Demonios**: No se queda corriendo en segundo plano. El puente hacia Telegram solo existe mientras dura el comando envuelto.
|
|
58
|
+
- **Smart Buffering**: Acumula las salidas rápidas para no hacer spam ni exceder el límite de mensajes de la API de Telegram.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
sesigram/__init__.py
|
|
4
|
+
sesigram/cli.py
|
|
5
|
+
sesigram/telegram_api.py
|
|
6
|
+
sesigram/wrapper.py
|
|
7
|
+
sesigram.egg-info/PKG-INFO
|
|
8
|
+
sesigram.egg-info/SOURCES.txt
|
|
9
|
+
sesigram.egg-info/dependency_links.txt
|
|
10
|
+
sesigram.egg-info/entry_points.txt
|
|
11
|
+
sesigram.egg-info/requires.txt
|
|
12
|
+
sesigram.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sesigram
|
sesigram-0.1.0/setup.cfg
ADDED