Compare commits
2
Commits
f6d2870635
...
3911d71529
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3911d71529 | ||
|
|
bab0d93dd2 |
No files matched your search
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"defaultProvider": "github-copilot",
|
||||
"defaultModel": "claude-opus-5.5"
|
||||
}
|
||||
@@ -7,6 +7,17 @@ y el proyecto usa [Versionado Semántico](https://semver.org/lang/es/).
|
||||
|
||||
## [No publicado]
|
||||
|
||||
### Añadido
|
||||
|
||||
- Licencia MIT: fichero `LICENSE` y campo `license` en `package.json`.
|
||||
|
||||
### Cambiado
|
||||
|
||||
- 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
|
||||
|
||||
@@ -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,7 @@ pi-new-project/
|
||||
├── INSTALL.md # instalación en otro ordenador
|
||||
├── CHANGELOG.md
|
||||
├── TODO.md
|
||||
├── LICENSE # licencia MIT
|
||||
├── extensions/
|
||||
│ └── modelo-proyecto.ts # orden /modelo-proyecto y herramienta elegir_modelo_proyecto
|
||||
└── skills/
|
||||
@@ -75,3 +76,7 @@ copiando también `extensions/`).
|
||||
- `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
|
||||
biblioteca estándar.
|
||||
|
||||
## Licencia
|
||||
|
||||
Distribuido bajo la licencia MIT. Ver [`LICENSE`](LICENSE).
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
## Hecho
|
||||
|
||||
- [x] 2026-10-18 — licencia MIT (`LICENSE`).
|
||||
- [x] 2026-10-18 — modelo por defecto por proyecto: selector al crear y orden
|
||||
`/modelo-proyecto` para cambiarlo.
|
||||
- [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 type { Api, Model } from "@earendil-works/pi-ai";
|
||||
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";
|
||||
|
||||
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 {
|
||||
return `${m.provider}/${m.id}`;
|
||||
@@ -88,10 +92,51 @@ async function elegir(ctx: ExtensionContext, proyecto: string): Promise<Model<Ap
|
||||
const lista = disponibles(ctx);
|
||||
if (lista.length === 0) throw new Error("no hay modelos disponibles (¿falta /login o credenciales?)");
|
||||
const actual = modeloDelProyecto(proyecto);
|
||||
const opciones = lista.map((m) => etiqueta(m, actual));
|
||||
const elegido = await ctx.ui.select(`Modelo por defecto del proyecto (${proyecto})`, opciones);
|
||||
if (!elegido) return undefined;
|
||||
return lista[opciones.indexOf(elegido)];
|
||||
const titulo = `Modelo por defecto del proyecto (${proyecto})`;
|
||||
|
||||
// Fuera de la TUI (p. ej. RPC) no hay componentes propios: diálogo estándar.
|
||||
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) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "pi-new-project",
|
||||
"version": "0.2.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).",
|
||||
"keywords": [
|
||||
"pi-package"
|
||||
|
||||
Reference in new issue
Block a user