@lark-apaas/coding-steering 0.1.18-dev.e2d9278 → 0.1.18-dev.ec88bb5

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.
Files changed (31) hide show
  1. package/README.md +19 -21
  2. package/package.json +1 -1
  3. package/steering/design-html/skills/animated-video/SKILL.md +2 -2
  4. package/steering/design-html/skills/charts/SKILL.md +48 -7
  5. package/steering/design-html/skills/{data-report → data-viz}/SKILL.md +65 -9
  6. package/steering/design-html/skills/frontend-design/SKILL.md +2 -2
  7. package/steering/design-html/skills/interactive-prototype/SKILL.md +35 -2
  8. package/steering/design-html/skills/mini-game/SKILL.md +71 -0
  9. package/steering/design-html/skills/mini-game/references/three-js.md +54 -0
  10. package/steering/design-html/skills/pptx-style-extract/SKILL.md +112 -0
  11. package/steering/design-html/skills/pptx-style-extract/font-fallback.yaml +129 -0
  12. package/steering/design-html/skills/pptx-style-extract/scripts/census.py +955 -0
  13. package/steering/design-html/skills/pptx-style-extract/scripts/check_v2.py +907 -0
  14. package/steering/design-html/skills/pptx-style-extract/scripts/draft.py +945 -0
  15. package/steering/design-html/skills/pptx-style-extract/scripts/export_consumer_md.py +75 -0
  16. package/steering/design-html/skills/pptx-style-extract/scripts/export_consumer_zip.py +175 -0
  17. package/steering/design-html/skills/pptx-style-extract/scripts/extract.py +765 -0
  18. package/steering/design-html/skills/pptx-style-extract/scripts/ooxml.py +699 -0
  19. package/steering/design-html/skills/pptx-style-extract/scripts/package.py +1120 -0
  20. package/steering/design-html/skills/pptx-style-extract/scripts/parts.py +461 -0
  21. package/steering/design-html/skills/pptx-style-extract/scripts/query.py +562 -0
  22. package/steering/design-html/skills/pptx-style-extract/scripts/render_pages.py +679 -0
  23. package/steering/design-html/skills/pptx-style-extract/scripts/verify_font.py +68 -0
  24. package/steering/design-html/skills/pptx-style-extract/v2-format-spec.md +193 -0
  25. package/steering/design-html/skills/preflight/SKILL.md +51 -0
  26. package/steering/design-html/skills/preflight/scripts/probe.sh +108 -0
  27. package/steering/design-html/skills/slide-deck/SKILL.md +165 -0
  28. package/steering/design-html/skills/{visual-exposure → visual-report}/SKILL.md +24 -2
  29. package/steering/nestjs-react-fullstack/skills_common/trigger-guide/SKILL.md +180 -0
  30. package/steering/nestjs-react-fullstack/{skills/trigger-guide/SKILL.md → skills_common/trigger-guide/references/trigger-lifecycle.md} +11 -162
  31. package/steering/design-html/skills/make-a-deck/SKILL.md +0 -209
package/README.md CHANGED
@@ -2,23 +2,21 @@
2
2
 
