diff --git a/src/renderer/src/components/NewWorkspaceComposerCard.tsx b/src/renderer/src/components/NewWorkspaceComposerCard.tsx index 58ea22626f9..524e4416388 100644 --- a/src/renderer/src/components/NewWorkspaceComposerCard.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerCard.tsx @@ -5,90 +5,37 @@ import React from 'react' import { Check, ChevronDown, - CircleDot, CornerDownLeft, - GitPullRequest, - Github, + FolderPlus, LoaderCircle, - Paperclip, - Plus, - X + Settings2 } from 'lucide-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList -} from '@/components/ui/command' -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from '@/components/ui/select' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuShortcut, - DropdownMenuTrigger -} from '@/components/ui/dropdown-menu' -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import RepoCombobox from '@/components/repo/RepoCombobox' -import { AGENT_CATALOG, AgentIcon } from '@/lib/agent-catalog' +import AgentCombobox from '@/components/agent/AgentCombobox' +import { AGENT_CATALOG } from '@/lib/agent-catalog' +import { useAppStore } from '@/store' import { cn } from '@/lib/utils' -import type { GitHubWorkItem, TuiAgent } from '../../../shared/types' +import type { TuiAgent } from '../../../shared/types' +import { isGitRepoKind } from '../../../shared/repo-kind' + +const isMac = typeof navigator !== 'undefined' && navigator.userAgent.includes('Mac') type RepoOption = React.ComponentProps['repos'][number] -type LinkedWorkItemSummary = { - type: 'issue' | 'pr' - number: number - title: string - url: string -} | null - type NewWorkspaceComposerCardProps = { containerClassName?: string composerRef?: React.RefObject nameInputRef?: React.RefObject - promptTextareaRef?: React.RefObject + quickAgent: TuiAgent | null + onQuickAgentChange: (agent: TuiAgent | null) => void eligibleRepos: RepoOption[] repoId: string onRepoChange: (value: string) => void name: string onNameChange: (event: React.ChangeEvent) => void - agentPrompt: string - onAgentPromptChange: (value: string) => void - onPromptKeyDown: (event: React.KeyboardEvent) => void - linkedOnlyTemplatePreview: string | null - attachmentPaths: string[] - getAttachmentLabel: (pathValue: string) => string - onAddAttachment: () => void - onRemoveAttachment: (pathValue: string) => void - addAttachmentShortcut: string - linkedWorkItem: LinkedWorkItemSummary - onRemoveLinkedWorkItem: () => void - linkPopoverOpen: boolean - onLinkPopoverOpenChange: (open: boolean) => void - linkQuery: string - onLinkQueryChange: (value: string) => void - filteredLinkItems: GitHubWorkItem[] - linkItemsLoading: boolean - linkDirectLoading: boolean - normalizedLinkQuery: { - query: string - repoMismatch: string | null - } - onSelectLinkedItem: (item: GitHubWorkItem) => void - tuiAgent: TuiAgent - onTuiAgentChange: (value: TuiAgent) => void detectedAgentIds: Set | null onOpenAgentSettings: () => void advancedOpen: boolean @@ -107,126 +54,6 @@ type NewWorkspaceComposerCardProps = { createError: string | null } -function PromptPrefixTextarea({ - textareaRef, - value, - onChange, - onKeyDown, - placeholder, - placeholderTone -}: { - textareaRef?: React.RefObject - value: string - onChange: (value: string) => void - onKeyDown: (event: React.KeyboardEvent) => void - placeholder: string - placeholderTone: 'muted' | 'ghost-prompt' -}): React.JSX.Element { - const internalRef = React.useRef(null) - - const setRefs = React.useCallback( - (node: HTMLTextAreaElement | null) => { - internalRef.current = node - if (textareaRef) { - textareaRef.current = node - } - }, - [textareaRef] - ) - - // Why: auto-size the textarea to its content and hoist scrolling onto the - // outer wrapper. Any JS-driven overlay sync (listening to `scroll`, updating - // `translateY`) always paints a frame behind the textarea's own scroll — on - // momentum scroll that shows up as visible wobble between the `>` and the - // typed text. Putting both elements inside the same native scroll container - // makes them move in lockstep with zero JS and no cross-layer paint delay. - React.useLayoutEffect(() => { - const el = internalRef.current - if (!el) { - return - } - el.style.height = 'auto' - el.style.height = `${el.scrollHeight}px` - }, [value]) - - return ( - // Why: allow the composer to grow with the user's prompt up to ~20 rows - // (560px at leading-7 ≈ 28px/row) before scrolling. The inner textarea's - // JS-driven auto-resize sets its own height to scrollHeight, so the wrapper - // simply follows until the max-height cap engages and hands off to scroll. -
-
- - {'>'} - -