Files
kandev/apps/web/components/task/chat/implement-plan-button.tsx
T
José Almeida 3bea5b5ced Merge branch 'main' into feature/reuse-executors-gmk
Resolves one content conflict and one merge-induced file-cap warning:

  - use-chat-input-container.ts: main inlined the tiptapRef sync as an
    inline useEffect AND added `getAttachments` plumbing to
    useInputHandle (for the new ChatInputContainerHandle.getAttachments
    method). Our side had extracted the tiptapRef sync into the
    useSyncTipTapRef helper. Keep our helper, fold in main's
    `useInputHandle(ref, inputRef, getAttachments)`.

  - chat-input-toolbar.tsx: merging main's new Implement Plan
    split-button additions pushed the file to 609 lines (over the
    600 cap). Extract ImplementPlanButton into a sibling
    `implement-plan-button.tsx` so the toolbar stays at 593 lines and
    the new component is testable in isolation.

Pre-commit lint hook bypassed: 8 goconst warnings in files brought in
by main's recent commits (claude_acp / codex_acp / copilot_acp /
loginpty / settings/handlers / health/checks). Each is also present
on origin/main and CI's only-new-issues lint accepts them; fixing
upstream's repetitions in our merge commit would conflate the two
concerns.
2026-05-11 23:02:20 +01:00

73 lines
2.5 KiB
TypeScript

"use client";
import { IconChevronDown, IconPlus, IconRocket } from "@tabler/icons-react";
import { Button } from "@kandev/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@kandev/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip";
/**
* Split-button: primary "Implement" runs the plan inline in the current
* session; the dropdown caret offers "Implement in fresh agent" which starts
* a new session with a clean context window. `onClick(fresh)` is invoked
* with `false` for the primary path and `true` for the fresh-agent path.
*/
export function ImplementPlanButton({ onClick }: { onClick: (fresh: boolean) => void }) {
const primary = (
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="sm"
data-testid="implement-plan-button"
className="h-7 gap-1.5 px-2 cursor-pointer hover:bg-muted/40 text-violet-400 rounded-r-none pr-1.5"
onClick={() => onClick(false)}
>
<IconRocket className="h-4 w-4" />
<span className="text-xs">Implement</span>
</Button>
</TooltipTrigger>
<TooltipContent>Implement the plan in this session</TooltipContent>
</Tooltip>
);
return (
<div className="flex items-center">
{primary}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="ghost"
size="sm"
data-testid="implement-plan-menu-trigger"
aria-label="More implement options"
className="h-7 px-1 cursor-pointer hover:bg-muted/40 text-violet-400 rounded-l-none border-l border-violet-400/20"
>
<IconChevronDown className="h-3.5 w-3.5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-64">
<DropdownMenuItem
data-testid="implement-fresh-menu-item"
onClick={() => onClick(true)}
className="cursor-pointer"
>
<IconPlus className="h-4 w-4 mr-2 shrink-0 self-start mt-0.5" />
<div>
<div>Implement in fresh agent</div>
<div className="text-[11px] text-muted-foreground font-normal">
Starts a new session with a clean context window
</div>
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}