feat: consolidate testdrive-jsui to capabilities and implement plugin self-declaration
## Major Changes - Moved all testdrive-jsui assets from root to capabilities/testdrive-jsui/ - Consolidated directory structure: js/, static/css/, static/images/, static/templates/ - Implemented plugin self-declaration (get_plugin_source_dir, get_asset_paths) - Removed hardcoded plugin discovery from rendering.py - Updated all asset paths to be relative to capability root ## Architecture Improvements - Single source of truth for all testdrive-jsui assets - Plugin declares its own location (no hardcoded paths) - Generic plugin discovery using hasattr check - Clean separation: all JS in .js files, no code mixing - Standalone capability ready for independent use ## Files Changed - markitect/plugins/testdrive_jsui.py: Added self-declaration methods - markitect/plugins/rendering.py: Removed hardcoded discovery - capabilities/testdrive-jsui/README.md: Added standalone usage documentation - Moved 17 asset files to consolidated structure - Deleted obsolete /testdrive-jsui/ root directory ## Testing - All 17 assets verified and working - Tested via CLI: markitect md-render --engine testdrive-jsui - Full document rendering successful Prepares testdrive-jsui to become a git submodule with proper dependency management. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -296,17 +296,21 @@ class RenderingEngineManager:
|
||||
return deployed_assets
|
||||
|
||||
def _get_plugin_source_dir(self, engine_name: str) -> Optional[Path]:
|
||||
"""Get the source directory for a plugin."""
|
||||
if engine_name == 'testdrive-jsui':
|
||||
# Look for testdrive-jsui directory relative to current directory
|
||||
candidates = [
|
||||
Path('testdrive-jsui'),
|
||||
Path(__file__).parent.parent.parent / 'testdrive-jsui',
|
||||
Path('.') / 'testdrive-jsui'
|
||||
]
|
||||
"""
|
||||
Get the source directory for a plugin.
|
||||
Uses plugin self-declaration if available, no hardcoded paths.
|
||||
"""
|
||||
engine = self.get_engine(engine_name)
|
||||
if not engine:
|
||||
return None
|
||||
|
||||
for candidate in candidates:
|
||||
if candidate.exists() and candidate.is_dir():
|
||||
return candidate
|
||||
# Use plugin's self-declared source directory if available
|
||||
if hasattr(engine, 'get_plugin_source_dir'):
|
||||
try:
|
||||
source_dir = engine.get_plugin_source_dir()
|
||||
if source_dir and source_dir.exists():
|
||||
return source_dir
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error getting plugin source dir for {engine_name}: {e}")
|
||||
|
||||
return None
|
||||
@@ -35,21 +35,45 @@ class TestDriveJSUIEngine(RenderingEnginePlugin):
|
||||
"""Support edit and view modes."""
|
||||
return ["edit", "view"]
|
||||
|
||||
def get_plugin_source_dir(self) -> Path:
|
||||
"""
|
||||
Return the source directory for this plugin.
|
||||
This allows the plugin to declare its own location.
|
||||
"""
|
||||
# Plugin is located in capabilities/testdrive-jsui/
|
||||
return Path(__file__).parent.parent.parent / "capabilities" / "testdrive-jsui"
|
||||
|
||||
def get_asset_paths(self) -> Dict[str, Path]:
|
||||
"""
|
||||
Return paths to asset directories relative to plugin source.
|
||||
This allows flexible asset organization within the plugin.
|
||||
"""
|
||||
base = self.get_plugin_source_dir()
|
||||
return {
|
||||
'js': base / 'js',
|
||||
'css': base / 'static' / 'css',
|
||||
'images': base / 'static' / 'images',
|
||||
'templates': base / 'static' / 'templates',
|
||||
}
|
||||
|
||||
def get_required_assets(self) -> Dict[str, List[str]]:
|
||||
"""Define required JavaScript, CSS, and other assets."""
|
||||
"""
|
||||
Define required JavaScript, CSS, and other assets.
|
||||
All paths are relative to the plugin source directory.
|
||||
"""
|
||||
return {
|
||||
"js": [
|
||||
"static/js/core/debug-system.js",
|
||||
"static/js/core/section-manager.js",
|
||||
"static/js/components/debug-panel.js",
|
||||
"static/js/components/dom-renderer.js",
|
||||
"../capabilities/testdrive-jsui/js/controls/control-base.js",
|
||||
"../capabilities/testdrive-jsui/js/controls/contents-control.js",
|
||||
"../capabilities/testdrive-jsui/js/controls/status-control.js",
|
||||
"../capabilities/testdrive-jsui/js/controls/debug-control.js",
|
||||
"../capabilities/testdrive-jsui/js/controls/edit-control.js",
|
||||
"static/js/config-loader.js",
|
||||
"static/js/main-updated.js"
|
||||
"js/core/debug-system.js",
|
||||
"js/core/section-manager.js",
|
||||
"js/components/debug-panel.js",
|
||||
"js/components/dom-renderer.js",
|
||||
"js/controls/control-base.js",
|
||||
"js/controls/contents-control.js",
|
||||
"js/controls/status-control.js",
|
||||
"js/controls/debug-control.js",
|
||||
"js/controls/edit-control.js",
|
||||
"js/config-loader.js",
|
||||
"js/main-updated.js"
|
||||
],
|
||||
"css": [
|
||||
"static/css/editor.css",
|
||||
@@ -57,9 +81,9 @@ class TestDriveJSUIEngine(RenderingEnginePlugin):
|
||||
"static/css/themes/github.css"
|
||||
],
|
||||
"images": [
|
||||
"images/icons/edit.png",
|
||||
"images/icons/save.png",
|
||||
"images/icons/reset.png"
|
||||
"static/images/icons/edit.png",
|
||||
"static/images/icons/save.png",
|
||||
"static/images/icons/reset.png"
|
||||
],
|
||||
"external": [
|
||||
"https://cdn.jsdelivr.net/npm/marked/marked.min.js"
|
||||
@@ -68,15 +92,16 @@ class TestDriveJSUIEngine(RenderingEnginePlugin):
|
||||
|
||||
def get_template_path(self) -> Optional[Path]:
|
||||
"""Return path to the HTML template."""
|
||||
# Look for template in plugin directory structure
|
||||
plugin_dir = Path(__file__).parent.parent.parent / "testdrive-jsui"
|
||||
template_path = plugin_dir / "templates" / "index.html"
|
||||
# Template is in the plugin's static/templates directory
|
||||
template_path = self.get_asset_paths()['templates'] / "index.html"
|
||||
|
||||
if template_path.exists():
|
||||
return template_path
|
||||
|
||||
# Fallback to current template location
|
||||
return Path(__file__).parent.parent / "templates" / "edit-mode-fixed.html"
|
||||
raise FileNotFoundError(
|
||||
f"Template not found at {template_path}. "
|
||||
f"Ensure testdrive-jsui is properly installed in capabilities/"
|
||||
)
|
||||
|
||||
def render_document(self,
|
||||
content: str,
|
||||
|
||||
Reference in New Issue
Block a user