import { useRegisterState } from 'cedar-os';
import { Node } from 'reactflow';
// Register nodes state with custom setters
useRegisterState({
key: 'nodes',
value: nodes,
setValue: setNodes,
description: 'Product roadmap nodes',
customSetters: {
addNode: {
name: 'addNode',
description: 'Add a new node to the roadmap',
parameters: [
{
name: 'node',
type: 'Node<FeatureNodeData>',
description: 'The node to add',
},
],
execute: (currentNodes, node) => {
const newNode = {
...node,
id: node.id || uuidv4(),
type: 'featureNode',
position: { x: Math.random() * 400, y: Math.random() * 400 },
data: {
...node.data,
nodeType: node.data.nodeType || 'feature',
status: node.data.status || 'planned',
upvotes: node.data.upvotes || 0,
comments: node.data.comments || [],
diff: 'added' as const,
},
};
setNodes([...currentNodes, newNode]);
},
},
removeNode: {
name: 'removeNode',
description: 'Remove a node from the roadmap',
parameters: [
{
name: 'id',
type: 'string',
description: 'The ID of the node to remove',
},
],
execute: async (currentNodes, id) => {
// Mark as removed with diff instead of immediate deletion
setNodes(
currentNodes.map((node) =>
node.id === id
? { ...node, data: { ...node.data, diff: 'removed' } }
: node
)
);
},
},
acceptAllDiffs: {
name: 'acceptAllDiffs',
description: 'Accept all pending diffs',
parameters: [],
execute: async (currentNodes) => {
const nodesWithDiffs = currentNodes.filter((n) => n.data.diff);
// Process removals
const removedNodeIds = nodesWithDiffs
.filter((n) => n.data.diff === 'removed')
.map((n) => n.id);
for (const nodeId of removedNodeIds) {
await deleteNode(nodeId);
}
// Update remaining nodes
const remainingNodes = currentNodes.filter(
(n) => !removedNodeIds.includes(n.id)
);
setNodes(
remainingNodes.map((n) => ({
...n,
data: { ...n.data, diff: undefined },
}))
);
},
},
},
});