Compare commits
5
Commits
f6d2870635
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fd367d00e | ||
|
|
c00f020056 | ||
|
|
0a6b2af1d7 | ||
|
|
3911d71529 | ||
|
|
bab0d93dd2 |
No files matched your search
+29
@@ -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.*
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"defaultProvider": "github-copilot",
|
||||||
|
"defaultModel": "claude-opus-5.5"
|
||||||
|
}
|
||||||
@@ -12,6 +12,40 @@ y el proyecto usa [Versionado Semántico](https://semver.org/lang/es/).
|
|||||||
- Fijar las reglas de modelo y de funcionamiento que la skill escribirá en el
|
- Fijar las reglas de modelo y de funcionamiento que la skill escribirá en el
|
||||||
`AGENTS.md` de cada proyecto generado (hoy quedan como `PENDIENTE`).
|
`AGENTS.md` de cada proyecto generado (hoy quedan como `PENDIENTE`).
|
||||||
|
|
||||||
|
## [0.3.1] - 2026-10-18
|
||||||
|
|
||||||
|
### Añadido
|
||||||
|
|
||||||
|
- Campos `author` y `bugs` en `package.json` (también en `pi-new-project-dist`).
|
||||||
|
|
||||||
|
## [0.3.0] - 2026-10-18
|
||||||
|
|
||||||
|
### Añadido
|
||||||
|
|
||||||
|
- Repositorio de distribución
|
||||||
|
<https://git.sargatxet.cloud/sargatxet/pi-new-project-dist> 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
|
||||||
|
<https://git.sargatxet.cloud/sargatxet/pi-new-project>
|
||||||
|
(`pi install git:git.sargatxet.cloud/sargatxet/pi-new-project`) en
|
||||||
|
`README.md` e `INSTALL.md`, con actualización y desinstalación; campos
|
||||||
|
`homepage` y `repository` en `package.json`.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
## [0.2.0] - 2026-10-18
|
## [0.2.0] - 2026-10-18
|
||||||
|
|
||||||
### Añadido
|
### Añadido
|
||||||
|
|||||||
+71
-17
@@ -3,6 +3,13 @@
|
|||||||
Instalación del paquete/skill `new-project` en pi, en este ordenador o en
|
Instalación del paquete/skill `new-project` en pi, en este ordenador o en
|
||||||
cualquier otro.
|
cualquier otro.
|
||||||
|
|
||||||
|
Repositorios:
|
||||||
|
|
||||||
|
- **Distribución** (para usarlo): <https://git.sargatxet.cloud/sargatxet/pi-new-project-dist>.
|
||||||
|
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): <https://git.sargatxet.cloud/sargatxet/pi-new-project>.
|
||||||
|
|
||||||
## 1. Requisitos
|
## 1. Requisitos
|
||||||
|
|
||||||
| Componente | Versión mínima | Notas |
|
| Componente | Versión mínima | Notas |
|
||||||
@@ -12,23 +19,42 @@ cualquier otro.
|
|||||||
| git | cualquiera | Opcional: `--git` y autor por defecto. |
|
| git | cualquiera | Opcional: `--git` y autor por defecto. |
|
||||||
| shellcheck | opcional | Para validar el script (`shellcheck new-project.sh`). |
|
| shellcheck | opcional | Para validar el script (`shellcheck new-project.sh`). |
|
||||||
|
|
||||||
## 2. Opción A — instalarlo como paquete de pi (recomendado)
|
## 2. Opción A — instalarlo como paquete de pi desde git (recomendado)
|
||||||
|
|
||||||
Desde el directorio que contiene `pi-new-project/`:
|
pi clona el repositorio de distribución y lo instala directamente:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pi install ./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-dist
|
||||||
```
|
```
|
||||||
|
|
||||||
O desde git/npm cuando se publique:
|
Para fijar una versión concreta, añade una etiqueta (`v0.3.1`, …) o un commit:
|
||||||
|
`pi install git:git.sargatxet.cloud/sargatxet/pi-new-project-dist@<etiqueta-o-commit>`.
|
||||||
```bash
|
Añade `-l` (`--local`) para declararlo solo en el proyecto actual
|
||||||
pi install git:github.com/<usuario>/pi-new-project@v0.1.0
|
(`.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
|
Comprueba con `pi list` y arranca pi: la skill aparecerá como `new-project` y
|
||||||
estará disponible la orden `/modelo-proyecto`.
|
estará disponible la orden `/modelo-proyecto`.
|
||||||
Para una prueba puntual sin instalarlo: `pi -e ./pi-new-project`.
|
Para una prueba puntual sin instalarlo:
|
||||||
|
`pi -e git:git.sargatxet.cloud/sargatxet/pi-new-project-dist`.
|
||||||
|
|
||||||
|
> 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.
|
||||||
|
|
||||||
|
### 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
|
||||||
|
pi install ./pi-new-project
|
||||||
|
```
|
||||||
|
|
||||||
|
Una instalación local se carga desde ese directorio sin copiarlo: los cambios
|
||||||
|
(o un `git pull`) se aplican en la siguiente sesión de pi.
|
||||||
|
|
||||||
## 3. Opción B — copiar la skill
|
## 3. Opción B — copiar la skill
|
||||||
|
|
||||||
@@ -47,6 +73,10 @@ ln -s "$PWD/pi-new-project/skills/new-project" ~/.agents/skills/new-project
|
|||||||
|
|
||||||
Rutas equivalentes: `~/.pi/agent/skills/` y, por proyecto, `.agents/skills/`.
|
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-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
|
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,
|
`elegir_modelo_proyecto`; cópialas también (o la skill usará el plan B,
|
||||||
`pi --list-models` + `--modelo`):
|
`pi --list-models` + `--modelo`):
|
||||||
@@ -56,20 +86,22 @@ mkdir -p ~/.pi/agent/extensions
|
|||||||
cp pi-new-project/extensions/modelo-proyecto.ts ~/.pi/agent/extensions/
|
cp pi-new-project/extensions/modelo-proyecto.ts ~/.pi/agent/extensions/
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. Opción C — exportar a otro ordenador
|
## 4. Opción C — exportar a otro ordenador sin acceso al repositorio
|
||||||
|
|
||||||
No hay más que copiar el directorio; no tiene dependencias.
|
Si el ordenador destino tiene acceso a
|
||||||
|
<https://git.sargatxet.cloud/sargatxet/pi-new-project-dist>, 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
|
```bash
|
||||||
# en el ordenador origen
|
# en el ordenador origen
|
||||||
tar -czf pi-new-project-0.1.0.tar.gz pi-new-project/
|
tar -czf pi-new-project-0.3.1.tar.gz pi-new-project/
|
||||||
|
|
||||||
# en el ordenador destino
|
# en el ordenador destino
|
||||||
tar -xzf pi-new-project-0.1.0.tar.gz
|
tar -xzf pi-new-project-0.3.1.tar.gz
|
||||||
pi install ./pi-new-project # o la opción B
|
pi install ./pi-new-project # o la opción B
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternativa sin `tar`: publicar el repositorio y usar `pi install <url-de-git>`.
|
|
||||||
|
|
||||||
## 5. Verificación
|
## 5. Verificación
|
||||||
|
|
||||||
@@ -100,20 +132,42 @@ modelos y actualizar `.pi/settings.json`.
|
|||||||
## 6. Actualización
|
## 6. Actualización
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git pull
|
pi update --extensions # instalado desde git: actualiza el clon gestionado por pi
|
||||||
pi update --extensions # si se instaló como paquete
|
|
||||||
|
# instalado desde una copia local o copiado (opción B):
|
||||||
|
cd pi-new-project && git pull
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Si se instaló con una etiqueta o un commit fijo (`@<ref>`), `pi update` no lo
|
||||||
|
mueve: reinstala con la nueva referencia.
|
||||||
|
|
||||||
## 7. Desinstalación
|
## 7. Desinstalación
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pi remove ./pi-new-project # si se instaló como paquete
|
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 -rf ~/.agents/skills/new-project # si se copió o enlazó
|
||||||
rm -f ~/.pi/agent/extensions/modelo-proyecto.ts
|
rm -f ~/.pi/agent/extensions/modelo-proyecto.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
La skill no deja estado propio: no hay caché ni configuración que limpiar.
|
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
|
## 8. Resolución de problemas
|
||||||
|
|
||||||
| Síntoma | Causa probable | Solución |
|
| Síntoma | Causa probable | Solución |
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Toni Ramiro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -16,6 +16,9 @@ pi-new-project/
|
|||||||
├── INSTALL.md # instalación en otro ordenador
|
├── INSTALL.md # instalación en otro ordenador
|
||||||
├── CHANGELOG.md
|
├── CHANGELOG.md
|
||||||
├── TODO.md
|
├── TODO.md
|
||||||
|
├── LICENSE # licencia MIT
|
||||||
|
├── scripts/
|
||||||
|
│ └── publicar-dist.sh # publica la versión instalable en pi-new-project-dist
|
||||||
├── extensions/
|
├── extensions/
|
||||||
│ └── modelo-proyecto.ts # orden /modelo-proyecto y herramienta elegir_modelo_proyecto
|
│ └── modelo-proyecto.ts # orden /modelo-proyecto y herramienta elegir_modelo_proyecto
|
||||||
└── skills/
|
└── skills/
|
||||||
@@ -64,10 +67,28 @@ El script nunca sobreescribe ficheros existentes salvo con `--force`, y admite
|
|||||||
|
|
||||||
## Instalación
|
## Instalación
|
||||||
|
|
||||||
Ver [`INSTALL.md`](INSTALL.md). Resumen: copia (o enlaza) el directorio en
|
Para usarlo, instala la **versión de distribución**
|
||||||
`~/.pi/agent/skills/` o instálalo como paquete con `pi install ./pi-new-project`.
|
(<https://git.sargatxet.cloud/sargatxet/pi-new-project-dist>), que contiene solo
|
||||||
La orden `/modelo-proyecto` solo está disponible al instalarlo como paquete (o
|
los ficheros que necesita pi (`package.json`, `LICENSE`, `extensions/` y `skills/`):
|
||||||
copiando también `extensions/`).
|
|
||||||
|
```bash
|
||||||
|
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.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Este repositorio (<https://git.sargatxet.cloud/sargatxet/pi-new-project>) 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
|
||||||
|
pi install ./pi-new-project
|
||||||
|
```
|
||||||
|
|
||||||
|
Ver [`INSTALL.md`](INSTALL.md) para el resto de opciones (copiar solo la skill,
|
||||||
|
exportar sin acceso al repositorio, actualizar y desinstalar). La orden
|
||||||
|
`/modelo-proyecto` solo está disponible al instalarlo como paquete (o copiando
|
||||||
|
también `extensions/`).
|
||||||
|
|
||||||
## Requisitos
|
## Requisitos
|
||||||
|
|
||||||
@@ -75,3 +96,7 @@ copiando también `extensions/`).
|
|||||||
- `bash` 4+ y `git` (opcional, solo para `--git` y el autor por defecto).
|
- `bash` 4+ y `git` (opcional, solo para `--git` y el autor por defecto).
|
||||||
- El script no usa Python, Node ni dependencias externas: es `bash` con
|
- El script no usa Python, Node ni dependencias externas: es `bash` con
|
||||||
biblioteca estándar.
|
biblioteca estándar.
|
||||||
|
|
||||||
|
## Licencia
|
||||||
|
|
||||||
|
Distribuido bajo la licencia MIT. Ver [`LICENSE`](LICENSE).
|
||||||
@@ -15,11 +15,20 @@
|
|||||||
- [ ] Detectar y completar el stack automáticamente (¿`--stack python|node|rust`?)
|
- [ ] Detectar y completar el stack automáticamente (¿`--stack python|node|rust`?)
|
||||||
para prellenar `INSTALL.md` y los comandos de verificación.
|
para prellenar `INSTALL.md` y los comandos de verificación.
|
||||||
- [ ] Valorar soporte multiidioma (`--lang es|en`) en plantillas y script.
|
- [ ] Valorar soporte multiidioma (`--lang es|en`) en plantillas y script.
|
||||||
- [ ] Publicar el paquete (git o npm) para instalarlo con `pi install <url>`.
|
- [ ] 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).
|
- [ ] Prueba automática del script (golden test de los ficheros generados).
|
||||||
|
|
||||||
## Hecho
|
## 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
|
||||||
|
(<https://git.sargatxet.cloud/sargatxet/pi-new-project>) e instalación con
|
||||||
|
`pi install` documentada.
|
||||||
- [x] 2026-10-18 — modelo por defecto por proyecto: selector al crear y orden
|
- [x] 2026-10-18 — modelo por defecto por proyecto: selector al crear y orden
|
||||||
`/modelo-proyecto` para cambiarlo.
|
`/modelo-proyecto` para cambiarlo.
|
||||||
- [x] 2026-10-18 — estructura del paquete, skill, script y plantillas.
|
- [x] 2026-10-18 — estructura del paquete, skill, script y plantillas.
|
||||||
|
|||||||
@@ -16,9 +16,13 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
|
|||||||
import { join, resolve } from "node:path";
|
import { join, resolve } from "node:path";
|
||||||
import type { Api, Model } from "@earendil-works/pi-ai";
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
||||||
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
|
||||||
import { Type } from "typebox";
|
import { Type } from "typebox";
|
||||||
|
|
||||||
const SETTINGS_REL = join(".pi", "settings.json");
|
const SETTINGS_REL = join(".pi", "settings.json");
|
||||||
|
/** Máximo de modelos visibles a la vez en el selector (la lista se desplaza). */
|
||||||
|
const MAX_VISIBLES = 15;
|
||||||
|
|
||||||
function clave(m: Model<Api>): string {
|
function clave(m: Model<Api>): string {
|
||||||
return `${m.provider}/${m.id}`;
|
return `${m.provider}/${m.id}`;
|
||||||
@@ -88,10 +92,51 @@ async function elegir(ctx: ExtensionContext, proyecto: string): Promise<Model<Ap
|
|||||||
const lista = disponibles(ctx);
|
const lista = disponibles(ctx);
|
||||||
if (lista.length === 0) throw new Error("no hay modelos disponibles (¿falta /login o credenciales?)");
|
if (lista.length === 0) throw new Error("no hay modelos disponibles (¿falta /login o credenciales?)");
|
||||||
const actual = modeloDelProyecto(proyecto);
|
const actual = modeloDelProyecto(proyecto);
|
||||||
const opciones = lista.map((m) => etiqueta(m, actual));
|
const titulo = `Modelo por defecto del proyecto (${proyecto})`;
|
||||||
const elegido = await ctx.ui.select(`Modelo por defecto del proyecto (${proyecto})`, opciones);
|
|
||||||
if (!elegido) return undefined;
|
// Fuera de la TUI (p. ej. RPC) no hay componentes propios: diálogo estándar.
|
||||||
return lista[opciones.indexOf(elegido)];
|
if (ctx.mode !== "tui") {
|
||||||
|
const opciones = lista.map((m) => etiqueta(m, actual));
|
||||||
|
const elegido = await ctx.ui.select(titulo, opciones);
|
||||||
|
if (!elegido) return undefined;
|
||||||
|
return lista[opciones.indexOf(elegido)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: SelectItem[] = lista.map((m) => ({ value: clave(m), label: etiqueta(m, actual) }));
|
||||||
|
const valor = await ctx.ui.custom<string | null>((tui, theme, _kb, done) => {
|
||||||
|
const contenedor = new Container();
|
||||||
|
contenedor.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
|
||||||
|
contenedor.addChild(new Text(theme.fg("accent", theme.bold(titulo))));
|
||||||
|
|
||||||
|
// Ventana de MAX_VISIBLES elementos que se desplaza con el cursor;
|
||||||
|
// ↑ en el primero salta al último y ↓ en el último vuelve al primero.
|
||||||
|
const selector = new SelectList(items, Math.min(items.length, MAX_VISIBLES), {
|
||||||
|
selectedPrefix: (t) => theme.fg("accent", t),
|
||||||
|
selectedText: (t) => theme.fg("accent", t),
|
||||||
|
description: (t) => theme.fg("muted", t),
|
||||||
|
scrollInfo: (t) => theme.fg("dim", t),
|
||||||
|
noMatch: (t) => theme.fg("warning", t),
|
||||||
|
});
|
||||||
|
const inicial = actual ? items.findIndex((i) => i.value === actual) : -1;
|
||||||
|
if (inicial >= 0) selector.setSelectedIndex(inicial);
|
||||||
|
selector.onSelect = (item) => done(item.value);
|
||||||
|
selector.onCancel = () => done(null);
|
||||||
|
contenedor.addChild(selector);
|
||||||
|
|
||||||
|
contenedor.addChild(new Text(theme.fg("dim", "↑↓ moverse • enter elegir • esc cancelar")));
|
||||||
|
contenedor.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
|
||||||
|
|
||||||
|
return {
|
||||||
|
render: (width: number) => contenedor.render(width),
|
||||||
|
invalidate: () => contenedor.invalidate(),
|
||||||
|
handleInput: (data: string) => {
|
||||||
|
selector.handleInput(data);
|
||||||
|
tui.requestRender();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (!valor) return undefined;
|
||||||
|
return lista.find((m) => clave(m) === valor);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (pi: ExtensionAPI) {
|
export default function (pi: ExtensionAPI) {
|
||||||
|
|||||||
+11
-1
@@ -1,8 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "pi-new-project",
|
"name": "pi-new-project",
|
||||||
"version": "0.2.0",
|
"version": "0.3.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Toni Ramiro <sargatxet@gmail.com>",
|
||||||
"description": "Paquete de pi con la skill new-project (base documental de un proyecto) y la orden /modelo-proyecto (modelo por defecto del proyecto).",
|
"description": "Paquete de pi con la skill new-project (base documental de un proyecto) y la orden /modelo-proyecto (modelo por defecto del proyecto).",
|
||||||
|
"homepage": "https://git.sargatxet.cloud/sargatxet/pi-new-project",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://git.sargatxet.cloud/sargatxet/pi-new-project.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://git.sargatxet.cloud/sargatxet/pi-new-project/issues"
|
||||||
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"pi-package"
|
"pi-package"
|
||||||
],
|
],
|
||||||
|
|||||||
Executable
+110
@@ -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 <<EOF
|
||||||
|
Uso: $(basename "$0") [opciones]
|
||||||
|
|
||||||
|
Publica en el repositorio de distribución los ficheros necesarios para usar
|
||||||
|
el paquete: ${RUTAS[*]} y un README.md mínimo.
|
||||||
|
|
||||||
|
-n, --dry-run Prepara la publicación sin subir nada y muestra el contenido.
|
||||||
|
-r, --remoto URL Repositorio de distribución (por defecto: $REMOTO_DEF).
|
||||||
|
-h, --help Muestra esta ayuda.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
die() { printf 'error: %s\n' "$*" >&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" <<EOF
|
||||||
|
# pi-new-project (distribución)
|
||||||
|
|
||||||
|
Versión instalable de **pi-new-project** $ETIQUETA: solo los ficheros que pi
|
||||||
|
necesita para usar el paquete (skill \`new-project\` y orden \`/modelo-proyecto\`).
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
pi install $INSTALAR
|
||||||
|
# versión fija:
|
||||||
|
pi install $INSTALAR@$ETIQUETA
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Documentación, cambios e incidencias: <$DESARROLLO>
|
||||||
|
|
||||||
|
> 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"
|
||||||
Reference in new issue
Block a user