diff --git a/packages/kilo-docs/pages/ai-providers/openai-compatible.md b/packages/kilo-docs/pages/ai-providers/openai-compatible.md index 07498e8d57..3eb6a59d45 100644 --- a/packages/kilo-docs/pages/ai-providers/openai-compatible.md +++ b/packages/kilo-docs/pages/ai-providers/openai-compatible.md @@ -43,11 +43,11 @@ You'll find these settings in the Kilo Code settings panel (click the {% codicon 1. Open **Settings** (gear icon) and go to the **Providers** tab. 2. Scroll to the bottom and click **Custom provider**. -![Custom provider button](/docs/img/custom-models/custom-provider-button.png) +![Custom provider button](/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png) 3. Fill in the custom provider dialog: -![Custom provider configuration dialog](/docs/img/custom-models/custom-provider-details.png) +![Custom provider configuration dialog](/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png) - **Provider ID** — A unique identifier (e.g., `my-provider`). - **Display name** — A human-readable name shown in the UI. diff --git a/packages/kilo-docs/pages/code-with-ai/agents/custom-models.md b/packages/kilo-docs/pages/code-with-ai/agents/custom-models.md index db8dc74c64..7c25686023 100644 --- a/packages/kilo-docs/pages/code-with-ai/agents/custom-models.md +++ b/packages/kilo-docs/pages/code-with-ai/agents/custom-models.md @@ -24,11 +24,11 @@ Add custom models under the `provider..models` key in your config f 2. Scroll to the bottom of the provider list and click **Custom provider**. -![Custom provider button in the Providers tab](/docs/img/custom-models/custom-provider-button.png) +![Custom provider button in the Providers tab](/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png) 3. Fill in the custom provider dialog: -![Custom provider configuration dialog](/docs/img/custom-models/custom-provider-details.png) +![Custom provider configuration dialog](/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png) - **Provider ID** — A unique identifier using lowercase letters, numbers, hyphens, or underscores (e.g., `myprovider`). This becomes the `provider_id` in the `provider_id/model_id` format. - **Display name** — A human-readable name shown in the UI (e.g., `My AI Provider`). diff --git a/packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md b/packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md index 249692c8d5..19ff14dc2d 100644 --- a/packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md +++ b/packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md @@ -9,7 +9,7 @@ description: "Track and manage tasks with AI-generated todo lists" **Why it matters**: Complex workflows have lots of moving parts. Without structure, it's easy to miss steps, duplicate work, or forget what comes next. -{% image src="/docs/img/task-todo-list/task-todo-list-1.png" alt="Task Todo List overview showing interactive checklist in Kilo Code" width="500" /%} +{% image src="/docs/img/screenshot-tests/kilo-vscode/visual-regression/composite-webview/todo-write-docs-overview-chromium-linux.png" alt="Task Todo List overview showing interactive checklist in Kilo Code" width="420" /%} ## How to trigger todo lists @@ -53,7 +53,7 @@ Kilo updates the list when: **1. Task Header Summary** Quick progress overview with your next important item -{% image src="/docs/img/task-todo-list/task-header.png" alt="Task header summary showing todo list progress" width="500" /%} +{% image src="/docs/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png" alt="Task header summary showing todo list progress" width="420" /%} Click the task header summary to expand the full list inline and jump to the current item. diff --git a/packages/kilo-docs/pages/customize/workflows.md b/packages/kilo-docs/pages/customize/workflows.md index 50ea192b3b..d57d1d1b31 100644 --- a/packages/kilo-docs/pages/customize/workflows.md +++ b/packages/kilo-docs/pages/customize/workflows.md @@ -8,7 +8,7 @@ platform: new Workflows (also called **slash commands** in the new extension) automate repetitive tasks by defining step-by-step instructions for Kilo Code to execute. -{% image src="/docs/img/slash-commands/workflows.png" alt="Workflows tab in Kilo Code" width="600" caption="Workflows tab in Kilo Code" /%} +{% image src="/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/agent-behaviour-workflows-chromium-linux.png" alt="Workflows tab in Kilo Code" width="420" caption="Workflows tab in Kilo Code" /%} ## Creating Workflows diff --git a/packages/kilo-vscode/tests/visual-regression.spec.mts b/packages/kilo-vscode/tests/visual-regression.spec.mts index d3d816ca19..ac6e198764 100644 --- a/packages/kilo-vscode/tests/visual-regression.spec.mts +++ b/packages/kilo-vscode/tests/visual-regression.spec.mts @@ -53,6 +53,41 @@ const SKIP = new Set([ "composite-webview--permission-dock-config-preloaded", ]) +const DOCS = new Map([ + [ + "chat--task-header-with-todos", + [ + "packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png", + ], + ], + [ + "composite-webview--todo-write-docs-overview", + [ + "packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/composite-webview/todo-write-docs-overview-chromium-linux.png", + ], + ], + [ + "settings--agent-behaviour-workflows", + [ + "packages/kilo-docs/pages/customize/workflows.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/agent-behaviour-workflows-chromium-linux.png", + ], + ], + [ + "settings--providers-configure", + [ + "packages/kilo-docs/pages/ai-providers/openai-compatible.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png", + "packages/kilo-docs/pages/code-with-ai/agents/custom-models.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png", + ], + ], + [ + "settings--custom-provider-dialog-docs", + [ + "packages/kilo-docs/pages/ai-providers/openai-compatible.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png", + "packages/kilo-docs/pages/code-with-ai/agents/custom-models.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png", + ], + ], +]) + // Generate one test() per story so Playwright's scheduler can distribute // them freely across workers — no manual sharding needed. // Skip fetching stories on macOS since test.skip() above already marks the file skipped. @@ -60,6 +95,10 @@ const stories = IS_DARWIN ? [] : (await fetchStories()).filter((s) => !SKIP.has( for (const story of stories) { test(`${story.title} / ${story.name}`, async ({ page }) => { + for (const ref of DOCS.get(story.id) ?? []) { + test.info().annotations.push({ type: "docs", description: ref }) + } + // Narrow stories (IDs ending in "-200") use a 200px viewport // The "-200" suffix comes from the export name convention (e.g. Default200, WithThinking200) const narrow = story.id.endsWith("-200") diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts b/packages/kilo-vscode/tests/visual-regression.spec.ts index f5354e4cd6..1af0ed0933 100644 --- a/packages/kilo-vscode/tests/visual-regression.spec.ts +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts @@ -54,6 +54,41 @@ const SKIP = new Set([ "composite-webview--permission-dock-config-preloaded", ]) +const DOCS = new Map([ + [ + "chat--task-header-with-todos", + [ + "packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png", + ], + ], + [ + "composite-webview--todo-write-docs-overview", + [ + "packages/kilo-docs/pages/code-with-ai/features/task-todo-list.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/composite-webview/todo-write-docs-overview-chromium-linux.png", + ], + ], + [ + "settings--agent-behaviour-workflows", + [ + "packages/kilo-docs/pages/customize/workflows.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/agent-behaviour-workflows-chromium-linux.png", + ], + ], + [ + "settings--providers-configure", + [ + "packages/kilo-docs/pages/ai-providers/openai-compatible.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png", + "packages/kilo-docs/pages/code-with-ai/agents/custom-models.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/providers-configure-chromium-linux.png", + ], + ], + [ + "settings--custom-provider-dialog-docs", + [ + "packages/kilo-docs/pages/ai-providers/openai-compatible.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png", + "packages/kilo-docs/pages/code-with-ai/agents/custom-models.md:/docs/img/screenshot-tests/kilo-vscode/visual-regression/settings/custom-provider-dialog-docs-chromium-linux.png", + ], + ], +]) + // Generate one test() per story so Playwright's scheduler can distribute // them freely across workers — no manual sharding needed. // Skip fetching stories on macOS since test.skip() above already marks the file skipped. @@ -61,6 +96,10 @@ const stories = IS_DARWIN ? [] : (await fetchStories()).filter((s) => !SKIP.has( for (const story of stories) { test(`${story.title} / ${story.name}`, async ({ page }) => { + for (const ref of DOCS.get(story.id) ?? []) { + test.info().annotations.push({ type: "docs", description: ref }) + } + // Narrow stories (IDs ending in "-200") use a 200px viewport const narrow = story.id.endsWith("-200") await page.setViewportSize({ width: narrow ? 200 : 420, height: 720 }) diff --git a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx index 69a755de63..58e2e88b87 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx @@ -292,6 +292,52 @@ const todoWriteCompleted: ToolPart = { }, } +const docsTodos = [ + { + id: "1", + content: "Project setup and core architecture (package.json, tsconfig, documentation, type definitions)", + status: "completed", + }, + { + id: "2", + content: "Configuration system (scraper config, targets.json, validation utilities)", + status: "completed", + }, + { + id: "3", + content: "Core scraping engine (browser manager, orchestrator, selector engine, content extractor)", + status: "completed", + }, + { + id: "4", + content: "Utility modules (DOM utils, retry logic, URL handling, validation)", + status: "completed", + }, + { id: "5", content: "CLI interface implementation", status: "in_progress" }, + { id: "6", content: "Storage layer implementation (database and file storage)", status: "pending" }, + { id: "7", content: "Chart extractors for specific chart types", status: "pending" }, + { id: "8", content: "Logging and error handling systems", status: "pending" }, + { id: "9", content: "Test suites (unit and integration tests)", status: "pending" }, + { id: "10", content: "Main entry point and final integration", status: "pending" }, +] + +const todoWriteDocsOverview: ToolPart = { + id: "part-todo-docs-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-todo-docs-001", + tool: "todowrite", + state: { + status: "completed", + input: { todos: docsTodos }, + output: "Updated 10 todos", + title: "Todo List Updated", + metadata: { todos: docsTodos }, + time: { start: now - 3000, end: now - 2800 }, + }, +} + const todoWritePermission: PermissionRequest = { id: "perm-todo-001", sessionID: SESSION_ID, @@ -609,6 +655,18 @@ export const TodoWriteCompleted: Story = { }, } +export const TodoWriteDocsOverview: Story = { + name: "TodoWrite — docs overview", + render: () => { + const data = dataWith([todoWriteDocsOverview]) + return ( + + + + ) + }, +} + // --------------------------------------------------------------------------- // 12. Permission dock — edit tool with file patterns // --------------------------------------------------------------------------- diff --git a/packages/kilo-vscode/webview-ui/src/stories/settings.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/settings.stories.tsx index 77db67c4e7..a7db770d7d 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/settings.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/settings.stories.tsx @@ -3,16 +3,18 @@ * Stories for Settings and ProvidersTab components. */ -import { onMount } from "solid-js" +import { onMount, type JSXElement } from "solid-js" +import { useDialog } from "@kilocode/kilo-ui/context/dialog" import type { Meta, StoryObj } from "storybook-solidjs-vite" import { StoryProviders, mockSessionValue } from "./StoryProviders" import { SessionContext } from "../context/session" import Settings from "../components/settings/Settings" import ProvidersTab from "../components/settings/ProvidersTab" +import CustomProviderDialog from "../components/settings/CustomProviderDialog" import AgentBehaviourTab from "../components/settings/AgentBehaviourTab" import ModeEditView from "../components/settings/ModeEditView" import McpEditView from "../components/settings/McpEditView" -import type { AgentConfig, CommandConfig } from "../types/messages" +import type { AgentConfig, CommandConfig, Config, ProviderConfig } from "../types/messages" const meta: Meta = { title: "Settings", @@ -23,6 +25,12 @@ type Story = StoryObj function noop() {} +function DialogStory(props: { render: () => JSXElement }) { + const dialog = useDialog() + onMount(() => dialog.show(props.render)) + return
+} + const MOCK_AGENTS = [ { name: "code", description: "General-purpose coding agent", mode: "primary" as const, native: true }, { name: "debug", description: "Diagnose and fix bugs", mode: "primary" as const, native: true }, @@ -57,6 +65,31 @@ export const ProvidersConfigure: Story = { ), } +const CUSTOM_PROVIDER: ProviderConfig = { + npm: "@ai-sdk/openai-compatible", + options: { baseURL: "https://api.myprovider.com/v1" }, + models: { + "my-model": { name: "My Custom Model" }, + }, +} + +const CUSTOM_CONFIG: Config = { provider: { myprovider: CUSTOM_PROVIDER } } + +export const CustomProviderDialogDocs: Story = { + name: "CustomProviderDialog — configured provider (docs)", + render: () => ( + + ( + + )} + /> + + ), +} + export const AgentBehaviourAgents: Story = { name: "AgentBehaviourTab — available agents list", render: () => {