Phase 2: Refactor Tasks cluster to MCP SDK types

Replace ad hoc TaskCardProps data shape with SDK Task type across the
Tasks group components and TasksScreen.

- TaskCard: accept `task: Task` instead of flat props (taskId, status,
  method, target, progress, etc.); derive all display fields from the
  SDK Task object (taskId, status, ttl, createdAt, lastUpdatedAt,
  statusMessage); remove fields not present on SDK Task (method, target,
  progress as number, error, completedAt, elapsed)
- TaskControls: type statusFilter as `TaskStatus | undefined`; add
  runtime validation guard on Select onChange
- TaskListPanel: accept `Task[]` instead of `TaskCardProps[]`; pass
  `onCancel(taskId)` through to each TaskCard; use `task.taskId` as key
- TasksScreen: accept `Task[]` + `onCancel(taskId)` callback; type
  internal statusFilter state as `TaskStatus | undefined`
- Delete re-export of `TaskStatus` from TaskCard (import directly from
  SDK where needed)
- Update all stories with real SDK `Task` fixtures
- Update ConnectedView TasksActive story

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-20 10:28:24 -04:00
commit 6abb39a5fe

View file

@ -1,4 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import type { Task } from "@modelcontextprotocol/sdk/types.js";
import { fn } from "storybook/test";
import { TaskCard } from "./TaskCard";
@ -14,84 +15,71 @@ const meta: Meta<typeof TaskCard> = {
export default meta;
type Story = StoryObj<typeof TaskCard>;
const workingTask: Task = {
taskId: "d0b22eba71fa36229ce5c4dfadeaa7de",
status: "working",
ttl: 300000,
createdAt: "2026-03-29T20:18:20Z",
lastUpdatedAt: "2026-03-29T20:18:22Z",
statusMessage: "Synthesizing findings...",
};
const inputRequiredTask: Task = {
taskId: "4100b5e0b0ed9cd0023330342d1bf647",
status: "input_required",
ttl: 300000,
createdAt: "2026-03-29T20:17:55Z",
lastUpdatedAt: "2026-03-29T20:17:55Z",
statusMessage: "Waiting for user confirmation",
};
const completedTask: Task = {
taskId: "d487b49aa39023d907b5a2a5b506cb3",
status: "completed",
ttl: 300000,
createdAt: "2026-03-29T20:16:47Z",
lastUpdatedAt: "2026-03-29T20:16:51Z",
statusMessage: "Report generated successfully",
};
const failedTask: Task = {
taskId: "e6ebffd9cca84ddd1646d3c579a4d453",
status: "failed",
ttl: 300000,
createdAt: "2026-03-29T20:17:27Z",
lastUpdatedAt: "2026-03-29T20:17:28Z",
statusMessage:
"Connection refused: upstream server not responding after 3 retries",
};
const cancelledTask: Task = {
taskId: "c416bc183cb04468d3f81696f1b868f6",
status: "cancelled",
ttl: 300000,
createdAt: "2026-03-29T20:18:15Z",
lastUpdatedAt: "2026-03-29T20:18:18Z",
};
export const Working: Story = {
args: {
taskId: "d0b22eba71fa36229ce5c4dfadeaa7de",
status: "working",
method: "tools/call",
target: "generate_report",
progress: 80,
progressDescription: "Synthesizing findings...",
startedAt: "3/29/2026, 8:18:20 PM",
lastUpdated: "3/29/2026, 8:18:22 PM",
ttl: 300000,
},
args: { task: workingTask },
};
export const InputRequired: Story = {
args: {
taskId: "4100b5e0b0ed9cd0023330342d1bf647",
status: "input_required",
method: "resources/read",
target: "file:///data/report.csv",
startedAt: "3/29/2026, 8:17:55 PM",
lastUpdated: "3/29/2026, 8:17:55 PM",
ttl: 300000,
},
args: { task: inputRequiredTask },
};
export const Completed: Story = {
args: {
taskId: "d487b49aa39023d907b5a2a5b506cb3",
status: "completed",
method: "tools/call",
target: "generate_summary",
startedAt: "3/29/2026, 8:16:47 PM",
completedAt: "3/29/2026, 8:16:51 PM",
lastUpdated: "3/29/2026, 8:16:51 PM",
ttl: 300000,
progressDescription: "Generating report...",
},
args: { task: completedTask },
};
export const Failed: Story = {
args: {
taskId: "e6ebffd9cca84ddd1646d3c579a4d453",
status: "failed",
method: "tools/call",
target: "fetch_remote_data",
startedAt: "3/29/2026, 8:17:27 PM",
completedAt: "3/29/2026, 8:17:28 PM",
lastUpdated: "3/29/2026, 8:17:28 PM",
ttl: 300000,
error: "Connection refused: upstream server not responding after 3 retries",
},
args: { task: failedTask },
};
export const Cancelled: Story = {
args: {
taskId: "c416bc183cb04468d3f81696f1b868f6",
status: "cancelled",
method: "tools/call",
target: "long_running_analysis",
startedAt: "3/29/2026, 8:18:15 PM",
completedAt: "3/29/2026, 8:18:18 PM",
lastUpdated: "3/29/2026, 8:18:18 PM",
ttl: 300000,
},
args: { task: cancelledTask },
};
export const Collapsed: Story = {
args: {
taskId: "d0b22eba71fa36229ce5c4dfadeaa7de",
status: "working",
method: "tools/call",
target: "generate_report",
progress: 80,
progressDescription: "Synthesizing findings...",
startedAt: "3/29/2026, 8:18:20 PM",
lastUpdated: "3/29/2026, 8:18:22 PM",
ttl: 300000,
isListExpanded: false,
},
args: { task: workingTask, isListExpanded: false },
};