Add CLAUDE.md for project guidance and enhance get_object_subtree_with_fields to handle circular references

- Introduced CLAUDE.md to provide comprehensive guidance on the Penpot MCP Server, including project overview, key commands, architecture, and common workflows.
- Enhanced the `get_object_subtree_with_fields` function to track visited nodes and handle circular references, ensuring robust tree structure retrieval.
- Added tests for circular reference handling in `test_penpot_tree.py` to validate new functionality.
This commit is contained in:
chema
2025-06-29 17:21:17 +02:00
parent c38aec23d4
commit 0d4d34904c
3 changed files with 198 additions and 2 deletions

View File

@@ -1087,4 +1087,61 @@ def test_get_object_subtree_with_fields_root_frame():
assert result['tree']['type'] == 'frame'
assert 'children' in result['tree']
assert len(result['tree']['children']) == 1
assert result['tree']['children'][0]['name'] == 'Main Container'
assert result['tree']['children'][0]['name'] == 'Main Container'
def test_get_object_subtree_with_fields_circular_reference():
"""Test handling of circular references in object tree."""
file_data = {
'data': {
'pagesIndex': {
'page1': {
'name': 'Test Page',
'objects': {
# Object A references B as parent
'object-a': {
'type': 'frame',
'name': 'Object A',
'parentId': 'object-b'
},
# Object B references A as parent (circular)
'object-b': {
'type': 'frame',
'name': 'Object B',
'parentId': 'object-a'
},
# Object C references itself as parent
'object-c': {
'type': 'frame',
'name': 'Object C',
'parentId': 'object-c'
}
}
}
}
}
}
# Test getting object A - should handle circular reference with B
result = get_object_subtree_with_fields(file_data, 'object-a')
assert 'error' not in result
assert result['tree']['id'] == 'object-a'
assert 'children' in result['tree']
# Check that object-b appears as a child
assert len(result['tree']['children']) == 1
assert result['tree']['children'][0]['id'] == 'object-b'
# The circular reference appears when object-a appears again as a child of object-b
assert 'children' in result['tree']['children'][0]
assert len(result['tree']['children'][0]['children']) == 1
assert result['tree']['children'][0]['children'][0]['id'] == 'object-a'
assert result['tree']['children'][0]['children'][0]['_circular_reference'] == True
# Test getting object C - should handle self-reference
result = get_object_subtree_with_fields(file_data, 'object-c')
assert 'error' not in result
assert result['tree']['id'] == 'object-c'
assert 'children' in result['tree']
# Check that object-c appears as its own child with circular reference marker
assert len(result['tree']['children']) == 1
assert result['tree']['children'][0]['id'] == 'object-c'
assert result['tree']['children'][0]['_circular_reference'] == True