Files
oh-my-pi/packages/coding-agent/src/modes/components/todo-reminder.ts
T

56 lines
1.6 KiB
TypeScript

import { Box, Container, Spacer, Text } from "@oh-my-pi/pi-tui";
import { theme } from "../../modes/theme/theme";
import type { TodoItem } from "../../tools/todo";
/**
* Component that renders a todo completion reminder notification, committed into
* the transcript like a TTSR notification so it stays anchored in history rather
* than floating above the editor.
* Shows when the agent stops with incomplete todos.
*/
export class TodoReminderComponent extends Container {
#box: Box;
#toolActivityVisible = true;
constructor(
private readonly todos: TodoItem[],
private readonly attempt: number,
private readonly maxAttempts: number,
) {
super();
this.addChild(new Spacer(1));
this.#box = new Box(1, 1, t => theme.inverse(theme.fg("warning", t)));
this.#box.setIgnoreTight(true);
this.addChild(this.#box);
this.#rebuild();
}
setToolActivityVisible(visible: boolean): void {
if (this.#toolActivityVisible === visible) return;
this.#toolActivityVisible = visible;
this.invalidate();
}
override render(width: number): readonly string[] {
if (!this.#toolActivityVisible) return [];
return super.render(width);
}
#rebuild(): void {
this.#box.clear();
const count = this.todos.length;
const label = count === 1 ? "todo" : "todos";
const header = `${theme.icon.warning} ${count} incomplete ${label} - reminder ${this.attempt}/${this.maxAttempts}`;
this.#box.addChild(new Text(header, 0, 0));
this.#box.addChild(new Spacer(1));
const todoList = this.todos.map(todo => ` ${theme.checkbox.unchecked} ${todo.content}`).join("\n");
this.#box.addChild(new Text(theme.italic(todoList), 0, 0));
}
}