deepagents-architectur…
Guides architectural decisions for Deep Agents applications. Use when deciding between Deep Agents vs alternatives, choosing backend strategies, designing…
Advanced React Flow patterns for complex use cases. Use when implementing sub-flows, custom connection lines, programmatic layouts, drag-and-drop, undo/redo, or complex state synchronization.
$ npx -y skills add existential-birds/beagle --skill react-flow-advanced --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/react-flow-advancedContext preview
The summary Claude sees to decide when to auto-load this skill.
Advanced React Flow patterns for complex use cases. Use when implementing sub-flows, custom connection lines, programmatic layouts, drag-and-drop, undo/redo, or complex state synchronization.
name: react-flow-advanced description: Advanced React Flow patterns for complex use cases. Use when implementing sub-flows, custom connection lines, programmatic layouts, drag-and-drop, undo/redo, or complex state synchronization.
Use these as **sequenced** checks—not “I think it works.”
1. **Sub-flows / groups:** **Pass:** Every `parentId` matches an existing node `id`; the parent `type` is registered in `nodeTypes`; child positions are relative to the parent as intended (spot-check one drag inside/outside the group). 2. **Custom connection line:** **Pass:** With a valid/invalid drag, stroke or `connectionStatus` visibly differs; path renders without console errors from `getSmoothStepPath` (invalid coords). 3. **External drag-and-drop:** **Pass:** `onDragOver` always `preventDefault()`; drop position uses `screenToFlowPosition` (not raw `clientX`/`clientY` as flow coords); new node appears under the cursor on the pane. 4. **Undo/redo:** **Pass:** One undo returns to the prior `{ nodes, edges }`; redo restores; rapid changes do not leave `canUndo`/`canRedo` inconsistent with visible graph (exercise add → undo → redo once). 5. **Programmatic layout (dagre):** **Pass:** After `setNodes`, node positions match intended `rankdir`; `fitView` runs after layout (e.g. `requestAnimationFrame`) so the viewport is not stale. 6. **Connect on drop (new node):** **Pass:** Dropping on empty pane creates a node **and** an edge from the source handle; dropping on a valid target does not duplicate nodes (only the invalid-drop path adds a node). 7. **Selectors / store:** **Pass:** Components that `useStore` with objects use `shallow` (or equivalent) so unrelated store updates do not re-render every frame.
const nodes = [
// Parent (group) node
{
id: 'group-1',
type: 'group',
position: { x: 0, y: 0 },
style: { width: 400, height: 300, padding: 10 },
data: { label: 'Group' },
},
// Child nodes
{
id: 'child-1',
parentId: 'group-1', // Reference parent
extent: 'parent', // Constrain to parent bounds
expandParent: true, // Auto-expand parent if dragged to edge
position: { x: 20, y: 50 }, // Relative to parent
data: { label: 'Child 1' },
},
{
id: 'child-2',
parentId: 'group-1',
extent: 'parent',
position: { x: 200, y: 50 },
data: { label: 'Child 2' },
},
];function GroupNode({ data, id }: NodeProps) {
return (
<div className="group-node">
<div className="group-header">{data.label}</div>
{/* Children are rendered automatically by React Flow */}
</div>
);
}import { ConnectionLineComponentProps, getSmoothStepPath } from '@xyflow/react';
function CustomConnectionLine({
fromX, fromY, fromPosition,
toX, toY, toPosition,
connectionStatus,
}: ConnectionLineComponentProps) {
const [path] = getSmoothStepPath({
sourceX: fromX,
sourceY: fromY,
sourcePosition: fromPosition,
targetX: toX,
targetY: toY,
targetPosition: toPosition,
});
return (
<g>
<path
d={path}
fill="none"
stroke={connectionStatus === 'valid' ? '#22c55e' : '#ef4444'}
strokeWidth={2}
strokeDasharray="5 5"
/>
</g>
);
}
<ReactFlow connectionLineComponent={CustomConnectionLine} />import { useCallback, useRef, useState } from 'react';
import { useReactFlow } from '@xyflow/react';
function DnDFlow() {
const reactFlowWrapper = useRef(null);
const { screenToFlowPosition, addNodes } = useReactFlow();
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const onDragOver = useCallback((event: DragEvent) => {
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
}, []);
const onDrop = useCallback((event: DragEvent) => {
event.preventDefault();
const type = event.dataTransfer.getData('application/reactflow');
if (!type) return;
// Convert screen position to flow position
const position = screenToFlowPosition({
x: event.clientX,
y: event.clientY,
});
const newNode = {
id: `${Date.now()}`,
type,
position,
data: { label: `${type} node` },
};
addNodes(newNode);
}, [screenToFlowPosition, addNodes]);
return (
<div ref={reactFlowWrapper} style={{ height: '100%' }}>
<ReactFlow
onDragOver={onDragOver}
onDrop={onDrop}
onInit={setReactFlowInstance}
/>
</div>
);
}
// Sidebar component
function Sidebar() {
const onDragStart = (event: DragEvent, nodeType: string) => {
event.dataTransfer.setData('application/reactflow', nodeType);
event.dataTransfer.effectAllowed = 'move';
};
return (
<aside>
<div draggable onDragStart={(e) => onDragStart(e, 'input')}>
Input Node
</div>
<div draggable onDragStart={(e) => onDragStart(e, 'default')}>
Default Node
</div>
</aside>
);
}import { useCallback, useState } from 'react';
function useUndoRedo<T>(initialState: T) {
const [history, setHistory] = useState<T[]>([initialState]);
const [index, setIndex] = useState(0);
const state = history[index];
const setState = useCallback((newState: T | ((prev: T) => T)) => {
setHistory((prev) => {
const resolved = typeof newState === 'function'
? (newState as (prev: T) => T)(prev[index])
: newState;
// Remove future states and add new state
const newHistory = prev.slice(0, index + 1);
return [...newHistory, resolved];
});
setIndex((i) => i + 1);
}, [index]);
const undo = useCallback(() => {
setIndex((i) => Math.max(0, i - 1));
}, []);
const redo = useCallback(() => {
setIndex((i) => Math.min(history.length - 1,Image: NASA, Public Domain. Source Beagle is an Agent Skills marketplace: framework-aware code review, documentation, testing, architectural analysis, and git workflows for any compatible coding agent.
Repo: existential-birds/beagle
Guides architectural decisions for Deep Agents applications. Use when deciding between Deep Agents vs alternatives, choosing backend strategies, designing…
Reviews Deep Agents code for bugs, anti-patterns, and improvements. Use when reviewing code that uses create_deep_agent, backends, subagents, middleware, or…
Implements agents using Deep Agents. Use when building agents with create_deep_agent, configuring backends, defining subagents, adding middleware, or setting…
Guides architectural decisions for LangGraph applications. Use when deciding between LangGraph vs alternatives, choosing state management strategies, designing…
Reviews LangGraph code for bugs, anti-patterns, and improvements. Use when reviewing code that uses StateGraph, nodes, edges, checkpointing, or other LangGraph…
Implements stateful agent graphs using LangGraph. Use when building graphs, adding nodes/edges, defining state schemas, implementing checkpointing, handling…