fix: adjust task progress panel height and improve effective todos handling in agent info panel

- Reduced the maximum height of the task progress panel from 300px to 200px for better UI consistency.
- Introduced a new `effectiveTodos` calculation in the agent info panel to correctly display tasks from `planSpec` when available, ensuring accurate task counts and statuses.
- Updated references to use `effectiveTodos` instead of the original `agentInfo.todos` for task display logic in the agent info panel.
- Adjusted the height of various modal components to align with the new task progress panel height.
This commit is contained in:
Shirone
2026-01-14 21:02:24 +01:00
parent ca3286a374
commit ca0f3ecedf
3 changed files with 31 additions and 15 deletions

View File

@@ -230,7 +230,7 @@ export function TaskProgressPanel({
)}
>
<div className="overflow-hidden">
<div className="p-4 pt-2 relative max-h-[300px] overflow-y-auto scrollbar-visible">
<div className="p-4 pt-2 relative max-h-[200px] overflow-y-auto scrollbar-visible">
{/* Vertical Connector Line */}
<div className="absolute left-[2.35rem] top-4 bottom-8 w-px bg-linear-to-b from-border/80 via-border/40 to-transparent" />

View File

@@ -1,6 +1,6 @@
// @ts-nocheck
import { useEffect, useState } from 'react';
import { Feature, ThinkingLevel } from '@/store/app-store';
import { useEffect, useState, useMemo } from 'react';
import { Feature, ThinkingLevel, ParsedTask } from '@/store/app-store';
import type { ReasoningEffort } from '@automaker/types';
import { getProviderFromModel } from '@/lib/utils';
import {
@@ -72,6 +72,22 @@ export function AgentInfoPanel({
const [isSummaryDialogOpen, setIsSummaryDialogOpen] = useState(false);
const [isTodosExpanded, setIsTodosExpanded] = useState(false);
// Derive effective todos from planSpec.tasks when available, fallback to agentInfo.todos
// This fixes the issue where Kanban cards show "0/0 tasks" when the agent uses planSpec
// instead of emitting TodoWrite tool calls in the output log
const effectiveTodos = useMemo(() => {
// First priority: use planSpec.tasks if available (modern approach)
if (feature.planSpec?.tasks && feature.planSpec.tasks.length > 0) {
return feature.planSpec.tasks.map((task: ParsedTask) => ({
content: task.description,
// Map 'failed' status to 'pending' since todo display doesn't support 'failed'
status: task.status === 'failed' ? 'pending' : task.status,
}));
}
// Fallback: use parsed agentInfo.todos from agent-output.md
return agentInfo?.todos || [];
}, [feature.planSpec?.tasks, agentInfo?.todos]);
useEffect(() => {
const loadContext = async () => {
if (contextContent) {
@@ -189,13 +205,13 @@ export function AgentInfoPanel({
</div>
{/* Task List Progress */}
{agentInfo.todos.length > 0 && (
{effectiveTodos.length > 0 && (
<div className="space-y-1">
<div className="flex items-center gap-1 text-[10px] text-muted-foreground/70">
<ListTodo className="w-3 h-3" />
<span>
{agentInfo.todos.filter((t) => t.status === 'completed').length}/
{agentInfo.todos.length} tasks
{effectiveTodos.filter((t) => t.status === 'completed').length}/
{effectiveTodos.length} tasks
</span>
</div>
<div
@@ -204,7 +220,7 @@ export function AgentInfoPanel({
isTodosExpanded ? 'max-h-40' : 'max-h-16'
)}
>
{(isTodosExpanded ? agentInfo.todos : agentInfo.todos.slice(0, 3)).map(
{(isTodosExpanded ? effectiveTodos : effectiveTodos.slice(0, 3)).map(
(todo, idx) => (
<div key={idx} className="flex items-center gap-1.5 text-[10px]">
{todo.status === 'completed' ? (
@@ -227,7 +243,7 @@ export function AgentInfoPanel({
</div>
)
)}
{agentInfo.todos.length > 3 && (
{effectiveTodos.length > 3 && (
<button
onClick={(e) => {
e.stopPropagation();
@@ -237,7 +253,7 @@ export function AgentInfoPanel({
onMouseDown={(e) => e.stopPropagation()}
className="text-[10px] text-muted-foreground/60 pl-4 hover:text-muted-foreground transition-colors cursor-pointer"
>
{isTodosExpanded ? 'Show less' : `+${agentInfo.todos.length - 3} more`}
{isTodosExpanded ? 'Show less' : `+${effectiveTodos.length - 3} more`}
</button>
)}
</div>
@@ -286,10 +302,10 @@ export function AgentInfoPanel({
<Wrench className="w-2.5 h-2.5" />
{agentInfo.toolCallCount} tool calls
</span>
{agentInfo.todos.length > 0 && (
{effectiveTodos.length > 0 && (
<span className="flex items-center gap-1">
<CheckCircle2 className="w-2.5 h-2.5 text-[var(--status-success)]" />
{agentInfo.todos.filter((t) => t.status === 'completed').length} tasks done
{effectiveTodos.filter((t) => t.status === 'completed').length} tasks done
</span>
)}
</div>

View File

@@ -380,11 +380,11 @@ export function AgentOutputModal({
<TaskProgressPanel
featureId={featureId}
projectPath={projectPath}
className="flex-shrink-0 mx-1"
className="shrink mx-1"
/>
{effectiveViewMode === 'changes' ? (
<div className="flex-1 min-h-0 sm:min-h-[400px] sm:max-h-[60vh] overflow-y-auto scrollbar-visible">
<div className="flex-1 min-h-0 sm:min-h-[200px] sm:max-h-[60vh] overflow-y-auto scrollbar-visible">
{projectPath ? (
<GitDiffPanel
projectPath={projectPath}
@@ -401,7 +401,7 @@ export function AgentOutputModal({
)}
</div>
) : effectiveViewMode === 'summary' && summary ? (
<div className="flex-1 min-h-0 sm:min-h-[400px] sm:max-h-[60vh] overflow-y-auto bg-card border border-border/50 rounded-lg p-4 scrollbar-visible">
<div className="flex-1 min-h-0 sm:min-h-[200px] sm:max-h-[60vh] overflow-y-auto bg-card border border-border/50 rounded-lg p-4 scrollbar-visible">
<Markdown>{summary}</Markdown>
</div>
) : (
@@ -409,7 +409,7 @@ export function AgentOutputModal({
<div
ref={scrollRef}
onScroll={handleScroll}
className="flex-1 min-h-0 sm:min-h-[400px] sm:max-h-[60vh] overflow-y-auto bg-zinc-950 rounded-lg p-4 font-mono text-xs scrollbar-visible"
className="flex-1 min-h-0 sm:min-h-[200px] sm:max-h-[60vh] overflow-y-auto bg-zinc-950 rounded-lg p-4 font-mono text-xs scrollbar-visible"
>
{isLoading && !output ? (
<div className="flex items-center justify-center h-full text-muted-foreground">