Merge pull request #7192 from Kilo-Org/session/agent_7729b70c-3760-4ad1-bc23-de5aa42ad00c

test(vscode): add marketplace screenshot stories for MCP and Modes tabs
This commit is contained in:
Mark IJbema
2026-03-17 19:04:45 +01:00
committed by GitHub
11 changed files with 370 additions and 4 deletions
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d027fc81aa110b8a3fa94816c18ddd7d104ed1fc103abd234c39e805637afce
size 12263
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a69ac58dc72885950a702661b75bc1989a28e8b07b3136037255891b7e5a3b06
size 12839
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1edca81fb2c946f87df5436684418e63b7a9c761079e44f024971a81316b8263
size 6549
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ce4ba314abb23bb43694d512ade273d99760f250b061e235899d86e170bb5f9a
size 52892
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:631d41ecf6216249943722a797f75c3aefb2f84ebdb7ee80529662a26fa35af5
size 50206
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c925148c349c6ab1f14190a2a379aa24869de35e5b77455fa15d8868eb08343
size 5943
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:30346f68598419d1fe80a3f33d3326cc844a30356ebedb022a841be4096514c6
size 53909
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e654374e5c12a4a184a0d27709cd773684e31e08a3d7b6305358849cf30c75be
size 50986
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9399ad494d6bc3302cc01f6f815763662c43d1eafe0b2ecff4b8eacb5dc5e8ef
size 10770
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b7e17426d82ff00ac8194963a3c3be946994018e2f6c9553dfaee237cb043fd9
size 11324
@@ -10,7 +10,12 @@ import type { Meta, StoryObj } from "storybook-solidjs-vite"
import { StoryProviders } from "./StoryProviders"
import { MarketplaceListView } from "../components/marketplace/MarketplaceListView"
import { ItemCard } from "../components/marketplace/ItemCard"
import type { SkillMarketplaceItem, MarketplaceInstalledMetadata } from "../types/marketplace"
import type {
SkillMarketplaceItem,
McpMarketplaceItem,
ModeMarketplaceItem,
MarketplaceInstalledMetadata,
} from "../types/marketplace"
import "../components/marketplace/marketplace.css"
const meta: Meta = {
@@ -98,13 +103,160 @@ const MOCK_SKILLS: SkillMarketplaceItem[] = [
},
]
const MOCK_MCPS: McpMarketplaceItem[] = [
{
type: "mcp",
id: "github-mcp",
name: "GitHub",
description:
"Interact with GitHub repositories, issues, and pull requests. Search code, manage branches, and automate workflows.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/github",
content:
'{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } }',
parameters: [{ name: "GitHub Token", key: "GITHUB_TOKEN", placeholder: "ghp_xxxxxxxxxxxx" }],
author: "Anthropic",
tags: ["version-control", "development"],
},
{
type: "mcp",
id: "postgres-mcp",
name: "PostgreSQL",
description: "Query and manage PostgreSQL databases. Run SQL, inspect schemas, and manage connections.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/postgres",
content: [
{
name: "npx",
content:
'{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres", "${CONNECTION_STRING}"] }',
parameters: [
{ name: "Connection String", key: "CONNECTION_STRING", placeholder: "postgresql://user:pass@localhost/db" },
],
},
{
name: "Docker",
content:
'{ "command": "docker", "args": ["run", "--rm", "-e", "CONNECTION_STRING=${CONNECTION_STRING}", "mcp/postgres"] }',
parameters: [
{ name: "Connection String", key: "CONNECTION_STRING", placeholder: "postgresql://user:pass@localhost/db" },
],
prerequisites: ["Docker must be installed and running"],
},
],
author: "Anthropic",
tags: ["database", "sql"],
},
{
type: "mcp",
id: "filesystem-mcp",
name: "Filesystem",
description: "Read, write, and manage files on the local filesystem with configurable access controls.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem",
content: '{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "${ALLOWED_DIR}"] }',
parameters: [{ name: "Allowed Directory", key: "ALLOWED_DIR", placeholder: "/path/to/directory" }],
tags: ["filesystem", "development"],
},
{
type: "mcp",
id: "slack-mcp",
name: "Slack",
description: "Send and receive messages, manage channels, and search conversations in Slack workspaces.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/slack",
content:
'{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-slack"], "env": { "SLACK_TOKEN": "${SLACK_TOKEN}" } }',
parameters: [{ name: "Slack Bot Token", key: "SLACK_TOKEN", placeholder: "xoxb-xxxxxxxxxxxx" }],
author: "Anthropic",
tags: ["communication", "productivity"],
},
{
type: "mcp",
id: "brave-search-mcp",
name: "Brave Search",
description: "Search the web using the Brave Search API for real-time information retrieval.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search",
content:
'{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-brave-search"], "env": { "BRAVE_API_KEY": "${BRAVE_API_KEY}" } }',
parameters: [{ name: "API Key", key: "BRAVE_API_KEY", placeholder: "BSA-xxxxxxxxxxxx" }],
tags: ["search", "web"],
},
{
type: "mcp",
id: "puppeteer-mcp",
name: "Puppeteer",
description: "Automate browser interactions, take screenshots, and scrape web pages using headless Chrome.",
url: "https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer",
content: '{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-puppeteer"] }',
prerequisites: ["Chrome or Chromium must be installed"],
tags: ["browser", "automation", "web"],
},
]
const MOCK_MODES: ModeMarketplaceItem[] = [
{
type: "mode",
id: "architect",
name: "Architect",
description:
"High-level system design and planning. Focuses on architecture decisions, component boundaries, and technical specifications without writing implementation code.",
content: "name: Architect\nroleDefinition: You are a software architect...\ngroups:\n - read\n",
author: "Kilo",
tags: ["planning", "design"],
},
{
type: "mode",
id: "reviewer",
name: "Code Reviewer",
description:
"Reviews code for bugs, security issues, and best practices. Provides actionable feedback with specific line references.",
content: "name: Code Reviewer\nroleDefinition: You are a code reviewer...\ngroups:\n - read\n",
author: "Kilo",
tags: ["review", "quality"],
},
{
type: "mode",
id: "docs-writer",
name: "Documentation Writer",
description: "Generates and maintains documentation including READMEs, API docs, and inline code comments.",
content: "name: Documentation Writer\nroleDefinition: You write documentation...\ngroups:\n - read\n - edit\n",
tags: ["documentation", "writing"],
},
{
type: "mode",
id: "tdd",
name: "Test-Driven Developer",
description:
"Follows strict TDD methodology: write failing tests first, implement minimum code to pass, then refactor.",
content:
"name: Test-Driven Developer\nroleDefinition: You follow TDD...\ngroups:\n - read\n - edit\n - command\n",
author: "Community",
tags: ["testing", "methodology"],
},
{
type: "mode",
id: "debug",
name: "Debugger",
description: "Systematically diagnoses and fixes bugs. Uses logs, stack traces, and bisection to isolate issues.",
content: "name: Debugger\nroleDefinition: You are a debugger...\ngroups:\n - read\n - command\n",
tags: ["debugging", "troubleshooting"],
},
]
const EMPTY_METADATA: MarketplaceInstalledMetadata = { project: {}, global: {} }
const PARTIAL_INSTALLED: MarketplaceInstalledMetadata = {
const PARTIAL_INSTALLED_SKILLS: MarketplaceInstalledMetadata = {
project: { "nextjs-developer": { type: "skill" } },
global: { "python-data-science": { type: "skill" } },
}
const PARTIAL_INSTALLED_MCPS: MarketplaceInstalledMetadata = {
project: { "github-mcp": { type: "mcp" } },
global: { "postgres-mcp": { type: "mcp" } },
}
const PARTIAL_INSTALLED_MODES: MarketplaceInstalledMetadata = {
project: { architect: { type: "mode" } },
global: { reviewer: { type: "mode" } },
}
const noop = () => {}
// ---------------------------------------------------------------------------
@@ -138,7 +290,7 @@ export const SkillsTabWithInstalled: Story = {
<div style={{ width: "420px", height: "700px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={MOCK_SKILLS}
metadata={PARTIAL_INSTALLED}
metadata={PARTIAL_INSTALLED_SKILLS}
fetching={false}
type="skill"
searchPlaceholder="Search skills..."
@@ -196,7 +348,7 @@ export const InstalledSkillCard: Story = {
<div style={{ width: "420px", padding: "12px" }}>
<ItemCard
item={MOCK_SKILLS[0]}
metadata={PARTIAL_INSTALLED}
metadata={PARTIAL_INSTALLED_SKILLS}
displayName={MOCK_SKILLS[0].displayName}
linkUrl={MOCK_SKILLS[0].githubUrl}
onInstall={noop}
@@ -206,3 +358,187 @@ export const InstalledSkillCard: Story = {
</StoryProviders>
),
}
// ---------------------------------------------------------------------------
// MCP Stories
// ---------------------------------------------------------------------------
export const McpTabWithItems: Story = {
name: "MCP tab — with items",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "700px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={MOCK_MCPS}
metadata={EMPTY_METADATA}
fetching={false}
type="mcp"
searchPlaceholder="Search MCP servers..."
emptyMessage="No MCP servers found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const McpTabWithInstalled: Story = {
name: "MCP tab — some installed",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "700px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={MOCK_MCPS}
metadata={PARTIAL_INSTALLED_MCPS}
fetching={false}
type="mcp"
searchPlaceholder="Search MCP servers..."
emptyMessage="No MCP servers found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const McpTabEmpty: Story = {
name: "MCP tab — empty state",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "400px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={[]}
metadata={EMPTY_METADATA}
fetching={false}
type="mcp"
searchPlaceholder="Search MCP servers..."
emptyMessage="No MCP servers found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const SingleMcpCard: Story = {
name: "ItemCard — single MCP not installed",
render: () => (
<StoryProviders>
<div style={{ width: "420px", padding: "12px" }}>
<ItemCard
item={MOCK_MCPS[0]}
metadata={EMPTY_METADATA}
linkUrl={MOCK_MCPS[0].url}
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const InstalledMcpCard: Story = {
name: "ItemCard — installed MCP",
render: () => (
<StoryProviders>
<div style={{ width: "420px", padding: "12px" }}>
<ItemCard
item={MOCK_MCPS[0]}
metadata={PARTIAL_INSTALLED_MCPS}
linkUrl={MOCK_MCPS[0].url}
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
// ---------------------------------------------------------------------------
// Mode Stories
// ---------------------------------------------------------------------------
export const ModesTabWithItems: Story = {
name: "Modes tab — with items",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "700px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={MOCK_MODES}
metadata={EMPTY_METADATA}
fetching={false}
type="mode"
searchPlaceholder="Search modes..."
emptyMessage="No modes found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const ModesTabWithInstalled: Story = {
name: "Modes tab — some installed",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "700px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={MOCK_MODES}
metadata={PARTIAL_INSTALLED_MODES}
fetching={false}
type="mode"
searchPlaceholder="Search modes..."
emptyMessage="No modes found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const ModesTabEmpty: Story = {
name: "Modes tab — empty state",
render: () => (
<StoryProviders>
<div style={{ width: "420px", height: "400px", overflow: "auto", padding: "12px" }}>
<MarketplaceListView
items={[]}
metadata={EMPTY_METADATA}
fetching={false}
type="mode"
searchPlaceholder="Search modes..."
emptyMessage="No modes found"
onInstall={noop}
onRemove={noop}
/>
</div>
</StoryProviders>
),
}
export const SingleModeCard: Story = {
name: "ItemCard — single mode not installed",
render: () => (
<StoryProviders>
<div style={{ width: "420px", padding: "12px" }}>
<ItemCard item={MOCK_MODES[0]} metadata={EMPTY_METADATA} onInstall={noop} onRemove={noop} />
</div>
</StoryProviders>
),
}
export const InstalledModeCard: Story = {
name: "ItemCard — installed mode",
render: () => (
<StoryProviders>
<div style={{ width: "420px", padding: "12px" }}>
<ItemCard item={MOCK_MODES[0]} metadata={PARTIAL_INSTALLED_MODES} onInstall={noop} onRemove={noop} />
</div>
</StoryProviders>
),
}