Background agents → sidebar section (owner): the retired floating dock's successor

The old activity dock (fixed bottom-right, every view) was a cross-session
widget parked inside the session view — the same boundary confusion that
got the plan window moved. The sidebar is the app's cross-session surface,
so the agents section lives at its bottom strip now (user-locked design):

- ALWAYS present: empty means empty — the header ('Background agents',
  matching the Sessions label language) sits alone; nothing hides and
  nothing decorates (the total-cost span only renders when populated).
- Populates and grows when processes run: same blobs (sub-agents +
  extraction runs, one poll, inferred cost, elapsed heartbeat), capped by
  max-h-[40dvh] + internal scroll so a pile never crowds the session list.
- Per-blob END button (unchanged abort contract); the detail popover
  becomes an INLINE expansion — the section scrolls, a floating popover
  would clip at its bounds.
- Sidebar-native skin: border-t separator matching the sidebar's edge,
  session-row hover language, no floating-card chrome.
- Sidebar closed = the learner opted out; no ambient signal for now
  (user decision — invisibility until a clearer observability story).
- Narrow-mode count badge/drawer machinery retired with the dock.

app/layout.tsx: ActivityDock mount removed, ActivityProvider stays (the
sidebar consumes the context). Live-verified: populated rows with inline
detail + session link, abort makes the row vanish, idle renders the
header alone, closed sidebar hides the section with nothing floating.
Gates: typecheck, lint, 423/423 tests.
This commit is contained in:
amosblomqvist
2026-09-14 11:56:22 +03:00
parent 38d77204ed
commit bbee72f354
4 changed files with 83 additions and 107 deletions
+5 -8
View File
@@ -3,7 +3,7 @@ import { JetBrains_Mono, Source_Sans_3 } from "next/font/google";
import "katex/dist/katex.min.css";
import "./globals.css";
import { AppShell, SidebarProvider } from "@/components/sidebar";
import { ActivityDock, ActivityProvider } from "@/components/activity-dock";
import { ActivityProvider } from "@/components/activity-dock";
// Chrome = JetBrains Mono, teaching prose = Source Sans 3, titles = CMU
// Serif (the bundled lh-cmu @font-face in globals.css — no CDN).
@@ -20,13 +20,10 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<html lang="en" className={`dark ${ui.variable} ${prose.variable}`}>
<body className="min-h-dvh antialiased">
<SidebarProvider>
<ActivityProvider>
<AppShell>{children}</AppShell>
{/* The reserved bottom-right corner of every view — renders
nothing while no background process runs. */}
<ActivityDock />
</ActivityProvider>
</SidebarProvider>
<ActivityProvider>
<AppShell>{children}</AppShell>
</ActivityProvider>
</SidebarProvider>
</body>
</html>
);