diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mcp-card-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mcp-card-chromium-linux.png new file mode 100644 index 00000000000..a4d77020e8c --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mcp-card-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d027fc81aa110b8a3fa94816c18ddd7d104ed1fc103abd234c39e805637afce +size 12263 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mode-card-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mode-card-chromium-linux.png new file mode 100644 index 00000000000..a20ba79fd7a --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/installed-mode-card-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a69ac58dc72885950a702661b75bc1989a28e8b07b3136037255891b7e5a3b06 +size 12839 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-empty-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-empty-chromium-linux.png new file mode 100644 index 00000000000..e6db4c0c7e4 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-empty-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1edca81fb2c946f87df5436684418e63b7a9c761079e44f024971a81316b8263 +size 6549 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-installed-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-installed-chromium-linux.png new file mode 100644 index 00000000000..59da02c6806 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-installed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce4ba314abb23bb43694d512ade273d99760f250b061e235899d86e170bb5f9a +size 52892 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-items-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-items-chromium-linux.png new file mode 100644 index 00000000000..62f2ae9b606 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/mcp-tab-with-items-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:631d41ecf6216249943722a797f75c3aefb2f84ebdb7ee80529662a26fa35af5 +size 50206 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-empty-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-empty-chromium-linux.png new file mode 100644 index 00000000000..f190c5fac6e --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-empty-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c925148c349c6ab1f14190a2a379aa24869de35e5b77455fa15d8868eb08343 +size 5943 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-installed-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-installed-chromium-linux.png new file mode 100644 index 00000000000..b43f90cbf3b --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-installed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30346f68598419d1fe80a3f33d3326cc844a30356ebedb022a841be4096514c6 +size 53909 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-items-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-items-chromium-linux.png new file mode 100644 index 00000000000..b86b588ce51 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/modes-tab-with-items-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e654374e5c12a4a184a0d27709cd773684e31e08a3d7b6305358849cf30c75be +size 50986 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mcp-card-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mcp-card-chromium-linux.png new file mode 100644 index 00000000000..ba9374ed8bd --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mcp-card-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9399ad494d6bc3302cc01f6f815763662c43d1eafe0b2ecff4b8eacb5dc5e8ef +size 10770 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mode-card-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mode-card-chromium-linux.png new file mode 100644 index 00000000000..ec8a7a5e249 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/marketplace/single-mode-card-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7e17426d82ff00ac8194963a3c3be946994018e2f6c9553dfaee237cb043fd9 +size 11324 diff --git a/packages/kilo-vscode/webview-ui/src/stories/marketplace.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/marketplace.stories.tsx index c6c30fb9528..fe65248a094 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/marketplace.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/marketplace.stories.tsx @@ -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 = {
), } + +// --------------------------------------------------------------------------- +// MCP Stories +// --------------------------------------------------------------------------- + +export const McpTabWithItems: Story = { + name: "MCP tab — with items", + render: () => ( + +
+ +
+
+ ), +} + +export const McpTabWithInstalled: Story = { + name: "MCP tab — some installed", + render: () => ( + +
+ +
+
+ ), +} + +export const McpTabEmpty: Story = { + name: "MCP tab — empty state", + render: () => ( + +
+ +
+
+ ), +} + +export const SingleMcpCard: Story = { + name: "ItemCard — single MCP not installed", + render: () => ( + +
+ +
+
+ ), +} + +export const InstalledMcpCard: Story = { + name: "ItemCard — installed MCP", + render: () => ( + +
+ +
+
+ ), +} + +// --------------------------------------------------------------------------- +// Mode Stories +// --------------------------------------------------------------------------- + +export const ModesTabWithItems: Story = { + name: "Modes tab — with items", + render: () => ( + +
+ +
+
+ ), +} + +export const ModesTabWithInstalled: Story = { + name: "Modes tab — some installed", + render: () => ( + +
+ +
+
+ ), +} + +export const ModesTabEmpty: Story = { + name: "Modes tab — empty state", + render: () => ( + +
+ +
+
+ ), +} + +export const SingleModeCard: Story = { + name: "ItemCard — single mode not installed", + render: () => ( + +
+ +
+
+ ), +} + +export const InstalledModeCard: Story = { + name: "ItemCard — installed mode", + render: () => ( + +
+ +
+
+ ), +}