diff --git a/src/components/swarm/archetype-picker.tsx b/src/components/swarm/archetype-picker.tsx
new file mode 100644
index 0000000..8d95bd5
--- /dev/null
+++ b/src/components/swarm/archetype-picker.tsx
@@ -0,0 +1,131 @@
+"use client";
+
+import React from 'react';
+import { X, Blocks, Check, Pencil, Plus } from 'lucide-react';
+import type { AgentArchetype } from '../../lib/types-swarm';
+import { getArchetypeDisplayChar } from '../../lib/utils';
+
+interface ArchetypePickerProps {
+ archetypes: AgentArchetype[];
+ isOpen: boolean;
+ onClose: () => void;
+ onSelect: (archetype: AgentArchetype) => void;
+ onEdit: (archetypeId: string) => void;
+ onCreateNew: () => void;
+}
+
+export function ArchetypePicker({
+ archetypes,
+ isOpen,
+ onClose,
+ onSelect,
+ onEdit,
+ onCreateNew
+}: ArchetypePickerProps) {
+ if (!isOpen) return null;
+
+ const handleBackdropClick = (e: React.MouseEvent) => {
+ if (e.target === e.currentTarget) {
+ onClose();
+ }
+ };
+
+ const handleSelect = (archetype: AgentArchetype) => {
+ onSelect(archetype);
+ onClose();
+ };
+
+ return (
+
+
+
+
+
+
+ Select Archetype
+
+
+
+
+
+
+ {archetypes.length === 0 ? (
+
+
+
No archetypes available
+
Create one to get started
+
+ ) : (
+
+ {archetypes.map((archetype) => {
+ const displayChar = getArchetypeDisplayChar(archetype);
+ return (
+
+
+
+ {displayChar}
+
+
+
+ {archetype.name}
+
+
+ {archetype.description || 'No description'}
+
+
+
+
+
+
+
+
+
+ );
+ })}
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/swarm/template-picker.tsx b/src/components/swarm/template-picker.tsx
new file mode 100644
index 0000000..1c736d0
--- /dev/null
+++ b/src/components/swarm/template-picker.tsx
@@ -0,0 +1,153 @@
+"use client";
+
+import React from 'react';
+import { X, Check, Pencil, Plus, Users } from 'lucide-react';
+import type { SwarmTemplate } from '../../lib/types-swarm';
+import { getTemplateDisplayChar, getTemplateColor } from '../../lib/utils';
+
+interface TemplatePickerProps {
+ templates: SwarmTemplate[];
+ isOpen: boolean;
+ onClose: () => void;
+ onSelect: (template: SwarmTemplate) => void;
+ onEdit: (templateId: string) => void;
+ onCreateNew: () => void;
+}
+
+export function TemplatePicker({
+ templates,
+ isOpen,
+ onClose,
+ onSelect,
+ onEdit,
+ onCreateNew
+}: TemplatePickerProps) {
+ if (!isOpen) return null;
+
+ const handleBackdropClick = (e: React.MouseEvent) => {
+ if (e.target === e.currentTarget) {
+ onClose();
+ }
+ };
+
+ const handleSelect = (template: SwarmTemplate) => {
+ onSelect(template);
+ onClose();
+ };
+
+ const handleEdit = (e: React.MouseEvent, templateId: string) => {
+ e.stopPropagation();
+ onEdit(templateId);
+ };
+
+ const getTotalTeamSize = (template: SwarmTemplate): number => {
+ return template.team.reduce((acc, member) => acc + member.count, 0);
+ };
+
+ return (
+
+
+
+
+
+ Select Template
+
+
+
+
+
+ {templates.length === 0 ? (
+
+
No templates available
+
Create a template to get started
+
+ ) : (
+
+ {templates.map((template) => {
+ const displayChar = getTemplateDisplayChar(template);
+ const color = getTemplateColor(template);
+ const teamSize = getTotalTeamSize(template);
+
+ return (
+
handleSelect(template)}
+ >
+
+
+ {displayChar}
+
+
+
+ {template.name}
+
+ {template.isBuiltIn && (
+
+ Built-in
+
+ )}
+
+
+
+
+ {template.description}
+
+
+
+
+ {teamSize} agent{teamSize !== 1 ? 's' : ''}
+
+
+
+
+
+
+
+ );
+ })}
+
+ )}
+
+
+
+
+
+
+
+
+ );
+}