Skip to content

Commit d1f2064

Browse files
committed
feat(stats): add slash entry and statistics webview
1 parent 808ec5e commit d1f2064

8 files changed

Lines changed: 1913 additions & 1 deletion

File tree

webview-ui/src/App.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ import HistoryView from "./components/history/HistoryView"
1616
import SettingsView, { SettingsViewRef } from "./components/settings/SettingsView"
1717
import WelcomeView from "./components/welcome/WelcomeViewProvider"
1818
import { MarketplaceView } from "./components/marketplace/MarketplaceView"
19+
import StatsView from "./components/stats/StatsView"
1920
import { CheckpointRestoreDialog } from "./components/chat/CheckpointRestoreDialog"
2021
import { DeleteMessageDialog, EditMessageDialog } from "./components/chat/MessageModificationConfirmationDialog"
2122
import ErrorBoundary from "./components/ErrorBoundary"
2223
import { useAddNonInteractiveClickListener } from "./components/ui/hooks/useNonInteractiveClick"
2324
import { TooltipProvider } from "./components/ui/tooltip"
2425
import { STANDARD_TOOLTIP_DELAY } from "./components/ui/standard-tooltip"
2526

26-
type Tab = "settings" | "history" | "chat" | "marketplace"
27+
type Tab = "settings" | "history" | "chat" | "marketplace" | "stats"
2728

2829
interface DeleteMessageDialogState {
2930
isOpen: boolean
@@ -246,6 +247,7 @@ const App = () => {
246247
targetTab={currentMarketplaceTab as "mcp" | "mode" | undefined}
247248
/>
248249
)}
250+
{tab === "stats" && <StatsView onDone={() => switchTab("chat")} />}
249251
<ChatView
250252
ref={chatViewRef}
251253
isHidden={tab !== "chat"}

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,18 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
615615
(text: string, images: string[]) => {
616616
text = text.trim()
617617

618+
// Intercept exact "/stats" command before sending to the LLM.
619+
// This opens the statistics tab without consuming tokens or
620+
// interfering with the task lifecycle. Only exact "/stats"
621+
// (no arguments, no images) is intercepted — "/stats foo" or
622+
// "/stats" with attached images falls through to normal send.
623+
if (text === "/stats" && images.length === 0) {
624+
vscode.postMessage({ type: "switchTab", tab: "stats" })
625+
setInputValue("")
626+
setSelectedImages([])
627+
return
628+
}
629+
618630
if (text || images.length > 0) {
619631
// Intercept when the active provider is retired — show a
620632
// WarningRow instead of sending anything to the backend.

0 commit comments

Comments
 (0)