Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# .githooks — enforcement de versionado (Atenea)

Hooks git-native (POSIX, sin dependencias). Corren para **cualquier** commit, hecho por una
persona o por un agente. Alinean el manual de versionado del equipo.

- **`commit-msg`** — bloquea el commit si el mensaje no sigue Conventional Commits
(`<tipo>(<alcance>)(!): descripción`). Avisa (no bloquea) si el tipo no cuadra con el prefijo
de la rama.
- **`pre-commit`** — bloquea commits directos sobre `main` o `beta` (el desarrollo va en ramas
temporales). Escape para promoción de release: `ATENEA_ALLOW_PROTECTED=1 git commit ...`.

## Activación

`core.hooksPath` es config local por clon (no se versiona), así que cada clon la activa una vez.
El proyecto lo automatiza con un script `prepare` en `package.json`:

```json
"scripts": { "prepare": "git config core.hooksPath .githooks || true" }
```

Así, en cada `yarn install` queda cableado. Manual, si hiciera falta:

```bash
git config core.hooksPath .githooks
chmod +x .githooks/*
```

Bypass puntual de un hook (no recomendado): `git commit --no-verify`.
53 changes: 53 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/sh
# ─────────────────────────────────────────────────────────────────────────
# Atenea · commit-msg · valida Conventional Commits (manual de versionado Venteks)
#
# Git-native: corre para CUALQUIER commit (humano o agente), esté o no Claude.
# Bloquea el commit si el mensaje no cumple. Escape puntual: git commit --no-verify.
#
# Formato exigido: <tipo>(<alcance opcional>)(!): <descripción en imperativo>
# tipos: feat fix docs style refactor perf test build ci chore revert
# ejemplos: feat(auth): agregar login por sesión
# fix: corregir cálculo de permisos
# feat(store)!: cambiar shape del estado (BREAKING CHANGE)
# ─────────────────────────────────────────────────────────────────────────

msg_file="$1"
first_line="$(head -n 1 "$msg_file")"

# Saltar commits de merge/revert automáticos y fixup/squash.
case "$first_line" in
"Merge "*|"Revert "*|"fixup!"*|"squash!"*) exit 0 ;;
esac

pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9._/-]+\))?(!)?: .+'

