@lark-apaas/coding-steering 0.1.31 → 0.1.32-beta.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 +1 -1
- package/steering/design-html/skills/pptx-style-extract/SKILL.md +112 -0
- package/steering/design-html/skills/pptx-style-extract/font-fallback.yaml +129 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/census.py +955 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/check_v2.py +907 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/draft.py +945 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/export_consumer_md.py +75 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/export_consumer_zip.py +175 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/extract.py +765 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/ooxml.py +699 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/package.py +1120 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/parts.py +461 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/query.py +562 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/render_pages.py +679 -0
- package/steering/design-html/skills/pptx-style-extract/scripts/verify_font.py +68 -0
- package/steering/design-html/skills/pptx-style-extract/v2-format-spec.md +193 -0
package/package.json
CHANGED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pptx-style-extract
|
|
3
|
+
description: 从 PPTX/POTX 模板抽取 deck 风格包 v2(design.md + layouts.md + assets/ + ref/)。当用户上传 PPTX/POTX 并要求按附件模板、参考 PPT 风格、保持同款视觉、生成演示/PPT/deck 时,必须先用本 skill 抽取风格;不要只读附件文本摘要后开工。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pptx-style-extract(PPT 模板风格抽取)
|
|
7
|
+
|
|
8
|
+
一份 PPTX → 一个风格包:`manifest.json`(机器清单)+ `design.md`(消费入口)+ `layouts.md` + `assets/` + `ref/`。**机械动作全部由脚本承担**(解析、普查、聚类、草案、落盘、门禁),你只做机器做不了的三件事:**认图、命名、写气质**。
|
|
9
|
+
|
|
10
|
+
脚本路径相对本 skill 根目录;不做环境检测,依赖缺失脚本自己降级并在输出里报。
|
|
11
|
+
|
|
12
|
+
## When To Use This Skill
|
|
13
|
+
|
|
14
|
+
Use this skill before making a slide deck when a `.pptx` or `.potx` attachment is meant as a template, visual reference, brand/style source, or "make it like this" example.
|
|
15
|
+
|
|
16
|
+
Do not treat `SummarizeAttachmentOrFile` output as a substitute for this skill. Attachment text summaries lose theme colors, fonts, slide master geometry, layout coordinates, and reusable visual assets.
|
|
17
|
+
|
|
18
|
+
If the user only asks to summarize, translate, extract text, or review an existing PPTX, do not run this skill unless they also ask to reuse its visual style.
|
|
19
|
+
|
|
20
|
+
## Runtime Contract
|
|
21
|
+
|
|
22
|
+
- Required dependency boundary: Python 3 standard library only.
|
|
23
|
+
- Pillow may be present and improves image hashing, palette extraction, contact sheets, and asset transcoding. If Pillow is missing or fails, continue with degraded extraction and record the degradation in outputs.
|
|
24
|
+
- Do not run `pip install`, `uv pip install`, `npm install`, or any other dependency installation in the user session.
|
|
25
|
+
- Run Python with bytecode disabled: `PYTHONDONTWRITEBYTECODE=1 python3 -B ...`.
|
|
26
|
+
- Default working directory: `/tmp/pptx-style-extract/<unique-id>/`.
|
|
27
|
+
- Do not write extraction intermediates into `/home/gem/workspace/code` or the user app source tree. Only the final deck assets copied by the deck authoring step should enter the project.
|
|
28
|
+
- `package.py` only runs v1 checks when `--check-v1 <path>` is passed or `DSM_V1_DIR` points to a sibling checker. It must not rely on developer-machine paths in the sandbox.
|
|
29
|
+
|
|
30
|
+
## Fast Path Contract
|
|
31
|
+
|
|
32
|
+
Generated packages must make the attachment-consumption path explicit in `design.md` and exported consumer attachments, not in the user prompt:
|
|
33
|
+
|
|
34
|
+
- `design.md` and `layouts.md` are the authoritative generation entrypoints. Audit files under `ref/` and zip payload internals are not generation material.
|
|
35
|
+
- If an attachment summary returns `assetRoot` / `assetPaths`, treat `assetRoot` as an opaque prefix and only concatenate declared asset paths. Do not inspect, list, glob, or repair attachment directories.
|
|
36
|
+
- The generated Agent Fast Path must forbid shell exploration such as `ls <assetRoot>`, `ls <assetRoot>/assets/backgrounds`, `find <assetRoot>`, `glob("<assetRoot>/**")`, or any command containing `assets/design-style-packages`.
|
|
37
|
+
- If self-checking asset usage is needed, inspect final HTML/CSS for the declared path strings or use browser runtime resource checks. Do not fall back to shell directory exploration.
|
|
38
|
+
- Background, logo, layout safety, and asset-use rules belong in the generated style package (`design.md` / `layouts.md`), not in ad hoc query wording.
|
|
39
|
+
|
|
40
|
+
## 1. 抽取
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
mkdir -p /tmp/pptx-style-extract/<unique-id>
|
|
44
|
+
PYTHONDONTWRITEBYTECODE=1 python3 -B scripts/extract.py <pptx_path> /tmp/pptx-style-extract/<unique-id>/stage1
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
一条命令出全部:`extract.json`(普查数值)、`media-out/`(候选图)、`ref/`(审计层)、`l-out/`(**四件判断单草案 + BRIEF.md + contact-sheet.png + layout-sheet.png**)。
|
|
48
|
+
|
|
49
|
+
非 OOXML / 损坏 / 加密 → 报告调用方,不产半成品。
|
|
50
|
+
|
|
51
|
+
## 2. 判断
|
|
52
|
+
|
|
53
|
+
1. 读 `<outdir>/l-out/BRIEF.md` —— 事实、草案依据、待判断清单一页看完。
|
|
54
|
+
2. 看 `<outdir>/l-out/contact-sheet.png` 与 `<outdir>/l-out/layout-sheet.png` —— 候选图和代表页型都已拼好,对应 BRIEF 的表。
|
|
55
|
+
3. 用一次批量编辑/patch 改掉四件草案里的每一处 `TODO`:风格命名与气质、页型中文名、logo 与封面归属、Colors 用途列、模板特有硬规则。
|
|
56
|
+
4. 对每张真实背景图补 `text_safe` / `avoid` 判断:标清背景视觉主体、强光斑、深色透明区等禁放区,并把每个 archetype 与适配背景绑定;标题、正文、关键数字、图表、卡片、时间线及其容器的外接矩形都不得压住背景主体,透明容器也不能跨进禁放区。
|
|
57
|
+
|
|
58
|
+
判断口径:
|
|
59
|
+
|
|
60
|
+
- **满屏图默认属背景族**——整幅替换底图的艺术图/摄影图就是背景(首页那张记 `role: cover`);「内容图不进包」只指内容区里的图表、截图、配图。
|
|
61
|
+
- **logo 宁缺勿错**——看图确认有品牌文字或标志图形才留;拿不准就把该条从 `manifest.yaml` 删掉,在 `gaps` 写一句,候选图留在 `media-out/`。
|
|
62
|
+
- **数值只改名不改值**——草案里的坐标/色值/字号来自普查;确需推导值(CJK 行高转译、投影尺度上抬)在 manifest 写 `derived:` 声明理由,机检认声明。
|
|
63
|
+
- **页型按用途命名**——草案按背景+结构聚类,名字(`cover`/`section`/`content-dense`)只是占位,按 BRIEF 里的 slot 原文改成表意的中文名,role 跟着改。
|
|
64
|
+
- **背景和版式要配对**——真实背景不是纯色底。看 `contact-sheet.png` 判断每张背景的视觉主体/禁放区,看 `layout-sheet.png` 判断文字与卡片落点;在 `layouts.yaml` 给每个页型写清 `background`、`text_safe`、`avoid`、`pairing_rule`,避免消费 Agent 把文字、图表、卡片、时间线、标题容器、正文容器或宽透明容器的外接矩形压到金字塔、人物、产品图、强光斑或深色区域上。
|
|
65
|
+
- 双主题只认 BRIEF 的 `themes`;单主题包不写 `theme` 字段。
|
|
66
|
+
|
|
67
|
+
要更多依据时用 `PYTHONDONTWRITEBYTECODE=1 python3 -B scripts/query.py <outdir> <子命令>`(`shapes` / `colors` / `fonts` / `text-scale` / `images` / `clusters` / `media` / `slides` / `layouts` / `recipes` / `grids` / `get <点路径>`)。读数一律走它,**不写解析脚本、不读 XML、不开浏览器**。
|
|
68
|
+
|
|
69
|
+
## 3. 打包
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
PYTHONDONTWRITEBYTECODE=1 python3 -B scripts/package.py <outdir> <outdir>/l-out <包输出目录>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
exit 0 即交付。FAIL 会指名道姓(TODO 未改 / 数值不可追溯 / 枚举误用 / 引用断链 / 体量超标),改判断单重跑,不要去改产物;体量 FAIL 走降级链(审计出包 → sidecar 化 → archetype 收缩)。
|
|
76
|
+
|
|
77
|
+
## 完成判据
|
|
78
|
+
|
|
79
|
+
- [ ] package.py exit 0
|
|
80
|
+
- [ ] design.md 的 Usage 能回答消费三问:封面底图是哪个文件?logo 每页放哪、用哪个文件?版式坐标去哪查?
|
|
81
|
+
- [ ] design.md / layouts.md 能回答背景安全三问:每张背景的可放文字区域在哪里?禁放区在哪里?每个页型必须配哪张背景?
|
|
82
|
+
- [ ] Agent Fast Path 写清 `assetRoot` / `assetPaths` 的不透明前缀协议,并禁止目录探索。
|
|
83
|
+
- [ ] 抽不出的都在 `gaps`,无编造
|
|
84
|
+
|
|
85
|
+
配套 `v2-format-spec.md`(包形态与 schema)、`font-fallback.yaml`(商业字体降级表)只在你要偏离草案结构时才需要读——草案已经是最终格式。
|
|
86
|
+
|
|
87
|
+
## Consume The Style Pack In A Deck
|
|
88
|
+
|
|
89
|
+
After `package.py` succeeds, the output package is for immediate model consumption.
|
|
90
|
+
|
|
91
|
+
Read `<pack_dir>/design.md` first, especially `## Usage`, `## Hard Rules`, colors, typography, components, assets, and safe-area. Then read `<pack_dir>/layouts.md`; its `canvas` and `slots[].box` are the geometry source for deck-stage sections.
|
|
92
|
+
|
|
93
|
+
When generating a deck:
|
|
94
|
+
|
|
95
|
+
1. Call `copy_starter_component` with `kind: "deck-stage.js"`.
|
|
96
|
+
2. Build `<deck-stage width="1920" height="1080">`; each slide is one static `<section>`.
|
|
97
|
+
3. Inline CSS variables from `design.md` into the HTML `<style>` block using a `--ppt-*` prefix.
|
|
98
|
+
4. Map `layouts.md` slots `[x,y,w,h]` to absolute-positioned elements inside each section. Do not reflow them as generic web grids.
|
|
99
|
+
5. Copy `<pack_dir>/assets/` into the project, for example `assets/pptx-style/<pack-name>/`, and reference those copied files with relative URLs. Never reference `/tmp/pptx-style-extract/...` from final HTML.
|
|
100
|
+
6. Use the font stacks and fallback rules from `design.md`; do not install fonts or dependencies at runtime.
|
|
101
|
+
7. Run the slide preflight checks: no resource failures, no section overflow, and sampled screenshots follow the package colors, typography, layouts, assets, and Hard Rules.
|
|
102
|
+
|
|
103
|
+
## Export Consumer Attachments
|
|
104
|
+
|
|
105
|
+
When the style package is sent as a runtime attachment rather than mounted as a directory, export a consumer artifact that makes the fast path visible to the model:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
PYTHONDONTWRITEBYTECODE=1 python3 -B scripts/export_consumer_zip.py <pack_dir> <out.zip> --work-dir <consumer_dir>
|
|
109
|
+
PYTHONDONTWRITEBYTECODE=1 python3 -B scripts/export_consumer_md.py <pack_dir> <out.md>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The consumer zip starts with a text prefix containing Agent Fast Path, `design.md`, and a bounded `layouts.md` excerpt. The markdown exporter inlines `design.md` / `layouts.md` for flows that should avoid archive preprocessing altogether.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# 商业字体降级映射表(随 skill 分发,E5:初始 20+ 族)
|
|
2
|
+
#
|
|
3
|
+
# 消费方:L4 字体角色分配。直读本文件文本即可,不依赖 yaml 库。
|
|
4
|
+
# 命中 families[].match 中任一名字(含碎片化变体)→ 降级链写进 fontFamily 栈:
|
|
5
|
+
# 原始名留栈首,fallback 依序追加,末位永远可加系统兜底
|
|
6
|
+
# `"PingFang SC", "Microsoft YaHei", sans-serif`。
|
|
7
|
+
# 查无对应 → 按 dsm-v1-spec.md 的气质候选清单选近似体 + 记 gaps,不编造。
|
|
8
|
+
# 匹配纪律:先做字体名归一化聚类(中文名/拉丁名、weight 后缀剥离、31 字符截断),
|
|
9
|
+
# 再拿聚类后的 family 与 match 逐条比对(大小写不敏感、忽略空格/连字符)。
|
|
10
|
+
|
|
11
|
+
version: 2
|
|
12
|
+
|
|
13
|
+
# fallback 用到的 web 字体实测状态(镜像 https://miaoda.feishu.cn/fonts/css2)。
|
|
14
|
+
# verified: true = 该镜像已 curl 实测返回 @font-face(2026-08-06)。
|
|
15
|
+
# 状态过期不影响正确性:L4 对 verified 为 false 或存疑的字体按 dsm-v1-spec 字体条款
|
|
16
|
+
# 重新 curl 实测后再用,加载不到降到下一档。
|
|
17
|
+
web-fonts:
|
|
18
|
+
"Noto Sans SC": {verified: true}
|
|
19
|
+
"Noto Serif SC": {verified: true}
|
|
20
|
+
"ZCOOL XiaoWei": {verified: true}
|
|
21
|
+
"ZCOOL QingKe HuangYou": {verified: true}
|
|
22
|
+
"Ma Shan Zheng": {verified: true}
|
|
23
|
+
"Inter": {verified: true}
|
|
24
|
+
"Montserrat": {verified: true}
|
|
25
|
+
"Barlow": {verified: true}
|
|
26
|
+
"Jost": {verified: true}
|
|
27
|
+
"Nunito Sans": {verified: true}
|
|
28
|
+
"Roboto Condensed": {verified: true}
|
|
29
|
+
"Arial": {verified: system} # 系统字体,不走镜像
|
|
30
|
+
|
|
31
|
+
families:
|
|
32
|
+
# ---- 方正系 ----
|
|
33
|
+
- family: 方正兰亭黑
|
|
34
|
+
match: [方正兰亭黑Pro_GB18030, FZLanTingHeiPro, FZLanTingHeiPro_GB18030, FZLTHProS-R--GB1-0, FZLTHProS, 方正兰亭黑]
|
|
35
|
+
category: sans
|
|
36
|
+
fallback: ["Noto Sans SC"]
|
|
37
|
+
- family: 方正兰亭圆
|
|
38
|
+
match: [方正兰亭圆, FZLanTingYuan, FZLTYuanS]
|
|
39
|
+
category: rounded
|
|
40
|
+
fallback: ["ZCOOL XiaoWei", "Noto Sans SC"]
|
|
41
|
+
- family: 方正准圆
|
|
42
|
+
match: [方正准圆, FZZhunYuan, FZY3JW]
|
|
43
|
+
category: rounded
|
|
44
|
+
fallback: ["ZCOOL XiaoWei", "Noto Sans SC"]
|
|
45
|
+
- family: 方正书宋/宋体系
|
|
46
|
+
match: [方正书宋, FZShuSong, 方正宋体, FZSongS]
|
|
47
|
+
category: serif
|
|
48
|
+
fallback: ["Noto Serif SC"]
|
|
49
|
+
|
|
50
|
+
# ---- 汉仪系 ----
|
|
51
|
+
- family: 汉仪旗黑
|
|
52
|
+
match: [汉仪旗黑, HYQiHei, HYQiHeiX]
|
|
53
|
+
category: sans
|
|
54
|
+
fallback: ["Noto Sans SC"]
|
|
55
|
+
- family: 汉仪文黑
|
|
56
|
+
match: [汉仪文黑, HYWenHei]
|
|
57
|
+
category: sans
|
|
58
|
+
fallback: ["Noto Sans SC"]
|
|
59
|
+
- family: 汉仪菱心体
|
|
60
|
+
match: [汉仪菱心体, HYLingXin]
|
|
61
|
+
category: display
|
|
62
|
+
fallback: ["ZCOOL QingKe HuangYou", "Noto Sans SC"]
|
|
63
|
+
- family: 汉仪粗黑
|
|
64
|
+
match: [汉仪粗黑, HYCuHei]
|
|
65
|
+
category: display
|
|
66
|
+
fallback: ["Noto Sans SC"]
|
|
67
|
+
weight-hint: 900
|
|
68
|
+
|
|
69
|
+
# ---- 系统/厂商中文 ----
|
|
70
|
+
- family: 苹方
|
|
71
|
+
match: [苹方, PingFang SC, PingFangSC, 苹方-简]
|
|
72
|
+
category: sans
|
|
73
|
+
fallback: ["Noto Sans SC"]
|
|
74
|
+
- family: 微软雅黑
|
|
75
|
+
match: [微软雅黑, Microsoft YaHei, MicrosoftYaHei, 微软雅黑 UI]
|
|
76
|
+
category: sans
|
|
77
|
+
fallback: ["Noto Sans SC"]
|
|
78
|
+
- family: 等线
|
|
79
|
+
match: [等线, DengXian, 等线 Light, DengXian Light]
|
|
80
|
+
category: sans
|
|
81
|
+
fallback: ["Noto Sans SC"]
|
|
82
|
+
- family: 华文黑体
|
|
83
|
+
match: [华文黑体, STHeiti, 华文细黑, STXihei]
|
|
84
|
+
category: sans
|
|
85
|
+
fallback: ["Noto Sans SC"]
|
|
86
|
+
- family: 华文宋体/楷体
|
|
87
|
+
match: [华文宋体, STSong, 华文楷体, STKaiti, 楷体, KaiTi]
|
|
88
|
+
category: serif
|
|
89
|
+
fallback: ["Noto Serif SC"] # 手写楷气质另可选 Ma Shan Zheng,按场景判断
|
|
90
|
+
- family: 思源黑体
|
|
91
|
+
match: [思源黑体, Source Han Sans, Source Han Sans SC, SourceHanSansSC, 思源黑体 CN]
|
|
92
|
+
category: sans
|
|
93
|
+
fallback: ["Noto Sans SC"] # 同源设计,无损替换
|
|
94
|
+
- family: 思源宋体
|
|
95
|
+
match: [思源宋体, Source Han Serif, Source Han Serif SC, SourceHanSerifSC]
|
|
96
|
+
category: serif
|
|
97
|
+
fallback: ["Noto Serif SC"] # 同源设计,无损替换
|
|
98
|
+
|
|
99
|
+
# ---- 互联网厂商定制体 ----
|
|
100
|
+
- family: 阿里巴巴普惠体
|
|
101
|
+
match: [阿里巴巴普惠体, Alibaba PuHuiTi, AlibabaPuHuiTi]
|
|
102
|
+
category: sans
|
|
103
|
+
fallback: ["Noto Sans SC"]
|
|
104
|
+
- family: 字节跳动定制体
|
|
105
|
+
match: [Byte Sans, ByteDance Sans, Douyin Sans]
|
|
106
|
+
category: sans
|
|
107
|
+
fallback: ["Noto Sans SC"]
|
|
108
|
+
- family: 小米/OPPO/荣耀定制体
|
|
109
|
+
match: [MiSans, OPPO Sans, HarmonyOS Sans, HONOR Sans]
|
|
110
|
+
category: sans
|
|
111
|
+
fallback: ["Noto Sans SC"]
|
|
112
|
+
|
|
113
|
+
# ---- 拉丁商业体 ----
|
|
114
|
+
- family: Helvetica Neue
|
|
115
|
+
match: [Helvetica Neue, HelveticaNeue, Helvetica Neue Medium, Helvetica]
|
|
116
|
+
category: sans-latin
|
|
117
|
+
fallback: ["Inter", "Arial"]
|
|
118
|
+
- family: Gotham / Proxima Nova
|
|
119
|
+
match: [Gotham, Proxima Nova, ProximaNova]
|
|
120
|
+
category: sans-latin
|
|
121
|
+
fallback: ["Montserrat", "Inter"]
|
|
122
|
+
- family: DIN
|
|
123
|
+
match: [DIN, DIN Pro, DIN Next, FF DIN]
|
|
124
|
+
category: sans-latin
|
|
125
|
+
fallback: ["Barlow", "Roboto Condensed"]
|
|
126
|
+
- family: Futura / Avenir
|
|
127
|
+
match: [Futura, Avenir, Avenir Next]
|
|
128
|
+
category: sans-latin
|
|
129
|
+
fallback: ["Jost", "Nunito Sans"]
|