04-oct: instalar_dependencias.ps1 + omniroute-autostart.ts al repo + comparativa equipos

This commit is contained in:
minguezsanzjuanjose
2026-10-04 00:15:07 +02:00
parent 0b4fe1cf7f
commit 29157d4f08
6 changed files with 242 additions and 4 deletions

View File

@@ -0,0 +1,116 @@
/**
* OmniRoute autostart — OpenCode plugin
*
* Arranca el servidor local OmniRoute (http://127.0.0.1:20128) cada vez que
* OpenCode se inicia, si no está ya escuchando. También lo relanza si se cae
* durante la sesión. Esto garantiza que los modelos del proveedor `omniroute`
* estén siempre disponibles (modelos gratuitos de la suscripción Claude Code).
*
* Se carga automáticamente desde ~/.config/opencode/plugins/*.ts
*/
import type { Plugin } from "@opencode-ai/plugin"
import { spawn } from "node:child_process"
import { appendFileSync, mkdirSync } from "node:fs"
import { homedir } from "node:os"
import { join } from "node:path"
// ─── Configuración ───────────────────────────────────────────────────────────
const OR_URL = "http://127.0.0.1:20128"
const OR_PORT = 20128
const NODE_BIN = process.env.OMNIROUTE_NODE ?? "C:\\Program Files\\nodejs\\node.exe"
const OR_ENTRY =
process.env.OMNIROUTE_ENTRY ??
join(
process.env.APPDATA ?? join(homedir(), "AppData", "Roaming"),
"npm",
"node_modules",
"omniroute",
"bin",
"omniroute.mjs",
)
const LOG_FILE = join(homedir(), ".omniroute", "autostart-plugin.log")
// ─── Utilidades ──────────────────────────────────────────────────────────────
function log(msg: string): void {
try {
mkdirSync(join(homedir(), ".omniroute"), { recursive: true })
appendFileSync(LOG_FILE, `[${new Date().toISOString()}] ${msg}\n`)
} catch {
// el log nunca debe romper el arranque de OpenCode
}
}
/** ¿Responde OmniRoute? El dashboard en "/" devuelve 200 sin autenticación. */
async function isUp(): Promise<boolean> {
try {
const ctrl = new AbortController()
const timer = setTimeout(() => ctrl.abort(), 3000)
const res = await fetch(`${OR_URL}/`, { signal: ctrl.signal })
clearTimeout(timer)
return res.status > 0 && res.status < 500
} catch {
return false
}
}
/** Lanza OmniRoute desacoplado para que sobreviva al cierre de OpenCode. */
function startServer(): void {
const child = spawn(NODE_BIN, [OR_ENTRY, "serve"], {
detached: true,
stdio: "ignore",
windowsHide: true,
env: process.env,
})
child.unref()
log(`lanzado OmniRoute (pid ${child.pid})`)
}
// Evita arranques concurrentes si coinciden el inicio y varios session.created
let starting: Promise<void> | null = null
/** Arranca OmniRoute si no está levantado y espera a que responda. */
async function ensureServer(reason: string): Promise<void> {
if (await isUp()) return
if (starting) return starting
starting = (async () => {
log(`OmniRoute caído (${reason}) — arrancando...`)
startServer()
// El arranque puede tardar ~60s; sondeamos hasta 2 minutos
for (let i = 0; i < 40; i++) {
await new Promise((r) => setTimeout(r, 3000))
if (await isUp()) {
log(`OmniRoute listo en puerto ${OR_PORT}`)
return
}
}
log("OmniRoute no respondió dentro del tiempo de espera")
})()
try {
await starting
} finally {
starting = null
}
}
// ─── Plugin ──────────────────────────────────────────────────────────────────
export const OmniRouteAutostart: Plugin = async () => {
// Al cargar el plugin (= arranque de OpenCode) nos aseguramos de que esté vivo
void ensureServer("opencode-start")
return {
event: async ({ event }) => {
// Re-verificación barata al crear sesión (cubre una caída a mitad de sesión)
if (event.type === "session.created") {
void ensureServer("session-created")
}
},
}
}