minimal-agent 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -8
- package/package.json +34 -1
- package/plugins/cron-runner/.claude-plugin/plugin.json +5 -0
- package/plugins/cron-runner/commands/cron.md +26 -0
- package/plugins/cron-runner/commands/crons.md +7 -0
- package/plugins/cron-runner/plugin.js +34 -0
- package/plugins/cron-runner/src/commands.js +348 -0
- package/plugins/cron-runner/src/cronTime.js +148 -0
- package/plugins/cron-runner/src/lock.js +68 -0
- package/plugins/cron-runner/src/runs.js +89 -0
- package/plugins/cron-runner/src/scheduleEngine.js +72 -0
- package/plugins/cron-runner/src/scheduler.js +355 -0
- package/plugins/cron-runner/src/schema.js +140 -0
- package/plugins/cron-runner/src/service.js +167 -0
- package/plugins/cron-runner/src/store.js +298 -0
- package/plugins/cron-runner/src/types.js +1 -0
- package/plugins/workflow-runner/commands/workflow.md +4 -4
- package/plugins/workflow-runner/commands/workflows.md +1 -1
- package/plugins/workflow-runner/plugin.js +2 -1
- package/plugins/workflow-runner/src/agentCommon.js +172 -9
- package/plugins/workflow-runner/src/dslManifest.js +72 -0
- package/plugins/workflow-runner/src/expressions.js +150 -13
- package/plugins/workflow-runner/src/index.js +39 -8
- package/plugins/workflow-runner/src/loader.js +216 -64
- package/plugins/workflow-runner/src/multimodal.js +37 -0
- package/plugins/workflow-runner/src/recovery.js +26 -24
- package/plugins/workflow-runner/src/runner.js +693 -287
- package/plugins/workflow-runner/src/stepExecutors/agent.js +126 -37
- package/plugins/workflow-runner/src/stepExecutors/assert.js +3 -2
- package/plugins/workflow-runner/src/stepExecutors/llm.js +38 -30
- package/plugins/workflow-runner/src/stepExecutors/skill.js +27 -38
- package/plugins/workflow-runner/src/stepExecutors/tool.js +56 -3
- package/plugins/workflow-runner/src/stepExecutors/verify.js +19 -10
- package/plugins/workflow-runner/src/taskIdentity.js +185 -30
- package/plugins/workflow-runner/src/types.js +18 -7
- package/plugins/workflow-runner/src/workflowState.js +355 -55
- package/skills/ai-image/SKILL.md +89 -0
- package/skills/ai-image/scripts/generate.mjs +497 -0
- package/skills/ai-image/scripts/generate_from_plan.mjs +469 -0
- package/skills/ai-image/scripts/generate_from_plan_test.mjs +223 -0
- package/skills/ai-image/scripts/generate_test.mjs +74 -0
- package/skills/browser-automation/SKILL.md +47 -0
- package/skills/docx/SKILL.md +25 -3
- package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
- package/skills/docx/scripts/opc_check.py +253 -0
- package/skills/image-gen-openrouter/SKILL.md +10 -2
- package/skills/image-stats/SKILL.md +65 -0
- package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/image_stats.py +368 -0
- package/skills/image-stats/scripts/image_stats_test.py +181 -0
- package/skills/pptx/SKILL.md +123 -95
- package/skills/pptx/design.md +82 -0
- package/skills/pptx/examples/README.md +29 -0
- package/skills/pptx/examples/hybrid_example.mjs +107 -0
- package/skills/pptx/examples/hybrid_example.pptx +0 -0
- package/skills/pptx/pptxgenjs.md +41 -0
- package/skills/pptx/scripts/deck_helpers.mjs +224 -0
- package/skills/pptx/scripts/layout_lint.py +293 -0
- package/skills/pptx/scripts/layout_lint_test.py +160 -0
- package/skills/pptx/scripts/opc_check.py +339 -0
- package/skills/pptx/scripts/svg_fallback.mjs +145 -0
- package/skills/pptx/svg.md +67 -0
- package/skills/tts-zh/SKILL.md +19 -2
- package/skills/ui-design/SKILL.md +158 -0
- package/skills/ui-design/claude_design.md +309 -0
- package/skills/ui-design/evals/evals.json +254 -0
- package/skills/ui-design/references/aesthetic-direction.md +83 -0
- package/skills/ui-design/references/claude-design-protocol.md +36 -0
- package/skills/ui-design/references/design-context.md +53 -0
- package/skills/ui-design/references/design-execution-playbook.md +82 -0
- package/skills/ui-design/references/export-pptx.md +124 -0
- package/skills/ui-design/references/layout-composition.md +654 -0
- package/skills/ui-design/references/preview-feedback.md +37 -0
- package/skills/ui-design/references/source-image-layout.md +189 -0
- package/skills/ui-design/references/starter-components.md +78 -0
- package/skills/ui-design/references/vi-aegis-vector.md +144 -0
- package/skills/ui-design/references/vi-amber-prism.md +133 -0
- package/skills/ui-design/references/vi-aqua-glass.md +200 -0
- package/skills/ui-design/references/vi-comfort-vision.md +147 -0
- package/skills/ui-design/references/vi-ember-prism.md +140 -0
- package/skills/ui-design/references/vi-nebula-console.md +151 -0
- package/skills/ui-design/references/vi-obsidian-optics.md +139 -0
- package/skills/ui-design/references/vi-obsidian-xui.md +143 -0
- package/skills/ui-design/references/vi-precision-horizon-dark.md +117 -0
- package/skills/ui-design/references/vi-precision-horizon.md +215 -0
- package/skills/ui-design/references/vi-solar-relay.md +130 -0
- package/skills/ui-design/references/vi-template-workflow.md +48 -0
- package/skills/ui-design/references/vi-verdant-grid.md +141 -0
- package/skills/ui-design/references/vi-violet-meridian.md +172 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/assemble_material.py +217 -0
- package/skills/ui-design/scripts/assemble_material_test.py +149 -0
- package/skills/ui-design/scripts/browser_check_ui_artifact.mjs +221 -0
- package/skills/ui-design/scripts/chart_sanity_check.py +261 -0
- package/skills/ui-design/scripts/chart_sanity_check_test.py +165 -0
- package/skills/ui-design/scripts/check_language_policy.py +351 -0
- package/skills/ui-design/scripts/check_ui_artifact.py +435 -0
- package/skills/ui-design/scripts/check_ui_artifact_pptx_test.py +251 -0
- package/skills/ui-design/scripts/deck_pages_check.py +158 -0
- package/skills/ui-design/scripts/deck_pages_check_test.py +134 -0
- package/skills/ui-design/scripts/deck_visual_style_check.py +767 -0
- package/skills/ui-design/scripts/deck_visual_style_check_test.py +713 -0
- package/skills/ui-design/scripts/design_budget_check.py +271 -0
- package/skills/ui-design/scripts/design_budget_check_test.py +183 -0
- package/skills/ui-design/scripts/design_repair_hints.py +162 -0
- package/skills/ui-design/scripts/design_repair_hints_test.py +54 -0
- package/skills/ui-design/scripts/design_style_check.py +397 -0
- package/skills/ui-design/scripts/design_style_check_test.py +233 -0
- package/skills/ui-design/scripts/draft_coverage_check.py +184 -0
- package/skills/ui-design/scripts/draft_coverage_check_test.py +131 -0
- package/skills/ui-design/scripts/export_pptx_from_html.mjs +2367 -0
- package/skills/ui-design/scripts/extract_source_assets.py +607 -0
- package/skills/ui-design/scripts/extract_source_assets_test.py +256 -0
- package/skills/ui-design/scripts/generated_image_review_collect.py +206 -0
- package/skills/ui-design/scripts/generated_image_review_collect_test.py +91 -0
- package/skills/ui-design/scripts/image_plan_lint.py +571 -0
- package/skills/ui-design/scripts/image_plan_lint_test.py +515 -0
- package/skills/ui-design/scripts/image_prompt_rewrite.py +713 -0
- package/skills/ui-design/scripts/image_prompt_rewrite_test.py +966 -0
- package/skills/ui-design/scripts/layout_balance.py +881 -0
- package/skills/ui-design/scripts/layout_balance_test.py +927 -0
- package/skills/ui-design/scripts/normalize_design_json.py +272 -0
- package/skills/ui-design/scripts/normalize_design_json_test.py +119 -0
- package/skills/ui-design/scripts/plan_source_layout.py +1450 -0
- package/skills/ui-design/scripts/plan_source_layout_test.py +1136 -0
- package/skills/ui-design/scripts/resolve_source_input.py +270 -0
- package/skills/ui-design/scripts/resolve_source_input_test.py +98 -0
- package/skills/ui-design/scripts/scaffold_ui_artifact.py +377 -0
- package/skills/ui-design/scripts/source_usage_check.py +581 -0
- package/skills/ui-design/scripts/source_usage_check_test.py +427 -0
- package/skills/ui-design/scripts/text_readability_pixel.py +340 -0
- package/skills/ui-design/scripts/text_readability_pixel_test.py +219 -0
- package/skills/ui-design/scripts/visual_quality_gate.py +301 -0
- package/skills/ui-design/scripts/visual_quality_gate_test.py +233 -0
- package/skills/ui-design/tests/e2e/prompts/deck.md +19 -0
- package/skills/ui-design/tests/e2e/prompts/webpage.md +17 -0
- package/skills/ui-design/tests/e2e/render_check.mjs +101 -0
- package/skills/ui-design/tests/e2e/rubric.json +54 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/language-check.txt +12 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/static-check.txt +15 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/outputs/index.html +837 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/prompt.md +12 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/review.md +21 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/outputs/homepage.html +373 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/outputs/platform.html +378 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/prompt.md +13 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/review.md +26 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/outputs/index.html +656 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/prompt.md +12 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/render_check.mjs +67 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/outputs/index.html +587 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/prompt.md +12 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/review.md +36 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/language-check.txt +8 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/static-check.txt +16 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/outputs/index.html +739 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/prompt.md +11 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/review.md +22 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/checks/browser-check.json +52 -0
- package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/outputs/index.html +641 -0
- package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/outputs/index.html +467 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/outputs/homepage.html +373 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/outputs/platform.html +378 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/prompt.md +13 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/review.md +26 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/language-check.txt +4 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/execution_notes.md +10 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/outputs/index.html +587 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/prompt.md +14 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/review.md +13 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/checks/browser-check.json +24 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/execution_notes.md +21 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/outputs/deck.html +451 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/screenshots/slide-01.png +0 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/deck/screenshots/slide-02.png +0 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/review.md +79 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/checks/browser-check.json +26 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/execution_notes.md +20 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/outputs/index.html +534 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/browser-check.json +64 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/language-check.txt +7 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/quick-validate.txt +1 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/static-console.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/static-homepage.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/outputs/console.html +600 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/outputs/homepage.html +556 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/prompt.md +29 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/review.md +57 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/console-desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/console-mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/homepage-desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/homepage-mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/browser-check.json +33 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/language-check.txt +6 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/quick-validate.txt +1 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/outputs/index.html +682 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/prompt.md +13 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/review.md +59 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/outputs/page-01.html +466 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/outputs/page-02.html +433 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/prompt.md +13 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/language-check.txt +3 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/execution_notes.md +24 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/outputs/index.html +723 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/prompt.md +15 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/review.md +26 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/browser-dark.json +49 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/browser-light.json +49 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/language-check.txt +11 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/static-dark.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/static-light.txt +3 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/execution_notes.md +23 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/outputs/dark.html +392 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/outputs/light.html +476 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/prompt.md +23 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/review.md +41 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/dark/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/dark/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/light/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/light/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/browser-check.json +54 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/language-check.txt +5 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/quick-validate.txt +1 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/outputs/index.html +765 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/prompt.md +15 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/review.md +59 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/outputs/index.html +508 -0
- package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/browser-check.json +49 -0
- package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/mobile.png +0 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/browser-check.json +54 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/language-check.txt +6 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/quick-validate.txt +1 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/static-check.txt +2 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/outputs/index.html +788 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/prompt.md +14 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/review.md +60 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/screenshots/desktop.png +0 -0
- package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/screenshots/mobile.png +0 -0
- package/skills/video-compose/SKILL.md +8 -1
- package/skills/web-crawler/SKILL.md +70 -0
- package/skills/web-crawler/scripts/crawl.mjs +538 -0
- package/skills/web-crawler/scripts/crawl.test.mjs +204 -0
- package/skills/xlsx/SKILL.md +12 -0
- package/skills/xlsx/scripts/opc_check.py +253 -0
- package/src/advisorState.js +22 -0
- package/src/askBridge.js +87 -3
- package/src/bootstrap/workingDir.js +12 -1
- package/src/cli/args.js +17 -1
- package/src/cli/configMenu.js +236 -0
- package/src/cli/configWizard.js +7 -5
- package/src/cli/print.js +37 -4
- package/src/cli/streamJson.js +77 -24
- package/src/cli/wizards/advisorWizard.js +147 -0
- package/src/cli/wizards/fieldForm.js +149 -0
- package/src/cli/wizards/imageWizard.js +60 -0
- package/src/cli/wizards/openRouterWizard.js +23 -0
- package/src/cli/wizards/providerPresets.js +95 -0
- package/src/cli/wizards/providerWizard.js +219 -0
- package/src/cli/wizards/searchWizard.js +23 -0
- package/src/cli/wizards/ttsWizard.js +34 -0
- package/src/config/configFile.js +441 -83
- package/src/config/configService.js +446 -0
- package/src/config.js +24 -64
- package/src/context/agentHome.js +9 -0
- package/src/context/archive.js +3 -2
- package/src/context/compact.js +8 -5
- package/src/context/contextLock.js +81 -0
- package/src/context/persistContext.js +30 -11
- package/src/context/reactiveCompact.js +4 -2
- package/src/context/recentDirs.js +21 -61
- package/src/context/sessionPath.js +97 -23
- package/src/context/sessionRegistry.js +303 -24
- package/src/context/tokenCounter.js +18 -0
- package/src/context/workspaceIndex.js +731 -0
- package/src/infra/verification.js +3 -2
- package/src/llm/client.js +293 -206
- package/src/llm/providers/anthropicFormat.js +241 -0
- package/src/llm/providers/openaiFormat.js +190 -0
- package/src/loop.js +211 -27
- package/src/main.js +61 -11
- package/src/messageQueue.js +97 -0
- package/src/multimodal.js +203 -0
- package/src/plugin-sdk.js +15 -0
- package/src/plugins/commandRouter.js +3 -0
- package/src/plugins/hookEngine.js +5 -1
- package/src/plugins/pluginLifecycle.js +28 -0
- package/src/plugins/pluginRunner.js +40 -0
- package/src/plugins/transcript.js +4 -3
- package/src/prompts/pluginList.js +2 -2
- package/src/prompts/projectInstructions.js +3 -3
- package/src/prompts/promptAssembly.js +133 -109
- package/src/prompts/skillList.js +12 -22
- package/src/session/runAgentTurn.js +70 -0
- package/src/session/runTurn.js +41 -6
- package/src/toolGate.js +17 -0
- package/src/tools/advisor/advisor.js +379 -0
- package/src/tools/agent/agent.js +555 -0
- package/src/tools/agent/agentTypes.js +59 -0
- package/src/tools/agent/coordinator.js +93 -0
- package/src/tools/agent/worktree.js +270 -0
- package/src/tools/ask/ask.js +7 -2
- package/src/tools/bash/bash.js +112 -18
- package/src/tools/download/download.js +144 -0
- package/src/tools/edit/edit.js +1 -0
- package/src/tools/edit/multi-edit.js +1 -0
- package/src/tools/genimage/genimage.js +242 -0
- package/src/tools/genspeech/genspeech.js +67 -0
- package/src/tools/glob/glob.js +1 -0
- package/src/tools/grep/grep.js +3 -0
- package/src/tools/grep/rgPath.js +2 -0
- package/src/tools/index.js +25 -2
- package/src/tools/read/read.js +1 -0
- package/src/tools/shared/killTree.js +52 -0
- package/src/tools/toolProgressBridge.js +48 -0
- package/src/tools/webbrowser/agentBrowserPath.js +258 -0
- package/src/tools/webbrowser/browser.js +59 -42
- package/src/tools/webbrowser/browserControl.js +118 -0
- package/src/tools/webbrowser/browserDaemon.js +97 -0
- package/src/tools/webbrowser/browserService.js +27 -0
- package/src/tools/webbrowser/browserStream.js +119 -0
- package/src/tools/webbrowser/webbrowser.js +699 -130
- package/src/tools/webfetch/webfetch.js +1 -0
- package/src/tools/websearch/websearch.js +134 -51
- package/src/tools/write/write.js +1 -0
- package/src/ui/App.js +249 -22
- package/src/ui/AskQuestion.js +19 -17
- package/src/ui/InputBox.js +34 -9
- package/src/ui/LiveArea.js +112 -19
- package/src/ui/MessageList.js +100 -14
- package/src/ui/ModelPicker.js +56 -0
- package/src/ui/QueuedMessagesBanner.js +14 -0
- package/src/ui/Root.js +18 -10
- package/src/ui/SessionPicker.js +102 -0
- package/src/ui/StatusLine.js +13 -4
- package/src/ui/WorkspacePicker.js +55 -0
- package/src/ui/figures.js +44 -0
- package/src/ui/hooks/askSlot.js +82 -0
- package/src/ui/hooks/useChat.js +345 -64
- package/src/ui/hooks/usePasteHandler.js +11 -1
- package/src/ui/hooks/useTextBuffer.js +1 -3
- package/src/ui/liveViewport.js +5 -1
- package/src/ui/markdown.js +206 -0
- package/src/ui/textBuffer.js +0 -7
- package/src/ui/theme.js +32 -0
- package/src/utils/debugLog.js +0 -4
- package/src/utils/resourcePaths.js +2 -2
- package/src/utils/stripThink.js +50 -0
- package/src/web/browserBridge.js +447 -0
- package/src/web/protocol.js +19 -0
- package/workflows/adaptive-research.yaml +9 -2
- package/workflows/book-review-short.yaml +31 -7
- package/workflows/e2e-write-greet.yaml +3 -0
- package/workflows/illustrate.yaml +227 -0
- package/workflows/plan.yaml +437 -207
- package/workflows/ppt.yaml +1659 -0
- package/workflows/ralph-loop.yaml +142 -112
- package/workflows/schema.json +81 -23
- package/workflows/webppt.yaml +496 -0
- package/workflows/word.yaml +710 -0
- package/workflows/youtube-shorts.yaml +38 -10
- package/MINIMAL-TRACE.md +0 -77
- package/plugins/workflow-runner/src/voteHelpers.js +0 -110
- package/skills/config/SKILL.md +0 -123
- package/skills/frontend-design/LICENSE.txt +0 -177
- package/skills/frontend-design/SKILL.md +0 -42
- package/skills/pptx/scripts/office/__pycache__/soffice.cpython-314.pyc +0 -0
- package/src/ui/ProgressPanel.js +0 -54
- package/src/ui/StreamingBlock.js +0 -11
- package/src/ui/ToolStatus.js +0 -11
|
@@ -0,0 +1,1659 @@
|
|
|
1
|
+
name: ppt
|
|
2
|
+
description: >
|
|
3
|
+
生成 PPT(素材驱动版,ppt):**统一摄取用户给的任意素材(Word/PPT/Excel/PDF/图片,可多种混合)+ 一句要求** →
|
|
4
|
+
①抽取文字+图片+图像统计 ②逐图多模态识图(内容/重点区/是否宜做背景)③确定性合并成一份「用户原始材料」统一中间文件
|
|
5
|
+
`build/material.md`+`material.json`(文字主干 + 每图:路径+识图详述+重点区+统计) →
|
|
6
|
+
分析需求并定样式 → 以用户原始输入 + material 为主干写深度基础稿件(默认不联网) →
|
|
7
|
+
**先产详细 Web 页面设计文档**(每页:内容 + 构图法 + 每块渲染决策 + 配图/呼应文案的生图提示词 + 背景意图;
|
|
8
|
+
客户图按识图内容配到最契合页、据重点区/统计定构图与配色)→ 配图分流(结构图回退 HTML)→ 按比例文生图/图生图 →
|
|
9
|
+
按设计文档**分批生成** HTML deck(默认 fast 每轮 ≤3 页,页数闸门 + **客户图用尽闸门** 双收口)→
|
|
10
|
+
HTML 层硬构图闸门(重叠/越界/截图夹带文本,关闭占空比迭代)→ 三层可编辑导出 hybrid PPTX **一次** → OPC 校验 → 报告。
|
|
11
|
+
三层 = hybrid:背景整页截图垫底(不可编辑);前景每个离散元素逐元素切图成独立可编辑图片对象;文本顶层还原为
|
|
12
|
+
PPT 原生可编辑文本框;全幅氛围背景图(B 路线)连同 scrim 留背景层。
|
|
13
|
+
**客户图铁律:必须全部用进 PPT(确定性闸门把关)、一律走 Seedream 图生图重绘到高清并贴 PPT 风格(不直接用原图——
|
|
14
|
+
低清/原背景/比例都不契合编辑式版面),派生图必须保留与原始 src_K 的映射;落槽默认 `object-fit:cover` 填满(配
|
|
15
|
+
`object-position` 保重点区),仅 dense-info 数据图(截图/图表)走忠实保真 img2img 后 contain 完整展示;按朝向/重点区
|
|
16
|
+
图文混排、配色随图、文字避让重点区、宜做背景者铺背景。**
|
|
17
|
+
version: "0.1"
|
|
18
|
+
|
|
19
|
+
# 声明产物:只列最终交付物(new-task 清理旧 PPT / completed 报产物 / 完成闸门校验落盘)。
|
|
20
|
+
# 中间 scratch(draft/design/deck.html/img_plan/assets/export)故意不声明——收尾 cleanup 删;
|
|
21
|
+
# 声明进来会被「声明产物必须存在」判缺失而 halt。
|
|
22
|
+
artifacts:
|
|
23
|
+
- "./out/deck.pptx"
|
|
24
|
+
|
|
25
|
+
# 自愈:LLM/网络瞬态故障 in-run 重跑(端点会分钟级拥塞波,给恢复窗口)。
|
|
26
|
+
self_heal:
|
|
27
|
+
max_retries: 2
|
|
28
|
+
retry_delay_ms: 20000
|
|
29
|
+
|
|
30
|
+
# 输入设计:用户「打一句话描述」即可(topic greedy 吸收全部位置参数)+ 可选 source 文档。
|
|
31
|
+
# 页数不是输入(由设计文档按内容自动定);source/style/mode/illustrations/out 仅作高级 --input 覆盖。
|
|
32
|
+
inputs:
|
|
33
|
+
- name: topic
|
|
34
|
+
type: string
|
|
35
|
+
required: true
|
|
36
|
+
greedy: true
|
|
37
|
+
description: "PPT 主题 / 完整需求(中文,可直接一句话自然语言:内容要点/指挥语 + 样式偏好如\"浅色/紫色\" + 任何要求如\"先搜资料\"。配 source 文档时这里写「怎么用这份文档」如\"做成12页投资人PPT\")"
|
|
38
|
+
- name: source
|
|
39
|
+
type: string
|
|
40
|
+
default: ""
|
|
41
|
+
description: "【素材文档·可选 --input】用户提供的 Word/PPT/PDF/Excel/图片路径(支持老 .doc 自动转 .docx;文字+图片会被高权重抽取作素材)。留空时会解析 topic 里的自然语言文件线索(如“下载目录里的某 Word 文件”),仍无明确素材时才扫当前工作目录支持格式;都没有则退化为纯 topic 生成。"
|
|
42
|
+
- name: style
|
|
43
|
+
type: string
|
|
44
|
+
default: ""
|
|
45
|
+
description: "【高级·可选 --input】视觉样式覆盖:留空=由 stage0 按需求+配色推荐让用户选;填内置 VI 名=强制套用(13 个:aqua-glass/violet-meridian/ember-prism/amber-prism/verdant-grid/aegis-vector/precision-horizon/comfort-vision/nebula-console/obsidian-xui/obsidian-optics/precision-horizon-dark/solar-relay,配色/适合见 ui-design SKILL.md 视觉模板库);填一句风格方向=据此设计。"
|
|
46
|
+
- name: mode
|
|
47
|
+
type: enum
|
|
48
|
+
values: ["hybrid", "flat"]
|
|
49
|
+
default: "hybrid"
|
|
50
|
+
description: "【高级·可选 --input】导出模式:hybrid=文字/插图可编辑、背景截图(推荐);flat=全图最保真但不可编辑"
|
|
51
|
+
- name: illustrations
|
|
52
|
+
type: number
|
|
53
|
+
default: -1
|
|
54
|
+
description: "【高级·可选 --input】AI 生图张数控制:默认 -1=最佳质量、不设上限;0=完全不生 AI 图(仅纯示意主题);N>0=显式上限 N 张。只要页面需要真实画面、产品感、场景、操作、安装、环境、特写、氛围背景,且客户图没有合适素材,就必须积极文生图;流程图、数据图表、架构图、关系图、时间线、参数轴等精确信息必须 HTML/SVG,不占额度。"
|
|
55
|
+
- name: out
|
|
56
|
+
type: string
|
|
57
|
+
default: "./out/deck.pptx"
|
|
58
|
+
description: "【高级·可选 --input】输出 PPTX 路径"
|
|
59
|
+
- name: image_intensity
|
|
60
|
+
type: enum
|
|
61
|
+
values: ["minimal", "balanced", "rich"]
|
|
62
|
+
default: "rich"
|
|
63
|
+
description: "【高级·可选 --input】AI 生图积极性(与 illustrations 张数上限叠加):minimal=只给封面/章节/必要真实画面配图;balanced=封面/章节 + 产品/场景/操作/使用案例页配 AI 图;rich(默认)=最佳质量,除 HTML/SVG 精确信息页外,所有需要画面帮助理解的页面都积极生成语义背景、产品/场景图、特写图。**红线任何档不变:结构图(架构/流程/树/对比/时间线/数据图表)必须 HTML/SVG、绝不当 AI 图生。**"
|
|
64
|
+
- name: quality
|
|
65
|
+
type: enum
|
|
66
|
+
values: ["fast", "best"]
|
|
67
|
+
default: "fast"
|
|
68
|
+
description: "【高级·可选 --input】质量模式:fast=默认快速可用,只跑确定性硬门和一次导出;best=保留多轮设计修复、视觉修复,耗时更长(生成图语义复核已屏蔽:验证只走确定性脚本,见阶段7c 注释)。"
|
|
69
|
+
- name: debug_keep_build
|
|
70
|
+
type: enum
|
|
71
|
+
values: ["true", "false"]
|
|
72
|
+
default: "true"
|
|
73
|
+
description: "【调试·可选 --input】是否保留 ./build 中间产物。默认 true,便于检查 deck.html、design.json、截图和报告;设为 false 时最终 PPT 生成后清理 ./build。"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
steps:
|
|
77
|
+
# ---------- 阶段1:需求分析 + 样式推荐(受众/深度能推断自己定;**视觉样式 style 为空时必问用户**,最多问一轮) ----------
|
|
78
|
+
- id: stage0_clarify
|
|
79
|
+
title: "阶段1/22·需求分析 + 样式推荐"
|
|
80
|
+
agent: |
|
|
81
|
+
你要为用户做一套 PPT。**本步的唯一任务 = 需求分析 + 定视觉样式,输出结论后立即结束。**
|
|
82
|
+
|
|
83
|
+
⚠️ 严格边界(弱模型尤其注意):本步**只做分析、给结论**,**绝对不要**在本步:
|
|
84
|
+
写 HTML、写任何文件、制作或生成 PPT、调用任何生成/导出类工具、开始"做 PPT"。
|
|
85
|
+
撰稿/设计文档/生图/导出都是**后续独立阶段**的事。你输出下面要求的分析结论后就**停下**。
|
|
86
|
+
|
|
87
|
+
## 一、分析需求(能推断的自己定,无需翻工作目录/代码库)
|
|
88
|
+
直接从主题(${inputs.topic})文字推断:受众与场合、内容目的与深度取向、内容范围与详略。
|
|
89
|
+
主题文字本身自足,**不要去 Read/Grep/Glob 工作目录探索**(会跑偏、烧轮数)。这几项能推断的一律自己拍板、不问——
|
|
90
|
+
**唯一例外是「视觉样式」:见第二节,style 为空时必须问用户,不得自己替用户拍样式。**
|
|
91
|
+
|
|
92
|
+
## 二、视觉样式(style="${inputs.style}")——⚠️ **本步唯一必做的人机交互**
|
|
93
|
+
- **style 已填**(内置 VI 名 / 一句风格方向):直接采用、**不要再问样式**,跳过提问。
|
|
94
|
+
- **style 为空**:**你必须调用一次 AskUserQuestion 让用户选视觉样式——不论主题多明确都要问,绝不自己替用户拍板样式**
|
|
95
|
+
(样式是主观偏好,必须用户拍)。**没问就直接进下一步 = 执行错误。** 做法:
|
|
96
|
+
⚠️ 非交互宿主(-p/gateway/子进程)会自动选推荐项,那没问题;但**交互运行(TUI)时这一问绝不能省**。
|
|
97
|
+
|
|
98
|
+
**怎么挑(先理解配色再给用户推)**:把客户需求拆成「**行业属性 + 情绪基调 + 任何品牌/偏好色**」,
|
|
99
|
+
映射到下面某个模板的**配色**,挑配色最贴合的 **2–3 个**作选项(每项写「VI 名 + 主色调 + 一句气质」)。
|
|
100
|
+
用户没提颜色偏好时按**行业惯例配色**兜底:能源/电力→绿 verdant-grid、军工/国防/政企工业→蓝 aegis-vector、
|
|
101
|
+
金融/物流/B2B 管理→暖白纸感 comfort-vision、AI 模型发布→红 ember-prism / 橙金 amber-prism、
|
|
102
|
+
影像/创作硬件→黑红 obsidian-optics、高端消费硬件→黑白 precision-horizon(深色场景 -dark)、
|
|
103
|
+
云/开发者/数据/安全平台→蓝黑 nebula-console / obsidian-xui、通用 AI 产品/SaaS/官网→蓝白 aqua-glass、
|
|
104
|
+
AI 工作台/智能路径→紫 violet-meridian、网络加速/连接/移动活力→红橙 solar-relay。
|
|
105
|
+
需要细节可 Read ui-design 技能目录的 `SKILL.md`「视觉模板库」(13 个模板的配色/气质/适合/慎用全表 + 配色速查)。
|
|
106
|
+
AskUserQuestion 会自带「其它」让用户**自由输入自定义风格方向**——这就实现了「两三个可选 + 一个自定义输入」。
|
|
107
|
+
|
|
108
|
+
全部 13 个内置 VI(**配色** + 气质 + 适合;按色系分组便于按需求匹配):
|
|
109
|
+
【浅色/通透底】
|
|
110
|
+
- aqua-glass:蓝白玻璃通透 + 近黑蓝字——AI 产品/效率工具/知识库/SaaS/官网/现代控制台
|
|
111
|
+
- violet-meridian:冷白底 + 主紫 + 钴蓝、清爽智能——AI 工作台/开发者工具/路径节点/图标配色
|
|
112
|
+
- ember-prism:暖白底 + 红色主视觉 + 橙火花、前沿发布感——AI 模型官网/多模态矩阵/红色发布
|
|
113
|
+
- amber-prism:暖白底 + 橙金 + 少量红、温暖亲和发布感——AI 科技/模型官网/多模态(比 ember 更暖)
|
|
114
|
+
- verdant-grid:白底 + 深绿 + 浅绿分区、稳健基础设施——能源/电力/电网/能源央企汇报/电力 PPT
|
|
115
|
+
- aegis-vector:白底 + 兵工蓝 + 黑大字、权威工业准星感——军工/国防/装备制造/政企/工业集团
|
|
116
|
+
- precision-horizon:灰白底 + 黑白灰克制 + 可换行动色、极简产品感——高端硬件官网/产品发布/Apple·DJI 气质
|
|
117
|
+
- comfort-vision:雾灰暖白纸感 + 深墨绿 + 铁锈橙、克制管理层可读——B2B/金融/物流/能源/管理驾驶舱/高密度决策
|
|
118
|
+
【深色/科技底】
|
|
119
|
+
- nebula-console:深空黑半透明 + 电光蓝、蓝黑理性未来——云服务/开发者工具/数据基础设施/安全
|
|
120
|
+
- obsidian-xui:极黑 + 电光蓝、更黑更锋利 XUI——黑色科技/未来控制台/HUD/数据大屏/工业·安全·机器人
|
|
121
|
+
- obsidian-optics:黑底 + 冷白 + 少量信号红、精密影像硬件——影像器材/镜头/电影机/监看/调色/创作者硬件
|
|
122
|
+
- precision-horizon-dark:石墨黑 + 暖橙材质、产品剧场强性能——深色产品官网/高性能硬件/黑橙性能/iPhone Pro 气质
|
|
123
|
+
【暖色多彩/活力】
|
|
124
|
+
- solar-relay:暖白底 + 红橙日冕弧带 + 青蓝、活力连接移动感——网络加速/VPN/连接/流量/移动应用
|
|
125
|
+
|
|
126
|
+
## 三、其它澄清(克制)
|
|
127
|
+
第二节的样式问是**必做**的;其它澄清则克制——仅当「缺了它整套 PPT 方向会完全不同、且推断不出」时,
|
|
128
|
+
才把它**并进第二节那同一轮 AskUserQuestion**(连同样式题最多 4 题,选项式优先、每题给推荐项)。其它澄清目标已明确就别问。
|
|
129
|
+
|
|
130
|
+
输出(简洁,供后续步骤引用)后**立即结束本步**:
|
|
131
|
+
- 受众/场合、内容目的与深度、内容范围与详略(页数由后续设计文档按章节自动定,不在此预设);
|
|
132
|
+
**额外定【术语深度档】= L1 入门(类比开路、避免黑话)/ L2 专业(精确术语)/ L3 高管速读(数字与决策意义先行)+ 信息密度取向**,写进结论供 draft/design 据此调文案深度(治「精炼相对于谁的话不明确」)
|
|
133
|
+
- **最终采用的视觉样式**(VI 名或风格方向,写明确,后续设计步据此执行)
|
|
134
|
+
- 哪类内容可能需要配图
|
|
135
|
+
- 你自行拍板的关键默认假设
|
|
136
|
+
allowed_tools: [AskUserQuestion]
|
|
137
|
+
maxTurns: 8
|
|
138
|
+
capture: clarifications
|
|
139
|
+
goal_supplement: true
|
|
140
|
+
onError: continue
|
|
141
|
+
max_retries: 1
|
|
142
|
+
|
|
143
|
+
# ---------- 阶段2:摄取素材(抽取文字+图片 + 图像统计)—— 素材驱动的地基(无素材则空跑、不阻断) ----------
|
|
144
|
+
# 两个确定性脚本干机械活:extract_source_assets.py(任意素材→文字+图片+base manifest)+ image_stats.py(逐图统计)。
|
|
145
|
+
# 产物:build/source.md(文字主干)+ build/assets/src_*.png(客户图)+ build/source_assets.json(base 清单)+ build/source_stats.json(图像统计)。
|
|
146
|
+
- id: stage_extract
|
|
147
|
+
title: "阶段2/22·摄取素材:抽取文字+图片 + 图像统计"
|
|
148
|
+
tool: Bash
|
|
149
|
+
args:
|
|
150
|
+
command: |
|
|
151
|
+
set -e
|
|
152
|
+
mkdir -p ./build ./build/assets
|
|
153
|
+
# 只清理本次运行的状态/哨兵/旧报告,不删除 build 全目录,保留用户排障需要的中间产物。
|
|
154
|
+
rm -f \
|
|
155
|
+
./build/build_complete \
|
|
156
|
+
./build/layout_ok \
|
|
157
|
+
./build/visual_quality_ok \
|
|
158
|
+
./build/visual_quality_state.json \
|
|
159
|
+
./build/visual_quality_report.json \
|
|
160
|
+
./build/visual_quality_report.md \
|
|
161
|
+
./build/visual_quality_residual.md \
|
|
162
|
+
./build/image_generation_report.json \
|
|
163
|
+
./build/generated_image_review.json \
|
|
164
|
+
./build/generated_image_semantic_retry_report.json \
|
|
165
|
+
./build/export-summary.md \
|
|
166
|
+
./build/build_probe.json \
|
|
167
|
+
./build/build_probe.txt \
|
|
168
|
+
./build/design_repair_done \
|
|
169
|
+
./build/design_repair_residual.md \
|
|
170
|
+
./build/design_json_ok \
|
|
171
|
+
./build/design_json_gate.json \
|
|
172
|
+
./build/design_json_gate.md \
|
|
173
|
+
./build/design.raw.json \
|
|
174
|
+
./build/design.draft.json \
|
|
175
|
+
./build/img_route_ok
|
|
176
|
+
rm -rf ./build/export ./build/generated-image-reviews
|
|
177
|
+
RESOLVE="skills/ui-design/scripts/resolve_source_input.py"
|
|
178
|
+
EXTRACT="skills/ui-design/scripts/extract_source_assets.py"
|
|
179
|
+
STATS="skills/image-stats/scripts/image_stats.py"
|
|
180
|
+
RAW_TOPIC="$(cat <<'EOF_TOPIC'
|
|
181
|
+
${inputs.topic}
|
|
182
|
+
EOF_TOPIC
|
|
183
|
+
)"
|
|
184
|
+
RAW_SOURCE="$(cat <<'EOF_SOURCE'
|
|
185
|
+
${inputs.source}
|
|
186
|
+
EOF_SOURCE
|
|
187
|
+
)"
|
|
188
|
+
python3 "$RESOLVE" \
|
|
189
|
+
--source "$RAW_SOURCE" \
|
|
190
|
+
--topic "$RAW_TOPIC" \
|
|
191
|
+
--cwd . \
|
|
192
|
+
--out ./build/source_resolution.json
|
|
193
|
+
SOURCE="$(python3 -c 'import json; data=json.load(open("./build/source_resolution.json", encoding="utf-8")); print(data.get("resolved_path") or "")')"
|
|
194
|
+
if [ -n "$SOURCE" ]; then
|
|
195
|
+
python3 "$EXTRACT" "$SOURCE" --out ./build -v
|
|
196
|
+
else
|
|
197
|
+
python3 "$EXTRACT" . --scan --out ./build -v
|
|
198
|
+
fi
|
|
199
|
+
python3 -c 'import json,sys; r=json.load(open("./build/source_resolution.json", encoding="utf-8")); a=json.load(open("./build/source_assets.json", encoding="utf-8")); ok=not (r.get("requires_source") and not a.get("has_source")); print("PPT_SOURCE_REQUIRED_BUT_EMPTY: 用户明确要求使用素材文件,但抽取结果为空。", file=sys.stderr) if not ok else None; print(json.dumps(r, ensure_ascii=False, indent=2), file=sys.stderr) if not ok else None; sys.exit(0 if ok else 3)'
|
|
200
|
+
python3 "$STATS" ./build/assets --scan --json > ./build/source_stats.json
|
|
201
|
+
cat > ./build/user_request.md <<'EOF'
|
|
202
|
+
# 用户原始输入与目标
|
|
203
|
+
|
|
204
|
+
- 主题/指令:${inputs.topic}
|
|
205
|
+
- 素材路径:${inputs.source}
|
|
206
|
+
- 视觉风格:${inputs.style}
|
|
207
|
+
- 导出模式:${inputs.mode}
|
|
208
|
+
- AI 生图积极性:${inputs.image_intensity}
|
|
209
|
+
|
|
210
|
+
## 素材解析结果
|
|
211
|
+
EOF
|
|
212
|
+
printf '\n```json\n' >> ./build/user_request.md
|
|
213
|
+
cat ./build/source_resolution.json >> ./build/user_request.md
|
|
214
|
+
printf '\n```\n\n## 素材抽取结果\n\n```json\n' >> ./build/user_request.md
|
|
215
|
+
cat ./build/source_assets.json >> ./build/user_request.md
|
|
216
|
+
printf '\n```\n' >> ./build/user_request.md
|
|
217
|
+
cat >> ./build/user_request.md <<'EOF'
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
## 阶段1澄清结论
|
|
221
|
+
|
|
222
|
+
${clarifications}
|
|
223
|
+
|
|
224
|
+
## 执行优先级
|
|
225
|
+
|
|
226
|
+
1. 用户原始输入和目标最高权重,后续写稿、设计、评审都必须回看本文件。
|
|
227
|
+
2. 客户提供的文字和图片是高权重素材,默认不联网扩写,不另起炉灶。
|
|
228
|
+
3. 客户图片必须直接使用或通过图生图增强派生后使用,不能无故丢弃。
|
|
229
|
+
EOF
|
|
230
|
+
echo "PPT_SOURCE_EXTRACT_READY"
|
|
231
|
+
test -f ./build/source_assets.json
|
|
232
|
+
onError: halt # 用户明确提到素材但解析/抽取失败时必须停下,避免伪装成纯 topic
|
|
233
|
+
|
|
234
|
+
# ---------- 阶段3:逐图多模态识图(best-effort)—— for-each 遍历 readJson 拿到的真实图片清单 ----------
|
|
235
|
+
# 内核已支持多模态读图:每张客户图喂 LLM(images:[...]),产出「内容详述 + 重点区(归一化) + 是否宜做背景 + 建议文字位」。
|
|
236
|
+
# 写 build/vision/<file>.json;无多模态模型 / 单图识图失败都不阻断(onError:continue)。images:[] 时 0 轮(when 守门)。
|
|
237
|
+
- id: stage_vision_loop
|
|
238
|
+
title: "阶段3/22·逐图识图(内容+重点区+背景适配)"
|
|
239
|
+
when: "fileExists('./build/source_assets.json')"
|
|
240
|
+
type: loop
|
|
241
|
+
over: "${asArray(readJson('./build/source_assets.json', 'images'))}"
|
|
242
|
+
as: img
|
|
243
|
+
fresh_context: true
|
|
244
|
+
do:
|
|
245
|
+
- id: vision_one
|
|
246
|
+
title: "阶段3/22·识图 ${img.file}"
|
|
247
|
+
llm: |
|
|
248
|
+
你在「看图」——下方已附上客户图片 `${img.file}`(朝向 ${img.orient},来自素材章节「${img.section}」)。
|
|
249
|
+
**唯一任务**:仔细看这张图,直接输出结构化 JSON。不要解释、不要 Markdown、不要代码围栏。
|
|
250
|
+
⚠️ 必须是**合法 JSON**:字符串值内部如需引号一律用中文引号「」或单引号,绝不能出现未转义的英文双引号。
|
|
251
|
+
|
|
252
|
+
JSON 字段:
|
|
253
|
+
- `description`:这张图画的是什么(具体:主体/场景/物体/文字/图表类型,1–3 句,别空泛说"一张图片")。
|
|
254
|
+
- `key_elements`:图中关键元素数组(如 ["电路板","标注电容","型号文字"])。
|
|
255
|
+
- `key_region`:图中**最重要内容**所在的归一化矩形 `{"x":0~1,"y":0~1,"w":0~1,"h":0~1}`(左上原点;
|
|
256
|
+
如主体在中部偏左→约 {"x":0.25,"y":0.2,"w":0.5,"h":0.6})。下游据此让文字避让、裁切时保住重点。
|
|
257
|
+
- `suitable_as_background`:true/false——画面完整、留白足、**不是密集图表/截图**、适合整页铺底当背景吗?
|
|
258
|
+
- `content_type`:图的形态 ∈ photo|screenshot_slide|screenshot_ui|poster|chart|other。
|
|
259
|
+
**screenshot_slide = 完整幻灯片/宣传页整版截图**(自带标题/排版/箭头的"一页")——这类图下游只允许
|
|
260
|
+
contain 框图展示、绝不铺背景(识别错会导致整版截图被当壁纸再叠字的事故)。
|
|
261
|
+
- `relevant_to_topic`:true/false——图的内容与本次 PPT 的主题/正面叙事相关吗?
|
|
262
|
+
与主题无关、或含负面暗示(如事故/坠机/灾难资讯图用在产品方案里)→ false,下游会弃用它。
|
|
263
|
+
- `recommended_text_zone`:文字放哪不挡重点 ∈ left|right|top|bottom|center(key_region 的互补侧)。
|
|
264
|
+
- `palette_impression`:一句话色彩印象(如"冷色金属灰蓝")。
|
|
265
|
+
- `key_message`(**`content_type` ∈ chart|screenshot_slide|poster 时必填**,其余留空串):
|
|
266
|
+
这张图想说明/证明的**一句话核心结论**——不是画面描述,是它的论点/数据/道理
|
|
267
|
+
(如"全景相机 1 台顶 9 台传统监控""巡检效率提升 3 倍""告警响应从数周缩到数小时")。
|
|
268
|
+
这是治"图表类客户图的价值没被写进大纲、最终配不上"的关键字段,别写成"图中有柱状图"这种表层重复。
|
|
269
|
+
- `data_points`(可选数组,仅图表/截图类):图上能辨认的关键数字/对比(如 `["68% → 12%","3 倍提速"]`),认不出就 `[]`。
|
|
270
|
+
- `embedded_text`(**图上烧进画面本身的文字必填此字段,没有就 `[]`——不能只写进 description/notes**):
|
|
271
|
+
数组,每项 `{"text":"逐字抄原文","region":"大致位置,如'顶部标题'/'左侧标签'"}`。🚨 **自查**:如果你
|
|
272
|
+
在 `description`/`key_elements` 里已经写了图上的标题/标签文字(如"标题为「AI全景相机优势」"),
|
|
273
|
+
这里必须**原样再抄一遍**到 `embedded_text`——这不是重复劳动,是两个不同下游消费者:
|
|
274
|
+
description 给人看排版,`embedded_text` 给图生图当"必须去掉这些字"的确定性指令,两者缺一都会
|
|
275
|
+
让下游拿不到可执行的去字依据。这类文字下游图生图会被要求**去掉重绘**(治"带字图当背景/截图用,
|
|
276
|
+
字既不能编辑又可能和页面自己的标题重复")——去字后若信息有价值,设计阶段要靠这份记录用真实
|
|
277
|
+
HTML 文字重新配出,抄错/漏抄=信息丢失。真正的图表坐标轴/图例数值(`content_type=chart` 时)
|
|
278
|
+
不算"烧进画面的文字",那是数据本身,不要往这个字段里塞。
|
|
279
|
+
- `notes`:其它对排版有用的观察(如"右上角有大片留白可放标题"),没有就空串。
|
|
280
|
+
capture:
|
|
281
|
+
text: vision_json
|
|
282
|
+
images: ["./build/assets/${img.file}"]
|
|
283
|
+
image_detail: high
|
|
284
|
+
onError: continue # 无多模态模型 / 单图识图失败 → 跳过该图,下游容缺(只用文字+统计)
|
|
285
|
+
- id: write_vision_json
|
|
286
|
+
title: "阶段3/22·写入识图 JSON ${img.file}"
|
|
287
|
+
when: "length(vision_json) > 0"
|
|
288
|
+
tool: Write
|
|
289
|
+
args:
|
|
290
|
+
file_path: "./build/vision/${img.file}.json"
|
|
291
|
+
content: "${vision_json}"
|
|
292
|
+
onError: continue
|
|
293
|
+
# 写后消毒校验(2026-07-02 事故:src_6 识图结论正确但 JSON 引号未转义 → assemble 静默吞 None →
|
|
294
|
+
# 规划器盲态把旧 PPT 整版截图铺成背景)。非法 → 剥围栏/提取最外层 {...} 再试;仍非法 → 删文件 +
|
|
295
|
+
# 响亮 WARNING,交由下一步重识别一次。合法 → 原地规范化落盘。
|
|
296
|
+
- id: sanitize_vision_json
|
|
297
|
+
title: "阶段3/22·校验识图 JSON ${img.file}"
|
|
298
|
+
when: "length(vision_json) > 0"
|
|
299
|
+
tool: Bash
|
|
300
|
+
args:
|
|
301
|
+
command: |
|
|
302
|
+
python3 - "./build/vision/${img.file}.json" <<'PYEOF'
|
|
303
|
+
import json, re, sys
|
|
304
|
+
path = sys.argv[1]
|
|
305
|
+
try:
|
|
306
|
+
raw = open(path, encoding="utf-8-sig").read()
|
|
307
|
+
except OSError:
|
|
308
|
+
print("VISION_JSON_MISSING"); raise SystemExit(0)
|
|
309
|
+
def try_load(s):
|
|
310
|
+
try: return json.loads(s)
|
|
311
|
+
except Exception: return None
|
|
312
|
+
obj = try_load(raw)
|
|
313
|
+
if obj is None:
|
|
314
|
+
m = re.search(r"\{[\s\S]*\}", re.sub(r"```[a-zA-Z]*", "", raw))
|
|
315
|
+
if m: obj = try_load(m.group(0))
|
|
316
|
+
if isinstance(obj, dict):
|
|
317
|
+
json.dump(obj, open(path, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
|
|
318
|
+
print("VISION_JSON_OK")
|
|
319
|
+
else:
|
|
320
|
+
import os; os.remove(path)
|
|
321
|
+
print("WARNING: 识图 JSON 非法(引号未转义/围栏残留),已删除待重识别")
|
|
322
|
+
print("VISION_JSON_BAD")
|
|
323
|
+
onError: continue
|
|
324
|
+
# 坏 JSON 重识别一次(强化 JSON 纪律的短 prompt);仍坏则删除,assemble 阶段逐图 WARNING + 盲态保守。
|
|
325
|
+
- id: vision_one_retry
|
|
326
|
+
title: "阶段3/22·重识别 ${img.file}(上次 JSON 非法)"
|
|
327
|
+
when: "length(vision_json) > 0 && !fileExists('./build/vision/${img.file}.json')"
|
|
328
|
+
llm: |
|
|
329
|
+
上一次你对图片 `${img.file}` 的识图输出不是合法 JSON(多半是字符串里出现了未转义的英文双引号)。
|
|
330
|
+
重新只输出**一段合法 JSON**(无解释、无代码围栏;字符串内部引号一律用中文「」),字段:
|
|
331
|
+
description / key_elements / key_region{x,y,w,h} / suitable_as_background /
|
|
332
|
+
content_type(photo|screenshot_slide|screenshot_ui|poster|chart|other) /
|
|
333
|
+
relevant_to_topic(true|false) / recommended_text_zone / palette_impression / notes。
|
|
334
|
+
capture:
|
|
335
|
+
text: vision_json_retry
|
|
336
|
+
images: ["./build/assets/${img.file}"]
|
|
337
|
+
image_detail: high
|
|
338
|
+
onError: continue
|
|
339
|
+
- id: rewrite_vision_json
|
|
340
|
+
title: "阶段3/22·重写识图 JSON ${img.file}"
|
|
341
|
+
when: "length(vision_json_retry) > 0 && !fileExists('./build/vision/${img.file}.json')"
|
|
342
|
+
tool: Write
|
|
343
|
+
args:
|
|
344
|
+
file_path: "./build/vision/${img.file}.json"
|
|
345
|
+
content: "${vision_json_retry}"
|
|
346
|
+
onError: continue
|
|
347
|
+
- id: sanitize_vision_json_retry
|
|
348
|
+
title: "阶段3/22·复验识图 JSON ${img.file}"
|
|
349
|
+
when: "length(vision_json_retry) > 0"
|
|
350
|
+
tool: Bash
|
|
351
|
+
args:
|
|
352
|
+
command: |
|
|
353
|
+
python3 - "./build/vision/${img.file}.json" <<'PYEOF'
|
|
354
|
+
import json, re, sys
|
|
355
|
+
path = sys.argv[1]
|
|
356
|
+
try:
|
|
357
|
+
raw = open(path, encoding="utf-8-sig").read()
|
|
358
|
+
except OSError:
|
|
359
|
+
print("VISION_JSON_MISSING"); raise SystemExit(0)
|
|
360
|
+
def try_load(s):
|
|
361
|
+
try: return json.loads(s)
|
|
362
|
+
except Exception: return None
|
|
363
|
+
obj = try_load(raw)
|
|
364
|
+
if obj is None:
|
|
365
|
+
m = re.search(r"\{[\s\S]*\}", re.sub(r"```[a-zA-Z]*", "", raw))
|
|
366
|
+
if m: obj = try_load(m.group(0))
|
|
367
|
+
if isinstance(obj, dict):
|
|
368
|
+
json.dump(obj, open(path, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
|
|
369
|
+
print("VISION_JSON_OK")
|
|
370
|
+
else:
|
|
371
|
+
import os; os.remove(path)
|
|
372
|
+
print("WARNING: 重识别 JSON 仍非法,放弃(该图按盲态保守处理)")
|
|
373
|
+
print("VISION_JSON_BAD")
|
|
374
|
+
onError: continue
|
|
375
|
+
|
|
376
|
+
# ---------- 阶段4:合并「用户原始材料」+ 客户图版式/图生图确定性规划 ----------
|
|
377
|
+
# assemble_material.py 把 source.md + source_assets.json + source_stats.json + vision/*.json 合成
|
|
378
|
+
# build/material.md(人/LLM 读)+ build/material.json(机读富 manifest,驱动下游全程)。容缺、不报错。
|
|
379
|
+
# 紧接 plan_source_layout.py:纯算法逐图算定 quality/usage_intent/是否图生图/目标比例/推荐模板/文字落区与深浅
|
|
380
|
+
# + 生成图生图提示词骨架 → build/source_layout_plan.json/md。把「客户图怎么用」这一逐图决策从弱模型手里
|
|
381
|
+
# 收成确定性(治根因:低清图被硬铺当背景、该图生图的没图生图、提示词写不稳),设计步从此「按算好的选模板」。
|
|
382
|
+
- id: stage_assemble_material
|
|
383
|
+
title: "阶段4/22·合并统一材料 + 客户图版式/图生图规划"
|
|
384
|
+
when: "fileExists('./build/source_assets.json')"
|
|
385
|
+
tool: Bash
|
|
386
|
+
args:
|
|
387
|
+
command: |
|
|
388
|
+
set -e
|
|
389
|
+
python3 skills/ui-design/scripts/assemble_material.py --build ./build
|
|
390
|
+
test -f ./build/material.json
|
|
391
|
+
# 确定性客户图版式/图生图规划(恒产出 source_layout_plan.json/md,无客户图则空规划)。
|
|
392
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --build ./build || true
|
|
393
|
+
echo "PPT_MATERIAL_ASSEMBLED"
|
|
394
|
+
sed -n '1,120p' ./build/material.md || true
|
|
395
|
+
sed -n '1,80p' ./build/source_layout_plan.md 2>/dev/null || true
|
|
396
|
+
onError: continue # 合并失败不阻断(脚本恒产出,最坏是空材料,下游退化纯 topic)
|
|
397
|
+
|
|
398
|
+
# ---------- 阶段5:基于客户材料撰写知乎深度长文式基础稿件(默认不联网) ----------
|
|
399
|
+
- id: stage_draft_from_material
|
|
400
|
+
title: "阶段5/22·客户材料成稿(默认不联网)"
|
|
401
|
+
agent: |
|
|
402
|
+
为主题「${inputs.topic}」撰写一篇**知乎高赞深度长文式**的基础稿件,落到 `./build/draft.md`。
|
|
403
|
+
这篇稿件是后续整套 PPT 的**唯一内容源**——它薄,PPT 必然肤浅;它厚且有料,PPT 才立得住。
|
|
404
|
+
成败标准只有一个:**专业、有深度、有观点、有据可依,绝不灌水、绝不百科式罗列。**
|
|
405
|
+
|
|
406
|
+
## -1、先回看用户目标(最高权重)
|
|
407
|
+
**先 Read `./build/user_request.md`**。后续所有取舍都以这里记录的用户原始输入、素材路径、视觉偏好和澄清结论为最高权重。
|
|
408
|
+
如果材料与模型常识冲突,以客户材料为准;如果用户目标与材料范围冲突,写稿时明确采用用户目标做取舍。
|
|
409
|
+
|
|
410
|
+
## 〇、先看「用户原始材料」(素材驱动的关键)
|
|
411
|
+
**先 Read `./build/material.md`**(统一中间材料:文字主干 + 每张客户图的识图详述/重点区/统计):
|
|
412
|
+
- **有素材(material.md 有实质文字或图片)**:**以它为内容主干**——
|
|
413
|
+
**忠实保留其要点/数据/结构/事实(高权重,这是用户的原始资料,不得丢弃或随意改写)**;
|
|
414
|
+
你的工作是把它**消化、补全、深化**成知乎长文式稿件(理顺逻辑、补背景与机制、补必要常识),
|
|
415
|
+
而**不是另起炉灶忽略它**。topic 是「怎么用这份资料」的指挥语,据它定取舍与侧重。
|
|
416
|
+
draft.md 里**标注哪些内容来自素材**(便于后续设计优先承载),并记下 material 里有哪些客户图、各自画的是什么(识图详述)可配哪段内容。
|
|
417
|
+
🚨 **图表类客户图的核心结论必须落进正文(治"图配了但内容对不上")**:material.md 里标了
|
|
418
|
+
`🚨 图表核心结论` 的图(`vision.key_message`,图表/截图/海报类),它的结论**必须体现为某个论点或证据**
|
|
419
|
+
写进 draft.md——不能只在"配图列表"里记一笔"这张图配哪段",那样图有了位置、但论点没写进正文,
|
|
420
|
+
后续设计步一样接不住。
|
|
421
|
+
- **无素材(material.md 提示纯 topic / 无图无文字)**:基于用户主题和模型已有知识从零成稿;**默认不联网**。
|
|
422
|
+
|
|
423
|
+
## 一、先锚定"为谁写、写给谁用"(决定深度的取向)
|
|
424
|
+
开篇就把上文📌用户补充要求里的**受众 / 场合 / 目的 / 深度取向**吃进去:通篇围绕
|
|
425
|
+
"**这个受众为什么要懂这个、懂了能做什么决策/动作**"展开,而不是泛泛科普。深度不打折。
|
|
426
|
+
**按【术语深度档】(user_request.md 阶段1结论)调粒度**:L3 高管速读 → 数字/对标/决策意义先行、术语换高管能懂的;L2 专业 → 精确术语与机制;L1 入门 → 多用类比/例子开路、避免黑话。后续 design 步据此把每页 key_point 精炼到该受众"一眼看懂"。
|
|
427
|
+
|
|
428
|
+
## 二、搭专业理解框架(先你自己的判断)
|
|
429
|
+
**结合你的专业知识**先列专业骨架:背景与真问题 / 现状与关键概念 / 核心机制或原理 /
|
|
430
|
+
争议或难点 / 不同路线的取舍 / 趋势与实践要点。这一步决定文章有没有"观点和骨头"。
|
|
431
|
+
|
|
432
|
+
## 三、只用客户材料 + 既有知识补全,不默认联网
|
|
433
|
+
默认**不要调用联网检索工具**。用客户材料、图片识别、图像统计和你的专业知识补出必要背景、机制解释、反方视角和实践启示。
|
|
434
|
+
涉及最新价格、政策、版本等强时效信息时,不要编造;写成「需按用户最新资料或公开信息复核」,除非用户在 topic 里明确要求联网查新。
|
|
435
|
+
不要整段复制材料原文;要把材料消化成适合 PPT 叙事的论点、证据和例子。
|
|
436
|
+
|
|
437
|
+
## 四、按"知乎深度长文"结构成稿(用 Write 写 `./build/draft.md`)
|
|
438
|
+
简体中文、Markdown,**篇幅按主题复杂度自适应**:默认 `quality=fast` 写 1200–2500 字的高密度成稿(快、够用、不注水);
|
|
439
|
+
`quality=best` 才写 2500–6000 字深稿(愿意等待时用)。结构:
|
|
440
|
+
1. **引子**:抛真问题 / 认知张力 / 反直觉点(不要"随着……的发展"套话)。
|
|
441
|
+
2. **核心论点(thesis)**:一句话立住全文判断。
|
|
442
|
+
3. **多个分论点小节**(带小标题):每节 = 一个子观点 + **支撑事实/数据/机制**(讲清"为什么")+ 必要时给**反方视角或适用边界**。
|
|
443
|
+
4. **综合与启示**:回到受众,给出"所以对你意味着什么 / 该怎么做"。
|
|
444
|
+
5. **难懂概念顺带配个类比/例子**(供后续 PPT 上屏「说人话」):对抽象/专业概念,draft 里随手记一个贴切类比或具体例子
|
|
445
|
+
(如「全景相机」≈「多镜头拼成谷歌街景那种可转视角画面」、「π」≈「约 3.14~3.15」)——近似但好懂,后续做 PPT 精炼文案时直接用。
|
|
446
|
+
|
|
447
|
+
文末加一小段「资料边界」:说明本稿以用户提供材料和模型既有知识为基础,未默认联网检索;需强时效数据时建议后续单独核验。
|
|
448
|
+
|
|
449
|
+
完成后简述:字数、核心论点、几个论点小节、使用了哪些客户材料和图片信息。
|
|
450
|
+
allowed_tools: [Read, Write, Glob]
|
|
451
|
+
maxTurns: 24
|
|
452
|
+
done_when: "fileExists('./build/draft.md')"
|
|
453
|
+
# 地基步:稿件是后续全流程的唯一内容源。LLM 调用失败(如 minimax 端点拥塞/空闲超时)时**必须 halt 保留现场**,
|
|
454
|
+
# 不能 continue——否则没 draft.md 会让后面 5 个内容步全因 when=false 跳过、空手撞到导出步「假装推进、实则烂尾」。
|
|
455
|
+
# halt 后重跑按任务身份从本步续跑(错峰/网络恢复即可成)。max_retries 给 2 次 in-run 重试吸收瞬态拥塞。
|
|
456
|
+
onError: halt
|
|
457
|
+
max_retries: 2
|
|
458
|
+
|
|
459
|
+
# ---------- 阶段5b:原文主题覆盖检查 + 一次性回填(2026-07-03,治「客户图配不上」根因①) ----------
|
|
460
|
+
# 用户真机复盘:客户图和内容对不上,根因之一是 draft 撰写时被要求"不要整段复制材料原文、自由重组",
|
|
461
|
+
# 原文里靠图片说话的模糊章节容易被判定"缺乏论点"而略过,design 阶段又完全不读全文——于是这些主题在
|
|
462
|
+
# draft.md 里彻底消失,后面自然没有页面能承载对应客户图。检查 + 单次 best-effort 回填,fast/best 都跑
|
|
463
|
+
# (这是用户点名最高优先级问题,不能只在 best 生效);查无遗漏时零开销(when 直接短路,跳过修复步)。
|
|
464
|
+
- id: stage_draft_coverage
|
|
465
|
+
title: "阶段5/22·原文主题覆盖检查"
|
|
466
|
+
when: "fileExists('./build/draft.md')"
|
|
467
|
+
tool: Bash
|
|
468
|
+
args:
|
|
469
|
+
command: |
|
|
470
|
+
python3 skills/ui-design/scripts/draft_coverage_check.py --build ./build -v
|
|
471
|
+
onError: continue
|
|
472
|
+
|
|
473
|
+
- id: stage_draft_coverage_repair
|
|
474
|
+
title: "阶段5/22·回填未覆盖主题"
|
|
475
|
+
when: "fileExists('./build/draft_coverage_report.json') && readJson('./build/draft_coverage_report.json', 'ok') == false"
|
|
476
|
+
agent: |
|
|
477
|
+
`./build/draft_coverage_report.md` 列出了原文档里"有章节标题/有客户图表核心结论,但在
|
|
478
|
+
`./build/draft.md` 里找不到对应内容"的主题——这类主题多半靠图片本身说话、原文写得模糊,
|
|
479
|
+
上一步写 draft.md 时被判定"缺乏明确论点"而略过了,但客户图还在等着这些内容配页。
|
|
480
|
+
|
|
481
|
+
必读:
|
|
482
|
+
- `./build/draft_coverage_report.md`
|
|
483
|
+
- `./build/material.md`(找回原文对应段落 + 相关客户图的识图详述/图表核心结论)
|
|
484
|
+
- `./build/draft.md`
|
|
485
|
+
|
|
486
|
+
对报告里每个未覆盖主题:回 `material.md` 找到对应原文段落或客户图的 `key_message`/识图详述,
|
|
487
|
+
提炼成一条论点/证据/例子,**补进 draft.md 现有相关小节,或新增一个简短小节**(用 Edit 或 Write)。
|
|
488
|
+
不要求 100% 覆盖、不要重写全文——只做**尽力而为的单次回填**,把明显遗漏的主题内容找补回来即可,
|
|
489
|
+
别为了凑覆盖率硬灌无实质的空话。
|
|
490
|
+
|
|
491
|
+
完成后简述:回填了几个主题、分别加进了 draft.md 哪个小节。
|
|
492
|
+
allowed_tools: [Read, Edit, Write, Glob]
|
|
493
|
+
maxTurns: 16
|
|
494
|
+
onError: continue
|
|
495
|
+
max_retries: 0
|
|
496
|
+
|
|
497
|
+
# ---------- 阶段3:Web 页面设计文档(替换"大纲"——先设计后实现的核心) ----------
|
|
498
|
+
# 产三份:design.md(人读)+ design.json(机读,驱动分批生成 + 配图分流 + 页数闸门)+ img_plan.json(配图计划)。
|
|
499
|
+
# design.json 比旧 outline.json 更细:每页带 composition(空间构图法)、每内容块 render(视觉表达决策)、
|
|
500
|
+
# visual.prompt(与文案呼应的生图提示词,不再事后搬文案)、background(页面级背景变化意图)。
|
|
501
|
+
# **保留 visual.{route,side,note} 字段名** → 下游 image_plan_lint.py(--outline 参数)直接吃 design.json,零适配。
|
|
502
|
+
- id: stage_design_doc
|
|
503
|
+
title: "阶段6/22·Web 页面设计文档(先设计后实现)"
|
|
504
|
+
when: "fileExists('./build/draft.md')"
|
|
505
|
+
agent: |
|
|
506
|
+
读 `./build/draft.md`,产出一份**详细的 Web 页面设计文档**——这是后续"做网页"的唯一蓝图。
|
|
507
|
+
关键心态:**先把每一页设计清楚(装什么内容、用什么构图、每块怎么呈现、配什么图、背景什么变化),再去实现**。
|
|
508
|
+
不要在本步写 deck.html / 生图(那是后续阶段)。本步只产设计文档 + 配图计划。
|
|
509
|
+
|
|
510
|
+
## -1、先回看用户目标
|
|
511
|
+
先 Read `./build/user_request.md`,确认用户原始输入、素材路径、视觉风格和阶段1澄清结论。后续设计取舍优先满足用户目标,
|
|
512
|
+
不要在长流程里忘掉用户最初说法。
|
|
513
|
+
|
|
514
|
+
## 先读设计规则(单一规则源)
|
|
515
|
+
从系统提示「可用技能」里 ui-design 的【技能目录】,用 Read 读 `references/layout-composition.md`
|
|
516
|
+
(构图法枚举 + 每页内容预算 + 元素渲染决策 + 配图分流 + 生图提示词配方 + 构图均衡)。严格照其执行。
|
|
517
|
+
|
|
518
|
+
## 〇、先盘点「用户原始材料」——决定客户图怎么高权重用(素材驱动的关键)
|
|
519
|
+
**先 Read `./build/material.json`**(富 manifest:每张客户图带 base 字段 + `vision`[识图详述/key_elements/key_region/suitable_as_background/recommended_text_zone] + `stats`[average_color/dominant_colors/tone/brightness],图已在 `./build/assets/`):
|
|
520
|
+
- **有客户图(material.json images 非空)**:**再 Read `./build/source_layout_plan.md`(确定性版式/图生图规划)和 ui-design 技能目录下的 `references/source-image-layout.md`**(客户图布局铁律:全图生图重绘到槽位比例 + 默认 `object-fit:cover` 填满槽、`object-position` 保重点区,仅 dense-info 数据图 contain + 按朝向/重点区图文混排 + 配色随图 + 文字避让重点区 + 宜做背景者铺背景)。
|
|
521
|
+
🚨 **逐图决策已由 `source_layout_plan.md`/`.json` 算定,你【直接照它执行、不要自己重算分辨率/比例】**——每张图它都给了:
|
|
522
|
+
`usage_intent`(用途)、`enhance_required`(是否必须图生图)、`enhance_target_aspect`(目标比例)、`recommended_templates`(推荐图文混排模板,对齐 layout-composition §2.2)、`text_zone`(文字落区,避让重点区)、`text_color`(深墨字/白字)。
|
|
523
|
+
你的工作只剩两件:① **章节锚定配页(治张冠李戴·第一优先级)**:每张客户图先看规划里的 `section`(来源章节)+ `near_text`(原文邻近文案)——**必须配到覆盖该章节内容的页**(客户图是给原文特定章节配的,排到别的主题页 = 张冠李戴);vision.description(识图内容)只用于「该章节对应多页时挑最贴的一页」;**仅当**该章节无对应页、或图无 section(独立散图/页号锚)时,才按 vision.description ↔ key_point 语义契合配页。配好后从 `recommended_templates` 里挑一个落地;② 让该页文案呼应 vision.description、配色随 stats。
|
|
524
|
+
🚨 **图表核心结论必须呼应(治"图配了但论点没对上")**:source_layout_plan 标了 `key_message` 的图(图表/截图/海报类),它所在页的 `key_point`/`evidence` **必须体现该结论**(不是随便配一页了事)——这是 draft.md 阶段已回填的同一条论点,这里只是承接,不是重新判断要不要用它。
|
|
525
|
+
🚨 **原图文字重配(治"带字图去字后信息丢失、或字残留烧死不可编辑")**:source_layout_plan 标了 `embedded_text` 的图(原图上烧着标题/标签/说明文字),图生图阶段已把这些字从图片本身抹掉——若其内容对本页论点有价值(标题句、关键对比标签、结论性说明),必须在该页用**真实 HTML/DOM 文字**重新写出(不必逐字照抄,按 `key_point`/`points` 整合进正文即可);纯水印/logo/无信息量的装饰字判定为噪音,直接丢弃不用管。
|
|
526
|
+
🚨 **硬要求:material.json 里的客户图必须【全部】用进 deck,且严格服从规划的 `enhance_required` / `enhance_style` / `background_kind`**:
|
|
527
|
+
- **plan_source_layout 现已把所有客户图 `enhance_required=true`(全图生图重绘到高清/贴 PPT 风格,唯一例外=无 vision 盲态)**——这些一律 **route=source-enhanced**:deck 引用 `enhanced_src_K.png`,visual 与 img_plan 保留 `source_file:"src_K.png"` 映射;图生图提示词用规划算好的 `enhance_prompt`(在 source_layout_plan.json,明确 style/质量/高分辨率),需贴合该页 key_point 时按 §0.5 微调。
|
|
528
|
+
- 照 `enhance_style` 落地:`bg`=换干净/VI 同色系全幅底图、`hero`=场景主视觉、`cutout`=离散主体抠**透明前景插图**、`dense`=截图/图表**忠实保版面与数据重绘**(best-effort、有重绘风险);`background_kind` real_scene→保场景、flat_base→去底或换 VI 色。
|
|
529
|
+
- **仅极少 `enhance_required=false`(无 vision 盲态)**才 route=source 直接引用 `src_K.png`(small_evidence/contain 小图)。
|
|
530
|
+
用户给了不用是不允许的(后续 source_usage_check 会把原图和增强派生图都纳入用尽检查)。客户图用尽后才考虑纯 AI 图/HTML 图。
|
|
531
|
+
- **无客户图(images 为空 / 无 source_layout_plan)**:按常规(AI 图 + HTML 图)设计,跳过 source 相关字段。
|
|
532
|
+
|
|
533
|
+
## 一、按总-分-总叙事弧分页(页数由内容定,不预设、不硬凑)
|
|
534
|
+
- **总(开篇)**:封面 → 可选目录 → 1 页综述/背景页(综述全文要解决的问题 + 给读者"地图")。
|
|
535
|
+
- **分(主体)**:draft 每个分论点展开成章节页,**一页 = 一个想法**(`one_sentence_takeaway` 一句话说不清这页想法 → 就是两页,拆)。
|
|
536
|
+
🎤 **屏上讲清重点、论证进讲稿**:这是演讲式 PPT 不是文章——观众 **3–5 秒**要能读完一页上屏文字;
|
|
537
|
+
draft 的论证/机制/数据出处写进该页 `speaker_notes`(讲稿字段,导出进 PPT 备注栏),**深度不丢、但不上屏**。
|
|
538
|
+
🚨 **内容多就拆成两页、别死磕一页**(页数不要钱、顶出画布才是灾难):单页内容**严格按 archetype 内容预算**(见 §0.6,
|
|
539
|
+
如 cards 4–6 卡 / list 5–7 条 / split ≤5 条);**超预算就当场拆成 2 页**(同一子观点分上下篇),绝不硬塞致挤压/顶出。
|
|
540
|
+
⚠️ **预算不是软建议**:评审步会跑确定性脚本 `design_budget_check.py` 逐页核对,超预算必被打回改——所以**第一版就按预算设计**,别指望后面补救。
|
|
541
|
+
**目录页 / list 列表页:要点一旦超单列预算(>7 条)默认改双列**(`grid-template-columns:1fr 1fr`,左右各半铺满),别塞窄单列任其顶出底部。
|
|
542
|
+
**能图形化的别堆文字(图文并茂省字)**:流程/对比/层级/数据/关系用 HTML 图表/SVG/图标/卡片表达,一张图顶一段话——
|
|
543
|
+
既省文字又有视觉,是把内容塞进预算的首选手段(不是先写满文字再想怎么塞)。
|
|
544
|
+
**编辑式融合页 ≠ 稀疏页(治「卡片墙主导、不像产品详情页」)**:苹果/大疆产品详情页式的「**图铺满做背景 + 文字浮前景 + scrim**」
|
|
545
|
+
融合页是产品/场景/能力/封面/章节/总结页的**首选默认**——它承载实质文案(前景仍有要点/参数/证据,信息量不减),
|
|
546
|
+
是**有意的编辑式负空间、不是空半/没做完**,**不算「极少文字稀疏页」、不受下面 20% 限额约束、也别再用卡片把它填实**。
|
|
547
|
+
真正要克制的是**纯一句话/金句且无实质**的稀疏页(金句页/极简过渡页),守两条:① 这类纯稀疏页 ≤ 20%;
|
|
548
|
+
② 每张必须配 AI 氛围图 或 渐变色/半透明色底图(在该页 `background` 里写明),避免简陋。其余正文页正常填实(编辑式前景文字 或 卡片/图表均可)。
|
|
549
|
+
- **总(收束)**:1 页总结/展望页。综述页 + 总结页**必须有**。
|
|
550
|
+
|
|
551
|
+
## 二、每页定五件事(设计文档的核心,逐页写清)
|
|
552
|
+
默认 `quality=fast` 时,`design.md` 只写必要页级摘要和关键取舍,主要产出紧凑、可执行的 `design.json` / `img_plan.json`;
|
|
553
|
+
只有 `quality=best` 才写长篇设计解释和更细的审美论证,避免默认链路把时间耗在说明文字上。
|
|
554
|
+
🚨 **产品详情页式硬字段(不写就算设计失败)**:每一页都必须在 `design.json` 里写出
|
|
555
|
+
`one_sentence_takeaway / composition_style / page_grammar / visual_focus / text_zone / safe_text_zone / visual_role /
|
|
556
|
+
primary_visual_type / image_weight / text_overlay_mode / max_visible_words / copy_budget /
|
|
557
|
+
main_visual_layer / supporting_visual_layer / text_overlay_zone / visual_story / semantic_image_prompt / forbidden_layout /
|
|
558
|
+
visual_asset_contract`。
|
|
559
|
+
这些字段是后续构建和确定性检查的主入口,不是备注:
|
|
560
|
+
- `one_sentence_takeaway`:观众一眼要带走的一句话,中文尽量 ≤24 字。
|
|
561
|
+
- `composition_style` 只能取 `product-hero|feature-theater|detail-closeup|scenario-fullbleed|data-visual|gallery-strip|chapter-cinematic|quote-focus`。
|
|
562
|
+
- `page_grammar` 只能取 `hero-scene|cinematic-feature|product-closeup|image-mosaic|spec-overlay|data-visual|before-after-scene`,这是 Apple/DJI 产品详情页式页面语法。
|
|
563
|
+
- `visual_focus`:第一眼视觉焦点,必须是图片、场景、特写、图表或一个明确数字,不许写“文字内容”。
|
|
564
|
+
- `text_zone`:文字净区 ∈ left|right|top|bottom|center,必须避开图片重点区。
|
|
565
|
+
- `safe_text_zone`:真实落字净区,取值同 `text_zone`;必须避让人物、产品、设备、图表主体。
|
|
566
|
+
- `visual_role`:背景图 / 前景透明特写 / 客户图增强 / AI 场景 / HTML-SVG 数据图 / 证据画廊。
|
|
567
|
+
- `primary_visual_type`:ai-background / source-enhanced-background / source-enhanced-hero / transparent-closeup / scene-photo / product-render / html-svg-chart / image-mosaic。
|
|
568
|
+
- `image_weight`:0–1 数字,表示图片/场景/产品/图表视觉重量;产品/场景/特写页通常 0.60–0.90。
|
|
569
|
+
- `text_overlay_mode`:scrim / floating-text / frosted-caption / side-copy / none,说明文字如何贴图,不是分区卡片。
|
|
570
|
+
- `max_visible_words`:本页可见中文字数上限;产品/场景页通常 30–55,数据页最多约 80。
|
|
571
|
+
- `copy_budget`:写 `{title_max,takeaway_max,point_max,note_max}`,用于限制上屏文字;数据页也要写。
|
|
572
|
+
- `main_visual_layer`:主视觉层,必须是具体画面/图表/主体(如 AI 场景底图、客户图增强背景、透明前景特写、HTML/SVG 数据图),不能是“渐变背景”或“文字内容”。
|
|
573
|
+
- `supporting_visual_layer`:辅助视觉层。无客户图的总结/实施/观点页默认写底部锚点 AI 场景、前景特写插图或参数条/图表,不能留空白卡。
|
|
574
|
+
- `text_overlay_zone`:真实文字落区,比 `safe_text_zone` 更具体(如 left-center/bottom-left/right-top),必须避让主体。
|
|
575
|
+
- `visual_story`:这一页第一眼画面如何帮助理解 `one_sentence_takeaway`,一句话说明。
|
|
576
|
+
- `semantic_image_prompt`:页面级最终生图提示词;AI 页必须融合 takeaway、VI、构图、文字净区、图片角色、目标比例和 `no text` 禁令;HTML/SVG 页写 `html-svg:<图表类型>`。
|
|
577
|
+
- `forbidden_layout`:本页禁用项数组,通常包含 `no card wall`、`no table wall`、`no white floating panels`、`no image frame`。
|
|
578
|
+
- `visual_asset_contract`:图片角色契约对象,必须写
|
|
579
|
+
`{background_role,background_asset,foreground_role,foreground_asset,source_file?,enhance_style?}`。
|
|
580
|
+
背景和前景**不得使用同一张图片**;`ai_p<page>.png` 是背景专用,若需要前景 AI 特写/插图,必须单独规划
|
|
581
|
+
`ai_p<page>_fg.png`,并在契约里写 `foreground_asset:"ai_p<page>_fg.png"`。
|
|
582
|
+
🚫 **背景/场景/hero 图零文字铁律**:背景图只负责画面语义和氛围,**不得要求 AI 生成章节序号、1/2/3/4、标签、编号、标题、Logo、界面字或任何可读文字**;这些全部属于 HTML/SVG 可编辑前景层。
|
|
583
|
+
如果页面需要章节序号/步骤编号/参数标签,写在 `visual_asset_contract.foreground_role:"html_svg_marks"` 或 `blocks.render:"html+text"`,**不要写进 `semantic_image_prompt / visual_focus / visual_story` 的背景画面描述**。
|
|
584
|
+
🚫 **没有这些字段的页,后续 `design_style_check.py` 必须打回**;不要只靠 `archetype/composition` 让构建步猜。
|
|
585
|
+
|
|
586
|
+
**0. 先定整页视觉策略(★编辑式最高标准·强制默认,治「卡片墙划区」)**:每页动笔前先从 `layout-composition.md §0「编辑式最高标准」+ §2.2 模板库` 选一种编辑式整页策略——
|
|
587
|
+
**背景主导 / 左右产品剧场 / 上图下文 / 半包围文字 / 参数条+大图 / 中心产品+周围论点**。
|
|
588
|
+
🚨 **强制默认 = 「图打底 + 文字浮前景 + scrim」**(苹果手机/大疆产品详情页范式,**不靠表格/网格/悬浮卡片划分区域**)——**这是最高标准、不是"优先"而是"默认就这么做"**:
|
|
589
|
+
- **每个内容页都必须有背景层(默认高清 AI 图,渐变只作失败兜底)**:① 有客户图(route=source/source-enhanced,**已全部图生图重绘高清**)→ 客户图打底 / 半幅 hero;② **无客户图 → 优先配高清 AI 全幅底图(route=ai-B)**(成本不计、积极生图——产品/物体/环境/使用/操作/抽象观点页都给);③ **仅 AI 生成失败、或极简金句过渡页**才退化用 **VI 同色系渐变 / 纹理 + scrim**。**绝不留"白底 + 卡海"**,文字/图表/要点一律浮在背景层之上。
|
|
590
|
+
🍎 **心智模型(务必内化):背景层【永远有】(客户图 / AI / 兜底渐变),`route` 只决定【前景怎么呈现】(html=前景是 HTML 图表/结构、ai-*=前景或背景是 AI 图、source*=客户图),【不决定有没有背景】**——**别因为「这页主视觉是 HTML 图表 / 纯文字」就给它 `route:none` 当作「这页不要图」**(那正是真机 p3/9/10 退化成白底卡片墙的根因)。有真实画面(产品/场景/操作/使用案例)的页**主动写 `route=ai-B` + 内容提示词**;纯结构页写 `route=html`(前景图表)即可、背景会被阶段9 `--ensure-page-backgrounds` 确定性补一张 VI 氛围底图,**你无需为结构页手写背景**,但也**别用 `route:none` 把整页背景一起取消**。
|
|
591
|
+
- **数据 → 图表**(柱/曲线/进阶时间线/指标胶囊/对比列);**特写 → 插图**(含透明背景前景切图)。
|
|
592
|
+
- **DJI 式网格 ≠ 文字卡片墙**:允许 `page_grammar=image-mosaic` 的多块圆角影像拼贴,但每块必须**图片/产品渲染/镜头剖面/场景图为主体 + 一句短标签浮在图上**;若块里主要是标题+正文+小图标,就是文字卡片墙,必须打回。
|
|
593
|
+
- **卡片墙 / 网格 / 表格 = 罕见例外**:仅「真·并列指标矩阵且无法编辑式表达」时才用,且每'卡'是**图表/指标面板浮在背景上**、禁白底分区卡海(评审步罪状 🅵 逐页抓)。实施路径、总结、决策项、范式对比这类页**不得**用三张白卡总结,必须转成路线图/参数轴/场景叠字/左右 before-after 大场景。
|
|
594
|
+
延用「同类页换不同构图」防单调;少量插图特写走「图像证据卡 / 中心产品」(仍浮在背景上)。
|
|
595
|
+
🚨 **铁律·有底图就别再划区(治 p4 表格+挤图 / p5 五图挤页 / p6 卡墙)**:**凡该页有客户图(route=source / source-enhanced)、或规划了 AI 全幅底图 → 该页【禁用表格、禁用悬浮卡片墙/网格划区】**——
|
|
596
|
+
改成「图打底(出血) + 文字 / 参数条 / 指标胶囊 / 侧栏列表 / 对比列 浮前景 + scrim」,**字色随底图明暗自适应**(`stats.brightness` 深图→白字、浅图→深墨字,见 source-image-layout.md §5)。
|
|
597
|
+
**表格 / 悬浮卡墙只允许出现在「纯 HTML 结构页、且该页无客户图 / 无 AI 底图」**;有底图还套表格/卡墙 = 退回上一代「卡片墙划区」,评审步罪状 🅵 会逐页抓。
|
|
598
|
+
🚨 **过载页按内容分流(混合处理:编辑式 ≠ 把同样多东西全塞到底图上)**:一页元素超 archetype 预算时按内容类型分两路——
|
|
599
|
+
**数据 / 对比 / 矩阵页(如范式对比、成本结构)→ 拆成两页(同子观点分上下篇)或转成图表/对比列,保全内容**;
|
|
600
|
+
**叙事 / 能力 / 场景页(如多场景客户图)→ 整合为一张 hero 大图打底 + 概要前景(要点强调重点、次要元素下沉/合并),同页绝不堆叠多张大图**。两类各按合适方式,既不挤、又不丢实质。
|
|
601
|
+
**0.5 动笔前三问 + 苹果式精辟文案(深度理解长文 + 画像 → 每页一句话抓重点)**:
|
|
602
|
+
每页先三问定 render:① 这一页第一眼应该看到什么画面/图表?② 有无可画的物体/场景/产品/操作/安装/使用案例 → 优先 `text+image` 或 `html+text+image`(**图承载内容**,HTML 画不出的真实画面积极 AI 生图,不考虑成本费用)?③ 有无数据/对比/流程 → 优先 HTML **图表**(数据可视化,非表格/卡墙)?
|
|
603
|
+
**文案 = 重点概括 + 必要补充,绝不搬全文**(像苹果 MacBook Pro 详情页:标题 = 一句精辟洞察一眼看懂,背景图/前景插图承载画面,图表承载数据,正文只做必要补充)。
|
|
604
|
+
**`key_point` 按【用户画像/受众】精炼**(读 `user_request.md` 的受众 + 术语深度档):高管速读 → 数字与决策意义先行、一句话可转述;专业受众 → 精确术语;入门 → 类比开路、避免黑话。**每页一眼抓住重点、不堆长定义**。
|
|
605
|
+
**识图×文案对应(图生图微调)**:把客户图配到页后,核对 `vision.description`(识图内容)与该页 key_point 的对应度——若需更贴文案的具体主体/场景,**在 design.json `visual.prompt` 里微调 `enhance_prompt`**(plan_source_layout 给的是基础提示词,设计步据实际文案精修;明确 style/质量/高分辨率)。
|
|
606
|
+
1. **archetype 版式原型** ∈ cover|section|split|cards|metric|fullbleed|list(见 layout-composition.md「0.6 内容预算」表)——**内容页编辑式默认走 split/fullbleed/section/list/metric(图打底 + 前景浮层);`cards` 已降为罕见例外、默认别选**(并列要点先用编辑式前景浮层或图表,见 layout-composition.md §0 + §0.6)。
|
|
607
|
+
2. **composition 空间构图法** ∈ 左右 | 左中右 | 上下 | 上中下 | 四宫格 | 中心辐射 | 全幅浮层(见 layout-composition.md「六种构图模式」+ 补充构图法)——
|
|
608
|
+
**同类页要换不同构图,避免页页一个样**。
|
|
609
|
+
3. **实质内容**:`key_point`(一句话核心论点)+ `evidence`(支撑事实/数据/机制 1–3 条,带信息时点——
|
|
610
|
+
**evidence 是图表与讲稿的原料,不是 points 的原料池**,别整条搬上屏);
|
|
611
|
+
`points` 是上屏文案草案,**默认短语/数字标签(≤14 字,每条承载具体主张/事实,禁空话填充)**——
|
|
612
|
+
影像叙事页(hero-scene/cinematic-feature/product-closeup/before-after-scene)**≤3 条且每条 ≤20 字**(style_check 会拦超载);
|
|
613
|
+
`speaker_notes`(**每个内容页都写,1–3 句讲稿**):论证展开/机制解释/数据出处放这里,导出进 PPT 备注栏供演讲者用。
|
|
614
|
+
⚠️ **对账铁律**:takeaway+points 实际字数不得超本页自声明的 `max_visible_words`(style_check 逐页对账)——
|
|
615
|
+
**朗读测试:这页上屏文字 3–5 秒读得完吗?读不完就短语化/交给图表/移入讲稿/拆页。**
|
|
616
|
+
4. **每个内容块的 render 渲染决策** ∈ text(纯文字)| html+text(HTML元素[卡片/色块/图标/分隔]+文字)|
|
|
617
|
+
text+image(文字+AI插图)| html+text+image —— **依内容性质决定,编辑式优先(html+text 卡片不再是自动默认)**:
|
|
618
|
+
产品/场景/能力/真实画面/叙事内容 → **优先 `text+image`/`html+text+image`,图作背景或半幅 hero、文字作前景浮层**(编辑式融合,别拆成卡片墙);
|
|
619
|
+
**真正并列的数据/对比/成本/效率/时间变化** → html+text,**优先图表化(柱/曲线/进阶时间线/指标胶囊/对比列)而非表格**——**表格是最后手段**(仅确为多维矩阵、且该页无客户图/无 AI 底图时才用,且绝不与大图/底图同页争位)。
|
|
620
|
+
柱状图、折线图、进阶时间线、流程图、架构图、对比矩阵、指标胶囊等结构性表达必须 HTML/CSS/SVG(绝不当 AI 图生)、数据优先图表化、表格仅作兜底;安装图、产品使用场景图、车间/航空器/设备场景图、真实物体图,若客户图没有合适素材,优先文生图;客户图低清但内容重要则图生图。
|
|
621
|
+
5. **每页 ≥1 视觉元素(铁律,区别于 Word)**:没 AI 配图的页也要有 SVG 图表 / 图标组 / 装饰几何 / 色块结构,增页面活力、
|
|
622
|
+
也让构图不空。纯文字 + 背景板的页不允许。
|
|
623
|
+
6. **放映级可读性 / 分布 / 对比(设计阶段就定好,别留给实现踩坑)**——在 design.md 逐页写明:
|
|
624
|
+
- **标题精简 + 跨页对齐**:每页 `title` 精简到一行(**内容页 ≤14 字、封面 ≤12 字**——长了 Office 重折行会顶出/压副标,评审步 design_budget_check 会拦【标题过长】);内容页主标与副标统一**左对齐**(实现走统一 header 约定,各页一致)。
|
|
625
|
+
- **字号档**:各块按 layout-composition §0.85 放映级阶梯(≈1.5×:正文 ≥38px、注释 ~30px、图内文字同标准且图形画大装下;只有封面主标/章节大序号不放大)。
|
|
626
|
+
- **分布占满画布**:稀疏页(尤其 list/目录)选**满宽构图**(双列 或「文字+侧栏视觉」),别规划成挤左单列右半空。
|
|
627
|
+
- **全页文字对比**:每页文字与底色高对比——**浅底配深墨字、深底配白/浅字,绝不深底深字/浅底浅字**(VI 深色只用于封面/章节且文字转白);封面底图亮暗不可控,文字方案=深字+浅磨砂板 或 白字+足够暗 scrim(见 §1.B)。
|
|
628
|
+
- **文案精炼·说人话**:每条要点精炼归纳、用类比/例子讲透(近似但好懂优于堆砌精确),别规划成一页塞一堆长定义(后续必顶出/缩字)。
|
|
629
|
+
- **文字皆真实 DOM 文本**:规划时就别把可读文字设计进 `::before/::after`/烧进图(除 AI 插图自带字外),保证可隐藏可编辑。
|
|
630
|
+
- **可拖结构 = 离散 HTML 元素**:架构层/流程节点/决策树/一排圆/卡片矩阵规划成「每块一个 div」(导出递归切成各自可拖对象),别规划成整块 SVG(节点不可拆);SVG 只画连线/真矢量。
|
|
631
|
+
- **卡片填实 + 不溢出**:卡/底板按内容定尺寸别留大片空白;一列层块/节点别堆到高过画布(多就拆栏/拆页)。
|
|
632
|
+
|
|
633
|
+
## 三、配图意图 + 与文案呼应的生图提示词(治"提示词搬文案")
|
|
634
|
+
- 🆕 **产品/客户视觉身份锚(治"文生图配图跑题变成另一个产品",2026-07-07 真机 p9 复盘)**:PPT 正文为求简洁常省略
|
|
635
|
+
主语(如"拆除 WiFi 模块"不会每页重复"全景相机"),但生图提示词若只抓该页孤立名词、不带住这份 deck 真正
|
|
636
|
+
在讲的客户/产品,AI 会凭空生成一个无关设备(真机事故:安防定制页画出通用电路板/工控盒小机箱,而非客户
|
|
637
|
+
真实产品外观)。**写 design.json 前先通读 `build/vision/*.json` 里 `content_type=="photo" &&
|
|
638
|
+
relevant_to_topic==true` 的条目**,找出真正展示"客户自己产品实物"的那(几)张(通常 description 会写
|
|
639
|
+
"实物"/机身颜色/logo/型号等具体外观特征,区别于场景/环境类照片),提炼一句**只写物理外观、不写文字/logo/
|
|
640
|
+
型号字样**的产品视觉描述(如 "a compact panoramic camera unit, matte black cylindrical housing with a
|
|
641
|
+
red accent ring around the lens"),连同客户/行业身份(如"沈阳泰科易,服务航空制造客户的全景影像档案
|
|
642
|
+
系统")一起写进 `design.json` 顶层 `deck_meta:{"product_identity":"...","customer_context":"..."}`
|
|
643
|
+
(**整份 deck 只写一次,不必每页重复**——下游 `image_prompt_rewrite.py` 会自动把它拼进**每一张** AI 生图
|
|
644
|
+
(ai-A/ai-B)提示词,即使该页文案本身没提产品名也不受影响)。**没有真实产品照/纯示意主题时留空字符串
|
|
645
|
+
即可**,不得凭空编造。
|
|
646
|
+
- 🆕 **产品页优先复用真实产品照而非凭空生图**(同上真机复盘):若某页画面主体本质上仍是"客户自己的产品"
|
|
647
|
+
(即便讲的是这个产品的新场景/新配置,如安防定制、极端环境,只是没恰好拍到这个具体场景的原图),且
|
|
648
|
+
material.json/vision 里已有该产品的清晰实物照 → **优先 route=source-enhanced 复用那张实物照做图生图**
|
|
649
|
+
(`enhance_prompt` 里说明新场景/新语境),而非 route=ai-* 凭空文生图(生图模型没见过客户真实产品长什么样,
|
|
650
|
+
文生图会画出完全不同的设备)。只有画面主体确实是**产品之外**的场景/环境/抽象概念(机房环境、安全氛围、
|
|
651
|
+
行业场景)且客户没有相关素材时才用 route=ai-* 纯文生图,此时靠上面的 `product_identity` 锚保证画面里
|
|
652
|
+
若出现产品元素仍与客户实物外观一致。
|
|
653
|
+
- **客户图优先且必须全用(现已【全部 route=source-enhanced 图生图重绘】;最高优先级)**:material.json 的客户图是高权重资产,
|
|
654
|
+
**先按 `section`(来源章节,见 source_layout_plan)锚定到覆盖该章节内容的页,章节内再按 vision.description ↔ key_point 挑最契合页**(无 section / 该章节无对应页才纯语义配;source_usage_check 有【图片章节错位】确定性核对),带 `source_file` + `enhanced_file` + `aspect`(=槽位目标比例) + `orient` + `side`(横图→top/bottom、竖图→left/right);**suitable_as_background=true 的图**铺整页背景(文字落 recommended_text_zone)。
|
|
655
|
+
**该页文案要呼应 vision.description(别配与画面无关的话);该页配色参考 stats.dominant_colors/brightness(深图白字、浅图深字,见 source-image-layout.md §5)。**
|
|
656
|
+
**所有客户图都走 `visual.route="source-enhanced"`**(plan_source_layout 已全设 `enhance_required=true`):visual 带 `source_file:"src_K.png"`、`enhanced_file:"enhanced_src_K.png"`、`aspect`、`prompt`(用规划 `enhance_prompt`、按 `enhance_style` 重绘到高清/换 VI 底/抠透明/忠实保数据,按页 key_point 微调;明确 style/质量/高分辨率);对应 `img_plan.json` 写 `mode:"image-to-image"`。enhanced 图用 `.fig-fill` `object-fit:cover` **填满槽**(见 build_batch)。
|
|
657
|
+
其中 `enhance_style=cutout` 的客户图必须写进 `visual_asset_contract` 为 `foreground_role:"source_cutout"`,它是透明前景特写,不能做背景、不能裱白卡、不能 padding/border 包装。
|
|
658
|
+
生图失败兜底:reconcile 脚本自动 cp 原图顶上(不留死链);唯一 `enhance_required=false`(无 vision 盲态)才 route=source 直接引用 `src_K.png`。
|
|
659
|
+
🚨 **每张客户图都必须落到某页**(增强图或兜底原图);能用客户图担的页就别再叫纯 AI 图。
|
|
660
|
+
- **配图分流**:示意/图表/流程/架构/分层/树/决策树/时间线/关系/观点分块/分类对比 → 一律 HTML(route=html,不生 AI 图)。
|
|
661
|
+
AI 图(route=ai-A/ai-B)只给:客户图覆盖不到、且封面/章节/总结氛围大图、产品/物体外观/线条图/使用·安装演示、真实场景、文字与 HTML 都画不清的画面。
|
|
662
|
+
- 🍎 **一页一主视觉·背景前景禁同主体重复(2026-07-03 真机第3页事故)**:背景已是该主题的实景/氛围大图时,
|
|
663
|
+
前景**禁止**再排同主体的图片卡/特写卡(背景驾驶舱+前景再插 3 张驾驶舱特写 = 重复堆料,与 Apple/DJI
|
|
664
|
+
「视觉优先、简洁但不简单」直接冲突)——前景改放数据/图形/结论文字或干脆留白让背景呼吸;
|
|
665
|
+
确需多图对比时背景退成低干扰氛围(弱化/虚化/暗角),别两层抢戏。
|
|
666
|
+
- **AI 生图积极性 = `${inputs.image_intensity}`**(质量优先;除 `illustrations=0` 明确禁用外,不以成本费用为约束):
|
|
667
|
+
- **共同底线(balanced/rich 必守,治「封面空洞无背景」)**:**封面、每个章节分隔页、尾页【必出】AI 氛围背景**(route=ai-B 全幅底图 + scrim/磨砂文字板),不是「可用」是「必出」——封面裸黑+淡网格、内容沉底是事故。
|
|
668
|
+
- 🚨 **每个内容页都必须有背景层(★编辑式最高标准·治「白底卡海」)= 默认高清 AI 图**:有客户图→客户图(已全图生图高清)打底;**无客户图→优先配高清 AI 全幅底图(route=ai-B,成本不计、积极生图)**;**仅 AI 生成失败、或极简金句过渡页**才退化用 **VI 同色系渐变 / 纹理 + scrim**。**没有任何内容页是裸白底 + 一堆卡片**——文字/图表/要点一律浮在背景层之上。
|
|
669
|
+
- **minimal**:仅用户强制少图时使用;封面/章节/尾页仍必出 AI 氛围大图;正文页可多用 HTML/SVG,但仍必须有背景层。
|
|
670
|
+
- **balanced**:封面/章节/尾页 + 真实画面/场景/物体/概念隐喻页必须配 AI 图。
|
|
671
|
+
- **rich(默认)**:最佳质量模式。内容较少的观点页也配低干扰 AI 背景或底部锚点场景;应用场景、安装、产品外观、真实使用情境、决策收束页**优先文生图/图生图补足画面**,不能只留抽象渐变或三张白卡。
|
|
672
|
+
⚠️ **任何档都守红线**:**结构图(架构/分层/流程/决策树/对比/时间线/关系)永远 HTML/SVG、绝不当 AI 图生**(image_plan_lint 会拦);积极性只放大「画面/氛围/物体/隐喻」类 AI 图的量,不碰结构图。
|
|
673
|
+
- ⚠️ **严禁把结构图伪装成"抽象背景"用 AI 生**:凡承载可命名结构(层级/步骤/分支/并轨/对比/架构/流程/树/拓扑/时间线)即便在
|
|
674
|
+
section/cover 页也 route=html。route=ai-* 的 prompt/note **只许写画面/光影/质感/物体/隐喻,不得出现** 架构/分层/流程图/
|
|
675
|
+
决策树/双轨/对比图 等结构名词(下游 image_plan_lint 会拦截违规并回退 HTML)。
|
|
676
|
+
- **生图提示词不是搬文案**:对每张 AI 图,先想"这一页 key_point 对应的**具体可画主体/场景/实物**是什么",再写**英文**提示词——
|
|
677
|
+
画出与文案呼应的具体对象(如「a circuit board close-up with labeled capacitors」而非「technology background」);
|
|
678
|
+
**配色解耦**:B 路线全幅底图跟所选 VI 色调走,**A 路线内容插图以画面真实色为准**(电路板=铜绿、产品=本色),只需与 VI 协调不冲突、别强染成 VI 单色致配图失真;
|
|
679
|
+
A 路线半幅图让主体填满画面(`subject fills the frame`、不要 airy)、仅 B 路线全幅封面在文字侧留低对比净空带;
|
|
680
|
+
**结尾必须含 `no text, no words, no letters, no captions, no logos`**。比例由槽位几何定(全幅16:9/左右半4:5/上下横幅21:9/卡片4:3或1:1)。
|
|
681
|
+
- **图表/HTML 配图配色(配色解耦)**:route=html 的图表(柱/饼/折线/进度环)与辅助解释图形**用可区分的数据系列分类色**
|
|
682
|
+
(见所选 VI 文档「数据可视化分类色」+ layout-composition §0.9),别全用 VI 主色一种致数据系列分不清;VI 只管背景/底板/chrome/主强调色。
|
|
683
|
+
|
|
684
|
+
## 四、背景变化意图(治"各页背景雷同")
|
|
685
|
+
读所选 VI 的 `references/vi-<name>.md`(尤其「页面级背景变化」一节),为每页写 `background` 意图——
|
|
686
|
+
**在同色系内做深浅/邻近色/光位变化**(如封面/章节页偏深或带 AI 氛围图、内容页冷白、相邻页换径向光位置或渐变角度),
|
|
687
|
+
**相邻页不要完全一样**;但不破坏色系一致(仍是同一 VI)。
|
|
688
|
+
|
|
689
|
+
## 五、产物(严格落这些路径)
|
|
690
|
+
1. 用 Write 写 `./build/design.md`(人读):逐页 `## 第N页 · <标题>` + archetype + composition + key_point + 要点 +
|
|
691
|
+
各块 render + 配图说明 + 背景意图,便于人复核。
|
|
692
|
+
2. 用 Write 写 `./build/design.json`(机读,**严格 JSON、无注释、无 ``` 包裹**):
|
|
693
|
+
- 可以写成多行缩进的漂亮 JSON;下一阶段会用 `normalize_design_json.py` 做硬解析、规范化和结构验收。
|
|
694
|
+
不要追求单行大 JSON;单行过长更容易被弱模型写坏。**但必须是真 JSON:不能有注释、Markdown、尾随解释文字。**
|
|
695
|
+
- 字段精炼(key_point/points/evidence/note/prompt 都用短句,别灌长文);下面是**字段结构示例**:
|
|
696
|
+
`{"deck_meta":{"product_identity":"<客户真实产品的物理外观描述,纯英文、只写形状/颜色/材质,不写文字/logo/型号;无真实产品照留空字符串>","customer_context":"<客户与行业身份简述;无特定客户留空字符串>"},"pages":[{"page":1,"archetype":"cover","composition":"中心辐射","composition_style":"product-hero","page_grammar":"hero-scene","one_sentence_takeaway":"...","visual_focus":"...","text_zone":"center","safe_text_zone":"center","visual_role":"AI 场景背景","primary_visual_type":"ai-background","image_weight":0.82,"text_overlay_mode":"scrim","max_visible_words":38,"copy_budget":{"title_max":12,"takeaway_max":24,"point_max":0,"note_max":24},"main_visual_layer":"AI 全幅场景底图","supporting_visual_layer":"底部设备剪影","text_overlay_zone":"left-center","visual_story":"用与本页主题匹配的真实场景让观众先看到结论落地环境","semantic_image_prompt":"page-specific realistic scene derived from this slide topic, wide clean text-safe area on the left, high-end product-detail-page mood, no text, no words, no letters, no captions, no logos","forbidden_layout":["no card wall","no table wall","no white floating panels","no image frame"],"visual_asset_contract":{"background_role":"ai_background","background_asset":"ai_p1.png","foreground_role":"none","foreground_asset":""},"title":"...","key_point":"...","evidence":["..."],"points":["..."],"speaker_notes":"<1–3 句讲稿:论证展开/机制/数据出处,导出进 PPT 备注栏>","blocks":[{"content":"...","render":"html+text"}],"visual":{"route":"ai-B","side":"full","note":"<画什么,中文,扣紧 key_point>","aspect":"16:9","prompt":"<与文案呼应的英文提示词,含 no text 尾巴>"},"background":"<本页背景变化意图>"}]}`
|
|
697
|
+
- `page` 从 1 连续编号(**供分批页数闸门 deck_pages_check 比对,必填**)。
|
|
698
|
+
- `archetype` ∈ cover|section|split|cards|metric|fullbleed|list;`composition` ∈ 左右|左中右|上下|上中下|四宫格|中心辐射|全幅浮层。
|
|
699
|
+
- `composition_style` 必填,且只能取 `product-hero|feature-theater|detail-closeup|scenario-fullbleed|data-visual|gallery-strip|chapter-cinematic|quote-focus`;`cards` archetype 只有在 `composition_style=gallery-strip` 或少量指标浮层时才可用,不能当普通正文页默认。
|
|
700
|
+
- `page_grammar` 必填,且只能取 `hero-scene|cinematic-feature|product-closeup|image-mosaic|spec-overlay|data-visual|before-after-scene`。`image-mosaic` 允许多图 rounded tile,但每块必须图片为主体、短标签浮在图上,禁止文字卡片网格。
|
|
701
|
+
- `one_sentence_takeaway / visual_focus / text_zone / safe_text_zone / visual_role / primary_visual_type / image_weight / text_overlay_mode / max_visible_words / copy_budget / main_visual_layer / supporting_visual_layer / text_overlay_zone / visual_story / semantic_image_prompt / forbidden_layout / visual_asset_contract` 必填;`visual_focus` 不是“文字”,必须是画面、主体、图表或数字焦点。
|
|
702
|
+
- `route` ∈ html|ai-A|ai-B|source|source-enhanced|none;`side` ∈ left|right|top|bottom|full|none;`render` ∈ text|html+text|text+image|html+text+image。
|
|
703
|
+
**AI 图片命名契约**:`side=full` 的 ai-* 是背景图 `ai_p<page>.png`;`side=left/right/top/bottom` 的 ai-* 是前景图 `ai_p<page>_fg.png`。
|
|
704
|
+
`ai_p<page>.png` 只能进 `.edit-bg`,绝不放进前景 `<img>`;前景需要 AI 特写/插图时必须单独用 `ai_p<page>_fg.png`,避免背景/前景重复。
|
|
705
|
+
⚠️🍎 **内容页避免 `route:none`**(route 只描述【前景类型】、不代表「无背景」——背景层恒由约定名 `ai_p<page>.png` + 阶段9 兜底保证):有画面→`ai-B`、纯结构→`html`、有客户图→`source*`;`none` 仅留给「连前景视觉都没有」的极罕见页,且该页背景仍会被阶段9 自动补 VI 氛围底图(绝不会因 route:none 而变白底卡墙)。
|
|
706
|
+
- **route=source(仅无 vision 盲态原图直接用,罕见)**:visual 额外带 `source_file`(=manifest 的 file,如 src_1.png)+ `aspect_ratio`(=manifest)+ `orient`(landscape/portrait/square)+ `usage_intent`(direct_contain/small_evidence/gallery),side 据 orient 选(横→top/bottom、竖→left/right),`object-fit:contain` 保原貌;不需 prompt(build 步会按 source_file 去 material.json 取识图/统计/重点区做精细排版)。
|
|
707
|
+
- **route=source-enhanced(客户图增强)**:visual 额外带 `source_file`(原图,如 src_1.png)+ `enhanced_file`(如 enhanced_src_1.png)+ `usage_intent`(source_enhanced_bg/source_enhanced_hero)+ `aspect` + `prompt`,用于图生图增强;deck 引用 enhanced_file,但用尽闸门仍按 source_file 计入客户图使用。
|
|
708
|
+
⚠️ **`aspect` 必须 = 该图所在槽位的比例**(你为它选的模板/grid 单元决定,如全幅背景 16:9、左右半 4:5、上下横带 21:9)——图生图据此**重绘到槽位所需比例/分辨率**,落进槽位**正好填满、不留白不裁切**;`prompt` 用 `source_layout_plan.json` 里算好的 `enhance_prompt`(保留原图内容 + 高清重绘 + 缺失区域智能补全),别自己另写。
|
|
709
|
+
- `key_point` 每页必填;`evidence` 内容页必填、封面/章节页可 [];route=ai-* 或 source-enhanced 才需 visual.prompt(route=source 用 source_file、不需 prompt)。
|
|
710
|
+
- `speaker_notes` 内容页建议必写(封面/章节可省):**演讲讲稿**,把 draft 的论证/机制/出处收进来——它是「上屏短语化」的另一半,没有它深度就只能塞上屏。不计入 max_visible_words。
|
|
711
|
+
3. 用 Write 写 `./build/img_plan.json`(机读,配图计划):**只写 route=source-enhanced 客户图增强条目**(best-effort——阶段9 `--ensure-img-plan` 还会从 source_layout_plan 兜底 union,写不全没关系)。
|
|
712
|
+
🚫 **route=ai-A/ai-B 的 AI 底图条目【不用你写进 img_plan】**——阶段9 `--ensure-ai-img-plan` 读 design.json 按**约定名 `ai_p<page>.png`** 确定性注入(弱模型手写 ai-* 易整批丢失 / 起错名致重复生两张,故收归确定性);你只要把 `route`/`prompt`/`aspect` 写进 design.json 的 `visual` 即可,文件名由约定派定。
|
|
713
|
+
(`illustrations=${inputs.illustrations}`:-1=由内容定、0=不主动配 AI 图;N>0=AI 图不超 N,source-enhanced 不计入浪费额度),图生图增强每条:
|
|
714
|
+
- 图生图增强:`{"file":"enhanced_src_K.png","mode":"image-to-image","source_file":"src_K.png","aspect":"<目标比例>","prompt":"<扩图/换背景/清晰化/比例修复提示词>"}`
|
|
715
|
+
⚠️ **只要有任何 route=ai-* 或 source-enhanced 页 → 必须写出 `./build/img_plan.json`(无客户图增强就写 `[]` 空数组也行)**,保证阶段9 闸门触发、ai-* 被注入;纯示意主题且零 AI/客户图才可不写此文件。
|
|
716
|
+
|
|
717
|
+
完成后简述:共几页、是否含综述+总结页、各页 archetype+composition、其中几页 route=source/source-enhanced(客户图)/ai-A/ai-B、img_plan.json 几条。
|
|
718
|
+
allowed_tools: [Read, Write, Glob]
|
|
719
|
+
maxTurns: 20
|
|
720
|
+
capture: design_notes
|
|
721
|
+
done_when: "fileExists('./build/design.md') && fileExists('./build/design.json')"
|
|
722
|
+
onError: halt
|
|
723
|
+
# 重活步(读长 draft+layout+vi、出 16 页 JSON)拥塞下首字节延迟易撞空闲超时 → 给 2 次 in-run 重试吸收瞬态拥塞。
|
|
724
|
+
max_retries: 2
|
|
725
|
+
|
|
726
|
+
# ---------- 阶段4:对抗评审设计文档(回顾原始需求,挑刺并修订定稿;全自动、无人工打断) ----------
|
|
727
|
+
# 设计文档定稿前的质量闸门:换一个挑剔的评审视角,对照用户**原始需求**逐条审 design.json/md,
|
|
728
|
+
# 当场修订到位。不引入人工 pause(webppt 定位=一句话自动产出);不重跑研究,只打磨设计文档。
|
|
729
|
+
- id: stage_design_json_gate
|
|
730
|
+
title: "阶段7/22·设计 JSON 硬验收 + 确定性预检"
|
|
731
|
+
when: "fileExists('./build/design.json')"
|
|
732
|
+
tool: Bash
|
|
733
|
+
args:
|
|
734
|
+
command: |
|
|
735
|
+
set -e
|
|
736
|
+
mkdir -p ./build
|
|
737
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build ./build
|
|
738
|
+
test -f ./build/design_json_ok
|
|
739
|
+
BUDGET_LOG=./build/design_budget_check.txt
|
|
740
|
+
STYLE_LOG=./build/design_style_check.txt
|
|
741
|
+
set +e
|
|
742
|
+
python3 skills/ui-design/scripts/design_budget_check.py ./build/design.json -v > "$BUDGET_LOG" 2>&1
|
|
743
|
+
BUDGET_STATUS=$?
|
|
744
|
+
python3 skills/ui-design/scripts/design_style_check.py ./build/design.json -v > "$STYLE_LOG" 2>&1
|
|
745
|
+
STYLE_STATUS=$?
|
|
746
|
+
set -e
|
|
747
|
+
export BUDGET_STATUS STYLE_STATUS
|
|
748
|
+
python3 - <<'PY'
|
|
749
|
+
import json
|
|
750
|
+
import os
|
|
751
|
+
from pathlib import Path
|
|
752
|
+
|
|
753
|
+
build = Path("./build")
|
|
754
|
+
budget_status = int(os.environ.get("BUDGET_STATUS", "1"))
|
|
755
|
+
style_status = int(os.environ.get("STYLE_STATUS", "1"))
|
|
756
|
+
budget_log = (build / "design_budget_check.txt").read_text(encoding="utf-8", errors="replace")
|
|
757
|
+
style_log = (build / "design_style_check.txt").read_text(encoding="utf-8", errors="replace")
|
|
758
|
+
ok = budget_status == 0 and style_status == 0
|
|
759
|
+
report = {
|
|
760
|
+
"ok": ok,
|
|
761
|
+
"budget_ok": budget_status == 0,
|
|
762
|
+
"style_ok": style_status == 0,
|
|
763
|
+
"budget_status": budget_status,
|
|
764
|
+
"style_status": style_status,
|
|
765
|
+
"budget_log": budget_log[-12000:],
|
|
766
|
+
"style_log": style_log[-12000:],
|
|
767
|
+
}
|
|
768
|
+
(build / "design_review_checks.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
769
|
+
(build / "design_review_checks.md").write_text(
|
|
770
|
+
"# 设计文档确定性预检\n\n"
|
|
771
|
+
f"- budget_ok: {report['budget_ok']} (status={budget_status})\n"
|
|
772
|
+
f"- style_ok: {report['style_ok']} (status={style_status})\n"
|
|
773
|
+
f"- ok: {ok}\n\n"
|
|
774
|
+
"## design_budget_check\n\n```text\n" + budget_log[-12000:] + "\n```\n\n"
|
|
775
|
+
"## design_style_check\n\n```text\n" + style_log[-12000:] + "\n```\n",
|
|
776
|
+
encoding="utf-8",
|
|
777
|
+
)
|
|
778
|
+
print("DESIGN_REVIEW_PRECHECK_OK" if ok else "DESIGN_REVIEW_PRECHECK_ISSUES")
|
|
779
|
+
PY
|
|
780
|
+
onError: halt
|
|
781
|
+
|
|
782
|
+
- id: stage_design_review
|
|
783
|
+
title: "阶段8/22·对抗评审设计文档(短修订)"
|
|
784
|
+
when: "inputs.quality == 'best' && fileExists('./build/design_json_ok')"
|
|
785
|
+
agent: |
|
|
786
|
+
你是一名挑剔的**设计评审 + 内容总监**,对刚产出的 Web 页面设计文档做**对抗式审查并当场修订定稿**。
|
|
787
|
+
先 Read `./build/user_request.md`、`./build/design_review_checks.md`、`./build/design.md` 与 `./build/design.json`,
|
|
788
|
+
再按需 Read `./build/material.json`、`./build/source_layout_plan.json`(确定性版式/图生图规划——逐张核对设计是否服从它)。
|
|
789
|
+
|
|
790
|
+
## 最高裁决顺序:非破坏性评审,防止把好设计改坏
|
|
791
|
+
本步是**非破坏性评审**:你可以修 `design.json`,但只能修**证据明确**违反下面顺序的地方,不能为了"空"、"不满"、
|
|
792
|
+
"看起来没填满"而把 Apple/DJI 式影像叙事改成卡片、表格、浮动白/灰面板。
|
|
793
|
+
最高裁决顺序:
|
|
794
|
+
1. 用户原始输入与 `build/user_request.md`(目标、受众、素材、风格偏好)。
|
|
795
|
+
2. `ui-design` 产品详情页式规则(图文融合、中文可读、三层导出、客户图策略)。
|
|
796
|
+
3. Apple/DJI 式「图片/场景/产品为主视觉,文字浮在净区」;合理留白、大图背景、少量前景文案是合格目标,不是错误。
|
|
797
|
+
4. 客户图 `source-enhanced` 与 AI 配图策略;无客户图的场景/产品/操作页积极 AI 生图。
|
|
798
|
+
5. 内容预算、可读性、越界、重叠、图片变形等工程检查;这些只用于防文字过量和硬错误,不驱动页面填满。
|
|
799
|
+
内容预算只限制**文字过量/顶出画布**,不要求填满页面。
|
|
800
|
+
|
|
801
|
+
明确禁止:
|
|
802
|
+
- 禁止为了填满页面新增卡片墙、表格墙、浮动白/灰面板。
|
|
803
|
+
- 禁止把影像叙事页改成文字列表页。
|
|
804
|
+
- 禁止把 Apple/DJI 式大图主视觉改成多块等权信息块。
|
|
805
|
+
- 禁止凭感觉改;每次改动必须指到具体页号、违反哪条、证据是什么。
|
|
806
|
+
- 拿不准就保留原设计,写入"存疑,交末端构图门复核",不要硬改。
|
|
807
|
+
|
|
808
|
+
## 第零步:只读预检报告,不再自己跑脚本
|
|
809
|
+
`./build/design_review_checks.md/json` 已由上一步确定性生成,里面包含 `design_budget_check.py` 与 `design_style_check.py`
|
|
810
|
+
的结果。你只根据报告中的明确问题修 `design.json`/`design.md`:
|
|
811
|
+
- budget 问题:只修文字过量、标题/要点过长、可能顶出画布;**不为填满页面加内容**。
|
|
812
|
+
- style 问题:只修缺字段、卡片墙/大表格/文字墙、缺主视觉、缺客户图增强或缺 AI 主视觉。
|
|
813
|
+
- 报告为 OK 时,只做用户目标、客户图、Apple/DJI 图文融合的快速抽查;没有证据就不改。
|
|
814
|
+
|
|
815
|
+
## 第一遍:罪状质问清单(⚠️ 预设你有罪,逐条用事实自证)
|
|
816
|
+
**铁律一(治"问好吗必答好"的确认偏误)**:**默认假设你已经犯了下面每一条错**,逐条**主动去量证据**(内容内边距 px / 槽位占比 / 字数 / 逐图字段 / design_budget_check 结果)核对——别自我表扬、别"总体不错/基本合理"放过;这里**只问"你是不是又犯了 X"**,逼你真去查、别想当然说没问题。
|
|
817
|
+
**铁律二(治"胆小 AI 把对的改错"的过度修正——同等重要)**:**「自证」是拿事实/数字核对、不是为交差硬找错**。每条处理 = 「**质问 → 量出证据 → 只有证据坐实违规才改,且必须指到具体哪页/哪图/超了多少;证据显示没问题就明确判『此条通过』、原样保留**」。
|
|
818
|
+
**无依据的改动比漏判更糟**(会把本来对的改坏):拿不准、光看 design.json 量不出确凿违规的(如纯渲染期才知道的文字溢出),**默认保留不动 + 记一句"存疑,交末端构图门复核"**,**绝不**凭"感觉可能有问题"去动对的东西。改对的 = 倒扣分,不是尽职。
|
|
819
|
+
逐条过这份「长期累积的真实失败模式」罪状清单(**每条都先量证据**),**唯有证据坐实违规**才改 design.json:
|
|
820
|
+
- 🅰 **标题贴边/不对齐/超界**:你内容页主标是不是又贴到画布最左边了(离左边线 < 约定的内容内边距 96–112px)?主标与副标、与其它各页是否在**同一条左竖线**上?标题有没有超出画布右/下边界?主标 >14 字(封面 >12)会不会被 Office 重折行顶出?——**逐页报 header 内容内边距 + title 字数**自证。
|
|
821
|
+
- 🅱 **客户图过大/过小/糊**:用户每张图是不是又被缩成角落小图/底部小条看不清了(< 最小可读尺寸)?低清原图是不是被放大超 1× 糊了?有没有图过大硬塞进小卡?`source_layout_plan.json` 的 `display_role`/`max_upscale`/`enhance_required` 是否被服从?——**逐图报 display_role + 槽位占画布比例 + 是否 ≤1× + 是否 enhance**自证。
|
|
822
|
+
🚨 **图片本身就是"信息集锦/综述"时更要给够大的槽(2026-07-07 真机 p8 两次复盘,第一次强调"给大槽"后模型仍原样重犯——这次给明确数值门槛,不再用"大/够大"这类模糊词)**:有些客户图不是"配合本页文字的一张辅助证据照",而是**图片自己就承载了大量独立信息点**——如"一张图里网格排列 20+ 个行业应用小缩略图共同证明规模化落地"这类"综述型/集锦型"素材(识别信号:`vision_description`/`data_points`/`key_elements` 列了大量并列条目,如"20余个圆形应用场景缩略图,覆盖边防/零售安防/电信/警务/医疗/教育/农业/电力/建筑施工/工业巡检")——这类图当"次要辅助证据"挤进小图槽(如与另一张图共享半页、缩进 200px 高的条状小图)会让图里的 20+ 个信息点全部变得不可辨认,等于图白配了。**硬性数值门槛(不是建议,是下限)**:这类图渲染宽度必须 ≥ 画布宽度的 60%(1920px 画布下 ≥1150px)且不得与另一张 `display_role=foreground_hero` 的图共享同一屏——**第一次复盘后模型仍把它塞进 `width:380px;height:160px` 的绝对定位小框、与另一张 560×380px 的大图叠放在同一页右下角,说明"给大槽"这种定性描述会被模型解读成"比之前大一点点就算了"**,这次必须满足以下之一:①**独立一整页**(作为这页的唯一/主视觉,配一句话说明"应用场景全景"即可,不需要另写大段文字——图本身就是论据);②与另一张图并列平分页面(各占约 50% 宽度,不是"背景大图 + 角落小条"这种主次结构)。**绝不允许它以 <500px 宽的绝对定位小框叠加/共享另一张 hero 图所在的同一屏**。
|
|
823
|
+
🚨🚨 **(2026-07-07 同日复现——上条数值门槛生效后的直接连带事故,务必同步看)**:p8 这次终于给了 src_8 全宽整页处理(`grid-column:1/-1`),但图内联写的是 `<img style="width:100%;height:auto;display:block">`,且所在行是 `grid-template-rows:auto 1fr auto` 的最后一个 `auto` 行——`height:auto` 让图按自身原生宽高比独立撑出高度,`auto` 行照单全收不设上限,这张图原生比例偏高、撑出的高度加上 `header` 行和中间 `metric-chip+图7` 行的总高度一起超过 1080px 画布,导致整组 `.edit-content` 内容溢出,`header` 与两个 `metric-chip` 被推到画布上边界之外(geometry catastrophic hard gate 判『可见部分仅 8%』,直接在 `stage_export` 硬 halt,全程无 pptx 产出)——这跟已记录的『`aspect-ratio` 覆盖 `height:100%` 撑爆 `1fr` 轨道』事故是同一种病灶的另一种写法(这次是 `height:auto` 撑爆 `auto` 行)。**给这类大图整页/大半页的槽时,"给够大的空间"绝不等于"让图片用原生宽高比自由撑高"**:必须让该图所在的行是 `1fr`(把剩余可用高度让给它,行高不由图片决定)+ 图片 `width:100%;height:100%;object-fit:contain`(贴合行的实际可用尺寸显示,不裁切也不撑爆);绝不写 `height:auto` 或用裸 `<img>`(不套 `.fig-contain`/`.fig-fill` 组件类)去承载这类满宽大图。
|
|
824
|
+
🚨🚨🚨 **(2026-07-07 同日连续 3 次未达标后已转确定性检测,不要再继续加第 4 段 prompt 文字)**:p8 的 src_8 连续 3 次未达到应有视觉份量(①小绝对定位框;②满宽但 height:auto 撑爆画布 halt;③crash 修好但 flex 列共享缩水到实测仅 26% 宽——`mediaRects` 容器框本身 47%宽×26%高≈31% 面积,虽压线满足通用 `min_canvas_fraction`(0.30,按面积算),但 object-fit:contain 在这种宽扁槽里仍会把 20+ 并列小图标压缩到实际可见宽度过窄、不可辨认)——证明只靠 prompt 文字描述"给多大空间",模型每次都能找到字面上不违反新增规则、但实质仍不达标的写法。**已在 `export_pptx_from_html.mjs` 给 mediaRects 透传 sourceFile(回落取 `<img src>` 文件名比对,多数页不带 `data-source-file` 属性)+ `layout_balance.py` 新增 `is_dense_info` 客户图专属宽度检查(`DENSE_INFO_MIN_WIDTH_FRACTION=0.55`,WARNING 不硬拦)+ 两处调用点(`visual_quality_gate.py`/本文件 stage_export)都已接线 `--source-layout-plan`**——下一轮生成会在 `visual_quality_residual.md` 看到【信息集锦图槽位偏窄】的确定性报告(若仍不达标),无需再猜测/再加文字规则;这条规则仍保留作为给设计/生成 agent 的目标说明,不要删除。
|
|
825
|
+
🐛 **(同日接线后真机验证,发现并修复了检测本身的盲区)**:第一次真机跑发现 `mediaRects` **全部 14 页恒为空数组**(不止 src_8)——根因是 p8 这次把图直接实现成裸 `<img>` 标签自身作为前景切图块(没有 div 包裹),而 `hasMedia = node.querySelector('img,...')` 只查**后代**,节点自身是 `<img>` 时恒 false(`layout_balance.py` 里 `PPT_STRICT_MEDIA_TAGS` 早就为**别的检查**记录过这个已知盲区,但 mediaRects 构建时没有同步用这个 tag 兜底)。已在 `export_pptx_from_html.mjs` 给 mediaRects 的判定加 `BARE_MEDIA_TAGS`(img/svg/picture/video/canvas)兜底,不改 `hasMedia` 本体语义。修复后真机复核:p8 的 src_8 实测宽度 40%(仍 <55% 门槛,WARNING 正确触发),**同时发现 p6 的 src_6 也是同一个 is_dense_info 客户图、同样只有 39% 宽**——检测生效后一次性揪出了 2 处,不是本次才有的新问题,只是此前从未被测到过。
|
|
826
|
+
- 🅲 **文字过多/溢出/重叠**:这页是不是又塞太多要点/单条太长(design_budget_check 报超了没)?一行多卡时每卡是不是太窄装不下文字会溢出/与邻卡重叠糊成一团?——**报 design_budget_check 结果 + 每行卡数 vs 各卡文字行数**自证。
|
|
827
|
+
- 🅳 **视觉失焦/无效空白(不是反留白)**:合理留白、大图背景、少量前景文案、文字净区是 Apple/DJI 式产品详情页的合格目标;**空白本身不是错误**。
|
|
828
|
+
只有证据显示页面没有主视觉、文字不可读、内容缺失、正文被挤到角落、或卡片/底板大而无信息时才改。改法优先是强化主视觉、精炼文案、调整 text_zone 或补语义 AI 图;**禁止为了填满而新增卡片/表格/浮动面板**。
|
|
829
|
+
- 🅴 **AI 配图不积极**:封面/章节/尾页是不是又没规划 AI 氛围背景(rich/balanced 档**必出**)?该 source-enhanced 图生图的客户图漏了没?正文真实画面/场景/物体页是不是干巴巴全 HTML?
|
|
830
|
+
- 🅵 **有底图还在表格/卡墙划区 + 过载页没处理**(治 p4 表格+挤图 / p5 五图挤页 / p6 卡墙):route=source / source-enhanced 或规划了 AI 全幅底图的页,render 是不是又退回了**表格 / 悬浮卡片墙 / 网格划区**(应是纯前景浮层 text/html+text/text+image + scrim、字色随底图明暗)?`source_layout_plan.json` 算定 `layout_constraint=fusion_no_cards` 的图所在页是否服从(无 table/卡墙)?过载页(元素超预算)是否已按**数据/对比页拆页或转图表、叙事/能力页整合成一张 hero+概要**处理,而不是把多张大图 + 长列表硬塞一页?——**逐页报 route + 该页是否含 table/卡墙 + 同页大图张数**自证,命中即当场改 design.json。
|
|
831
|
+
- 🅶 **画像对齐 + 背景默认 AI + 全图生图 + 文案精辟**:① 每页 `key_point` 用词深度是否贴 user_request.md 的【术语深度档】(高管页别啰嗦、入门页别黑话),是否**一眼看懂重点**、有没有堆全文长定义?② **每个内容页是否都有背景层、且无客户图的页优先 AI 全幅底图(route=ai-B)**而非裸白底/纯渐变(成本不计、积极生图)?③ **客户图是否全部 route=source-enhanced(图生图重绘高清)**、有没有漏成直接用低清原图?④ 数据是否图表化、产品/场景/操作是否用图、文本是否只做概括+必要补充?命中即当场改 design.json。
|
|
832
|
+
- 🅷 **绝不渐变压图**:检查每个 `.edit-bg`/全幅背景,有没有 `background:<不透明渐变>,url(img)`(渐变写在 url 前会盖死 AI 图)?背景必须 **图 cover 填满 + 纯色 `--vi-fallback` 兜底**,渐变只进半透明 `.edit-scrim`;图是否都 cover 填满槽(无 `max-height` 帽、无 `.src-figure` 白裱框)?是否用了未定义 grid 的自创布局类(会塌空白)?命中即改。
|
|
833
|
+
- 🅸 **文章化页面(文本阅读型排布)**:这页是不是又把论证塞上屏了?——**逐页量证据自证**:① takeaway+points 实际字数 vs 自声明 `max_visible_words`(超 = 违约);② 影像叙事页(hero-scene 等)points 是否 >3 条或有 >20 字长句;③ 有没有 ≥4 条平均 >18 字的长句堆(3–5 秒读不完);④ 论证/机制细节是否写进了 `speaker_notes`(没写 = 深度只能塞上屏的结构病)。命中 = 短语化 points + 论证移入 speaker_notes / 交给图表 / 拆页——**内容不删、换地方**,不许借机砍成空心页。
|
|
834
|
+
(以上每条命中即当场改 design.json。下面是同一立场的细审展开——同样「默认有罪、挑得出就是有问题」:)
|
|
835
|
+
0. **用户目标回看**:design 是否还在回应 `build/user_request.md` 里的原始主题/指令/视觉偏好?有没有为了模板或生图而偏离用户真正要的 PPT?
|
|
836
|
+
1. **客户素材利用(有客户图时必查,最高优先级)**:material.json 里的客户图是否**【全部】被用上**(每张都有某页 route=source 或 route=source-enhanced —— 用户给了不用是红线违规,逐一比对 images[].file 与 design.json 的 source_file,缺哪张就当场补一页/补进相关页)?
|
|
837
|
+
🚨 **张冠李戴逐图核对(最高优先)**:每张客户图是否配在**覆盖其来源章节(plan 的 `section`/`near_text`)内容的页**?原文 A 章的图被排到 B 主题页 = 张冠李戴,当场移回该章节对应页(仅无 section/该章节无对应页才允许语义配页)。
|
|
838
|
+
🚨 **图表结论呼应核对**:带 `key_message`(plan 里标了图表核心结论)的图,其所在页 `key_point`/`evidence` 是否**体现了这条结论**?只把图摆上去、论点没写进文字 = 图和内容对不上(用户点名的最严重问题),当场把结论补进该页。
|
|
839
|
+
🚨 **背景前景同主体重复核对(2026-07-03 第3页事故)**:逐页问——背景已是该主题实景/氛围图的页,前景是不是又排了同主体的图片卡/特写卡(背景驾驶舱+前景 3 张驾驶舱特写)?命中即删前景重复图,改数据/图形/结论或留白(一页一主视觉,Apple/DJI 式克制)。
|
|
840
|
+
🚨 **原图文字重配核对(2026-07-03 src_6 事故)**:带 `embedded_text` 的图(原图烧着标题/标签,图生图已抹掉)——该文字若有信息量(标题句/关键标签/结论),该页有没有用真实 HTML 文字重新写出?没有=信息凭空丢失,当场补;纯水印/logo 无需管。
|
|
841
|
+
配图是否按 **vision.description(识图内容)配到内容契合的页**(别把电路板图配到讲市场的页)?该页**文案是否呼应识图内容**(而非与画面无关)?该页**配色是否参考 stats**(深图白字、浅图深字、强调色取自 dominant_colors,别与图靠色)?
|
|
842
|
+
route=source(仅无 vision 盲态的罕见例外才用,主路是下面的 source-enhanced)的页是否带对 source_file/aspect_ratio/orient/side、按朝向/重点区图文混排(横图上下带、竖图左右列;suitable_as_background 的图是否标 bg 并让文字落 recommended_text_zone)?这类直接用的原图才声明 `object-fit:contain` 保原貌;**走图生图重绘的 source-enhanced 一律 cover 填满槽**。
|
|
843
|
+
🚨 **逐张比对 `source_layout_plan.json`(确定性裁决,不服从就是 bug,当场改 design)**:
|
|
844
|
+
- 每个 `enhance_required=true` 的图:design 是否确实 `route=source-enhanced` 且引用 `enhanced_<file>`、img_plan 有对应 `mode=image-to-image` 条目(含算好的 enhance_prompt)?漏了就补。
|
|
845
|
+
- 每张图的 `usage_intent` 是否被服从(背景图没被缩成角落小图、证据图没被硬铺成背景)?`recommended_templates` 是否选了其一落地?
|
|
846
|
+
- **所有客户图都应 `enhance_required=true`(route=source-enhanced 图生图重绘)**——design 有没有漏成 route=source 直接用低清原图(除无 vision 盲态)?`is_dense_info`(截图/图表)现在也走 img2img(`enhance_style=dense`,忠实保版面与数据、best-effort),其增强图 `contain` 展示保数据,别再当"绝不图生图"。
|
|
847
|
+
route=source-enhanced 是否有 `source_file` + `enhanced_file` + `mode=image-to-image` 的 img_plan 映射,且增强目的明确是扩图/修比例/清晰化/换低干扰背景,而不是把客户图内容换掉?文案是否围绕 material 的内容主干(而非跑题另写)?不达标当场改 design。
|
|
848
|
+
2. **覆盖度**:是否回应了用户原始需求「${inputs.topic}」的每个要点?有没有漏讲、跑偏、答非所问?
|
|
849
|
+
2. **深度**:每页 key_point 是真实质判断还是泛标签?evidence 是否落到具体事实/数据/机制?有没有"正确的废话"?
|
|
850
|
+
3. **构图多样性**:composition 是否雷同(页页左右分栏 / 页页四宫格)?同类页有没有换构图?
|
|
851
|
+
4. **视觉活力**:是否**每页都有 ≥1 视觉元素**(AI图/SVG/图标/图表/装饰几何)?有没有纯文字+背景板的"Word 页"?
|
|
852
|
+
5. **配图质量 + 配色解耦**:route 分流对不对(结构图误塞 AI?)?visual.prompt 是否与文案呼应、画的是具体主体(不是"抽象科技背景")?
|
|
853
|
+
表格、柱状图、折线图、时间线、流程图、架构图、对比矩阵、指标卡是否优先 HTML/SVG?客户未提供但文案需要的安装图、产品使用场景、车间现场、设备图是否积极规划文生图?
|
|
854
|
+
**图表数据系列是否用可区分分类色(别全是 VI 主色一种致柱/饼/折线分不清数据)?非背景插图/辅助图形是否被染成单一 VI 色(应以内容色为准、与 VI 协调)?**
|
|
855
|
+
6. **背景变化**:各页 background 是否有同色系深浅/光位变化?是否页页雷同?
|
|
856
|
+
7. **分页节奏 + 合理留白**:有没有综述页 + 总结页?有没有一页塞太多?
|
|
857
|
+
**「一句话/极少文字占一页」的稀疏页(封面/章节分隔/金句页)不再一律禁止,但要守两条硬规:**
|
|
858
|
+
① **数量 ≤ 全 deck 页数的 20%**(如 16 页最多 ~3 张这种页)——超额就把多出的合并进相邻页或补足实质内容;
|
|
859
|
+
② **每张这类页必须配 AI 氛围图,或用渐变色 / 半透明色底图**(`background` 写明),避免页面过于简陋空洞——
|
|
860
|
+
裸白 + 一句话的稀疏页不允许。其余正文页按内容预算控制文字量,并保证一处主视觉;**不要为了填实而塞卡片/表格**。
|
|
861
|
+
8. **字号可读性(放映级,≈1.5×)**:正文/卡片正文是否够大可读(deck 别用网页 16px、**正文 ≥38px 量级**、屏上别低于 24px)?
|
|
862
|
+
图表/框图内文字(坐标轴/图例/节点名)是否达标、图形是否够大装下不挤不裁?有无非主标元素字号 ≥ 该页主标题(不允许)?只有封面主标/章节大序号维持现状,其余各级是否都按 ≈1.5× 放大?
|
|
863
|
+
9. **封面/章节对比度**:封面/章节页文字在氛围底图(尤其浅色底图)上对比是否达标?是否用了「深字+浅色磨砂板」或「白字+足够暗 scrim/板」(见 §1.B),而非浅底白字靠弱 scrim(必糊)?
|
|
864
|
+
10. **文字皆真实 DOM 文本**:有无把可读文字写进 CSS `::before/::after content`、或烧进背景图/HTML 图元(会被截图夹带、不可编辑、可能双层)?除 AI 插图自带画面字外,文字一律真实 DOM 文本节点。
|
|
865
|
+
11. **目录/list 页不是填满竞赛**:list/目录等页若只有窄单列且右半无主视觉,才改成「文字主栏 + 侧栏视觉」或双列;如果右侧是大图/氛围/产品特写净区,则保留,不要硬加信息块。
|
|
866
|
+
12. **可拖结构离散化 + 信息有效 + 不溢出**:架构层/流程节点/决策树/一排圆/卡片矩阵是否规划成离散 HTML 元素(每块一 div、可递归切成各自可拖对象),而非整块 SVG(节点不可拆)?卡片/底板只在确有并列指标/证据时使用,且信息有效、不过量、不溢出;**不要为了填满画布制造卡片**。一列层块/节点是否未堆到高过画布?
|
|
867
|
+
13. **对比度 + 文案精炼**:每页文字与底色是否高对比(绝无深底深字/浅底浅字;深底必白字)?文案是否精炼、说人话(类比/例子讲透、近似但好懂),有没有一页硬塞长定义(会顶出/缩字)?不达标当场改 design:深底转白字 + 文案精炼/拆点/长列表两列。
|
|
868
|
+
🚨 **强调色角标/标签系统性靠色核对(2026-07-03 事故)**:`.t-eyebrow`/`.bullet-row .label` 这类强调色短文字有没有裸色浮在照片/渐变背景上?(同一 class 全 deck 复用,一处靠色=处处靠色)命中即给该 class 统一加色块/半透明底,一次改完全 deck 同类实例。
|
|
869
|
+
|
|
870
|
+
## 第二遍:逐条修订(design.md 用 Edit;design.json 用整体 Write 重写)
|
|
871
|
+
把上面挑出的每个缺陷**直接改好**——补实质内容、换构图、给纯文字页加视觉元素、修配图提示词、调背景变化、调分页。
|
|
872
|
+
- **design.json 必须是严格 JSON**:别用 Edit 零碎改 JSON(极易匹配错/改坏),**直接用 Write 把整份修订后的 design.json 重写一遍**
|
|
873
|
+
(可多行缩进;下一阶段会规范化;字段完整 page/archetype/composition/visual/background;字段精炼)。
|
|
874
|
+
- design.md(人读 markdown)可照常用 Edit 局部修。
|
|
875
|
+
若同时有 img_plan.json,相应同步(提示词随 visual.prompt 改)。
|
|
876
|
+
|
|
877
|
+
**重要**:本步是设计文档层的打磨,**不写 deck.html、不生图**。修订到你作为评审"能签字放行"为止。
|
|
878
|
+
完成后报告:是否根据预检报告做了修订、挑出并修复了哪些缺陷、最终共几页、构图法分布、每页是否都有视觉元素。
|
|
879
|
+
allowed_tools: [Read, Edit, Write, Glob]
|
|
880
|
+
maxTurns: 16
|
|
881
|
+
onError: continue
|
|
882
|
+
max_retries: 1
|
|
883
|
+
|
|
884
|
+
- id: stage_design_recheck
|
|
885
|
+
title: "阶段9/22·设计文档确定性复核"
|
|
886
|
+
when: "fileExists('./build/design_json_ok')"
|
|
887
|
+
tool: Bash
|
|
888
|
+
args:
|
|
889
|
+
command: |
|
|
890
|
+
set -e
|
|
891
|
+
mkdir -p ./build
|
|
892
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build ./build
|
|
893
|
+
test -f ./build/design_json_ok
|
|
894
|
+
BUDGET_LOG=./build/design_budget_recheck.txt
|
|
895
|
+
STYLE_LOG=./build/design_style_recheck.txt
|
|
896
|
+
if [ "${inputs.quality}" != "best" ]; then
|
|
897
|
+
cp ./build/design_budget_check.txt "$BUDGET_LOG" 2>/dev/null || true
|
|
898
|
+
cp ./build/design_style_check.txt "$STYLE_LOG" 2>/dev/null || true
|
|
899
|
+
cp ./build/design_review_checks.json ./build/design_review_recheck.json 2>/dev/null || true
|
|
900
|
+
cp ./build/design_review_checks.md ./build/design_review_recheck.md 2>/dev/null || true
|
|
901
|
+
cp ./build/design_review_checks.md ./build/design_repair_residual.md 2>/dev/null || true
|
|
902
|
+
echo "DESIGN_REVIEW_RECHECK_SKIPPED_FAST"
|
|
903
|
+
exit 0
|
|
904
|
+
fi
|
|
905
|
+
set +e
|
|
906
|
+
python3 skills/ui-design/scripts/design_budget_check.py ./build/design.json -v > "$BUDGET_LOG" 2>&1
|
|
907
|
+
BUDGET_STATUS=$?
|
|
908
|
+
python3 skills/ui-design/scripts/design_style_check.py ./build/design.json -v > "$STYLE_LOG" 2>&1
|
|
909
|
+
STYLE_STATUS=$?
|
|
910
|
+
set -e
|
|
911
|
+
export BUDGET_STATUS STYLE_STATUS
|
|
912
|
+
python3 - <<'PY'
|
|
913
|
+
import json
|
|
914
|
+
import os
|
|
915
|
+
from pathlib import Path
|
|
916
|
+
|
|
917
|
+
build = Path("./build")
|
|
918
|
+
budget_status = int(os.environ.get("BUDGET_STATUS", "1"))
|
|
919
|
+
style_status = int(os.environ.get("STYLE_STATUS", "1"))
|
|
920
|
+
budget_log = (build / "design_budget_recheck.txt").read_text(encoding="utf-8", errors="replace")
|
|
921
|
+
style_log = (build / "design_style_recheck.txt").read_text(encoding="utf-8", errors="replace")
|
|
922
|
+
ok = budget_status == 0 and style_status == 0
|
|
923
|
+
report = {
|
|
924
|
+
"ok": ok,
|
|
925
|
+
"budget_ok": budget_status == 0,
|
|
926
|
+
"style_ok": style_status == 0,
|
|
927
|
+
"budget_status": budget_status,
|
|
928
|
+
"style_status": style_status,
|
|
929
|
+
"budget_log": budget_log[-12000:],
|
|
930
|
+
"style_log": style_log[-12000:],
|
|
931
|
+
}
|
|
932
|
+
(build / "design_review_recheck.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
933
|
+
(build / "design_review_recheck.md").write_text(
|
|
934
|
+
"# 设计文档确定性复核\n\n"
|
|
935
|
+
f"- budget_ok: {report['budget_ok']} (status={budget_status})\n"
|
|
936
|
+
f"- style_ok: {report['style_ok']} (status={style_status})\n"
|
|
937
|
+
f"- ok: {ok}\n\n"
|
|
938
|
+
"## design_budget_check\n\n```text\n" + budget_log[-12000:] + "\n```\n\n"
|
|
939
|
+
"## design_style_check\n\n```text\n" + style_log[-12000:] + "\n```\n",
|
|
940
|
+
encoding="utf-8",
|
|
941
|
+
)
|
|
942
|
+
print("DESIGN_REVIEW_RECHECK_OK" if ok else "DESIGN_REVIEW_RECHECK_ISSUES")
|
|
943
|
+
PY
|
|
944
|
+
onError: halt
|
|
945
|
+
|
|
946
|
+
- id: stage_design_repair
|
|
947
|
+
title: "阶段10/22·设计文档短修复(fast只写残留·best最多3轮)"
|
|
948
|
+
when: "inputs.quality == 'best' && fileExists('./build/design_review_recheck.json') && readJson('./build/design_review_recheck.json', 'ok') == false"
|
|
949
|
+
type: loop
|
|
950
|
+
max_iterations: 3
|
|
951
|
+
fresh_context: true
|
|
952
|
+
do:
|
|
953
|
+
- id: design_repair_hints
|
|
954
|
+
title: "阶段10/22·归并设计短修复批次"
|
|
955
|
+
tool: Bash
|
|
956
|
+
args:
|
|
957
|
+
command: |
|
|
958
|
+
python3 skills/ui-design/scripts/design_repair_hints.py --build ./build --max-pages 3
|
|
959
|
+
onError: continue
|
|
960
|
+
- id: design_repair_batch
|
|
961
|
+
title: "阶段10/22·短修复本批页面"
|
|
962
|
+
when: "inputs.quality == 'best' && fileExists('./build/design_repair_batch.md') && readJson('./build/design_review_recheck.json', 'ok') == false"
|
|
963
|
+
agent: |
|
|
964
|
+
你只做**本批页面短修复**,不要重写全稿。
|
|
965
|
+
|
|
966
|
+
必读:
|
|
967
|
+
- `./build/user_request.md`
|
|
968
|
+
- `./build/design_repair_batch.md`
|
|
969
|
+
- `./build/design.json`
|
|
970
|
+
- 必要时读 `./build/material.json`、`./build/source_layout_plan.json`
|
|
971
|
+
|
|
972
|
+
只修 `design_repair_batch.md` 列出的 1–3 页:
|
|
973
|
+
- budget 失败:删减/改写超长标题、超长要点、文字过量页面;不要新增内容填满画布。
|
|
974
|
+
- style 失败:补缺失字段、修卡片墙/表格墙/文字墙、补 Apple/DJI 式主视觉、补 source-enhanced 或 AI 主视觉规划。
|
|
975
|
+
- 非破坏性原则:合理留白、大图背景、少量前景文案不是错误;禁止为填满页面新增卡片、表格、浮动白/灰面板。
|
|
976
|
+
- 对图片页,优先修 `one_sentence_takeaway / composition_style / page_grammar / visual_focus / safe_text_zone / visual_role / semantic_image_prompt / copy_budget / forbidden_layout`。
|
|
977
|
+
|
|
978
|
+
修复方式:
|
|
979
|
+
- 直接用 Write 重写 `./build/design.json` 为严格 JSON。
|
|
980
|
+
- 可用 Edit 同步 `./build/design.md` 的人读说明。
|
|
981
|
+
- 不写 deck.html、不生图;修完只报告本批修了哪些页。
|
|
982
|
+
allowed_tools: [Read, Edit, Write, Glob]
|
|
983
|
+
maxTurns: 12
|
|
984
|
+
onError: continue
|
|
985
|
+
max_retries: 0
|
|
986
|
+
- id: design_repair_recheck
|
|
987
|
+
title: "阶段10/22·短修复复核"
|
|
988
|
+
tool: Bash
|
|
989
|
+
args:
|
|
990
|
+
command: |
|
|
991
|
+
set -e
|
|
992
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build ./build
|
|
993
|
+
test -f ./build/design_json_ok
|
|
994
|
+
# 只跑一遍:把退出码落 .status(&&/|| 在 set -e 下安全,$? 取的是检查器真实退出码),
|
|
995
|
+
# 内联 Python 读状态即可,不再重跑同一对慢检查器(去「耗时高收益小」双跑)。
|
|
996
|
+
python3 skills/ui-design/scripts/design_budget_check.py ./build/design.json -v > ./build/design_budget_recheck.txt 2>&1 && echo 0 > ./build/design_budget_recheck.status || echo $? > ./build/design_budget_recheck.status
|
|
997
|
+
python3 skills/ui-design/scripts/design_style_check.py ./build/design.json -v > ./build/design_style_recheck.txt 2>&1 && echo 0 > ./build/design_style_recheck.status || echo $? > ./build/design_style_recheck.status
|
|
998
|
+
python3 - <<'PY'
|
|
999
|
+
import json
|
|
1000
|
+
from pathlib import Path
|
|
1001
|
+
build = Path("./build")
|
|
1002
|
+
def _status(name):
|
|
1003
|
+
try:
|
|
1004
|
+
return int((build / (name + ".status")).read_text(encoding="utf-8").strip())
|
|
1005
|
+
except Exception:
|
|
1006
|
+
return 1
|
|
1007
|
+
budget_status = _status("design_budget_recheck")
|
|
1008
|
+
style_status = _status("design_style_recheck")
|
|
1009
|
+
budget_log = (build / "design_budget_recheck.txt").read_text(encoding="utf-8", errors="replace") if (build / "design_budget_recheck.txt").exists() else ""
|
|
1010
|
+
style_log = (build / "design_style_recheck.txt").read_text(encoding="utf-8", errors="replace") if (build / "design_style_recheck.txt").exists() else ""
|
|
1011
|
+
ok = budget_status == 0 and style_status == 0
|
|
1012
|
+
report = {
|
|
1013
|
+
"ok": ok,
|
|
1014
|
+
"budget_ok": budget_status == 0,
|
|
1015
|
+
"style_ok": style_status == 0,
|
|
1016
|
+
"budget_status": budget_status,
|
|
1017
|
+
"style_status": style_status,
|
|
1018
|
+
"budget_log": budget_log[-12000:],
|
|
1019
|
+
"style_log": style_log[-12000:],
|
|
1020
|
+
}
|
|
1021
|
+
(build / "design_review_recheck.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
1022
|
+
(build / "design_review_recheck.md").write_text(
|
|
1023
|
+
"# 设计文档确定性复核\n\n"
|
|
1024
|
+
f"- budget_ok: {report['budget_ok']} (status={budget_status})\n"
|
|
1025
|
+
f"- style_ok: {report['style_ok']} (status={style_status})\n"
|
|
1026
|
+
f"- ok: {ok}\n\n"
|
|
1027
|
+
"## design_budget_check\n\n```text\n" + budget_log[-12000:] + "\n```\n\n"
|
|
1028
|
+
"## design_style_check\n\n```text\n" + style_log[-12000:] + "\n```\n",
|
|
1029
|
+
encoding="utf-8",
|
|
1030
|
+
)
|
|
1031
|
+
if ok:
|
|
1032
|
+
(build / "design_repair_done").touch()
|
|
1033
|
+
print("DESIGN_REPAIR_RECHECK_OK" if ok else "DESIGN_REPAIR_RECHECK_ISSUES")
|
|
1034
|
+
PY
|
|
1035
|
+
if [ "${inputs.quality}" != "best" ]; then
|
|
1036
|
+
cp ./build/design_review_recheck.md ./build/design_repair_residual.md 2>/dev/null || true
|
|
1037
|
+
touch ./build/design_repair_done
|
|
1038
|
+
fi
|
|
1039
|
+
onError: continue
|
|
1040
|
+
- id: design_repair_done
|
|
1041
|
+
type: break
|
|
1042
|
+
when: "fileExists('./build/design_repair_done')"
|
|
1043
|
+
|
|
1044
|
+
# ---------- 阶段6:图生图兜底注入 + 配图分流闸门(结构图必须 HTML,不准当 AI 图生) ----------
|
|
1045
|
+
# ① 确定性兜底注入:plan_source_layout.py --ensure-img-plan 把「必须图生图增强」的客户图条目 union 进
|
|
1046
|
+
# img_plan.json(按 file 去重)——保证低清/比例不合的客户图一定被 Seedream 图生图增强,不靠设计 LLM 记得加。
|
|
1047
|
+
# ② 配图分流(确定性净化,不是观察型硬门):image_prompt_rewrite.py 是 t2i prompt 的**唯一生产/净化点**——
|
|
1048
|
+
# 它与 image_plan_lint 共享同一份黑名单词表(import,单一真相源),原 prompt/design 字段命中结构词/坏审美词
|
|
1049
|
+
# 时**机器重组成安全的页面绑定 prompt**(= 结构图回退:结构交 HTML 层,AI 图退化为安全底图),确定性完成、
|
|
1050
|
+
# 不需要 halt 等人来修。随后 image_plan_lint 只扫 img_plan prompt 作兜底验证(不带 --outline:note 到不了
|
|
1051
|
+
# 生图模型,扫 note 只剩误伤面;若未来移除 rewrite 需恢复 --outline)。lint 在此失败 = rewrite 不变量被破坏
|
|
1052
|
+
# 的真 bug → halt 正确;确定性步重试无意义,max_retries=0。
|
|
1053
|
+
# when 放宽:img_plan 存在【或】规划里有待增强客户图(length null 安全)→ 即使设计步漏写 img_plan,兜底注入也能创建它。
|
|
1054
|
+
- id: stage_img_route_gate
|
|
1055
|
+
title: "阶段11/22·图生图兜底注入 + 配图分流闸门"
|
|
1056
|
+
when: "fileExists('./build/design_json_ok') && (fileExists('./build/img_plan.json') || length(readJson('./build/source_layout_plan.json', 'enhance_entries')) > 0)"
|
|
1057
|
+
tool: Bash
|
|
1058
|
+
args:
|
|
1059
|
+
command: |
|
|
1060
|
+
set -e
|
|
1061
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-img-plan --build ./build
|
|
1062
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-extensions --build ./build --design ./build/design.json
|
|
1063
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-ai-img-plan --build ./build --design ./build/design.json
|
|
1064
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-page-backgrounds --build ./build --design ./build/design.json
|
|
1065
|
+
python3 skills/ui-design/scripts/image_prompt_rewrite.py --build ./build
|
|
1066
|
+
python3 skills/ui-design/scripts/image_plan_lint.py ./build/img_plan.json -v
|
|
1067
|
+
# 章节错位预警(张冠李戴,WARNING 级恒 exit 0):生图**之前**就核对客户图是否配在
|
|
1068
|
+
# 其来源章节对应页(词元交集,见 source_usage_check.section_mismatch_warnings),
|
|
1069
|
+
# 错位在此最便宜(design 层可改,还没花生图/建页成本)。|| true 双保险,绝不 halt。
|
|
1070
|
+
python3 skills/ui-design/scripts/source_usage_check.py --build ./build --design-only || true
|
|
1071
|
+
touch ./build/img_route_ok
|
|
1072
|
+
echo "IMG_ROUTE_GATE_OK"
|
|
1073
|
+
onError: halt
|
|
1074
|
+
max_retries: 0
|
|
1075
|
+
|
|
1076
|
+
# ---------- 阶段7:按 img_plan.json 生成插图(ai-image 的 generate.mjs,按比例生成) ----------
|
|
1077
|
+
# 分层/时序不变量:AI 图必须在本阶段全部落盘、**先于阶段8构图闸门**——闸门 --measure-only 渲染真实 deck.html
|
|
1078
|
+
# 量的是「含图成品」。两类 AI 图各归各层(export_pptx_from_html.mjs::tagLayers 的 isFullBleed 分流):
|
|
1079
|
+
# B 路线全幅底图 → 背景层整页截图;A 路线半幅插图 → 中层逐元素切图(独立可编辑图片)。
|
|
1080
|
+
# 用专用 GenerateImage 工具(非 Bash):无 120s 帽(生图是分钟级长操作,Bash 会半途 SIGKILL),
|
|
1081
|
+
# 内建优雅退化(单图失败→图生图退原图/文生图退渐变占位,恒不阻断),仅凭 Ctrl+C 中断。
|
|
1082
|
+
- id: stage_gen_images
|
|
1083
|
+
title: "阶段12/22·生成插图(按比例)"
|
|
1084
|
+
when: "fileExists('./build/img_plan.json')"
|
|
1085
|
+
tool: GenerateImage
|
|
1086
|
+
args:
|
|
1087
|
+
plan: ./build/img_plan.json
|
|
1088
|
+
assets: ./build/assets
|
|
1089
|
+
size: 2k
|
|
1090
|
+
timeout_ms: 300000
|
|
1091
|
+
wall_budget_ms: 3600000
|
|
1092
|
+
# 批内并发 2(2026-07-02 提速裁决):31 张串行 ≈15.5min 是全流程最大耗时项,并发 2 → ~8min。
|
|
1093
|
+
# provider 侧 Seedream/中转普遍容许小并发;单张失败照走降级占位,语义与串行一致。
|
|
1094
|
+
concurrency: 2
|
|
1095
|
+
onError: continue
|
|
1096
|
+
max_retries: 1
|
|
1097
|
+
|
|
1098
|
+
# ---------- 阶段7b:生图质量门(fast 只补一轮降级图;best 的深度复核在后续语义复核阶段) ----------
|
|
1099
|
+
- id: stage_image_quality_gate
|
|
1100
|
+
title: "阶段13/22·AI 配图质量门(fast一轮补降级图)"
|
|
1101
|
+
when: "fileExists('./build/image_generation_report.json')"
|
|
1102
|
+
tool: GenerateImage
|
|
1103
|
+
args:
|
|
1104
|
+
plan: ./build/img_plan.json
|
|
1105
|
+
assets: ./build/assets
|
|
1106
|
+
size: 2k
|
|
1107
|
+
timeout_ms: 300000
|
|
1108
|
+
wall_budget_ms: 3600000
|
|
1109
|
+
retry_degraded_report: ./build/image_generation_report.json
|
|
1110
|
+
max_rounds: 1
|
|
1111
|
+
concurrency: 2
|
|
1112
|
+
onError: continue
|
|
1113
|
+
max_retries: 1
|
|
1114
|
+
|
|
1115
|
+
# ---------- 阶段7c:生成图语义复核(多模态看图,跑题图只重试失败项) ----------
|
|
1116
|
+
# 🚫 已屏蔽(2026-07-02 用户裁决):构图/视觉验证只走**确定性脚本**,LLM 图像识别复核暂停——
|
|
1117
|
+
# 阶段14/15/16 三步 when:"false" 整体跳过(骨架保留 → defFingerprint 不变,旧断点可续跑);
|
|
1118
|
+
# visual_quality_gate.py 已同步把 generated_review 从 hard_failed 摘除。
|
|
1119
|
+
# 恢复 = 三步 when 还原为原条件(记录于各步注释)+ gate 加回 `or not generated_review_ok`。
|
|
1120
|
+
- id: stage_generated_image_review
|
|
1121
|
+
title: "阶段14/22·生成图语义复核(已屏蔽)"
|
|
1122
|
+
# 原条件:"inputs.quality == 'best' && fileExists('./build/img_plan.json')"
|
|
1123
|
+
when: "false"
|
|
1124
|
+
type: loop
|
|
1125
|
+
over: "${asArray(readJson('./build/img_plan.json'))}"
|
|
1126
|
+
as: gen_img
|
|
1127
|
+
do:
|
|
1128
|
+
- id: review_generated_image
|
|
1129
|
+
title: "阶段14/22·复核生成图 #${gen_img.file}"
|
|
1130
|
+
when: "fileExists('./build/assets/' + gen_img.file)"
|
|
1131
|
+
history_mode: isolated
|
|
1132
|
+
llm: |
|
|
1133
|
+
你是 PPT 产品详情页配图验收员。请只看下方这一张生成图,并结合本轮 PPT 的目标判断它是否适合继续使用。
|
|
1134
|
+
|
|
1135
|
+
必读上下文:
|
|
1136
|
+
- 用户目标和原始要求:`./build/user_request.md`
|
|
1137
|
+
- PPT 设计文档:`./build/design.json`
|
|
1138
|
+
- 图片计划条目:`${json(gen_img)}`
|
|
1139
|
+
|
|
1140
|
+
只输出 JSON 对象,不要 markdown:
|
|
1141
|
+
{
|
|
1142
|
+
"file": "${gen_img.file}",
|
|
1143
|
+
"pass": true/false,
|
|
1144
|
+
"score": 0-10,
|
|
1145
|
+
"reason": "一句话中文原因",
|
|
1146
|
+
"issues": ["跑题/有文字Logo/VI不符/随机消费电子/不适合背景/不适合前景/其他"],
|
|
1147
|
+
"suggested_retry_prompt": "若失败,给出更贴合页面文案和VI的重试提示词;若通过为空"
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
判失败的典型情况:
|
|
1151
|
+
- 出现游戏手柄、药瓶/化妆瓶、普通显示器、随机消费电子等和用户主题、素材内容、页面 takeaway 或当前 VI 无关主体。
|
|
1152
|
+
- 背景/场景/hero 图含任何文字、数字、章节序号、Logo、字母、水印、界面标签;**即使看起来是装饰性的 1/2/3/4 也必须失败**,因为 PPT 顶层会另有可编辑文字。
|
|
1153
|
+
- 没有可放 PPT 文案的净区,或需要靠大白/灰卡遮住背景才能读字。
|
|
1154
|
+
- 与 design.json 该页 one_sentence_takeaway / visual_focus 不匹配。
|
|
1155
|
+
- 不符合当前 VI 的色彩、材质、光线和产品详情页气质。
|
|
1156
|
+
- 图像花哨、拼贴、像 UI 卡片/缩略图阵列,不能作为 Apple/DJI 式产品详情页主视觉。
|
|
1157
|
+
context_files:
|
|
1158
|
+
- path: "./build/user_request.md"
|
|
1159
|
+
hint: "用户原始目标与最高优先级要求"
|
|
1160
|
+
- path: "./build/design.json"
|
|
1161
|
+
hint: "每页文案、视觉焦点与配图意图"
|
|
1162
|
+
- path: "./build/img_plan.json"
|
|
1163
|
+
hint: "当前生成图计划与提示词"
|
|
1164
|
+
allowed_tools: [Read]
|
|
1165
|
+
images:
|
|
1166
|
+
- source: "./build/assets/${gen_img.file}"
|
|
1167
|
+
detail: high
|
|
1168
|
+
max_long_side_pixel: 1600
|
|
1169
|
+
capture:
|
|
1170
|
+
text: generated_image_review_text
|
|
1171
|
+
onError: continue
|
|
1172
|
+
max_retries: 1
|
|
1173
|
+
- id: write_generated_image_review
|
|
1174
|
+
title: "阶段14/22·记录生成图复核 #${gen_img.file}"
|
|
1175
|
+
when: "length(generated_image_review_text) > 0"
|
|
1176
|
+
tool: Write
|
|
1177
|
+
args:
|
|
1178
|
+
file_path: "./build/generated-image-reviews/${gen_img.file}.json"
|
|
1179
|
+
content: "${generated_image_review_text}"
|
|
1180
|
+
onError: continue
|
|
1181
|
+
|
|
1182
|
+
- id: stage_generated_image_review_collect
|
|
1183
|
+
title: "阶段15/22·汇总生成图语义复核(已屏蔽)"
|
|
1184
|
+
# 原条件:"inputs.quality == 'best' && fileExists('./build/img_plan.json')"(屏蔽见阶段7c 头注)
|
|
1185
|
+
when: "false"
|
|
1186
|
+
tool: Bash
|
|
1187
|
+
args:
|
|
1188
|
+
command: |
|
|
1189
|
+
set -e
|
|
1190
|
+
python3 skills/ui-design/scripts/generated_image_review_collect.py --build ./build
|
|
1191
|
+
onError: continue
|
|
1192
|
+
max_retries: 1
|
|
1193
|
+
|
|
1194
|
+
- id: stage_generated_image_retry
|
|
1195
|
+
title: "阶段16/22·生成图语义失败重试(已屏蔽)"
|
|
1196
|
+
# 原条件:"inputs.quality == 'best' && fileExists('./build/generated_image_semantic_retry_report.json')"(屏蔽见阶段7c 头注)
|
|
1197
|
+
when: "false"
|
|
1198
|
+
tool: GenerateImage
|
|
1199
|
+
args:
|
|
1200
|
+
plan: ./build/img_plan.json
|
|
1201
|
+
assets: ./build/assets
|
|
1202
|
+
size: 2k
|
|
1203
|
+
timeout_ms: 300000
|
|
1204
|
+
wall_budget_ms: 3600000
|
|
1205
|
+
retry_degraded_report: ./build/generated_image_semantic_retry_report.json
|
|
1206
|
+
max_rounds: 3
|
|
1207
|
+
onError: continue
|
|
1208
|
+
max_retries: 1
|
|
1209
|
+
|
|
1210
|
+
# ---------- 阶段5:按设计文档分批生成 HTML deck(每轮 ≤5 页,确定性页数闸门收口,防大 deck 烂尾) ----------
|
|
1211
|
+
# 治"50 页 deck 单步一次写完撞 maxTurns、做了 5 页就停":每轮先用 build_probe 确定性判断是否已完成,
|
|
1212
|
+
# 只有缺页/客户图未用时才让 agent 生成"下一批 ≤5 页"(2026-07-02 提速裁决:3→5,23 页 8 批→5 批省 ~4-5min)。fresh_context 每轮重置 history 防膨胀
|
|
1213
|
+
# (design.json/deck.html 在磁盘,每轮 Read 即可,不靠 history 记忆);loop 级断点支持中断续跑。
|
|
1214
|
+
- id: stage_build_loop
|
|
1215
|
+
title: "阶段17/22·分批生成网页(fast每轮≤5页·页数+客户图双闸门收口)"
|
|
1216
|
+
when: "fileExists('./build/design_json_ok')"
|
|
1217
|
+
type: loop
|
|
1218
|
+
max_iterations: 6
|
|
1219
|
+
fresh_context: true
|
|
1220
|
+
do:
|
|
1221
|
+
- id: build_probe
|
|
1222
|
+
title: "阶段17/22·构建进度探针"
|
|
1223
|
+
tool: Bash
|
|
1224
|
+
args:
|
|
1225
|
+
command: |
|
|
1226
|
+
python3 - <<'PY'
|
|
1227
|
+
import json, subprocess
|
|
1228
|
+
from pathlib import Path
|
|
1229
|
+
|
|
1230
|
+
root = Path.cwd()
|
|
1231
|
+
build = root / "build"
|
|
1232
|
+
build.mkdir(parents=True, exist_ok=True)
|
|
1233
|
+
complete = build / "build_complete"
|
|
1234
|
+
complete.unlink(missing_ok=True)
|
|
1235
|
+
|
|
1236
|
+
def run(cmd):
|
|
1237
|
+
proc = subprocess.run(cmd, cwd=str(root), text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
1238
|
+
return proc.returncode, proc.stdout.strip()
|
|
1239
|
+
|
|
1240
|
+
pages_status, pages_log = run(["python3", "skills/ui-design/scripts/deck_pages_check.py", "./build"])
|
|
1241
|
+
source_status, source_log = run(["python3", "skills/ui-design/scripts/source_usage_check.py", "--build", "./build"])
|
|
1242
|
+
pages_complete = pages_status == 0 and "COMPLETE" in pages_log
|
|
1243
|
+
source_ok = source_status == 0 and "SOURCE_USAGE_OK" in source_log
|
|
1244
|
+
report = {
|
|
1245
|
+
"pages_complete": pages_complete,
|
|
1246
|
+
"source_usage_ok": source_ok,
|
|
1247
|
+
"pages_status": pages_status,
|
|
1248
|
+
"source_status": source_status,
|
|
1249
|
+
"pages_log": pages_log,
|
|
1250
|
+
"source_log": source_log,
|
|
1251
|
+
"ok": pages_complete and source_ok,
|
|
1252
|
+
}
|
|
1253
|
+
(build / "build_probe.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
1254
|
+
(build / "build_probe.txt").write_text(
|
|
1255
|
+
"# build_probe\n\n"
|
|
1256
|
+
f"pages_complete={pages_complete}\nsource_usage_ok={source_ok}\n\n"
|
|
1257
|
+
"## deck_pages_check\n\n```text\n" + pages_log + "\n```\n\n"
|
|
1258
|
+
"## source_usage_check\n\n```text\n" + source_log + "\n```\n",
|
|
1259
|
+
encoding="utf-8",
|
|
1260
|
+
)
|
|
1261
|
+
if report["ok"]:
|
|
1262
|
+
complete.touch()
|
|
1263
|
+
print("WEBPPT_BUILD_COMPLETE")
|
|
1264
|
+
else:
|
|
1265
|
+
print("WEBPPT_BUILD_MORE")
|
|
1266
|
+
print((build / "build_probe.txt").read_text(encoding="utf-8")[-4000:])
|
|
1267
|
+
PY
|
|
1268
|
+
onError: halt
|
|
1269
|
+
- id: build_batch
|
|
1270
|
+
title: "阶段17/22·生成下一批页面"
|
|
1271
|
+
when: "!fileExists('./build/build_complete')"
|
|
1272
|
+
agent: |
|
|
1273
|
+
按设计文档**分批**生成 1920x1080 的 HTML deck(单文件 `./build/deck.html`、自包含 CSS)。
|
|
1274
|
+
**本轮只做 `./build/build_probe.txt` 指出的缺页或未用客户图(默认 fast 最多 5 页),做完即止**——大 deck 一次写完会撞轮数上限、半途烂尾,分批是为了稳。
|
|
1275
|
+
|
|
1276
|
+
动手前从系统提示「可用技能」里 ui-design 的【技能目录】Read `references/layout-composition.md`
|
|
1277
|
+
(grid 结构化构图 + 三层语义化 HTML + 构图均衡),严格照其执行。
|
|
1278
|
+
|
|
1279
|
+
## 本轮步骤
|
|
1280
|
+
1. **先 Read `./build/build_probe.txt`**。这个文件由上一小步确定性生成;不要自己重新判断完成状态。
|
|
1281
|
+
- 若显示页数 MISSING:按下面生成缺页。
|
|
1282
|
+
- 若显示 SOURCE_USAGE_UNUSED:把**未用的客户图补进最相关的页**(route=source 直接用,或 route=source-enhanced 增强后用,见下)。
|
|
1283
|
+
- 🚫 **客户图引用契约(2026-07-02 坠机原图上墙事故)**:Read `./build/source_layout_plan.json`——
|
|
1284
|
+
规划标 `enhance_required:true` 或 `has_embedded_text:true` 的图**只准引用 `enhanced_src_N`,绝不引用原图 `src_N`**(原图带字幕/水印,字会烧死在页面里);
|
|
1285
|
+
`usage_intent:"discard"` 的图**任何页都不准用**;`usage_intent:"direct_contain"`/`content_type:screenshot_slide` 的图只准 contain 框图展示、**绝不铺整页背景、绝不在其上叠正文**
|
|
1286
|
+
(视觉门有确定性【版式违规】ERROR 核对——contain/gallery/small_evidence 图出现在 `.bg-img`/CSS 背景必被打回,2026-07-03 第4页影子标题真机事故,写对省一轮);
|
|
1287
|
+
同一主体的 `src_N` 与 `enhanced_src_N` **绝不同页并存**(背景已是它、前景别再放它的特写);
|
|
1288
|
+
推广到任意图源(🍎 2026-07-03 第3页事故):**背景已是该主题实景/氛围图时,前景禁止再排同主体图片卡**
|
|
1289
|
+
(背景驾驶舱+前景 3 张驾驶舱特写=重复堆料)——前景改放数据/图形/结论或留白,一页一主视觉。
|
|
1290
|
+
🚨🚫 **绝不修改 `img_plan.json`(2026-07-06 真机复盘:`build_batch` 往 `img_plan.json` 补了一条 `enhanced_src_4.png` 条目试图"修复"页6缺图,但阶段7 `stage_gen_images` 是只跑一次的确定性工具步、早已跑完,build_batch 阶段再编辑 `img_plan.json` 不会触发任何新的实际生图——结果是 `enhanced_src_4.png` 永远不存在于 `assets/`,deck 却引用了它,`source_usage_check` 判客户图 `src_4.png` 未用上,硬门失败,整个 `-p` 进程直接 halt,比平时"带残留放行"严重得多)**:写 HTML 前先用 Glob/Read 确认 `assets/enhanced_src_N.png` 这类文件**真实存在**再引用;**发现该文件不存在时,绝不要去编辑 `img_plan.json` 加条目"修复"它**(这个阶段编辑该文件毫无效果,只会留下一个此后永远 404 的幽灵引用)——正确做法是**直接引用原始 `assets/src_N.png`**(哪怕带一点原始水印/低清也好过引用不存在的文件,让下一轮 visual_repair_batch 或用户重跑整体流程处理这张图的增强),`img_plan.json` 只能由阶段 7 之前的确定性脚本步骤写,build_batch 对它只读不写。
|
|
1291
|
+
- 若两者都 OK,说明 build_probe 会直接 break,本 step 不应运行。
|
|
1292
|
+
2. **若 MISSING**:Read `./build/design.json` 拿到**缺页**(build_probe 列出的页号)的设计(archetype/composition/blocks.render/key_point/points/visual/background);
|
|
1293
|
+
Read `./build/deck.html`(若已存在)了解已有结构与**全局 CSS / VI 视觉系统**(保持一致)。
|
|
1294
|
+
3. **生成缺页里的下一批(默认 fast 最多 5 页)**,每页一个 `<section class="slide" data-screen-label="NN ...">`(NN=该页 page 号两位数、含中文标题),
|
|
1295
|
+
必须先读取该页的 `composition_style / page_grammar / one_sentence_takeaway / visual_focus / text_zone / safe_text_zone / visual_role / primary_visual_type / image_weight / text_overlay_mode / max_visible_words / copy_budget / main_visual_layer / supporting_visual_layer / text_overlay_zone / visual_story / semantic_image_prompt / forbidden_layout`,
|
|
1296
|
+
然后按这些字段实现;不要只看 `archetype/composition` 自由发挥。
|
|
1297
|
+
- 🎤 **讲稿落盘**:该页 design.json 有 `speaker_notes` 时,在该 `<section>` **末尾**原文写入
|
|
1298
|
+
`<aside class="speaker-notes" hidden>…</aside>`——`[hidden]{display:none!important}` 已全局定义,
|
|
1299
|
+
它**不渲染、不进几何测量、不算上屏文字**;导出器会把它写进 PPT **备注栏**(演讲者视图)。
|
|
1300
|
+
无 speaker_notes 的页不写 aside;**绝不**把讲稿渲染成可见文字/卡片。
|
|
1301
|
+
- 🎤 **上屏文字以 design 的 points 为准、禁扩写**:不要把 evidence/speaker_notes 的论证句搬上屏——
|
|
1302
|
+
观众 3–5 秒要能读完一页;想补充的话写进 aside 讲稿。
|
|
1303
|
+
- `main_visual_layer` 是本页第一眼视觉,必须真实落地为背景图、产品/场景/特写图、客户图增强图或 HTML/SVG 数据图;不能只写成渐变底、文字内容或卡片容器。
|
|
1304
|
+
- `supporting_visual_layer` 是辅助视觉,若写了底部场景锚点、前景透明特写、局部插图、参数轴、证据图带,就必须在 HTML 中出现;不要只保留文字。
|
|
1305
|
+
- `text_overlay_zone` / `safe_text_zone` 是文字净区,标题和主句必须落在这里,不能再用大白卡/灰卡强行切割画面。
|
|
1306
|
+
- `semantic_image_prompt` 是本页语义配图约束:AI/图生图页的画面必须回应 `one_sentence_takeaway`,背景/场景/特写图不得含文字、Logo、字母、水印;HTML/SVG 页写 `html-svg:<图表类型>`,前景用可编辑图形表达。
|
|
1307
|
+
- `forbidden_layout` 是硬禁令:若写了 no card wall / no table wall / no white floating panels / no image frame,本页就绝不能出现文字卡片墙、表格墙、大白浮层或带边框裱图。
|
|
1308
|
+
- `page_grammar=hero-scene / cinematic-feature / product-closeup / before-after-scene / spec-overlay`:图片、产品、场景或特写是第一主角,按 `image_weight` 让视觉占 60%–90%,文字按 `text_overlay_mode` 浮在 `safe_text_zone`。
|
|
1309
|
+
- `page_grammar=image-mosaic`:做 DJI 式影像拼贴,多张 rounded image tile,每块图为主体,短标签浮在图上;禁止标题+正文+小图标的文字卡片网格。
|
|
1310
|
+
- `page_grammar=data-visual`:必须有 SVG/chart/axis/bar/line 等可编辑数据视觉,文字只是结论和图例。
|
|
1311
|
+
**同一组数字禁「图表+卡片」双重复述**(2026-07-02 体检:柱图与右侧卡片重复同三个百分比)——图表已表达的数据,旁边只放一句结论,不再排一列数字卡。
|
|
1312
|
+
**图表数值必须与图形一致**:柱高/条长 ∝ 数值(20% 的柱绝不能画得比 80% 高);图内标签必须装得下(图形画大而不是字缩小)。视觉门有确定性图表检查(chart_sanity_check)。
|
|
1313
|
+
🚫🚨 **真机复盘(2026-07-05 ROI 页事故):水平柱图里数值接近/等于满刻度的那根柱(条长撑到绘图区右边缘),其数值标签沿用了"画在柱子右侧"的写法(`text-anchor:end` 且 x 落在柱子末端附近),但柱子右边已经没有余量可画——标签只能叠画在柱子内部,且标签沿用了"柱外文字"的深色 fill(与柱子填充色几乎同色),导致标签实测对比度 1.00(完全不可见)**:柱长 ≥ 绘图区宽度 90% 时,数值标签必须画**在柱内部靠右**(`text-anchor:end`,x 取柱右端往左留 12–16px),并把 fill 换成**柱子填充色的高对比色**(深色柱配白/浅字、浅色柱配深字)——不能沿用"柱外标签"那套深色写法;柱长 < 90% 时才继续用画在柱子右侧外部的写法。同一张图里几根柱子长短不一时,每根柱子的标签样式要按自己的柱长单独判断,不能整张图统一套一种标签写法。
|
|
1314
|
+
🚨 **真机复盘(2026-07-05 复盘:13 页 deck 里 `list`/`metric` 数据结构页——第 2/9/10/11 页共 4 页同时中招):这类页 `design.json` 算出的 `image_weight≈0`/`text_overlay_mode:none`(图只是给 HTML/SVG 图表留白的"低干扰材质背景",`img_plan.json` 里的 prompt 也明确写了 `subtle material depth`),但 build_batch 仍照抄编辑式三层骨架给了一层 `.edit-scrim`,不透明度写到 0.82~0.90(近纯白)——生成的 AI 背景图被整页盖死,导出截图上完全看不出任何图片痕迹,等于白花一次生图成本、图片形同虚设**:`image_weight` 判定接近 0 的 data-visual/list/metric 结构页,`.edit-scrim` 的最高不透明度不得超过约 0.6(让"低干扰材质深浅纹理"仍隐约可辨,不能整页糊成纯色白板);若该页文字/图表对比度因此不够,靠**局部**scrim(只在文字/图例紧贴区域加深)而不是把整页拉到 90% 不透明度去解决——整页高不透明度 scrim 只留给 `image_weight` 真正高(≥0.6,hero/scene 类页面需要衬文字)的页面用。
|
|
1315
|
+
- `product-hero / feature-theater / scenario-fullbleed / detail-closeup`:图像、产品、场景或特写占 60%–85%,文字浮在净区。
|
|
1316
|
+
- `data-visual`:做 HTML/SVG 柱状图、曲线、参数轴、对比条或指标环,禁止大表格矩阵。
|
|
1317
|
+
- `gallery-strip`:仅作证据图带/小画廊,禁止卡片墙。
|
|
1318
|
+
- `chapter-cinematic / quote-focus`:大图大字,少量信息,不补卡片填满。
|
|
1319
|
+
按设计实现:
|
|
1320
|
+
- **deck 纵向流式(人可滚动审阅,像 PPT 导出的 PDF)**:`.slide` 容器用 **`position:relative`、每页 1920×1080 自上而下排开**
|
|
1321
|
+
(body 深色衬底分隔每页,见 §0.7 骨架)——**绝不把各页 `position:absolute` 叠在同一位置**(那样直接打开 deck.html 所有页会糊成一团、没法审阅)。
|
|
1322
|
+
导出器导出时会逐页隐藏其余页、把当前页钉回视口截图,**流式布局不影响导出/构图门几何**(仍按真实 1920×1080、零偏移)。
|
|
1323
|
+
- **页内 grid 结构化构图**(按 composition:左右/左中右/上下/上中下/四宫格/中心辐射…用 `display:grid` + 模板,**页内别绝对定位**;
|
|
1324
|
+
`position:absolute` 只许页**内部**的 B 路线全幅底图 + 浮层文字)。
|
|
1325
|
+
- 🚨 **结构性高度 bound(治反复出现的「内容超出页面尤其下边缘」——slide 物理上溢不出,构图门才不用反复脑算)**:
|
|
1326
|
+
页内容区高度被 `.slide` 卡死(= 1080 − 上下 padding ≈ 976px,不会被内容撑大)。**多行 grid 的行用 `1fr`(如 `grid-template-rows:1fr 1fr`)+ 每个 grid 单元/卡片 `min-height:0`/`max-height:100%`**——行/单元被容器卡死、绝不被内容顶高溢出页底;
|
|
1327
|
+
单元内**图片默认 `width:100%;height:100%;object-fit:cover`(填满该单元、被单元 1fr/min-height:0/max-height:100% 卡死,绝不靠 `aspect-ratio` 把行撑高溢出);仅 dense-info 证据图需完整保数据时 `max-height:100%;object-fit:contain`**;
|
|
1328
|
+
🚫🚨 **真机复盘(2026-07-05 第4页事故):`grid-row:2` 的图片写了 `height:auto; aspect-ratio:21/9`(放弃 `height:100%`),图按自身宽高比在 976px 高的页面里独立撑出 ≈724px 高,把同页 `grid-row:3` 的底部内容压穿、几何门报【内容相互叠加】93%**——
|
|
1329
|
+
错误写法:`<div class="fig-fill" style="grid-row:2; height:auto; aspect-ratio:21/9;">`;
|
|
1330
|
+
正确写法:`<div class="fig-fill" style="grid-row:2; height:100%; min-height:0;"><img style="width:100%;height:100%;object-fit:cover;">`(高度交给行轨道 `1fr` 决定,图片用 `object-fit:cover` 裁填,不用 `aspect-ratio` 二次决定高度)。
|
|
1331
|
+
`aspect-ratio` 只在该图独占一整页/一整栏(无需与其他行竞争剩余高度)时才安全用。
|
|
1332
|
+
🚫🚨 **真机复盘(2026-07-05 又见同类事故,这次是 `.fig-contain` 共享组件被内联 `aspect-ratio` 覆盖):`references/layout-composition.md` 定义的 `.fig-contain` 类本身是 `width:100%;height:100%`(正确、安全,交给父级 1fr 轨道决定尺寸),但第6/8页各自写了 `<div class="fig-contain" style="aspect-ratio:1432/792;width:min(1320px,80%);">`——**内联 style 里的 `aspect-ratio` 会覆盖类里的 `height:100%`**,图按自身宽高比独立撑出固定像素高(如 729px),撑爆 `grid-template-rows:auto 1fr auto` 的中间 `1fr` 行,几何门报「可见部分仅7%~13%」的 catastrophic 不可见错误、直接把 `-p` 进程在 `stage_export` 硬 halt(无重试)**:
|
|
1333
|
+
错误写法:`<div class="fig-contain" style="aspect-ratio:1432/792;width:min(1320px,80%);">`;
|
|
1334
|
+
正确写法:`<div class="fig-contain" style="width:min(1320px,80%);">`(不加 `aspect-ratio`,让类自带的 `width:100%;height:100%` 生效,容器尺寸由外层 flex/grid 决定;图内部已经是 `object-fit:contain`,不需要外层再定死宽高比)——**任何 `.fig-contain`/`.fig-fill` 组件都不准在内联 style 里加 `aspect-ratio`,这两个类的类级 CSS 已经是安全写法,加 `aspect-ratio` 就是在覆盖它、重演这个事故**。
|
|
1335
|
+
🚫🚨 **真机复盘(2026-07-05 第8页事故):图片和它下方的说明卡片被写成两个独立 `<div>`,各自声明同一个 `grid-column:1/2; grid-row:2/3`**(图 `height:100%` 铺满整格,卡片行 `display:flex; justify-content:flex-end` 也铺满同一整格、只是把内容推到格子底部)——CSS Grid 允许多个子元素落在同一格,两者各自撑满整格高度、互不知道对方存在,图和卡片按 DOM 顺序**直接叠在一起**,几何门报卡片与图片重叠 74%~78%:
|
|
1336
|
+
错误写法:`<div style="grid-column:1/2;grid-row:2/3"><img ...></div>` 紧跟 `<div style="grid-column:1/2;grid-row:2/3;display:flex;justify-content:flex-end">卡片行</div>`(两个独立同格子兄弟节点);
|
|
1337
|
+
正确写法:把图和卡片行**包进同一个 `<div style="grid-column:1/2;grid-row:2/3;display:flex;flex-direction:column">`**,图用 `flex:1;min-height:0` 占据剩余空间、卡片行紧跟其后自然排在图下方(普通 flex 文档流顺序落位,不再各自二次声明整格 grid 定位)。**同一 grid 格子如果要塞「图+其下方内容」两块东西,只能靠嵌套一层 flex 容器实现"先图后卡"的顺序流,绝不能让两块内容各自单独占位同一个 `grid-column/grid-row`**(那样是重叠不是堆叠)。
|
|
1338
|
+
卡内内容用 flex 纵向排,**预估装不下就走下面「排不下时的自救顺序」(精炼→双列→拆页)**,绝不让单元内容顶破页底。**四宫格塞 3+ 图易溢出:超 3 张改画廊/拆页,别硬塞 2×2。**
|
|
1339
|
+
- **三层语义化**:卡片用带底色/边框的 div、文字用 h*/p/span、图用 img/svg——导出器自动分层,正常写语义 HTML 即可
|
|
1340
|
+
(标注仅作 override:`data-pptx-layer="foreground"` 强制成块 / `data-pptx-export="ignore"` 保留烧底图)。
|
|
1341
|
+
- **每页 ≥1 真实主视觉**:无客户图且不是流程/数据/架构/关系/时间线/参数轴这类 HTML/SVG 精确信息页时,必须引用 `assets/ai_p<page>.png` 作为语义主视觉或背景,不得只用抽象渐变/色块;流程/数据/架构页则必须有 SVG/chart/axis/bar/line/节点图等可编辑图形,别只有文字+背景板。
|
|
1342
|
+
- **字号阶梯(放映级,≈1.5×,治正文太小)**:正文/卡片正文 **≥38px**;小标题/卡标 ~44–52px、副标/引言 ~40–46px、注释/角标 ~28–32px、药丸/图例/图内标签 ~26–28px(**屏上别低于 24px 导出下限**);
|
|
1343
|
+
小标题/副标按构图比例介于正文与该页主标之间、**绝不 ≥ 主标**;**只有封面主标(~88–120px)/章节大序号(~150–180px)维持现状不缩**,内容页主标 ~72–88px。
|
|
1344
|
+
图表/框图/图标**内部文字**同样达放映级下限,**图形相应画大以装下、不挤不裁**(见 layout-composition §0.85;导出端 layout_balance 会对屏上 <24px 报【字号过小】WARNING)。
|
|
1345
|
+
**字体 token 固定档位**:CSS 必须定义并复用 `--fs-hero`、`--fs-title`、`--fs-subtitle`、`--fs-body`、`--fs-note`、`--fs-label`、`--fs-axis`(或等价类 `.fs-hero/.fs-title/.fs-body/.fs-label`),正文、图表标签、节点标签只用这些档位;**禁止随手 inline 写很多 22px/23px 小字**,SVG `<text>` 也必须 >=24px 且与 token 对齐。
|
|
1346
|
+
- **所有可读文字必须是真实 DOM 文本节点**(h*/p/span/SVG `<text>`)——**严禁**把可读文字写进 CSS `::before/::after content`、**严禁**把文字烧进背景图/HTML 图元/SVG `<path>`(否则被截图夹带、不可编辑、还会与还原文本双层)。唯一例外=AI 插图画面自带字。(导出端 layout_balance 有【截图夹带文本】ERROR 兜底。)
|
|
1347
|
+
- **list/目录等稀疏页占满整宽**:用「文字主栏 + 侧栏视觉」两栏,或多条等价项直接双列铺满(`grid-template-columns:1fr 1fr`),**绝不**塞进 max-width 受限的窄单列任右半空(见 §0.7)。
|
|
1348
|
+
- **可拖结构用离散 HTML 元素搭、别画整块 SVG**:架构层/流程节点/决策树/一排圆/卡片矩阵——**每个层/节点/圆/卡是独立 `<div>`**(自带底色边框、grid/flex 排),导出会**递归切成各自可拖对象**;SVG 只画连线/箭头/真矢量(连线作底层)。整块 SVG 画的结构图节点不可拆(矢量整张)。
|
|
1349
|
+
**结构图类名契约**:节点统一 `.diagram-node` / `.flow-step` / `.metric-chip`,连线统一 `.diagram-link`,线标签统一 `.diagram-label`;每条 `<line>/<path>/<polyline>` 必须连接两个可识别节点中心或边缘,不能有孤立连线、乱飘线、无归属箭头。连线文字、轴标、问答标签都用字体 token,不得出现小于 24px 的 SVG 文本。
|
|
1350
|
+
- **卡片/选项卡内部填实 + 文字不溢出 + 卡数随文长(治「窄卡长文溢出重叠糊成一团」「大白卡大片留白」「文字沉底中间空」)**:
|
|
1351
|
+
① **文字必须完整容纳在卡内、不溢出不裁切不与邻卡重叠**——卡内文字用正常**流式排版**(block/flex 流,**绝不**对卡内文字 `position:absolute`),卡高/卡宽按文字量给足;屏上预估装不下就**减字/拆卡/拆页**,绝不硬塞溢出。
|
|
1352
|
+
② **一行卡数随单卡文字长度收敛**:单卡文字多(>1–2 行说明)时**一行最多 3 卡**;要排 4–5 卡只能放「短标签/小标题」类极短文字,长文 4–5 列必溢出重叠(实测事故)——宁可拆成两行卡或两页。
|
|
1353
|
+
③ **卡内内容垂直+水平填满、不留大空**:标题/正文/图元用 flex 纵向**均匀分布或居中**(`justify-content`),别标题挤顶、正文沉底、中间一大段空白;「大白卡装一句话」按内容定卡尺寸/减 padding/放大内部图元铺满。
|
|
1354
|
+
🚨 **点名机制:`margin-top:auto`/`align-self:flex-end`/`justify-content:flex-end` 这类"把文字推向卡片边缘"的写法就是③的反面(2026-07-05 真机复盘:`.security-card{display:flex;flex-direction:column;height:100%}` 配 `.desc{margin-top:auto}`,图标+标题贴顶、仅 1 行描述被推到卡底,网格 `align-items:stretch` 把卡撑到整行高,中间露出大片模糊背景——四重防线安全矩阵页实测事故;这类"空心大卡"外框仍算满,构图门测不出,只能靠写对 CSS 防患于未然)**:卡内文字/图标元素禁止用 `margin-top:auto`/`align-self:flex-end`/`justify-content:flex-end` 把自己撑向卡片边缘;描述文字撑不满整卡高度时,要么给父容器 `justify-content:center` 让内容整体垂直居中,要么把描述写够 2–3 行实质内容——不能用外边距/对齐属性把单薄内容"撑"到看起来占满卡高。
|
|
1355
|
+
④ 一列层块/节点别堆到高过画布可用区(1080 − 上下 padding,内容多就拆两栏/拆页)。导出端有【卡片/分组填充不足】【文本裁切】【超出画布】WARNING 兜底,但**靠这里写对最省事**。
|
|
1356
|
+
🚨 **`align-self:center`/`align-items:center` 撑爆画布时会把顶部(含标题)挤出画布,比溢出到底部更隐蔽更严重(2026-07-05 真机复盘:p6「必被替换的五个理由」左栏 `align-self:center` 的 flex 列里塞了 eyebrow 角标+两行大标题+正文+5 条 `bullet-strip`(每条 label+sub 两行),总高度远超 1080px 画布,垂直居中导致顶部的 eyebrow 角标和标题第一行整体被推到画布外、完全看不见,只露出标题被切掉顶部的残影)**:这一列内容如果包含"大标题 + 正文 + ≥4 条 bullet/卡片"这种量级组合,先粗估总高度(标题行高 + 正文行高 + 每条 bullet 的 label/sub 两行 × 条数 + 间距),压线或超出画布可用高度时——**优先精简 bullet 数量或拆两栏/拆页**,而不是继续用 `align-self:center`/`align-items:center` 掩盖溢出(居中会静默吃掉标题,`align-self:start`/`flex-start` 至少能让溢出的部分留在底部、标题仍可见,但这终究是兜底不是正解,治本是控制内容量不超高)。
|
|
1357
|
+
⑤ **文字必须是卡片的 DOM 子元素、卡尺寸随内容自然撑开**(inline-block/fit-content + padding;**禁止固定宽高卡片 + 更宽的文字/外层 wrapper 兜字**——字会骑出卡缘,2026-07-02 末页 CTA 实测事故)。视觉门 --ppt-strict 有【文字溢出卡片】ERROR 兜底,写对省一轮。
|
|
1358
|
+
⑥ **同一空洞原理在页面级的另一种写法:内容块自身高度只由内容撑开(auto),却被放进 `grid-template-rows:auto 1fr` 的 `1fr` body 行——若该内容块没有显式撑满这个 1fr 行(如 `height:100%` 配合 `justify-content:center` 让整组内容居中),渲染结果就是内容块贴在行顶部、下方露出大片空白背景(2026-07-05 真机复盘:`.slide.list` 「链式价值」页,4 张证据卡的 flex 行实测只有 251px 高,但它所在的 `1fr` body 行可用空间远不止于此,下方约 540px——接近整页高度一半——完全空置;构图门测不出这类"块内已填实、但块与可用行高不匹配"的页面级空洞)**:body 内容块(卡片行/图文组等)要么给自己 `height:100%` 且用 `justify-content:center`/`align-items:center` 让内容组在这个满高容器里整体居中(而不是让内容组自身只有 auto 高度浮在行顶),要么确实需要更多与主题相关的内容/图形把这份可用高度用起来——不能让一组内容卡浮在页面上方、下半页整页留白。
|
|
1359
|
+
🚨 **圆形徽标/环形进度条内嵌文字(`.ring`/`.ring-label`/`.step-num` 这类固定直径的圆形组件)默认按 1–3 位短数字/百分比/序号设计,塞进较长文本会溢出圆外、与旁边内容重叠(2026-07-06 真机复盘:两页同一根因——①`.ring-label`(140px 圆)塞入 7 字符「N周→N小时」,文字宽度远超圆直径,视觉溢出圆环;②`.step-num`(80px 圆)塞入「6–12 月」4 字符,无 `white-space:nowrap` 折成「6/12/月」三行堆叠,溢出圆外与下方的步骤标题重叠,像素实测最差对比度 1.00~1.03)**:写入这类圆形容器前先数内容的字符数——1–3 位数字/百分比/单字符序号可以直接放圆里;超过 3–4 个字符(含范围符号"→""–"的多段文本,如"N周→N小时"、"6–12 月")**必须改用横向胶囊/矩形标签**(`border-radius` 较小的圆角矩形,宽度随文字内容撑开),不能硬套圆形容器指望文字自己缩小或换行躲开——圆形组件的直径是为短内容定的,长文本没有"缩小到能塞进圆里"这个自动机制。
|
|
1360
|
+
- **文字对比度铁律(治深底黑字看不清)**:浅底(VI 浅紫/白)配**深墨字 `var(--ink)`**;深底(封面/章节/深色卡)配**白/浅字**;**绝不深底深字、浅底浅字**。任何页/卡用了深底,其文字必须随之转白。导出端【文字对比度不足】会 WARNING 提示(导出步顺手改)——**靠这里写对最省事**,别留给后面修。
|
|
1361
|
+
🚫🚨 **给深底文字转白时,别用 `text-white` 这类单类工具类去覆盖已有更高特异性的选择器(2026-07-05 真机复盘:`.slide.section` 章节分隔页 5 页全部中招——CSS 里 `.t-takeaway{color:var(--ink)}` 是单类选择器,但同一份 CSS 还定义了 `.slide.section .t-takeaway{font-size:...;color:var(--ink);max-width:1200px}`【两个类的后代选择器,特异性 (0,3,0),高于单类 `.text-white{color:#fff}` 的 (0,1,0)】——模型给该段落写了 `class="t-takeaway text-white"` 想转白,但 `.slide.section .t-takeaway` 的 `color:var(--ink)` 因特异性更高而胜出,`text-white` 完全不生效,段落实际仍渲染成近黑色 `rgb(16,19,24)`,叠在右侧照片上像素实测仅 23%~43% 可读)**:①写这类"归档式"选择器(`.slide.<archetype> .<组件类>`)时,除非**真的要改**颜色,否则不要顺手把 `color` 也一起复制进去(那条规则本意通常只是调字号/宽度,混进 `color` 纯属埋雷,其它页面还想转白时就会被这条规则的特异性挡住);②确实需要给某个具体元素转白/转深时,**用内联 `style="color:#fff"`**(内联样式特异性天然最高,不受任何 class 选择器组合影响),不要依赖 `text-white`/`text-ink` 这类工具类去对抗可能存在的多类选择器覆盖——工具类只在"没有更高特异性规则"时才可靠。
|
|
1362
|
+
- 🚨 **角标/标签强调色文字必须自带色块底,禁止裸色浮在不确定背景上(2026-07-03 真机复盘:`--arsenal-blue` 类强调色被 `.t-eyebrow`/`.bullet-row .label` 全局复用,在 15+ 处因背景明暗不定而不可读)**:`.t-eyebrow`(页角标"01·XXX")、`.bullet-row .label`("2019 事故"这类短标签)等**强调色短文字**,不得直接裸色浮在照片/渐变/不确定底色上——该 class 统一加一层小色块或半透明底(如浅灰/白色 pill、或紧贴的深色 scrim 条),不需要逐处判断背景深浅、一次 CSS 规则覆盖全部实例即可稳定可读。这类文字**优先本身就用 `var(--ink)`/白色高对比色**(不是必须用强调色),确需强调色时才加色块。
|
|
1363
|
+
- **文字压图必须垫 scrim(2026-07-02 逐页体检:标题横穿明暗跨界照片不可读)**:任何直接落在**背景图片**上的标题/正文,必须满足其一——①文字区下有紧贴的局部 scrim/渐变暗角(linear-gradient 或半透明底条,不是大白卡);②文字落在图的**纯净留白区**(source_layout_plan 的 text_zone);③背景图在文字区本来就是低细节暗部/亮部且与字色对比 ≥3。视觉门有**像素级实测**(text_readability_pixel),压图不可读会被打回重修——写对省一轮。
|
|
1364
|
+
- 🚨 **任何用 `.edit-bg`+`.edit-scrim`+`.edit-content` 三层的页(不只 split/two-col,`.slide.section` 章节分隔页同样适用!),渐变方向必须对齐文字实际所在的栏(2026-07-04 真机复盘:p3「一次代价高昂的质量事故」+ p7「1台顶多台」两页同一根因;2026-07-05 复盘再现:p2「「看见」所有细节」+ p5「从拍照到全景复刻」两个 `.slide.section` 章节引导页,文字明明在 `grid-column:1/2`【左栏】,`.edit-scrim` 却原样照抄 `layout-composition.md §0.7` 示例的「左透明→右不透明」方向,文字所在的左栏恰好是渐变最透明的一端,标题/副标题落在背景图的亮部上,像素实测 44%~85% 采样点不可读——说明上一轮把这条规则误读成「只对 split/two-col 生效」,`.slide.section` 被漏判)**:写 `.edit-scrim` 前先看这页文字在 `.edit-content` 的哪个 `grid-column`,**与页面用的是 split/two-col/section/hero-scene 等哪个 archetype 无关**——文字在右栏就要把渐变**镜像**成「左透明→右不透明」(如 `linear-gradient(90deg, rgba(8,12,20,0) 0%, rgba(8,12,20,.28) 44%, rgba(8,12,20,.64) 100%)`,浅底模板对应换成浅色磨砂那版镜像);文字在左栏就要维持/换成「左不透明→右透明」(如 `linear-gradient(90deg, rgba(8,12,20,.78) 0%, rgba(8,12,20,.32) 64%, rgba(8,12,20,0) 100%)`,即把 §0.7 示例整个反过来抄,不是原样抄)。**唯一判据是文字所在的 `grid-column`,不是 class 名字**;不透明端永远跟着文字栏走。
|
|
1365
|
+
🚫🚨 **深浅 scrim 变体必须跟文字色绑定(2026-07-05 真机复盘:镜像方向改对了、字色没跟着换——第3页浅色 VI 模板用了深色 `rgba(8,12,20,…)` 镜像 scrim,文字却仍是模板默认的 `var(--ink)`/`var(--ink-soft)` 深墨色,深底深字 100% 不可读)**:选了深色(`rgba(8,12,20,…)`)scrim 变体,该栏文字必须整体换成白色/浅色(`#fff`/`rgba(255,255,255,.85)` 等),不能留用 `var(--ink)`;**浅色 VI 模板(白底+深字,如 aegis-vector 系)优先选浅色磨砂镜像变体**(如 `rgba(255,255,255,.85) 0% → rgba(255,255,255,0) 100%` 镜像),这样可以继续沿用模板默认深字、不用整页切换字色,出错概率更低。
|
|
1366
|
+
🚫🚨 **"图渐隐入纸感面板"式 scrim 的不透明拐点必须早于文字栏起点、不能跟文字栏同步才刚开始变浓(2026-07-05 真机复盘:p4「一次代价高昂的质量事故」+ p14「安全性能否保障」两页同一根因——`.slide.split` 用 `.85fr 1.15fr`,文字栏(`grid-column:2/3`)大约从 44%~46% 宽度处开始,但 `.edit-scrim` 写的是 `linear-gradient(90deg, rgba(8,12,20,0) 0%, rgba(8,12,20,.18) 44%, rgba(255,255,255,.88) 72%, rgba(255,255,255,.95) 100%)`——白色不透明度要到 72% 宽度才冲到 0.88,44%~72% 这一段(恰好是文字栏靠左近一半的区域)背景还是「原图 + 一点点暗调」,`.body-text`/`.evidence` 这类中等灰字(`var(--ink-soft)`/`var(--muted)`)落在这段里被原图内容影响得忽隐忽现、像素实测发白发糊;`.takeaway` 标题字因为字号大、字重粗、恰好起始位置更靠右,反而躲过了这段没暴露)**:文字栏起点算法(图栏 fr 值/(图栏 fr+文栏 fr) 的百分比,如 `.85fr 1.15fr` 约 43%~46%,`1.15fr .85fr` 约 54%~57%)算出来后,**渐变必须在这个百分比之前就已经到达 ≥0.85 不透明度**(如上例应把 `.88` 那个 stop 从 `72%` 提前到 `46%` 左右,而不是让白色接管发生在文字栏中段)——不能让文字栏内还有一截背景仍是「原图 + 淡淡暗调」的过渡区,纸感面板要在文字开始前就已经铺满。
|
|
1367
|
+
🚨 **以上"scrim 不透明区必须覆盖文字实际所在区域"这条原理不分横竖轴、不分具体 CSS 写法(2026-07-05 真机复盘:某页自建了 `.edit-scrim.light-bottom{background:linear-gradient(180deg, rgba(255,255,255,0) 28%, rgba(255,255,255,.55) 100%)}`——上到下、透明到半透明白,但该页标题/副标题在 `.deck-header`,天生落在 `.edit-content` 的顶部第一行,恰好是这个渐变最透明【0%】的区域;`.deck-title`/`.deck-subtitle` 用的是 `var(--ink)`/`var(--ink-soft)` 深色字,深字配透明底、露出的是原始背景图,标题几乎融进背景看不清——这与前面两条横向 scrim 规则是同一个原理在【竖轴】上的重演,只是这次渐变类名/写法是这一轮自建的 `light-bottom`,不是之前见过的 `dark-left/right`)**:不管这页的 `.edit-scrim` 是横向渐变、纵向渐变、径向渐变,还是随手定义的什么类名,动笔前先确认——深色文字(`var(--ink)`系)落的区域,该渐变在那个区域必须是浅色/高不透明度;浅色文字(`#fff`/`rgba(255,255,255,…)`)落的区域,该渐变在那个区域必须是深色/高不透明度。`.deck-header` 天生在页顶(`grid-template-rows` 的第一个 `auto` 行),凡是纵向渐变都要先检查页顶这个区域是否已经给到位,不能只顾着给页面某一角落(如底部字幕条)留不透明度、却让页顶的标题落空。
|
|
1368
|
+
🚨 **同一原理还有第三种漏判:方向和拐点位置都对,但超大号单行标题本身的渲染宽度超出了共享 scrim 类固定的不透明区宽度(2026-07-05 真机复盘:p3「一次代价高昂的质量事故」这次方向已改对——`.scrim-left-dark` 确实左深右浅,与文字所在的单列 `grid-column:1/-1` 同侧——但 `.scrim-left-dark` 的不透明度在 44% 已经掉到 .48、78% 完全归零;该页 `.section-name`(96px 大字号单行标题)是 11 个满宽汉字,渲染宽度已经延伸到约 60% 页宽,标题后半"昂的质"几个字落进渐变已经显著变透明的区域,与背景航拍图里飞机机身的亮部叠在一起、可读性骤降——`--ink` 深色字这次没错,scrim 方向也没错,错的是"以为这个共享 scrim 类的固定拐点百分比对所有标题长度都够用")**:给 `.section-name` 这类内容量可变的超大号单行标题配置/复用 `scrim-left-dark`(或同类共享 scrim 类)时,不能假设共享类的固定百分比拐点天然够用——按"字符数 × 字号"粗估这行标题的实际渲染宽度,确认 scrim 深色区(≥0.7 不透明度那一段)**延伸到覆盖这个估算宽度**;标题偏长(章节页大标题 8 字以上很常见)就要把这页的 scrim 拐点百分比相应改宽(不必和其它标题较短的页面共享同一个固定百分比),或把标题精简到能被现有 scrim 宽度盖住的长度。
|
|
1369
|
+
- 🚨 **`.slide.section` 章节分隔页是纯居中布局(`grid-template-columns:1fr; align-content:center`,标题/副标题永远钉在画面正中,没有左右栏可言),若给它的 `.edit-scrim` 选用径向渐变,深色区必须覆盖中心,绝不能是"中心透明、只在边缘变暗"的暗角/vignette 型径向渐变(2026-07-06 真机复盘:`ai_p7.png` 是一张办公桌场景照片,画面最亮的区域恰好在正中央,却配了 `radial-gradient(ellipse at center, transparent 0%, transparent 40%, rgba(8,12,20,.55) 90%, rgba(8,12,20,.78) 100%)`——中心 0~40% 完全透明、只有 90%+ 的边缘才变暗——但该页标题「三个疑虑」/副标题都用 `align-self:center;justify-self:center` 定位在正中央,恰好落在 scrim 完全不起作用的透明区,直接叠在图片最亮的白墙上,像素实测 100% 采样点对比度 <3.0、最差仅 1.03;同一份 CSS 里另外两页章节分隔页因背景图中心恰好偏暗才侥幸没暴露同一颗雷)**:`.slide.section` 用径向渐变时必须选"中心深、边缘浅"(如 `radial-gradient(ellipse at center, rgba(8,12,20,.6) 0%, rgba(8,12,20,.6) 40%, rgba(8,12,20,0) 100%)`),不能假设 AI 生成的背景图中心天然是暗的;暗角/vignette 型(中心透明只暗边缘)只适合文字紧贴四周边缘的页面,绝不能用在内容居中的模板上——更省心的做法是 `.slide.section` 一律直接用线性 `scrim-top`/`scrim-bottom` 或简单纯色半透明底(`rgba(8,12,20,.5)` 铺满整页),不必纠结径向渐变的中心/边缘取舍。
|
|
1370
|
+
- **文案精炼·说人话(治内容顶出/字太小)**:上屏文案精炼归纳、用类比/例子把概念讲透(如「全景相机」=「多镜头拼谷歌街景那种可转视角画面」、「π」=「约 3.14~3.15」),近似但好懂优于堆砌精确;**别把长定义硬塞一页**。
|
|
1371
|
+
- **排不下时的自救顺序(绝不缩字到 <24px、绝不顶出画布)**:① **精炼文案 + 图文并茂**(流程/对比/层级/数据用 HTML 图表/SVG/图标/卡片表达,一图省一段话)→ ② 一列条目多就改 **grid 两列**(`grid-template-columns:1fr 1fr`)→ ③ 仍排不下就**拆成两页**(新增一个 `<section class="slide">`、同一主题分上下篇,别死磕一页)。导出端【超出画布】【字号过小】WARNING 触发时按此序处理。
|
|
1372
|
+
- **配色解耦(治一片单色)**:只有背景/页面底板/chrome 用 VI;**图表数据系列用可区分分类色**(见所选 VI 文档「数据可视化分类色」)、非背景插图用画面真实色、辅助解释图形用语义色,都与 VI 协调不冲突(见 §0.9)。
|
|
1373
|
+
- **背景按 design 的 background 意图**做同色系深浅/光位变化,相邻页不雷同。
|
|
1374
|
+
- **客户图(现已【全部 route=source-enhanced 图生图重绘到槽位比例】)= 必须全用 + 填满槽(`.fig-fill` cover)+ 按朝向/重点区图文混排 + 配色随图**(首轮动手前 Read ui-design 技能目录的 `references/source-image-layout.md`,并 Read `./build/material.json` 取每图的 vision/stats):
|
|
1375
|
+
**plan_source_layout 已把所有客户图 `enhance_required=true`**(唯一例外=无 vision 盲态)——用 `<img src="assets/<enhanced_file>">` 并在 `data-source-file="<source_file>"` 保留原图映射(用尽闸门/追溯用)。
|
|
1376
|
+
若 `enhanced_file` 生成失败,回退 `<img src="assets/<source_file>">` 的合适布局,不能删除该客户图、不能空占位(缺图兜底脚本会自动 cp 原图顶上,见 stage_export `--reconcile-missing`)。
|
|
1377
|
+
**图生图已重绘到槽位目标比例,所以放进 §0.7 `.fig-fill` 用 `object-fit:cover` 填满该槽**(配 `object-position:<key_region 中心%>` 保重点)——**默认 cover 填满、不留白裱框/letterbox 黑边**;**仅 dense-info(截图/图表,需完整保数据)才 `object-fit:contain`**(其槽 `aspect-ratio` 按图比例定、零裁切)。🚫禁 `max-height` 帽、🚫禁 `.src-figure{background:白/surface;padding}` 白裱框(真凶 2)。
|
|
1378
|
+
按 orient 用 grid 排:横图→上/下整幅横带+文字在另一侧、竖图→左/右整列+文字对侧栏、方图→左右或居中配题注。
|
|
1379
|
+
**据 material.json 精排(§5/§6)**:① 该页文案呼应该图 `vision.description`(图文对得上);② 文字/卡片放 `vision.recommended_text_zone`,**绝不压在 `vision.key_region` 上**;③ 配色取 `stats.dominant_colors`、文字按 `stats.brightness` 定深浅(深图白字、浅图深字,绝不靠色);
|
|
1380
|
+
④ `visual.bg`(或 vision.suitable_as_background)的图可铺**整页背景**:`background-size:cover` + `background-position:<key_region 中心%>`(重点不被裁)+ scrim 只压文字侧。客户原图**已真实存在于 assets/**(src_K.png),增强图在阶段10生成(enhanced_src_K.png)。**material.json 里每张客户图都要以原图或增强图形式在 deck 里出现(用尽闸门会查)。**
|
|
1381
|
+
- **背景层放图 = 逐字复用 §0.7【锁定编辑式三层骨架】(🚫🚫绝不渐变压图)**:
|
|
1382
|
+
原样 inline `layout-composition.md §0.7` 的锁定骨架——`.edit-bg`(图 `background-size:cover` 或内部 `<img class="bg-img">` `object-fit:cover` **填满** + `--vi-fallback` 纯色兜底在底)/ `.edit-scrim`(**半透明**遮罩,渐变只进这层)/ `.edit-content`(前景 z-index:2)。
|
|
1383
|
+
🚫🚫 **绝对禁止 `background:<不透明渐变>,url(img)`**——CSS 逗号前的渐变画在图**上面**、把 AI 图整张盖死(真机头号事故:封面/综述全成空蓝渐变)。AI 失败的兜底靠**资产级渐变占位 PNG**(generate 写)+ `.edit-bg` 的 `--vi-fallback` 纯色,**绝不靠 CSS 渐变盖图**。
|
|
1384
|
+
🍎🚨 **每个内容页 `.edit-bg` 必有背景图层——`route` 只决定【前景怎么呈现】(HTML 图表 / 文字 / 插图),【不决定有没有背景】,背景层永远在**。按优先级取底图:
|
|
1385
|
+
① 该页有 `source_enhanced_bg` 客户图 → `assets/enhanced_src_K.png` 做整页底;
|
|
1386
|
+
② **其余一切内容页(含 route=ai-A/ai-B / html / none)→ 一律按约定名 `assets/ai_p<page>.png`(page=该页页号)放底图**:
|
|
1387
|
+
`.edit-bg{background:var(--vi-fallback) center/cover}` 内部放
|
|
1388
|
+
`<img class="bg-img" src="assets/ai_p<page>.png" onerror="this.onerror=null;this.remove();this.parentNode.classList.add('ai-fallback')">`
|
|
1389
|
+
—— AI 图在则 cover 铺满;生图失败时 `generate_from_plan` 已写**渐变占位 PNG**会显示;连占位都没有才 onerror 露 `.edit-bg.ai-fallback` 的 VI 渐变兜底。
|
|
1390
|
+
🚫🚨 **任何内容页都绝不「只上 CSS 渐变 class、不放 `<img>`」,更绝不「因为 route=html/none 就不给背景层」——那等于放弃底图、整页平涂近白 + 退化成白底卡片墙(治真机 p3/9/10「无背景→卡墙」事故)**。
|
|
1391
|
+
`ai_p<page>.png` 由阶段9 `--ensure-ai-img-plan`(设计选的 ai-*)+ `--ensure-page-backgrounds`(其余页的 VI 氛围底)确定性注入 img_plan + 阶段10 生成,你**只管按约定名 `ai_p<page>.png` 引用、不用自己起名、不用写 img_plan**。
|
|
1392
|
+
🚫🚨 **`route=source-enhanced` 的页(含 `source_enhanced_hero`/`source_enhanced_bg`/`foreground_cutout` 任意 `usage_intent`)绝不适用上面②这条约定名规则(2026-07-05 真机复盘:`fullbleed.top-hero` archetype 第4/6/7/9/12/13/14 页——客户图已作前景 hero 用在 `.hero-strip`,但 `.edit-bg` 又照抄②的写法引用了从未被规划/生成的 `assets/ai_p<page>.png`,虽有 onerror 兜底不会破图,但仍会被 `deck_visual_style_check` 判定「引用的图片资产不存在」)**——`阶段9 --ensure-page-backgrounds` 对**所有** `route=="source-enhanced"` 页一律跳过独立 AI 背景注入(该页已有客户图真实视觉,见 `plan_source_layout.py::ensure_page_backgrounds`),`ai_p<page>.png` **不会**为这类页生成,引用即 404。这类页如果 archetype 需要 hero 图之外**再有**一层背景(如 `fullbleed.top-hero` 的下半区),`.edit-bg` 直接留空即可——`<div class="edit-bg"></div>`(内部不放 `<img>`)会自动吃到 CSS 里 `.edit-bg{background:var(--vi-fallback)...}` 的默认渐变;要指定其它颜色就显式加 `.edit-bg.ai-fallback` 类 + 内联 `background:linear-gradient(...)`,两种写法都不需要、也不能引用任何 `ai_p<page>.png`。
|
|
1393
|
+
🚫 **`ai_p<page>.png` 背景专用**:它只允许放在 `.edit-bg > img.bg-img`。如果该页还需要 AI 前景特写/插图,必须使用独立资产 `ai_p<page>_fg.png`(由 design 的 ai-* `side=left/right/top/bottom` 注入),前景 `<img>` 绝不复用 `ai_p<page>.png`,避免背景和前景语义重复、画面花。
|
|
1394
|
+
🍎 **结构页(route=html)的 HTML 图表/SVG 是【前景 `.edit-content`】、AI 氛围是【背景 `.edit-bg`】,三层共存**——别把「这页主视觉是 HTML 图表」误解成「这页不要背景」(苹果 specs 页就是深色氛围底 + 浮动规格文字 + 图表)。
|
|
1395
|
+
🚨 **所有 SVG 连线必须有语义归属**:只要写 `<line>/<path>/<polyline>`,同页必须有 `diagram-node` / `data-node` / `flow-step` / `data-viz` / `bar-chart` / `axis` 等节点或图表类;流程连线归属节点,数据连线归属 chart/axis,绝不留下孤立线条。
|
|
1396
|
+
🚨 **SVG 柱状图内嵌标签画之前先估算标签宽度,别让短柱塞不下自己的标签(2026-07-05 真机复盘:p10「3万元撬动千万级风险」成本条形图,`查看基础·4–5千`标签估宽 221 但所属柱 `rect width=180`,溢出 61px 侵入右侧`查看高级`柱的地盘;`编辑器(可选)·4.5万`标签估宽 302 但柱宽仅 240,溢出 82px——4 根柱按数值比例画宽(全景相机 2.28 万最长、查看基础 4–5 千最短),但标签文字长度跟数值大小不成比例,短柱配长标签必然溢出)**:每根柱画完宽度后,按"字符数 × 字号"估算该柱标签的渲染宽度,若估算宽度 > 该柱 `rect` 自身宽度,标签必须画在柱子**外侧**(紧跟柱右边缘之外,配深色 `var(--ink)` 或高对比字色而非柱内白字),不能硬塞进比标签窄的柱子内部——这与已修的"柱长 ≥90% 时标签画柱内换高对比色"是同一类"标签宽度 vs 柱宽"问题的另一侧(那次是长柱,这次是短柱),两种情况都要先量标签宽度再决定画哪、别凭手感直接把文字塞进 `<rect>` 中心。
|
|
1397
|
+
🚨 **径向/放射状图表(五角分布图、雷达图、环形分布图等)外围标签按固定像素坐标+方向性 `text-anchor` 摆放时,必须确认文字延伸方向仍落在 `viewBox` 范围内,不能只看锚点本身在不在框内(2026-07-05 真机复盘:p6「必被替换的五个理由」`viewBox="0 0 600 600"` 的五角图,右侧两个标签 `时间碎片`/`主观选择` 用默认 `text-anchor:start` 在 `x=510` 起笔向右延伸,4 字 × 26px 字号 ≈108px 宽,延伸到 x≈618,超出 600 的右边界 18px 被裁切;左侧标签 `空间感丧失` 用 `text-anchor:end` 在 `x=90` 收笔向左延伸,5 字 ×26px≈130px,实际从 x≈-40 开始,超出左边界 0 达 40px,导致"空间"两字完全裁没、只剩"感丧失"三字——`start` 锚点文字向右长、`end` 锚点文字向左长、`middle` 向两侧对称长,画之前必须按"字符数 × 字号"估算这段延伸的长度,加上锚点坐标本身,确认没有超出 `viewBox` 的对应边界)**:径向标签的锚点半径/坐标不能只按几何对称摆放(照抄装饰性路径/扇形的半径),必须为文字预留延伸空间——不够就把该标签的锚点半径往圆心方向收一些,或把 `viewBox` 在文字可能超出的方向上加宽边距,两者选一,不能让文字第一个字/最后一个字被 `viewBox` 边界硬裁。
|
|
1398
|
+
🚨 **source-enhanced 图层必须服从 `design.visual_asset_contract`**:`background_asset` 必须落在 `.edit-bg > img.bg-img`,`foreground_asset` 必须落在前景证据/hero 图槽;`foreground_role=none` 时不得再插任何前景图片,同一张图不得同页既背景又前景。
|
|
1399
|
+
- 🍎 **编辑式融合分层 = §0.7 锁定骨架(逐字复用、不自创每页布局类)**:内容页选 §2.2 编辑式策略时三层分离——背景 `.edit-bg`(图 cover 填满、**不被渐变盖**、出血到画布边被 slide overflow:hidden 钳死)+ `.edit-scrim`(半透明:浅底图→深字+浅磨砂板、深底图→白字 scrim≥.72)+ `.edit-content`(前景守安全内边距、落 `recommended_text_zone` 净区不压 key_region,照放标题+要点+参数胶囊/对比列,实质不减)。
|
|
1400
|
+
- 🚨🚨 **archetype 的 `grid-template-columns` 一律写在 `.slide.X .edit-content` 上(`.edit-content{display:grid}`),【绝对禁止写在 `.slide` 上】**(如 `.slide.split{grid-template-columns:1fr 1fr}` = 真机头号事故):`.slide` 只承载 3 个 z 层、背景/scrim 是 `position:absolute` 脱流、**`.edit-content` 是 `.slide` 唯一在流子项** —— 栅格写在 `.slide` 上会让 edit-content 独占第 1 列、第 2 列永远空、且内部 `grid-column` 失效 → **两栏页(split/metric/list)全塌进左半、第二栏溢出被裁到屏外**(p4/5/7/8/10/12 全中)。`.slide` **不要写 `display:grid`**;左右栏内容用 `grid-column:1`/`grid-column:2` 落位、`header` 用 `.deck-header{grid-column:1/-1}` 跨满。
|
|
1401
|
+
**前景层只放:文字框 / 参数条 / 指标胶囊 / 侧栏列表 / 对比列——🚫【禁卡片墙、禁网格划区、禁表格】**。**半幅产品剧场**则一侧 `.fig-fill` 大图填满、另一侧前景文字,零重叠。
|
|
1402
|
+
🍎🚨 **现在【每个内容页都有背景层、都是编辑式三层页】,所以这条「前景禁卡墙」对【所有】内容页生效(不再是「只有带图的页才编辑式」)**——route=html/none 的结构/文字页也一样:HTML 图表/要点浮在背景 scrim 之上,**绝不退回「白底 + 一排圆角卡/网格/表格」分区**。
|
|
1403
|
+
🚫 **磨砂文字垫(frost / 磨砂板)只许作「贴着一段文字的可读性背板」、尺寸随该段文字**(深底图压暗、浅底图加浅磨砂保对比)——**绝不是分区卡片/网格/一排等高卡**。要把内容分成几块就用「前景浮层文字小标题 + 间距」或「图表/指标胶囊」分,**不靠白底卡划区**(真机 p3/6/8/9/10 病灶 = 把磨砂板当分区卡堆成卡墙)。
|
|
1404
|
+
🚫🍎 **图槽(`.fig-fill` / 画廊格 / 任何放客户图或 AI 图的容器)绝不加 `background:白/surface` 底色、`border`、`padding`、白裱框、或「选项卡/标签条」把图框成小卡缩略图**(真机 p4/5/7/8 病灶)——半幅 hero 直接 `object-fit:cover` **满铺该半幅、贴槽边**(圆角至多 ≤14px 或干脆不留);图上要标签只作**图上半透明 scrim 文字**(`position:absolute` 贴图底 + 渐变 scrim),**绝不另起白底卡/边框**。图要么做整页底(`.edit-bg`),要么 cover 满半幅,二者之间没有「小图浮白卡」这种中间态。
|
|
1405
|
+
🪞 **`enhance_style=cutout` 的客户图 = 已抠成透明背景 PNG 的【前景特写插图】**(原背景色已去除、不再与 PPT 风格冲突)——直接 `<img>` 放进前景 grid 单元【浮在背景之上】、容器 `background:transparent`、**绝不套 `.src-figure` 白底/边框/padding/裱框**;它是「透明特写插图」不是「带框照片」,让透明边缘自然融进编辑式背景(与上面去框铁律一致)。
|
|
1406
|
+
🚫 **每页 `class="slide X"` 的 X 必须是 §0.7 已定义 grid 的标准 archetype(cover/section/split/fullbleed/list/metric)——禁自创 `.cockpit/.paradigm/.five-shift` 等无 grid 定义的 bespoke 类(真凶:grid 未定义→内容塌成空白页)**;要语义命名就 `class="slide split paradigm"` 但布局走标准类。
|
|
1407
|
+
- 🚨 **图片必须落在 design 指定的槽位、并填满它(治「位置/填充大小不是设计的、躲角、只填一半」)**:
|
|
1408
|
+
**位置忠实**——每张图放进 design.json 为它定的槽位(该页 archetype + composition + `visual.side` 决定的那个 grid 单元,如左右半/上下带/全幅),**绝不**自行挪到角落、换到别的位置、或缩成半幅;位置由 **grid 单元确定性落位**(页内一律 grid、不绝对定位,absolute 只留 B 路线全幅底图)。
|
|
1409
|
+
**填满该单元(用 §0.7 `.fig-fill`)**——槽 `div width:100%;height:100%`,`<img>` **优先 `object-fit:cover` 填满**(背景/hero/大图,配 `object-position:<key_region 中心%>` 保重点);仅 dense-info 证据图需完整保数据时才 `contain`、且槽按图比例定。
|
|
1410
|
+
🚫 **禁 `max-height` 帽、🚫禁 `.src-figure{background:白/surface;padding}` 白裱框**(真凶 2:低清图缩成 340px 小裱照浮空框)。**绝不**让图缩在槽一角、`width:auto` 只占一小块、或留半空。槽比例与图差太多就走 route=source-enhanced 图生图重绘到槽位比例(现在所有客户图都图生图,比例可定制)。
|
|
1411
|
+
(导出忠实搬运 HTML 几何——图在 PPT 里的位置/大小 = 它在 HTML 里的位置/大小,所以**落槽 + 占满靠这里写对**。)
|
|
1412
|
+
- 🚨 **客户图尺寸/缩放铁律(治「用户图缩成角落小图看不清 / 低清原图被放大糊 / 图过大硬塞小卡」——按 `source_layout_plan.json` 确定性档位落地)**:
|
|
1413
|
+
每张客户图按其 `display_role` 给**够大的槽**——`background`=整页底图、`foreground_hero`=前景主视觉/半幅大图(≈半背景)、`evidence_card`=证据图、`gallery`=画廊格;
|
|
1414
|
+
**槽位至少占到该图的 `min_canvas_fraction`(hero ≥30%、证据 ≥12%、画廊格 ≥10% 画布)——绝不把客户图缩成角落小图/底部小缩略图条**(截图实测事故)。
|
|
1415
|
+
**缩放上限 ≤1×(`max_upscale`)**:栅格客户原图**绝不放大超过原生像素**(`w×h`),放大必糊——想显示得比原生大,**只能走 route=source-enhanced 图生图重绘到目标分辨率**(plan 已为低清/需放大的图标了 `enhance_required`),不是用大槽 + object-fit 硬拉伸。
|
|
1416
|
+
反之**图过大**(高清大图)别硬塞进小卡:作 `background`/`foreground_hero` 大图用(用户原话「太大可作背景或半背景」)。
|
|
1417
|
+
- 🚨 **插图图层 = 次顶层,绝不被非文本元素遮挡(治「插图被卡片/色块盖住、显示不出」)**:导出三层固定为 **背景 < 前景插图/卡片 < 文本(最顶可编辑)**。
|
|
1418
|
+
A 路线插图独占自己的 grid 单元,**不得被任何不透明的非文本元素(卡片/色块/装饰形状)压在上面**;要装饰就放**相邻单元**,别叠在插图上。
|
|
1419
|
+
**只有文本可浮在插图之上**(浮字垫 scrim/磨砂板保可读)。页内**一律 grid 布局、不绝对定位**(`position:absolute` 只留给 B 路线全幅底图+浮层),从结构上杜绝互相压盖(导出端【内容相互叠加】ERROR 会兜底拦截)。
|
|
1420
|
+
- 🚨 **统一内容内边距 + 标题不贴边、跨页对齐(治「标题贴最左/各页不对齐/超界」——web 排版问题,导出忠实搬运)**:
|
|
1421
|
+
**全 deck 统一「内容内边距」铁律**:每页 `.slide` 内容区四周留 **上下 ≥ 64px、左右 ≥ 104px**(1920×1080),
|
|
1422
|
+
**所有 header/正文/卡片一律对齐到这条内边距线、绝不贴画布边(x≈0)、绝不超出画布**。
|
|
1423
|
+
⚠️ **此 padding 约束只针对前景内容/文字层(header/正文/卡片)**;**编辑式融合的背景/全幅图层例外**——它走 `position:absolute; inset:0` **出血到画布边、不受 padding 约束**(被 slide `overflow:hidden` 钳死、不溢出),只有前景文字守这条内边距线。二者并存:**图出血、字守边**(既要编辑式满幅图、又不退化前轮「标题贴边/超下边缘」修复)。
|
|
1424
|
+
所有内容页(cover/section 除外)用同一套 header 约定——
|
|
1425
|
+
主标与副标**左对齐到内容内边距线(= 左 112px,不是画布边 0)**、占顶部同一条 header 带、**各页 header 位置/对齐完全一致**(靠统一 class + 统一 padding,不逐页手摆、不贴边)。`<head>` 全局 CSS 定义一次复用:
|
|
1426
|
+
```css
|
|
1427
|
+
.slide{ box-sizing:border-box; padding:56px 112px 48px; } /* 内容内边距:左右 112 不贴边;上 56 下 48(少吃竖向、给内容更多高度,治底部溢出) */
|
|
1428
|
+
.deck-header{ grid-column:1 / -1; margin-bottom:28px; }/* 顶部整宽 header 行 */
|
|
1429
|
+
.deck-title{ text-align:left; margin:0; } /* 主标左对齐到内容内边距线(非画布边 0) */
|
|
1430
|
+
.deck-subtitle{ text-align:left; margin:6px 0 0; } /* 副标与主标同左边缘、紧随其下 */
|
|
1431
|
+
```
|
|
1432
|
+
内容页结构固定为 `<header class="deck-header"><h2 class="deck-title">…</h2><p class="deck-subtitle">…</p></header>` 起头——
|
|
1433
|
+
**导出把 HTML 的 x 原样搬运,于是统一 padding+左对齐 → 各页标题/副标在 PPT 里天然对齐且留出左边距**(贴边/不齐 100% 是 HTML 摆得不一致,不是导出问题)。**主标 ≤14 字一行**(design 已控)。
|
|
1434
|
+
- **封面/章节标题**:可居中或大字戏剧化(不强求与内容页同位、尾页居中已验证好看),但**仍在 `.slide` padding 内、不贴画布边、不超画布**;封面主标 ≤12 字保持一行,主标与副标分属不同 grid 行留足行距(防 Office 重折行压副标题)。
|
|
1435
|
+
- **封面/章节文字对比度铁律(治浅底图白字看不清)**:氛围底图亮暗不可控(浅色模板 AI 底图常偏亮),**别默认白字靠弱 scrim**。浅色模板首选 **① 深字(`var(--ink)`) + 浅色磨砂文字板**(`background:rgba(255,255,255,.55);backdrop-filter:blur(6px)`);要白字则 **② scrim/板压到足够暗(不透明度 ≥ .72)**(见 §1.B 两套 CSS)。
|
|
1436
|
+
- **同一条铁律对所有内容页同样生效,不止封面/章节**(真机事故:p5「三大结构性盲区」list 页 `deck-title`/`deck-subtitle` 直接叠在全幅 AI 照片背景上、无任何 scrim,像素实测最差对比度 1.00,标题实质不可读)——只要页面结构是「`.edit-bg` 全幅 AI/照片背景 + `.deck-header` 直接叠加」(内容页背景层是硬规则、见上「每个内容页都有背景层」),无论页面 route 是 list/split/dense 哪种,都必须给 `.deck-header` 区域加同等保护(局部 scrim 紧贴 header 区域,或整页 scrim,或深字+磨砂板),不能因为"这是内容页不是封面"就假设背景干净、省掉这层——内容页 AI 背景要求"低干扰"是生图侧的目标,不是版式侧可以省略保护的理由。
|
|
1437
|
+
- 🚨 **VI 自己定义的强调色/次要文字色变量(如 `--arsenal-blue`「eyebrow 标签色」、`--ink-soft`/`--muted`「副标/次要说明色」)默认按纯白背景校准,套进 vi_fallback 渐变背景/AI图/照片背景时不能假设天然够对比度(2026-07-07 真机复盘:单份 deck 里 26 处像素实测不可读,锁定 4 个 CSS 变量值——`--arsenal-blue`/`--arsenal-blue-deep`/`--ink-soft`/`--muted`——全 deck 复用,落在灰白渐变/深色照片背景时对比度普遍跌破 3.0,最差仅 1.01)**:这些"品牌强调色/次要色"跟普通正文字一样必须过对比度检查,不能因为"这是 VI 标准配色,看起来专业"就跳过验证——写这类文字前先确认它实际落点的背景亮度,背景不是纯白就要么换成 `var(--ink)`/白色高对比色,要么给这块文字单独加局部 scrim/色块;不要在非白背景上无条件复用这几个 VI 强调色变量。
|
|
1438
|
+
4. **写入 `./build/deck.html`**:首轮若文件不存在 → 新建含 `<head>` + 全局 CSS(§0.7 流式骨架:`body` 深色衬底 + `.slide{position:relative;box-sizing:border-box;width:1920px;height:1080px;margin:0 auto 40px;padding:56px 112px 48px}`(**统一内容内边距:左右 112 不贴边、上 56 下 48 少吃竖向**)纵向排开 + VI 视觉系统 + `[hidden]{display:none!important}`)+ 本批 section;
|
|
1439
|
+
后续轮 → 用 Edit 把本批 `<section>` 追加进 `</body>` 前(保持单文件自包含、CSS 不重复定义)。
|
|
1440
|
+
5. **deck 卫生**:不要加 Tweaks/localStorage/postMessage/fitStage/翻页 nav/React/Babel(对导出无用、只干扰)。
|
|
1441
|
+
6. 做完本批后不要自判完成,也不要强行输出完成标记。下一轮 `build_probe` 会重新跑页数和客户图闸门,OK 时自动 `build_complete` 并 break。
|
|
1442
|
+
|
|
1443
|
+
完成后简述:本轮生成/修复了哪几页、补了哪些客户图。
|
|
1444
|
+
allowed_tools: [Read, Write, Edit, Bash, Glob]
|
|
1445
|
+
maxTurns: 24
|
|
1446
|
+
onError: halt
|
|
1447
|
+
max_retries: 1
|
|
1448
|
+
- id: build_done
|
|
1449
|
+
type: break
|
|
1450
|
+
when: "fileExists('./build/build_complete')"
|
|
1451
|
+
|
|
1452
|
+
# ---------- 阶段14b:产品详情页视觉硬门(确定性,不再交给 agent 自觉执行) ----------
|
|
1453
|
+
- id: stage_visual_quality_gate
|
|
1454
|
+
title: "阶段18/22·产品详情页视觉硬门(最多两轮修复)"
|
|
1455
|
+
when: "fileExists('./build/deck.html')"
|
|
1456
|
+
type: loop
|
|
1457
|
+
# 轮数 3→2(2026-07-02 用户裁决);修复步同步开放给 fast——上一轮 fast 跑出 41 个 ERROR
|
|
1458
|
+
# 却因 when 限死 best 而 0 次修复带残留放行,是缺陷出货的直接原因。
|
|
1459
|
+
max_iterations: 2
|
|
1460
|
+
fresh_context: true
|
|
1461
|
+
do:
|
|
1462
|
+
- id: visual_quality_measure
|
|
1463
|
+
title: "阶段18/22·几何测量(measure-only→喂几何门)"
|
|
1464
|
+
tool: Bash
|
|
1465
|
+
args:
|
|
1466
|
+
command: |
|
|
1467
|
+
# 先渲染当轮 deck.html 的几何到 layout-report.json,visual_quality_gate.py 才判得到几何门。
|
|
1468
|
+
# 放循环内:每轮 repair 改了 deck.html 后重新测量,几何门读到的是当轮最新几何。
|
|
1469
|
+
# 先删旧 report:万一本轮 measure 失败(如 chromium 缺失),几何门走 else 干净跳过,
|
|
1470
|
+
# 不会误读上一轮(修复前)的陈旧 report → 不误判。
|
|
1471
|
+
# --with-bg-shots:顺带落背景态截图(slide-NN-background.png),像素级文字可读性门
|
|
1472
|
+
# (text_readability_pixel.py)按文本矩形采真实像素——CSS 对比度在压图文字上物理测不准。
|
|
1473
|
+
mkdir -p ./build/export
|
|
1474
|
+
rm -f ./build/export/layout-report.json
|
|
1475
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs ./build/deck.html \
|
|
1476
|
+
--measure-only --with-bg-shots --mode hybrid --width 1920 --height 1080 --workdir ./build/export
|
|
1477
|
+
onError: continue
|
|
1478
|
+
- id: visual_quality_check
|
|
1479
|
+
title: "阶段18/22·视觉质量检查"
|
|
1480
|
+
tool: Bash
|
|
1481
|
+
args:
|
|
1482
|
+
command: |
|
|
1483
|
+
python3 skills/ui-design/scripts/visual_quality_gate.py --build ./build --max-rounds 2 --strict-product-detail
|
|
1484
|
+
onError: halt
|
|
1485
|
+
max_retries: 0 # 确定性检查步:重试=原样重跑纯空转(exit 1 仅剩 hard 档=真缺陷,halt 正确)
|
|
1486
|
+
- id: visual_quality_done
|
|
1487
|
+
type: break
|
|
1488
|
+
when: "fileExists('./build/visual_quality_ok')"
|
|
1489
|
+
- id: visual_repair_batch
|
|
1490
|
+
title: "阶段18/22·修复前几个视觉问题"
|
|
1491
|
+
when: "fileExists('./build/visual_quality_report.md') && !fileExists('./build/visual_quality_ok')"
|
|
1492
|
+
agent: |
|
|
1493
|
+
只修 `./build/visual_quality_report.md` 里最高优先级的前 3–5 个问题,不要重写整份 deck。
|
|
1494
|
+
|
|
1495
|
+
必读:
|
|
1496
|
+
- `./build/visual_quality_report.md`
|
|
1497
|
+
- `./build/design.json`
|
|
1498
|
+
- `./build/deck.html`
|
|
1499
|
+
|
|
1500
|
+
🚨 **先看报告里有没有"⚠️ N 处文字压图问题共享同一文字颜色 rgb(...)"这行归组提示(2026-07-03 真机
|
|
1501
|
+
复盘:27 处 ERROR 里 15+ 处共享同一个 VI 强调色 CSS 变量,逐条加局部 scrim 在 2 轮修复预算内根本
|
|
1502
|
+
修不完,只有改一次共享 CSS 规则才能同时清零全部同色实例)**——有则**优先**处理:找到该颜色对应的
|
|
1503
|
+
共享 class(通常是 `.t-eyebrow`/`.bullet-row .label`/`.brand-mark .label` 这类角标/标签强调色),**一次性改共享 CSS
|
|
1504
|
+
规则**(把该颜色对应的 CSS 变量调深,或给该 class 统一加一层不透明色块/半透明底),而不是照着报告
|
|
1505
|
+
逐条打局部 scrim 补丁——这一条改动计入本批 1 个问题名额,但能一次性让全部同色 ERROR 清零,比逐条
|
|
1506
|
+
修快得多、也不会撞 maxTurns。改完后其余名额再处理别的独立问题。
|
|
1507
|
+
🚨 **`.brand-mark`(左上角 Logo 角标)专属提醒(2026-07-05 真机复盘:本轮已把 `.label` 颜色改深成
|
|
1508
|
+
`--deep-blue` 仍在 8 处照片背景上实测最差对比度 1.00)**——`.brand-mark` 全 deck 复用、每页背景明暗
|
|
1509
|
+
都不同,**纯改文字颜色治标不治本**(总有某页背景比这个新深色还深/还花,颜色永远猜不完);唯一稳的
|
|
1510
|
+
修法是照抄 `.t-eyebrow` 已验证有效的模式——给 `.brand-mark` 整体加一层不透明色块/半透明磨砂底
|
|
1511
|
+
(如 `background:rgba(255,255,255,.85);padding:6px 12px;border-radius:6px;`),而不是继续在颜色值上
|
|
1512
|
+
调整。
|
|
1513
|
+
🚨 **同理,先看报告里有没有"⚠️ N 处过小字体共享同一数值 font-size:Npx"这行归组提示(2026-07-05
|
|
1514
|
+
真机复盘:单份 deck 里 10 处 ERROR 共享同一个错误字号 font-size:22px,分散在 3 个不同页面/组件——
|
|
1515
|
+
跟共享色变量同一根因,逐条改在 2 轮修复预算内修不完)**——有则**优先**处理:不要逐个 `<div>` 改,
|
|
1516
|
+
用 Bash/Edit 全文批量把这个错误数值(如 `font-size:22px` 或 `font-size: 22px`)替换成 ≥24px
|
|
1517
|
+
(如 `font-size:26px`),一次改动清零全部同数值实例,比逐条改快得多。
|
|
1518
|
+
|
|
1519
|
+
修复范围:
|
|
1520
|
+
- 卡片墙/表格墙/文字墙:改成图像主导 + 短文案 + 必要 HTML/SVG 图表。
|
|
1521
|
+
- 背景图含不可编辑文字/数字/Logo:移除该图引用,改用重试后的干净背景;章节序号/标签必须改成 HTML/SVG 可编辑前景。
|
|
1522
|
+
- 文字不可读:先移动到安全净区或加局部 scrim/暗角;只允许紧贴文字的小背板,禁止大面积白/灰浮动卡。
|
|
1523
|
+
- 【文字压图不可读】(像素实测):按报告坐标给该文字加紧贴 scrim/移到净区/换字色——报告给的是真实像素对比度,别怀疑它。
|
|
1524
|
+
- 【文字压图不可读】若整段正文大范围不可读(不是单行局部):**不限于 `.slide.split`/`.slide.two-col`,`.slide.section` 章节引导页同样常见此根因(2026-07-05 复盘:p2/p5 两个 section 页同一路数据)**——先查 `.edit-scrim` 的 `linear-gradient` 不透明端是否跟文字所在 `grid-column` 同侧,判据只看文字实际的 `grid-column`、与页面 archetype/class 名无关;常见根因是渐变方向照抄示例、没跟着文字栏镜像。把渐变整体镜像成不透明端对齐文字栏,一次改好整段文字,别在同一页逐行加局部 scrim 补丁。**若只有 `.body-text`/`.evidence` 这类中等灰正文字不可读、但同页的 `.takeaway` 大标题却正常(2026-07-05 复盘:p4/p14 同一根因)**:大概率不是方向错,是"图渐隐入纸感面板"式 scrim 的不透明拐点太晚——按 `.85fr 1.15fr`(或 `1.15fr .85fr`)算出文字栏起点百分比,把渐变里 ≥0.85 不透明度的那个 stop 提前到这个百分比之前,而不是留到 70%+ 才到达。**若不可读的是 `.deck-header`/`.deck-title`(页顶标题),且该页 `.edit-scrim` 是纵向(`180deg`)渐变(2026-07-05 复盘:`light-bottom` 类顶部 0% 不透明、只在底部才浅色)**:判据同上——不分横竖轴,检查该渐变在**页顶这个区域**(标题实际所在处)是否已经给了足够不透明度,不要只顾着某个局部(如只给底部字幕条留白);不透明区域覆盖范围要扩大到页顶,或改用横向/别的渐变方向重做。
|
|
1525
|
+
- 【内容相互叠加】/【超出画布】(几何坐标):先移动/重排躲开 → 精炼文案 → 缩字(≤20%);超下边缘的改两列或拆页。**若重叠双方是「一张图」和「其下方说明卡片行」且重叠占比 >70%(2026-07-05 第8页事故)**:大概率是两者被写成各自独立声明同一 `grid-column/grid-row` 的兄弟节点(各自撑满整格、互相不知道对方存在)——把两者包进同一个 `display:flex;flex-direction:column` 父容器(图 `flex:1;min-height:0`、卡片行紧随其后),别只挪坐标微调。
|
|
1526
|
+
- 【文字溢出卡片】:加大卡片(padding/尺寸随内容自然撑开)或让文字换行收进卡内 → 精炼文案——别缩字;文字必须是卡片的 DOM 子元素、禁固定宽高卡片配更宽的文字/wrapper。**若溢出的是圆形徽标/环形进度条内的文字(`.ring-label`/`.step-num` 这类固定直径圆形容器,2026-07-06 复盘)**:不是加大圆的直径能解决的——把这个圆形容器整体换成横向胶囊/圆角矩形(宽度随文字内容撑开),不要继续用圆形硬装长文本。
|
|
1527
|
+
- 【圆形徽标塞长文本溢出】(`.ring`/`.step-num` 类固定直径圆形组件,2026-07-06 复盘):数一下溢出文字的字符数,超过 3–4 个字符(含"N周→N小时"「6–12 月」这类带范围符号的多段文本)就把该容器从圆形改成横向胶囊/圆角矩形,不要保留圆形再想办法缩字/换行。
|
|
1528
|
+
- 【版式违规】(确定性比对 source_layout_plan,2026-07-03 第4页影子标题事故):规划为 direct_contain/gallery/small_evidence 的客户图被铺成 `.bg-img`/CSS 整页背景——把该图改回 contain 框图/画廊格放进图槽,背景换 `assets/ai_p<page>.png` 氛围图或纯色;其上叠的正文一并挪回净区。
|
|
1529
|
+
- 【空心大卡】:按内容收紧卡尺寸或删掉空板;禁靠放大字号硬撑。
|
|
1530
|
+
- 【图表数据颠倒】/【图表标签装不下】:按数值重算柱高(尺寸∝数值)、把图形画大装下标签——别缩字。**若报告标出的不可读文字是柱状图的数值标签、且该柱长度接近满刻度(2026-07-05 ROI 页事故)**:标签是画在柱子内部还是外部要按柱长判断——柱长≥绘图区 90% 时标签必须画在柱内靠右且换成与柱子同色系的高对比 fill(深柱配白字/浅柱配深字),不能沿用柱外标签的深色写法。
|
|
1531
|
+
- 客户原图带字被直接引用(报告给出 enhanced_ 替代名):把 src_N 引用改成 enhanced_src_N;弃用图直接删引用。
|
|
1532
|
+
- 证据/截图类客户图被铺成整页背景:改为 contain 框图 + 短说明,绝不在其上叠正文。
|
|
1533
|
+
- source-enhanced 被白卡/边框/padding 裱起来:去容器,做完整 hero/cutout/evidence。
|
|
1534
|
+
- 前景/背景重复抢戏(含 src_N 与 enhanced_src_N 同族):保留一个主视觉,另一个移除或换成独立互补背景。
|
|
1535
|
+
- 【文字压图不可读】若该文字在 HTML 里已经带了 `text-white`/类似转色工具类、颜色却仍是深色(实测 rgb 接近 `var(--ink)`):不是工具类没生效那么简单,是 CSS 里存在更高特异性的选择器(常见形如 `.slide.<archetype> .<组件类>{color:var(--ink)}`,两个类的后代选择器特异性高于单类工具类)在覆盖它——去 `<head>` 全局 CSS 里找这条规则,要么删掉它里面多余的 `color` 声明(如果那条规则本意只是调字号/宽度),要么把该元素改成内联 `style="color:#fff"`(内联特异性最高,稳赢任何 class 组合),不要继续加/换别的工具类名重试,换了也大概率还是打不过。
|
|
1536
|
+
- 【引用的图片资产不存在】若该页 `route=="source-enhanced"`(design.json 该页 visual 字段可查,含 hero/bg/cutout 任意 `usage_intent`)却引用了 `assets/ai_p<page>.png`(2026-07-05 真机复盘:`top-hero` archetype 第4/6/7/9/12/13/14 页事故,客户图已作前景 hero,`.edit-bg` 却照抄"其余页用约定名"规则引用了从未规划/生成的 ai_p 文件):这类页的 `ai_p<page>.png` **永远不会存在**(阶段9 对 `route=="source-enhanced"` 一律跳过独立背景注入)——把 `.edit-bg` 内的 `<img>` 整个删掉,改成 `<div class="edit-bg"></div>`(自动吃到 CSS 默认 `--vi-fallback` 渐变)或显式 `.edit-bg.ai-fallback` + 内联渐变,绝不改猜其它文件名重试。
|
|
1537
|
+
- data-visual 缺 SVG/chart/axis/bar/line:补可编辑 HTML/SVG 图形,别用大表格。
|
|
1538
|
+
- 【AI 背景图被 scrim 盖到不可辨识】(2026-07-05 复盘:list/metric 数据结构页 `image_weight≈0` 却套了 0.82~0.90 近纯白整页 scrim,生成的低干扰材质背景在截图上完全看不出痕迹,等于图片形同虚设):把该页 `.edit-scrim` 的整页不透明度降到 ≤0.6,让底图纹理隐约可辨;若因此文字/图例对比度不够,改成只在文字/图例紧贴区域加局部深色小背板,不要靠拉高整页不透明度解决。
|
|
1539
|
+
- 低对比/小字/孤立连线:统一字体 token、节点和连线归属。
|
|
1540
|
+
- **内容飞出画布/整页不可见**(几何 catastrophic,见 `./build/visual_quality_report.md` 的 layout_balance 段:某页 coverage≈0 或元素可见部分<20%):**报告里这条即使文字前缀写的是"WARNING"也必须排进本批最优先修——它对应的是导出阶段 `--catastrophic-only` 硬门(无重试预算,2026-07-05 真机两次因此在 `stage_export` 直接 halt 整个 `-p` 进程),比其它真正的 WARNING 后果严重得多,别被"WARNING"字面误导降低优先级**。多为 CSS Grid 轨道被大图撑爆 → 按 `references/layout-composition.md §0.7` 给 `.edit-content>*` 加 `min-width:0;min-height:0`,或收敛该页图尺寸/改用不炸轨的版式,让标题正文回到画布内。**若该块是 `.fig-contain`/`.fig-fill` 且内联 style 里带了 `aspect-ratio`(2026-07-05 第6/8页事故):删掉这个内联 `aspect-ratio`,让类自带的 `width:100%;height:100%` 生效——这两个类本身已经安全,加 `aspect-ratio` 就是在覆盖它。**
|
|
1541
|
+
- 修完本批(3–5 个)后重跑 `python3 skills/ui-design/scripts/deck_visual_style_check.py ./build/deck.html --design ./build/design.json --image-report ./build/image_generation_report.json --source-plan ./build/source_layout_plan.json --strict-product-detail`,确认**本批问题已消**;本批消掉即收尾(不能只写 residual 糊弄),**剩余/新暴露的问题留给外层循环下一轮重新测量再修**——别在本步内追着全量 ERROR 无界修下去(那会撞 maxTurns 被截断)。
|
|
1542
|
+
|
|
1543
|
+
不要碰已正常的页面。完成后简述修改页号。
|
|
1544
|
+
allowed_tools: [Read, Edit, Write, Glob]
|
|
1545
|
+
maxTurns: 20
|
|
1546
|
+
onError: continue
|
|
1547
|
+
# 截断续跑(2026-07-02 真机 ⚠「达到最大轮数 20 被截断(可续跑)」裁决):max_retries=2 启用引擎
|
|
1548
|
+
# 内建的 maxTurns 截断续作——同一共享 history 上接着干、每次再给 20 轮预算;此前 0 把续跑废掉,
|
|
1549
|
+
# 「可续跑」名不副实。用尽仍是 onError:continue 黄警告放行,绝不红 halt。
|
|
1550
|
+
max_retries: 2
|
|
1551
|
+
|
|
1552
|
+
# ---------- 阶段8:构图均衡闸门(HTML 层廉价循环)→ 导出 hybrid PPTX 一次 + OPC 校验 ----------
|
|
1553
|
+
# 单一真相源 = ui-design。构图闸门(2026-06-24):**ERROR=重叠 + 截图夹带文本 + 整页空;WARNING=溢出 + 字号过小 + 超画布/对比度**;
|
|
1554
|
+
# 占空比/空半/卡片填充率默认不参与工作流迭代,只保留 layout_balance 手动调试开关。
|
|
1555
|
+
# 修重叠 移动>精炼>缩字(≤20%);夹带文本=改真实 DOM 文本;**视觉门最多修 2 轮、达轮数带残留放行**(2026-07-02 由 3 轮调 2 轮,防反复改烧配额)。
|
|
1556
|
+
- id: stage_export
|
|
1557
|
+
title: "阶段19/22·快速导出 PPTX + 确定性硬门"
|
|
1558
|
+
tool: Bash
|
|
1559
|
+
args:
|
|
1560
|
+
command: |
|
|
1561
|
+
set -euo pipefail
|
|
1562
|
+
OUT="${inputs.out}"
|
|
1563
|
+
MODE="${inputs.mode}"
|
|
1564
|
+
mkdir -p "$(dirname "$OUT")" ./build/export
|
|
1565
|
+
|
|
1566
|
+
echo "[export] deck pages check (完整度硬门 + 页序报告)"
|
|
1567
|
+
python3 skills/ui-design/scripts/deck_pages_check.py ./build --check-order || {
|
|
1568
|
+
rc=$?
|
|
1569
|
+
# 完整度缺页(exit 1/2) → 硬门 halt;仅页序错乱(exit 3) → 非阻断报告
|
|
1570
|
+
# (批量生成天然乱序,别为顺序反复 halt 烧配额;ORDER_MISMATCH 已在上面日志留痕,建议按编号重排 <section>)。
|
|
1571
|
+
[ "$rc" = "3" ] && echo "[export] ⚠ 页序 ORDER_MISMATCH(见上):建议按编号从小到大重排 <section>(非阻断)" || exit "$rc"
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
echo "[export] ui artifact check"
|
|
1575
|
+
python3 skills/ui-design/scripts/check_ui_artifact.py --for-pptx-export ./build/deck.html
|
|
1576
|
+
|
|
1577
|
+
echo "[export] reconcile missing enhanced/source assets"
|
|
1578
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-missing --build ./build
|
|
1579
|
+
|
|
1580
|
+
echo "[export] source usage hard gate"
|
|
1581
|
+
python3 skills/ui-design/scripts/source_usage_check.py --build ./build --require-existing-derived
|
|
1582
|
+
|
|
1583
|
+
# deck_visual_style_check 不在此重跑(减法:与阶段18 视觉门完全同参双跑)——
|
|
1584
|
+
# 它已在 stage_visual_quality_gate 有界循环里跑过(fast/best 统一 2 轮修复,2026-07-02 裁决),
|
|
1585
|
+
# 达轮数带残留放行(visual_quality_ok + visual_quality_residual.md)。此处只验哨兵。
|
|
1586
|
+
echo "[export] visual quality gate must already be accepted"
|
|
1587
|
+
test -f ./build/visual_quality_ok
|
|
1588
|
+
|
|
1589
|
+
echo "[export] measure-only layout report"
|
|
1590
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs ./build/deck.html \
|
|
1591
|
+
--measure-only --mode hybrid --width 1920 --height 1080 --workdir ./build/export
|
|
1592
|
+
|
|
1593
|
+
echo "[export] layout balance report"
|
|
1594
|
+
python3 skills/ui-design/scripts/layout_balance.py ./build/export/layout-report.json --no-occupancy -v \
|
|
1595
|
+
--source-layout-plan ./build/source_layout_plan.json || true
|
|
1596
|
+
touch ./build/layout_ok
|
|
1597
|
+
|
|
1598
|
+
echo "[export] geometry catastrophic hard gate(内容不可见零容忍:严重飞出画布 / 无真实视觉空页 → 拒绝导出)"
|
|
1599
|
+
# 只拦「内容根本看不到」的灾难(可见<20% 越界 + content_boxes==0 且无真实视觉),
|
|
1600
|
+
# 不含重叠/占空族噪声 → 干净 deck 不误伤、不重烧配额。治本在 layout-composition §0.7 的 min-width:0 骨架;此为兜底网。
|
|
1601
|
+
python3 skills/ui-design/scripts/layout_balance.py ./build/export/layout-report.json --catastrophic-only
|
|
1602
|
+
|
|
1603
|
+
echo "[export] write pptx"
|
|
1604
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs ./build/deck.html \
|
|
1605
|
+
--out "$OUT" --mode "$MODE" --width 1920 --height 1080 --workdir ./build/export
|
|
1606
|
+
|
|
1607
|
+
echo "[export] opc check"
|
|
1608
|
+
python3 skills/pptx/scripts/opc_check.py "$OUT"
|
|
1609
|
+
rm -f "$OUT.tmp" "$OUT.fixed.pptx" 2>/dev/null || true
|
|
1610
|
+
|
|
1611
|
+
cat > ./build/export-summary.md <<EOF
|
|
1612
|
+
输出路径: $OUT
|
|
1613
|
+
导出模式: $MODE
|
|
1614
|
+
可编辑性: hybrid=背景不可编辑,文本和部分前景对象可编辑;flat=整页图片不可编辑
|
|
1615
|
+
OPC: PASSED
|
|
1616
|
+
layout_balance: REPORT_ONLY(占空族)+ catastrophic 硬门(内容不可见零容忍)
|
|
1617
|
+
EOF
|
|
1618
|
+
onError: halt
|
|
1619
|
+
max_retries: 0
|
|
1620
|
+
|
|
1621
|
+
# ---------- 守门 verify ----------
|
|
1622
|
+
- id: verify_output
|
|
1623
|
+
title: "阶段20/22·守门校验"
|
|
1624
|
+
type: verify
|
|
1625
|
+
checks:
|
|
1626
|
+
- "file_exists:${inputs.out}"
|
|
1627
|
+
onFail: "PPTX 未生成(${inputs.out} 不存在),请检查导出日志。"
|
|
1628
|
+
|
|
1629
|
+
# ---------- 阶段10:按 debug_keep_build 策略处理中间产物 ----------
|
|
1630
|
+
- id: cleanup_intermediates
|
|
1631
|
+
title: "阶段21/22·处理中间产物"
|
|
1632
|
+
when: "fileExists(inputs.out)"
|
|
1633
|
+
tool: Bash
|
|
1634
|
+
args:
|
|
1635
|
+
command: |
|
|
1636
|
+
set -euo pipefail
|
|
1637
|
+
if [ "${inputs.debug_keep_build}" = "false" ]; then
|
|
1638
|
+
rm -rf ./build
|
|
1639
|
+
echo "[cleanup] debug_keep_build=false,已清理 ./build,仅保留最终 PPT:${inputs.out}"
|
|
1640
|
+
else
|
|
1641
|
+
echo "[cleanup] debug_keep_build=true,保留 ./build 中间产物用于排障:deck.html / design.json / export 报告 / 截图。"
|
|
1642
|
+
fi
|
|
1643
|
+
onError: continue
|
|
1644
|
+
|
|
1645
|
+
# ---------- 完成报告(echo,确定性、零 LLM 复述) ----------
|
|
1646
|
+
- id: final_report
|
|
1647
|
+
title: "阶段22/22·完成报告"
|
|
1648
|
+
type: echo
|
|
1649
|
+
message: |
|
|
1650
|
+
✅ PPT 生成完成(ppt·素材驱动)。
|
|
1651
|
+
|
|
1652
|
+
- 主题/指挥:${inputs.topic}
|
|
1653
|
+
- 最终产物(**唯一保留**):${inputs.out}(页数由设计文档按内容/章节自动确定;模式 ${inputs.mode})
|
|
1654
|
+
- 流程:摄取素材(抽文字+图片+图像统计)→ 逐图多模态识图 → 合并「用户原始材料」统一文件(material.md/json)→ 客户材料成稿(默认不联网)→ 详细 Web 页面设计文档(客户图按识图内容高权重配页,全部图生图重绘到高清并贴 PPT 风格)→ 配图分流 → 文生图/图生图 → 分批生成网页(页数+客户图用尽双闸门)→ 产品详情页视觉硬门 → 三层导出。
|
|
1655
|
+
- 可编辑性:hybrid 三层=背景整页截图垫底(不可编辑),前景每个离散元素(卡片/色块/图标/SVG/插图)为独立可编辑图片对象,
|
|
1656
|
+
文本为 PPT 原生可编辑文本框;全幅氛围背景图(B 路线)连同遮罩留背景层;flat=全图不可编辑。
|
|
1657
|
+
- 中间产物处理:由 debug_keep_build=${inputs.debug_keep_build} 控制;默认保留 ./build 用于检查 deck.html、design.json、截图和报告,设为 false 时只保留最终 PPT。
|
|
1658
|
+
|
|
1659
|
+
用 PowerPoint / WPS 打开 ${inputs.out} 核验。
|