import { useMemo, useState } from 'react' import type { ApiClient } from '@/api/client' import type { Machine } from '@/types/api' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { usePlatform } from '@/hooks/usePlatform' import { useSpawnSession } from '@/hooks/mutations/useSpawnSession' type SessionType = 'simple' | 'worktree' function getMachineTitle(machine: Machine | null): string { if (!machine) return 'Machine' if (machine.metadata?.displayName) return machine.metadata.displayName if (machine.metadata?.host) return machine.metadata.host return machine.id.slice(0, 8) } export function SpawnSession(props: { api: ApiClient machineId: string machine: Machine | null onSuccess: (sessionId: string) => void onCancel: () => void }) { const { haptic } = usePlatform() const [directory, setDirectory] = useState('') const [sessionType, setSessionType] = useState('simple') const [worktreeName, setWorktreeName] = useState('') const [error, setError] = useState(null) const { spawnSession, isPending, error: spawnError } = useSpawnSession(props.api) const machineTitle = useMemo(() => getMachineTitle(props.machine), [props.machine]) async function spawn() { const trimmed = directory.trim() if (!trimmed) return setError(null) try { const result = await spawnSession({ machineId: props.machineId, directory: trimmed, sessionType, worktreeName: sessionType === 'worktree' ? (worktreeName.trim() || undefined) : undefined }) if (result.type === 'success') { haptic.notification('success') props.onSuccess(result.sessionId) return } haptic.notification('error') setError(result.message) } catch (e) { haptic.notification('error') setError(e instanceof Error ? e.message : 'Failed to spawn session') } } return (
Create Session {machineTitle}
setDirectory(e.target.value)} className="w-full rounded-md border border-[var(--app-border)] bg-[var(--app-bg)] p-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--app-link)]" />
{(['simple', 'worktree'] as const).map((type) => (
{type === 'worktree' ? (
setSessionType('worktree')} disabled={isPending} className="mt-1 accent-[var(--app-link)]" />
{sessionType === 'worktree' ? ( setWorktreeName(e.target.value)} disabled={isPending} className="w-full rounded-md border border-[var(--app-border)] bg-[var(--app-bg)] px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--app-link)] disabled:opacity-60" /> ) : ( )}
Create a new worktree next to the repo
) : ( )}
))}
{(error ?? spawnError) ? (
{error ?? spawnError}
) : null}
) }