chore: harden installer workflow and setup docs

This commit is contained in:
Paco 2026-04-25 00:20:38 +02:00
parent 420c6c85bb
commit f7ff5a2315
11 changed files with 261 additions and 24 deletions

View file

@ -75,6 +75,7 @@ opencode-browser-tool/
- `docs/QUICKSTART.md`
- `docs/VALIDACION_ENTORNO_LIMPIO.md`
- `docs/PLAN_CIERRE_INSTALABLE.md`
- `docs/INSTALACION_WINDOWS.md`
- `docs/REGISTRO_SITUACIONES.md`
- `docs/contexto_workspace/` (snapshot de docs globales clave para continuidad)
@ -83,18 +84,28 @@ opencode-browser-tool/
La idea es que este proyecto pueda copiarse o descargarse en un PC con OpenCode y dejarse listo mediante:
- `./install.sh`
- `npm run setup` (alternativa neutral por npm/node)
- una guia de instalacion clara
- o instrucciones que un agente de OpenCode pueda ejecutar
### Que hace `install.sh` con Chromium
### Que hace el setup
El script instala dependencias y luego ejecuta:
El setup ejecuta, en orden:
- `npx playwright install chromium`
- validacion de `Node.js 20+`
- instalacion de dependencias (`npm ci` cuando hay lockfile)
- compilacion (`npm run build`)
- instalacion de `Chromium managed by Playwright`
Esto instala el `Chromium managed by Playwright` para garantizar compatibilidad estable en la v1.
Al terminar, muestra un snippet MCP con la ruta absoluta local de `dist/server.js`.
Si el sistema ya tiene un Chromium propio, en esta fase igualmente se usa el gestionado por Playwright.
### Verificacion
Tras instalar, ejecutar:
- `./check.sh` o `npm run check`
La verificacion recompila y confirma archivos clave para puesta en marcha en otro PC.
## Nota

View file

@ -20,14 +20,30 @@ node --version
printf 'npm: '
npm --version
if [ -d "$SCRIPT_DIR/node_modules" ]; then
printf 'Dependencias instaladas: si\n'
else
printf 'Dependencias instaladas: no\n'
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
if [ "$NODE_MAJOR" -lt 20 ]; then
printf 'Se requiere Node.js 20 o superior.\n' >&2
exit 1
fi
if [ ! -d "$SCRIPT_DIR/node_modules" ]; then
printf 'Dependencias instaladas: no\n' >&2
printf 'Ejecuta ./install.sh primero.\n' >&2
exit 1
fi
printf 'Dependencias instaladas: si\n'
if [ -d "$SCRIPT_DIR/artifacts" ]; then
printf 'Carpeta artifacts: lista\n'
else
printf 'Carpeta artifacts: ausente\n'
fi
printf 'Compilando para verificar integridad...\n'
npm run --prefix "$SCRIPT_DIR" build
printf 'Validando archivos clave...\n'
node "$SCRIPT_DIR/scripts/verify-install.mjs"
printf 'Verificacion completada correctamente.\n'

View file

@ -0,0 +1,57 @@
# Instalacion Windows (guia para agente local)
Objetivo: que un agente OpenCode en un PC Windows pueda instalar y dejar operativa la tool desde esta carpeta.
## Prerrequisitos
- Node.js 20+
- npm
- OpenCode instalado
- Git (opcional si la carpeta ya fue copiada)
## Flujo recomendado
1) Abrir terminal en la carpeta `opencode-browser-tool`.
2) Ejecutar setup neutral (sin `.sh`):
```bash
npm run setup
```
3) Verificar instalacion:
```bash
npm run verify
```
4) Crear configuracion MCP de OpenCode con la ruta absoluta local de `dist/server.js`:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"browser-tool": {
"type": "local",
"command": [
"node",
"C:/ABSOLUTE/PATH/opencode-browser-tool/dist/server.js"
]
}
}
}
```
5) Confirmar conexion MCP:
```bash
opencode mcp list
```
6) Smoke test desde OpenCode: abrir browser -> navegar a `https://example.com` -> snapshot -> cerrar.
## Notas operativas
- En Windows evitar `install.sh`; usar `npm run setup`.
- Si se quiere `browserKind=system`, configurar la ruta real de Chrome en `browser_config`.
- Perfil persistente debe usar una ruta local valida de Windows (ej. `C:/Users/<usuario>/...`).

View file

@ -10,7 +10,13 @@ Desde `opencode-browser-tool/`:
./install.sh
```
Esto instala dependencias y `Chromium managed by Playwright`.
Alternativa neutral por npm/node:
```bash
npm run setup
```
Esto instala dependencias, compila y prepara `Chromium managed by Playwright`.
## 2) Compilar
@ -18,6 +24,12 @@ Esto instala dependencias y `Chromium managed by Playwright`.
npm run build
```
## 2.1) Verificar
```bash
./check.sh
```
## 3) Configurar MCP en el proyecto
Crear `opencode-browser-tool/.opencode/opencode.json` con:
@ -30,7 +42,7 @@ Crear `opencode-browser-tool/.opencode/opencode.json` con:
"type": "local",
"command": [
"node",
"/home/pancho/Documentos/Empresa/IA/opencode-browser-tool/dist/server.js"
"/ABSOLUTE/PATH/opencode-browser-tool/dist/server.js"
]
}
}

View file

