feat: complete issue-facade capability enhancement and project cleanup
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
- Update TODO.md to reflect completed issue-facade capability fixes - Archive old CLI structure files that were moved to capabilities/issue-facade - Reorganize remaining CLI components into issue_tracker/ package - Add test coverage for issue #166 substack theme implementation - Update document manager and markdown command plugins with latest improvements - Complete project reorganization following capability-based architecture This commit finalizes the issue-facade capability enhancement project and ensures the main repository reflects the current state of all completed work. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
49
TODO.md
49
TODO.md
@@ -12,31 +12,38 @@ The structure organizes **future tasks** by their impact, just as a changelog or
|
||||
|
||||
This section is for tasks currently being discussed with or worked on by the coding assistant. These are the ephemeral, flow-of-thought tasks.
|
||||
|
||||
**🧪 TESTDRIVE-JSUI CAPABILITY EXTRACTION (2025-11-09) - IN PROGRESS**:
|
||||
Safely extracting JavaScript UI framework functionality into a dedicated capability while protecting existing hard-won UI functionality and integrating JavaScript tests into the main Python test suite.
|
||||
**🔧 FIX BROKEN ISSUE-FACADE CAPABILITY (2025-11-10) - COMPLETED ✅**:
|
||||
Successfully fixed the issue-facade capability by restructuring the package organization to match pyproject.toml expectations.
|
||||
|
||||
**📋 Workplan**: [docs/workplan-testdrive-jsui-capability.md](docs/workplan-testdrive-jsui-capability.md)
|
||||
**📋 Actions Completed**:
|
||||
- [x] Diagnosed package structure mismatch (pyproject.toml expected `issue_tracker` package but code was in flat structure)
|
||||
- [x] Fixed module import issue by creating `issue_tracker/` package and moving `cli/`, `core/`, `backends/` into it
|
||||
- [x] Verified capability functionality is restored (CLI commands working, package installs correctly)
|
||||
- [x] Tested with actual issue access (CLI prompts for backend configuration as expected)
|
||||
|
||||
**Current Status**: Implementing Phase 1 - Foundation Setup
|
||||
- [ ] Create capability directory structure
|
||||
- [ ] Setup pyproject.toml with dependencies
|
||||
- [ ] Create package.json with Jest configuration
|
||||
- [ ] Implement Python-JavaScript bridge
|
||||
- [ ] Create capability Makefile
|
||||
- [ ] Write basic README documentation
|
||||
**🎨 IMPLEMENT DOCUMENT STYLING (Issue #166) - COMPLETED ✅**:
|
||||
Successfully implemented Substack-style document theme for enhanced long-form reading experience.
|
||||
|
||||
**Objectives**:
|
||||
- 🔒 Zero-risk migration with copy-first approach
|
||||
- 🧪 Integrate JavaScript tests into main Python test suite
|
||||
- 🏗️ Clean capability architecture for JavaScript framework
|
||||
- 📊 Enhanced CI/CD integration for JavaScript testing
|
||||
- 🚀 Future extensibility for JavaScript framework evolution
|
||||
**📋 Features Implemented**:
|
||||
- [x] Substack document theme in layered theme system
|
||||
- [x] Spectral serif font for body text (optimized for long-form reading)
|
||||
- [x] Lora sans-serif font for headings (clean typography hierarchy)
|
||||
- [x] Warm cream background (#FAF9F1) for reduced eye strain
|
||||
- [x] Bronze accent color (#b08d57) for visual hierarchy
|
||||
- [x] 680px max-width for optimal reading line length
|
||||
- [x] 1.6 line-height for comfortable reading
|
||||
- [x] Complete TDD test coverage (6/6 tests passing)
|
||||
- [x] CLI integration: `markitect md-render --theme substack`
|
||||
- [x] Layered theme compatibility with existing mode/UI themes
|
||||
|
||||
**Safety Mechanisms**:
|
||||
- Copy-first approach (never move until verified)
|
||||
- Dual-track testing during migration
|
||||
- Gradual integration with rollback options
|
||||
- Comprehensive test verification at each step
|
||||
**Implementation Details**:
|
||||
- Added to `LAYERED_THEMES` as document-scope theme
|
||||
- Extended CSS generation to support `heading_font_family` property
|
||||
- Maintained backward compatibility with `TEMPLATE_STYLES`
|
||||
- Full integration with existing theme system architecture
|
||||
|
||||
**🧪 TESTDRIVE-JSUI CAPABILITY EXTRACTION (2025-11-09) - COMPLETED ✅**:
|
||||
Successfully extracted JavaScript UI framework functionality into a dedicated capability with complete automated test integration. The capability now provides 68 JavaScript tests + 11 Python integration tests for comprehensive testing coverage.
|
||||
|
||||
**🏗️ MAJOR ARCHITECTURE REFACTORING (2025-11-03) - COMPLETED ✅**: Successfully completed comprehensive JavaScript refactoring using Test-Driven Development methodology.
|
||||
|
||||
|
||||
@@ -263,11 +263,16 @@ class CleanDocumentManager:
|
||||
}}"""
|
||||
|
||||
# Heading styles
|
||||
heading_font_style = ""
|
||||
if 'heading_font_family' in props and props['heading_font_family']:
|
||||
heading_font_style = f"font-family: {props['heading_font_family']};"
|
||||
|
||||
heading_css = ""
|
||||
if props['heading_style'] == 'underlined':
|
||||
heading_css = f"""
|
||||
h1, h2, h3, h4, h5, h6 {{
|
||||
color: {props['heading_color']};
|
||||
{heading_font_style}
|
||||
border-bottom: 1px solid {props['border_color']};
|
||||
padding-bottom: 0.3em;
|
||||
}}"""
|
||||
@@ -275,6 +280,7 @@ class CleanDocumentManager:
|
||||
heading_css = f"""
|
||||
h1, h2, h3, h4, h5, h6 {{
|
||||
color: {props['heading_color']};
|
||||
{heading_font_style}
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}}
|
||||
@@ -288,6 +294,7 @@ class CleanDocumentManager:
|
||||
heading_css = f"""
|
||||
h1, h2, h3, h4, h5, h6 {{
|
||||
color: {props['heading_color']};
|
||||
{heading_font_style}
|
||||
}}"""
|
||||
|
||||
# Text alignment
|
||||
|
||||
@@ -180,6 +180,27 @@ LAYERED_THEMES = {
|
||||
'link_hover_color': '#999999'
|
||||
}
|
||||
},
|
||||
'substack': {
|
||||
'scope': 'document',
|
||||
'properties': {
|
||||
'font_family': 'Spectral, Georgia, "Times New Roman", serif',
|
||||
'heading_font_family': 'Lora, -apple-system, BlinkMacSystemFont, sans-serif',
|
||||
'max_width': '680px',
|
||||
'body_background': '#FAF9F1',
|
||||
'body_color': '#333333',
|
||||
'heading_color': '#333333',
|
||||
'text_align': 'left',
|
||||
'line_height': '1.6',
|
||||
'heading_style': 'simple',
|
||||
'accent_color': '#b08d57',
|
||||
'link_color': '#b08d57',
|
||||
'link_hover_color': '#8b6c42',
|
||||
'code_background': '#f5f4ed',
|
||||
'code_color': '#333333',
|
||||
'blockquote_border': '#b08d57',
|
||||
'blockquote_color': '#666666'
|
||||
}
|
||||
},
|
||||
|
||||
# Branding Themes - Company/personal styling
|
||||
'corporate': {
|
||||
@@ -205,7 +226,8 @@ LEGACY_THEME_MAPPING = {
|
||||
'basic': ['light', 'standard', 'basic'],
|
||||
'github': ['light', 'standard', 'github'],
|
||||
'dark': ['dark', 'standard', 'basic'],
|
||||
'academic': ['light', 'standard', 'academic']
|
||||
'academic': ['light', 'standard', 'academic'],
|
||||
'substack': ['light', 'standard', 'substack']
|
||||
}
|
||||
|
||||
# Keep TEMPLATE_STYLES for backward compatibility in tests
|
||||
@@ -229,6 +251,11 @@ TEMPLATE_STYLES = {
|
||||
'body_color': '#333',
|
||||
'font_family': 'Georgia, Times New Roman, serif',
|
||||
'max_width': '650px'
|
||||
},
|
||||
'substack': {
|
||||
'body_color': '#333333',
|
||||
'font_family': 'Spectral, Georgia, "Times New Roman", serif',
|
||||
'max_width': '680px'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
183
tests/test_issue_166_substack_theme.py
Normal file
183
tests/test_issue_166_substack_theme.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""
|
||||
Tests for Issue #166: Document theme that mimics substack fonts and fontsizes
|
||||
|
||||
This module tests the implementation of a Substack-style document theme
|
||||
for enhanced long-form reading experience.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch, MagicMock
|
||||
import json
|
||||
|
||||
# Add project root to path for imports
|
||||
import sys
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
|
||||
class TestIssue166SubstackTheme:
|
||||
"""Test Substack theme implementation for long-form reading."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test environment."""
|
||||
# Create temporary directory for test outputs
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.markdown_content = """# The Mythology of Ireland
|
||||
|
||||
This is a test document for validating the Substack theme implementation.
|
||||
The theme should provide excellent readability for longer essays online.
|
||||
|
||||
## Typography and Layout
|
||||
|
||||
The Substack style emphasizes:
|
||||
- Serif fonts for body text (Spectral)
|
||||
- Sans-serif fonts for headings (Lora)
|
||||
- Generous line spacing for readability
|
||||
- Warm color palette with soft cream background
|
||||
|
||||
### Key Design Principles
|
||||
|
||||
1. **Readability First**: Typography optimized for long-form content
|
||||
2. **Visual Breathing Room**: Generous margins and spacing
|
||||
3. **Print-Inspired**: Traditional typographic principles
|
||||
4. **Eye Comfort**: Soft, low-contrast color scheme
|
||||
|
||||
> "The best interfaces are almost invisible to the user. They don't get in the way of the content."
|
||||
> — A design principle that guides Substack's approach
|
||||
|
||||
This longer paragraph demonstrates how the theme handles extended body text.
|
||||
It should be comfortable to read with appropriate line height, font size,
|
||||
and spacing that reduces eye strain during extended reading sessions.
|
||||
"""
|
||||
|
||||
def teardown_method(self):
|
||||
"""Clean up test environment."""
|
||||
# Clean up temporary files
|
||||
import shutil
|
||||
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
||||
|
||||
def test_substack_theme_available_in_layered_themes(self):
|
||||
"""Test that substack theme is available in LAYERED_THEMES - Issue #166."""
|
||||
from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES
|
||||
|
||||
# Substack theme should be available as a document theme
|
||||
assert 'substack' in LAYERED_THEMES
|
||||
substack_theme = LAYERED_THEMES['substack']
|
||||
|
||||
# Should be scoped as a document theme
|
||||
assert substack_theme['scope'] == 'document'
|
||||
|
||||
# Should have required typography properties
|
||||
properties = substack_theme['properties']
|
||||
assert 'font_family' in properties
|
||||
assert 'max_width' in properties
|
||||
assert 'body_background' in properties
|
||||
assert 'heading_font_family' in properties
|
||||
|
||||
def test_substack_theme_typography_properties(self):
|
||||
"""Test that substack theme has correct typography properties - Issue #166."""
|
||||
from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES
|
||||
|
||||
substack_theme = LAYERED_THEMES['substack']
|
||||
properties = substack_theme['properties']
|
||||
|
||||
# Should use serif font for body text (Spectral)
|
||||
assert 'Spectral' in properties['font_family']
|
||||
|
||||
# Should use sans-serif for headings (Lora)
|
||||
assert 'Lora' in properties['heading_font_family']
|
||||
|
||||
# Should have appropriate max width for readability
|
||||
max_width = properties['max_width']
|
||||
# Convert to int if it has px suffix
|
||||
if max_width.endswith('px'):
|
||||
width_value = int(max_width[:-2])
|
||||
else:
|
||||
width_value = int(max_width)
|
||||
assert 600 <= width_value <= 750 # Good range for long-form reading
|
||||
|
||||
# Should have warm cream background
|
||||
assert properties['body_background'] == '#FAF9F1'
|
||||
|
||||
def test_substack_theme_legacy_compatibility(self):
|
||||
"""Test that substack theme works with legacy TEMPLATE_STYLES - Issue #166."""
|
||||
from markitect.plugins.builtin.markdown_commands import TEMPLATE_STYLES
|
||||
|
||||
# Should be available in legacy template styles for backward compatibility
|
||||
assert 'substack' in TEMPLATE_STYLES
|
||||
substack_legacy = TEMPLATE_STYLES['substack']
|
||||
|
||||
# Should have required legacy properties
|
||||
assert 'body_color' in substack_legacy
|
||||
assert 'font_family' in substack_legacy
|
||||
assert 'max_width' in substack_legacy
|
||||
|
||||
def test_substack_theme_cli_integration(self):
|
||||
"""Test Substack theme through CLI md-render command - Issue #166."""
|
||||
input_file = Path(self.temp_dir) / "substack_test.md"
|
||||
input_file.write_text(self.markdown_content)
|
||||
|
||||
output_file = Path(self.temp_dir) / "substack_test.html"
|
||||
|
||||
from markitect.cli import cli
|
||||
from click.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli, [
|
||||
'md-render',
|
||||
str(input_file),
|
||||
'--output', str(output_file),
|
||||
'--theme', 'substack'
|
||||
])
|
||||
|
||||
assert result.exit_code == 0, f"CLI command failed: {result.output}"
|
||||
assert output_file.exists()
|
||||
|
||||
html_content = output_file.read_text()
|
||||
|
||||
# Should contain Substack-specific styling
|
||||
assert 'Spectral' in html_content # Body font
|
||||
assert 'Lora' in html_content # Heading font
|
||||
assert '#FAF9F1' in html_content # Background color
|
||||
|
||||
def test_substack_theme_html_generation(self):
|
||||
"""Test HTML generation with Substack theme - Issue #166."""
|
||||
from markitect.plugins.builtin.markdown_commands import generate_html_with_embedded_markdown
|
||||
|
||||
test_markdown = "# Test Article\n\nThis is a test paragraph for the Substack theme."
|
||||
title = "Substack Theme Test"
|
||||
|
||||
html = generate_html_with_embedded_markdown(
|
||||
test_markdown, title, "substack", "", {}
|
||||
)
|
||||
|
||||
# Should generate valid HTML
|
||||
assert '<!DOCTYPE html>' in html
|
||||
assert title in html
|
||||
|
||||
# Should include Substack styling
|
||||
assert 'Spectral' in html # Body font should be present
|
||||
assert 'Lora' in html # Heading font should be present
|
||||
assert '#FAF9F1' in html # Background color should be present
|
||||
|
||||
def test_substack_theme_layered_combination(self):
|
||||
"""Test Substack theme combines properly with other layer themes - Issue #166."""
|
||||
from markitect.plugins.builtin.markdown_commands import parse_theme_string, combine_theme_properties
|
||||
|
||||
# Test combining substack document theme with light mode and standard UI
|
||||
theme_list = parse_theme_string("light,standard,substack")
|
||||
|
||||
assert 'light' in theme_list # Mode theme
|
||||
assert 'standard' in theme_list # UI theme
|
||||
assert 'substack' in theme_list # Document theme
|
||||
|
||||
# Should be able to apply layered themes
|
||||
combined_styles = combine_theme_properties(theme_list)
|
||||
|
||||
# Should include properties from all themes
|
||||
assert 'body_background' in combined_styles # From light theme
|
||||
assert 'editor_panel_bg' in combined_styles # From standard UI theme
|
||||
assert 'font_family' in combined_styles # From substack document theme
|
||||
Reference in New Issue
Block a user