06-oct: [omniroute] re-auth provider Claude + helper OAuth y vigilante portapapeles
This commit is contained in:
@@ -15,9 +15,18 @@
|
|||||||
- **2026-10-04-protocolo-encendido-sobremesa-validado-wol-falla-ciclo-regle** [servicios] Protocolo encendido sobremesa validado: WoL falla, ciclo regleta funciona (Power On Loss) (aplicado en: portatil)
|
- **2026-10-04-protocolo-encendido-sobremesa-validado-wol-falla-ciclo-regle** [servicios] Protocolo encendido sobremesa validado: WoL falla, ciclo regleta funciona (Power On Loss) (aplicado en: portatil)
|
||||||
- **2026-10-04-rdp-activado-en-sobremesa-por-tailscale-cuenta-sin-password** [servicios] RDP activado en sobremesa por Tailscale (cuenta sin password) (aplicado en: portatil)
|
- **2026-10-04-rdp-activado-en-sobremesa-por-tailscale-cuenta-sin-password** [servicios] RDP activado en sobremesa por Tailscale (cuenta sin password) (aplicado en: portatil)
|
||||||
- **2026-10-04-fix-encender-sobremesa-py-cargar-env-home-assistant** [scripts] Fix encender_sobremesa.py: cargar .env (Home Assistant) (aplicado en: portatil)
|
- **2026-10-04-fix-encender-sobremesa-py-cargar-env-home-assistant** [scripts] Fix encender_sobremesa.py: cargar .env (Home Assistant) (aplicado en: portatil)
|
||||||
|
- **2026-10-06-re-auth-provider-claude-omniroute-helper-oauth-vigilante-por** [omniroute] Re-auth provider Claude OmniRoute (helper OAuth + vigilante portapapeles) (aplicado en: portatil)
|
||||||
|
|
||||||
## Historial
|
## Historial
|
||||||
|
|
||||||
|
### 2026-10-06 · Re-auth provider Claude OmniRoute (helper OAuth + vigilante portapapeles)
|
||||||
|
- **id**: `2026-10-06-re-auth-provider-claude-omniroute-helper-oauth-vigilante-por`
|
||||||
|
- **Equipo**: portatil
|
||||||
|
- **Categoria**: omniroute
|
||||||
|
- **Transferible**: si
|
||||||
|
- **Aplicado en**: portatil
|
||||||
|
- **Detalle**: Scripts reutilizables en INFRAESTRUCTURA/omniroute: oauth_helper.py (mantiene vivo el proceso OAuth y le inyecta code#state por stdin, sin timeout) y clipboard_watch.ps1 (lee el codigo del portapapeles en modo -STA). Uso: lanzar helper, abrir URL con --no-browser, autorizar, copiar codigo -> auto-inyectado. Necesario cuando caduca el token OAuth del provider claude.
|
||||||
|
|
||||||
### 2026-10-04 · Protocolo de encendido remoto del sobremesa + PowerShell por SSH
|
### 2026-10-04 · Protocolo de encendido remoto del sobremesa + PowerShell por SSH
|
||||||
- **id**: `2026-10-04-protocolo-de-encendido-remoto-del-sobremesa-powershell-por-s`
|
- **id**: `2026-10-04-protocolo-de-encendido-remoto-del-sobremesa-powershell-por-s`
|
||||||
- **Equipo**: portatil
|
- **Equipo**: portatil
|
||||||
|
|||||||
@@ -462,6 +462,18 @@
|
|||||||
"portatil"
|
"portatil"
|
||||||
],
|
],
|
||||||
"detalle": "encender_sobremesa.py no cargaba el .env -> ha_alexa sin HOMEASSISTANT_URL/TOKEN, la regleta no respondia. Anadido load_dotenv(biblioteca/.env). Protocolo validado end-to-end: apagado por SSH -> verificado offline -> encendido por ciclo de regleta (Power On Loss)."
|
"detalle": "encender_sobremesa.py no cargaba el .env -> ha_alexa sin HOMEASSISTANT_URL/TOKEN, la regleta no respondia. Anadido load_dotenv(biblioteca/.env). Protocolo validado end-to-end: apagado por SSH -> verificado offline -> encendido por ciclo de regleta (Power On Loss)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2026-10-06-re-auth-provider-claude-omniroute-helper-oauth-vigilante-por",
|
||||||
|
"fecha": "2026-10-06",
|
||||||
|
"equipo": "portatil",
|
||||||
|
"categoria": "omniroute",
|
||||||
|
"titulo": "Re-auth provider Claude OmniRoute (helper OAuth + vigilante portapapeles)",
|
||||||
|
"transferible": true,
|
||||||
|
"aplicado_en": [
|
||||||
|
"portatil"
|
||||||
|
],
|
||||||
|
"detalle": "Scripts reutilizables en INFRAESTRUCTURA/omniroute: oauth_helper.py (mantiene vivo el proceso OAuth y le inyecta code#state por stdin, sin timeout) y clipboard_watch.ps1 (lee el codigo del portapapeles en modo -STA). Uso: lanzar helper, abrir URL con --no-browser, autorizar, copiar codigo -> auto-inyectado. Necesario cuando caduca el token OAuth del provider claude."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
24
omniroute/clipboard_watch.ps1
Normal file
24
omniroute/clipboard_watch.ps1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
$codeFile = "C:\Users\juanm\Documents\Github\INFRAESTRUCTURA\omniroute\oauth_code.txt"
|
||||||
|
$exitFile = "C:\Users\juanm\Documents\Github\INFRAESTRUCTURA\omniroute\oauth_helper.exit"
|
||||||
|
$last = ""
|
||||||
|
try { $last = [System.Windows.Forms.Clipboard]::GetText() } catch {}
|
||||||
|
$deadline = (Get-Date).AddMinutes(20)
|
||||||
|
while ((Get-Date) -lt $deadline) {
|
||||||
|
if (Test-Path $exitFile) { break }
|
||||||
|
$c = ""
|
||||||
|
try { $c = [System.Windows.Forms.Clipboard]::GetText() } catch {}
|
||||||
|
if ($c -and $c -ne $last -and $c.Length -ge 20 -and ($c -match "#" -or $c -match "code=")) {
|
||||||
|
# Limpiar espacios/saltos por si copia con formato
|
||||||
|
$clean = $c.Trim()
|
||||||
|
if ($clean -match "https?://") {
|
||||||
|
$m = [regex]::Match($clean, "code=([^&#\s]+)")
|
||||||
|
$s = [regex]::Match($clean, "state=([^&#\s]+)")
|
||||||
|
if ($m.Success -and $s.Success) { $clean = $m.Groups[1].Value + "#" + $s.Groups[1].Value }
|
||||||
|
}
|
||||||
|
Set-Content -Path $codeFile -Value $clean -NoNewline
|
||||||
|
break
|
||||||
|
}
|
||||||
|
$last = $c
|
||||||
|
Start-Sleep -Milliseconds 700
|
||||||
|
}
|
||||||
90
omniroute/oauth_helper.py
Normal file
90
omniroute/oauth_helper.py
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import subprocess, time, os, threading
|
||||||
|
|
||||||
|
base = r"C:\Users\juanm\Documents\Github\INFRAESTRUCTURA\omniroute"
|
||||||
|
url_file = os.path.join(base, "oauth_url.txt")
|
||||||
|
code_file = os.path.join(base, "oauth_code.txt")
|
||||||
|
log_file = os.path.join(base, "oauth_helper.log")
|
||||||
|
exit_file = os.path.join(base, "oauth_helper.exit")
|
||||||
|
hb_file = os.path.join(base, "oauth_helper.hb")
|
||||||
|
|
||||||
|
for f in (url_file, code_file, log_file, exit_file, hb_file):
|
||||||
|
try:
|
||||||
|
os.remove(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
["omniroute.cmd", "oauth", "start", "--provider", "claude-code", "--no-browser"],
|
||||||
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||||
|
text=True, bufsize=1
|
||||||
|
)
|
||||||
|
|
||||||
|
log = open(log_file, "w", encoding="utf-8", buffering=1)
|
||||||
|
buf = ""
|
||||||
|
|
||||||
|
|
||||||
|
def reader():
|
||||||
|
global buf
|
||||||
|
while True:
|
||||||
|
ch = proc.stdout.read(1)
|
||||||
|
if ch == "":
|
||||||
|
if proc.poll() is not None:
|
||||||
|
break
|
||||||
|
time.sleep(0.05)
|
||||||
|
continue
|
||||||
|
log.write(ch)
|
||||||
|
buf += ch
|
||||||
|
if "https://claude.ai/oauth/authorize" in buf and not os.path.exists(url_file):
|
||||||
|
start = buf.find("https://claude.ai/oauth/authorize")
|
||||||
|
nl = buf.find("\n", start)
|
||||||
|
if nl != -1:
|
||||||
|
with open(url_file, "w", encoding="utf-8") as uf:
|
||||||
|
uf.write(buf[start:nl].strip())
|
||||||
|
if len(buf) > 200000:
|
||||||
|
buf = buf[-50000:]
|
||||||
|
|
||||||
|
|
||||||
|
threading.Thread(target=reader, daemon=True).start()
|
||||||
|
|
||||||
|
# Esperar la URL (max 2 min, es rapido)
|
||||||
|
wait_url = time.time() + 120
|
||||||
|
while time.time() < wait_url and not os.path.exists(url_file):
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Sondear el codigo SIN limite de tiempo; hasta que el proceso termine
|
||||||
|
sent = False
|
||||||
|
while proc.poll() is None:
|
||||||
|
with open(hb_file, "w") as hb:
|
||||||
|
hb.write(str(time.time()))
|
||||||
|
if not sent and os.path.exists(code_file):
|
||||||
|
try:
|
||||||
|
with open(code_file, "r", encoding="utf-8") as cf:
|
||||||
|
code = cf.read().strip()
|
||||||
|
except Exception:
|
||||||
|
code = ""
|
||||||
|
if code:
|
||||||
|
try:
|
||||||
|
os.remove(code_file)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
log.write("\n[helper] enviando codigo al proceso...\n")
|
||||||
|
try:
|
||||||
|
proc.stdin.write(code + "\n")
|
||||||
|
proc.stdin.flush()
|
||||||
|
except Exception as e:
|
||||||
|
log.write("[helper] fallo al escribir stdin: %r\n" % e)
|
||||||
|
sent = True
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
rest = proc.stdout.read()
|
||||||
|
if rest:
|
||||||
|
log.write(rest)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
log.write("\n=== PROCESO TERMINADO rc=%s ===\n" % proc.poll())
|
||||||
|
log.close()
|
||||||
|
|
||||||
|
with open(exit_file, "w") as ef:
|
||||||
|
ef.write("done")
|
||||||
Reference in New Issue
Block a user