diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1dc20cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Ficheros innecesarios para instalar el paquete (pi install / copia). +# Lo que se necesita: package.json, extensions/, skills/ (y LICENSE). + +# Configuración local de pi en este directorio (modelo por defecto, confianza…) +.pi/ + +# Dependencias y artefactos de empaquetado +node_modules/ +*.tgz +*.tar.gz +*.zip + +# Registros y temporales +*.log +*.tmp +*.bak +*~ +*.swp +*.swo + +# Editores y sistema +.vscode/ +.idea/ +.DS_Store +Thumbs.db + +# Variables de entorno / secretos +.env +.env.* diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b80ca..ccec0f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,21 @@ y el proyecto usa [Versionado Semántico](https://semver.org/lang/es/). ## [No publicado] +### Pendiente + +- Fijar las reglas de modelo y de funcionamiento que la skill escribirá en el + `AGENTS.md` de cada proyecto generado (hoy quedan como `PENDIENTE`). + +## [0.3.0] - 2026-10-18 + ### Añadido +- Repositorio de distribución + con solo los + ficheros que necesita pi (`package.json`, `LICENSE`, `extensions/`, `skills/` + y un `README.md` mínimo), y script `scripts/publicar-dist.sh` para publicar + cada versión en él (commit + etiqueta `vX.Y.Z`, con `--dry-run`). +- `.gitignore` del repositorio (configuración local de pi, temporales, editores). - Licencia MIT: fichero `LICENSE` y campo `license` en `package.json`. - Documentada la descarga e instalación desde el repositorio @@ -18,16 +31,15 @@ y el proyecto usa [Versionado Semántico](https://semver.org/lang/es/). ### Cambiado +- La instalación recomendada pasa a ser + `pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist`; + `README.md` e `INSTALL.md` actualizados (actualización, desinstalación y + publicación de versiones). - El selector de modelo (`/modelo-proyecto` y `elegir_modelo_proyecto`) muestra como máximo 15 modelos a la vez en una ventana que se desplaza con el cursor; ↑/↓ dan la vuelta de un extremo a otro y el cursor parte del modelo actual del proyecto. Fuera de la TUI se mantiene el diálogo estándar. -### Pendiente - -- Fijar las reglas de modelo y de funcionamiento que la skill escribirá en el - `AGENTS.md` de cada proyecto generado (hoy quedan como `PENDIENTE`). - ## [0.2.0] - 2026-10-18 ### Añadido diff --git a/INSTALL.md b/INSTALL.md index 163e604..137e4c6 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -3,7 +3,12 @@ Instalación del paquete/skill `new-project` en pi, en este ordenador o en cualquier otro. -Repositorio: +Repositorios: + +- **Distribución** (para usarlo): . + Solo contiene lo que pi necesita: `package.json`, `LICENSE`, `extensions/`, + `skills/` y un `README.md` mínimo. Se genera con `scripts/publicar-dist.sh`. +- **Desarrollo** (para modificarlo): . ## 1. Requisitos @@ -16,27 +21,32 @@ Repositorio: ## 2. Opción A — instalarlo como paquete de pi desde git (recomendado) -pi clona el repositorio y lo instala directamente: +pi clona el repositorio de distribución y lo instala directamente: ```bash -pi install git:git.sargatxet.cloud/sargatxet/pi-new-project +pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist # equivalente, con la URL completa: -pi install https://git.sargatxet.cloud/sargatxet/pi-new-project +pi install https://git.sargatxet.cloud/sargatxet/pi-new-project-dist ``` -Para fijar una versión concreta, añade una etiqueta o un commit: -`pi install git:git.sargatxet.cloud/sargatxet/pi-new-project@`. +Para fijar una versión concreta, añade una etiqueta (`v0.3.0`, …) o un commit: +`pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist@`. Añade `-l` (`--local`) para declararlo solo en el proyecto actual (`.pi/settings.json`) en lugar de en `~/.pi/agent/settings.json`. Comprueba con `pi list` y arranca pi: la skill aparecerá como `new-project` y estará disponible la orden `/modelo-proyecto`. Para una prueba puntual sin instalarlo: -`pi -e git:git.sargatxet.cloud/sargatxet/pi-new-project`. +`pi -e git:git.sargatxet.cloud/sargatxet/pi-new-project-dist`. -### Desde una copia local +> Si ya lo tenías instalado desde el repositorio de desarrollo +> (`git:git.sargatxet.cloud/sargatxet/pi-new-project`), pi lo considera otro +> paquete: quítalo antes con `pi remove git:git.sargatxet.cloud/sargatxet/pi-new-project` +> para que la skill no se cargue dos veces. -Si prefieres descargar antes el repositorio (para revisarlo o modificarlo): +### Desde una copia local del repositorio de desarrollo + +Si vas a revisarlo o modificarlo: ```bash git clone https://git.sargatxet.cloud/sargatxet/pi-new-project.git @@ -64,7 +74,8 @@ ln -s "$PWD/pi-new-project/skills/new-project" ~/.agents/skills/new-project Rutas equivalentes: `~/.pi/agent/skills/` y, por proyecto, `.agents/skills/`. En estos ejemplos, `pi-new-project/` es una copia del repositorio obtenida con -`git clone https://git.sargatxet.cloud/sargatxet/pi-new-project.git`. +`git clone https://git.sargatxet.cloud/sargatxet/pi-new-project-dist.git pi-new-project` +(o del de desarrollo, `.../pi-new-project.git`; ambos tienen `skills/` y `extensions/`). La skill sola no incluye la orden `/modelo-proyecto` ni la herramienta `elegir_modelo_proyecto`; cópialas también (o la skill usará el plan B, @@ -78,15 +89,16 @@ cp pi-new-project/extensions/modelo-proyecto.ts ~/.pi/agent/extensions/ ## 4. Opción C — exportar a otro ordenador sin acceso al repositorio Si el ordenador destino tiene acceso a -, basta con la opción A. -Si no, copia el directorio; no tiene dependencias. +, basta con la opción A. +Si no, copia el directorio (mejor el de distribución, que solo trae lo necesario); +no tiene dependencias. ```bash # en el ordenador origen -tar -czf pi-new-project-0.2.0.tar.gz pi-new-project/ +tar -czf pi-new-project-0.3.0.tar.gz pi-new-project/ # en el ordenador destino -tar -xzf pi-new-project-0.2.0.tar.gz +tar -xzf pi-new-project-0.3.0.tar.gz pi install ./pi-new-project # o la opción B ``` @@ -132,7 +144,8 @@ mueve: reinstala con la nueva referencia. ## 7. Desinstalación ```bash -pi remove git:git.sargatxet.cloud/sargatxet/pi-new-project # paquete desde git +pi remove git:git.sargatxet.cloud/sargatxet/pi-new-project-dist # paquete desde git +pi remove git:git.sargatxet.cloud/sargatxet/pi-new-project # instalaciones antiguas pi remove ./pi-new-project # paquete desde una copia local rm -rf ~/.agents/skills/new-project # si se copió o enlazó rm -f ~/.pi/agent/extensions/modelo-proyecto.ts @@ -140,6 +153,21 @@ rm -f ~/.pi/agent/extensions/modelo-proyecto.ts La skill no deja estado propio: no hay caché ni configuración que limpiar. +## Publicar una versión (mantenedores) + +El repositorio de distribución se genera desde el de desarrollo; no se edita a +mano. Con los cambios ya commiteados y la versión subida en `package.json` y +`CHANGELOG.md`: + +```bash +scripts/publicar-dist.sh --dry-run # prepara y muestra el contenido sin subir nada +scripts/publicar-dist.sh # commit + etiqueta vX.Y.Z en pi-new-project-dist +``` + +El script toma el contenido de `HEAD` (no del directorio de trabajo), se niega a +publicar si hay cambios sin commitear en lo que se publica o si la etiqueta ya +existe, y necesita permiso de escritura en el repositorio de distribución. + ## 8. Resolución de problemas | Síntoma | Causa probable | Solución | diff --git a/README.md b/README.md index 64aa5f3..ec1fa95 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ pi-new-project/ ├── CHANGELOG.md ├── TODO.md ├── LICENSE # licencia MIT +├── scripts/ +│ └── publicar-dist.sh # publica la versión instalable en pi-new-project-dist ├── extensions/ │ └── modelo-proyecto.ts # orden /modelo-proyecto y herramienta elegir_modelo_proyecto └── skills/ @@ -65,14 +67,18 @@ El script nunca sobreescribe ficheros existentes salvo con `--force`, y admite ## Instalación -El repositorio está en -y se instala directamente desde ahí como paquete de pi: +Para usarlo, instala la **versión de distribución** +(), que contiene solo +los ficheros que necesita pi (`package.json`, `LICENSE`, `extensions/` y `skills/`): ```bash -pi install git:git.sargatxet.cloud/sargatxet/pi-new-project +pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist +# o una versión fija: +pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist@v0.3.0 ``` -También puedes clonarlo e instalar la copia local: +Este repositorio () es el +de desarrollo. Para modificar el paquete, clónalo e instala la copia local: ```bash git clone https://git.sargatxet.cloud/sargatxet/pi-new-project.git diff --git a/TODO.md b/TODO.md index ddb7316..4eea4a1 100644 --- a/TODO.md +++ b/TODO.md @@ -15,13 +15,16 @@ - [ ] Detectar y completar el stack automáticamente (¿`--stack python|node|rust`?) para prellenar `INSTALL.md` y los comandos de verificación. - [ ] Valorar soporte multiidioma (`--lang es|en`) en plantillas y script. -- [ ] Publicar etiquetas de versión (`v0.2.0`, …) para poder fijar la versión - con `pi install git:...@`. +- [ ] Valorar automatizar la publicación con Gitea Actions al subir una + etiqueta `v*` (requiere runner y un token con escritura en `-dist`). - [ ] Valorar publicarlo también en npm (galería de paquetes de pi). - [ ] Prueba automática del script (golden test de los ficheros generados). ## Hecho +- [x] 2026-10-18 — publicada `v0.3.0` en `pi-new-project-dist`. +- [x] 2026-10-18 — repositorio de distribución `pi-new-project-dist` y script + `scripts/publicar-dist.sh`. - [x] 2026-10-18 — licencia MIT (`LICENSE`). - [x] 2026-10-18 — paquete publicado en git () e instalación con diff --git a/package.json b/package.json index 7aac93e..7f47f7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pi-new-project", - "version": "0.2.0", + "version": "0.3.0", "private": true, "license": "MIT", "description": "Paquete de pi con la skill new-project (base documental de un proyecto) y la orden /modelo-proyecto (modelo por defecto del proyecto).", diff --git a/scripts/publicar-dist.sh b/scripts/publicar-dist.sh new file mode 100755 index 0000000..8f4effc --- /dev/null +++ b/scripts/publicar-dist.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# publicar-dist.sh — publica en el repositorio de distribución +# (pi-new-project-dist) solo los ficheros que necesita pi para usar el paquete. +# +# Toma el contenido del commit actual (HEAD), no del directorio de trabajo. +# Cada publicación añade un commit y una etiqueta vX.Y.Z (versión de +# package.json) en el repositorio de distribución. +set -euo pipefail + +REMOTO_DEF="https://git.sargatxet.cloud/sargatxet/pi-new-project-dist.git" +DESARROLLO="https://git.sargatxet.cloud/sargatxet/pi-new-project" +INSTALAR="git:git.sargatxet.cloud/sargatxet/pi-new-project-dist" +# Lo único que se publica (README.md se genera aparte). +RUTAS=(package.json LICENSE extensions skills) + +uso() { + cat <&2; exit 1; } +info() { printf '%s\n' "$*"; } + +DRY_RUN=0 +REMOTO="$REMOTO_DEF" +while [[ $# -gt 0 ]]; do + case "$1" in + -n|--dry-run) DRY_RUN=1 ;; + -r|--remoto) [[ $# -ge 2 ]] || die "falta el valor de $1"; REMOTO="$2"; shift ;; + -h|--help) uso; exit 0 ;; + *) die "opción desconocida: $1 (usa --help)" ;; + esac + shift +done + +RAIZ="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)" || die "no estoy dentro del repositorio" +cd "$RAIZ" + +# 1. Comprobaciones +[[ -z "$(git status --porcelain -- "${RUTAS[@]}")" ]] \ + || die "hay cambios sin commitear en: ${RUTAS[*]}" +VERSION="$(sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)".*/\1/p' package.json | head -n1)" +[[ -n "$VERSION" ]] || die "no encuentro la versión en package.json" +ETIQUETA="v$VERSION" +ORIGEN="$(git rev-parse --short HEAD)" +if [[ -n "$(git ls-remote --tags "$REMOTO" "refs/tags/$ETIQUETA")" ]]; then + die "$ETIQUETA ya está publicada en $REMOTO; sube la versión en package.json" +fi +if git rev-parse -q --verify '@{u}' >/dev/null && [[ -n "$(git log --oneline '@{u}..HEAD')" ]]; then + info "aviso: HEAD ($ORIGEN) tiene commits sin subir al repositorio de desarrollo" +fi + +# 2. Preparar el contenido sobre el último estado del repositorio de distribución +TMP="$(mktemp -d)" +if [[ $DRY_RUN -eq 0 ]]; then trap 'rm -rf "$TMP"' EXIT; fi +DIST="$TMP/dist" +git clone -q "$REMOTO" "$DIST" 2>/dev/null || die "no puedo clonar $REMOTO" +if ! git -C "$DIST" rev-parse -q --verify HEAD >/dev/null; then + git -C "$DIST" symbolic-ref HEAD refs/heads/main # repositorio vacío +fi +find "$DIST" -mindepth 1 -maxdepth 1 ! -name .git -exec rm -rf {} + +git archive HEAD "${RUTAS[@]}" | tar -x -C "$DIST" + +cat >"$DIST/README.md" < + +> Repositorio generado automáticamente desde $DESARROLLO +> (commit \`$ORIGEN\`). No hagas cambios aquí: se perderán en la próxima publicación. + +Licencia MIT, ver [\`LICENSE\`](LICENSE). +EOF + +git -C "$DIST" add -A +if git -C "$DIST" diff --cached --quiet; then + info "sin cambios respecto a la última publicación; no hay nada que publicar" + exit 0 +fi +git -C "$DIST" commit -q -m "release $ETIQUETA (origen $ORIGEN)" +git -C "$DIST" tag -a "$ETIQUETA" -m "pi-new-project $ETIQUETA (origen $ORIGEN)" + +info "contenido de $ETIQUETA:" +git -C "$DIST" ls-tree -r --name-only HEAD | sed 's/^/ /' + +# 3. Publicar +if [[ $DRY_RUN -eq 1 ]]; then + info "dry-run: no se ha subido nada; revisa $DIST" + exit 0 +fi +git -C "$DIST" push -q origin HEAD:refs/heads/main "refs/tags/$ETIQUETA" +info "publicado $ETIQUETA en $REMOTO" +info "instalar: pi install $INSTALAR"