+
+ {insights?.totalSessions}
+@@ -115,8 +116,8 @@ export function SessionInsights() {
+
+
+ {/* Average Duration Card */}
+-
++
+-
++
+
+
+ {insights?.avgSessionDuration?.toFixed(1)}m
+@@ -128,8 +129,8 @@ export function SessionInsights() {
+
+
+ {/* Total Tokens Card */}
+-
++
+-
++
+
+
+ {insights?.totalTokens ? `${(insights.totalTokens / 1000000).toFixed(2)}M` : ''}
+@@ -141,70 +142,52 @@ export function SessionInsights() {
+
+
+- {/* Bottom row with two equal columns */}
+-
+- {/* Recent Projects Card */}
+- {/*
*/}
+- {/* */}
+- {/* */}
+- {/* */}
+- {/* Recent projects*/}
+- {/* */}
+- {/* */}
+- {/*
*/}
+- {/* */}
+- {/*
*/}
+- {/* {recentProjects.length > 0 ? (*/}
+- {/* recentProjects.map((project, index) => (*/}
+- {/* handleProjectClick(project.id)}*/}
+- {/* role="button"*/}
+- {/* tabIndex={0}*/}
+- {/* initial={{ opacity: 0, y: 5 }}*/}
+- {/* animate={{ opacity: 1, y: 0 }}*/}
+- {/* transition={{ duration: 0.3, delay: index * 0.1 }}*/}
+- {/* onKeyDown={(e) => {*/}
+- {/* if (e.key === 'Enter' || e.key === ' ') {*/}
+- {/* handleProjectClick(project.id);*/}
+- {/* }*/}
+- {/* }}*/}
+- {/* >*/}
+- {/* */}
+- {/* */}
+- {/* {project.name}*/}
+- {/*
*/}
+- {/* */}
+- {/* {formatDateOnly(project.updatedAt)}*/}
+- {/* */}
+- {/* */}
+- {/* ))*/}
+- {/* ) : (*/}
+- {/* */}
+- {/* No recent projects found.*/}
+- {/*
*/}
+- {/* )}*/}
+- {/* */}
+- {/*
*/}
+- {/* */}
+- {/**/}
++ {/* Projects and Chats row */}
++
++ {/* Recent Projects Card */}
++
++
++
++
++ Recent projects
++
++
++
++
++
++ No recent projects found.
++
++
++
++
+
+ {/* Recent Chats Card */}
+-
++
+-
++
+-
++
+
+ Recent chats
+
+@@ -242,11 +225,13 @@ export function SessionInsights() {
+ ) : (
+-
++
+ No recent chat sessions found.
+
+ )}
+
+
+
+
+
+-
++
++ {/* Filler container - extends to fill remaining space */}
++
+
+
+ );
+
+diff --git a/ui/desktop/src/components/hub.tsx b/ui/desktop/src/components/hub.tsx
+index 1234567..abcdefg 100644
+--- a/ui/desktop/src/components/hub.tsx
++++ b/ui/desktop/src/components/hub.tsx
+@@ -65,7 +65,7 @@ export default function Hub({
+
+ return (
+
+-
++
+-
++
+
+
+
+-
{}}
+
+diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx
+index 1234567..abcdefg 100644
+--- a/ui/desktop/src/components/ChatInput.tsx
++++ b/ui/desktop/src/components/ChatInput.tsx
+@@ -658,7 +658,7 @@ export default function ChatInput({
+
+ return (
+
-
+
+
{/* Loader when generating recipe */}
{isGeneratingRecipe && }
{/* Custom header */}
{renderHeader && renderHeader()}
- {/* Recipe agent header - fixed at top when recipe is active */}
- {recipeConfig?.title && (
- {
- console.log('Change profile clicked');
- }}
- showBorder={messages.length > 0}
- />
- )}
+ {/* Recipe agent header - inside the messages container when present */}
+
+
+ {/* Recipe agent header - now inside the messages container */}
+ {recipeConfig?.title && (
+
+
{
+ console.log('Change profile clicked');
+ }}
+ showBorder={messages.length > 0}
+ />
+
+ )}
-
- {/* Custom content before messages */}
- {renderBeforeMessages && renderBeforeMessages()}
+ {/* Custom content before messages */}
+ {renderBeforeMessages && renderBeforeMessages()}
- {/* Messages or Splash */}
- {messages.length === 0 ? (
- /* Show Splash when no messages and we have a recipe config */
- recipeConfig && (
- append(text)}
- activities={Array.isArray(recipeConfig.activities) ? recipeConfig.activities : null}
- title={recipeConfig.title}
- />
- )
- ) : (
- <>
- {disableSearch ? (
- // Render messages without SearchView wrapper when search is disabled
- renderMessages()
- ) : (
- // Render messages with SearchView wrapper when search is enabled
- {renderMessages()}
- )}
+ {/* Messages or Splash */}
+ {messages.length === 0 ? (
+ /* Show Splash when no messages and we have a recipe config */
+ recipeConfig && (
+ append(text)}
+ activities={Array.isArray(recipeConfig.activities) ? recipeConfig.activities : null}
+ title={recipeConfig.title}
+ />
+ )
+ ) : (
+ <>
+ {disableSearch ? (
+ // Render messages without SearchView wrapper when search is disabled
+ renderMessages()
+ ) : (
+ // Render messages with SearchView wrapper when search is enabled
+ {renderMessages()}
+ )}
- {error && (
-
-
- {error.message || 'Honk! Goose experienced an error while responding'}
+ {error && (
+
+
+ {error.message || 'Honk! Goose experienced an error while responding'}
+
+
{
+ // Find the last user message
+ const lastUserMessage = messages.reduceRight(
+ (found, m) => found || (m.role === 'user' ? m : null),
+ null as Message | null
+ );
+ if (lastUserMessage) {
+ append(lastUserMessage);
+ }
+ }}
+ >
+ Retry Last Message
+
-
{
- // Find the last user message
- const lastUserMessage = messages.reduceRight(
- (found, m) => found || (m.role === 'user' ? m : null),
- null as Message | null
- );
- if (lastUserMessage) {
- append(lastUserMessage);
- }
- }}
- >
- Retry Last Message
-
-
- )}
-
- >
- )}
+ )}
+
+ >
+ )}
- {/* Custom content after messages */}
- {renderAfterMessages && renderAfterMessages()}
-
+ {/* Loading indicator at bottom of messages container */}
+ {isLoading && (
+
+
+
+ )}
+
+ {/* Custom content after messages */}
+ {renderAfterMessages && renderAfterMessages()}
+
+
-
- {isLoading && (
-
- )}
-
= ({ children }) => {
+ removeTopPadding?: boolean;
+}> = ({ children, removeTopPadding = false }) => {
return (
- {/* Padding top matches the app toolbar drag area height */}
-
+ {/* Padding top matches the app toolbar drag area height - can be removed for full bleed */}
+
{children}
diff --git a/ui/desktop/src/components/hub.tsx b/ui/desktop/src/components/hub.tsx
index 924bcf98b5..af2b44e04f 100644
--- a/ui/desktop/src/components/hub.tsx
+++ b/ui/desktop/src/components/hub.tsx
@@ -86,8 +86,8 @@ export default function Hub({
return (
-
-
+
+
diff --git a/ui/desktop/src/components/sessions/SessionsInsights.tsx b/ui/desktop/src/components/sessions/SessionsInsights.tsx
index 25c71fec69..c047a8081f 100644
--- a/ui/desktop/src/components/sessions/SessionsInsights.tsx
+++ b/ui/desktop/src/components/sessions/SessionsInsights.tsx
@@ -106,25 +106,29 @@ export function SessionInsights() {
}
return (
-
-
-
-
-
-
+
+ {/* Header container with rounded bottom */}
+
-
+ {/* Stats containers - full bleed with 2px gaps */}
+
{/* Top row with three equal columns */}
-
+
{/* Total Sessions Card */}
-
-
+
+
{insights?.totalSessions}
@@ -135,8 +139,8 @@ export function SessionInsights() {
{/* Average Duration Card */}
-
-
+
+
{insights?.avgSessionDuration?.toFixed(1)}m
@@ -147,8 +151,8 @@ export function SessionInsights() {
{/* Total Tokens Card */}
-
-
+
+
{insights?.totalTokens ? `${(insights.totalTokens / 1000000).toFixed(2)}M` : ''}
@@ -159,66 +163,36 @@ export function SessionInsights() {
- {/* Bottom row with two equal columns */}
-
+ {/* Projects and Chats row */}
+
{/* Recent Projects Card */}
- {/*
*/}
- {/* */}
- {/* */}
- {/* */}
- {/* Recent projects*/}
- {/* */}
- {/* */}
- {/*
*/}
- {/* */}
- {/*
*/}
- {/* {recentProjects.length > 0 ? (*/}
- {/* recentProjects.map((project, index) => (*/}
- {/* handleProjectClick(project.id)}*/}
- {/* role="button"*/}
- {/* tabIndex={0}*/}
- {/* initial={{ opacity: 0, y: 5 }}*/}
- {/* animate={{ opacity: 1, y: 0 }}*/}
- {/* transition={{ duration: 0.3, delay: index * 0.1 }}*/}
- {/* onKeyDown={(e) => {*/}
- {/* if (e.key === 'Enter' || e.key === ' ') {*/}
- {/* handleProjectClick(project.id);*/}
- {/* }*/}
- {/* }}*/}
- {/* >*/}
- {/* */}
- {/* */}
- {/* {project.name}*/}
- {/*
*/}
- {/* */}
- {/* {formatDateOnly(project.updatedAt)}*/}
- {/* */}
- {/* */}
- {/* ))*/}
- {/* ) : (*/}
- {/* */}
- {/* No recent projects found.*/}
- {/*
*/}
- {/* )}*/}
- {/* */}
- {/*
*/}
- {/* */}
- {/**/}
+
+
+
+
+ Recent projects
+
+
+
+
+
+ No recent projects found.
+
+
+
+
{/* Recent Chats Card */}
-
-
-
+
+
+
Recent chats
@@ -271,7 +245,9 @@ export function SessionInsights() {
-
+
+ {/* Filler container - extends to fill remaining space */}
+
);