From 34d80fdead09e7deca364e8fad11b901abe8fbec Mon Sep 17 00:00:00 2001 From: soryu Date: Mon, 26 Jan 2026 03:09:36 +0000 Subject: [WIP] Heartbeat checkpoint - 2026-01-26 03:09:36 UTC --- makima/frontend/src/routes/mesh.tsx | 82 ++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/makima/frontend/src/routes/mesh.tsx b/makima/frontend/src/routes/mesh.tsx index fb366a2..dfc6123 100644 --- a/makima/frontend/src/routes/mesh.tsx +++ b/makima/frontend/src/routes/mesh.tsx @@ -8,8 +8,8 @@ import { UnifiedMeshChatInput } from "../components/mesh/UnifiedMeshChatInput"; import { ContractCompleteQuestion } from "../components/mesh/ContractCompleteQuestion"; import { useTasks } from "../hooks/useTasks"; import { useTaskSubscription, type TaskUpdateEvent, type TaskOutputEvent } from "../hooks/useTaskSubscription"; -import type { TaskWithSubtasks, MeshChatContext, ContractSummary, ContractWithRelations, DaemonDirectory, TaskSummary, RepositoryHistoryEntry } from "../lib/api"; -import { startTask as startTaskApi, stopTask as stopTaskApi, getTaskOutput, listContracts, getContract, getDaemonDirectories, continueTask as continueTaskApi, resumeSupervisor, branchTask, getRepositorySuggestions } from "../lib/api"; +import type { TaskWithSubtasks, MeshChatContext, ContractSummary, ContractWithRelations, DaemonDirectory, TaskSummary, RepositoryHistoryEntry, ContractTypeTemplate } from "../lib/api"; +import { startTask as startTaskApi, stopTask as stopTaskApi, getTaskOutput, listContracts, getContract, getDaemonDirectories, continueTask as continueTaskApi, resumeSupervisor, branchTask, getRepositorySuggestions, listContractTypes } from "../lib/api"; import { DirectoryInput } from "../components/mesh/DirectoryInput"; import { useAuth } from "../contexts/AuthContext"; import { useSupervisorQuestions } from "../contexts/SupervisorQuestionsContext"; @@ -131,6 +131,10 @@ export default function MeshPage() { const [standaloneRepoPath, setStandaloneRepoPath] = useState(""); const [repoSuggestions, setRepoSuggestions] = useState([]); const [showRepoSuggestions, setShowRepoSuggestions] = useState(false); + // Contract type selection for standalone tasks + const [standaloneContractTypes, setStandaloneContractTypes] = useState([]); + const [standaloneContractType, setStandaloneContractType] = useState("simple"); + const [contractTypesLoading, setContractTypesLoading] = useState(false); // Track which subtask's output we're viewing (null = parent task) const [viewingSubtaskId, setViewingSubtaskId] = useState(null); const [viewingSubtaskName, setViewingSubtaskName] = useState(null); @@ -364,6 +368,41 @@ export default function MeshPage() { } }, [showContractModal, modalStep, selectedContract, standaloneRepoType]); + // Fetch contract types when standalone task modal is open + useEffect(() => { + if (showContractModal && modalStep === 2 && !selectedContract) { + setContractTypesLoading(true); + listContractTypes() + .then((res) => { + setStandaloneContractTypes(res.types); + setContractTypesLoading(false); + }) + .catch((err) => { + console.error("Failed to fetch contract types:", err); + // Fall back to built-in types + setStandaloneContractTypes([ + { + id: "simple", + name: "Simple", + description: "Plan → Execute: Simple workflow with a plan document", + phases: ["plan", "execute"], + defaultPhase: "plan", + isBuiltin: true, + }, + { + id: "specification", + name: "Specification", + description: "Research → Specify → Plan → Execute → Review: Full specification-driven development with TDD", + phases: ["research", "specify", "plan", "execute", "review"], + defaultPhase: "research", + isBuiltin: true, + }, + ]); + setContractTypesLoading(false); + }); + } + }, [showContractModal, modalStep, selectedContract]); + // Apply a repository suggestion const applyRepoSuggestion = useCallback((suggestion: RepositoryHistoryEntry) => { if (suggestion.repositoryUrl) { @@ -576,6 +615,7 @@ export default function MeshPage() { setStandaloneRepoType("remote"); setStandaloneRepoUrl(""); setStandaloneRepoPath(""); + setStandaloneContractType("simple"); setModalStep(2); }, []); @@ -625,6 +665,7 @@ export default function MeshPage() { setStandaloneRepoType("remote"); setStandaloneRepoUrl(""); setStandaloneRepoPath(""); + setStandaloneContractType("simple"); setRepoSuggestions([]); setShowRepoSuggestions(false); }, []); @@ -1006,6 +1047,43 @@ export default function MeshPage() { )} + {/* Contract type selector - for standalone tasks */} + {!selectedContract && ( +
+ + {contractTypesLoading ? ( +
+ Loading contract types... +
+ ) : ( + <> +
+ {standaloneContractTypes.map((type) => ( + + ))} +
+

+ {standaloneContractTypes.find((t) => t.id === standaloneContractType)?.description || + "Select a contract type"} +

+ + )} +
+ )} + {/* Task name */}
-- cgit v1.2.3