All blocks
Block
AI-driven plan
The agent emits a todo list, then walks it. The thinking bar narrates the active step; pk-todo-list ticks each item off as it lands. The user can also click items to override the agent. Once everything is done the list auto-collapses.
Agent plans → executes → checks off
// AI-driven plan: model emits a todo list, walks it, and the user can intervene.
@if (state() === 'planning' || state() === 'executing') {
<pk-thinking-bar
[text]="currentLabel()"
stopLabel="Stop"
[showStop]="true"
(stopped)="stop()"
/>
}
@if (items().length > 0) {
<pk-todo-list
title="plan steps"
[items]="items()"
(toggled)="onUserToggle($event)"
(allCompleted)="onAllDone()"
/>
}
// Component
const PLAN = [
{ id: 'fetch', label: 'Fetch the open issue list', durationMs: 900 },
{ id: 'group', label: 'Group by label and priority', durationMs: 1100 },
{ id: 'draft', label: 'Draft the weekly status update', durationMs: 1300 },
{ id: 'post', label: 'Post the update to #engineering', durationMs: 800 },
];
protected readonly items = signal<PkTodoItem[]>([]);
protected readonly state = signal<'idle' | 'planning' | 'executing' | 'done'>('idle');
protected run(): void {
this.state.set('planning');
// Phase 1 — agent emits each plan item with a small delay
let i = 0;
const emit = () => {
if (i >= PLAN.length) {
this.state.set('executing');
this.runStep(0);
return;
}
this.items.update(list => [...list, { ...PLAN[i++], done: false }]);
setTimeout(emit, 350);
};
setTimeout(emit, 400);
}
private runStep(index: number): void {
if (index >= PLAN.length) { this.state.set('done'); return; }
const step = PLAN[index];
setTimeout(() => {
this.items.update(list =>
list.map(it => it.id === step.id ? { ...it, done: true } : it)
);
this.runStep(index + 1);
}, step.durationMs);
}
// User can also override the agent
protected onUserToggle(item: PkTodoItem): void {
this.items.update(list =>
list.map(it => it.id === item.id ? { ...it, done: !it.done } : it)
);
}