From bd29c0ca436852da44389aa094569032176f7c08 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 9 Nov 2025 11:31:10 -0800 Subject: [PATCH 1/6] add package.json --- packages/models/package.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 packages/models/package.json diff --git a/packages/models/package.json b/packages/models/package.json new file mode 100644 index 00000000000..a0b7492998a --- /dev/null +++ b/packages/models/package.json @@ -0,0 +1,13 @@ +{ + "name": "@superset/models", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": {}, + "devDependencies": { + "@superset/typescript": "*", + "@types/node": "^24.9.1", + "bun-types": "^1.3.1", + "typescript": "^5.9.3" + } +} \ No newline at end of file From 0a06bc1d39ad7a3bc24f2140c4526580334a78ea Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 9 Nov 2025 11:38:46 -0800 Subject: [PATCH 2/6] start button --- .../main/components/PlanView/TaskPage.tsx | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx index 3d56278785a..8d8d65d1dac 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx @@ -123,22 +123,30 @@ export const TaskPage: React.FC = ({
{/* Header with Breadcrumbs */}
-
+
+
+ + / + + {task.slug} + +
- / - - {task.slug} -
@@ -272,9 +280,8 @@ export const TaskPage: React.FC = ({ )}
From 3fc7aabd74a9fc1b8eb3e1bd16f90960f38870f0 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 9 Nov 2025 11:39:35 -0800 Subject: [PATCH 3/6] add todo start task --- .../main/components/PlanView/TaskCard.tsx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx index 39ef1effcba..180b4f4f1c0 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx @@ -1,5 +1,6 @@ import type { RouterOutputs } from "@superset/api"; import type React from "react"; +import { useState } from "react"; type Task = RouterOutputs["task"]["all"][number]; @@ -21,12 +22,21 @@ const statusColors: Record = { export const TaskCard: React.FC = ({ task, onClick }) => { const statusColor = statusColors[task.status] || "bg-neutral-500"; + const [isHovered, setIsHovered] = useState(false); + + const handleStartTask = (e: React.MouseEvent) => { + e.stopPropagation(); + // TODO: Implement start task functionality + console.log("Start task:", task.id); + }; return ( + )}
); From 9064ac38f5134f9d3a0bd124dba40cda8a50cd08 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 9 Nov 2025 11:40:16 -0800 Subject: [PATCH 4/6] refactor --- .../renderer/screens/main/components/PlanView/TaskCard.tsx | 6 ++++-- .../renderer/screens/main/components/PlanView/TaskPage.tsx | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx index 180b4f4f1c0..7a1d4c6705d 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx @@ -1,4 +1,5 @@ import type { RouterOutputs } from "@superset/api"; +import { Play } from "lucide-react"; import type React from "react"; import { useState } from "react"; @@ -72,9 +73,10 @@ export const TaskCard: React.FC = ({ task, onClick }) => { )} diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx index 8d8d65d1dac..681eab0bad4 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx @@ -1,5 +1,5 @@ import type { RouterOutputs } from "@superset/api"; -import { ChevronDown, ChevronLeft, User as UserIcon } from "lucide-react"; +import { ChevronDown, ChevronLeft, Play, User as UserIcon } from "lucide-react"; import type React from "react"; import { useEffect, useRef, useState } from "react"; @@ -143,9 +143,10 @@ export const TaskPage: React.FC = ({ From 86149f946619ebd336f17e532fa6e80aadd873df Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 9 Nov 2025 12:06:51 -0800 Subject: [PATCH 5/6] update command --- .../components/NewLayout/NewLayoutMain.tsx | 7 ++- .../main/components/PlanView/KanbanColumn.tsx | 24 +++++++ .../main/components/PlanView/PlanView.tsx | 44 ++++++++++++- .../main/components/PlanView/TaskCard.tsx | 62 +++++++++++++++++-- .../main/components/PlanView/TaskPage.tsx | 46 ++++++++++++++ 5 files changed, 177 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/renderer/screens/main/components/NewLayout/NewLayoutMain.tsx b/apps/desktop/src/renderer/screens/main/components/NewLayout/NewLayoutMain.tsx index b8f90207164..577c3faa0a7 100644 --- a/apps/desktop/src/renderer/screens/main/components/NewLayout/NewLayoutMain.tsx +++ b/apps/desktop/src/renderer/screens/main/components/NewLayout/NewLayoutMain.tsx @@ -867,7 +867,12 @@ export const NewLayoutMain: React.FC = () => {
{mode === "plan" ? ( // Plan mode - show kanban board - + ) : ( // Edit mode - show workspace/terminal view void; statusColor?: string; + currentWorkspace: Workspace | null; + selectedWorktreeId: string | null; + onTabSelect: (worktreeId: string, tabId: string) => void; + onReload: () => void; + onUpdateTask: ( + taskId: string, + updates: { + title: string; + description: string; + status: Task["status"]; + assigneeId?: string | null; + }, + ) => void; } export const KanbanColumn: React.FC = ({ @@ -16,6 +30,11 @@ export const KanbanColumn: React.FC = ({ tasks, onTaskClick, statusColor = "bg-neutral-500", + currentWorkspace, + selectedWorktreeId, + onTabSelect, + onReload, + onUpdateTask, }) => { return (
@@ -39,6 +58,11 @@ export const KanbanColumn: React.FC = ({ key={task.id} task={task} onClick={() => onTaskClick(task)} + currentWorkspace={currentWorkspace} + selectedWorktreeId={selectedWorktreeId} + onTabSelect={onTabSelect} + onReload={onReload} + onUpdateTask={onUpdateTask} /> ))}
diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/PlanView.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/PlanView.tsx index e2c31342336..a76c3e60e8e 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/PlanView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/PlanView.tsx @@ -2,6 +2,7 @@ import type { RouterOutputs } from "@superset/api"; import { Plus } from "lucide-react"; import type React from "react"; import { useMemo, useState } from "react"; +import type { Workspace } from "shared/types"; import { mockTasks, mockUsers } from "../../../../../lib/mock-data"; import { CreateTaskModal } from "./CreateTaskModal"; import { KanbanColumn } from "./KanbanColumn"; @@ -10,7 +11,19 @@ import { TaskPage } from "./TaskPage"; type Task = RouterOutputs["task"]["all"][number]; type User = RouterOutputs["user"]["all"][number]; -export const PlanView: React.FC = () => { +interface PlanViewProps { + currentWorkspace: Workspace | null; + selectedWorktreeId: string | null; + onTabSelect: (worktreeId: string, tabId: string) => void; + onReload: () => void; +} + +export const PlanView: React.FC = ({ + currentWorkspace, + selectedWorktreeId, + onTabSelect, + onReload, +}) => { // Initialize with mock tasks and add some variety to statuses const [tasks, setTasks] = useState(() => { // Modify some tasks to have different statuses for demo purposes @@ -128,6 +141,10 @@ export const PlanView: React.FC = () => { users={mockUsers} onBack={() => setViewingTask(null)} onUpdate={handleUpdateTask} + currentWorkspace={currentWorkspace} + selectedWorktreeId={selectedWorktreeId} + onTabSelect={onTabSelect} + onReload={onReload} /> ); } @@ -163,30 +180,55 @@ export const PlanView: React.FC = () => { tasks={tasksByStatus.backlog} onTaskClick={setViewingTask} statusColor="bg-neutral-500" + currentWorkspace={currentWorkspace} + selectedWorktreeId={selectedWorktreeId} + onTabSelect={onTabSelect} + onReload={onReload} + onUpdateTask={handleUpdateTask} />
diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx index 7a1d4c6705d..e6c01dbc48c 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskCard.tsx @@ -2,12 +2,26 @@ import type { RouterOutputs } from "@superset/api"; import { Play } from "lucide-react"; import type React from "react"; import { useState } from "react"; +import type { Workspace } from "shared/types"; type Task = RouterOutputs["task"]["all"][number]; interface TaskCardProps { task: Task; onClick: () => void; + currentWorkspace: Workspace | null; + selectedWorktreeId: string | null; + onTabSelect: (worktreeId: string, tabId: string) => void; + onReload: () => void; + onUpdateTask: ( + taskId: string, + updates: { + title: string; + description: string; + status: Task["status"]; + assigneeId?: string | null; + }, + ) => void; } const statusColors: Record = { @@ -21,14 +35,54 @@ const statusColors: Record = { canceled: "bg-red-500", }; -export const TaskCard: React.FC = ({ task, onClick }) => { +export const TaskCard: React.FC = ({ + task, + onClick, + currentWorkspace, + selectedWorktreeId, + onTabSelect, + onReload, + onUpdateTask, +}) => { const statusColor = statusColors[task.status] || "bg-neutral-500"; const [isHovered, setIsHovered] = useState(false); - const handleStartTask = (e: React.MouseEvent) => { + const handleStartTask = async (e: React.MouseEvent) => { e.stopPropagation(); - // TODO: Implement start task functionality - console.log("Start task:", task.id); + + if (!currentWorkspace || !selectedWorktreeId) { + console.error("No workspace or worktree selected"); + return; + } + + try { + // Create a new terminal with claude command + const result = await window.ipcRenderer.invoke("tab-create", { + workspaceId: currentWorkspace.id, + worktreeId: selectedWorktreeId, + name: `Task: ${task.slug}`, + type: "terminal", + command: `claude "hi"`, + }); + + if (result.success) { + const newTabId = result.tab?.id; + if (newTabId) { + onTabSelect(selectedWorktreeId, newTabId); + } + + // Update task status to planning (pending) + onUpdateTask(task.id, { + title: task.title, + description: task.description || "", + status: "planning", + }); + + onReload(); + } + } catch (error) { + console.error("Error starting task:", error); + } }; return ( diff --git a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx index 681eab0bad4..492f1001858 100644 --- a/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx +++ b/apps/desktop/src/renderer/screens/main/components/PlanView/TaskPage.tsx @@ -2,6 +2,7 @@ import type { RouterOutputs } from "@superset/api"; import { ChevronDown, ChevronLeft, Play, User as UserIcon } from "lucide-react"; import type React from "react"; import { useEffect, useRef, useState } from "react"; +import type { Workspace } from "shared/types"; type Task = RouterOutputs["task"]["all"][number]; type User = RouterOutputs["user"]["all"][number]; @@ -19,6 +20,10 @@ interface TaskPageProps { assigneeId?: string | null; }, ) => void; + currentWorkspace: Workspace | null; + selectedWorktreeId: string | null; + onTabSelect: (worktreeId: string, tabId: string) => void; + onReload: () => void; } const statusColors: Record = { @@ -48,6 +53,10 @@ export const TaskPage: React.FC = ({ users, onBack, onUpdate, + currentWorkspace, + selectedWorktreeId, + onTabSelect, + onReload, }) => { const statusColor = statusColors[task.status] || "bg-neutral-500"; const [title, setTitle] = useState(task.title); @@ -119,6 +128,42 @@ export const TaskPage: React.FC = ({ ? users.find((u) => u.id === assigneeId) : null; + const handleStartTask = async () => { + if (!currentWorkspace || !selectedWorktreeId) { + console.error("No workspace or worktree selected"); + return; + } + + try { + // Create a new terminal with claude command + const result = await window.ipcRenderer.invoke("tab-create", { + workspaceId: currentWorkspace.id, + worktreeId: selectedWorktreeId, + name: `Task: ${task.slug}`, + type: "terminal", + command: `claude "hi"`, + }); + + if (result.success) { + const newTabId = result.tab?.id; + if (newTabId) { + onTabSelect(selectedWorktreeId, newTabId); + } + + // Update task status to planning (pending) + onUpdate(task.id, { + title: task.title, + description: task.description || "", + status: "planning", + }); + + onReload(); + } + } catch (error) { + console.error("Error starting task:", error); + } + }; + return (
{/* Header with Breadcrumbs */} @@ -143,6 +188,7 @@ export const TaskPage: React.FC = ({