diff --git a/.changeset/fn-6347-chat-input-visible.md b/.changeset/fn-6347-chat-input-visible.md new file mode 100644 index 0000000000..0fd8e84a2f --- /dev/null +++ b/.changeset/fn-6347-chat-input-visible.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Keep the task-detail Chat composer pinned and visible while the transcript scrolls internally on mobile and desktop. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index 5eb454da90..16017e5cb3 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -728,7 +728,7 @@ Recommended workflow: ordinary chains stay as `Blocks N` so noise stays low, hig ### Logs → Agent Log view -The **Chat** tab sits between Definition and Logs and presents a live, chat-styled transcript of task agent output. Consecutive entries are grouped by role and labeled as Planner, Executor, Reviewer, or Merger; legacy log rows without an agent role use the neutral Agent fallback. Consecutive text/message chunks inside a role group render as one continuous markdown bubble, while consecutive tool/tool-result/tool-error rows collapse into one expandable tool-call summary that stays collapsed by default; the summary counts tool invocations, lists deduped tool names with overflow, and shows an error count when failures are present, while the expanded body pairs each call with its result or error. Thinking entries render in a collapsible block that starts expanded. The transcript opens at the latest output whenever the tab loads or becomes active, then follows new live output when you are already near the bottom while preserving your scroll position when you review older messages. For active, assigned, non-paused agent sessions in `in-progress` or `in-review` (reviewing/merging/fixing) tasks, the composer sends guidance to the running agent through the same steering path used by comments; this includes regular engine agents working in a task worktree as well as live CLI sessions. When no active session is available, the composer is disabled with an explanatory hint. +The **Chat** tab sits between Definition and Logs and presents a live, chat-styled transcript of task agent output. Consecutive entries are grouped by role and labeled as Planner, Executor, Reviewer, or Merger; legacy log rows without an agent role use the neutral Agent fallback. Consecutive text/message chunks inside a role group render as one continuous markdown bubble, while consecutive tool/tool-result/tool-error rows collapse into one expandable tool-call summary that stays collapsed by default; the summary counts tool invocations, lists deduped tool names with overflow, and shows an error count when failures are present, while the expanded body pairs each call with its result or error. Thinking entries render in a collapsible block that starts expanded. The transcript opens at the latest output whenever the tab loads or becomes active, then follows new live output when you are already near the bottom while preserving your scroll position when you review older messages. For active, assigned, non-paused agent sessions in `in-progress` or `in-review` (reviewing/merging/fixing) tasks, the composer sends guidance to the running agent through the same steering path used by comments; this includes regular engine agents working in a task worktree as well as live CLI sessions. When no active session is available, the composer is disabled with an explanatory hint. The task-detail Chat tab keeps the composer pinned and visible on mobile and desktop while the transcript scrolls internally. The **Logs** tab includes an **Agent Log** subview designed for debugging long-running and tool-heavy sessions: diff --git a/packages/dashboard/app/components/TaskChatTab.css b/packages/dashboard/app/components/TaskChatTab.css index c22787397d..b265169ff2 100644 --- a/packages/dashboard/app/components/TaskChatTab.css +++ b/packages/dashboard/app/components/TaskChatTab.css @@ -1,16 +1,18 @@ .task-chat-tab { display: flex; + flex: 1; flex-direction: column; gap: var(--space-md); min-height: 0; + height: 100%; } .task-chat-transcript { display: flex; + flex: 1 1 auto; flex-direction: column; gap: var(--space-lg); min-height: 0; - max-height: var(--task-chat-transcript-max-height, 70vh); overflow-y: auto; padding: var(--space-md); border: var(--btn-border-width) solid var(--border); @@ -246,6 +248,7 @@ .task-chat-composer { display: flex; + flex: 0 0 auto; flex-direction: column; gap: var(--space-sm); padding: var(--space-md); @@ -282,7 +285,8 @@ } .task-chat-transcript { - max-height: var(--task-chat-transcript-mobile-max-height, 62vh); + flex: 1 1 auto; + min-height: 0; padding: var(--space-sm); } diff --git a/packages/dashboard/app/components/TaskDetailModal.css b/packages/dashboard/app/components/TaskDetailModal.css index b9d339df9d..c5f0bb4bab 100644 --- a/packages/dashboard/app/components/TaskDetailModal.css +++ b/packages/dashboard/app/components/TaskDetailModal.css @@ -94,6 +94,15 @@ overflow-y: hidden; } +/* Chat mirrors the Agent Log fill-height layout: the modal body does not scroll; + the transcript owns internal scrolling while the composer stays visible. */ +.detail-body--chat { + display: flex; + flex-direction: column; + min-height: 0; + overflow-y: hidden; +} + .detail-title { font-size: 18px; font-weight: 600; @@ -711,6 +720,14 @@ margin-top: var(--space-lg); } +.detail-section--chat { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + margin-top: var(--space-lg); +} + .detail-spec-edit-trigger { margin-bottom: var(--space-md); @@ -925,6 +942,18 @@ border-radius: 0; resize: none; } + + .detail-body--chat { + display: flex; + flex-direction: column; + min-height: 0; + overflow-y: hidden; + } + + .detail-section--chat { + flex: 1; + min-height: 0; + } } .detail-actions-menu-item-danger { diff --git a/packages/dashboard/app/components/TaskDetailModal.tsx b/packages/dashboard/app/components/TaskDetailModal.tsx index 1d5b2fd1bb..25b471b38d 100644 --- a/packages/dashboard/app/components/TaskDetailModal.tsx +++ b/packages/dashboard/app/components/TaskDetailModal.tsx @@ -2680,7 +2680,7 @@ export function TaskDetailContent({ )} -