/** Unified tool starter — workspace-first, fetches real tool types and config profiles. */ import { useState, useEffect, useCallback } from "react"; import { Icon } from "../../icon"; import { listToolTypes, type ToolType } from "../../../api/tool-types"; import { listConfigProfiles, type ConfigProfile } from "../../../api/config-profiles"; import { listSSHKeys, type SSHKey } from "../../../api/ssh-keys"; import type { Workspace } from "../../../types/workspace"; import type { ToolInstance } from "../../../api/sessions"; export interface ToolStarterProps { workspace: Workspace; onStarted: (instance: ToolInstance) => void; onCancel?: () => void; } export function ToolStarter({ workspace, onStarted, onCancel, }: ToolStarterProps) { const [toolTypes, setToolTypes] = useState([]); const [toolTypesLoading, setToolTypesLoading] = useState(true); const [toolTypesError, setToolTypesError] = useState(null); const [selectedToolTypeId, setSelectedToolTypeId] = useState(""); const [profiles, setProfiles] = useState([]); const [profilesLoading, setProfilesLoading] = useState(false); const [selectedProfileId, setSelectedProfileId] = useState(""); const [sshKeys, setSshKeys] = useState([]); const [sshKeysLoading, setSshKeysLoading] = useState(true); const [selectedSshKeyIds, setSelectedSshKeyIds] = useState([]); const [starting, setStarting] = useState(false); const [error, setError] = useState(null); // Fetch tool types on mount useEffect(() => { const load = async () => { try { const data = await listToolTypes(); setToolTypes(data); } catch (err) { setToolTypesError( err instanceof Error ? err.message : "Failed to load tool types", ); } finally { setToolTypesLoading(false); } }; void load(); }, []); // Fetch config profiles when tool type changes useEffect(() => { if (!selectedToolTypeId) { setProfiles([]); setSelectedProfileId(""); return; } const load = async () => { setProfilesLoading(true); try { const data = await listConfigProfiles( workspace.project_id, selectedToolTypeId, ); setProfiles(data); // Auto-select default profile if available const defaultProfile = data.find((p) => p.is_default); if (defaultProfile) { setSelectedProfileId(defaultProfile.id); } else { setSelectedProfileId(""); } } catch { setProfiles([]); } finally { setProfilesLoading(false); } }; void load(); }, [selectedToolTypeId, workspace.project_id]); // Fetch SSH keys on mount useEffect(() => { const load = async () => { try { const data = await listSSHKeys(); setSshKeys(data); // Auto-select the repository's SSH key if available if (workspace.repo_ssh_key_id) { setSelectedSshKeyIds([workspace.repo_ssh_key_id]); } } catch (err) { console.error("Failed to load SSH keys:", err); } finally { setSshKeysLoading(false); } }; void load(); }, [workspace.repo_ssh_key_id]); const repoHasSshKey = !!workspace.repo_ssh_key_id; const repoSshKey = sshKeys.find((k) => k.id === workspace.repo_ssh_key_id); const handleStart = useCallback(async () => { if (!selectedToolTypeId) { setError("Please select a tool type"); return; } setStarting(true); setError(null); try { const { createInstance, startInstance } = await import("../../../api/sessions"); const instance = await createInstance( workspace.project_id, workspace.repo_id, selectedToolTypeId, workspace.name, undefined, undefined, undefined, selectedProfileId || undefined, selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined, workspace.id, ); await startInstance( workspace.project_id, workspace.repo_id, instance.id, selectedProfileId || undefined, selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined, ); onStarted(instance); } catch (err) { setError(err instanceof Error ? err.message : "Failed to start tool"); } finally { setStarting(false); } }, [selectedToolTypeId, selectedProfileId, workspace, onStarted]); return (
{/* Context header — read-only workspace info */}
Project {workspace.project_name}
Repository {workspace.repo_name}
Workspace {workspace.name} {workspace.branch}
{/* Tool Type */}
{toolTypesLoading && Loading tools...} {toolTypesError && {toolTypesError}}
{/* Config Profile */} {selectedToolTypeId && (
{profilesLoading && ( Loading profiles... )} {profiles.length === 0 && !profilesLoading && ( No custom profiles for this tool. )}
)} {/* SSH Key Selection */}
{sshKeysLoading ? ( Loading SSH keys... ) : sshKeys.length === 0 ? ( No SSH keys configured. ) : (
{sshKeys.map((key) => ( ))}
)} {!sshKeysLoading && repoHasSshKey && repoSshKey && (
Repository key {repoSshKey.name} is pre-selected.
)}
{error &&

{error}

}
{onCancel && ( )}
); }