feat: org chart sidebar section + pane with agent management - #115
Conversation
- Replace AGENTS/ORG CHART tab bar with clickable section headers - ORG CHART header opens card-based HierarchyPanel as a pane on the right - Add "orgchart" as a new ActivePane type in the pane/layout system - Org chart pane renders in SessionMountLayer, appears in TabBar - Add show/hide toggle for stopped agents in sidebar (eye icon) - Add permanent remove with confirmation for stopped agents (sidebar + org chart cards) - Org chart cards show trash overlay on hover with kill+remove confirmation - Include exited sessions in org chart status resolution - Fix: prevent duplicate orgchart tabs via findLeafByPaneId guard - Fix: removeSession throws on failure instead of silent swallow - Fix: handleRemove has loading guard and keeps confirm open on failure - Fix: fetchSessions compares exited session IDs, not just length - Align terminology: "stopped" instead of "exited" in all UI labels Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| const agentStatus: AgentStatus = info?.agentStatus ?? "stopped"; | ||
| const isRunning = info != null && info.session.status !== "stopped"; | ||
| const isRunning = | ||
| info != null && |
There was a problem hiding this comment.
🟡 Warning
Problem: In AgentCard's handleRemove, the isRunning variable is captured at component render time. If killSession succeeds and the store's polling cycle updates session.status to 'exited' before removeSession completes, the component re-renders with isRunning = false. This can cause the confirmation overlay to visually disappear while removeSession is still in-flight — confusing UX.
Why it matters: The user may see the confirm overlay vanish or the agent appear as stopped mid-operation.
Suggested fix: Re-check session status inside handleRemove rather than relying on the render-time const:
| const agentStatus: AgentStatus = info?.agentStatus ?? "stopped"; | ||
| const isRunning = info != null && info.session.status !== "stopped"; | ||
| const isRunning = | ||
| info != null && |
There was a problem hiding this comment.
Suggested fix: Capture running status at click time instead of render time:
| if (!(e.currentTarget as HTMLElement).draggable) | ||
| e.preventDefault(); | ||
| }} | ||
| draggable |
There was a problem hiding this comment.
🟡 Silent error feedback in exited-agent removal
Problem: In Sidebar.tsx, when removeSession(s.id) fails, the catch block silently swallows the error — confirmRemoveId stays set (keeping dialog visible) but the user gets no error message. If the backend returns a non-OK status (e.g. 404 session already gone, 500 server error), the user sees no indication what went wrong.
Why it matters: The confirm dialog staying open is a decent signal something went wrong, but without a visible error message the user may click Remove repeatedly or assume the UI is broken.
Suggested fix:
onClick={async () => {
try {
await removeSession(s.id);
setConfirmRemoveId(null);
} catch {
// Keep confirm visible + surface a transient error message
// e.g. setErrorId(s.id) to show "Failed to remove agent" inline
}
}}Alternative (minimal): At minimum, log to console with the session ID so it's debuggable: console.error('[Sidebar] removeSession failed for', s.id).
nox-0x
left a comment
There was a problem hiding this comment.
Overall solid implementation. The org chart as a pane, exited session separation, and singleton pane pattern are all well-designed. Two non-blocking UX issues flagged in comments: (1) isRunning captured at render time in handleRemove creating a potential mid-operation visual inconsistency, (2) silent error swallowing in Sidebar removeSession without user-visible feedback. Both are minor — fix before merge or track as follow-up.
Summary
"orgchart"toActivePaneunion, renders inSessionMountLayer, shows in tab bar — integrates fully with the existing split-pane/tab system.Key design decisions
"orgchart") — only one can exist,openOrgChartusesfindLeafByPaneIdto switch to existing tab instead of creating duplicatesremoveSessionthrows on failure (not silent swallow) — callers keep confirmation UI open so user knows it failedFiles changed
store.tsActivePanetype,openOrgChart/removeSession/toggleShowExitedAgentsactions,exitedSessionsstateSidebar.tsxHierarchyPanel.tsxSessionMountLayer.tsxHierarchyPanelin pane slotTabBar.tsxCodicon.tsxTest plan
make checkpasses (lint + types + 63 tests)🤖 Generated with Claude Code