Integrates BooCoder as a 'coder' workspace pane within the existing BooChat SPA at code.indifferentketchup.com. Renamed the placeholder 'agent' pane kind to 'coder' across all types, menus, hooks, and mobile switcher (Icon: Code instead of Bot). CoderPane.tsx: split layout with chat area (messages via WS to boocoder:9502, input bar posting to /api/coder/sessions/:id/messages) and diff panel (pending changes with Approve/Reject per change plus Approve All/Reject All). Reuses MarkdownRenderer for message content. Proxy: Vite dev config adds /api/coder → boocoder:9502 (ordered above /api per CLAUDE.md proxy-ordering rule). Production: Fastify route in apps/server/src/index.ts proxies /api/coder/* to http://boocoder:3000 via fetch() pass-through. WS connects directly to :9502 (same Tailscale network, no proxy needed for WebSocket upgrade). WorkspacePaneKind mirror updated in both apps/web and apps/server types. useWorkspacePanes gains coderPane() factory (replaces the old agent toast stub). Workspace.tsx switch renders CoderPane for pane.kind === 'coder'. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { Code, MessageSquare, Plus, Terminal } from 'lucide-react';
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from '@/components/ui/dropdown-menu';
|
|
|
|
interface Props {
|
|
onAddPane: (kind: 'chat' | 'terminal' | 'coder') => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
// v1.8 row-2 right cluster: mirrors the desktop Workspace.tsx Split dropdown.
|
|
// Terminal + Coder items pass through to addSplitPane which creates panes
|
|
// of the appropriate kind.
|
|
export function NewPaneMenu({ onAddPane, disabled }: Props) {
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<button
|
|
type="button"
|
|
disabled={disabled}
|
|
className="inline-flex items-center justify-center min-h-[44px] min-w-[44px] rounded-full bg-muted/40 hover:bg-muted/70 text-foreground disabled:opacity-40 disabled:cursor-not-allowed shrink-0"
|
|
aria-label="New pane"
|
|
>
|
|
<Plus size={16} />
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem onSelect={() => onAddPane('chat')}>
|
|
<MessageSquare size={14} /> New chat
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onSelect={() => onAddPane('terminal')}>
|
|
<Terminal size={14} /> New terminal
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onSelect={() => onAddPane('coder')}>
|
|
<Code size={14} /> New coder
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
}
|