3
3
  Stack-specific steering content for [miaoda coding](https://code.byted.org/apaas/miaoda-coding) templates.
4
4
 
5
- Consumed by [miaoda-cli](https://code.byted.org/apaas/miaoda-cli) at `app init` time and synced into the user project's `.agent/steering/`. **Not a runtime dependency** — no entry in user `package.json`.
5
+ Consumed by [miaoda-cli](https://code.byted.org/apaas/miaoda-cli) during `miaoda skills sync` (including `app init`). It is **not a runtime dependency** — no entry in the user project's `package.json`.
6
6
 
7
7
  ## Layout
8
8
 
9
9
  ```
10
10
  steering/
11
- ├── _common/
12
- │ └── skills/ # cross-stack shared skills
13
11
  ├── <stack>/
14
- │ ├── tech.md # always-loaded, injected into agent system prompt
15
- │ ├── skills/<id>/SKILL.md # progressive disclosure, triggered by description match
16
- └── skills_local/<id>/SKILL.md # local-only variant; overrides skills/<id> when syncing
17
- # to a local-dev project (e.g. via lark-cli)
12
+ │ ├── tech.md # optional, stack overview
13
+ │ ├── skills_common/<id>/SKILL.md # both local and sandbox; copied first
14
+ ├── skills/<id>/SKILL.md # sandbox-only; copied after common
15
+ └── skills_local/<id>/SKILL.md # local-only; copied after common
18
16
  └── ...
19
17
  ```
20
18
 
21
- Top-level directory names (other than `_common`) ARE the stackId — discovery is by directory convention, no central manifest.
19
+ Top-level directory names are stack IDs — discovery is by directory convention, with no central manifest.
22
20
 
23
21
  ## Supported stacks
24
22
 
@@ -31,7 +29,7 @@ vice versa). Current state:
31
29
  | `vite-react` | React + Vite SPA | ✅ | `plugin-guide`, `react-three-fiber` | [`coding-template-vite-react`](../../templates/vite-react) |
32
30
  | `html` | 妙搭 html,带 devserver | ✅ | `rich-interactive-design` | [`coding-template-html`](../../templates/html) |
33
31
  | `nestjs-react-fullstack` | NestJS + React 全栈 | — | `authn`/`authz`/`feishu`/`plugin`/`devops`/`trigger`/`user-*` … + `skills_local/` (`code-fix`, `coding-guide`) | [`coding-template-nestjs-react-fullstack`](../../templates/nestjs-react-fullstack) |
34
- | `design-html` | **无构建**纯静态 HTML 托管(源码即产物,类 Claude Design) | — | _(占位,待补)_ | [`coding-template-design-html`](../../templates/design-html) |
32
+ | `design-html` | **无构建**纯静态 HTML 托管(源码即产物) | — | _(占位,待补)_ | [`coding-template-design-html`](../../templates/design-html) |
35
33
  | `design-stack` | **带构建**的 design / 创意栈(有工具链,区别于 buildless 的 `design-html`) | — | _(占位,待补)_ | _(暂无)_ |
36
34
 
37
35
  `design-html` 与 `design-stack` 是两个**有意分开**的 design 栈:前者无构建、纯静态托管;
@@ -41,20 +39,20 @@ vice versa). Current state:
41
39
 
42
40
  ## Sync mapping (executed by miaoda-cli)
43
41
 
44
- | Source in this package | Destination in user project |
45
- |---|---|
46
- | `steering/<stack>/tech.md` | `.agent/steering/tech.md` |
47
- | `steering/<stack>/skills/<id>/**` | `.agent/steering/skills/<id>/**` |
48
- | `steering/<stack>/skills_local/<id>/**` | `.agent/steering/skills/<id>/**` (local-dev sync only) |
49
- | `steering/_common/skills/<id>/**` | `.agent/steering/skills/<id>/**` |
42
+ `MIAODA_DEP_CACHE_DIR` selects the source mode; `--local` selects only the output layout. Do not use a sandbox environment plus `--local` as evidence for either supported flow.
50
43
 
51
- Precedence when the same `<id>` exists in multiple sources (lowest → highest, later wins):
52
- `_common/skills` `<stack>/skills` `<stack>/skills_local` (local-dev sync only).
44
+ | Source in this package | Local output (`MIAODA_DEP_CACHE_DIR` empty + `--local`) | Sandbox output (`MIAODA_DEP_CACHE_DIR` non-empty, no `--local`) |
45
+ | ---------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------- |
46
+ | `steering/<stack>/skills_common/<id>/**` | `.agents/skills/<id>/**` | `.agent/skills/steering/<stack>/skills/<id>/**` |
47
+ | `steering/<stack>/skills_local/<id>/**` | Same local path, copied after common. | Not copied. |
48
+ | `steering/<stack>/skills/<id>/**` | Not copied. | Same sandbox path, copied after common. |
53
49
 
54
- `skills_local` is a stack-specific variant intended for the local-development sync path
55
- (`miaoda skills sync --local`, driven by `lark-cli apps`). The cloud sandbox sync path
56
- ignores `skills_local` and uses `skills` as-is, so authors of `skills_local` content can
57
- assume "本地 agent" semantics (no `ddl_sql` / `plugin_instance` / sandbox-log tools, etc.).
50
+ For a duplicated skill ID, the copy order is:
51
+
52
+ - Local: `skills_common skills_local`; the local variant wins.
53
+ - Sandbox: `skills_common skills`; the sandbox variant wins.
54
+
55
+ Put a guide in `skills_common/<id>/SKILL.md` when it must reach both supported modes. Keep a same-name `skills/` or `skills_local/` copy only when a deliberate mode-specific override is required.
58
56
 
59
57
  ## Writing rules
60
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/coding-steering",
3
- "version": "0.1.18-dev.e2d9278",
3
+ "version": "0.1.18-dev.ec88bb5",
4
4
  "description": "Stack-specific steering content for miaoda-coding templates",
5
5
  "type": "module",
6
6
  "files": [
@@ -9,11 +9,11 @@ metadata:
9
9
 
10
10
  # Animated video
11
11
 
12
- Create an animated video or motion design piece rendered as an HTML page. Build a timeline-based animation with smooth transitions. Design frame-by-frame sequences with playback controls (play/pause, scrubber). Focus on visual storytelling with the Anthropic brand palette. Export-ready at a fixed aspect ratio (16:9 or 9:16). If you need to know the position of an element (eg to move a cursor or character between elements) use refs to grab the position.
12
+ Create an animated video or motion design piece rendered as an HTML page. Build a timeline-based animation with smooth transitions. Design frame-by-frame sequences with playback controls (play/pause, scrubber). Focus on visual storytelling. Export-ready at a fixed aspect ratio (16:9 or 9:16). If you need to know the position of an element (eg to move a cursor or character between elements) use refs to grab the position.
13
13
 
14
14
  START by calling `copy_starter_component` with `kind: "animations.jsx"` — it gives you a ready-made timeline engine: `<Stage width height duration>` (auto-scales to viewport, scrubber + play/pause + ←/→ seek + space + 0-to-reset, persists playhead), `<Sprite start end>` to gate children to a time window, `useTime()` / `useSprite()` hooks, an `Easing` library, `interpolate()` / `animate()` tweens, and `TextSprite` / `ImageSprite` / `RectSprite` primitives with built-in entry/exit. Read the file after copying and build YOUR scenes by composing Sprites inside a Stage; only fall back to Popmotion (https://sf3-scmcdn-cn.feishucdn.com/obj/feishu-static/miaoda/coding-unpkg-sdk/popmotion@11.0.5/dist/popmotion.min.js) if the starter genuinely can't do what you need.
15
15
 
16
- Animations are complex code! Make reusable JSX components for each visual element and each scene. Invest in tweaking the timeline iteratively.
16
+ Animations are complex code! Make reusable JSX components for each visual element and each scene. Every moment gets ONE definition; sprite-local times and offsets derive from it, never stored separately. The failure: `cardSelectStart = 1.2` inside a scene while the cursor holds `{ t: 9.2 }` for the same beat. Timing shared with nothing else — entry stagger, easing durations — stays local.
17
17
 
18
18
  Animation tips:
19
19
  - Storytelling is KEY! Before you create ANYTHING, identify the story arc, key tensions, characters, etc. Align on the message you want to convey. Run it by the user.
@@ -48,7 +48,7 @@ metadata:
48
48
 
49
49
  5. **编写 ECharts 代码。** 挂载模式和 API 约束见下方技术参考。
50
50
 
51
- 6. **自检。** 截图检查结果。按文末清单验证。然后回到视觉编码步骤:渲染出来的图表是否真的表达了你想表达的信息?颜色编码与仪表盘其他部分是否一致?
51
+ 6. **自检。** 按文末清单逐项检查你写出的 option 代码(源码级自查,不用打开浏览器截图)。然后回到视觉编码步骤:这套配置渲染出来的图表是否真的表达了你想表达的信息?颜色编码与仪表盘其他部分是否一致?
52
52
 
53
53
  ## 图表类型映射
54
54
 
@@ -77,6 +77,44 @@ metadata:
77
77
  - **表达覆盖**:把用户需求拆成需要被回答的信息关系;每个被承诺的关系都要有对应的图表、表格、矩阵或文字证据承载。不要用少量通用指标和默认图表替代所有分析任务。
78
78
  - **小容器防崩**:小尺寸图表优先用 bar / line / number strip。饼图、雷达图、词云和外部标签很容易挤压重叠;空间不足时换图表类型,而不是缩小到不可读。
79
79
 
80
+ ## 窄屏适配
81
+
82
+ 图表出现在报表或看板中时,移动端(≤768px)的容器宽度可能压到 300px 以下。盲目把桌面端图表原样塞进窄容器,会导致 axis label 堆叠、legend 遮盖绘图区、饼图标签溢出。以下是在窄屏容器中保证可读性的规则:
83
+
84
+ ### 布局容器
85
+
86
+ 报表中承载图表的网格必须在窄屏时折叠为单列。写多列网格时,用 `auto-fit` + `minmax()` 让浏览器自动折叠,或配合 `@media` 断点显式切换:
87
+
88
+ ```css
89
+ /* 自动折叠:每列最小 320px,不够就换行 */
90
+ .chart-grid {
91
+ display: grid;
92
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
93
+ gap: 16px;
94
+ }
95
+
96
+ /* 或显式断点 */
97
+ @media (max-width: 768px) {
98
+ .chart-grid { grid-template-columns: 1fr; }
99
+ }
100
+ ```
101
+
102
+ 不要写死 `grid-template-columns: 1.2fr 2fr` 而不提供窄屏回退——390px 视口下,1.2fr 只有 146px,放不下任何图表。
103
+
104
+ ### ECharts option 适配
105
+
106
+ 在窄容器(宽度 <400px)中调整 ECharts option:
107
+
108
+ - **legend**:改为 `orient: 'horizontal'` + `type: 'scroll'`,放在图表底部(`bottom: 0`),不要放在侧面挤占绘图区。
109
+ - **grid**:增大 `left` / `right` 留白到 `'12%'` 以上,防止 axis label 被裁切。
110
+ - **x 轴 label**:长文本加 `axisLabel: { rotate: 30, interval: 0 }` 或截断 formatter;分类超过 8 个时用 `interval: 'auto'` 让 ECharts 自动跳标签。
111
+ - **tooltip**:窄屏下 tooltip 容易超出视口,设 `confine: true`。
112
+ - **图表类型降级**:桌面端的并排双图在移动端改为上下堆叠;桌面端的 Pie 在容器宽度 <250px 时考虑改为横向 Bar。
113
+
114
+ ### 容器尺寸监听
115
+
116
+ 用 `ResizeObserver` 而非 `window.resize` 监听图表容器(见下方「技术参考 · 挂载」的封装代码)。当网格从双列折叠为单列时,window 尺寸不变但容器变宽,`resize` 事件不触发,图表不会重绘。
117
+
80
118
  ## 技术参考
81
119
 
82
120
  ### 加载 ECharts
@@ -94,23 +132,24 @@ metadata:
94
132
  <script>
95
133
  const chart = echarts.init(document.getElementById('chart'));
96
134
  chart.setOption({ /* ... */ });
97
- window.addEventListener('resize', () => chart.resize());
135
+ new ResizeObserver(() => chart.resize()).observe(document.getElementById('chart'));
98
136
  </script>
99
137
  ```
100
138
 
101
139
  ### 挂载——React 封装
102
140
 
103
- 定义一次,复用。**不要**添加 echarts-for-react
141
+ 定义一次,复用。**不要**添加 echarts-for-react。用 `ResizeObserver` 而非 `window.resize` 监听容器尺寸变化(见「窄屏适配」说明)。
104
142
 
105
143
  ```jsx
106
144
  function EChart({ option, style }) {
107
145
  const ref = React.useRef(null);
108
146
  React.useEffect(() => {
109
- const chart = echarts.init(ref.current);
147
+ const el = ref.current;
148
+ const chart = echarts.init(el);
110
149
  chart.setOption(option);
111
- const onResize = () => chart.resize();
112
- window.addEventListener('resize', onResize);
113
- return () => { chart.dispose(); window.removeEventListener('resize', onResize); };
150
+ const ro = new ResizeObserver(() => chart.resize());
151
+ ro.observe(el);
152
+ return () => { ro.disconnect(); chart.dispose(); };
114
153
  }, [option]);
115
154
  return <div ref={ref} style={{ width: '100%', minHeight: 300, ...style }} />;
116
155
  }
@@ -152,6 +191,8 @@ Object.assign(window, { EChart });
152
191
  | 17 | 双 Y 轴零点未对齐 | 匹配 `\|min\| / max` 比例 |
153
192
  | 18 | 图表 series 或容器使用阴影/发光效果 | 移除 `shadowBlur`、`shadowColor`、容器 `box-shadow`,改用线宽、透明度、注释或面积大小表达层级 |
154
193
  | 19 | 图表或标签挤压、重叠、被容器裁切 | 增大容器、减少标签、改用 tooltip / inside label,或换成更稳的图表类型 |
194
+ | 20 | 图表容器的父级网格在窄屏(≤768px)下没有折叠为单列 | 用 `auto-fit + minmax(320px, 1fr)` 或 `@media` 断点,保证每个图表容器至少 320px 宽 |
195
+ | 21 | 使用 `window.addEventListener('resize', ...)` 监听图表尺寸 | 改用 `ResizeObserver`——网格列折叠时 window 尺寸不变但容器变宽,`resize` 事件不触发 |
155
196
 
156
197
  ### 不建议
157
198
 
@@ -1,15 +1,15 @@
1
1
  ---
2
- name: data-report
3
- description: "数据驱动的报表与看板设计。从数据分析到报表规划、信息层级组织,适用于用户有数据文件或明确指标,需要产出结构化数据报表的场景。图表绘制部分由 charts skill 承担。触发词:数据报表, 数据看板, 数据分析报表, BI, 经营报表, 指标看板, 周报, 月报, 数据大盘, KPI, 报表设计, data report, dashboard report, analytics report"
2
+ name: data-viz
3
+ description: "数据可视化设计。从数据分析到版面规划、信息层级组织,适用于用户有数据文件或明确指标,需要产出结构化报表、看板或可视化页面的场景。图表绘制部分由 charts skill 承担。触发词:数据可视化, 数据报表, 数据看板, 数据分析报表, BI, 经营报表, 指标看板, 周报, 月报, 数据大盘, KPI, 报表设计, data visualization, data report, dashboard report, analytics report"
4
4
  metadata:
5
5
  display-names:
6
- zh-CN: 数据看板
7
- en-US: Data Dashboard
6
+ zh-CN: 数据可视化
7
+ en-US: Data Visualization
8
8
  ---
9
9
 
10
- # 数据报表
10
+ # 数据可视化
11
11
 
12
- 你是数据报表设计者。你的工作是把原始数据变成一份读者能直接用来做判断的报表——不只是画几张图,而是回答"这份数据在说什么、读者应该关注什么"。
12
+ 你是数据可视化设计者。你的工作是把原始数据变成一份读者能直接用来做判断的可视化页面——不只是画几张图,而是回答"这份数据在说什么、读者应该关注什么"。
13
13
 
14
14
  报表的价值不在图表数量,而在信息层级:读者能在 5 秒内抓到主要结论,30 秒内理解支撑证据,需要时能下钻到明细。
15
15
 
@@ -19,7 +19,9 @@ metadata:
19
19
 
20
20
  布局必须比普通上下堆叠更丰富。先根据数据任务选择版式骨架,再写代码:监控型、复盘型、诊断型、对比型、明细型、汇报型可以有完全不同的扫描路径。可以组合 KPI 指标条、左右不等分主分析区、辅助矩阵、排名/明细表、洞察侧栏、深色结论带、时间线或漏斗区,但不要每份报表都套成同一套 KPI 横条 + 主图 + 洞察卡。不要把每个章节都做成同宽标题加一张满宽卡片;核心模块占更大面积,支撑模块用不同宽度、密度和位置服务它。
21
21
 
22
- 报表不是产品原型。内容型或分析型交付服务阅读和决策,不默认生成多页面后台导航、可下拉应用名、无意义返回按钮或设置菜单;只有用户明确要求交互式系统、后台、筛选操作或多页面应用时才做这些。标题、范围、口径、结论、图表、洞察和明细都是可用的信息部件,不是每份报表都必须同时出现的固定章节。
22
+ 报表不是产品原型。内容型或分析型交付服务阅读和决策,不默认生成多页面后台导航、可下拉应用名、无意义返回按钮或设置菜单。标题、范围、口径、结论、图表、洞察和明细都是可用的信息部件,不是每份报表都必须同时出现的固定章节。
23
+
24
+ 看板中的筛选器、标签页切换(如"今日/近7天/近30天"、"库存量/库存金额"、"30天/90天")、下拉选择等控件如果出现在页面上,必须用 JavaScript 实现真实的切换逻辑——点击后切换数据视图、过滤图表或改变显示内容。不实现功能的控件不得使用 `<button>`、`cursor:pointer` 或 active/hover 样式暗示可点击;纯标注用 `<span>` 或静态文字呈现。
23
25
 
24
26
  不要让页面全是文字,也不要把所有章节都做成同一种"结论 + 指标 + 图表 + 洞察"结构。长材料先判断每段内容在当前报表里的作用:它是在给背景、定义口径、证明结论、展示变化、比较对象、解释异常、列明细,还是提出行动。每段只选择最适合的表达方式,可以是短结论、关键数字、对比、时间顺序、表格、矩阵、引用、图表、注释或截图。重要内容不能被塞进附录或角落;如果一个章节是汇报目标的核心,就给它相称的版面面积和区别于其他章节的版式处理。
25
27
 
@@ -50,6 +52,13 @@ metadata:
50
52
 
51
53
  产出:维度-指标清单,以及一句话叙事重点。
52
54
 
55
+ **数据忠实度约束。** 在此步完成后,明确标注哪些指标可以直接从源数据计算、哪些缺少必要数据(如历史期、目标值、预算基线)。后续步骤中:
56
+
57
+ - 可直接计算的指标:使用真实值。
58
+ - 源数据不含的派生指标(同比/环比变化率、完成率、差额等需要两期或多源数据而只有单期的):不编造数值,用"—"占位或省略该指标。
59
+ - 超出数据时间范围的外推值:不补齐,图表只覆盖数据实际跨度。
60
+ - 确需补充示例数据时:必须在页面上用视觉标记(虚线边框、"示例数据"标签、灰色斜体)明确区分。
61
+
53
62
  ### 3. 报表规划
54
63
 
55
64
  在写代码之前,先确定报表由哪些组件构成:
@@ -59,7 +68,7 @@ metadata:
59
68
  - **候选部件**:标题 / 范围 / 口径、摘要、KPI、主图表、辅助图表、文字洞察、明细表、时间线、矩阵、截图或注释都只是候选。需要哪个用哪个,不要为了"完整"把它们凑齐。
60
69
  - **核心承载**:只给真正承载核心问题的模块更大面积。核心可能是一张趋势图、一张排名表、一段异常解释、一个流程漏斗,也可能是一组明细,不固定。
61
70
  - **版式差异**:为不同信息角色安排不同形态,例如紧凑指标条、宽图、窄侧栏、表格区、注释带、对比矩阵或分段背景。避免每个章节都重复同一张满宽白卡。
62
- - **布局骨架**:明确每个模块的相对面积和扫描路径,例如 `1.2fr 2fr`、`1fr 1.6fr`、`repeat(4,1fr)`、`auto 1fr` 等混合栅格;移动端再自然折叠。
71
+ - **布局骨架**:明确每个模块的相对面积和扫描路径,例如 `1.2fr 2fr`、`1fr 1.6fr`、`repeat(4,1fr)`、`auto 1fr` 等混合栅格。多列网格必须提供窄屏回退(`auto-fit + minmax()` 或 `@media` 断点),不要写死 fr 比例而不处理移动端——详见下方「移动端适配」。
63
72
 
64
73
  组件取舍由读者任务、数据复杂度和材料内容决定。
65
74
 
@@ -84,12 +93,53 @@ metadata:
84
93
  - 表格用于精确查数和比较对象,不要把长表伪装成密集柱状图。
85
94
  - KPI 用于概览,不要把每个字段都做成指标卡。
86
95
  - 没有真实依据时不编造结论;可写"待补充口径"或使用中性描述。
96
+ - 页面中每个数值必须可溯源:源数据直读、或从源数据可验证计算得出。缺少计算所需数据时(如同比需要上期数据但只有本期),用"—"占位或省略,不编造。
97
+ - 所有视觉上暗示可交互的控件(标签页、筛选器、按钮、下拉、日期切换)必须绑定真实 JS 逻辑。不实现切换功能就不画成可点击样式。
87
98
 
88
99
  产出:完整报表页面。
89
100
 
101
+ ### 5.5 移动端适配
102
+
103
+ 报表在桌面端的复杂网格不会自动适配移动端。写完桌面布局后,必须为 ≤768px 视口补充响应式处理:
104
+
105
+ **页面基础**:HTML 必须包含 `<meta name="viewport" content="width=device-width, initial-scale=1">`,否则移动浏览器用 980px 默认视口渲染再缩小,所有字都变成蚊子大小。
106
+
107
+ **模块折叠策略**:
108
+
109
+ - **KPI 指标条**:桌面端横排 4 个时,移动端折叠为 2×2 网格。用 `repeat(auto-fit, minmax(160px, 1fr))` 自动处理,或 `@media (max-width: 768px)` 显式切到两列。
110
+ - **主分析区(左右不等分)**:`1.2fr 2fr` 或 `auto 1fr` 这类侧栏 + 主区布局,移动端必须折叠为单列——侧栏内容移到主区上方或下方。
111
+ - **并列图表**:两图并排在移动端改为上下堆叠,每个图表独占一行。图表容器的窄屏处理由 charts skill 的「窄屏适配」规则覆盖。
112
+ - **明细表格**:宽表在窄屏下加 `overflow-x: auto` 让表格可横向滚动,不要压缩列宽到不可读。
113
+ - **洞察侧栏 / 注释带**:移动端折叠到对应图表下方,不要浮动遮盖内容。
114
+
115
+ **断点写法**(二选一):
116
+
117
+ ```css
118
+ /* 方式 A:auto-fit 自动折叠 */
119
+ .report-grid {
120
+ display: grid;
121
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
122
+ gap: 16px;
123
+ }
124
+
125
+ /* 方式 B:显式断点 */
126
+ .report-layout {
127
+ display: grid;
128
+ grid-template-columns: 1.2fr 2fr;
129
+ gap: 24px;
130
+ }
131
+ @media (max-width: 768px) {
132
+ .report-layout {
133
+ grid-template-columns: 1fr;
134
+ }
135
+ }
136
+ ```
137
+
138
+ **字号底线**:移动端正文不低于 14px,KPI 数字不低于 20px,图表标题不低于 13px。
139
+
90
140
  ### 6. 自检
91
141
 
92
- 截图检查结果,验证以下几点:
142
+ 读一遍自己写出的代码(源码级自查),逐项验证以下几点:
93
143
 
94
144
  - 报表是否回答了步骤 1 确定的核心问题。
95
145
  - 信息层级是否清晰(读者能在 5 秒内抓到主要结论)。
@@ -101,5 +151,11 @@ metadata:
101
151
  - 文字洞察是否与图表数据互相支撑。
102
152
  - 图表部分是否通过了 charts skill 的自检清单。
103
153
  - 口径和单位是否全报表一致。
154
+ - 页面中展示的每个数值是否可溯源到用户提供的数据;同比/环比/完成率等派生指标是否有对应的基准数据支撑,没有的是否已用"—"占位而非编造。
155
+ - 所有视觉上可点击的控件(标签页、筛选器、按钮、下拉)是否都绑定了真实 JS 逻辑,点击后确实切换数据或视图;没有功能的元素是否已改为静态文字样式。
156
+ - HTML 是否包含 `<meta name="viewport" content="width=device-width, initial-scale=1">`。
157
+ - 多列网格是否提供了窄屏回退(`auto-fit + minmax()` 或 `@media` 断点),在 390px 视口下是否折叠为单列且无横向滚动。
158
+ - 宽表格是否有 `overflow-x: auto` 容器包裹。
159
+ - 移动端字号是否达到底线(正文 ≥14px、KPI 数字 ≥20px、图表标题 ≥13px)。
104
160
 
105
161
  产出:确认或修正。
@@ -24,7 +24,7 @@ metadata:
24
24
  - **配色(Palette)**——哪些颜色承担语义或品牌职责,哪些是中性的支撑色,哪一个唯一的强调色赢得注意力?
25
25
  - **签名元素(Signature)**——整个页面靠它被记住的那一个手法。它必须只可能属于这个主题;一个换到下份 brief 也能复用的签名元素,是默认值,不是选择。
26
26
 
27
- 风格不是版式排完后再涂上去的装饰。这个方向决定字体排印、间距、图表处理、章节节奏、边框、图标风格,以及哪些组件值得强调。
27
+ 风格不是版式排完后再涂上去的装饰。这个方向决定字体排印、间距、图表处理、图像质感、章节节奏、边框、图标风格,以及哪些组件值得强调。
28
28
 
29
29
  ## 设计原则
30
30
 
@@ -54,7 +54,7 @@ metadata:
54
54
 
55
55
  ## 克制与自我评审
56
56
 
57
- 把大胆花在一个地方。让签名元素成为唯一被记住的东西,它周围的一切保持安静、克制,砍掉任何不服务于 brief 的装饰。不冒险本身也可能是一种冒险!默默守住质量底线,不必声张:响应式适配到移动端、键盘焦点可见、尊重 reduced motion。边构建边评审自己的作品,环境支持就截图看——一图胜千 token。想想香奈儿的忠告:出门前照照镜子,摘掉一件配饰。人类创作者有记忆,总在尝试新东西;如果你有地方快速记下自己试过什么,会对后续迭代有帮助。
57
+ 把大胆花在一个地方。让签名元素成为唯一被记住的东西,它周围的一切保持安静、克制,砍掉任何不服务于 brief 的装饰。不冒险本身也可能是一种冒险!默默守住质量底线,不必声张:响应式适配到移动端、键盘焦点可见、尊重 reduced motion。边构建边评审自己的作品——读你写出的代码,在脑子里过一遍它渲染成什么样。想想香奈儿的忠告:出门前照照镜子,摘掉一件配饰。人类创作者有记忆,总在尝试新东西;如果你有地方快速记下自己试过什么,会对后续迭代有帮助。
58
58
 
59
59
  ## 再谈设计中的写作
60
60
 
@@ -1,10 +1,43 @@
1
1
  ---
2
2
  name: interactive-prototype
3
- description: Working app with real interactions
3
+ description: 创建具备真实交互的可运行应用原型。触发词:interactive prototype, 交互原型, 可交互原型, 动态原型, 原型演示, 交互演示, working app
4
4
  metadata:
5
5
  display-names:
6
6
  zh-CN: 交互原型
7
7
  en-US: Interactive Prototype
8
8
  ---
9
9
 
10
- Create a fully interactive prototype with realistic state management and transitions. Use React useState/useEffect for dynamic behavior. Include hover states, click interactions, form validation, animated transitions, and multi-step navigation flows. It should feel like a real working app, not a static mockup.
10
+ # 交互原型
11
+
12
+ 创建一个完全可交互的原型,具备真实的状态管理和页面切换。用 React 的 useState/useEffect 实现动态行为。包含悬停状态、点击交互、表单验证、动画过渡和多步导航流程。用起来要像真正能运行的应用,而不是静态效果图。
13
+
14
+ ## 响应式适配
15
+
16
+ 先判断 brief 的目标场景,走不同策略:
17
+
18
+ **面向终端用户的产品**(官网、营销页、C 端应用、展示型页面)——必须适配移动端。用 `@media (max-width: 768px)` 做断点,375px 宽度下无水平滚动、无内容不可读、无元素互相遮挡:
19
+
20
+ - **侧边栏**:窄屏默认收起,汉堡按钮切换;展开时 `position: fixed` + 半透明遮罩覆盖内容,不挤压主区域。
21
+ - **顶部导航**:导航项超出视口宽度时折叠为汉堡菜单,不允许换行堆叠或水平溢出。
22
+ - **网格与卡片**:用 CSS Grid `auto-fit` / `minmax()` 或 Flexbox `flex-wrap`,窄屏自动堆叠为单列;卡片内数字和文字不因容器变窄而截断。
23
+ - **固定定位元素**:浮动按钮、悬浮面板等 `position: fixed/absolute` 元素用 `right: 16px` 等安全边距约束在视口内,不允许超出屏幕边缘。
24
+
25
+ **面向桌面的场景**(管理后台、内部工具、数据密集型仪表盘)——不需要重排为移动端布局,但必须设 `min-width`(通常 1024px–1200px),窄于此宽度时整体水平滚动,而不是让布局被挤压变形。
26
+
27
+ brief 未指明时默认按终端用户产品处理。
28
+
29
+ ## 宣告可升级为全栈应用
30
+
31
+ 宿主为交互原型提供「升级为全栈应用」入口,把纯前端原型转成带服务端的真实应用。入口是否出现,取决于原型有没有向父窗口宣告:
32
+
33
+ ```js
34
+ function announceUpgrade() {
35
+ window.parent.postMessage({ type: 'miaoda:upgrade:available', kind: 'interactive-prototype' }, '*');
36
+ }
37
+ announceUpgrade();
38
+ // 宿主在 iframe 'load' 时重置能力声明,脚本早于 load 执行时补一次
39
+ if (document.readyState !== 'complete') window.addEventListener('load', announceUpgrade, { once: true });
40
+ ```
41
+
42
+ - 重复宣告无副作用;宁可多发,也不要因时序错过让入口不出现。
43
+ - 只宣告,不实现:原型侧不写升级逻辑,转全栈由宿主发起。
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: mini-game
3
+ description: 创建有胜负、挑战目标或玩法循环的小游戏(休闲 / 益智 / 街机 / 答题 / 反应类)。触发词:game, 游戏, 小游戏, 玩法, 街机, 益智, 关卡, playable。产品界面与流程演示用 interactive-prototype;无胜负的系统模拟不适用。
4
+ metadata:
5
+ display-names:
6
+ zh-CN: 小游戏
7
+ en-US: Mini Game
8
+ ---
9
+
10
+ # 小游戏
11
+
12
+ 为有胜负 / 挑战目标 / 玩法循环的小游戏做玩法与工程决策。视觉方向仍由 `frontend-design` 先行确立;本 skill 条款与通用规则冲突时,以本 skill 为准。
13
+
14
+ **边界**:产品界面与流程演示 → `interactive-prototype`;无胜负的系统模拟(元胞自动机 / 流体 / 粒子沙盒)与 3D 沉浸漫游 → 不套用本 skill。
15
+
16
+ ## Quick Reference
17
+
18
+ | 决策 | 默认 | 例外 |
19
+ |---|---|---|
20
+ | 渲染层 | 回合 + 离散网格 → DOM Grid;实时连续 → Canvas 2D | 用户指定时尊重 |
21
+ | 主循环 | 实时类 `requestAnimationFrame` | 回合类事件驱动,无主循环 |
22
+ | 输入 | 桌面键鼠 + 移动 touch 同时支持 | 用户明确单端 |
23
+ | 再来一局 | 真 reset 全部状态 | — |
24
+ | 最高分 | localStorage 持久化 | 用户明确不要 |
25
+ | 库 | 原生 Canvas / DOM / 原生 JS | 白名单按需行(物理 / 3D) |
26
+
27
+ ## 交互契约
28
+
29
+ - 「再来一局」必须重置全部状态(分数 / 棋盘 / 计时器),禁 `location.reload()` 充当重启。
30
+ - 报分、结束、确认一律游戏内 UI 面板,禁 `alert()` / `confirm()` / `prompt()`。
31
+ - 结束面板至少含:本局分数、最高分、「再来一局」按钮。
32
+ - 暂停必须真停主循环(`cancelAnimationFrame`),不是 dt 置 0 空转;监听 `visibilitychange`,切后台自动暂停。
33
+ - 实时类主循环用 `requestAnimationFrame`,禁 `setInterval`;回合类事件驱动即可,不为「像游戏」硬塞 rAF。
34
+ - 最高分读写 `localStorage` 包 `try/catch`(隐私模式会抛错)。
35
+
36
+ ## 渲染层
37
+
38
+ - 回合驱动 + 离散网格(2048 / 三消 / 棋盘 / 卡牌 / 答题)→ DOM + CSS Grid(`grid-template-columns: repeat(N, 1fr)`),移动 / 合并动画走 `transform` + `transition`。不默认上 Canvas——会丢掉免费的过渡动画与清晰文字;也不要 `position: absolute` + 像素 left/top 排格子。
39
+ - 实时连续运动(跑酷 / 弹幕 / 打砖块)→ Canvas 2D。
40
+
41
+ ## 双端输入
42
+
43
+ - 桌面键鼠 + 移动 touch 必须同时支持(产物常在飞书容器内用手机打开),用户明确单端时除外。
44
+ - 优先 Pointer Events 统一两端;键盘方向类操作在移动端补虚拟方向键或 swipe 手势。
45
+ - 游戏容器设 `user-select: none; touch-action: none;`,防长按选中与手势拖动页面;触控目标 ≥ 44×44px。
46
+
47
+ ## 素材
48
+
49
+ - 需要精灵 / 角色 / 背景图时用 `generate_image`,prompt 尾缀固定:`game asset, transparent background, flat icon, no text overlay`。写「epic / cinematic scene」会产出电影海报而非可用素材。
50
+ - 纯数字 / 色块 / 几何即可成立的玩法(2048 类)不生图。
51
+
52
+ ## 难度
53
+
54
+ - 进度感至少满足一种:得分递增 / 速度递增 / 关卡推进。禁从头到尾单一难度、单一速度。
55
+
56
+ ## 缩略图态
57
+
58
+ 平台在提交前会截 `index.html?thumbnail=1` 作为应用缩略图:菜单首屏按海报感设计;检测到 URL 带 `thumbnail` 参数时定格菜单态——不自动开局、不停在 loading。
59
+
60
+ ## 库白名单(CDN 锁定)
61
+
62
+ | 用途 | 选型 | 默认/按需 | 引入方式 |
63
+ |---|---|---|---|
64
+ | 游戏渲染 | 原生 Canvas 2D / DOM / SVG | 默认 | 无需引入 |
65
+ | 交互 / 动画 | 原生 JS + rAF / 原生 CSS | 默认 | 无需引入 |
66
+ | 2D 物理 | Matter.js | 按需:真实刚体(抛体 / 碰撞堆叠 / 铰链);简单弹跳自己写积分 | `<script src="https://cdn.jsdelivr.net/npm/matter-js@0.20.0/build/matter.min.js"></script>` |
67
+ | 3D 游戏 | Three.js r147 UMD | 按需:用户明确要 3D。引入前先 Read 本 skill 的 `references/three-js.md` | `<script src="https://cdn.jsdelivr.net/npm/three@0.147.0/build/three.min.js"></script>` |
68
+
69
+ - CDN URL 原样复制,不自行替换版本号。明确不引入:Phaser 等游戏引擎(原生 Canvas 替代)、GSAP(原生 CSS / rAF 替代)。
70
+ - 游戏主体不走 React+Babel 栈,用原生 JS 组织(本条按媒介 skill 优先规则覆盖系统级 React 指引);仅在既有 React 产物内嵌游戏时保留 React 外壳,且每帧游戏状态不进 React state。
71
+ - 音效仅在用户要求时做:Web Audio 合成,首次用户手势后 `AudioContext.resume()` 解锁,并提供静音开关。
@@ -0,0 +1,54 @@
1
+ # Three.js r147 UMD 引入指南(3D 小游戏按需)
2
+
3
+ r147 是最后一个含 UMD `examples/js/` 的版本:经典 `<script>` 标签引入,全局 `THREE` 命名空间。无需 importmap、无需 `type="module"`。
4
+
5
+ ## 基础引入
6
+
7
+ ```html
8
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/build/three.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/controls/OrbitControls.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/loaders/GLTFLoader.js"></script>
11
+ <script>
12
+ const controls = new THREE.OrbitControls(camera, renderer.domElement);
13
+ const loader = new THREE.GLTFLoader();
14
+ </script>
15
+ ```
16
+
17
+ 覆盖路径:`examples/js/{controls,loaders,postprocessing,objects,shaders,exporters,...}/<Name>.js`。
18
+
19
+ ## extensions 隐式依赖(黑屏陷阱)
20
+
21
+ **`examples/js` 下各文件之间有隐式全局依赖,且按 script 标签顺序求值。漏引或顺序错会直接抛 `TypeError` 并中断整个初始化脚本——页面卡在 loading 或永久黑屏,且没有任何报错提示。** 用到 addon 时整段复制下方清单,不要只挑名字对得上的那几个。
22
+
23
+ ## 后期处理(EffectComposer / Bloom 等)——整段复制,顺序不可调换
24
+
25
+ ```html
26
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/build/three.min.js"></script>
27
+ <!-- EffectComposer.js 内部定义 THREE.Pass 基类,必须排在所有 *Pass 之前 -->
28
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/postprocessing/EffectComposer.js"></script>
29
+ <!-- 纯 shader 对象,供下面的 Pass 引用 -->
30
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/shaders/CopyShader.js"></script>
31
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
32
+ <!-- 各 Pass 均为 class X extends THREE.Pass,依赖上面的基类 -->
33
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/postprocessing/ShaderPass.js"></script>
34
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/postprocessing/RenderPass.js"></script>
35
+ <script src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
36
+ ```
37
+
38
+ | 你要用 | 必须同时引入 |
39
+ |---|---|
40
+ | `EffectComposer` | `CopyShader` + `ShaderPass`(构造函数里立即用到) |
41
+ | `UnrealBloomPass` | `LuminosityHighPassShader` + `CopyShader` |
42
+ | 任意 `*Pass` | `EffectComposer.js`(提供 `THREE.Pass` 基类),且必须排在它之后 |
43
+
44
+ 只引 `EffectComposer` + `RenderPass` + `UnrealBloomPass` 这三个是**错的**,会报 `THREE.ShaderPass is not a constructor`。
45
+
46
+ ## 色彩管理(r147 默认 Linear,必须显式启用 sRGB)
47
+
48
+ ```js
49
+ renderer.outputEncoding = THREE.sRGBEncoding; // 输出 sRGB
50
+ texture.encoding = THREE.sRGBEncoding; // 颜色纹理(baseColor / albedo)
51
+ // 注意:normalMap / roughnessMap / metalnessMap 保持默认 Linear,不要改
52
+ ```
53
+
54
+ 未启用会导致 PBR 材质看上去发淡 / 过饱和。
@@ -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.