@ -57,9 +57,9 @@ Recoger el trabajo completo necesario desde el estado actual hasta un producto t
- [x] Documentar instalacion paso a paso en un `.md` (`docs/QUICKSTART.md`)
- [ ] Verificar instalacion en un entorno limpio con OpenCode (checklist en `docs/VALIDACION_ENTORNO_LIMPIO.md`)
- [x] Asegurar que todo el proyecto se despliega desde una unica carpeta
- [ ] Cerrar instalable Linux sin rutas hardcodeadas (proyecto, perfil, OpenCode)
- [ ] Alinear `install.sh` y `check.sh` con puesta en marcha en PC nuevo
- [ ] Cerrar plantilla MCP portable para rutas locales variables
- [x] Cerrar instalable Linux sin rutas hardcodeadas (proyecto, perfil, OpenCode)
- [x] Alinear `install.sh` y `check.sh` con puesta en marcha en PC nuevo
- [x] Cerrar plantilla MCP portable para rutas locales variables
---

View file

@ -30,11 +30,16 @@ cd "$HOME/opencode-browser-tool"
./install.sh
```
Alternativa neutral:
```bash
npm run setup
```
3) Verificacion basica:
```bash
npm run check
npm run build
./check.sh
```
4) Configurar MCP para OpenCode con la ruta local real de `dist/server.js`:

View file

@ -3,14 +3,18 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if ! command -v node >/dev/null 2>&1; then
printf 'Node.js no esta disponible en el sistema.\n' >&2
exit 1
fi
if ! command -v npm >/dev/null 2>&1; then
printf 'npm no esta disponible en el sistema.\n' >&2
exit 1
fi
mkdir -p "$SCRIPT_DIR/artifacts"
npm install --prefix "$SCRIPT_DIR"
npx --yes playwright install chromium
printf 'Iniciando setup en %s\n' "$SCRIPT_DIR"
node "$SCRIPT_DIR/scripts/setup.mjs"
printf 'Instalacion base completada.\n'
printf 'Siguiente paso sugerido: revisar opencode.mcp.example.json\n'
printf 'Siguiente paso sugerido: ejecutar ./check.sh\n'

View file

@ -1,9 +1,11 @@
{
"mcpServers": {
"$schema": "https://opencode.ai/config.json",
"mcp": {
"browser-tool": {
"command": "node",
"args": [
"/ruta/a/opencode-browser-tool/dist/server.js"
"type": "local",
"command": [
"node",
"/ABSOLUTE/PATH/opencode-browser-tool/dist/server.js"
]
}
}

View file

@ -5,7 +5,9 @@
"description": "Browser MCP tool external to OpenCode",
"type": "module",
"scripts": {
"setup": "node ./scripts/setup.mjs",
"build": "tsc -p tsconfig.json",
"verify": "node ./scripts/verify-install.mjs",
"check": "bash ./check.sh",
"dev": "tsx src/server.ts",
"start": "node dist/server.js"

81
scripts/setup.mjs Normal file
View file

@ -0,0 +1,81 @@
#!/usr/bin/env node
import { mkdir, access } from "node:fs/promises"
import path from "node:path"
import { fileURLToPath } from "node:url"
import { spawn } from "node:child_process"
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const projectDir = path.resolve(__dirname, "..")
function run(cmd, args, cwd = projectDir) {
return new Promise((resolve, reject) => {
const child = spawn(cmd, args, {
cwd,
stdio: "inherit",
shell: false,
})
child.on("error", reject)
child.on("exit", (code) => {
if (code === 0) {
resolve()
return
}
reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code ?? -1}`))
})
})
}
async function exists(filePath) {
try {
await access(filePath)
return true
} catch {
return false
}
}
function ensureNode20() {
const major = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10)
if (!Number.isFinite(major) || major < 20) {
throw new Error(`Node.js 20+ required. Current: ${process.versions.node}`)
}
}
async function main() {
ensureNode20()
await mkdir(path.join(projectDir, "artifacts"), { recursive: true })
await mkdir(path.join(projectDir, "config"), { recursive: true })
const lockPath = path.join(projectDir, "package-lock.json")
if (await exists(lockPath)) {
await run("npm", ["ci"])
} else {
await run("npm", ["install"])
}
await run("npm", ["run", "build"])
await run("npm", ["exec", "playwright", "install", "chromium"])
const distPath = path.join(projectDir, "dist", "server.js")
const mcpConfig = {
$schema: "https://opencode.ai/config.json",
mcp: {
"browser-tool": {
type: "local",
command: ["node", distPath],
},
},
}
process.stdout.write("\nInstall complete.\n")
process.stdout.write("Suggested MCP config snippet:\n")
process.stdout.write(`${JSON.stringify(mcpConfig, null, 2)}\n`)
}
main().catch((error) => {
process.stderr.write(`Setup failed: ${error instanceof Error ? error.message : String(error)}\n`)
process.exit(1)
})

View file

@ -0,0 +1,47 @@
#!/usr/bin/env node
import { access } from "node:fs/promises"
import path from "node:path"
import { fileURLToPath } from "node:url"
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const projectDir = path.resolve(__dirname, "..")
async function has(filePath) {
try {
await access(filePath)
return true
} catch {
return false
}
}
function nodeOk() {
const major = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10)
return Number.isFinite(major) && major >= 20
}
async function main() {
const report = {
node: process.versions.node,
nodeOk: nodeOk(),
packageJson: await has(path.join(projectDir, "package.json")),
nodeModules: await has(path.join(projectDir, "node_modules")),
distServer: await has(path.join(projectDir, "dist", "server.js")),
configFile: await has(path.join(projectDir, "config", "browser-tool.config.json")),
mcpTemplate: await has(path.join(projectDir, "opencode.mcp.example.json")),
}
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`)
const ok = Object.values(report).every((value) => value !== false)
if (!ok) {
process.exit(1)
}
}
main().catch((error) => {
process.stderr.write(`Verify failed: ${error instanceof Error ? error.message : String(error)}\n`)
process.exit(1)
})