- ToolsScreen.fixtures.ts: replace empty `{}` schemas in query_database
params and post_request body with explicit `type` for consistency
- ToolControls WithSearch story: add play function that types "git" so
the story actually demonstrates filtering
- ResourcesScreen stories: comment expandUserProfileTemplate to document
the userId/readUserProfileState.uri coupling
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Selecting a resource now clears the active template selection (and vice
versa), so the right-hand panel reflects what the user just clicked.
The template's Read Resource button still only sets the resource URI,
preserving the template-with-preview layout for the read flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extract a 20-tool fixture (filesystem, database, git, http, misc) into
ToolsScreen.fixtures.ts — large enough that the ToolControls list scrolls
and the Tools tab in InspectorView shows realistic surface area.
Wire it into the Default stories of both ToolControls and InspectorView,
mirroring the LoggingScreen.fixtures.ts pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ToolsScreen, PromptsScreen, and ResourcesScreen each tracked the user's
current selection via `selectedXxxName` / `onSelectXxx` props, hoisting
screen-local UI state into whatever rendered them. InspectorView never
threaded those callbacks anywhere, so clicks in the controls panel did
not display the matching detail panel — the detail panel only rendered
if a parent fed selection back in.
Move selection into `useState` inside each screen and drop the
`selectedXxxName` / `onSelectXxx` props. MCP-derived data (`callState`,
`getPromptState`, `readState`) keeps flowing in from `InspectorView` as
props. ResourcesScreen wraps `onReadResource` so a template-expanded URI
becomes the selected resource for preview rendering.
Update each screen's stories to drop the deleted props. Stories that
need a pre-selected item use a `play` function to click it — no
component coupling to Storybook.
Add Phase 4.3 to the interfaces plan describing the rule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Extract `mixedEntries` (50 mixed-level log entries) into
`LoggingScreen.fixtures.ts` so both `LoggingScreen.stories` and
`InspectorView.stories` can consume it. The InspectorView Default story
now shows a populated, scrollable Logs tab.
- InspectorView screen transitions: separate enter (350ms) and exit (250ms)
durations via Mantine Transition's `exitDuration` prop, so screens leave
faster than they enter.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- InspectorView: simulate the connect flow through "connecting" with a
randomized 50-500ms handshake delay and an 85% success rate. On success,
measure observed latency from connect start; on failure, set a plausible
error message. Connection error message flows through to the active
ServerCard's connection state. Real wiring (Phase 3) replaces this with
`useConnection`.
- InspectorView: document that the view owns connection state (input
`serversInput` connection fields are intentionally ignored), and mark
`noop` callbacks as Phase-3 stubs.
- ServerStatusIndicator: add `showLabel?: boolean` escape hatch so consumers
in constrained containers can override the default viewport-based
visibility.
- ServerListScreen.stories: add `WithActiveServer` story exercising the
dimming + `inert` behaviour in isolation.
- ViewHeader.stories: rename "Logging" → "Logs" to match `ALL_TABS` in
InspectorView.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Distinguishes server `id` (the unique map key in MCPConfig.mcpServers)
from `name` (display label) so containers can dispatch by id without
relying on display strings. ServerCard, ConnectionToggle, ServerListScreen,
and supporting stories all updated.
- ServerCard: add `id` prop; all action callbacks now `(id: string) => void`
- ConnectionToggle: collapse `onConnect`/`onDisconnect` into single `onToggle`
- ServerListScreen: lift `activeServer` to a prop; combine `onSetActive` +
`onToggleConnection` into a single `onToggleConnection(id)` callback
- Stories: use UUIDs for server ids so callbacks visibly carry ids, not names
Removes the "Direct"/"Via Proxy" connection mode concept, which is no
longer planned. ServerSettingsForm drops the section, ServerCard drops
the badge, InspectorServerSettings drops the field.
Removes the "Test Client Features" dropdown from ServerCard along with
its four handlers; that surface will live elsewhere.
TransportBadge now collapses `sse` and `streamable-http` into a single
"HTTP" label; ServerCard adds a grey transport descriptor next to the
badge ("Standard I/O", "SSE (Server Sent Events) [deprecated]",
"Streamable HTTP"). The version badge moves from the header row to sit
beside the transport badge.
ServerCard header no longer wraps; long server names truncate with
ellipsis.
Specification docs (`v2_scope.md`, `v2_screenshots.md`,
`v2_ux_interfaces.md`, `v2_ux_storybook.md`) updated to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ServerCard: Replace flat scalar props (name, version, transport, status,
error) with grouped objects (config: MCPServerConfig, info?: Implementation,
connection: ConnectionState). Remove auto-connect useEffect — dumb
components must not self-dispatch side effects. Derive transport and
command/url from config.
ServerInfoContent: Replace flat props with initializeResult: InitializeResult
and clientCapabilities: ClientCapabilities from MCP SDK. Derive capability
lists by iterating the ServerCapabilities record.
ServerSettingsForm: Collapse flat setting props (connectionMode, headers,
metadata, timeouts, oauth*) into settings: InspectorServerSettings. Add
InspectorServerSettings type to core/mcp/types.ts.
ImportServerJsonPanel: Replace scattered scalar props (jsonContent,
selectedPackageIndex, serverName) with draft: InspectorServerJsonDraft.
ViewHeader: Replace serverName: string with serverInfo: Implementation.
Use ConnectionStatus from core types.
ConnectedView: Update to pass serverInfo: Implementation instead of
serverName. Use ConnectionStatus type.
Update all stories for ServerCard, ServerInfoContent, ServerSettingsForm,
ImportServerJsonPanel, ViewHeader, ServerListScreen, ConnectedView, and
UnconnectedView.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add three new stories showing sampling/elicitation flows overlaid
on the ToolsScreen via Mantine Modal:
- WithSamplingModal: SamplingRequestPanel in a modal during tool execution
- WithElicitationModal: ElicitationFormPanel in a modal during tool execution
- WithPendingRequests: PendingClientRequests with inline sampling and
elicitation cards in a modal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Progress notifications arrive separately from the Task object, so the
parent provides a map of progress data keyed by taskId. TaskListPanel
and TasksScreen accept an optional progressByTaskId prop and pass the
matching entry to each TaskCard.
Updated Mixed story and ConnectedView TasksActive story to demonstrate
the progress bar on the active "working" task.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Replace string-typed log levels with SDK LoggingLevel across the Logs
group components and LoggingScreen.
- LogControls: type currentLevel, visibleLevels, and all handlers with
LoggingLevel instead of string; type LOG_LEVELS array and LEVEL_COLORS
record with LoggingLevel
- LogStreamPanel: type visibleLevels as Record<LoggingLevel, boolean>
instead of Record<string, boolean>
- LoggingScreen: type currentLevel, onSetLevel, visibleLevels state,
and toggle handlers with LoggingLevel; extract NO_LEVELS_VISIBLE as
a module-level constant
- Stories already used LoggingLevel literals; updated type annotations
to use Record<LoggingLevel, boolean>
- No ConnectedView story changes needed (already passes valid
LoggingLevel values)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix template-expanded URIs not rendering: construct synthetic Resource
from readState.uri when the URI is absent from the resources list
- Fix non-image blob content rendering raw base64: show placeholder
message; also handle audio blobs properly
- Hide mimeType display when multiple content items to avoid confusion
- Rename ResourceControls selectedTemplate → selectedTemplateUri for
consistency with selectedUri and selectedResourceUri
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with MCP SDK schema types across the Resources
group components and ResourcesScreen, per the v2 UX interfaces plan.
- ResourceListItem: accept `resource: Resource | ResourceTemplate` instead
of flat `name`/`uri`; render `title ?? name`; delete local
`ResourceAnnotations` type
- ResourceControls: accept `Resource[]`, `ResourceTemplate[]`,
`InspectorResourceSubscription[]` + `selectedUri`/`selectedTemplate`
instead of `ResourceItem[]`/`TemplateListItem[]`/`SubscriptionItem[]`;
no-op on re-selecting
- ResourcePreviewPanel: accept `resource: Resource` +
`contents: (TextResourceContents | BlobResourceContents)[]` instead of
flat `content: string`; use SDK `Annotations` (audience as Role[]);
`lastUpdated` as `Date` not `string`
- ResourceTemplatePanel: accept `template: ResourceTemplate` instead of
flat props; use SDK `Annotations`
- ResourceSubscribedItem: accept `subscription: InspectorResourceSubscription`
instead of flat `name`/`lastUpdated`; `lastUpdated` as `Date`
- ResourcesScreen: accept `Resource[]`, `ResourceTemplate[]`,
`InspectorResourceSubscription[]` + `selectedResourceUri`/
`selectedTemplateUri` + `ReadResourceState`; derive selections via
`find()`; add loading/error states
- Delete local `ResourceItem`, `TemplateListItem`, `SubscriptionItem`,
`SelectedResource`, `SelectedTemplate`, `ResourceAnnotations` types
- Update all stories with real SDK fixtures
- Update ConnectedView ResourcesActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a loader when GetPromptState status is "pending" and a red alert
when status is "error". Add Loading and WithError stories.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with MCP SDK schema types across the Prompts
group components and PromptsScreen, per the v2 UX interfaces plan.
- PromptListItem: accept `prompt: Prompt` instead of flat `name`/`description`;
render `title ?? name` as primary label
- PromptControls: accept `Prompt[]` + `selectedName` instead of `PromptItem[]`;
no-op on clicking already-selected prompt; search includes title field
- PromptArgumentsForm: accept `prompt: Prompt` instead of flat props;
read `prompt.arguments` directly; display `title ?? name` as heading
- PromptMessagesDisplay: narrow type from `(PromptMessage | SamplingMessage)[]`
to `PromptMessage[]` per spec
- PromptsScreen: accept `Prompt[]` + `selectedPromptName` + `GetPromptState`;
derive selected prompt via `prompts.find()`; own `argumentValues` state
locally; reset arguments on tool switch
- Delete local `PromptItem`, `SelectedPrompt`, `PromptArgument` types
- Update all stories with real SDK `Prompt` fixtures
- Update ConnectedView PromptsActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix hasAnyAnnotation checking annotations.title which is never rendered
- Reset formValues when switching tools via onSelectTool handler
- Extract ToolProgress type from ToolDetailPanel, reuse in ToolsScreen
- Fix contradictory readOnlyHint + destructiveHint in story fixture
- Replace listMaxHeight function with LIST_MAX_HEIGHT constant
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ad hoc local types with MCP SDK schema types across the Tools
group components and ToolsScreen, per the v2 UX interfaces plan.
- ToolListItem: accept `tool: Tool` instead of flat `name`/`title`
- ToolControls: accept `Tool[]` + `selectedName` instead of `ToolListItemProps[]`
- ToolDetailPanel: accept `tool: Tool` instead of flat props; use SDK
`ToolAnnotations` (readOnlyHint/destructiveHint/idempotentHint/openWorldHint);
use `ProgressNotification['params']` for progress
- ToolResultPanel: accept `CallToolResult` instead of `ResultContentItem[]`
- ToolsScreen: accept `Tool[]` + `selectedToolName` + `ToolCallState`;
derive selected tool via `tools.find()`; own `formValues` state locally
- Delete local `ToolAnnotations`, `ResultContentItem` types
- Update all stories with real SDK `Tool` fixtures
- Update ConnectedView ToolsActive story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Theme & styling:
- Add custom "inspector" color palette with dark navy primary
- Change primaryShade to { light: 7, dark: 8 }
- Add Input theme override to apply --inspector-input-background globally
- Add --inspector-input-background token (white in light, dark-9 in dark)
- Override --mantine-color-body in dark mode via cssVariablesResolver
in both main.tsx and Storybook preview.tsx
- Add dark-mode CSS overrides for Select dropdown and option hover
- Add dark-mode CSS override for Accordion control hover
- Rename CSS variable --inspector-status-failed → --inspector-status-error
Component changes:
- CopyButton: increase icon font size to 24px, use --inspector-text-primary
for high-contrast color (black/white per theme)
- TaskControls: remove onClearHistory (moved to TaskListPanel), fix Select
clear button not disappearing by passing null instead of undefined
- TaskListPanel: add onClearCompleted callback, render "Clear" button
next to Completed section header
- HistoryListPanel: move "Clear" button from toolbar to History section
header, rename from "Clear All"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces inline style and opacity prop on ServerCard with a new
'disabled' variant on the Card theme, per AGENTS.md rules against
inline styles on components. Also picks up prettier formatting on
ResourcesScreen.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ToolControls and PromptControls now manage searchText as local state
and filter their lists internally (matches on name + title/description)
- Removed searchText/onSearchChange props from ToolsScreen, PromptsScreen,
and their associated stories
- HistoryListPanel search now also matches against stringified response
payloads
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename StatusIndicator to ServerStatusIndicator across all files
- ServerCard: add activeServer/onSetActiveServer props for coordinated
connection flow — when a card's toggle is switched on, it sets itself
as the active server, shows "Connecting" status, and dims all other
cards (opacity + pointerEvents none + inert for full keyboard blocking)
- ServerListScreen: manage activeServer state internally, pass to cards;
switch to full-width layout with 3-column grid and scrollable card area
- ServerCard: move "Test Client Features" dropdown above ContentViewer
with min-height row for consistent card heights
- ToolResultPanel: move Clear button to top-right header row
- ToolDetailPanel: right-align Execute Tool button, size md, not full-width
- ListChangedIndicator: bump Refresh button to size sm
- ToolsActive story: expand to 30 tools with titles
- UnconnectedView stories: all servers disconnected, remove Connecting story
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ResourceControls now manages its own search state internally and filters
all three accordion sections (URIs, Templates, Subscriptions) by name
and URI. Added ListToggle to expand/collapse all sections. Moved Export
JSON and Clear All buttons from HistoryControls sidebar to the
HistoryListPanel header for better proximity to the data they act on.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Place ListChangedIndicator on same line as section titles using Group with space-between in ToolControls, ResourceControls, and PromptControls
- Add ListChanged stories for ResourceControls and show indicators in ConnectedView stories
- Normalize ScreenLayout gap from "xl" to "md" across all screens for consistent spacing
- Rename ResultPanel to ToolResultPanel (component, interface, files, and stories)
- Replace Grid layout in ToolsScreen with equal-width flex children for detail and result panels
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract ToolControls group from ToolsScreen (search, list, list-changed indicator)
- Extract PromptControls and PromptListItem groups for PromptsScreen sidebar
- Refactor PromptsScreen to sidebar + detail layout (matching ResourcesScreen pattern)
- Refactor PromptArgumentsForm to accept a single prompt instead of a dropdown
- Normalize all screen sidebar widths to 340px (Tools, Resources, Prompts, Logs, Tasks, History)
- Convert ToolsScreen from Grid-only to sidebar + Grid layout
- Replace LogControls checkboxes with full-width toggle buttons
- Move Clear/Export buttons from LogControls to LogStreamPanel toolbar
- Make PromptArgumentsForm "Get Prompt" button right-aligned and compact
- Update all affected stories and ConnectedView
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract ResourceControls group component from ResourcesScreen:
title, search, list-changed indicator, and three-section accordion
(URIs, Templates, Subscriptions) with per-panel ScrollArea.Autosize
- Refactor ResourcesScreen to sidebar+panel Flex layout matching
HistoryScreen/LoggingScreen pattern (ScreenLayout, Sidebar, SidebarCard)
- Each accordion panel dynamically computes max height based on how many
sections are open, dividing available space evenly
- Accordion uses controlled state (value/onChange) to track open sections
- Sidebar card sizes to content naturally (compact when collapsed,
grows with open sections, capped by scroll areas)
- Right panel wrapped in ScrollArea.Autosize for long content
- Add AllSections story with 20 URIs, 7 templates, 8 subscriptions
- Add more templates and subscriptions to ConnectedView ResourcesActive
- Add ResourceControls stories (Default, WithSearch, Empty)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Redesign TaskCard to match v1 Task Details panel layout:
header with task ID + status badge + cancel button,
always-visible summary row (Status, Last Updated, Created At, TTL)
with Expand/Collapse button, expandable section with status message,
progress bar, error, and Full Task Object JSON viewer
- Add TaskControls group: search input + status filter dropdown +
Refresh/Clear History buttons (mirrors HistoryControls pattern)
- Add TaskListPanel group: scrollable panel with ListToggle for
expand/collapse all, splits tasks into Active/Completed sections
with counts, filters by search text and status
- Refactor TasksScreen to sidebar + panel layout matching HistoryScreen:
manages search/filter state internally, flat tasks array
- Simplify TaskCard callbacks to just onCancel
- Extract named .withProps() subcomponents (HeaderLeftGroup,
HeaderRightGroup, SectionTitle, SummaryRow, DetailRow) for
AGENTS.md compliance
- Update all stories (TaskCard, TaskControls, TaskListPanel,
TasksScreen, ConnectedView)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename ResourceTemplateInput to ResourceTemplatePanel with panel layout
(title header, URI with live variable preview, labeled inputs, Read Resource button)
- ResourceTemplatePanel manages its own variable state via useState;
single onReadResource(uri) callback returns fully resolved URI
- Extract ResourceSubscribedItem group component with name, timestamp, and
subtle Unsubscribe button
- Add hover state to listItem variant via theme classNames + App.css pseudo-selector
- Add Refresh button to ResourcePreviewPanel
- Refactor ResourcesScreen callbacks: onSelectUri, onSelectTemplate,
onReadResource, onSubscribeResource, onUnsubscribeResource replace
per-item onClick/onUnsubscribe props; screen wires callbacks to children
- Define data-only types (ResourceItem, TemplateListItem, SubscriptionItem,
SelectedResource, SelectedTemplate) separating data from callbacks
- Extract named .withProps() subcomponents (FooterRow, AnnotationGroup,
ActionGroup, Spacer) for AGENTS.md compliance
- Update all stories (ResourceTemplatePanel, ResourcesScreen, ConnectedView)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New element components:
- ListToggle: expand/collapse button using react-icons (RiExpandVerticalLine/RiCollapseVerticalLine)
- LogLevelBadge: extracted from LogEntry, handles all 8 log levels with filled variant and dark/light text contrast
New group components:
- ViewHeader: shared header bar for ConnectedView and UnconnectedView with discriminated union on `connected` prop; MCP logo links to modelcontextprotocol.io
- ServerListControls: combines ListToggle and AddServerMenu, hides toggle when no servers
- LogStreamPanel: extracted from LoggingScreen with scroll containment, filtering by visible levels and search text
- HistoryControls: vertical sidebar with search, method filter, export, and clear
- HistoryListPanel: extracted from HistoryScreen with ListToggle compact mode, filtering by method and search text
Badge contrast improvements:
- AnnotationBadge: filled variant for both dark/light modes; black text in dark, white text in light
- LogLevelBadge: same contrast approach; bold weight for alert/emergency levels
- Badge theme default weight reduced from 700 to 600
Typography:
- Added Fredoka (300-700) as body and heading font
- Added Roboto Mono as monospace font
- Google Fonts loaded in index.html and Storybook previewHead
- Heading weight set to 600
Screen layout refactors:
- LoggingScreen: owns filterText and visibleLevels state; passes to LogControls and LogStreamPanel; removed controls prop in favor of flat props
- HistoryScreen: owns searchText and methodFilter state; passes to HistoryControls and HistoryListPanel for filtering
- Both screens use new ScreenLayout (Flex variant="screen") and Sidebar subcomponents
- Added Flex theme with "screen" variant (overflow: hidden)
- Added Paper theme "panel" variant (flex column, overflow hidden)
Component enhancements:
- ServerCard: added compact prop showing only header row
- HistoryEntry: renamed isExpanded to isListExpanded; internal useState syncs via useEffect; individual entries toggle independently
- LogControls: Select All / Deselect All toggle for level checkboxes; nowrap on level selector group
- ConnectionToggle: LoadingOverlay with rounded corners for connecting state
- ConnectedView: ThemeToggle ActionIcon matched to DisconnectButton height (36px) and border color (outline variant)
- Storybook preview: fullscreen layout wrapper with 100vh overflow hidden
New stories:
- UnconnectedView: Connecting and ManyServers (12 servers for scroll testing)
- ServerCard: CompactConnected and CompactDisconnected
- All new components have corresponding stories
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>