if printf '%s' "$first_line" | grep -Eq "$pattern"; then
# Aviso suave: coherencia tipo ↔ prefijo de rama (no bloquea).
# Una rama feat/* es un contenedor de feature: acumula fix/docs/refactor/chore/
# test intermedios de forma legítima, así que NO se avisa sobre ella. Solo se
# revisan fix/* y hotfix/*, que son de propósito único.
branch="$(git symbolic-ref --short HEAD 2>/dev/null || echo '')"
type="$(printf '%s' "$first_line" | sed -E 's/^([a-z]+).*/\1/')"
case "$branch" in
fix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: rama fix/* pero commit "%s" (¿debería ser fix?)\n' "$type" >&2 ;;
hotfix/*) [ "$type" = "fix" ] || printf '⚠️ Atenea: rama hotfix/* pero commit "%s" (¿debería ser fix?)\n' "$type" >&2 ;;
esac
exit 0
fi

cat >&2 <<'EOF'
✕ Atenea · commit rechazado: el mensaje no sigue Conventional Commits.

Formato: <tipo>(<alcance>)(!): <descripción en imperativo>
Tipos: feat fix docs style refactor perf test build ci chore revert

Ejemplos válidos:
feat(auth): agregar login por sesión
fix: corregir cálculo de permisos
feat(store)!: cambiar shape del estado

Manual de versionado del equipo (plugin Atenea, skill git-flow).
Bypass puntual (no recomendado): git commit --no-verify
EOF
exit 1
36 changes: 36 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/sh
# ─────────────────────────────────────────────────────────────────────────
# Atenea · pre-commit · protege ramas permanentes (manual de versionado Venteks)
#
# Regla del md: "nunca desarrolles directo sobre main". El desarrollo va en ramas
# temporales (feat/ fix/ chore/) desde beta; hotfix/ desde main. Este hook
# bloquea commits DIRECTOS sobre main o beta.
#
# Escape para promoción/merge de release: ATENEA_ALLOW_PROTECTED=1 git commit ...
# Bypass total puntual: git commit --no-verify
# ─────────────────────────────────────────────────────────────────────────

[ "${ATENEA_ALLOW_PROTECTED:-}" = "1" ] && exit 0

branch="$(git symbolic-ref --short HEAD 2>/dev/null || echo '')"

case "$branch" in
main|beta)
cat >&2 <<EOF
✕ Atenea · commit directo sobre '$branch' bloqueado.

El desarrollo va en ramas temporales:
feat/<func> · fix/<bug> · chore/<ajuste> (desde beta)
hotfix/<bug> (desde main)

Crea la rama y muévete a ella:
git switch -c feat/mi-cambio

Promoción de release (merge a $branch): ATENEA_ALLOW_PROTECTED=1 git commit ...
Bypass puntual (no recomendado): git commit --no-verify
EOF
exit 1
;;
esac

exit 0
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
pull_request:
branches: [beta, main]
push:
branches: [beta, main]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
check:
name: Instalar y revisar sintaxis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run check
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Changelog

Todas las notas relevantes de este proyecto se documentan aquí.
Formato basado en [Keep a Changelog](https://keepachangelog.com/es-ES/); versionado [SemVer](https://semver.org/lang/es/).

## [Sin liberar]

### Añadido

### Cambiado

### Corregido

### Eliminado

## [1.0.0] - 2026-11-01

### Añadido
- Visor web del emulador: `screenrecord` H.264 por WebSocket, decodificado con WebCodecs. Guarda el GOP para quien se conecta después y manda una captura mientras la pantalla está quieta.
- Selector con todos los AVDs del equipo y los dispositivos de adb; un AVD apagado se arranca desde el visor.
- Controles como los del emulador: Atrás, Inicio, Recientes, Encendido, volumen, rotar izquierda/derecha, guardar captura a resolución completa y posturas de plegable.
- Posturas: en emuladores mueven la bisagra simulada (`emu posture`); en dispositivos físicos y Trasera, `cmd device_state state`. El stream sigue al display activo al plegar o rotar.
- API HTTP del visor (`/api/devices`, `/state`, `/screenshot`, `/tap`, `/swipe`, `/key`, `/text`, `/posture`, `/rotate`, `/launch`), solo desde orígenes locales.
- MCP por stdio (`list_devices`, `launch_avd`, `get_state`, `screenshot`, `tap`, `swipe`, `press_key`, `type_text`, `rotate`, `set_posture`): habla con el visor para que todo se vea en vivo, o con adb directo si el visor está apagado.
- Capturas en JavaScript puro: `screencap` en crudo, reducción por promedio de área y PNG con `zlib`, sin `sips` ni otras herramientas del sistema, así que funcionan en macOS, Linux y Windows. `GET /api/screenshot?max=<px>` reduce la imagen y devuelve el tamaño real en `X-Screen-Width`/`X-Screen-Height`.
- Comando `android-viewer` para `npx @acertijosapps/android-viewer`: sin argumentos arranca el visor (`--port`, `--host`) y `mcp` arranca el MCP (`--viewer-url`); `--help` y `--version`.
- README en inglés con captura del visor (`media/`, incluida en el paquete y servida por unpkg), instalación con `npx` y configuración del MCP para Claude Code y otros clientes.
- Textos en inglés: interfaz del visor, errores de la API, herramientas del MCP y mensajes de la terminal.
- Git flow del proyecto: CHANGELOG, guía de contribución, hooks de git (Conventional Commits y ramas protegidas) y CI en GitHub Actions.

<!--
Al promover beta → main: renombra [Sin liberar] a [X.Y.Z] - AAAA-MM-DD y vuelve a crear una
sección [Sin liberar] vacía encima de ella. Las versiones liberadas quedan debajo, de la más
nueva a la más vieja.
-->
79 changes: 79 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Contributing

Contributions are welcome. Keep changes small, focused, and traceable.

## Development workflow

Use the Node.js version in [`.nvmrc`](./.nvmrc). Install dependencies from the root:

```sh
npm install
```

`npm install` also wires the repository git hooks (`core.hooksPath` → `.githooks/`).

You need the Android SDK (`adb` and `emulator`). The tools are looked up in `ANDROID_HOME`, `ANDROID_SDK_ROOT` or the default SDK location; override them with `ADB` and `EMULATOR`.

### Commands

```sh
npm start # start the viewer on http://localhost:8093
npm run mcp # start the MCP server (stdio)
npm run check # syntax-check the sources
```

## Branching model

Two permanent branches, both protected:

- **`main`** — production. No direct pushes; changes land only through an approved Pull Request.
- **`beta`** — release candidate.

Temporary branches, always created from `beta`, in kebab-case:

- `feat/<name>` · `fix/<name>` · `chore/<name>` → Pull Request **into `beta`**, deleted after merge.
- `hotfix/<name>` is the only exception: created from `main`, PR into `main`, then back-merged into `beta`.

One branch = one focused change.

## Commits

[Conventional Commits](https://www.conventionalcommits.org/):

```
<type>(<optional scope>)(!): <imperative description>
```

Types: `feat` `fix` `docs` `style` `refactor` `perf` `test` `build` `ci` `chore` `revert`.

[SemVer](https://semver.org/) mapping: `feat` → MINOR, `fix` → PATCH, breaking (`feat!` or `BREAKING CHANGE:`) → MAJOR.

The git hooks in [`.githooks/`](./.githooks) run for every commit:

- `commit-msg` rejects messages that are not Conventional Commits.
- `pre-commit` blocks direct commits on `main` and `beta`.

One-off bypass (not recommended): `git commit --no-verify`.

## Changelog

Any change that affects behavior updates [`CHANGELOG.md`](./CHANGELOG.md) ([Keep a Changelog](https://keepachangelog.com/)): add the entry under `## [Sin liberar]` in the right category (Añadido · Cambiado · Corregido · Eliminado).

## Pull Requests

When opening a PR:

- Target `beta` (or `main` only for `hotfix`).
- Keep it small and focused on one change.
- Assign at least one reviewer; merge requires their approval.
- Link the related work item for traceability.
- Gates must be green: `npm run check`. CI ([`.github/workflows/ci.yml`](./.github/workflows/ci.yml)) runs it on every PR to `beta` or `main`.
- Include the `CHANGELOG.md` entry.

## Releasing (`beta` → `main`)

1. Confirm gates are green on `beta`.
2. Decide the SemVer bump from the commits since the last tag.
3. Update `version` in `package.json`.
4. Rename the `## [Sin liberar]` section of the changelog to `## [X.Y.Z] - YYYY-MM-DD` and open a fresh empty one.
5. Tag `vX.Y.Z` on `main`.
Loading
Loading