Skip to content

LOU-M: real ReactFlow canvas for the agent graph editor - #18

Merged
LinuxDevil merged 1 commit into
mainfrom
loushy/lou-m
Sep 29, 2026
Merged

LinuxDevil merged 1 commit into
mainfrom
loushy/lou-m

Conversation

@LinuxDevil

Copy link
Copy Markdown
Owner

Summary

  • Adds @xyflow/react v12 (the current, actively-maintained React Flow package; reactflow is the predecessor name, now in maintenance mode) plus dagre/@types/dagre for auto-layout, as real dependencies of apps/agent-forge.
  • CanvasArea.tsx: real ReactFlow canvas with custom node types, MiniMap/Controls/Background, palette drag-and-drop, connect-drag with inline invalid-connection rejection, delete key, duplicate (Ctrl/Cmd+D), auto-layout + fit-view toolbar buttons.
  • canvas/graphMutations.ts: pure functions (addNode/removeNode/duplicateNode/renameNode/moveNode/updateNodeData/connectNodes/removeEdge) are the only way the canvas mutates AgentGraphSpec. CanvasArea derives ReactFlow's nodes/edges from AppState.graph via useMemo every render and never calls ReactFlow's own setNodes/setEdges/addEdge — there is no second source of truth to drift.
  • graph/connectionRules.ts's port-compatibility matrix backs both isValidConnection in the live canvas and the batch validateGraph() pass — the same rule, enforced in both places.
  • AppState.tsx: graph: AgentGraphSpec is now canonical state; spec is derived via graphToSpec(); added multi-agent switchAgent/createAgent/agents.
  • Inspector.tsx/LeftRail.tsx rewired accordingly.

Verification

Independently verified on this branch (not just taken on faith from the original implementation report):

  • Diff footprint is scoped to apps/agent-forge/** + package-lock.json only.
  • Read graphMutations.ts and CanvasArea.tsx end to end: confirmed every node/edge change (position, delete, connect, drag-drop, duplicate, auto-layout) routes through graphMutations.ts + setGraph; ReactFlow's nodes/edges props are recomputed from AppState.graph every render.
  • Confirmed connectionRules.ts's isEdgeTypeAllowed is called from both CanvasArea's isValidConnection and validateGraph.ts.
  • Confirmed @xyflow/react@12.12.0 is installed and is a real, sensible, actively-versioned package.
  • Ran apps/agent-forge's own build/lint/typecheck/test: all clean, 56/56 tests passing.
  • Ran root npm run build, npm run lint (0 errors, pre-existing warnings only), npx tsc --noEmit (clean), and npm run test:coverage: 747 passed / 5 failed / 3 skipped. Verified the 5 failures are in packages/create-loushy-agent, caused only by that package's dist/ not being built yet in this fresh worktree (Cannot find module '../dist/index.js') — confirmed by building that package locally (npm run build --workspace=packages/create-loushy-agent), after which those same tests pass (8/8). CI's workflow already runs that build step before test:coverage, so this is not a real regression.

Test plan

  • apps/agent-forge: npm run build, npm run lint, npx tsc --noEmit, npm test -- --run (56/56 passing)
  • Root: npm run build, npm run lint, npx tsc --noEmit, npm run test:coverage
  • Wait for and confirm green GitHub Actions run on this branch before merge

🤖 Generated with Claude Code

Replaces the LOU-L1 CanvasArea placeholder with a genuine @xyflow/react
integration:

- Custom node components (trigger/llm/tool/approval/output) driven by
  AgentGraphSpec data, with ReactFlow's own Handle/MiniMap/Controls/
  Background rather than reimplementing pan/zoom/minimap.
- Drag-from-palette node creation, inline rename, delete, duplicate
  (Ctrl/Cmd+D), connect-drag edge creation with inline port-compatibility
  rejection, and a dagre-based "Auto layout" toolbar action.
- Pure, unit-tested graph-mutation functions (src/canvas/graphMutations.ts)
  so every canvas interaction flows through AgentGraphSpec - ReactFlow's
  nodes/edges props are a recomputed view of that state, not a second
  source of truth.
- Extended validateGraph()/connectionRules.ts with the same edge-type
  compatibility rules the canvas rejects inline (e.g. trigger -> trigger).
- AppState now owns `graph: AgentGraphSpec` as canonical state, derives
  `spec` for persistence/back-compat, and adds multi-agent switching plus
  a template-based "New agent" flow (blank / support-bot templates).

56 tests passing in apps/agent-forge (18 new for graph mutations, 5 for
connection rules, 3 for auto-layout, 1 new validateGraph case).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@LinuxDevil
LinuxDevil merged commit 9dc547f into main Sep 29, 2026
1 check passed
@LinuxDevil
LinuxDevil deleted the loushy/lou-m branch September 29, 2026 10:56
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