vipcode 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/app.js +12 -2
- package/dist/tui/app.js +19 -10
- package/dist/tui/dialogs.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ vipcode trust # confiar en la configuración que trae esta carpet
|
|
|
118
118
|
- **Con npm** (`npm install -g vipcode` o el paquete de la release): mira cuál es la última versión publicada en npm y en GitHub y, si es más nueva que la tuya, la instala.
|
|
119
119
|
- **Desde el código** (`git clone` + `npm link`): trae lo último del repositorio con `git pull`, instala las dependencias y compila. Si tienes cambios sin guardar en esa carpeta, no toca nada y te avisa.
|
|
120
120
|
|
|
121
|
-
Después cierra vipcode y vuelve a abrirlo. Además, una vez al día vipcode mira si hay una versión nueva y te avisa al abrirlo; se desactiva con `"checkUpdates": false` en la configuración.
|
|
121
|
+
Después cierra vipcode y vuelve a abrirlo. Además, una vez al día vipcode mira si hay una versión nueva y te avisa al abrirlo con un recuadro verde, y te lo recuerda en la barra de abajo hasta que actualizas; se desactiva con `"checkUpdates": false` en la configuración.
|
|
122
122
|
|
|
123
123
|
### En la interfaz
|
|
124
124
|
|
package/dist/app.js
CHANGED
|
@@ -127,6 +127,10 @@ export class App {
|
|
|
127
127
|
yolo = false;
|
|
128
128
|
local = {};
|
|
129
129
|
lastSessions = [];
|
|
130
|
+
// Versión nueva de vipcode publicada: la interfaz la recuerda abajo hasta que la instalas con /update
|
|
131
|
+
newVersion = null;
|
|
132
|
+
// /update ya la ha instalado: se usa al cerrar y volver a abrir vipcode
|
|
133
|
+
updateInstalled = false;
|
|
130
134
|
// La interfaz pone aquí cómo preguntar los permisos
|
|
131
135
|
promptPermission = async () => ({
|
|
132
136
|
allow: false,
|
|
@@ -206,7 +210,11 @@ export class App {
|
|
|
206
210
|
}
|
|
207
211
|
privacyNotice() {
|
|
208
212
|
const names = [...new Set(this.router.slots.filter((slot) => slot.anonymous).map((slot) => (slot.provider.label || slot.provider.name).replace(/ \(sin clave\)$/, "")))];
|
|
209
|
-
return
|
|
213
|
+
return [
|
|
214
|
+
`Para que puedas empezar ya mismo, vipcode usa IAs gratuitas que no piden registro (${names.join(", ")}).`,
|
|
215
|
+
"Como son gratis, pueden guardar lo que les escribes para mejorar sus modelos, así que mejor no compartas contraseñas, claves ni datos privados.",
|
|
216
|
+
"Cuando quieras, conecta una cuenta gratuita con /connect y tendrás más mensajes y más modelos.",
|
|
217
|
+
].join("\n");
|
|
210
218
|
}
|
|
211
219
|
acceptPrivacyNotice() {
|
|
212
220
|
let data = {};
|
|
@@ -303,7 +311,7 @@ export class App {
|
|
|
303
311
|
}
|
|
304
312
|
anonymousNotice() {
|
|
305
313
|
const names = [...new Set(this.router.slots.map((slot) => (slot.provider.label || slot.provider.name).replace(/ \(sin clave\)/, "")))];
|
|
306
|
-
return `
|
|
314
|
+
return `Estás usando IAs gratuitas sin registro (${names.join(", ")}). Consejo: conecta una cuenta gratuita con /connect para tener más mensajes y más modelos (y recuerda no compartir datos privados).`;
|
|
307
315
|
}
|
|
308
316
|
// Siguiente agente principal (Tab)
|
|
309
317
|
cycleAgent(direction = 1) {
|
|
@@ -913,6 +921,8 @@ export class App {
|
|
|
913
921
|
}
|
|
914
922
|
else {
|
|
915
923
|
ui.info(result.message);
|
|
924
|
+
this.newVersion = null;
|
|
925
|
+
this.updateInstalled ||= result.status === "updated";
|
|
916
926
|
}
|
|
917
927
|
return {};
|
|
918
928
|
}
|
package/dist/tui/app.js
CHANGED
|
@@ -200,6 +200,8 @@ function ItemView(props) {
|
|
|
200
200
|
const shown = lines.slice(-30);
|
|
201
201
|
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsxs(Text, { color: "yellow", bold: true, children: ["$", " "] }), _jsx(Text, { bold: true, children: showControl(item.command) })] }), lines.length > shown.length ? _jsxs(Text, { dimColor: true, children: [" \u2026 ", lines.length - shown.length, " l\u00EDneas antes"] }) : null, shown.length > 0 ? _jsx(Text, { children: shown.map((line) => ` ${line}`).join("\n") }) : null, _jsxs(Text, { dimColor: true, children: [" ", item.code === 0 ? "✓" : "✗", " c\u00F3digo ", item.code ?? "?", " \u00B7 el agente ver\u00E1 la salida con tu siguiente mensaje"] })] }));
|
|
202
202
|
}
|
|
203
|
+
case "update":
|
|
204
|
+
return (_jsxs(Box, { marginY: 1, alignSelf: "flex-start", flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 2, children: [_jsx(Text, { bold: true, color: "green", children: "\u2191 \u00A1Hay una versi\u00F3n nueva de vipcode!" }), _jsxs(Text, { children: [VERSION, " \u2192 ", _jsx(Text, { bold: true, color: "green", children: stripControl(item.version) }), " \u00B7 escribe", " ", _jsx(Text, { bold: true, color: "cyan", children: "/update" }), " ", "para instalarla"] })] }));
|
|
203
205
|
// Avisos y bloques pueden llevar mensajes de los proveedores o datos de fuera: solo se dejan los colores
|
|
204
206
|
case "info":
|
|
205
207
|
return _jsx(Text, { dimColor: true, children: stripUnsafe(item.text) });
|
|
@@ -275,11 +277,17 @@ function StatusBar(props) {
|
|
|
275
277
|
const usage = app.agent.session.usage;
|
|
276
278
|
const spent = usage.prompt + usage.completion;
|
|
277
279
|
const queued = app.agent.queue.length;
|
|
278
|
-
let hint = "ctrl+p comandos
|
|
280
|
+
let hint = _jsx(Text, { dimColor: true, children: "ctrl+p comandos \u00B7 /help" });
|
|
279
281
|
if (props.busy) {
|
|
280
|
-
hint = "esc interrumpe
|
|
282
|
+
hint = _jsx(Text, { dimColor: true, children: "esc interrumpe \u00B7 escribe para a\u00F1adir instrucciones" });
|
|
281
283
|
}
|
|
282
|
-
|
|
284
|
+
else if (app.updateInstalled) {
|
|
285
|
+
hint = _jsx(Text, { color: "green", children: "\u2713 vipcode actualizado \u00B7 ci\u00E9rralo y vuelve a abrirlo para usarlo" });
|
|
286
|
+
}
|
|
287
|
+
else if (app.newVersion) {
|
|
288
|
+
hint = (_jsxs(Text, { bold: true, color: "green", children: ["\u2191 vipcode ", stripControl(app.newVersion), " disponible \u00B7 escribe /update"] }));
|
|
289
|
+
}
|
|
290
|
+
return (_jsxs(Box, { justifyContent: "space-between", paddingX: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { bold: true, color: agent?.color || "magenta", children: props.agentName }), _jsxs(Text, { dimColor: true, children: [" ", "\u00B7 ", current || "rotación automática", slot && slot.score !== null ? ` ★${slot.score}` : "", app.router.pinned ? " (fijado)" : ""] }), _jsx(ContextGauge, { used: app.agent.lastTokens, total: context }), _jsxs(Text, { dimColor: true, children: [" ", "\u00B7 ", available, "/", app.router.slots.length, " modelos", spent > 0 ? ` · ${shortTokens(spent)} tokens` : "", queued > 0 ? ` · ${queued} en cola` : ""] }), app.yolo ? _jsx(Text, { color: "red", children: " \u00B7 yolo" }) : null] }), _jsx(Text, { wrap: "truncate-start", children: hint })] }));
|
|
283
291
|
}
|
|
284
292
|
function Main(props) {
|
|
285
293
|
const { app } = props;
|
|
@@ -513,10 +521,10 @@ function Main(props) {
|
|
|
513
521
|
};
|
|
514
522
|
// La primera vez que se van a usar proveedores sin clave, explicamos qué pasa con lo que envías
|
|
515
523
|
const askPrivacy = async () => {
|
|
516
|
-
const choice = await adapter.select(
|
|
517
|
-
{ label: "
|
|
518
|
-
{ label: "
|
|
519
|
-
{ label: "
|
|
524
|
+
const choice = await adapter.select(`¡Te damos la bienvenida a vipcode!\n${app.privacyNotice()}`, [
|
|
525
|
+
{ label: "Empezar", description: "con las IAs gratuitas sin registro", value: "ok" },
|
|
526
|
+
{ label: "Conectar antes una cuenta gratuita", description: "para tener más mensajes y más modelos", value: "connect" },
|
|
527
|
+
{ label: "Prefiero usar solo mis cuentas", description: "y no las IAs sin registro", value: "off" },
|
|
520
528
|
]);
|
|
521
529
|
if (!choice) {
|
|
522
530
|
// Con Esc se vuelve a preguntar la próxima vez
|
|
@@ -528,7 +536,7 @@ function Main(props) {
|
|
|
528
536
|
}
|
|
529
537
|
else if (choice === "off") {
|
|
530
538
|
app.disableKeyless();
|
|
531
|
-
push({ kind: "info", text:
|
|
539
|
+
push({ kind: "info", text: 'Hecho: solo usaré las cuentas que conectes. Si cambias de idea, pon "keyless": true en tu configuración (/config te dice dónde está).' });
|
|
532
540
|
if (app.router.slots.length === 0) {
|
|
533
541
|
await app.connect(adapter, "");
|
|
534
542
|
}
|
|
@@ -683,7 +691,7 @@ function Main(props) {
|
|
|
683
691
|
if (app.router.slots.length === 0) {
|
|
684
692
|
push({
|
|
685
693
|
kind: "notice",
|
|
686
|
-
text: "
|
|
694
|
+
text: "Para empezar, conecta una IA gratuita: elige una de la lista y sigue los pasos (puedes repetirlo cuando quieras con /connect).",
|
|
687
695
|
});
|
|
688
696
|
void app.connect(adapter, "").then(refresh);
|
|
689
697
|
}
|
|
@@ -705,7 +713,8 @@ function Main(props) {
|
|
|
705
713
|
if (app.config.checkUpdates !== false) {
|
|
706
714
|
void checkForUpdate().then((version) => {
|
|
707
715
|
if (version) {
|
|
708
|
-
|
|
716
|
+
app.newVersion = version;
|
|
717
|
+
push({ kind: "update", version });
|
|
709
718
|
}
|
|
710
719
|
});
|
|
711
720
|
}
|
package/dist/tui/dialogs.js
CHANGED
|
@@ -154,7 +154,9 @@ export function SelectDialog(props) {
|
|
|
154
154
|
const windowSize = 12;
|
|
155
155
|
const start = Math.max(0, Math.min(selected - Math.floor(windowSize / 2), filtered.length - windowSize));
|
|
156
156
|
const visible = filtered.slice(start, start + windowSize);
|
|
157
|
-
|
|
157
|
+
// La primera línea del título va destacada; las siguientes, si las hay, explican la pregunta
|
|
158
|
+
const [heading, ...body] = props.title.split("\n");
|
|
159
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: heading }), body.length > 0 ? (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: body.join("\n") }) })) : null, _jsx(Text, { dimColor: true, children: filter ? `Filtro: ${filter}` : "Escribe para filtrar · ↑↓ elegir · Enter aceptar · Esc salir" }), visible.length === 0 ? _jsx(Text, { dimColor: true, children: "(nada coincide)" }) : null, visible.map((item, index) => {
|
|
158
160
|
const active = start + index === selected;
|
|
159
161
|
return (_jsxs(Text, { color: active ? "cyan" : undefined, wrap: "truncate-end", children: [active ? "❯ " : " ", stripControl(item.label), item.description ? _jsxs(Text, { dimColor: true, children: [" ", stripControl(item.description)] }) : null] }, `${start + index}-${item.label}`));
|
|
160
162
|
}), filtered.length > windowSize ? (_jsxs(Text, { dimColor: true, children: [selected + 1, "/", filtered.length] })) : null] }));
|