{"id":"e36d47df-642e-4cfe-bd54-db444212e5c9","shortId":"XK8Fab","kind":"skill","title":"sn-ppt-standard","tagline":"Standard-mode PPT pipeline. All LLM / VLM / T2I calls are wrapped in a\nsingle CLI entry (scripts/run_stage.py). The main agent's job is simple:\nemit ONE shell command per stage, never write loops, never write prompts.","description":"# sn-ppt-standard\n\nThis skill is **self-contained** — no dependency on `sn-image-base` for LLM/VLM (T2I still goes through `sn-image-base`). Every call through `$SKILL_DIR/scripts/run_stage.py`. Every subcommand is deterministic: one input set → one output artifact → one-line JSON status.\n\n## Preconditions\n\n- `<deck_dir>/task_pack.json` exists and `ppt_mode == \"standard\"`\n- `<deck_dir>/info_pack.json` exists\n\nAny missing → stop and tell user to enter via `/skill sn-ppt-entry`.\n\n## 🚫 Hard rules (the main agent MUST NOT)\n\n1. **Do NOT write Python scripts that loop over pages or slots** in a single exec. Use the batch subcommands, or per-item execs in the agent's own loop of tool_calls.\n2. **Do NOT fake image generation.** If `gen-image` fails, don't write a placeholder PNG — the HTML stage will redesign around the missing slot.\n3. **Do NOT construct LLM prompts yourself.** `run_stage.py` is the only place that builds payloads.\n4. **Do NOT add `timing` / logging / retry layers.** The skill is intentionally thin.\n5. **Do NOT go silent between execs.** Echo a one-line Chinese progress message after each exec before issuing the next.\n\n## Pipeline\n\n```bash\nR=\"python3 $SKILL_DIR/scripts/run_stage.py\"\nD=\"<deck_dir>\"\n\n$R preflight     --deck-dir $D              # validate + stage assets\n$R style         --deck-dir $D              # -> style_spec.json\n$R outline       --deck-dir $D              # -> outline.json\n$R asset-plan    --deck-dir $D              # -> asset_plan.json\n\n# Per-item forms — one progress line per item:\n$R gen-image     --deck-dir $D --page N --slot SLOT_ID\n$R page-html     --deck-dir $D --page N\n\n# Batch (concurrent) equivalents — default 4 workers. Each prints one summary\n# JSON to stdout plus per-item status lines to stderr.\n$R batch-gen-image  --deck-dir $D [--concurrency 4]\n$R batch-page-html  --deck-dir $D [--concurrency 4]\n\n$R export        --deck-dir $D              # -> <deck_id>.pptx\n```\n\n`batch-gen-image` serializes writes to `asset_plan.json` under a process-local lock so concurrent workers don't clobber each other.\n\n### How `page-html` works (two LLM calls per page)\n\n1. **Rewrite** — `prompts/page_html_rewrite.md` converts the structured outline + style_spec + inherited content into a natural-language user prompt (content, layout, palette, inherited material).\n2. **Generate** — `prompts/page_html.md` is a hard-contract system prompt (document shell, image path format, ECharts rules, single-layer background, `<span>` wrapping rule, language lock). Receives the rewritten query as the user message and returns the final `<!DOCTYPE html>...</html>`.\n\nThis split keeps converter-facing mechanical contracts (chart container id = `chart_N`, `{renderer:'svg'}`, `__pptxChartsReady` counter, allowed chart types, etc.) in the generator's system prompt — not buried in the natural-language query where they'd get smoothed out.\n\n## Output on each exec\n\nOne JSON line to stdout:\n\n```json\n{\"status\": \"ok\", \"page_no\": 3, \"path\": \"images/page_003_hero.png\"}\n```\n\nor on failure (exit code 1):\n\n```json\n{\"status\": \"failed\", \"error\": \"<reason>\", \"page_no\": 3}\n```\n\nFor `gen-image` failures: **don't retry**, don't substitute — the HTML stage will redesign around it.\n\n## Progress echo — MANDATORY\n\n| Stage | Example |\n|---|---|\n| After preflight | `已进入 sn-ppt-standard，共 N 页` |\n| After style | `[1] style_spec.json ✓ 主色 #2D5BFF` |\n| After outline | `[2] outline.json ✓ 10 页` |\n| After asset-plan | `[3] asset_plan.json ✓ N 槽位` |\n| Per gen-image | `[图 5/14] page_003/hero ✓` or `... ✗ 服务端 502` |\n| After all gen-image | `图片生成阶段完成：成功 12，失败 2` |\n| Per page-html | `[页 3/10] HTML ✓` |\n| After export | `PPTX ✓ (10/10 页)` or `PPTX 失败: ...` |\n\n**Silence for more than ~30 seconds = a bug.**\n\n## Resume semantics\n\nThe script is stateless — re-run a subcommand and it'll overwrite its output artifact. Quick `ls <deck_dir>` decides what's left:\n\n- `style_spec.json` exists → skip `style`\n- `outline.json` exists → skip `outline`\n- `asset_plan.json` exists → skip `asset-plan` (but any slot whose `local_path` is missing or `status != \"ok\"` still needs `gen-image`)\n- `pages/page_NNN.html` exists → skip `page-html` for that page\n- `<deck_id>.pptx` exists → skip `export`\n\n`scripts/resume_scan.py` emits a JSON manifest summarizing all this.\n\n## Env\n\nConfigured via `.env` at the repo root (or `<repo>/skills/.env`). `model_client.py` auto-loads both. Required:\n\n- `SN_API_KEY` for shared text/vision/image-generation auth, or per-kind overrides `SN_CHAT_API_KEY` / `SN_TEXT_API_KEY` / `SN_VISION_API_KEY` / `SN_IMAGE_GEN_API_KEY`\n- `SN_BASE_URL`, `SN_IMAGE_GEN_MODEL`\n\nOptional `SN_CHAT_BASE_URL` / `SN_TEXT_BASE_URL` / `SN_VISION_BASE_URL`, `SN_CHAT_MODEL` / `SN_TEXT_MODEL` / `SN_VISION_MODEL`, and `SN_CHAT_TIMEOUT` / `SN_TEXT_TIMEOUT` / `SN_VISION_TIMEOUT` override defaults.\n\nRun `python $SKILL_DIR/lib/model_client.py health` to verify env before running the pipeline.\n\n## Export PPTX gate\n\n`scripts/export_pptx/html_to_pptx.mjs` is invoked with `--force` — skips built-in motif / real-photo gates (this skill doesn't use the motif protocol). PPTX still produces even if some slots are missing images.\n\nIf the converter crashes, `run_stage.py export` returns `status: \"failed\"`. That's the deck's ending state; PPTX is simply absent.\n\n## Does NOT\n\n- Does not call `sn-image-base` for LLM/VLM (only for T2I).\n- Does not retry failed model calls.\n- Does not write progress to disk.\n- Does not do per-page visual review or rewriting (removed in this iteration).","tags":["ppt","standard","sensenova","skills","opensensenova","agent","agent-skills","ai-agents","ai-assistant","data-analysis","document-processing","office-automation"],"capabilities":["skill","source-opensensenova","skill-sn-ppt-standard","topic-agent","topic-agent-skills","topic-ai-agents","topic-ai-assistant","topic-data-analysis","topic-document-processing","topic-office-automation","topic-presentation-slides"],"categories":["SenseNova-Skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/OpenSenseNova/SenseNova-Skills/sn-ppt-standard","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add OpenSenseNova/SenseNova-Skills","source_repo":"https://github.com/OpenSenseNova/SenseNova-Skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 1627 github stars · SKILL.md body (5,507 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:05.636Z","embedding":null,"createdAt":"2026-05-15T06:53:10.763Z","updatedAt":"2026-05-18T18:53:05.636Z","lastSeenAt":"2026-05-18T18:53:05.636Z","tsv":"'/info_pack.json':96 '/skill':107 '/skills/.env':694 '/task_pack.json':90 '003/hero':573 '1':119,382,505,548 '10':556 '10/10':597 '12':584 '2':153,405,554,586 '2d5bff':551 '3':179,497,512,562 '3/10':592 '30':606 '4':194,304,331,342 '5':207 '5/14':571 '502':576 'absent':837 'add':197 'agent':25,116,146 'allow':459 'api':702,715,719,723,728 'around':175,529 'artifact':83,627 'asset':244,261,560,646 'asset-plan':260,559,645 'asset_plan.json':267,357,563,642 'auth':707 'auto':697 'auto-load':696 'background':425 'base':58,68,731,740,744,748,846 'bash':230 'batch':137,300,323,334,351 'batch-gen-imag':322,350 'batch-page-html':333 'bug':609 'build':192 'built':793 'built-in':792 'buri':470 'call':14,70,152,379,842,857 'chart':450,453,460 'chat':714,739,751,761 'chines':219 'cli':20 'clobber':369 'code':504 'command':33 'concurr':301,330,341,365 'configur':686 'construct':182 'contain':51,451 'content':392,400 'contract':412,449 'convert':385,446,820 'converter-fac':445 'counter':458 'crash':821 'd':235,241,250,257,266,284,297,329,340,348,479 'decid':630 'deck':239,248,255,264,282,295,327,338,346,830 'deck-dir':238,247,254,263,281,294,326,337,345 'default':303,770 'depend':53 'determinist':77 'dir':240,249,256,265,283,296,328,339,347 'dir/lib/model_client.py':774 'dir/scripts/run_stage.py':73,234 'disk':863 'document':415 'doesn':802 'echart':420 'echo':214,532 'emit':30,678 'end':832 'enter':105 'entri':21,111 'env':685,688,778 'equival':302 'error':509 'etc':462 'even':811 'everi':69,74 'exampl':535 'exec':134,143,213,224,486 'exist':91,97,635,639,643,665,674 'exit':503 'export':344,595,676,783,823 'face':447 'fail':163,508,826,855 'failur':502,517 'fake':156 'final':441 'forc':790 'form':271 'format':419 'gate':785,799 'gen':161,279,324,352,515,568,580,662,727,735 'gen-imag':160,278,514,567,579,661 'generat':158,406,465 'get':480 'go':210 'goe':63 'hard':112,411 'hard-contract':410 'health':775 'html':171,293,336,375,525,590,593,669 'id':289,452 'imag':57,67,157,162,280,325,353,417,516,569,581,663,726,734,817,845 'images/page_003_hero.png':499 'inherit':391,403 'input':79 'intent':205 'invok':788 'issu':226 'item':142,270,276,316 'iter':877 'job':27 'json':87,310,488,492,506,680 'keep':444 'key':703,716,720,724,729 'kind':711 'languag':397,428,475 'layer':201,424 'layout':401 'left':633 'line':86,218,274,318,489 'll':623 'llm':11,183,378 'llm/vlm':60,848 'load':698 'local':362,652 'lock':363,429 'log':199 'loop':38,126,149 'ls':629 'main':24,115 'mandatori':533 'manifest':681 'materi':404 'mechan':448 'messag':221,437 'miss':99,177,655,816 'mode':7,94 'model':736,752,755,758,856 'model_client.py':695 'motif':795,806 'must':117 'n':286,299,454,544,564 'natur':396,474 'natural-languag':395,473 'need':660 'never':36,39 'next':228 'ok':494,658 'one':31,78,81,85,217,272,308,487 'one-lin':84,216 'option':737 'outlin':253,388,553,641 'outline.json':258,555,638 'output':82,483,626 'overrid':712,769 'overwrit':624 'page':128,285,292,298,335,374,381,495,510,572,589,668,672,869 'page-html':291,373,588,667 'pages/page_nnn.html':664 'palett':402 'path':418,498,653 'payload':193 'per':34,141,269,275,315,380,566,587,710,868 'per-item':140,268,314 'per-kind':709 'per-pag':867 'photo':798 'pipelin':9,229,782 'place':190 'placehold':168 'plan':262,561,647 'plus':313 'png':169 'ppt':3,8,44,93,110,541 'pptx':349,596,600,673,784,808,834 'pptxchartsreadi':457 'precondit':89 'preflight':237,537 'print':307 'process':361 'process-loc':360 'produc':810 'progress':220,273,531,861 'prompt':41,184,399,414,468 'prompts/page_html.md':407 'prompts/page_html_rewrite.md':384 'protocol':807 'python':123,772 'python3':232 'queri':433,476 'quick':628 'r':231,236,245,252,259,277,290,321,332,343 're':617 're-run':616 'real':797 'real-photo':796 'receiv':430 'redesign':174,528 'remov':874 'render':455 'repo':691 'requir':700 'resum':610 'retri':200,520,854 'return':439,824 'review':871 'rewrit':383,873 'rewritten':432 'root':692 'rule':113,421,427 'run':618,771,780 'run_stage.py':186,822 'script':124,613 'scripts/export_pptx/html_to_pptx.mjs':786 'scripts/resume_scan.py':677 'scripts/run_stage.py':22 'second':607 'self':50 'self-contain':49 'semant':611 'serial':354 'set':80 'share':705 'shell':32,416 'silenc':602 'silent':211 'simpl':29 'simpli':836 'singl':19,133,423 'single-lay':422 'skill':47,72,203,233,773,801 'skill-sn-ppt-standard' 'skip':636,640,644,666,675,791 'slot':130,178,287,288,650,814 'smooth':481 'sn':2,43,56,66,109,540,701,713,717,721,725,730,733,738,742,746,750,753,756,760,763,766,844 'sn-image-bas':55,65,843 'sn-ppt-entri':108 'sn-ppt-standard':1,42,539 'source-opensensenova' 'spec':390 'split':443 'stage':35,172,243,526,534 'standard':4,6,45,95,542 'standard-mod':5 'state':833 'stateless':615 'status':88,317,493,507,657,825 'stderr':320 'stdout':312,491 'still':62,659,809 'stop':100 'structur':387 'style':246,389,547,637 'style_spec.json':251,549,634 'subcommand':75,138,620 'substitut':523 'summar':682 'summari':309 'svg':456 'system':413,467 't2i':13,61,851 'tell':102 'text':718,743,754,764 'text/vision/image-generation':706 'thin':206 'time':198 'timeout':762,765,768 'tool':151 'topic-agent' 'topic-agent-skills' 'topic-ai-agents' 'topic-ai-assistant' 'topic-data-analysis' 'topic-document-processing' 'topic-office-automation' 'topic-presentation-slides' 'two':377 'type':461 'url':732,741,745,749 'use':135,804 'user':103,398,436 'valid':242 'verifi':777 'via':106,687 'vision':722,747,757,767 'visual':870 'vlm':12 'whose':651 'work':376 'worker':305,366 'wrap':16,426 'write':37,40,122,166,355,860 '主色':550 '共':543 '图':570 '图片生成阶段完成':582 '失败':585,601 '已进入':538 '成功':583 '服务端':575 '槽位':565 '页':545,557,591,598","prices":[{"id":"5f6cd674-3dc5-4292-b106-faddcdd228f6","listingId":"e36d47df-642e-4cfe-bd54-db444212e5c9","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"OpenSenseNova","category":"SenseNova-Skills","install_from":"skills.sh"},"createdAt":"2026-05-15T06:53:10.763Z"}],"sources":[{"listingId":"e36d47df-642e-4cfe-bd54-db444212e5c9","source":"github","sourceId":"OpenSenseNova/SenseNova-Skills/sn-ppt-standard","sourceUrl":"https://github.com/OpenSenseNova/SenseNova-Skills/tree/main/skills/sn-ppt-standard","isPrimary":false,"firstSeenAt":"2026-05-15T06:53:10.763Z","lastSeenAt":"2026-05-18T18:53:05.636Z"}],"details":{"listingId":"e36d47df-642e-4cfe-bd54-db444212e5c9","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"OpenSenseNova","slug":"sn-ppt-standard","github":{"repo":"OpenSenseNova/SenseNova-Skills","stars":1627,"topics":["agent","agent-skills","ai-agents","ai-assistant","data-analysis","document-processing","office-automation","presentation-slides"],"license":"mit","html_url":"https://github.com/OpenSenseNova/SenseNova-Skills","pushed_at":"2026-05-15T04:43:37Z","description":"Modular SenseNova skills for building AI-powered office assistants and productivity workflows","skill_md_sha":"ca618127b465affb5608680bd1db0095131b6d80","skill_md_path":"skills/sn-ppt-standard/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/OpenSenseNova/SenseNova-Skills/tree/main/skills/sn-ppt-standard"},"layout":"multi","source":"github","category":"SenseNova-Skills","frontmatter":{"name":"sn-ppt-standard","description":"Standard-mode PPT pipeline. All LLM / VLM / T2I calls are wrapped in a\nsingle CLI entry (scripts/run_stage.py). The main agent's job is simple:\nemit ONE shell command per stage, never write loops, never write prompts."},"skills_sh_url":"https://skills.sh/OpenSenseNova/SenseNova-Skills/sn-ppt-standard"},"updatedAt":"2026-05-18T18:53:05.636Z"}}