diff --git a/.changeset/FN-7826-worktree-terminal-always-available.md b/.changeset/FN-7826-worktree-terminal-always-available.md new file mode 100644 index 0000000000..cb2dd6375b --- /dev/null +++ b/.changeset/FN-7826-worktree-terminal-always-available.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": minor +--- + +summary: The Task Detail Terminal tab is now always available, falling back to the project root when a task has no worktree. +category: feature +dev: Relaxes the TaskDetailModal `showWorktreeTerminalTab` gate to always render and passes `defaultCwd` = worktree when present else undefined (project-root auto-create via useTerminalSessions). Covers no-worktree and multi-repo workspace tasks. Sessions stay task-scoped via `scopeId`. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index a03b5a721f..c1c2fdd05f 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -625,8 +625,8 @@ Mailbox view shows inbox/outbox communication threads and unread state. Fusion embeds a terminal using xterm.js. Desktop and tablet use the footer status bar as the terminal launcher; mobile keeps the full-screen terminal path. - -Task Detail has two terminal-adjacent tabs when both are applicable: **Session** shows the pre-existing CLI agent session transcript/control surface, while **Terminal** embeds the interactive multi-tab terminal inside the task detail body. The interactive **Terminal** tab appears only for non-workspace tasks with a single recorded worktree; its first shell starts in that task worktree, and its terminal tabs are stored separately from the footer/global project terminal tabs. + +Task Detail has two terminal-adjacent tabs when both are applicable: **Session** shows the pre-existing CLI agent session transcript/control surface, while **Terminal** embeds the interactive multi-tab terminal inside the task detail body. The interactive **Terminal** tab is always available in Task Detail; its first shell starts in the task worktree when one is recorded, otherwise it starts in the project base directory (project root), including for multi-repo workspace tasks that have no single task worktree. Its terminal tabs are stored separately from the footer/global project terminal tabs. On Windows, the embedded terminal starts a supported shell inside Fusion, such as Command Prompt (`cmd.exe`) or Windows PowerShell. Windows Terminal (`wt.exe`) is an external terminal host and is not required or launched for the embedded panel, so Fusion should not show native Windows Terminal help/version popups while starting a terminal. If embedded terminal startup fails, Fusion shows an inline error with **Retry** instead of a blocking native dialog; install or repair Windows Terminal separately with `winget install Microsoft.WindowsTerminal` only if you want to use Windows Terminal outside Fusion. diff --git a/packages/dashboard/app/components/TaskDetailModal.tsx b/packages/dashboard/app/components/TaskDetailModal.tsx index 8b43b6013a..966aeae873 100644 --- a/packages/dashboard/app/components/TaskDetailModal.tsx +++ b/packages/dashboard/app/components/TaskDetailModal.tsx @@ -1158,11 +1158,11 @@ export function TaskDetailContent({ ); const showCliTab = cliTabVisibility.kind !== "hidden"; /* - FNXC:TaskDetailTerminal 2026-07-10-00:00: - FN-7813 exposes a dedicated interactive Terminal tab only for single-worktree tasks. Workspace tasks have multiple repo roots and no single safe default shell cwd, so they intentionally hide this tab rather than falling back to the project root. + FNXC:TaskDetailTerminal 2026-07-11-13:20: + FN-7826 makes the interactive Terminal tab always available in Task Detail. The first shell opens in task.worktree when present; otherwise defaultCwd stays undefined so useTerminalSessions creates a project-root shell, including for multi-repo workspace tasks with no single worktree. Terminal sessions remain task-scoped through scopeId so they do not share the footer/global terminal namespace. */ const taskWorktreeCwd = typeof task.worktree === "string" && task.worktree.trim().length > 0 ? task.worktree : undefined; - const showWorktreeTerminalTab = Boolean(taskWorktreeCwd) && !isWorkspaceTask(workingTask); + const showWorktreeTerminalTab = true; const cliPosture: SessionTerminalPosture | undefined = useMemo(() => { if (!cliSession) return undefined; const p = cliSession.autonomyPosture ?? {}; @@ -1197,10 +1197,6 @@ export function TaskDetailContent({ if (activeTab === "terminal" && !showCliTab) setActiveTab("definition"); }, [activeTab, showCliTab]); - // If the worktree-rooted terminal tab loses its single-worktree cwd, fall back. - useEffect(() => { - if (activeTab === "worktree-terminal" && !showWorktreeTerminalTab) setActiveTab("definition"); - }, [activeTab, showWorktreeTerminalTab]); // Track mount state to avoid setting state on unmounted component useEffect(() => { @@ -4858,7 +4854,7 @@ export function TaskDetailContent({ ) : null} - ) : activeTab === "worktree-terminal" && showWorktreeTerminalTab && taskWorktreeCwd ? ( + ) : activeTab === "worktree-terminal" && showWorktreeTerminalTab ? (