feat: complete asset deployment for plugin engines

**Asset Deployment Infrastructure:**
- Enhanced RenderingEngineManager with complete asset deployment
- Automatic plugin source directory discovery and asset copying
- File system operations with proper directory structure preservation
- Comprehensive error handling for missing assets

**CLI Integration:**
- Automatic asset deployment when using plugin engines
- Verbose output showing deployment progress and statistics
- Asset verification and accessibility validation
- Production-ready deployment to _markitect/plugins/ structure

**TestDrive JSUI Assets:**
- Complete CSS asset suite (editor, controls, GitHub theme)
- Placeholder image assets for testing deployment
- Proper asset organization following plugin conventions
- All 18 assets now deployed correctly

**Testing Infrastructure:**
- Comprehensive asset deployment testing
- CLI integration verification with asset shipping
- File existence and accessibility validation
- Complete directory structure verification

**Key Features:**
- Assets deployed to `_markitect/plugins/testdrive-jsui/` when using --edit
- HTML references match deployed asset locations
- 18 total assets: 12 JS, 3 CSS, 3 images
- Automatic deployment without --ship-assets flag needed
- Clean separation of development vs production asset handling

**Example Output:**
```
🎯 Using rendering engine: testdrive-jsui (supports: edit, view)
📦 Deploying assets for engine 'testdrive-jsui'...
📄 Deployed 18 asset files
   js: 12 files
   css: 3 files
   images: 3 files
 Rendered with INTERACTIVE editing mode
```

This fixes the "HTML assets not found" issue when using explicit
output directories with plugin engines. All plugin assets are now
properly deployed and accessible.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-14 09:20:37 +01:00
parent 8f1cc0faf9
commit 409d1a8d9f
11 changed files with 842 additions and 5 deletions

150
test_asset_deployment.py Normal file
View File

@@ -0,0 +1,150 @@
#!/usr/bin/env python3
"""
Test asset deployment functionality
"""
import sys
from pathlib import Path
import shutil
# Add current directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))
def test_asset_deployment():
"""Test plugin asset deployment to output directory."""
print("📦 Testing Asset Deployment")
print("=" * 50)
try:
# Clean up and create test output directory
output_dir = Path('/tmp/test_asset_deployment')
if output_dir.exists():
shutil.rmtree(output_dir)
output_dir.mkdir()
# Import plugin system
from markitect.plugins import PluginManager, RenderingEngineManager, RenderingConfig
# Initialize plugin system
print("1⃣ Initializing plugin system...")
plugin_manager = PluginManager()
rendering_manager = RenderingEngineManager(plugin_manager)
print(" ✅ Plugin system initialized")
# Get testdrive-jsui engine
engine_name = 'testdrive-jsui'
engine = rendering_manager.get_engine(engine_name)
if not engine:
print(f" ❌ Engine '{engine_name}' not found")
return False
print(f" ✅ Engine loaded: {engine.metadata.name}")
# Setup rendering configuration
print("\n2⃣ Setting up rendering configuration...")
config = RenderingConfig(
asset_base_url="_markitect",
development_mode=False,
output_directory=output_dir
)
print(f" 📁 Output directory: {config.output_directory}")
print(f" 🔗 Asset base URL: {config.asset_base_url}")
# Test asset deployment
print(f"\n3⃣ Deploying assets...")
deployed_assets = rendering_manager.deploy_engine_assets(engine_name, config)
print(f" ✅ Asset deployment completed")
# Verify deployment results
print(f"\n4⃣ Verifying deployment...")
total_deployed = 0
for asset_type, files in deployed_assets.items():
if isinstance(files, list):
print(f" {asset_type}: {len(files)} files")
total_deployed += len(files)
# Check first few files exist
for file_path in files[:3]:
if Path(file_path).exists():
size = Path(file_path).stat().st_size
print(f"{Path(file_path).name} ({size:,} bytes)")
else:
print(f"{Path(file_path).name} (missing)")
if len(files) > 3:
print(f" ... and {len(files) - 3} more")
print(f"\n5⃣ Testing with document rendering...")
# Test full rendering with asset deployment
test_content = """# Asset Deployment Test
This document tests the complete asset deployment pipeline.
## Features
- Plugin rendering with testdrive-jsui
- Asset deployment to output directory
- Verification of deployed files
The HTML should reference assets that are deployed to the output directory.
"""
html_content = engine.render_document(test_content, 'edit', config)
html_file = output_dir / 'test_document.html'
html_file.write_text(html_content)
print(f" ✅ Document rendered: {html_file}")
print(f" 📄 HTML size: {len(html_content):,} characters")
# Directory structure verification
print(f"\n6⃣ Output directory structure:")
def print_tree(directory, prefix="", max_depth=3, current_depth=0):
if current_depth >= max_depth:
return
items = sorted(directory.iterdir())
for i, item in enumerate(items):
is_last = i == len(items) - 1
current_prefix = "└── " if is_last else "├── "
print(f"{prefix}{current_prefix}{item.name}")
if item.is_dir() and current_depth < max_depth - 1:
extension = " " if is_last else ""
print_tree(item, prefix + extension, max_depth, current_depth + 1)
print_tree(output_dir)
# Final verification
asset_dir = output_dir / "_markitect" / "plugins" / "testdrive-jsui"
if asset_dir.exists():
print(f"\n✅ Plugin asset directory created: {asset_dir}")
# Count deployed files
js_files = list((asset_dir / "static" / "js").rglob("*.js")) if (asset_dir / "static" / "js").exists() else []
css_files = list((asset_dir / "static" / "css").rglob("*.css")) if (asset_dir / "static" / "css").exists() else []
print(f" 📄 JavaScript files: {len(js_files)}")
print(f" 🎨 CSS files: {len(css_files)}")
if js_files:
print(f" 🌐 Open in browser: file://{html_file.absolute()}")
return True
else:
print(f"\n❌ Plugin asset directory not created")
return False
except Exception as e:
print(f"❌ Asset deployment test failed: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
success = test_asset_deployment()
sys.exit(0 if success else 1)