From 9f5f89a4a032b2d7073c0501299122cabee292f3 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:21:05 +0000 Subject: [PATCH 1/8] refactor(browser): move UI-only feature files into components --- .../Runtime => components/CoderControls}/CoderControls.tsx | 0 .../PowerModeOverlay}/PowerModeOverlay.tsx | 0 .../{features/AIElements => components/Shimmer}/Shimmer.tsx | 0 src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx | 2 +- src/browser/contexts/PowerModeContext.test.tsx | 2 +- src/browser/contexts/PowerModeContext.tsx | 2 +- src/browser/features/ChatInput/CreationCenterContent.tsx | 2 +- src/browser/features/ChatInput/CreationControls.tsx | 2 +- src/browser/features/Messages/InitMessage.tsx | 2 +- src/browser/features/Messages/ReasoningMessage.tsx | 2 +- src/browser/features/Settings/Sections/RuntimesSection.tsx | 2 +- 11 files changed, 8 insertions(+), 8 deletions(-) rename src/browser/{features/Runtime => components/CoderControls}/CoderControls.tsx (100%) rename src/browser/{features/PowerMode => components/PowerModeOverlay}/PowerModeOverlay.tsx (100%) rename src/browser/{features/AIElements => components/Shimmer}/Shimmer.tsx (100%) diff --git a/src/browser/features/Runtime/CoderControls.tsx b/src/browser/components/CoderControls/CoderControls.tsx similarity index 100% rename from src/browser/features/Runtime/CoderControls.tsx rename to src/browser/components/CoderControls/CoderControls.tsx diff --git a/src/browser/features/PowerMode/PowerModeOverlay.tsx b/src/browser/components/PowerModeOverlay/PowerModeOverlay.tsx similarity index 100% rename from src/browser/features/PowerMode/PowerModeOverlay.tsx rename to src/browser/components/PowerModeOverlay/PowerModeOverlay.tsx diff --git a/src/browser/features/AIElements/Shimmer.tsx b/src/browser/components/Shimmer/Shimmer.tsx similarity index 100% rename from src/browser/features/AIElements/Shimmer.tsx rename to src/browser/components/Shimmer/Shimmer.tsx diff --git a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx b/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx index b50036ffb5..ab1babcc4f 100644 --- a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx +++ b/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx @@ -18,7 +18,7 @@ import { useContextMenuPosition } from "@/browser/hooks/useContextMenuPosition"; import { PositionedMenu, PositionedMenuItem } from "../PositionedMenu/PositionedMenu"; import { Trash2, Ellipsis, Loader2, Sparkles } from "lucide-react"; import { WorkspaceStatusIndicator } from "../WorkspaceStatusIndicator/WorkspaceStatusIndicator"; -import { Shimmer } from "@/browser/features/AIElements/Shimmer"; +import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; import { ArchiveIcon } from "../icons/ArchiveIcon/ArchiveIcon"; import { WorkspaceTerminalIcon } from "../icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; import { diff --git a/src/browser/contexts/PowerModeContext.test.tsx b/src/browser/contexts/PowerModeContext.test.tsx index 5537693cf0..8ea45c61bf 100644 --- a/src/browser/contexts/PowerModeContext.test.tsx +++ b/src/browser/contexts/PowerModeContext.test.tsx @@ -6,7 +6,7 @@ import { GlobalWindow } from "happy-dom"; import { POWER_MODE_ENABLED_KEY } from "@/common/constants/storage"; import { PowerModeEngine } from "@/browser/utils/powerMode/PowerModeEngine"; -void mock.module("@/browser/features/PowerMode/PowerModeOverlay", () => ({ +void mock.module("@/browser/components/PowerModeOverlay/PowerModeOverlay", () => ({ // Overlay rendering is unrelated to caret alignment; keep tests focused on context behavior. PowerModeOverlay: () => null, })); diff --git a/src/browser/contexts/PowerModeContext.tsx b/src/browser/contexts/PowerModeContext.tsx index 741bc391a8..f15e17a037 100644 --- a/src/browser/contexts/PowerModeContext.tsx +++ b/src/browser/contexts/PowerModeContext.tsx @@ -16,7 +16,7 @@ import { PowerModeEngine, type PowerModeBurstKind, } from "@/browser/utils/powerMode/PowerModeEngine"; -import { PowerModeOverlay } from "@/browser/features/PowerMode/PowerModeOverlay"; +import { PowerModeOverlay } from "@/browser/components/PowerModeOverlay/PowerModeOverlay"; interface PowerModeContextValue { enabled: boolean; diff --git a/src/browser/features/ChatInput/CreationCenterContent.tsx b/src/browser/features/ChatInput/CreationCenterContent.tsx index a87d352dd3..744079ebbe 100644 --- a/src/browser/features/ChatInput/CreationCenterContent.tsx +++ b/src/browser/features/ChatInput/CreationCenterContent.tsx @@ -1,5 +1,5 @@ import { useTheme } from "@/browser/contexts/ThemeContext"; -import { Shimmer } from "@/browser/features/AIElements/Shimmer"; +import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; import { LoadingAnimation } from "@/browser/components/LoadingAnimation/LoadingAnimation"; interface CreationCenterContentProps { diff --git a/src/browser/features/ChatInput/CreationControls.tsx b/src/browser/features/ChatInput/CreationControls.tsx index bc8062fb27..4e1dd24643 100644 --- a/src/browser/features/ChatInput/CreationControls.tsx +++ b/src/browser/features/ChatInput/CreationControls.tsx @@ -48,7 +48,7 @@ import { resolveCoderAvailability, type CoderAvailabilityState, type CoderControlsProps, -} from "../Runtime/CoderControls"; +} from "@/browser/components/CoderControls/CoderControls"; /** * Shared styling for inline form controls in the creation UI. diff --git a/src/browser/features/Messages/InitMessage.tsx b/src/browser/features/Messages/InitMessage.tsx index 54e7adbd3c..db7c53e5c0 100644 --- a/src/browser/features/Messages/InitMessage.tsx +++ b/src/browser/features/Messages/InitMessage.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef } from "react"; import { cn } from "@/common/lib/utils"; import type { DisplayedMessage } from "@/common/types/message"; import { Loader2, Wrench, CheckCircle2, AlertCircle } from "lucide-react"; -import { Shimmer } from "../AIElements/Shimmer"; +import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; import { formatDuration } from "@/common/utils/formatDuration"; interface InitMessageProps { diff --git a/src/browser/features/Messages/ReasoningMessage.tsx b/src/browser/features/Messages/ReasoningMessage.tsx index fb38d1603e..be067e0f51 100644 --- a/src/browser/features/Messages/ReasoningMessage.tsx +++ b/src/browser/features/Messages/ReasoningMessage.tsx @@ -4,7 +4,7 @@ import { MarkdownRenderer } from "./MarkdownRenderer"; import { TypewriterMarkdown } from "./TypewriterMarkdown"; import { normalizeReasoningMarkdown } from "./MarkdownStyles"; import { cn } from "@/common/lib/utils"; -import { Shimmer } from "../AIElements/Shimmer"; +import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; import { Lightbulb } from "lucide-react"; interface ReasoningMessageProps { diff --git a/src/browser/features/Settings/Sections/RuntimesSection.tsx b/src/browser/features/Settings/Sections/RuntimesSection.tsx index 931f117e0a..cd85b2ecd1 100644 --- a/src/browser/features/Settings/Sections/RuntimesSection.tsx +++ b/src/browser/features/Settings/Sections/RuntimesSection.tsx @@ -4,7 +4,7 @@ import { AlertTriangle, Loader2 } from "lucide-react"; import { CoderWorkspaceForm, resolveCoderAvailability, -} from "@/browser/features/Runtime/CoderControls"; +} from "@/browser/components/CoderControls/CoderControls"; import { RuntimeConfigInput } from "@/browser/components/RuntimeConfigInput/RuntimeConfigInput"; import { Select, From 83448fcfc57aabd05394992306eb63b8c8db7703 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:20:05 +0000 Subject: [PATCH 2/8] refactor: move useGitBranchDetails into browser hooks --- .../components/GitStatusIndicator/GitStatusIndicator.tsx | 2 +- src/browser/{features/Hooks => hooks}/useGitBranchDetails.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/browser/{features/Hooks => hooks}/useGitBranchDetails.ts (100%) diff --git a/src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx b/src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx index 00192bf965..798c8ad0ec 100644 --- a/src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx +++ b/src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx @@ -8,7 +8,7 @@ import { GitStatusIndicatorView, type GitStatusIndicatorMode, } from "../GitStatusIndicatorView/GitStatusIndicatorView"; -import { useGitBranchDetails } from "@/browser/features/Hooks/useGitBranchDetails"; +import { useGitBranchDetails } from "@/browser/hooks/useGitBranchDetails"; interface GitStatusIndicatorProps { gitStatus: GitStatus | null; diff --git a/src/browser/features/Hooks/useGitBranchDetails.ts b/src/browser/hooks/useGitBranchDetails.ts similarity index 100% rename from src/browser/features/Hooks/useGitBranchDetails.ts rename to src/browser/hooks/useGitBranchDetails.ts From e35dc99294ce876963014feea4b64d72e78ae3b1 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:23:52 +0000 Subject: [PATCH 3/8] Rename browser icons directory to Icons --- docs/AGENTS.md | 4 ++-- src/browser/assets/file-icons/seti-icon-theme.json | 2 +- .../components/ArchivedWorkspaces/ArchivedWorkspaces.tsx | 2 +- src/browser/components/CopyButton/CopyButton.tsx | 2 +- .../components/GatewayToggleButton/GatewayToggleButton.tsx | 2 +- .../components/{icons => Icons}/ArchiveIcon/ArchiveIcon.tsx | 0 src/browser/components/{icons => Icons}/CopyIcon/CopyIcon.tsx | 0 .../components/{icons => Icons}/EmojiIcon/EmojiIcon.tsx | 0 .../components/{icons => Icons}/GatewayIcon/GatewayIcon.tsx | 0 .../components/{icons => Icons}/RuntimeIcons/RuntimeIcons.tsx | 0 .../components/{icons => Icons}/SkillIcon/SkillIcon.tsx | 0 .../WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx | 0 src/browser/components/ProviderIcon/ProviderIcon.tsx | 2 +- .../components/ShareMessagePopover/ShareMessagePopover.tsx | 2 +- .../ShareTranscriptDialog/ShareTranscriptDialog.tsx | 2 +- src/browser/components/SkillIndicator/SkillIndicator.tsx | 2 +- src/browser/components/TitleBar/TitleBar.tsx | 2 +- .../WorkspaceActionsMenuContent.tsx | 2 +- .../components/WorkspaceListItem/WorkspaceListItem.tsx | 4 ++-- src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx | 2 +- .../WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx | 2 +- src/browser/features/Messages/CodeBlockSSR.tsx | 2 +- src/browser/features/SplashScreens/OnboardingWizardSplash.tsx | 2 +- src/browser/features/Tools/Shared/ToolPrimitives.tsx | 2 +- src/browser/utils/runtimeUi.ts | 2 +- vscode/src/webview/WorkspacePicker.tsx | 2 +- 26 files changed, 21 insertions(+), 21 deletions(-) rename src/browser/components/{icons => Icons}/ArchiveIcon/ArchiveIcon.tsx (100%) rename src/browser/components/{icons => Icons}/CopyIcon/CopyIcon.tsx (100%) rename src/browser/components/{icons => Icons}/EmojiIcon/EmojiIcon.tsx (100%) rename src/browser/components/{icons => Icons}/GatewayIcon/GatewayIcon.tsx (100%) rename src/browser/components/{icons => Icons}/RuntimeIcons/RuntimeIcons.tsx (100%) rename src/browser/components/{icons => Icons}/SkillIcon/SkillIcon.tsx (100%) rename src/browser/components/{icons => Icons}/WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx (100%) diff --git a/docs/AGENTS.md b/docs/AGENTS.md index f59c2460aa..621021b115 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -116,9 +116,9 @@ Mobile app tests live in `mobile/src/**/*.test.ts` and use Bun's built-in test r ## Styling - Never use emoji characters as UI icons or status indicators; emoji rendering varies across platforms and fonts. -- Prefer SVG icons (usually from `lucide-react`) or shared icon components under `src/browser/components/icons/`. +- Prefer SVG icons (usually from `lucide-react`) or shared icon components under `src/browser/components/Icons/`. - For tool call headers, use `ToolIcon` from `src/browser/components/tools/shared/ToolPrimitives.tsx`. -- If a tool/agent provides an emoji string (e.g., `status_set` or `displayStatus`), render via `EmojiIcon` (`src/browser/components/icons/EmojiIcon.tsx`) instead of rendering the emoji. +- If a tool/agent provides an emoji string (e.g., `status_set` or `displayStatus`), render via `EmojiIcon` (`src/browser/components/Icons/EmojiIcon.tsx`) instead of rendering the emoji. - If a new emoji appears in tool output, extend `EmojiIcon` to map it to an SVG icon. - Colors defined in `src/browser/styles/globals.css` (`:root @theme` block). Reference via CSS variables (e.g., `var(--color-plan-mode)`), never hardcode hex values. diff --git a/src/browser/assets/file-icons/seti-icon-theme.json b/src/browser/assets/file-icons/seti-icon-theme.json index 2610c1a3a6..fe0e806c1c 100644 --- a/src/browser/assets/file-icons/seti-icon-theme.json +++ b/src/browser/assets/file-icons/seti-icon-theme.json @@ -3,7 +3,7 @@ "This file has been generated from data in https://github.com/jesseweed/seti-ui", "- icon definitions: https://github.com/jesseweed/seti-ui/blob/master/styles/_fonts/seti.less", "- icon colors: https://github.com/jesseweed/seti-ui/blob/master/styles/ui-variables.less", - "- file associations: https://github.com/jesseweed/seti-ui/blob/master/styles/components/icons/mapping.less", + "- file associations: https://github.com/jesseweed/seti-ui/tree/master/styles/components/icons", "If you want to provide a fix or improvement, please create a pull request against the jesseweed/seti-ui repository.", "Once accepted there, we are happy to receive an update request." ], diff --git a/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx b/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx index 976ae62f13..314b8b3cf2 100644 --- a/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx +++ b/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx @@ -7,7 +7,7 @@ import { usePersistedState } from "@/browser/hooks/usePersistedState"; import { getArchivedWorkspacesExpandedKey } from "@/common/constants/storage"; import { useAPI } from "@/browser/contexts/API"; import { ChevronDown, ChevronRight, Loader2, Search, Trash2 } from "lucide-react"; -import { ArchiveIcon, ArchiveRestoreIcon } from "../icons/ArchiveIcon/ArchiveIcon"; +import { ArchiveIcon, ArchiveRestoreIcon } from "../Icons/ArchiveIcon/ArchiveIcon"; import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; import { RuntimeBadge } from "../RuntimeBadge/RuntimeBadge"; import { Skeleton } from "../Skeleton/Skeleton"; diff --git a/src/browser/components/CopyButton/CopyButton.tsx b/src/browser/components/CopyButton/CopyButton.tsx index 5caa3563f4..2352a6d13b 100644 --- a/src/browser/components/CopyButton/CopyButton.tsx +++ b/src/browser/components/CopyButton/CopyButton.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { CopyIcon } from "@/browser/components/icons/CopyIcon/CopyIcon"; +import { CopyIcon } from "@/browser/components/Icons/CopyIcon/CopyIcon"; import { copyToClipboard } from "@/browser/utils/clipboard"; interface CopyButtonProps { diff --git a/src/browser/components/GatewayToggleButton/GatewayToggleButton.tsx b/src/browser/components/GatewayToggleButton/GatewayToggleButton.tsx index 7976d6180d..36432bf750 100644 --- a/src/browser/components/GatewayToggleButton/GatewayToggleButton.tsx +++ b/src/browser/components/GatewayToggleButton/GatewayToggleButton.tsx @@ -1,5 +1,5 @@ import { cn } from "@/common/lib/utils"; -import { GatewayIcon } from "../icons/GatewayIcon/GatewayIcon"; +import { GatewayIcon } from "../Icons/GatewayIcon/GatewayIcon"; import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/Tooltip"; interface GatewayToggleButtonProps { diff --git a/src/browser/components/icons/ArchiveIcon/ArchiveIcon.tsx b/src/browser/components/Icons/ArchiveIcon/ArchiveIcon.tsx similarity index 100% rename from src/browser/components/icons/ArchiveIcon/ArchiveIcon.tsx rename to src/browser/components/Icons/ArchiveIcon/ArchiveIcon.tsx diff --git a/src/browser/components/icons/CopyIcon/CopyIcon.tsx b/src/browser/components/Icons/CopyIcon/CopyIcon.tsx similarity index 100% rename from src/browser/components/icons/CopyIcon/CopyIcon.tsx rename to src/browser/components/Icons/CopyIcon/CopyIcon.tsx diff --git a/src/browser/components/icons/EmojiIcon/EmojiIcon.tsx b/src/browser/components/Icons/EmojiIcon/EmojiIcon.tsx similarity index 100% rename from src/browser/components/icons/EmojiIcon/EmojiIcon.tsx rename to src/browser/components/Icons/EmojiIcon/EmojiIcon.tsx diff --git a/src/browser/components/icons/GatewayIcon/GatewayIcon.tsx b/src/browser/components/Icons/GatewayIcon/GatewayIcon.tsx similarity index 100% rename from src/browser/components/icons/GatewayIcon/GatewayIcon.tsx rename to src/browser/components/Icons/GatewayIcon/GatewayIcon.tsx diff --git a/src/browser/components/icons/RuntimeIcons/RuntimeIcons.tsx b/src/browser/components/Icons/RuntimeIcons/RuntimeIcons.tsx similarity index 100% rename from src/browser/components/icons/RuntimeIcons/RuntimeIcons.tsx rename to src/browser/components/Icons/RuntimeIcons/RuntimeIcons.tsx diff --git a/src/browser/components/icons/SkillIcon/SkillIcon.tsx b/src/browser/components/Icons/SkillIcon/SkillIcon.tsx similarity index 100% rename from src/browser/components/icons/SkillIcon/SkillIcon.tsx rename to src/browser/components/Icons/SkillIcon/SkillIcon.tsx diff --git a/src/browser/components/icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx b/src/browser/components/Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx similarity index 100% rename from src/browser/components/icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx rename to src/browser/components/Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon.tsx diff --git a/src/browser/components/ProviderIcon/ProviderIcon.tsx b/src/browser/components/ProviderIcon/ProviderIcon.tsx index 39638f5292..80c7941625 100644 --- a/src/browser/components/ProviderIcon/ProviderIcon.tsx +++ b/src/browser/components/ProviderIcon/ProviderIcon.tsx @@ -8,7 +8,7 @@ import OllamaIcon from "@/browser/assets/icons/ollama.svg?react"; import DeepSeekIcon from "@/browser/assets/icons/deepseek.svg?react"; import AWSIcon from "@/browser/assets/icons/aws.svg?react"; import GitHubIcon from "@/browser/assets/icons/github.svg?react"; -import { GatewayIcon } from "@/browser/components/icons/GatewayIcon/GatewayIcon"; +import { GatewayIcon } from "@/browser/components/Icons/GatewayIcon/GatewayIcon"; import { PROVIDER_DEFINITIONS, PROVIDER_DISPLAY_NAMES, diff --git a/src/browser/components/ShareMessagePopover/ShareMessagePopover.tsx b/src/browser/components/ShareMessagePopover/ShareMessagePopover.tsx index 317c29785e..3db326784e 100644 --- a/src/browser/components/ShareMessagePopover/ShareMessagePopover.tsx +++ b/src/browser/components/ShareMessagePopover/ShareMessagePopover.tsx @@ -10,7 +10,7 @@ import { import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; import { Button } from "@/browser/components/Button/Button"; import { Check, ExternalLink, Link2, Loader2, Trash2 } from "lucide-react"; -import { CopyIcon } from "@/browser/components/icons/CopyIcon/CopyIcon"; +import { CopyIcon } from "@/browser/components/Icons/CopyIcon/CopyIcon"; import { copyToClipboard } from "@/browser/utils/clipboard"; import { diff --git a/src/browser/components/ShareTranscriptDialog/ShareTranscriptDialog.tsx b/src/browser/components/ShareTranscriptDialog/ShareTranscriptDialog.tsx index f8bd883e9d..54384aa7aa 100644 --- a/src/browser/components/ShareTranscriptDialog/ShareTranscriptDialog.tsx +++ b/src/browser/components/ShareTranscriptDialog/ShareTranscriptDialog.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { Check, ExternalLink, Loader2, Trash2 } from "lucide-react"; -import { CopyIcon } from "@/browser/components/icons/CopyIcon/CopyIcon"; +import { CopyIcon } from "@/browser/components/Icons/CopyIcon/CopyIcon"; import { Button } from "@/browser/components/Button/Button"; import { Checkbox } from "@/browser/components/Checkbox/Checkbox"; import { diff --git a/src/browser/components/SkillIndicator/SkillIndicator.tsx b/src/browser/components/SkillIndicator/SkillIndicator.tsx index 2855b08e01..32605519ef 100644 --- a/src/browser/components/SkillIndicator/SkillIndicator.tsx +++ b/src/browser/components/SkillIndicator/SkillIndicator.tsx @@ -1,7 +1,7 @@ import React from "react"; import { AlertTriangle, Check, EyeOff, XCircle } from "lucide-react"; import { cn } from "@/common/lib/utils"; -import { SkillIcon } from "@/browser/components/icons/SkillIcon/SkillIcon"; +import { SkillIcon } from "@/browser/components/Icons/SkillIcon/SkillIcon"; import { HoverClickPopover } from "@/browser/components/HoverClickPopover/HoverClickPopover"; import type { LoadedSkill, diff --git a/src/browser/components/TitleBar/TitleBar.tsx b/src/browser/components/TitleBar/TitleBar.tsx index 518a264fbc..79c099403e 100644 --- a/src/browser/components/TitleBar/TitleBar.tsx +++ b/src/browser/components/TitleBar/TitleBar.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { cn } from "@/common/lib/utils"; import { VERSION } from "@/version"; import { SettingsButton } from "../SettingsButton/SettingsButton"; -import { GatewayIcon } from "../icons/GatewayIcon/GatewayIcon"; +import { GatewayIcon } from "../Icons/GatewayIcon/GatewayIcon"; import { Button } from "../Button/Button"; import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; import type { UpdateStatus } from "@/common/orpc/types"; diff --git a/src/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent.tsx b/src/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent.tsx index 7b318c309c..8a1ad87651 100644 --- a/src/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent.tsx +++ b/src/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent.tsx @@ -1,5 +1,5 @@ import { formatKeybind, KEYBINDS } from "@/browser/utils/ui/keybinds"; -import { ArchiveIcon } from "../icons/ArchiveIcon/ArchiveIcon"; +import { ArchiveIcon } from "../Icons/ArchiveIcon/ArchiveIcon"; import { GitBranch, Link2, Maximize2, Pencil, Server } from "lucide-react"; import React from "react"; diff --git a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx b/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx index ab1babcc4f..81ff7ff1e9 100644 --- a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx +++ b/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx @@ -19,8 +19,8 @@ import { PositionedMenu, PositionedMenuItem } from "../PositionedMenu/Positioned import { Trash2, Ellipsis, Loader2, Sparkles } from "lucide-react"; import { WorkspaceStatusIndicator } from "../WorkspaceStatusIndicator/WorkspaceStatusIndicator"; import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; -import { ArchiveIcon } from "../icons/ArchiveIcon/ArchiveIcon"; -import { WorkspaceTerminalIcon } from "../icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; +import { ArchiveIcon } from "../Icons/ArchiveIcon/ArchiveIcon"; +import { WorkspaceTerminalIcon } from "../Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; import { WORKSPACE_DRAG_TYPE, type WorkspaceDragItem, diff --git a/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx b/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx index e83bd81b93..2a3c1a1b12 100644 --- a/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx +++ b/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx @@ -37,7 +37,7 @@ import { ShareTranscriptDialog } from "../ShareTranscriptDialog/ShareTranscriptD import { ConfirmationModal } from "../ConfirmationModal/ConfirmationModal"; import { PopoverError } from "../PopoverError/PopoverError"; import { WorkspaceActionsMenuContent } from "../WorkspaceActionsMenuContent/WorkspaceActionsMenuContent"; -import { WorkspaceTerminalIcon } from "../icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; +import { WorkspaceTerminalIcon } from "../Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; import { SkillIndicator } from "../SkillIndicator/SkillIndicator"; import { useAPI } from "@/browser/contexts/API"; diff --git a/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx b/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx index 1497714eba..49a27faec4 100644 --- a/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx +++ b/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx @@ -1,6 +1,6 @@ import { useWorkspaceSidebarState } from "@/browser/stores/WorkspaceStore"; import { ModelDisplay } from "@/browser/features/Messages/ModelDisplay"; -import { EmojiIcon } from "@/browser/components/icons/EmojiIcon/EmojiIcon"; +import { EmojiIcon } from "@/browser/components/Icons/EmojiIcon/EmojiIcon"; import { CircleHelp, ExternalLinkIcon, Loader2 } from "lucide-react"; import { memo } from "react"; import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; diff --git a/src/browser/features/Messages/CodeBlockSSR.tsx b/src/browser/features/Messages/CodeBlockSSR.tsx index 45e74a626a..964ea47734 100644 --- a/src/browser/features/Messages/CodeBlockSSR.tsx +++ b/src/browser/features/Messages/CodeBlockSSR.tsx @@ -5,7 +5,7 @@ */ import React from "react"; -import { CopyIcon } from "@/browser/components/icons/CopyIcon/CopyIcon"; +import { CopyIcon } from "@/browser/components/Icons/CopyIcon/CopyIcon"; interface CodeBlockSSRProps { code: string; diff --git a/src/browser/features/SplashScreens/OnboardingWizardSplash.tsx b/src/browser/features/SplashScreens/OnboardingWizardSplash.tsx index ff4c3c29cd..82875b5c07 100644 --- a/src/browser/features/SplashScreens/OnboardingWizardSplash.tsx +++ b/src/browser/features/SplashScreens/OnboardingWizardSplash.tsx @@ -18,7 +18,7 @@ import { LocalIcon, SSHIcon, WorktreeIcon, -} from "@/browser/components/icons/RuntimeIcons/RuntimeIcons"; +} from "@/browser/components/Icons/RuntimeIcons/RuntimeIcons"; import { ProjectAddForm, type ProjectAddFormHandle, diff --git a/src/browser/features/Tools/Shared/ToolPrimitives.tsx b/src/browser/features/Tools/Shared/ToolPrimitives.tsx index 1ebcf4eef1..d6013124be 100644 --- a/src/browser/features/Tools/Shared/ToolPrimitives.tsx +++ b/src/browser/features/Tools/Shared/ToolPrimitives.tsx @@ -16,7 +16,7 @@ import { Square, Wrench, } from "lucide-react"; -import { EmojiIcon } from "@/browser/components/icons/EmojiIcon/EmojiIcon"; +import { EmojiIcon } from "@/browser/components/Icons/EmojiIcon/EmojiIcon"; import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; /** diff --git a/src/browser/utils/runtimeUi.ts b/src/browser/utils/runtimeUi.ts index 08638e3e2c..e9ad53fdc2 100644 --- a/src/browser/utils/runtimeUi.ts +++ b/src/browser/utils/runtimeUi.ts @@ -7,7 +7,7 @@ import { DockerIcon, DevcontainerIcon, CoderIcon, -} from "@/browser/components/icons/RuntimeIcons/RuntimeIcons"; +} from "@/browser/components/Icons/RuntimeIcons/RuntimeIcons"; export interface RuntimeIconProps { size?: number; diff --git a/vscode/src/webview/WorkspacePicker.tsx b/vscode/src/webview/WorkspacePicker.tsx index 9ec6f9903e..545c0bdf85 100644 --- a/vscode/src/webview/WorkspacePicker.tsx +++ b/vscode/src/webview/WorkspacePicker.tsx @@ -7,7 +7,7 @@ import { LocalIcon, SSHIcon, WorktreeIcon, -} from "mux/browser/components/icons/RuntimeIcons/RuntimeIcons"; +} from "mux/browser/components/Icons/RuntimeIcons/RuntimeIcons"; import { Shimmer } from "mux/browser/features/AIElements/Shimmer"; import { Button } from "mux/browser/components/Button/Button"; import { Input } from "mux/browser/components/Input/Input"; From 68981d98c0ea6947368febef0f8db6c534c4fbe8 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:32:11 +0000 Subject: [PATCH 4/8] refactor(browser): move domain components into features --- src/browser/App.tsx | 2 +- src/browser/components/AIView/AIView.tsx | 2 +- src/browser/components/ChatPane/ChatPane.tsx | 6 ++-- .../components/LeftSidebar/LeftSidebar.tsx | 2 +- .../ProjectCreateModal/ProjectCreateModal.tsx | 2 +- .../components/ProjectPage/ProjectPage.tsx | 4 +-- src/browser/contexts/RouterContext.tsx | 2 +- src/browser/contexts/WorkspaceContext.tsx | 2 +- .../BranchSelector/BranchSelector.tsx | 4 +-- .../DirectoryPickerModal.tsx | 4 +-- .../Project}/GitInitBanner/GitInitBanner.tsx | 0 .../GitStatusIndicator/GitStatusIndicator.tsx | 0 .../GitStatusIndicatorView.tsx | 4 +-- .../ProjectSidebar/ProjectSidebar.tsx | 26 ++++++++--------- .../ArchivedWorkspaces/ArchivedWorkspaces.tsx | 10 +++---- .../ConcurrentLocalWarning.tsx | 0 .../PinnedTodoList/PinnedTodoList.tsx | 2 +- .../WorkspaceLinks/WorkspaceLinks.tsx | 2 +- .../WorkspaceListItem/WorkspaceListItem.tsx | 18 ++++++------ .../WorkspaceMenuBar/WorkspaceMenuBar.tsx | 28 +++++++++---------- .../WorkspaceShell/WorkspaceShell.tsx | 8 +++--- .../WorkspaceStatusIndicator.tsx | 3 +- src/browser/hooks/useUnreadTracking.ts | 2 +- .../stories/App.readmeScreenshots.stories.tsx | 10 +++---- src/browser/stories/App.sidebar.stories.tsx | 2 +- 25 files changed, 73 insertions(+), 72 deletions(-) rename src/browser/{components => features/Project}/BranchSelector/BranchSelector.tsx (99%) rename src/browser/{components => features/Project}/DirectoryPickerModal/DirectoryPickerModal.tsx (98%) rename src/browser/{components => features/Project}/GitInitBanner/GitInitBanner.tsx (100%) rename src/browser/{components => features/Project/GitStatus}/GitStatusIndicator/GitStatusIndicator.tsx (100%) rename src/browser/{components => features/Project/GitStatus}/GitStatusIndicatorView/GitStatusIndicatorView.tsx (98%) rename src/browser/{components => features/Project}/ProjectSidebar/ProjectSidebar.tsx (98%) rename src/browser/{components => features/Workspace}/ArchivedWorkspaces/ArchivedWorkspaces.tsx (98%) rename src/browser/{components => features/Workspace}/ConcurrentLocalWarning/ConcurrentLocalWarning.tsx (100%) rename src/browser/{components => features/Workspace}/PinnedTodoList/PinnedTodoList.tsx (96%) rename src/browser/{components => features/Workspace}/WorkspaceLinks/WorkspaceLinks.tsx (86%) rename src/browser/{components => features/Workspace}/WorkspaceListItem/WorkspaceListItem.tsx (97%) rename src/browser/{components => features/Workspace}/WorkspaceMenuBar/WorkspaceMenuBar.tsx (94%) rename src/browser/{components => features/Workspace}/WorkspaceShell/WorkspaceShell.tsx (95%) rename src/browser/{components => features/Workspace}/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx (95%) diff --git a/src/browser/App.tsx b/src/browser/App.tsx index dba6636336..a848959254 100644 --- a/src/browser/App.tsx +++ b/src/browser/App.tsx @@ -6,7 +6,7 @@ import "./styles/globals.css"; import { useWorkspaceContext, toWorkspaceSelection } from "./contexts/WorkspaceContext"; import { MUX_HELP_CHAT_WORKSPACE_ID } from "@/common/constants/muxChat"; import { useProjectContext } from "./contexts/ProjectContext"; -import type { WorkspaceSelection } from "./components/ProjectSidebar/ProjectSidebar"; +import type { WorkspaceSelection } from "./features/Project/ProjectSidebar/ProjectSidebar"; import { LeftSidebar } from "./components/LeftSidebar/LeftSidebar"; import { ProjectCreateModal } from "./components/ProjectCreateModal/ProjectCreateModal"; import { AIView } from "./components/AIView/AIView"; diff --git a/src/browser/components/AIView/AIView.tsx b/src/browser/components/AIView/AIView.tsx index bbd2644d78..029dbe50fa 100644 --- a/src/browser/components/AIView/AIView.tsx +++ b/src/browser/components/AIView/AIView.tsx @@ -6,7 +6,7 @@ import { ThinkingProvider } from "@/browser/contexts/ThinkingContext"; import { WorkspaceModeAISync } from "@/browser/components/WorkspaceModeAISync/WorkspaceModeAISync"; import { AgentProvider } from "@/browser/contexts/AgentContext"; import { BackgroundBashProvider } from "@/browser/contexts/BackgroundBashContext"; -import { WorkspaceShell } from "../WorkspaceShell/WorkspaceShell"; +import { WorkspaceShell } from "@/browser/features/Workspace/WorkspaceShell/WorkspaceShell"; interface AIViewProps { workspaceId: string; diff --git a/src/browser/components/ChatPane/ChatPane.tsx b/src/browser/components/ChatPane/ChatPane.tsx index 8e4cd0438d..4074b64a75 100644 --- a/src/browser/components/ChatPane/ChatPane.tsx +++ b/src/browser/components/ChatPane/ChatPane.tsx @@ -24,7 +24,7 @@ import { InterruptedBarrier } from "@/browser/features/Messages/ChatBarrier/Inte import { EditCutoffBarrier } from "@/browser/features/Messages/ChatBarrier/EditCutoffBarrier"; import { StreamingBarrier } from "@/browser/features/Messages/ChatBarrier/StreamingBarrier"; import { RetryBarrier } from "@/browser/features/Messages/ChatBarrier/RetryBarrier"; -import { PinnedTodoList } from "../PinnedTodoList/PinnedTodoList"; +import { PinnedTodoList } from "@/browser/features/Workspace/PinnedTodoList/PinnedTodoList"; import { VIM_ENABLED_KEY } from "@/common/constants/storage"; import { ChatInput, type ChatInputAPI } from "@/browser/features/ChatInput/index"; import type { QueueDispatchMode } from "@/browser/features/ChatInput/types"; @@ -50,7 +50,7 @@ import { useWorkspaceStoreRaw, type WorkspaceState, } from "@/browser/stores/WorkspaceStore"; -import { WorkspaceMenuBar } from "../WorkspaceMenuBar/WorkspaceMenuBar"; +import { WorkspaceMenuBar } from "@/browser/features/Workspace/WorkspaceMenuBar/WorkspaceMenuBar"; import type { DisplayedMessage, QueuedMessage as QueuedMessageData } from "@/common/types/message"; import type { RuntimeConfig } from "@/common/types/runtime"; import { getRuntimeTypeForTelemetry } from "@/common/telemetry"; @@ -58,7 +58,7 @@ import { useAIViewKeybinds } from "@/browser/hooks/useAIViewKeybinds"; import { QueuedMessage } from "@/browser/features/Messages/QueuedMessage"; import { CompactionWarning } from "../CompactionWarning/CompactionWarning"; import { ContextSwitchWarning as ContextSwitchWarningBanner } from "../ContextSwitchWarning/ContextSwitchWarning"; -import { ConcurrentLocalWarning } from "../ConcurrentLocalWarning/ConcurrentLocalWarning"; +import { ConcurrentLocalWarning } from "@/browser/features/Workspace/ConcurrentLocalWarning/ConcurrentLocalWarning"; import { BackgroundProcessesBanner } from "../BackgroundProcessesBanner/BackgroundProcessesBanner"; import { checkAutoCompaction } from "@/common/utils/compaction/autoCompactionCheck"; import { cancelCompaction } from "@/browser/utils/compaction/handler"; diff --git a/src/browser/components/LeftSidebar/LeftSidebar.tsx b/src/browser/components/LeftSidebar/LeftSidebar.tsx index 7af348f288..99293006f9 100644 --- a/src/browser/components/LeftSidebar/LeftSidebar.tsx +++ b/src/browser/components/LeftSidebar/LeftSidebar.tsx @@ -1,7 +1,7 @@ import React from "react"; import { cn } from "@/common/lib/utils"; import type { FrontendWorkspaceMetadata } from "@/common/types/workspace"; -import ProjectSidebar from "../ProjectSidebar/ProjectSidebar"; +import ProjectSidebar from "@/browser/features/Project/ProjectSidebar/ProjectSidebar"; import { TitleBar } from "../TitleBar/TitleBar"; import { isDesktopMode } from "@/browser/hooks/useDesktopTitlebar"; diff --git a/src/browser/components/ProjectCreateModal/ProjectCreateModal.tsx b/src/browser/components/ProjectCreateModal/ProjectCreateModal.tsx index 123b1a0d8a..d64e58ae43 100644 --- a/src/browser/components/ProjectCreateModal/ProjectCreateModal.tsx +++ b/src/browser/components/ProjectCreateModal/ProjectCreateModal.tsx @@ -8,7 +8,7 @@ import { DialogDescription, DialogFooter, } from "@/browser/components/Dialog/Dialog"; -import { DirectoryPickerModal } from "../DirectoryPickerModal/DirectoryPickerModal"; +import { DirectoryPickerModal } from "@/browser/features/Project/DirectoryPickerModal/DirectoryPickerModal"; import { Button } from "@/browser/components/Button/Button"; import { ToggleGroup, diff --git a/src/browser/components/ProjectPage/ProjectPage.tsx b/src/browser/components/ProjectPage/ProjectPage.tsx index 2935ed7be3..3549b1733f 100644 --- a/src/browser/components/ProjectPage/ProjectPage.tsx +++ b/src/browser/components/ProjectPage/ProjectPage.tsx @@ -7,10 +7,10 @@ import { ThinkingProvider } from "@/browser/contexts/ThinkingContext"; import { ChatInput } from "@/browser/features/ChatInput/index"; import type { ChatInputAPI, WorkspaceCreatedOptions } from "@/browser/features/ChatInput/types"; import { ProjectMCPOverview } from "../ProjectMCPOverview/ProjectMCPOverview"; -import { ArchivedWorkspaces } from "../ArchivedWorkspaces/ArchivedWorkspaces"; +import { ArchivedWorkspaces } from "@/browser/features/Workspace/ArchivedWorkspaces/ArchivedWorkspaces"; import { useAPI } from "@/browser/contexts/API"; import { isWorkspaceArchived } from "@/common/utils/archive"; -import { GitInitBanner } from "../GitInitBanner/GitInitBanner"; +import { GitInitBanner } from "@/browser/features/Project/GitInitBanner/GitInitBanner"; import { ConfiguredProvidersBar } from "../ConfiguredProvidersBar/ConfiguredProvidersBar"; import { ConfigureProvidersPrompt } from "../ConfigureProvidersPrompt/ConfigureProvidersPrompt"; import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig"; diff --git a/src/browser/contexts/RouterContext.tsx b/src/browser/contexts/RouterContext.tsx index 6c202c19be..14530bda08 100644 --- a/src/browser/contexts/RouterContext.tsx +++ b/src/browser/contexts/RouterContext.tsx @@ -12,7 +12,7 @@ import { readPersistedState } from "@/browser/hooks/usePersistedState"; import { MUX_HELP_CHAT_WORKSPACE_ID } from "@/common/constants/muxChat"; import { SELECTED_WORKSPACE_KEY } from "@/common/constants/storage"; import { getProjectRouteId } from "@/common/utils/projectRouteId"; -import type { WorkspaceSelection } from "@/browser/components/ProjectSidebar/ProjectSidebar"; +import type { WorkspaceSelection } from "@/browser/features/Project/ProjectSidebar/ProjectSidebar"; export interface RouterContext { navigateToWorkspace: (workspaceId: string) => void; diff --git a/src/browser/contexts/WorkspaceContext.tsx b/src/browser/contexts/WorkspaceContext.tsx index 54e3ad3133..47f0896f7d 100644 --- a/src/browser/contexts/WorkspaceContext.tsx +++ b/src/browser/contexts/WorkspaceContext.tsx @@ -12,7 +12,7 @@ import { } from "react"; import type { FrontendWorkspaceMetadata } from "@/common/types/workspace"; import type { ThinkingLevel } from "@/common/types/thinking"; -import type { WorkspaceSelection } from "@/browser/components/ProjectSidebar/ProjectSidebar"; +import type { WorkspaceSelection } from "@/browser/features/Project/ProjectSidebar/ProjectSidebar"; import type { RuntimeConfig } from "@/common/types/runtime"; import type { MuxDeepLinkPayload } from "@/common/types/deepLink"; import { MUX_HELP_CHAT_WORKSPACE_ID } from "@/common/constants/muxChat"; diff --git a/src/browser/components/BranchSelector/BranchSelector.tsx b/src/browser/features/Project/BranchSelector/BranchSelector.tsx similarity index 99% rename from src/browser/components/BranchSelector/BranchSelector.tsx rename to src/browser/features/Project/BranchSelector/BranchSelector.tsx index db00d87097..5d3ad1772f 100644 --- a/src/browser/components/BranchSelector/BranchSelector.tsx +++ b/src/browser/features/Project/BranchSelector/BranchSelector.tsx @@ -2,8 +2,8 @@ import React, { useState, useCallback, useEffect, useRef } from "react"; import { GitBranch, Loader2, Check, Copy, Globe, ChevronRight } from "lucide-react"; import { cn } from "@/common/lib/utils"; import { useAPI } from "@/browser/contexts/API"; -import { Popover, PopoverContent, PopoverTrigger } from "../Popover/Popover"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; +import { Popover, PopoverContent, PopoverTrigger } from "@/browser/components/Popover/Popover"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; import { useCopyToClipboard } from "@/browser/hooks/useCopyToClipboard"; import { invalidateGitStatus, useGitStatus } from "@/browser/stores/GitStatusStore"; import { createLRUCache } from "@/browser/utils/lruCache"; diff --git a/src/browser/components/DirectoryPickerModal/DirectoryPickerModal.tsx b/src/browser/features/Project/DirectoryPickerModal/DirectoryPickerModal.tsx similarity index 98% rename from src/browser/components/DirectoryPickerModal/DirectoryPickerModal.tsx rename to src/browser/features/Project/DirectoryPickerModal/DirectoryPickerModal.tsx index f316838310..8571f26b0c 100644 --- a/src/browser/components/DirectoryPickerModal/DirectoryPickerModal.tsx +++ b/src/browser/features/Project/DirectoryPickerModal/DirectoryPickerModal.tsx @@ -8,10 +8,10 @@ import { DialogFooter, } from "@/browser/components/Dialog/Dialog"; import { Button } from "@/browser/components/Button/Button"; -import { Checkbox } from "../Checkbox/Checkbox"; +import { Checkbox } from "@/browser/components/Checkbox/Checkbox"; import { Input } from "@/browser/components/Input/Input"; import type { FileTreeNode } from "@/common/utils/git/numstatParser"; -import { DirectoryTree } from "../DirectoryTree/DirectoryTree"; +import { DirectoryTree } from "@/browser/components/DirectoryTree/DirectoryTree"; import { useAPI } from "@/browser/contexts/API"; import { formatKeybind, isMac } from "@/browser/utils/ui/keybinds"; import { getErrorMessage } from "@/common/utils/errors"; diff --git a/src/browser/components/GitInitBanner/GitInitBanner.tsx b/src/browser/features/Project/GitInitBanner/GitInitBanner.tsx similarity index 100% rename from src/browser/components/GitInitBanner/GitInitBanner.tsx rename to src/browser/features/Project/GitInitBanner/GitInitBanner.tsx diff --git a/src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx b/src/browser/features/Project/GitStatus/GitStatusIndicator/GitStatusIndicator.tsx similarity index 100% rename from src/browser/components/GitStatusIndicator/GitStatusIndicator.tsx rename to src/browser/features/Project/GitStatus/GitStatusIndicator/GitStatusIndicator.tsx diff --git a/src/browser/components/GitStatusIndicatorView/GitStatusIndicatorView.tsx b/src/browser/features/Project/GitStatus/GitStatusIndicatorView/GitStatusIndicatorView.tsx similarity index 98% rename from src/browser/components/GitStatusIndicatorView/GitStatusIndicatorView.tsx rename to src/browser/features/Project/GitStatus/GitStatusIndicatorView/GitStatusIndicatorView.tsx index 40688ef480..cf3be0c421 100644 --- a/src/browser/components/GitStatusIndicatorView/GitStatusIndicatorView.tsx +++ b/src/browser/features/Project/GitStatus/GitStatusIndicatorView/GitStatusIndicatorView.tsx @@ -3,8 +3,8 @@ import type { GitStatus } from "@/common/types/workspace"; import type { GitCommit, GitBranchHeader } from "@/common/utils/git/parseGitLog"; import { cn } from "@/common/lib/utils"; import { stopKeyboardPropagation } from "@/browser/utils/events"; -import { ToggleGroup, ToggleGroupItem } from "../ToggleGroupPrimitive/ToggleGroupPrimitive"; -import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../Dialog/Dialog"; +import { ToggleGroup, ToggleGroupItem } from "@/browser/components/ToggleGroupPrimitive/ToggleGroupPrimitive"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/browser/components/Dialog/Dialog"; import { BaseSelectorPopover } from "@/browser/features/RightSidebar/CodeReview/BaseSelectorPopover"; // Helper for indicator colors diff --git a/src/browser/components/ProjectSidebar/ProjectSidebar.tsx b/src/browser/features/Project/ProjectSidebar/ProjectSidebar.tsx similarity index 98% rename from src/browser/components/ProjectSidebar/ProjectSidebar.tsx rename to src/browser/features/Project/ProjectSidebar/ProjectSidebar.tsx index da5a89467a..1103703dc6 100644 --- a/src/browser/components/ProjectSidebar/ProjectSidebar.tsx +++ b/src/browser/features/Project/ProjectSidebar/ProjectSidebar.tsx @@ -51,13 +51,13 @@ import { getSectionTierKey, sortSectionsByLinkedList, } from "@/browser/utils/ui/workspaceFiltering"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; -import { SidebarCollapseButton } from "../SidebarCollapseButton/SidebarCollapseButton"; -import { ConfirmationModal } from "../ConfirmationModal/ConfirmationModal"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; +import { SidebarCollapseButton } from "@/browser/components/SidebarCollapseButton/SidebarCollapseButton"; +import { ConfirmationModal } from "@/browser/components/ConfirmationModal/ConfirmationModal"; import { useSettings } from "@/browser/contexts/SettingsContext"; -import { WorkspaceListItem, type WorkspaceSelection } from "../WorkspaceListItem/WorkspaceListItem"; -import { WorkspaceStatusIndicator } from "../WorkspaceStatusIndicator/WorkspaceStatusIndicator"; +import { WorkspaceListItem, type WorkspaceSelection } from "@/browser/features/Workspace/WorkspaceListItem/WorkspaceListItem"; +import { WorkspaceStatusIndicator } from "@/browser/features/Workspace/WorkspaceStatusIndicator/WorkspaceStatusIndicator"; import { TitleEditProvider, useTitleEdit } from "@/browser/contexts/WorkspaceTitleEditContext"; import { useConfirmDialog } from "@/browser/contexts/ConfirmDialogContext"; import { useProjectContext } from "@/browser/contexts/ProjectContext"; @@ -67,19 +67,19 @@ import { useWorkspaceActions } from "@/browser/contexts/WorkspaceContext"; import { useRouter } from "@/browser/contexts/RouterContext"; import { usePopoverError } from "@/browser/hooks/usePopoverError"; import { forkWorkspace } from "@/browser/utils/chatCommands"; -import { PopoverError } from "../PopoverError/PopoverError"; -import { SectionHeader } from "../SectionHeader/SectionHeader"; -import { AddSectionButton } from "../AddSectionButton/AddSectionButton"; -import { WorkspaceSectionDropZone } from "../WorkspaceSectionDropZone/WorkspaceSectionDropZone"; -import { WorkspaceDragLayer } from "../WorkspaceDragLayer/WorkspaceDragLayer"; -import { SectionDragLayer } from "../SectionDragLayer/SectionDragLayer"; -import { DraggableSection } from "../DraggableSection/DraggableSection"; +import { PopoverError } from "@/browser/components/PopoverError/PopoverError"; +import { SectionHeader } from "@/browser/components/SectionHeader/SectionHeader"; +import { AddSectionButton } from "@/browser/components/AddSectionButton/AddSectionButton"; +import { WorkspaceSectionDropZone } from "@/browser/components/WorkspaceSectionDropZone/WorkspaceSectionDropZone"; +import { WorkspaceDragLayer } from "@/browser/components/WorkspaceDragLayer/WorkspaceDragLayer"; +import { SectionDragLayer } from "@/browser/components/SectionDragLayer/SectionDragLayer"; +import { DraggableSection } from "@/browser/components/DraggableSection/DraggableSection"; import type { SectionConfig } from "@/common/types/project"; import { getErrorMessage } from "@/common/utils/errors"; import { getProjectWorkspaceCounts } from "@/common/utils/projectRemoval"; // Re-export WorkspaceSelection for backwards compatibility -export type { WorkspaceSelection } from "../WorkspaceListItem/WorkspaceListItem"; +export type { WorkspaceSelection } from "@/browser/features/Workspace/WorkspaceListItem/WorkspaceListItem"; // Draggable project item moved to module scope to avoid remounting on every parent render. // Defining components inside another component causes a new function identity each render, diff --git a/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx b/src/browser/features/Workspace/ArchivedWorkspaces/ArchivedWorkspaces.tsx similarity index 98% rename from src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx rename to src/browser/features/Workspace/ArchivedWorkspaces/ArchivedWorkspaces.tsx index 314b8b3cf2..cc49f75ed3 100644 --- a/src/browser/components/ArchivedWorkspaces/ArchivedWorkspaces.tsx +++ b/src/browser/features/Workspace/ArchivedWorkspaces/ArchivedWorkspaces.tsx @@ -7,10 +7,10 @@ import { usePersistedState } from "@/browser/hooks/usePersistedState"; import { getArchivedWorkspacesExpandedKey } from "@/common/constants/storage"; import { useAPI } from "@/browser/contexts/API"; import { ChevronDown, ChevronRight, Loader2, Search, Trash2 } from "lucide-react"; -import { ArchiveIcon, ArchiveRestoreIcon } from "../Icons/ArchiveIcon/ArchiveIcon"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; -import { RuntimeBadge } from "../RuntimeBadge/RuntimeBadge"; -import { Skeleton } from "../Skeleton/Skeleton"; +import { ArchiveIcon, ArchiveRestoreIcon } from "@/browser/components/Icons/ArchiveIcon/ArchiveIcon"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; +import { RuntimeBadge } from "@/browser/components/RuntimeBadge/RuntimeBadge"; +import { Skeleton } from "@/browser/components/Skeleton/Skeleton"; import { Dialog, DialogContent, @@ -19,7 +19,7 @@ import { DialogDescription, DialogFooter, } from "@/browser/components/Dialog/Dialog"; -import { ForceDeleteModal } from "../ForceDeleteModal/ForceDeleteModal"; +import { ForceDeleteModal } from "@/browser/components/ForceDeleteModal/ForceDeleteModal"; import { Button } from "@/browser/components/Button/Button"; import type { z } from "zod"; import type { SessionUsageFileSchema } from "@/common/orpc/schemas/chatStats"; diff --git a/src/browser/components/ConcurrentLocalWarning/ConcurrentLocalWarning.tsx b/src/browser/features/Workspace/ConcurrentLocalWarning/ConcurrentLocalWarning.tsx similarity index 100% rename from src/browser/components/ConcurrentLocalWarning/ConcurrentLocalWarning.tsx rename to src/browser/features/Workspace/ConcurrentLocalWarning/ConcurrentLocalWarning.tsx diff --git a/src/browser/components/PinnedTodoList/PinnedTodoList.tsx b/src/browser/features/Workspace/PinnedTodoList/PinnedTodoList.tsx similarity index 96% rename from src/browser/components/PinnedTodoList/PinnedTodoList.tsx rename to src/browser/features/Workspace/PinnedTodoList/PinnedTodoList.tsx index ff8e387d8c..fca41c1d4b 100644 --- a/src/browser/components/PinnedTodoList/PinnedTodoList.tsx +++ b/src/browser/features/Workspace/PinnedTodoList/PinnedTodoList.tsx @@ -1,5 +1,5 @@ import React, { useSyncExternalStore } from "react"; -import { TodoList } from "../TodoList/TodoList"; +import { TodoList } from "@/browser/components/TodoList/TodoList"; import { useWorkspaceStoreRaw } from "@/browser/stores/WorkspaceStore"; import { usePersistedState } from "@/browser/hooks/usePersistedState"; import { cn } from "@/common/lib/utils"; diff --git a/src/browser/components/WorkspaceLinks/WorkspaceLinks.tsx b/src/browser/features/Workspace/WorkspaceLinks/WorkspaceLinks.tsx similarity index 86% rename from src/browser/components/WorkspaceLinks/WorkspaceLinks.tsx rename to src/browser/features/Workspace/WorkspaceLinks/WorkspaceLinks.tsx index 8700f6dcb7..2b5cffafa0 100644 --- a/src/browser/components/WorkspaceLinks/WorkspaceLinks.tsx +++ b/src/browser/features/Workspace/WorkspaceLinks/WorkspaceLinks.tsx @@ -4,7 +4,7 @@ */ import { useWorkspacePR } from "@/browser/stores/PRStatusStore"; -import { PRLinkBadge } from "../PRLinkBadge/PRLinkBadge"; +import { PRLinkBadge } from "@/browser/components/PRLinkBadge/PRLinkBadge"; interface WorkspaceLinksProps { workspaceId: string; diff --git a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx b/src/browser/features/Workspace/WorkspaceListItem/WorkspaceListItem.tsx similarity index 97% rename from src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx rename to src/browser/features/Workspace/WorkspaceListItem/WorkspaceListItem.tsx index 81ff7ff1e9..319b2d5ea3 100644 --- a/src/browser/components/WorkspaceListItem/WorkspaceListItem.tsx +++ b/src/browser/features/Workspace/WorkspaceListItem/WorkspaceListItem.tsx @@ -10,25 +10,25 @@ import type { FrontendWorkspaceMetadata } from "@/common/types/workspace"; import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from "react"; import { useDrag } from "react-dnd"; import { getEmptyImage } from "react-dnd-html5-backend"; -import { GitStatusIndicator } from "../GitStatusIndicator/GitStatusIndicator"; +import { GitStatusIndicator } from "@/browser/features/Project/GitStatus/GitStatusIndicator/GitStatusIndicator"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; -import { Popover, PopoverContent, PopoverTrigger, PopoverAnchor } from "../Popover/Popover"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; +import { Popover, PopoverContent, PopoverTrigger, PopoverAnchor } from "@/browser/components/Popover/Popover"; import { useContextMenuPosition } from "@/browser/hooks/useContextMenuPosition"; -import { PositionedMenu, PositionedMenuItem } from "../PositionedMenu/PositionedMenu"; +import { PositionedMenu, PositionedMenuItem } from "@/browser/components/PositionedMenu/PositionedMenu"; import { Trash2, Ellipsis, Loader2, Sparkles } from "lucide-react"; import { WorkspaceStatusIndicator } from "../WorkspaceStatusIndicator/WorkspaceStatusIndicator"; import { Shimmer } from "@/browser/components/Shimmer/Shimmer"; -import { ArchiveIcon } from "../Icons/ArchiveIcon/ArchiveIcon"; -import { WorkspaceTerminalIcon } from "../Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; +import { ArchiveIcon } from "@/browser/components/Icons/ArchiveIcon/ArchiveIcon"; +import { WorkspaceTerminalIcon } from "@/browser/components/Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; import { WORKSPACE_DRAG_TYPE, type WorkspaceDragItem, -} from "../WorkspaceSectionDropZone/WorkspaceSectionDropZone"; +} from "@/browser/components/WorkspaceSectionDropZone/WorkspaceSectionDropZone"; import { useLinkSharingEnabled } from "@/browser/contexts/TelemetryEnabledContext"; import { formatKeybind, KEYBINDS } from "@/browser/utils/ui/keybinds"; -import { ShareTranscriptDialog } from "../ShareTranscriptDialog/ShareTranscriptDialog"; -import { WorkspaceActionsMenuContent } from "../WorkspaceActionsMenuContent/WorkspaceActionsMenuContent"; +import { ShareTranscriptDialog } from "@/browser/components/ShareTranscriptDialog/ShareTranscriptDialog"; +import { WorkspaceActionsMenuContent } from "@/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent"; import { useAPI } from "@/browser/contexts/API"; export interface WorkspaceSelection { diff --git a/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx b/src/browser/features/Workspace/WorkspaceMenuBar/WorkspaceMenuBar.tsx similarity index 94% rename from src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx rename to src/browser/features/Workspace/WorkspaceMenuBar/WorkspaceMenuBar.tsx index 2a3c1a1b12..6357edd6a9 100644 --- a/src/browser/components/WorkspaceMenuBar/WorkspaceMenuBar.tsx +++ b/src/browser/features/Workspace/WorkspaceMenuBar/WorkspaceMenuBar.tsx @@ -10,13 +10,13 @@ import { getNotifyOnResponseKey, getNotifyOnResponseAutoEnableKey, } from "@/common/constants/storage"; -import { GitStatusIndicator } from "../GitStatusIndicator/GitStatusIndicator"; -import { RuntimeBadge } from "../RuntimeBadge/RuntimeBadge"; -import { BranchSelector } from "../BranchSelector/BranchSelector"; -import { WorkspaceMCPModal } from "../WorkspaceMCPModal/WorkspaceMCPModal"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; -import { Popover, PopoverTrigger, PopoverContent } from "../Popover/Popover"; -import { Checkbox } from "../Checkbox/Checkbox"; +import { GitStatusIndicator } from "@/browser/features/Project/GitStatus/GitStatusIndicator/GitStatusIndicator"; +import { RuntimeBadge } from "@/browser/components/RuntimeBadge/RuntimeBadge"; +import { BranchSelector } from "@/browser/features/Project/BranchSelector/BranchSelector"; +import { WorkspaceMCPModal } from "@/browser/components/WorkspaceMCPModal/WorkspaceMCPModal"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; +import { Popover, PopoverTrigger, PopoverContent } from "@/browser/components/Popover/Popover"; +import { Checkbox } from "@/browser/components/Checkbox/Checkbox"; import { formatKeybind, KEYBINDS, matchesKeybind } from "@/browser/utils/ui/keybinds"; import { useGitStatus } from "@/browser/stores/GitStatusStore"; import { useWorkspaceSidebarState } from "@/browser/stores/WorkspaceStore"; @@ -31,15 +31,15 @@ import { useOpenInEditor } from "@/browser/hooks/useOpenInEditor"; import { usePersistedState } from "@/browser/hooks/usePersistedState"; import { usePopoverError } from "@/browser/hooks/usePopoverError"; import { isDesktopMode, DESKTOP_TITLEBAR_HEIGHT_CLASS } from "@/browser/hooks/useDesktopTitlebar"; -import { DebugLlmRequestModal } from "../DebugLlmRequestModal/DebugLlmRequestModal"; +import { DebugLlmRequestModal } from "@/browser/components/DebugLlmRequestModal/DebugLlmRequestModal"; import { WorkspaceLinks } from "../WorkspaceLinks/WorkspaceLinks"; -import { ShareTranscriptDialog } from "../ShareTranscriptDialog/ShareTranscriptDialog"; -import { ConfirmationModal } from "../ConfirmationModal/ConfirmationModal"; -import { PopoverError } from "../PopoverError/PopoverError"; -import { WorkspaceActionsMenuContent } from "../WorkspaceActionsMenuContent/WorkspaceActionsMenuContent"; -import { WorkspaceTerminalIcon } from "../Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; +import { ShareTranscriptDialog } from "@/browser/components/ShareTranscriptDialog/ShareTranscriptDialog"; +import { ConfirmationModal } from "@/browser/components/ConfirmationModal/ConfirmationModal"; +import { PopoverError } from "@/browser/components/PopoverError/PopoverError"; +import { WorkspaceActionsMenuContent } from "@/browser/components/WorkspaceActionsMenuContent/WorkspaceActionsMenuContent"; +import { WorkspaceTerminalIcon } from "@/browser/components/Icons/WorkspaceTerminalIcon/WorkspaceTerminalIcon"; -import { SkillIndicator } from "../SkillIndicator/SkillIndicator"; +import { SkillIndicator } from "@/browser/components/SkillIndicator/SkillIndicator"; import { useAPI } from "@/browser/contexts/API"; import { useAgent } from "@/browser/contexts/AgentContext"; diff --git a/src/browser/components/WorkspaceShell/WorkspaceShell.tsx b/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx similarity index 95% rename from src/browser/components/WorkspaceShell/WorkspaceShell.tsx rename to src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx index 997f09ed2b..12be90b5b9 100644 --- a/src/browser/components/WorkspaceShell/WorkspaceShell.tsx +++ b/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx @@ -1,21 +1,21 @@ import type { TerminalSessionCreateOptions } from "@/browser/utils/terminal"; import React, { useCallback, useRef } from "react"; import { cn } from "@/common/lib/utils"; -import { LoadingAnimation } from "../LoadingAnimation/LoadingAnimation"; +import { LoadingAnimation } from "@/browser/components/LoadingAnimation/LoadingAnimation"; import { RIGHT_SIDEBAR_WIDTH_KEY, getReviewImmersiveKey } from "@/common/constants/storage"; import { useResizableSidebar } from "@/browser/hooks/useResizableSidebar"; import { useResizeObserver } from "@/browser/hooks/useResizeObserver"; import { useOpenTerminal } from "@/browser/hooks/useOpenTerminal"; import { usePersistedState } from "@/browser/hooks/usePersistedState"; import { RightSidebar } from "@/browser/features/RightSidebar/RightSidebar"; -import { PopoverError } from "../PopoverError/PopoverError"; +import { PopoverError } from "@/browser/components/PopoverError/PopoverError"; import type { RuntimeConfig } from "@/common/types/runtime"; import { useBackgroundBashError } from "@/browser/contexts/BackgroundBashContext"; import { useWorkspaceState } from "@/browser/stores/WorkspaceStore"; import { useReviews } from "@/browser/hooks/useReviews"; import type { ReviewNoteData } from "@/common/types/review"; -import { ConnectionStatusToast } from "../ConnectionStatusToast/ConnectionStatusToast"; -import { ChatPane } from "../ChatPane/ChatPane"; +import { ConnectionStatusToast } from "@/browser/components/ConnectionStatusToast/ConnectionStatusToast"; +import { ChatPane } from "@/browser/components/ChatPane/ChatPane"; // ChatPane uses tailwind `min-w-96`. const CHAT_PANE_MIN_WIDTH_PX = 384; diff --git a/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx b/src/browser/features/Workspace/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx similarity index 95% rename from src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx rename to src/browser/features/Workspace/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx index 49a27faec4..8f4c611044 100644 --- a/src/browser/components/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx +++ b/src/browser/features/Workspace/WorkspaceStatusIndicator/WorkspaceStatusIndicator.tsx @@ -3,7 +3,8 @@ import { ModelDisplay } from "@/browser/features/Messages/ModelDisplay"; import { EmojiIcon } from "@/browser/components/Icons/EmojiIcon/EmojiIcon"; import { CircleHelp, ExternalLinkIcon, Loader2 } from "lucide-react"; import { memo } from "react"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; +import { Button } from "@/browser/components/Button/Button"; export const WorkspaceStatusIndicator = memo<{ workspaceId: string; diff --git a/src/browser/hooks/useUnreadTracking.ts b/src/browser/hooks/useUnreadTracking.ts index 72e57b5e51..c384844f00 100644 --- a/src/browser/hooks/useUnreadTracking.ts +++ b/src/browser/hooks/useUnreadTracking.ts @@ -1,5 +1,5 @@ import { useEffect, useCallback, useRef } from "react"; -import type { WorkspaceSelection } from "@/browser/components/ProjectSidebar/ProjectSidebar"; +import type { WorkspaceSelection } from "@/browser/features/Project/ProjectSidebar/ProjectSidebar"; import { getWorkspaceLastReadKey } from "@/common/constants/storage"; import { readPersistedState, updatePersistedState } from "./usePersistedState"; diff --git a/src/browser/stories/App.readmeScreenshots.stories.tsx b/src/browser/stories/App.readmeScreenshots.stories.tsx index a93a7e5bc0..860b6ff40d 100644 --- a/src/browser/stories/App.readmeScreenshots.stories.tsx +++ b/src/browser/stories/App.readmeScreenshots.stories.tsx @@ -273,10 +273,10 @@ export const CodeReview: AppStory = { window.localStorage.setItem(RIGHT_SIDEBAR_WIDTH_KEY, "950"); window.localStorage.removeItem(getRightSidebarLayoutKey(workspaceId)); - const REVIEW_DIFF = `diff --git a/src/browser/components/WorkspaceShell.tsx b/src/browser/components/WorkspaceShell.tsx + const REVIEW_DIFF = `diff --git a/src/browser/features/Workspace/WorkspaceShell.tsx b/src/browser/features/Workspace/WorkspaceShell.tsx index aaa1111..bbb2222 100644 ---- a/src/browser/components/WorkspaceShell.tsx -+++ b/src/browser/components/WorkspaceShell.tsx +--- a/src/browser/features/Workspace/WorkspaceShell.tsx ++++ b/src/browser/features/Workspace/WorkspaceShell.tsx @@ -1,8 +1,18 @@ import React from 'react'; +import { useRightSidebarLayout } from '../Hooks/useRightSidebarLayout'; @@ -328,7 +328,7 @@ index 0000000..def5678 + return layout; +}`; - const REVIEW_NUMSTAT = `10\t2\tsrc/browser/components/WorkspaceShell.tsx + const REVIEW_NUMSTAT = `10\t2\tsrc/browser/features/Workspace/WorkspaceShell.tsx 12\t0\tsrc/browser/utils/layout.ts 18\t0\tsrc/browser/hooks/useRightSidebarLayout.ts`; @@ -354,7 +354,7 @@ index 0000000..def5678 toolCalls: [ createFileReadTool( "call-read-1", - "src/browser/components/WorkspaceShell.tsx", + "src/browser/features/Workspace/WorkspaceShell.tsx", 'import React from \'react\';\nimport { useRightSidebarLayout } from \'../hooks/useRightSidebarLayout\';\nimport { clamp } from \'../utils/layout\';\n\nexport function WorkspaceShell(props: WorkspaceShellProps) {\n const layout = useRightSidebarLayout(props.workspaceId);\n const sidebarWidth = clamp(layout.width, 200, 800);\n return (\n
\n
Mux
\n
\n
\n );\n}' ), createFileReadTool( diff --git a/src/browser/stories/App.sidebar.stories.tsx b/src/browser/stories/App.sidebar.stories.tsx index ec4d383e06..a2706312f7 100644 --- a/src/browser/stories/App.sidebar.stories.tsx +++ b/src/browser/stories/App.sidebar.stories.tsx @@ -88,7 +88,7 @@ function createGitStatusExecutor(gitStatus?: Map) { const dirtyFiles = dirtyCount > 0 - ? [" M src/App.tsx", " M src/browser/components/GitStatusIndicatorView.tsx"].join("\n") + ? [" M src/App.tsx", " M src/browser/features/Project/GitStatus/GitStatusIndicatorView.tsx"].join("\n") : ""; return [ From fc8fa13639cc737278be8149454ddf9ee980d914 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:31:22 +0000 Subject: [PATCH 5/8] refactor(browser): move chat, command palette, and app shell components into features --- src/browser/App.tsx | 6 ++-- .../AppLoader/AppLoader.auth.test.tsx | 6 ++-- .../AppShell}/AppLoader/AppLoader.tsx | 30 +++++++++---------- .../BackgroundProcessesBanner.tsx | 4 +-- .../ConnectionStatusToast.tsx | 0 .../WindowsToolchainBanner.tsx | 0 .../Chat}/AIView/AIView.tsx | 0 .../AgentModePicker/AgentModePicker.test.tsx | 2 +- .../Chat}/AgentModePicker/AgentModePicker.tsx | 0 .../Chat}/ChatPane/ChatPane.tsx | 15 ++++++---- src/browser/features/ChatInput/index.tsx | 4 +-- .../CommandPalette/CommandPalette.test.ts | 0 .../CommandPalette/CommandPalette.tsx | 0 .../features/Tools/SwitchAgentToolCall.tsx | 2 +- .../WorkspaceShell/WorkspaceShell.tsx | 4 +-- src/browser/main.tsx | 2 +- src/browser/stories/meta.tsx | 2 +- tests/ui/renderReviewPanel.tsx | 2 +- 18 files changed, 41 insertions(+), 38 deletions(-) rename src/browser/{components => features/AppShell}/AppLoader/AppLoader.auth.test.tsx (96%) rename src/browser/{components => features/AppShell}/AppLoader/AppLoader.tsx (83%) rename src/browser/{components => features/AppShell}/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx (97%) rename src/browser/{components => features/AppShell}/ConnectionStatusToast/ConnectionStatusToast.tsx (100%) rename src/browser/{components => features/AppShell}/WindowsToolchainBanner/WindowsToolchainBanner.tsx (100%) rename src/browser/{components => features/Chat}/AIView/AIView.tsx (100%) rename src/browser/{components => features/Chat}/AgentModePicker/AgentModePicker.test.tsx (99%) rename src/browser/{components => features/Chat}/AgentModePicker/AgentModePicker.tsx (100%) rename src/browser/{components => features/Chat}/ChatPane/ChatPane.tsx (98%) rename src/browser/{components => features/CommandPalette}/CommandPalette/CommandPalette.test.ts (100%) rename src/browser/{components => features/CommandPalette}/CommandPalette/CommandPalette.tsx (100%) diff --git a/src/browser/App.tsx b/src/browser/App.tsx index a848959254..eef7880fdd 100644 --- a/src/browser/App.tsx +++ b/src/browser/App.tsx @@ -9,7 +9,7 @@ import { useProjectContext } from "./contexts/ProjectContext"; import type { WorkspaceSelection } from "./features/Project/ProjectSidebar/ProjectSidebar"; import { LeftSidebar } from "./components/LeftSidebar/LeftSidebar"; import { ProjectCreateModal } from "./components/ProjectCreateModal/ProjectCreateModal"; -import { AIView } from "./components/AIView/AIView"; +import { AIView } from "./features/Chat/AIView/AIView"; import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary"; import { usePersistedState, @@ -29,7 +29,7 @@ import { CommandRegistryProvider, useCommandRegistry } from "./contexts/CommandR import { useOpenTerminal } from "./hooks/useOpenTerminal"; import type { CommandAction } from "./contexts/CommandRegistryContext"; import { useTheme, type ThemeMode } from "./contexts/ThemeContext"; -import { CommandPalette } from "./components/CommandPalette/CommandPalette"; +import { CommandPalette } from "./features/CommandPalette/CommandPalette/CommandPalette"; import { buildCoreSources, type BuildSourcesParams } from "./utils/commands/sources"; import { THINKING_LEVELS, type ThinkingLevel } from "@/common/types/thinking"; @@ -81,7 +81,7 @@ import { FeatureFlagsProvider } from "./contexts/FeatureFlagsContext"; import { ExperimentsProvider } from "./contexts/ExperimentsContext"; import { ProviderOptionsProvider } from "./contexts/ProviderOptionsContext"; import { getWorkspaceSidebarKey } from "./utils/workspace"; -import { WindowsToolchainBanner } from "./components/WindowsToolchainBanner/WindowsToolchainBanner"; +import { WindowsToolchainBanner } from "./features/AppShell/WindowsToolchainBanner/WindowsToolchainBanner"; import { RosettaBanner } from "./components/RosettaBanner/RosettaBanner"; import { isDesktopMode } from "./hooks/useDesktopTitlebar"; import { cn } from "@/common/lib/utils"; diff --git a/src/browser/components/AppLoader/AppLoader.auth.test.tsx b/src/browser/features/AppShell/AppLoader/AppLoader.auth.test.tsx similarity index 96% rename from src/browser/components/AppLoader/AppLoader.auth.test.tsx rename to src/browser/features/AppShell/AppLoader/AppLoader.auth.test.tsx index 6e3bcc3d8e..3a3dfe22c5 100644 --- a/src/browser/components/AppLoader/AppLoader.auth.test.tsx +++ b/src/browser/features/AppShell/AppLoader/AppLoader.auth.test.tsx @@ -1,10 +1,10 @@ -import "../../../../tests/ui/dom"; +import "../../../../../tests/ui/dom"; import React from "react"; import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { cleanup, render } from "@testing-library/react"; -import { useTheme } from "../../contexts/ThemeContext"; -import { installDom } from "../../../../tests/ui/dom"; +import { useTheme } from "@/browser/contexts/ThemeContext"; +import { installDom } from "../../../../../tests/ui/dom"; let cleanupDom: (() => void) | null = null; diff --git a/src/browser/components/AppLoader/AppLoader.tsx b/src/browser/features/AppShell/AppLoader/AppLoader.tsx similarity index 83% rename from src/browser/components/AppLoader/AppLoader.tsx rename to src/browser/features/AppShell/AppLoader/AppLoader.tsx index 0e1517e56c..868eb57917 100644 --- a/src/browser/components/AppLoader/AppLoader.tsx +++ b/src/browser/features/AppShell/AppLoader/AppLoader.tsx @@ -1,23 +1,23 @@ import { useState, useEffect } from "react"; import { AnimatePresence, motion } from "motion/react"; -import App from "../../App"; -import { AuthTokenModal } from "../AuthTokenModal/AuthTokenModal"; -import { ThemeProvider } from "../../contexts/ThemeContext"; -import { LoadingScreen } from "../LoadingScreen/LoadingScreen"; -import { StartupConnectionError } from "../StartupConnectionError/StartupConnectionError"; -import { useReducedMotion } from "../../hooks/useReducedMotion"; -import { useWorkspaceStoreRaw, workspaceStore } from "../../stores/WorkspaceStore"; -import { useGitStatusStoreRaw } from "../../stores/GitStatusStore"; -import { useBackgroundBashStoreRaw } from "../../stores/BackgroundBashStore"; -import { getPRStatusStoreInstance } from "../../stores/PRStatusStore"; -import { ProjectProvider, useProjectContext } from "../../contexts/ProjectContext"; +import App from "@/browser/App"; +import { AuthTokenModal } from "@/browser/components/AuthTokenModal/AuthTokenModal"; +import { ThemeProvider } from "@/browser/contexts/ThemeContext"; +import { LoadingScreen } from "@/browser/components/LoadingScreen/LoadingScreen"; +import { StartupConnectionError } from "@/browser/components/StartupConnectionError/StartupConnectionError"; +import { useReducedMotion } from "@/browser/hooks/useReducedMotion"; +import { useWorkspaceStoreRaw, workspaceStore } from "@/browser/stores/WorkspaceStore"; +import { useGitStatusStoreRaw } from "@/browser/stores/GitStatusStore"; +import { useBackgroundBashStoreRaw } from "@/browser/stores/BackgroundBashStore"; +import { getPRStatusStoreInstance } from "@/browser/stores/PRStatusStore"; +import { ProjectProvider, useProjectContext } from "@/browser/contexts/ProjectContext"; import { PolicyProvider, usePolicy } from "@/browser/contexts/PolicyContext"; import { PolicyBlockedScreen } from "@/browser/components/PolicyBlockedScreen/PolicyBlockedScreen"; import { APIProvider, useAPI, type APIClient } from "@/browser/contexts/API"; -import { WorkspaceProvider, useWorkspaceContext } from "../../contexts/WorkspaceContext"; -import { RouterProvider } from "../../contexts/RouterContext"; -import { TelemetryEnabledProvider } from "../../contexts/TelemetryEnabledContext"; -import { TerminalRouterProvider } from "../../terminal/TerminalRouterContext"; +import { WorkspaceProvider, useWorkspaceContext } from "@/browser/contexts/WorkspaceContext"; +import { RouterProvider } from "@/browser/contexts/RouterContext"; +import { TelemetryEnabledProvider } from "@/browser/contexts/TelemetryEnabledContext"; +import { TerminalRouterProvider } from "@/browser/terminal/TerminalRouterContext"; interface AppLoaderProps { /** Optional pre-created ORPC api?. If provided, skips internal connection setup. */ diff --git a/src/browser/components/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx b/src/browser/features/AppShell/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx similarity index 97% rename from src/browser/components/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx rename to src/browser/features/AppShell/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx index ede9c0dca4..75c71b5905 100644 --- a/src/browser/components/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx +++ b/src/browser/features/AppShell/BackgroundProcessesBanner/BackgroundProcessesBanner.tsx @@ -1,8 +1,8 @@ import React, { useState, useCallback, useEffect } from "react"; import { Terminal, X, ChevronDown, ChevronRight, Loader2, FileText } from "lucide-react"; -import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip"; +import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; import { cn } from "@/common/lib/utils"; -import { BackgroundBashOutputDialog } from "../BackgroundBashOutputDialog/BackgroundBashOutputDialog"; +import { BackgroundBashOutputDialog } from "@/browser/components/BackgroundBashOutputDialog/BackgroundBashOutputDialog"; import { formatDuration } from "@/browser/features/Tools/Shared/toolUtils"; import { useBackgroundBashTerminatingIds, diff --git a/src/browser/components/ConnectionStatusToast/ConnectionStatusToast.tsx b/src/browser/features/AppShell/ConnectionStatusToast/ConnectionStatusToast.tsx similarity index 100% rename from src/browser/components/ConnectionStatusToast/ConnectionStatusToast.tsx rename to src/browser/features/AppShell/ConnectionStatusToast/ConnectionStatusToast.tsx diff --git a/src/browser/components/WindowsToolchainBanner/WindowsToolchainBanner.tsx b/src/browser/features/AppShell/WindowsToolchainBanner/WindowsToolchainBanner.tsx similarity index 100% rename from src/browser/components/WindowsToolchainBanner/WindowsToolchainBanner.tsx rename to src/browser/features/AppShell/WindowsToolchainBanner/WindowsToolchainBanner.tsx diff --git a/src/browser/components/AIView/AIView.tsx b/src/browser/features/Chat/AIView/AIView.tsx similarity index 100% rename from src/browser/components/AIView/AIView.tsx rename to src/browser/features/Chat/AIView/AIView.tsx diff --git a/src/browser/components/AgentModePicker/AgentModePicker.test.tsx b/src/browser/features/Chat/AgentModePicker/AgentModePicker.test.tsx similarity index 99% rename from src/browser/components/AgentModePicker/AgentModePicker.test.tsx rename to src/browser/features/Chat/AgentModePicker/AgentModePicker.test.tsx index 570ecf9b74..bafe400d0d 100644 --- a/src/browser/components/AgentModePicker/AgentModePicker.test.tsx +++ b/src/browser/features/Chat/AgentModePicker/AgentModePicker.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { afterEach, beforeEach, describe, expect, test } from "bun:test"; import { cleanup, fireEvent, render, waitFor } from "@testing-library/react"; -import { installDom } from "../../../../tests/ui/dom"; +import { installDom } from "../../../../../tests/ui/dom"; import { AgentProvider } from "@/browser/contexts/AgentContext"; import { TooltipProvider } from "@/browser/components/Tooltip/Tooltip"; diff --git a/src/browser/components/AgentModePicker/AgentModePicker.tsx b/src/browser/features/Chat/AgentModePicker/AgentModePicker.tsx similarity index 100% rename from src/browser/components/AgentModePicker/AgentModePicker.tsx rename to src/browser/features/Chat/AgentModePicker/AgentModePicker.tsx diff --git a/src/browser/components/ChatPane/ChatPane.tsx b/src/browser/features/Chat/ChatPane/ChatPane.tsx similarity index 98% rename from src/browser/components/ChatPane/ChatPane.tsx rename to src/browser/features/Chat/ChatPane/ChatPane.tsx index 4074b64a75..83035c6eec 100644 --- a/src/browser/components/ChatPane/ChatPane.tsx +++ b/src/browser/features/Chat/ChatPane/ChatPane.tsx @@ -14,7 +14,10 @@ import { getTranscriptContextMenuText, } from "@/browser/utils/messages/transcriptContextMenu"; import { useContextMenuPosition } from "@/browser/hooks/useContextMenuPosition"; -import { PositionedMenu, PositionedMenuItem } from "../PositionedMenu/PositionedMenu"; +import { + PositionedMenu, + PositionedMenuItem, +} from "@/browser/components/PositionedMenu/PositionedMenu"; import { MessageListProvider } from "@/browser/features/Messages/MessageListContext"; import { cn } from "@/common/lib/utils"; import { MessageRenderer } from "@/browser/features/Messages/MessageRenderer"; @@ -56,22 +59,22 @@ import type { RuntimeConfig } from "@/common/types/runtime"; import { getRuntimeTypeForTelemetry } from "@/common/telemetry"; import { useAIViewKeybinds } from "@/browser/hooks/useAIViewKeybinds"; import { QueuedMessage } from "@/browser/features/Messages/QueuedMessage"; -import { CompactionWarning } from "../CompactionWarning/CompactionWarning"; -import { ContextSwitchWarning as ContextSwitchWarningBanner } from "../ContextSwitchWarning/ContextSwitchWarning"; +import { CompactionWarning } from "@/browser/components/CompactionWarning/CompactionWarning"; +import { ContextSwitchWarning as ContextSwitchWarningBanner } from "@/browser/components/ContextSwitchWarning/ContextSwitchWarning"; import { ConcurrentLocalWarning } from "@/browser/features/Workspace/ConcurrentLocalWarning/ConcurrentLocalWarning"; -import { BackgroundProcessesBanner } from "../BackgroundProcessesBanner/BackgroundProcessesBanner"; +import { BackgroundProcessesBanner } from "@/browser/features/AppShell/BackgroundProcessesBanner/BackgroundProcessesBanner"; import { checkAutoCompaction } from "@/common/utils/compaction/autoCompactionCheck"; import { cancelCompaction } from "@/browser/utils/compaction/handler"; import type { ContextSwitchWarning } from "@/browser/utils/compaction/contextSwitchCheck"; import { useProviderOptions } from "@/browser/hooks/useProviderOptions"; -import { useAutoCompactionSettings } from "../../hooks/useAutoCompactionSettings"; +import { useAutoCompactionSettings } from "@/browser/hooks/useAutoCompactionSettings"; import { useContextSwitchWarning } from "@/browser/hooks/useContextSwitchWarning"; import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig"; import { useSendMessageOptions } from "@/browser/hooks/useSendMessageOptions"; import type { TerminalSessionCreateOptions } from "@/browser/utils/terminal"; import { useAPI } from "@/browser/contexts/API"; import { useReviews } from "@/browser/hooks/useReviews"; -import { ReviewsBanner } from "../ReviewsBanner/ReviewsBanner"; +import { ReviewsBanner } from "@/browser/components/ReviewsBanner/ReviewsBanner"; import type { ReviewNoteData } from "@/common/types/review"; import { useWorkspaceContext } from "@/browser/contexts/WorkspaceContext"; import { diff --git a/src/browser/features/ChatInput/index.tsx b/src/browser/features/ChatInput/index.tsx index 5457909dd6..03ce3943a6 100644 --- a/src/browser/features/ChatInput/index.tsx +++ b/src/browser/features/ChatInput/index.tsx @@ -5,7 +5,7 @@ import { FILE_SUGGESTION_KEYS, } from "@/browser/features/ChatInput/CommandSuggestions"; import type { Toast } from "@/browser/features/ChatInput/ChatInputToast"; -import { ConnectionStatusToast } from "@/browser/components/ConnectionStatusToast/ConnectionStatusToast"; +import { ConnectionStatusToast } from "@/browser/features/AppShell/ConnectionStatusToast/ConnectionStatusToast"; import { ChatInputToast } from "@/browser/features/ChatInput/ChatInputToast"; import type { SendMessageError } from "@/common/types/errors"; import { createErrorToast } from "@/browser/features/ChatInput/ChatInputToasts"; @@ -65,7 +65,7 @@ import { type SlashSuggestion, } from "@/browser/utils/slashCommands/suggestions"; import { Tooltip, TooltipTrigger, TooltipContent } from "@/browser/components/Tooltip/Tooltip"; -import { AgentModePicker } from "@/browser/components/AgentModePicker/AgentModePicker"; +import { AgentModePicker } from "@/browser/features/Chat/AgentModePicker/AgentModePicker"; import { ContextUsageIndicatorButton } from "@/browser/components/ContextUsageIndicatorButton/ContextUsageIndicatorButton"; import { useWorkspaceUsage } from "@/browser/stores/WorkspaceStore"; import { useProviderOptions } from "@/browser/hooks/useProviderOptions"; diff --git a/src/browser/components/CommandPalette/CommandPalette.test.ts b/src/browser/features/CommandPalette/CommandPalette/CommandPalette.test.ts similarity index 100% rename from src/browser/components/CommandPalette/CommandPalette.test.ts rename to src/browser/features/CommandPalette/CommandPalette/CommandPalette.test.ts diff --git a/src/browser/components/CommandPalette/CommandPalette.tsx b/src/browser/features/CommandPalette/CommandPalette/CommandPalette.tsx similarity index 100% rename from src/browser/components/CommandPalette/CommandPalette.tsx rename to src/browser/features/CommandPalette/CommandPalette/CommandPalette.tsx diff --git a/src/browser/features/Tools/SwitchAgentToolCall.tsx b/src/browser/features/Tools/SwitchAgentToolCall.tsx index 758f4a0574..1e93f38fe0 100644 --- a/src/browser/features/Tools/SwitchAgentToolCall.tsx +++ b/src/browser/features/Tools/SwitchAgentToolCall.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { formatAgentIdLabel } from "@/browser/components/AgentModePicker/AgentModePicker"; +import { formatAgentIdLabel } from "@/browser/features/Chat/AgentModePicker/AgentModePicker"; import { ToolContainer, ToolHeader, diff --git a/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx b/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx index 12be90b5b9..1a60b0f20f 100644 --- a/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx +++ b/src/browser/features/Workspace/WorkspaceShell/WorkspaceShell.tsx @@ -14,8 +14,8 @@ import { useBackgroundBashError } from "@/browser/contexts/BackgroundBashContext import { useWorkspaceState } from "@/browser/stores/WorkspaceStore"; import { useReviews } from "@/browser/hooks/useReviews"; import type { ReviewNoteData } from "@/common/types/review"; -import { ConnectionStatusToast } from "@/browser/components/ConnectionStatusToast/ConnectionStatusToast"; -import { ChatPane } from "@/browser/components/ChatPane/ChatPane"; +import { ConnectionStatusToast } from "@/browser/features/AppShell/ConnectionStatusToast/ConnectionStatusToast"; +import { ChatPane } from "@/browser/features/Chat/ChatPane/ChatPane"; // ChatPane uses tailwind `min-w-96`. const CHAT_PANE_MIN_WIDTH_PX = 384; diff --git a/src/browser/main.tsx b/src/browser/main.tsx index 287df55e93..96377a2b7f 100644 --- a/src/browser/main.tsx +++ b/src/browser/main.tsx @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { installBrowserLogCapture } from "@/browser/utils/browserLog"; -import { AppLoader } from "@/browser/components/AppLoader/AppLoader"; +import { AppLoader } from "@/browser/features/AppShell/AppLoader/AppLoader"; import { initTelemetry, trackAppStarted } from "@/common/telemetry"; import { initTitlebarInsets } from "@/browser/hooks/useDesktopTitlebar"; diff --git a/src/browser/stories/meta.tsx b/src/browser/stories/meta.tsx index 1be7f8e15a..1405cf93d2 100644 --- a/src/browser/stories/meta.tsx +++ b/src/browser/stories/meta.tsx @@ -8,7 +8,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import type { FC, ReactNode } from "react"; import { useRef } from "react"; -import { AppLoader } from "../components/AppLoader/AppLoader"; +import { AppLoader } from "../features/AppShell/AppLoader/AppLoader"; import { TooltipProvider } from "@/browser/components/Tooltip/Tooltip"; import type { APIClient } from "@/browser/contexts/API"; import { ThemeProvider } from "@/browser/contexts/ThemeContext"; diff --git a/tests/ui/renderReviewPanel.tsx b/tests/ui/renderReviewPanel.tsx index 6f3983e5a6..ecfd358883 100644 --- a/tests/ui/renderReviewPanel.tsx +++ b/tests/ui/renderReviewPanel.tsx @@ -1,6 +1,6 @@ import { render, type RenderResult, waitFor } from "@testing-library/react"; -import { AppLoader } from "@/browser/components/AppLoader/AppLoader"; +import { AppLoader } from "@/browser/features/AppShell/AppLoader/AppLoader"; import type { APIClient } from "@/browser/contexts/API"; import type { FrontendWorkspaceMetadata } from "@/common/types/workspace"; From 6debd35e8598ca77195a42e9b31d8c5227525256 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 28 Feb 2026 07:32:08 +0000 Subject: [PATCH 6/8] chore: regenerate built-in skill content --- .../builtInSkillContent.generated.ts | 6137 +++++++++++++++++ 1 file changed, 6137 insertions(+) create mode 100644 src/node/services/agentSkills/builtInSkillContent.generated.ts diff --git a/src/node/services/agentSkills/builtInSkillContent.generated.ts b/src/node/services/agentSkills/builtInSkillContent.generated.ts new file mode 100644 index 0000000000..355f1eecc2 --- /dev/null +++ b/src/node/services/agentSkills/builtInSkillContent.generated.ts @@ -0,0 +1,6137 @@ +// AUTO-GENERATED - DO NOT EDIT +// Run: bun scripts/gen_builtin_skills.ts +// Source: src/node/builtinSkills/*.md and docs/ + +export const BUILTIN_SKILL_FILES: Record> = { + init: { + "SKILL.md": [ + "---", + "name: init", + "description: Bootstrap an AGENTS.md file in a new or existing project", + "---", + "", + "", + "Use your tools to create or improve an AGENTS.md file in the root of the workspace which will serve as a contribution guide for AI agents.", + "If an AGENTS.md file already exists, focus on additive improvement (preserve intent and useful information; refine, extend, and reorganize as needed) rather than replacing it wholesale.", + "Inspect the workspace layout, code, documentation and git history to ensure correctness and accuracy.", + "", + "Ensure the following preamble exists at the top of the file before any other sections. Do not include the surrounding code fence backticks; only include the text.", + "", + "```md", + "You are an experienced, pragmatic software engineering AI agent. Do not over-engineer a solution when a simple one is possible. Keep edits minimal. If you want an exception to ANY rule, you MUST stop and get permission first.", + "```", + "", + "Recommended sections:", + "", + "- Project Overview (mandatory)", + " - Basic details about the project (e.g., high-level overview and goals).", + " - Technology choices (e.g., languages, databases, frameworks, libraries, build tools).", + "- Reference (mandatory)", + " - List important code files.", + " - List important directories and basic code structure tips.", + " - Project architecture.", + "- Essential commands (mandatory)", + " - build", + " - format", + " - lint", + " - test", + " - clean", + " - development server", + " - other _important_ scripts (use `find -type f -name '*.sh'` or similar)", + "- Patterns (optional)", + " - List any important or uncommon patterns (compared to other similar codebases), with examples (e.g., how to authorize an HTTP request).", + " - List any important workflows and their steps (e.g., how to make a database migration).", + " - Testing patterns.", + "- Anti-patterns (optional)", + " - Search git history and comments to find recurring mistakes or forbidden patterns.", + " - List each pattern and its reason.", + "- Code style (optional)", + " - Style guide to follow (with link).", + "- Commit and Pull Request Guidelines (mandatory)", + " - Required steps for validating changes before committing.", + " - Commit message conventions (read `git log`, or use `type: message` by default).", + " - Pull request description requirements.", + "", + "You can add other sections if they are necessary.", + "If the information required for mandatory sections isn't available due to the workspace being empty or sparse, add TODO text in its place.", + "Optional sections should be scrapped if the information is too thin.", + "", + "Some investigation tips:", + "", + "- Read existing lint configs, tsconfig, and CI workflows to find any style or layout rules.", + '- Search for "TODO", "HACK", "FIXME", "don\'t", "never", "always" in comments.', + "- Examine test files for patterns.", + "- Read PR templates and issue templates if they exist.", + "- Check for existing CONTRIBUTING.md, CODE_OF_CONDUCT.md, or similar documentation files.", + "", + "Some writing tips:", + "", + '- Each "do X" should have a corresponding "don\'t Y" where applicable.', + "- Commands should be easily copy-pastable and tested.", + "- Terms or phrases specific to this project should be explained on first use.", + "- Anything that is against the norm should be explicitly highlighted and called out.", + "", + "Above all things:", + "", + "- The document must be clear and concise. Simple projects should need less than 400 words, but larger and more mature codebases will likely need 700+. Prioritize completeness over brevity.", + "- Don't include useless fluff.", + "- The document must be in Markdown format and use headings for structure.", + "- Give examples where necessary or helpful (commands, directory paths, naming patterns).", + "- Explanations and examples must be correct and specific to this codebase.", + "- Maintain a professional, instructional tone.", + "", + "If the workspace is empty or sparse, ask the user for more information. Avoid hallucinating important decisions. You can provide suggestions to the user for language/technology/tool choices, but always respect the user's decision.", + "", + "- Project description and goals.", + "- Language(s).", + "- Technologies (database?), frameworks, libraries.", + "- Tools.", + "- Any other questions as you deem necessary.", + "", + "For empty or sparse workspaces ONLY, when finished writing/updating AGENTS.md, ask the user if they would like you to do the following:", + "", + "- initialize git IF it's not already set up (e.g., `git init`, `git remote add`, etc.)", + "- write a concise README.md file", + "- generate the bare minimum project scaffolding (e.g., initializing the package manager, writing a minimal build tool config)", + " ", + "", + ].join("\n"), + }, + "mux-diagram": { + "SKILL.md": [ + "---", + "name: mux-diagram", + "description: Mermaid diagram best practices and text-based chart alternatives", + "---", + "", + "# Diagrams & Charts", + "", + "Use this skill when creating diagrams, flowcharts, or chart-like visualizations.", + "", + "## Mermaid (rendered)", + "", + "The app renders fenced `mermaid` code blocks as interactive diagrams.", + "", + "Best practices:", + "", + "- Avoid side-by-side subgraphs (they display too wide)", + "- For comparisons, use separate diagram blocks or single graph with visual separation", + "- When using custom fill colors, include contrasting color property (e.g., `style note fill:#ff6b6b,color:#fff`)", + "- Make good use of visual space: e.g. use inline commentary", + '- Wrap node labels containing brackets or special characters in quotes (e.g., `Display["Message[]"]` not `Display[Message[]]`)', + "", + "Supported diagram types: flowchart, sequence, class, state, ER, Gantt, pie, git graph, mindmap, timeline, sankey, and more. Choose the type that best fits the data.", + "", + "## Text-based alternatives (no rendering required)", + "", + "Not every visualization needs Mermaid. Prefer lightweight formats when they suffice:", + "", + "- **Markdown tables** β€” best for structured comparisons, feature matrices, or tabular data", + "- **Bulleted/numbered lists** β€” best for hierarchies, step sequences, or simple trees", + "- **Indented tree notation** β€” for directory structures or shallow hierarchies", + "- **ASCII/Unicode bars** β€” quick inline quantitative comparisons (e.g., `β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘ 67%`)", + "", + "Choose Mermaid when relationships, flow, or topology matter. Choose text when the data is tabular or sequential.", + "", + ].join("\n"), + }, + "mux-docs": { + "references/docs/AGENTS.md": [ + "---", + "title: AGENTS.md", + "description: Agent instructions for AI assistants working on the Mux codebase", + "---", + "", + "**Prime directive:** keep edits minimal and token-efficientβ€”say only what conveys actionable signal.", + "", + "## Project Snapshot", + "", + "- `mux`: Electron + React desktop app for parallel agent workflows; UX must be fast, responsive, predictable.", + "- Minor breaking changes are expected, but critical flows must allow upgrade↔downgrade without friction; skip migrations when breakage is tightly scoped.", + "- **Before creating or updating any PR, commit, or public issue**, you **MUST** read the `pull-requests` skill (`agent_skill_read`) for attribution footer requirements and workflow conventions. Do not skip this step.", + "", + "## External Submissions", + "", + "- **Do not submit updates to the Terminal-Bench leaderboard repo directly.** Only provide the user with commands they can run themselves.", + "", + "## Repo Reference", + "", + "- Core files: `src/main.ts`, `src/preload.ts`, `src/App.tsx`, `src/config.ts`.", + "- Up-to-date model names: see `src/common/knownModels.ts` for current provider model IDs.", + "- Persistent data: `~/.mux/config.json`, `~/.mux/src//` (worktrees), `~/.mux/sessions//chat.jsonl`.", + "", + "## Documentation Rules", + "", + "- No free-floating Markdown. User docs live in `docs/` (read `docs/README.md`, add pages to `docs.json` navigation, use standard Markdown + mermaid). Developer notes belong inline as comments.", + " - Exception: the `rfc` folder contains human-written RFCs for implementation planning.", + "- For planning artifacts, use the `propose_plan` tool or inline comments instead of ad-hoc docs.", + "- Do not add new root-level docs without explicit request; during feature work rely on code + tests + inline comments.", + "- External API docs already live inside `/tmp/ai-sdk-docs/**.mdx`; never browse `https://sdk.vercel.ai/docs/ai-sdk-core` directly.", + "", + "### Code Comments", + "", + "- When delivering a user's request, leave their rationale in the code as comments.", + '- Generally, prefer code comments that explain the "why" behind a change.', + '- Still explain the "what" if the code is opaque, surprising, confusing, etc.', + "", + "## Key Features & Performance", + "", + "- Core UX: projects sidebar (left panel), workspace management (local git worktrees or SSH clones), config stored in `~/.mux/config.json`.", + "- Fetch bulk data in one IPC callβ€”no O(n) frontendβ†’backend loops.", + "- **React Compiler enabled** β€” auto-memoization handles components/hooks; do not add manual `React.memo()`, `useMemo`, or `useCallback` for memoization purposes. Focus instead on fixing unstable object references that the compiler cannot optimize (e.g., `new Set()` in state setters, inline object literals as props).", + "- **useEffect** β€” Before adding effects, consult the `react-effects` skill. Most effects for derived state, prop resets, or event-triggered logic are anti-patterns.", + "", + "## Tooling & Commands", + "", + "- Package manager: bun only. Use `bun install`, `bun add`, `bun run` (which proxies to Make when relevant). Run `bun install` if modules/types go missing.", + "- Makefile is source of truth (new commands land there, not `package.json`).", + "- Primary targets: `make dev|start|build|lint|lint-fix|fmt|fmt-check|typecheck|test|test-integration|clean|help`.", + "- Full `static-check` includes docs link checking via `mintlify broken-links`.", + "- `.mux/tool_env` is sourced before every `bash` tool call. Use `run_and_report ` when running multiple validation steps in one call.", + "- Do not pipe/redirect/wrap `run_and_report` output; keep helper markers intact so Mux can show clean step status.", + "- `./scripts/wait_pr_ready.sh ` is the preferred tail-end helper after local validation and after you've exhausted useful local work.", + "- `./scripts/wait_pr_checks.sh ` is the checks watcher; `wait_pr_ready.sh` must execute `wait_pr_checks.sh --once` on each loop iteration.", + "- `./scripts/wait_pr_codex.sh ` is the Codex gate used by `wait_pr_ready.sh`.", + "", + "## PR Workflow (Codex)", + "", + "- If a PR has Codex review comments, address + resolve them, then re-request review by commenting `@codex review` on the PR.", + "- Prefer `gh` CLI for GitHub interactions over manual web/curl flows.", + "- In Orchestrator mode, delegate implementation/verification commands to `exec` or `explore` sub-agents and integrate their patches; do not bypass delegation with direct local edits.", + "- In Orchestrator mode, route higher-complexity implementation tasks to `plan` sub-agents so they can research and produce a precise plan before auto-handoff to implementation.", + "", + "- User preference: when work is already on an open PR, push branch updates at the end of each completed change set so the PR stays current.", + '- **PR creation gate:** Do **not** open/create a pull request unless the user explicitly asks (e.g., "open a PR", "create PR", "submit this"). By default, complete local validation, commit/push branch updates as requested, and let the user review before deciding whether to open a PR.', + "", + "> PR readiness is mandatory. You MUST keep iterating until the PR is fully ready.", + '> A PR is fully ready only when: (1) Codex confirms approval (thumbs-up reaction on the PR description or an approval comment like "Didn\'t find any major issues"), (2) all Codex review threads are resolved, and (3) all required CI checks pass.', + "> You MUST NOT report success or stop the loop before these conditions are met.", + "", + "When a PR exists, you MUST remain in this loop until the PR is fully ready:", + "", + "1. Push your latest fixes.", + "2. Run local validation (`make static-check` and targeted tests as needed); in Orchestrator mode, delegate command execution to sub-agents.", + "3. Request review with `@codex review`.", + "4. Run `./scripts/wait_pr_ready.sh ` (which must execute `./scripts/wait_pr_checks.sh --once` while checks are pending).", + "5. If Codex leaves comments, address them (delegate fixes in Orchestrator mode), resolve threads with `./scripts/resolve_pr_comment.sh `, push, and repeat.", + "6. If checks/mergeability fail, fix issues locally (delegate fixes in Orchestrator mode), push, and repeat.", + "", + "The only early-stop exception is when the reviewer is clearly misunderstanding the intended change and further churn would be counterproductive. In that case, leave a clarifying PR comment and pause for human direction.", + "", + "## Testing: HistoryService", + "", + "HistoryService is pure local disk I/O with a single dependency (`getSessionDir`). **Always use a real instance** via `createTestHistoryService()` (`src/node/services/testHistoryService.ts`) rather than mocking.", + "", + "- Partial message lifecycle (`readPartial` / `writePartial` / `deletePartial` / `commitPartial`) is part of HistoryService; there is no separate PartialService.", + "- For pre-seeded data: call `historyService.appendToHistory()` in `beforeEach`", + '- For error injection: use real instance + `spyOn(historyService, "method").mockRejectedValueOnce(...)`', + '- For call tracking: `spyOn(historyService, "method")` without `mockImplementation` β€” real impl runs, calls are recorded', + "- For assertions: read history back with `getHistoryFromLatestBoundary()` or `getLastMessages()` instead of checking mock calls", + "", + "## Mobile Testing", + "", + "Mobile app tests live in `mobile/src/**/*.test.ts` and use Bun's built-in test runner (`bun test`).", + "", + "- Run mobile tests: `make test-mobile` or `bun run test:mobile`.", + "- The environment currently lacks native mobile testing tools (ADB, iOS Simulator), so focus on unit and integration tests that can run in a Node/Bun environment.", + "- Mobile components do not yet have automated UI tests.", + "", + "## Refactoring & Runtime Etiquette", + "", + "- Use `git mv` to retain history when moving files.", + "", + "## Self-Healing & Crash Resilience", + "", + "- Prefer **self-healing** behavior: if corrupted or invalid data exists in persisted state (e.g., `chat.jsonl`), the system should sanitize or filter it at load/request time rather than failing permanently.", + "- Never let a single malformed line in history brick a workspaceβ€”apply defensive filtering in request-building paths so the user can continue working.", + "- When streaming crashes, any incomplete state committed to disk should either be repairable on next load or excluded from provider requests to avoid API validation errors.", + "- **Startup-time initialization must never crash the app.** Wrap in try-catch, use timeouts, fall back silently.", + "", + "## Command Palette & UI Access", + "", + "- Open palette with `Cmd+Shift+P` (mac) / `Ctrl+Shift+P` (win/linux) / `F4`; quick toggle via `Cmd+P` / `Ctrl+P`.", + "- Palette covers workspace mgmt, navigation, chat utils, mode/model switches, slash commands (`/` for suggestions, `>` for actions).", + "", + "## Styling", + "", + "- Never use emoji characters as UI icons or status indicators; emoji rendering varies across platforms and fonts.", + "- Prefer SVG icons (usually from `lucide-react`) or shared icon components under `src/browser/components/Icons/`.", + "- For tool call headers, use `ToolIcon` from `src/browser/components/tools/shared/ToolPrimitives.tsx`.", + "- If a tool/agent provides an emoji string (e.g., `status_set` or `displayStatus`), render via `EmojiIcon` (`src/browser/components/Icons/EmojiIcon.tsx`) instead of rendering the emoji.", + "- If a new emoji appears in tool output, extend `EmojiIcon` to map it to an SVG icon.", + "- Colors defined in `src/browser/styles/globals.css` (`:root @theme` block). Reference via CSS variables (e.g., `var(--color-plan-mode)`), never hardcode hex values.", + "", + "## Security: Renderer HTML & XSS", + "", + "- Treat repo-controlled strings (file paths, diff content, branch names, commit messages) as attacker-controlled input.", + "- Never render attacker-controlled data through `dangerouslySetInnerHTML`, `innerHTML`, `outerHTML`, or `insertAdjacentHTML`.", + "- Prefer React element trees for highlighting (split + `` nodes) so React escaping stays in effect.", + "- If raw HTML/SVG rendering is unavoidable (e.g., Shiki/Mermaid), require explicit sanitization/hardening and document the trust boundary with a `SECURITY AUDIT` comment at the sink.", + "", + "## TypeScript Discipline", + "", + "- Ban `as any`; rely on discriminated unions, type guards, or authored interfaces.", + "- Use `Record` for exhaustive mappings to catch missing cases.", + "- Apply utility types (`Omit`, `Pick`, etc.) to build UI-specific variants of backend types, preventing unnecessary re-renders and clarifying intent.", + "- Let types drive design: prefer discriminated unions for state, minimize runtime checks, and simplify when types feel unwieldy.", + "- Use `using` declarations (or equivalent disposables) for processes, file handles, etc., to ensure cleanup even on errors.", + "- Centralize magic constants under `src/constants/`; share them instead of duplicating values across layers.", + "- Never repeat constant values (like keybinds) in commentsβ€”they become stale when the constant changes.", + "- **Avoid `void asyncFn()`** - fire-and-forget async calls hide race conditions. When state is observable by other code (in-memory cache, event emitters), ensure visibility order matches invariants. If memory and disk must stay in sync, persist before updating memory so observers see consistent state.", + "- **Avoid `setTimeout` for component coordination** - racy and fragile; use callbacks or effects.", + "- **Keyboard event propagation** - React's `e.stopPropagation()` only stops synthetic event bubbling; native `window` listeners still fire. Escape-to-interrupt is **safe-by-default** in editable elements (``, `