chore: harden installer workflow and setup docs
This commit is contained in:
parent
420c6c85bb
commit
f7ff5a2315
11 changed files with 261 additions and 24 deletions
21
README.md
21
README.md
|
|
@ -75,6 +75,7 @@ opencode-browser-tool/
|
||||||
- `docs/QUICKSTART.md`
|
- `docs/QUICKSTART.md`
|
||||||
- `docs/VALIDACION_ENTORNO_LIMPIO.md`
|
- `docs/VALIDACION_ENTORNO_LIMPIO.md`
|
||||||
- `docs/PLAN_CIERRE_INSTALABLE.md`
|
- `docs/PLAN_CIERRE_INSTALABLE.md`
|
||||||
|
- `docs/INSTALACION_WINDOWS.md`
|
||||||
- `docs/REGISTRO_SITUACIONES.md`
|
- `docs/REGISTRO_SITUACIONES.md`
|
||||||
- `docs/contexto_workspace/` (snapshot de docs globales clave para continuidad)
|
- `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:
|
La idea es que este proyecto pueda copiarse o descargarse en un PC con OpenCode y dejarse listo mediante:
|
||||||
|
|
||||||
- `./install.sh`
|
- `./install.sh`
|
||||||
|
- `npm run setup` (alternativa neutral por npm/node)
|
||||||
- una guia de instalacion clara
|
- una guia de instalacion clara
|
||||||
- o instrucciones que un agente de OpenCode pueda ejecutar
|
- 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
|
## Nota
|
||||||
|
|
||||||
|
|
|
||||||
24
check.sh
24
check.sh
|
|
@ -20,14 +20,30 @@ node --version
|
||||||
printf 'npm: '
|
printf 'npm: '
|
||||||
npm --version
|
npm --version
|
||||||
|
|
||||||
if [ -d "$SCRIPT_DIR/node_modules" ]; then
|
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
|
||||||
printf 'Dependencias instaladas: si\n'
|
if [ "$NODE_MAJOR" -lt 20 ]; then
|
||||||
else
|
printf 'Se requiere Node.js 20 o superior.\n' >&2
|
||||||
printf 'Dependencias instaladas: no\n'
|
exit 1
|
||||||
fi
|
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
|
if [ -d "$SCRIPT_DIR/artifacts" ]; then
|
||||||
printf 'Carpeta artifacts: lista\n'
|
printf 'Carpeta artifacts: lista\n'
|
||||||
else
|
else
|
||||||
printf 'Carpeta artifacts: ausente\n'
|
printf 'Carpeta artifacts: ausente\n'
|
||||||
fi
|
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'
|
||||||
|
|
|
||||||
57
docs/INSTALACION_WINDOWS.md
Normal file
57
docs/INSTALACION_WINDOWS.md
Normal 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>/...`).
|
||||||
|
|
@ -10,7 +10,13 @@ Desde `opencode-browser-tool/`:
|
||||||
./install.sh
|
./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
|
## 2) Compilar
|
||||||
|
|
||||||
|
|
@ -18,6 +24,12 @@ Esto instala dependencias y `Chromium managed by Playwright`.
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 2.1) Verificar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./check.sh
|
||||||
|
```
|
||||||
|
|
||||||
## 3) Configurar MCP en el proyecto
|
## 3) Configurar MCP en el proyecto
|
||||||
|
|
||||||
Crear `opencode-browser-tool/.opencode/opencode.json` con:
|
Crear `opencode-browser-tool/.opencode/opencode.json` con:
|
||||||
|
|
@ -30,7 +42,7 @@ Crear `opencode-browser-tool/.opencode/opencode.json` con:
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"command": [
|
"command": [
|
||||||
"node",
|
"node",
|
||||||
"/home/pancho/Documentos/Empresa/IA/opencode-browser-tool/dist/server.js"
|
"/ABSOLUTE/PATH/opencode-browser-tool/dist/server.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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`)
|
- [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`)
|
- [ ] 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
|
- [x] Asegurar que todo el proyecto se despliega desde una unica carpeta
|
||||||
- [ ] Cerrar instalable Linux sin rutas hardcodeadas (proyecto, perfil, OpenCode)
|
- [x] Cerrar instalable Linux sin rutas hardcodeadas (proyecto, perfil, OpenCode)
|
||||||
- [ ] Alinear `install.sh` y `check.sh` con puesta en marcha en PC nuevo
|
- [x] Alinear `install.sh` y `check.sh` con puesta en marcha en PC nuevo
|
||||||
- [ ] Cerrar plantilla MCP portable para rutas locales variables
|
- [x] Cerrar plantilla MCP portable para rutas locales variables
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,16 @@ cd "$HOME/opencode-browser-tool"
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Alternativa neutral:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run setup
|
||||||
|
```
|
||||||
|
|
||||||
3) Verificacion basica:
|
3) Verificacion basica:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run check
|
./check.sh
|
||||||
npm run build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4) Configurar MCP para OpenCode con la ruta local real de `dist/server.js`:
|
4) Configurar MCP para OpenCode con la ruta local real de `dist/server.js`:
|
||||||
|
|
|
||||||
12
install.sh
12
install.sh
|
|
@ -3,14 +3,18 @@ set -euo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
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
|
if ! command -v npm >/dev/null 2>&1; then
|
||||||
printf 'npm no esta disponible en el sistema.\n' >&2
|
printf 'npm no esta disponible en el sistema.\n' >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$SCRIPT_DIR/artifacts"
|
printf 'Iniciando setup en %s\n' "$SCRIPT_DIR"
|
||||||
npm install --prefix "$SCRIPT_DIR"
|
node "$SCRIPT_DIR/scripts/setup.mjs"
|
||||||
npx --yes playwright install chromium
|
|
||||||
|
|
||||||
printf 'Instalacion base completada.\n'
|
printf 'Instalacion base completada.\n'
|
||||||
printf 'Siguiente paso sugerido: revisar opencode.mcp.example.json\n'
|
printf 'Siguiente paso sugerido: ejecutar ./check.sh\n'
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"mcp": {
|
||||||
"browser-tool": {
|
"browser-tool": {
|
||||||
"command": "node",
|
"type": "local",
|
||||||
"args": [
|
"command": [
|
||||||
"/ruta/a/opencode-browser-tool/dist/server.js"
|
"node",
|
||||||
|
"/ABSOLUTE/PATH/opencode-browser-tool/dist/server.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@
|
||||||
"description": "Browser MCP tool external to OpenCode",
|
"description": "Browser MCP tool external to OpenCode",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"setup": "node ./scripts/setup.mjs",
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
|
"verify": "node ./scripts/verify-install.mjs",
|
||||||
"check": "bash ./check.sh",
|
"check": "bash ./check.sh",
|
||||||
"dev": "tsx src/server.ts",
|
"dev": "tsx src/server.ts",
|
||||||
"start": "node dist/server.js"
|
"start": "node dist/server.js"
|
||||||
|
|
|
||||||
81
scripts/setup.mjs
Normal file
81
scripts/setup.mjs
Normal 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)
|
||||||
|
})
|
||||||
47
scripts/verify-install.mjs
Normal file
47
scripts/verify-install.mjs
Normal 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)
|
||||||
|
})
|
||||||
Loading…
Add table
Reference in a new issue