From db8558fa17548888f2300177d91a8dc1d0416eb7 Mon Sep 17 00:00:00 2001 From: KeyInfo Bot Date: Tue, 21 Jul 2026 00:01:29 +0800 Subject: [PATCH] Sync third-party and MCP marketplace plugins Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed. --- config/external-sources.lock.json | 42 +- .../plugins/mcp-playwright/MCP_SOURCE.json | 2 +- .../next-skills/THIRD_PARTY_SOURCE.json | 4 +- .../next-cache-components-adoption/SKILL.md | 49 +- .../SKILL.md | 123 + .../oh-my-codex/.codex-plugin/plugin.json | 2 +- .../oh-my-codex/THIRD_PARTY_SOURCE.json | 4 +- .../oh-my-codex/hooks/codex-native-hook.mjs | 24 + .../oh-my-codex/skills/omx-setup/SKILL.md | 15 +- .../plugins/oh-my-codex/skills/ralph/SKILL.md | 8 +- .../oh-my-codex/skills/ralplan/SKILL.md | 8 +- .../plugins/oh-my-codex/skills/team/SKILL.md | 22 +- plugins/codex/plugins/ppt-master/README.md | 54 +- .../ppt-master/THIRD_PARTY_SOURCE.json | 4 +- .../ppt-master/skills/ppt-master/.env.example | 4 +- .../ppt-master/skills/ppt-master/SKILL.md | 939 +--- .../references/ai-image-comparison/README.md | 12 +- .../ppt-master/references/animations.md | 18 +- .../references/artifact-ownership.md | 39 +- .../ppt-master/references/canvas-formats.md | 12 +- .../ppt-master/references/executor-base.md | 500 +- .../ppt-master/references/executor-chart.md | 132 + .../ppt-master/references/executor-image.md | 32 + .../ppt-master/references/executor-notes.md | 54 + .../references/executor-structured.md | 176 + .../references/executor-web-image.md | 25 + .../ppt-master/references/image-base.md | 4 +- .../ppt-master/references/image-generator.md | 123 +- .../references/image-layout-patterns.md | 14 +- .../references/image-layout-spec.md | 6 +- .../references/image-palettes/_index.md | 143 +- .../references/image-renderings/_index.md | 16 +- .../references/image-renderings/chalkboard.md | 10 +- .../image-renderings/fantasy-animation.md | 14 +- .../references/image-renderings/ink-notes.md | 14 +- .../image-renderings/sketch-notes.md | 12 +- .../references/image-renderings/warm-scene.md | 14 +- .../ppt-master/references/image-searcher.md | 10 +- .../references/image-type-templates/_index.md | 4 +- .../ppt-master/references/modes/_index.md | 26 +- .../ppt-master/references/modes/briefing.md | 2 +- .../references/modes/instructional.md | 2 +- .../ppt-master/references/modes/narrative.md | 2 +- .../ppt-master/references/modes/pyramid.md | 2 +- .../ppt-master/references/modes/showcase.md | 2 +- .../references/native-data-interface.md | 368 ++ .../references/native-shape-authoring.md | 99 +- .../references/pptx-structure-interface.md | 195 + .../ppt-master/references/semantic-svg.md | 27 +- .../references/shared-standards-core.md | 642 +++ .../ppt-master/references/shared-standards.md | 1530 +----- .../ppt-master/references/strategist-image.md | 56 + .../references/strategist-template.md | 82 + .../ppt-master/references/strategist.md | 871 +--- .../ppt-master/references/svg-effects.md | 746 +++ .../references/svg-image-embedding.md | 19 +- .../references/template-designer.md | 318 +- .../ppt-master/references/visual-review.md | 4 +- .../references/visual-styles/_index.md | 8 +- .../skills/ppt-master/scripts/README.md | 132 +- .../ppt-master/scripts/analyze_images.py | 8 +- .../ppt-master/scripts/animation_config.py | 11 +- .../ppt-master/scripts/batch_validate.py | 2 +- .../ppt-master/scripts/beautify_identity.py | 6 +- .../ppt-master/scripts/beautify_inventory.py | 4 +- .../skills/ppt-master/scripts/chart_recall.py | 299 ++ .../scripts/compact_svg_coordinates.py | 345 ++ .../skills/ppt-master/scripts/config.py | 13 +- .../ppt-master/scripts/confirm_ui/server.py | 629 ++- .../scripts/confirm_ui/static/app.js | 1517 ++++-- .../scripts/confirm_ui/static/catalogs.json | 40 +- .../scripts/confirm_ui/static/style.css | 128 +- .../ppt-master/scripts/docs/chart-recall.md | 45 + .../ppt-master/scripts/docs/confirm_ui.md | 233 +- .../ppt-master/scripts/docs/conversion.md | 238 +- .../skills/ppt-master/scripts/docs/image.md | 5 +- .../scripts/docs/pptx-animations.md | 2 +- .../scripts/docs/pptx-transitions.md | 2 +- .../skills/ppt-master/scripts/docs/project.md | 94 +- .../ppt-master/scripts/docs/prompt_audit.md | 39 + .../ppt-master/scripts/docs/svg-pipeline.md | 308 +- .../ppt-master/scripts/docs/update_spec.md | 4 +- .../skills/ppt-master/scripts/error_helper.py | 14 +- .../ppt-master/scripts/extract_svg_assets.py | 328 +- .../scripts/extract_svg_pictures.py | 1006 ++++ .../skills/ppt-master/scripts/finalize_svg.py | 2 +- .../scripts/generate_examples_index.py | 26 +- .../scripts/mirror_template_materialize.py | 2934 +++++++++++ .../ppt-master/scripts/native_enhance_pptx.py | 4 +- .../scripts/native_enhance_pptx_core.py | 969 ++++ .../scripts/native_narration_pptx.py | 951 +--- .../ppt-master/scripts/native_payloads.py | 655 +++ .../ppt-master/scripts/notes_to_audio.py | 2 +- .../skills/ppt-master/scripts/page_context.py | 911 ++++ .../skills/ppt-master/scripts/pptx_effects.py | 143 + .../skills/ppt-master/scripts/pptx_intake.py | 2 +- .../scripts/pptx_template_import.py | 51 +- .../skills/ppt-master/scripts/pptx_to_svg.py | 51 +- .../scripts/pptx_to_svg/chart_to_svg.py | 6 +- .../scripts/pptx_to_svg/chartex_to_svg.py | 5 +- .../scripts/pptx_to_svg/color_resolver.py | 693 ++- .../scripts/pptx_to_svg/converter.py | 189 +- .../scripts/pptx_to_svg/effect_to_svg.py | 409 +- .../scripts/pptx_to_svg/emu_units.py | 23 +- .../scripts/pptx_to_svg/fill_to_svg.py | 476 +- .../scripts/pptx_to_svg/import_diagnostics.py | 37 + .../scripts/pptx_to_svg/ln_to_svg.py | 270 +- .../scripts/pptx_to_svg/ooxml_loader.py | 69 + .../scripts/pptx_to_svg/pic_to_svg.py | 208 +- .../scripts/pptx_to_svg/preset_authoring.py | 316 +- .../scripts/pptx_to_svg/preset_svg_markup.py | 38 +- .../scripts/pptx_to_svg/shape_walker.py | 132 +- .../scripts/pptx_to_svg/slide_to_svg.py | 671 ++- .../scripts/pptx_to_svg/tbl_to_svg.py | 21 +- .../scripts/pptx_to_svg/txbody_to_svg.py | 194 +- .../ppt-master/scripts/preset_shape_svg.py | 12 +- .../ppt-master/scripts/project_manager.py | 134 +- .../ppt-master/scripts/project_specs.py | 1112 +++++ .../ppt-master/scripts/project_utils.py | 208 +- .../skills/ppt-master/scripts/prompt_audit.py | 1764 +++++++ .../scripts/prompt_audit_manifest.json | 1114 +++++ .../ppt-master/scripts/register_template.py | 94 +- .../ppt-master/scripts/resource_paths.py | 7 + .../ppt-master/scripts/svg_authoring_view.py | 606 ++- .../ppt-master/scripts/svg_editor/server.py | 18 +- .../scripts/svg_editor/static/app.js | 58 +- .../scripts/svg_finalize/__init__.py | 4 +- .../scripts/svg_finalize/embed_icons.py | 84 +- .../scripts/svg_finalize/flatten_tspan.py | 80 +- .../ppt-master/scripts/svg_quality_checker.py | 4303 +++++++++++++---- .../scripts/svg_to_pptx/__init__.py | 26 +- .../scripts/svg_to_pptx/animation_config.py | 52 +- .../scripts/svg_to_pptx/canvas_contract.py | 226 + .../scripts/svg_to_pptx/drawingml/context.py | 11 +- .../svg_to_pptx/drawingml/converter.py | 784 ++- .../scripts/svg_to_pptx/drawingml/elements.py | 1616 +++++-- .../scripts/svg_to_pptx/drawingml/paths.py | 465 +- .../scripts/svg_to_pptx/drawingml/styles.py | 266 +- .../svg_to_pptx/drawingml/text_properties.py | 763 +++ .../svg_to_pptx/drawingml/theme_colors.py | 9 +- .../svg_to_pptx/drawingml/theme_fonts.py | 17 +- .../scripts/svg_to_pptx/drawingml/utils.py | 2417 ++++++++- .../svg_to_pptx/native_objects/__init__.py | 45 +- .../svg_to_pptx/native_objects/chart_style.py | 20 +- .../native_objects/fallback_hash.py | 23 +- .../native_objects/marker_attributes.py | 182 + .../native_objects/marker_common.py | 275 +- .../native_objects/marker_status.py | 176 +- .../svg_to_pptx/native_objects/table.py | 6 +- .../svg_to_pptx/pptx_package/builder.py | 91 +- .../scripts/svg_to_pptx/pptx_package/cli.py | 605 ++- .../svg_to_pptx/pptx_package/dimensions.py | 112 +- .../pptx_package/template_structure.py | 790 ++- .../pptx_package/template_validation.py | 37 +- .../scripts/svg_to_pptx/semantic_markers.py | 2 +- .../scripts/svg_to_pptx/use_expander.py | 11 + .../scripts/template_import/manifest.py | 175 +- .../template_import/native_structure.py | 4 + .../scripts/template_preview_pptx.py | 182 +- .../ppt-master/scripts/template_text_slots.py | 175 + .../ppt-master/scripts/visual_review.py | 2 +- .../skills/ppt-master/templates/README.md | 97 +- .../ppt-master/templates/brands/README.md | 30 +- .../templates/charts/CHART_STYLE_GUIDE.md | 816 ++-- .../ppt-master/templates/charts/README.md | 53 +- .../templates/charts/agenda_list.svg | 81 +- .../templates/charts/arc_anchored_list.svg | 56 +- .../templates/charts/area_chart.svg | 173 +- .../templates/charts/bar_of_pie_chart.svg | 67 +- .../templates/charts/basic_table.svg | 84 +- .../templates/charts/box_plot_chart.svg | 145 +- .../templates/charts/bubble_chart.svg | 185 +- .../templates/charts/bullet_chart.svg | 179 +- .../templates/charts/butterfly_chart.svg | 161 +- .../templates/charts/charts_index.json | 4 +- .../charts/chevron_chain_with_tail.svg | 160 +- .../templates/charts/chevron_process.svg | 194 +- .../templates/charts/circular_stages.svg | 154 +- .../templates/charts/client_server_flow.svg | 111 +- .../templates/charts/column_chart.svg | 112 +- .../templates/charts/comparison_columns.svg | 124 +- .../templates/charts/comparison_table.svg | 128 +- .../templates/charts/concentric_circles.svg | 123 +- .../templates/charts/consulting_table.svg | 107 +- .../templates/charts/donut_chart.svg | 102 +- .../templates/charts/dual_axis_line_chart.svg | 169 +- .../templates/charts/dumbbell_chart.svg | 66 +- .../templates/charts/feature_matrix_table.svg | 63 +- .../charts/financial_statement_table.svg | 147 +- .../templates/charts/fishbone_diagram.svg | 133 +- .../templates/charts/funnel_chart.svg | 127 +- .../templates/charts/gantt_chart.svg | 184 +- .../templates/charts/gauge_chart.svg | 131 +- .../templates/charts/grouped_bar_chart.svg | 147 +- .../templates/charts/harvey_balls_table.svg | 52 +- .../templates/charts/heatmap_chart.svg | 126 +- .../templates/charts/histogram_chart.svg | 81 +- .../templates/charts/horizontal_bar_chart.svg | 123 +- .../templates/charts/hub_inward_arrows.svg | 136 +- .../ppt-master/templates/charts/hub_spoke.svg | 261 +- .../ppt-master/templates/charts/icon_grid.svg | 283 +- .../templates/charts/isometric_stairs.svg | 86 +- .../templates/charts/journey_map.svg | 69 +- .../ppt-master/templates/charts/kpi_cards.svg | 165 +- .../templates/charts/labeled_card.svg | 105 +- .../templates/charts/layered_architecture.svg | 206 +- .../templates/charts/line_chart.svg | 252 +- .../templates/charts/matrix_2x2.svg | 149 +- .../ppt-master/templates/charts/mind_map.svg | 189 +- .../templates/charts/module_composition.svg | 148 +- .../templates/charts/numbered_steps.svg | 166 +- .../templates/charts/pareto_chart.svg | 125 +- .../ppt-master/templates/charts/pie_chart.svg | 84 +- .../templates/charts/pie_of_pie_chart.svg | 63 +- .../templates/charts/pipeline_with_stages.svg | 214 +- .../templates/charts/process_flow.svg | 136 +- .../templates/charts/progress_bar_chart.svg | 157 +- .../charts/project_schedule_table.svg | 94 +- .../templates/charts/pros_cons_chart.svg | 127 +- .../templates/charts/pyramid_chart.svg | 109 +- .../templates/charts/pyramid_isometric.svg | 50 +- .../charts/quadrant_bubble_scatter.svg | 56 +- .../charts/quadrant_text_bullets.svg | 121 +- .../templates/charts/radar_chart.svg | 115 +- .../templates/charts/roadmap_vertical.svg | 151 +- .../templates/charts/sankey_chart.svg | 138 +- .../templates/charts/scatter_chart.svg | 164 +- .../templates/charts/segmented_wheel.svg | 90 +- .../templates/charts/snake_flow.svg | 151 +- .../templates/charts/stacked_area_chart.svg | 213 +- .../templates/charts/stacked_bar_chart.svg | 154 +- .../templates/charts/stock_chart.svg | 71 +- .../templates/charts/sunburst_chart.svg | 80 +- .../templates/charts/team_roster.svg | 75 +- .../ppt-master/templates/charts/timeline.svg | 408 +- .../templates/charts/top_down_tree.svg | 151 +- .../templates/charts/treemap_chart.svg | 152 +- .../templates/charts/venn_diagram.svg | 94 +- .../templates/charts/vertical_list.svg | 98 +- .../templates/charts/vertical_pillars.svg | 118 +- .../templates/charts/waterfall_chart.svg | 146 +- .../templates/charts/word_cloud.svg | 61 +- .../ppt-master/templates/decks/README.md | 163 +- .../templates/decks/decks_index.json | 4 +- .../decks/中国电信/templates/01_cover.svg | 32 +- .../decks/中国电信/templates/02_toc.svg | 38 +- .../{02_chapter.svg => 03_chapter.svg} | 26 +- .../{03_content.svg => 04_content.svg} | 30 +- .../{04_ending.svg => 05_ending.svg} | 30 +- .../decks/中国电信/templates/design_spec.md | 33 +- .../decks/中汽研/templates/01_cover.svg | 26 +- .../decks/中汽研/templates/02_toc.svg | 48 +- .../{02_chapter.svg => 03_chapter.svg} | 16 +- .../{03_content.svg => 04_content.svg} | 24 +- .../{04_ending.svg => 05_ending.svg} | 26 +- .../decks/中汽研/templates/design_spec.md | 35 +- .../templates/design_spec_reference.md | 387 +- .../ppt-master/templates/icons/README.md | 8 + .../ppt-master/templates/layouts/README.md | 175 +- .../templates/layouts/layouts_index.json | 2 +- .../templates/01_title_slide.svg | 10 +- .../templates/02_title_content.svg | 10 +- .../templates/03_section_header.svg | 10 +- .../templates/04_two_content.svg | 16 +- .../templates/05_comparison.svg | 28 +- .../templates/06_title_only.svg | 4 +- .../templates/08_content_caption.svg | 16 +- .../templates/09_picture_caption.svg | 16 +- .../templates/10_hero_statement.svg | 10 +- .../templates/11_editorial_split.svg | 16 +- .../templates/12_three_card.svg | 22 +- .../templates/13_kpi_dashboard.svg | 34 +- .../templates/14_process_timeline.svg | 34 +- .../templates/15_data_story.svg | 22 +- .../templates/16_title_picture.svg | 10 +- .../templates/17_two_picture_caption.svg | 20 +- .../templates/18_screenshot_focus.svg | 16 +- .../templates/19_chart_insight.svg | 27 +- .../templates/20_table_summary.svg | 27 +- .../templates/design_spec.md | 35 +- .../templates/scaffolds/design_spec.md | 123 + .../templates/scaffolds/spec_lock.md | 44 + .../templates/schemas/design_spec.schema.json | 93 + .../templates/schemas/spec_lock.schema.json | 305 ++ .../templates/spec_lock_reference.md | 248 +- .../ppt-master/workflows/create-brand.md | 231 - .../ppt-master/workflows/create-template.md | 576 ++- .../workflows/create-template/create-brand.md | 161 + .../workflows/create-template/create-deck.md | 130 + .../create-template/create-layout.md | 123 + .../ppt-master/workflows/failure-recovery.md | 69 - .../ppt-master/workflows/generate-pptx.md | 477 ++ .../workflows/governance/failure-recovery.md | 83 + .../skills/ppt-master/workflows/index.md | 65 +- .../workflows/native-enhance-pptx.md | 51 +- .../workflows/native-narration-pptx.md | 35 - .../workflows/{ => profiles}/beautify-pptx.md | 47 +- .../ppt-master/workflows/refine-spec.md | 60 - .../workflows/restore-pptx-structure.md | 208 - .../ppt-master/workflows/resume-execute.md | 68 - .../skills/ppt-master/workflows/routing.md | 162 +- .../stages/apply-template-workspace.md | 117 + .../{ => stages}/customize-animations.md | 38 +- .../workflows/{ => stages}/generate-audio.md | 31 +- .../workflows/{ => stages}/live-preview.md | 14 +- .../workflows/stages/refine-spec.md | 60 + .../workflows/stages/resume-execute.md | 73 + .../workflows/stages/topic-research.md | 149 + .../workflows/{ => stages}/verify-charts.md | 21 +- .../workflows/{ => stages}/visual-review.md | 34 +- .../workflows/template-fill-pptx.md | 24 +- .../ppt-master/workflows/topic-research.md | 119 - .../plugins/shadcn/THIRD_PARTY_SOURCE.json | 4 +- .../taste-skill/THIRD_PARTY_SOURCE.json | 4 +- .../ui-ux-pro-max/.codex-plugin/plugin.json | 2 +- plugins/codex/plugins/ui-ux-pro-max/README.md | 22 +- .../ui-ux-pro-max/THIRD_PARTY_SOURCE.json | 4 +- .../skills/ui-ux-pro-max/SKILL.md | 651 +-- .../ui-ux-pro-max/data/stacks/threejs.csv | 108 +- .../ui-ux-pro-max/references/pro-rules.md | 109 + .../references/quick-reference.md | 240 + .../skills/ui-ux-pro-max/scripts/core.py | 272 +- .../ui-ux-pro-max/scripts/design_system.py | 83 +- .../skills/ui-ux-pro-max/scripts/search.py | 113 +- .../ui-ux-pro-max/scripts/tests/test_core.py | 134 + .../ui-ux-pro-max/scripts/validate_data.py | 114 + 326 files changed, 43415 insertions(+), 17908 deletions(-) create mode 100644 plugins/codex/plugins/next-skills/skills/next-partial-prefetching-adoption/SKILL.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-image.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/strategist-template.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/references/svg-effects.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/chart_recall.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/compact_svg_coordinates.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/chart-recall.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/docs/prompt_audit.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/extract_svg_pictures.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/mirror_template_materialize.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/native_enhance_pptx_core.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/native_payloads.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/page_context.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/pptx_effects.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/pptx_to_svg/import_diagnostics.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/project_specs.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/prompt_audit_manifest.json create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/canvas_contract.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/drawingml/text_properties.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/svg_to_pptx/native_objects/marker_attributes.py create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/scripts/template_text_slots.py rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/{02_chapter.svg => 03_chapter.svg} (80%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/{03_content.svg => 04_content.svg} (75%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中国电信/templates/{04_ending.svg => 05_ending.svg} (73%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/{02_chapter.svg => 03_chapter.svg} (83%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/{03_content.svg => 04_content.svg} (75%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/templates/decks/中汽研/templates/{04_ending.svg => 05_ending.svg} (83%) create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/scaffolds/design_spec.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/scaffolds/spec_lock.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/design_spec.schema.json create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/templates/schemas/spec_lock.schema.json delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-brand.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-brand.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-deck.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/create-template/create-layout.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/failure-recovery.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/generate-pptx.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/governance/failure-recovery.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/native-narration-pptx.md rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => profiles}/beautify-pptx.md (74%) delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/refine-spec.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/restore-pptx-structure.md delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/resume-execute.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/apply-template-workspace.md rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => stages}/customize-animations.md (84%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => stages}/generate-audio.md (74%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => stages}/live-preview.md (95%) create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/refine-spec.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/resume-execute.md create mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/stages/topic-research.md rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => stages}/verify-charts.md (94%) rename plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/{ => stages}/visual-review.md (83%) delete mode 100644 plugins/codex/plugins/ppt-master/skills/ppt-master/workflows/topic-research.md create mode 100644 plugins/codex/plugins/ui-ux-pro-max/skills/ui-ux-pro-max/references/pro-rules.md create mode 100644 plugins/codex/plugins/ui-ux-pro-max/skills/ui-ux-pro-max/references/quick-reference.md create mode 100644 plugins/codex/plugins/ui-ux-pro-max/skills/ui-ux-pro-max/scripts/tests/test_core.py create mode 100644 plugins/codex/plugins/ui-ux-pro-max/skills/ui-ux-pro-max/scripts/validate_data.py diff --git a/config/external-sources.lock.json b/config/external-sources.lock.json index 84f9d6bc..896dcc3d 100644 --- a/config/external-sources.lock.json +++ b/config/external-sources.lock.json @@ -9,14 +9,23 @@ "commit": "d884ae04edebef577e82ff7c4e143debd0bbec99", "syncedAt": "2026-07-03T16:00:00Z" }, + { + "id": "superpowers-zh", + "pluginName": "superpowers-zh", + "repo": "https://github.com/AreChen/superpowers-zh.git", + "ref": "main", + "adapter": "codex-plugin", + "commit": "c51f23adcd482fd908aa60928f2ece34d12f7768", + "syncedAt": "2026-07-14T02:27:30Z" + }, { "id": "oh-my-codex", "pluginName": "oh-my-codex", "repo": "https://github.com/Yeachan-Heo/oh-my-codex.git", "ref": "main", "adapter": "codex-plugin", - "commit": "fce27bfd6c17c7665a6f1505b6b8384cc2c8edd5", - "syncedAt": "2026-07-12T16:00:00Z" + "commit": "435d4a9cc982ffaf83fabbfbb8711ae6c178ffca", + "syncedAt": "2026-07-19T16:00:01Z" }, { "id": "ui-ux-pro-max", @@ -24,8 +33,8 @@ "repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git", "ref": "main", "adapter": "claude-skill", - "commit": "0468898265b1552e19f96e9da448e971b6d325fd", - "syncedAt": "2026-07-13T16:00:00Z" + "commit": "b484e8338c25b9cea3a25981a992d2817188971a", + "syncedAt": "2026-07-20T16:00:00Z" }, { "id": "caveman", @@ -42,8 +51,8 @@ "repo": "https://github.com/Leonxlnx/taste-skill.git", "ref": "main", "adapter": "skill-collection", - "commit": "b17742737e796305d829b3ad39eda3add0d79060", - "syncedAt": "2026-07-07T02:43:19Z" + "commit": "7c397f22d3af6f2b3f1925eb147d8e8801086151", + "syncedAt": "2026-07-18T16:00:01Z" }, { "id": "shadcn", @@ -51,8 +60,8 @@ "repo": "https://github.com/shadcn-ui/ui.git", "ref": "main", "adapter": "claude-skill", - "commit": "bb8ba0daceb717eefc3a6ecb3457f28ca770d138", - "syncedAt": "2026-07-13T16:00:00Z" + "commit": "20442886c5cfb440441c35030462fbdf64838655", + "syncedAt": "2026-07-20T16:00:00Z" }, { "id": "frontend-slides", @@ -87,8 +96,8 @@ "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", "adapter": "claude-skill", - "commit": "465e3b4149b852d33ddd1cb94ac059401fe4e823", - "syncedAt": "2026-07-13T16:00:00Z" + "commit": "b05ac551468098ed7b4c1c21d9d0d413b4230c79", + "syncedAt": "2026-07-20T16:00:00Z" }, { "id": "next-skills", @@ -96,17 +105,8 @@ "repo": "https://github.com/vercel/next.js.git", "ref": "canary", "adapter": "skill-collection", - "commit": "41b823880d688b3e9f9aae3323b08ddd457240c2", - "syncedAt": "2026-07-13T16:00:00Z" - }, - { - "id": "superpowers-zh", - "pluginName": "superpowers-zh", - "repo": "https://github.com/AreChen/superpowers-zh.git", - "ref": "main", - "adapter": "codex-plugin", - "commit": "c51f23adcd482fd908aa60928f2ece34d12f7768", - "syncedAt": "2026-07-14T02:27:30Z" + "commit": "d3e41fb496aeddeb448ba454bd663c36ea8183a5", + "syncedAt": "2026-07-20T16:00:00Z" } ] } diff --git a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json index c92f2d69..6c82ba08 100644 --- a/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json +++ b/plugins/codex/plugins/mcp-playwright/MCP_SOURCE.json @@ -3,5 +3,5 @@ "name": "playwright浏览器自动化操作", "version": "20260605", "keySource": "none", - "syncedAt": "2026-07-13T16:01:28Z" + "syncedAt": "2026-07-20T16:01:28Z" } diff --git a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json index a193cbc0..dff42096 100644 --- a/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/next-skills/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "next-skills", "repo": "https://github.com/vercel/next.js.git", "ref": "canary", - "commit": "41b823880d688b3e9f9aae3323b08ddd457240c2", + "commit": "d3e41fb496aeddeb448ba454bd663c36ea8183a5", "adapter": "skill-collection", "sourcePath": "skills", - "syncedAt": "2026-07-13T16:00:00Z" + "syncedAt": "2026-07-20T16:00:00Z" } diff --git a/plugins/codex/plugins/next-skills/skills/next-cache-components-adoption/SKILL.md b/plugins/codex/plugins/next-skills/skills/next-cache-components-adoption/SKILL.md index d57a86ce..0c2e5fee 100644 --- a/plugins/codex/plugins/next-skills/skills/next-cache-components-adoption/SKILL.md +++ b/plugins/codex/plugins/next-skills/skills/next-cache-components-adoption/SKILL.md @@ -23,28 +23,30 @@ Enable Cache Components on an app and walk it to a passing build. This skill seq - **No passing baseline before the flag.** If the app already uses `"use cache"`, the pre-flag build errors with `please enable the feature flag cacheComponents`. Enabling the flag is the first thing you do (in Incremental, before the codemod; in Direct, before fixing routes) — not a thing to do _after_ getting a passing build. Note this in your starting summary so it doesn't read as a regression. -- **Offline docs.** Offline copies of guide links live under `node_modules/next/dist/docs/`, with the directory layout numbered for ordering (e.g. `node_modules/next/dist/docs/01-app/02-guides/migrating-to-cache-components.md`). The trailing filename matches the slug. If you can't predict the numbered prefix, `find node_modules/next/dist/docs -name '.md'` resolves it. The `/docs/messages/*` error pages are not bundled. If offline docs are missing entirely, run `npx @next/codemod@latest agents-md` to write a version-matched index into `AGENTS.md` / `CLAUDE.md`. +- **Offline docs.** Guide links have offline copies under `node_modules/next/dist/docs/` (bundled since Next.js 16.2), with the directory layout numbered for ordering (e.g. `node_modules/next/dist/docs/01-app/02-guides/migrating-to-cache-components.md`). If you can't predict the numbered prefix, `find node_modules/next/dist/docs -name '.md'` resolves it. The `/docs/messages/*` error pages are not bundled. + +- **Older versions without bundled docs.** Suggest `npx @next/codemod@latest agents-md` to the user before starting: it downloads a version-matched copy to `.next-docs/` and writes an index into `AGENTS.md` / `CLAUDE.md`. It touches files in their repo, so ask first and run it only if they want it. ## the shape of the work There's one loop: walk the route tree top-down, one feature at a time, adopting each route against `next dev` + a browser. The build is a final check for each feature, not the working surface. -The choice in step 1 is whether to silence the validation errors first or fix them as you go. Either way the loop is the same: +The choice in step 1 is whether to opt every route out of validation first or fix routes as you go. Either way the loop is the same: -- **With a quiet pre-step (Incremental).** Run the codemod to opt every page and layout out of validation. Once you've also fixed what the codemod can't (sync-IO calls, leftover `revalidate`/`dynamic`/`fetchCache` exports), the build passes; you ship that as its own PR and then start the loop — removing one opt-out at a time and adopting that route. Picks the work apart into small reviewable PRs. +- **With a quiet pre-step (Incremental).** Run the codemod to opt every page and layout out of validation. Once you've also fixed what the codemod can't (sync-IO calls, leftover `revalidate`/`dynamic`/`fetchCache` exports), the build passes; you ship that as its own PR and then start the loop — removing one opt-out at a time and adopting that route. This splits the work into small, reviewable PRs. - **Without (Direct).** Enable `cacheComponents` and start the loop on whatever the build flags first. Same loop, but every fix sits on one branch until adoption is complete. In both, the per-route success bar is the same: **dev loop reports no errors AND `next build` passes**. Check in with the user after every feature. Expect to spend most of the time in the loop, not in the pre-step. ## background -`cacheComponents: true` requires every route to be prerenderable. A route that reads request-time data outside `` is "blocking" and fails the build. `export const instant = false` marks a route as allowed to block, which clears it in both dev and build; on a layout it covers the whole subtree beneath it. Reads wrapped in a [`"use cache"`](https://nextjs.org/docs/app/api-reference/directives/use-cache) function count as cache boundaries, not blocking reads. +`cacheComponents: true` requires every route to be prerenderable. A route that reads request-time data outside `` is "blocking" and fails the build. `export const instant = false` marks a route as allowed to block, which clears it in both dev and build; on a layout it covers the whole subtree during the build, but client navigations still validate each descendant segment on its own. Reads wrapped in a [`"use cache"`](https://nextjs.org/docs/app/api-reference/directives/use-cache) function count as cache boundaries, not blocking reads. -Three classes of blocker bite agents in this order: +Three classes of blocker come up, usually in this order: 1. **Request-time reads** (`cookies()`, `headers()`, `await params`, `await searchParams`). All four block when awaited at the top of a page or layout. `params` and `searchParams` often get missed because they're not framed as "request data" the way cookies and headers are. The fix is to push the read into a ``-wrapped child — and for `params`/`searchParams`, forward the promise into the child and await it there; don't `await` at the page top. -2. **Sync-IO at module/render time** (`new Date()`, `Date.now()`, `Math.random()`, `crypto.randomUUID()`). These fail the build even with `instant = false` — the opt-out doesn't suppress them. If they're in a shared layout, they block every route under it. The codemod can't fix them; you have to translate each one (cache it with `"use cache"` if it's stable, or wrap it in `await connection()` + `` if it's per-request) before the build can pass. Grep the whole repo for these calls before running anything else. -3. **`"use cache"` files that read request data.** A file with a top-level `"use cache"` directive can't export `instant`; combining the two errors with `Only async functions are allowed to be exported in a "use cache" file.` and means the directive was wrong for that route. Remove it before running the codemod. +2. **Sync-IO at module/render time** (`new Date()`, `Date.now()`, `Math.random()`, `crypto.randomUUID()`). These fail the build even with `instant = false` — the opt-out doesn't suppress them. If they're in a shared layout, they block every route under it. The codemod can't fix them; you have to translate each one by hand before the build can pass (see the [incremental pre-step](#incremental)). Grep the whole repo for these calls before running anything else. +3. **`"use cache"` files that read request data.** A file with a top-level `"use cache"` directive can't export `instant`; combining the two errors with `Only async functions are allowed to be exported in a "use cache" file.`, which means the directive was wrong for that route. Remove it before running the codemod. ## working surfaces @@ -52,8 +54,8 @@ Three classes of blocker bite agents in this order: Prefer `next dev` over `next build` while you work. -- **`next dev`** — the working surface. Visit a route; its blocking errors surface in the dev overlay with full stack traces and fix cards linking the per-error docs. Work one route at a time — errors don't accumulate in one place. The route itself still returns HTTP 200, so read the overlay (or `.next-dev.log`), not status codes. A cleared overlay is one half of route-clean — the other half is browser verification (see [step 2](#step-2-the-inner-loop-remove-opt-outs-one-feature-at-a-time)) and a passing build for that route. -- **`next build`** — detection only. The build is `next dev`'s authoritative check, not its replacement. Use it as the last gate on each feature in the loop (a passing build is part of the per-route success bar) and as the final verification across the whole app. In Incremental, the build also confirms the pre-step (codemod opted every route out, no shared layout still has a sync-IO blocker) before you ship that PR. Don't reach for the build instead of the dev loop while you're working a route — a clean compile error doesn't tell you what ended up in the static shell vs streamed. By default the build stops at the first blocking route, so it's also poor for sizing the work. Two flags help when iterating: `--debug-build-paths` builds only the routes you name (comma-separated glob patterns of file paths relative to the project root, e.g. `--debug-build-paths="app/admin/**/page.tsx"` — not URL paths; `--debug-build-paths="app/(marketing)/about/page.tsx"` — not `/about`; `--debug-build-paths="app/admin"` matches nothing and silently builds zero routes), and `--debug-prerender` disables the early exit so the build continues past the first prerender failure, reports every blocking route, and prints a fuller stack trace that names the originating file and line. +- **`next dev`** — the working surface. Visit a route; its blocking errors surface in the dev overlay with full stack traces and fix cards linking the per-error docs. Work one route at a time — errors don't accumulate in one place. The route itself still returns HTTP 200, so read the overlay (or `.next-dev.log`), not status codes. A cleared overlay is one half of calling a route clean — the other half is browser verification (see [step 2](#step-2-the-inner-loop-remove-opt-outs-one-feature-at-a-time)) and a passing build for that route. +- **`next build`** — detection only. The build is `next dev`'s authoritative check, not its replacement. Use it as the last gate on each feature in the loop (a passing build is part of the per-route success bar) and as the final verification across the whole app. In Incremental, the build also confirms the pre-step (codemod opted every route out, no shared layout still has a sync-IO blocker) before you ship that PR. Don't reach for the build instead of the dev loop while you're working a route — a passing compile doesn't tell you what ended up in the static shell and what streamed. By default the build stops at the first blocking route, so it's also poor for sizing the work. Two flags help when iterating: `--debug-build-paths` builds only the routes you name (comma-separated glob patterns of file paths relative to the project root, e.g. `--debug-build-paths="app/admin/**/page.tsx"` — not URL paths; `--debug-build-paths="app/(marketing)/about/page.tsx"` — not `/about`; `--debug-build-paths="app/admin"` matches nothing and silently builds zero routes), and `--debug-prerender` disables the early exit so the build continues past the first prerender failure, reports every blocking route, and prints a fuller stack trace that names the originating file and line. Every blocking error has a docs page — open it. Both the dev overlay and the build terminal print a `https://nextjs.org/docs/messages/` link with each error. That page is the canonical recipe for the fix; the inline message is a summary. Fetch the link for every distinct error you encounter, even if you think you know the pattern — the recipes evolve, and the same error class can have different correct fixes depending on what the route reads. Don't improvise from the inline message alone. (`/docs/messages/*` pages aren't bundled offline; if you have no network, fall back to the per-API guides under `node_modules/next/dist/docs/` and note the limitation when you report back.) @@ -75,7 +77,7 @@ In preference order: **Requires Turbopack.** If `package.json`'s `dev` script passes `--webpack`, flag it to the user and ask whether there's a reason to stay on webpack. If not, switch to Turbopack (the Next.js 16.3+ default). If they want to keep webpack, skip this install and use the [build-only loop](#the-loop-build-only-fallback) instead. - You don't need permission to install `next-dev-loop` itself. It's a tool, like installing a dev dependency. If a user is on the line, briefly tell them you're installing it for verification. In a non-interactive run (CI, dashboard, sandbox), install it without asking — "can't prompt the user" is not a reason to skip. The only legitimate skip is a real technical blocker: no network, no npm, read-only filesystem, a stated no-new-deps policy, or a webpack-only dev script. If you skip, name the specific blocker in your final report. + You don't need permission to install `next-dev-loop` itself. It's a tool, like installing a dev dependency. If a user is present, briefly tell them you're installing it for verification. In a non-interactive run (CI, dashboard, sandbox), install it without asking — "can't prompt the user" is not a reason to skip. The only legitimate skip is a real technical blocker: no network, no npm, read-only filesystem, a stated no-new-deps policy, or a webpack-only dev script. If you skip, name the specific blocker in your final report. 2. **A browser you can drive yourself.** Playwright, `agent-browser` directly, any browser-automation tool. Use only when `next-dev-loop` is genuinely blocked. You'll miss the framework-side checks (`/_next/mcp`), so DOM assertions alone don't catch every regression — be more cautious about what you call "verified." @@ -85,7 +87,7 @@ In preference order: ## step 1: choose a strategy -Ask the user. Phrase it as a PR-shape question, not a sizing call. Never use the internal labels (Incremental, Direct, milestone A) when talking to the user — those are your own scaffolding. Ask in terms of PRs and features, e.g.: _"Do you want me to first open a PR that turns on Cache Components and opts every route out of validation, then handle the actual route adoptions feature-by-feature in follow-up PRs? Or do everything on one branch?"_ Even on a tiny app, the incremental path still has value (review-sized PR, revertible, the `// TODO: Cache Components adoption` markers double as your work queue for next session). Don't pick on their behalf. +Ask the user, in terms of the PRs they want, not the size of the job. Never use the internal labels (Incremental, Direct) when talking to the user — those are your own scaffolding. Ask in terms of PRs and features, e.g.: _"Do you want me to first open a PR that turns on Cache Components and opts every route out of validation, then handle the actual route adoptions feature-by-feature in follow-up PRs? Or do everything on one branch?"_ Even on a tiny app, the incremental path still has value (review-sized PR, revertible, the `// TODO: Cache Components adoption` markers double as your work queue for next session). Don't pick on their behalf. If there's no user to ask, default to **Incremental** and document the choice. @@ -96,7 +98,13 @@ If there's no user to ask, default to **Incremental** and document the choice. Before invoking the codemod, fix the two classes of blocker it can't. -1. **Sync-IO at module/render time.** Grep the whole repo for `new Date()`, `Date.now()`, `Math.random()`, and `crypto.randomUUID()` (not only `app/**/layout.{js,jsx,ts,tsx}` — the read might live in any component imported by a layout). Translate each match using the recipe from its `blocking-prerender-*` error card. +1. **Sync-IO at module/render time.** Grep the whole repo for `new Date()`, `Date.now()`, `Math.random()`, and `crypto.randomUUID()` (not only `app/**/layout.{js,jsx,ts,tsx}` — the read might live in any component imported by a layout). Unblock each match with the `await connection()` + `` fix from its `blocking-prerender-*` error card: it defers the value to request time, exactly as it behaved before the migration, so it needs no product decision. Add this exact comment on the line above the `await connection()`: + + ```tsx + // TODO: Cache Components adoption. Added to unblock the build: remove this connection() to re-trigger the error and review the fix options. + ``` + + It shares the `TODO: Cache Components adoption` prefix with the comments the codemod writes, so the check-in grep finds both. Removing the `await connection()` makes the error fire again with its fix cards — the same motion as removing an opt-out in the loop. 2. **Incompatible segment configs.** Grep for `^export const (revalidate|dynamic|fetchCache)` across `app/` and translate per the `requires` note above. The codemod does not touch them; leaving them in place fails the build after the codemod. @@ -130,7 +138,7 @@ Synthetic routes like `/_not-found` have no user file — when they block, fix t ### end of the pre-step: check in -Incremental only. Stop here before starting step 2 — the pre-step is the shippable PR. Talk to the user in their language; don't say "milestone A" or "Incremental"; talk about adoption, PRs, and what the app does now. Tell them: +Incremental only. Stop here before starting step 2 — the pre-step is the shippable PR. Talk to the user in their language; don't say "Incremental" or other internal labels; talk about adoption, PRs, and what the app does now. Tell them: - What you did: turned on Cache Components, ran the codemod that opts every page and layout out of the new validation (or did it by hand), fixed any blockers the codemod can't (list them), confirmed the build passes. - What changed: every page and layout in `app/` now exports `instant = false` with a `// TODO: Cache Components adoption` comment, except client components and any that already had an `instant` export. @@ -178,7 +186,7 @@ Per route: ### loop notes - The [three blocker classes from background](#background) often get missed when fixing in place. Caching a downstream fetch (`getThing(id)`) doesn't clear an `await params` at the top of the page body — push the param promise into the ``-wrapped child. -- Ambiguous calls are user check-ins, not agent judgment. When you're not sure which fix fits, the blocking code looks security-sensitive, or the user might want to keep the route blocking on purpose — read [references/per-page-decisions.md](./references/per-page-decisions.md) before editing. +- Ambiguous calls are user check-ins, not agent judgment. When you're not sure which fix fits, the blocking code looks security-sensitive, or the user might want to keep the route blocking on purpose — read [references/per-page-decisions.md](./references/per-page-decisions.md) before editing. Show the route while you ask: the `next-dev-loop` session runs the browser headed, so drive to the page and leave it on screen so the user is looking at the thing they're deciding about, with a screenshot as the fallback when a headed browser isn't possible. "Should this stay blocking?" is much easier to answer while looking at the page than at a file path. - Don't narrate the refactor with comments. The only comment the codemod (or you) should leave is `// TODO: Cache Components adoption` on opt-outs, and the user's existing comments. Don't annotate every `` boundary or `"use cache"` call with what it does — the code says that. Drop a comment only when the _why_ isn't clear from the code (e.g. a deliberate Block with a reason). Keep a todo list of the feature's routes. When every route in the feature is clean, move to step 3. @@ -188,14 +196,15 @@ Keep a todo list of the feature's routes. When every route in the feature is cle Checklist before checking in with the user: - `next build` completes without blocking-route errors. -- No bare `// TODO: Cache Components adoption` opt-outs in the feature (`grep` to confirm). Any `instant = false` left behind is a deliberate, documented Block — comment rewritten to a reason (see [references/per-page-decisions.md](./references/per-page-decisions.md) → "when to leave a Block in place"). +- No bare TODOs in the feature: `grep -rn "TODO: Cache Components adoption"` finds both the codemod's opt-out comments and the sync-IO unblocks from the pre-step. Any `instant = false` left behind is a deliberate, documented Block — comment rewritten to a reason (see [references/per-page-decisions.md](./references/per-page-decisions.md) → "when to leave a Block in place"). Any `await connection()` left behind has been reviewed and kept on purpose, not left over from the pre-step. - Each route visited in the browser: confirm the static shell renders first and every `` fallback resolves to its real content. Capture both states if you can — the fallback (mid-stream) and the final paint — so you have a streaming-experience demo to show the user. Throttle the network in the browser if streaming is too fast to observe. -Then check in with the user. Same rule as the pre-step: speak their language. Don't say "milestone B" or "feature‑by‑feature loop"; talk about the feature you adopted and what the user will see. +Then check in with the user. Same rule as the pre-step: speak their language. Don't say "feature-by-feature loop" or other internal labels; talk about the feature you adopted and what the user will see. - What you did: which routes you touched, and the user-visible result per route (e.g. "the post page now streams the article body behind a skeleton while the layout stays static"). - What changed: opt-outs removed, fallbacks added, caching boundaries introduced. -- Show, don't tell. If the browser is running, drive the route live for the user so they see the static shell → fallback → final content sequence in real time. If you can't drive a live browser, attach the before/after screenshots you captured instead. +- Show, don't tell. The `next-dev-loop` session runs the browser headed, so drive the route live for the user so they see the static shell → fallback → final content sequence in real time. If you can't drive a live browser, attach the before/after screenshots you captured instead. +- Give them the click-through: a short table of the feature's routes — the URL to open and what to look for (what renders instantly, which fallbacks appear, what streams in) — so they can verify each one themselves. - The question: "Want to open this feature as a PR and move on to the next, or stop here?" Wait for the answer. **Trivial features can skip the check-in.** If adopting a feature only meant removing its `// TODO: Cache Components adoption` opt-out (no `` added, no `'use cache'` introduced, no render order change), the user sees nothing different. Move on to the next feature without stopping; mention it in passing the next time you do check in. @@ -204,7 +213,7 @@ When the loop has run on every feature — every remaining `instant = false` sit ### route table glyphs -`ƒ` → `◐` is the adoption landing. `◐ (Partial Prerender)` means a static shell prerenders and the request-time content streams in — the goal state for any route that reads `cookies()`, `headers()`, `params`, or `searchParams`. Some routes legitimately stay `ƒ` when they do request-time work through a documented escape hatch (e.g. a layout that uses `await connection()`); the page is no longer _opted out_, it's genuinely dynamic. Don't rip the escape hatch back out chasing a `◐`. The inverse holds: `instant = false` does not force a route to be `ƒ`. The glyph reflects what the route does at prerender time, not which validation knobs it exports. +`ƒ` → `◐` is where adoption usually lands. `◐ (Partial Prerender)` means a static shell prerenders and the request-time content streams in — the goal state for any route that reads `cookies()`, `headers()`, `params`, or `searchParams`. Some routes legitimately stay `ƒ` when they do request-time work through a documented escape hatch (e.g. a layout that uses `await connection()`); the page is no longer _opted out_, it's genuinely dynamic. Don't remove the escape hatch only to chase a `◐`. The inverse holds: `instant = false` does not force a route to be `ƒ`. The glyph reflects what the route does at prerender time, not which validation knobs it exports. `◐` tells you a shell exists, not what's in it. A `` boundary placed too high (e.g. wrapping the entire page body, or `` around the article content) pushes the visible content out of the static shell into the streamed payload; the build still reports `◐` because _some_ shell prerendered (often only `` with framework markup). The route table can't tell you what's in the shell; a browser can. If the shell is empty and everything streams, pull the `` boundary down closer to the actual dynamic read. @@ -213,7 +222,7 @@ When the loop has run on every feature — every remaining `instant = false` sit The work below is optional and lives in the docs — link the user to them and let them decide which to take on next. Don't walk these through inside this skill. - [Instant navigation](https://nextjs.org/docs/app/guides/instant-navigation) — dev-only validation warnings the overlay raises on client navigation. Same shape as the blocking-prerender errors you cleared in step 2; the guide covers the per-warning details. Recommend it next if the user wants navigations to actually be instant (a passing build doesn't guarantee that — a `` above the shared layout caught the page-load case but doesn't cover client navigation). -- [Adopting Partial Prefetching](https://nextjs.org/docs/app/guides/adopting-partial-prefetching) — walks an audit of `` calls driven by the dev overlay's `link-prefetch-partial` warning, then flips the `partialPrefetching` config. Walk the audit first, with the flag off — flipping it before the audit makes every route count as adopted, so the warnings never fire and the per-link signal is lost. The biggest payoff of Cache Components: `` prefetches only the static App Shell by default. Recommended after instant navigation, since its fixes feed directly into how much of each route the shell can prefetch. +- [`next-partial-prefetching-adoption`](https://github.com/vercel/next.js/tree/canary/skills/next-partial-prefetching-adoption) — the follow-up skill that adopts Partial Prefetching: it audits `` calls (driven by the dev overlay's `link-prefetch-partial` warning) with the flag off first, then flips the `partialPrefetching` config. It sequences this the same way this skill sequences Cache Components, but the insights are dev-only, so it's a browser click-through, not a build loop. Recommended after instant navigation, since those fixes feed directly into how much of each route the shell can prefetch. Concepts live in the [Adopting Partial Prefetching guide](https://nextjs.org/docs/app/guides/adopting-partial-prefetching). - [Prefetching](https://nextjs.org/docs/app/guides/prefetching) and [Runtime prefetching](https://nextjs.org/docs/app/guides/runtime-prefetching) — broader prefetching reference. Runtime prefetching extends the static shell with per-session content; reach for it when a route's shell is too thin to be useful and Partial Prefetching alone doesn't cover the gap. -- [Locking the result in with e2e tests](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) — the `@next/playwright` [`instant()`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/instant#testing-instant-navigation) helper asserts on the UI that's available immediately on navigation, so regressions surface in CI. Recommend it once a route is instant: `next-dev-loop` confirms it _now_; an `instant()` test keeps it that way. +- [Prevent regressions with e2e tests](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) — the `@next/playwright` [`instant()`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/instant#testing-instant-navigation) helper asserts on the UI that's available immediately on navigation, so regressions surface in CI. Recommend it once a route is instant: `next-dev-loop` confirms it _now_; an `instant()` test keeps it that way. - [`next-cache-components-optimizer`](https://github.com/vercel/next.js/tree/canary/skills/next-cache-components-optimizer) — a separate skill that grows each route's static shell so more of the page prerenders and less streams in. Pure optimization, not part of adoption. diff --git a/plugins/codex/plugins/next-skills/skills/next-partial-prefetching-adoption/SKILL.md b/plugins/codex/plugins/next-skills/skills/next-partial-prefetching-adoption/SKILL.md new file mode 100644 index 00000000..65b48a34 --- /dev/null +++ b/plugins/codex/plugins/next-skills/skills/next-partial-prefetching-adoption/SKILL.md @@ -0,0 +1,123 @@ +--- +name: next-partial-prefetching-adoption +description: > + Turn on Partial Prefetching in a Next.js app and work through the + insights it surfaces. Use when the user wants to enable or adopt + Partial Prefetching, flip the `partialPrefetching` flag, opt routes + in with `export const prefetch = 'partial'`, audit + `` calls, or resolve the + link-prefetch-partial and instant-shell-url-data insights. +--- + +# next-partial-prefetching-adoption + +Enable Partial Prefetching and walk the app until every link reuses a shared App Shell. This skill sequences the work; per-insight recipes live in the dev overlay fix cards and their docs pages. The [Adopting Partial Prefetching guide](https://nextjs.org/docs/app/guides/adopting-partial-prefetching) is the canonical reference for the concepts this skill applies. + +The one thing that shapes everything below: **these insights surface only in `next dev`, in the dev overlay's Insights tab.** Nothing fails the build. There is no build-only fallback loop for this skill — the work is a sweep of the running app in the browser. If you can't drive a browser, stop and tell the user what you can't verify, or commit the milestone you've reached and hand off. + +Talk to the user in terms of what they'll see — PRs, features, and how the app behaves after — never the insight slugs or step labels. Before you start, tell them briefly what Partial Prefetching changes: a `` loads a shared App Shell, and `prefetch={true}` no longer prefetches everything the old full prefetch did. + +## requires + +- **Cache Components already adopted.** `partialPrefetching` only works with `cacheComponents: true`, and the sweep below assumes the app has no blocking-route errors left: a route whose static shell fails validation surfaces the blocking-prerender error _instead of_ the prefetch insight, so unfinished adoption hides exactly the signal this skill works from. Run [`next-cache-components-adoption`](https://github.com/vercel/next.js/tree/canary/skills/next-cache-components-adoption) to completion first — this skill is its follow-up. + +- **Next.js 16.3 or later.** `partialPrefetching`, the `prefetch` route segment config, and the prefetch insights all land there. + +- **A browser you can drive.** Install [`next-dev-loop`](https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop) before starting (`npx skills add https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop`). Link prefetches fire when a link renders and enters the viewport, and shell validation fires on navigation — neither is reachable from `curl` or the build. If the app is webpack-pinned, drive a browser directly (`agent-browser`, Playwright) — you lose the framework cross-checks, not the insights; they're still in the overlay and the dev log. + +### notes + +- **Offline docs.** Guide links have offline copies under `node_modules/next/dist/docs/` (bundled since Next.js 16.2), with the directory layout numbered for ordering (e.g. `node_modules/next/dist/docs/01-app/02-guides/adopting-partial-prefetching.md`). If you can't predict the numbered prefix, `find node_modules/next/dist/docs -name '.md'` resolves it. The `/docs/messages/*` error pages are not bundled. + +- **Older versions without bundled docs.** Suggest `npx @next/codemod@latest agents-md` to the user before starting: it downloads a version-matched copy to `.next-docs/` and writes an index into `AGENTS.md` / `CLAUDE.md`. It touches files in their repo, so ask first and run it only if they want it. + +## background + +Adopting Partial Prefetching means every route still delivers what its links prefetched before, now split between the App Shell (static and cached content) and the per-link runtime data behind `prefetch = 'allow-runtime'`. The [guide](https://nextjs.org/docs/app/guides/adopting-partial-prefetching) is the canonical reference for what a prefetch contains and how to decide each case; this skill sequences that work against a running app. + +## working surfaces + +- **The dev server terminal — your primary record.** Each validated route's insights are logged as `Error: Route "...": Next.js encountered ...` lines with the `https://nextjs.org/docs/messages/` link. Tail the dev log during the sweep; it's the greppable record of what fired where, and it works the same on Turbopack and webpack. +- **The dev overlay Insights tab.** Insights are the amber, non-blocking tab. It appears only once an insight has fired, so a route that surfaces nothing shows no tab at all — that's the clean state, not a missing feature. Don't hunt for the tab on a quiet route; confirm clean from the dev log above, which is the reliable signal. The precondition is no blocking-prerender errors — those replace the insight on their route (see requires). An unrelated Issue (a hydration error, a console error) doesn't block the sweep; don't stall on it. When the tab is present, the overlay pill shows the count and each insight has fix cards linking its docs page. The overlay renders inside a shadow root (`nextjs-portal`), so accessibility-tree snapshots don't see it — evaluate into `shadowRoot` when you need to read or click it programmatically. +- **`next-dev-loop`** to drive navigations and read the overlay. Prefer it over hand-rolled browser automation for the same reasons as in the Cache Components skill (webpack apps: see requires). + +Every insight has a docs page — open it. Fetch the linked page for every distinct insight you encounter; the inline message is a summary, the page is the recipe. + +## step 1: audit `` (before enabling) + +If `partialPrefetching: true` is already set in `next.config.ts`, the app is adopted — skip to [step 3](#step-3-sweep-for-url-data-insights-after-enabling). Otherwise work the audit with the global flag **off**, adopting each destination with `export const prefetch = 'partial'` — enabling the flag first would mark every route adopted and silence the [`link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial) insight this audit runs on. Ask the user how to ship it, in the language of PRs: + +- **One branch** — the whole audit in one change, with the flag enabled and the codemod run at the end (step 2). +- **Route by route** — each adopted destination ships as its own PR. The insight still fires for the destinations you haven't reached, a live worklist, and step 2 comes after the last one. + +The work is identical either way — only the commit boundaries differ. Default by app size: one branch for a handful of links, route by route when the audit is big enough that reviewers need smaller diffs. Note the choice in your report. + +Enumerate the links across the whole source tree, not only `app/` — they often live in `src/components` or shared UI packages: `grep -rnE '\bprefetch\b' --include='*.tsx' --include='*.jsx' .`, then keep the `prefetch={true}` and bare `prefetch` prop matches (a bare prop is `true`) and drop `prefetch={false}` and other values. If nothing matches, check for a custom link wrapper before calling the audit empty — grep for `from 'next/link'`, and if a wrapper sets `prefetch={true}` internally or forwards it under another prop name, audit its call sites the same way. If there's still nothing, say so in your report and move on to [step 2](#step-2-enable-the-flag). + +Then, for each one: + +1. **Click it** in `next dev`. The insight fires at navigation time, not when the link prefetches, so a link sitting in the viewport won't trip it — you have to navigate through it. +2. **Adopt the destination.** Add `export const prefetch = 'partial'`. That clears the insight for every link pointing at it. If the route reads URL data (`params`, `searchParams`), it's a runtime-prefetch candidate for step 5 — keep `prefetch={true}` on its links and mark the route: + + ```tsx + // TODO(runtime-prefetch): assess with the user (prefetch = 'allow-runtime') + export const prefetch = 'partial' + ``` + + Use that exact prefix so step 5 can grep them back. Don't cache or decide anything for these routes now. + +3. **Preserve what that prefetch delivered.** The guide's [audit table](https://nextjs.org/docs/app/guides/adopting-partial-prefetching#auditing-link-prefetchtrue-calls) is the canonical decision — fetch it and apply the matching row rather than re-deriving it. Caching uncached content is the judgment call in that table: trace where the data comes from and what freshness and revalidation it needs, per the [`use cache`](https://nextjs.org/docs/app/api-reference/directives/use-cache) docs, and ask the user when the answer isn't clear-cut. The URL-data routes you marked in the previous item wait for step 5. + +## step 2: enable the flag + +Once every audited destination has `prefetch = 'partial'`, finish in two moves. + +1. **Enable the flag globally.** Set `partialPrefetching: true` in `next.config.ts` (alongside `cacheComponents: true`). Every route is adopted now, so every link is good. +2. **Strip the redundant `prefetch = 'partial'` exports.** Run the first-party `remove-partial-prefetch` codemod rather than a text find-and-replace. It removes only `export const prefetch = 'partial'` and leaves any other value (a deliberate `prefetch = 'allow-runtime'`) in place, along with your `TODO(runtime-prefetch)` markers, which wait for step 5. + + Use the `@canary` channel, not `@latest`. The `remove-partial-prefetch` transform isn't in the stable `@next/codemod` release yet, and `@next/codemod@latest` errors with `Invalid transform choice`. + + ```bash + npx @next/codemod@canary remove-partial-prefetch ./app + ``` + + The codemod refuses to run on a dirty working tree. Commit or stash unrelated work first, or pass `--force` to let its edits land alongside your WIP. If the codemod isn't available (older `@next/codemod`, sandboxed environment, offline run), reproduce it by hand by removing `export const prefetch = 'partial'` from every `app/**/{page,layout}.{js,jsx,ts,tsx}` — leave any other `prefetch` value in place, and leave the `TODO(runtime-prefetch)` markers where they are. Don't hand-edit when the codemod can run. + +## step 3: sweep for URL-data insights (after enabling) + +This is a dev-only second pass. The shell check runs only with the flag on, fires at navigation time, and never blocks the build, so it can happen any time after step 2. The work is one loop — build a route queue from a concrete source (the last `next build` route table, or the `app/` tree), keep it as a todo list, and load every route in `next dev` until the queue is empty. + +Watch the Insights tab and the dev log for `Next.js encountered … data` lines. The signal this step adds is [`URL data`](https://nextjs.org/docs/messages/instant-shell-url-data): a `params` or `searchParams` read outside `` ties the shared shell to one URL. It can surface even inside an existing `` when the boundary sits above the read. Open its docs page and follow the fix there. + +If Cache Components adoption left gaps, loading routes can also re-surface the blocking-prerender errors from that step — [`runtime data`](https://nextjs.org/docs/messages/blocking-prerender-runtime) (`cookies()`/`headers()`) or [`uncached data`](https://nextjs.org/docs/messages/blocking-prerender-dynamic) (an uncached `fetch`/DB call). Those aren't Partial Prefetching insights; treat them as unfinished Cache Components work and fix them the same way. + +These fixes rarely involve the user — each insight names the offending read and its docs page has the fix, so apply it and keep sweeping. Collect the rare exceptions for one batched question at the end: a page that is entirely one URL-dependent region (wrapping it all leaves an empty shell), or a route that should arguably stay opted out. Don't narrate the refactor with comments — the `` boundaries speak for themselves. + +## step 4: verify + +Checklist before checking in with the user: + +- **An empty sweep is the expected outcome when Cache Components adoption finished cleanly** — the prereq already forced every `params`/`searchParams`/`cookies()` read behind `` (surfaced there as `blocking-prerender-*` errors), so a quiet log is success, not a missing signal. Any entry still in the Insights tab is a deliberate, documented decision. To confirm the signal can still fire, check `partialPrefetching` is on, the version is 16.3 or later, and the dev server was restarted after the config change — or move one URL read back outside ``, watch validation fire, then revert. Expect the probe to surface the Cache Components `blocking-prerender-runtime` error rather than the URL-data insight (the upstream check catches the read first) — either one proves the pipeline is alive. +- The App Shells are real: for each route you changed, confirm the first paint after a navigation shows the intended shared content, not an empty shell or a stuck fallback. A `` around the whole page body passes validation with an empty shell, which defeats the point. +- `next build` still passes. + +Then check in with the user. Speak their language — no insight slugs or step labels. + +- What you did: which links you audited, which destinations you adopted, and what each link now prefetches. +- What changed: dropped props, `use cache` boundaries added, and which routes carry a `TODO(runtime-prefetch)` marker for later. +- Demo against a production run. Prefetching is limited in development, so `next dev` won't show the result — run `next build` and `next start`, and hand the user that URL. +- Show, don't tell: drive one link live in the headed browser against the production server, so they see the shared App Shell paint instantly and the URL-specific region stream in. Attach before/after screenshots only when a live browser isn't possible. +- Give them the click-through: a table of each changed route — the link to click, and what to expect after the click (what paints instantly, what streams in) — so they can verify each result themselves. +- The question: "Want to commit this (or open the PR) before we look at which routes should also prefetch their URL-specific content?" Wait for the answer — adoption and runtime prefetching read best as their own changes. + +## step 5: runtime prefetching (optional) + +The audit marked the candidates instead of deciding them. Grep for `TODO(runtime-prefetch)` and walk the list with the user in one conversation. The question per route is whether they want the URL-dependent content prefetched ahead of the click, or streaming in after navigation is fine. A runtime prefetch costs a server invocation per prefetchable link — the guide's [per-link prefetching trade-offs](https://nextjs.org/docs/app/guides/runtime-prefetching#per-link-prefetching-trade-offs) section is the checklist. Don't make these calls alone. + +Where the answer is yes, follow the [runtime prefetching guide](https://nextjs.org/docs/app/guides/runtime-prefetching) — add `export const prefetch = 'allow-runtime'` to the route (the codemod in step 2 already stripped the `'partial'` export) and cache the content behind the read using the guide's patterns (`use cache` with the runtime value passed in, or `use cache: private` for per-user data). Where it's no, delete the marker and leave the route on the default. Either way no `TODO(runtime-prefetch)` marker survives this step. Confirm the opted-in routes against a production run (`next build` and `next start` — the runtime prefetch fires there, not in `next dev`), give the user the same click-through for them, and keep this as its own commit or PR. + +## further reading + +- [Instant navigation](https://nextjs.org/docs/app/guides/instant-navigation) — the broader validation model and loading-state tooling. +- [Prevent regressions with e2e tests](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) — the `@next/playwright` `instant()` helper locks in what a navigation shows immediately; recommend it once the sweep is clean, since nothing else guards these in CI. +- [`next-cache-components-optimizer`](https://github.com/vercel/next.js/tree/canary/skills/next-cache-components-optimizer) — grows each route's static shell so the App Shell carries more. diff --git a/plugins/codex/plugins/oh-my-codex/.codex-plugin/plugin.json b/plugins/codex/plugins/oh-my-codex/.codex-plugin/plugin.json index 772eb979..de1d428a 100644 --- a/plugins/codex/plugins/oh-my-codex/.codex-plugin/plugin.json +++ b/plugins/codex/plugins/oh-my-codex/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "oh-my-codex", - "version": "0.20.1", + "version": "0.20.3", "description": "oh-my-codex 是 Codex CLI 的多 Agent 编排、结构化工作流、插件级 hooks、MCP 和 HUD 扩展插件。", "author": { "name": "Yeachan Heo", diff --git a/plugins/codex/plugins/oh-my-codex/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/oh-my-codex/THIRD_PARTY_SOURCE.json index 2206e460..eb537796 100644 --- a/plugins/codex/plugins/oh-my-codex/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/oh-my-codex/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "oh-my-codex", "repo": "https://github.com/Yeachan-Heo/oh-my-codex.git", "ref": "main", - "commit": "fce27bfd6c17c7665a6f1505b6b8384cc2c8edd5", + "commit": "435d4a9cc982ffaf83fabbfbb8711ae6c178ffca", "adapter": "codex-plugin", "sourcePath": "plugins/oh-my-codex", - "syncedAt": "2026-07-12T16:00:00Z" + "syncedAt": "2026-07-19T16:00:01Z" } diff --git a/plugins/codex/plugins/oh-my-codex/hooks/codex-native-hook.mjs b/plugins/codex/plugins/oh-my-codex/hooks/codex-native-hook.mjs index 046deea2..16c025ad 100644 --- a/plugins/codex/plugins/oh-my-codex/hooks/codex-native-hook.mjs +++ b/plugins/codex/plugins/oh-my-codex/hooks/codex-native-hook.mjs @@ -241,6 +241,25 @@ function writeOversizedStopNoop() { process.exitCode = 0; } +function writeOversizedToolHookOutput(eventName) { + const systemMessage = 'OMX native hook rejected oversized stdin JSON before parsing; maxBytes=1048576.'; + const output = eventName === 'PreToolUse' + ? { + systemMessage, + hookSpecificOutput: { + hookEventName: 'PreToolUse', + permissionDecision: 'deny', + permissionDecisionReason: systemMessage, + }, + } + : { + continue: false, + stopReason: 'native_hook_stdin_oversized', + systemMessage, + }; + process.stdout.write(`${JSON.stringify(output)}\n`); + process.exitCode = 0; +} function writeCompactFallback() { process.exitCode = 0; } @@ -440,6 +459,11 @@ async function main() { writeOversizedStopNoop(); return; } + const eventName = extractTopLevelHookEventName(input.toString('utf8')); + if (eventName === 'PreToolUse' || eventName === 'PostToolUse') { + writeOversizedToolHookOutput(eventName); + return; + } console.error(`[oh-my-codex] ${message}`); process.exitCode = 1; return; diff --git a/plugins/codex/plugins/oh-my-codex/skills/omx-setup/SKILL.md b/plugins/codex/plugins/oh-my-codex/skills/omx-setup/SKILL.md index 476749d4..cd3e3b88 100644 --- a/plugins/codex/plugins/oh-my-codex/skills/omx-setup/SKILL.md +++ b/plugins/codex/plugins/oh-my-codex/skills/omx-setup/SKILL.md @@ -10,14 +10,14 @@ Use this skill when users want to install or refresh oh-my-codex for the **curre ## Command ```bash -omx setup [--force] [--merge-agents] [--dry-run] [--verbose] [--scope ] [--plugin|--legacy|--install-mode ] +omx setup [--force] [--merge-agents|--no-merge-agents|--clear-merge-agents-policy] [--dry-run] [--verbose] [--scope ] [--plugin|--legacy|--install-mode ] ``` If you only want lightweight `AGENTS.md` scaffolding for an existing repo or subtree, use `omx agents-init [path]` instead of full setup. Supported setup flags (current implementation): -- `--force`: overwrite/reinstall managed artifacts where applicable -- `--merge-agents`: when `AGENTS.md` already exists, preserve user-authored content and insert/refresh OMX-managed generated sections between explicit `` / `` markers +- `--force`: overwrite/reinstall managed artifacts where applicable; it is transient and is neither persisted nor replayed +- `--merge-agents`, `--no-merge-agents`, `--clear-merge-agents-policy`: exact bare policy selectors (equals/value spellings are rejected). Repeated identical selectors are idempotent; conflicting set/clear selectors fail before setup mutations. An explicit set overrides saved policy. `--merge-agents` selects the existing managed-section merge branch; `--no-merge-agents` only suppresses that branch; clear always removes the saved explicit policy and cannot combine with a set selector - `--dry-run`: print actions without mutating files - `--verbose`: print per-file/per-step details - `--scope`: choose install scope (`user`, `project`) @@ -41,7 +41,7 @@ Supported setup flags (current implementation): - else discovered installed plugin cache under `${CODEX_HOME:-~/.codex}/plugins/cache/**/.codex-plugin/plugin.json` with `name: oh-my-codex` makes `plugin` the default for both `user` and `project` scope, so project setup does not duplicate plugin-provided skills/hooks with legacy `.codex/skills` and `.codex/hooks.json` - else in `user` scope, interactive prompt on TTY (`legacy` by default, or `plugin` when a plugin cache is discovered) - else default `legacy` unless a plugin cache is discovered -3. Create directories and persist effective scope/install mode +3. Create required directories. Preferences are atomically persisted only after all setup work succeeds. 4. In legacy mode, install prompts/native agents/skills and merge full config.toml. In plugin mode, archive/remove legacy OMX-managed prompts/skills, refresh installable native agent TOMLs for `agent_type` routing, clean up stale generated non-installable native agents, and keep native Codex hooks installed. 5. Verify Team CLI API interop markers exist in built `dist/cli/team.js` 6. Generate AGENTS.md defaults only when selected/allowed (or legacy behavior outside plugin mode) @@ -55,6 +55,11 @@ Supported setup flags (current implementation): - Local project orchestration file is `./AGENTS.md` (project root). - If `AGENTS.md` exists and neither `--force` nor `--merge-agents` is used, interactive TTY runs ask whether to overwrite. Non-interactive runs preserve the file. - Use `--merge-agents` to keep existing project guidance while allowing setup to refresh OMX-managed AGENTS sections and the generated model capability table idempotently. +- A successful explicit set persists `mergeAgents: true` or `false` in the invoking working root's `./.omx/setup-scope.json`, even for `--scope user`; it is never a global user preference and cannot leak to another root. A valid matching policy is replayed by both immediate and deferred `omx update` refreshes. +- `--no-merge-agents` is contextual, not a preserve, replace, or safety mode: the current prompt, skip, managed-refresh, plugin-default, and force behavior still controls the non-merge path. Absence keeps existing behavior exactly. +- TTY review preserves a matching policy while unrelated settings change. Reset or a scope change removes the inherited policy unless the same setup run explicitly sets true or false. `--clear-merge-agents-policy` always removes the policy and cannot combine with a set selector. Malformed, unknown, nonboolean, scopeless, or wrong-scope policy data is treated as absent. +- Explicit policy intent is atomically committed only after all setup work succeeds. If active-session or plugin-symlink safeguards skip the current AGENTS write but setup otherwise succeeds, explicit true, false, or clear still persists as future update intent; the safeguards themselves are unchanged. +- Merge is not the default, and this policy does not adopt the rejected #2892 merge-by-default behavior. Older OMX binaries ignore this additive field safely but can erase it when rewriting their known setup preferences. - Scope targets: - `user`: user directories (`~/.codex`, `~/.codex/skills`, `~/.omx/agents`) - `project`: local directories (`./.codex`, `./.codex/skills`, `./.omx/agents`) @@ -73,7 +78,7 @@ Use this map when reconciling setup behavior or debugging a confusing install: | Surface | Owner | Notes | | --- | --- | --- | -| `./.omx/setup-scope.json` | `omx setup` | Persists setup scope and install mode when needed. TTY reruns summarize it and offer keep/review/reset. | +| `./.omx/setup-scope.json` | `omx setup` | Persists setup scope, install mode, and an optional explicit AGENTS merge policy per working root. TTY reruns summarize choices and offer keep/review/reset; only valid matching-scope boolean policy replays on update. | | `~/.codex/config.toml` / `./.codex/config.toml` | `omx setup` generated blocks + user edits | Setup refreshes OMX-managed blocks while preserving supported manual content; setup-owned runtime feature flags include `multi_agent`, `child_agents_md`, the Codex hook feature flag (`hooks` or legacy `codex_hooks`), and `goals`. | | `~/.codex/hooks.json` / `./.codex/hooks.json` | `omx setup` shared ownership | Setup owns OMX native hook wrappers and preserves user-owned hooks. | | prompts, skills, native agents | `omx setup` or Codex plugin delivery | Legacy mode installs local files; plugin mode relies on plugin discovery for bundled skills, archives/removes legacy OMX-managed prompt/skill copies, and refreshes setup-owned native agent TOMLs for `agent_type` routing while cleaning up stale generated/non-installable native agents. | diff --git a/plugins/codex/plugins/oh-my-codex/skills/ralph/SKILL.md b/plugins/codex/plugins/oh-my-codex/skills/ralph/SKILL.md index 7eab77ca..5f6a94e0 100644 --- a/plugins/codex/plugins/oh-my-codex/skills/ralph/SKILL.md +++ b/plugins/codex/plugins/oh-my-codex/skills/ralph/SKILL.md @@ -32,7 +32,9 @@ Complex tasks often fail silently: partial implementations get declared "done", - Fire independent agent calls simultaneously -- never wait sequentially for independent work - Use `run_in_background: true` for long operations (installs, builds, test suites) -- Always set `agent_type` when spawning native subagents; use `reasoning_effort` for per-dispatch intensity when needed +- Before substantive planning, reviewer delegation, HUD/runtime activation, or adapted role work, inspect the native task surface. Keyword routing state is not authority. When the surface exposes `agent_type`, use typed routing. When it reports `role_routing_unavailable`, run `omx ralplan preflight --json`; on `unsupported_documented_leader_proof`, stop before planner/reviewer work or adapted authority and use a Codex surface with documented root proof or a reviewed alternative workflow. Do not infer root authority from `session_id`, undocumented `thread_id`, session/pointer/transcript/cwd state, absent child data, or prompt labels. +- When the native surface exposes `agent_type` role routing, set `agent_type` to an installed OMX role and never omit it for OMX work; use `reasoning_effort` for per-dispatch intensity when needed. +- **OMX adapted role-pass protocol:** when native routing is `role_routing_unavailable`, do not fabricate `agent_type`. On documented Codex 0.144.5 the adapted path is unavailable: run `omx ralplan preflight --json`, stop on `unsupported_documented_leader_proof`, and do not use prompt labels, task-name carriers, pending intents, markers, or `omx ralplan role-intent write` as substitutes. - Preserve legacy Ralph tier intent through native reasoning effort: LOW -> `low`, STANDARD -> `medium`, THOROUGH -> `xhigh` - Deliver the full implementation: no scope reduction, no partial completion, no deleting tests to make them pass - Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step execution, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches. @@ -52,6 +54,7 @@ Complex tasks often fail silently: partial implementations get declared "done", - If an existing relevant snapshot is available, reuse it and record the path in Ralph state. - If request ambiguity is high, gather brownfield facts first. `omx explore` is deprecated; use normal repository inspection tools/subagents for simple read-only repository lookups and `omx sparkshell` only for explicit shell-native read-only evidence. Then run `$deep-interview --quick ` to close critical gaps. - Do not begin Ralph execution work (delegation, implementation, or verification loops) until snapshot grounding exists. If forced to proceed quickly, note explicit risk tradeoffs. + - When this is a Ralplan-originated handoff and native role routing is unavailable, complete `omx ralplan preflight --json` before intake. On `unsupported_documented_leader_proof`, record the reason in Execution Policy and stop; do not create the snapshot or begin the loop. 1. **Review progress**: Check TODO list and any prior iteration state 2. **Continue from where you left off**: Pick up incomplete tasks 3. **Delegate in parallel**: Route tasks to specialist native agents with explicit `agent_type` and appropriate `reasoning_effort` @@ -77,6 +80,7 @@ Complex tasks often fail silently: partial implementations get declared "done", - Standard changes: `task(agent_type="architect", reasoning_effort="medium", prompt="...")` - >20 files or security/architectural changes: `task(agent_type="architect", reasoning_effort="xhigh", prompt="...")` - Ralph floor: always run an explicit `architect` native subagent, even for small changes + - On `role_routing_unavailable`, do not invoke `omx ralplan role-intent write` or manufacture an Architect identity. On documented Codex 0.144.5, the adapted Architect path is unavailable; surface the leader-proof diagnostic/remediation from Execution Policy and stop. On a future or other surface, use an adapted route only after its documented positive root proof has been reviewed and implemented. 7.5 **Mandatory Deslop Pass**: - After Step 7 passes, run `oh-my-codex:ai-slop-cleaner` on **all files changed during the Ralph session**. - Scope the cleaner to **changed files only**; do not widen the pass beyond Ralph-owned edits. @@ -200,7 +204,7 @@ Why bad: These are independent tasks that should run in parallel, not sequential - [ ] Fresh test run output shows all tests pass - [ ] Fresh build output shows success - [ ] lsp_diagnostics shows 0 errors on affected files -- [ ] Architect verification passed through explicit `task(agent_type="architect", reasoning_effort="medium"...)` minimum +- [ ] Architect verification passed: on a routing-capable surface via explicit `task(agent_type="architect", reasoning_effort="medium"...)` minimum. On documented Codex 0.144.5 role-routing-unavailable surfaces, no adapted Architect pass is valid; Ralplan-originated work must have stopped with the leader-proof diagnostic. - [ ] Codex goal-mode completion audit passed, and `update_goal({status: "complete"})` was called when an active goal exists - [ ] ai-slop-cleaner pass completed on changed files (or --no-deslop specified) - [ ] Post-deslop regression tests pass diff --git a/plugins/codex/plugins/oh-my-codex/skills/ralplan/SKILL.md b/plugins/codex/plugins/oh-my-codex/skills/ralplan/SKILL.md index 7d67156d..61fc23c5 100644 --- a/plugins/codex/plugins/oh-my-codex/skills/ralplan/SKILL.md +++ b/plugins/codex/plugins/oh-my-codex/skills/ralplan/SKILL.md @@ -49,8 +49,12 @@ The consensus workflow: - If only one viable option remains, explicit invalidation rationale for alternatives - Deliberate mode only: pre-mortem (3 scenarios) + expanded test plan (unit/integration/e2e/observability) 2. **User feedback** *(--interactive only)*: If `--interactive` is set, use the structured question UI (`omx question` in attached tmux; native structured input outside tmux when available) to present the draft plan **plus the Principles / Drivers / Options summary** before review (Proceed to review / Request changes / Skip review). Otherwise, automatically proceed to review. -3. **Architect** reviews for architectural soundness and must provide the strongest steelman antithesis, at least one real tradeoff tension, and (when possible) synthesis — **await completion before step 4**. Launch this as a subsequent `Architect` subagent (`agent_type: "architect"`) and pass the full task statement, context snapshot, PRD/test-spec paths, and relevant prior findings; do not use a default subagent with only a short improvised reviewer prompt. In deliberate mode, Architect should explicitly flag principle violations. -4. **Critic** evaluates against quality criteria — run only after step 3 completes. Launch this as a subsequent `Critic` subagent (`agent_type: "critic"`) with the full task statement, context snapshot, PRD/test-spec paths, and the completed Architect review; do not ask the Architect subagent to perform the Critic gate and do not substitute a default subagent fantasy prompt for the packaged Critic role. Critic must enforce principle-option consistency, fair alternatives, risk mitigation clarity, testable acceptance criteria, and concrete verification steps. In deliberate mode, Critic must reject missing/weak pre-mortem or expanded test plan. +**Native role-routing preflight:** Before substantive planning, reviewer delegation, HUD/runtime activation, or adapted-role work, inspect the native task surface. Keyword routing may already have selected Ralplan, but it is not authority. When the surface exposes `agent_type`, use typed native routing and do not run the adapted preflight. When it reports `role_routing_unavailable`, run `omx ralplan preflight --json`; on `unsupported_documented_leader_proof`, stop before planner/reviewer work or adapted authority and use a Codex surface with documented root proof or a reviewed alternative workflow. Do not infer root identity from `session_id`, undocumented `thread_id`, session/pointer/transcript/cwd state, absence of child data, or a prompt label. + +**Native role-routing rule:** When the native surface exposes `agent_type` role routing, set `agent_type` to an installed OMX role and never omit it for OMX work. When it does not (`role_routing_unavailable`), do not fabricate `agent_type`. The formerly adapted `omx ralplan role-intent write` path is unavailable on documented Codex 0.144.5 because it lacks documented root proof; do not silently weaken routing with a prompt role label or inferred carrier. Use a Codex surface with documented root proof or a reviewed alternative workflow. A direct `omx ralplan role-intent write` attempt is denied with machine reason `unsupported_documented_leader_proof`. + +3. **Architect** reviews for architectural soundness and must provide the strongest steelman antithesis, at least one real tradeoff tension, and (when possible) synthesis — **await completion before step 4**. Launch this as a subsequent role-specific `Architect` subagent and pass the full task statement, context snapshot, PRD/test-spec paths, and relevant prior findings; do not substitute an unvalidated reviewer identity or a short improvised reviewer prompt. In deliberate mode, Architect should explicitly flag principle violations. +4. **Critic** evaluates against quality criteria — run only after step 3 completes. Launch this as a subsequent role-specific `Critic` subagent with the full task statement, context snapshot, PRD/test-spec paths, and the completed Architect review; do not ask the Architect subagent to perform the Critic gate and do not substitute an unvalidated reviewer identity or a short improvised reviewer prompt. Critic must enforce principle-option consistency, fair alternatives, risk mitigation clarity, testable acceptance criteria, and concrete verification steps. In deliberate mode, Critic must reject missing/weak pre-mortem or expanded test plan. 5. **Re-review loop** (max 5 iterations): Any non-`APPROVE` Critic verdict (`ITERATE` or `REJECT`) MUST run the same full closed loop: a. Collect Architect and Critic feedback b. Revise the plan with Planner diff --git a/plugins/codex/plugins/oh-my-codex/skills/team/SKILL.md b/plugins/codex/plugins/oh-my-codex/skills/team/SKILL.md index 40569a61..3980988e 100644 --- a/plugins/codex/plugins/oh-my-codex/skills/team/SKILL.md +++ b/plugins/codex/plugins/oh-my-codex/skills/team/SKILL.md @@ -203,17 +203,21 @@ Default-model rule: - Use `OMX_DEFAULT_SPARK_MODEL` for spark/low-complexity worker-default guidance. Thinking-level rule (critical): -- **No model-name heuristic mapping.** -- Team runtime must **not** infer `model_reasoning_effort` from model-name substrings (e.g., `spark`, `high-capability`, `mini`). -- When the leader assigns teammate roles/tasks, OMX allocates **per-worker reasoning effort dynamically** from the resolved worker role and `agentReasoning` overrides (`low`, `medium`, `high`, `xhigh`). -- Explicit launch args still win: if `OMX_TEAM_WORKER_LAUNCH_ARGS` already includes `-c model_reasoning_effort=...`, that explicit value overrides dynamic allocation for every worker. +- **No model-name heuristic mapping.** Team runtime must not infer `model_reasoning_effort` from model-name substrings (for example `spark`, `high-capability`, or `mini`). +- OMX-owned `agentReasoning` accepts exactly `low`, `medium`, `high`, `xhigh`, and `max`; configured values are case-normalized. +- Without explicit raw reasoning, Team selects the resolved role default or valid `agentReasoning` override for each worker. +- `max` is passed to Codex unchanged. Its support is capability-dependent on the selected Codex version, model, and provider; preserve authoritative downstream errors. +- `ultra` is unsupported in OMX-owned `agentReasoning` and is not an alias for configured `max`. Other invalid configured values retain the built-in role-default fallback. +- Explicit raw `-c model_reasoning_effort=...` is opaque and wins over configured and built-in role defaults, including `ultra` and future values. Preserve the selected raw token exactly. +- When both sources provide explicit raw reasoning, inherited Team reasoning wins over environment reasoning. Explicit raw reasoning always wins over the role default. +- Do not downgrade or retry `max` as `xhigh`; built-in role defaults remain unchanged. Normalization requirements: -- Parse both `--model ` and `--model=` -- Remove duplicate/conflicting model flags -- Emit exactly one final canonical flag: `--model ` -- Preserve unrelated args in worker launch config -- If explicit reasoning exists, preserve canonical `-c model_reasoning_effort=""`; otherwise inject the worker role's default or `agentReasoning`-overridden reasoning level +- Parse both `--model ` and `--model=`. +- Remove duplicate/conflicting model flags. +- Emit exactly one final canonical flag: `--model `. +- Preserve unrelated args in worker launch config. +- Preserve the selected explicit raw `-c model_reasoning_effort=...` token exactly; otherwise inject the worker role's default or `agentReasoning`-overridden reasoning level. ## Required Lifecycle (Operator Contract) diff --git a/plugins/codex/plugins/ppt-master/README.md b/plugins/codex/plugins/ppt-master/README.md index c58952f9..deb06b7b 100644 --- a/plugins/codex/plugins/ppt-master/README.md +++ b/plugins/codex/plugins/ppt-master/README.md @@ -1,4 +1,4 @@ -# PPT Master — AI generates natively editable PPTX from any document +# PPT Master — AI generates native PowerPoint from any document [![Version](https://img.shields.io/github/v/release/hugohe3/ppt-master?label=version&color=blue)](https://github.com/hugohe3/ppt-master/releases) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) @@ -46,7 +46,7 @@ Thanks to [Kimi](https://www.kimi.com/code/?aff=ppt-master) for sponsoring this -> **AI generates your deck — it doesn't fill in a template.** PPT Master is a workflow that runs inside AI IDEs (Claude Code, Cursor, VS Code + Copilot, etc.): hand the AI your PDF / DOCX / web pages, and it produces a real PowerPoint on your machine — every element editable in PowerPoint, your data stays local, no platform or model lock-in. How it works and where the limits are → [Product Positioning](#product-positioning). +> **Editable is already table stakes — what sets PPT Master apart is native depth.** It hands you a real PowerPoint: slide masters, native shapes, data-backed charts and tables — not flat text boxes, and not a filled-in template. It also does more than lay slides out nicely — it reasons the argument into shape first, then designs; and that native depth keeps **converging with PowerPoint itself**, adding more of its native capabilities release after release. In form, it's a workflow that runs inside any agent-capable AI tool: hand the AI your topic or material, and it generates on your machine — your data stays local, no platform or model lock-in. How it works and where the limits are → [Product Positioning](#product-positioning).

Live Demo · @@ -100,30 +100,29 @@ Thanks to [Kimi](https://www.kimi.com/code/?aff=ppt-master) for sponsoring this --- -Drop in your source material, and the deck you get back is **more than just editable**: it has native slide transitions plus opt-in entrance animations (off by default), speaker notes that can become audio narration, charts and tables that can ship as real data-backed PowerPoint objects, and it can follow your own PPT template — a complete deck you can present as-is and keep refining. How to use each capability → [Getting Started](./docs/getting-started.md). +Drop in your source material, and what you get back isn't a static layout you can edit — it's **a complete deck with real PowerPoint behavior**: native slide transitions, opt-in entrance animations (off by default), speaker notes that can become audio narration and even video, charts and tables that can ship as real data-backed PowerPoint objects, and it can follow your own PPT template — present it as-is, and keep refining. How to use each capability → [Getting Started](./docs/getting-started.md). ## Product Positioning -**If a file can't be opened and edited in PowerPoint, it shouldn't be called a PPT.** AI presentation tools roughly fall into four categories, and PPT Master only does the last one: +**Editable is now table stakes — the real question is how much of PowerPoint you actually get.** PPT Master delivers PowerPoint's native object model itself, and in depth: native shapes and connectors with working adjustment handles, data-backed charts and tables on demand, and the full text / picture / fill / effect model — click any element and keep editing it as a native PowerPoint object; and through the template / structured route, it can hand you a deck with real slide masters and layouts (`p:sldMaster` / `p:sldLayout` inheritance). -| Category | Output | Editable element-by-element in PowerPoint? | -|---|---|:---:| -| Template fill-in | PPTX built from a fixed template | Partially — limited by the template | -| Image-based | One large image per slide, packed into PPTX | ❌ each slide is a picture | -| HTML presentation | Web-based deck | ❌ not a PPTX | -| **Native editable (PPT Master)** | **Real DrawingML shapes, text boxes, charts** | ✅ click any element to edit | +And that depth is a **direction of travel, not a fixed checklist.** PPT Master's north star is to keep converging with PowerPoint itself: an ongoing effort to build and integrate more of PowerPoint's native capabilities, release after release, closing the gap between what an AI can generate for you and what you could build by hand in PowerPoint. The [PowerPoint ↔ SVG Mapping Guide](./docs/powerpoint-svg-mapping.md) is the honest, feature-by-feature record of how far that reaches today — and SmartArt is a deliberate omission, not a gap. -In form, it's not a website or an app but a workflow (a "skill") that runs inside AI IDEs like Claude Code, Cursor, VS Code + Copilot, or Codebuddy: you tell the AI in the IDE's chat — "make a deck from this PDF" — and it follows the workflow to produce a genuinely editable `.pptx` on your machine. No coding on your side; you do exactly three things — install Python, install an AI IDE, drop in your material. +In form, it's a workflow (a "skill") that runs inside any agent-capable AI tool: tell it in chat — "make a deck from this PDF" — and it runs the workflow on your machine and exports a natively editable `.pptx`. No coding on your side; you do exactly three things — install Python, install an AI tool, drop in your material. -This form buys three promises that other tools struggle to make at the same time: +Generating a new deck from source documents is the main pipeline, but not the only route. PPT Master can also distill reusable brand / layout / deck templates from your references, fill an existing `.pptx` with new content while preserving its design, and add native transitions, animations, and narration to a finished deck — each route with an explicit contract for what gets preserved. -- **Transparent, predictable cost** — the tool is free and open source; the only cost is your AI model usage. You pay exactly what you consume — no separate PPT subscription added on top -- **Data stays local** — your files shouldn't have to be uploaded to someone else's server just to make a presentation. Apart from AI model communication, the entire pipeline runs on your machine -- **No platform lock-in** — your workflow shouldn't be held hostage by any single company. Works with Claude Code, Cursor, VS Code Copilot, and more; supports Claude, GPT, Gemini, Kimi, and other models +On top of that native depth, this form comes with three promises: + +- **Transparent, predictable cost** — free and open source; the only cost is your AI model usage, with no PPT subscription on top +- **Data stays local** — apart from AI model communication, the entire pipeline runs on your machine +- **No platform lock-in** — any agent-capable AI IDE can drive it; Claude, GPT, Gemini, Kimi, and other models all work + +Why you'd choose it, and where it isn't the right fit → [Why PPT Master](./docs/why-ppt-master.md); the long-term capability boundaries behind these promises → [Project Positioning](./docs/project-positioning.md). > [!IMPORTANT] > ### This is a tool, not a wishing well -> `harness + model = agent` — PPT Master only owns the workflow; the model sets the ceiling. Recommended: **Claude with a large context window (~1M tokens) + AI image generation (`gpt-image-2`)**; other models can run the pipeline, with a quality gap. +> `harness + model = agent` — PPT Master only owns the workflow; the model sets the ceiling. Recommended: **Kimi K3 (or Claude) with a large context window (~1M tokens) + AI image generation (`gpt-image-2` or Google `gemini-3.1-flash-image`)**; other models can run the pipeline, with a quality gap. > > And don't expect a finished, perfect deck in one shot. The tool's value is taking most of the tedious work off your plate; the polishing that's left is yours — a natively editable deck exists precisely so you can keep working on it, not a flat image you can't touch. The cheaper the model, the more there is to do; if results disappoint, upgrade the model first, then check your usage against [Getting Started](./docs/getting-started.md) and the example projects. @@ -234,7 +233,7 @@ Never used one of these? Don't worry — in this project they play exactly one r | **IDE plugin / extension** | [Claude Code](https://claude.ai/code) (VS Code / JetBrains extension), [GitHub Copilot](https://github.com/features/copilot), [Cline](https://cline.bot/), etc. | Installed inside hosts like VS Code or JetBrains | | **CLI agent** | [Claude Code](https://claude.ai/code) CLI, [Codex CLI](https://github.com/openai/codex), Gemini CLI, etc. | Runs in the terminal; suits scripting, remote, or server use | -> **Model recommendation**: for the best results, use **Claude Opus** with `gpt-image-2`; **Gemini 3.5 Flash** currently offers great overall value for money — notably fast and well worth a try. +> **Model recommendation**: for the best results, use **[Kimi K3](https://www.kimi.com/code/?aff=ppt-master)** (or Claude) to drive the pipeline, paired with AI image generation — **`gpt-image-2`** (OpenAI) or **`gemini-3.1-flash-image`** (Google). Kimi Code, the project sponsor, is a great pick for pay-as-you-go access. **🔑 Want to use Claude / GPT / Gemini but don't have access yet?** Project sponsors **[PackyCode](https://www.packyapi.com/register?aff=ppt-master)**, **[APIKEY.FUN](https://apikey.fun/register?aff=PPT-MASTER)** and **[RunAPI](https://runapi.co/register?aff=WMLJ)** offer pay-as-you-go access to Claude, GPT, Gemini and more — no subscription required, with exclusive discounts for our users (details at the top of this page). @@ -316,7 +315,7 @@ AI: Sure. Let's confirm the design spec: The AI handles everything — content analysis, visual design, SVG generation, and PPTX export. -> **Output:** The SVG pipeline has one PPTX export route: PPT Master's converter reads `svg_output/` and writes a directly editable native DrawingML deck to `exports/_.pptx`. Step 7 still always runs `finalize_svg.py`, producing self-contained files in `svg_final/` for visual inspection or manual insertion as SVG pictures; PowerPoint's manual **Convert to Shape** command is outside the supported contract. A copy of `svg_output/` is always snapshotted to `backup//svg_output/` for re-export / archival. By default charts and tables export as SVG-derived shapes (pixel-consistent across PowerPoint / Keynote / WPS); pass `--native-objects` to instead emit them as **real editable PowerPoint chart / table objects backed by data** (rendering may vary across apps), saved as `exports/__native_charts.pptx`. +> **Output:** The SVG pipeline has one PPTX export route: PPT Master's converter reads `svg_output/` and writes a directly editable native DrawingML deck to `exports/_.pptx`. Step 7 still always runs `finalize_svg.py`, producing self-contained files in `svg_final/` for visual inspection or manual insertion as SVG pictures; PowerPoint's manual **Convert to Shape** command is outside the supported contract. A copy of `svg_output/` is always snapshotted to `backup//svg_output/` for re-export / archival. By default charts and tables export as individually editable SVG-derived DrawingML shapes, which prioritize cross-app visual consistency. Pass `--native-charts-and-tables` to replace eligible groups with PowerPoint-native Chart/Table objects backed by data, which provide **Edit Data** and object-specific controls but may render differently across apps; this variant is saved as `exports/__native_charts_tables.pptx`. Both routes are editable—the distinction is the PowerPoint object model, not editability itself. > **Already have a `.pptx` you want to reuse?** Hand the AI that deck plus your material and ask it to "fill this deck with the new content" — it fills text, table, and chart data into your existing design and exports only the pages you pick, staying natively editable. See the [FAQ](./docs/faq.md) and [template-fill workflow](./skills/ppt-master/workflows/template-fill-pptx.md). @@ -353,7 +352,8 @@ PPT Master reads the current process environment first, then the first `.env` fo | | Document | Description | |---|----------|-------------| | 📘 | [Getting Started](./docs/getting-started.md) | First deck in 3 steps, plus how to use templates, live preview, animations, narration, voice cloning (**new users start here**) | -| 🆚 | [Why PPT Master](./docs/why-ppt-master.md) | How it compares to Gamma, Copilot, and other AI tools | +| 🆚 | [Why PPT Master](./docs/why-ppt-master.md) | Why choose it, and where it's not the right fit | +| 🧭 | [Project Positioning](./docs/project-positioning.md) | Long-term positioning, product promises, and capability boundaries | | 🪟 | [Windows Installation](./docs/windows-installation.md) | Step-by-step setup guide for Windows users | | 📖 | [SKILL.md](./skills/ppt-master/SKILL.md) | Core workflow and rules | | 📐 | [Canvas Formats](./skills/ppt-master/references/canvas-formats.md) | PPT 16:9, Xiaohongshu, WeChat, and 10+ formats | @@ -362,6 +362,8 @@ PPT Master reads the current process environment first, then the first `.env` fo | 🏗️ | [Technical Design](./docs/technical-design.md) | Architecture, design philosophy, why SVG | | ❓ | [FAQ](./docs/faq.md) | Model selection, cost, layout troubleshooting, custom templates | +Full documentation index → [`docs/`](./docs/README.md) + --- ## Contributing @@ -389,18 +391,6 @@ Looking to collaborate, integrate PPT Master into your workflow, or just have qu --- -## Star History - - - - - - Star History Chart - - - ---- - ## Sponsors & Support PPT Master is currently built and maintained primarily by me. Every new template, bug fix, and documentation update takes ongoing resources — currently shared by the sponsors and individual supporters below. @@ -433,4 +423,4 @@ Made with ❤️ by [Hugo He](https://www.hehugo.com/) — if this project helps Official distribution: GitHub (primary) · AtomGit (mirror). Redistributions on other platforms are unofficial. MIT licensed — attribution required. -[⬆ Back to Top](#ppt-master--ai-generates-natively-editable-pptx-from-any-document) +[⬆ Back to Top](#ppt-master--ai-generates-native-powerpoint-from-any-document) diff --git a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json index fa95b323..c695c64d 100644 --- a/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json +++ b/plugins/codex/plugins/ppt-master/THIRD_PARTY_SOURCE.json @@ -2,8 +2,8 @@ "sourceId": "ppt-master", "repo": "https://github.com/hugohe3/ppt-master.git", "ref": "main", - "commit": "465e3b4149b852d33ddd1cb94ac059401fe4e823", + "commit": "b05ac551468098ed7b4c1c21d9d0d413b4230c79", "adapter": "claude-skill", "sourcePath": "skills/ppt-master", - "syncedAt": "2026-07-13T16:00:00Z" + "syncedAt": "2026-07-20T16:00:00Z" } diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/.env.example b/plugins/codex/plugins/ppt-master/skills/ppt-master/.env.example index a463323a..6bcd1f81 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/.env.example +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/.env.example @@ -170,12 +170,12 @@ # Use cloud providers only when you want high-quality or cloned voices — # all four (ElevenLabs / MiniMax / Qwen / CosyVoice) accept a cloned voice_id. # Clone the voice in the provider's console first, then pass --voice-id to -# notes_to_audio.py. See docs/audio-narration.md "Use a cloned voice". +# notes_to_audio.py. See workflows/stages/generate-audio.md. # edge-tts 是默认旁白后端,无需 API Key。 # 需要高质量云端旁白或复刻音色时再配置云端提供商—— # ElevenLabs / MiniMax / Qwen / CosyVoice 四家都支持传入复刻 voice_id。 # 先在 provider 控制台复刻得到 voice_id,再用 --voice-id 传给 notes_to_audio.py。 -# 详见 docs/zh/audio-narration.md "使用复刻音色"。 +# 详见 workflows/stages/generate-audio.md。 # # ELEVENLABS_API_KEY=your-elevenlabs-api-key # MINIMAX_API_KEY=your-minimax-key diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md index 607c5a4e..5bd5c1de 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/SKILL.md @@ -5,902 +5,42 @@ description: "多格式源文档到高质量 SVG 页面再导出 PPTX 的多阶 # PPT Master Skill -> AI-driven multi-format SVG content generation system. Converts source documents into high-quality SVG pages through multi-role collaboration and exports to PPTX. +PPT Master is a routed presentation workflow. This entry owns global execution discipline and route selection only; each selected route owns its procedure. -**Core Pipeline**: `Source Document → Create Project → [Template] → Strategist Structured Plan → [Image_Generator] → Executor Live Preview → Quality Check → Post-processing → Export` +## Mandatory Load Order -### SVG Page-Design Boundary +1. Read this file. +2. Read [`workflows/routing.md`](workflows/routing.md). +3. Select exactly one top-level route from the routing authority. +4. Read only that route's authority and its explicitly triggered supporting documents. -| Scope | Contract | +| Selected route | Runtime authority | |---|---| -| Any route that authors or regenerates slide visuals through SVG | `svg_output/` is the complete page-design source: every visible text, image, shape, chart/table fallback, and layout element that should appear on the exported slide is present in that page SVG or referenced by it. | -| Templates, `design_spec.md`, and `spec_lock.md` | Authoring/control inputs. They guide SVG creation but MUST NOT supply visible slide content that is absent from the completed SVG during export. | -| Semantic SVG markers | Minimal rendering-neutral compiler hints used only after existing Layout/Layer/Placeholder/Native metadata has been considered. They never replace native SVG geometry, text, styles, grouping, or asset references. | -| `svg_final/` | Mandatory derived, self-contained SVG visual preview. It may be opened directly or inserted into PowerPoint as an SVG picture, but it is not a supported PPTX source and carries no manual Convert-to-Shape compatibility contract. | -| SVG-to-PPTX export | The only supported generated-PPTX route reads `svg_output/` and maps its content through the project converter to DrawingML/native objects. It may reorganize represented content into Master/Layout/Slide structure but MUST NOT invent new visible page content. | -| Direct PPTX and presentation-behavior workflows | Remain separate. `template-fill-pptx`, `native-enhance-pptx`, animations, transitions, speaker notes, narration, and package relationships are not required to round-trip through SVG. | +| Generate PPTX | [`workflows/generate-pptx.md`](workflows/generate-pptx.md) | +| Create Template | [`workflows/create-template.md`](workflows/create-template.md) | +| Fill Native PPTX | [`workflows/template-fill-pptx.md`](workflows/template-fill-pptx.md) | +| Enhance Native PPTX | [`workflows/native-enhance-pptx.md`](workflows/native-enhance-pptx.md) | -**MUST — page-design closure**: For an SVG-authoring route, inspect the final page SVG to determine what the exported slide looks like. Do not reinterpret “SVG is the page-design language” as “SVG is the complete PPTX package description language.” - -> [!CAUTION] -> ## 🚨 Global Execution Discipline (MANDATORY) -> -> **This workflow is a strict serial pipeline. The following rules have the highest priority — violating any one of them constitutes execution failure:** -> -> 1. **SERIAL EXECUTION** — Steps MUST be executed in order; the output of each step is the input for the next. Non-BLOCKING adjacent steps may proceed continuously once prerequisites are met, without waiting for the user to say "continue" -> 2. **BLOCKING = HARD STOP** — Steps marked ⛔ BLOCKING require a full stop; the AI MUST wait for an explicit user response before proceeding and MUST NOT make any decisions on behalf of the user -> 3. **NO CROSS-PHASE BUNDLING** — Cross-phase bundling is FORBIDDEN. (Note: the Strategist confirmation stage in Step 4 is ⛔ BLOCKING — the AI MUST present recommendations and wait for explicit user confirmation before proceeding. Once the user confirms, all subsequent non-BLOCKING steps — design spec output, SVG generation, speaker notes, and post-processing — may proceed automatically without further user confirmation) -> 4. **GATE BEFORE ENTRY** — Each Step has prerequisites (🚧 GATE) listed at the top; these MUST be verified before starting that Step -> 5. **NO SPECULATIVE EXECUTION** — "Pre-preparing" content for subsequent Steps is FORBIDDEN (e.g., writing SVG code during the Strategist phase) -> 6. **NO SUB-AGENT SVG GENERATION** — Executor Step 6 SVG generation is context-dependent and MUST be completed by the current main agent end-to-end. Delegating page SVG generation to sub-agents is FORBIDDEN -> 7. **SEQUENTIAL PAGE GENERATION ONLY** — In Executor Step 6, after the global design context is confirmed, SVG pages MUST be generated sequentially page by page in one continuous pass. Grouped page batches (for example, 5 pages at a time) are FORBIDDEN -> 8. **SPEC_LOCK RE-READ PER PAGE** — Before generating each SVG page, Executor MUST `read_file /spec_lock.md`. All colors / fonts / icons / images MUST come from this file — no values from memory or invented on the fly. Executor MUST also read `pptx_structure.mode`, the current page's `page_rhythm` (`anchor` / `dense` / `breathing`), and `page_charts`. Only a deck/layout template route (`mode: structured`) looks up `page_layouts` (the input template SVG), `page_pptx_layouts` (the page assignment), `pptx_masters`, `pptx_layouts` (the unique reusable roster), and `template_adherence`; free-design and brand-only routes use `mode: flat` and omit those sections. This rule exists to resist context-compression drift on long decks and to break the uniform "every page is a card grid" default -> 9. **SVG MUST BE HAND-WRITTEN, NOT SCRIPT-GENERATED** — Every SVG page is written by the main agent directly, one page at a time (see rules 6 and 7). Writing or running a Python / Node / shell script that produces the SVG files in batch — looping over pages, templating from data, or emitting them via a generator — is FORBIDDEN, including under "save tokens", "quick draft", or "user is in a hurry" pretexts. The script-generation path was tried on a feature branch and abandoned: cross-page visual consistency depends on per-page authoring with full upstream context, which a generator script cannot reproduce. **Narrow exception**: `preset_shape_svg.py` may print one deterministic stock-shape fragment to stdout after the main agent has selected its semantic role, frame, and paint. It cannot write `svg_output/`, choose layout, batch shapes, or generate a page; the main agent reads the fragment and inserts it through the normal hand-authored page edit -> 10. **FOLLOW DETERMINISTIC ROUTING RULES** — Do not add blocking routing questions when this skill defines a route. If the user request violates a route precondition, state the required prerequisite and stop that route instead of asking the user to choose around the rule. Ordinary finite options, stylistic preferences, and recoverable details are surfaced with a recommended value plus alternatives at the next existing confirmation gate. - -> [!IMPORTANT] -> ## 🌐 Language & Communication Rule -> -> - **Response language**: match the user's input and source materials. Explicit user override (e.g., "请用英文回答") takes precedence. -> - **User-facing option labels**: when presenting confirmations, brief proposals, choices, or finite option sets, use the user's language for labels and explanations. English enum IDs / file fields may appear in parentheses for precision, but never rely on English-only labels such as `deck`, `layout`, `mirror`, or `fidelity` without a localized explanation. -> - **Template format**: `design_spec.md` MUST follow its original English template structure (section headings, field names) regardless of conversation language. Content values may be in the user's language. - -> [!IMPORTANT] -> ## 🔌 Compatibility With Generic Coding Skills -> -> - `ppt-master` is a repository-specific workflow, not a general application scaffold -> - Do NOT create `.worktrees/`, `tests/`, branch workflows, or generic engineering structure by default -> - On conflict with a generic coding skill, follow this skill unless the user explicitly says otherwise - -## Rule Strength Labels - -| Label | Meaning | -|---|---| -| `MUST` | Required behavior; violation is workflow failure | -| `MUST NOT` | Forbidden behavior | -| `DEFAULT` | Used when the user has not specified otherwise | -| `OPTIONAL` | Run only when explicitly triggered or when the route says so | -| `FALLBACK` | Recovery path after the primary path fails | -| `GATE` | Required checkpoint before entering the next step | - -## Cross-Cutting Authorities - -| Concern | Authority | Contract | -|---|---|---| -| Main pipeline sequencing | This `SKILL.md` | Owns Step 1-7 order, gates, role switching, and mandatory commands | -| Route selection | [`workflows/routing.md`](workflows/routing.md) | Owns deterministic route choice before the main pipeline or a standalone workflow | -| Workflow registry | [`workflows/index.md`](workflows/index.md) | Owns standalone workflow trigger/precondition/output inventory | -| Artifact ownership | [`references/artifact-ownership.md`](references/artifact-ownership.md) | Owns fact channels, source/derived artifact boundaries, and regeneration rules | -| Failure recovery | [`workflows/failure-recovery.md`](workflows/failure-recovery.md) | Owns stop/continue decisions for common failures | -| Confirm UI details | [`scripts/docs/confirm_ui.md`](scripts/docs/confirm_ui.md) | Owns schema, launcher behavior, port strategy, and chat fallback details | - -## Main Pipeline Scripts - -| Script | Purpose | -|--------|---------| -| `${SKILL_DIR}/scripts/source_to_md.py` | Unified source-to-Markdown dispatcher — default Step 1 entry for explicit file(s) or URL(s) | -| `${SKILL_DIR}/scripts/pptx_intake.py` | Standard PPTX intake enrichment — canvas / identity / slide geometry / tables / native chart data / SmartArt structure | -| `${SKILL_DIR}/scripts/project_manager.py` | Project init / validate / manage | -| `${SKILL_DIR}/scripts/icon_sync.py` | Copy chosen library icons into `/icons/` at selection time; missing names reported + non-zero (re-pick gate) | -| `${SKILL_DIR}/scripts/analyze_images.py` | Image analysis | -| `${SKILL_DIR}/scripts/latex_render.py` | LaTeX formula rendering (manifest-driven PNG assets) | -| `${SKILL_DIR}/scripts/image_gen.py` | AI image generation (multi-provider) | -| `${SKILL_DIR}/scripts/slice_images.py` | Slice one AI illustration sheet into individual spot-illustration elements | -| `${SKILL_DIR}/scripts/svg_authoring_view.py` | Create a lightweight non-destructive inspection projection of PPTX-imported SVGs; never a release source | -| `${SKILL_DIR}/scripts/svg_quality_checker.py` | SVG quality check | -| `${SKILL_DIR}/scripts/preset_shape_svg.py` | Print one registry-backed native PowerPoint preset fragment to stdout for hand-authored SVG insertion | -| `${SKILL_DIR}/scripts/total_md_split.py` | Speaker notes splitting | -| `${SKILL_DIR}/scripts/finalize_svg.py` | SVG post-processing (unified entry) | -| `${SKILL_DIR}/scripts/svg_to_pptx.py` | Export to PPTX | -| `${SKILL_DIR}/scripts/native_enhance_pptx.py` | Existing PPTX enhancement project init / validation / direct OOXML patch export | -| `${SKILL_DIR}/scripts/native_narration_pptx.py` | Backward-compatible entrypoint for existing PPTX notes / narration enhancement | -| `${SKILL_DIR}/scripts/update_spec.py` | Propagate a `spec_lock.md` color / font_family change across all generated SVGs | - -For complete tool documentation, see `${SKILL_DIR}/scripts/README.md`. - -> **Windows note**: if a `python3 ...` command fails (common on python.org installs, which provide `python.exe` but not `python3.exe`), rerun the same command with `python` instead. - -## Template Index - -| Index | Path | Purpose | -|-------|------|---------| -| Layout templates | `${SKILL_DIR}/templates/layouts/layouts_index.json` | Query available page layout templates | -| Brand presets | `${SKILL_DIR}/templates/brands/brands_index.json` | Query available brand identity presets (color / typography / logo / voice) | -| Visualization templates | `${SKILL_DIR}/templates/charts/charts_index.json` | Query available visualization SVG templates (charts, infographics, diagrams, frameworks) | -| Icon library | `${SKILL_DIR}/templates/icons/` | See `${SKILL_DIR}/templates/icons/README.md`; search icons on demand with `ls templates/icons// \| grep ` | - -## Standalone Workflows - -**Route authority**: Use [`workflows/routing.md`](workflows/routing.md) before entering the main pipeline or any standalone workflow. - -**Registry**: Use [`workflows/index.md`](workflows/index.md) for the complete workflow list, triggers, preconditions, exclusions, outputs, and blocking points. - -### PPTX Route Boundary - -| User intent | Route | -|---|---| -| Raw PPTX template plus new material/topic, generate a PPTX | [`template-fill-pptx`](workflows/template-fill-pptx.md) | -| Existing PPTX, preserve page count/order and slide wording 1:1, improve layout | [`beautify-pptx`](workflows/beautify-pptx.md) | -| Existing PPTX as source material, rethink outline or change page count/order | Main pipeline via `source_to_md.py` plus PPTX intake | -| Build a reusable template package from a PPTX/design reference | [`create-template`](workflows/create-template.md), then return with the generated template workspace path | -| Finished PPTX, keep content/layout stable and add notes/audio/timing/transitions | [`native-enhance-pptx`](workflows/native-enhance-pptx.md) | - -**MUST**: Raw `.pptx` template plus "generate PPTX" routes to `template-fill-pptx` by default. The SVG generation route consumes only an explicit template workspace path with a valid `templates/design_spec.md`, or a supported direct/legacy package root with `design_spec.md`. - -**MUST**: Beautify is strictly 1:1. Any split, merge, drop, reorder, or page-count change routes to the main pipeline. - -**MUST — reusable template mode boundary**: `create-template` has two distinct -contracts. `standard` and `fidelity` author new SVG prototypes and their own -Master/Layout/slot system; source visuals and assets are references, and source -Master/Layout topology is neither preserved nor distilled. `mirror` is a -restoration path: preserve the source slide roster/order, visual appearance, -Master/Layout parentage and identities, placeholder type/index/bounds, native -object ownership, and supported native-shape metadata. The lossless import is -the restoration authority; the lightweight authoring projection exists only to -keep model context small. Mechanical normalization may express the source facts -in the current explicit SVG contract and expand fixed-layer group wrappers into -direct atoms, but it MUST NOT merge, split, promote, demote, rename, or -re-parent source structure. Export compiles the selected contract and never -infers a different one. Mirror emits one complete page prototype per source -Slide plus one definition-only `layout_.svg` prototype for every -source Layout unused by those Slides. The independent Master/Layout roster then -registers the complete supported source graph without publishing synthetic -carrier pages. Stop only when required native evidence is missing or unsupported; -never silently drop or merge an identity. - -**FALLBACK**: Ambiguous requests such as "make this PPT more professional" require exactly one discriminator question: preserve original page count/order and slide wording, or treat the deck as source material and restructure it? +**Hard rule — selected authority only**: Do not load another top-level route's procedure after routing. Profiles, stages, governance files, and child workflows refine the selected route; they never compete with it. --- -## Workflow - -### Step 1: Source Content Processing - -🚧 **GATE**: User has provided source material (PDF / DOCX / EPUB / URL / Markdown file / text description / conversation content — any form is acceptable). - -> **No source content?** When the user supplies only a topic name or requirements without any file or substantive description, run the [`topic-research`](workflows/topic-research.md) workflow first, then return here with its products as input. - -When the user provides non-Markdown content, convert immediately through the -unified dispatcher. It preserves the backend converters' existing behavior, -routes by source type, and writes the standard Markdown plus conversion profile. - -| User Provides | Action | -|---------------|--------| -| PDF / DOCX / Office document / XLSX / XLSM / PPTX / EPUB / HTML / LaTeX / RST / web URL | `python3 ${SKILL_DIR}/scripts/source_to_md.py [ ...]` | -| CSV / TSV | Read directly as plain-text table source | -| Markdown | Read directly | - -For PPTX sources, Step 1 converts the deck to Markdown content; after Step 2 -`import-sources`, standard PPTX intake is also written to `/analysis/`. -Use `source_to_md.py -t ` only when extension detection is ambiguous. -Default local conversion writes Markdown/profile outputs beside each source file. -Use `-o` only when a specific output file/directory is required; with multiple -inputs or directory inputs, `-o` is an output directory. Backend converter details are documented in -[`scripts/docs/conversion.md`](scripts/docs/conversion.md). - -> **Office vector assets (EMF/WMF) from DOCX/PPTX sources**: -> Source conversion extracts embedded Office vector images (.emf/.wmf) -> alongside bitmap images when the source format exposes them. After `import-sources`, these land in `images/` -> together with `image_manifest.json` and are first-class assets in §VIII Image Resource List. -> -> **Do NOT convert EMF/WMF to PNG.** The PPT Master pipeline preserves them as external -> references (`finalize_svg.py` skips them) and `svg_to_pptx.py` embeds them as -> PPTX-native media via `image/x-emf` / `image/x-wmf` MIME — PowerPoint renders them at full vector fidelity. -> Converting via LibreOffice/Inkscape introduces CJK font substitution drift and -> rasterization loss; the original EMF/WMF is always higher fidelity than the converted PNG. -> -> Browser-based live preview cannot render EMF (will show blank) — this is expected; -> the PPTX output is the source of truth. - -**✅ Checkpoint — Confirm source content is ready, proceed to Step 2.** - ---- - -### Step 2: Project Initialization - -🚧 **GATE**: Step 1 complete; source content is ready (Markdown file, user-provided text, or requirements described in conversation are all valid). - -```bash -python3 ${SKILL_DIR}/scripts/project_manager.py init --format -``` - -Format options must be named with concrete dimensions. Default: `ppt169` = `1280x720`, `viewBox="0 0 1280 720"`. Other examples: `ppt43` = `1024x768`, `story` = `1080x1920`, `banner` = `1920x1080`. For the full format list, see `references/canvas-formats.md`. - -Import source content (choose based on the situation): - -| Situation | Action | -|-----------|--------| -| Has source files (PDF/MD/etc.) | `python3 ${SKILL_DIR}/scripts/project_manager.py import-sources --move` | -| User provided text directly in conversation | No import needed — content is already in conversation context; subsequent steps can reference it directly | - -For PPTX sources, `import-sources` automatically runs the standard intake enrichment: - -```bash -python3 ${SKILL_DIR}/scripts/pptx_intake.py /sources/ -o /analysis -``` - -For each PPTX it writes `.identity.json` (canvas, theme palette/fonts, observed usage) and `.slide_library.json` (text slots, geometry, native tables, native chart caches, SmartArt nodes/connections), and merges that deck's Strategist-facing digest into the single multi-deck index `analysis/source_profile.json` (`decks[]`, one self-contained entry per source deck, with prefixed artifact pointers). In the main generation path these are source facts and recommendation candidates, not replica constraints; beautify and template-fill workflows decide separately which fields become locked constraints. - -Multi-deck: several PPTX files may be imported into one main-pipeline project — each gets its own `.*` artifacts and a deck entry in `source_profile.json`. `source_profile.json` stays the single must-read index (one entry for a one-deck project, several for a combined-source project). Stems must be distinct; re-importing the same stem replaces that deck's entry. The beautify / template-fill workflows remain single-deck (1:1 to one chosen source deck) and read that deck's `.*` artifacts. - -> ⚠️ **MUST use `--move`** (not copy): all source files — Step 1's generated Markdown, original PDFs / MDs / images — go into `sources/` via `import-sources --move`. If Step 1 wrote Markdown beside the original sources, pass that source path/directory once. If Step 1 used `-o` to write Markdown elsewhere, pass both the original source path(s)/directory and the Markdown output path(s)/directory. After execution they no longer exist at the original location. Intermediate artifacts (e.g., `_files/`) are handled automatically. - -**✅ Checkpoint — Confirm project structure created successfully, `sources/` contains all source files, converted materials are ready. Proceed to Step 3.** - ---- - -### Step 3: Template Option - -🚧 **GATE**: Step 2 complete; project directory structure is ready. - -**Default — free design.** Proceed directly to Step 4. Do NOT query any `*_index.json` unless triggered. Do NOT ask the user. Do NOT proactively suggest, hint at, or fuzzy-match any template based on content, slug-like words, or vague style descriptions. - -**Hard boundary — raw PPTX template references are not Step 3 templates.** PPTX-as-source remains valid in Step 1 / Step 2, and raw PPTX template + generated PPTX routes to `template-fill`. But if the user wants the SVG/template-based generation route from that PPTX, stop before Step 3. The user must first run [`workflows/create-template.md`](workflows/create-template.md), then return with the generated template workspace path. Step 3 consumes an explicit workspace whose `templates/design_spec.md` declares `kind: brand` / `kind: layout` / `kind: deck`, or a compatible legacy-flat package whose root `design_spec.md` declares one of those kinds. - -Do **not** reinterpret this boundary as 1:1 redesign or free SVG generation. Use `template-fill` for raw PPTX template + generated PPTX requests; use `beautify` only when the source deck's page count, order, and wording are preserved. - -**Template flow triggers ONLY on explicit directory paths** supplied by the user in their initial message, plus one narrow workflow handoff: a project-scoped `create-template` run in the current conversation may pass its exact validated project workspace root directly into this Step. The trigger rule is mechanical, not interpretive: - -| User input contains | Step 3 action | -|---|---| -| One or more explicit template workspace paths (each resolves to `templates/design_spec.md`, or to a compatible legacy-flat root `design_spec.md`, with `kind: brand` / `kind: layout` / `kind: deck` in YAML frontmatter) | Normalize each source directory, read its `kind`, dispatch per the kind matrix below, fuse if multiple | -| Current `create-template` workflow just completed project scope and validated its exact `/` workspace | Consume that single workspace in place; it cannot join multi-path fusion | -| Anything else — bare template names ("用 presentation_core"), style descriptions ("麦肯锡风格"), brand mentions ("中国电信风格"), vague intent ("想用个模板"), or silence | Skip Step 3, free design | - -There is no slug matching, no name lookup, no fuzzy resolution. A name without a path does not trigger — the user must give a path the AI can `cd` into. - -**Structured-template preflight (before copy)**: For every deck/layout workspace, inspect all SVG roots and slots under its normalized template source. Every page must declare root Master/Layout key and picker names; Master/Layout visuals must be direct atoms rather than ``; every slot must be a top-level `` with positive bounds and exactly one compatible carrier, or an explicit composite `object` proxy. A zero-slot Layout is valid. If the SVG package uses a legacy semantic contract, run [`restore-pptx-structure`](workflows/restore-pptx-structure.md) first and return to Step 3 with the migrated workspace. A legacy flat directory shape alone is read compatibility and does not trigger restoration. - -> Style descriptions ("麦肯锡风格" / "Keynote 风" / "极简风" / etc.) never trigger Step 3. They flow into the Strategist confirmation stage as a style brief (color / typography / tone in fields e–g). - -> Bare names ("presentation_core", "中国电信", "anthropic") do NOT trigger Step 3 even if a matching directory exists in the library. The user must give a path. AI must not "helpfully" resolve a name to a path. - -> "What templates exist?" is out-of-band Q&A — answer by listing entries from `brands_index.json` / `layouts_index.json` / `decks_index.json` together with their paths. Listing alone does not advance the pipeline; the user must send a path back to trigger Step 3. - -> To create a new layout or deck, read [`workflows/create-template.md`](workflows/create-template.md). To create a new brand, read [`workflows/create-brand.md`](workflows/create-brand.md). - -#### Three template kinds - -The architecture has three independent reference bundles. Full schema in [`docs/zh/templates-architecture.md`](../../docs/zh/templates-architecture.md). Summary: - -| Kind | Physical dir | Contains | Frontmatter | -|---|---|---|---| -| **brand** | `templates/brands//templates/` inside a complete workspace | identity-only segment: color / typography / logo / voice / icon style | `kind: brand` | -| **layout** | `templates/layouts//templates/` inside a complete workspace | structure-only segment: canvas / page structure / page types / SVG roster | `kind: layout` | -| **deck** | `templates/decks//templates/` inside a complete workspace | full identity + structure reference with the middle (template overview) segment | `kind: deck` | - -**Segment ownership** (governs fusion override priority): - -| Segment | Sections | Owner kind on fusion | -|---|---|---| -| Identity | Color Scheme / Typography / Logo / Voice & Tone / Icon Style | brand | -| Structure | Canvas / Page Structure / Page Types / SVG Roster | layout | -| Middle | Template Overview (use cases / design intent) | deck (no other kind writes this) | - -#### Single-path dispatch - -| User path's `kind` | Step 3 action | -|---|---| -| `kind: brand` | Install `templates/` plus any existing `images/` and `icons/` into the matching project roots; ignore `exports/`. Strategist locks identity; structure stays free. | -| `kind: layout` | Install `templates/` plus any existing `images/` and `icons/` into the matching project roots; ignore `exports/`. Strategist locks structure; identity is decided in confirmation fields e–g. | -| `kind: deck` | Install `templates/` plus any existing `images/` and `icons/` into the matching project roots; ignore `exports/`. Strategist locks all segments; confirmation narrows to deck-content fields. | - -Normalize every explicit path before any write: - -| Input shape | Spec / SVG source | Asset source | Install rule | -|---|---|---|---| -| Current workspace: `/templates/design_spec.md` | `/templates/` | Any existing `/images/`, `/icons/` | Map the existing portable roots to the target project's matching roots; ignore `/exports/` | -| Compatible legacy-flat package: `/design_spec.md` | `/` | Package-local files | SVG/spec/non-bitmaps → project `templates/`; bitmaps → project `images/`; route declared icons to project `icons/` | - -**Atomic install preflight (mandatory)**: Resolve source and destination paths, enumerate the complete file mapping, and reject every destination collision before copying any file. Equality between a current project workspace root and the target project root means in-place consumption and no copy. For an external single path, a collision stops Step 3 rather than overwriting. For multi-path fusion, do not copy packages sequentially: resolve segment conflicts and asset-name conflicts first, construct one final mapping, then write it once. Never use recursive copy as an implicit conflict policy. - -Never infer that a flat directory has legacy Master/Layout semantics solely from packaging. - -The same current-workspace routing applies to all three kinds: source/spec in `templates/`, visual assets in `images/`, runtime icons in `icons/`, and on-demand review artifacts in `exports/`. Empty optional roots are omitted rather than retained with placeholder files, so a normal workspace has no `exports/` until a review file is explicitly generated. The spec's `kind` tells Strategist how to read the installed source. Template SVGs are not export-time overlays: visible output still lives completely in `svg_output/`. Their complete visuals and explicit Master/Layout/placeholder metadata are nevertheless the authoring prototypes selected by `page_layouts`. - -When `create-template` used project output scope, its workspace root is the target project itself and all core directories are already final. Resolve both roots before copying: equality means **in-place consumption**, so skip the installation. An in-place workspace cannot participate in multi-path fusion; use external workspaces for fusion. Never place the local source under a nested `templates/local_master/` directory because the confirmation and quality gates read the project `templates/` root. - -A project-scoped workspace has the same portable routing as a library workspace. It may be copied or promoted across roots as one unit (`templates/` plus any existing `images/` and `icons/`); `exports/` stays review-only. Do not pass only another project's `templates/` subdirectory because that would omit sibling assets. - -Legacy template packages may ship `native_structure.json` + `source_template.pptx`, omit root Master identity, use direct atomic placeholders, or carry old baseline/distillation metadata. Do not copy or consume those semantic contracts through Step 3. Run [`restore-pptx-structure`](workflows/restore-pptx-structure.md) on the package first, then return with the migrated workspace path. Old flat packaging remains readable when its SVG structure is already current. - -The Strategist confirmation stage decides whether the selected deck/layout template is used `strict` or `adaptive`. Those template projects use `pptx_structure.mode: structured`, map every page to one input SVG in `page_layouts`, declare unique reusable identities in `pptx_masters` / `pptx_layouts`, and assign each page through `page_pptx_layouts` before SVG generation. A Layout definition may remain unused by generated pages when it names an installed template SVG as its prototype source. Brand-only projects remain on the free-design `mode: flat` route. Strict preserves the template's declared Master/Layout/slot contract. Adaptive keeps the template Master and may define and assign a new Layout key during authoring when the composition genuinely changes. Non-mirror paint and typography follow the project skin rules. - -#### Multi-path fusion - -When the user gives two or more paths of **different kinds**, Step 3 fuses them into a single `/templates/design_spec.md`. **Default granularity is segment-level integer replacement** — entire identity / structure / middle segments are taken from the highest-priority source for that segment, no implicit field-level mixing. - -Override priority by segment: - -| Combination | Identity from | Structure from | Middle from | -|---|---|---|---| -| brand only | brand | (free design) | (none) | -| layout only | (free design) | layout | (none) | -| deck only | deck | deck | deck | -| brand + layout | brand | layout | (none) | -| brand + deck | brand (overrides deck) | deck | deck | -| layout + deck | deck | layout (overrides deck) | deck | -| brand + layout + deck | brand | layout | deck | - -Field-level micro-adjustment (e.g. "use anthropic brand but primary changed to #FF0000") is **not** part of Step 3 fusion — it flows into Strategist confirmation stage e–g as a normal user request. - -#### Same-kind multiple paths — conflict resolution - -When the user gives two paths of the **same kind** (e.g. `brands/anthropic` + `brands/google`), Step 3 surfaces a conflict prompt before fusing — like resolving a git merge conflict: - -``` -AI: 你给了两个 brand,检测到段级冲突: - - Color Scheme(Anthropic 橙红 vs Google 多色) - - Typography(Styrene/AnthropicSans vs GoogleSans/Roboto) - - Logo(Anthropic 标 vs Google 标) - - Voice & Tone(restrained vs friendly) - - Icon Style(stroke vs filled) - - 要 (a) 全部按 Anthropic / (b) 全部按 Google / (c) 逐段挑? -``` - -Rules: -- Default: no implicit ordering — every cross-source segment difference is reported as a conflict -- Only when the user picks `(c)` does AI walk through each segment one by one -- Field-level conflicts are out of scope — segment-level only -- Three or more same-kind paths are not supported — ask the user to converge to at most two - -#### Fused spec provenance - -When fusion happens (any multi-path case), the resulting `/templates/design_spec.md` carries a provenance block immediately under its H1: - -```markdown -> **Fused from:** -> - deck: `templates/decks/中国电信/` (base) -> - brand: `templates/brands/anthropic/` (identity override) -> - layout: `templates/layouts/presentation_core/` (structure override) -> - conflicts resolved: Color Scheme from anthropic(user picked a) -``` - -Single-path Step 3 does **not** add provenance (the source is self-evident from the copied files). - -The fused frontmatter `kind` describes the resulting bundle: `deck` when both identity and structure are present, `layout` when only structure is present, and `brand` when only identity is present. Keep this field accurate; the Strategist confirmation server uses it to show template adherence only for bundles that actually own page structure. - -**✅ Checkpoint — Default path proceeds to Step 4 without user interaction. If the user supplied one or more explicit template paths, those have been copied, staged in place, or fused into `/templates/` before advancing.** - ---- - -### Step 4: Strategist Phase (MANDATORY — cannot be skipped) - -🚧 **GATE**: Step 3 complete; default free-design path taken, or (if triggered) template files copied or confirmed in place in the project. - -First, read the role definition: -``` -Read references/strategist.md -``` - -> ⚠️ **Mandatory gate**: before writing `design_spec.md`, Strategist MUST `read_file templates/design_spec_reference.md` and follow its full I–X section structure. See `strategist.md` Section 1. - -**Artifact ownership**: fact-channel and source/derived artifact boundaries are defined in [`references/artifact-ownership.md`](references/artifact-ownership.md). This Step uses those ownership rules; it does not redefine them. - -**`/analysis/` is the project's intermediate-analysis folder: the canonical home for machine-extracted source/asset facts — the PPTX intake bundle (`source_profile.json` index + per-deck `.identity.json` / `.slide_library.json`) and `image_analysis.csv`. It holds facts, not design contracts — `design_spec.md` / `spec_lock.md` stay at the project root.** The MUST-read contract covers only the **compact structured data files (`.json` / `.csv`)**; other artifacts that may live under `analysis/` (e.g. a beautify `source_svg_import/` vector reference package) are NOT bulk-read — they are read selectively only when a specific workflow step calls for them. Before the Strategist confirmation stage, Strategist MUST read the auto-extracted fact files already in `analysis/` — currently `source_profile.json` (PPTX intake), when present. This file is the multi-deck index: read it once for the `decks[]` digests (canvas / chart / table / SmartArt entries per source deck), then open a specific deck's `.identity.json` / `.slide_library.json` only if you need its full raw facts. Use these entries as **factual source context** (format default + content facts); when several decks are present, synthesize across all of them. The source's **palette / typography / visual identity are a reference, not a constraint**: the main pipeline may inherit them where they fit the content and the confirmed style, or design fresh where they don't — the Strategist's judgment, never an obligation to either keep or discard. (Template-fill preserves the native source design by editing cloned slides directly; beautify defaults to the source identity but still follows the confirmed values; the main pipeline treats source identity as reference only and defaults to fresh design.) (`image_analysis.csv` lands later, at the image-analysis step below, and is the authoritative regenerated image-fact view there — re-derived from the live `images/` folder, not a durable store.) - -**Channel ownership — read each fact once from its owning channel.** In the main pipeline the **content contract is the content-type files in `sources/`** — primarily `.md`, but also any user-supplied content the import archived there: `.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml` (a `metrics.json` or `data.csv` may carry core content — judge by what the file holds). Text, tables, chart data values, and SmartArt node wording come from these (`ppt_to_md` transcribes native charts as Markdown tables and SmartArt nodes as hierarchical bullets). **Do NOT read pipeline sidecars in `sources/` as content**: `*.conversion_profile.json` (conversion audit) and `*_files/image_manifest.json` (asset index) are process metadata — open them only to audit a conversion or resolve assets, never as slide content. Converted-source originals archived in `sources/` (`.pdf` / `.pptx` / `.docx` / `.xlsx` / `.html` / `.epub` / `.tex` / `.rst` / `.ipynb` / `.typ`, etc.) are read via their converted `.md`, not scanned directly in the main pipeline. The `analysis/` chart / table / diagram entries are a **structural digest** for outline decisions (which slides carried charts, tables, or SmartArt; chart types / series names; SmartArt layout and hierarchy) — not a second copy of the content values; do NOT also pull chart values or SmartArt wording from `.slide_library.json` in the main pipeline. The `.slide_library.json` full structured data is owned by the direct-PPTX workflows: template-fill uses it as the native fill contract while preserving SmartArt unchanged; beautify uses it for native chart / table data and SmartArt relationships while keeping all wording from the Markdown. - -**Strategist confirmation stage** (full template: `templates/design_spec_reference.md`): - -⛔ **BLOCKING**: present the Strategist confirmation stage and **wait for explicit user confirmation or modification** before outputting Design Specification & Content Outline. This is the single core confirmation gate — once the final confirmation lands, all subsequent steps proceed automatically. The default Confirm UI delivers the gate in **three stages** (direction → design system → images / execution; see below); the chat fallback mirrors the same staged order. - -1. Canvas format -2. Page count range -3. Target audience -4. Style objective -5. Template adherence — `strict` / `adaptive` (only when Step 3 loaded a deck/layout template) -6. Color scheme -7. Icon usage approach -8. Typography plan, including formula rendering policy -9. Image usage approach - -**Confirm UI Auto-Launch (Mandatory — default visual confirmation surface)**: by default the Strategist confirmation stage is presented through an interactive local page in **three stages within one browser session** — Stage 1 confirms the direction anchors; the AI then re-derives the design-system layer from the **user's actual** anchors; Stage 2 confirms that layer; the AI then re-derives image and execution choices from the confirmed direction + design system; Stage 3 confirms the final operational layer. Color swatches, live font previews, icon samples, image-style reference previews, and candidate picks appear where they help judgment; the chat path is the always-valid fallback. [`scripts/docs/confirm_ui.md`](scripts/docs/confirm_ui.md) owns the schema, server lifecycle, port strategy, and fallback details; this section keeps the orchestration contract. The split: - -| Stage | Confirms | Driven by | -|---|---|---| -| **1 — direction anchors** | canvas · audience + core message + `content_divergence` + `delivery_purpose` *(PPT only — omitted on non-PPT canvases)* (all §c key info) · `mode` + `visual_style` · `template_adherence` *(only when Step 3 loaded a deck/layout template)* | the source + user intent | -| **2 — design system** (re-derived from Stage 1) | page count · color · typography (font + size) · icons · formula policy | the confirmed Stage 1 | -| **3 — images / execution** (re-derived from Stage 1 + Stage 2) | image usage · generated-image style · AI-image generation path · generation mode · refine-spec toggle | the confirmed direction + design system | - -> **Why three stages.** Design-system fields are anchored by the same few choices (`visual_style` anchors color / icon / typography; `delivery_purpose` sets the body size, page density, **and** the page-count recommendation). Image strategy depends on both the confirmed visual direction and the confirmed color system — its palette is color behavior only, while final HEX values follow Stage 2. Confirming direction first, then design system, then image / execution choices means each downstream stage fits the user's *real* choices instead of the AI's original assumptions. Page count is a **derived** field (content volume × `delivery_purpose`), which is why it lives in Stage 2, not up front. - -Steps: - -> ⛔ **Steps 2 → 3 → 4 are ONE uninterrupted run — do NOT yield to the user mid-flow.** When an intermediate `--wait` returns, the AI **immediately and autonomously** re-derives and writes the next stage in the **same turn**: do **not** summarize, ask a question, report progress, or end the turn in between. The browser is sitting on a "deriving…" spinner polling for the next stage you must write — stopping here strands the page and the user must prod you in chat to finish (a bug, not the intended flow). **Stage-1 and Stage-2 confirmations are intermediate machine handoffs, not stopping points.** The single ⛔ BLOCKING wait is the **final** confirmation at the end of step 4. (Chat-fallback path — only when the page never opened — is the exception: there you do present each stage in chat and wait for a reply.) - -1. **Write Stage 1** to `/confirm_ui/recommendations.json` with `"stage": "stage1"` and only the anchor fields. New recommendations MUST use the canonical `stage` selector. Enumerable anchors (`canvas` / `mode` / `visual_style` / `delivery_purpose`) name a recommended canonical `id` in a `recommend` block (the page lists common options from `confirm_ui/static/catalogs.json`); `visual_style` also carries the ≥3-style `visual_style_spectrum` (safe / shifted / bold — same hard rule as h.5). When Step 3 loaded a deck/layout template, also set `recommend.template_adherence` to `strict` or `adaptive`; omit the field entirely for free design and brand-only templates so the page does not display it. `audience` and `content_divergence` are plain `{ "value": "" }`. `content_divergence` is the **free-text** field shown under audience in §c — how closely to follow the source vs how freely to reshape it (blank = balanced; facts stay sourced at every level); it is consumed by Strategist when authoring `§IX`, recorded in `design_spec.md §I`, carries no page-count coupling, and is **not** written to `spec_lock.md`. Set `lang` to the page language (`zh` / `en` / `ja`); visible text matches `lang`, or provide multilingual `name_zh` / `name_en` / `name_ja` + `note_zh` / `note_en` / `note_ja` — when the user's language is Japanese, set `lang: "ja"` and always include the `_ja` variants (labels resolve in the page language first — a `ja` page falls back ja → en → zh, so missing `_ja` labels silently render in English; zh/en pages keep their zh↔en fallback and only try `_ja` last). -2. **Launch + wait for Stage 1.** Background launch; the parent returns when the page writes the stage-1 `result.json`. **Long tool timeout — 600000 ms** (the `--wait` ≈590 s budget): - ```bash - python3 ${SKILL_DIR}/scripts/confirm_ui/server.py --daemon --wait - ``` - Page opens at the launch-log URL such as `http://127.0.0.1:5050` — the **same port as the Step 6 live preview** (they never run at once: this page shuts down at the end of Step 4). If 5050 is held, the launcher **auto-advances** (5051, …) — read the actual URL from the launch log and report it. The page does **not** close after Stage 1: it shows a "deriving…" state and polls for Stage 2. **Launch or wait failure is non-fatal**: if it fails or times out (flask missing, port blocked, no GUI / remote / web host), do **NOT** troubleshoot — **on any non-zero exit, re-check `result.json` once** for a fresh `status: stage1-confirmed` before dropping to the chat fallback. **On success (exit 0 with a stage-1 result), do not pause or report — go straight to step 3 in the same turn.** -3. **Re-derive Stage 2 from the confirmed anchors, write it, then wait for the design-system handoff — immediately, same turn (the page is polling for it).** Read the stage-1 `result.json` (`status: stage1-confirmed`). Using the user's **actual** confirmed anchors (not your originals), author the design-system candidates and **overwrite** `recommendations.json` with `"stage": "stage2"`: page count (content volume × `delivery_purpose`); color and typography as **generative ≥3-candidate** fields (creative recommendations always offer real choice; fewer than 3 only on the honest-shortfall exception, with a stated reason; color: core `palette` with background/secondary_bg/primary/accent/secondary_accent/body_text; typography: CJK + Latin for `heading` and `body` with `css` preview stacks + `body_size` as the body baseline in **px** (every canvas) — **one fixed value per confirmed `delivery_purpose`** (`text` 20 / `balanced` 24 / `presentation` 32), not a range; each typography candidate must include topic-matched `sample_heading` / `sample_heading_latin` / `sample_body` / `sample_body_latin` preview text, never a fixed unrelated industry sample); enumerable `icons` / `formula_policy` (recommended `id`). **Stage 2 is never skipped** — an active deck/layout template (`strict` adherence included) does not exempt it: the template skin becomes the recommended color / typography candidate and real alternatives fill the remaining cards. Never jump `recommendations.json` from `stage1` to `stage3`: the server refuses to render a skipped stage (the page stays on "deriving…") and the waits exit non-zero until the stages are written in order. The still-open page polls, renders Stage 2, and preserves the user's Stage 1 picks. Then attach to the already-running page; if Windows cleaned up the server, `--wait-only` auto-recovers it on the recorded/default port so the browser reconnects: - ```bash - python3 ${SKILL_DIR}/scripts/confirm_ui/server.py --wait-only --wait-stage stage2 - ``` - This returns when the page writes the stage-2 `result.json` (`status: stage2-confirmed`). On a non-zero exit, re-check `result.json` once before falling back to chat — except a `stage skip detected` error, which is not a page failure: you wrote a stage out of order; rewrite `recommendations.json` with the stage the error names and re-attach. -4. **Re-derive Stage 3 from the confirmed anchors + design system, then wait for the final confirmation.** Read the stage-2 `result.json`. Author the image and execution recommendations and **overwrite** `recommendations.json` with `"stage": "stage3"`: `image_usage` as one or more source ids (`["ai"]`, `["ai","provided"]`, `["web","placeholder"]`, or `["none"]`; `none` is exclusive); `image_strategy.candidates` as **exactly three non-custom** rendering × palette recommendations from h.5 when `image_usage` includes `ai` (the page adds the fourth Custom card itself); enumerable `image_ai_path` / `generation_mode` and `refine_spec` (recommended `id` / boolean). If the recommendation involves several image sources, keep the source list structured in `recommend.image_usage` and write the usage rationale / page-role guidance into `image_notes` (for example, "封面和章节页用 AI 主视觉,产品页优先用户素材,行业背景页可用网络参考"). Write `image_ai_path` only when `image_usage` includes `ai`. Spot-illustration lean is **not** a candidate field here: it derives from the locked `visual_style`'s illustration propensity and is expressed only in the recommendation rationale / `image_notes`, never as a new confirmation field. Generated-image style palettes are **color behavior only**; final image colors follow the confirmed Stage-2 `color`. Custom image-strategy dimensions are handled by the built-in Custom card, are prose-only, and should not promise a gallery reference image. Then attach to the already-running page; `--wait-only` auto-recovers a dead server as above (same 600000 ms budget): - ```bash - python3 ${SKILL_DIR}/scripts/confirm_ui/server.py --wait-only - ``` - This is the ⛔ BLOCKING completion: returns when the page writes the final `result.json` (`status: confirmed`, `stage: final`, carrying Stage 1 + Stage 2 + Stage 3 fields). On a non-zero exit, re-check `result.json` once (a `stage skip detected` error means Stage 2 was never confirmed — go back to step 3, not the chat fallback). Confirmed sizes are **already px** (the system is px-only — no pt anywhere, no conversion): write `result.json` `typography.body_size` / `sizes` into `design_spec.md` / `spec_lock.md` / SVG verbatim. `generation_mode: "split"` / `refine_spec: true` are explicit user choices. -5. **Close the confirm page (Mandatory cleanup — every path).** Shut the server down before leaving Step 4 so it cannot keep holding port 5050 (which Step 6 live preview reuses): - ```bash - python3 ${SKILL_DIR}/scripts/confirm_ui/server.py --shutdown - ``` - **Idempotent and required regardless of whether Confirm was clicked**: clicking the final Confirm already shuts the page down (then a no-op); the chat-fallback path leaves it running. Run it after reading the confirmation, before Step 5. - -**Always also print each stage's recommendations + URL in chat** as the always-valid fallback. **The chat fallback is staged too**: if the page never opens or a wait times out with no fresh result, present Stage 1 in chat → get confirmation → re-derive → present Stage 2 → get confirmation → re-derive → present Stage 3 → get confirmation → take those values. Either path converges. - -**Honoring the confirmation (result.json is authoritative — Mandatory)**: the confirmed values **override your own recommendations** when you write `design_spec.md` / `spec_lock.md`. A user who changed any field changed it on purpose. In particular, map `image_usage` to §VIII `Acquire Via` (its value names differ from §h options — translate). `image_usage` may be either a legacy single string or a Confirm UI multi-select array; for arrays, apply every selected source. `image_notes`, when present, is a user-authored image intent note that Strategist must honor while assigning per-page §VIII rows: - -| `result.json.image_usage` | §VIII `Acquire Via` | h.5 + Step 5 generation | -|---|---|---| -| `ai` | `ai` rows | Run h.5 (lock rendering + palette); Step 5 generates | -| `web` | `web` rows | None | -| `provided` | **`user`** rows | None — never generate | -| `placeholder` | `placeholder` rows | None | -| `none` | no image rows (§h option A) | None | -| Legacy custom prose | Infer the intended rows from the prose | Run h.5 only if the prose includes AI | - -When the confirmed `image_usage` does not include `ai` (and no legacy custom prose includes AI), do **NOT** run h.5, do **NOT** write `ai` rows, and do **NOT** generate images in Step 5 — regardless of what you recommended. `none` is exclusive: if confirmed, write no §VIII image rows. The same "confirmed value wins" rule applies to every field (color → §III, typography → §IV, etc.). - -**Small spot illustrations are a Strategist judgment, not a confirmation field.** The user chooses image *source* through `image_usage`; whether the deck leans into decorative illustrations is anchored by the locked `visual_style`'s **illustration propensity** (`core` / `supportive` / `sparse`), expressed only in the `image_notes` rationale — never a new confirmation control. An explicit user request to use or skip illustrations overrides that default either way; `image_usage: none` still wins (write no illustration rows); and source still comes from `image_usage` — a `core` style does not silently generate AI spots when the user did not pick AI. They are ordinary §VIII image rows (`Type: Illustration` / `Illustration Sheet`) using normal `Acquire Via` values. If the plan needs ≥3 same-family AI spot illustrations, use the `ai` Illustration Sheet + `slice` workflow by default; do not generate one AI image per spot. Full rule + precedence: [`references/strategist.md`](references/strategist.md) §h. Use them on suitable pages and omit them where they would weaken clarity. - -**Upstream override → re-derive untouched downstream (Mandatory — chat-fallback / single-pass path).** On the **three-stage page path this is already handled** (Step 3 re-derives Stage 2 from the user's actual anchors; Step 4 re-derives Stage 3 from the confirmed anchors + design system). It still applies whenever anchors and downstream fields are confirmed **together** — the staged chat fallback collapsed into one bundle, or a legacy single-pass `result.json`. "Confirmed value wins" governs each field's *own* value — never recompute a value the user set (a size, canvas, or palette they edited stays verbatim). But a single-pass `result.json` can carry a changed **anchor** beside downstream fields still holding your original — now incoherent — recommendation (e.g. switched to `dark-tech` while the light palette you proposed is untouched). Before writing the spec, reconcile: when the user changed an anchor, re-derive the downstream fields the user did **not** themselves edit so they realize the new anchor; fields the user pinned stay as confirmed. - -| Anchor the user changed | Re-derive (only the downstream fields the user left at your recommendation) | -|---|---| -| `visual_style` (§d Layer 2 — anchors e–h) | color neutral tiers (§e), icon library / stroke (§f), typography character (§g), image rendering (§h.5) | -| `mode` (§d Layer 1) | outline structure + register (§IX) | -| `delivery_purpose` (§g) | body baseline + per-page density / rhythm (§6.1) | -| `audience` / core message (§c) | tone across e–h, outline emphasis (§IX) | -| `color` HEX (§e) | h.5 palette (re-filter for the new HEX) | - -Reconcile **without a new blocking wait** — fold the coherent values into `design_spec.md` / `spec_lock.md` and state the adjustment in the §8 next-step handoff (e.g. "you switched to `dark-tech`; the light palette you had left no longer fit, so background / accent were re-derived — tell me if you wanted the original"). Canvas is the explicit exception: font sizes are deliberately **not** rescaled on a canvas change (see strategist §g). - -**Opt-out**: if the user has said they don't want the page (e.g. "不要网页" / "just confirm in chat" / "纯聊天确认"), skip the launch entirely (step 2) and present the Strategist confirmation stage in chat as before — steps 1, 3, 4 still apply (recommendations summary in chat; wait; take chat values). - -The page is a **confirmation surface only** — Strategist still authors every recommendation; the page never generates content. - -**Mandatory — split-mode note** (not a separate confirmation): after listing the Strategist confirmation stage details, you MUST append exactly one short line (rendered in the user's language, prefixed with 💡) about generation mode. Pick the variant by qualitative read of upstream-load signals — recommended page count, source-material bulk, whether `topic-research` ran with substantial web-fetch accumulation: - -| Signal read | Line content | -|---|---| -| Heavy (long page count / bulky sources / heavy web-fetch accumulation) | State estimated page count and large source size; recommend switching to [split mode](workflows/resume-execute.md) after Step 5 — stop this chat, open a fresh window and input `继续生成 projects/` to enter the execution session (SVG generation + export); no response or "continue" = default continuous mode. | -| Normal (default) | State scale is moderate, default continuous mode generates in one go; if mid-way window switch is desired, input `继续生成 projects/` after Step 5 to switch to [split mode](workflows/resume-execute.md). | - -This line is required output every run — the user must always see the mode choice exists. Whether to act on it is the user's call. When the Confirm UI is used, this choice also appears as the in-page generation-mode toggle and is captured in `result.json` (`generation_mode`); the chat-summary fallback still prints this line. - -**Mandatory — spec-refinement note** (not a separate confirmation): after the split-mode line, you MUST append one short opt-in line (rendered in the user's language, prefixed with 💡) telling the user they may **refine the spec first** — Strategist will produce the full design spec, then stop for review/revision of any part of it before any generation, via the [refine-spec](workflows/refine-spec.md) workflow. Default is OFF: no request → the spec is written in one go and the pipeline auto-proceeds as usual. Only when the user explicitly asks in chat (e.g. "refine the spec first") or confirms `refine_spec: true` through Confirm UI does the [refine-spec](workflows/refine-spec.md) workflow take over after the Strategist confirmation stage. This line, like the split-mode line, is required output every run — the user must see the choice exists; whether to act on it is theirs. When the Confirm UI is used, this choice also appears as the in-page refine-spec toggle and is captured in `result.json` (`refine_spec`); the chat-summary fallback still prints this line. - -**Formula rendering policy lives inside item 7 (Typography plan)**: - -| Policy | Behavior | -|---|---| -| `mixed` (default) | Strategist renders complex formula-worthy expressions as PNG assets; simple inline expressions remain editable text / Unicode | -| `render-all` | Strategist renders every formula-worthy expression as PNG assets | -| `text-only` | No formula rendering; formulas remain editable text / Unicode | - -After the Strategist confirmation stage is approved and **before outputting `design_spec.md` / `spec_lock.md`**, if the confirmed formula policy is `mixed` or `render-all` and the content contains formula-worthy expressions, Strategist MUST: - -1. Identify explicit LaTeX and any source expressions that should be faithfully structured as formulas. -2. Write `/images/formula_manifest.json` with only the formulas selected for rendering. -3. Run: - ```bash - python3 ${SKILL_DIR}/scripts/latex_render.py - ``` -4. Include the rendered formula PNGs as `Acquire Via: formula`, `Status: Rendered`, `Type: Latex Formula` rows in `design_spec.md §VIII Image Resource List`; also list them in `spec_lock.md images` with `| no-crop`. - -The formula renderer uses a provider fallback chain by default: `codecogs,quicklatex,mathpad,wikimedia`. The first three are color-aware; Wikimedia is an availability fallback. Formula PNGs are transparent by default: manifest `background` is the temporary render matte and transparency-removal reference, not a retained final background unless `transparent: false` is set for that item. Do not scan `spec_lock.md` for `$...$` or `$$...$$`. Dollar-delimited math in source material is only a signal for Strategist; the renderer consumes the explicit manifest. - -If the user provided images or formula PNGs were rendered, run analysis **before outputting the design spec**. It writes `analysis/image_analysis.csv` — the authoritative regenerated image-fact view in the `analysis/` folder, which MUST be read before authoring §VIII: -```bash -python3 ${SKILL_DIR}/scripts/analyze_images.py /images -``` - -> 🔁 **Image facts are regenerated on demand, never a durable store.** `images/` is a live working folder — pictures are extracted from the source at import, the user may drop or replace files at any time, and Step 5 writes web/AI images into it. The single source of truth is therefore the **current contents of `images/`**, and `analysis/image_analysis.csv` is a *regenerated view* of it, not a fact to keep in sync. Re-run `analyze_images.py /images` immediately **before any step that reads image facts** so the view reflects the live folder: before the §h image-usage recommendation (see [strategist.md](references/strategist.md) §h), here before authoring §VIII, after Step 5 acquisition (so web/AI files join the view), and again any time the user says they added or replaced images. This is the staleness strategy — re-derive on use, no cache to invalidate. - -> ⚠️ **Image handling**: NEVER directly read / open / view image files (`.jpg`, `.png`, etc.). All image info comes from `analyze_images.py` output (`analysis/image_analysis.csv`) or the Design Spec's Image Resource List. - -**Output**: -- `/design_spec.md` — human-readable design narrative -- `/spec_lock.md` — machine-readable execution contract (skeleton: `templates/spec_lock_reference.md`); Executor re-reads before every page - -**✅ Checkpoint — Phase deliverables complete, auto-proceed to next step**: -```markdown -## ✅ Strategist Phase Complete -- [x] Read the auto-extracted facts already in `analysis/` (e.g. `source_profile.json`) before the Strategist confirmation stage -- [x] Strategist confirmation stage completed (user confirmed via Confirm UI `result.json` or chat fallback) -- [x] Split-mode note appended below the confirmation fields (heavy or normal variant) -- [x] Spec-refinement opt-in line appended (default OFF; only the user's explicit request enters the refine-spec workflow) -- [x] Design Specification & Content Outline generated -- [x] Execution lock (spec_lock.md) generated -- [ ] **Next**: Auto-proceed to [Image_Generator / Executor] phase -``` - ---- - -### Step 5: Image Acquisition Phase (Conditional) - -🚧 **GATE**: Step 4 complete; Design Specification & Content Outline generated and user confirmed. Any formula rows already have `Acquire Via: formula` and `Status: Rendered`. - -> **Trigger**: At least one row in the resource list has `Acquire Via: ai`, `web`, and/or `slice`. If every row is `user`, `formula`, or `placeholder`, skip to Step 6. - -**Failure recovery**: stop/continue behavior for AI/web/slice/image-readiness failures is defined in [`workflows/failure-recovery.md`](workflows/failure-recovery.md). This Step keeps the acquisition procedure. - -**Always load the common framework**: - -``` -Read references/image-base.md -``` - -Then **lazy-load the path-specific reference** for each row that actually needs it: - -| Acquire Via | Load reference (only if any such row exists) | Run | -|---|---|---| -| `ai` | `references/image-generator.md` | write `/images/image_prompts.json`, then follow `image-generator.md §7 Path Selection` (`image_gen.py --manifest` is **Path A only**) | -| `web` | `references/image-searcher.md` | `python3 ${SKILL_DIR}/scripts/image_search.py ...` (≥2 web rows → `--batch images/image_queries.json`) | -| `slice` | `references/image-generator.md` §4.3 | derived — **after** the parent `ai` sheet row is `Generated`, run `python3 ${SKILL_DIR}/scripts/slice_images.py /images/.png --grid RxC --names ... --trim --alpha` (see workflow step 2.5) | -| `user` / `formula` / `placeholder` | (skip) | (skip) | - -A deck with only `ai` rows never loads `image-searcher.md`; a deck with only `web` rows never loads `image-generator.md`. A mixed deck loads both, processes each row through its own path, and writes both `image_prompts.json` and `image_sources.json`. - -> ⚠️ **In-pipeline ai rows MUST use the manifest contract** — even when only 1 ai row exists. Always write `images/image_prompts.json` first and render `image_prompts.md` with `image_gen.py --render-md`. Then execute the confirmed path from `image-generator.md §7`: `image_gen.py --manifest` is **Path A only**; `host-native` is **Path B** and MUST skip `--manifest`; `manual` writes the prompts and stops for external generation. The positional form (`image_gen.py "prompt" ...`) is reserved for **out-of-pipeline one-off testing / single-image fixups** — it skips manifest + sidecar, leaving no audit trail. - -> ⚠️ **web path — batch multiple rows**: when ≥2 rows are `Acquire Via: web`, write all queries into `images/image_queries.json` and run `image_search.py --batch` once (concurrent acquisition, status written back), instead of one CLI call per row. A single web row may use the positional single-query form. See [image-searcher.md](references/image-searcher.md) §5. - -> 💡 **ai path — spot illustrations as one sheet**: when the §VIII image resource plan needs ≥3 same-family spot illustrations as decorative accessories, generate **one grid sheet** (a single `ai` sheet row) instead of one row per element, then slice it (workflow step 2.5 below). Choose sheet geometry from intended placement: `1xN` / `Nx1` are useful for extreme portrait / landscape cells, and a designed `MxN` grid is valid when its cell ratio fits the planned elements. The sheet row is generated but not placed; each cut **element row** (`Acquire Via: slice`) is placed and must appear in `spec_lock.md images`. One generation = one coherent style across all pieces. Resource contract + the geometry rules: [image-generator.md](references/image-generator.md) §4.3. - -> ⚠️ **Honor the confirmed image source before running any generation command**: the `ai` generation path (Path A = `image_gen.py` API / Path B = host-native tool / Offline Manual) is **not** auto-only — a confirmed choice other than `auto` wins, whether it came from chat (canonical) or, when the page was used, `result.json.image_ai_path`. `host-native` forces Path B even when `IMAGE_BACKEND` is configured; `api` forces Path A; `manual` forces offline. Never run `image_gen.py --manifest` when the confirmed value is `host-native` or `manual`. Full selection rule: [image-generator.md](references/image-generator.md) §7 Path Selection. - -Workflow: - -1. Extract all resource rows from the design spec and group them by `Acquire Via`; rows with `Status: Pending` or `Status: Failed` and `Acquire Via ∈ {ai, web, slice}` must all reach a terminal state before Executor starts -2. Generate prompts (ai rows) and/or run search (web rows) per [image-base.md](references/image-base.md) §3 dispatch table -2.5. **Slice any spot-illustration sheets (only if `slice` rows exist).** For each generated `ai` **sheet** row, run `slice_images.py` (grid + the element `--names` matching the `slice` rows, `--trim --alpha`) so every element file lands in `images/`; mark each `slice` row `Generated`. A sheet still in `Needs-Manual` cannot be sliced — leave its `slice` rows `Needs-Manual` and surface them at the Step 7 readiness gate. Contract: [image-generator.md](references/image-generator.md) §4.3. -3. Verify every row reaches a terminal status: `Generated` (ai success / sliced element), `Sourced` (web success), or `Needs-Manual`. `Failed` is not a terminal status: it means the current run did not generate that item, but the item remains retryable. The agent must resolve every residual `Failed` item by rerunning the confirmed path or marking it `Needs-Manual` before Executor starts -4. Re-derive image facts now that web / AI / sliced files are in the folder — `python3 ${SKILL_DIR}/scripts/analyze_images.py /images` — so `analysis/image_analysis.csv` reflects every acquired image **including the sliced elements** (real measured sizes) before the Executor lays them out. Image facts are regenerated on use, never a stale store (see Step 4's image-facts note). - -**✅ Checkpoint — Confirm acquisition attempted for every row**: -```markdown -## ✅ Image Acquisition Phase Complete -- [x] image_prompts.json created (when any ai rows processed) -- [x] image_prompts.md sidecar rendered (when any ai rows processed) -- [x] image_sources.json created (when any web rows processed) -- [x] Spot-illustration sheets sliced (when any `slice` rows exist); every element file present in `images/` and listed in `spec_lock.md images` -- [x] Each row: status is `Generated` / `Sourced` / `Needs-Manual` (no `Pending` or `Failed` remaining) -- [x] analyze_images.py re-run so image_analysis.csv covers the acquired web / AI / sliced images -``` - -**Default — auto-proceed to Step 6.** Only when the user's Step 4 response explicitly opted into split mode (in chat or via Confirm UI `result.json` with `generation_mode: "split"`), output the planning-session handoff below and stop this conversation: - - ```markdown - ## ✅ Planning Session Complete - - [x] Spec: `design_spec.md`, `spec_lock.md` - - [x] Resources: `sources/`, `images/`, `templates/` - - [ ] **Next**: open a fresh chat window and input `继续生成 projects/` to enter the execution session via the [`resume-execute`](workflows/resume-execute.md) workflow. - ``` - -> On acquisition failure, do NOT halt — follow the Failure Handling rule in [image-base.md](references/image-base.md) §5: retry once, then mark the row `Needs-Manual`, report to user, and continue to the checkpoint above. - ---- - -### Step 6: Executor Phase - -🚧 **GATE**: Step 4 (and Step 5 if triggered) complete; all prerequisite deliverables are ready. - -**Artifact ownership**: `svg_output/` is the author source, `svg_final/` is derived, and image facts come from the regenerated `analysis/image_analysis.csv`; see [`references/artifact-ownership.md`](references/artifact-ownership.md). - -Read the execution references for this deck's locked `mode` + `visual_style` (from `spec_lock.md`): -``` -Read references/executor-base.md # REQUIRED: common guidelines -Read references/shared-standards.md # REQUIRED: SVG/PPT technical constraints -Read references/native-shape-authoring.md # REQUIRED: stock-shape selection and fragment helper contract -Read references/modes/.md # narrative skeleton (spec_lock.md `mode`) -Read references/visual-styles/.md # aesthetic (spec_lock.md `visual_style`) -``` - -> Read executor-base + shared-standards + native-shape-authoring + the one locked mode file + the one locked visual-style file. For `mode: custom` or `visual_style: custom`, skip that preset file and follow `mode_behavior` / `visual_style_behavior` from `spec_lock.md` instead. Never glob `modes/` or `visual-styles/`. - -**Design Parameter Confirmation (Mandatory)**: before the first SVG, output key design parameters from the spec (canvas dimensions, color scheme, font plan, body font size). See executor-base.md §2. - -**Live Preview Auto-Startup (Mandatory)**: before the first SVG, automatically start the browser editor in live mode and keep it running continuously through Executor + Step 7 export: -```bash -python3 ${SKILL_DIR}/scripts/svg_editor/server.py --live --daemon -``` -- Start it immediately when Executor begins; `svg_output/` may be empty. Editor opens at the launch-log URL such as `http://127.0.0.1:5050`; if another project already holds it, the launcher **auto-advances to the next free port** — read the actual URL from the launch log and report that. -- Treat the launch URL as a checkpoint value: before writing the first SVG, either report the actual URL from the launcher or state the launch failure explicitly. Do not silently continue while claiming preview is available. -- Run it as a long-running side process/session; do not wait for it to exit before generating SVG pages. Do not wait for user confirmation after startup. -- **Service must keep running** until one of: (a) the user clicks **Exit preview** in the browser, or (b) the user explicitly asks in chat to stop it. Generation continues even if the user closes the editor. -- **Do NOT read or apply submitted annotations during generation.** Users may annotate at any time, but Executor proceeds without touching them. The window to apply annotations opens only after Step 7 completes — see [`workflows/live-preview.md`](workflows/live-preview.md). -- The editor also supports **staged direct edits** (text content + SVG element attributes previewed immediately, then written to `svg_output/` only when the user clicks **Apply changes**; `Ctrl+Z` / Undo drops staged edits) alongside annotation; re-export stays chat-driven. Full scope and editor details: see [`workflows/live-preview.md`](workflows/live-preview.md) Notes. - -**Pre-generation Batch Read (Mandatory)**: before the first SVG, batch-read every distinct layout SVG referenced in `spec_lock.page_layouts` and every distinct chart SVG referenced in `spec_lock.page_charts` (plus any §VII backup charts). One read per file, up front — do not re-read these during page generation. See executor-base.md §1.0. - -> Image facts: trust the `analysis/image_analysis.csv` regenerated at the end of Step 5. If `images/` changed since (the user swapped or added files), re-run `python3 ${SKILL_DIR}/scripts/analyze_images.py /images` before laying images out — facts are re-derived on use, never a stale store (Step 4 image-facts note). - -**Per-page spec_lock re-read (Mandatory)**: before **each** SVG page, `read_file /spec_lock.md` and use only its colors / fonts / icons / images, plus `pptx_structure.mode` and the per-page `page_rhythm` / `page_charts` lookups. Read `page_layouts` / `page_pptx_layouts` / `pptx_masters` / `pptx_layouts` only on a structured deck/layout template route; they are absent in flat free-design and brand-only projects. Resists context-compression drift on long decks. See executor-base.md §2.1. - -> ⚠️ **Main-agent only**: SVG generation MUST stay in the current main agent — page design depends on full upstream context. Do NOT delegate to sub-agents. -> ⚠️ **Generation rhythm**: generate pages sequentially, one at a time, in the same continuous context. Do NOT batch (e.g., 5 per group). - -**Visual Construction Phase**: generate SVG pages sequentially, one at a time, in one continuous pass → `/svg_output/` - -Each completed SVG MUST be a standalone, complete representation of that slide's visible design. Template SVGs and locked planning artifacts may guide construction, but export must not reach back to them to add visible objects omitted from `svg_output/`. Speaker notes, animation, narration, transitions, and direct native-PPTX workflows remain separately owned artifacts/capabilities. Before drawing a literal stock shape, apply [`native-shape-authoring.md`](references/native-shape-authoring.md): use the stdout-only helper when one PowerPoint preset exactly matches, keep basic SVG primitives for rect/round-rect/ellipse, and keep free SVG for custom semantics. Never infer a preset from contour similarity. - -Template pages MUST start from the complete `page_layouts` SVG, keep all inherited visible objects in `svg_output/`, and preserve the locked root Master/Layout identity plus stable atomic Master/Layout and slot ids. Strict keeps the prototype structure unchanged. Adaptive keeps its Master contract and, when Layout atoms or slot topology/bounds genuinely evolve, assigns a new key/name and updates `spec_lock.md` immediately. Non-mirror fill/stroke/effects/font sizes still follow `spec_lock`. - -Free-design and brand-only pages use `pptx_structure.mode: flat`. Draw the complete page directly: keep backgrounds, repeated chrome, headings, text, images, and decoration as ordinary Slide-local SVG content. Do not plan `pptx_masters` / `pptx_layouts` / `page_pptx_layouts`, do not add root Master/Layout identity, and do not add `data-pptx-layer` or `data-pptx-placeholder` metadata. Group logical content normally with top-level `` elements. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme colors/fonts/title-body defaults, removes stock content placeholders and unused built-in Layouts, and retains only the standard date/footer/slide-number capability hooks. It does not promote or deduplicate page content. - -Do not duplicate specialized identity with `data-pptx-role`. Add it only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by `data-pptx-layer`, `data-pptx-placeholder`, or `data-pptx-native`; such an element needs a stable unique `id`. Do not add generic content roles to ordinary titles, body text, cards, KPIs, diagrams, charts, icons, or images. Full contract: [`references/semantic-svg.md`](references/semantic-svg.md). - -**First-page gate (Mandatory)** — after the **first** SVG page, before drawing page 2: -```bash -python3 ${SKILL_DIR}/scripts/svg_quality_checker.py /svg_output/.svg -``` -Fix every `error` on page 1 first — structural violations are systematic, and a first-page error repeated deck-wide costs a whole-deck rewrite. - -**Quality Check Gate (Mandatory)** — after all SVGs, BEFORE annotation handling and speaker notes: -```bash -python3 ${SKILL_DIR}/scripts/svg_quality_checker.py -``` -- Any `error` (banned SVG features, viewBox mismatch, spec_lock drift, etc.) MUST be fixed before proceeding — return to Visual Construction, regenerate that page, re-run check. -- `warning` entries (low-res image, non-PPT-safe font tail, etc.): fix when straightforward, otherwise acknowledge and release. -- **Structured template routes only — PPTX-structure warnings are the exception.** For each empty-Layout / framing-only-Layout / bare-Master / duplicate-layout-key warning, output one disposition line: either the fix applied (merge keys in `spec_lock.md pptx_layouts` + SVG roots, mark the missing slots/layers) or why the flagged state is intended (e.g. "P01 cover is a fixed composition, zero-slot by design"). Flat free-design and brand-only routes have no positive Master/Layout checkpoint; the checker instead enforces a complete flat lock including colors/fonts/title-body defaults, plus the absence of Master/Layout/layer/placeholder metadata. "0 errors" alone does not pass a structured template gate when such warnings remain undispositioned. -- Run against `svg_output/` (not after `finalize_svg.py` — finalize rewrites SVG and masks violations). - -**Logic Construction Phase**: generate speaker notes → `/notes/total.md` - -**✅ Checkpoint — Confirm all SVGs and notes are fully generated and quality-checked. Run the applicable conditional gates below, then proceed to Step 7**: -```markdown -## ✅ Executor Phase Complete -- [x] Live preview started before the first SVG and kept available at the reported URL -- [x] First-page gate run after page 1 (errors fixed before page 2) -- [x] All SVGs generated to svg_output/ -- [x] svg_quality_checker.py passed (0 errors) -- [x] Structured-template PPTX warnings dispositioned one by one when applicable -- [x] Speaker notes generated at notes/total.md -``` - -> **Chart pages?** If this deck contains data charts (bar / line / pie / radar / etc.), run the standalone [`verify-charts`](workflows/verify-charts.md) workflow before Step 7 to calibrate coordinates. AI models routinely introduce 10–50 px errors when mapping data to pixel positions; verify-charts eliminates that class of error. Skip if no chart pages. - -> **Visual self-check (opt-in)?** If the user explicitly asked for a per-page visual re-pass on the SVGs ("跑一下视觉自检 / 视觉回看", "visual review", "check pages visually", etc.), run the standalone [`visual-review`](workflows/visual-review.md) workflow before Step 7. Do NOT run it by default and do NOT recommend it based on inferred model capability or deck size — trigger is user request only. - ---- - -### Step 7: Post-processing & Export - -🚧 **GATE**: Step 6 complete; all SVGs generated to `svg_output/`; speaker notes `notes/total.md` generated. - -🚧 **Image readiness GATE** (when Step 5 left ai rows in `Needs-Manual`): every expected file must exist at `project/images/` before running 7.1. - -**Failure recovery**: if a Step 7 command fails, fix the owning source artifact and resume from the failed sub-step per [`workflows/failure-recovery.md`](workflows/failure-recovery.md). Do not restart the planning session unless the owning source changed. - -> If files are missing: PAUSE, list the missing filenames, point the user to `images/image_prompts.md` (each `### Image N:` block is paste-ready for ChatGPT / Gemini / Midjourney; auto-generated from `image_prompts.json`) and the required placement `project/images/`. Resume Step 7.1 only after all expected files are in place. `finalize_svg.py` and `svg_to_pptx.py` do not detect missing files at this layer — proceeding with gaps produces a deck with broken image references. - -> **Spot-illustration sheets at this gate**: `slice` element files are **derived**, not placed by the user. If a sheet was `Needs-Manual` (offline), the element files do not exist yet — list the **sheet** filename (`images/.png`) plus its element target names, and instruct: place the sheet, then run the Step 5 `slice_images.py` command for it, then re-run `analyze_images.py`, before resuming 7.1. Never tell the user to hand-place the individual element files — they only come from slicing the sheet. - -> ⚠️ Run the three sub-steps **one at a time** — each must complete successfully before the next. -> ❌ **NEVER** combine them into a single code block or shell invocation. - -Canonical three-command pipeline (this step is the workflow authority; -`references/shared-standards.md` §5 points here): - -**Step 7.1** — Split speaker notes: -```bash -python3 ${SKILL_DIR}/scripts/total_md_split.py -``` - -**Step 7.2** — SVG post-processing (icon embedding / image crop & embed / raster image optimization / text flattening): -```bash -python3 ${SKILL_DIR}/scripts/finalize_svg.py -``` -This mandatory step writes self-contained visual-preview SVGs to `svg_final/`. Those files may be opened directly or manually inserted into PowerPoint as SVG pictures. Default raster handling embeds images at the rendered SVG size budget (`--image-scale 2`, `--max-dimension 2560`); opaque PNG photos may be written as JPEG, and transparent assets remain PNG. The existing EMF/WMF exception still applies: Office vector assets stay externally referenced for lossless native-PPTX passthrough, so the native PPTX remains the source of truth for pages that use them. Use `--no-compress` or a higher `--max-dimension` only for diagnostic / high-fidelity SVG previews. - -**Step 7.3** — Export PPTX (embeds speaker notes by default): -```bash -python3 ${SKILL_DIR}/scripts/svg_to_pptx.py -# Output (default-flow mode): -# exports/_.pptx ← native pptx (canonical output, reads svg_output/) -# backup//svg_output/ ← Executor SVG source backup (always written) -# Add --native-objects to emit real editable chart/table objects instead of flattened shapes: -# exports/__native_charts.pptx ← native chart/table objects (data-pptx-native markers) -# Re-export with --recorded-narration audio (generate-audio workflow) embeds per-slide narration: -# exports/__narrated.pptx ← narrated pptx (embedded audio + auto-advance timings) -``` - -> The native pptx consumes `svg_output/` directly so the converter can preserve -> high-fidelity primitives (icon `` placeholders, image `preserveAspectRatio` -> → native picture crop metadata, rounded rect `rx/ry` → `prstGeom roundRect`). -> Native raster images are optimized by default before writing `ppt/media` -> (`--image-sizing cap`, `--image-max-dimension 2560`, `--image-quality 85`). -> This optimization downscales only oversized full source images; it does not -> crop pixels out of embedded PPTX media, and it does not reduce a small -> placement image merely because it is currently displayed small. Display -> cropping remains editable PPT picture-crop metadata. Add `--no-image-optimize` -> only when the deck must retain original image bytes. Use -> `--image-sizing display --image-scale 2` only for aggressive size reduction. -> The `svg_output/` -> snapshot in `backup//` is always written so the project can be -> re-exported from frozen SVG sources without re-running the LLM. The SVG-rendered -> preview remains the mandatory `svg_final/` artifact from Step 7.2; it is not -> packaged as a second PPTX. Use the default source selection for release -> exports. `-s final` is diagnostic-only -> when comparing conversion behavior against the post-processed SVGs; it does -> not change `svg_output/` ownership or establish a supported release route. - -> **Supported PPTX boundary** — the only supported generated-PPTX path is -> `svg_output/` → the project SVG-to-DrawingML converter → native PPTX. The -> project does not emit an SVG-image PPTX and does not support PowerPoint's -> manual **Convert to Shape** operation on `svg_final/`. Inserted `svg_final/` -> pages remain ordinary SVG pictures unless the user independently accepts the -> results of an unsupported Office conversion. - -> **PPTX structure mode** — release export reads the explicit route from -> `spec_lock.md`. Free-design and brand-only projects use -> `pptx_structure.mode: flat`, omit `pptx_masters` / `pptx_layouts` / -> `page_pptx_layouts` / `page_layouts`, and author no Master/Layout/layer/placeholder metadata in -> SVG. Export keeps every represented object Slide-local while materializing -> one clean project-owned Master and one Blank Layout from the current lock; -> stock content placeholders and unused built-in Layouts are removed; only the -> standard date/footer/slide-number capability hooks remain. -> -> Deck/layout template projects use `pptx_structure.mode: structured`, a -> complete `pptx_masters` roster, one unique `pptx_layouts` definition per -> reusable Layout, and exactly one `page_pptx_layouts` assignment per page. -> A Layout definition records Master key, PowerPoint picker name, and either a -> `P` or `template:` prototype source; an unused Layout uses a template prototype -> and is registered without a published carrier slide. Every SVG -> root repeats the Master/Layout keys and picker names. Master/Layout fixed -> visuals are direct root atoms; a `` is -> forbidden. Reusable slots are direct root `` elements with positive -> design-zone bounds and exactly one compatible carrier. A composite region -> uses only the explicit `object` + `proxy` fallback, and a Layout may -> intentionally have zero slots. -> -> Structured template export creates the declared Masters and Layouts, -> promotes the represented -> atoms, binds slot carriers, installs the locked theme/text defaults, and -> reopens the candidate package to verify Presentation → Master → Layout → -> Slide registration, picker names, static-object rosters, placeholder -> type/index/bounds, carrier bindings, hidden proxies, and zero-slot Layouts. -> It never selects pages, clusters visuals, promotes repeated chrome by -> heuristic, or invents missing structure. Legacy structured/template projects -> using `baseline`, `template`, -> `preserve`, `layout_strategy`, `data-pptx-layout-kind`, -> `distilled`/`utility`, direct atomic placeholders, or incomplete Master -> identity must run -> [`restore-pptx-structure`](workflows/restore-pptx-structure.md) before -> export. - - -> **Template structured export** — `page_layouts` records the complete -> input prototype per page, `pptx_masters` / `pptx_layouts` record the unique -> reusable output roster, and `page_pptx_layouts` records page assignment. -> Strict keeps the prototype -> Master/Layout/slot contract. Adaptive keeps its Master and may assign a new -> Layout identity during page authoring only when fixed Layout atoms or slot -> topology/bounds change; the lock is updated immediately. Non-mirror skin -> remains project-controlled, mirror preserves the reused visual identities, -> and the exporter never reads a template to add visible objects missing from -> `svg_output/`. Raw PPTX templates still route to `template-fill-pptx`; -> reusable template creation goes through `create-template`. - -> **Paragraph editability vs line fidelity** — by default, mergeable dy-stacked -> paragraph blocks collapse into one editable PowerPoint text frame with multiple -> ``, improving body-text editing and resize/reflow behavior. Add `--no-merge` -> only when the user explicitly asks for strict line-layout fidelity or when a -> layout-tight page must keep every dy-stacked line as its own text frame. The -> merge detector is conservative: adjacent lines with different effective font -> sizes retain a paragraph break, and mixed-layout text falls back to per-line frames. -> A multiline -> text carrier inside a slot must remain one native text frame; do not combine -> it with `--no-merge`. Strict-line text stays Slide-local rather than claiming -> one PowerPoint placeholder. - -> **Native table/chart objects** — supported data charts and pure text-grid -> tables carry `data-pptx-native` markers by default (Executor transcribes -> them at draw time; see `references/executor-base.md` §3.2) and the markers -> stay dormant. -> Add `--native-objects` only when the user explicitly wants -> PowerPoint-editable native tables/charts and accepts that those objects may -> render differently across PowerPoint / Keynote / LibreOffice / WPS; marker-local -> details not represented by native metadata may be omitted. This is a lossy -> editable-first contract, not a reason to disable an otherwise supported marker. Without -> the flag, marked groups export through their SVG fallback children like -> ordinary SVG content. Imported objects that carry -> `data-pptx-native-status` are fallback-only; the quality checker and -> `--native-objects` export surface their reason as warnings rather than silently -> claiming editability. An imported chart with no baked preview is a different -> case: `data-pptx-visual-status="placeholder"` plus -> `data-pptx-route-status="reconstruction-only"` records a diagnostic route. -> Default export keeps that placeholder with a warning; when the same group has -> a valid active `data-pptx-native="chart"` payload, `--native-objects` may still -> reconstruct the editable chart. Invalid or contradictory status declarations -> remain export errors. For supported parsed classic families, the importer -> instead emits a deterministic visible fallback with -> `data-pptx-visual-status="normalized"`; this is readable reconstruction, not -> a claim of Office pixel parity. Active imported table/chart markers also carry -> `data-pptx-fallback-sha256`. If their fallback, reachable SVG fragment -> definition, local reference target, or marker transform changes later, default -> export keeps that SVG, the mandatory quality checker warns, and -> `--native-objects` fails rather than discard the edit. Legacy markers -> without a baseline remain native-compatible and only warn that stale detection -> is unavailable. -> Imported table markers may also cover the verified narrow P2 subset: -> exact physical row/grid topology, canonical rectangular merges with blank -> covered cells, safe per-side borders, plain multi-paragraph cells, and closed -> run-level rich text. A rich paragraph contains non-empty `runs`; each run -> requires `text` and may use only -> `bold` / `italic` / `underline` / `strike` / `color` / `font_size` / -> `font_family` / `lang` / `alt_lang`. Presentation-only source run XML -> normalizes, while relationship-bearing text, extensions, line breaks, fields, -> tabs, bullets, broken text topology, noncanonical merges, and unsafe direct -> formatting remain fallback-only. Imported classic charts -> additionally cover verified column/line/area combos, canonical OHLC stock, -> area date-axis cases, verified scatter/bubble axes, radar, safe `of_pie` -> `serLines`, and the closed axis/title/legend plus bar-gap/overlap normalization -> cases. The importer also accepts the seven closed ChartEx data models: -> treemap, sunburst, histogram, pareto, box-whisker, waterfall, and funnel. -> ChartEx data topology is retained for native read-back, but style, axis, -> labels, and binning details may normalize. These additions do not create a -> full `AxisSpec`, arbitrary ChartEx import, arbitrary rich OOXML, or new -> normalized-renderer coverage; unmodeled semantics continue to fail closed -> without reducing existing active-marker SVG-to-native conversion. - -**Optional animation flags** (page transitions are on by default; per-element entrance is off by default — turn it on only when the user asks for it): -- `-t ` — page transition. Default `fade`. Options: `fade` / `push` / `wipe` / `split` / `strips` / `cover` / `random` / `none`. `none` removes only the visual transition; an explicit automatic advance remains valid. -- `-a ` — per-element entrance animation. **Default `none`** — pages appear as a whole, no auto-firing element builds (the unsolicited cascade reads as the "AI deck" tell). Opt in with `auto` (map effect from group id: chart→wipe, card-/step-/pillar-→fly, title/takeaway→fade; image-like ids `hero` / `figure-` / `image` / `img-` / `kpi` cycle a richer pool — zoom / dissolve / circle / box / diamond / wheel — so multiple images vary across the deck), a specific effect like `fade`, or `mixed` for the legacy 16-effect cycle. Requires top-level `` groups (already required by Executor). -- `--animation-trigger {on-click,with-previous,after-previous}` — Start mode (matches PowerPoint's animation-pane Start dropdown). Default `after-previous` (click-free cascade; pace via `--animation-stagger`). Use `on-click` for presenter-paced reveals, or `with-previous` for all-at-once. -- `--animation-config ` — optional object-level sidecar. Default: `/animations.json` when present. -- `--auto-advance ` — kiosk-style auto-play. Click remains enabled, so click or timer may advance the slide. - -**Animation compatibility gate**: the default element animation remains `none`. -When animation is enabled, unknown effects/modes/triggers, invalid numeric or -order values, missing slide/group references, and explicit structural layer, -static-role, or static-placeholder targets fail export; they never downgrade -or disappear silently. An explicit -sidecar group may override only the legacy chrome-name heuristic. `random` -resolution is stable for the same effective input; with `--conversion-trace`, -its resolved rows are written to the trace. Generated export performs per-slide semantic -read-back plus package timing/`p:cTn`/`p:spTgt` validation. Narration merges -audio timing into the existing DOM and preserves animation rows. Direct-PPTX -routes preserve source object animation, compare its object-animation fingerprint -before/after allowed edits, and validate structure; they do not author -animation effects. The exact 22 tuples and OOXML rules live in -[`scripts/docs/pptx-animations.md`](scripts/docs/pptx-animations.md). - -**Optional custom animations** (only when the user asks to tune animation order/effects/timing for specific objects): - -Run the standalone [`customize-animations`](workflows/customize-animations.md) workflow. Default export applies page transitions but no per-element entrance animation; create `animations.json` (or pass `-a auto`) only when the user asks for element animation or object-level customization. - -**Optional recorded narration** (only when the user asks for narrated/video export): - -Run the standalone [`generate-audio`](workflows/generate-audio.md) workflow. The AI picks a narration backend (`edge` by default, or a configured cloud provider such as ElevenLabs / MiniMax / Qwen / CosyVoice for high-quality or cloned voices), asks the user once (backend + voice + rate/settings + embed-or-not, all with recommended values), then executes `notes_to_audio.py` and (if chosen) re-exports the PPTX with `--recorded-narration audio`. - -Do NOT call `notes_to_audio.py` directly without going through the workflow — `--voice` / `--voice-id` is required and the workflow produces the locale/provider-aware recommendation that makes the choice meaningful. - -Full effect list, anchor logic, and limits: [`references/animations.md`](references/animations.md). -The compatibility contract covers PowerPoint OOXML; do not promise identical -animation playback in Keynote or other presentation applications. - -> ❌ **NEVER** substitute `cp` for `finalize_svg.py` — finalize performs multiple critical processing steps -> ❌ **NEVER** use `-s final` for a release export. It is a diagnostic comparison only; the supported native route reads `svg_output/`. - -> **Post-export annotation window**: the preview service from Step 6 typically remains running after export. If the user submitted annotations in the browser (during Executor or after export) and now asks to apply them — they may quote the browser prompt (`Changes saved to svg_output...` / `修改已保存到 svg_output...`), say "apply my annotations" / "应用注解" / equivalent — run [`live-preview`](workflows/live-preview.md) Step 2 to apply and re-export. Annotations submitted during generation are also handled here, not earlier. - -> **Direct edits in the browser**: the user may also stage text / SVG attribute edits in the preview. These land in `svg_output/` only after the user clicks **Apply changes**. If they ask to "re-export" / "重新导出" after applying such edits, just re-run Step 7.2–7.3 (finalize + export); no annotation-application step is needed unless they also saved AI-needed annotations. - -> **Preview not running?** Any time the user mentions "live preview", "preview", "看效果", or wants to select/click a slide element and the service is not running, run [`live-preview`](workflows/live-preview.md) Step 1 to start it. If the service is already running, just point them at the URL — do not restart. - ---- - -## Role Switching Protocol - -Before switching roles, **MUST first read** the corresponding reference file. Output marker: +## Global Execution Discipline + +1. **Serial execution** — Follow the selected authority's steps in order. A completed non-blocking step may continue directly to the next eligible step. +2. **Blocking means stop** — At every `⛔ BLOCKING` gate, wait for explicit user confirmation. Do not decide on the user's behalf. +3. **No cross-phase bundling** — Do not combine work across an unclosed gate. Once the route's final user gate closes, later non-blocking steps may continue automatically. +4. **Gate before entry** — Verify every listed prerequisite before entering a step. +5. **No speculative execution** — Do not prepare later-phase artifacts before their owning step. +6. **Deterministic routing** — Do not add a route-choice question when [`routing.md`](workflows/routing.md) resolves the request. If a route prerequisite is missing, state it and stop that route. +7. **Owning-source recovery** — On failure, repair or regenerate the owning source artifact and resume from the route's declared pointer. Do not silently downgrade a required artifact. + +## Global Communication Rules + +- Match the user's language and source language unless the user explicitly overrides it. +- Localize user-facing option labels and explanations. Keep exact enum IDs or field names when needed for precision. +- Keep `design_spec.md` section headings and field names in the template's original English; content values may use the user's language. +- Before switching roles, read the corresponding role reference and output: ```markdown ## [Role Switch: ] @@ -910,22 +50,9 @@ Before switching roles, **MUST first read** the corresponding reference file. Ou --- -## Reference Resources +## Repository Compatibility -| Resource | Path | -|----------|------| -| Shared technical constraints | `references/shared-standards.md` | -| Native preset shape authoring | `references/native-shape-authoring.md` | -| Semantic SVG marker contract | `references/semantic-svg.md` | -| Canvas format specification | `references/canvas-formats.md` | -| Image-text layout patterns (Primary structures + Modifier layers — combine freely) | `references/image-layout-patterns.md` | -| Image layout sizing (math for side-by-side container dimensions) | `references/image-layout-spec.md` | -| SVG image embedding | `references/svg-image-embedding.md` | -| Icon library | `templates/icons/README.md` | - ---- - -## Notes - -- Local preview: `python3 -m http.server -d /svg_final 8000` -- **Troubleshooting**: on generation issues (layout overflow, export errors, blank images, etc.), check `docs/faq.md` for known solutions +- This package is a workflow/skill, not a generic application scaffold. Do not create `.worktrees/`, `tests/`, branch workflows, or generic engineering structure by default. +- Keep required workflow, reference, script, and template documentation inside this Skill directory. +- Repository-level documents may point into the package; package runtime files must not depend on repository-level instructions. +- On Windows, if a documented `python3 ...` command is unavailable, rerun the same command with `python`. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/ai-image-comparison/README.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/ai-image-comparison/README.md index 3252dba3..dd69a724 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/ai-image-comparison/README.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/ai-image-comparison/README.md @@ -1,9 +1,9 @@ -# AI Image Comparison — Three-Dimension Reference Gallery +# AI Image Comparison — Reference Gallery -PPT Master's AI images are governed by three orthogonal dimensions: **rendering (visual style) × palette (color behavior) × type (internal composition)**. +This directory preserves rendering, legacy palette, and type comparison assets. The current Confirm UI displays **rendering only**; deck colors come directly from the selected PPT color system. The palette gallery remains for legacy diagnostics and must not become a second confirmation control. This directory uses **controlled-variable comparison** — vary one dimension while holding the other two fixed — so you can see exactly what each dimension contributes. -> This is **not** an example project (see `examples/` for those). It is a dimension-selection reference for the Strategist role and end users when picking AI image parameters. +> This is **not** an example project. The rendering set remains a selection reference; the palette set is legacy diagnostic material, and the type set is an internal composition reference. ## The three comparison sets @@ -58,8 +58,8 @@ Generated images land in the corresponding subdirectory. Each item's `status` in | If you are deciding... | Look at | |---|---| -| Which rendering to lock in Strategist h.5 | `rendering/` — scan all 20 side by side; pick the visual temperament that matches the deck | -| Which palette pairs best with your chosen rendering | `palette/` — see how color behavior shifts the same subject | +| Which rendering to lock in [`strategist-image.md`](../strategist-image.md) §2 | `rendering/` — scan all 20 side by side; pick the visual temperament that matches the deck | +| Diagnosing a legacy palette lock or comparison asset | `palette/` — see how historical color behaviors shift the same subject; do not expose it as a new-flow choice | | Which type fits a specific image's purpose | `type/` — match the internal composition to the page's content shape | -> The three sets are intentionally independent. When deciding rendering, do not look at the palette set — its varying colors will distort your judgment of pure rendering style. +> The three sets are intentionally independent. When deciding rendering in the current flow, use only `rendering/`; the legacy palette set must not influence or reintroduce a separate color decision. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md index 44c5ca7b..854205df 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/animations.md @@ -1,8 +1,8 @@ # Page Transitions & Per-Element Animations -PPT Master's exported PPTX supports **page transitions** and **per-element -entrance animations** as real PowerPoint OOXML. Other applications may -interpret timing differently; this contract makes no unconditional Keynote guarantee. +Execution contract for generated-PPTX **page transitions** and **per-element +entrance animations**. This file owns defaults, sidecar semantics, anchor +selection, validation, and package read-back. ## 1. Defaults @@ -19,7 +19,7 @@ To regenerate a deck with different settings, rerun `svg_to_pptx.py` against the Per-element animation is off by default. To enable it deck-wide, pass `-a auto` at export (no config needed). When a deck instead needs specific object timing — for example title first, chart second, annotation last — use the optional `animations.json` sidecar. The SVG remains static visual source; the sidecar only controls PPTX export behavior. -Run the standalone [`customize-animations`](../workflows/customize-animations.md) workflow when the user asks to tune animation order, effects, timing, or object-level reveals. +Run the [`customize-animations`](../workflows/stages/customize-animations.md) post-processing stage when the user asks to tune animation order, effects, timing, or object-level reveals. ```bash # Build an editable scaffold from real top-level anchors @@ -67,6 +67,12 @@ Rules: - An explicit sidecar group may override the legacy chrome-name heuristic, but it cannot override `data-pptx-layer` or an explicit static role/placeholder marker. - Unknown effects, modes, or triggers and invalid numeric/order fields fail validation; no fallback effect is substituted. +**Declared inheritance for omitted sidecar fields**: + +- The whole `animations.json` artifact is optional. When absent, normal exporter CLI resolution applies. +- In any existing sparse sidecar, an omitted slide transition/animation property inherits the matching `defaults.transition` / `defaults.animation` property; when that defaults property is also absent, normal exporter CLI resolution applies. Explicit CLI overrides still win. Current authoring writes each slide's complete transition and animation blocks. +- A group override inherits `effect` and `duration` from its resolved slide animation; omitted `order` and `delay` use the exporter's sidecar resolution. + --- ## 3. Page Transitions @@ -150,7 +156,7 @@ Flags: ## 5. Anchor Logic — Top-Level `` -Per-element animations are anchored on **top-level `` content groups** in the SVG (e.g. ``, ``). One group produces one animation-pane entrance row; whether that row needs a click depends on the selected Start mode. +Per-element animations are anchored on **top-level `` content groups** in the SVG (e.g. ``, ``). IDs must be unique within the page. One group produces one animation-pane entrance row; whether that row needs a click depends on the selected Start mode. Nested implementation groups may remain anonymous because the sidecar does not target them. Aim for **3–8 content groups per slide**. This is also the granularity PowerPoint uses for group-select / group-move, so it improves editing ergonomics regardless of animation. @@ -161,7 +167,7 @@ Aim for **3–8 content groups per slide**. This is also the granularity PowerPo - ≤ 8 visible top-level primitives → each becomes one anchor (capped to avoid 70+ atom cascades on dense pages). - > 8 → animation is skipped on that slide. The slide still renders, just without entrance animation. -Executors should wrap logical sections in `` regardless of whether you plan to animate. The Executor reference (`skills/ppt-master/references/shared-standards.md`) requires it. +Executors should wrap logical sections in `` regardless of whether you plan to animate. [`shared-standards-core.md`](./shared-standards-core.md) requires it. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md index c9f9789f..6b42bd20 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/artifact-ownership.md @@ -11,24 +11,37 @@ Global artifact ownership rules for PPT Master projects. | Artifact | Owner | Role | Read/write contract | |---|---|---|---| | `sources/` content-type files | Content contract | Main pipeline source for text, tables, chart data values, and SmartArt node wording | Strategist reads content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`) and judges by content; do not replace values with PPTX geometry JSON in the main pipeline | +| `sources/*.facts.json` | Fact provenance contract | Stable external `fact_id` → claim/source mapping created by topic research | Strategist cites IDs in §IX; Executor resolves them for visible footnotes / natural notes attribution. Scenario data never enters this file. | | `sources/` converted-source originals | Source archive | Imported source files that have a converted content contract (`.pdf` / `.pptx` / `.docx` / `.xlsx` / `.html` / `.epub` / `.tex` / `.rst` / `.ipynb` / `.typ`, etc.) and source-adjacent extracted assets | Read via the converted `.md` in the main pipeline; direct-PPTX workflows read the `.pptx` by route | | `sources/*.conversion_profile.json`, `sources/*_files/image_manifest.json` | Pipeline sidecar | Conversion audit record / asset index | NOT read as slide content; open only to audit a conversion or resolve assets | | `analysis/source_profile.json` | Machine fact index | Compact Strategist-facing PPTX intake digest | Main pipeline reads as factual context and recommendation candidates | | `analysis/.identity.json` | Native deck identity facts | Canvas, theme palette/fonts, observed usage | Read selectively when detailed identity facts are needed | | `analysis/.slide_library.json` | Native PPTX structure facts | Text slots, geometry, native tables, native chart caches, SmartArt nodes/connections | Direct PPTX workflows use as native fill/structure contract | | `analysis/image_analysis.csv` | Regenerated image fact view | Measured facts about the current `images/` folder | Re-run `analyze_images.py` before reading image facts after changes | -| `design_spec.md` | Human design narrative | Explains design intent, outline, rationale, and resource plan | Strategist writes; humans and later roles read for intent | -| `spec_lock.md` | Execution contract | Literal colors, typography, icons, images, page rhythm, charts, and the route's PowerPoint structure mode; deck/layout template routes additionally own input prototypes, the Master roster, and the complete page-to-Master/Layout mapping | Strategist writes the route-specific contract; Executor re-reads it before every page and may add a new adaptive Layout identity only on a structured template route while authoring the page that first needs it; `restore-pptx-structure` owns legacy template migration | +| `design_spec.md` | Strategist design authority | Human-readable design intent, outline, rationale, and resource plan authored from the final confirmation plus source analysis | Strategist writes and audits it against every confirmed field before lock projection; humans and later roles read it for intent | +| `spec_lock.md` | Execution projection | Machine-readable colors, typography, icons, images, page rhythm, charts, `template_reuse_scope`, and the route's PowerPoint structure mode; mirror/layout template routes additionally own input prototypes, the Master roster, and the complete page-to-Master/Layout mapping | Strategist projects the route-specific contract from the audited Design Spec without making another design decision; `page-context` deliberately repeats its compact global projection per page as an anti-drift guard and adds current-page routing values. Executor may add a new adaptive Layout identity only on a structured mirror/layout route while authoring the page that first needs it. | +| `project_manager.py page-context` stdout | Derived per-page context | Read-only model-facing lock projection + current-page delta + fingerprints for large references | Generate immediately before each page without `--bundle`; never edit or persist it as a replacement source of truth. `global` is the bounded repeated lock guard. `reference_set` carries path/SHA/load policy for project/template Design Specs and selected prototype/chart SVGs, but never appends their payloads. | +| `analysis/page-context/P.usage.json` | Derived context telemetry | Actual compact page-context size plus hashes of owning inputs/references | `page-context --record-usage` deterministically replaces that page's snapshot; `page-context-report` summarizes current snapshots and unique references. Use token data to evaluate context cost, never as content or an execution contract. | | `images/` | Runtime image pool | User, extracted, AI, web, formula, slice, EMF/WMF assets | Step 5 writes here; `analysis/image_analysis.csv` derives from current contents | | `icons/` | Project icon inventory | Icons copied by `icon_sync.py` for this project | Executor uses locked project icons; exporter may fall back to global library only as documented | -| `templates/` | Project template reference | Step 3 imported specs, template SVGs, and non-image assets | Strategist/Executor read only when Step 3 is triggered | +| `templates/` | Project template reference | Step 3 imported specs, template SVGs, and non-image assets | Strategist reads the template Design Spec and actual SVG roster during planning. Continuous Executor reuses that context; fresh Executor reads the Design Spec once and each selected complete SVG only before first use or after its SHA changes. | +| `templates/template_execution_manifest.json` (`v1`) + `templates/template_execution/*.text-slots.json` (`v2-min`) | Derived template index | Compact prototype/source-import summary plus per-prototype text-slot diagnostics; the sidecar integrity hash is tool-only | Materialization may publish these deterministic records, but page-context does not inject or require them and models do not read them during page authoring. The complete prototype SVG is the sole visual/template authority; never author from either JSON artifact. | +| `/svg/` | Imported native-payload backing | Complete PPTX-derived metadata, hidden carriers, fallback evidence, and source structure | Keep immutable; create-template materialization may resolve a validated source ref against these files, but models do not edit or bulk-read them | +| `/svg-flat/` | Optional complete-page verification backing | Self-contained visual composition generated only by explicit `--inheritance-mode both` | Keep immutable when requested; never use as authoring or materialization input | +| `/authoring-svg/` | Template-creation author source | Layered editable SVG IR for imported Master, Layout, and Slide objects | Template_Designer reads and edits this bundle; final template SVGs are materialized from it rather than copied from lossless backing | +| `/authoring-svg/authoring_summary.json` | Model-readable authoring index | Current SVG roster plus compact per-file canvas, size, text, image, vector, placeholder, and source-ref counts | Models read this before authoring SVGs; regenerate after direct IR edits | +| `/authoring-svg/authoring_manifest.json` | Tool-only authoring provenance contract | Per-document source/authoring hashes and document-local source-ref paths | Generated atomically with the IR; materialization validates it before reusing native payload; never load it into model context or duplicate raw payload here | +| `/authoring-svg-flat/` | Optional complete-page verification IR | Self-contained page composition view with its own summary and provenance manifest | Generate only from an explicitly requested `svg-flat/`; use to verify composition, while layered `authoring-svg/` remains the canonical editable source | +| `/icons/imported/` | Imported vector pool | One canonical copy of every factored vector subtree | Authoring SVGs reference `data-icon="imported/"`; vector inventories retain source refs so expansion re-establishes IR identity | | `confirm_ui/recommendations.json` | Confirmation proposal | Strategist-authored confirmation payload | Confirm UI reads; rewritten between Stage 1, Stage 2, and Stage 3 | | `confirm_ui/result.json` | Confirmation result | User-confirmed values | Strategist treats final result as authoritative over recommendations | | `svg_output/` | Page-design author source | Main-agent handwritten SVG pages containing the complete visible design | Quality checker and native PPTX export read this as the canonical visual/page-layout source; templates and locks do not add missing visible objects at export | | `notes/total.md` | Speaker-note source | Complete notes before splitting | Step 6 writes; Step 7.1 splits | | `notes/slide_*.md` | Split notes | Per-slide notes generated from `total.md` | Derived by `total_md_split.py` | | `svg_final/` | Derived visual preview | Self-contained post-processed SVGs that may be opened directly or inserted as SVG pictures | Rebuild from `svg_output/` with `finalize_svg.py`; do not use as a supported PPTX source | -| `exports/` | Delivery artifacts | Native DrawingML PPTX and its explicit native-object/narration variants | Step 7.3 writes final outputs from `svg_output/` | +| `validation/svg_quality_report.json` | Quality provenance | Final SVG gate split into blocking / introduced / inherited / source-import categories, bound to the checked SVG bytes by SHA-256 | `svg_quality_checker.py --stage final --json` writes before export; the exporter reads it programmatically and links it only when the export-source fingerprint matches. Agents use successful command output and do not load the full JSON except for targeted failure/audit reads. | +| `validation/.report.json` | Published-package audit | PPTX package/resource postflight status, part counts, and quality-gate linkage | Step 7.3 writes after the PPTX passes package validation and emits a compact `[POSTFLIGHT]` receipt. Agents use the receipt on routine success and keep the full JSON cold unless targeted failure/audit evidence is required. | +| `exports/` | Delivery artifacts | Native DrawingML PPTX and explicit native-object/narration variants | Step 7.3 writes only final deliverables from `svg_output/`. | | `backup//svg_output/` | Frozen author-source archive | Re-export source without re-running LLM | `svg_to_pptx.py` writes a snapshot during export | | `animations.json` | Optional animation config | Object-level animation sidecar | Created only by explicit animation workflow/request | @@ -41,10 +54,12 @@ Global artifact ownership rules for PPT Master projects. | Content values | Main pipeline text, tables, chart values, and SmartArt node wording come from content-type files in `sources/` (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`), not from `slide_library.json`. | | Sources read policy | In `sources/`, read content-type files (`.md` / `.markdown` / `.txt` / `.csv` / `.tsv` / `.json` / `.jsonl` / `.yaml` / `.yml`) and judge by content — a `.json` / `.csv` may be core content or just data. Exclude known sidecars: `*.conversion_profile.json` and `*_files/image_manifest.json`. `analysis/` facts (`source_profile.json`, `.slide_library.json`) are read per Step 4 / direct-PPTX workflow, not in the `sources/` content scan. | | PPTX structure | `slide_library.json` owns native geometry, slot facts, and SmartArt layout/relationships for direct PPTX workflows. | -| Design contract | `design_spec.md` explains; `spec_lock.md` executes. Executor must not infer execution values from prose. | -| Free-design / brand-only packaging authority | `spec_lock.md` declares `pptx_structure.mode: flat` and omits `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. `svg_output/` owns the complete Slide-local visual design without root Master/Layout identity, fixed-layer ownership, or placeholder metadata. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme defaults, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. | -| Template structure authority | `page_layouts` owns each page's authoring-input prototype. `pptx_masters` / `pptx_layouts` own the unique reusable output definitions, while `page_pptx_layouts` owns page assignment. Strict keeps the prototype contract; adaptive may create a new Layout definition during page authoring and updates its assignment immediately. Unused definitions may register without a published Slide. Templates validate provenance but never add missing visible page objects during export. | -| Legacy structure migration | [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) owns conversion of old unmapped/distilled/preserve structured projects and legacy template packages into the current template contract. An intentional free-design or brand-only `flat` project is not a migration input. The exporter does not migrate or visually cluster legacy template structure. | +| Design contract | Final confirmation → audited `design_spec.md` → projected `spec_lock.md`. Executor may apply projected `Template Application` prose to visible template content, but never infer lock values from it. On divergence, repair the lock from the Design Spec unless the Design Spec itself fails confirmation fidelity. | +| Flat packaging authority | Free-design, brand-only, and `template_reuse_scope: style` declare `pptx_structure.mode: flat` and omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. `svg_output/` owns the complete Slide-local visual design without root Master/Layout identity, fixed-layer ownership, or placeholder metadata. Export materializes one clean project-owned Master plus one Blank Layout, applies the locked theme defaults, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. | +| Template structure authority | `template_reuse_scope: mirror|layout` uses `page_layouts` for each page's authoring-input prototype. `pptx_masters` / `pptx_layouts` own the unique reusable output definitions, while `page_pptx_layouts` owns page assignment. Strict keeps the prototype contract; adaptive may create a new Layout definition during page authoring and updates its assignment immediately. Mirror additionally preserves literal visuals/text topology; layout allows project-controlled reflow/re-skinning. Unused definitions may register without a published Slide. Templates validate provenance but never add missing visible page objects during export. | +| Fact classes | External facts resolve through `sources/*.facts.json`; invented demo KPIs/targets/internal ratios are labeled `scenario` in `design_spec.md §IX` and visibly in the page. Never promote scenario data into the external fact registry. | +| Imported-template authoring | Editable SVGs under `authoring-svg/` own create-template edits, `authoring_summary.json` owns model-facing orientation, and `authoring_manifest.json` owns tool-only source-object identity. Lossless `svg/` owns immutable native payload and fallback evidence; optional `svg-flat/` owns only complete-page verification. Materialized `templates/*.svg` own the validated deliverable contract and contain no IR-only source refs. | +| Legacy template input | Old unmapped/distilled/preserve structured projects and incomplete template packages are not migrated in place. [`create-template`](../workflows/create-template.md) authors a new current workspace: original PPTX Type A may preserve existing native topology in mirror; legacy SVG-only Type B is visual reference for `standard` / `fidelity`. An intentional free-design or brand-only `flat` project is already current. The exporter does not migrate or visually cluster legacy structure. | | Image facts | `images/` is live state; `analysis/image_analysis.csv` is a regenerated view, not a durable cache. | | SVG source | `svg_output/` is the only author source for generated pages. | | Page-design closure | On SVG-authoring routes, every visible exported-slide object exists in the corresponding page SVG or an explicitly referenced visual asset. | @@ -52,9 +67,9 @@ Global artifact ownership rules for PPT Master projects. | Post-processed SVG | `svg_final/` is disposable, must be rebuilt in Step 7.2, and serves only as a self-contained visual preview / manually insertable SVG picture. | | Export source | The only supported generated-PPTX route reads `svg_output/` through the project SVG-to-DrawingML converter. A diagnostic `-s final` override does not change ownership or create a supported release route. | | Shape-conversion boundary | PowerPoint's manual Convert-to-Shape operation on `svg_final/` is outside the project compatibility contract. | -| Confirmation | Final `confirm_ui/result.json` or chat confirmation overrides recommendations. | +| Confirmation | Final `confirm_ui/result.json` or chat confirmation overrides recommendations and is the mandatory input contract for `design_spec.md`; `spec_lock.md` is derived only after that Design Spec passes confirmation-fidelity review. | -**Forbidden - mixed ownership**: Do not copy chart values from Markdown into `analysis/` by hand, do not edit `svg_final/` as the source of a fix, and do not treat `design_spec.md` prose as a replacement for `spec_lock.md`. +**Forbidden - mixed ownership**: Do not copy chart values from Markdown into `analysis/` by hand, do not edit `svg_final/` as the source of a fix, do not edit imported lossless SVGs instead of their authoring IR, and do not treat `design_spec.md` prose as a replacement for `spec_lock.md`. --- @@ -63,8 +78,10 @@ Global artifact ownership rules for PPT Master projects. | Derived artifact | Regenerate from | Command / owner | |---|---|---| | `analysis/image_analysis.csv` | Current `images/` | `python3 ${SKILL_DIR}/scripts/analyze_images.py /images` | +| `/authoring-svg/authoring_summary.json` | Current authoring SVGs plus tool-only manifest roster | `python3 ${SKILL_DIR}/scripts/svg_authoring_view.py /authoring-svg --refresh-summary`; in-place vector/picture extraction refreshes it automatically | | `notes/slide_*.md` | `notes/total.md` | `python3 ${SKILL_DIR}/scripts/total_md_split.py ` | | `svg_final/` | `svg_output/` plus project assets | `python3 ${SKILL_DIR}/scripts/finalize_svg.py ` | -| Native PPTX | `svg_output/` plus notes/assets | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py ` | +| `validation/svg_quality_report.json` | `svg_output/`, locks, template provenance | `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py --stage final --json` | +| Native PPTX + `validation/.report.json` | `svg_output/` plus notes/assets and final quality report | `python3 ${SKILL_DIR}/scripts/svg_to_pptx.py ` | **Default - regenerate derived views**: When a source artifact changes, regenerate the derived artifact at the owning step instead of patching the derived file directly. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md index 0be72bf4..d801b1b7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/canvas-formats.md @@ -1,6 +1,7 @@ # Canvas Format Specification -> See shared-standards.md for SVG basic rules. +> See [`shared-standards-core.md`](./shared-standards-core.md) §4.1 for the normative root +> `viewBox` grammar, compatibility spellings, and fail-closed validation rules. ## Format Quick Reference @@ -15,6 +16,13 @@ | `banner` | Landscape Banner | `1920x1080` | `0 0 1920 1080` | 16:9 | Web banners, digital screens | | `a4` | A4 Print | `1240x1754` | `0 0 1240 1754` | 1:sqrt(2) | Print posters, flyers | +The table lists canonical root spellings. New custom canvases likewise use +`0 0 W H` with positive integer pixels. A fractional positive canvas is accepted +only as compatible input for an imported custom PowerPoint slide size; it is not +the default authoring form. All pages and internal Layout prototypes in one +export use the same numeric canvas and stay within PowerPoint's supported slide +range (914,400–51,206,400 EMU per side, approximately 96–5,376 SVG px). + `ppt169` is the canonical PPT wide-screen canvas in this repo: `1280x720`, not any arbitrary 16:9 size. Same-ratio canvases such as `banner` (`1920x1080`) must be treated as different coordinate systems. ## Format Selection Decision Tree @@ -63,7 +71,7 @@ Content purpose? | Story | — | Middle 1500px | Top safe zone 120px, bottom 180px | | WeChat Article Header | Center/left-aligned 48-72px | — | Image on right or as background | -> **Body font baseline scales with canvas and delivery purpose** — a PPT 16:9 baseline confirmed for read-close / business / projection cannot be carried onto tall canvases (Xiaohongshu / Story / A4). Pick the baseline from the confirmed canvas, not the recommended one; see the per-canvas px anchors in [`strategist.md`](strategist.md) §g "Font Size Ramp" (the system is px-only — all sizes are unitless px on every canvas). +> **Body font baseline scales with canvas and reading mode** — a PPT 16:9 baseline confirmed for read-close / business / projection cannot be carried onto tall canvases (Xiaohongshu / Story / A4). Pick the baseline from the confirmed canvas, not the recommended one; see the per-canvas px anchors in [`strategist.md`](strategist.md) §g "Typography Plan Confirmation" (the system is px-only — all sizes are unitless px on every canvas). ## ViewBox Examples diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md index 2d72cafd..72acc6cf 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-base.md @@ -1,10 +1,23 @@ -# Executor Common Guidelines +# Executor Flat and Shared Core -> Narrative skeleton and visual aesthetic come from this deck's locked files under [`modes/`](./modes/_index.md) and [`visual-styles/`](./visual-styles/_index.md). Technical constraints are in shared-standards.md. +Always-loaded Executor authority for flat SVG page authoring and behavior shared by every Generate route. Load conditional branches only when their trigger is present. + +**Conditional branch routing**: + +| Trigger | Load | +|---|---| +| `pptx_structure.mode: structured` | [`executor-structured.md`](./executor-structured.md) | +| Any data chart, chart catalog selection, or text-grid table | [`executor-chart.md`](./executor-chart.md) | +| A page will use a preset pattern fill or evaluate native chart/table replacement | [`native-data-interface.md`](./native-data-interface.md) before deciding eligibility or emitting metadata | +| Any image or formula resource, including template-bundled images | [`executor-image.md`](./executor-image.md) | +| Any `Status: Sourced` web image | [`executor-web-image.md`](./executor-web-image.md), after `executor-image.md` | +| Speaker notes generation after all SVG pages pass | [`executor-notes.md`](./executor-notes.md) | + +> Narrative skeleton and visual aesthetic come from this deck's locked files under [`modes/`](./modes/_index.md) and [`visual-styles/`](./visual-styles/_index.md). Technical constraints are in [`shared-standards-core.md`](./shared-standards-core.md). **Hard rule — complete page SVG**: Every visible object intended for the exported slide MUST exist in the final page SVG or be explicitly referenced by it. Templates and `spec_lock.md` guide construction; they are not export-time overlays for missing visible content. -**Hard rule — route-specific PowerPoint structure**: Free-design and brand-only projects use `pptx_structure.mode: flat`: write no root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder`; every visible object remains Slide-local. Export materializes one clean project-owned Master plus one Blank Layout from the current lock. Deck/layout template projects use `mode: structured`: every page reads its locked Master/Layout row and declares the four root identity attributes from the first draft. Do not add `data-pptx-layout-kind` or duplicate identity with `data-pptx-page-role`. Add `data-pptx-role` only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by specialized metadata; the marked element uses a stable unique `id`. See [`semantic-svg.md`](./semantic-svg.md). +**Hard rule — flat PowerPoint structure**: Free-design, brand-only, and `template_reuse_scope: style` projects use `pptx_structure.mode: flat`: write no root Master/Layout identity, `data-pptx-layer`, or `data-pptx-placeholder`; every visible object remains Slide-local, and the root declares exactly one canonical `data-pptx-page-role` (`cover` / `toc` / `section` / `content` / `ending`). A `style` template supplies colors, typography, decoration, and rhythm as style input without creating per-page prototype mappings. Export materializes one clean project-owned Master plus one Blank Layout from the current lock. Add `data-pptx-role` only to structural page-frame objects whose package, page-number, or animation behavior is not already expressed by specialized metadata; the marked element uses a stable unique `id`. See [`semantic-svg.md`](./semantic-svg.md). **Hard rule — supported PPTX route**: The only supported generated-PPTX path is `svg_output/` through the project SVG-to-DrawingML converter. Step 7.2 still generates `svg_final/` as a mandatory self-contained visual preview that may be inserted as an SVG picture. Do not treat PowerPoint's manual Convert-to-Shape operation as an authoring target or compatibility requirement. @@ -12,160 +25,63 @@ --- -## 1. Template Adherence Rules - -### 1.0 Pre-generation Batch Read - -**Hard rule**: Before the first SVG page, batch-read every template SVG this deck will reference. Read once up front, never re-read during generation. - -| Source list | Read path | -|---|---| -| Chosen template's `design_spec.md` (read frontmatter to detect `replication_mode`) | `templates/design_spec.md` | -| Every distinct `` in `spec_lock.md page_layouts` | `templates/.svg` | -| Every distinct chart name in `spec_lock.md page_charts` | `templates/charts/.svg` | -| Chart types in `design_spec.md §VII` not covered above | `templates/charts/.svg` | - -**Default — read each template once; re-read only on the mid-deck exception below**: -- Layout SVG already loaded in this batch -- Chart SVG already loaded in this batch - -`spec_lock.md` is the only file re-read per page (§2.1). - -**Exception**: user mid-deck adds pages or swaps templates introducing a basename/chart absent from the original batch → read the new file once, continue. - -> Note: batched prefix reads stay in the cached prompt prefix; per-page `spec_lock.md` re-reads append below and benefit from that cache. Scattered on-demand reads of layout/chart SVGs would invalidate downstream cache and sit in the compression-vulnerable mid-context region. - -Resolve the per-page template SVG via `spec_lock.md page_layouts` (authoritative). There is no filename/page-type fallback. - -**Resolution order (per page):** - -1. **Mirror-mode template** (template's `design_spec.md` frontmatter has `replication_mode: mirror`) → see §1.1 below. The page is consumed as a **visual reference**, not as a placeholder shell. -2. `spec_lock.md page_layouts` has `P: ` for this page → inherit the structure of `templates/.svg` (already in context from §1.0). -3. `template_adherence` is present but this page has no `page_layouts` entry → stop; the template contract is incomplete. Adaptive mode must still select a reference SVG. -4. No deck/layout template at all → flat free design: use the visual composition planned in §IX, but write no native Master/Layout mapping or SVG structure metadata. - -> Note: `page_layouts` disambiguates the multiple content variants a template may ship; missing mappings are contract errors. - -**Templates supply structure, not skin (non-mirror)**: a chart or layout template's gradients, drop-shadows, palette, **and font sizes** are placeholder. Inherit its geometry, label / legend placement, and series-encoding logic; re-skin every fill / stroke to the deck's `visual_style` + `spec_lock.colors` — flat styles strip the gradients and shadows, gradient / glass styles repaint their own. Forbidden — shipping a template's default `` / `cardShadow` / Tailwind fills unchanged. Mirror templates are the exception: §1.1 preserves their visuals verbatim. - -**Font size is skin, not geometry (non-mirror).** A chart / layout template's hardcoded `font-size` values (often 11–16px, sized for the template's own dense placeholder text) are NOT inherited — classify each text into its `spec_lock.md` role and use that role's locked size, exactly as you re-skin color. **Structural roles (page title / body / subtitle / annotation / footnote) hold their one deck-wide size on every page** — the template's placeholder px never overrides it; same-role text drifting page to page is what makes a deck look unprofessional. - -**Typography execution order (mandatory):** - -1. Build a per-page text inventory from `design_spec.md §IX` + the current `notes/_*.md`. -2. Classify each text item before drawing. **Structural roles** (`title`, `subtitle` / `lead`, `body`, `annotation`, `footnote` / `page_number`) must map to their declared `spec_lock.typography` slot. A **one-off feature element** (a single hero number, an isolated emphasis label) may take an in-ramp intermediate value — the ramp is anchored on `body`, not a closed menu — but a feature size that **recurs** must be promoted to a declared slot. The failure mode this guards against is structural text silently inheriting the template's compact px, not legitimate feature sizing. -3. Copy the role's locked px value into `font-size` verbatim. Do this before placing the text; never start from a template `font-size` and then "adjust". -4. Layout from those locked sizes: compute line-height, wrapped line count, child `y` / `dy`, card padding, card height, column gaps, and available image/chart area from the chosen px values. -5. Only after this reflow may you inspect fit. If fit fails, move / resize containers or simplify local geometry first; do not reduce the role size merely because the inherited template slot was smaller. - -**Geometry adapts to the type, never the reverse**: when the locked size is larger than the template's placeholder text, widen / heighten the card, open spacing, and recompute child `y` / `dy` to make room — do not shrink the font to fit the inherited container. A `font-size` change is a layout change: revise line-height and every downstream vertical coordinate that depends on it. For wrapped text, allocate at least the wrapped line count × line-height plus top / bottom padding; fixed `y` stacks copied from a smaller template are invalid once the locked role size is applied. The Executor renders the page it was given; page count and per-page density are the Strategist's call, fixed at confirmation — do **not** re-paginate, split the page, or drop authored content to cope with size here. Only when a single block still cannot fit after the geometry is fully reflowed may you shrink **that block** as a bounded last resort — and **only body text** is ever shrunk this way. Title, subtitle, annotation / caption, footnote and page number are **locked once set and never adjusted to fit** — their values hold across the whole deck. Step the overflowing body block's `font-size` down by `2`px at a time, and only if it still overflows step it down again, up to a cumulative floor of **`4`px below the locked body size** (e.g. `24` → no smaller than `20`). This is a **local, single-block** reduction — the deck-wide locked body size is unchanged on every other block and page. (The Executor works in **unitless px** throughout — spec_lock and SVG carry no `pt`.) If the block still overflows at the floor, surface a `warning:` rather than silently restructure the page. (Mirror templates are the exception: §1.1 preserves their sizes verbatim — there the source deck's typography *is* the spec.) - -### 1.1 Mirror-mode templates — reference-style consumption - -When the project's chosen template is a `mirror` template (`design_spec.md` frontmatter declares `replication_mode: mirror`), Executor switches to a **reference-style** consumption path that bypasses placeholder substitution: - -1. **Per-page reference selection** — Strategist selects one mirror page per project page via `spec_lock.md page_layouts` (e.g., `P04: 015_content`). The basename is the mirror filename without extension; Strategist made this choice by reading `design_spec.md §V Page Roster` descriptions, not by guessing. -2. **Copy, don't fill** — open the referenced mirror SVG (already in context from §1.0). Copy it as the starting point, then edit slide-specific text in place. Preserve every non-text element and every `data-pptx-*` structure attribute verbatim unless adaptive mode intentionally assigns a new Layout contract. -3. **What you may edit** — the visible text content of `` / `` elements that express slide-specific content (title, body, captions, KPI labels, dates, page numbers). Replace the source deck's example text with the project's text for this page from `design_spec.md §IX` and `notes/_*.md`. -4. **What you must not touch** — element positions, sizes, fonts, colors, fills, strokes, gradients, **which image each `` points at**, `` grouping, sprite-sheet `` wrappers, decorative `` / `` / `` / `` shapes, `` markers, embedded chart data structures. Mirror's value is preserving the source deck's visual identity — any geometric / decorative drift defeats the purpose. **The `href` path is not the image**: normalizing a bare `href="cover_bg.png"` to `href="../images/"` (when Step 3 relocated the asset to `images/`) points at the *same* image and changes nothing visual — that is an allowed path fix, not a fidelity edit. Leaving the bare href as-is is also fine; the exporter and live preview resolve bare hrefs against `images/` either way. -5. **Content fit** — the mirror page was chosen by Strategist because its layout matches the content slot. If the project's content for `P` legitimately needs more / fewer items than the mirror page provides (e.g. mirror shows 3 KPI cards, project has 4 metrics), keep the mirror page's visual rhythm and either drop one metric to fit or split across two pages — do **not** restructure the mirror page's grid. If neither works, surface a `warning: P content does not fit mirror reference ; suggest different reference page` and proceed with the closest-fit edit. -6. **Visible text editing** — mirror SVGs may keep literal source text rather than `{{...}}` authoring markers. Edit visible text in place, but retain any imported semantic `data-pptx-placeholder` identity. -7. **Output filename** — follow the standard project SVG naming convention (`_.svg` where `` matches the project page index, not the mirror source index). The mirror filename is the *reference*, not the *output*. - -**Detecting mirror mode**: read the chosen template's `design_spec.md` frontmatter once during §1.0 batch read. If `replication_mode: mirror`, every page follows §1.1 through its mandatory `page_layouts` reference. - -**Mirror + chart pages**: chart structures inside a mirror SVG are already drawn (axis, series, labels). Treat them as visual references — replace the data labels and series text content to match the project's chart spec, but do not redraw the chart from a `templates/charts/.svg` baseline. A mirror template's `page_charts` entries are normally absent for this reason. - -**Legacy template boundary**: A template with missing root Master identity, direct atomic placeholders, `data-pptx-layout-kind`, unmapped `baseline`, `preserve`, or `layout_strategy: distill` is not a fallback input. Stop and run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation. - -### Page-Template Mapping Declaration (Required Output) - -Before generating each page, output which template is used: - -``` -📝 **Template mapping**: `templates/03a_content_image_text.svg` (free-design routes may use "None") -🎯 **Adherence rules / layout strategy**: [specific description] -``` - -- **Content pages**: template defines only header/footer; content area is free -- **No template**: allowed only on free-design or brand-only routes - -### 1.2 PowerPoint Master / Layout Mapping - -This section applies only to deck/layout template routes. `page_layouts` selects the input SVG prototype, `pptx_masters` / `pptx_layouts` declare unique reusable output definitions, and `page_pptx_layouts` assigns every generated page before the first page is drawn. Free-design and brand-only routes use `pptx_structure.mode: flat`, omit all four sections, skip the rest of §1.2, and keep every SVG object Slide-local. - -**Hard rule — template mode only**: A deck/layout template project uses `pptx_structure.mode: structured`. Missing mode or legacy values (`baseline`, `template`, `preserve`), `layout_strategy`, Layout-kind fields, partial mappings, and old direct placeholders must stop generation and route to [`restore-pptx-structure`](../workflows/restore-pptx-structure.md). `flat` is valid only when no deck/layout template is active. - -**Hard rule — root identity**: A `page_pptx_layouts` row binds the page to one key in `pptx_layouts`; that unique definition supplies its Master key, Layout picker name, and prototype source. Put the declared Master key/name and Layout key/name on the root SVG. A Layout key belongs to exactly one Master and remains globally unique. - -**Hard rule — atomic fixed layers**: Every `data-pptx-layer="master|layout"` visual is one direct root child that compiles to one DrawingML object. A marked `` is forbidden. When reconstructing source PPTX groups, recursively push supported transforms, paint, opacity, and z-order into atomic children. Repeat the identical ordered Master atom contract on every page using that Master and the identical ordered Layout atom contract on every page sharing that `(master, layout)` pair. - -**Hard rule — PowerPoint paint order**: Direct children appear in this order: Master background atoms, Layout background atoms, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local content groups. Backgrounds are the inheritance plane beneath all shapes. - -**Mandatory — slot authoring**: A reusable content slot is one direct root `` carrying `data-pptx-placeholder` and positive `data-pptx-placeholder-bounds`. A normal slot contains exactly one compatible direct drawable child marked `data-pptx-placeholder-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. Decorations do not belong in the slot; move reusable decoration to a root Layout atom and keep page-specific labels/captions in another slot or Slide-local group. - -**Mandatory — slot identity**: Preserve imported `data-pptx-placeholder-idx` values where available; otherwise omit the title index and assign unique indices only where repeated roles need disambiguation. Pages sharing one Layout key repeat the same slot ids/types/effective indices/default bounds/binding modes. Current text, crop, and Slide-local carrier geometry may differ. - -**Composite proxy fallback**: A genuinely composite region may use a direct `` with positive bounds. Its visible group remains Slide-local and export creates one hidden transparent matching placeholder proxy. This downgrade is valid only for `object`; do not use it for an ordinary title, body, picture, chart, table, or media slot. - -**Zero-slot Layout**: A Layout may have no slot groups. Covers, posters, and fixed visual pages still declare their named Master/Layout and fixed atoms. Do not manufacture a full-page `object` slot or empty `utility` identity. - -**Mandatory — per-page slot coverage**: On every mapped page, declare a slot for each standard role the page actually has: the page heading as `title`, a cover tagline as `subtitle`, the page number as `slide-number`, running footer text as `footer`, a hero / content image as `picture`, and a body block already authored as one merged text frame as `body`. A page shipping zero slots exports a Layout with no insertable placeholders — valid only for a genuinely fixed composition (see Zero-slot Layout above), never as the deck-wide default. Pages sharing one layout key ship the same slot set. - -**Hard rule — variable slot content**: “Per-page headings never stay Slide-local by default” means authoring them as `title` / `subtitle` slots; it never permits page-varying text or images to become fixed Layout atoms. Any such value that varies across pages sharing one Layout key MUST be carried by a slot or remain Slide-local. - -**Mandatory — master/layout layer coverage**: On every mapped page, mark the deck-wide background and every-page chrome (footer bar, running logo) `data-pptx-layer="master"`, and mark the static framing that defines this layout key's composition (header rule, divider band, zone panels — including chrome repeated on every content page but absent from the cover) `data-pptx-layer="layout"`. A mapped page with zero `data-pptx-layer` marks exports a bare Master and an empty Layout — the layer marks, not the slide content, give each Layout its visible design. - -**Layout identity**: Different keys differ in fixed Layout atoms or slot topology/default bounds/binding modes. Identical contracts should share one key. Current wording, imagery, crop, and Slide-local geometry never define identity. - -**Template adherence**: Strict copies the prototype Master/Layout/slot contract exactly. Adaptive keeps the prototype Master and may change reusable Layout atoms or slots only under a new explicit Layout key/name. When the completed composition genuinely needs that change, update `spec_lock.md pptx_layouts` immediately while authoring the first affected page; later pages may reuse the new key only by repeating its exact contract. Changing only a label is not a new Layout. - -**Layout-content boundary**: Mark only genuinely reusable fixed framing as a Master/Layout atom. Concrete titles, body copy, metrics, chart marks, images, and page-specific groups remain inside slot groups or ordinary Slide-local content groups. The exporter never infers or clusters structure. - -**Background ownership**: - -| Scope | SVG authoring | -|---|---| -| Deck-wide default | Direct full-canvas solid `` repeated identically on every page | -| Page-type default | Direct full-canvas solid `` repeated on every page sharing that layout key | -| One-page exception | Direct full-canvas solid `` | - -The exporter writes these solid fills as real Master/Layout/Slide `p:bg`, not selectable full-canvas shapes. Gradients, images, textures, and overlay panels stay explicit shapes unless the shared standard says otherwise. - ---- - ## 2. Design Parameter Confirmation (Mandatory Step) -Before the first SVG page, output a confirmation listing: canvas dimensions, body font size, color scheme (primary/secondary/accent HEX), font plan, and the live-preview URL reported by the launcher. If the preview launch failed, state that failure before generating SVGs instead of silently proceeding. Prevents spec/execution drift. +Before the first SVG page, output a confirmation listing: the compact communication objective, canvas dimensions, body font size, color scheme (primary/secondary/accent HEX), font plan, and the live-preview URL reported by the launcher. If the preview launch failed, state that failure before generating SVGs instead of silently proceeding. Prevents purpose/spec/execution drift. -### 2.1 Per-page spec_lock re-read (Mandatory) +### 2.1 Per-page execution context (Mandatory) -> Long decks drift off the declared palette/icons mid-deck due to context compression. `spec_lock.md` is the canonical execution reference — re-read it per page to bypass model memory. +Before the first SVG, retain `design_spec.md`: continuous execution reuses planning context; fresh/resumed execution reads it once. -**Hard rule**: Before generating **each** SVG page, `read_file /spec_lock.md`. Use only values from this file, not from memory. If context was auto-compacted, also `read_file /design_spec.md` for the current page's §IX brief. +**Hard rule**: Before generating **each** SVG page, load its canonical current-page delta and record its model-facing size: + +```bash +python3 skills/ppt-master/scripts/project_manager.py page-context P --record-usage +``` + +`global` deliberately repeats the sub-1000-token lock projection as an anti-drift guard; `lock_source.sha256` binds its version. `page_context` is the current §IX/resource/template/chart delta. For every `reference_set` entry—project/template Design Spec or selected prototype/chart SVG—reuse an in-context path + SHA; read it once only when absent or changed. + +Use lock values literally and optional `Template Application` from the retained Design Spec. The delta overrides neither facts nor constraints. After an approved change, rerun the command and reload only changed references. Deprecated `--bundle` is a compatibility no-op. + +**Source facts**: The page delta carries page intent and routing facts, not the complete source corpus. Read the relevant `sources/` content and resolve listed `Fact IDs` from `sources/*.facts.json` when the page needs concrete claims, quotes, names, or data. + +**Per-page communication trace**: Read `communication.objective`, `communication.core_message`, and the current §IX `Core message` + `Audience move` before choosing composition. The page must advance the compact objective and move the audience as authored in §IX; the global core message remains the deck-wide north star. A page that cannot state this movement is an upstream outline defect — surface `warning: P has no communication move` instead of compensating with decorative layout. Do not invent a new purpose, ask, or outcome at execution time. Structural pages may advance the contract by establishing relevance / tension / decision frame or by completing the final commitment; they are not exempt from having a reason to exist. + +**Per-page reading-mode check**: Read `communication.consumption_mode` before choosing the page's composition. Apply it together with the authored §IX block texture and `page_rhythm`: + +| `consumption_mode` | Page execution | +|---|---| +| `text` | Make the visible page independently understandable. Preserve complete prose, explicit labels / captions / sources, tables, and necessary detail; use bullets only for genuinely parallel or ordered items. | +| `balanced` | Keep the primary claim and its evidence on the page; let notes add interpretation and transitions. Mix prose, structured evidence, and necessary lists according to their semantic relationship. | +| `presentation` | Make one claim and one dominant visual expression legible at projection distance. Keep visible copy concise; put explanation and transitions in notes instead of creating paragraph dumps or compressed bullet prose. | + +The §IX wording and sourced facts remain authoritative. Do not rewrite, drop, or invent content to force a mode at execution time. When the authored texture materially conflicts with the lock, render the least-destructive faithful composition and surface `warning: P content texture conflicts with consumption_mode ` as an upstream outline issue; do not encode this subjective judgment in the checker. **Per-block expression**: render each `design_spec.md §IX Content` block in its written texture — a full-sentence block as wrapped prose, a fragment/label block as bullets/keywords. **Never split a full-sentence block into a bullet list** — splitting loses the information that the block was continuous reasoning, not a set of parallel points; not because a bullet lays out easier, and not because an inherited template slot is shaped as a list. If a block carries no clear texture, infer the mode from its wording and the page layout. -- **Prose render recipe**: one `` per paragraph; wrap lines with sibling `` where the first line uses `dy="0"` and every subsequent line repeats the parent ``'s **exact `x`** and the **same positive relative `dy`** (the line-height). Equal relative `dy` + matching `x` + the same effective `font-size` lets lines flow inside one PowerPoint paragraph; a font-size change preserves a new paragraph inside the same text frame, while a growing/cumulative `dy`, an irregular gap, or a mismatched `x` (e.g. `x="0"` under ``) may split them into separate single-line boxes. Set the line-height `dy` from the font size × a line-height factor. **Default — line-height by density (may override per content fit)**: ~1.4–1.5× for dense / small-body blocks (CLReq comfortable minimum), 1.6–2.0× for large-type, sparse, or `breathing` blocks. Fit about width ÷ font-size CJK glyphs per line (Latin fits roughly twice that); the last line runs short. Use the body ramp size, not a new one. +- **Hard rule — one paragraph, one text frame**: use one `` per prose paragraph, never one sibling `` per visual line. Keep the first line as direct text; each later wrap is a direct `` that repeats the parent `x`, keeps its effective font size, and uses one positive relative `dy`. An all-`` form may start with `dy="0"`. Line height: 1.4–1.5× for dense/small body, 1.6–2.0× for large/breathing text. - **Template precedence**: when an inherited template slot is a bullet list but the §IX block is prose, the prose wins — widen or reflow the container to hold the paragraph, or drop that card; do not pour the sentence back into the list slot. - **Mode precedence**: the locked mode shapes voice / register, not §IX's authored titles or page order. When a `§IX` title is a user-authored topic label, keep it — do not upgrade it to an assertion just because the mode (e.g. `pyramid`) favors them; mode title-tendencies apply only to AI-drafted titles. > Note: block-level phrasing, applied *within* the page's `page_rhythm` density (below), not against it. -**If `spec_lock.md` is missing**: emit `warning: spec_lock.md missing — generating without execution lock` once, then proceed using `design_spec.md` values. Expected only for legacy projects; new projects MUST have it (see [strategist.md](strategist.md) §6 step 4). +**Missing `spec_lock.md` or `design_spec.md`** → stop before drawing and report the missing gate artifact. Recover through [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §3; do not bypass a failed page-context command or silently downgrade. + +**Missing field in an existing lock**: follow [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2. **Forbidden — values outside the lock**: - Colors (fill / stroke / stop-color) MUST come from `colors` - Icons MUST come from `icons.inventory`; library MUST equal `icons.library` - Font family from `typography`: use role override (`title_family` / `body_family` / `emphasis_family` / `code_family`) if declared, else fall back to `font_family` -- Font sizes follow a **ramp anchored on `typography.body`**, not a closed menu. **Structural roles — page title, body, subtitle, annotation / caption, footnote / page number — render at one consistent size deck-wide, taken from their `spec_lock` slot; never re-pick a structural role's size page by page or carry a template's placeholder px.** This locks the **role**, not every glyph: a page may still carry deliberate typographic hierarchy — a lead-in sentence, an inline emphasis figure, a pull-quote, a kicker, a hero number — but each of those is its **own role / feature element** with its own size, **applied consistently deck-wide** (declare a recurring one as its own `spec_lock` slot). In-band intermediate sizes are for exactly these feature elements. What is banned is the *same* role drifting size to fit a container or by page whim — that scatter is what reads as unprofessional. Sizes outside every band require extending the lock first. -- **The page's core message is primary — render it ≥ `body`.** The one-idea / key-claim / key-takeaway line a page is built around is its most important text; map it to the locked `lead` or `subtitle` slot (≥ `body`), never to a sub-`body` size. Demoting it below body while data callouts or labels sit larger inverts the hierarchy — the failure this prevents. If no `lead` / `subtitle` slot is locked for a recurring core-message line, surface it (per below) instead of improvising a smaller one. A footnote / page number / source credit uses the locked `footnote` (or `annotation`) slot — never an invented sub-`annotation` size; and the body-shrink last resort (§1.0) bottoms out at `body − 4`px, a hard floor never crossed. -- **Write the locked px verbatim; at most 2 decimals.** `font-size` MUST be the exact px from `spec_lock.typography` — if `body` is `24`, write `24`; never substitute a "rounder" or PowerPoint-familiar number (`20` / `18` / `36`). The system is px-only — there is no pt to convert, and a remembered pt-style value written as px renders the whole deck the wrong size. Prefer whole numbers (sizes are clean even px); keep a decimal only for a slot that genuinely carries one in `spec_lock`. Never emit long tails like `20.8026`: the exporter rounds the final size to 1 decimal pt, so extra px precision is wasted noise. +- Font sizes follow a ramp anchored on `typography.body`. Structural roles use their locked size deck-wide; recurring feature roles such as lead, pull quote, or hero number need their own lock slot. Never resize one role page by page or inherit a template placeholder size. +- **Core message ≥ `body`**: map the page's primary claim to locked `lead` / `subtitle`, never below body. Footnotes, page numbers, and credits use locked `footnote` / `annotation`; do not invent smaller sizes. +- **Write locked px verbatim, with at most two decimals.** Do not substitute familiar pt-style numbers or emit long precision tails. +- **Bounded body-fit last resort**: reflow geometry first; only an overflowing body block may step down by `2`px, never below `body − 4`px. Other roles never shrink. At the floor, warn instead of dropping content or repaginating. Mirror pages preserve source typography. - Images MUST reference files listed under `images`; no invented filenames -- Formula PNGs are images with `Acquire Via: formula` / `Status: Rendered`; place them only from the listed file path and never recreate the formula as text. +- Formula PNGs are images with `Acquire Via: formula`; place a `Rendered` file only from its listed path, use the normal placeholder for `Needs-Manual`, and never recreate the formula as text. -If a page needs a value not in `spec_lock.md`, surface it — do not silently invent one. +If a page needs a value not in `spec_lock.md`, surface it — do not silently invent one. When an intentional deck-wide or recurring color, type role/size, icon, or image is approved, extend `spec_lock.md` **before** drawing the first affected object, regenerate that page's context bundle, and only then author the page; do not draw with a temporary hardcoded value and retroactively silence drift warnings. **Per-page layout rhythm — `page_rhythm` section**: @@ -173,89 +89,35 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P` | Tag | Layout discipline | |-----|-------------------| -| `anchor` | Structural page (cover / chapter / TOC / ending). With a template, follow the matching template verbatim. In free design (no template), realize the page's §IX intent — for the cover deliver its `Cover impact` and for a closing page its `Closing impact` (the committed hook / takeaway + composition), never a default centered title + subtitle or a generic "Thank you" sign-off. | +| `anchor` | Structural page (cover / chapter / TOC / ending). With `template_reuse_scope: mirror`, follow the selected prototype verbatim except visible text values. With `layout`, retain the selected structure system while realizing the page's §IX intent. With `style` or free design, realize §IX directly — for the cover deliver its `Cover impact` and for a closing page its `Closing impact`, never a default centered title + subtitle or generic "Thank you" sign-off. | | `dense` | Information-heavy. Card grids, multi-column layouts, KPI dashboards, tables, and charts are all permitted. This is the baseline behavior. | | `breathing` | Low-density impact page. Avoid **multi-card grid layouts** — do not organize content as multiple parallel rounded containers (3-card row, 4-card KPI grid, 2×2 matrix rendered as cards). Use naked text blocks, dividers, whitespace, or full-bleed imagery as the content structure. Single rounded visual elements (hero image corners, callouts, tags, one emphasis block) are fine — the rule is about grid structure, not about the `rx` attribute. Proportions follow information weight (not a preset ratio). Typical forms: hero quote, single large number with one-line interpretation, full-bleed image with floating caption, section transition. | > Without rhythm variation, every page defaults to card grids (the "AI-generated" look). `page_rhythm` is the only narrative lever that survives context compression. -**Missing `page_rhythm` section** → emit `warning: spec_lock.md missing page_rhythm — defaulting all pages to dense` once, fall back to `dense` for all pages. +**Missing or empty `page_rhythm` section — fixed compatibility default** → emit `warning: spec_lock.md missing/empty page_rhythm — defaulting all pages to dense` once, fall back to `dense` for all pages. -**Tag not found for current page** → emit `warning: spec_lock.md page_rhythm tag not found for P — falling back to dense` once per deck (aggregate; do not repeat per page), fall back to `dense`. Do not invent a tag. +**Tag not found for current page — fixed compatibility default** → emit `warning: spec_lock.md page_rhythm tag not found for P — falling back to dense` once per deck (aggregate; do not repeat per page), fall back to `dense`. Do not invent a tag. -**Per-page template lookup — `page_layouts` section**: - -Before drawing each page, look up its entry in `page_layouts` to decide which basename to inherit (the SVG itself was loaded in §1.0): - -- Entry present (e.g., `P04: 03a_content_image_text`) → inherit the corresponding SVG already in context. The basename **must match** an actual file in the chosen template directory. If it does not, stop before drawing and report the invalid mapping; neither `strict` nor `adaptive` may fall back to free design inside a template deck. -- No entry for this page with `template_adherence: strict|adaptive` → stop before drawing and report the missing Strategist mapping. Adaptive mode still requires one selected complete template SVG; flexibility applies to the post-design output Layout, not to whether an input prototype exists. -- Whole section absent while `template_adherence` is present → stop before drawing; the current template contract is incomplete. - -Do **not** invent a prototype entry, and do **not** assume a template just because `templates/` exists. For either template-adherence value, a missing or invalid `page_layouts` row is an upstream contract error. Free design is a separate deck route, never a per-page fallback. - -**Per-page PowerPoint layout lookup — structured deck/layout templates only**: - -- When `pptx_structure.mode` is `flat`, skip this lookup and the structured scaffold below. `pptx_masters`, `pptx_layouts`, `page_layouts`, and the corresponding SVG metadata must all be absent. -- When a deck/layout template is active, `pptx_structure.mode` must equal `structured`; any other or missing value routes to legacy restoration. -- Read the current page row as ` | | ` and resolve `master_key` in `pptx_masters`. Missing, malformed, or partial mappings stop before drawing. -- Write matching root Master/Layout key and picker names. Do not write `data-pptx-layout-kind` or `data-pptx-page-role`. -- On strict template use, the row and SVG contract match the selected prototype exactly. -- On adaptive template use, retain the prototype Master. If the final composition changes fixed Layout atoms or slot topology/bounds, allocate a new key/name and update this row before completing the page. -- A Layout key may repeat across non-adjacent pages only when its fixed atoms and slot contracts are identical. - -**Structured template-page scaffold**: - -```xml - - - - - - - - - - - - - - - - -``` - -On structured template pages, Master/Layout atoms and slot groups are direct root children and precede ordinary content groups. Structural metadata nested inside an ordinary content group fails export. Flat pages use ordinary top-level semantic groups only. - -**Per-page chart reference — `page_charts` section**: - -Before drawing each page, look up its entry in `page_charts` to decide which chart structure applies (the SVG itself was loaded in §1.0): - -- Entry present (e.g., `P09: timeline_horizontal`) → adapt the corresponding chart SVG already in context. Apply project colors/typography/density; do not copy verbatim. Cross-reference `templates/charts/charts_index.json` for the chart's purpose summary if needed. -- No entry for this page → either no chart on this page, or a chart that didn't match any catalog template (Strategist's `no-template-match` fallback). Design the visualization from scratch using `design_spec.md §VII` for guidance. -- Whole section absent → no chart pages in this deck. --- ## 3. Execution Guidelines - **Proximity**: group related elements with tight spacing; separate unrelated groups -- **Element grouping (Mandatory)**: wrap every logical Slide-local content unit — title, core-message line, each content block, card, list item, and diagram — in a top-level `` with a descriptive id. Flat free-design/brand-only pages use ordinary semantic groups for every logical unit. On structured template pages, slot `` elements are already semantic groups and direct Master/Layout atoms are the required exception to grouping. Authored native preset fragments (`preset_shape_svg.py`) already are one atomic `` each and count as one ordinary content group; keep their labels in a sibling parent ``. +- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level ``. Every visible direct root `` declares root-coordinate `data-pptx-bounds="x y width height"`; frame/native coordinates do not replace it, and placeholder bounds also supply the slot frame. Nested groups need no bounds and any such values are ignored. Checker compares root bounds with the `viewBox` and recursively checks only estimable text against its root module: through `1px` is ignored, through `5%` warns, above `5%` fails per side. Images, shapes, paths, ``, effects, and object frames remain geometrically free. Flat pages use ordinary groups; structured slots already qualify, while titles and direct Master/Layout atoms may remain root primitives. - **Spec adherence**: follow color, layout, canvas format, and typography in the spec -- **Template structure**: if templates exist, inherit the visual framework +- **Template structure**: inherit the native visual framework only for `template_reuse_scope: mirror|layout`; `style` uses the flat route - **Main-agent ownership**: SVG generation must run in the main agent (not sub-agents) — pages share upstream context for cross-page visual continuity -- **Generation rhythm**: lock global design context first, then generate pages sequentially in one continuous context. No batched groups (e.g., 5 at a time). +- **Generation rhythm**: P01 → first-page gate → uninterrupted remaining pages → final gate, in one context without batches or mid-run checker calls. +- **Fact provenance**: when a §IX page lists `Fact IDs`, resolve each ID from `sources/*.facts.json` and keep the claim/value unchanged. Render a compact source footnote using the source name and a short URL/domain when space permits; state the attribution naturally in speaker notes. When §IX says `Data class: scenario`, place a visible localized `Scenario data` / `情景数据` label adjacent to the affected KPI/chart and state naturally in notes that the number is illustrative. Never attach an external fact ID to scenario data or let an unlabeled invented KPI look factual. - **Default — stage each page with the style's composition geometry (may override when the content genuinely calls for a plain grid)**: an SVG page is a canvas, not a DOM. Before defaulting to stacked rounded-rect cards or uniform equal columns, pick one page-scale move from the locked visual style's §1 `Composition geometry` (a bleed shape, diagonal split, oversized numeral, orbit rings, …) to stage the page's primary zone. Card grids are one option among many, not the house layout. -- **Reference — image-led promotional pages (not a constraint)**: for travel, venue, product-introduction, hospitality, event, real-estate, and brochure-style decks, let images define the page skeleton before placing text. Consult [`image-layout-patterns.md`](image-layout-patterns.md) §Imported Deck Patterns and prefer patterns such as `#74` TOC image-navigation cards, `#75` asymmetric chapter banners, `#77` photo mosaic with a text cell, `#78` ambient banner + evidence photo + text panel, `#79` ribbon-header image cards, and `#80` side hero image + staggered evidence cards before falling back to plain left/right image-text splits. -- **Phased batch generation** (recommended): - 1. **Visual Construction Phase**: generate all SVG pages sequentially for visual consistency. Use layout judgment for chart marks during the draft. **MUST embed plot-area markers** per §3.1 below on every chart page — coordinate calibration is a post-generation step (see [`workflows/verify-charts.md`](../workflows/verify-charts.md)) that depends on these markers — and **native object metadata** per §3.2 on every eligible data-chart page. **Reach for native presets** per §3.0 as you draw each page: a block arrow, chevron, banner/ribbon, callout, standard flowchart node, or star is authored through `preset_shape_svg.py` at draw time — decided by the object's intent as you create it, never by scanning finished paths, and never committed to a bare ``/`` when a preset expresses it (a gradient fill/stroke or a pattern fill is the one paint exception — keep those ordinary SVG). **First-page gate (Mandatory)**: after completing the first page, run `python3 scripts/svg_quality_checker.py /svg_output/.svg` and fix every error before drawing page 2 — structural violations are systematic, and a first-page error repeated deck-wide costs a whole-deck rewrite. - 2. **Quality Check Gate**: run `python3 scripts/svg_quality_checker.py ` on `svg_output/`. Any `error` (banned features, viewBox mismatch, spec_lock drift, non-PPT-safe font, etc.) MUST be fixed on the offending page before proceeding — regenerate and re-check. Address `warning`s when straightforward. On a structured deck/layout template route, PPTX-structure warnings (empty Layout, framing-only Layout, bare Master, duplicate layout keys) are never acknowledge-and-release: list each one and either fix the page/lock or state per warning why the flagged state is intended (e.g. a zero-slot cover) before proceeding. Flat free-design/brand-only routes have no Master/Layout checkpoint. Do NOT defer to after `finalize_svg.py` — finalize rewrites SVG and masks some violations. +- **Containers are structural**: cards and grids express grouping, hierarchy, or capacity, not a house style. Preserve meaningful template frames; restyle radius, fill, stroke, and depth from the active Design Spec and `spec_lock.md`. Chart-catalog adaptation is owned by [`executor-chart.md`](./executor-chart.md); preview effects never override project styling or structural roles. +- **Reference — prefer semantic geometry over preset stacks**: for relationships such as ascending, converging, breaking through, or stacking, consider one page-specific polygon/path that expresses the relationship before stacking generic arrows. This does not override §3.0 when one literal stock shape is the semantic object. +- **Reference — create depth with restraint**: use rhythm, spacing, typography, accent bars, and subtle tints before shadows. Reserve lift for a few genuinely floating elements; keep peer grids, dividers, and body containers flat. +- **Phased generation** (recommended): + 1. **Visual Construction Phase**: generate all SVG pages sequentially for visual consistency. Use layout judgment for chart marks during the draft. **MUST embed plot-area markers** per [`executor-chart.md`](./executor-chart.md) §2.1 on every chart page — coordinate calibration is a post-generation step (see [`verify-charts`](../workflows/stages/verify-charts.md)) that depends on these markers — and **native object metadata** per [`executor-chart.md`](./executor-chart.md) §2.2 on every eligible data-chart page. **Reach for native presets** per §3.0 as you draw each page: a block arrow, chevron, banner/ribbon, callout, standard flowchart node, or star is authored through `preset_shape_svg.py` at draw time — decided by the object's intent as you create it, never by scanning finished paths, and never committed to a bare ``/`` when a preset expresses it (a gradient fill/stroke or a pattern fill is the one paint exception — keep those ordinary SVG). **First-page gate (Mandatory)**: after completing the first page, run `python3 scripts/svg_quality_checker.py --stage first-page` and fix every error before drawing page 2. This mode checks P01 only. After it passes, draw P02 through the last page without checker calls. + 2. **Quality Check Gate**: only after every planned SVG exists, run `python3 scripts/svg_quality_checker.py --stage final --json` on `svg_output/`. Any `error` (banned/unsupported features, invalid values, unresolved references, viewBox mismatch, etc.) MUST be fixed on the offending page before proceeding — regenerate and re-check. Every `warning` is advisory: it never sends the page back for required modification, never authorizes automatic rewriting of compatible user syntax, and needs no acknowledgement/disposition line. Recommendation warnings describe the generated-SVG default; fidelity/quality warnings may be surfaced when material, while the existing input remains releasable. Prototype-identical diagnostics are recorded as `inherited`, source conversion losses as `source-import`, changed/new advisories as `introduced`, and release failures as `blocking` in `validation/svg_quality_report.json`. If release truly depends on a condition, it belongs in `errors`. On success, use the exit status and terminal summary; do not open or `cat` the complete JSON into model context. Read only targeted fields for failure investigation or an explicit audit request. Do NOT defer error handling to after `finalize_svg.py` — finalize rewrites SVG and masks some violations. 3. **Logic Construction Phase**: after SVGs pass the quality check, batch-generate speaker notes for narrative continuity. ### 3.0 Native Preset Shape Selection @@ -282,89 +144,25 @@ This automatic decision applies only before drawing a new object. Do not scan existing SVG, classify path contours, or upgrade ordinary SVG during export. **Hard rule**: do not hand-write `data-pptx-authoring`, `data-pptx-prst`, -`data-pptx-frame`, adjustment, carrier, preview, or fingerprint metadata. The -helper generates them atomically from the shared 187-shape registry. Rerun the -helper when geometry or paint changes. +`data-pptx-frame`, adjustment metadata, or registry paths. The helper generates +one compact atomic `` from the shared 187-shape registry, with semantic +metadata and base paint written once. Rerun the helper when geometry or paint +changes; never edit one of its direct paths. -Connector-family presets require `--object-kind connector`, `fill="none"`, and -a visible stroke. They export as unconnected `p:cxnSp`; do not hand-add -endpoint/site metadata. `actionButton*` presets provide visual geometry only, -not actions or hyperlinks. +For chart-template and diagram authoring, thin relationships use ordinary +`` / supported open `` geometry with registered arrow markers; +solid directional blocks use ordinary `shape` presets such as `rightArrow` or +`chevron`. Do not select a connector-family preset merely because two nodes are +related, and never hand-add endpoint/site metadata. Connector-family presets +remain available only for an explicit request for a standalone unconnected +`p:cxnSp`; imported Connector topology stays under the preserve/mirror contract. +`actionButton*` presets provide visual geometry only, not actions or hyperlinks. **Hard rule — narrow helper scope**: the helper prints one shape fragment to stdout. It does not write a page or choose layout. Read the fragment and insert it through the normal `apply_patch` page edit; never redirect, loop, or batch it into `svg_output/`. -### 3.1 Chart Plot-Area Marker (MANDATORY on every chart page) - -> The [`verify-charts`](../workflows/verify-charts.md) workflow enumerates chart pages from `design_spec.md §VII`, then reads each page's plot-area marker to feed `svg_position_calculator.py`. Missing marker → verify-charts has to re-derive the plot area from axis lines, paying the cost on every run. - -**Hard rule**: every SVG page that contains a data visualization chart includes a plot-area marker inside ``, placed **after axis lines** and **before the first data element** (bar, line, area, point). - -**Rectangular plot area** (bar / horizontal_bar / grouped_bar / stacked_bar / line / area / stacked_area / scatter / waterfall / pareto / butterfly): - -```xml - -``` - -**Radial charts** (pie / donut / radar): - -```xml - - - -``` - -**How to determine coordinate values**: - -| Value | Derivation | -|-------|------------| -| `x_min` | X coordinate of the Y-axis line (leftmost data boundary) | -| `y_min` | Y coordinate of the topmost grid line (highest data boundary) | -| `x_max` | X coordinate of the rightmost axis endpoint or grid line | -| `y_max` | Y coordinate of the X-axis baseline | -| `cx, cy` | Center point of pie/donut/radar (accounting for `transform="translate()"`) | -| `r` | Outer radius of the chart | - -**Per-page verification** — after writing each chart SVG, confirm the marker exists: - -```bash -grep "chart-plot-area" /svg_output/.svg -``` - -> All chart templates in `templates/charts/` include this marker as a reference. If you are drawing a chart and the marker is absent, you have a bug. -- **Technical specs**: see [shared-standards.md](shared-standards.md) for SVG/PPT constraints -- **Card containers — use the documented patterns**: when a content page needs section cards (4 quadrants, parallel aspects, capability blocks, info cards), use the patterns codified in [`templates/charts/CHART_STYLE_GUIDE.md`](../templates/charts/CHART_STYLE_GUIDE.md) §11 — half-rounded section tab (§11.1), nested card border without stroke (§11.2), card-grid skeletons (§11.3), diagonal dashed connector for cross-quadrant relationships (§11.5), ground-anchor ellipse as a non-filter depth marker (§11.6), bidirectional interaction arrows for paired protocols (§11.7). Do not reinvent the "tinted full-rounded rect + white cover-rect to hide the bottom corners" hack; it survives in older templates but breaks SVG→PPTX color editing. Reference templates: [`labeled_card.svg`](../templates/charts/labeled_card.svg), [`quadrant_text_bullets.svg`](../templates/charts/quadrant_text_bullets.svg), [`kpi_cards.svg`](../templates/charts/kpi_cards.svg), [`matrix_2x2.svg`](../templates/charts/matrix_2x2.svg), [`team_roster.svg`](../templates/charts/team_roster.svg), [`client_server_flow.svg`](../templates/charts/client_server_flow.svg). -- **Reference — prefer semantic shapes over preset stacks (not a constraint)**: when a slide needs to express "ascending / converging / breaking through / stacking" — i.e., a relationship that goes beyond a generic arrow — prefer a single custom `` or `` that encodes the semantics geometrically, rather than stacking multiple preset arrows. A converging-tip path or a podium polygon reads faster than three arrows pointing at a label. Examples of this technique appear in many imported corporate decks; see `projects/01_template_import/svg_output/slide_01.svg` shape-158 for a reference (gradient-filled inward-pointing arrow). Do not codify these as templates — they are page-specific; the rule is just "consider polygon before stacking presets." -- **Reference — visual depth through restraint (not a constraint)**: layered depth comes from rhythm (flat vs lifted, dense vs spacious), not from shadows everywhere. Shadow typically suits 2-3 genuinely floating elements per page (cards on photos, primary CTA, overlays); keep peer-grid cards, dividers, body containers flat. Reach for typography weight, spacing, accent bars, subtle tints **before** shadow. - -### 3.2 Native Object Metadata Marker (MANDATORY on eligible data-chart and text-grid table pages) - -> `svg_to_pptx.py --native-objects` converts marked groups into real PowerPoint chart/table objects (charts get an embedded Excel workbook). Markers stay dormant in the default export — pages render from their SVG children — but a deck without markers can never form native objects. Write the marker at draw time: the data is already in hand, and recovering it later costs a full re-read pass. - -**Hard rule**: every data chart whose type appears in the **Supported chart types** list of [shared-standards.md](shared-standards.md) "Native PPTX Table / Chart Markers" (the single authority for the eligible set, marker contract, and JSON schemas) gets `data-pptx-native="chart"` plus a `` JSON child on its top-level ``, transcribing the same data just plotted. Every pure text-grid data table gets `data-pptx-native="table"` the same way, transcribing all visible cell text into `columns` / `rows`. - -- Chart types absent from that list and conceptual/diagrammatic graphics (process flows, cycles, quadrant cards, timelines, KPI cards) get **no marker** — `svg_quality_checker.py` rejects unsupported marker types. -- Canonical rectangular merged text cells may carry a table marker by putting anchor-only `row_span` / `col_span` in metadata and leaving covered cells blank. Nonrectangular/overlapping merges, nonblank covered cells, and graphical cells (icons, harvey balls, rating dots) get **no table marker** and stay on the SVG fallback route. -- Transcribe, don't restyle: `categories` / `series[].values` are the numbers just plotted; `style.colors` carries the series HEX values already used on the page (from `spec_lock.colors`). -- Data-point color: when a single column/bar series uses data-point colors in the fallback, copy those fills into `series[].point_colors` in category order. -- Data labels: when visible point values are part of the fallback chart, write `data_labels` instead of companion text; use `data_labels.points` for selected labels, and use `number_format`, `font_size`, `font_family`, and per-point `colors` / `color` when the fallback labels carry suffixes or color-coded text. -- Line markers: when the fallback line chart draws visible point nodes, set `line_style: "lineMarker"`; leave the default `line` only for line charts without nodes. -- Area-under-line: when a combo plot is drawn as a filled area under a line, keep `type: "line"`, add `area_fill: true`, and copy the area transparency into `series[].fill_opacity`; copy visible line `stroke-width` into `series[].line_width` for line/area series. -- Native chrome: write `title`, `subtitle`, axis titles, or `show_legend: true` only when the fallback visibly renders the same chrome inside the native chart's replacement scope. `title` is the PowerPoint chart title, not an object name; use `name` for page-semantic object naming (e.g. `p03-revenue-chart`). Write explicit `x`/`y`/`width`/`height` read from the drawn plot area; omission is the fallback — the exporter then infers the frame from the drawn fallback geometry. -- Value-axis labels: when the fallback keeps category labels but intentionally omits numeric value-axis tick labels, set `show_value_axis_labels: false`. -- Freeform chart text: transcribe center labels, source notes, and other in-chart annotations as companion `caption` / `note` / `notes` entries with explicit slide-coordinate bounds; do not rely on fallback `` children to survive native export. -- Native chart typography mirrors the SVG fallback. Copy the fallback's shared chart font into `style.font_family` and visible chart text sizes into the matching metadata fields (`title_font_size`, `subtitle_font_size`, `axis_font_size`, `note_font_size`, etc.) only when role sizes differ; otherwise let the exporter infer them from visible fallback text. When a visible chart title, subtitle, or axis title needs its own size/color/font, write that field as an object with `text`, `font_size`, `font_family`, and `color`. Use `axis_title_font_size`, `legend_font_size`, or companion per-entry `font_size` only when the fallback visibly uses a separate size. -- Native table typography mirrors the SVG fallback. Write `style.font_family` and `style.font_size` from the visible table text; use `header_font_size` or per-cell `font_size` only when the fallback visibly does so. If the fallback has no explicit table font, fall back to the deck body family and locked body size from `spec_lock.md typography`. -- The marker group's transform stays translate/scale only (no rotate / matrix / skew). -- Visual parity is not a goal: the SVG drawing remains the designed visual; the native object is a data-editable counterpart with PowerPoint-default styling that users restyle by hand after export. Never simplify the SVG design to match what a native object could show. - -**Per-page verification** — after writing each eligible data-chart or text-grid table page, confirm the marker exists: - -```bash -grep "data-pptx-native" /svg_output/.svg -``` ### SVG File Naming Convention @@ -380,6 +178,8 @@ Strategist chooses the library and inventory; Executor only implements. Library > **Resolution is project-first.** Strategist copied the chosen icons into `/icons//` (via `icon_sync.py`); `finalize_svg.py embed-icons` embeds from there, falling back to the global library per-icon. **Custom icons**: drop an `.svg` into `/icons//` (any ``, e.g. `custom/`) and reference it as `data-icon="/"` — it embeds like any other. Reference only icons in the `spec_lock.md` inventory. +> **Icon identifiers are case-sensitive filenames.** For bundled libraries, copy the verified lowercase basename exactly (`tabler-outline/award`, never `tabler-outline/Award`) into `spec_lock.md` and every `data-icon` value. Custom icon identifiers preserve the custom file's exact case; the pipeline never silently lowercases names. + **Built-in icons — Placeholder method (recommended)**: ```xml @@ -405,7 +205,9 @@ Strategist chooses the library and inventory; Executor only implements. Library > ⚠️ **Color**: ALWAYS use `fill="#HEX"` on ``. NEVER use `stroke` or `fill="none"`, even for stroke-style libraries. > -> **stroke-width** (stroke-style libraries only, currently `tabler-outline`): allowed values `{1.5, 2, 3}`. If `spec_lock.md icons.stroke_width` is declared, all placeholders MUST use that value deck-wide. Default `2` if absent (legacy). Ignored on non-stroke libraries. +> **stroke-width** (stroke-style libraries only, currently `tabler-outline`): allowed values `{1.5, 2, 3}`. If `spec_lock.md icons.stroke_width` is declared, all placeholders MUST use that value deck-wide. Ignored on non-stroke libraries. +> +> **Missing `icons.stroke_width` in an existing stroke-library lock — fixed compatibility default**: use `2`, emit one warning, and continue. New authoring must still declare the field. > > Icons are auto-embedded by `finalize_svg.py` — no need to run `embed_icons.py` manually. @@ -449,147 +251,27 @@ ls skills/ppt-master/templates/icons/simple-icons/ | grep github --- -## 5. Visualization Reference - -Chart SVGs referenced in **VII. Visualization Reference List** are loaded once via the §1.0 batch read. This section governs adaptation only. - -**Hard rule**: adapt the loaded chart SVG; do not improvise from memory and do not replicate verbatim. Apply project colors, typography, content; preserve visualization type. - -**Adaptation rules**: -- **Preserve**: visualization type (bar/line/pie/timeline/process/framework…) as specified -- **Adapt**: data, labels, colors (project scheme), dimensions -- **Freely adjust**: composition, axis ranges, grid, legend, spacing, decoration — as long as the chart stays accurate and readable -- **Forbidden**: changing visualization type without spec justification; omitting data points or structural elements from the outline - -> Templates: `templates/charts/` (76 types). Index: `templates/charts/charts_index.json` - -### 5.1 Chart Coordinate Calibration - -Coordinate calibration runs as a **standalone post-generation workflow**, not inside the executor pipeline. After SVG generation completes, if the deck contains data charts, run [`workflows/verify-charts.md`](../workflows/verify-charts.md) before post-processing. - -The executor's only obligation here is upstream: embed the `` marker on every chart page during initial draft (§3.1). Verify-charts enumerates chart pages from `design_spec.md §VII` (authoritative deck plan) and uses the marker to feed `svg_position_calculator.py`. - -> Do NOT run `svg_position_calculator.py` during the initial draft. The calculator calibrates already-generated SVGs against their declared plot areas; running it before the SVG exists has nothing to compare against. - ---- - -## 6. Image Handling - -Handle images by their status in the Design Spec's Image Resource List. Status enum and lifecycle: [`svg-image-embedding.md`](svg-image-embedding.md). - -| Status | Source | Handling | -|--------|--------|----------| -| **Existing** | User-provided | Reference images directly from `../images/` directory | -| **Generated** | Generated by Image_Generator | Reference images directly from `../images/` directory | -| **Sourced** | Web-acquired by Image_Searcher | Reference from `../images/`. **Read [`image_sources.json`](image-searcher.md) to decide attribution** — see §6.1 below. | -| **Rendered** | Deterministic formula PNG | Reference from `../images/`; use `preserveAspectRatio="xMidYMid meet"` | -| **Needs-Manual** | Acquisition failed and file is absent | Use dashed border placeholder unless the expected file exists | -| **Placeholder** | Not yet prepared | Use dashed border placeholder | - -**Reference syntax**: see [`svg-image-embedding.md`](svg-image-embedding.md). - -**Template-bundled images**: when a template (deck / layout / brand) is applied, its bitmaps are copied into the project's `images/` alongside every other runtime image (SKILL.md Step 3). Reference them the same way — `../images/` — and do **not** reproduce a template SVG's bare sibling href (e.g. `href="cover_bg.png"`): the template SVG is reference material, the rendered page lives in `svg_output/` and must point at `../images/`. Mirror templates (§1.1) are the one exception — they copy hrefs verbatim, and the exporter resolves those bare hrefs against `images/`. - -**Placeholder**: Dashed border `` + description text - -**`no-crop` images**: when a `spec_lock.md images` entry ends with ` | no-crop`, size the container to the image's native ratio (from `analyze_images.py` or file dims) and use `preserveAspectRatio="xMidYMid meet"`. Untagged entries are croppable — default to `slice`. - -**Formula images**: rows with `Acquire Via: formula` or `Type: Latex Formula` MUST be treated as no-crop even if a legacy `spec_lock.md` forgot the flag. Use the dimensions from `design_spec.md §VIII`, `analysis/image_analysis.csv`, or `images/formula_manifest.json`; do not normalize all formulas to one height unless the spec explicitly states that layout choice. - -### 6.1 Inline Attribution for Sourced Images (web path) - -Whenever the slide uses an image with `Status: Sourced`, look up the corresponding entry in `project/images/image_sources.json` and act on `license_tier`: - -| `license_tier` | Action on this slide | -|---|---| -| `no-attribution` | Embed the `` element only. **No credit element needed.** | -| `attribution-required` | Embed the `` element **plus** a small inline `` credit element per the visual spec in [image-searcher.md §7](./image-searcher.md). | -| `manual` | Embed the `` element only. **No credit element** — a user-supplied `--from-url` replacement; verifying usage rights / any required credit is the user's responsibility. | - -The credit text is **not** rendered by post-processing or export — it must be present in the SVG you produce. The shape of the credit element (size, position, color, multi-image source line, hero gradient overlay) is specified in [image-searcher.md §7](./image-searcher.md). Do not invent a different style. - -Use `attribution_text` from the manifest entry as the **starting point**, then compress for the small-text constraint (drop URL, drop filename, keep "via Provider / License"). For CC0/PD images that landed in the `attribution-required` tier only because of upstream metadata quirks (rare), credits are still safe to render. - -`svg_quality_checker.py` treats missing CC BY / CC BY-SA inline attribution as an **error**. Fix the offending SVG before post-processing. - -**The manifest is the single source of truth for credits.** Do not duplicate license info into speaker notes or any other artifact. - ---- - -## 7. Font Usage +## 5. Font Usage Source of truth: `spec_lock.md typography`. Use `font_family` as default; override per role with `title_family` / `body_family` / `emphasis_family` / `code_family` if declared. LaTeX formulas that Strategist rendered are PNG images, not a `code_family` text role. -If `spec_lock.md` is absent, consult [`strategist.md`](strategist.md) §g — do not invent a stack. +**Missing required field — `typography.font_family`** → stop and return to Generate Step 4 / [`strategist.md`](strategist.md) §6.2 to repair `spec_lock.md`; do not infer a stack from `design_spec.md`. **Hard rule**: every SVG `font-family` stack MUST resolve to pre-installed exported Latin / EA typefaces (Microsoft YaHei / SimHei / SimSun / Arial / Calibri / Segoe UI / Times New Roman / Georgia / Consolas / Courier New / Impact / Arial Black). PPTX has no runtime fallback — missing fonts degrade to Calibri. --- -## 8. Speaker Notes Generation Framework +## 6. Completion Routing -### Task 1. Generate Complete Speaker Notes Document +After every SVG page passes the final quality check, load [`executor-notes.md`](./executor-notes.md) and complete its notes contract before entering the route's Step 7. -After all SVG pages are finalized, enter Logic Construction Phase and write the full notes to `notes/total.md`. Batch-writing (not per-page) lets transitions plan coherently. - -**Pure spoken narration**: notes are read aloud verbatim by `notes_to_audio.py` (TTS). Write only what should be spoken. No visible markers, no labeled meta-lines, no enumerated key-point lists, no duration annotations — anything you write outside the heading will be vocalized. - -**Per-page structure**: `# _` heading (the `#` heading line is the only thing stripped before TTS), pages separated by `---`. Body is 2–5 natural sentences carrying the page's core message. Page-to-page transitions live inside the opening sentence as natural prose ("接下来……" / "Having framed X, let's turn to Y") — no bracketed `[过渡]` / `[Transition]` tags. - -**Concrete examples** — same shape applies to any language; just write naturally in that language. - -中文 deck: - -``` -# 02_市场格局 - -在明确了行业背景之后,我们来看具体的市场格局。当前线上零售集中度持续上升,前三大平台合计份额已经达到百分之六十八,腰部玩家正在被快速挤压,留给新进入者的窗口期不超过十八个月。这意味着我们的策略必须聚焦,而不是铺开。 -``` - -英文 deck: - -``` -# 02_market_landscape - -Having framed the industry backdrop, let's look at the actual market landscape. Online retail concentration keeps rising — the top three platforms now hold sixty-eight percent of combined share, mid-tier players are being squeezed fast, and the window for new entrants is under eighteen months. This means our strategy has to focus, not spread. -``` - -> 日本語 / 한국어 / 其他语言:照搬同样的结构,用对应语言自然书写即可。 - -**Number readability**: TTS reads digits and symbols literally. Prefer fully-spelled forms in the language being spoken when literal pronunciation would be awkward (e.g. Chinese "百分之六十八" reads better than "68%"; "1-2分钟" reads as "一减二分钟"). Plain integers and percentages in English are fine as-is. - -**Common mistakes to avoid**: -- Leaving any bracketed stage marker (`[过渡]` / `[Transition]` / `[Pause]` / `[Data]` / `[Scan Room]` / `[Interactive]` / `[Benchmark]` etc.) in the text — they will be read aloud literally. -- Adding `要点:① …` / `Key points: (1) …` / `时长:2分钟` / `Duration: 2 minutes` / `Flex: …` lines — TTS will speak "要点 一 …". -- Mixing languages within one deck's notes. - -### Task 2. Split Into Per-Page Note Files - -Auto-split `notes/total.md` into per-page files in `notes/`. - -**Naming**: match SVG names (`01_cover.svg` → `notes/01_cover.md`); `slide01.md` also supported (legacy). - ---- - -## 9. Next Steps After Completion +## 7. Next Steps After Completion > **Auto-continuation**: After Visual Construction Phase (all SVG pages) and Logic Construction Phase (all notes) are complete, the Executor proceeds directly to the post-processing pipeline. -**Post-processing & Export** (canonical workflow: [`SKILL.md` Step 7](../SKILL.md)): - -```bash -# 1. Split speaker notes -python3 scripts/total_md_split.py - -# 2. SVG post-processing (auto-embed icons/images and flatten positioned text) -python3 scripts/finalize_svg.py -# Output: svg_final/ self-contained SVG visual previews - -# 3. Export PPTX -python3 scripts/svg_to_pptx.py -# Output (default-flow mode): -# exports/_.pptx ← native pptx (canonical output) -# backup//svg_output/ ← Executor SVG source backup (always written) -``` +**Post-processing & Export**: Follow [`generate-pptx.md`](../workflows/generate-pptx.md) +Step 7. That workflow owns the serial commands, gates, success criteria, and +published artifacts; [`svg-pipeline.md`](../scripts/docs/svg-pipeline.md) owns +tool-specific flags and behavior. `svg_final/` may be opened directly or manually inserted into PowerPoint as an SVG picture. It is not a second PPTX route. Use `-s final` only for converter diagnostics; release exports use the default `svg_output/` source. Manual Convert-to-Shape behavior is unsupported. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md new file mode 100644 index 00000000..ac929775 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-chart.md @@ -0,0 +1,132 @@ +> See [`executor-base.md`](./executor-base.md) for the always-loaded Executor core and [`native-data-interface.md`](./native-data-interface.md) for native chart/table metadata schemas. + +# Executor Chart and Table Branch + +Conditional Executor authority for data charts, chart-catalog adaptations, chart verification markers, and eligible native chart/table replacement metadata. + +**Trigger**: load when `design_spec.md §VII` contains a chart/table visualization, `spec_lock.md page_charts` contains any row, or the current page carries any data-encoded chart or text-grid table. Mini charts, sparklines, inset charts, and small multiples count even when they are absent from `page_charts` or the chart catalog. + +## 1. Reference Loading and Per-page Selection + +For each selected `templates/charts/.svg`, use its Skill-relative `reference_set` path + SHA: read once before first use or after change, otherwise reuse it. Never load the full catalog. + +**Per-page chart reference — `page_charts` section**: + +Before drawing each page, look up its entry in `page_charts` to decide which chart structure applies (the SVG itself was loaded in §1): + +- Entry present (e.g., `P09: timeline_horizontal`) → adapt the corresponding chart SVG already in context under §3; do not copy it verbatim. Use the selected §VII row and SVG; do not load the full chart catalog during execution. +- No entry for this page → either no chart on this page, or a chart that didn't match any catalog template (Strategist's `no-template-match` fallback). Design the visualization from scratch using `design_spec.md §VII` for guidance. +- Whole section absent → no chart pages in this deck. + +--- + +## 2. Chart and Native-data Authoring + +### 2.1 Chart Plot-Area Marker (MANDATORY on every chart page) + +> The [`verify-charts`](../workflows/stages/verify-charts.md) stage enumerates chart pages from `design_spec.md §VII`, then reads each page's plot-area marker to feed `svg_position_calculator.py`. A missing marker invokes that stage's declared fallback and adds avoidable derivation work. + +**Hard rule**: every SVG page that contains a data visualization chart includes a plot-area marker inside ``, placed **after axis lines** and **before the first data element** (bar, line, area, point). + +**Rectangular plot area** (bar / horizontal_bar / grouped_bar / stacked_bar / line / area / stacked_area / scatter / waterfall / pareto / butterfly): + +```xml + +``` + +**Radial charts** (pie / donut / radar): + +```xml + + + +``` + +**How to determine coordinate values**: + +| Value | Derivation | +|-------|------------| +| `x_min` | X coordinate of the Y-axis line (leftmost data boundary) | +| `y_min` | Y coordinate of the topmost grid line (highest data boundary) | +| `x_max` | X coordinate of the rightmost axis endpoint or grid line | +| `y_max` | Y coordinate of the X-axis baseline | +| `cx, cy` | Center point of pie/donut/radar (accounting for `transform="translate()"`) | +| `r` | Outer radius of the chart | + +**Per-page verification** — after writing each chart SVG, confirm the marker exists: + +```bash +rg -n "chart-plot-area" /svg_output/.svg +``` + +> Calculator-supported data-chart templates in `templates/charts/` include this +> marker as a reference. If a data chart covered by §2.1 lacks it, that is a +> bug. Conceptual diagrams, frameworks, and other non-data visualizations in +> the same library do not use a plot-area marker. +Technical SVG/PPT constraints remain in [`shared-standards-core.md`](./shared-standards-core.md). + +### 2.2 PowerPoint-Native Chart/Table Replacement Marker (MANDATORY on eligible data-chart and text-grid table pages) + +> `svg_to_pptx.py --native-charts-and-tables` replaces marked groups with PowerPoint-native Chart/Table objects (charts get an embedded Excel workbook). Markers stay dormant in the default export, whose SVG children become independently editable DrawingML shapes, but a deck without markers can never form data-backed native Chart/Table objects. Write the marker at draw time: the data is already in hand, and recovering it later costs a full re-read pass. + +**Hard rule**: before deciding whether a chart or table is eligible for native replacement, load [`native-data-interface.md`](./native-data-interface.md). Every data chart whose type appears in that authority's **Supported chart types** list gets `data-pptx-replace-with="chart"` plus one `` JSON child on its top-level ``, transcribing the same data just plotted. Every pure text-grid data table gets `data-pptx-replace-with="table"` the same way, transcribing all visible cell text into `columns` / `rows`. The parent marker determines the JSON schema; do not duplicate a chart/table kind on the metadata child. + +**MUST — atomic authoring**: Treat the visible SVG fallback, the parent `data-pptx-replace-with` marker, and its JSON `` child as one object. Write all three in the same SVG edit while the plotted data is in context. A supported chart or eligible table is unfinished if either the marker or metadata is missing; do not defer either one to `verify-charts`, the final quality gate, or export. + +**Hard rule — eligibility follows data semantics**: Size, point count, visual prominence, page role, catalog match, and the current export mode do not change eligibility. A two-point mini line chart, sparkline, chart inset, KPI-card trend, or small multiple that encodes recoverable categories/values still gets its own marked top-level `` and metadata payload when its chart type is supported. Decorative strokes and arrows without recoverable chart data remain ordinary SVG geometry. + +Generated authoring MUST omit `data-pptx-import-source` and +`data-pptx-fallback-sha256`: those attributes record imported-PPTX provenance +and its sealed fallback baseline. Never copy a static baseline from a chart +catalog or reusable template; normal content edits would make it stale. + +`data-pptx-replace-with` is a **data-backed replacement claim**, not a generic label for a group that contains numbers and not a marker for ordinary PowerPoint shapes or connectors. Add it only when the matching JSON payload can be written in the same edit; if the object is meant to remain SVG geometry, do not add the marker. + +- Chart types absent from that list and conceptual/diagrammatic graphics (process flows, cycles, quadrant cards, timelines, or a KPI card container) get **no marker** — `svg_quality_checker.py` rejects unsupported marker types. A supported data chart nested visually inside one of those compositions still gets its own marker. +- Canonical rectangular merged text cells may carry a table marker by putting anchor-only `row_span` / `col_span` in metadata and leaving covered cells blank. Nonrectangular/overlapping merges, nonblank covered cells, and graphical cells (icons, harvey balls, rating dots) get **no table marker** and stay on the SVG fallback route. +- Transcribe, don't restyle: `categories` / `series[].values` are the numbers just plotted; `style.colors` carries the series HEX values already used on the page (from `spec_lock.colors`). +- Data-point color: when a single column/bar series uses data-point colors in the fallback, copy those fills into `series[].point_colors` in category order. +- Data labels: when visible point values are part of the fallback chart, write `data_labels` instead of companion text; use `data_labels.points` for selected labels, and use `number_format`, `font_size`, `font_family`, and per-point `colors` / `color` when the fallback labels carry suffixes or color-coded text. +- Line markers: when the fallback line chart draws visible point nodes, set `line_style: "lineMarker"`; leave the default `line` only for line charts without nodes. +- Area-under-line: when a combo plot is drawn as a filled area under a line, keep `type: "line"`, add `area_fill: true`, and copy the area transparency into `series[].fill_opacity`; copy visible line `stroke-width` into `series[].line_width` for line/area series. +- Native chrome: write `title`, `subtitle`, axis titles, or `show_legend: true` only when the fallback visibly renders the same chrome inside the native chart's replacement scope. `title` is the PowerPoint chart title, not an object name; use `name` for page-semantic object naming (e.g. `p03-revenue-chart`). Write explicit `x`/`y`/`width`/`height` read from the drawn plot area; omission is the fallback — the exporter then infers the frame from the drawn fallback geometry. +- Value-axis labels: when the fallback keeps category labels but intentionally omits numeric value-axis tick labels, set `show_value_axis_labels: false`. +- Freeform chart text: transcribe center labels, source notes, and other in-chart annotations as companion `caption` / `note` / `notes` entries with explicit slide-coordinate bounds; do not rely on fallback `` children to survive native export. +- Native chart typography mirrors the SVG fallback. Copy the fallback's shared chart font into `style.font_family` and visible chart text sizes into the matching metadata fields (`title_font_size`, `subtitle_font_size`, `axis_font_size`, `note_font_size`, etc.) only when role sizes differ; otherwise let the exporter infer them from visible fallback text. When a visible chart title, subtitle, or axis title needs its own size/color/font, write that field as an object with `text`, `font_size`, `font_family`, and `color`. Use `axis_title_font_size`, `legend_font_size`, or companion per-entry `font_size` only when the fallback visibly uses a separate size. +- Native table typography mirrors the SVG fallback. Write `style.font_family` and `style.font_size` from the visible table text; use `header_font_size` or per-cell `font_size` only when the fallback visibly does so. If the fallback has no explicit table font, fall back to the deck body family and locked body size from `spec_lock.md typography`. +- The marker group's transform stays translate/scale only (no rotate / matrix / skew). +- Visual parity is not a goal: the SVG drawing remains the designed visual and exports as editable DrawingML shapes; the native object is the data-backed counterpart with PowerPoint's chart/table-specific model. Never simplify the SVG design to match what a native object could show. + +**Per-page verification** — after writing each eligible data-chart or text-grid table page, enumerate the eligible objects and confirm a one-to-one match: every object has one parent marker and exactly one JSON metadata child. Finding one marker somewhere on a page is insufficient when the page contains multiple eligible objects. + +```bash +rg -n 'data-pptx-replace-with="(chart|table)"|' /svg_output/.svg +``` + + +--- + +## 3. Visualization Reference + +Chart SVGs referenced in **VII. Visualization Reference List** are loaded once through §1. This section governs adaptation only. + +**Hard rule**: adapt the loaded chart SVG; do not improvise from memory and do not replicate verbatim. Apply the active Design Spec and `spec_lock.md`; preserve the visualization type and data semantics. + +**Adaptation rules**: +- **Preserve**: visualization type (bar/line/pie/timeline/process/framework…), information relationships, data encoding, structural grouping, and capacity +- **Carry forward**: every planned label, value, unit, status, source, and explanatory block; never shorten or drop content to imitate a lighter catalog preview +- **Adapt**: project data and labels, dimensions, axes, legend, and spacing as the authored content requires +- **Project-owned**: palette, typography, container treatment, effects, background, and page chrome; catalog preview values are fallbacks, never defaults +- **Bound final body modules**: add or revise root-coordinate `data-pptx-bounds` on every visible direct root `` copied into the final page; nested groups need none, chart geometry and local references are not content-boundary inputs, and catalog reference warnings never waive the final-page contract +- **Adjust with fidelity**: composition, axis ranges, and grid may change within the project contract only when no content, relationship, hierarchy, or capacity is lost +- **Forbidden**: changing visualization type without spec justification; omitting data points or structural elements from the outline + +> Templates: `templates/charts/`. The Strategist's selected key is already locked in `page_charts`; execution opens only that key's SVG. + +### 3.1 Chart Coordinate Calibration + +Coordinate calibration runs as a **conditional post-generation stage**, not inside the Executor authoring loop. After SVG generation completes, if the deck contains data charts, run [`verify-charts`](../workflows/stages/verify-charts.md) before post-processing. + +The executor's only obligation here is upstream: embed the `` marker on every chart page during initial draft (§2.1). Verify-charts enumerates chart pages from `design_spec.md §VII` (authoritative deck plan) and uses the marker to feed `svg_position_calculator.py`. + +> Do NOT run `svg_position_calculator.py` during the initial draft. The calculator calibrates already-generated SVGs against their declared plot areas; running it before the SVG exists has nothing to compare against. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md new file mode 100644 index 00000000..a2b78278 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-image.md @@ -0,0 +1,32 @@ +> See [`executor-base.md`](./executor-base.md) for the always-loaded Executor core. + +# Executor Image Branch + +Conditional Executor authority for image status handling, placement, crop behavior, formula images, and template-bundled images. + +**Trigger**: load when `design_spec.md §VIII` or `spec_lock.md images` contains any image/formula row, or when a selected template carries bitmap assets. + +## 1. Image Handling + +Handle images by their status in the Design Spec's Image Resource List. Status enum and lifecycle: [`svg-image-embedding.md`](svg-image-embedding.md). + +| Status | Source | Handling | +|--------|--------|----------| +| **Existing** | User-provided | Reference images directly from `../images/` directory | +| **Generated** | Generated by Image_Generator | Reference images directly from `../images/` directory | +| **Sourced** | Web-acquired by Image_Searcher | Reference from `../images/`. **Read [`image_sources.json`](image-searcher.md) to decide attribution** — load [`executor-web-image.md`](./executor-web-image.md). | +| **Rendered** | Deterministic formula PNG | Reference from `../images/`; use `preserveAspectRatio="xMidYMid meet"` | +| **Needs-Manual** | Acquisition failed and file is absent | Use dashed border placeholder unless the expected file exists; the Step 7 readiness gate swaps placeholders for real files before export | +| **Placeholder** | Not yet prepared | Use dashed border placeholder | + +**Reference syntax**: see [`svg-image-embedding.md`](svg-image-embedding.md). + +**Template-bundled images**: when a template (deck / layout / brand) is applied, its bitmaps are copied into the project's `images/` alongside every other runtime image ([`apply-template-workspace.md`](../workflows/stages/apply-template-workspace.md)). Reference them the same way — `../images/` — and do **not** reproduce a template SVG's bare sibling href (e.g. `href="cover_bg.png"`): the template SVG is reference material, the rendered page lives in `svg_output/` and must point at `../images/`. `template_reuse_scope: mirror` ([`executor-structured.md`](./executor-structured.md) §1.1) is the one exception — it copies hrefs verbatim, and the exporter resolves those bare hrefs against `images/`. + +Use each resource row's locked layout pattern; do not collapse image-led pages into a generic left/right split. + +**Placeholder**: Dashed border `` + description text + +**`no-crop` images**: when a `spec_lock.md images` entry ends with ` | no-crop`, size the container to the image's native ratio (from `analyze_images.py` or file dims) and use `preserveAspectRatio="xMidYMid meet"`. Untagged entries are croppable — default to `slice`. + +**Formula images — declared-inference fallback for a missing `no-crop` flag**: rows with `Acquire Via: formula` or `Type: Latex Formula` MUST be treated as no-crop. For a rendered file, use dimensions in this order: current `analysis/image_analysis.csv`, `design_spec.md §VIII`, then `images/formula_manifest.json`. For a `Needs-Manual` row, size the dashed placeholder from the planned dimensions in §VIII, then the manifest; the Step 7 readiness gate re-analyzes the supplied file and reconciles the container before export. Do not normalize all formulas to one height unless the spec explicitly states that layout choice. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md new file mode 100644 index 00000000..ff252678 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-notes.md @@ -0,0 +1,54 @@ +> See [`executor-base.md`](./executor-base.md) for the always-loaded Executor core. + +# Executor Speaker-notes Branch + +Conditional late-stage authority for generating the complete speaker-notes document. + +**Trigger**: load only after all SVG pages pass the final quality check. + +## 1. Speaker Notes Generation Framework + +### 1.1 Generate Complete Speaker Notes Document + +After all SVG pages are finalized, enter Logic Construction Phase and write the full notes to `notes/total.md`. Batch-writing (not per-page) lets transitions plan coherently. + +**Pure spoken narration**: notes are read aloud verbatim by `notes_to_audio.py` (TTS). Write only what should be spoken. No visible markers, no labeled meta-lines, no enumerated key-point lists, no duration annotations — anything you write outside the heading will be vocalized. + +**Per-page structure**: `# _` heading (the `#` heading line is the only thing stripped before TTS), pages separated by `---`. Body is 2–5 natural sentences carrying the page's core message. Page-to-page transitions live inside the opening sentence as natural prose ("接下来……" / "Having framed X, let's turn to Y") — no bracketed `[过渡]` / `[Transition]` tags. + +**Reading-mode note burden**: + +| `consumption_mode` | Notes emphasis | +|---|---| +| `text` | Add interpretation or transition without reading the already self-contained page aloud. | +| `balanced` | Connect the visible claim and evidence, explain the trade-off, and bridge to the next page. | +| `presentation` | Carry the reasoning, context, and supporting detail intentionally omitted from the sparse projected surface. | + +**Concrete examples** — same shape applies to any language; just write naturally in that language. + +中文 deck: + +``` +# 02_市场格局 + +在明确了行业背景之后,我们来看具体的市场格局。当前线上零售集中度持续上升,前三大平台合计份额已经达到百分之六十八,腰部玩家正在被快速挤压,留给新进入者的窗口期不超过十八个月。这意味着我们的策略必须聚焦,而不是铺开。 +``` + +英文 deck: + +``` +# 02_market_landscape + +Having framed the industry backdrop, let's look at the actual market landscape. Online retail concentration keeps rising — the top three platforms now hold sixty-eight percent of combined share, mid-tier players are being squeezed fast, and the window for new entrants is under eighteen months. This means our strategy has to focus, not spread. +``` + +> 日本語 / 한국어 / 其他语言:照搬同样的结构,用对应语言自然书写即可。 + +**Number readability**: TTS reads digits and symbols literally. Prefer fully-spelled forms in the language being spoken when literal pronunciation would be awkward (e.g. Chinese "百分之六十八" reads better than "68%"; "1-2分钟" reads as "一减二分钟"). Plain integers and percentages in English are fine as-is. + +**Common mistakes to avoid**: +- Leaving any bracketed stage marker (`[过渡]` / `[Transition]` / `[Pause]` / `[Data]` / `[Scan Room]` / `[Interactive]` / `[Benchmark]` etc.) in the text — they will be read aloud literally. +- Adding `要点:① …` / `Key points: (1) …` / `时长:2分钟` / `Duration: 2 minutes` / `Flex: …` lines — TTS will speak "要点 一 …". +- Mixing languages within one deck's notes. + +After `notes/total.md` is complete, return to Generate Step 7.1. The route authority owns the serial split command and its success criterion. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md new file mode 100644 index 00000000..2b94c8ef --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-structured.md @@ -0,0 +1,176 @@ +> See [`executor-base.md`](./executor-base.md) for the always-loaded Executor core and [`pptx-structure-interface.md`](./pptx-structure-interface.md) for the SVG metadata contract. + +# Executor Structured Template Branch + +Conditional Executor authority for `template_reuse_scope: mirror|layout` with `pptx_structure.mode: structured`. + +**Trigger**: load only when the lock selects structured template reuse. + +## 1. Template Reuse Rules + +### 1.0 Template Context Load + +| Context | Load policy | +|---|---| +| `templates/design_spec.md` | Strategist reads once; continuous Executor reuses it, fresh Executor reads it once | +| Current page delta | Run [`executor-base.md`](./executor-base.md) §2.1 immediately before that page | +| Selected prototype SVG | Read once on an absent/changed `reference_set` path + SHA; otherwise reuse it | + +**Hard rule**: Page-context carries no prototype payload. `reference_set` identifies the authoritative complete SVG; never author from a roster, manifest, sidecar, filename, or summary alone. + +Manifest/text-slot files are derived tool metadata, not model inputs. Missing metadata neither invalidates a legacy workspace nor permits text-topology changes. + +**Mapping change**: update the owning plan and regenerate that page's delta; load only a new/changed prototype fingerprint. + +Resolve the per-page template SVG from `page_context.template.prototype`; the owning `spec_lock.md page_layouts` row remains authoritative. There is no filename/page-type fallback. + +**Resolution order (per page):** + +1. `template_reuse_scope: mirror` → see §1.1. The installed workspace must support `replication_mode: mirror`. +2. `template_reuse_scope: layout` → resolve `P: ` from `page_layouts`, retain the structure system, and apply the non-mirror skin/reflow rules below. +3. `mirror` / `layout` with no current-page `page_layouts` row → stop; adaptive mode still requires one selected input prototype. + +> Note: `page_layouts` disambiguates the multiple content variants a template may ship; missing mappings are contract errors. + +**Default — re-skin `layout` (may override when the application plan keeps template visuals and the lock reflects them)**: inherit geometry, label/legend placement, and series encoding; otherwise repaint template gradients, shadows, fills, and strokes from the current style/lock. Template font sizes remain placeholders. `mirror` preserves visuals under §1.1. + +**Font size is skin, not geometry (non-mirror).** A chart / layout template's hardcoded `font-size` values (often 11–16px, sized for the template's own dense placeholder text) are NOT inherited — classify each text into its `spec_lock.md` role and use that role's locked size, exactly as you re-skin color. **Structural roles (page title / body / subtitle / annotation / footnote) hold their one deck-wide size on every page** — the template's placeholder px never overrides it; same-role text drifting page to page is what makes a deck look unprofessional. + +**Typography execution order (mandatory):** + +1. Build a per-page text inventory from `design_spec.md §IX` + the current `notes/_*.md`. +2. Classify each text item before drawing. **Structural roles** (`title`, `subtitle` / `lead`, `body`, `annotation`, `footnote` / `page_number`) must map to their declared `spec_lock.typography` slot. A **one-off feature element** (a single hero number, an isolated emphasis label) may take an in-ramp intermediate value — the ramp is anchored on `body`, not a closed menu — but a feature size that **recurs** must be promoted to a declared slot. The failure mode this guards against is structural text silently inheriting the template's compact px, not legitimate feature sizing. +3. Copy the role's locked px value into `font-size` verbatim. Do this before placing the text; never start from a template `font-size` and then "adjust". +4. Layout from those locked sizes: compute line-height, wrapped line count, child `y` / `dy`, card padding, card height, column gaps, and available image/chart area from the chosen px values. +5. Only after this reflow may you inspect fit. If fit fails, move / resize containers or simplify local geometry first; do not reduce the role size merely because the inherited template slot was smaller. + +**Geometry adapts to the type, never the reverse**: when the locked size is larger than the template's placeholder text, widen or heighten the card, open spacing, and recompute child `y` / `dy`; do not shrink text to inherit a smaller container. Recompute line-height and downstream coordinates, and allocate wrapped-line height plus padding. Page count and density remain the confirmed Strategist decision: do not repaginate, split, or drop content. If a fully reflowed block still fails, apply the single bounded body-fit exception in [`executor-base.md`](./executor-base.md) §2.1. Mirror instead preserves source typography under §1.1. + +### 1.1 Mirror reuse — literal page replacement + +When `spec_lock.md` records the AI-derived `template_reuse_scope: mirror`, Executor switches to a literal replacement path. The workspace capability `replication_mode: mirror` is a prerequisite, not the trigger by itself: + +1. **Per-page reference selection** — Strategist selects one mirror page per project page via `spec_lock.md page_layouts` (e.g., `P04: 015_content`). The basename is the mirror filename without extension; Strategist made this choice by reading `design_spec.md §V Page Roster` descriptions, not by guessing. +2. **Copy, don't fill** — use the retained full mirror SVG as the starting point, then edit slide-specific text in place. Preserve every non-text element and every `data-pptx-*` structure attribute verbatim. Do not reopen the same path + SHA merely because another page selects it. +3. **What you may edit** — decide the semantic slot mapping and replacement text only. Change only visible string values already carried by `` and `` nodes that express slide-specific content (title, body, captions, KPI labels, dates, page numbers). Keep the number, order, nesting relationship, and **all attributes** of every `` / `` node unchanged. Never merge or split nodes, move a string between nodes, add a new tspan, or delete an empty carrier. `svg_quality_checker.py` and export validate attributes, topology, and prototype hashes against the complete prototype internally. +4. **What you must not touch** — element positions, sizes, fonts, colors, fills, strokes, gradients, **which image each `` points at**, `` grouping, sprite-sheet `` wrappers, decorative `` / `` / `` / `` shapes, `` markers, embedded chart data structures. Mirror's value is preserving the source deck's visual identity — any geometric / decorative drift defeats the purpose. **The `href` path is not the image**: normalizing a bare `href="cover_bg.png"` to `href="../images/"` (when Step 3 relocated the asset to `images/`) points at the *same* image and changes nothing visual — that is an allowed path fix, not a fidelity edit. Leaving the bare href as-is is also fine; the exporter and live preview resolve bare hrefs against `images/` either way. +5. **Content fit** — if the replacement needs a different number of text segments/items, do not merge/split nodes, drop sourced content, or restructure the grid. Select a better mirror prototype and update the planning mappings, or report `warning: P content does not fit mirror reference ; choose another prototype or change template_reuse_scope to layout/style`. +6. **Visible text editing** — mirror SVGs may keep literal source text rather than `{{...}}` authoring markers. Edit values in place while retaining imported semantic `data-pptx-placeholder` identity and exact text topology. +7. **Output filename** — follow the standard project SVG naming convention (`_.svg` where `` matches the project page index, not the mirror source index). The mirror filename is the *reference*, not the *output*. + +**Detecting mirror mode**: read `page_context.template.reuse_scope` from the current page delta. `replication_mode: mirror` in the installed template only determines whether that derived scope is legal; it must never force mirror behavior when the lock records `layout` or `style`. + +**Mirror + chart pages**: chart structures inside a mirror SVG are already drawn (axis, series, labels). Treat them as visual references — replace the data labels and series text content to match the project's chart spec, but do not redraw the chart from a `templates/charts/.svg` baseline. A mirror template's `page_charts` entries are normally absent for this reason. + +**Legacy template boundary**: A template with missing root Master identity, direct atomic placeholders, `data-pptx-layout-kind`, unmapped `baseline`, `preserve`, or `layout_strategy: distill` is not a fallback input. Stop and create a new current workspace through [`create-template`](../workflows/create-template.md) before generation. + +### Page-Template Mapping Declaration (Required Output) + +Before generating each page, output which template is used: + +``` +📝 **Template mapping**: `templates/03a_content_image_text.svg` (free-design routes may use "None") +🎯 **Adherence rules / layout strategy**: [specific description] +``` + +- **Content pages**: template defines only header/footer; content area is free +- **No template**: allowed only on free-design or brand-only routes + +### 1.2 PowerPoint Master / Layout Mapping + +This section applies only when a deck/layout template's AI-derived lock records `template_reuse_scope: mirror|layout`. `page_layouts` selects the input SVG prototype, `pptx_masters` / `pptx_layouts` declare unique reusable output definitions, and `page_pptx_layouts` assigns every generated page before the first page is drawn. `template_reuse_scope: style`, free-design, and brand-only routes use `pptx_structure.mode: flat`, omit all four sections, skip the rest of §1.2, and keep every SVG object Slide-local. + +**Hard rule — reuse-scope route**: `template_reuse_scope: mirror|layout` requires `pptx_structure.mode: structured`. `template_reuse_scope: style` requires `mode: flat` even though a template supplied its visual vocabulary. Missing mode or legacy values (`baseline`, `template`, `preserve`), `layout_strategy`, Layout-kind fields, partial mappings, and old direct placeholders stop generation. Create a new template workspace through [`create-template`](../workflows/create-template.md); do not upgrade the active SVG project in place. + +**Hard rule — root identity**: A `page_pptx_layouts` row binds the page to one key in `pptx_layouts`; that unique definition supplies its Master key, Layout picker name, and prototype source. Put the declared Master key/name and Layout key/name on the root SVG. A Layout key belongs to exactly one Master and remains globally unique. + +**Hard rule — atomic fixed layers**: Every `data-pptx-layer="master|layout"` visual is one direct root semantic atom that compiles to one DrawingML object. An ordinary marked `` is forbidden; one validated compact authored-preset `` emitted by `preset_shape_svg.py` is the sole group exception because it compiles to one native shape. When reconstructing source PPTX groups, recursively push supported transforms, paint, opacity, and z-order into atomic children. Repeat the identical ordered Master atom contract on every page using that Master and the identical ordered Layout atom contract on every page sharing that `(master, layout)` pair. + +**Hard rule — PowerPoint paint order**: Direct children appear in this order: Master background atoms, Layout background atoms, optional Slide background, remaining Master atoms, remaining Layout atoms, then slot groups and Slide-local content groups. Backgrounds are the inheritance plane beneath all shapes. + +**Mandatory — slot authoring**: A reusable content slot is one direct root `` carrying `data-pptx-placeholder` and one positive `data-pptx-bounds`; the same design zone is both the reusable Layout default and the slot module boundary. A normal slot contains exactly one compatible direct drawable child marked `data-pptx-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. Decorations do not belong in the slot; move reusable decoration to a root Layout atom and keep page-specific labels/captions in another bounded slot or Slide-local group. + +**Mandatory — slot identity**: Preserve imported `data-pptx-idx` values where available; otherwise omit the title index and assign unique indices only where repeated roles need disambiguation. Pages sharing one Layout key repeat the same slot ids/types/effective indices/default bounds/binding modes. Current text, crop, and Slide-local carrier geometry may differ. + +**Composite proxy fallback**: A genuinely composite region may use a direct `` with positive bounds. Its visible group remains Slide-local and export creates one hidden transparent matching placeholder proxy. This downgrade is valid only for `object`; do not use it for an ordinary title, body, picture, chart, table, or media slot. + +**Forbidden — dummy carriers**: Never satisfy a carrier slot with tiny text, near-transparent glyphs, background-colored punctuation, or other fake content. Leave an intentionally blank text carrier empty/whitespace-only—the exporter emits a legal invisible U+200B run—or use the composite `object` proxy contract. If `strict` prototype binding cannot represent the completed composition, surface the mismatch; select a compatible prototype or create an explicit adaptive Layout instead of hiding the conflict. + +**Zero-slot Layout**: A Layout may have no slot groups. Covers, posters, and fixed visual pages still declare their named Master/Layout and fixed atoms. Do not manufacture a full-page `object` slot or empty `utility` identity. + +**Mandatory — per-page slot coverage**: On every mapped page, declare a slot for each standard role the page actually has: the page heading as `title`, a cover tagline as `subtitle`, the page number as `slide-number`, running footer text as `footer`, a hero / content image as `picture`, and a body block already authored as one merged text frame as `body`. A page shipping zero slots exports a Layout with no insertable placeholders — valid only for a genuinely fixed composition (see Zero-slot Layout above), never as the deck-wide default. Pages sharing one layout key ship the same slot set. + +**Hard rule — variable slot content**: “Per-page headings never stay Slide-local by default” means authoring them as `title` / `subtitle` slots; it never permits page-varying text or images to become fixed Layout atoms. Any such value that varies across pages sharing one Layout key MUST be carried by a slot or remain Slide-local. + +**Mandatory — master/layout layer coverage**: On every mapped page, mark the deck-wide background and every-page chrome (footer bar, running logo) `data-pptx-layer="master"`, and mark the static framing that defines this layout key's composition (header rule, divider band, zone panels — including chrome repeated on every content page but absent from the cover) `data-pptx-layer="layout"`. A mapped page with zero `data-pptx-layer` marks exports a bare Master and an empty Layout — the layer marks, not the slide content, give each Layout its visible design. + +**Layout identity**: Different keys differ in fixed Layout atoms or slot topology/default bounds/binding modes. Identical contracts should share one key. Current wording, imagery, crop, and Slide-local geometry never define identity. + +**Template adherence**: Strict preserves reusable Master/Layout atoms and slot ids/types/indices/default bounds/bindings. Under `layout`, the application plan may still change current text/tspans, line height, crop, and carrier-local geometry inside those bounds; `mirror` remains topology-frozen. Adaptive keeps the prototype Master and changes reusable atoms or slots only under a new explicit Layout key/name, written to `spec_lock.md pptx_layouts` while authoring the first affected page. Changing only content is not a new Layout. + +**Layout-content boundary**: Mark only genuinely reusable fixed framing as a Master/Layout atom. Concrete titles, body copy, metrics, chart marks, images, and page-specific groups remain inside slot groups or ordinary Slide-local content groups. The exporter never infers or clusters structure. + +**Background ownership**: + +| Scope | SVG authoring | +|---|---| +| Deck-wide default | Direct full-canvas solid `` repeated identically on every page | +| Page-type default | Direct full-canvas solid `` repeated on every page sharing that layout key | +| One-page exception | Direct full-canvas solid `` | + +The exporter writes these solid fills as real Master/Layout/Slide `p:bg`, not selectable full-canvas shapes. In structured mode, gradients, preset patterns, images, textures, and overlay panels remain explicit shapes or pictures; the generic background-promotion rule outside structured mode does not expand this ownership contract. + +--- + +## 2. Per-page Structured Lookup + +**Per-page template lookup — `page_layouts` section (`mirror` / `layout` only)**: + +Before drawing each page, use `page_context.template.prototype` to identify the inherited basename. Its matching `reference_set` entry supplies the complete SVG's path and SHA; §1.0 owns whether that file must be read or can be reused from the active context: + +- Entry present (e.g., `P04: 03a_content_image_text`) → inherit the corresponding full SVG. The basename **must match** an actual file in the chosen template directory. If it does not, stop before drawing and report the invalid mapping; neither `strict` nor `adaptive` may fall back to free design inside a structured template deck. +- No entry for this page with `template_reuse_scope: mirror|layout` → stop before drawing and report the missing Strategist mapping. Adaptive mode still requires one selected complete template SVG; flexibility applies to the post-design output Layout, not to whether an input prototype exists. +- Whole section absent while `template_reuse_scope: mirror|layout` is present → stop before drawing; the current template contract is incomplete. +- `template_reuse_scope: style` → the whole section must be absent; do not perform per-page prototype lookup. + +Do **not** invent a prototype entry, and do **not** assume a structured template just because `templates/` exists. For `mirror` / `layout`, a missing or invalid `page_layouts` row is an upstream contract error. `style` is a separate flat deck route, never a per-page fallback. + +**Per-page PowerPoint layout lookup — `template_reuse_scope: mirror|layout` only**: + +- When `pptx_structure.mode` is `flat` (including `template_reuse_scope: style`), skip this lookup and the structured scaffold below. `pptx_masters`, `pptx_layouts`, `page_layouts`, and the corresponding SVG metadata must all be absent; each root still declares its canonical `data-pptx-page-role`. +- With `template_reuse_scope: mirror|layout`, `pptx_structure.mode` must equal `structured`; any other or missing value is rejected. Do not migrate an invalid structured contract in place: create a new current-contract workspace through Create Template before generation resumes. +- Read the current page assignment as `P: `. Resolve the assigned Layout key in `pptx_layouts`, then resolve its Master key in `pptx_masters`. Missing, malformed, or partial mappings stop before drawing. +- Write matching root Master/Layout key and picker names. Do not write `data-pptx-layout-kind` or `data-pptx-page-role`. +- On strict template use, the row and SVG contract match the selected prototype exactly. +- On adaptive template use, retain the prototype Master. If the final composition changes fixed Layout atoms or slot topology/bounds, allocate a new key/name and update this row before completing the page. +- A Layout key may repeat across non-adjacent pages only when its fixed atoms and slot contracts are identical. + +**Structured template-page scaffold**: + +```xml + + + + + + + + + + + + + + + + +``` + +On structured template pages, Master/Layout atoms and slot groups are direct root children and precede ordinary content groups. Structural metadata nested inside an ordinary content group fails export. Flat pages use ordinary top-level semantic groups only. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md new file mode 100644 index 00000000..e9f580e8 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/executor-web-image.md @@ -0,0 +1,25 @@ +> Load after [`executor-image.md`](./executor-image.md). + +# Executor Web-image Attribution Branch + +Conditional Executor authority for inline attribution on web-sourced images. + +**Trigger**: load when at least one placed image has `Status: Sourced`. + +## 1. Inline Attribution for Sourced Images + +Whenever the slide uses an image with `Status: Sourced`, look up the corresponding entry in `project/images/image_sources.json` and act on `license_tier`: + +| `license_tier` | Action on this slide | +|---|---| +| `no-attribution` | Embed the `` element only. **No credit element needed.** | +| `attribution-required` | Embed the `` element **plus** a small inline `` credit element per the visual spec in [image-searcher.md §7](./image-searcher.md). | +| `manual` | Embed the `` element only. **No credit element** — a user-supplied `--from-url` replacement; verifying usage rights / any required credit is the user's responsibility. | + +The credit text is **not** rendered by post-processing or export — it must be present in the SVG you produce. The shape of the credit element (size, position, color, multi-image source line, hero gradient overlay) is specified in [image-searcher.md §7](./image-searcher.md). Do not invent a different style. + +Use `attribution_text` from the manifest entry as the **starting point**, then compress for the small-text constraint (drop URL, drop filename, keep "via Provider / License"). For CC0/PD images that landed in the `attribution-required` tier only because of upstream metadata quirks (rare), credits are still safe to render. + +`svg_quality_checker.py` treats missing CC BY / CC BY-SA inline attribution as an **error**. Fix the offending SVG before post-processing. + +**The manifest is the single source of truth for credits.** Do not duplicate license info into speaker notes or any other artifact. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md index 63333e20..24f355cd 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-base.md @@ -28,7 +28,7 @@ Defined in `design_spec.md §VIII`. Status enum: see [`svg-image-embedding.md`]( | formula_001.png | 736x168 | Block equation on P03 | Latex Formula | `formula` | Rendered | `E = mc^2` | | spot_team.png | TBD after slicing | Team spot illustration | Illustration | `slice` | Pending | From `spot_sheet.png` cell 1,1 | -**Required per non-skipped row**: `Acquire Via`, `Status`, `Reference`. +**Required per non-skipped row**: `Acquire Via` and `Status`. `Reference` is required for every `web` / `slice` row and every newly authored `ai` row. An existing `ai` row whose `Reference` is omitted or blank may continue only through the declared inference in [`image-generator.md`](./image-generator.md) §8; no other path may infer it. --- @@ -99,7 +99,7 @@ License / attribution data lives **only** in `project/images/image_sources.json` - SVG `` / `` (stripped by `svg_to_pptx.py`) - A separate "Image Credits" appendix slide (lost on single-page sharing) -Executor reads the manifest per slide and renders inline credits when needed — see [`executor-base.md`](./executor-base.md) §6.1 and [`image-searcher.md`](./image-searcher.md) §7. +Executor reads the manifest per slide and renders inline credits when needed — see [`executor-web-image.md`](./executor-web-image.md) §1 and [`image-searcher.md`](./image-searcher.md) §7. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md index cb921552..f3fbea94 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-generator.md @@ -28,7 +28,7 @@ AI images exist to serve the deck's communication goal. Pick whatever combinatio **Hard rule — only what's actually hard**: -- Same `deck_rendering` + same `deck_palette` for every image in the deck +- Same `deck_rendering` + same locked deck color roles for every image in the deck - HEX codes and color names are rendering guidance — never visible text in the image - Long body copy / data points / bulleted lists / long quotes stay in SVG (improving them later means regenerating the image, which is expensive) - **In-image text is only for words that will not need editing later** — visual keywords, decorative lettering, mood words. Editable text (titles that may be reworded, subtitles, dates, authors, captions, body) belongs in SVG. Changing one in-image word costs an image regeneration; one SVG word costs a keystroke. @@ -38,33 +38,31 @@ Everything else is the AI's judgment per page. No mandated padding, no type-lock --- -## 2. Three Dimensions +## 2. Style and Composition Inputs -Every AI image is described by three orthogonal dimensions. Lock them in this order: **Rendering** (deck-wide) → **Palette** (deck-wide) → **Type** (per image). +Every AI image uses one deck-wide rendering, the deck's already-locked color roles, and a per-image type / composition. Only rendering is a separate image-direction decision. | Dimension | Decides | When fixed | |---|---|---| | **Rendering** | Visual style family (vector / sketch-notes / 3d-isometric / corporate-photo / …) | Once per deck — every AI image in the deck shares one rendering | -| **Palette** | How the deck's HEX colors are *used* (proportion + role + temperament). HEX values come from `design_spec.colors`, not from the palette | Once per deck | +| **Deck colors** | The exact background / primary / accent / secondary-accent / text roles from `spec_lock.md colors`; these are consumed directly, not reconfirmed | Already locked in Stage 2 | | **Type** | What the image's internal composition skeleton looks like — geometric layout of a local infographic block (infographic / flowchart / framework / matrix / cycle / funnel / pyramid / comparison / timeline / map / scene). Only applies to `page_role: local`; for `page_role: hero_page`, describe composition with §4.1 primitives instead of picking a type. | Per image | -> **What rendering vs palette means**: rendering is *how the image is drawn* (line quality, texture, depth). Palette is *how colors are distributed and behave* (which color dominates, which is accent, what proportion). The HEX values come from Strategist; palette is the **usage contract** for those HEX values. +> Rendering decides *how the image is drawn* (line quality, texture, depth). Color instructions come from the deck roles: background / secondary background usually dominate, primary carries main forms, and accents stay scarce. Adjust those proportions to the page role, but never invent or substitute HEX. ### 2.1 Where to find each dimension | Reference | Loaded | |---|---| | [`image-renderings/_index.md`](./image-renderings/_index.md) — rendering catalog + auto-selection table | Always (Step 1 below) | -| [`image-palettes/_index.md`](./image-palettes/_index.md) — palette catalog + auto-selection table | Always (Step 1 below) | | [`image-type-templates/_index.md`](./image-type-templates/_index.md) — type catalog + auto-selection table | Always (Step 1 below) | | `image-renderings/.md` | After Step 2 picks the rendering — only the chosen one | -| `image-palettes/.md` | After Step 2 picks the palette — only the chosen one | | `image-type-templates/.md` | After Step 3 picks the type per image — only the types actually used | **Hard rule — on-demand loading**: -- Read the three `_index.md` files once at role entry. -- After locking dimensions, read **only** the specific rendering / palette / type files you selected. +- Read the rendering and type `_index.md` files once at role entry. +- After locking inputs, read **only** the specific rendering / type files selected. - **Never** glob-read an entire subdirectory (`image-renderings/*.md` is forbidden). Token cost balloons and the AI loses focus. --- @@ -73,56 +71,62 @@ Every AI image is described by three orthogonal dimensions. Lock them in this or ### Step 1 — Load the dimension indices -Read all three index files. They are short (~50 lines each) and contain auto-selection tables that let you map `design_spec` signals → dimension values without reading every detail file. +Read the two index files that own user-visible image direction and per-image composition. ``` read_file references/image-renderings/_index.md -read_file references/image-palettes/_index.md read_file references/image-type-templates/_index.md ``` -### Step 2 — Resolve deck-wide rendering + palette +### Step 2 — Resolve deck-wide rendering + deck colors -**Primary path — Strategist already locked these in `spec_lock.md colors`**: +**Primary path — Strategist already locked rendering and ordinary deck colors in `spec_lock.md colors`**: ``` image_rendering: vector-illustration -image_palette: cool-corporate +background: #F8F9FA +primary: #1E3A5F +accent: #D4AF37 ``` -If both fields are present, use them directly — Strategist made the decision in h.5 with full d-e-f-g-h linkage context. Do NOT re-decide. +Use them directly. Do not create another image-color choice and do not change HEX to suit a rendering. -**Hard rule — `custom` escape hatch**: when either value is the literal string `custom`, do NOT `read_file` the preset library for that dimension. Read the sibling `*_behavior` line from `spec_lock.md colors` and splice that prose into the prompt in place of the preset's fewshot snippet. The behavior prose owns the style paragraph (for `custom` rendering) or the proportion/role rules (for `custom` palette). See [`image-renderings/_index.md`](./image-renderings/_index.md) §1.5 / [`image-palettes/_index.md`](./image-palettes/_index.md) §2 for the invocation rules. +**Hard rule — `custom` escape hatch**: when `image_rendering` is `custom`, do not read a preset rendering file. Splice `image_rendering_behavior` into the prompt. The deck color-role rows remain authoritative. -**Fallback path — when `spec_lock.md` lacks both fields** (legacy decks or pipelines that skipped h.5): +**Declared-inference fallback — when an existing `spec_lock.md` omits the `image_rendering` key** (see [`failure-recovery.md`](../workflows/governance/failure-recovery.md) §2): + +This fallback covers a missing key only. An empty or invalid value stops for lock repair. If `spec_lock.md` itself is absent, stop at [`generate-pptx.md`](../workflows/generate-pptx.md) Step 5 before prompt assembly or image generation; do not use `design_spec.md` as a substitute. | Signal | Maps to | |---|---| | `design_spec.md d. Style` mode + descriptor | Rendering (consult renderings `_index.md` auto-selection table) | -| `design_spec.md e. Color Scheme` (HEX) + content vibe | Palette (consult palettes `_index.md` auto-selection table) | -| `design_spec.md f. Icon library` | Sanity check: chosen rendering should be compatible with the icon library's visual weight | +| Existing `spec_lock.md colors` rows | Deck color-role source; never replace them from `design_spec.md` | +| Existing `spec_lock.md icons.library` | Sanity check: chosen rendering should be compatible with the icon library's visual weight | -If the auto-selection table surfaces multiple candidates, pick the first; do not present a choice to the user. +If rendering inference surfaces multiple candidates, pick the first; do not present another choice after confirmation. -> **Tell the user**: when falling back, print one line "spec_lock.md missing `image_rendering`/`image_palette` — inferring `` / `` from design_spec. For optimal deck consistency, lock these in Strategist h.5." Then proceed. +If the table returns `custom`, stop and repair the lock: authoring `image_rendering_behavior` is a planning decision this fallback cannot make, and the deck's SVG style prose is not an image-rendering description. -Then `read_file` the **single resolved** rendering file and the **single resolved** palette file. These two files give you: +> **Tell the user**: when falling back, print one line "spec_lock.md has no `image_rendering`—inferring `` from design_spec; image colors still use the locked deck roles." Then proceed. + +Then read the **single resolved** rendering file. It gives you: - The 80-120 word style paragraph (rendering) -- The proportion / role / temperament rules for the deck's three HEX values (palette) -- Two ready-to-paste prompt snippets per file (fewshot) +- Two ready-to-paste rendering snippets (fewshot) + +Derive color behavior directly from the available roles: background / secondary background carry roughly 55–70% of the image field, primary carries main forms, and accent / secondary accent together usually stay below 10%. A rendering may justify a different balance, but all colors still come from the lock and decorative text colors must remain readable. ### Step 3 — Per-image type + assembly For each `Acquire Via: ai` row in `design_spec.md §VIII`: -1. **Determine type** — only when `page_role: local` (the image sits as a region block on an SVG page). Match the row's `Purpose` against the `_index.md` auto-selection table (methodology visualization → `framework`; process steps → `flowchart`; SWOT/Eisenhower → `matrix`; PDCA / flywheel → `cycle`; etc.). `Purpose` is authoritative for picking among the 11 internal-composition types. **When `page_role: hero_page`, skip type selection** and describe composition directly using §4.1 primitives (single-subject / portrait / typographic / atmospheric). -2. **Determine `text_policy`** — Strategist's value wins when set. Otherwise pick `none` or `embedded` based on whether in-image text serves the page. Long body / data / lists stay in SVG. -3. **Determine `page_role`** — Strategist's value wins when set. Otherwise pick `local` or `hero_page` based on whether the image carries the page or sits inside one. +1. **Determine `page_role`** — Strategist's explicit value wins; a blank or omitted value resolves to `local`. `hero_page` must be explicit. +2. **Determine `text_policy`** — Strategist's value wins when set. **Declared-inference fallback for a blank or omitted value**: pick `none` or `embedded` from the row's `Purpose`, `Reference`, and page intent based on whether in-image text serves the page. Long body / data / lists stay in SVG. +3. **Determine type** — only when the resolved `page_role` is `local` (the image sits as a region block on an SVG page). Match the row's `Purpose` against the `_index.md` auto-selection table (methodology visualization → `framework`; process steps → `flowchart`; SWOT/Eisenhower → `matrix`; PDCA / flywheel → `cycle`; etc.). `Purpose` is authoritative for picking among the 11 internal-composition types. **When the resolved `page_role` is `hero_page`, skip type selection** and describe composition directly using §4.1 primitives (single-subject / portrait / typographic / atmospheric). 4. `read_file references/image-type-templates/.md` (only if not already read — types are commonly reused across images in one deck) 5. **Assemble the prompt** by combining: - The rendering's style paragraph (from Step 2) - - The palette's proportion + role rules applied to the deck's HEX values (from Step 2) + - Color-role instructions derived directly from the locked deck HEX values (from Step 2) - The type's structural layout (from Step 3) - The image's specific `Reference` intent (from `design_spec.md §VIII`) - The container sizing guidance from the type file (so the model knows it's painting a local block, not a full canvas) @@ -142,7 +146,7 @@ Every assembled prompt follows this paragraph structure. **Write prose, not tag ``` [Rendering style paragraph — 80-120 words from the chosen rendering file]. -[Palette behavior — apply the chosen palette's proportion + role rules to the deck's HEX values, e.g. "primary #1E3A5F dominates as the main shape, secondary #F8F9FA provides 60% breathing space, accent #D4AF37 appears in one or two emphasis points only"]. +[Deck color behavior — apply the locked color roles directly, e.g. "secondary background #F8F9FA provides 60% breathing space, primary #1E3A5F carries main forms, accent #D4AF37 appears in one or two emphasis points only"]. [Type-specific composition — from the chosen type file, e.g. "central hub node with four radiating satellite nodes connected by clean lines"]. [Image-specific subject — translated from the row's Reference intent into concrete visual nouns]. [Container note — "composed as a {W}x{H}px image for {page_role} use"; add composition cues only when the page actually needs them. SVG-overlay-reservation cues ("leave the lower band calm — SVG title overlays it", "keep the right third calmer for SVG text") are valid **only** when `page_role: hero_page` (SVG sits on top of the image). For `page_role: local`, the image sits inside a region block and the SVG layer never overlays its interior — never reserve overlay space in a local prompt]. @@ -242,7 +246,7 @@ Example opening for a triptych hero: ### 4.3 Illustration sheets — one generation, many spot elements -When a deck wants several small **spot illustrations** scattered as decorative accessories across pages (the illustration counterpart to icons), do **not** generate them one image per slot — that multiplies generation cost and lets the style drift between calls. Generate **one sheet** that lays out all the elements in a grid, then slice it. One call buys a set of elements with an identical style, palette, and line quality — the same cross-page consistency the deck-wide `deck_rendering` / `deck_palette` lock exists to protect. +When a deck wants several small **spot illustrations** scattered as decorative accessories across pages, do **not** generate them one image per slot. Generate one sheet and slice it. One call buys identical rendering, deck-color treatment, and line quality—the same consistency protected by `deck_rendering` + `color_scheme`. **When to use**: the §VIII image resource plan needs ≥3 small spot illustrations from the same family across the deck. For a single hero/local image, stay with the normal one-row-per-image flow (§4.1). Use sheets only where decorative illustration genuinely lifts the page; an unused element costs nothing, but a deck papered in decoration reads cheap. @@ -254,7 +258,7 @@ When a deck wants several small **spot illustrations** scattered as decorative a - Lay the elements out in an explicit **R×C grid, evenly spaced with clear gutters**, each element **centered in its own cell** and isolated (no element bleeds into a neighbor). - State the intended cell shape in the prompt: compact square object, tall portrait element, or wide landscape vignette. Do not let the model shrink every subject into a centered square sticker. - One **flat single-color background** across the whole sheet, set to the deck's background/secondary HEX — this is what lets the slicer key it out cleanly and lets the cut element sit on the slide without a visible box. -- Shared `deck_rendering` + `deck_palette` as always. NO text, labels, or numbers anywhere (§5.1, §5.3). +- Shared `deck_rendering` + `color_scheme` as always. NO text, labels, or numbers anywhere (§5.1, §5.3). **Cell geometry is designed, not assumed.** `slice_images.py --grid RxC` cuts rows first and columns second. The cell ratio is: @@ -270,9 +274,9 @@ Use that deliberately. On a wide sheet (`16:9`, `21:9`, `4:1`, `8:1`), `1xN` mak | Tall side accents / upright objects | wide or square sheet | `1xN`, or any `MxN` whose cells are portrait | | Wide banners / horizontal vignettes | wide sheet | `Nx1`, or any `MxN` whose cells are landscape | -If one deck needs mixed shapes, create separate sheets per shape family unless one carefully designed grid gives every element enough room in its own cell. Keep the visual family consistent through the same `deck_rendering` and `deck_palette`, not by forcing all cells into one square sheet. +If one deck needs mixed shapes, create separate sheets per shape family unless one carefully designed grid gives every element enough room. Keep the visual family consistent through the same `deck_rendering` and `color_scheme`, not by forcing all cells into one square sheet. -**Resource contract — the sheet and its elements are different row kinds.** A sliced element can only be placed if it exists as a resource the Executor is allowed to reference (`spec_lock.md images`). So §VIII carries two row kinds (full rules: [`design_spec_reference.md`](../templates/design_spec_reference.md) §VIII): +**Resource contract — the sheet and its elements are different row kinds.** A sliced element can only be placed if it exists as a resource the Executor is allowed to reference (`spec_lock.md images`). So §VIII carries two row kinds (planning authority: [`strategist-image.md`](./strategist-image.md)): - **Sheet row** — `Acquire Via: ai`, `Type: Illustration Sheet`, the intent prompt, named as the slice source with its intended cell shape and placement purpose (`Reference: landscape footer-vignette spot set`). It is generated in Step 5 but **never placed on a slide** — keep it **out of** `spec_lock.md images`. Image_Generator resolves the exact `aspect_ratio`, grid, and slice command from this intent. - **Element rows** — one per used element, `Acquire Via: slice`, filename matching a `--names` output, `Reference` naming the parent sheet + cell/element. These **are** placed — list every one in `spec_lock.md images`, usually with ` | no-crop` (a tight-trimmed transparent spot should be fit, not cover-cropped). Their dimensions are filled in after slicing (Step 5 re-runs `analyze_images.py`). **Set each element row's Layout pattern from the decorative-cutout family, never a boxed container** — see Placement below. @@ -292,9 +296,9 @@ python3 scripts/slice_images.py /images/illus_sheet.png --grid 2x3 \ 2. **Clean grid, or it cuts ugly.** The model will not place every element perfectly; force a clear grid with gutters, and generate **a few sheets** (re-roll the same prompt) to pick the cleanest-laid-out one before slicing. State the exact row/column structure and cell shape so the model does not invent a square matrix. `--trim` absorbs the rest. 3. **Generate only as large as needed.** Each cell is a fraction of the sheet. Pick the smallest sheet size that keeps each sliced cell at least **1.5-2x** the intended display size. `1K` is usually enough for small 80-160px decorative spots; use `2K` for medium 180-320px placements; reserve `4K` for large, cropped, or potentially enlarged elements. -**Placement — these are decorative accessories, not boxed pictures.** A transparent spot wasted in a centered rectangle looks cheaper than no spot at all. Each element row's Layout pattern comes from the decorative-cutout family in [`image-layout-patterns.md`](./image-layout-patterns.md): `#63` sticker/cutout, `#4` bleed off the canvas edge, `#58` corner fragment, `#66` fade into the background, `#69` slight editorial rotation, `#49` asymmetric cluster. Push spots to the margins, let them run off-edge or sit behind/beside text, vary size and angle across pages, and overlap the content rather than reserving a tidy tile for them. Anchor most pages on one primary element and let the rest stay small ([primary-per-page](./strategist.md) §h) — scattered same-weight tiles are exactly the generic look to avoid. +**Placement — these are decorative accessories, not boxed pictures.** A transparent spot wasted in a centered rectangle looks cheaper than no spot at all. Each element row's Layout pattern comes from the decorative-cutout family in [`image-layout-patterns.md`](./image-layout-patterns.md): `#63` sticker/cutout, `#4` bleed off the canvas edge, `#58` corner fragment, `#66` fade into the background, `#69` slight editorial rotation, `#49` asymmetric cluster. Push spots to the margins, let them run off-edge or sit behind/beside text, vary size and angle across pages, and overlap the content rather than reserving a tidy tile for them. Anchor most pages on one primary element and let the rest stay small ([primary-per-page](./strategist-image.md)) — scattered same-weight tiles are exactly the generic look to avoid. -**Through-line — one family, many roles.** A spot sheet pays off more when the same motif family also drives the deck's cover and section dividers, so the deck reads as one designed system rather than a hero plus unrelated doodles. Because the slicer cuts a **uniform grid**, a large cover / divider anchor is **not** a giant cell in the spot sheet — generate it as its own `page_role: hero_page` image (§4.1 primitives) that shares this sheet's `deck_rendering`, `deck_palette`, and subject world. In §VIII the hero_page anchor row(s) and the `slice` spot rows then belong to one visual family (name the shared subject world in each `Reference`), differing only in scale and role. Plan this only when the deck leans into illustration — never a per-section quota; the planning rule lives in [strategist.md](./strategist.md) (deck illustration motif). +**Through-line — one family, many roles.** A spot sheet pays off more when the same motif family also drives the cover and section dividers. A large cover / divider anchor is not a giant sheet cell—generate it as its own `hero_page` image sharing the sheet's `deck_rendering`, `color_scheme`, and subject world. Plan this only when the deck leans into illustration, never as a quota. --- @@ -369,7 +373,7 @@ The table below is **a reference for the one case where you want the in-image le - Decorative / background lettering, posters, large mood words → describe the artistic treatment freely - Cover hero title that wants its own visual identity (blackletter, retro chrome, art-deco display, brushed script) → describe freely - Sketch-notes / ink-notes / hand-drawn renderings where the lettering is part of the rendering itself → describe freely -- Any case where rendering + palette already imply a font character (e.g. `vintage-poster` rendering implies period display lettering) → trust the rendering, no need to echo SVG body +- Any case where rendering already implies a font character (e.g. `vintage-poster` implies period display lettering) → trust the rendering, no need to echo SVG body **When to use the table**: a designed title (cover main title, chapter heading) on a deck whose visual identity is grounded in the SVG body typography, and where a surprise font choice would feel out of place. @@ -403,11 +407,13 @@ Write `project/images/image_prompts.json` with this shape: "project": "{project_name}", "generated_at": "{ISO-8601 date}", "deck_rendering": "vector-illustration", - "deck_palette": "cool-corporate", "color_scheme": { + "background": "#FFFFFF", + "secondary_bg": "#F8F9FA", "primary": "#1E3A5F", - "secondary": "#F8F9FA", - "accent": "#D4AF37" + "accent": "#D4AF37", + "secondary_accent": "#4A7BB5", + "body_text": "#1D2430" }, "items": [ { @@ -441,8 +447,7 @@ Write `project/images/image_prompts.json` with this shape: | Field | Required | Source | Description | |---|---|---|---| | `deck_rendering` | yes | Step 2 lock | Single rendering name shared by all items in this deck | -| `deck_palette` | yes | Step 2 lock | Single palette name shared by all items | -| `color_scheme` | yes | `design_spec.md §III` | HEX triplet from Strategist | +| `color_scheme` | yes | `spec_lock.md colors` | Exact deck color roles used by every item; no separate image palette | | `items[].filename` | yes | `§VIII` resource list | Output filename with extension | | `items[].type` | conditional | Step 3 per-image (only when `page_role: local`) | One of 11 internal-composition types: `infographic`, `flowchart`, `framework`, `matrix`, `cycle`, `funnel`, `pyramid`, `comparison`, `timeline`, `map`, `scene`. **Omit `type` entirely when `page_role: hero_page`** — the composition comes from §4.1 primitives written directly into the prompt, not from a type file. | | `items[].page_role` | yes | Step 3 per-image | `local` (default — region block on SVG page) or `hero_page` (image is page's main voice; SVG overlay minimal or empty) | @@ -457,7 +462,11 @@ Write `project/images/image_prompts.json` with this shape: > **Back-compat for legacy `type` values**: existing manifests using `background` / `hero` / `portrait` / `typography` (the four removed pseudo-types) remain readable. Read them as: `background` → `page_role: hero_page` + no type; `hero` → `page_role: hero_page` + no type (use §4.1 Primitive A in prompt); `portrait` → `page_role: local` + no type (use §4.1 Primitive B); `typography` → `page_role: hero_page` + `text_policy: embedded` + no type (use §4.1 Primitive C). New manifests should follow the rule above (omit `type` when `page_role: hero_page`). > -> Existing manifests without `deck_rendering` / `deck_palette` / `type` / `page_role` / `text_policy` remain valid — older items default to `page_role: local`, `text_policy: none`. Legacy `page_role: full_page` (pre-2026-05-15) is read as `hero_page`. +> **Existing manifest compatibility**: +> +> - **Fixed compatibility defaults**: a missing `page_role` resolves to `local`; a missing `text_policy` resolves to `none`. Emit one aggregate legacy-compatibility warning per manifest. +> - **Declared replay procedure**: an existing manifest may lack `deck_rendering`, or an existing local item may lack `type`, because `items[].prompt` is already assembled. Leave that metadata absent, execute the existing prompt verbatim, and do not reconstruct either value. This exception applies only to replaying an existing manifest; new manifests must satisfy the field table above. A `hero_page` item still omits `type` intentionally. +> - A legacy `deck_palette` field may remain but cannot override `color_scheme`. Read legacy `page_role: full_page` as `hero_page`. --- @@ -475,13 +484,13 @@ C (AI-generated) supports three implementation modes sharing one `image_prompts. | `IMAGE_BACKEND` not configured (or Path A fails) AND host has a native image tool | **Path B**: Host-native tool | Agent invokes the host's image capability; outputs land at `project/images/` | | **Both Path A and Path B fail/unavailable** | **Offline Manual Mode** | Manifest stays on disk; user generates externally from `items[].prompt` and places files at `project/images/` | -**Selection logic** — the confirmed user choice wins; absent one, fall back to the automatic A → B → C chain: +**Selection logic — declared-procedure fallback when no path is confirmed**: the confirmed user choice wins. When neither channel confirmed a specific path — the effective choice is `auto` (explicitly confirmed or defaulted) or absent — use the automatic A → B → C chain: -0. **Confirmed override (wins)** — honor the confirmed image source. The **chat choice is canonical**; the Confirm UI is only a convenience surface that, when used, records the same choice to `/confirm_ui/result.json` as `image_ai_path` (so there is no `result.json` on the chat path — read the choice from the conversation). From either channel, if the choice is set and not `auto`, honor it directly, **even when it contradicts `IMAGE_BACKEND`**: +0. **Confirmed override (wins)** — honor the confirmed image source **from whichever channel the confirmation actually happened in**: when the Confirm UI was used, it records the choice to `/confirm_ui/result.json` as `image_ai_path`; a chat confirmation is equally binding and leaves no `result.json` — read the choice from the conversation. From either channel, if the choice is set and not `auto`, honor it directly, **even when it contradicts `IMAGE_BACKEND`**: - `api` → **Path A** (`image_gen.py --manifest`). - `host-native` → **Path B** (host's native image tool) — skip A and do **not** run `image_gen.py --manifest`, *even if `IMAGE_BACKEND` is configured*. - `manual` → **Offline Manual** (write prompts, render the Markdown sidecar, hand off; do **not** run `image_gen.py --manifest`). - ("use Codex's image tool" / "走接口生成" in chat = `host-native` / `api`.) If the chosen path turns out unavailable (e.g. `host-native` but the host has no image tool), fall through along the chain below from that point. Only when no source named a path (chat silent, and `image_ai_path` `auto` / absent) does the automatic chain decide. + ("use Codex's image tool" / "走接口生成" in chat = `host-native` / `api`.) If an explicitly chosen path is unavailable or still fails after its retry, mark the affected row `Needs-Manual`; do not switch to another automated provider. Only when no channel named a specific path (the effective value is `auto` — explicitly confirmed or defaulted — or absent) does the automatic chain decide. 1. **Try Path A** — if `IMAGE_BACKEND` is configured (env or `.env`), run `image_gen.py --manifest`. If it fails twice in a row, fall to Path B. 2. **Try Path B** — if `IMAGE_BACKEND` was not configured (A skipped), or A failed, and the host has a native image tool (Codex / Antigravity / Claude Code / similar), the agent invokes the host's image capability directly. 3. **Fall to C (Offline Manual)** — if B is also unavailable (no host-native tool) or fails, write prompts to `images/image_prompts.json` and hand off to the user. @@ -557,19 +566,19 @@ Triggered automatically when `IMAGE_BACKEND` is not configured (or Path A fails) - Do **not** run `image_gen.py --manifest` in Path B. That command is Path A and may use configured API/proxy backends even when the user confirmed host-native. - Still run `python3 scripts/image_gen.py --render-md project/images/image_prompts.json` so the human-readable sidecar exists without touching any backend. - **Batch for speed, mind the rate**: when the host can run independent tool calls in parallel (e.g. Claude Code issues independent calls concurrently), fire several generations together in modest groups — a few rows at a time (~3–4), not the whole manifest at once — so their latency overlaps without flooding the host's image quota. When the host only runs tools serially, generate one row at a time. This mirrors Path A's default concurrency of 3. -- Outputs **must** land at `project/images/`. Match the Image Resource List dimensions when the host supports arbitrary sizes. Hosts with **fixed native resolutions** (common — e.g. ~1672x941 landscape / ~1086x1448 portrait) generate at the closest native size and backfill the actual pixels into the resource list `Dimensions` column — same convention as formula rows ("actual dimensions from formula manifest") and slice rows ("dimensions filled after slicing"). Do **not** upscale the file to fake the requested size (interpolation adds no detail); minor display-side upscaling (up to ~1.3x in practice) surfaces as a quality-checker warning — acknowledge and release per the warning policy. +- Outputs **must** land at `project/images/`. Match the Image Resource List dimensions when the host supports arbitrary sizes. Hosts with **fixed native resolutions** (common — e.g. ~1672x941 landscape / ~1086x1448 portrait) generate at the closest native size and backfill the actual pixels into the resource list `Dimensions` column — same convention as formula rows ("actual dimensions from formula manifest") and slice rows ("dimensions filled after slicing"). Do **not** upscale the file to fake the requested size (interpolation adds no detail); minor display-side upscaling (up to ~1.3x in practice) may surface as a non-blocking quality-checker warning and requires no acknowledgement. - Mark each item's `status` `Generated` in the manifest the moment its file lands — as each completes, not in one pass at the end (so an interrupted batch leaves accurate state) - Executor downstream is path-agnostic — no spec change required between Path A and Path B ### Offline Manual Mode (C's third implementation mode) -**Trigger**: Both Path A and Path B fail or are unavailable. +**Trigger**: the automatic chain reaches this point after both Path A and Path B fail or are unavailable, the user explicitly confirmed `manual`, or an explicitly confirmed automated path still fails after its own retry. **Workflow** (no user prompting; system enters this mode automatically): 1. Verify `images/image_prompts.json` was written 2. Set `status: "Needs-Manual"` on every affected item per [`image-base.md`](./image-base.md) §6 -3. Continue to Step 6 — SVG references `images/` optimistically; Step 7 entry verifies presence +3. Continue to Step 6 — Executor draws a dashed placeholder for each `Needs-Manual` row; the Step 7 image readiness gate verifies the supplied files and swaps them in 4. Print one consolidated handoff to the user: - Filenames awaiting manual generation - Pointer to `images/image_prompts.md` (paste-ready `### Image N:` block per item) or `image_prompts.json` (`items[].prompt`) @@ -582,13 +591,15 @@ Triggered automatically when `IMAGE_BACKEND` is not configured (or Path A fails) #### AI-specific Failure Handling (extends image-base.md §6) -If Path A's backend fails twice in a row: +When the path is `auto` and Path A's backend fails twice in a row: 1. Do not halt. Automatically attempt to fall back to **Path B (Host-Native Tool)**. 2. If Path B also fails or is unavailable, mark the row `Needs-Manual`. 3. Report to user: filename, prompt used, error message. 4. Fall through to **Offline Manual Mode** above. +When `api` or `host-native` was explicitly confirmed, failure or unavailability does not authorize an automated provider switch. Retry the confirmed path once; if it still fails, mark the row `Needs-Manual`, report the filename/prompt/error, and use the manual handoff above. + > If the alternate platform watermarks outputs (e.g. Gemini web), the repository includes `scripts/gemini_watermark_remover.py`. #### Guardrails (All Modes) @@ -596,16 +607,16 @@ If Path A's backend fails twice in a row: **Hard rule**: - Do not claim an image is generated without an actual file at the expected path -- `Needs-Manual` is set after a failed attempt OR on entering Offline Manual Mode — not as a way to skip work that automation could have done -- Status transitions are evidence-driven: `Pending` → `Generated` (file exists) or `Pending` → `Needs-Manual` (no automation, or attempt failed once) +- `Needs-Manual` is set only when `manual` was confirmed or the selected automated recovery path was attempted and failed — not as a way to skip work that automation could have done +- Status transitions are evidence-driven: a file at the expected path permits `Generated`; an exhausted recovery path permits `Needs-Manual` --- ## 8. Common Issues & Variant Workflow -### Reference field is blank — quick examples +### Reference field is omitted or blank — declared-inference fallback for existing AI rows -When the Resource List row has no `Reference`, infer a reasonable image from `Purpose`. Examples (not prescriptions): +When an existing AI Resource List row omits `Reference` or contains a blank `Reference`, infer a reasonable image from its non-empty `Purpose`. If `Purpose` is also omitted or blank, stop and repair the row. Examples (not prescriptions): | Purpose | A reasonable starting point | |---------|-----------------------------| @@ -627,7 +638,7 @@ Diagnose the failure category, adjust the **one specific dimension** responsible |---|---|---| | Image looks generic, model-average | Tag-soup prompt | Rewrite as one coherent paragraph per §4 | | Wrong style family (looks photorealistic when flat was intended) | Rendering mismatch or rendering paragraph diluted | Reaffirm chosen rendering's style paragraph at the top of the prompt | -| Colors don't match deck | HEX not echoed in prompt, or palette proportion rule omitted | Repeat HEX values 2-3 times in the prompt; restate palette proportion rule | +| Colors don't match deck | Locked role HEX not echoed, or their role / proportion instructions were diluted | Repeat the locked HEX values 2-3 times; restate which deck role owns the field, main forms, and sparse accents | | Hex code or color name visible as text in image | Missing §5.1 closing sentence | Append the §5.1 hard rule verbatim | | Garbled letters in supposedly text-free image | `text_policy: none` rule too weak | Strengthen with explicit list: "no letters, no numbers, no words, no signs, no labels, no captions, no watermarks" | | SVG text overlay clashes with busy image area | Page design needs negative space the prompt didn't request | Add a composition cue like "leave the {center / left third / lower band} relatively calm for text overlay" — only when the page actually overlays text on top of the image | @@ -646,9 +657,9 @@ Diagnose the failure category, adjust the **one specific dimension** responsible - Generating prompts for `web` rows — those go through [`image-searcher.md`](./image-searcher.md) - Brand names or HEX codes inside the subject description (degrades output) -- Mixing renderings or palettes across images in the same deck +- Mixing renderings or inventing image-only colors across images in the same deck - Tag-soup prompts (keyword lists separated by commas without a coherent visual scene) - Globbing `image-renderings/*.md` or any subdirectory — read only the chosen file - Placing an image without updating its `image_prompts.json` `status` and the resource list status -- Switching rendering or palette for a single image — `hero_page` is not an exception to deck-wide coherence +- Switching rendering or deck-color roles for a single image—`hero_page` is not an exception to deck-wide coherence - Embedding body copy, data points, bullet lists, or long quotes inside an image — those route to SVG diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-patterns.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-patterns.md index 06476304..b3c94de0 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-patterns.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-patterns.md @@ -148,7 +148,7 @@ Stack any of these freely on top of a Primary structure. Multiple Modifiers per 24. **Custom path crop (blob, arrow, leaf, silhouette)** — ``; allows any curved or organic shape. PowerPoint export translates this to `custGeom` and survives roundtrip. -25. **Layered paper-cut stack** — clip each image layer under the image-only contract in [`shared-standards.md`](shared-standards.md) §1.2; draw vector layers directly in their final geometry. A small conditional shadow on each layer can create physical separation. +25. **Layered paper-cut stack** — clip each image layer under the image-only contract in [`shared-standards-core.md`](./shared-standards-core.md) §1.2; draw vector layers directly in their final geometry. A small conditional shadow on each layer can create physical separation. 26. **Triptych baked into a single wide image** — one wide `` whose internal composition already contains 2–3 scenes. Generate the triptych as one image (not three separate calls) when scene-to-scene consistency matters — the model preserves character identity, lighting continuity, and color grading far more reliably when panels are produced together. @@ -174,9 +174,9 @@ Stack any of these freely on top of a Primary structure. Multiple Modifiers per 35. **Duotone treatment** — two-color mapping of a photograph (e.g. deep navy shadows + warm cream highlights). Bake it into the source image; the native PPT route does not support a runtime duotone filter chain. -36. **Drop shadow under image panel** — `` applied to the image's container `` (or to the `` itself). Standard depth lift. +36. **Drop shadow under image panel** — `` applied to the image panel's backing ``. Standard depth lift; filters do not apply directly to `` under the project contract. -37. **Inner / outer glow on overlay shape** — `` on a shape, or simply a slightly larger blurred `` underneath the target. +37. **Inner / outer glow on overlay shape** — `` on a shape, or simply a slightly larger blurred `` underneath the target. ## Image as Texture / Atmosphere @@ -204,7 +204,7 @@ Stack any of these freely on top of a Primary structure. Multiple Modifiers per 67. **Image with knock-out / cut-out shape** — overlay a shape filled with the background color or another image, creating the impression of a hole punched through the underlying image. -68. **Text-as-mask over image** — letterforms revealing image through them. Under the canonical SVG compatibility boundary in [`shared-standards.md`](shared-standards.md), realize this pattern as a pre-rendered image rather than a runtime effect. Prompt for "large lettering revealing the underlying scene through letterforms" and treat the result as a fixed artistic choice. +68. **Text-as-mask over image** — letterforms revealing image through them. Under the canonical SVG compatibility boundary in [`shared-standards-core.md`](./shared-standards-core.md), realize this pattern as a pre-rendered image rather than a runtime effect. Prompt for "large lettering revealing the underlying scene through letterforms" and treat the result as a fixed artistic choice. 69. **Image rotated at a slight angle for editorial feel** — `transform="rotate(angle cx cy)"` on the `` or its container ``; 2–6 degrees typical. Adds dynamism without breaking layout. @@ -247,13 +247,13 @@ Combine freely. The "AI-default" failure mode is the opposite: defaulting to bar **Skip-detection signal** — if every page's `Layout pattern` column resolves to bare #2 / #3 / #5 / #6 with no Modifier ids, the catalog was not consulted. Re-read and reconsider. -**Cross-page through-line (recurring motif).** The patterns above are per-page, but a deck reads as *designed* when one illustration motif family recurs across pages — a cover anchor, section dividers repeating the motif for chapter identity (`#75`), and small `#63` spots from the same family threaded through the body. Keep them one family (shared rendering / palette / subject world), vary scale and placement, and never let the recurrence harden into a per-section quota. Planning lives in [strategist.md](./strategist.md) (deck illustration motif); generation mechanics split by role — hero / divider anchors: [image-generator.md](./image-generator.md) §4.1 primitives; body spot sheets: §4.3. +**Cross-page through-line (recurring motif).** The patterns above are per-page, but a deck reads as *designed* when one illustration motif family recurs across pages—a cover anchor, section dividers repeating the motif (`#75`), and small `#63` spots threaded through the body. Keep one family (shared rendering / locked deck colors / subject world), vary scale and placement, and never turn recurrence into a quota. ## Hard Constraints - Long body copy, data points, numeric labels, and Chinese text always go in the SVG layer — never baked into the image. -- All project-wide SVG compatibility exceptions and conditional mappings are - owned by [`shared-standards.md`](shared-standards.md). This catalog neither +- Project-wide SVG compatibility rules start at [`shared-standards-core.md`](./shared-standards-core.md), + whose routing table names each conditional owner. This catalog neither restates nor relaxes that contract; each pattern records only its scenario-specific rendering choice. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md index 723135b0..a72d49bc 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-layout-spec.md @@ -1,4 +1,4 @@ -> See shared-standards.md for common technical constraints. +> See [`shared-standards-core.md`](./shared-standards-core.md) for common technical constraints. # Image Layout Specification @@ -6,14 +6,14 @@ Layout rules for pages where the image is placed **side-by-side with body text** **Core principle (side-by-side)**: compute container layout from the image's original aspect ratio so the image displays completely — no excess whitespace, no cropping. -> **Scope**: this spec applies to *side-by-side* intent only. Other intents (hero / full-bleed, atmosphere / background, accent / inline) use full-bleed placement where ratio alignment is not a constraint and cropping is expected — the ratio→split table below does NOT apply. See `references/strategist.md` §h for intent selection. +> **Scope**: this spec applies to *side-by-side* intent only. Other intents (hero / full-bleed, atmosphere / background, accent / inline) use full-bleed placement where ratio alignment is not a constraint and cropping is expected — the ratio→split table below does NOT apply. See `references/strategist-image.md` for intent selection. --- ## Layout Decision Flow ``` -1. Decide narrative intent (hero / atmosphere / side-by-side / accent) — see strategist.md §h +1. Decide narrative intent (hero / atmosphere / side-by-side / accent) — see strategist-image.md 2. If intent = side-by-side: continue below. Otherwise: compose per narrative; this spec does not apply. 3. Get image original dimensions → Calculate ratio (width/height) 4. Select layout type based on ratio diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-palettes/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-palettes/_index.md index 7f060a93..5977ae64 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-palettes/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-palettes/_index.md @@ -1,127 +1,36 @@ -# Palettes — Index +# Image Palettes Legacy Reference -A **palette** is the deck's **color behavior** — proportion, role, temperament. It does **not** supply HEX values; those come from `design_spec.colors`. The palette tells the model how to use the HEX values: which dominates, which carries accent, what proportion the background occupies, what the overall temperament feels like. +Compatibility tombstone for retired `image_palette` fields and historical palette comparison assets. -> Why this split: SVG renders the HEX precisely from `design_spec`. The AI image must use the **same HEX values** so the image visually belongs in the deck — but the image needs more than a HEX list; it needs a **usage rule**. That's the palette. +## 1. Current Generation Contract ---- +**Hard rule**: Current deck generation never presents, selects, authors, or consumes `image_palette` or `image_palette_behavior`. -## 1. Catalog (14 palettes) - -Each palette has its own file with: rendering compatibility matrix and a fewshot prompt snippet. - -| Palette | Temperament | Best for | -|---|---|---| -| [`cool-corporate`](./cool-corporate.md) | Stable, professional, restrained | Consulting / B2B / finance | -| [`warm-earth`](./warm-earth.md) | Friendly, grounded, human | Brand / lifestyle / education | -| [`tech-neon`](./tech-neon.md) | Energetic, futuristic, high-contrast | AI / SaaS / product launch | -| [`editorial-classic`](./editorial-classic.md) | Refined, magazine, balanced | Journalism / opinion / culture | -| [`macaron`](./macaron.md) | Soft pastel, gentle, approachable | Education / children / onboarding | -| [`mono-ink`](./mono-ink.md) | High-contrast monochrome with sparse accents | Methodology / Before-After / manifesto | -| [`vivid-launch`](./vivid-launch.md) | Bold, saturated, attention-grabbing | Product launch / marketing / event | -| [`dark-cinematic`](./dark-cinematic.md) | Premium, atmospheric, low-light | Premium product / film / entertainment | -| [`duotone`](./duotone.md) | Two-color limited, poster-like | Cultural / cover hero / cinematic | -| [`nature-organic`](./nature-organic.md) | Earthy, natural, wellness | Environment / wellness / outdoor | -| [`jewel-tone`](./jewel-tone.md) | Deep saturated gemstone — emerald/sapphire/ruby + gold | Luxury / fashion / premium product / heritage | -| [`frost-ice`](./frost-ice.md) | Near-white field with pale cool accents | Health / medical / beauty / premium SaaS | -| [`sunset-gradient`](./sunset-gradient.md) | Warm gradient flow (pink → orange → purple) | Lifestyle / creative / travel / event | -| [`earthy-dusty`](./earthy-dusty.md) | Muted desaturated earth tones, Morandi-adjacent | Interior / wellness / mindfulness / slow living | - ---- - -## 2. Escape hatch — `custom` - -When no preset temperament matches (brand HEX outside preset ranges, ceremonial / cultural / niche aesthetic), set `image_palette: custom` and supply a one-paragraph `image_palette_behavior`. - -**Trigger** — all of: - -| Condition | Check against | +| Input | Current behavior | |---|---| -| No preset temperament fits | `design_spec.e Color Scheme` | -| Brand / template / chat names no preset | truth-precedence inputs | -| Not expressible as "preset X + small HEX swap" | Strategist confirmation chat | +| `spec_lock.md colors` | Sole source of generated-image color roles and exact HEX values | +| `image_rendering` | Controls rendering treatment only; it does not create a second color decision | +| Legacy `image_palette` row | Ignore it; it cannot override the deck color lock | +| No palette row | Expected; do not synthesize a preset or `custom` fallback | -**Hard rule — `palette_behavior` prose**: +**Forbidden — legacy activation**: -| Rule | Value | +- Do not load sibling palette preset files while planning or generating a current deck. +- Do not use the historical auto-selection table, compatibility matrix, or prompt snippets. +- Do not write `image_palette: custom` or `image_palette_behavior`. + +--- + +## 2. Legacy Interpretation and Maintenance + +The sibling preset files remain archived in place for diagnosing historical locks and maintaining the legacy palette comparison assets documented by [`README.md`](../ai-image-comparison/README.md). They are not a runtime catalog. + +| Legacy row | Historical meaning | |---|---| -| Length | One paragraph, 2-5 sentences | -| Per-HEX content | role + approximate area share (proportion follows information weight; no fixed % menu) | -| HEX source | Quote `design_spec.colors` values verbatim with backticks; never invent HEX | -| Forbidden | Naming a competing preset ("like macaron but darker") | +| `image_palette: ` | Selects the named sibling preset as the archived color-behavior definition. | +| `image_palette: custom` | Declares that no preset owns the behavior; the required sibling `image_palette_behavior` row is the complete definition. | +| `image_palette_behavior: ` | With `custom`, records a 2–5 sentence mapping from the lock's HEX roles to intended proportion and temperament. It must not name a competing preset or invent another HEX value. | -```yaml -- image_palette: custom -- image_palette_behavior: "Primary deep aubergine `#4C1D95` anchors the dominant ~35% of canvas; secondary warm cream `#FEF3C7` carries ~55% as breathing field; accent burnished gold `#D4AF37` appears only in 5-10% as small ceremonial accents. Restrained, ceremonial gravitas — no fourth color." -``` +A historical `custom` row without a non-empty `image_palette_behavior` is incomplete. Report the missing legacy definition; do not reconstruct it. -> Note: §4's rendering × palette matrix only covers the 14 presets. When `palette: custom`, Strategist owns the compatibility judgment in h.5. - -**Hard rule**: `custom` is a tail-case, not a default. See [`strategist.md`](../strategist.md) h.5 for the one-`custom`-per-dimension limit. - ---- - -## 3. Auto-selection table — `design_spec` → palette - -Match `design_spec.md d. Style` + `e. Color Scheme` content vibe. First match wins. **No row matches** → use `custom` per §2 rather than force-fitting `cool-corporate`. - -| Content vibe / industry | Recommended palette | Alternates | -|---|---|---| -| Consulting / finance / B2B / corporate | `cool-corporate` | `editorial-classic`, `frost-ice` | -| Tech / SaaS / AI | `tech-neon` | `cool-corporate`, `dark-cinematic` | -| Modern SaaS / fintech / health-tech | `frost-ice` | `cool-corporate`, `tech-neon` | -| Health / medical / beauty / skincare | `frost-ice` | `nature-organic`, `earthy-dusty` | -| Education / training / onboarding | `macaron` | `warm-earth` | -| Methodology / Before-After / mindset shift | `mono-ink` | `editorial-classic` | -| Personal / lifestyle / brand story | `warm-earth` | `nature-organic`, `earthy-dusty` | -| Interior / wellness / mindfulness / slow living | `earthy-dusty` | `warm-earth`, `nature-organic` | -| Product launch / marketing / event | `vivid-launch` | `tech-neon`, `sunset-gradient` | -| Creative agency / travel / music / lifestyle | `sunset-gradient` | `vivid-launch`, `warm-earth` | -| Luxury / fashion / jewelry / premium / heritage | `jewel-tone` | `dark-cinematic`, `editorial-classic` | -| Children / storybook | `macaron` | `warm-earth` | -| Premium / entertainment / film | `dark-cinematic` | `jewel-tone`, `duotone` | -| Cultural / media / cover-art | `duotone` | `editorial-classic` | -| Environment / wellness / outdoor | `nature-organic` | `warm-earth`, `earthy-dusty` | -| Finance / journalism / explainer | `editorial-classic` | `cool-corporate` | -| Government / formal | `cool-corporate` | `editorial-classic` | - ---- - -## 4. Rendering × Palette compatibility - -Some combinations clash. Use this matrix as a sanity check after auto-selection. - -| | cool-corp | warm-earth | tech-neon | editorial | macaron | mono-ink | vivid-launch | dark-cinem | duotone | nature-org | jewel-tone | frost-ice | sunset-grad | earthy-dusty | -|---|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:| -| vector-illustration | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | -| flat | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ | ✓✓ | ✓✓ | ✓✓ | -| minimalist-swiss | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✗ | ✓ | -| glassmorphism | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✗ | ✓ | ✓ | ✓✓ | ✓ | ✓ | -| 3d-isometric | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✗ | ✓✓ | ✓✓ | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ | -| digital-dashboard | ✓✓ | ✗ | ✓✓ | ✓✓ | ✗ | ✓ | ✓ | ✓✓ | ✗ | ✗ | ✗ | ✓✓ | ✗ | ✗ | -| corporate-photo | ✓✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✗ | ✓ | ✓✓ | ✗ | ✓✓ | ✓✓ | ✓ | ✗ | ✓✓ | -| blueprint | ✓✓ | ✗ | ✓✓ | ✓ | ✗ | ✓✓ | ✗ | ✓✓ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | -| editorial | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | -| sketch-notes | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✓ | ✓ | ✗ | ✗ | ✓✓ | ✗ | ✗ | ✗ | ✓ | -| ink-notes | ✓ | ✓ | ✗ | ✓✓ | ✗ | ✓✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ | ✗ | ✓ | -| chalkboard | ✗ | ✓ | ✗ | ✗ | ✓ | ✓ | ✗ | ✓✓ | ✓ | ✓ | ✗ | ✗ | ✗ | ✓ | -| paper-cut | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✗ | ✓ | ✗ | ✓ | ✓✓ | ✗ | ✓ | ✗ | ✓✓ | -| watercolor | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✗ | ✓ | ✓ | ✗ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓✓ | -| warm-scene | ✓ | ✓✓ | ✗ | ✓ | ✓ | ✗ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✗ | ✓✓ | ✓ | -| screen-print | ✓ | ✓ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| vintage-poster | ✓ | ✓✓ | ✗ | ✓✓ | ✓ | ✓ | ✓ | ✓ | ✓✓ | ✓ | ✗ | ✗ | ✓ | ✓✓ | -| fantasy-animation | ✗ | ✓✓ | ✗ | ✗ | ✓✓ | ✗ | ✓ | ✗ | ✗ | ✓✓ | ✗ | ✗ | ✓ | ✗ | -| pixel-art | ✗ | ✓ | ✓✓ | ✗ | ✓ | ✓ | ✓✓ | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | -| nature | ✓ | ✓✓ | ✗ | ✓ | ✓ | ✗ | ✓ | ✗ | ✗ | ✓✓ | ✓ | ✓ | ✓ | ✓✓ | - -✓✓ recommended | ✓ acceptable | ✗ avoid - ---- - -## 5. How to use - -1. After picking rendering, look up your candidate palette in the auto-selection table. -2. Cross-check the compatibility matrix — if `✗`, pick the alternate. -3. `read_file image-palettes/.md` and apply its proportion + role rules to the deck's HEX values when assembling prompts. (For `custom`, this step is replaced by the consumption branch in [`image-generator.md`](../image-generator.md) Step 2 — no preset file to read.) - -**Lock for the whole deck.** +When that maintenance is explicitly requested, read only the named historical asset or preset. Keep its palette behavior inside the historical fixture; do not copy it into current recommendations, `design_spec.md`, `spec_lock.md`, or generated-image prompts. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md index 0908d585..849ac81b 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/_index.md @@ -2,7 +2,9 @@ A **rendering** is a visual style family: line quality, texture, depth, material, mood. Lock one rendering per deck — every AI image in the deck shares it. -> **HEX values are not in renderings**. The deck's HEX triplet comes from `design_spec.colors`. Rendering describes *how* the image is drawn; palette describes *how* the HEX values are distributed. See [`image-generator.md`](../image-generator.md) §2. +> **HEX values are not in renderings.** Rendering describes how the image is drawn. The new flow reads exact deck color roles directly from `spec_lock.md colors`; it does not ask for or author a separate image palette. See [`image-generator.md`](../image-generator.md) §2. + +> **Deck HEX has hard precedence.** Any color name or sample HEX inside an individual rendering file is illustrative legacy prose and MUST be replaced by the current deck-role values when assembling a prompt. A rendering may change texture, lighting, opacity, and role proportions, but it may not tint, warm-grade, cool-grade, replace, or invent HEX. If its material language requires colors the selected deck roles cannot support, do not offer that rendering in Stage 2. --- @@ -52,15 +54,7 @@ Each rendering has its own file with: style paragraph, line / texture / depth no ### 1.5 Escape hatch — `custom` -When no preset carries the deck's temperament, set `image_rendering: custom` and supply a one-paragraph `image_rendering_behavior`. - -**Trigger** — all of: - -| Condition | Check against | -|---|---| -| No preset style fits | `design_spec.d Style` | -| Brand / template / chat names no preset | truth-precedence inputs | -| Not expressible as "preset X + small adjustment" | Strategist confirmation chat | +Whenever proposed image usage includes `ai`, Stage 2 authors one separate, visible custom rendering proposal in addition to the preset cards. It uses `rendering: custom` plus a complete behavior paragraph, remains initially unselected, and enters the confirmed contract only when the user chooses it. A template-backed proposal must honor inherited identity and the confirmed template-application plan. **Hard rule — `rendering_behavior` prose**: @@ -75,7 +69,7 @@ When no preset carries the deck's temperament, set `image_rendering: custom` and - image_rendering_behavior: "Hand-screened poster aesthetic — slightly misregistered halftone overlays, 3 flat ink colors with visible dot pattern at 12% opacity, no gradients, no anti-aliased edges; reads as silkscreen print." ``` -**Hard rule**: `custom` is a tail-case, not a default. See [`strategist.md`](../strategist.md) h.5 for the one-`custom`-per-dimension limit. +**Hard rule**: the custom candidate is mandatory when AI images are proposed; selecting `custom` is a tail-case, not the default. See [`strategist-image.md`](../strategist-image.md) for the Stage-2 carrier and downstream lock behavior. --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/chalkboard.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/chalkboard.md index dec6d5c5..d4905ab2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/chalkboard.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/chalkboard.md @@ -20,11 +20,11 @@ Chalk on a dark green or black board — classroom aesthetic. Used in teaching-f ## 3. Using the deck's HEX values -chalkboard has a strong **fixed-palette tendency**: dark slate background + white chalk + pastel accents. +chalkboard has a strong **material-color tendency**: dark field + light chalk + sparse accents. It never replaces deck colors. Offer it only when the confirmed background / body-text roles can support that contrast. -- Background: dark slate green `#1F3A2E` or near-black `#1A1A1A` (does not use the deck's secondary) -- Primary chalk: off-white `#F5F5F0` (the chalk itself); the deck's primary HEX may appear as a tinted pastel accent -- Accent: the deck's accent HEX rendered as a soft pastel chalk shade +- Board: use the deck's exact `background` or `secondary_bg` role +- Chalk strokes: use the exact `body_text` role; dry texture supplies the chalk effect without changing its HEX +- Accent marks: use exact `accent` / `secondary_accent` values sparingly; do not pastel-tint them --- @@ -32,4 +32,4 @@ chalkboard has a strong **fixed-palette tendency**: dark slate background + whit **Snippet A — half-page lesson visual, text_policy: embedded** -> Classroom chalkboard aesthetic. Dark slate green background `#1F3A2E` with visible chalk-dust texture at 20% opacity. Three rounded boxes drawn in soft white chalk strokes arranged in a row, each containing a simple chalk-drawn icon (a tree, a lightbulb, a paper plane). Above the boxes, a hand-lettered chalk title in confident white lettering reads "GROWTH" in English block caps. Hand-drawn chalk arrows connect the boxes left-to-right. Small chalk star and dot decorations sprinkled sparingly. One soft pastel-yellow chalk underline below the title, drawn with deliberate dry-medium quality. Composed as a 600×500 half-page block with 14% inner padding. Chalk text kept to short keywords. Color values are rendering guidance only. \ No newline at end of file +> Classroom chalkboard aesthetic. Use the deck's locked background role as the board, with visible chalk-dust texture at 20% opacity. Three rounded boxes drawn in the locked body-text color as soft chalk strokes sit in a row, each containing a simple chalk-drawn icon (a tree, a lightbulb, a paper plane). Above the boxes, a hand-lettered title reads "GROWTH" in English block caps. Hand-drawn chalk arrows connect the boxes left-to-right. Small chalk star and dot decorations appear sparingly. One underline uses the locked accent color with deliberate dry-medium texture. Composed as a 600×500 half-page block with 14% inner padding. Chalk text stays to short keywords. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/fantasy-animation.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/fantasy-animation.md index 5294a2b8..c8f9c096 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/fantasy-animation.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/fantasy-animation.md @@ -4,7 +4,7 @@ Ghibli/Disney-inspired hand-drawn animation warmth. Soft painterly forms, gentle ## 1. Style paragraph (paste-ready, 110 words) -> Hand-drawn animation style inspired by Ghibli and classic Disney storybook aesthetics. Forms are softly rendered with painterly fills and gentle outlines — never harsh, always warm. Color palette is warm and slightly desaturated, with pastel skies, soft greens, warm earth tones, occasional accents of magical color. Lighting is dreamy and atmospheric — soft window light, golden-hour glow, gentle morning haze. Characters (when present) are stylized in a friendly cartoon manner — large expressive eyes, simplified anatomy, warm body language. Subtle painterly brush texture across the image. Atmospheric perspective creates depth — foreground richer, background softer. Overall feel is dreamy, magical, comforting — children's storybook quality. +> Hand-drawn animation style inspired by Ghibli and classic Disney storybook aesthetics. Forms are softly rendered with painterly fills and gentle outlines — never harsh. Exact colors come only from the deck's locked roles; dreamy warmth comes from soft window light, gentle glow, morning haze, brush texture, and atmospheric perspective rather than invented pastel or earth-tone HEX. Characters (when present) are stylized in a friendly cartoon manner — large expressive eyes, simplified anatomy, warm body language. Foreground forms are richer and the background softer. Overall feel is dreamy, magical, comforting, and storybook-like. --- @@ -20,11 +20,13 @@ Ghibli/Disney-inspired hand-drawn animation warmth. Soft painterly forms, gentle ## 3. Using the deck's HEX values -fantasy-animation reads HEX values through a **warm storybook filter**: +fantasy-animation uses the exact deck roles with a storybook treatment: -- Primary HEX: dominant warm scene color (sky, foliage, environment) -- Secondary HEX: lighter atmospheric tone (cream, soft sky, morning haze) -- Accent HEX: a small magical pop — perhaps the glow of a window, a flower, a key character element +- Primary HEX: dominant environment or character color, unchanged +- Secondary HEX: atmospheric field or haze, unchanged +- Accent HEX: a small magical focal point — perhaps a window, flower, or key character element, unchanged + +If those roles cannot support the intended storybook mood without recoloring, choose another rendering in Stage 2. --- @@ -32,4 +34,4 @@ fantasy-animation reads HEX values through a **warm storybook filter**: **Snippet A — half-page storybook scene, text_policy: none** -> Hand-drawn animation style inspired by Ghibli storybook aesthetics. A soft warm scene of a small cottage on a hillside with a winding path leading down to the foreground. Sky in warm cream-amber `#FEF3C7` transitions to a soft accent peach `#FED7AA` at the horizon. Hillside in gentle warm green-amber blending the deck's primary tone, with painterly brush texture. A simplified storybook tree in the foreground left, hand-drawn cartoon-warm style. A small warm-glowing window in the cottage adds a magical accent color. Atmospheric perspective — distant hills are paler and softer, foreground has more saturated color. Subtle painterly brush quality throughout. Composed as a 600×800 half-page block with 10% inner padding. Simplified storybook style — any figures are gentle cartoon silhouettes, no realistic faces. NO text or labels. Color values are rendering guidance only. \ No newline at end of file +> Hand-drawn storybook animation. A small cottage sits on a hillside with a winding path leading to the foreground. The sky and haze use the deck's locked secondary-background role, the hillside and tree use the locked primary, and one small glowing cottage window uses the locked accent. Do not tint or replace those values. Painterly brush texture, soft light, and atmospheric perspective create the warmth: distant hills are softer, while foreground forms carry more visual weight. A simplified storybook tree stands at foreground left. Composed as a 600×800 half-page block with 10% inner padding. Any figures are gentle cartoon silhouettes with no realistic faces. No text or labels. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/ink-notes.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/ink-notes.md index 0cdb843e..addcbec2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/ink-notes.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/ink-notes.md @@ -4,7 +4,7 @@ Pure white paper, black ink, sparse semantic color accents — the Mike Rohde sk ## 1. Style paragraph (paste-ready, 105 words) -> Professional hand-drawn visual-note style on pure white paper. All line work is black ink with slight wobble — confident, intentional, with the human-hand quality of a thoughtful whiteboard session. Hand-lettered titles appear bold and slightly oversized (when text policy allows). Color is intentionally sparse — black ink dominates ~85% of the visible content, with one or two semantic accent colors (coral red for risk/emphasis, muted teal for positive/solution, dusty lavender for neutral categories) covering less than 10% of canvas combined. Backgrounds and shape fills are mostly empty white. Small doodle decorations — stars, dashes, dots — are minimal. Overall feel is professional, considered, manifesto-quality. +> Professional hand-drawn visual-note style on a clean paper field. All line work uses the deck's body-text color with slight wobble — confident, intentional, with the human-hand quality of a thoughtful whiteboard session. Hand-lettered titles appear bold and slightly oversized (when text policy allows). Color is intentionally sparse: line work dominates ~85% of the visible content, while one or two semantic accents drawn only from the deck's locked accent roles cover less than 10% combined. Backgrounds and shape fills remain mostly empty. Small doodle decorations — stars, dashes, dots — are minimal. Overall feel is professional, considered, manifesto-quality. --- @@ -20,13 +20,13 @@ Pure white paper, black ink, sparse semantic color accents — the Mike Rohde sk ## 3. Using the deck's HEX values -ink-notes has a near-fixed visual language: **black ink + white background + 1-2 semantic accents**. This palette tendency may override `design_spec.colors`: +ink-notes has a near-fixed material language: **dark ink + light background + 1-2 semantic accents**. It never overrides `design_spec.colors`; offer it only when the confirmed roles can support that contrast: -- Background: pure white `#FFFFFF` (do not replace with the deck's secondary unless it's already near-white) -- Lines and text: near-black `#1A1A1A` (do not replace with the deck's primary) -- Semantic accents: ink-notes traditionally uses coral red, muted teal, dusty lavender. The deck's `accent` HEX can serve as the emphasis color, but consider whether it carries the right semantic weight (red=risk, teal=positive, gold=highlight) +- Background: use the deck's `background` / `secondary_bg` +- Lines and text: use the deck's `body_text` +- Semantic accents: use the deck's `accent` / `secondary_accent` roles and their established meaning; do not add traditional ink-notes colors outside the lock -This makes ink-notes **the rendering most likely to deviate from the deck's HEX**. Reaffirm in the prompt that the ink-notes natural palette is intentional and the deck's primary HEX is reserved for the accent role. +This makes ink-notes the rendering most likely to fight a deck's HEX. Offer it only when the locked background / text / accent roles can support the treatment; never invent traditional coral / teal / lavender after confirmation. --- @@ -34,4 +34,4 @@ This makes ink-notes **the rendering most likely to deviate from the deck's HEX* **Snippet A — Before/After methodology (comparison type), text_policy: embedded** -> Professional hand-drawn visual-note style on pure white background. Composition is a Before/After split — vertical hand-drawn divider down the center. Both sides use black ink line work with slight wobble. Left side ("Before") shows a simple stick-figure character with a frustrated posture, a speech bubble with hand-lettered "OLD WAY" in English block caps, and a small list of three hand-drawn dashes with brief 1-2 word annotations (e.g. "manual", "slow", "fragile"). Right side ("After") shows a confident stick-figure character with a clean checkmark above, hand-lettered "NEW WAY" in English block caps, and three checkbox-style annotations (e.g. "automated", "fast", "reliable"). A curved hand-drawn "mindset shift" arrow bridges left to right with a small hand-lettered label "the shift". Sparse semantic color: coral red `#E8655A` (the deck's accent) appears only on the left side's pain points; muted teal `#5FA8A8` appears only on the right side's positives. Total color accent area under 10% of canvas. All hand-lettered text is short keywords. Composed as a 1200×500 hero banner with 14% inner padding. \ No newline at end of file +> Professional hand-drawn visual-note style on the deck's locked background color. Composition is a Before/After split — vertical hand-drawn divider down the center. Both sides use the locked body-text color as ink line work with slight wobble. Left side ("Before") shows a simple stick-figure character with a frustrated posture, a speech bubble with hand-lettered "OLD WAY" in English block caps, and a small list of three hand-drawn dashes with brief 1-2 word annotations (e.g. "manual", "slow", "fragile"). Right side ("After") shows a confident stick-figure character with a clean checkmark above, hand-lettered "NEW WAY" in English block caps, and three checkbox-style annotations (e.g. "automated", "fast", "reliable"). A curved hand-drawn "mindset shift" arrow bridges left to right with a small hand-lettered label "the shift". Sparse semantic color: the locked accent marks the left-side pain points and the locked secondary accent marks the right-side positives. Total accent area stays under 10% of canvas. All hand-lettered text is short keywords. Composed as a 1200×500 hero banner with 14% inner padding. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/sketch-notes.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/sketch-notes.md index e5ad14cd..f5625268 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/sketch-notes.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/sketch-notes.md @@ -4,7 +4,7 @@ Warm cream paper with black hand-drawn lines and soft pastel color blocks. The m ## 1. Style paragraph (paste-ready, 110 words) -> Warm hand-drawn sketchnote style on cream paper background. All lines are drawn with deliberate slight wobble — black ink on cream, never perfectly straight, with the human-hand quality that makes the image feel like a thoughtful teacher's whiteboard. Color blocks are soft pastels — light blue, mint, lavender, peach — filled into rounded shapes that don't quite reach their outlines (a deliberate "hand-painted overshoot" feel). Simple cartoon icons and small doodle decorations (stars, sparkles, dots, underlines) appear sparingly to add warmth. Composition is airy and well-organized, with generous white space between elements. Overall feel is warm, instructional, friendly — the visual language of educational explainer videos and knowledge cards. +> Warm hand-drawn sketchnote style on the deck's light background role. All lines use the locked body-text color with deliberate slight wobble, never perfectly straight, giving the human-hand quality of a thoughtful teacher's whiteboard. Soft color blocks derive only from the locked primary, secondary-accent, and accent roles and fill rounded shapes without quite reaching their outlines (a deliberate "hand-painted overshoot" feel). Simple cartoon icons and small doodle decorations (stars, sparkles, dots, underlines) appear sparingly to add warmth. Composition is airy and well organized, with generous whitespace. Overall feel is instructional, friendly, and approachable. --- @@ -20,11 +20,11 @@ Warm cream paper with black hand-drawn lines and soft pastel color blocks. The m ## 3. Using the deck's HEX values -sketch-notes has a strong **built-in palette tendency** toward warm cream + black ink + soft pastels. When the deck's `design_spec.colors` align (warm-earth or macaron palette family), use them directly. When they don't align (cool-corporate primary), sketch-notes may be the wrong rendering — consult the compatibility matrix in `image-palettes/_index.md`. +sketch-notes has a strong built-in tendency toward warm paper, dark ink, and soft color blocks. Offer it only when the locked deck roles can carry that tendency; otherwise choose another rendering in Stage 2. Once confirmed, use only the locked deck colors. -- Cream paper background: keep close to the rendering's natural `#F5F0E8` even if `design_spec.secondary` differs slightly (the cream **is** part of sketch-notes) -- Black ink lines: keep at `#1A1A1A` or near-black — do not replace with the deck's primary -- Pastel color blocks: the deck's primary / secondary / accent HEX values, **rendered as soft pastel tints** rather than full saturation +- Paper background: use the deck's `background` or `secondary_bg`; do not introduce a natural cream outside the lock +- Ink lines: use the deck's `body_text` role +- Color blocks: use the deck's primary / secondary-accent / accent roles with restrained coverage; do not invent pastel HEX - Single emphasis accent: the deck's accent HEX, used in 1-2 strong sparing places (a key arrow, an emphasized doodle) --- @@ -33,4 +33,4 @@ sketch-notes has a strong **built-in palette tendency** toward warm cream + blac **Snippet A — half-page educational concept, text_policy: embedded** -> Warm hand-drawn sketchnote on warm cream paper background. Black ink lines with slight wobble define three rounded rectangle info boxes arranged in a soft triangle layout. Each box is filled with a soft pastel block color: top box in light blue (a pastel tint of the deck's primary `#1E3A5F`), bottom-left box in mint, bottom-right box in lavender. Color fills don't completely reach the outlines (slight hand-painted overshoot). Hand-drawn wavy arrows connect the boxes — each arrow with a small inline hand-lettered keyword like "leads to", "becomes", "supports" (≤2 words per arrow). Each box contains one simple hand-drawn cartoon icon — a lightbulb, a plant, a gear — in black ink. Small doodle decorations (a few stars, dots, sparkles) sparingly around the composition. Composed as a 600×600 half-page block with 14% inner padding. Generous white space. Color values are rendering guidance only — do not display HEX codes or color names as text. \ No newline at end of file +> Warm hand-drawn sketchnote on the deck's locked background color. Lines use the locked body-text color with slight wobble and define three rounded rectangle info boxes arranged in a soft triangle. The top box uses the locked primary, the bottom-left uses the locked secondary accent, and the bottom-right uses the locked accent, each with restrained coverage and no invented tint. Color fills do not completely reach their outlines (slight hand-painted overshoot). Hand-drawn wavy arrows connect the boxes, each with a brief inline keyword such as "leads to", "becomes", or "supports" (≤2 words). Each box contains one simple hand-drawn cartoon icon — a lightbulb, a plant, a gear. Small doodle decorations appear sparingly. Composed as a 600×600 half-page block with 14% inner padding and generous whitespace. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/warm-scene.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/warm-scene.md index a41fa284..98822eec 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/warm-scene.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-renderings/warm-scene.md @@ -4,7 +4,7 @@ Golden-hour cinematic warmth — illustrated scenes with intentional warm lighti ## 1. Style paragraph (paste-ready, 100 words) -> Atmospheric scene illustration with golden-hour cinematic lighting. Forms are softly rendered — recognizable but not photo-realistic, with soft edges and intentional light direction. The scene has a clear primary light source (warm low sun, lamplight, window light) casting long soft shadows. Color palette leans warm and slightly desaturated — ambers, terracottas, cream highlights against deeper warm shadows. A subtle bloom or halo effect around the light source adds cinematic warmth. Composition follows narrative principles — foreground subject, middle ground context, atmospheric background. Overall feel is cinematic, contemplative, emotionally warm — well suited to brand story and personal narrative content. +> Atmospheric scene illustration with golden-hour cinematic lighting. Forms are softly rendered — recognizable but not photorealistic, with soft edges and intentional light direction. The scene has a clear primary light source (low sun, lamplight, window light) casting long soft shadows. Exact colors come only from the deck's locked roles; emotional warmth comes from light placement, bloom, contrast, and atmosphere rather than hue substitution. Composition follows narrative principles — foreground subject, middle-ground context, atmospheric background. Overall feel is cinematic, contemplative, and emotionally warm, well suited to brand story and personal narrative content. --- @@ -20,13 +20,13 @@ Golden-hour cinematic warmth — illustrated scenes with intentional warm lighti ## 3. Using the deck's HEX values -warm-scene reads HEX values through a **warm-graded filter**: +warm-scene uses the deck's exact HEX roles and creates warmth through light, not recoloring: -- Primary HEX: dominant warm tone in shadows and midground (warm-graded version of the deck's primary) -- Secondary HEX: highlight tone in the lit areas (warm cream, soft amber) -- Accent HEX: a small bright concentrated zone — sun bloom, lamp glow, key warm reflection +- Primary HEX: dominant tone in shadows and middle ground, unchanged +- Secondary HEX: lit field or atmospheric separation, unchanged +- Accent HEX: a small concentrated zone — sun bloom, lamp glow, or key reflection, unchanged -If the deck's primary is cool (navy, teal), warm-scene will subtly warm-grade it; if the deck's palette is already warm, the rendering reinforces it directly. +If the locked roles cannot support an emotionally warm scene without hue shifts, do not offer `warm-scene` in Stage 2. Never warm-grade a cool primary after confirmation. --- @@ -34,4 +34,4 @@ If the deck's primary is cool (navy, teal), warm-scene will subtly warm-grade it **Snippet A — half-page personal story, text_policy: none** -> Atmospheric scene illustration with golden-hour cinematic lighting. A softly rendered figure (simplified silhouette, no detailed face) walks along a path in a warm landscape — the figure in the foreground left, the path leading to a small distant cabin in the middleground, soft warm hills in the atmospheric background. Strong golden warm light comes from the upper right (the sun near the horizon), casting long soft shadows toward the left. Sky transitions from amber `#D97706` at the horizon to soft cream `#FEF3C7` at the top. Foreground shadows in deeper warm primary `#7C2D12`. Subtle bloom around the sun. No hard outlines — forms emerge from light and shadow. Subtle film grain at 8% opacity. Composed as a 600×800 half-page block with 10% inner padding. Simplified silhouette figures only — no realistic faces. NO text or labels. Color values are rendering guidance only. \ No newline at end of file +> Atmospheric scene illustration with golden-hour cinematic lighting. A softly rendered figure (simplified silhouette, no detailed face) walks along a path — foreground left, a small distant cabin in the middle ground, soft hills in the atmospheric background. Strong low-angle light comes from the upper right and casts long soft shadows. The sky uses the deck's locked secondary-background role, main forms use the locked primary, and a small sun bloom uses the locked accent; none is hue-shifted. No hard outlines — forms emerge from light and shadow. Add subtle bloom and film grain at 8% opacity. Composed as a 600×800 half-page block with 10% inner padding. Simplified silhouette figures only; no realistic faces, text, or labels. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md index 82b845ca..55fcc9ba 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-searcher.md @@ -1,4 +1,4 @@ -> See [`image-base.md`](./image-base.md) for the common framework. Technical SVG/PPT constraints are in [`shared-standards.md`](./shared-standards.md). +> See [`image-base.md`](./image-base.md) for the common framework. Technical SVG/PPT constraints are in [`shared-standards-core.md`](./shared-standards-core.md). # Image_Searcher Reference Manual @@ -196,7 +196,7 @@ Never treat a generic `required_terms` pass as acceptance. For example, matching ```bash python3 scripts/image_search.py --from-url --filename .jpg -o /images ``` - Recorded with `license_tier: manual` — verifying usage rights is the user's call. Human replacement is a legitimate outcome, not a failure. It updates the image and `image_sources.json` but does **not** rewrite `image_queries.json`, so a row fixed this way may still read `Needs-Manual` in the batch manifest — harmless: the file is present, so export proceeds (executor-base §6.1); + Recorded with `license_tier: manual` — verifying usage rights is the user's call. Human replacement is a legitimate outcome, not a failure. It updates the image and `image_sources.json` but does **not** rewrite `image_queries.json`, so a row fixed this way may still read `Needs-Manual` in the batch manifest — harmless: the file is present, so export proceeds ([`executor-web-image.md`](./executor-web-image.md) §1); 3. (opt-in) `--save-candidates` to pull auto-alternatives with their own `source_page_url`s, then `--promote` the best (below); 4. if nothing fits, mark the row `Needs-Manual`. @@ -281,7 +281,7 @@ Applied by Executor when an image's `license_tier == "attribution-required"`. Th - **Position**: bottom-right of the image's container, hugging the image edge (within ~8 px) - **Font size**: 6–8pt equivalent (≈ 0.7–1 % of canvas short edge) -- **Color**: `#999` on light/photo backgrounds; `rgba(255,255,255,0.6)` on dark/photo +- **Color**: `fill="#999999"` on light/photo backgrounds; `fill="#FFFFFF" fill-opacity="0.6"` on dark/photo - **Content**: `© {author} / {provider_short} / {license_short}` - `provider_short`: `Openverse` / `Wikimedia` / `Pexels` / `Pixabay` - `license_short`: `CC BY 4.0` / `CC BY-SA 4.0` / `Public Domain` @@ -301,8 +301,8 @@ Use single-letter labels (a/b/c) only when needed for disambiguation. ### 7.3 Hero / full-bleed image -- Bottom 1.5 cm gradient overlay: transparent → `rgba(0,0,0,0.5)` -- 7pt white semi-transparent text inside the overlay band, right-aligned ~24 px from edge +- Bottom 1.5 cm gradient overlay: `stop-color="#000000" stop-opacity="0"` → `stop-color="#000000" stop-opacity="0.5"` +- 7pt text with `fill="#FFFFFF" fill-opacity="0.6"` inside the overlay band, right-aligned ~24 px from edge ### 7.4 Source for the credit text diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-type-templates/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-type-templates/_index.md index 0e31c8ac..2ddc1808 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-type-templates/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/image-type-templates/_index.md @@ -86,6 +86,6 @@ For `page_role: hero_page` images, default container is the slide canvas (e.g. 1 1. For each `page_role: local` row in the Image Resource List, pick the type using the auto-selection table above. 2. For each `page_role: hero_page` row, **skip type selection** — go straight to [`image-generator.md`](../image-generator.md) §4.1 primitives. 3. `read_file image-type-templates/.md` — only the types actually used in this deck. Most decks use 2-4 types; load each at most once. -4. Apply the type's composition skeleton when assembling the prompt, alongside the locked deck-wide rendering and palette. +4. Apply the type's composition skeleton alongside the locked deck-wide rendering and deck color roles. -**Multiple types per deck is normal.** Locking is at rendering + palette level, not type level. +**Multiple types per deck is normal.** Rendering and deck colors stay fixed; type varies per image. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md index 59e40f87..84f193c2 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/_index.md @@ -18,23 +18,23 @@ Each mode has its own file with: narrative skeleton, page-structure tendencies, | [`showcase`](./showcase.md) | Visual-led impact; big imagery / numbers; emotional rhythm | Launches, brand reveals, event / promo decks | | [`briefing`](./briefing.md) | Neutral, complete, scannable; topic titles, even weight, no thesis | Status updates, reference decks, catalogs, meeting packs, FAQs | -> The five partition presentation *intent*, not aesthetics: persuade (`pyramid`) · tell a story (`narrative`) · teach (`instructional`) · impress (`showcase`) · simply inform (`briefing`). +> The five are **argument strategies, not a taxonomy of communication purposes**. A presentation may inform + align + request a decision at once; that composite intent stays as open prose in the Stage-1 communication contract. Stage 2 chooses the mode that best carries the dominant body-page spine, or one concrete `custom` act sequence when no preset can serve the stated priority / sequence. > > **A mode is a lens, not a mandate over the user's own structure.** When the user brings their own outline, it is authoritative: transcribe it into `design_spec.md §IX` as given — page order and titles preserved — and let the mode govern only voice / register and page-internal treatment. A mode never reorders a user's pages or rewrites their given titles (mode is Reference-strength; a user-authored outline is exactly the override). When the user gives no structure, the mode does the structural lifting. To lay an outline out with the least reshaping, `briefing` imposes the lightest skeleton. --- -## 2. Auto-selection — content / audience signal → mode +## 2. Auto-selection — communication contract + source signal → mode -| Signal | Recommended mode | Alternates | +| Contract / source signal | Recommended mode | Alternates | |---|---|---| -| Strategic decision / analysis / board / investor | `pyramid` | `narrative` | -| Pitch / case study / origin story / campaign arc | `narrative` | `showcase` | -| Course / onboarding / how-to / science explainer | `instructional` | `pyramid` | -| Product launch / brand reveal / event opener / keynote / 发布会 / TED | `showcase` | `narrative` | -| Status update / reference / catalog / FAQ / meeting pack / 周报 / 参考 | `briefing` | `pyramid` | +| Decision / recommendation outcome; analysis, board, investor; criteria and trade-offs must land | `pyramid` | `narrative` | +| Persuasion or mobilization lands through a case, tension, transformation, or origin arc | `narrative` | `showcase`, `pyramid` | +| Understanding or capability must build step by step; course, onboarding, how-to, explainer | `instructional` | `pyramid`, `briefing` | +| Attention / emotion / launch moment is primary; sparse presenter-led delivery | `showcase` | `narrative` | +| Complete reference, status, record, hand-off, FAQ, meeting pack; no thesis dominates | `briefing` | `pyramid`, `instructional` | -> No single signal dominates — read the deck's actual purpose from `c. Key Information`. When two modes fit, follow the **primary** intent of the body pages, not the cover. A data review legitimately runs almost entirely `pyramid`; do not force variety. +> No keyword decides the mode. Read `communication_intent`, `audience_outcome`, `core_message`, delivery context / afterlife, source texture, and any user-authored outline together. When several purposes coexist, follow the dominant **argument movement of the body pages**, not the cover and not the first purpose word. A data review can legitimately run almost entirely `pyramid`; a progress report whose durable hand-off matters more than persuasion may stay `briefing`. **Close calls** — the genuinely adjacent pairs; every other pair is far enough apart that the auto-selection signal decides. @@ -52,8 +52,8 @@ Each mode has its own file with: narrative skeleton, page-structure tendencies, ## 3. How to use 1. Strategist reads this index at confirmation `d. Layer 1`. -2. Pick one mode from the auto-selection table + the deck's stated purpose. -3. Lock it: write `- mode: ` into `spec_lock.md`, record the rationale in `design_spec.md`. +2. Preselect one mode from the auto-selection table + the confirmed communication contract and source structure; separately author the visible AI custom candidate required by §4. +3. Record the confirmed mode and rationale in `design_spec.md`, then project `- mode: ` into `spec_lock.md`. 4. Executor reads **only** `modes/.md` at generation entry — never globs this directory. **Lock scope**: deck-wide (one mode per deck). The five are the catalog you select from; if the structure is genuinely mixed, pick the mode of the body pages and let pages vary within it, or recommend a `custom` blend (§4). Recommend the best fit; the user confirms. @@ -64,10 +64,10 @@ Each mode has its own file with: narrative skeleton, page-structure tendencies, `custom` holds **any bespoke narrative direction the five don't give as-is** — and what *kind* of thing it is doesn't matter. It might be a nameable cadence (dialectic 正反合, myth-vs-reality, countdown / Top-N, Socratic), a deliberate multi-act fusion of several modes, or the user's own feel for how the deck should carry (confrontational here, detached there). Don't try to taxonomize it. -**Either side may originate it.** The user can ask for it directly; or the Strategist — as the deck's strategist — may **recommend** `custom` when a bespoke direction (often a fusion of two modes) genuinely serves the deck better than any single preset. Like every confirmation, it's a recommendation the user confirms or overrides — and the recommendation must **spell the custom out in plain language** (what the cadence / fusion / posture actually is), never present the bare token `custom`, so the user confirms something legible. Either way, the Strategist **crystallizes the intent into a `- mode_behavior:` paragraph** — concrete enough that the Executor can follow it per page (the act sequence or posture shifts, the title voice, the page rhythm, the notes register). Set `- mode: custom` in `spec_lock.md` with that sibling line; the Executor follows the prose in place of a preset file. (This records the intent so it survives 20 pages of generation — the Executor only ever reads `spec_lock.md`, never the chat.) +**Always author the candidate; select it only when warranted.** Stage 2 includes one visible, non-empty AI custom proposal beside the five presets, spelling out the cadence / fusion / posture in plain language. It is initially unselected and does not replace the best-fit preset recommendation unless the user already supplied that exact custom direction; with a template, it must fit available prototype capacity. When the user selects it, the editable prose is saved as `mode: custom` plus `mode_behavior`; otherwise it remains recommendation-only. The Strategist crystallizes a selected custom direction in the Design Spec first, then projects the same pair to `spec_lock.md`. The Executor follows that prose in place of a preset file. (This records the intent so it survives 20 pages of generation — the Executor only ever reads `spec_lock.md`, never the chat.) > **One value per deck — fusion is *one* `custom`, not several modes.** A deck always locks a single `mode`. A multi-mode blend is expressed as **one** `mode: custom` whose `mode_behavior` paragraph describes the acts — never by locking several modes. > > **First ask whether it's really fusion.** A locked mode is a *tendency*, not a cage: a `narrative` deck can still carry one analytical (pyramid-style) page, an `instructional` deck one showcase reveal — that is leaning within a dominant mode, and needs **no** `custom`. Reach for `custom` only when there is genuinely no single dominant spine. -**The one thing to avoid**: reaching for `custom` as a *dodge* — defaulting to it because picking among the five takes judgment. When a preset genuinely fits, lock the preset; propose `custom` when a bespoke direction earns its place, not to avoid choosing. (And a user-stated direction is authoritative the same way a user-supplied outline is — see the lens-not-mandate note in §1.) +**The one thing to avoid**: selecting `custom` as a *dodge* — defaulting to it because picking among the five takes judgment. The custom candidate is mandatory; a custom lock is not. When a preset genuinely fits, keep that preset selected. A user-stated direction remains authoritative the same way a user-supplied outline is — see the lens-not-mandate note in §1. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/briefing.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/briefing.md index bb46a813..04c2252c 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/briefing.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/briefing.md @@ -30,7 +30,7 @@ Neutral information delivery. Lay the facts out plainly and completely, organize ## 3. Speaker-notes register -Even, factual, plain. State what the page shows without building tension or pressing a "so what". No rhetorical questions, no suspense — a clear read-out the listener can follow or skim. Numbers stated plainly. (Common framework: [`executor-base.md §8`](../executor-base.md).) +Even, factual, plain. State what the page shows without building tension or pressing a "so what". No rhetorical questions, no suspense — a clear read-out the listener can follow or skim. Numbers stated plainly. (Common framework: [`executor-notes.md`](../executor-notes.md) §1.) ## 4. Page skeleton example diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/instructional.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/instructional.md index b0181a73..d0feaefe 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/instructional.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/instructional.md @@ -32,7 +32,7 @@ Titles state what the page teaches ("How attention weights are computed") — cl ## 3. Speaker-notes register -Patient, explanatory. Define before using; analogy then principle. Anticipate the learner's question and answer it. Steady pace; signpost transitions ("now that we have X, we can ask Y"). Conversational data. (Common framework: [`executor-base.md §8`](../executor-base.md).) +Patient, explanatory. Define before using; analogy then principle. Anticipate the learner's question and answer it. Steady pace; signpost transitions ("now that we have X, we can ask Y"). Conversational data. (Common framework: [`executor-notes.md`](../executor-notes.md) §1.) --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/narrative.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/narrative.md index 44224531..a8276e82 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/narrative.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/narrative.md @@ -30,7 +30,7 @@ Titles read as beats that advance the arc ("Then the numbers stopped adding up") ## 3. Speaker-notes register -Conversational narration — like talking with the audience, not reading a report. Scenario-conflict-resolution per page. Metaphors make the abstract tangible ("like adding a turbocharger"). Plain rhetorical questions create suspense; bridge each page from the prior one. Conversational data ("nearly a third", "more than doubled"). (Common framework: [`executor-base.md §8`](../executor-base.md).) +Conversational narration — like talking with the audience, not reading a report. Scenario-conflict-resolution per page. Metaphors make the abstract tangible ("like adding a turbocharger"). Plain rhetorical questions create suspense; bridge each page from the prior one. Conversational data ("nearly a third", "more than doubled"). (Common framework: [`executor-notes.md`](../executor-notes.md) §1.) --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/pyramid.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/pyramid.md index 2f3ca71c..5dc50cee 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/pyramid.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/pyramid.md @@ -44,7 +44,7 @@ SCQA opening, pyramid body: ## 3. Speaker-notes register -Conclusion-driven: the first sentence of each page's notes is the takeaway, then 2-3 supporting facts in flowing prose. Composed, authoritative. Every number paired with its comparison in the same sentence ("23% — nearly double the industry's 12%"). Spell percentages as words where the spoken form reads more naturally. (Common framework: [`executor-base.md §8`](../executor-base.md).) +Conclusion-driven: the first sentence of each page's notes is the takeaway, then 2-3 supporting facts in flowing prose. Composed, authoritative. Every number paired with its comparison in the same sentence ("23% — nearly double the industry's 12%"). Spell percentages as words where the spoken form reads more naturally. (Common framework: [`executor-notes.md`](../executor-notes.md) §1.) --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/showcase.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/showcase.md index 31c00b69..301330b7 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/showcase.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/modes/showcase.md @@ -30,7 +30,7 @@ Titles are short and evocative — a phrase, not a sentence. ## 3. Speaker-notes register -Energetic, evocative — sets mood and builds anticipation. Short, punchy sentences. Lets the visual do the work and narrates the feeling around it. (Common framework: [`executor-base.md §8`](../executor-base.md).) +Energetic, evocative — sets mood and builds anticipation. Short, punchy sentences. Lets the visual do the work and narrates the feeling around it. (Common framework: [`executor-notes.md`](../executor-notes.md) §1.) --- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md new file mode 100644 index 00000000..b475ac41 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-data-interface.md @@ -0,0 +1,368 @@ +> See [`shared-standards-core.md`](./shared-standards-core.md) for the mandatory SVG foundation. + +# Native Data Interface + +Conditional interface for preset pattern fills and PowerPoint-native chart/table replacement metadata. Load when either feature appears in the authored SVG. + +## 1. Pattern Fill — `` with PPTX preset annotation + +`` requests one fixed DrawingML preset; the converter does not render +the tile's arbitrary geometry. Use this interface only when that preset mapping +is intended. + +`data-pptx-pattern=""` is the generated default for selecting the +intended preset from the enum below. The converter retains an `ltUpDiag` +fallback when the annotation is absent; the checker reports that fallback as a +non-blocking fidelity warning. Invalid explicit preset names remain errors +because they violate the closed OOXML enum. + +Pattern colors may come from importer metadata (`data-pptx-fg` / +`data-pptx-bg`) or from the pattern's child paint. Without metadata, the first +child `` fill becomes the background and the first stroke (or other fill) +becomes the foreground. A missing background defaults to white; a missing +foreground means no native pattern fill can be emitted. The child geometry +itself is never used as a repeatable tile. + +**Valid `data-pptx-pattern` values** (OOXML `ST_PresetPatternVal` — closed enum, anything outside makes PowerPoint open with "needs to be repaired"): + +| Category | Values | +|---|---| +| Grids | `smGrid` · `lgGrid` · `dotGrid` *(no `ltGrid` — common typo)* | +| Diagonal lines | `ltUpDiag` · `ltDnDiag` · `dkUpDiag` · `dkDnDiag` · `wdUpDiag` · `wdDnDiag` · `dashUpDiag` · `dashDnDiag` · `diagCross` | +| Horizontal / vertical lines | `horz` · `vert` · `ltHorz` · `ltVert` · `dkHorz` · `dkVert` · `narHorz` · `narVert` · `dashHorz` · `dashVert` · `cross` | +| Percent fills | `pct5` · `pct10` · `pct20` · `pct25` · `pct30` · `pct40` · `pct50` · `pct60` · `pct70` · `pct75` · `pct80` · `pct90` | +| Checks & confetti | `smCheck` · `lgCheck` · `smConfetti` · `lgConfetti` | +| Decorative | `horzBrick` · `diagBrick` · `weave` · `plaid` · `trellis` · `zigZag` · `wave` · `sphere` · `divot` · `shingle` · `solidDmnd` · `openDmnd` · `dotDmnd` | + +`svg_quality_checker.py` warns when a referenced pattern lacks the annotation; +it errors when the pattern uses `patternTransform` or names a preset outside +this enum. + +## 2. PowerPoint-Native Chart / Table Replacement Markers (Authoring Mandatory; Export Opt-in) + +Native PowerPoint tables and Excel-backed charts activate at export time only. Metadata authoring is not opt-in: the default chart/table route still writes dormant replacement metadata while keeping hand-authored SVG geometry pixel-stable across PowerPoint / Keynote / LibreOffice / WPS. + +**Hard rule — authoring is mandatory**: Executor writes the marker and JSON metadata in the same edit as every supported data chart and pure text-grid data table ([`executor-chart.md`](./executor-chart.md) §2.2). Mini charts, sparklines, insets, KPI-card trends, and small multiples are included when they encode recoverable data in a supported chart type. Canonical rectangular merged text cells may use the narrow `row_span` / `col_span` contract below; graphical cells stay unmarked on the SVG fallback route. The marker group supplies both visible SVG fallback children for browser/live-preview rendering and JSON metadata for `svg_to_pptx` native export. + +**Hard rule — activation is the opt-in, dormant unless exported with `--native-charts-and-tables`**: A marker only declares that a group is eligible for PowerPoint-native Chart/Table replacement. Normal `svg_to_pptx.py` runs keep the fallback SVG children and convert them into independently editable DrawingML shapes. Pass `--native-charts-and-tables` only when the data source and chart/table-specific object model matter more than cross-renderer layout fidelity: it emits the PowerPoint Chart/Table object and skips the fallback children to avoid duplicates. Native styling preserves the core palette, text, axis, grid, and background colors where possible, but it is still a PowerPoint Chart/Table object rather than a pixel-identical SVG drawing. + +The native route is deliberately data-object-first and may be lossy: marker-local labels, callouts, KPIs, guide lines, custom split/bin semantics, or styling that is absent from the payload may disappear or normalize. Export warns about this route-level risk and any narrower issue it can detect. Loss of visual parity is not grounds to remove an active marker that the emitter can otherwise convert; use the default SVG-fallback export when exact authored artwork matters more than a native data source and object-specific controls. + +| Replacement marker | Native output | Required metadata | +|---|---|---| +| `` | `` with `` | bounds + `columns` or `rows` | +| `` | `` with `c:chart` / `cx:chart` + chart part + embedded workbook | bounds + `type`, plus chart data | + +**Metadata placement**: Put JSON in one child +``. The parent group's +`data-pptx-replace-with` value selects the table or chart schema, so the +metadata child does not repeat an object-kind attribute. Attribute JSON +(`data-pptx-json="..."`) remains read-compatible but is harder to XML-escape +correctly and is not canonical authoring. + +**Bounds**: Provide `x`, `y`, `width`, and `height` in metadata, or as +`data-pptx-x` / `data-pptx-y` / `data-pptx-width` / `data-pptx-height` on the +marker group. If any bound is omitted, the exporter infers the object frame +from the visible fallback geometry; this keeps SVG fallback and native object +placement aligned. Complete explicit bounds are absolute slide coordinates; +marker/ancestor `translate` and `scale` transforms apply only when at least one +bound is inferred. `x`, `y`, `width`, and `height` must be finite and resolve +inside PowerPoint's 32-bit DrawingML coordinate range; `width` and `height` +must resolve to at least one EMU. Native table frames must additionally resolve +to at least one EMU per resolved row and column. + +**Validation**: `svg_quality_checker.py` validates replacement marker kind, JSON +metadata, bounds/fallback availability, table rows/columns, supported chart +type, chart data shape, and any imported fallback baseline before export. + +Imported marker freshness, fallback classification, provenance, and legacy +read compatibility are operational import concerns. Keep generated authoring +free of those attributes; use the exact behavior and field index in +[`conversion.md`](../scripts/docs/conversion.md#native-table-and-chart-import-claims). + +```xml + + + { + "x": 120, "y": 150, "width": 520, "height": 320, + "type": "column", + "title": "Revenue by Segment", + "categories": ["Q1", "Q2", "Q3"], + "series": [ + {"name": "Cloud", "values": [12, 15, 19]}, + {"name": "Services", "values": [8, 9, 11]} + ] + } + + + +``` + +**Table schema**: Native tables are rectangular DrawingML grids. Use `columns` +for the optional header row and `rows` for body rows; shorter rows are padded +with blank cells unless `strict_grid: true` is set. Tables may contain at most +1000 resolved rows and 1000 resolved columns. Use `column_widths` and +`row_heights` as relative weights. Weight lists must match the resolved grid, +contain finite non-negative numbers, and include at least one positive value. +If present, `header_rows` must be an integer from `0` through the resolved row +count. Write `strict_grid`, `style.band_row`, and cell `bold` as JSON booleans. +Cell objects accept `text`, `fill`, `color`, +`align`, `valign`, `bold`, `font_size`, `padding`, `border_color`, and +`border_width`, plus optional `lang`; the same `padding`, `border_color`, +`border_width`, and `lang` keys may also live under `style` as table defaults. +For multi-paragraph text, replace cell `text` with a non-empty `paragraphs` +list. Each entry is either a string or an object containing optional +`align: "l|ctr|r"` and exactly one of `text` or non-empty `runs`; empty +paragraph strings are preserved, and cell `text` / `paragraphs` are mutually +exclusive. Each run is an object with required string `text` and optional JSON +boolean `bold`, `italic`, `underline`, and `strike`, plus optional `color`, +`font_size`, one-typeface `font_family`, `lang`, and `alt_lang`. Unknown fields, +wrong types, empty run lists, multi-typeface `font_family`, and unsupported +colors fail fast. PPTX import requires exact physical row/grid topology and +normalizes source presentation-only run XML outside this closed schema only +when it contains no non-empty `rPr` / `defRPr` / `endParaRPr` `effectLst` or +`effectDag`. A table-cell run effect follows the blocking effect contract above +instead of entering either the native payload or an effect-free fallback. +Relationship-bearing text, extensions, structural line breaks, fields, tabs, +bullets, malformed run topology, and unsupported text-body structure remain +fallback-only. +Per-side cell borders use `borders.left|right|top|bottom`, where each value is +either `{ "style": "none" }` or +`{ "style": "solid", "color": "#RRGGBB", "width": }`. +Per-side borders are cell-only; legacy uniform `border_color` / `border_width` +remain supported as defaults that an individual side may override. +When `lang` is absent, export derives `zh-CN` for CJK text and `en-US` +otherwise. `style.band_row: false` disables both `` and +materialized alternating row fills. Native table typography mirrors the +visible SVG fallback: put `style.font_family` and `style.font_size` on the +marker from the table text already drawn, then use `style.header_font_size` or +per-cell `font_size` only when the fallback visibly differs. If the fallback +has no explicit table font, use the deck body family and locked body size from +`spec_lock.md`. + +**Hard rule — table metadata is the native source of truth**: Every row, +summary line, value, and cell-level style that must survive +`--native-charts-and-tables` must be present in `columns` / `rows`. SVG fallback text is +discarded during native export. `svg_quality_checker.py` warns when visible +fallback `` inside a native table marker does not appear in metadata. +For numeric or currency columns, use cell objects with `align: "r"`; SVG +`text-anchor="end"` does not carry into the native table. + +**Merged table cells — canonical rectangular contract only**: Put positive JSON +integer `row_span` / `col_span` values on the merge anchor and keep every +covered grid cell blank. Spans must stay within the resolved rectangular grid +and may not overlap. The exporter emits the canonical DrawingML topology +(`rowSpan` on the top edge, `gridSpan` on the left edge, `hMerge` / `vMerge` on +covered cells). CamelCase aliases, raw OOXML merge fields, top-level merge lists, +nonblank covered cells, invalid spans, and overlaps fail fast. The PPTX importer +activates native reconstruction only for that same explicit rectangular topology +with empty merge-slave text bodies; other merge encodings remain fallback-only +with `unsupported-merge-topology`. + +**Category chart schema**: `column`, `bar`, `line`, `area`, `pie`, +`doughnut`, `pieOfPie`, `barOfPie`, and `radar` use `categories` plus +`series[].values`. Pie-family charts (`pie`, `doughnut`, `pieOfPie`, and +`barOfPie`) must have exactly one series; the exporter assigns per-category +slice colors so single-series charts do not collapse into one solid color. +Column and bar charts may set per-point colors with `series[].point_colors` +or `series[].pointColors`; the list must match `series[].values` length. +Classic category charts may set native PowerPoint data labels with +`data_labels`. Use `data_labels: true` for default value labels, or an object +with `show_value`, `position`, `number_format`, `font_size`, `font_family`, +`bold`, `color`, and optional per-point `colors`. Supported label positions +depend on chart type: clustered column/bar labels may use `outside_end`, +`inside_end`, `inside_base`, or `center`; stacked / percent-stacked column/bar +labels may use `inside_end`, `inside_base`, or `center`; line labels may use +`above`, `center`, or `best_fit`; area labels do not emit a native label +position. To label only selected data points, use `data_labels.points` with +zero-based `idx` plus optional per-point `position`, `number_format`, +`font_size`, `font_family`, `bold`, and `color`. + +**Combo chart schema**: `combo` uses shared `categories` plus either `plots[]` +or typed `series[]`. Each plot supports `type: "column" | "line" | "area"`, +its own `series`, and optional `axis: "secondary"` for a right-side value axis. +When primary and secondary plots genuinely use different category caches, +`plots[]` may also carry its own `categories` and `category_numeric`; the +workbook writer allocates independent category/value ranges. Typed `series[]` +continues to require the shared top-level categories. +Imported `plots[]` may carry `series_indices` so the verified source identity +where each `c:idx` equals its `c:order` survives when physical plot order differs +from legend order. If one plot supplies it, every plot must supply a same-length +list of unique non-negative JSON integers, and the combined values must form one +contiguous `0..N-1` range. Sources whose `idx` and `order` differ stay +fallback-only; typed `series[]` does not accept this plot-scoped field. +Typed `series[]` accepts the same `type` and `axis` fields per series, and +adjacent compatible series are grouped into the same PowerPoint plot. Area +series may set `fill_opacity` / `fillOpacity` as a `0..1` SVG opacity value +when the SVG fallback uses a transparent area fill under an opaque line. A line plot with `area_fill: true` +is exported as a PowerPoint area chart under the hood; `fill_opacity` only sets +the fill style and does not trigger conversion by itself. Combo export layers +area plots below columns and lines while preserving the original series indices. +Line and area series may set `line_width` / `lineWidth` in SVG px units to +match fallback `stroke-width`. + +**Narrow classic-axis schema**: `axes` is a closed object with the roles +`category`, `value`, `secondary_category`, and `secondary_value`. Each role may +set only `kind` (`text`, `date`, or `value`, as appropriate), `position`, +`visible`, `label_position` (`next_to`, `none`, `low`, or `high`), +`number_format`, `minimum`, `maximum`, `major_unit`, `reverse`, and +`major_gridlines`. `major_unit` applies to value axes only. PPTX date-axis +**import** is deliberately narrow: numeric Excel date serials are accepted for +area charts and OHLC stock charts; arbitrary date-axis source families are not. +This contract is not a full `AxisSpec`: logarithmic scales, minor units/gridlines, +crossing values, display units, tick skipping, and other unlisted OOXML semantics +remain unsupported and fail closed on import. + +**Narrow XY-axis schema**: `scatter` and `bubble` may use a closed `axes` object +with only `x` and `y` roles. Both roles have `kind: "value"`; `x.position` +is `bottom` or `top`, while `y.position` is `left` or `right`. Each accepts the +same closed fields above, and `major_unit` is valid on both value axes. PPTX +import requires the plot to reference exactly two mutually cross-linked +`c:valAx` nodes and separately enforces the closed field/topology gates. The +native writer emits and the importer reads back every field in this closed +contract. Scatter import derives the effective `scatter_style` from a uniform +per-series line/marker/smooth state; unsupported or nonuniform states remain +fallback-only. The normalized SVG fallback newly consumes only +`axes.x.major_gridlines` and `axes.y.major_gridlines`; the other fields do not +imply full visual-axis parity. + +**XY chart schema**: `scatter` and `bubble` use `series[].x` + `series[].y`; +`bubble` also requires one `series[].size` / `series[].sizes` value per point. +`series[].points` is also accepted as `[x, y]` / `[x, y, size]` tuples or +`{x, y, size}` objects. + +**Chart typography**: Metadata sizes use the same px-style unit as SVG text +(`1px = 0.75pt`). `style.font_family` and the role-specific +`title_font_size`, `subtitle_font_size`, `axis_font_size`, +`axis_title_font_size`, `legend_font_size`, and `note_font_size` fields are +required only when the native object must preserve typography that cannot be +inferred unambiguously from the visible fallback. + +**Chart chrome metadata**: Text that is visually part of the chart must be in +metadata, not only in SVG fallback children; metadata MUST still match visible +fallback chrome. `title` becomes the native chart title on classic charts; it +is not an object name, so use `name` for semantic object naming. `subtitle` +becomes the second rich-text line of that classic chart title. `title`, +`subtitle`, and axis-title values may be strings or objects with `text`, +`font_size`, `font_family`, and `color` when the fallback uses local role +typography. `svg_quality_checker.py` rejects `title`, `subtitle`, or axis-title +metadata whose text is not visible inside the replacement marker's fallback. Direct +`--native-charts-and-tables` export keeps the chart native but omits that inconsistent +chrome with a warning. chartEx keeps PowerPoint's empty `` and emits +the title / subtitle as companion editable text boxes until chartEx rich titles +are validated. Axis +titles are optional and explicit: use `axis_titles` with +`category`, `value`, `x`, `y`, or `secondary_value` keys, or the root aliases +`category_axis_title`, `value_axis_title`, `x_axis_title`, `y_axis_title`, and +`secondary_value_axis_title`; do not add semantic axis titles that are not +visible in the fallback. Set `show_value_axis_labels: false` when the fallback +keeps category labels but omits numeric value-axis tick labels, such as a radar +chart without radial coordinates. Native legends are metadata-controlled: use +`show_legend: true` and `legend_position` only when the fallback's legend is +meant to be replaced by PowerPoint's native legend. +Companion text such as `caption`, `source`, `note`, `notes`, `footnote`, and +`footnotes` is exported as editable PPT text boxes next to the native chart. A +companion entry may be a string or an object with `text`, `x`, `y`, `width`, +`height`, `font_size`, `color`, `align`, and `bold`; explicit bounds are +recommended so the native export matches the SVG fallback placement. Explicit +companion bounds are slide coordinates, not local coordinates inside a +transformed marker group. Use companion text for chart captions, source notes, +center labels, and freeform annotations; use `data_labels` for values that +belong to chart points. + +**Chart color styling**: For classic native charts, `style.colors` sets series +colors. The exporter also writes explicit chart-area fill, plot-area fill, +axis line, gridline, and label text colors so PowerPoint does not substitute a +white/default-theme chart. If omitted, the exporter infers these colors from +the visible SVG fallback: the largest panel-like `` becomes the chart +background, fallback text supplies label color, and fallback strokes supply +axis/grid colors. Override any of them explicitly under `style` with +`chart_area_fill`, `plot_area_fill`, `text_color`, `axis_color`, and +`grid_color`; use `"none"` for transparent chart or plot area fill. Generated +payloads default to uppercase `#RRGGBB`. The exporter retains compatibility for +`#RGB`, `rgb(...)` / `rgba(...)`, and common CSS names, normalizing them to +6-digit OOXML RGB. Bar and column series also disable PowerPoint's negative-value +inversion so negative bars keep the same series fill instead of turning into +white/theme fill. + +For ChartEx native charts, valid payload `style.colors` (or root `colors`) +populate the ChartEx color-style part instead of being replaced by a fixed +accent1–accent6 list. Other ChartEx style semantics remain normalized. + +**PowerPoint chartEx schema**: `treemap`, `sunburst`, `histogram`, `pareto`, +`boxWhisker`, `waterfall`, and `funnel` use Office 2016+ chartEx parts. Use +these input shapes: + +| Type | Required data | +|---|---| +| `treemap`, `sunburst` | `values` plus either `levels` (`levels[level][point]`) or path-style `categories` (`[["Region", "Group", "Leaf"], ...]`) | +| `treemap` display note | Top-level group labels default to `overlapping`; override with `parent_label_layout: "banner" \| "overlapping" \| "none"`. PowerPoint labels only the top level and leaves — intermediate levels group tiles spatially without labels (sunburst shows every ring). | +| `histogram` | `values` | +| `pareto`, `waterfall`, `funnel` | `categories` + `values`; `waterfall` also accepts `subtotals` / `subtotal_indices` point indexes | +| `boxWhisker` | `series[].values`; optional `series[].categories` per value | + +> Note: chartEx files are valid PPTX and editable in PowerPoint; non-Microsoft +> renderers can display a limited subset. + +**Stock chart schema**: `stock` uses numeric Excel date serials in +`categories` or `dates`, plus exactly four series in open / high / low / close +order. Use either `series` with four entries, or top-level `open`, `high`, +`low`, and `close` arrays. PPTX import currently recognizes only canonical OHLC +stock charts with shared numeric date caches, `hiLowLines`, and `upDownBars`. +Safe stock series style may pass the structural gate, but stock series, +`hiLowLines`, and up-down bar local styling can still normalize under the +data-object-first contract. HLC, volume, noncanonical structure, and style XML +outside the safe parsing boundary stay fallback-only. + +**PPTX chart-import boundary**: The importer recognizes conservative classic +single-plot charts plus the verified scatter/bubble XY-axis, column/line/area +combo, area date-axis, canonical OHLC stock, radar, safe `of_pie` `serLines`, +axis/title/legend normalization, and bar/column gap/overlap subsets. Imported +`gapWidth` must be one canonical integer in `0..500`; imported `overlap` must be +one canonical integer in `-100..100`. Both values intentionally normalize to +the native writer contract rather than claiming exact source-style retention. +Malformed, duplicate, or out-of-range values fail closed. + +ChartEx import is closed to seven validated data models: `treemap`, `sunburst`, +`histogram`, `pareto`, `box_whisker`, `waterfall`, and `funnel`. The importer +retains their supported hierarchy/category/value/series/subtotal topology for +native read-back. Numeric cache values must be non-empty and finite, and cache +counts/indexes must be canonical non-negative decimal integers with exact, +contiguous topology; malformed, non-numeric, `NaN`, infinite, sparse, duplicate, +or mismatched caches fail closed. ChartEx style, axis, label, and binning details +outside the payload normalize. Full `AxisSpec`, arbitrary ChartEx families or +presentation fidelity, arbitrary stock variants, and axis/combo/date-axis +semantics outside the closed fields above remain fallback-only. The C4/C5 +import work does not expand the normalized SVG renderer and does not reduce +existing SVG-marker-to-native writer support. + +**Deferred chart types**: Exploded pie / doughnut variants, `map`, `heatmap`, +`bullet`, and `gantt` are intentionally outside the current native-object +support boundary. The exporter fails fast for these types until each mapping is +implemented and validated one by one. + +**Supported chart types**: + +- `column`, `bar`: `clustered`, `stacked`, or `percentStacked` (`grouping`) +- `line`: `standard`, `stacked`, or `percentStacked` (`grouping`); `line` or `lineMarker` (`line_style`, default `line` / no markers) +- `area`: `standard`, `stacked`, or `percentStacked` (`grouping`) +- `pie`: exactly one series, per-slice colors +- `doughnut`: exactly one series, per-slice colors +- `pieOfPie`, `barOfPie`: exactly one series, per-slice colors +- `radar`, `radarMarkers`, `radarFilled` +- `scatter`: `marker` (default), `lineMarker`, `line`, `smoothMarker`, or `smooth` (`scatter_style`) +- `bubble`: x/y/size series +- `combo`: `column`, `line`, and `area` plots, optional secondary value axis +- `treemap`, `sunburst`: hierarchical chartEx charts +- `histogram`, `pareto` +- `boxWhisker` +- `waterfall`, `funnel` +- `stock`: open / high / low / close series + +3D chart aliases (`3DColumn`, `3DBar`, `3DLine`, `3DArea`, `3DPie`, cone, +cylinder, pyramid variants, and `surface`) are unsupported. + +Native legends are opt-in through `show_legend: true`; `legend_position` +defaults to `bottom` and accepts `top`, `left`, or `right`. + +**Forbidden — replacement marker transforms**: Do not rotate, skew, or matrix-transform table/chart replacement groups. Translate / scale is accepted; complex transforms fail export because PowerPoint-native table/chart frames do not preserve arbitrary SVG transforms. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md index cb5a2474..bf128708 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/native-shape-authoring.md @@ -1,11 +1,11 @@ -> See [`shared-standards.md`](./shared-standards.md) §§1.4–1.5 for the native-shape metadata and validation contracts. +> See [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5 for the native-shape metadata and validation contracts. # Native Preset Shape Authoring Reference -Use this reference during Executor SVG construction when one standard -PowerPoint shape can express one complete geometric object. The helper does -not create the preset shape's own `p:txBody`; keep visible text outside the -atomic fragment. +Use this reference during Executor SVG construction or project-owned canonical +template maintenance when one standard PowerPoint shape can express one +complete geometric object. The helper does not create the preset shape's own +`p:txBody`; keep visible text outside the atomic fragment. ## 1. Selection Gate @@ -19,14 +19,15 @@ Apply this decision order before drawing a stock geometric object. | Condition | Action | |---|---| | Plain rectangle, symmetric rounded rectangle, circle, or ellipse | Write the ordinary SVG primitive; the exporter already emits an editable native shape. | -| One DrawingML preset exactly expresses the intended object | Run `preset_shape_svg.py render`, then insert its complete stdout fragment into the hand-authored page. | +| One DrawingML preset exactly expresses the intended object | Run `preset_shape_svg.py render`, then insert its complete stdout fragment into the hand-authored page or canonical template. | | The visual meaning or contour exceeds one stock shape | Write ordinary `` / `` geometry; export keeps it as editable custom geometry. | | The shape only resembles a preset | Keep ordinary SVG; never infer a preset from contour similarity. | | Mirror/preserve input already owns native-shape metadata | Keep the existing object and metadata; never reselect its preset. | **Hard rule**: `preset_shape_svg.py` is the only authoring entry for `data-pptx-authoring="preset"`. Never add `data-pptx-prst`, frame, adjustment, -carrier, preview, or fingerprint attributes to a hand-written path. +or registry path data by hand. Insert the helper's complete compact `` and +rerun the helper whenever its geometry or paint changes. --- @@ -45,7 +46,7 @@ paths or contours, or upgrade ordinary SVG during export. | Literal geometric body | `triangle`, `diamond`, `pentagon`, `hexagon`, `octagon`, `star5` | Use only when the named geometry itself is the intent. | | Solid block direction | `rightArrow`, `leftArrow`, `upArrow`, `downArrow`, `leftRightArrow`, `upDownArrow`, `chevron` | Thin relationship geometry remains an ordinary SVG `` / `` with no attachment semantics. | | Standard flowchart node | `flowChartProcess`, `flowChartDecision`, `flowChartInputOutput`, `flowChartTerminator`, `flowChartDocument` | Use only for an actual flowchart; ordinary content cards remain cards. | -| Standard connector route | `straightConnector1`, `bentConnector*`, `curvedConnector*` | The SVG route must match the selected preset; otherwise use a free path. | +| Explicit standalone connector | `straightConnector1`, `bentConnector*`, `curvedConnector*` | Use only when the user explicitly requests a PowerPoint Connector object. Diagram relationships otherwise stay ordinary SVG line/path shapes with no attachment semantics. | | Stock callout | `wedgeRectCallout`, `wedgeRoundRectCallout`, `wedgeEllipseCallout`, `cloudCallout` | Brand-specific or custom-tail callouts remain free SVG. | | Stock ribbon or scroll | `ribbon*`, `ellipseRibbon*`, `verticalScroll`, `horizontalScroll` | Select only when the stock contour is visually acceptable. | | Standalone math symbol | `mathPlus`, `mathMinus`, `mathMultiply`, `mathDivide`, `mathEqual`, `mathNotEqual` | Inline formulas and prose symbols remain text/formula assets. | @@ -58,6 +59,14 @@ python3 ${SKILL_DIR}/scripts/preset_shape_svg.py list --search arrow python3 ${SKILL_DIR}/scripts/preset_shape_svg.py describe rightArrow ``` +**Shape-first diagram rule**: chart-template adaptations use ordinary line/path +shapes for thin relationships and ordinary `shape` presets for solid block +directions. Connector-family presets are reserved for an explicit request for +a standalone PowerPoint Connector; they are not the default for architecture, +process, hierarchy, or framework diagrams and do not gain attachment semantics. +Existing Connector topology imported from a source PPTX remains owned by the +preserve/mirror round-trip contract. + **Forbidden — false native semantics**: - `actionButton*` when navigation or trigger behavior is expected; the helper @@ -69,8 +78,10 @@ python3 ${SKILL_DIR}/scripts/preset_shape_svg.py describe rightArrow ## 3. Fragment Generation -Run one command for one selected object. Colors must come from the current -page's re-read `spec_lock.md`. +Run one command for one selected object. Generated project pages take colors +from the current page-context projection of `spec_lock.md`; `create-template` takes colors +from the confirmed brief and template `design_spec.md`. Mirror/preserve input +keeps the source object's paint instead of regenerating this authored form. ```bash python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ @@ -81,7 +92,7 @@ python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \ --adjust "adj1=val 50000" ``` -For a native connector: +For an explicitly requested standalone native connector only: ```bash python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render bentConnector3 \ @@ -98,33 +109,52 @@ and a visible stroke. It exports as an unconnected `p:cxnSp`; a connector preset can never be authored as an ordinary `shape`. **Hard rule — stdout-only exception**: the helper prints one deterministic -`` fragment. Read that output and insert it with the normal page -`apply_patch` edit. Do not redirect it into `svg_output/`, loop over pages, -batch shapes, or let it choose layout. The main Agent still authors every -complete SVG page sequentially. +`` fragment. Read that output and insert it with the normal page/template +`apply_patch` edit. Do not redirect it into `svg_output/`, loop over pages or +templates, batch shapes, or let it choose layout. The main Agent still authors +every complete SVG page sequentially and maintains each reusable template +explicitly. --- ## 4. Atomic Fragment Contract -The helper emits one logical group containing exactly one hidden native carrier -and one complete visible preview. +The helper emits one compact logical group. Metadata and base paint are written +once on the group; its direct children are the visible paths regenerated from +the locked preset registry. | Component | Ownership | |---|---| -| Logical `` | Stable id, object kind, preset, frame, adjustments, and preview fingerprint. | -| `path[data-pptx-part="geometry"]` | Native PowerPoint export authority; hidden from the browser. | -| `g[data-pptx-part="geometry-preview"]` | Browser-visible preset drawing. | -| `path[data-pptx-part="geometry-detail"]` | One visible layer per DrawingML path, including path-level fill/stroke behavior. | +| Logical `` | Stable id, object kind, preset, frame, adjustments, and explicit local base paint. | +| Direct `` children | Ordered browser-visible registry layers. A child writes only a path-specific fill/stroke override when the preset requires one. | +| Deliberately absent transport fields | No hidden carrier, preview wrapper, `data-pptx-part`, or stored fingerprint belongs in project-authored SVG. Those fields remain part of expanded PPTX import/round-trip transport. | -**Hard rule**: treat the returned group as atomic. Put labels, icons, or other -decorations beside it in a parent ``, never inside the preset group. +**Hard rule**: treat the returned group as atomic. Keep it as the content group +when it stands alone. When it needs labels, icons, or other decorations, put +the preset and those siblings in a separate parent content group; never put +them inside the preset group itself. Do not edit the direct paths; they are +validation evidence generated from the registry, not a freehand contour +surface. + +Canonical page/template authoring also keeps paint and opacity off ancestor +groups that contain the preset. Compatible ancestor paint still exports under +the general SVG composition rules, but the checker warns because the atom is no +longer paint-self-contained; rerun the helper with channel alpha instead. + +On a structured template, a validated authored-preset group is one semantic +atom. It may be Slide-local, the single carrier of an `object` slot, or a direct +Master/Layout fixed atom. This narrow exception does not permit ordinary nested +`` structures in Master/Layout layers or placeholder carriers. The template +workflow may add the registered structural ownership attributes to the complete +helper group; it still must not alter preset metadata, paint, or direct paths. **Frame coordinate space**: `--frame x y w h` is expressed in the coordinate space where you insert the fragment. At the page root that is page coordinates; inside a `` use **group-local** coordinates — the ancestor transform stacks on top, so page-absolute values would double-offset -the shape off-canvas. +the shape off-canvas. Keep the helper's exact space-separated ordinary-decimal +`data-pptx-frame` spelling; compact authoring does not accept alternate numeric +spellings. **Regeneration rule**: rerun the helper when preset, frame, adjustment, fill, stroke, or stroke width changes. Moving, scaling, rotating, or flipping the @@ -132,7 +162,12 @@ complete logical group is allowed; zero-scale transforms and shear/skew are forbidden, and the transformed frame must remain inside DrawingML's coordinate range. Stroke width must remain inside DrawingML's line-width range. To freely edit the contour, replace the whole fragment with ordinary SVG rather than -modifying a `geometry-detail` path. +modifying a generated direct path. + +For a canonical reusable template, the complete helper fragment may remain as +an executable exemplar. A final-page adaptation may copy it unchanged only +when all registry metadata, frame, adjustments, and paint remain unchanged; +otherwise regenerate the complete compact group. --- @@ -144,9 +179,13 @@ modifying a `geometry-detail` path. | Connector attachment | Authoring helper v1 creates an unconnected `p:cxnSp` and does not accept endpoint/site metadata. Do not hand-add it. The imported-shape contract may preserve an attachment that already exists in a source PPTX; creating a new attached connector is currently unsupported. | | Action button behavior | `actionButton*` presets map visual geometry only. No action, navigation target, or hyperlink is created automatically. | | Gradient/pattern paint | Authoring helper v1 accepts solid HEX paint only. Use ordinary SVG when a complex paint treatment is essential. | -| Multi-path darken/lighten | Browser preview uses the shared normalized paint behavior from the PPTX importer. | -| External edits | Any preview or semantic mismatch fails quality check and export; regenerate the fragment. | +| Multi-path darken/lighten | Direct visible layers use the shared normalized paint behavior from the PPTX importer. Their registry-derived HEX values are authorized derivatives of the locked base color, not spec-lock drift. | +| Expanded compatibility | Existing helper-authored carrier/preview fragments remain readable as ordinary Slide-local input and receive a non-blocking migration warning; they do not become structured fixed atoms or object-slot carriers. Imported expanded fragments remain the lossless mirror/preserve form. | +| External edits | Any registry-path, style, or semantic mismatch fails quality check and export; regenerate the fragment. | -**Validation**: `svg_quality_checker.py` independently rerenders every authored -preset from registry metadata and compares the carrier, visible layers, style, -and fingerprint before export. +**Validation**: `svg_quality_checker.py` independently rerenders every compact +authored preset from registry metadata and compares its direct visible paths +and paint. The exporter performs the same validation, then expands the compact +group only in memory to reuse the lossless native-shape conversion path. +Compatible expanded authored input remains under its separate carrier/preview +freshness contract. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md new file mode 100644 index 00000000..70a38091 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/pptx-structure-interface.md @@ -0,0 +1,195 @@ +> See [`shared-standards-core.md`](./shared-standards-core.md) for the mandatory SVG foundation. + +# PPTX Structure Interface + +Conditional interface for PowerPoint Master, Layout, fixed-layer, and placeholder authoring. Load only when `spec_lock.md pptx_structure.mode` is `structured`. + +**Cross-reference map**: unqualified §1.5 and §4.2 references point to [`shared-standards-core.md`](./shared-standards-core.md); this file's own sections are §1–§3. + +## 1. PPTX Structure Routing + +Every new SVG project declares one deterministic route. Free-design, brand-only, and `template_reuse_scope: style` projects use `pptx_structure.mode: flat`, omit `pptx_masters` / `pptx_layouts` / `page_pptx_layouts` / `page_layouts`, and author no Master/Layout/layer/placeholder metadata. Export keeps all represented content Slide-local while materializing one clean project-owned Master plus one Blank Layout from the current color/typography lock; stock content placeholders and unused built-in Layouts are removed, while the standard date/footer/slide-number capability hooks remain. Deck/layout template projects whose AI-derived lock records `template_reuse_scope: mirror|layout` use `mode: structured`; `standard` / `fidelity` templates use their authored contract, while mirror templates use the validated source identities and parentage declared by the newly materialized workspace. + +**Hard rule — no structure inference**: Flat export performs no promotion or deduplication; every object stays Slide-local. Structured template export compiles only declared root identities, atomic fixed layers, and slot groups—it does not assign Layout families, cluster pages, infer placeholders, repair missing metadata, or migrate legacy contracts. Create a new current workspace through [`create-template`](../workflows/create-template.md) before generating structured pages. + +**Layout reuse**: Reuse one Layout key only when its ordered fixed Layout atoms and slot ids/types/effective indices/default bounds/binding modes are identical. Different wording, data, imagery, crop, or Slide-local carrier geometry does not create a new Layout. A genuinely different reusable contract gets a new key even when both pages are semantically `content`. + +**Zero-slot Layout**: A named Layout may contain no slots and no fixed Layout atoms. This is valid for a cover, poster, full-visual page, or other fixed composition. Do not manufacture an empty `utility` kind or full-page fake `object` slot. + +**Adaptive change**: Template `strict` preserves the selected prototype contract. `adaptive` retains the prototype Master and may create a new Layout identity only when fixed Layout atoms or slot topology/bounds change. Update the page mapping immediately while authoring the first such page; never mutate a reused key silently. + +## 2. Explicit PPTX Master / Layout / Placeholder Metadata + +**Trigger**: This explicit metadata interface applies only to new pages generated from a current deck/layout template workspace with `template_reuse_scope: mirror|layout`. `spec_lock.md` declares `pptx_structure.mode: structured`, complete unique `pptx_masters` / `pptx_layouts` rosters, one `page_pptx_layouts` assignment per generated page, and `page_layouts` as authoring-prototype provenance. `template_reuse_scope: style`, free-design, and brand-only SVGs use `mode: flat` and none of these metadata fields. + +**Project lock**: A Master row is `: `. A unique Layout row is `: | | `, where the source is a generated `P` or installed `template:`. A page assignment is `P: ` under `page_pptx_layouts`. The SVG root values MUST match the assigned definition. A Layout key belongs to exactly one Master and must be globally unique. Reuse one key only when prototypes share identical ordered Layout atoms and slot ids/types/effective indices/default bounds/binding modes. An unused Layout uses a template SVG source and remains registered without a published carrier slide. Every structured route requires numeric `spec_lock.md` typography `title` / `body` rows. + +**Template behavior**: Strict preserves the selected prototype's declared Master/Layout/slot contract. Adaptive retains its Master and may allocate a new Layout key/name only when fixed Layout atoms or slot topology/bounds change; update the lock during authoring. Mirror-created prototypes preserve validated source identity, literal paint, typography, effects, atomic geometry, and referenced assets in a new workspace. `standard` / `fidelity` never make source topology authoritative; mirror does not synthesize a replacement topology or fill missing facts. + +Imported inherited-shape visibility remains an immutable analysis fact until a +structured mirror is materialized. The final mirror root carries that fact with +the two optional canonical booleans below so export can write the preserved source +package fields without inferring visibility from which shapes happen to be +present. Authored `standard` / `fidelity` templates normally omit both and use +the default `true`. See +[`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary). + +**Master text-style contract**: Flat and structured export map the +locked `title` size to every `a:defRPr` in Master `p:titleStyle`. Level 1 in +both `p:bodyStyle` and `p:otherStyle` uses the locked `body` size; levels 2–9 +use a deterministic descending hierarchy from `15/16` through `8/16` of that +size, rounded to 0.5 pt and floored at the smaller of 8 pt or the body size. +Existing per-level indentation and bullet properties remain unchanged. + +| Master style | Locked source | XML field changed | +|---|---|---| +| `p:titleStyle` | `typography.title` | Every `a:defRPr@sz` | +| `p:bodyStyle` | `typography.body` | Level 1 plus derived level 2–9 `a:defRPr@sz` | +| `p:otherStyle` | `typography.body` | Level 1 plus derived level 2–9 `a:defRPr@sz` | + +**Hard rule — narrow scope**: This Master update changes only Master +`p:txStyles//a:defRPr@sz`; it preserves level indentation, bullet, margin, and +paragraph settings. It does not rewrite direct run sizes on generated slides, +so the initial slide rendering remains controlled by the authored SVG. Missing +`title` or `body` rows fail flat or structured export. + +**Layout level-one text-default contract**: For every text-bearing placeholder +whose first prototype run has a direct `a:rPr@sz`, explicit Layout export copies that +size to the generated Layout prompt run and +`p:txBody/a:lstStyle/a:lvl1pPr/a:defRPr@sz`. It does not rewrite Slide direct +runs or Layout levels 2–9. This preserves the layout-specific size when +level-one placeholder text is inserted or reset; placeholders without a direct +prototype size remain unchanged. + +| Metadata | Placement | Behavior | +|---|---|---| +| `data-pptx-master="master-default"` | root `` | Binds the slide to one generated Slide Master key | +| `data-pptx-master-name="Default Master"` | root `` | Sets the Master picker/display name | +| `data-pptx-layout="content"` | root `` | Binds the slide to one generated reusable layout key | +| `data-pptx-layout-name="Title and Content"` | root `` | Sets the PowerPoint layout-picker name; defaults from the layout key | +| `data-pptx-show-master-shapes="false"` | root `` | Accepts exact lowercase `true` or `false` and writes the assigned Layout's `p:sldLayout@showMasterSp`; every SVG using the same Layout key must repeat the same value; omission means `true` | +| `data-pptx-show-inherited-shapes="false"` | root `` | Accepts exact lowercase `true` or `false` and writes this Slide's `p:sld@showMasterSp`; `false` hides inherited Layout and Master shapes without removing backgrounds, placeholders, parts, or parent relationships; omission means `true` | +| `data-pptx-layer="master"` | direct semantic atom | Moves one repeated static object/background into the named Slide Master; ordinary `` is forbidden, while one validated compact authored-preset `` (§1.5) is an atomic exception | +| `data-pptx-layer="layout"` | direct semantic atom | Moves one repeated static object/background into the selected Layout; ordinary `` is forbidden, while one validated compact authored-preset `` (§1.5) is an atomic exception | +| `data-pptx-layer="slide"` | direct full-canvas solid `` only | Writes a one-page override as Slide `p:bg` | +| `data-pptx-placeholder="..."` | direct slot `` | Declares a reusable Layout slot whose visible content remains Slide-local | +| `data-pptx-bounds="x y width height"` | slot `` | Supplies the positive reusable design-zone frame in SVG user units with at most two decimals per value | +| `data-pptx-idx="1"` | slot `` | Retains an imported source Layout placeholder index; optional for reconstructed layouts | +| `data-pptx-carrier="true"` | one compatible direct child of a normal slot | Binds that visible child as the real Slide placeholder carrier | +| `data-pptx-binding="proxy"` | composite `object` slot `` only | Keeps the visible group ordinary and creates one hidden transparent binding proxy | +| `data-pptx-editable="false"` | master/layout element or slide background | Declares intentional editing outside ordinary slide content | + +**Hard rule — explicit only**: On a structured `template_reuse_scope: mirror|layout` route, every SVG requires the four root Master/Layout identity attributes. Optional inherited-shape visibility uses only exact lowercase `true` / `false`; other spellings fail, and omission means `true`. Every Master/Layout atom and slot requires a unique stable `id` and is a direct root child. Layouts with zero slots are valid. `data-pptx-layout-kind`, `distilled`, and `utility` are legacy metadata and fail the structured contract. Flat `template_reuse_scope: style`, free-design, and brand-only pages omit the structural markers and visibility attributes; ordinary groups still use the shared `data-pptx-bounds` module contract. + +**Layer order**: Author the SVG in PowerPoint paint order: Master background, +Layout background, optional Slide background, remaining Master atoms, remaining Layout atoms, +then slot groups and Slide-local content groups. Backgrounds are a special inheritance +plane beneath every shape; this order keeps standalone SVG preview and +PowerPoint rendering aligned. The exporter rejects interleaved layers. + +**Solid background ownership**: Structured export deliberately narrows scoped +background ownership to a direct full-canvas solid `` and disables the +generic conversion-level promotion described in §4.2. Mark the solid rect +`data-pptx-layer="master"` for the deck-wide default, +`data-pptx-layer="layout"` for a page-type override, or +`data-pptx-layer="slide"` for a one-slide override. An unmarked direct +full-canvas solid rect in the background plane is also treated as Slide scope. +A Layout background overrides the Master background; a Slide background +overrides both. Use the Master for a globally stable color and the Layout for +cover/section/content variants under the same design language. Gradient and +preset-pattern rects remain ordinary shapes on declared Master/Layout layers +or as Slide-local content; images remain pictures. Textures, transformed rects, +and visible-stroke rects also remain ordinary objects. + +| Placeholder value | Direct carrier inside slot `` | PowerPoint placeholder | +|---|---|---| +| `title`, `subtitle`, `body` | one `` | `title`, `subTitle`, `body` | +| `date`, `footer`, `slide-number` | one `` | `dt`, `ftr`, `sldNum` | +| `picture` | one `` or supported imported crop ``, marked as carrier | `pic` | +| `chart`, `table` | one matching `data-pptx-replace-with` marker group, marked as carrier | `chart`, `tbl` | +| `object` | one text, image, basic SVG shape, or validated compact authored-preset `` marked as carrier; alternatively the slot group declares `binding="proxy"` | `obj` | +| `media` | one `` or supported imported crop ``, marked as carrier | `media` | + +**Text slot carrier**: A multiline text placeholder must remain one +native text frame. Use the default paragraph merge; `--no-merge` cannot supply +several line shapes as one +PowerPoint placeholder prototype/binding. Leave strict-line text Slide-local +when separate frames are the required result. + +For a materialized mirror, an imported text carrier may additionally keep the +source shape's positive `data-pptx-frame="x y width height"`. That frame owns +the Slide carrier `a:xfrm`; the converter reconstructs text-body insets from the +visible SVG anchor/baseline instead of shrinking the shape to glyph bounds. +`data-pptx-bounds` remains the reusable Layout default and may +legitimately differ. Do not add `data-pptx-frame` to an authored +`standard` / `fidelity` carrier merely to duplicate its Layout bounds. + +**Blank text carrier**: Leave a marked text carrier empty or whitespace-only +when the placeholder must remain visually blank. Export materializes one +invisible U+200B run so the carrier still becomes a native PowerPoint text +shape. Do not insert a dummy dash, shrink text below the DrawingML 1pt minimum, +or hide a visible glyph with opacity/background paint; those workarounds either +leak content or produce a PPTX that PowerPoint repairs. + +`title` is normally type-matched without an index in reconstructed layouts; if +an imported source title explicitly has one, preserve that exact index. Every +indexed placeholder on one layout uses a unique OOXML UInt32 index. Structured export writes the semantic type on both the Layout and Slide carrier (except `obj`, whose OOXML default is already `obj`) so PowerPoint and `python-pptx` retain the same identity. A composite object slot instead keeps its visible group ordinary and uses a hidden transparent proxy. +Date, footer, and slide-number placeholders enable their matching Layout `p:hf` +flags; a date placeholder also gets a `datetimeFigureOut` field in the reusable +Layout definition. The current Slide keeps its authored date content. + +Because an omitted `p:ph@idx` has the effective value `0`, an omitted-index +title reserves `0`; no other placeholder on that Layout may use the same +effective index. + +**Slot prototype**: The prototype source declared by the unique Layout definition supplies that Layout's placeholder formatting. `data-pptx-bounds` supplies the reusable default frame and is mandatory on every slot. Derive it from +the intended design zone, column, panel inset, safe area, or picture frame — +never from text length, glyph width, line count, or a tight content bounding +box. Repeat the same slot ids/types/effective indices/default bounds/binding modes on every slide using that Layout. The Layout owns the reusable `p:ph`; normal visible carriers keep a matching Slide binding so approved rendering stays identical. A composite `object` proxy adds one hidden transparent binding shape to suppress empty inherited placeholder paint. Bounds define the Layout default only; actual Slide content and local carrier geometry may differ. + +**Final-package read-back gate**: After writing a temporary structured PPTX and before publishing it, export reopens the package and +verifies that each published Slide targets exactly one Layout, one Layout key always resolves to the +same part, different keys do not collapse onto one part, and every declared Layout—including one unused by all published Slides—is +registered through its Master and the Presentation. Physical Slide/Layout/ +Master part rosters, their content-type overrides, and their Presentation/ +Master registrations must be exact. It also verifies the Layout picker name, +Master picker identity, placeholder type and effective index, matching `p:hf` flags, explicit design-zone frame, direct prompt size, and level-one default size. +Every owned `p:bg` is checked as an exact zero-or-one payload against the pre- +promotion result; this includes preserving the base Master background when no +authored Master background replaces it. During the same export, every finished +Slide, Layout, and Master must reproduce its exact top-level shape-name roster +and order after packaging. The gate verifies that each carrier-bound slot owns the expected Slide binding, each composite visible carrier remains ordinary, and every composite binding proxy is hidden. A zero-slot Layout must read back with no placeholder. Later slides may keep different Slide-local geometry; only the reusable +Layout frame is checked against the explicit/prototype contract. Any mismatch +fails export without replacing the requested output. + +**Static structure consistency**: Repeat the same master element ids on every +slide and the same layout element ids on every slide sharing a layout. Their +generated OOXML must be identical within the affected master/layout group. +Static structure may carry shapes, text, or images; non-image/external +relationships are rejected. Every static object is atomic. An ordinary +`` is forbidden; the validated compact +authored-preset group from §1.5 is the sole group exception because it compiles +to one native object. A full-canvas first rect may be marked as a Master or +Layout background. + +**Native object slot carriers**: `chart` / `table` slots require +`--native-charts-and-tables`; fallback groups contain several shapes and cannot map to one +PowerPoint placeholder. `object` is the generic PowerPoint content slot and +uses either one carrier object—including one validated compact authored-preset +group—or the explicit composite proxy downgrade. `media` currently binds +an authored image/crop to a native `media` placeholder; it does not synthesize +video or audio media from a decorative SVG group. + +## 3. Legacy Template Input Boundary + +Existing structured/template projects or packages that carry `native_structure.json` / `source_template.pptx`, `pptx_structure.mode: baseline|template|preserve`, `layout_strategy`, `data-pptx-layout-kind`, `distilled` / `utility`, direct atomic placeholders, or an incomplete root Master identity are not generation/export inputs and are never upgraded in place. Create a separate current workspace through [`create-template`](../workflows/create-template.md). A project explicitly declaring `pptx_structure.mode: flat` is the current free-design/brand-only route and needs no conversion merely because it has no Master/Layout metadata. + +| Available source | Allowed create-template behavior | +|---|---| +| Original PPTX Type A | `standard` / `fidelity` author new topology; `mirror` preserves supported Master/Layout/placeholder facts that still exist in the package | +| Legacy or unstructured SVG Type B | `standard` / `fidelity` use pages as visual/contextual reference and author a complete new contract; old metadata is not output topology | +| Complete current SVG Type B | `mirror` may preserve the explicit current contract in a new workspace; authored modes may replace it | + +Without an original PPTX or complete current Type B contract, do not claim mirror or source-topology recovery. After template creation, Generate PPTX Step 3 authors new structured `svg_output/` pages; the exporter only compiles those declarations and never derives, repairs, or migrates structure. + +--- diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md index 8e1ae683..d34543df 100644 --- a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/semantic-svg.md @@ -6,6 +6,7 @@ PPT Master uses rendering-neutral compiler hints only where ordinary SVG cannot | Marker | Placement | Purpose | |---|---|---| +| `data-pptx-page-role` | Root `` on flat pages only | Classify a free-design/brand-only page as `cover`, `toc`, `section`, `content`, or `ending`. | | `data-pptx-master` / `data-pptx-master-name` | Root `` | Bind the page to one named PowerPoint Slide Master. | | `data-pptx-layout` / `data-pptx-layout-name` | Root `` | Bind the page to one named Layout under that Master. | | `data-pptx-layer="master"` | Direct atomic child of root | Promote one fixed visual object to the named Master. | @@ -15,15 +16,15 @@ PPT Master uses rendering-neutral compiler hints only where ordinary SVG cannot The completed SVG remains the full visible page. Removing the metadata must not change browser rendering. Do not copy visible text, geometry, style, or asset values into metadata. -**Hard rule — route boundary**: Free-design and brand-only pages use `pptx_structure.mode: flat` and omit every Master/Layout/layer/placeholder marker in this document. Deck/layout template pages declare their final Master and Layout before drawing begins; the structured exporter compiles that contract and never selects, clusters, distills, or visually infers it. +**Hard rule — route boundary**: Free-design, brand-only, and `template_reuse_scope: style` pages use `pptx_structure.mode: flat`, declare one canonical root `data-pptx-page-role`, and omit every Master/Layout/layer/placeholder marker in this document. Only deck/layout template pages whose AI-derived lock records `template_reuse_scope: mirror|layout` declare their final Master and Layout before drawing begins and omit `data-pptx-page-role`; the structured exporter compiles that contract and never selects, clusters, distills, or visually infers it. -**Hard rule — specialized metadata wins**: Use Master/Layout/placeholder metadata for native structure, `data-pptx-native` for chart/table reconstruction, and the imported/authored shape metadata defined in [`shared-standards.md`](./shared-standards.md) §§1.4–1.5. Do not duplicate those facts with `data-pptx-role`. +**Hard rule — specialized metadata wins**: Use Master/Layout/placeholder metadata for native structure, `data-pptx-replace-with` for optional PowerPoint-native Chart/Table replacement, and the imported/authored shape metadata defined in [`shared-standards-core.md`](./shared-standards-core.md) §§1.4–1.5. Do not duplicate those facts with `data-pptx-role`. --- ## 2. Master and Layout Atoms -On structured deck/layout template routes, Master and fixed Layout visuals are atomic root children: +On structured `template_reuse_scope: mirror|layout` routes, Master and fixed Layout visuals are atomic root children: ```xml + data-pptx-bounds="72 48 1136 72"> Actual title ``` @@ -70,12 +71,12 @@ Use one direct root group as the authoring boundary and one compatible direct ch | Requirement | Rule | |---|---| | Placement | The slot `` is a direct root child. Structural metadata may not be nested below it. | -| Bounds | `data-pptx-placeholder-bounds="x y width height"` is mandatory, finite, and positive. It describes the reusable design zone, not the current glyph/content tight bounds. | -| Carrier | The group contains exactly one compatible direct drawable child marked `data-pptx-placeholder-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. | -| Identity | `data-pptx-placeholder-idx` is optional; effective indices must be unique within one Layout. Preserve a source index when reconstructing an existing PPTX. | +| Bounds | `data-pptx-bounds="x y width height"` is mandatory, finite, and positive. It describes the reusable design zone, not the current glyph/content tight bounds. | +| Carrier | The group contains exactly one compatible direct drawable child marked `data-pptx-carrier="true"`. Export unwraps that child into the real Slide placeholder binding. | +| Identity | `data-pptx-idx` is optional; effective indices must be unique within one Layout. Preserve a source index when reconstructing an existing PPTX. | | Fixed decoration | Reusable decoration does not belong in the slot. Author it as a root Layout atom. Page-specific labels/captions use another slot or remain Slide-local. | -Canonical placeholder values are `title`, `subtitle`, `body`, `picture`, `chart`, `table`, `object`, `media`, `date`, `footer`, and `slide-number`. Carrier compatibility is defined in [`shared-standards.md`](./shared-standards.md) §7. +Canonical placeholder values are `title`, `subtitle`, `body`, `picture`, `chart`, `table`, `object`, `media`, `date`, `footer`, and `slide-number`. Carrier compatibility is defined in [`pptx-structure-interface.md`](./pptx-structure-interface.md) §2. ### 3.2 Explicit composite proxy @@ -84,8 +85,8 @@ When one reusable region is a composite object that cannot bind to one real Powe ```xml + data-pptx-binding="proxy" + data-pptx-bounds="544 160 664 472"> Visible composite content @@ -116,11 +117,11 @@ Do not add structural roles to ordinary titles, body copy, cards, KPIs, diagrams ## 5. Validation and Migration -For structured deck/layout template projects, validation rejects: +For structured `template_reuse_scope: mirror|layout` projects, validation rejects: - a missing root Master/Layout identity or a page-to-lock mismatch; - a Master/Layout ``, nested structure marker, missing/stale id, or inconsistent shared atom contract; - a slot without positive bounds, a carrier-bound slot without exactly one compatible carrier, or a proxy binding on a non-`object` slot; - incomplete page mappings, cross-Master Layout-key reuse, or conflicting same-key Layout contracts. -Legacy structured/template SVGs using unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`, `utility`, direct atomic placeholders, or an incomplete Master identity are not a second supported structured contract. Run [`restore-pptx-structure`](../workflows/restore-pptx-structure.md) before generation or export. An explicit `mode: flat` free-design/brand-only project is current and intentionally has no Master identity. When original PPTX/native facts exist, migration restores those identities first; otherwise the main Agent explicitly derives structured template metadata. Export never performs that derivation. +Legacy structured/template SVGs using unmapped `baseline`, `preserve`, `layout_strategy: distill`, `data-pptx-layout-kind`, `distilled`, `utility`, direct atomic placeholders, or an incomplete Master identity are not a second supported structured contract. Create a new workspace through [`create-template`](../workflows/create-template.md) before generation or export. An explicit `mode: flat` free-design/brand-only project is current and intentionally has no Master identity. Original PPTX Type A may preserve native identities that still exist in the package; legacy SVG-only Type B may guide `standard` / `fidelity` visually but does not authorize topology recovery. Export never derives, repairs, or migrates structure. diff --git a/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md new file mode 100644 index 00000000..4a6603a6 --- /dev/null +++ b/plugins/codex/plugins/ppt-master/skills/ppt-master/references/shared-standards-core.md @@ -0,0 +1,642 @@ +# Shared SVG Core Standards + +Mandatory reference for every route that authors or regenerates slide visuals through SVG. It owns XML validity, the closed generated-authoring surface, basic converter compatibility, page closure, semantic grouping, and shared fidelity vocabulary. + +**Conditional module routing**: + +| Trigger | Load | +|---|---| +| Noncanonical/alpha paint, advanced line or text treatment, gradient/filter/effect, transform, freeform/radial geometry, or constructed style | [`svg-effects.md`](./svg-effects.md) | +| A page will use a preset pattern fill or evaluate native chart/table replacement | [`native-data-interface.md`](./native-data-interface.md) before deciding eligibility or emitting metadata | +| `pptx_structure.mode: structured` | [`pptx-structure-interface.md`](./pptx-structure-interface.md) | + +**Fidelity labels**: + +| Label | Meaning | +|---|---| +| `Native-stable` | Generated PPTX uses the corresponding native DrawingML property or object and retains the documented semantics within the technique-specific limits. | +| `Native-normalized` | Export targets an editable DrawingML equivalent, but normalizes the SVG into another structure such as a freeform, run property, or simplified paint/effect. | +| `Approximate` | DrawingML has no exact SVG equivalent; export targets the intended effect through a documented approximation, and material differences require output review. | +| `Bake-required` | The runtime effect is outside the native contract; pre-render it into an image or rebuild it with explicit supported geometry. | + +**Reading rules**: + +- **Required** / **Forbidden** statements are non-negotiable technical boundaries. +- **Conditional** contracts apply only when the corresponding feature is used. +- **Reference — not a constraint** passages expose capabilities and recipes; they do not require every page or visual style to use them. +- The locked `visual_style` controls whether and how strongly a compatible effect is used. It never expands the technical boundary. + +**Hard rule — generated authoring is fail-closed**: `svg_output/` and reusable +template SVGs may use only properties and conditional interfaces explicitly +listed in this file or a triggered module in the routing table above. `svg_quality_checker.py` rejects unknown inline visual +properties and conditional contracts that have no reliable compatibility +mapping; documented fallback forms remain valid and receive warnings. + +**Default — recommended authoring and supported input stay separate (may +preserve supported input)**: generated SVG uses one predictable default +spelling, while converter-supported equivalent spellings remain valid input. +The checker may recommend normalization, but such warnings do not require +modification or block export. Only invalid, unsafe, or unreliably convertible +input is an error; do not remove converter support to enforce a narrower +generation preference. + +**Hard rule — one-way fidelity vocabulary**: the labels above describe the +`svg_output/` → generated PPTX path. They do not promise reconstruction of the +original SVG syntax, `` graph, `` structure, path commands, or +`` layout after PPTX-to-SVG import, nor pixel identity across PowerPoint, +LibreOffice, Keynote, and WPS. + +**Hard rule — capability boundary**: a recipe never expands converter support. +Use only the target elements and syntax documented by each conditional +contract. Unsupported element tags fail preflight; browser-rendered attributes +outside these contracts must not be assumed to have a DrawingML mapping. + +--- + + +## 1. Required Foundation, Forbidden Features, and Conditional Interfaces + +### 1.0 Text characters: must be well-formed XML + +SVG is strict XML. Two rules for all text and attribute values: + +| Character category | Required form | Forbidden form | +|---|---|---| +| Typography & symbols (em dash, en dash, ©, ®, →, ·, NBSP, full-width punctuation, emoji…) | **Raw Unicode characters** — write `—` `–` `©` `®` `→` directly | HTML named entities — `—` `–` `©` `®` `→` `·` ` ` `…` `•` etc. | +| XML reserved characters (`&`, `<`, `>`, `"`, `'`) | **XML entities only** — `&` `<` `>` `"` `'` (e.g. `R&D`, `error < 5%`) | Bare `&` `<` `>` (e.g. `R&D`, `error < 5%`) | + +One offending character invalidates the file and aborts export. + +**Structural blacklist** (in addition to the character rules above): + +| Banned Feature | Description | +|----------------|-------------| +| `mask` | Masks | +| `