Skip to content

feat(desktop): running agents section in workspace sidebar - #5414

Merged
Kitenite merged 4 commits into
mainfrom
add-running-agents-sectio
Jul 2, 2026
Merged

Kitenite merged 4 commits into
mainfrom
add-running-agents-sectio

Conversation

@Kitenite

@Kitenite Kitenite commented Jul 2, 2026 •

Copy link
Copy Markdown
Member

What

Adds a running agents row beneath each workspace in the v2 dashboard sidebar, mirroring the inline ports row.

  • Lists every agent bound to the workspace's terminals (via useTerminalAgentBindings), not just those currently working/permission — idle agents show too.
  • Each badge resolves name + preset icon from the binding's agentId (BUILTIN_AGENT_LABELS + usePresetIcon), the same resolver the terminal pane icon uses.
  • State: the leading glyph is the live StatusIndicator when the agent is working/permission/review, and the agent's icon when idle — held in a fixed-size slot so the row doesn't shift as state changes. No trailing status element.
  • Click opens the agent's terminal pane (terminalId + focusRequestId), same as the port badge.
  • Agents are ordered by startedAt for stable positioning; the details toggle summary counts all bound agents.

Layout / decoupling

  • The agents row is decoupled from the experimental inlineWorkspacePortsEnabled flag — the details container renders whenever it has content; only the ports section stays gated by the flag (so ports don't double-render against the bottom ports list).
  • Both the agents and ports rows now use flex flex-wrap — a single row that wraps to a second only when needed (previously a forced 2-row horizontal-scroll grid), with tighter spacing.

Notes

  • This row is terminal-agent bindings only; the built-in "Superset" chat agent is not listed. Easy to add chat sources alongside if we want it.

Test plan

  • Bind an agent in a workspace terminal → it appears in the sidebar with icon + name.
  • While the agent is working / awaiting permission / ready for review, the leading glyph reflects state; idle shows the agent icon; no layout shift on transitions.
  • Clicking a badge opens the workspace and focuses that agent's terminal pane.
  • Rows wrap to a second line only when they overflow; ports behavior unchanged.

Open in Stage

Summary by cubic

Adds a running agents row under each workspace in the v2 dashboard sidebar, showing all terminal-bound agents with live status and one-click focus to the agent’s terminal. The feature is behind an experimental “Workspace agents” toggle (off by default).

  • New Features

    • Lists all agents bound via useTerminalAgentBindings (includes idle); label and icon resolved via BUILTIN_AGENT_LABELS/usePresetIcon.
    • Badge shows StatusIndicator when active, agent icon when idle; fixed icon slot to avoid layout shift; tooltip with name and status; click focuses the agent’s terminal (terminalId/focusRequestId).
    • Stable order by startedAt; summary count reflects all bound agents.
  • Refactors

    • Agents row gated by useWorkspaceAgentsRowEnabled with an Experimental Settings switch and search entry; bindings query supports { enabled } to skip when off.
    • Workspace details container renders when it has content; ports remain behind inlineWorkspacePortsEnabled.
    • Agents and ports rows use flex flex-wrap and wrap only when needed.

Written for commit 6cb32c6. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added a new “Workspace agents” section to the dashboard sidebar with clickable agent badges that open the workspace view.
    • Introduced an experimental “Workspace agents” toggle to enable the inline agents row in the sidebar.
  • Bug Fixes
    • Improved dashboard sidebar workspace details so the agents section renders more reliably when agents are available (reduced unnecessary gating).
  • UI Updates
    • Updated the ports list layout to a more compact, wrap-friendly presentation.
    • Enhanced agent badge visuals with status indicators and clearer hover tooltips.

Kitenite added 2 commits July 1, 2026 17:50
Show a per-workspace row of currently running agents (working / awaiting
permission) beneath the workspace item, each badge linking to the agent.
Decoupled from the experimental inline-ports flag: the details container
renders whenever it has content, the ports section stays gated by
inlineWorkspacePortsEnabled, and the agents section shows independently.
Drive the workspace agents row from terminal-agent bindings so every bound
agent shows (not only working/permission), resolving name + preset icon from
agentId. The leading glyph is the live state indicator when active, and the
agent icon when idle, in a fixed-size slot so the row doesn't shift. Both the
agents and ports rows now wrap (single row, second only when needed) and the
agents row is decoupled from the experimental inline-ports flag.
@ghost

ghost commented Jul 2, 2026 •

Copy link
Copy Markdown

Ready to review this PR? Stage has broken it down into 5 individual chapters for you:

Title
1 Define experimental toggle for workspace agents
2 Update agent bindings hook with enabled option
3 Implement running agents data fetching logic
4 Create workspace agent badge and row components
5 Integrate agents row into sidebar and refactor layout
Open in Stage

Chapters generated by Stage for commit 6cb32c6 on Jul 2, 2026 4:59pm UTC.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afd94271-2caa-4ea4-9bb2-654b34a28ceb

📥 Commits

Reviewing files that changed from the base of the PR and between 44470d7 and 6cb32c6.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx

📝 Walkthrough

Walkthrough

Adds a workspace-agents experiment setting and persisted enablement state, then wires a running-agents sidebar section into dashboard workspace details with clickable agent badges and updated ports rendering.

Changes

Workspace agents setting

Layer / File(s) Summary
Workspace agents setting
apps/desktop/src/renderer/stores/workspace-agents-row.ts, apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts, apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/ExperimentalSettings.tsx
Adds a persisted enabled flag for workspace agents, registers the new experimental setting item and v2 variant, and renders a toggle in Experimental Settings that reads and updates the new store.

Dashboard sidebar agents

Layer / File(s) Summary
Running agents hook
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents/*
Defines running-agent types, reads terminal agent bindings with an enable switch, derives per-terminal status from the notification store, and re-exports the hook and types.
Sidebar agent rendering
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/*
Adds the agents row and clickable agent badge components, plus public re-exports for consumers.

Workspace details and ports

Layer / File(s) Summary
Sidebar details wiring
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspacePortsRow/DashboardSidebarWorkspacePortsRow.tsx
Adds the agents section to workspace details, gates ports rendering behind the inline-ports flag, removes that gate from the workspace item, and changes the ports list wrapper to a flex-wrapping div.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • superset-sh/superset#5392: Both PRs change the inlineWorkspacePortsEnabled gating around DashboardSidebarWorkspaceItem and DashboardSidebarWorkspaceDetails.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a running agents section in the workspace sidebar.
Description check ✅ Passed The description clearly explains the change and includes a test plan, though it omits the template's Related Issues and Type of Change sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-running-agents-sectio

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a running agents row to each workspace entry in the v2 dashboard sidebar. Agents bound to a workspace's terminals are fetched via useTerminalAgentBindings, their live status is read from the notification store, and each is rendered as a clickable badge that navigates to the agent's terminal pane. The PR also decouples DashboardSidebarWorkspaceDetails from the inlineWorkspacePortsEnabled feature flag (the flag now gates only the ports section internally), and migrates the ports row from a scrollable 2-row grid to flex-wrap layout.

  • New hook useDashboardSidebarWorkspaceRunningAgents composes useTerminalAgentBindings + useV2NotificationStore into a sorted, status-enriched agent list; logic is correct with a proper \"idle\" fallback.
  • DashboardSidebarWorkspaceDetails calls the agents hook for counting and pushes an agents section, but the rendered DashboardSidebarWorkspaceAgentsRow child independently calls the same hook, running two independent memo-sort computations per workspace render.
  • Ports row UX changes from horizontal-scroll grid to wrapping flex; existing port behavior is preserved behind the feature flag.

Confidence Score: 4/5

Safe to merge; the new agents row is purely additive, the flag-decoupling is handled correctly inside the details component, and no existing data paths are broken.

The feature works correctly end-to-end: bindings are fetched, statuses are resolved with a proper idle fallback, keys are stable, and click navigation is wired correctly. The one design concern is that useDashboardSidebarWorkspaceRunningAgents is invoked twice per workspace — once in the parent for counting and once inside the child for rendering — causing duplicate memo-sort work and two separate Zustand subscriptions. In a typical session with a handful of active agents this has negligible impact, but it diverges from the single-invocation expectation set by the context-backed ports pattern.

DashboardSidebarWorkspaceDetails.tsx — the double hook invocation for agents is worth addressing in a follow-up; all other files are straightforward.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx Adds agents section to the details panel; calls useDashboardSidebarWorkspaceRunningAgents for counting but the rendered child (AgentsRow) independently calls the same hook, duplicating memo computation.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents/useDashboardSidebarWorkspaceRunningAgents.ts New hook that builds a sorted list of agents from terminal bindings + notification store status; logic is correct with proper idle fallback and stable sort.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx Badge renders the correct icon/status indicator per agent state; status narrowing before StatusIndicator call is type-safe; tooltip content is well-structured.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx Removes the inlineWorkspacePortsEnabled gate from the parent so DashboardSidebarWorkspaceDetails always mounts; the gate is now correctly handled inside the details component.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspacePortsRow/DashboardSidebarWorkspacePortsRow.tsx Replaces OverflowFadeContainer+grid with a flex-wrap div; intentional UX change removing horizontal scroll in favor of line wrapping.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Item as "WorkspaceItem"
    participant Det as "WorkspaceDetails"
    participant Row as "AgentsRow"
    participant Hook as "useRunningAgents"
    participant Query as "useTerminalAgentBindings"
    participant ZStore as "useV2NotificationStore"

    Item->>Det: "render (always when not pending)"
    Det->>Hook: "call #1 — for agentCount"
    Hook->>Query: "fetch bindings (cached)"
    Hook->>ZStore: "subscribe to terminal statuses"
    Hook-->>Det: "DashboardSidebarRunningAgent[]"
    Det->>Row: "render content (agentCount > 0)"
    Row->>Hook: "call #2 — for rendering"
    Hook->>Query: "same key → cache hit"
    Hook->>ZStore: "second subscription"
    Hook-->>Row: "DashboardSidebarRunningAgent[]"
    Row->>Row: "render AgentBadge per agent"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Item as "WorkspaceItem"
    participant Det as "WorkspaceDetails"
    participant Row as "AgentsRow"
    participant Hook as "useRunningAgents"
    participant Query as "useTerminalAgentBindings"
    participant ZStore as "useV2NotificationStore"

    Item->>Det: "render (always when not pending)"
    Det->>Hook: "call #1 — for agentCount"
    Hook->>Query: "fetch bindings (cached)"
    Hook->>ZStore: "subscribe to terminal statuses"
    Hook-->>Det: "DashboardSidebarRunningAgent[]"
    Det->>Row: "render content (agentCount > 0)"
    Row->>Hook: "call #2 — for rendering"
    Hook->>Query: "same key → cache hit"
    Hook->>ZStore: "second subscription"
    Hook-->>Row: "DashboardSidebarRunningAgent[]"
    Row->>Row: "render AgentBadge per agent"
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx:79-92
**Duplicate hook invocation per workspace render**

`useDashboardSidebarWorkspaceRunningAgents` is called here to get `agentCount` and then called again inside `DashboardSidebarWorkspaceAgentsRow` (which this code renders as `content`). Unlike `useDashboardSidebarWorkspacePorts`, which reads a lightweight context, this hook runs a `useMemo` with a sort on every call, plus two separate `useV2NotificationStore` subscriptions. For workspaces with active agents both subscriptions fire on every status change, doubling the memo work.

Consider accepting the pre-computed list as a prop in `DashboardSidebarWorkspaceAgentsRow`, or lifting the hook call to a shared context the way ports use `DashboardSidebarPortsProvider`.

Reviews (1): Last reviewed commit: "feat(desktop): show all bound agents wit..." | Re-trigger Greptile

Comment on lines +79 to +92
const runningAgents = useDashboardSidebarWorkspaceRunningAgents(workspaceId);
const agentCount = runningAgents.length;
if (agentCount > 0) {
sections.push({
key: "agents",
summary: `${agentCount} ${agentCount === 1 ? "agent" : "agents"}`,
content: (
<DashboardSidebarWorkspaceAgentsRow
workspaceId={workspaceId}
isInSection={isInSection}
/>
),
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate hook invocation per workspace render

useDashboardSidebarWorkspaceRunningAgents is called here to get agentCount and then called again inside DashboardSidebarWorkspaceAgentsRow (which this code renders as content). Unlike useDashboardSidebarWorkspacePorts, which reads a lightweight context, this hook runs a useMemo with a sort on every call, plus two separate useV2NotificationStore subscriptions. For workspaces with active agents both subscriptions fire on every status change, doubling the memo work.

Consider accepting the pre-computed list as a prop in DashboardSidebarWorkspaceAgentsRow, or lifting the hook call to a shared context the way ports use DashboardSidebarPortsProvider.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx
Line: 79-92

Comment:
**Duplicate hook invocation per workspace render**

`useDashboardSidebarWorkspaceRunningAgents` is called here to get `agentCount` and then called again inside `DashboardSidebarWorkspaceAgentsRow` (which this code renders as `content`). Unlike `useDashboardSidebarWorkspacePorts`, which reads a lightweight context, this hook runs a `useMemo` with a sort on every call, plus two separate `useV2NotificationStore` subscriptions. For workspaces with active agents both subscriptions fire on every status change, doubling the memo work.

Consider accepting the pre-computed list as a prop in `DashboardSidebarWorkspaceAgentsRow`, or lifting the hook call to a shared context the way ports use `DashboardSidebarPortsProvider`.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx (1)

12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer path alias over relative import.

Other imports in this file use renderer/... aliases; this one uses a relative path instead.

♻️ Suggested alias import
-import type { DashboardSidebarRunningAgent } from "../../hooks/useDashboardSidebarWorkspaceRunningAgents";
+import type { DashboardSidebarRunningAgent } from "renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents";

As per coding guidelines: "When possible, use the path aliases defined in tsconfig.json instead of relative imports."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx`
at line 12, The import in DashboardSidebarAgentBadge should use the existing
renderer path alias instead of a relative path to match the rest of the file.
Update the DashboardSidebarWorkspaceAgentBadge component’s
DashboardSidebarRunningAgent import so it follows the same alias-based pattern
used by the other imports in this module.

Source: Coding guidelines

apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx (1)

8-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import the hook via the sibling barrel instead of its internal path.

useDashboardSidebarWorkspaceRunningAgents is imported by reaching directly into DashboardSidebarWorkspaceAgentsRow/hooks/..., but the sibling barrel (DashboardSidebarWorkspaceAgentsRow/index.ts) already re-exports both the component and the hook. This bypasses the component's public interface and couples this file to its internal folder layout.

🔧 Proposed fix
-import { DashboardSidebarWorkspaceAgentsRow } from "../DashboardSidebarWorkspaceAgentsRow";
-import { useDashboardSidebarWorkspaceRunningAgents } from "../DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents";
+import {
+	DashboardSidebarWorkspaceAgentsRow,
+	useDashboardSidebarWorkspaceRunningAgents,
+} from "../DashboardSidebarWorkspaceAgentsRow";

As per coding guidelines, **/components/**/*.tsx: "Use one folder per component with structure ComponentName/ComponentName.tsx + index.ts for barrel export".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx`
around lines 8 - 9, The import in DashboardSidebarWorkspaceDetails should use
the sibling DashboardSidebarWorkspaceAgentsRow barrel instead of the internal
hooks path. Update the imports so both DashboardSidebarWorkspaceAgentsRow and
useDashboardSidebarWorkspaceRunningAgents come from the public index export,
keeping this component decoupled from the folder’s internal structure and
aligned with the one-folder-per-component barrel pattern.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx`:
- Around line 50-60: The non-idle badge state is rendering smaller than the idle
icon inside the fixed DashboardSidebarWorkspaceAgentBadge slot. Update the
DashboardSidebarWorkspaceAgentBadge rendering so the StatusIndicator used for
agent.status !== "idle" matches the 14px container, either by passing a matching
className at the call site or by increasing StatusIndicator’s default size where
it is defined.

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx`:
- Line 12: The import in DashboardSidebarAgentBadge should use the existing
renderer path alias instead of a relative path to match the rest of the file.
Update the DashboardSidebarWorkspaceAgentBadge component’s
DashboardSidebarRunningAgent import so it follows the same alias-based pattern
used by the other imports in this module.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx`:
- Around line 8-9: The import in DashboardSidebarWorkspaceDetails should use the
sibling DashboardSidebarWorkspaceAgentsRow barrel instead of the internal hooks
path. Update the imports so both DashboardSidebarWorkspaceAgentsRow and
useDashboardSidebarWorkspaceRunningAgents come from the public index export,
keeping this component decoupled from the folder’s internal structure and
aligned with the one-folder-per-component barrel pattern.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9d9db782-9477-4061-95e4-8b99f986b05d

📥 Commits

Reviewing files that changed from the base of the PR and between a9acdd2 and f932581.

📒 Files selected for processing (9)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/DashboardSidebarWorkspaceAgentsRow.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/hooks/useDashboardSidebarWorkspaceRunningAgents/useDashboardSidebarWorkspaceRunningAgents.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspacePortsRow/DashboardSidebarWorkspacePortsRow.tsx

Comment on lines +50 to +60
<span className="flex size-3.5 shrink-0 items-center justify-center">
{agent.status === "idle" ? (
iconUrl ? (
<img src={iconUrl} alt="" className="size-3.5 object-contain" />
) : (
<LuBot className="size-3.5" strokeWidth={STROKE_WIDTH} />
)
) : (
<StatusIndicator status={agent.status} />
)}
</span>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -t f "StatusIndicator" apps/desktop/src/renderer/screens/main/components/StatusIndicator --exec cat -n {}

Repository: superset-sh/superset

Length of output: 2336


Match StatusIndicator to the 14px badge slot. It currently renders at size-2 (8px), so the non-idle state reads smaller than the icon state inside the fixed size-3.5 container. Pass a matching className here or bump the default indicator size.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx`
around lines 50 - 60, The non-idle badge state is rendering smaller than the
idle icon inside the fixed DashboardSidebarWorkspaceAgentBadge slot. Update the
DashboardSidebarWorkspaceAgentBadge rendering so the StatusIndicator used for
agent.status !== "idle" matches the 14px container, either by passing a matching
className at the call site or by increasing StatusIndicator’s default size where
it is defined.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx:79">
P2: This hook is invoked here to compute `agentCount`, but `DashboardSidebarWorkspaceAgentsRow` (rendered as `content` below) calls the same hook internally. Unlike `useDashboardSidebarWorkspacePorts` which reads from a shared context provider, `useDashboardSidebarWorkspaceRunningAgents` sets up its own `useV2NotificationStore` subscription and runs a `useMemo` sort each time. This doubles the subscription and memo work for every workspace with agents.

Consider either passing the already-computed `runningAgents` list as a prop to `DashboardSidebarWorkspaceAgentsRow`, or lifting the hook into a shared context/provider pattern similar to how ports use `DashboardSidebarPortsProvider`.</violation>
</file>

<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx:58">
P3: The `StatusIndicator` renders at its default `size-2` (8px) inside the fixed `size-3.5` (14px) container. In contrast, the idle state renders icons at the full `size-3.5`. This size mismatch means the non-idle state glyph appears noticeably smaller than the idle icon, which undermines the goal of a fixed-size slot with no layout shifts. Consider passing a `className` to scale the indicator to match the 14px slot (e.g., `className="size-3.5"`) or wrapping it to fill the container.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant DSWI as DashboardSidebarWorkspaceItem
    participant DSWD as DashboardSidebarWorkspaceDetails
    participant DSWAR as DashboardSidebarWorkspaceAgentsRow
    participant Hook as useDashboardSidebarWorkspaceRunningAgents
    participant Bindings as useTerminalAgentBindings
    participant Notif as useV2NotificationStore
    participant Badge as DashboardSidebarWorkspaceAgentBadge
    participant Router as react-router navigate

    DSWI->>DSWD: render details
    Note over DSWD: Decoupled from inlineWorkspacePortsEnabled flag
    DSWD->>Hook: useDashboardSidebarWorkspaceRunningAgents(workspaceId)
    Hook->>Bindings: get terminal agent bindings for workspace
    Bindings-->>Hook: Map<terminalId, {agentId, startedAt, …}>
    Hook->>Notif: subscribe to notification statuses
    Notif-->>Hook: statusByTerminal map (working/permission/review/idle)
    Note over Hook: Resolve agentId -> label via BUILTIN_AGENT_LABELS
    Hook->>Hook: sort bindings by startedAt ascending
    Hook-->>DSWD: DashboardSidebarRunningAgent[]
    DSWD->>DSWD: check agentCount > 0
    alt No agents
        DSWD-->>DSWI: render nothing for agents section
    else Has agents
        DSWD->>DSWAR: render agents row with agents[]
        DSWAR->>DSWAR: agents.length === 0? return null
        DSWAR->>Badge: render badge per agent
        Note over Badge: Fixed-size 14px icon slot to prevent layout shift
        alt Agent status is "idle"
            Badge->>Badge: render agent icon (preset icon or fallback LuBot)
        else Agent is working/permission/review
            Badge->>Badge: render StatusIndicator(status)
        end
        Badge->>Badge: render label (truncated)
        Badge->>Router: onClick → navigateToV2Workspace with terminalId + focusRequestId
        Router-->>Badge: terminal pane opens with agent focused
    end
    Note over DSWD: Ports row still gated by inlineWorkspacePortsEnabled
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

}

// Add more detail rows here (e.g. running agents).
const runningAgents = useDashboardSidebarWorkspaceRunningAgents(workspaceId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This hook is invoked here to compute agentCount, but DashboardSidebarWorkspaceAgentsRow (rendered as content below) calls the same hook internally. Unlike useDashboardSidebarWorkspacePorts which reads from a shared context provider, useDashboardSidebarWorkspaceRunningAgents sets up its own useV2NotificationStore subscription and runs a useMemo sort each time. This doubles the subscription and memo work for every workspace with agents.

Consider either passing the already-computed runningAgents list as a prop to DashboardSidebarWorkspaceAgentsRow, or lifting the hook into a shared context/provider pattern similar to how ports use DashboardSidebarPortsProvider.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceDetails/DashboardSidebarWorkspaceDetails.tsx, line 79:

<comment>This hook is invoked here to compute `agentCount`, but `DashboardSidebarWorkspaceAgentsRow` (rendered as `content` below) calls the same hook internally. Unlike `useDashboardSidebarWorkspacePorts` which reads from a shared context provider, `useDashboardSidebarWorkspaceRunningAgents` sets up its own `useV2NotificationStore` subscription and runs a `useMemo` sort each time. This doubles the subscription and memo work for every workspace with agents.

Consider either passing the already-computed `runningAgents` list as a prop to `DashboardSidebarWorkspaceAgentsRow`, or lifting the hook into a shared context/provider pattern similar to how ports use `DashboardSidebarPortsProvider`.</comment>

<file context>
@@ -72,7 +76,20 @@ export function DashboardSidebarWorkspaceDetails({
 	}
 
-	// Add more detail rows here (e.g. running agents).
+	const runningAgents = useDashboardSidebarWorkspaceRunningAgents(workspaceId);
+	const agentCount = runningAgents.length;
+	if (agentCount > 0) {
</file context>

<LuBot className="size-3.5" strokeWidth={STROKE_WIDTH} />
)
) : (
<StatusIndicator status={agent.status} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The StatusIndicator renders at its default size-2 (8px) inside the fixed size-3.5 (14px) container. In contrast, the idle state renders icons at the full size-3.5. This size mismatch means the non-idle state glyph appears noticeably smaller than the idle icon, which undermines the goal of a fixed-size slot with no layout shifts. Consider passing a className to scale the indicator to match the 14px slot (e.g., className="size-3.5") or wrapping it to fill the container.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceAgentsRow/components/DashboardSidebarWorkspaceAgentBadge/DashboardSidebarWorkspaceAgentBadge.tsx, line 58:

<comment>The `StatusIndicator` renders at its default `size-2` (8px) inside the fixed `size-3.5` (14px) container. In contrast, the idle state renders icons at the full `size-3.5`. This size mismatch means the non-idle state glyph appears noticeably smaller than the idle icon, which undermines the goal of a fixed-size slot with no layout shifts. Consider passing a `className` to scale the indicator to match the 14px slot (e.g., `className="size-3.5"`) or wrapping it to fill the container.</comment>

<file context>
@@ -0,0 +1,75 @@
+								<LuBot className="size-3.5" strokeWidth={STROKE_WIDTH} />
+							)
+						) : (
+							<StatusIndicator status={agent.status} />
+						)}
+					</span>
</file context>

Kitenite added 2 commits July 2, 2026 09:53
Add a 'Workspace agents' experimental toggle (off by default) mirroring the
inline-ports experiment: new store, settings-search entry, and Experimental
settings switch. The agents section only renders when enabled, and the
per-workspace terminal-agent-binding queries are skipped when disabled via a
threaded `enabled` flag.
@Kitenite
Kitenite merged commit 3f8e607 into main Jul 2, 2026
9 of 10 checks passed
@Kitenite
Kitenite deleted the add-running-agents-sectio branch July 2, 2026 21:01
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant