@hoilab/ada-cli 0.84.8 → 0.84.10
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/dist/cli/home-screen.d.ts +4 -3
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +25 -10
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +2 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/home-screen.d.ts +13 -0
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +102 -31
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Container, Input, getKeybindings, truncateToWidth } from "@earendil-works/pi-tui";
|
|
1
|
+
import { Container, Input, getKeybindings, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
2
|
import { checkForNewPiVersion } from "../../../utils/version-check.js";
|
|
3
3
|
import { theme } from "../theme/theme.js";
|
|
4
4
|
import { filterAndSortSessions } from "./session-selector-search.js";
|
|
@@ -10,6 +10,24 @@ const ASCII_LOGO = [
|
|
|
10
10
|
" ██║ ██║██████╔╝██║ ██║",
|
|
11
11
|
" ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝",
|
|
12
12
|
].join("\n");
|
|
13
|
+
/** Vertical teal-to-gray gradient for the ASCII logo. */
|
|
14
|
+
const LOGO_GRADIENT = ["accent", "accent", "borderAccent", "border", "borderMuted", "muted"];
|
|
15
|
+
/** Draw a rounded box around centered content with an optional title. */
|
|
16
|
+
function box(contentLines, width, options = {}) {
|
|
17
|
+
const color = options.color ?? ((str) => theme.fg("border", str));
|
|
18
|
+
const innerWidth = Math.max(10, width - 4);
|
|
19
|
+
const top = options.title !== undefined
|
|
20
|
+
? color(`╭─ ${options.title} `) + "─".repeat(Math.max(1, innerWidth - options.title.length - 2)) + color("─╮")
|
|
21
|
+
: color(`╭${"─".repeat(innerWidth)}╮`);
|
|
22
|
+
const bottom = color(`╰${"─".repeat(innerWidth)}╯`);
|
|
23
|
+
const pad = (line) => {
|
|
24
|
+
const visible = visibleWidth(line);
|
|
25
|
+
const left = Math.max(0, Math.floor((innerWidth - visible) / 2));
|
|
26
|
+
const right = Math.max(0, innerWidth - visible - left);
|
|
27
|
+
return color("│ ") + " ".repeat(left) + line + " ".repeat(right) + color(" │");
|
|
28
|
+
};
|
|
29
|
+
return [top, ...contentLines.map(pad), bottom];
|
|
30
|
+
}
|
|
13
31
|
function sessionTitle(session) {
|
|
14
32
|
if (session.name)
|
|
15
33
|
return session.name;
|
|
@@ -53,12 +71,26 @@ export class HomeScreenComponent extends Container {
|
|
|
53
71
|
searchInput;
|
|
54
72
|
loadSessions;
|
|
55
73
|
version;
|
|
74
|
+
modelLabel = null;
|
|
75
|
+
cwdLabelValue = null;
|
|
76
|
+
memoryEnabled = true;
|
|
56
77
|
_focused = false;
|
|
57
78
|
requestRenderFn = () => { };
|
|
58
79
|
onNew;
|
|
59
80
|
onResume;
|
|
60
81
|
onExit;
|
|
61
82
|
onUpdate;
|
|
83
|
+
/** Fired when the entry screen transitions to the home screen. */
|
|
84
|
+
onEnterHome;
|
|
85
|
+
setModelLabel(label) {
|
|
86
|
+
this.modelLabel = label;
|
|
87
|
+
}
|
|
88
|
+
setCwdLabel(label) {
|
|
89
|
+
this.cwdLabelValue = label;
|
|
90
|
+
}
|
|
91
|
+
setMemoryEnabled(enabled) {
|
|
92
|
+
this.memoryEnabled = enabled;
|
|
93
|
+
}
|
|
62
94
|
constructor(loadSessions, version) {
|
|
63
95
|
super();
|
|
64
96
|
this.loadSessions = loadSessions;
|
|
@@ -111,6 +143,7 @@ export class HomeScreenComponent extends Container {
|
|
|
111
143
|
enterHome() {
|
|
112
144
|
this.phase = "home";
|
|
113
145
|
this.selectedIndex = 0;
|
|
146
|
+
this.onEnterHome?.();
|
|
114
147
|
void this.reload();
|
|
115
148
|
void this.checkUpdate();
|
|
116
149
|
}
|
|
@@ -188,55 +221,73 @@ export class HomeScreenComponent extends Container {
|
|
|
188
221
|
render(width) {
|
|
189
222
|
const lines = [];
|
|
190
223
|
const center = (text) => {
|
|
191
|
-
const pad = Math.max(0, Math.floor((width - text
|
|
224
|
+
const pad = Math.max(0, Math.floor((width - visibleWidth(text)) / 2));
|
|
192
225
|
return " ".repeat(pad) + text;
|
|
193
226
|
};
|
|
194
227
|
const dim = (t) => theme.fg("dim", t);
|
|
195
228
|
const muted = (t) => theme.fg("muted", t);
|
|
196
229
|
const accent = (t) => theme.fg("accent", t);
|
|
230
|
+
const border = (t) => theme.fg("border", t);
|
|
231
|
+
const success = (t) => theme.fg("success", t);
|
|
197
232
|
const warning = (t) => theme.fg("warning", t);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
233
|
+
// Gradient logo (teal -> gray)
|
|
234
|
+
const logoLines = ASCII_LOGO.split("\n").map((line, i) => theme.fg(LOGO_GRADIENT[Math.min(i, LOGO_GRADIENT.length - 1)], line));
|
|
235
|
+
const tagline = accent("Ada") + dim(" · coding agent · HOILAB TECH") + muted(` v${this.version}`);
|
|
201
236
|
lines.push("");
|
|
202
237
|
if (this.phase === "login") {
|
|
203
238
|
// ---- Entry screen -------------------------------------------
|
|
239
|
+
const boxW = Math.min(56, width - 4);
|
|
240
|
+
const boxLines = box([
|
|
241
|
+
"",
|
|
242
|
+
...logoLines,
|
|
243
|
+
tagline,
|
|
244
|
+
"",
|
|
245
|
+
dim("Bienvenido a Ada — el agente de codificación de HOILAB TECH"),
|
|
246
|
+
"",
|
|
247
|
+
accent("▸ ") + theme.bold("Entrar como invitado"),
|
|
248
|
+
muted(" Loguearme") + dim(" (próximamente)"),
|
|
249
|
+
"",
|
|
250
|
+
], boxW, { title: " ✦ HOILAB TECH ✦ " });
|
|
251
|
+
lines.push(...boxLines);
|
|
204
252
|
lines.push("");
|
|
205
|
-
lines.push(center(dim("
|
|
206
|
-
lines.push("");
|
|
207
|
-
lines.push(center(accent("▸ ") + theme.bold("Entrar como invitado")));
|
|
208
|
-
lines.push(center(muted(" Loguearme") + dim(" (próximamente)")));
|
|
209
|
-
lines.push("");
|
|
253
|
+
lines.push(center(success("●") + dim(" En línea · sin conexión a cuentas") + muted(" · todo queda en tu máquina")));
|
|
210
254
|
lines.push("");
|
|
211
255
|
lines.push(center(muted(["Enter para continuar", "q para salir"].join(" · "))));
|
|
212
|
-
return lines;
|
|
256
|
+
return this.finishRender(lines, width);
|
|
213
257
|
}
|
|
214
258
|
// ---- Home screen ------------------------------------------------
|
|
259
|
+
const boxW = Math.min(58, width - 4);
|
|
260
|
+
// Header box: logo + status
|
|
261
|
+
const statusParts = [
|
|
262
|
+
dim(`model: ${this.defaultModelLabel()}`),
|
|
263
|
+
dim(`cwd: ${this.cwdLabel()}`),
|
|
264
|
+
dim(`memoria: ${this.memoryLabel()}`),
|
|
265
|
+
];
|
|
266
|
+
lines.push(...box(["", ...logoLines, tagline, "", ...statusParts, ""], boxW, { title: " ✦ HOILAB TECH ✦ " }));
|
|
267
|
+
lines.push("");
|
|
268
|
+
// Update notice
|
|
215
269
|
if (this.updateAvailable) {
|
|
216
270
|
lines.push(center(warning(`⚠ Nueva versión disponible: v${this.updateAvailable} ` +
|
|
217
|
-
|
|
218
|
-
dim(" ·
|
|
219
|
-
lines.push("");
|
|
271
|
+
accent("[u] actualizar") +
|
|
272
|
+
dim(" · q para ignorar"))));
|
|
220
273
|
}
|
|
221
274
|
else if (this.updateChecked) {
|
|
222
|
-
lines.push(center(
|
|
223
|
-
lines.push("");
|
|
275
|
+
lines.push(center(success("✓ Sistema actualizado")));
|
|
224
276
|
}
|
|
225
|
-
lines.push(center(dim("Elige una conversación o empieza una nueva:")));
|
|
226
277
|
lines.push("");
|
|
227
|
-
//
|
|
278
|
+
// Conversations box
|
|
279
|
+
const convLines = [""];
|
|
228
280
|
const isNew = this.selectedIndex === 0;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
lines.push("");
|
|
281
|
+
convLines.push(`${isNew ? accent("▸ ") : " "}${accent("✦")} ${isNew ? theme.bold("Nueva conversación") : "Nueva conversación"}`);
|
|
282
|
+
convLines.push(dim("─".repeat(Math.max(4, boxW - 6))));
|
|
283
|
+
convLines.push("");
|
|
233
284
|
if (this.loading) {
|
|
234
|
-
|
|
285
|
+
convLines.push(dim("Cargando conversaciones…"));
|
|
235
286
|
}
|
|
236
287
|
else if (this.filtered.length === 0) {
|
|
237
|
-
|
|
288
|
+
convLines.push(muted(this.query
|
|
238
289
|
? "No hay conversaciones que coincidan con tu búsqueda"
|
|
239
|
-
: "Todavía no hay conversaciones anteriores"))
|
|
290
|
+
: "Todavía no hay conversaciones anteriores"));
|
|
240
291
|
}
|
|
241
292
|
else {
|
|
242
293
|
const maxVisible = Math.max(1, Math.min(12, Math.floor((width * 2) / 3)));
|
|
@@ -245,17 +296,20 @@ export class HomeScreenComponent extends Container {
|
|
|
245
296
|
const session = visible[i];
|
|
246
297
|
const isSelected = this.selectedIndex === i + 1;
|
|
247
298
|
const title = sessionTitle(session);
|
|
248
|
-
const meta = `${relativeTime(session.modified.toISOString())} · ${session.messageCount} msgs
|
|
249
|
-
const arrow = isSelected ? "▸ " : " ";
|
|
299
|
+
const meta = muted(`${relativeTime(session.modified.toISOString())} · ${session.messageCount} msgs`);
|
|
300
|
+
const arrow = isSelected ? accent("▸ ") : " ";
|
|
250
301
|
const titleStyled = isSelected ? theme.bold(accent(title)) : title;
|
|
251
|
-
|
|
302
|
+
convLines.push(`${arrow}${titleStyled} ${meta}`);
|
|
252
303
|
}
|
|
253
304
|
if (this.filtered.length > maxVisible) {
|
|
254
|
-
|
|
305
|
+
convLines.push(dim(`… y ${this.filtered.length - maxVisible} más`));
|
|
255
306
|
}
|
|
256
307
|
}
|
|
308
|
+
convLines.push("");
|
|
309
|
+
lines.push(...box(convLines, boxW, { title: " Conversaciones " }));
|
|
257
310
|
lines.push("");
|
|
258
|
-
|
|
311
|
+
// Search + hints
|
|
312
|
+
lines.push(center(accent("🔎") + dim(` Buscar: ${this.query}${this.searchInput.focused ? "▍" : ""}`)));
|
|
259
313
|
lines.push("");
|
|
260
314
|
const hints = [
|
|
261
315
|
"↑/↓ navegar",
|
|
@@ -265,8 +319,25 @@ export class HomeScreenComponent extends Container {
|
|
|
265
319
|
"escribir para buscar",
|
|
266
320
|
"q salir",
|
|
267
321
|
].filter((h) => h !== null);
|
|
322
|
+
lines.push(border("─".repeat(Math.min(52, width - 8))));
|
|
268
323
|
lines.push(center(muted(hints.join(" · "))));
|
|
269
|
-
return
|
|
324
|
+
return this.finishRender(lines, width);
|
|
325
|
+
}
|
|
326
|
+
/** Vertical centering + truncation of every rendered line. */
|
|
327
|
+
finishRender(lines, width) {
|
|
328
|
+
const rows = process.stdout.rows ?? 24;
|
|
329
|
+
const contentHeight = lines.length;
|
|
330
|
+
const topPad = Math.max(0, Math.floor((rows - contentHeight) / 2) - 1);
|
|
331
|
+
return [...Array(topPad).fill(""), ...lines.map((line) => truncateToWidth(line, width))];
|
|
332
|
+
}
|
|
333
|
+
defaultModelLabel() {
|
|
334
|
+
return this.modelLabel ?? "no configurado (/model)";
|
|
335
|
+
}
|
|
336
|
+
cwdLabel() {
|
|
337
|
+
return this.cwdLabelValue ?? process.cwd();
|
|
338
|
+
}
|
|
339
|
+
memoryLabel() {
|
|
340
|
+
return this.memoryEnabled ? "activada" : "desactivada";
|
|
270
341
|
}
|
|
271
342
|
}
|
|
272
343
|
//# sourceMappingURL=home-screen.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home-screen.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/home-screen.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, Input, getKeybindings, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { SessionInfo, SessionListProgress } from \"../../../core/session-manager.ts\";\nimport { checkForNewPiVersion } from \"../../../utils/version-check.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { filterAndSortSessions } from \"./session-selector-search.ts\";\n\nexport type HomeScreenResult = { kind: \"new\" } | { kind: \"resume\"; path: string } | null;\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\nconst ASCII_LOGO = [\n\t\" █████╗ ██████╗ █████╗\",\n\t\" ██╔══██╗██╔══██╗██╔══██╗\",\n\t\" ███████║██║ ██║███████║\",\n\t\" ██╔══██║██║ ██║██╔══██║\",\n\t\" ██║ ██║██████╔╝██║ ██║\",\n\t\" ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝\",\n].join(\"\\n\");\n\nfunction sessionTitle(session: SessionInfo): string {\n\tif (session.name) return session.name;\n\tconst first = (session.firstMessage ?? \"\").replace(/\\s+/g, \" \").trim();\n\tif (first.length > 0) return first.length > 60 ? `${first.slice(0, 60)}…` : first;\n\treturn \"Conversation\";\n}\n\nfunction relativeTime(iso: string): string {\n\tconst diffMs = Date.now() - new Date(iso).getTime();\n\tconst mins = Math.floor(diffMs / 60000);\n\tif (mins < 1) return \"now\";\n\tif (mins < 60) return `${mins}m`;\n\tconst hours = Math.floor(mins / 60);\n\tif (hours < 24) return `${hours}h`;\n\tconst days = Math.floor(hours / 24);\n\tif (days < 7) return `${days}d`;\n\tif (days < 30) return `${Math.floor(days / 7)}w`;\n\treturn `${Math.floor(days / 30)}mo`;\n}\n\n/**\n * Central welcome flow (opencode style) shown when the CLI starts:\n * 1) entry screen: \"Enter as guest\" (login is disabled for now)\n * 2) home screen: welcome banner, update notice, recent conversations and\n * a \"New conversation\" action.\n */\nexport class HomeScreenComponent extends Container implements Component {\n\tprivate phase: \"login\" | \"home\" = \"login\";\n\tprivate sessions: SessionInfo[] = [];\n\tprivate filtered: SessionInfo[] = [];\n\tprivate selectedIndex = 0; // 0 = \"New conversation\", then sessions\n\tprivate query = \"\";\n\tprivate loading = false;\n\tprivate updateAvailable: string | null = null;\n\tprivate updateChecked = false;\n\tprivate searchInput: Input;\n\tprivate loadSessions: SessionsLoader;\n\tprivate version: string;\n\tprivate _focused = false;\n\tprivate requestRenderFn: () => void = () => {};\n\n\tpublic onNew?: () => void;\n\tpublic onResume?: (path: string) => void;\n\tpublic onExit?: () => void;\n\tpublic onUpdate?: () => void;\n\n\tconstructor(loadSessions: SessionsLoader, version: string) {\n\t\tsuper();\n\t\tthis.loadSessions = loadSessions;\n\t\tthis.version = version;\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.onSubmit = () => this.confirmSelection();\n\t}\n\n\t// Focusable\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tthis.loading = true;\n\t\tthis.requestRenderFn();\n\t\ttry {\n\t\t\tthis.sessions = await this.loadSessions();\n\t\t} catch {\n\t\t\tthis.sessions = [];\n\t\t}\n\t\tthis.loading = false;\n\t\tthis.applyFilter();\n\t\tthis.requestRenderFn();\n\t}\n\n\tprivate applyFilter(): void {\n\t\tconst q = this.query.trim();\n\t\tthis.filtered = q\n\t\t\t? filterAndSortSessions(this.sessions, q, \"recent\", \"all\")\n\t\t\t: [...this.sessions].sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, this.filtered.length);\n\t}\n\n\tprivate confirmSelection(): void {\n\t\tif (this.phase === \"login\") {\n\t\t\tthis.enterHome();\n\t\t\treturn;\n\t\t}\n\t\tif (this.selectedIndex === 0) {\n\t\t\tthis.onNew?.();\n\t\t} else {\n\t\t\tconst session = this.filtered[this.selectedIndex - 1];\n\t\t\tif (session) this.onResume?.(session.path);\n\t\t}\n\t}\n\n\tprivate enterHome(): void {\n\t\tthis.phase = \"home\";\n\t\tthis.selectedIndex = 0;\n\t\tvoid this.reload();\n\t\tvoid this.checkUpdate();\n\t}\n\n\tprivate async checkUpdate(): Promise<void> {\n\t\tif (this.updateChecked) return;\n\t\tthis.updateChecked = true;\n\t\ttry {\n\t\t\tconst release = await checkForNewPiVersion(this.version);\n\t\t\tif (release) {\n\t\t\t\tthis.updateAvailable = release.version;\n\t\t\t\tthis.requestRenderFn();\n\t\t\t}\n\t\t} catch {\n\t\t\t// Offline or unreachable — ignore silently.\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (this.phase === \"login\") {\n\t\t\tif (kb.matches(data, \"tui.select.confirm\") || data === \"\\r\" || data === \"\\n\") {\n\t\t\t\tthis.enterHome();\n\t\t\t} else if (kb.matches(data, \"tui.select.cancel\") || data === \"q\" || data === \"Q\") {\n\t\t\t\tthis.onExit?.();\n\t\t\t} else if (kb.matches(data, \"tui.select.down\")) {\n\t\t\t\t// Only one actionable option on the login screen; ignore.\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.requestRenderFn();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filtered.length, this.selectedIndex + 1);\n\t\t\tthis.requestRenderFn();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\") || data === \"\\r\" || data === \"\\n\") {\n\t\t\tthis.confirmSelection();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \"n\" || data === \"N\") {\n\t\t\tthis.onNew?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \"u\" || data === \"U\") {\n\t\t\tif (this.updateAvailable) {\n\t\t\t\tthis.onUpdate?.();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (data === \"q\" || data === \"Q\") {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\t// Anything else goes to the search input (filters sessions)\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.query = this.searchInput.getValue();\n\t\tthis.applyFilter();\n\t\tthis.requestRenderFn();\n\t}\n\n\tinvalidate(): void {}\n\n\tsetRequestRender(fn: () => void): void {\n\t\tthis.requestRenderFn = fn;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst center = (text: string) => {\n\t\t\tconst pad = Math.max(0, Math.floor((width - text.length) / 2));\n\t\t\treturn \" \".repeat(pad) + text;\n\t\t};\n\t\tconst dim = (t: string) => theme.fg(\"dim\", t);\n\t\tconst muted = (t: string) => theme.fg(\"muted\", t);\n\t\tconst accent = (t: string) => theme.fg(\"accent\", t);\n\t\tconst warning = (t: string) => theme.fg(\"warning\", t);\n\n\t\tlines.push(\"\");\n\t\tlines.push(center(accent(ASCII_LOGO)));\n\t\tlines.push(center(accent(\"Ada\") + dim(\" · coding agent · HOILAB TECH\") + muted(` v${this.version}`)));\n\t\tlines.push(\"\");\n\n\t\tif (this.phase === \"login\") {\n\t\t\t// ---- Entry screen -------------------------------------------\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(center(dim(\"Bienvenido a Ada — el agente de codificación de HOILAB TECH\")));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(center(accent(\"▸ \") + theme.bold(\"Entrar como invitado\")));\n\t\t\tlines.push(center(muted(\" Loguearme\") + dim(\" (próximamente)\")));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\tcenter(\n\t\t\t\t\tmuted(\n\t\t\t\t\t\t[\"Enter para continuar\", \"q para salir\"].join(\" · \"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn lines;\n\t\t}\n\n\t\t// ---- Home screen ------------------------------------------------\n\t\tif (this.updateAvailable) {\n\t\t\tlines.push(\n\t\t\t\tcenter(\n\t\t\t\t\twarning(\n\t\t\t\t\t\t`⚠ Nueva versión disponible: v${this.updateAvailable} ` +\n\t\t\t\t\t\t\ttheme.fg(\"accent\", \"[u] actualizar\") +\n\t\t\t\t\t\t\tdim(\" · pulsa q para ignorar\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t\tlines.push(\"\");\n\t\t} else if (this.updateChecked) {\n\t\t\tlines.push(center(dim(\"✓ Sistema actualizado\")));\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(center(dim(\"Elige una conversación o empieza una nueva:\")));\n\t\tlines.push(\"\");\n\n\t\t// \"New conversation\" option\n\t\tconst isNew = this.selectedIndex === 0;\n\t\tconst newLine = `${isNew ? accent(\"▸ \") : \" \"}${accent(\"✦\")} ${\n\t\t\tisNew ? theme.bold(\"Nueva conversación\") : \"Nueva conversación\"\n\t\t}`;\n\t\tlines.push(center(newLine));\n\t\tlines.push(center(dim(\"─\".repeat(Math.min(46, width - 4)))));\n\t\tlines.push(\"\");\n\n\t\tif (this.loading) {\n\t\t\tlines.push(center(dim(\"Cargando conversaciones…\")));\n\t\t} else if (this.filtered.length === 0) {\n\t\t\tlines.push(\n\t\t\t\tcenter(\n\t\t\t\t\tmuted(\n\t\t\t\t\t\tthis.query\n\t\t\t\t\t\t\t? \"No hay conversaciones que coincidan con tu búsqueda\"\n\t\t\t\t\t\t\t: \"Todavía no hay conversaciones anteriores\",\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tconst maxVisible = Math.max(1, Math.min(12, Math.floor((width * 2) / 3)));\n\t\t\tconst visible = this.filtered.slice(0, maxVisible);\n\t\t\tfor (let i = 0; i < visible.length; i++) {\n\t\t\t\tconst session = visible[i];\n\t\t\t\tconst isSelected = this.selectedIndex === i + 1;\n\t\t\t\tconst title = sessionTitle(session);\n\t\t\t\tconst meta = `${relativeTime(session.modified.toISOString())} · ${session.messageCount} msgs`;\n\t\t\t\tconst arrow = isSelected ? \"▸ \" : \" \";\n\t\t\t\tconst titleStyled = isSelected ? theme.bold(accent(title)) : title;\n\t\t\t\tlines.push(center(`${arrow}${titleStyled} ${muted(meta)}`));\n\t\t\t}\n\t\t\tif (this.filtered.length > maxVisible) {\n\t\t\t\tlines.push(center(dim(`… y ${this.filtered.length - maxVisible} más`)));\n\t\t\t}\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(center(dim(`Buscar: ${this.query}${this.searchInput.focused ? \"▍\" : \"\"}`)));\n\t\tlines.push(\"\");\n\t\tconst hints = [\n\t\t\t\"↑/↓ navegar\",\n\t\t\t\"Enter seleccionar\",\n\t\t\t\"n nueva\",\n\t\t\tthis.updateAvailable ? \"u actualizar\" : null,\n\t\t\t\"escribir para buscar\",\n\t\t\t\"q salir\",\n\t\t].filter((h): h is string => h !== null);\n\t\tlines.push(center(muted(hints.join(\" · \"))));\n\t\treturn lines.map((line) => truncateToWidth(line, width));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"home-screen.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/home-screen.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, Input, getKeybindings, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { SessionInfo, SessionListProgress } from \"../../../core/session-manager.ts\";\nimport { checkForNewPiVersion } from \"../../../utils/version-check.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { filterAndSortSessions } from \"./session-selector-search.ts\";\n\nexport type HomeScreenResult = { kind: \"new\" } | { kind: \"resume\"; path: string } | null;\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\nconst ASCII_LOGO = [\n\t\" █████╗ ██████╗ █████╗\",\n\t\" ██╔══██╗██╔══██╗██╔══██╗\",\n\t\" ███████║██║ ██║███████║\",\n\t\" ██╔══██║██║ ██║██╔══██║\",\n\t\" ██║ ██║██████╔╝██║ ██║\",\n\t\" ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝\",\n].join(\"\\n\");\n\n/** Vertical teal-to-gray gradient for the ASCII logo. */\nconst LOGO_GRADIENT = [\"accent\", \"accent\", \"borderAccent\", \"border\", \"borderMuted\", \"muted\"] as const;\n\n/** Draw a rounded box around centered content with an optional title. */\nfunction box(\n\tcontentLines: string[],\n\twidth: number,\n\toptions: { title?: string; color?: (str: string) => string } = {},\n): string[] {\n\tconst color = options.color ?? ((str: string) => theme.fg(\"border\", str));\n\tconst innerWidth = Math.max(10, width - 4);\n\tconst top =\n\t\toptions.title !== undefined\n\t\t\t? color(`╭─ ${options.title} `) + \"─\".repeat(Math.max(1, innerWidth - options.title.length - 2)) + color(\"─╮\")\n\t\t\t: color(`╭${\"─\".repeat(innerWidth)}╮`);\n\tconst bottom = color(`╰${\"─\".repeat(innerWidth)}╯`);\n\tconst pad = (line: string) => {\n\t\tconst visible = visibleWidth(line);\n\t\tconst left = Math.max(0, Math.floor((innerWidth - visible) / 2));\n\t\tconst right = Math.max(0, innerWidth - visible - left);\n\t\treturn color(\"│ \") + \" \".repeat(left) + line + \" \".repeat(right) + color(\" │\");\n\t};\n\treturn [top, ...contentLines.map(pad), bottom];\n}\n\nfunction sessionTitle(session: SessionInfo): string {\n\tif (session.name) return session.name;\n\tconst first = (session.firstMessage ?? \"\").replace(/\\s+/g, \" \").trim();\n\tif (first.length > 0) return first.length > 60 ? `${first.slice(0, 60)}…` : first;\n\treturn \"Conversation\";\n}\n\nfunction relativeTime(iso: string): string {\n\tconst diffMs = Date.now() - new Date(iso).getTime();\n\tconst mins = Math.floor(diffMs / 60000);\n\tif (mins < 1) return \"now\";\n\tif (mins < 60) return `${mins}m`;\n\tconst hours = Math.floor(mins / 60);\n\tif (hours < 24) return `${hours}h`;\n\tconst days = Math.floor(hours / 24);\n\tif (days < 7) return `${days}d`;\n\tif (days < 30) return `${Math.floor(days / 7)}w`;\n\treturn `${Math.floor(days / 30)}mo`;\n}\n\n/**\n * Central welcome flow (opencode style) shown when the CLI starts:\n * 1) entry screen: \"Enter as guest\" (login is disabled for now)\n * 2) home screen: welcome banner, update notice, recent conversations and\n * a \"New conversation\" action.\n */\nexport class HomeScreenComponent extends Container implements Component {\n\tprivate phase: \"login\" | \"home\" = \"login\";\n\tprivate sessions: SessionInfo[] = [];\n\tprivate filtered: SessionInfo[] = [];\n\tprivate selectedIndex = 0; // 0 = \"New conversation\", then sessions\n\tprivate query = \"\";\n\tprivate loading = false;\n\tprivate updateAvailable: string | null = null;\n\tprivate updateChecked = false;\n\tprivate searchInput: Input;\n\tprivate loadSessions: SessionsLoader;\n\tprivate version: string;\n\tprivate modelLabel: string | null = null;\n\tprivate cwdLabelValue: string | null = null;\n\tprivate memoryEnabled = true;\n\tprivate _focused = false;\n\tprivate requestRenderFn: () => void = () => {};\n\n\tpublic onNew?: () => void;\n\tpublic onResume?: (path: string) => void;\n\tpublic onExit?: () => void;\n\tpublic onUpdate?: () => void;\n\t/** Fired when the entry screen transitions to the home screen. */\n\tpublic onEnterHome?: () => void;\n\n\tsetModelLabel(label: string | null): void {\n\t\tthis.modelLabel = label;\n\t}\n\n\tsetCwdLabel(label: string): void {\n\t\tthis.cwdLabelValue = label;\n\t}\n\n\tsetMemoryEnabled(enabled: boolean): void {\n\t\tthis.memoryEnabled = enabled;\n\t}\n\n\tconstructor(loadSessions: SessionsLoader, version: string) {\n\t\tsuper();\n\t\tthis.loadSessions = loadSessions;\n\t\tthis.version = version;\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.onSubmit = () => this.confirmSelection();\n\t}\n\n\t// Focusable\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tthis.loading = true;\n\t\tthis.requestRenderFn();\n\t\ttry {\n\t\t\tthis.sessions = await this.loadSessions();\n\t\t} catch {\n\t\t\tthis.sessions = [];\n\t\t}\n\t\tthis.loading = false;\n\t\tthis.applyFilter();\n\t\tthis.requestRenderFn();\n\t}\n\n\tprivate applyFilter(): void {\n\t\tconst q = this.query.trim();\n\t\tthis.filtered = q\n\t\t\t? filterAndSortSessions(this.sessions, q, \"recent\", \"all\")\n\t\t\t: [...this.sessions].sort((a, b) => b.modified.getTime() - a.modified.getTime());\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, this.filtered.length);\n\t}\n\n\tprivate confirmSelection(): void {\n\t\tif (this.phase === \"login\") {\n\t\t\tthis.enterHome();\n\t\t\treturn;\n\t\t}\n\t\tif (this.selectedIndex === 0) {\n\t\t\tthis.onNew?.();\n\t\t} else {\n\t\t\tconst session = this.filtered[this.selectedIndex - 1];\n\t\t\tif (session) this.onResume?.(session.path);\n\t\t}\n\t}\n\n\tprivate enterHome(): void {\n\t\tthis.phase = \"home\";\n\t\tthis.selectedIndex = 0;\n\t\tthis.onEnterHome?.();\n\t\tvoid this.reload();\n\t\tvoid this.checkUpdate();\n\t}\n\n\tprivate async checkUpdate(): Promise<void> {\n\t\tif (this.updateChecked) return;\n\t\tthis.updateChecked = true;\n\t\ttry {\n\t\t\tconst release = await checkForNewPiVersion(this.version);\n\t\t\tif (release) {\n\t\t\t\tthis.updateAvailable = release.version;\n\t\t\t\tthis.requestRenderFn();\n\t\t\t}\n\t\t} catch {\n\t\t\t// Offline or unreachable — ignore silently.\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (this.phase === \"login\") {\n\t\t\tif (kb.matches(data, \"tui.select.confirm\") || data === \"\\r\" || data === \"\\n\") {\n\t\t\t\tthis.enterHome();\n\t\t\t} else if (kb.matches(data, \"tui.select.cancel\") || data === \"q\" || data === \"Q\") {\n\t\t\t\tthis.onExit?.();\n\t\t\t} else if (kb.matches(data, \"tui.select.down\")) {\n\t\t\t\t// Only one actionable option on the login screen; ignore.\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.requestRenderFn();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filtered.length, this.selectedIndex + 1);\n\t\t\tthis.requestRenderFn();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.confirm\") || data === \"\\r\" || data === \"\\n\") {\n\t\t\tthis.confirmSelection();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \"n\" || data === \"N\") {\n\t\t\tthis.onNew?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \"u\" || data === \"U\") {\n\t\t\tif (this.updateAvailable) {\n\t\t\t\tthis.onUpdate?.();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (data === \"q\" || data === \"Q\") {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\t// Anything else goes to the search input (filters sessions)\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.query = this.searchInput.getValue();\n\t\tthis.applyFilter();\n\t\tthis.requestRenderFn();\n\t}\n\n\tinvalidate(): void {}\n\n\tsetRequestRender(fn: () => void): void {\n\t\tthis.requestRenderFn = fn;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst center = (text: string) => {\n\t\t\tconst pad = Math.max(0, Math.floor((width - visibleWidth(text)) / 2));\n\t\t\treturn \" \".repeat(pad) + text;\n\t\t};\n\t\tconst dim = (t: string) => theme.fg(\"dim\", t);\n\t\tconst muted = (t: string) => theme.fg(\"muted\", t);\n\t\tconst accent = (t: string) => theme.fg(\"accent\", t);\n\t\tconst border = (t: string) => theme.fg(\"border\", t);\n\t\tconst success = (t: string) => theme.fg(\"success\", t);\n\t\tconst warning = (t: string) => theme.fg(\"warning\", t);\n\n\t\t// Gradient logo (teal -> gray)\n\t\tconst logoLines = ASCII_LOGO.split(\"\\n\").map((line, i) =>\n\t\t\ttheme.fg(LOGO_GRADIENT[Math.min(i, LOGO_GRADIENT.length - 1)], line),\n\t\t);\n\t\tconst tagline =\n\t\t\taccent(\"Ada\") + dim(\" · coding agent · HOILAB TECH\") + muted(` v${this.version}`);\n\n\t\tlines.push(\"\");\n\n\t\tif (this.phase === \"login\") {\n\t\t\t// ---- Entry screen -------------------------------------------\n\t\t\tconst boxW = Math.min(56, width - 4);\n\t\t\tconst boxLines = box(\n\t\t\t\t[\n\t\t\t\t\t\"\",\n\t\t\t\t\t...logoLines,\n\t\t\t\t\ttagline,\n\t\t\t\t\t\"\",\n\t\t\t\t\tdim(\"Bienvenido a Ada — el agente de codificación de HOILAB TECH\"),\n\t\t\t\t\t\"\",\n\t\t\t\t\taccent(\"▸ \") + theme.bold(\"Entrar como invitado\"),\n\t\t\t\t\tmuted(\" Loguearme\") + dim(\" (próximamente)\"),\n\t\t\t\t\t\"\",\n\t\t\t\t],\n\t\t\t\tboxW,\n\t\t\t\t{ title: \" ✦ HOILAB TECH ✦ \" },\n\t\t\t);\n\t\t\tlines.push(...boxLines);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(center(success(\"●\") + dim(\" En línea · sin conexión a cuentas\") + muted(\" · todo queda en tu máquina\")));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\tcenter(muted([\"Enter para continuar\", \"q para salir\"].join(\" · \"))),\n\t\t\t);\n\t\t\treturn this.finishRender(lines, width);\n\t\t}\n\n\t\t// ---- Home screen ------------------------------------------------\n\t\tconst boxW = Math.min(58, width - 4);\n\n\t\t// Header box: logo + status\n\t\tconst statusParts = [\n\t\t\tdim(`model: ${this.defaultModelLabel()}`),\n\t\t\tdim(`cwd: ${this.cwdLabel()}`),\n\t\t\tdim(`memoria: ${this.memoryLabel()}`),\n\t\t];\n\t\tlines.push(...box([\"\", ...logoLines, tagline, \"\", ...statusParts, \"\"], boxW, { title: \" ✦ HOILAB TECH ✦ \" }));\n\t\tlines.push(\"\");\n\n\t\t// Update notice\n\t\tif (this.updateAvailable) {\n\t\t\tlines.push(\n\t\t\t\tcenter(\n\t\t\t\t\twarning(\n\t\t\t\t\t\t`⚠ Nueva versión disponible: v${this.updateAvailable} ` +\n\t\t\t\t\t\t\taccent(\"[u] actualizar\") +\n\t\t\t\t\t\t\tdim(\" · q para ignorar\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (this.updateChecked) {\n\t\t\tlines.push(center(success(\"✓ Sistema actualizado\")));\n\t\t}\n\t\tlines.push(\"\");\n\n\t\t// Conversations box\n\t\tconst convLines: string[] = [\"\"];\n\t\tconst isNew = this.selectedIndex === 0;\n\t\tconvLines.push(\n\t\t\t`${isNew ? accent(\"▸ \") : \" \"}${accent(\"✦\")} ${isNew ? theme.bold(\"Nueva conversación\") : \"Nueva conversación\"}`,\n\t\t);\n\t\tconvLines.push(dim(\"─\".repeat(Math.max(4, boxW - 6))));\n\t\tconvLines.push(\"\");\n\n\t\tif (this.loading) {\n\t\t\tconvLines.push(dim(\"Cargando conversaciones…\"));\n\t\t} else if (this.filtered.length === 0) {\n\t\t\tconvLines.push(\n\t\t\t\tmuted(\n\t\t\t\t\tthis.query\n\t\t\t\t\t\t? \"No hay conversaciones que coincidan con tu búsqueda\"\n\t\t\t\t\t\t: \"Todavía no hay conversaciones anteriores\",\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tconst maxVisible = Math.max(1, Math.min(12, Math.floor((width * 2) / 3)));\n\t\t\tconst visible = this.filtered.slice(0, maxVisible);\n\t\t\tfor (let i = 0; i < visible.length; i++) {\n\t\t\t\tconst session = visible[i];\n\t\t\t\tconst isSelected = this.selectedIndex === i + 1;\n\t\t\t\tconst title = sessionTitle(session);\n\t\t\t\tconst meta = muted(\n\t\t\t\t\t`${relativeTime(session.modified.toISOString())} · ${session.messageCount} msgs`,\n\t\t\t\t);\n\t\t\t\tconst arrow = isSelected ? accent(\"▸ \") : \" \";\n\t\t\t\tconst titleStyled = isSelected ? theme.bold(accent(title)) : title;\n\t\t\t\tconvLines.push(`${arrow}${titleStyled} ${meta}`);\n\t\t\t}\n\t\t\tif (this.filtered.length > maxVisible) {\n\t\t\t\tconvLines.push(dim(`… y ${this.filtered.length - maxVisible} más`));\n\t\t\t}\n\t\t}\n\t\tconvLines.push(\"\");\n\t\tlines.push(...box(convLines, boxW, { title: \" Conversaciones \" }));\n\t\tlines.push(\"\");\n\n\t\t// Search + hints\n\t\tlines.push(center(accent(\"🔎\") + dim(` Buscar: ${this.query}${this.searchInput.focused ? \"▍\" : \"\"}`)));\n\t\tlines.push(\"\");\n\t\tconst hints = [\n\t\t\t\"↑/↓ navegar\",\n\t\t\t\"Enter seleccionar\",\n\t\t\t\"n nueva\",\n\t\t\tthis.updateAvailable ? \"u actualizar\" : null,\n\t\t\t\"escribir para buscar\",\n\t\t\t\"q salir\",\n\t\t].filter((h): h is string => h !== null);\n\t\tlines.push(\n\t\t\tborder(\"─\".repeat(Math.min(52, width - 8))) ,\n\t\t);\n\t\tlines.push(center(muted(hints.join(\" · \"))));\n\t\treturn this.finishRender(lines, width);\n\t}\n\n\t/** Vertical centering + truncation of every rendered line. */\n\tprivate finishRender(lines: string[], width: number): string[] {\n\t\tconst rows = process.stdout.rows ?? 24;\n\t\tconst contentHeight = lines.length;\n\t\tconst topPad = Math.max(0, Math.floor((rows - contentHeight) / 2) - 1);\n\t\treturn [...Array<string>(topPad).fill(\"\"), ...lines.map((line) => truncateToWidth(line, width))];\n\t}\n\n\tprivate defaultModelLabel(): string {\n\t\treturn this.modelLabel ?? \"no configurado (/model)\";\n\t}\n\n\tprivate cwdLabel(): string {\n\t\treturn this.cwdLabelValue ?? process.cwd();\n\t}\n\n\tprivate memoryLabel(): string {\n\t\treturn this.memoryEnabled ? \"activada\" : \"desactivada\";\n\t}\n}\n"]}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoilab/ada-cli",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.10",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@hoilab/ada-cli",
|
|
9
|
-
"version": "0.84.
|
|
9
|
+
"version": "0.84.10",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@earendil-works/pi-agent-core": "^0.84.2",
|
package/package.json
CHANGED