+ {handoffMessages.map(({ card, message, zebraShade }) => (
+
{
+ shellRefs.current.set(card.key, element);
+ }}
+ className="pointer-events-none absolute z-[9] origin-center opacity-0 transition-opacity duration-150 ease-out"
+ style={{
+ width: `${CARD_WIDTH}px`,
+ maxWidth: `${CARD_WIDTH}px`,
+ }}
+ onDragStart={(event) => {
+ event.preventDefault();
+ }}
+ >
+
+
+ ))}
+
+ );
+};
diff --git a/src/features/agent-graph/renderer/ui/TeamGraphOverlay.tsx b/src/features/agent-graph/renderer/ui/TeamGraphOverlay.tsx
index c5e87d8c..69e3bc65 100644
--- a/src/features/agent-graph/renderer/ui/TeamGraphOverlay.tsx
+++ b/src/features/agent-graph/renderer/ui/TeamGraphOverlay.tsx
@@ -18,6 +18,7 @@ import { GraphActivityHud } from './GraphActivityHud';
import { GraphBlockingEdgePopover } from './GraphBlockingEdgePopover';
import { GraphNodePopover } from './GraphNodePopover';
import { GraphProvisioningHud } from './GraphProvisioningHud';
+import { GraphTransientHandoffHud } from './GraphTransientHandoffHud';
import type { GraphDomainRef, GraphEventPort } from '@claude-teams/agent-graph';
import type {
@@ -88,7 +89,6 @@ export const TeamGraphOverlay = ({
const openCreateTask = useCallback(() => {
openCreateTaskDialog('');
}, [openCreateTaskDialog]);
-
const events: GraphEventPort = {
onNodeDoubleClick: useCallback(
(ref: GraphDomainRef) => {
@@ -141,13 +141,30 @@ export const TeamGraphOverlay = ({
height: number;
} | null;
getCameraZoom?: () => number;
+ getTransientHandoffSnapshot?: (options?: {
+ focusNodeIds?: ReadonlySet