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/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
|
||||
|
||||
|
|
|
|||
24
check.sh
24
check.sh
|
|
@ -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'
|
||||
|
|
|
|||
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
|
||||
```
|
||||
|
||||
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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -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`:
|
||||
|
|
|
|||
12
install.sh
12
install.sh
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
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