@vascend/talos 0.1.3 → 0.1.5
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/LICENSE +22 -0
- package/README.md +49 -13
- package/dist/core/agent.js +58 -38
- package/dist/core/session-naming.d.ts +3 -0
- package/dist/core/session-naming.js +43 -0
- package/dist/core/session-usage.js +4 -1
- package/dist/core/session.d.ts +1 -0
- package/dist/core/session.js +9 -3
- package/dist/core/storage-health.d.ts +24 -0
- package/dist/core/storage-health.js +72 -0
- package/dist/core/types.d.ts +17 -0
- package/dist/tui/agent-sessions-screen.d.ts +25 -0
- package/dist/tui/agent-sessions-screen.js +132 -0
- package/dist/tui/agent-sessions.d.ts +39 -0
- package/dist/tui/agent-sessions.js +175 -0
- package/dist/tui/bottom-input.d.ts +11 -0
- package/dist/tui/bottom-input.js +106 -10
- package/dist/tui/commands.js +2 -1
- package/dist/tui/i18n-catalog.js +39 -1
- package/dist/tui/logo.js +3 -0
- package/dist/tui/model-picker.d.ts +2 -0
- package/dist/tui/model-picker.js +49 -0
- package/dist/tui/native-scrollback.d.ts +2 -1
- package/dist/tui/native-scrollback.js +26 -6
- package/dist/tui/prompt-queue-store.d.ts +1 -0
- package/dist/tui/prompt-queue-store.js +4 -0
- package/dist/tui/queued-questions.js +2 -4
- package/dist/tui/quick-help.d.ts +1 -1
- package/dist/tui/quick-help.js +3 -0
- package/dist/tui/repl.d.ts +3 -0
- package/dist/tui/repl.js +110 -24
- package/dist/tui/review-store.d.ts +7 -1
- package/dist/tui/review-store.js +36 -4
- package/dist/tui/scrollback-archive.d.ts +16 -0
- package/dist/tui/scrollback-archive.js +90 -0
- package/dist/tui/selector.d.ts +4 -0
- package/dist/tui/selector.js +9 -2
- package/dist/tui/session-naming-notice.d.ts +14 -0
- package/dist/tui/session-naming-notice.js +57 -0
- package/dist/tui/session-picker.d.ts +2 -0
- package/dist/tui/session-picker.js +32 -0
- package/dist/tui/storage-warning.d.ts +2 -0
- package/dist/tui/storage-warning.js +35 -0
- package/dist/vascend/context-feedback-loop.js +2 -0
- package/dist/vascend/context-snapshot.d.ts +1 -0
- package/dist/vascend/context-snapshot.js +4 -3
- package/dist/vascend/context-window-compiler.d.ts +1 -0
- package/dist/vascend/context-window-compiler.js +1 -0
- package/dist/vascend/granular-kingdom.js +32 -4
- package/dist/vascend/kingdom.js +4 -0
- package/dist/vascend/memory-store.d.ts +1 -0
- package/dist/vascend/memory-store.js +12 -4
- package/dist/vascend/room-memory.d.ts +3 -1
- package/dist/vascend/room-memory.js +6 -4
- package/package.json +2 -2
package/dist/tui/commands.js
CHANGED
|
@@ -24,7 +24,7 @@ export const BUILTIN_COMMANDS = [
|
|
|
24
24
|
{ name: "help", hint: "", get desc() { return tr("Sfoglia i comandi con frecce o mouse", "Browse commands with arrow keys or the mouse"); }, category: "sistema" },
|
|
25
25
|
{ name: "copy", hint: "[testo]", get desc() { return tr("Copia l’ultima risposta o il testo indicato", "Copy the last response or the specified text"); }, category: "interfaccia" },
|
|
26
26
|
{ name: "queue", hint: "", get desc() { return tr("Gestisci la coda · Alt+Q; da 3 richieste, Alt+T invia al team", "Manage queued messages; Alt+Q; Alt+T sends 3 or more requests to a team"); }, category: "interfaccia", aliases: ["coda"] },
|
|
27
|
-
{ name: "rename", hint: "
|
|
27
|
+
{ name: "rename", hint: "[titolo]", get desc() { return tr("Rinomina la chat: scegli se rigenerare dall'ultimo prompt o scrivere il titolo", "Rename the chat: regenerate from the latest prompt or enter a title"); }, category: "sessione" },
|
|
28
28
|
{ name: "commands", hint: "", get desc() { return tr("Cerca e apri tutti i comandi", "Search and open all commands"); }, category: "sistema", aliases: ["cmd"] },
|
|
29
29
|
{ name: "model", hint: "[prov/modello]", get desc() { return tr("Scegli o imposta il modello", "Choose or set the model"); }, category: "modello" },
|
|
30
30
|
{ name: "models", hint: "", get desc() { return tr("Esplora i modelli disponibili", "Browse available models"); }, category: "modello" },
|
|
@@ -39,6 +39,7 @@ export const BUILTIN_COMMANDS = [
|
|
|
39
39
|
{ name: "theme", hint: "[nome]", get desc() { return tr("Personalizza l'aspetto del terminale", "Customize terminal appearance"); }, category: "interfaccia", aliases: ["themes"] },
|
|
40
40
|
{ name: "language", hint: "[system|it|en|es|de]", get desc() { return tr("Scegli la lingua dell'interfaccia o segui il sistema", "Choose the interface language or follow the system"); }, category: "interfaccia", aliases: ["lang", "lingua", "idioma", "sprache"] },
|
|
41
41
|
{ name: "review", hint: "[attivita|modifiche|team|problemi]", get desc() { return tr("Esamina attività e modifiche · Ctrl+R", "Review tasks and changes; Ctrl+R"); }, category: "interfaccia", aliases: ["revisione"] },
|
|
42
|
+
{ name: "agents", hint: "", get desc() { return tr("Sessioni degli agenti · Alt+A", "Agent sessions; Alt+A"); }, category: "interfaccia", aliases: ["agenti"] },
|
|
42
43
|
{ name: "compact", hint: "[istruzioni]", get desc() { return tr("Compatta conservando obiettivo, attivita aperte e lavoro recente; salva un checkpoint", "Compact while preserving the goal, open tasks and recent work; save a checkpoint"); }, category: "vascend", aliases: ["vascend-compact"] },
|
|
43
44
|
{ name: "vascend", hint: "[on|off|goal]", get desc() { return tr("Configura il metodo di lavoro Vascend", "Configure the Vascend workflow"); }, category: "vascend" },
|
|
44
45
|
{ name: "todo", hint: "", get desc() { return tr("Lista delle attività: da fare, in corso, completate e fallite · Ctrl+G", "Task list: pending, running, completed and failed; Ctrl+G"); }, category: "attivita", aliases: ["piano", "tasks", "attivita", "regno", "castello", "castelli"] },
|
package/dist/tui/i18n-catalog.js
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
// English keys correspond to tr()'s stable fallback. User text, tool output,
|
|
2
2
|
// command names and model identifiers never pass through this catalogue.
|
|
3
3
|
export const TRANSLATION_ROWS = [
|
|
4
|
+
["Rename the chat: regenerate from the latest prompt or enter a title", "Renombra el chat: regenera desde el último mensaje o introduce un título", "Chat umbenennen: aus der letzten Nachricht generieren oder einen Titel eingeben"],
|
|
5
|
+
["Running command", "Ejecutando comando", "Befehl wird ausgeführt"],
|
|
6
|
+
["Rename chat", "Renombrar chat", "Chat umbenennen"],
|
|
7
|
+
["Regenerate from the latest prompt", "Regenerar desde el último mensaje", "Aus der letzten Nachricht neu generieren"],
|
|
8
|
+
["Use the selected model to choose the title.", "Usa el modelo seleccionado para elegir el título.", "Das ausgewählte Modell bestimmt den Titel."],
|
|
9
|
+
["Set manually", "Establecer manualmente", "Manuell festlegen"],
|
|
10
|
+
["Type the new chat name.", "Escribe el nuevo nombre del chat.", "Den neuen Chatnamen eingeben."],
|
|
11
|
+
["Chat name (Enter confirms · Esc cancels)", "Nombre del chat (Intro confirma · Esc cancela)", "Chatname (Enter bestätigt · Esc bricht ab)"],
|
|
12
|
+
["Models", "Modelos", "Modelle"],
|
|
13
|
+
["total", "en total", "insgesamt"],
|
|
14
|
+
["Current", "Actual", "Aktuell"],
|
|
15
|
+
["↑↓ select · Enter confirm · Tab details · Esc cancel", "↑↓ elegir · Intro confirmar · Tab detalles · Esc cancelar", "↑↓ wählen · Enter bestätigen · Tab Details · Esc abbrechen"],
|
|
16
|
+
["disk full", "disco lleno", "Datenträger voll"],
|
|
17
|
+
["disk quota exceeded", "cuota de disco agotada", "Speicherkontingent erschöpft"],
|
|
18
|
+
["permission denied", "permiso denegado", "Zugriff verweigert"],
|
|
19
|
+
["read-only filesystem", "sistema de archivos de solo lectura", "Dateisystem schreibgeschützt"],
|
|
20
|
+
["I/O error", "error de entrada/salida", "E/A-Fehler"],
|
|
21
|
+
["path unavailable", "ruta no disponible", "Pfad nicht verfügbar"],
|
|
22
|
+
["too many open files", "demasiados archivos abiertos", "Zu viele offene Dateien"],
|
|
23
|
+
["file busy", "archivo ocupado", "Datei belegt"],
|
|
24
|
+
["storage error", "error de guardado", "Speicherfehler"],
|
|
25
|
+
["conversation", "conversación", "Unterhaltung"],
|
|
26
|
+
["queue", "cola", "Warteschlange"],
|
|
27
|
+
["token usage", "consumo de tokens", "Tokenverbrauch"],
|
|
28
|
+
["Saving {target} resumed · some earlier data may be missing", "Guardado de {target} reanudado · pueden faltar datos anteriores", "Speichern von {target} fortgesetzt · frühere Daten fehlen möglicherweise"],
|
|
29
|
+
["{target}: data not saved ({code})", "{target}: datos sin guardar ({code})", "{target}: Daten nicht gespeichert ({code})"],
|
|
30
|
+
["Saving {target} failed ({reason}) · recent data may not be saved", "Error al guardar {target} ({reason}) · puede que los datos recientes no estén guardados", "Speichern von {target} fehlgeschlagen ({reason}) · aktuelle Daten sind möglicherweise nicht gespeichert"],
|
|
31
|
+
["Starting", "Iniciando", "Startet"],
|
|
32
|
+
["Thinking", "Procesando", "Verarbeitet"],
|
|
33
|
+
["Writing", "Escribiendo", "Schreibt"],
|
|
34
|
+
["Finished", "Finalizado", "Abgeschlossen"],
|
|
35
|
+
["Session", "Sesión", "Sitzung"],
|
|
36
|
+
["Agent sessions; Alt+A", "Sesiones de agentes; Alt+A", "Agentensitzungen; Alt+A"],
|
|
37
|
+
["↑↓ select · Enter open · main: primary session", "↑↓ seleccionar · Intro abrir · main: sesión principal", "↑↓ auswählen · Enter öffnen · main: Hauptsitzung"],
|
|
38
|
+
["↓ sessions · Alt+A select", "↓ sesiones · Alt+A seleccionar", "↓ Sitzungen · Alt+A auswählen"],
|
|
39
|
+
["↑↓ select · Enter open · select main to return · PgUp/PgDn output", "↑↓ seleccionar · Intro abrir · main para volver · RePág/AvPág salida", "↑↓ auswählen · Enter öffnen · main zur Rückkehr · Bild↑/Bild↓ Ausgabe"],
|
|
40
|
+
["Tokens not yet reported by the provider.", "El proveedor aún no ha comunicado los tokens.", "Der Anbieter hat noch keine Token gemeldet."],
|
|
41
|
+
["Waiting for activity…", "Esperando actividad…", "Warte auf Aktivität…"],
|
|
4
42
|
["Connect your account and get started.", "Conecta tu cuenta y empieza.", "Konto verbinden und loslegen."],
|
|
5
43
|
["1. Sign in in your browser", "1. Inicia sesión en el navegador", "1. Im Browser anmelden"],
|
|
6
44
|
["vascend.it will open to continue.", "Se abrirá vascend.it para continuar.", "vascend.it wird zum Fortfahren geöffnet."],
|
|
@@ -39,7 +77,7 @@ export const TRANSLATION_ROWS = [
|
|
|
39
77
|
["1 question", "1 pregunta", "1 Frage"],
|
|
40
78
|
["{count} questions", "{count} preguntas", "{count} Fragen"],
|
|
41
79
|
["Shift+← to answer", "Shift+← para responder", "Shift+← zum Antworten"],
|
|
42
|
-
["Enter submit ·
|
|
80
|
+
["Enter submit · Del skip · Alt+↓ main prompt", "Intro envía · Supr omite · Alt+↓ prompt", "Enter senden · Entf überspringen · Alt+↓ Eingabe"],
|
|
43
81
|
["Other", "Otra respuesta", "Andere Antwort"],
|
|
44
82
|
["Exploring", "Explorando", "Wird erkundet"],
|
|
45
83
|
["Explored", "Explorado", "Erkundet"],
|
package/dist/tui/logo.js
CHANGED
|
@@ -35,6 +35,9 @@ export function renderBlockLogo(svg, options = {}) {
|
|
|
35
35
|
function readVascendTerminalSvg() {
|
|
36
36
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
37
37
|
const candidates = [
|
|
38
|
+
join(here, "..", "..", "..", "vascend-horizon", "assets", "logo.svg"),
|
|
39
|
+
join(process.cwd(), "..", "vascend-horizon", "assets", "logo.svg"),
|
|
40
|
+
join(process.cwd(), "vascend-horizon", "assets", "logo.svg"),
|
|
38
41
|
join(here, "..", "..", "..", "vascend-terminal", "assets", "logo.svg"),
|
|
39
42
|
join(process.cwd(), "..", "vascend-terminal", "assets", "logo.svg"),
|
|
40
43
|
join(process.cwd(), "vascend-terminal", "assets", "logo.svg"),
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { fitLine, oneLine, padLine, wrapText } from "./terminal-text.js";
|
|
2
|
+
import { tr } from "./i18n.js";
|
|
3
|
+
// Use provider metadata verbatim: prices and capabilities are never guessed.
|
|
4
|
+
export function renderModelPicker(opts) {
|
|
5
|
+
const width = Math.max(1, opts.columns - 2);
|
|
6
|
+
const height = Math.max(3, (opts.rows ?? opts.pageSize + 13) - 1);
|
|
7
|
+
const t = opts.theme;
|
|
8
|
+
const row = (text) => " " + fitLine(text, width);
|
|
9
|
+
const divider = row(t.muted("─".repeat(width)));
|
|
10
|
+
const page = Math.max(1, Math.min(opts.pageSize, height - 6));
|
|
11
|
+
const index = Math.max(0, Math.min(opts.index, opts.options.length - 1));
|
|
12
|
+
const start = Math.max(0, Math.min(index - Math.floor(page / 2), opts.options.length - page));
|
|
13
|
+
const selected = opts.options[index];
|
|
14
|
+
const current = (option) => option && (opts.currentKey !== undefined
|
|
15
|
+
? (option.key ?? String(option.value)) === opts.currentKey
|
|
16
|
+
: opts.current !== undefined && option.value === opts.current);
|
|
17
|
+
const lines = [row(t.bold(`/model ${opts.title}`)), divider,
|
|
18
|
+
row(t.muted("/ ") + (opts.query ? t.silver(oneLine(opts.query)) : t.muted(tr("Cerca", "Search")))), ""];
|
|
19
|
+
const providerWidth = width >= 50 ? Math.min(24, Math.floor(width * 0.27)) : 0;
|
|
20
|
+
const labelWidth = Math.max(1, width - providerWidth - 5);
|
|
21
|
+
for (const [offset, option] of opts.options.slice(start, start + page).entries()) {
|
|
22
|
+
const active = start + offset === index;
|
|
23
|
+
const text = `${active ? "›" : " "}${current(option) ? "●" : " "} `
|
|
24
|
+
+ padLine(oneLine(option.label), labelWidth)
|
|
25
|
+
+ (providerWidth ? " " + fitLine(oneLine(option.group ?? ""), providerWidth) : "");
|
|
26
|
+
lines.push(row(active ? t.selected(padLine(text, width)) : t.silver(text)));
|
|
27
|
+
}
|
|
28
|
+
if (!opts.options.length)
|
|
29
|
+
lines.push(row(t.muted(tr(" Nessun risultato. Modifica la ricerca.", " No results. Change your search."))));
|
|
30
|
+
while (lines.length < page + 4)
|
|
31
|
+
lines.push("");
|
|
32
|
+
lines.push(row(t.muted(`${opts.options.length ? index + 1 : 0} / ${opts.options.length}`
|
|
33
|
+
+ (opts.totalCount !== undefined && opts.totalCount !== opts.options.length ? ` · ${opts.totalCount} ${tr("totali", "total")}` : ""))));
|
|
34
|
+
if (selected && height >= 12) {
|
|
35
|
+
lines.push(divider, row(t.accent(oneLine(selected.label))
|
|
36
|
+
+ (current(selected) ? t.muted(" · " + tr("Attuale", "Current")) : "")));
|
|
37
|
+
if (selected.group)
|
|
38
|
+
lines.push(row(t.muted(oneLine(selected.group))));
|
|
39
|
+
const detailSpace = Math.max(0, height - lines.length - 2);
|
|
40
|
+
lines.push(...wrapText(selected.detail, width, true).slice(0, detailSpace).map(text => row(t.silver(text))));
|
|
41
|
+
}
|
|
42
|
+
const footer = row(t.muted(width >= 55
|
|
43
|
+
? tr("↑↓ scegli · Invio conferma · Tab dettagli · Esc annulla", "↑↓ select · Enter confirm · Tab details · Esc cancel")
|
|
44
|
+
: tr("↑↓ · Invio · Tab · Esc", "↑↓ · Enter · Tab · Esc")));
|
|
45
|
+
const body = lines.slice(0, height - 1);
|
|
46
|
+
while (body.length < height - 1)
|
|
47
|
+
body.push("");
|
|
48
|
+
return [...body, footer];
|
|
49
|
+
}
|
|
@@ -22,6 +22,7 @@ export declare class NativeScrollback {
|
|
|
22
22
|
isCommitted(id: number): boolean;
|
|
23
23
|
invalidate(): void;
|
|
24
24
|
reset(): string;
|
|
25
|
-
render(log: readonly ScrollbackLine[], input: ScrollbackInput, width: number, height: number, hideCursor?: boolean, preamble?: readonly string[]): string;
|
|
25
|
+
render(log: readonly ScrollbackLine[], input: ScrollbackInput, width: number, height: number, hideCursor?: boolean, preamble?: readonly string[], emit?: (chunk: string) => void): string;
|
|
26
26
|
release(): string;
|
|
27
|
+
dispose(): void;
|
|
27
28
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fitLine } from "./terminal-text.js";
|
|
2
|
+
import { ScrollbackArchive } from "./scrollback-archive.js";
|
|
2
3
|
const RESET = "\x1b[0m\x1b]8;;\x1b\\";
|
|
3
4
|
const SYNC_ON = "\x1b[?2026h";
|
|
4
5
|
const SYNC_OFF = "\x1b[?2026l";
|
|
@@ -9,7 +10,7 @@ const move = (from, to) => from === to ? "\r"
|
|
|
9
10
|
// the composer are mutable; cursor movement never targets archived rows.
|
|
10
11
|
export class NativeScrollback {
|
|
11
12
|
committedThrough = 0;
|
|
12
|
-
history =
|
|
13
|
+
history = new ScrollbackArchive();
|
|
13
14
|
frame = [];
|
|
14
15
|
tail = [];
|
|
15
16
|
cursorRow = 0;
|
|
@@ -24,7 +25,7 @@ export class NativeScrollback {
|
|
|
24
25
|
// A session change replaces both the visible frame and native scrollback.
|
|
25
26
|
reset() {
|
|
26
27
|
this.committedThrough = 0;
|
|
27
|
-
this.history.
|
|
28
|
+
this.history.clear();
|
|
28
29
|
this.frame = [];
|
|
29
30
|
this.tail = [];
|
|
30
31
|
this.cursorRow = 0;
|
|
@@ -35,7 +36,7 @@ export class NativeScrollback {
|
|
|
35
36
|
this.preamble = [];
|
|
36
37
|
return SYNC_ON + RESET + "\x1b[2J\x1b[3J\x1b[H" + SYNC_OFF;
|
|
37
38
|
}
|
|
38
|
-
render(log, input, width, height, hideCursor = false, preamble = []) {
|
|
39
|
+
render(log, input, width, height, hideCursor = false, preamble = [], emit) {
|
|
39
40
|
if (width < 1 || height < 1)
|
|
40
41
|
return "";
|
|
41
42
|
const columns = Math.max(1, width);
|
|
@@ -82,19 +83,37 @@ export class NativeScrollback {
|
|
|
82
83
|
if (!changed && row === this.cursorRow && col === this.cursorCol)
|
|
83
84
|
return "";
|
|
84
85
|
let out = SYNC_ON;
|
|
86
|
+
const append = (text) => {
|
|
87
|
+
out += text;
|
|
88
|
+
if (emit && out.length >= 64 * 1024) {
|
|
89
|
+
emit(out);
|
|
90
|
+
out = "";
|
|
91
|
+
}
|
|
92
|
+
};
|
|
85
93
|
if (resized)
|
|
86
94
|
out += RESET + "\x1b[2J\x1b[3J\x1b[H";
|
|
87
95
|
if (resized || this.width === 0) {
|
|
88
96
|
for (const line of preamble)
|
|
89
97
|
out += fitLine(line, textWidth) + RESET + "\r\n";
|
|
90
98
|
for (const line of this.history)
|
|
91
|
-
|
|
99
|
+
append(fitLine(line.text, textWidth) + RESET + "\r\n");
|
|
92
100
|
}
|
|
93
101
|
let current = this.cursorRow;
|
|
94
|
-
if (changed) {
|
|
102
|
+
if (changed && !resized && !committed.length && frame.length === this.frame.length) {
|
|
103
|
+
// Spinner/timer updates must not erase the composer and every row below
|
|
104
|
+
// them. Paint only changed rows, including on terminals without sync.
|
|
105
|
+
out += "\x1b[?25l";
|
|
106
|
+
for (let i = start; i < frame.length; i++) {
|
|
107
|
+
if (frame[i] === this.frame[i])
|
|
108
|
+
continue;
|
|
109
|
+
out += move(current, i) + "\x1b[2K" + frame[i] + RESET;
|
|
110
|
+
current = i;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (changed) {
|
|
95
114
|
out += move(current, start) + "\x1b[J";
|
|
96
115
|
for (const line of committed)
|
|
97
|
-
|
|
116
|
+
append(fitLine(line.text, textWidth) + RESET + "\r\n");
|
|
98
117
|
out += frame.slice(start).map(line => line + RESET).join("\r\n");
|
|
99
118
|
current = Math.max(start, frame.length - 1);
|
|
100
119
|
}
|
|
@@ -131,4 +150,5 @@ export class NativeScrollback {
|
|
|
131
150
|
this.cursorCol = 1;
|
|
132
151
|
return out;
|
|
133
152
|
}
|
|
153
|
+
dispose() { this.history.clear(); }
|
|
134
154
|
}
|
|
@@ -20,6 +20,7 @@ export declare class PromptQueueFile implements QueuePersistence {
|
|
|
20
20
|
private path;
|
|
21
21
|
load(): QueueFile | undefined;
|
|
22
22
|
save(snapshot: QueueSnapshot): void;
|
|
23
|
+
private write;
|
|
23
24
|
}
|
|
24
25
|
declare function processAlive(pid: number): boolean;
|
|
25
26
|
export declare function recoverableQueue(base: string, alive?: typeof processAlive): string | undefined;
|
|
@@ -2,6 +2,7 @@ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, renameSync
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { validateSessionId } from "../core/session.js";
|
|
5
|
+
import { storageHealth } from "../core/storage-health.js";
|
|
5
6
|
export class PromptQueueFile {
|
|
6
7
|
base;
|
|
7
8
|
sessionId;
|
|
@@ -43,6 +44,9 @@ export class PromptQueueFile {
|
|
|
43
44
|
return data;
|
|
44
45
|
}
|
|
45
46
|
save(snapshot) {
|
|
47
|
+
storageHealth.write({ directory: this.base, sessionId: this.sessionId, kind: "queue" }, () => this.write(snapshot));
|
|
48
|
+
}
|
|
49
|
+
write(snapshot) {
|
|
46
50
|
const file = this.path(true);
|
|
47
51
|
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
48
52
|
const data = { version: 1, sessionId: this.sessionId, updatedAt: Date.now(), ownerPid: process.pid, ...snapshot };
|
|
@@ -64,7 +64,7 @@ export class QueuedQuestions {
|
|
|
64
64
|
this.hide();
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
-
if (text === "\x1d" || key.ctrl && key.name === "]") {
|
|
67
|
+
if (key.name === "delete" || text === "\x1d" || key.ctrl && key.name === "]") {
|
|
68
68
|
q.finish(null);
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
@@ -100,8 +100,6 @@ export class QueuedQuestions {
|
|
|
100
100
|
q.text = q.text.slice(0, q.cursor - 1) + q.text.slice(q.cursor);
|
|
101
101
|
q.cursor--;
|
|
102
102
|
}
|
|
103
|
-
else if (key.name === "delete")
|
|
104
|
-
q.text = q.text.slice(0, q.cursor) + q.text.slice(q.cursor + 1);
|
|
105
103
|
else if (text && !key.ctrl && !key.meta && !/[\x00-\x1f\x7f]/.test(text)) {
|
|
106
104
|
this.paste(text);
|
|
107
105
|
return;
|
|
@@ -145,7 +143,7 @@ export class QueuedQuestions {
|
|
|
145
143
|
if (index === q.index)
|
|
146
144
|
selectedEnd = body.length;
|
|
147
145
|
});
|
|
148
|
-
const shortcuts = tr("Invio invia ·
|
|
146
|
+
const shortcuts = tr("Invio invia · Canc salta · Alt+↓ prompt", "Enter submit · Del skip · Alt+↓ main prompt");
|
|
149
147
|
const footer = wrapText(shortcuts, bodyWidth, true).map(row => style.muted(" " + row));
|
|
150
148
|
const page = Math.max(1, maxRows - footer.length - 2);
|
|
151
149
|
if (q.offset < 0)
|
package/dist/tui/quick-help.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const QUICK_HELP = "## Inizia qui\nScrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'input resta in basso.\n\n### Token e contesto\n- **Contesto~** mostra una barra breve con token e percentuale **attivi** e **archiviati**, stimati rispetto alla finestra del modello. Il valore dopo **/** \u00E8 la capacit\u00E0 della finestra. Sotto l'input, **7g** \u00E8 la quota settimanale residua e **reset** il tempo rimasto; **~** davanti alla quota indica un dato non recente. Tutte le finestre e i consumi restano in **/usage**.\n- I blocchi **lime** rappresentano il contesto attivo; i **grigi** la quantit\u00E0 originale archiviata, dal pi\u00F9 vecchio (scuro) al pi\u00F9 recente (chiaro). **Archiviato** e **attivo** hanno percentuali separate rispetto alla finestra del modello. Il materiale grigio \u00E8 conservato fuori dalla finestra viva; riassunti e riferimenti fanno parte dell'attivo. **\u00D7N** indica la scala della barra quando il totale supera una finestra. Dettagli in **/context**.\n- Il totale in **/usage** somma i token delle chiamate della sessione, anche input ripetuti e cache: non indica il contesto di una singola richiesta. **\u2265** significa totale parziale.\n- Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione; i consumi del provider restano reali.\n- **ctx~** \u00E8 una stima locale del contesto, non la misura esatta del payload inviato. La quota ChatGPT \u00E8 separata. **/usage** mostra dettagli, cache e ultima chiamata.\n\n### Copiare e incollare\n- **/copy** copia l'ultima risposta testuale, senza colori del terminale (mantiene il Markdown).\n- **/copy una frase** copia soltanto il testo scritto dopo il comando.\n- Per selezionare una frase dalla chat: trascina il mouse senza tenere Shift, poi usa **Ctrl+Shift+C** (Windows/Linux) o **Cmd+C** (macOS). Dipende dalle impostazioni del terminale.\n- Incolla testo con **Ctrl+Shift+V** o **Cmd+V**. **Alt+V** legge un'immagine dagli appunti; puoi anche usare **/img percorso**.\n- I riferimenti **img #N** e **txt #N** sono evidenziati in ciano nel campo di input e nella chat; il contenuto completo viene allegato all'invio.\n- **Ctrl+C non \u00E8 il comando di copia di Talos.**\n\n### Fermare senza perdere il controllo\n- Primo **Ctrl+C**: avviso, nessuna azione. Secondo **Ctrl+C entro 2 secondi**: conferma l'azione indicata (fermare il lavoro, svuotare la bozza o uscire).\n- Un altro tasto annulla la conferma. **Esc** ferma subito il lavoro; in un menu o una domanda chiude solo quel pannello.\n- Fermare il lavoro conserva i messaggi in coda e li mette in pausa. **Alt+Q** apre la gestione per riprenderli o eliminarli. I processi in background si gestiscono con **/bg**.\n- **/quit** esce direttamente. Le chat gi\u00E0 inviate restano salvate; le bozze non sono salvate.\n\n### Messaggi in attesa\n- Sopra l'input, il punto **\u2022** indica i messaggi in attesa e quando verranno consegnati; la riga rientrata **\u21B3** mostra il prossimo messaggio. Normalmente partono in ordine dopo la risposta corrente; **Alt+Q** mostra tutti i messaggi.\n- **Alt+Q** o **/queue** (anche **/coda**) apre subito la coda: frecce per scegliere, **Invio** modifica, **Canc** elimina, **Shift+Su/Gi\u00F9** riordina, **p** mette in pausa o riprende.\n- **Alt+S** invia subito il testo che stai scrivendo, anche durante la risposta; se l'input \u00E8 vuoto, invia la prima richiesta in coda. Nella coda, **s \u00B7 Invia subito** invia il messaggio selezionato. Talos interrompe la generazione e riparte con il nuovo input; un'operazione gi\u00E0 avviata termina prima. **Alt+Invio** \u00E8 un alias nei terminali che lo inoltrano.\n- Con **almeno 3 richieste** in coda, **Alt+T** le invia subito insieme e chiede all'agente di ingaggiare il team per implementarle tutte. Nella gestione coda puoi usare anche **g \u00B7 Invia al team**. I comandi sono esclusi e la bozza che stai scrivendo resta intatta. Fino alla consegna puoi ancora modificare le singole richieste; il gruppo viene conservato anche al riavvio, in pausa.\n- **t** sceglie tra \u201Cdopo la risposta\u201D e \u201Cdurante il lavoro\u201D. Questa seconda modalit\u00E0 attende la risposta o l'operazione corrente senza interromperla.\n- Mentre gestisci o modifichi la coda nessun messaggio viene consegnato. **Invio** salva la modifica, **Esc** la annulla e conserva l'originale. La bozza precedente resta intatta.\n- Un messaggio compare nella conversazione solo alla consegna, con l'etichetta **Dalla coda \u00B7 consegnato**. Da quel momento non \u00E8 pi\u00F9 modificabile nella coda.\n- La coda \u00E8 salvata per chat, con ordine, modifiche confermate, testo incollato e immagini. Dopo la chiusura, il normale avvio riprende la chat con l'ultima coda pendente; una chat scelta esplicitamente ha precedenza. Aprire la chat lascia i messaggi **in pausa**. Quando Talos \u00E8 a riposo, **Invio** riprende la coda, anche con input vuoto; un nuovo prompt viene aggiunto in fondo e avvia la consegna. Puoi anche usare **Alt+Q**, poi **p** per riprenderli oppure **s** per inviarne uno subito.\n\n### Modalit\u00E0 fast\n- **/fast on** attiva la modalit\u00E0 veloce per ChatGPT/OpenAI, **/fast off** la disattiva, **/fast status** mostra lo stato. Quando \u00E8 attiva, **fast** compare accanto al modello. La preferenza \u00E8 salvata per i prossimi avvii.\n- Fast richiede il relativo supporto del modello e del provider e pu\u00F2 aumentare i consumi.\n\n### Ritrovare le chat\n- **/new** apre una chat vuota: la precedente resta salvata.\n- **/chats** (o **/resume**) apre la ricerca delle chat salvate; scrivi per filtrare, usa le frecce e Invio, Esc per annullare.\n- **/rename Titolo** assegna un nome riconoscibile alla chat corrente.\n- **/sessions** mostra gli ID; **/resume ID** riprende una chat specifica.\n\n### Leggere e navigare\n- **PageUp / PageDown**, rotella o **Shift+Su/Gi\u00F9** scorrono la conversazione senza spostare l'input.\n- **Su/Gi\u00F9** in fondo alla chat richiamano le richieste precedenti. **Tab** completa i comandi.\n- **Ctrl+R** apre la revisione delle attivit\u00E0; **Ctrl+O** apre l'elenco dei file modificati: frecce per scegliere, Invio per leggere il confronto, Esc per tornare. **Ctrl+G** o **/todo** apre la lista delle attivit\u00E0, con gruppi e stati: da fare, in corso, completata e fallita.\n- **/commands** apre tutti i comandi, con ricerca. **/help** riapre questa guida.\n\nLe scorciatoie descritte valgono nella TUI interattiva. In terminali remoti, copia e selezione dipendono anche dal client; /copy usa gli appunti della macchina dove gira Talos.\n";
|
|
1
|
+
export declare const QUICK_HELP = "## Inizia qui\nScrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'input resta in basso.\n\n### Token e contesto\n- **Contesto~** mostra una barra breve con token e percentuale **attivi** e **archiviati**, stimati rispetto alla finestra del modello. Il valore dopo **/** \u00E8 la capacit\u00E0 della finestra. Sotto l'input, **7g** \u00E8 la quota settimanale residua e **reset** il tempo rimasto; **~** davanti alla quota indica un dato non recente. Tutte le finestre e i consumi restano in **/usage**.\n- I blocchi **lime** rappresentano il contesto attivo; i **grigi** la quantit\u00E0 originale archiviata, dal pi\u00F9 vecchio (scuro) al pi\u00F9 recente (chiaro). **Archiviato** e **attivo** hanno percentuali separate rispetto alla finestra del modello. Il materiale grigio \u00E8 conservato fuori dalla finestra viva; riassunti e riferimenti fanno parte dell'attivo. **\u00D7N** indica la scala della barra quando il totale supera una finestra. Dettagli in **/context**.\n- Il totale in **/usage** somma i token delle chiamate della sessione, anche input ripetuti e cache: non indica il contesto di una singola richiesta. **\u2265** significa totale parziale.\n- Talos seleziona informazioni rilevanti e gestisce la cronologia con recupero e compattazione secondo la configurazione; i consumi del provider restano reali.\n- **ctx~** \u00E8 una stima locale del contesto, non la misura esatta del payload inviato. La quota ChatGPT \u00E8 separata. **/usage** mostra dettagli, cache e ultima chiamata.\n\n### Copiare e incollare\n- **/copy** copia l'ultima risposta testuale, senza colori del terminale (mantiene il Markdown).\n- **/copy una frase** copia soltanto il testo scritto dopo il comando.\n- Per selezionare una frase dalla chat: trascina il mouse senza tenere Shift, poi usa **Ctrl+Shift+C** (Windows/Linux) o **Cmd+C** (macOS). Dipende dalle impostazioni del terminale.\n- Incolla testo con **Ctrl+Shift+V** o **Cmd+V**. **Alt+V** legge un'immagine dagli appunti; puoi anche usare **/img percorso**.\n- I riferimenti **img #N** e **txt #N** sono evidenziati in ciano nel campo di input e nella chat; il contenuto completo viene allegato all'invio.\n- **Ctrl+C non \u00E8 il comando di copia di Talos.**\n\n### Fermare senza perdere il controllo\n- Se il salvataggio di conversazione, coda o consumi fallisce, compare un avviso con la causa (per esempio disco pieno o permesso negato). Resta visibile finch\u00E9 le scritture falliscono; dopo una scrittura riuscita scompare in 5 secondi. La ripresa non garantisce il recupero dei dati precedenti non salvati.\n- Primo **Ctrl+C**: avviso, nessuna azione. Secondo **Ctrl+C entro 2 secondi**: conferma l'azione indicata (fermare il lavoro, svuotare la bozza o uscire).\n- Un altro tasto annulla la conferma. **Esc** ferma subito il lavoro; in un menu o una domanda chiude solo quel pannello.\n- Fermare il lavoro conserva i messaggi in coda e li mette in pausa. **Alt+Q** apre la gestione per riprenderli o eliminarli. I processi in background si gestiscono con **/bg**.\n- **/quit** esce direttamente. Le chat gi\u00E0 inviate restano salvate; le bozze non sono salvate.\n\n### Messaggi in attesa\n- **Shift+\u2190** apre le domande in coda. **Invio** invia la risposta; **Canc** salta la domanda aperta. **Alt+\u2193** torna al prompt conservando la domanda e la bozza della risposta.\n- Sopra l'input, il punto **\u2022** indica i messaggi in attesa e quando verranno consegnati; la riga rientrata **\u21B3** mostra il prossimo messaggio. Normalmente partono in ordine dopo la risposta corrente; **Alt+Q** mostra tutti i messaggi.\n- **Alt+Q** o **/queue** (anche **/coda**) apre subito la coda: frecce per scegliere, **Invio** modifica, **Canc** elimina, **Shift+Su/Gi\u00F9** riordina, **p** mette in pausa o riprende.\n- **Alt+S** invia subito il testo che stai scrivendo, anche durante la risposta; se l'input \u00E8 vuoto, invia la prima richiesta in coda. Nella coda, **s \u00B7 Invia subito** invia il messaggio selezionato. Talos interrompe la generazione e riparte con il nuovo input; un'operazione gi\u00E0 avviata termina prima. **Alt+Invio** \u00E8 un alias nei terminali che lo inoltrano.\n- Con **almeno 3 richieste** in coda, **Alt+T** le invia subito insieme e chiede all'agente di ingaggiare il team per implementarle tutte. Nella gestione coda puoi usare anche **g \u00B7 Invia al team**. I comandi sono esclusi e la bozza che stai scrivendo resta intatta. Fino alla consegna puoi ancora modificare le singole richieste; il gruppo viene conservato anche al riavvio, in pausa.\n- **t** sceglie tra \u201Cdopo la risposta\u201D e \u201Cdurante il lavoro\u201D. Questa seconda modalit\u00E0 attende la risposta o l'operazione corrente senza interromperla.\n- Mentre gestisci o modifichi la coda nessun messaggio viene consegnato. **Invio** salva la modifica, **Esc** la annulla e conserva l'originale. La bozza precedente resta intatta.\n- Un messaggio compare nella conversazione solo alla consegna, con l'etichetta **Dalla coda \u00B7 consegnato**. Da quel momento non \u00E8 pi\u00F9 modificabile nella coda.\n- La coda \u00E8 salvata per chat, con ordine, modifiche confermate, testo incollato e immagini. Dopo la chiusura, il normale avvio riprende la chat con l'ultima coda pendente; una chat scelta esplicitamente ha precedenza. Aprire la chat lascia i messaggi **in pausa**. Quando Talos \u00E8 a riposo, **Invio** riprende la coda, anche con input vuoto; un nuovo prompt viene aggiunto in fondo e avvia la consegna. Puoi anche usare **Alt+Q**, poi **p** per riprenderli oppure **s** per inviarne uno subito.\n\n### Modalit\u00E0 fast\n- **/fast on** attiva la modalit\u00E0 veloce per ChatGPT/OpenAI, **/fast off** la disattiva, **/fast status** mostra lo stato. Quando \u00E8 attiva, **fast** compare accanto al modello. La preferenza \u00E8 salvata per i prossimi avvii.\n- Fast richiede il relativo supporto del modello e del provider e pu\u00F2 aumentare i consumi.\n\n### Ritrovare le chat\n- **/new** apre una chat vuota: la precedente resta salvata.\n- **/chats** (o **/resume**) apre la ricerca delle chat salvate; scrivi per filtrare, usa le frecce e Invio, Esc per annullare.\n- **/rename Titolo** assegna un nome riconoscibile alla chat corrente.\n- **/sessions** mostra gli ID; **/resume ID** riprende una chat specifica.\n\n### Leggere e navigare\n- Con collaboratori attivi, **Gi\u00F9** dal prompt vuoto seleziona le sessioni; **Alt+A** o **/agents** attiva lo stesso elenco. **Su/Gi\u00F9** seleziona e **Invio** apre. Ogni riga mostra attivit\u00E0, durata e token. Per tornare scegli **main** e premi **Invio**; se il collaboratore visualizzato viene rimosso, il ritorno a **main** \u00E8 automatico. Nella sua vista **PageUp/PageDown** scorre l'output e **End** riprende il seguito automatico.\n- **PageUp / PageDown**, rotella o **Shift+Su/Gi\u00F9** scorrono la conversazione senza spostare l'input.\n- **Su/Gi\u00F9** in fondo alla chat richiamano le richieste precedenti. **Tab** completa i comandi.\n- **Ctrl+R** apre la revisione delle attivit\u00E0; **Ctrl+O** apre l'elenco dei file modificati: frecce per scegliere, Invio per leggere il confronto, Esc per tornare. **Ctrl+G** o **/todo** apre la lista delle attivit\u00E0, con gruppi e stati: da fare, in corso, completata e fallita.\n- **/commands** apre tutti i comandi, con ricerca. **/help** riapre questa guida.\n\nLe scorciatoie descritte valgono nella TUI interattiva. In terminali remoti, copia e selezione dipendono anche dal client; /copy usa gli appunti della macchina dove gira Talos.\n";
|
package/dist/tui/quick-help.js
CHANGED
|
@@ -18,12 +18,14 @@ Scrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'i
|
|
|
18
18
|
- **Ctrl+C non è il comando di copia di Talos.**
|
|
19
19
|
|
|
20
20
|
### Fermare senza perdere il controllo
|
|
21
|
+
- Se il salvataggio di conversazione, coda o consumi fallisce, compare un avviso con la causa (per esempio disco pieno o permesso negato). Resta visibile finché le scritture falliscono; dopo una scrittura riuscita scompare in 5 secondi. La ripresa non garantisce il recupero dei dati precedenti non salvati.
|
|
21
22
|
- Primo **Ctrl+C**: avviso, nessuna azione. Secondo **Ctrl+C entro 2 secondi**: conferma l'azione indicata (fermare il lavoro, svuotare la bozza o uscire).
|
|
22
23
|
- Un altro tasto annulla la conferma. **Esc** ferma subito il lavoro; in un menu o una domanda chiude solo quel pannello.
|
|
23
24
|
- Fermare il lavoro conserva i messaggi in coda e li mette in pausa. **Alt+Q** apre la gestione per riprenderli o eliminarli. I processi in background si gestiscono con **/bg**.
|
|
24
25
|
- **/quit** esce direttamente. Le chat già inviate restano salvate; le bozze non sono salvate.
|
|
25
26
|
|
|
26
27
|
### Messaggi in attesa
|
|
28
|
+
- **Shift+←** apre le domande in coda. **Invio** invia la risposta; **Canc** salta la domanda aperta. **Alt+↓** torna al prompt conservando la domanda e la bozza della risposta.
|
|
27
29
|
- Sopra l'input, il punto **•** indica i messaggi in attesa e quando verranno consegnati; la riga rientrata **↳** mostra il prossimo messaggio. Normalmente partono in ordine dopo la risposta corrente; **Alt+Q** mostra tutti i messaggi.
|
|
28
30
|
- **Alt+Q** o **/queue** (anche **/coda**) apre subito la coda: frecce per scegliere, **Invio** modifica, **Canc** elimina, **Shift+Su/Giù** riordina, **p** mette in pausa o riprende.
|
|
29
31
|
- **Alt+S** invia subito il testo che stai scrivendo, anche durante la risposta; se l'input è vuoto, invia la prima richiesta in coda. Nella coda, **s · Invia subito** invia il messaggio selezionato. Talos interrompe la generazione e riparte con il nuovo input; un'operazione già avviata termina prima. **Alt+Invio** è un alias nei terminali che lo inoltrano.
|
|
@@ -44,6 +46,7 @@ Scrivi una richiesta e premi **Invio**. Talos mostra la risposta nella chat; l'i
|
|
|
44
46
|
- **/sessions** mostra gli ID; **/resume ID** riprende una chat specifica.
|
|
45
47
|
|
|
46
48
|
### Leggere e navigare
|
|
49
|
+
- Con collaboratori attivi, **Giù** dal prompt vuoto seleziona le sessioni; **Alt+A** o **/agents** attiva lo stesso elenco. **Su/Giù** seleziona e **Invio** apre. Ogni riga mostra attività, durata e token. Per tornare scegli **main** e premi **Invio**; se il collaboratore visualizzato viene rimosso, il ritorno a **main** è automatico. Nella sua vista **PageUp/PageDown** scorre l'output e **End** riprende il seguito automatico.
|
|
47
50
|
- **PageUp / PageDown**, rotella o **Shift+Su/Giù** scorrono la conversazione senza spostare l'input.
|
|
48
51
|
- **Su/Giù** in fondo alla chat richiamano le richieste precedenti. **Tab** completa i comandi.
|
|
49
52
|
- **Ctrl+R** apre la revisione delle attività; **Ctrl+O** apre l'elenco dei file modificati: frecce per scegliere, Invio per leggere il confronto, Esc per tornare. **Ctrl+G** o **/todo** apre la lista delle attività, con gruppi e stati: da fare, in corso, completata e fallita.
|
package/dist/tui/repl.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export interface InputControl {
|
|
|
28
28
|
replaceTail?(lines: readonly string[], count: number): void;
|
|
29
29
|
refresh?(): void;
|
|
30
30
|
setStatus(label: string | null): void;
|
|
31
|
+
setCompacting?(active: boolean): void;
|
|
32
|
+
showSessionNaming?(title: string): void;
|
|
33
|
+
setSessionNaming?(phase: "start" | "end", title: string): void;
|
|
31
34
|
setStatusTool?(name: string | null): void;
|
|
32
35
|
setRoomStatus?(label: string | null, state?: "running" | "done" | "failed"): void;
|
|
33
36
|
setLogLine?(index: number, text: string): void;
|