This repository was archived by the owner on Mar 15, 2026. It is now read-only.
Add product and format card formats with secure rendering - #30
Merged
Conversation
Introduces four new standard formats for visualizing products and formats in user interfaces: - product_card_standard: Fixed 300x400px card for product display - product_card_detailed: Responsive detailed card with full product specs - format_card_standard: Fixed 300x400px card for format display - format_card_detailed: Responsive detailed card with full format specs These meta formats enable rich UI presentations of products and creative formats, supporting use cases like format catalogs and product showcases. The standard cards use fixed dimensions while detailed cards are responsive for maximum flexibility in different UI contexts. Testing: - Added comprehensive test suite in test_meta_formats.py - Updated format count in test_filter_formats.py - All 65 unit tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Adds a modular renderer architecture for creative previews with specialized renderers for different format types. Architecture: - BaseRenderer: Abstract base with common utilities - ImageRenderer: Handles image-based display formats (default) - ProductCardRenderer: Renders product_card_standard and product_card_detailed Product Card Features: - Standard card (300x400px fixed): Compact product display with image, name, markdown description, price, and brand colors - Detailed card (responsive): Full-featured card with image carousel, categories, formatted markdown content, and CTA button - Markdown conversion: Descriptions support GitHub-flavored markdown - Brand styling: Respects brand colors and fonts from promoted_offerings - Graceful fallbacks: Handles missing data with sensible defaults Dependencies: - Added markdown>=3.6 for markdown-to-HTML conversion - Added types-markdown>=3.6 for type checking Refactoring: - Moved sanitize_url to utils.py to avoid circular imports - Updated generate_preview_html to route to specialized renderers Testing: - 10 new tests covering standard/detailed cards, markdown, fallbacks - All 75 unit tests pass - Coverage increased to 34.26% 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Adds FormatCardRenderer to display creative format specifications as visual cards, completing the meta format rendering system. Format Card Features: - Standard card (300x400px fixed): Compact format display showing format name, type, dimensions, and markdown description - Detailed card (responsive): Full-featured card with complete format specification including assets table and supported macros - JSON parsing: Handles format data as JSON or plain text - Markdown support: Format descriptions rendered as rich HTML - Asset requirements table: Shows required/optional assets with types - Macro display: Lists supported macros with truncation for long lists Testing: - 10 new tests for format cards (standard, detailed, fallbacks) - Test script (scripts/test_card_rendering.py) to generate HTML previews - All 85 unit tests pass - Coverage increased to 38.46% Testing the Rendering: Run `uv run python scripts/test_card_rendering.py` to generate HTML previews in the output/ directory. Open these files in your browser to visually inspect the card rendering. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…erings
Changed product card formats to use individual text and image assets (product_image, product_name, product_description, pricing_model, pricing_amount, pricing_currency, delivery_type, primary_asset_type) instead of a single promoted_offerings asset.
This aligns with the ADCP principle of using existing asset types with specific asset_ids to define meaning, rather than creating new specialized asset types.
Updated ProductCardRenderer to:
- Extract individual assets from manifest
- Display pricing in format: "{model} ${amount} {currency}"
- Show colored badges for delivery_type (guaranteed/bidded) and primary_asset_type
- Render media product cards for ad inventory (not e-commerce products)
Updated tests to match new asset structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed output directory and temporary analysis files from version control. These are generated by test scripts and don't need to be tracked. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed two critical security vulnerabilities identified in code review: 1. Markdown XSS vulnerability - Now using bleach library to sanitize markdown-generated HTML, preventing injection of malicious scripts through description fields 2. Missing URL sanitization for images - Now using sanitize_url() utility for all image URLs to block dangerous protocols (javascript:, data:, etc.) Security measures added: - Added bleach dependency for HTML sanitization - Created _sanitize_markdown() method in both renderers - Defined allowed HTML tags, attributes, and protocols - Applied URL sanitization to product_image assets All 180 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Created <rendered-creative> web component that provides an elegant solution for embedding creative previews in grids and lists. Features: - Shadow DOM for complete CSS isolation (no style conflicts) - Lazy loading with Intersection Observer (only loads when visible) - Framework agnostic (React, Vue, Angular, vanilla JS) - Lightweight alternative to iframes Usage: <rendered-creative src="preview-url.com/..." width="300" height="400"></rendered-creative> Added: - src/creative_agent/static/rendered-creative.js - Web component implementation - examples/web-component-grid.html - Working demo with product/format cards - examples/README.md - Comprehensive usage documentation Updated renderers to support fragment parameter (preparation for future enhancement where we can return HTML fragments directly instead of full documents for web component consumption). All 180 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added instructions for testing the web component locally with a web server, since file:// URLs are blocked by CORS policies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Wrapped bleach.clean() return value with str() for explicit type safety to avoid mypy no-any-return errors. Kept type:ignore for imports as type stubs may not be available in all environments. Changes: - Wrapped bleach.clean() with str() cast - Kept type:ignore[import-untyped] for bleach/markdown imports - All 180 tests passing - Mypy clean (0 errors) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added mypy.ini configuration to disable warn_unused_ignores for the renderer modules since bleach/markdown type stubs may not be available in all environments (like pre-commit hooks). This allows the type:ignore comments to work correctly in environments without stubs while not causing errors in environments with stubs installed. Changes: - Added per-module mypy config for product_card_renderer and format_card_renderer - Re-added type:ignore[import-untyped] comments for bleach and markdown - All 180 tests passing - Mypy clean in all environments 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This is the proper fix for the mypy CI failures. The root cause was that type stubs (types-bleach, types-markdown) were installed in CI but not in the pre-commit environment, creating inconsistent behavior. Changes: - Added types-markdown and types-bleach to pre-commit mypy dependencies - Removed module-level warn_unused_ignores overrides from mypy.ini - Removed now-unnecessary type:ignore comments from imports - Environments now consistent: both have type stubs This resolves the technical debt from the previous workaround and ensures consistent type checking across all environments. All 180 tests passing, mypy clean. Thanks to code-reviewer agent for identifying the root cause! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changed terminology throughout codebase: - META_FORMATS → INFO_CARD_FORMATS - 'meta format' → 'info card format' in comments and docs - test_meta_formats.py → test_info_card_formats.py - Updated all test class names and docstrings The term 'info card formats' better describes their purpose (informational cards for displaying products and formats) without the Facebook association that 'meta' carries. All 180 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds four new meta formats for displaying product and format information:
product_card_standard(300x400) - Compact media product displayproduct_card_detailed(responsive) - Rich media product showcaseformat_card_standard(300x400) - Format specification displayformat_card_detailed(responsive) - Detailed format documentationProduct cards are designed for ADCP media/ad inventory products (e.g., "Homepage Leaderboard", "Video Pre-Roll"), not e-commerce products.
Key Architectural Decisions
Individual Assets Instead of Specialized Types
Product cards use 8 individual assets with existing asset types (image, text) rather than a single
promoted_offeringsasset. This aligns with ADCP principles:AssetType.imageandAssetType.textasset_id(e.g.,product_image,product_name,pricing_model)Product Card Assets
product_image(image) - Primary product/placement previewproduct_name(text) - Display nameproduct_description(text) - Markdown-formatted descriptionpricing_model(text) - e.g., "CPM", "flat_rate"pricing_amount(text) - e.g., "15.00"pricing_currency(text) - e.g., "USD"delivery_type(text) - "guaranteed" or "bidded"primary_asset_type(text) - "display", "video", "audio", "native"Security Fixes
Fixed two critical security vulnerabilities identified in code review:
sanitize_url()to all image URLs to block dangerous protocols (javascript:, data:, etc.)Security measures:
Rendering Features
Product Cards
Format Cards
Implementation
New Files:
src/creative_agent/renderers/base.py- Base renderer with shared utilitiessrc/creative_agent/renderers/product_card_renderer.py- Media product card renderersrc/creative_agent/renderers/format_card_renderer.py- Format specification renderersrc/creative_agent/utils.py- Shared utilities (sanitize_url)scripts/test_card_rendering.py- Local HTML preview generatorModified Files:
src/creative_agent/data/standard_formats.py- Added 4 meta formatssrc/creative_agent/storage.py- Routes to specialized rendererspyproject.toml- Added markdown and bleach dependenciesTests:
tests/unit/test_meta_formats.py(18 tests)tests/unit/test_product_card_renderer.py(9 tests)tests/unit/test_format_card_renderer.py(10 tests)Testing
Run test script to generate local HTML previews:
Opens
output/directory with rendered examples:product_card_standard.html- "Homepage Leaderboard" 300x400 cardproduct_card_detailed.html- "Video Pre-Roll Package" responsive cardformat_card_standard.html- Format specification cardformat_card_detailed.html- Detailed format documentationFuture Enhancements
When ADCP #180 merges with
markdownasset type:product_card_detailedandformat_card_detailedto useAssetType.markdownfor description fieldsAssetType.textwith markdown contentTest Coverage