minimal-agent 0.11.0 → 0.13.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/package.json +5 -1
- package/plugins/workflow-runner/plugin.js +27 -15
- package/plugins/workflow-runner/plugin.ts +34 -20
- package/plugins/workflow-runner/src/agentCommon.js +13 -12
- package/plugins/workflow-runner/src/agentCommon.ts +22 -13
- package/plugins/workflow-runner/src/expressions.js +29 -8
- package/plugins/workflow-runner/src/expressions.ts +28 -10
- package/plugins/workflow-runner/src/index.js +50 -20
- package/plugins/workflow-runner/src/index.ts +75 -31
- package/plugins/workflow-runner/src/multimodal.js +2 -1
- package/plugins/workflow-runner/src/multimodal.ts +2 -1
- package/plugins/workflow-runner/src/recovery.js +9 -2
- package/plugins/workflow-runner/src/recovery.ts +9 -2
- package/plugins/workflow-runner/src/runner.js +31 -5
- package/plugins/workflow-runner/src/runner.ts +33 -5
- package/plugins/workflow-runner/src/stepExecutors/assert.js +2 -1
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +3 -1
- package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +12 -7
- package/plugins/workflow-runner/src/stepExecutors/tool.js +91 -61
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +111 -71
- package/plugins/workflow-runner/src/stepExecutors/verify.js +6 -3
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +7 -3
- package/plugins/workflow-runner/src/taskIdentity.js +197 -21
- package/plugins/workflow-runner/src/taskIdentity.ts +201 -20
- package/plugins/workflow-runner/src/toolRuntime.js +48 -0
- package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
- package/plugins/workflow-runner/src/types.js +113 -7
- package/plugins/workflow-runner/src/types.ts +137 -14
- package/plugins/workflow-runner/src/workflowState.js +455 -54
- package/plugins/workflow-runner/src/workflowState.ts +508 -63
- package/plugins/workflow-runner/test/cli.e2e.test.ts +20 -0
- package/plugins/workflow-runner/test/context-files.test.ts +47 -16
- package/plugins/workflow-runner/test/e2eNewLayout.test.ts +314 -0
- package/plugins/workflow-runner/test/engineRobustness.test.ts +9 -1
- package/plugins/workflow-runner/test/expressions.test.ts +42 -0
- package/plugins/workflow-runner/test/hostCapability.test.ts +9 -3
- package/plugins/workflow-runner/test/illustrate.load.test.ts +2 -2
- package/plugins/workflow-runner/test/multimodal.test.ts +61 -10
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +19 -0
- package/plugins/workflow-runner/test/ppt.load.test.ts +15 -15
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +3 -2
- package/plugins/workflow-runner/test/research.load.test.ts +328 -0
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +68 -11
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +60 -12
- package/plugins/workflow-runner/test/taskArbitration.test.ts +19 -3
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +61 -7
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
- package/plugins/workflow-runner/test/webppt.load.test.ts +4 -4
- package/plugins/workflow-runner/test/word.load.test.ts +9 -9
- package/skills/skill-creator/scripts/run_eval.py +3 -2
- package/src/cli/print.js +36 -4
- package/src/cli/print.ts +42 -4
- package/src/cli/streamJson.js +19 -4
- package/src/cli/streamJson.ts +17 -4
- package/src/config/configDefaults.js +25 -0
- package/src/config/configDefaults.ts +33 -0
- package/src/config/configFile.js +2 -21
- package/src/config/configFile.ts +11 -24
- package/src/config/configManagement.js +1 -1
- package/src/config/configManagement.ts +2 -2
- package/src/config/configService.js +24 -0
- package/src/config/configService.ts +23 -0
- package/src/context/compact.js +4 -0
- package/src/context/compact.ts +4 -0
- package/src/context/contextBundle.js +38 -13
- package/src/context/contextBundle.ts +47 -13
- package/src/harness/stallGuard.js +19 -4
- package/src/harness/stallGuard.ts +30 -7
- package/src/infra/verification.js +25 -18
- package/src/infra/verification.ts +50 -18
- package/src/loop.js +95 -11
- package/src/loop.ts +125 -16
- package/src/main.js +8 -1
- package/src/main.tsx +7 -1
- package/src/memory/constants.js +10 -0
- package/src/memory/constants.ts +13 -0
- package/src/memory/episodicMemory.js +274 -2
- package/src/memory/episodicMemory.ts +306 -1
- package/src/memory/fileStore.js +24 -4
- package/src/memory/fileStore.ts +22 -2
- package/src/memory/memoryService.js +79 -12
- package/src/memory/memoryService.ts +108 -9
- package/src/memory/repository.js +415 -85
- package/src/memory/repository.ts +437 -86
- package/src/memory/turnJournal.js +95 -0
- package/src/memory/turnJournal.ts +120 -0
- package/src/memory/types.ts +16 -0
- package/src/plugins/pluginApi.ts +30 -6
- package/src/plugins/pluginRunner.js +23 -8
- package/src/plugins/pluginRunner.ts +32 -13
- package/src/prompts/policyRegistry.js +55 -1
- package/src/prompts/policyRegistry.ts +55 -1
- package/src/prompts/promptAssembly.js +39 -7
- package/src/prompts/promptAssembly.ts +145 -59
- package/src/session/runAgentTurn.js +43 -21
- package/src/session/runAgentTurn.ts +68 -26
- package/src/session/runTurn.js +11 -46
- package/src/session/runTurn.ts +12 -46
- package/src/session/runtimeStore.js +149 -0
- package/src/session/runtimeStore.ts +197 -0
- package/src/session/sessionState.js +5 -0
- package/src/session/sessionState.ts +14 -0
- package/src/tools/advisor/advisor.js +76 -9
- package/src/tools/advisor/advisor.ts +79 -9
- package/src/tools/agent/agent.js +143 -14
- package/src/tools/agent/agent.ts +149 -14
- package/src/tools/agent/agentTaskService.js +60 -0
- package/src/tools/agent/agentTaskService.ts +113 -0
- package/src/tools/agent/agentTypes.js +5 -0
- package/src/tools/agent/agentTypes.ts +5 -0
- package/src/tools/bash/bash.js +80 -15
- package/src/tools/bash/bash.ts +83 -15
- package/src/tools/capabilities.js +5 -0
- package/src/tools/capabilities.ts +11 -1
- package/src/tools/edit/edit.js +7 -4
- package/src/tools/edit/edit.ts +7 -4
- package/src/tools/edit/multi-edit.js +4 -2
- package/src/tools/edit/multi-edit.ts +4 -2
- package/src/tools/glob/glob.js +156 -40
- package/src/tools/glob/glob.ts +185 -46
- package/src/tools/index.js +35 -17
- package/src/tools/index.ts +81 -20
- package/src/tools/lsp/lsp.js +165 -22
- package/src/tools/lsp/lsp.ts +206 -36
- package/src/tools/powershell/powershell.js +134 -27
- package/src/tools/powershell/powershell.ts +171 -30
- package/src/tools/presentresult/presentresult.js +10 -0
- package/src/tools/presentresult/presentresult.ts +10 -0
- package/src/tools/read/read.js +249 -29
- package/src/tools/read/read.ts +396 -59
- package/src/tools/shared/diffSummary.js +44 -0
- package/src/tools/shared/diffSummary.ts +63 -0
- package/src/tools/shared/fileActivity.js +2 -1
- package/src/tools/shared/fileActivity.ts +3 -0
- package/src/tools/shared/permanentDeleteGuard.js +57 -0
- package/src/tools/shared/permanentDeleteGuard.ts +71 -0
- package/src/tools/shared/toolOutputStore.js +97 -0
- package/src/tools/shared/toolOutputStore.ts +110 -0
- package/src/tools/skill/skill.js +86 -0
- package/src/tools/skill/skill.ts +94 -0
- package/src/tools/snip/snip.js +67 -0
- package/src/tools/snip/snip.ts +80 -0
- package/src/tools/tasks/backgroundTaskService.js +79 -28
- package/src/tools/tasks/backgroundTaskService.ts +165 -49
- package/src/tools/tasks/taskManagement.js +163 -0
- package/src/tools/tasks/taskManagement.ts +180 -0
- package/src/tools/tasks/taskOutput.js +64 -14
- package/src/tools/tasks/taskOutput.ts +102 -23
- package/src/tools/tasks/taskStop.js +48 -8
- package/src/tools/tasks/taskStop.ts +69 -9
- package/src/tools/tasks/taskStore.js +46 -0
- package/src/tools/tasks/taskStore.ts +77 -0
- package/src/tools/terminal/terminalCapture.js +167 -0
- package/src/tools/terminal/terminalCapture.ts +179 -0
- package/src/tools/trash/trash.js +233 -0
- package/src/tools/trash/trash.ts +283 -0
- package/src/tools/webbrowser/browserControl.js +5 -1
- package/src/tools/webbrowser/browserControl.ts +7 -1
- package/src/tools/webbrowser/webbrowser.js +8 -4
- package/src/tools/webbrowser/webbrowser.ts +8 -4
- package/src/tools/worktree/sessionWorktree.js +128 -0
- package/src/tools/worktree/sessionWorktree.ts +158 -0
- package/src/tools/write/write.js +6 -2
- package/src/tools/write/write.ts +6 -2
- package/src/types.ts +22 -4
- package/src/ui/hooks/useChat.js +31 -11
- package/src/ui/hooks/useChat.ts +31 -13
- package/src/web/protocol.ts +78 -3
- package/workflows/adaptive-research.yaml +5 -5
- package/workflows/book-review-short.yaml +5 -5
- package/workflows/e2e-write-greet.yaml +2 -2
- package/workflows/illustrate.yaml +12 -12
- package/workflows/plan.yaml +18 -18
- package/workflows/ppt.yaml +201 -201
- package/workflows/ralph-loop.yaml +3 -1
- package/workflows/research.md +449 -0
- package/workflows/research.yaml +873 -0
- package/workflows/webppt.yaml +47 -47
- package/workflows/word.yaml +80 -80
- package/workflows/youtube-shorts.yaml +25 -25
package/workflows/ppt.yaml
CHANGED
|
@@ -20,7 +20,7 @@ version: "0.1"
|
|
|
20
20
|
# 中间 scratch(draft/design/deck.html/img_plan/assets/export)故意不声明——收尾 cleanup 删;
|
|
21
21
|
# 声明进来会被「声明产物必须存在」判缺失而 halt。
|
|
22
22
|
artifacts:
|
|
23
|
-
- "
|
|
23
|
+
- "out/ppt/${session}/deck.pptx"
|
|
24
24
|
|
|
25
25
|
# 自愈:LLM/网络瞬态故障 in-run 重跑(端点会分钟级拥塞波,给恢复窗口)。
|
|
26
26
|
self_heal:
|
|
@@ -54,7 +54,7 @@ inputs:
|
|
|
54
54
|
description: "【高级·可选 --input】AI 生图张数控制:默认 -1=最佳质量、不设上限;0=完全不生 AI 图(仅纯示意主题);N>0=显式上限 N 张。只要页面需要真实画面、产品感、场景、操作、安装、环境、特写、氛围背景,且客户图没有合适素材,就必须积极文生图;流程图、数据图表、架构图、关系图、时间线、参数轴等精确信息必须 HTML/SVG,不占额度。"
|
|
55
55
|
- name: out
|
|
56
56
|
type: string
|
|
57
|
-
default: "
|
|
57
|
+
default: "out/ppt/${session}/deck.pptx"
|
|
58
58
|
description: "【高级·可选 --input】输出 PPTX 路径"
|
|
59
59
|
- name: image_intensity
|
|
60
60
|
type: enum
|
|
@@ -70,7 +70,7 @@ inputs:
|
|
|
70
70
|
type: enum
|
|
71
71
|
values: ["true", "false"]
|
|
72
72
|
default: "true"
|
|
73
|
-
description: "【调试·可选 --input】是否保留
|
|
73
|
+
description: "【调试·可选 --input】是否保留 out/ppt/${session}/build 中间产物。默认 true,便于检查 deck.html、design.json、截图和报告;设为 false 时最终 PPT 生成后清理 out/ppt/${session}/build。"
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
steps:
|
|
@@ -149,31 +149,31 @@ steps:
|
|
|
149
149
|
args:
|
|
150
150
|
command: |
|
|
151
151
|
set -e
|
|
152
|
-
mkdir -p
|
|
152
|
+
mkdir -p out/ppt/${session}/build out/ppt/${session}/build/assets
|
|
153
153
|
# 只清理本次运行的状态/哨兵/旧报告,不删除 build 全目录,保留用户排障需要的中间产物。
|
|
154
154
|
rm -f \
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
rm -rf
|
|
155
|
+
out/ppt/${session}/build/build_complete \
|
|
156
|
+
out/ppt/${session}/build/layout_ok \
|
|
157
|
+
out/ppt/${session}/build/visual_quality_ok \
|
|
158
|
+
out/ppt/${session}/build/visual_quality_state.json \
|
|
159
|
+
out/ppt/${session}/build/visual_quality_report.json \
|
|
160
|
+
out/ppt/${session}/build/visual_quality_report.md \
|
|
161
|
+
out/ppt/${session}/build/visual_quality_residual.md \
|
|
162
|
+
out/ppt/${session}/build/image_generation_report.json \
|
|
163
|
+
out/ppt/${session}/build/generated_image_review.json \
|
|
164
|
+
out/ppt/${session}/build/generated_image_semantic_retry_report.json \
|
|
165
|
+
out/ppt/${session}/build/export-summary.md \
|
|
166
|
+
out/ppt/${session}/build/build_probe.json \
|
|
167
|
+
out/ppt/${session}/build/build_probe.txt \
|
|
168
|
+
out/ppt/${session}/build/design_repair_done \
|
|
169
|
+
out/ppt/${session}/build/design_repair_residual.md \
|
|
170
|
+
out/ppt/${session}/build/design_json_ok \
|
|
171
|
+
out/ppt/${session}/build/design_json_gate.json \
|
|
172
|
+
out/ppt/${session}/build/design_json_gate.md \
|
|
173
|
+
out/ppt/${session}/build/design.raw.json \
|
|
174
|
+
out/ppt/${session}/build/design.draft.json \
|
|
175
|
+
out/ppt/${session}/build/img_route_ok
|
|
176
|
+
rm -rf out/ppt/${session}/build/export out/ppt/${session}/build/generated-image-reviews
|
|
177
177
|
RESOLVE="skills/ui-design/scripts/resolve_source_input.py"
|
|
178
178
|
EXTRACT="skills/ui-design/scripts/extract_source_assets.py"
|
|
179
179
|
STATS="skills/image-stats/scripts/image_stats.py"
|
|
@@ -189,16 +189,16 @@ steps:
|
|
|
189
189
|
--source "$RAW_SOURCE" \
|
|
190
190
|
--topic "$RAW_TOPIC" \
|
|
191
191
|
--cwd . \
|
|
192
|
-
--out
|
|
193
|
-
SOURCE="$(python3 -c 'import json; data=json.load(open("
|
|
192
|
+
--out out/ppt/${session}/build/source_resolution.json
|
|
193
|
+
SOURCE="$(python3 -c 'import json; data=json.load(open("out/ppt/${session}/build/source_resolution.json", encoding="utf-8")); print(data.get("resolved_path") or "")')"
|
|
194
194
|
if [ -n "$SOURCE" ]; then
|
|
195
|
-
python3 "$EXTRACT" "$SOURCE" --out
|
|
195
|
+
python3 "$EXTRACT" "$SOURCE" --out out/ppt/${session}/build -v
|
|
196
196
|
else
|
|
197
|
-
python3 "$EXTRACT" . --scan --out
|
|
197
|
+
python3 "$EXTRACT" . --scan --out out/ppt/${session}/build -v
|
|
198
198
|
fi
|
|
199
|
-
python3 -c 'import json,sys; r=json.load(open("
|
|
200
|
-
python3 "$STATS"
|
|
201
|
-
cat >
|
|
199
|
+
python3 -c 'import json,sys; r=json.load(open("out/ppt/${session}/build/source_resolution.json", encoding="utf-8")); a=json.load(open("out/ppt/${session}/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" out/ppt/${session}/build/assets --scan --json > out/ppt/${session}/build/source_stats.json
|
|
201
|
+
cat > out/ppt/${session}/build/user_request.md <<'EOF'
|
|
202
202
|
# 用户原始输入与目标
|
|
203
203
|
|
|
204
204
|
- 主题/指令:${inputs.topic}
|
|
@@ -209,12 +209,12 @@ steps:
|
|
|
209
209
|
|
|
210
210
|
## 素材解析结果
|
|
211
211
|
EOF
|
|
212
|
-
printf '\n```json\n' >>
|
|
213
|
-
cat
|
|
214
|
-
printf '\n```\n\n## 素材抽取结果\n\n```json\n' >>
|
|
215
|
-
cat
|
|
216
|
-
printf '\n```\n' >>
|
|
217
|
-
cat >>
|
|
212
|
+
printf '\n```json\n' >> out/ppt/${session}/build/user_request.md
|
|
213
|
+
cat out/ppt/${session}/build/source_resolution.json >> out/ppt/${session}/build/user_request.md
|
|
214
|
+
printf '\n```\n\n## 素材抽取结果\n\n```json\n' >> out/ppt/${session}/build/user_request.md
|
|
215
|
+
cat out/ppt/${session}/build/source_assets.json >> out/ppt/${session}/build/user_request.md
|
|
216
|
+
printf '\n```\n' >> out/ppt/${session}/build/user_request.md
|
|
217
|
+
cat >> out/ppt/${session}/build/user_request.md <<'EOF'
|
|
218
218
|
|
|
219
219
|
|
|
220
220
|
## 阶段1澄清结论
|
|
@@ -228,7 +228,7 @@ steps:
|
|
|
228
228
|
3. 客户图片必须直接使用或通过图生图增强派生后使用,不能无故丢弃。
|
|
229
229
|
EOF
|
|
230
230
|
echo "PPT_SOURCE_EXTRACT_READY"
|
|
231
|
-
test -f
|
|
231
|
+
test -f out/ppt/${session}/build/source_assets.json
|
|
232
232
|
onError: halt # 用户明确提到素材但解析/抽取失败时必须停下,避免伪装成纯 topic
|
|
233
233
|
|
|
234
234
|
# ---------- 阶段3:逐图多模态识图(best-effort)—— for-each 遍历 readJson 拿到的真实图片清单 ----------
|
|
@@ -236,9 +236,9 @@ steps:
|
|
|
236
236
|
# 写 build/vision/<file>.json;无多模态模型 / 单图识图失败都不阻断(onError:continue)。images:[] 时 0 轮(when 守门)。
|
|
237
237
|
- id: stage_vision_loop
|
|
238
238
|
title: "阶段3/22·逐图识图(内容+重点区+背景适配)"
|
|
239
|
-
when: "fileExists('
|
|
239
|
+
when: "fileExists('out/ppt/${session}/build/source_assets.json')"
|
|
240
240
|
type: loop
|
|
241
|
-
over: "${asArray(readJson('
|
|
241
|
+
over: "${asArray(readJson('out/ppt/${session}/build/source_assets.json', 'images'))}"
|
|
242
242
|
as: img
|
|
243
243
|
fresh_context: true
|
|
244
244
|
do:
|
|
@@ -279,7 +279,7 @@ steps:
|
|
|
279
279
|
- `notes`:其它对排版有用的观察(如"右上角有大片留白可放标题"),没有就空串。
|
|
280
280
|
capture:
|
|
281
281
|
text: vision_json
|
|
282
|
-
images: ["
|
|
282
|
+
images: ["out/ppt/${session}/build/assets/${img.file}"]
|
|
283
283
|
image_detail: high
|
|
284
284
|
onError: continue # 无多模态模型 / 单图识图失败 → 跳过该图,下游容缺(只用文字+统计)
|
|
285
285
|
- id: write_vision_json
|
|
@@ -287,7 +287,7 @@ steps:
|
|
|
287
287
|
when: "length(vision_json) > 0"
|
|
288
288
|
tool: Write
|
|
289
289
|
args:
|
|
290
|
-
file_path: "
|
|
290
|
+
file_path: "out/ppt/${session}/build/vision/${img.file}.json"
|
|
291
291
|
content: "${vision_json}"
|
|
292
292
|
onError: continue
|
|
293
293
|
# 写后消毒校验(2026-07-02 事故:src_6 识图结论正确但 JSON 引号未转义 → assemble 静默吞 None →
|
|
@@ -299,7 +299,7 @@ steps:
|
|
|
299
299
|
tool: Bash
|
|
300
300
|
args:
|
|
301
301
|
command: |
|
|
302
|
-
python3 - "
|
|
302
|
+
python3 - "out/ppt/${session}/build/vision/${img.file}.json" <<'PYEOF'
|
|
303
303
|
import json, re, sys
|
|
304
304
|
path = sys.argv[1]
|
|
305
305
|
try:
|
|
@@ -324,7 +324,7 @@ steps:
|
|
|
324
324
|
# 坏 JSON 重识别一次(强化 JSON 纪律的短 prompt);仍坏则删除,assemble 阶段逐图 WARNING + 盲态保守。
|
|
325
325
|
- id: vision_one_retry
|
|
326
326
|
title: "阶段3/22·重识别 ${img.file}(上次 JSON 非法)"
|
|
327
|
-
when: "length(vision_json) > 0 && !fileExists('
|
|
327
|
+
when: "length(vision_json) > 0 && !fileExists('out/ppt/${session}/build/vision/${img.file}.json')"
|
|
328
328
|
llm: |
|
|
329
329
|
上一次你对图片 `${img.file}` 的识图输出不是合法 JSON(多半是字符串里出现了未转义的英文双引号)。
|
|
330
330
|
重新只输出**一段合法 JSON**(无解释、无代码围栏;字符串内部引号一律用中文「」),字段:
|
|
@@ -333,15 +333,15 @@ steps:
|
|
|
333
333
|
relevant_to_topic(true|false) / recommended_text_zone / palette_impression / notes。
|
|
334
334
|
capture:
|
|
335
335
|
text: vision_json_retry
|
|
336
|
-
images: ["
|
|
336
|
+
images: ["out/ppt/${session}/build/assets/${img.file}"]
|
|
337
337
|
image_detail: high
|
|
338
338
|
onError: continue
|
|
339
339
|
- id: rewrite_vision_json
|
|
340
340
|
title: "阶段3/22·重写识图 JSON ${img.file}"
|
|
341
|
-
when: "length(vision_json_retry) > 0 && !fileExists('
|
|
341
|
+
when: "length(vision_json_retry) > 0 && !fileExists('out/ppt/${session}/build/vision/${img.file}.json')"
|
|
342
342
|
tool: Write
|
|
343
343
|
args:
|
|
344
|
-
file_path: "
|
|
344
|
+
file_path: "out/ppt/${session}/build/vision/${img.file}.json"
|
|
345
345
|
content: "${vision_json_retry}"
|
|
346
346
|
onError: continue
|
|
347
347
|
- id: sanitize_vision_json_retry
|
|
@@ -350,7 +350,7 @@ steps:
|
|
|
350
350
|
tool: Bash
|
|
351
351
|
args:
|
|
352
352
|
command: |
|
|
353
|
-
python3 - "
|
|
353
|
+
python3 - "out/ppt/${session}/build/vision/${img.file}.json" <<'PYEOF'
|
|
354
354
|
import json, re, sys
|
|
355
355
|
path = sys.argv[1]
|
|
356
356
|
try:
|
|
@@ -381,34 +381,34 @@ steps:
|
|
|
381
381
|
# 收成确定性(治根因:低清图被硬铺当背景、该图生图的没图生图、提示词写不稳),设计步从此「按算好的选模板」。
|
|
382
382
|
- id: stage_assemble_material
|
|
383
383
|
title: "阶段4/22·合并统一材料 + 客户图版式/图生图规划"
|
|
384
|
-
when: "fileExists('
|
|
384
|
+
when: "fileExists('out/ppt/${session}/build/source_assets.json')"
|
|
385
385
|
tool: Bash
|
|
386
386
|
args:
|
|
387
387
|
command: |
|
|
388
388
|
set -e
|
|
389
|
-
python3 skills/ui-design/scripts/assemble_material.py --build
|
|
390
|
-
test -f
|
|
389
|
+
python3 skills/ui-design/scripts/assemble_material.py --build out/ppt/${session}/build
|
|
390
|
+
test -f out/ppt/${session}/build/material.json
|
|
391
391
|
# 确定性客户图版式/图生图规划(恒产出 source_layout_plan.json/md,无客户图则空规划)。
|
|
392
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --build
|
|
392
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --build out/ppt/${session}/build || true
|
|
393
393
|
echo "PPT_MATERIAL_ASSEMBLED"
|
|
394
|
-
sed -n '1,120p'
|
|
395
|
-
sed -n '1,80p'
|
|
394
|
+
sed -n '1,120p' out/ppt/${session}/build/material.md || true
|
|
395
|
+
sed -n '1,80p' out/ppt/${session}/build/source_layout_plan.md 2>/dev/null || true
|
|
396
396
|
onError: continue # 合并失败不阻断(脚本恒产出,最坏是空材料,下游退化纯 topic)
|
|
397
397
|
|
|
398
398
|
# ---------- 阶段5:基于客户材料撰写知乎深度长文式基础稿件(默认不联网) ----------
|
|
399
399
|
- id: stage_draft_from_material
|
|
400
400
|
title: "阶段5/22·客户材料成稿(默认不联网)"
|
|
401
401
|
agent: |
|
|
402
|
-
为主题「${inputs.topic}」撰写一篇**知乎高赞深度长文式**的基础稿件,落到
|
|
402
|
+
为主题「${inputs.topic}」撰写一篇**知乎高赞深度长文式**的基础稿件,落到 `out/ppt/${session}/build/draft.md`。
|
|
403
403
|
这篇稿件是后续整套 PPT 的**唯一内容源**——它薄,PPT 必然肤浅;它厚且有料,PPT 才立得住。
|
|
404
404
|
成败标准只有一个:**专业、有深度、有观点、有据可依,绝不灌水、绝不百科式罗列。**
|
|
405
405
|
|
|
406
406
|
## -1、先回看用户目标(最高权重)
|
|
407
|
-
**先 Read
|
|
407
|
+
**先 Read `out/ppt/${session}/build/user_request.md`**。后续所有取舍都以这里记录的用户原始输入、素材路径、视觉偏好和澄清结论为最高权重。
|
|
408
408
|
如果材料与模型常识冲突,以客户材料为准;如果用户目标与材料范围冲突,写稿时明确采用用户目标做取舍。
|
|
409
409
|
|
|
410
410
|
## 〇、先看「用户原始材料」(素材驱动的关键)
|
|
411
|
-
**先 Read
|
|
411
|
+
**先 Read `out/ppt/${session}/build/material.md`**(统一中间材料:文字主干 + 每张客户图的识图详述/重点区/统计):
|
|
412
412
|
- **有素材(material.md 有实质文字或图片)**:**以它为内容主干**——
|
|
413
413
|
**忠实保留其要点/数据/结构/事实(高权重,这是用户的原始资料,不得丢弃或随意改写)**;
|
|
414
414
|
你的工作是把它**消化、补全、深化**成知乎长文式稿件(理顺逻辑、补背景与机制、补必要常识),
|
|
@@ -434,7 +434,7 @@ steps:
|
|
|
434
434
|
涉及最新价格、政策、版本等强时效信息时,不要编造;写成「需按用户最新资料或公开信息复核」,除非用户在 topic 里明确要求联网查新。
|
|
435
435
|
不要整段复制材料原文;要把材料消化成适合 PPT 叙事的论点、证据和例子。
|
|
436
436
|
|
|
437
|
-
## 四、按"知乎深度长文"结构成稿(用 Write 写
|
|
437
|
+
## 四、按"知乎深度长文"结构成稿(用 Write 写 `out/ppt/${session}/build/draft.md`)
|
|
438
438
|
简体中文、Markdown,**篇幅按主题复杂度自适应**:默认 `quality=fast` 写 1200–2500 字的高密度成稿(快、够用、不注水);
|
|
439
439
|
`quality=best` 才写 2500–6000 字深稿(愿意等待时用)。结构:
|
|
440
440
|
1. **引子**:抛真问题 / 认知张力 / 反直觉点(不要"随着……的发展"套话)。
|
|
@@ -449,7 +449,7 @@ steps:
|
|
|
449
449
|
完成后简述:字数、核心论点、几个论点小节、使用了哪些客户材料和图片信息。
|
|
450
450
|
allowed_tools: [Read, Write, Glob]
|
|
451
451
|
maxTurns: 24
|
|
452
|
-
done_when: "fileExists('
|
|
452
|
+
done_when: "fileExists('out/ppt/${session}/build/draft.md')"
|
|
453
453
|
# 地基步:稿件是后续全流程的唯一内容源。LLM 调用失败(如 minimax 端点拥塞/空闲超时)时**必须 halt 保留现场**,
|
|
454
454
|
# 不能 continue——否则没 draft.md 会让后面 5 个内容步全因 when=false 跳过、空手撞到导出步「假装推进、实则烂尾」。
|
|
455
455
|
# halt 后重跑按任务身份从本步续跑(错峰/网络恢复即可成)。max_retries 给 2 次 in-run 重试吸收瞬态拥塞。
|
|
@@ -463,25 +463,25 @@ steps:
|
|
|
463
463
|
# (这是用户点名最高优先级问题,不能只在 best 生效);查无遗漏时零开销(when 直接短路,跳过修复步)。
|
|
464
464
|
- id: stage_draft_coverage
|
|
465
465
|
title: "阶段5/22·原文主题覆盖检查"
|
|
466
|
-
when: "fileExists('
|
|
466
|
+
when: "fileExists('out/ppt/${session}/build/draft.md')"
|
|
467
467
|
tool: Bash
|
|
468
468
|
args:
|
|
469
469
|
command: |
|
|
470
|
-
python3 skills/ui-design/scripts/draft_coverage_check.py --build
|
|
470
|
+
python3 skills/ui-design/scripts/draft_coverage_check.py --build out/ppt/${session}/build -v
|
|
471
471
|
onError: continue
|
|
472
472
|
|
|
473
473
|
- id: stage_draft_coverage_repair
|
|
474
474
|
title: "阶段5/22·回填未覆盖主题"
|
|
475
|
-
when: "fileExists('
|
|
475
|
+
when: "fileExists('out/ppt/${session}/build/draft_coverage_report.json') && readJson('out/ppt/${session}/build/draft_coverage_report.json', 'ok') == false"
|
|
476
476
|
agent: |
|
|
477
|
-
|
|
478
|
-
|
|
477
|
+
`out/ppt/${session}/build/draft_coverage_report.md` 列出了原文档里"有章节标题/有客户图表核心结论,但在
|
|
478
|
+
`out/ppt/${session}/build/draft.md` 里找不到对应内容"的主题——这类主题多半靠图片本身说话、原文写得模糊,
|
|
479
479
|
上一步写 draft.md 时被判定"缺乏明确论点"而略过了,但客户图还在等着这些内容配页。
|
|
480
480
|
|
|
481
481
|
必读:
|
|
482
|
-
-
|
|
483
|
-
-
|
|
484
|
-
-
|
|
482
|
+
- `out/ppt/${session}/build/draft_coverage_report.md`
|
|
483
|
+
- `out/ppt/${session}/build/material.md`(找回原文对应段落 + 相关客户图的识图详述/图表核心结论)
|
|
484
|
+
- `out/ppt/${session}/build/draft.md`
|
|
485
485
|
|
|
486
486
|
对报告里每个未覆盖主题:回 `material.md` 找到对应原文段落或客户图的 `key_message`/识图详述,
|
|
487
487
|
提炼成一条论点/证据/例子,**补进 draft.md 现有相关小节,或新增一个简短小节**(用 Edit 或 Write)。
|
|
@@ -501,14 +501,14 @@ steps:
|
|
|
501
501
|
# **保留 visual.{route,side,note} 字段名** → 下游 image_plan_lint.py(--outline 参数)直接吃 design.json,零适配。
|
|
502
502
|
- id: stage_design_doc
|
|
503
503
|
title: "阶段6/22·Web 页面设计文档(先设计后实现)"
|
|
504
|
-
when: "fileExists('
|
|
504
|
+
when: "fileExists('out/ppt/${session}/build/draft.md')"
|
|
505
505
|
agent: |
|
|
506
|
-
读
|
|
506
|
+
读 `out/ppt/${session}/build/draft.md`,产出一份**详细的 Web 页面设计文档**——这是后续"做网页"的唯一蓝图。
|
|
507
507
|
关键心态:**先把每一页设计清楚(装什么内容、用什么构图、每块怎么呈现、配什么图、背景什么变化),再去实现**。
|
|
508
508
|
不要在本步写 deck.html / 生图(那是后续阶段)。本步只产设计文档 + 配图计划。
|
|
509
509
|
|
|
510
510
|
## -1、先回看用户目标
|
|
511
|
-
先 Read
|
|
511
|
+
先 Read `out/ppt/${session}/build/user_request.md`,确认用户原始输入、素材路径、视觉风格和阶段1澄清结论。后续设计取舍优先满足用户目标,
|
|
512
512
|
不要在长流程里忘掉用户最初说法。
|
|
513
513
|
|
|
514
514
|
## 先读设计规则(单一规则源)
|
|
@@ -516,8 +516,8 @@ steps:
|
|
|
516
516
|
(构图法枚举 + 每页内容预算 + 元素渲染决策 + 配图分流 + 生图提示词配方 + 构图均衡)。严格照其执行。
|
|
517
517
|
|
|
518
518
|
## 〇、先盘点「用户原始材料」——决定客户图怎么高权重用(素材驱动的关键)
|
|
519
|
-
**先 Read
|
|
520
|
-
- **有客户图(material.json images 非空)**:**再 Read
|
|
519
|
+
**先 Read `out/ppt/${session}/build/material.json`**(富 manifest:每张客户图带 base 字段 + `vision`[识图详述/key_elements/key_region/suitable_as_background/recommended_text_zone] + `stats`[average_color/dominant_colors/tone/brightness],图已在 `out/ppt/${session}/build/assets/`):
|
|
520
|
+
- **有客户图(material.json images 非空)**:**再 Read `out/ppt/${session}/build/source_layout_plan.md`(确定性版式/图生图规划)和 ui-design 技能目录下的 `references/source-image-layout.md`**(客户图布局铁律:全图生图重绘到槽位比例 + 默认 `object-fit:cover` 填满槽、`object-position` 保重点区,仅 dense-info 数据图 contain + 按朝向/重点区图文混排 + 配色随图 + 文字避让重点区 + 宜做背景者铺背景)。
|
|
521
521
|
🚨 **逐图决策已由 `source_layout_plan.md`/`.json` 算定,你【直接照它执行、不要自己重算分辨率/比例】**——每张图它都给了:
|
|
522
522
|
`usage_intent`(用途)、`enhance_required`(是否必须图生图)、`enhance_target_aspect`(目标比例)、`recommended_templates`(推荐图文混排模板,对齐 layout-composition §2.2)、`text_zone`(文字落区,避让重点区)、`text_color`(深墨字/白字)。
|
|
523
523
|
你的工作只剩两件:① **章节锚定配页(治张冠李戴·第一优先级)**:每张客户图先看规划里的 `section`(来源章节)+ `near_text`(原文邻近文案)——**必须配到覆盖该章节内容的页**(客户图是给原文特定章节配的,排到别的主题页 = 张冠李戴);vision.description(识图内容)只用于「该章节对应多页时挑最贴的一页」;**仅当**该章节无对应页、或图无 section(独立散图/页号锚)时,才按 vision.description ↔ key_point 语义契合配页。配好后从 `recommended_templates` 里挑一个落地;② 让该页文案呼应 vision.description、配色随 stats。
|
|
@@ -687,9 +687,9 @@ steps:
|
|
|
687
687
|
**相邻页不要完全一样**;但不破坏色系一致(仍是同一 VI)。
|
|
688
688
|
|
|
689
689
|
## 五、产物(严格落这些路径)
|
|
690
|
-
1. 用 Write 写
|
|
690
|
+
1. 用 Write 写 `out/ppt/${session}/build/design.md`(人读):逐页 `## 第N页 · <标题>` + archetype + composition + key_point + 要点 +
|
|
691
691
|
各块 render + 配图说明 + 背景意图,便于人复核。
|
|
692
|
-
2. 用 Write 写
|
|
692
|
+
2. 用 Write 写 `out/ppt/${session}/build/design.json`(机读,**严格 JSON、无注释、无 ``` 包裹**):
|
|
693
693
|
- 可以写成多行缩进的漂亮 JSON;下一阶段会用 `normalize_design_json.py` 做硬解析、规范化和结构验收。
|
|
694
694
|
不要追求单行大 JSON;单行过长更容易被弱模型写坏。**但必须是真 JSON:不能有注释、Markdown、尾随解释文字。**
|
|
695
695
|
- 字段精炼(key_point/points/evidence/note/prompt 都用短句,别灌长文);下面是**字段结构示例**:
|
|
@@ -708,17 +708,17 @@ steps:
|
|
|
708
708
|
⚠️ **`aspect` 必须 = 该图所在槽位的比例**(你为它选的模板/grid 单元决定,如全幅背景 16:9、左右半 4:5、上下横带 21:9)——图生图据此**重绘到槽位所需比例/分辨率**,落进槽位**正好填满、不留白不裁切**;`prompt` 用 `source_layout_plan.json` 里算好的 `enhance_prompt`(保留原图内容 + 高清重绘 + 缺失区域智能补全),别自己另写。
|
|
709
709
|
- `key_point` 每页必填;`evidence` 内容页必填、封面/章节页可 [];route=ai-* 或 source-enhanced 才需 visual.prompt(route=source 用 source_file、不需 prompt)。
|
|
710
710
|
- `speaker_notes` 内容页建议必写(封面/章节可省):**演讲讲稿**,把 draft 的论证/机制/出处收进来——它是「上屏短语化」的另一半,没有它深度就只能塞上屏。不计入 max_visible_words。
|
|
711
|
-
3. 用 Write 写
|
|
711
|
+
3. 用 Write 写 `out/ppt/${session}/build/img_plan.json`(机读,配图计划):**只写 route=source-enhanced 客户图增强条目**(best-effort——阶段9 `--ensure-img-plan` 还会从 source_layout_plan 兜底 union,写不全没关系)。
|
|
712
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
713
|
(`illustrations=${inputs.illustrations}`:-1=由内容定、0=不主动配 AI 图;N>0=AI 图不超 N,source-enhanced 不计入浪费额度),图生图增强每条:
|
|
714
714
|
- 图生图增强:`{"file":"enhanced_src_K.png","mode":"image-to-image","source_file":"src_K.png","aspect":"<目标比例>","prompt":"<扩图/换背景/清晰化/比例修复提示词>"}`
|
|
715
|
-
⚠️ **只要有任何 route=ai-* 或 source-enhanced 页 → 必须写出
|
|
715
|
+
⚠️ **只要有任何 route=ai-* 或 source-enhanced 页 → 必须写出 `out/ppt/${session}/build/img_plan.json`(无客户图增强就写 `[]` 空数组也行)**,保证阶段9 闸门触发、ai-* 被注入;纯示意主题且零 AI/客户图才可不写此文件。
|
|
716
716
|
|
|
717
717
|
完成后简述:共几页、是否含综述+总结页、各页 archetype+composition、其中几页 route=source/source-enhanced(客户图)/ai-A/ai-B、img_plan.json 几条。
|
|
718
718
|
allowed_tools: [Read, Write, Glob]
|
|
719
719
|
maxTurns: 20
|
|
720
720
|
capture: design_notes
|
|
721
|
-
done_when: "fileExists('
|
|
721
|
+
done_when: "fileExists('out/ppt/${session}/build/design.md') && fileExists('out/ppt/${session}/build/design.json')"
|
|
722
722
|
onError: halt
|
|
723
723
|
# 重活步(读长 draft+layout+vi、出 16 页 JSON)拥塞下首字节延迟易撞空闲超时 → 给 2 次 in-run 重试吸收瞬态拥塞。
|
|
724
724
|
max_retries: 2
|
|
@@ -728,20 +728,20 @@ steps:
|
|
|
728
728
|
# 当场修订到位。不引入人工 pause(webppt 定位=一句话自动产出);不重跑研究,只打磨设计文档。
|
|
729
729
|
- id: stage_design_json_gate
|
|
730
730
|
title: "阶段7/22·设计 JSON 硬验收 + 确定性预检"
|
|
731
|
-
when: "fileExists('
|
|
731
|
+
when: "fileExists('out/ppt/${session}/build/design.json')"
|
|
732
732
|
tool: Bash
|
|
733
733
|
args:
|
|
734
734
|
command: |
|
|
735
735
|
set -e
|
|
736
|
-
mkdir -p
|
|
737
|
-
python3 skills/ui-design/scripts/normalize_design_json.py --build
|
|
738
|
-
test -f
|
|
739
|
-
BUDGET_LOG
|
|
740
|
-
STYLE_LOG
|
|
736
|
+
mkdir -p out/ppt/${session}/build
|
|
737
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build out/ppt/${session}/build
|
|
738
|
+
test -f out/ppt/${session}/build/design_json_ok
|
|
739
|
+
BUDGET_LOG=out/ppt/${session}/build/design_budget_check.txt
|
|
740
|
+
STYLE_LOG=out/ppt/${session}/build/design_style_check.txt
|
|
741
741
|
set +e
|
|
742
|
-
python3 skills/ui-design/scripts/design_budget_check.py
|
|
742
|
+
python3 skills/ui-design/scripts/design_budget_check.py out/ppt/${session}/build/design.json -v > "$BUDGET_LOG" 2>&1
|
|
743
743
|
BUDGET_STATUS=$?
|
|
744
|
-
python3 skills/ui-design/scripts/design_style_check.py
|
|
744
|
+
python3 skills/ui-design/scripts/design_style_check.py out/ppt/${session}/build/design.json -v > "$STYLE_LOG" 2>&1
|
|
745
745
|
STYLE_STATUS=$?
|
|
746
746
|
set -e
|
|
747
747
|
export BUDGET_STATUS STYLE_STATUS
|
|
@@ -750,7 +750,7 @@ steps:
|
|
|
750
750
|
import os
|
|
751
751
|
from pathlib import Path
|
|
752
752
|
|
|
753
|
-
build = Path("
|
|
753
|
+
build = Path("out/ppt/${session}/build")
|
|
754
754
|
budget_status = int(os.environ.get("BUDGET_STATUS", "1"))
|
|
755
755
|
style_status = int(os.environ.get("STYLE_STATUS", "1"))
|
|
756
756
|
budget_log = (build / "design_budget_check.txt").read_text(encoding="utf-8", errors="replace")
|
|
@@ -781,11 +781,11 @@ steps:
|
|
|
781
781
|
|
|
782
782
|
- id: stage_design_review
|
|
783
783
|
title: "阶段8/22·对抗评审设计文档(短修订)"
|
|
784
|
-
when: "inputs.quality == 'best' && fileExists('
|
|
784
|
+
when: "inputs.quality == 'best' && fileExists('out/ppt/${session}/build/design_json_ok')"
|
|
785
785
|
agent: |
|
|
786
786
|
你是一名挑剔的**设计评审 + 内容总监**,对刚产出的 Web 页面设计文档做**对抗式审查并当场修订定稿**。
|
|
787
|
-
先 Read
|
|
788
|
-
再按需 Read
|
|
787
|
+
先 Read `out/ppt/${session}/build/user_request.md`、`out/ppt/${session}/build/design_review_checks.md`、`out/ppt/${session}/build/design.md` 与 `out/ppt/${session}/build/design.json`,
|
|
788
|
+
再按需 Read `out/ppt/${session}/build/material.json`、`out/ppt/${session}/build/source_layout_plan.json`(确定性版式/图生图规划——逐张核对设计是否服从它)。
|
|
789
789
|
|
|
790
790
|
## 最高裁决顺序:非破坏性评审,防止把好设计改坏
|
|
791
791
|
本步是**非破坏性评审**:你可以修 `design.json`,但只能修**证据明确**违反下面顺序的地方,不能为了"空"、"不满"、
|
|
@@ -806,7 +806,7 @@ steps:
|
|
|
806
806
|
- 拿不准就保留原设计,写入"存疑,交末端构图门复核",不要硬改。
|
|
807
807
|
|
|
808
808
|
## 第零步:只读预检报告,不再自己跑脚本
|
|
809
|
-
|
|
809
|
+
`out/ppt/${session}/build/design_review_checks.md/json` 已由上一步确定性生成,里面包含 `design_budget_check.py` 与 `design_style_check.py`
|
|
810
810
|
的结果。你只根据报告中的明确问题修 `design.json`/`design.md`:
|
|
811
811
|
- budget 问题:只修文字过量、标题/要点过长、可能顶出画布;**不为填满页面加内容**。
|
|
812
812
|
- style 问题:只修缺字段、卡片墙/大表格/文字墙、缺主视觉、缺客户图增强或缺 AI 主视觉。
|
|
@@ -883,29 +883,29 @@ steps:
|
|
|
883
883
|
|
|
884
884
|
- id: stage_design_recheck
|
|
885
885
|
title: "阶段9/22·设计文档确定性复核"
|
|
886
|
-
when: "fileExists('
|
|
886
|
+
when: "fileExists('out/ppt/${session}/build/design_json_ok')"
|
|
887
887
|
tool: Bash
|
|
888
888
|
args:
|
|
889
889
|
command: |
|
|
890
890
|
set -e
|
|
891
|
-
mkdir -p
|
|
892
|
-
python3 skills/ui-design/scripts/normalize_design_json.py --build
|
|
893
|
-
test -f
|
|
894
|
-
BUDGET_LOG
|
|
895
|
-
STYLE_LOG
|
|
891
|
+
mkdir -p out/ppt/${session}/build
|
|
892
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build out/ppt/${session}/build
|
|
893
|
+
test -f out/ppt/${session}/build/design_json_ok
|
|
894
|
+
BUDGET_LOG=out/ppt/${session}/build/design_budget_recheck.txt
|
|
895
|
+
STYLE_LOG=out/ppt/${session}/build/design_style_recheck.txt
|
|
896
896
|
if [ "${inputs.quality}" != "best" ]; then
|
|
897
|
-
cp
|
|
898
|
-
cp
|
|
899
|
-
cp
|
|
900
|
-
cp
|
|
901
|
-
cp
|
|
897
|
+
cp out/ppt/${session}/build/design_budget_check.txt "$BUDGET_LOG" 2>/dev/null || true
|
|
898
|
+
cp out/ppt/${session}/build/design_style_check.txt "$STYLE_LOG" 2>/dev/null || true
|
|
899
|
+
cp out/ppt/${session}/build/design_review_checks.json out/ppt/${session}/build/design_review_recheck.json 2>/dev/null || true
|
|
900
|
+
cp out/ppt/${session}/build/design_review_checks.md out/ppt/${session}/build/design_review_recheck.md 2>/dev/null || true
|
|
901
|
+
cp out/ppt/${session}/build/design_review_checks.md out/ppt/${session}/build/design_repair_residual.md 2>/dev/null || true
|
|
902
902
|
echo "DESIGN_REVIEW_RECHECK_SKIPPED_FAST"
|
|
903
903
|
exit 0
|
|
904
904
|
fi
|
|
905
905
|
set +e
|
|
906
|
-
python3 skills/ui-design/scripts/design_budget_check.py
|
|
906
|
+
python3 skills/ui-design/scripts/design_budget_check.py out/ppt/${session}/build/design.json -v > "$BUDGET_LOG" 2>&1
|
|
907
907
|
BUDGET_STATUS=$?
|
|
908
|
-
python3 skills/ui-design/scripts/design_style_check.py
|
|
908
|
+
python3 skills/ui-design/scripts/design_style_check.py out/ppt/${session}/build/design.json -v > "$STYLE_LOG" 2>&1
|
|
909
909
|
STYLE_STATUS=$?
|
|
910
910
|
set -e
|
|
911
911
|
export BUDGET_STATUS STYLE_STATUS
|
|
@@ -914,7 +914,7 @@ steps:
|
|
|
914
914
|
import os
|
|
915
915
|
from pathlib import Path
|
|
916
916
|
|
|
917
|
-
build = Path("
|
|
917
|
+
build = Path("out/ppt/${session}/build")
|
|
918
918
|
budget_status = int(os.environ.get("BUDGET_STATUS", "1"))
|
|
919
919
|
style_status = int(os.environ.get("STYLE_STATUS", "1"))
|
|
920
920
|
budget_log = (build / "design_budget_recheck.txt").read_text(encoding="utf-8", errors="replace")
|
|
@@ -945,7 +945,7 @@ steps:
|
|
|
945
945
|
|
|
946
946
|
- id: stage_design_repair
|
|
947
947
|
title: "阶段10/22·设计文档短修复(fast只写残留·best最多3轮)"
|
|
948
|
-
when: "inputs.quality == 'best' && fileExists('
|
|
948
|
+
when: "inputs.quality == 'best' && fileExists('out/ppt/${session}/build/design_review_recheck.json') && readJson('out/ppt/${session}/build/design_review_recheck.json', 'ok') == false"
|
|
949
949
|
type: loop
|
|
950
950
|
max_iterations: 3
|
|
951
951
|
fresh_context: true
|
|
@@ -955,19 +955,19 @@ steps:
|
|
|
955
955
|
tool: Bash
|
|
956
956
|
args:
|
|
957
957
|
command: |
|
|
958
|
-
python3 skills/ui-design/scripts/design_repair_hints.py --build
|
|
958
|
+
python3 skills/ui-design/scripts/design_repair_hints.py --build out/ppt/${session}/build --max-pages 3
|
|
959
959
|
onError: continue
|
|
960
960
|
- id: design_repair_batch
|
|
961
961
|
title: "阶段10/22·短修复本批页面"
|
|
962
|
-
when: "inputs.quality == 'best' && fileExists('
|
|
962
|
+
when: "inputs.quality == 'best' && fileExists('out/ppt/${session}/build/design_repair_batch.md') && readJson('out/ppt/${session}/build/design_review_recheck.json', 'ok') == false"
|
|
963
963
|
agent: |
|
|
964
964
|
你只做**本批页面短修复**,不要重写全稿。
|
|
965
965
|
|
|
966
966
|
必读:
|
|
967
|
-
-
|
|
968
|
-
-
|
|
969
|
-
-
|
|
970
|
-
- 必要时读
|
|
967
|
+
- `out/ppt/${session}/build/user_request.md`
|
|
968
|
+
- `out/ppt/${session}/build/design_repair_batch.md`
|
|
969
|
+
- `out/ppt/${session}/build/design.json`
|
|
970
|
+
- 必要时读 `out/ppt/${session}/build/material.json`、`out/ppt/${session}/build/source_layout_plan.json`
|
|
971
971
|
|
|
972
972
|
只修 `design_repair_batch.md` 列出的 1–3 页:
|
|
973
973
|
- budget 失败:删减/改写超长标题、超长要点、文字过量页面;不要新增内容填满画布。
|
|
@@ -976,8 +976,8 @@ steps:
|
|
|
976
976
|
- 对图片页,优先修 `one_sentence_takeaway / composition_style / page_grammar / visual_focus / safe_text_zone / visual_role / semantic_image_prompt / copy_budget / forbidden_layout`。
|
|
977
977
|
|
|
978
978
|
修复方式:
|
|
979
|
-
- 直接用 Write 重写
|
|
980
|
-
- 可用 Edit 同步
|
|
979
|
+
- 直接用 Write 重写 `out/ppt/${session}/build/design.json` 为严格 JSON。
|
|
980
|
+
- 可用 Edit 同步 `out/ppt/${session}/build/design.md` 的人读说明。
|
|
981
981
|
- 不写 deck.html、不生图;修完只报告本批修了哪些页。
|
|
982
982
|
allowed_tools: [Read, Edit, Write, Glob]
|
|
983
983
|
maxTurns: 12
|
|
@@ -989,16 +989,16 @@ steps:
|
|
|
989
989
|
args:
|
|
990
990
|
command: |
|
|
991
991
|
set -e
|
|
992
|
-
python3 skills/ui-design/scripts/normalize_design_json.py --build
|
|
993
|
-
test -f
|
|
992
|
+
python3 skills/ui-design/scripts/normalize_design_json.py --build out/ppt/${session}/build
|
|
993
|
+
test -f out/ppt/${session}/build/design_json_ok
|
|
994
994
|
# 只跑一遍:把退出码落 .status(&&/|| 在 set -e 下安全,$? 取的是检查器真实退出码),
|
|
995
995
|
# 内联 Python 读状态即可,不再重跑同一对慢检查器(去「耗时高收益小」双跑)。
|
|
996
|
-
python3 skills/ui-design/scripts/design_budget_check.py
|
|
997
|
-
python3 skills/ui-design/scripts/design_style_check.py
|
|
996
|
+
python3 skills/ui-design/scripts/design_budget_check.py out/ppt/${session}/build/design.json -v > out/ppt/${session}/build/design_budget_recheck.txt 2>&1 && echo 0 > out/ppt/${session}/build/design_budget_recheck.status || echo $? > out/ppt/${session}/build/design_budget_recheck.status
|
|
997
|
+
python3 skills/ui-design/scripts/design_style_check.py out/ppt/${session}/build/design.json -v > out/ppt/${session}/build/design_style_recheck.txt 2>&1 && echo 0 > out/ppt/${session}/build/design_style_recheck.status || echo $? > out/ppt/${session}/build/design_style_recheck.status
|
|
998
998
|
python3 - <<'PY'
|
|
999
999
|
import json
|
|
1000
1000
|
from pathlib import Path
|
|
1001
|
-
build = Path("
|
|
1001
|
+
build = Path("out/ppt/${session}/build")
|
|
1002
1002
|
def _status(name):
|
|
1003
1003
|
try:
|
|
1004
1004
|
return int((build / (name + ".status")).read_text(encoding="utf-8").strip())
|
|
@@ -1033,13 +1033,13 @@ steps:
|
|
|
1033
1033
|
print("DESIGN_REPAIR_RECHECK_OK" if ok else "DESIGN_REPAIR_RECHECK_ISSUES")
|
|
1034
1034
|
PY
|
|
1035
1035
|
if [ "${inputs.quality}" != "best" ]; then
|
|
1036
|
-
cp
|
|
1037
|
-
touch
|
|
1036
|
+
cp out/ppt/${session}/build/design_review_recheck.md out/ppt/${session}/build/design_repair_residual.md 2>/dev/null || true
|
|
1037
|
+
touch out/ppt/${session}/build/design_repair_done
|
|
1038
1038
|
fi
|
|
1039
1039
|
onError: continue
|
|
1040
1040
|
- id: design_repair_done
|
|
1041
1041
|
type: break
|
|
1042
|
-
when: "fileExists('
|
|
1042
|
+
when: "fileExists('out/ppt/${session}/build/design_repair_done')"
|
|
1043
1043
|
|
|
1044
1044
|
# ---------- 阶段6:图生图兜底注入 + 配图分流闸门(结构图必须 HTML,不准当 AI 图生) ----------
|
|
1045
1045
|
# ① 确定性兜底注入:plan_source_layout.py --ensure-img-plan 把「必须图生图增强」的客户图条目 union 进
|
|
@@ -1053,22 +1053,22 @@ steps:
|
|
|
1053
1053
|
# when 放宽:img_plan 存在【或】规划里有待增强客户图(length null 安全)→ 即使设计步漏写 img_plan,兜底注入也能创建它。
|
|
1054
1054
|
- id: stage_img_route_gate
|
|
1055
1055
|
title: "阶段11/22·图生图兜底注入 + 配图分流闸门"
|
|
1056
|
-
when: "fileExists('
|
|
1056
|
+
when: "fileExists('out/ppt/${session}/build/design_json_ok') && (fileExists('out/ppt/${session}/build/img_plan.json') || length(readJson('out/ppt/${session}/build/source_layout_plan.json', 'enhance_entries')) > 0)"
|
|
1057
1057
|
tool: Bash
|
|
1058
1058
|
args:
|
|
1059
1059
|
command: |
|
|
1060
1060
|
set -e
|
|
1061
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-img-plan --build
|
|
1062
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-extensions --build
|
|
1063
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-ai-img-plan --build
|
|
1064
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-page-backgrounds --build
|
|
1065
|
-
python3 skills/ui-design/scripts/image_prompt_rewrite.py --build
|
|
1066
|
-
python3 skills/ui-design/scripts/image_plan_lint.py
|
|
1061
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-img-plan --build out/ppt/${session}/build
|
|
1062
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-extensions --build out/ppt/${session}/build --design out/ppt/${session}/build/design.json
|
|
1063
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-ai-img-plan --build out/ppt/${session}/build --design out/ppt/${session}/build/design.json
|
|
1064
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --ensure-page-backgrounds --build out/ppt/${session}/build --design out/ppt/${session}/build/design.json
|
|
1065
|
+
python3 skills/ui-design/scripts/image_prompt_rewrite.py --build out/ppt/${session}/build
|
|
1066
|
+
python3 skills/ui-design/scripts/image_plan_lint.py out/ppt/${session}/build/img_plan.json -v
|
|
1067
1067
|
# 章节错位预警(张冠李戴,WARNING 级恒 exit 0):生图**之前**就核对客户图是否配在
|
|
1068
1068
|
# 其来源章节对应页(词元交集,见 source_usage_check.section_mismatch_warnings),
|
|
1069
1069
|
# 错位在此最便宜(design 层可改,还没花生图/建页成本)。|| true 双保险,绝不 halt。
|
|
1070
|
-
python3 skills/ui-design/scripts/source_usage_check.py --build
|
|
1071
|
-
touch
|
|
1070
|
+
python3 skills/ui-design/scripts/source_usage_check.py --build out/ppt/${session}/build --design-only || true
|
|
1071
|
+
touch out/ppt/${session}/build/img_route_ok
|
|
1072
1072
|
echo "IMG_ROUTE_GATE_OK"
|
|
1073
1073
|
onError: halt
|
|
1074
1074
|
max_retries: 0
|
|
@@ -1081,11 +1081,11 @@ steps:
|
|
|
1081
1081
|
# 内建优雅退化(单图失败→图生图退原图/文生图退渐变占位,恒不阻断),仅凭 Ctrl+C 中断。
|
|
1082
1082
|
- id: stage_gen_images
|
|
1083
1083
|
title: "阶段12/22·生成插图(按比例)"
|
|
1084
|
-
when: "fileExists('
|
|
1084
|
+
when: "fileExists('out/ppt/${session}/build/img_plan.json')"
|
|
1085
1085
|
tool: GenerateImage
|
|
1086
1086
|
args:
|
|
1087
|
-
plan:
|
|
1088
|
-
assets:
|
|
1087
|
+
plan: out/ppt/${session}/build/img_plan.json
|
|
1088
|
+
assets: out/ppt/${session}/build/assets
|
|
1089
1089
|
size: 2k
|
|
1090
1090
|
timeout_ms: 300000
|
|
1091
1091
|
wall_budget_ms: 3600000
|
|
@@ -1098,15 +1098,15 @@ steps:
|
|
|
1098
1098
|
# ---------- 阶段7b:生图质量门(fast 只补一轮降级图;best 的深度复核在后续语义复核阶段) ----------
|
|
1099
1099
|
- id: stage_image_quality_gate
|
|
1100
1100
|
title: "阶段13/22·AI 配图质量门(fast一轮补降级图)"
|
|
1101
|
-
when: "fileExists('
|
|
1101
|
+
when: "fileExists('out/ppt/${session}/build/image_generation_report.json')"
|
|
1102
1102
|
tool: GenerateImage
|
|
1103
1103
|
args:
|
|
1104
|
-
plan:
|
|
1105
|
-
assets:
|
|
1104
|
+
plan: out/ppt/${session}/build/img_plan.json
|
|
1105
|
+
assets: out/ppt/${session}/build/assets
|
|
1106
1106
|
size: 2k
|
|
1107
1107
|
timeout_ms: 300000
|
|
1108
1108
|
wall_budget_ms: 3600000
|
|
1109
|
-
retry_degraded_report:
|
|
1109
|
+
retry_degraded_report: out/ppt/${session}/build/image_generation_report.json
|
|
1110
1110
|
max_rounds: 1
|
|
1111
1111
|
concurrency: 2
|
|
1112
1112
|
onError: continue
|
|
@@ -1119,22 +1119,22 @@ steps:
|
|
|
1119
1119
|
# 恢复 = 三步 when 还原为原条件(记录于各步注释)+ gate 加回 `or not generated_review_ok`。
|
|
1120
1120
|
- id: stage_generated_image_review
|
|
1121
1121
|
title: "阶段14/22·生成图语义复核(已屏蔽)"
|
|
1122
|
-
# 原条件:"inputs.quality == 'best' && fileExists('
|
|
1122
|
+
# 原条件:"inputs.quality == 'best' && fileExists('out/ppt/${session}/build/img_plan.json')"
|
|
1123
1123
|
when: "false"
|
|
1124
1124
|
type: loop
|
|
1125
|
-
over: "${asArray(readJson('
|
|
1125
|
+
over: "${asArray(readJson('out/ppt/${session}/build/img_plan.json'))}"
|
|
1126
1126
|
as: gen_img
|
|
1127
1127
|
do:
|
|
1128
1128
|
- id: review_generated_image
|
|
1129
1129
|
title: "阶段14/22·复核生成图 #${gen_img.file}"
|
|
1130
|
-
when: "fileExists('
|
|
1130
|
+
when: "fileExists('out/ppt/${session}/build/assets/' + gen_img.file)"
|
|
1131
1131
|
history_mode: isolated
|
|
1132
1132
|
llm: |
|
|
1133
1133
|
你是 PPT 产品详情页配图验收员。请只看下方这一张生成图,并结合本轮 PPT 的目标判断它是否适合继续使用。
|
|
1134
1134
|
|
|
1135
1135
|
必读上下文:
|
|
1136
|
-
-
|
|
1137
|
-
- PPT
|
|
1136
|
+
- 用户目标和原始要求:`out/ppt/${session}/build/user_request.md`
|
|
1137
|
+
- PPT 设计文档:`out/ppt/${session}/build/design.json`
|
|
1138
1138
|
- 图片计划条目:`${json(gen_img)}`
|
|
1139
1139
|
|
|
1140
1140
|
只输出 JSON 对象,不要 markdown:
|
|
@@ -1155,15 +1155,15 @@ steps:
|
|
|
1155
1155
|
- 不符合当前 VI 的色彩、材质、光线和产品详情页气质。
|
|
1156
1156
|
- 图像花哨、拼贴、像 UI 卡片/缩略图阵列,不能作为 Apple/DJI 式产品详情页主视觉。
|
|
1157
1157
|
context_files:
|
|
1158
|
-
- path: "
|
|
1158
|
+
- path: "out/ppt/${session}/build/user_request.md"
|
|
1159
1159
|
hint: "用户原始目标与最高优先级要求"
|
|
1160
|
-
- path: "
|
|
1160
|
+
- path: "out/ppt/${session}/build/design.json"
|
|
1161
1161
|
hint: "每页文案、视觉焦点与配图意图"
|
|
1162
|
-
- path: "
|
|
1162
|
+
- path: "out/ppt/${session}/build/img_plan.json"
|
|
1163
1163
|
hint: "当前生成图计划与提示词"
|
|
1164
1164
|
allowed_tools: [Read]
|
|
1165
1165
|
images:
|
|
1166
|
-
- source: "
|
|
1166
|
+
- source: "out/ppt/${session}/build/assets/${gen_img.file}"
|
|
1167
1167
|
detail: high
|
|
1168
1168
|
max_long_side_pixel: 1600
|
|
1169
1169
|
capture:
|
|
@@ -1175,34 +1175,34 @@ steps:
|
|
|
1175
1175
|
when: "length(generated_image_review_text) > 0"
|
|
1176
1176
|
tool: Write
|
|
1177
1177
|
args:
|
|
1178
|
-
file_path: "
|
|
1178
|
+
file_path: "out/ppt/${session}/build/generated-image-reviews/${gen_img.file}.json"
|
|
1179
1179
|
content: "${generated_image_review_text}"
|
|
1180
1180
|
onError: continue
|
|
1181
1181
|
|
|
1182
1182
|
- id: stage_generated_image_review_collect
|
|
1183
1183
|
title: "阶段15/22·汇总生成图语义复核(已屏蔽)"
|
|
1184
|
-
# 原条件:"inputs.quality == 'best' && fileExists('
|
|
1184
|
+
# 原条件:"inputs.quality == 'best' && fileExists('out/ppt/${session}/build/img_plan.json')"(屏蔽见阶段7c 头注)
|
|
1185
1185
|
when: "false"
|
|
1186
1186
|
tool: Bash
|
|
1187
1187
|
args:
|
|
1188
1188
|
command: |
|
|
1189
1189
|
set -e
|
|
1190
|
-
python3 skills/ui-design/scripts/generated_image_review_collect.py --build
|
|
1190
|
+
python3 skills/ui-design/scripts/generated_image_review_collect.py --build out/ppt/${session}/build
|
|
1191
1191
|
onError: continue
|
|
1192
1192
|
max_retries: 1
|
|
1193
1193
|
|
|
1194
1194
|
- id: stage_generated_image_retry
|
|
1195
1195
|
title: "阶段16/22·生成图语义失败重试(已屏蔽)"
|
|
1196
|
-
# 原条件:"inputs.quality == 'best' && fileExists('
|
|
1196
|
+
# 原条件:"inputs.quality == 'best' && fileExists('out/ppt/${session}/build/generated_image_semantic_retry_report.json')"(屏蔽见阶段7c 头注)
|
|
1197
1197
|
when: "false"
|
|
1198
1198
|
tool: GenerateImage
|
|
1199
1199
|
args:
|
|
1200
|
-
plan:
|
|
1201
|
-
assets:
|
|
1200
|
+
plan: out/ppt/${session}/build/img_plan.json
|
|
1201
|
+
assets: out/ppt/${session}/build/assets
|
|
1202
1202
|
size: 2k
|
|
1203
1203
|
timeout_ms: 300000
|
|
1204
1204
|
wall_budget_ms: 3600000
|
|
1205
|
-
retry_degraded_report:
|
|
1205
|
+
retry_degraded_report: out/ppt/${session}/build/generated_image_semantic_retry_report.json
|
|
1206
1206
|
max_rounds: 3
|
|
1207
1207
|
onError: continue
|
|
1208
1208
|
max_retries: 1
|
|
@@ -1213,7 +1213,7 @@ steps:
|
|
|
1213
1213
|
# (design.json/deck.html 在磁盘,每轮 Read 即可,不靠 history 记忆);loop 级断点支持中断续跑。
|
|
1214
1214
|
- id: stage_build_loop
|
|
1215
1215
|
title: "阶段17/22·分批生成网页(fast每轮≤5页·页数+客户图双闸门收口)"
|
|
1216
|
-
when: "fileExists('
|
|
1216
|
+
when: "fileExists('out/ppt/${session}/build/design_json_ok')"
|
|
1217
1217
|
type: loop
|
|
1218
1218
|
max_iterations: 6
|
|
1219
1219
|
fresh_context: true
|
|
@@ -1237,8 +1237,8 @@ steps:
|
|
|
1237
1237
|
proc = subprocess.run(cmd, cwd=str(root), text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
1238
1238
|
return proc.returncode, proc.stdout.strip()
|
|
1239
1239
|
|
|
1240
|
-
pages_status, pages_log = run(["python3", "skills/ui-design/scripts/deck_pages_check.py", "
|
|
1241
|
-
source_status, source_log = run(["python3", "skills/ui-design/scripts/source_usage_check.py", "--build", "
|
|
1240
|
+
pages_status, pages_log = run(["python3", "skills/ui-design/scripts/deck_pages_check.py", "out/ppt/${session}/build"])
|
|
1241
|
+
source_status, source_log = run(["python3", "skills/ui-design/scripts/source_usage_check.py", "--build", "out/ppt/${session}/build"])
|
|
1242
1242
|
pages_complete = pages_status == 0 and "COMPLETE" in pages_log
|
|
1243
1243
|
source_ok = source_status == 0 and "SOURCE_USAGE_OK" in source_log
|
|
1244
1244
|
report = {
|
|
@@ -1268,19 +1268,19 @@ steps:
|
|
|
1268
1268
|
onError: halt
|
|
1269
1269
|
- id: build_batch
|
|
1270
1270
|
title: "阶段17/22·生成下一批页面"
|
|
1271
|
-
when: "!fileExists('
|
|
1271
|
+
when: "!fileExists('out/ppt/${session}/build/build_complete')"
|
|
1272
1272
|
agent: |
|
|
1273
|
-
按设计文档**分批**生成 1920x1080 的 HTML deck(单文件
|
|
1274
|
-
**本轮只做
|
|
1273
|
+
按设计文档**分批**生成 1920x1080 的 HTML deck(单文件 `out/ppt/${session}/build/deck.html`、自包含 CSS)。
|
|
1274
|
+
**本轮只做 `out/ppt/${session}/build/build_probe.txt` 指出的缺页或未用客户图(默认 fast 最多 5 页),做完即止**——大 deck 一次写完会撞轮数上限、半途烂尾,分批是为了稳。
|
|
1275
1275
|
|
|
1276
1276
|
动手前从系统提示「可用技能」里 ui-design 的【技能目录】Read `references/layout-composition.md`
|
|
1277
1277
|
(grid 结构化构图 + 三层语义化 HTML + 构图均衡),严格照其执行。
|
|
1278
1278
|
|
|
1279
1279
|
## 本轮步骤
|
|
1280
|
-
1. **先 Read
|
|
1280
|
+
1. **先 Read `out/ppt/${session}/build/build_probe.txt`**。这个文件由上一小步确定性生成;不要自己重新判断完成状态。
|
|
1281
1281
|
- 若显示页数 MISSING:按下面生成缺页。
|
|
1282
1282
|
- 若显示 SOURCE_USAGE_UNUSED:把**未用的客户图补进最相关的页**(route=source 直接用,或 route=source-enhanced 增强后用,见下)。
|
|
1283
|
-
- 🚫 **客户图引用契约(2026-07-02 坠机原图上墙事故)**:Read
|
|
1283
|
+
- 🚫 **客户图引用契约(2026-07-02 坠机原图上墙事故)**:Read `out/ppt/${session}/build/source_layout_plan.json`——
|
|
1284
1284
|
规划标 `enhance_required:true` 或 `has_embedded_text:true` 的图**只准引用 `enhanced_src_N`,绝不引用原图 `src_N`**(原图带字幕/水印,字会烧死在页面里);
|
|
1285
1285
|
`usage_intent:"discard"` 的图**任何页都不准用**;`usage_intent:"direct_contain"`/`content_type:screenshot_slide` 的图只准 contain 框图展示、**绝不铺整页背景、绝不在其上叠正文**
|
|
1286
1286
|
(视觉门有确定性【版式违规】ERROR 核对——contain/gallery/small_evidence 图出现在 `.bg-img`/CSS 背景必被打回,2026-07-03 第4页影子标题真机事故,写对省一轮);
|
|
@@ -1289,8 +1289,8 @@ steps:
|
|
|
1289
1289
|
(背景驾驶舱+前景 3 张驾驶舱特写=重复堆料)——前景改放数据/图形/结论或留白,一页一主视觉。
|
|
1290
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
1291
|
- 若两者都 OK,说明 build_probe 会直接 break,本 step 不应运行。
|
|
1292
|
-
2. **若 MISSING**:Read
|
|
1293
|
-
Read
|
|
1292
|
+
2. **若 MISSING**:Read `out/ppt/${session}/build/design.json` 拿到**缺页**(build_probe 列出的页号)的设计(archetype/composition/blocks.render/key_point/points/visual/background);
|
|
1293
|
+
Read `out/ppt/${session}/build/deck.html`(若已存在)了解已有结构与**全局 CSS / VI 视觉系统**(保持一致)。
|
|
1294
1294
|
3. **生成缺页里的下一批(默认 fast 最多 5 页)**,每页一个 `<section class="slide" data-screen-label="NN ...">`(NN=该页 page 号两位数、含中文标题),
|
|
1295
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
1296
|
然后按这些字段实现;不要只看 `archetype/composition` 自由发挥。
|
|
@@ -1371,7 +1371,7 @@ steps:
|
|
|
1371
1371
|
- **排不下时的自救顺序(绝不缩字到 <24px、绝不顶出画布)**:① **精炼文案 + 图文并茂**(流程/对比/层级/数据用 HTML 图表/SVG/图标/卡片表达,一图省一段话)→ ② 一列条目多就改 **grid 两列**(`grid-template-columns:1fr 1fr`)→ ③ 仍排不下就**拆成两页**(新增一个 `<section class="slide">`、同一主题分上下篇,别死磕一页)。导出端【超出画布】【字号过小】WARNING 触发时按此序处理。
|
|
1372
1372
|
- **配色解耦(治一片单色)**:只有背景/页面底板/chrome 用 VI;**图表数据系列用可区分分类色**(见所选 VI 文档「数据可视化分类色」)、非背景插图用画面真实色、辅助解释图形用语义色,都与 VI 协调不冲突(见 §0.9)。
|
|
1373
1373
|
- **背景按 design 的 background 意图**做同色系深浅/光位变化,相邻页不雷同。
|
|
1374
|
-
- **客户图(现已【全部 route=source-enhanced 图生图重绘到槽位比例】)= 必须全用 + 填满槽(`.fig-fill` cover)+ 按朝向/重点区图文混排 + 配色随图**(首轮动手前 Read ui-design 技能目录的 `references/source-image-layout.md`,并 Read
|
|
1374
|
+
- **客户图(现已【全部 route=source-enhanced 图生图重绘到槽位比例】)= 必须全用 + 填满槽(`.fig-fill` cover)+ 按朝向/重点区图文混排 + 配色随图**(首轮动手前 Read ui-design 技能目录的 `references/source-image-layout.md`,并 Read `out/ppt/${session}/build/material.json` 取每图的 vision/stats):
|
|
1375
1375
|
**plan_source_layout 已把所有客户图 `enhance_required=true`**(唯一例外=无 vision 盲态)——用 `<img src="assets/<enhanced_file>">` 并在 `data-source-file="<source_file>"` 保留原图映射(用尽闸门/追溯用)。
|
|
1376
1376
|
若 `enhanced_file` 生成失败,回退 `<img src="assets/<source_file>">` 的合适布局,不能删除该客户图、不能空占位(缺图兜底脚本会自动 cp 原图顶上,见 stage_export `--reconcile-missing`)。
|
|
1377
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)。
|
|
@@ -1435,7 +1435,7 @@ steps:
|
|
|
1435
1435
|
- **封面/章节文字对比度铁律(治浅底图白字看不清)**:氛围底图亮暗不可控(浅色模板 AI 底图常偏亮),**别默认白字靠弱 scrim**。浅色模板首选 **① 深字(`var(--ink)`) + 浅色磨砂文字板**(`background:rgba(255,255,255,.55);backdrop-filter:blur(6px)`);要白字则 **② scrim/板压到足够暗(不透明度 ≥ .72)**(见 §1.B 两套 CSS)。
|
|
1436
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
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. **写入
|
|
1438
|
+
4. **写入 `out/ppt/${session}/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
1439
|
后续轮 → 用 Edit 把本批 `<section>` 追加进 `</body>` 前(保持单文件自包含、CSS 不重复定义)。
|
|
1440
1440
|
5. **deck 卫生**:不要加 Tweaks/localStorage/postMessage/fitStage/翻页 nav/React/Babel(对导出无用、只干扰)。
|
|
1441
1441
|
6. 做完本批后不要自判完成,也不要强行输出完成标记。下一轮 `build_probe` 会重新跑页数和客户图闸门,OK 时自动 `build_complete` 并 break。
|
|
@@ -1447,12 +1447,12 @@ steps:
|
|
|
1447
1447
|
max_retries: 1
|
|
1448
1448
|
- id: build_done
|
|
1449
1449
|
type: break
|
|
1450
|
-
when: "fileExists('
|
|
1450
|
+
when: "fileExists('out/ppt/${session}/build/build_complete')"
|
|
1451
1451
|
|
|
1452
1452
|
# ---------- 阶段14b:产品详情页视觉硬门(确定性,不再交给 agent 自觉执行) ----------
|
|
1453
1453
|
- id: stage_visual_quality_gate
|
|
1454
1454
|
title: "阶段18/22·产品详情页视觉硬门(最多两轮修复)"
|
|
1455
|
-
when: "fileExists('
|
|
1455
|
+
when: "fileExists('out/ppt/${session}/build/deck.html')"
|
|
1456
1456
|
type: loop
|
|
1457
1457
|
# 轮数 3→2(2026-07-02 用户裁决);修复步同步开放给 fast——上一轮 fast 跑出 41 个 ERROR
|
|
1458
1458
|
# 却因 when 限死 best 而 0 次修复带残留放行,是缺陷出货的直接原因。
|
|
@@ -1470,32 +1470,32 @@ steps:
|
|
|
1470
1470
|
# 不会误读上一轮(修复前)的陈旧 report → 不误判。
|
|
1471
1471
|
# --with-bg-shots:顺带落背景态截图(slide-NN-background.png),像素级文字可读性门
|
|
1472
1472
|
# (text_readability_pixel.py)按文本矩形采真实像素——CSS 对比度在压图文字上物理测不准。
|
|
1473
|
-
mkdir -p
|
|
1474
|
-
rm -f
|
|
1475
|
-
node skills/ui-design/scripts/export_pptx_from_html.mjs
|
|
1476
|
-
--measure-only --with-bg-shots --mode hybrid --width 1920 --height 1080 --workdir
|
|
1473
|
+
mkdir -p out/ppt/${session}/build/export
|
|
1474
|
+
rm -f out/ppt/${session}/build/export/layout-report.json
|
|
1475
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs out/ppt/${session}/build/deck.html \
|
|
1476
|
+
--measure-only --with-bg-shots --mode hybrid --width 1920 --height 1080 --workdir out/ppt/${session}/build/export
|
|
1477
1477
|
onError: continue
|
|
1478
1478
|
- id: visual_quality_check
|
|
1479
1479
|
title: "阶段18/22·视觉质量检查"
|
|
1480
1480
|
tool: Bash
|
|
1481
1481
|
args:
|
|
1482
1482
|
command: |
|
|
1483
|
-
python3 skills/ui-design/scripts/visual_quality_gate.py --build
|
|
1483
|
+
python3 skills/ui-design/scripts/visual_quality_gate.py --build out/ppt/${session}/build --max-rounds 2 --strict-product-detail
|
|
1484
1484
|
onError: halt
|
|
1485
1485
|
max_retries: 0 # 确定性检查步:重试=原样重跑纯空转(exit 1 仅剩 hard 档=真缺陷,halt 正确)
|
|
1486
1486
|
- id: visual_quality_done
|
|
1487
1487
|
type: break
|
|
1488
|
-
when: "fileExists('
|
|
1488
|
+
when: "fileExists('out/ppt/${session}/build/visual_quality_ok')"
|
|
1489
1489
|
- id: visual_repair_batch
|
|
1490
1490
|
title: "阶段18/22·修复前几个视觉问题"
|
|
1491
|
-
when: "fileExists('
|
|
1491
|
+
when: "fileExists('out/ppt/${session}/build/visual_quality_report.md') && !fileExists('out/ppt/${session}/build/visual_quality_ok')"
|
|
1492
1492
|
agent: |
|
|
1493
|
-
只修
|
|
1493
|
+
只修 `out/ppt/${session}/build/visual_quality_report.md` 里最高优先级的前 3–5 个问题,不要重写整份 deck。
|
|
1494
1494
|
|
|
1495
1495
|
必读:
|
|
1496
|
-
-
|
|
1497
|
-
-
|
|
1498
|
-
-
|
|
1496
|
+
- `out/ppt/${session}/build/visual_quality_report.md`
|
|
1497
|
+
- `out/ppt/${session}/build/design.json`
|
|
1498
|
+
- `out/ppt/${session}/build/deck.html`
|
|
1499
1499
|
|
|
1500
1500
|
🚨 **先看报告里有没有"⚠️ N 处文字压图问题共享同一文字颜色 rgb(...)"这行归组提示(2026-07-03 真机
|
|
1501
1501
|
复盘:27 处 ERROR 里 15+ 处共享同一个 VI 强调色 CSS 变量,逐条加局部 scrim 在 2 轮修复预算内根本
|
|
@@ -1537,8 +1537,8 @@ steps:
|
|
|
1537
1537
|
- data-visual 缺 SVG/chart/axis/bar/line:补可编辑 HTML/SVG 图形,别用大表格。
|
|
1538
1538
|
- 【AI 背景图被 scrim 盖到不可辨识】(2026-07-05 复盘:list/metric 数据结构页 `image_weight≈0` 却套了 0.82~0.90 近纯白整页 scrim,生成的低干扰材质背景在截图上完全看不出痕迹,等于图片形同虚设):把该页 `.edit-scrim` 的整页不透明度降到 ≤0.6,让底图纹理隐约可辨;若因此文字/图例对比度不够,改成只在文字/图例紧贴区域加局部深色小背板,不要靠拉高整页不透明度解决。
|
|
1539
1539
|
- 低对比/小字/孤立连线:统一字体 token、节点和连线归属。
|
|
1540
|
-
- **内容飞出画布/整页不可见**(几何 catastrophic,见
|
|
1541
|
-
- 修完本批(3–5 个)后重跑 `python3 skills/ui-design/scripts/deck_visual_style_check.py
|
|
1540
|
+
- **内容飞出画布/整页不可见**(几何 catastrophic,见 `out/ppt/${session}/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 out/ppt/${session}/build/deck.html --design out/ppt/${session}/build/design.json --image-report out/ppt/${session}/build/image_generation_report.json --source-plan out/ppt/${session}/build/source_layout_plan.json --strict-product-detail`,确认**本批问题已消**;本批消掉即收尾(不能只写 residual 糊弄),**剩余/新暴露的问题留给外层循环下一轮重新测量再修**——别在本步内追着全量 ERROR 无界修下去(那会撞 maxTurns 被截断)。
|
|
1542
1542
|
|
|
1543
1543
|
不要碰已正常的页面。完成后简述修改页号。
|
|
1544
1544
|
allowed_tools: [Read, Edit, Write, Glob]
|
|
@@ -1561,10 +1561,10 @@ steps:
|
|
|
1561
1561
|
set -euo pipefail
|
|
1562
1562
|
OUT="${inputs.out}"
|
|
1563
1563
|
MODE="${inputs.mode}"
|
|
1564
|
-
mkdir -p "$(dirname "$OUT")"
|
|
1564
|
+
mkdir -p "$(dirname "$OUT")" out/ppt/${session}/build/export
|
|
1565
1565
|
|
|
1566
1566
|
echo "[export] deck pages check (完整度硬门 + 页序报告)"
|
|
1567
|
-
python3 skills/ui-design/scripts/deck_pages_check.py
|
|
1567
|
+
python3 skills/ui-design/scripts/deck_pages_check.py out/ppt/${session}/build --check-order || {
|
|
1568
1568
|
rc=$?
|
|
1569
1569
|
# 完整度缺页(exit 1/2) → 硬门 halt;仅页序错乱(exit 3) → 非阻断报告
|
|
1570
1570
|
# (批量生成天然乱序,别为顺序反复 halt 烧配额;ORDER_MISMATCH 已在上面日志留痕,建议按编号重排 <section>)。
|
|
@@ -1572,43 +1572,43 @@ steps:
|
|
|
1572
1572
|
}
|
|
1573
1573
|
|
|
1574
1574
|
echo "[export] ui artifact check"
|
|
1575
|
-
python3 skills/ui-design/scripts/check_ui_artifact.py --for-pptx-export
|
|
1575
|
+
python3 skills/ui-design/scripts/check_ui_artifact.py --for-pptx-export out/ppt/${session}/build/deck.html
|
|
1576
1576
|
|
|
1577
1577
|
echo "[export] reconcile missing enhanced/source assets"
|
|
1578
|
-
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-missing --build
|
|
1578
|
+
python3 skills/ui-design/scripts/plan_source_layout.py --reconcile-missing --build out/ppt/${session}/build
|
|
1579
1579
|
|
|
1580
1580
|
echo "[export] source usage hard gate"
|
|
1581
|
-
python3 skills/ui-design/scripts/source_usage_check.py --build
|
|
1581
|
+
python3 skills/ui-design/scripts/source_usage_check.py --build out/ppt/${session}/build --require-existing-derived
|
|
1582
1582
|
|
|
1583
1583
|
# deck_visual_style_check 不在此重跑(减法:与阶段18 视觉门完全同参双跑)——
|
|
1584
1584
|
# 它已在 stage_visual_quality_gate 有界循环里跑过(fast/best 统一 2 轮修复,2026-07-02 裁决),
|
|
1585
1585
|
# 达轮数带残留放行(visual_quality_ok + visual_quality_residual.md)。此处只验哨兵。
|
|
1586
1586
|
echo "[export] visual quality gate must already be accepted"
|
|
1587
|
-
test -f
|
|
1587
|
+
test -f out/ppt/${session}/build/visual_quality_ok
|
|
1588
1588
|
|
|
1589
1589
|
echo "[export] measure-only layout report"
|
|
1590
|
-
node skills/ui-design/scripts/export_pptx_from_html.mjs
|
|
1591
|
-
--measure-only --mode hybrid --width 1920 --height 1080 --workdir
|
|
1590
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs out/ppt/${session}/build/deck.html \
|
|
1591
|
+
--measure-only --mode hybrid --width 1920 --height 1080 --workdir out/ppt/${session}/build/export
|
|
1592
1592
|
|
|
1593
1593
|
echo "[export] layout balance report"
|
|
1594
|
-
python3 skills/ui-design/scripts/layout_balance.py
|
|
1595
|
-
--source-layout-plan
|
|
1596
|
-
touch
|
|
1594
|
+
python3 skills/ui-design/scripts/layout_balance.py out/ppt/${session}/build/export/layout-report.json --no-occupancy -v \
|
|
1595
|
+
--source-layout-plan out/ppt/${session}/build/source_layout_plan.json || true
|
|
1596
|
+
touch out/ppt/${session}/build/layout_ok
|
|
1597
1597
|
|
|
1598
1598
|
echo "[export] geometry catastrophic hard gate(内容不可见零容忍:严重飞出画布 / 无真实视觉空页 → 拒绝导出)"
|
|
1599
1599
|
# 只拦「内容根本看不到」的灾难(可见<20% 越界 + content_boxes==0 且无真实视觉),
|
|
1600
1600
|
# 不含重叠/占空族噪声 → 干净 deck 不误伤、不重烧配额。治本在 layout-composition §0.7 的 min-width:0 骨架;此为兜底网。
|
|
1601
|
-
python3 skills/ui-design/scripts/layout_balance.py
|
|
1601
|
+
python3 skills/ui-design/scripts/layout_balance.py out/ppt/${session}/build/export/layout-report.json --catastrophic-only
|
|
1602
1602
|
|
|
1603
1603
|
echo "[export] write pptx"
|
|
1604
|
-
node skills/ui-design/scripts/export_pptx_from_html.mjs
|
|
1605
|
-
--out "$OUT" --mode "$MODE" --width 1920 --height 1080 --workdir
|
|
1604
|
+
node skills/ui-design/scripts/export_pptx_from_html.mjs out/ppt/${session}/build/deck.html \
|
|
1605
|
+
--out "$OUT" --mode "$MODE" --width 1920 --height 1080 --workdir out/ppt/${session}/build/export
|
|
1606
1606
|
|
|
1607
1607
|
echo "[export] opc check"
|
|
1608
1608
|
python3 skills/pptx/scripts/opc_check.py "$OUT"
|
|
1609
1609
|
rm -f "$OUT.tmp" "$OUT.fixed.pptx" 2>/dev/null || true
|
|
1610
1610
|
|
|
1611
|
-
cat >
|
|
1611
|
+
cat > out/ppt/${session}/build/export-summary.md <<EOF
|
|
1612
1612
|
输出路径: $OUT
|
|
1613
1613
|
导出模式: $MODE
|
|
1614
1614
|
可编辑性: hybrid=背景不可编辑,文本和部分前景对象可编辑;flat=整页图片不可编辑
|
|
@@ -1635,10 +1635,10 @@ steps:
|
|
|
1635
1635
|
command: |
|
|
1636
1636
|
set -euo pipefail
|
|
1637
1637
|
if [ "${inputs.debug_keep_build}" = "false" ]; then
|
|
1638
|
-
rm -rf
|
|
1639
|
-
echo "[cleanup] debug_keep_build=false,已清理
|
|
1638
|
+
rm -rf out/ppt/${session}/build
|
|
1639
|
+
echo "[cleanup] debug_keep_build=false,已清理 out/ppt/${session}/build,仅保留最终 PPT:${inputs.out}"
|
|
1640
1640
|
else
|
|
1641
|
-
echo "[cleanup] debug_keep_build=true,保留
|
|
1641
|
+
echo "[cleanup] debug_keep_build=true,保留 out/ppt/${session}/build 中间产物用于排障:deck.html / design.json / export 报告 / 截图。"
|
|
1642
1642
|
fi
|
|
1643
1643
|
onError: continue
|
|
1644
1644
|
|
|
@@ -1665,6 +1665,6 @@ steps:
|
|
|
1665
1665
|
- 流程:摄取素材(抽文字+图片+图像统计)→ 逐图多模态识图 → 合并「用户原始材料」统一文件(material.md/json)→ 客户材料成稿(默认不联网)→ 详细 Web 页面设计文档(客户图按识图内容高权重配页,全部图生图重绘到高清并贴 PPT 风格)→ 配图分流 → 文生图/图生图 → 分批生成网页(页数+客户图用尽双闸门)→ 产品详情页视觉硬门 → 三层导出。
|
|
1666
1666
|
- 可编辑性:hybrid 三层=背景整页截图垫底(不可编辑),前景每个离散元素(卡片/色块/图标/SVG/插图)为独立可编辑图片对象,
|
|
1667
1667
|
文本为 PPT 原生可编辑文本框;全幅氛围背景图(B 路线)连同遮罩留背景层;flat=全图不可编辑。
|
|
1668
|
-
- 中间产物处理:由 debug_keep_build=${inputs.debug_keep_build} 控制;默认保留
|
|
1668
|
+
- 中间产物处理:由 debug_keep_build=${inputs.debug_keep_build} 控制;默认保留 out/ppt/${session}/build 用于检查 deck.html、design.json、截图和报告,设为 false 时只保留最终 PPT。
|
|
1669
1669
|
|
|
1670
1670
|
用 PowerPoint / WPS 打开 [${inputs.out}](${inputs.out}) 核验。
|