Phase 2: Refactor History cluster to use MessageEntry

Replace ad hoc flat props with MessageEntry from core/mcp/types.ts
across the History group components and HistoryScreen.

- HistoryEntry: accept `entry: MessageEntry` instead of flat props
  (timestamp, method, target, status, durationMs, parameters, response);
  derive method/target/status from embedded JSON-RPC objects; fix
  Collapse animation by removing outer {isExpanded && ...} wrapper;
  drop childEntries (not part of MessageEntry)
- HistoryControls: type onMethodFilterChange as (string | undefined)
- HistoryListPanel: accept `MessageEntry[]` + `pinnedIds: Set<string>`
  instead of separate entries/pinnedEntries arrays with pre-bound
  callbacks; pass onReplay/onTogglePin by entry ID
- HistoryScreen: accept `MessageEntry[]` + `pinnedIds` + ID-based
  callbacks; collapse two-array model into single list with pinned
  overlay
- Delete local HistoryEntryProps data shape, HistoryChildEntry type
- Update all stories with real JSON-RPC MessageEntry fixtures
- Update ConnectedView HistoryActive story

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-20 16:55:23 -04:00
commit f104e6e21a

View file

@ -599,79 +599,98 @@ export const HistoryActive: Story = {
<HistoryScreen
entries={[
{
timestamp: "2026-03-17T10:00:00Z",
method: "tools/call",
target: "send_message",
status: "success",
durationMs: 120,
parameters: { message: "Hello, world!" },
response: { result: "Message sent successfully" },
isPinned: false,
isListExpanded: false,
onReplay: fn(),
onTogglePin: fn(),
},
{
timestamp: "2026-03-17T10:01:00Z",
method: "resources/read",
target: "config.json",
status: "success",
durationMs: 45,
parameters: { uri: "file:///config.json" },
response: {
contents: [{ uri: "file:///config.json", text: "{}" }],
id: "req-1",
timestamp: new Date("2026-03-17T10:00:00Z"),
direction: "request" as const,
message: {
jsonrpc: "2.0" as const,
id: 1,
method: "tools/call",
params: {
name: "send_message",
arguments: { message: "Hello, world!" },
},
},
isPinned: false,
isListExpanded: false,
onReplay: fn(),
onTogglePin: fn(),
response: {
jsonrpc: "2.0" as const,
id: 1,
result: {
content: [{ type: "text", text: "Message sent successfully" }],
},
},
duration: 120,
},
{
timestamp: "2026-03-17T10:02:00Z",
method: "tools/call",
target: "delete_records",
status: "error",
durationMs: 350,
parameters: { ids: [1, 2, 3] },
response: { error: "Permission denied" },
isPinned: false,
isListExpanded: true,
onReplay: fn(),
onTogglePin: fn(),
},
]}
pinnedEntries={[
{
timestamp: "2026-03-17T09:30:00Z",
method: "tools/list",
status: "success",
durationMs: 80,
response: { tools: ["send_message", "list_users"] },
isPinned: true,
isListExpanded: false,
onReplay: fn(),
onTogglePin: fn(),
},
{
timestamp: "2026-03-17T09:35:00Z",
method: "prompts/get",
target: "greeting",
status: "success",
durationMs: 60,
parameters: { name: "greeting" },
response: {
messages: [
{ role: "user", content: { type: "text", text: "Hello!" } },
],
},
isPinned: true,
isListExpanded: false,
onReplay: fn(),
onTogglePin: fn(),
id: "req-2",
timestamp: new Date("2026-03-17T10:01:00Z"),
direction: "request" as const,
message: {
jsonrpc: "2.0" as const,
id: 2,
method: "resources/read",
params: { uri: "file:///config.json" },
},
response: {
jsonrpc: "2.0" as const,
id: 2,
result: {
contents: [{ uri: "file:///config.json", text: "{}" }],
},
},
duration: 45,
},
{
id: "req-3",
timestamp: new Date("2026-03-17T10:02:00Z"),
direction: "request" as const,
message: {
jsonrpc: "2.0" as const,
id: 3,
method: "tools/call",
params: { name: "delete_records", arguments: { ids: [1, 2, 3] } },
},
response: {
jsonrpc: "2.0" as const,
id: 3,
error: { code: -32000, message: "Permission denied" },
},
duration: 350,
},
{
id: "req-4",
timestamp: new Date("2026-03-17T09:30:00Z"),
direction: "request" as const,
message: { jsonrpc: "2.0" as const, id: 4, method: "tools/list" },
response: { jsonrpc: "2.0" as const, id: 4, result: { tools: [] } },
duration: 80,
},
{
id: "req-5",
timestamp: new Date("2026-03-17T09:35:00Z"),
direction: "request" as const,
message: {
jsonrpc: "2.0" as const,
id: 5,
method: "prompts/get",
params: { name: "greeting" },
},
response: {
jsonrpc: "2.0" as const,
id: 5,
result: {
messages: [
{ role: "user", content: { type: "text", text: "Hello!" } },
],
},
},
duration: 60,
},
]}
pinnedIds={new Set(["req-4", "req-5"])}
onClearAll={fn()}
onExport={fn()}
onReplay={fn()}
onTogglePin={fn()}
/>
),
},