feat(skills): 两包资源索引机制与双向对账脚本

- product-planning:新建 references/manifest.md 作资源唯一登记处(资源/落点/引用点/口径);
  顶层 SKILL 加两条硬规矩,design-capture、stage-delivery、execution-runbook、stage-requirements
  四处把散落路径改为「落点见 references/manifest.md」
- session-mechanism:01-文档索引 新增 §四「包内资源索引」,并说明不放 manifest.md 的理由
  (那份由 install.py 本机生成、被 .gitignore 挡着)
- 新增两包共用的 scripts/check_resource_index.py(双向对账)与 product-planning/scripts/check_figures.py(图片机检),
  selftest 补对应用例,06-技能优化规程 写入写法规矩
- .gitignore:新增 _留痕/ 不入库(改造前整包快照,180K/688K,库内从无先例)
This commit is contained in:
admin committed 2026-10-18 18:07:40 +08:00
1 parent a9d2adaf72
commit acfb252bee
14 files changed
+626 -39

No files matched your search

+8 -1
View File
@@ -227,6 +227,8 @@ DESIGN.md 说明:`@google/design.md` 提供 `lint` / `diff` / `export` / `spec
- 禁止长文:单份产出物默认一页纸(≤120 行),超长必须拆分。
- ⭐ 落盘产出的排版(2026-10-14 用户令,原话「标题周围写小字的怪毛病 彻底改掉」):元信息(条数、口径、读法、状态)写进表格的列、条目的字段或表头;标题旁边、标题下面、标题后面都只放标题本身。④段的 `references/doc-language-spec.md` 另有一份更细的,冲突以那份为准。
- 🔴 路径写相对或占位(2026-10-14 用户令):本包内一切文字(`SKILL.md`、`references/**`、脚本与注释、模板)引用**本技能自己或同根技能**的位置时,写相对形态 —— 同根技能写 `<技能根>/<技能名>/`,本包自己的文件写包内相对路径(如 `references/stage-delivery/`)。只有**跨根引用**(工作区根、文档库根、本机软件安装位这类从本包推不出来的别的根)才落到具体位置,且优先读环境变量(`DSH_WS_ROOT` / `DSH_DOCS_ROOT` / `WORKBUDDY_BIN_ROOT`)。原因:技能根的位置随环境变(全局技能根还是工作区技能根、用户名与盘符各不相同),写死了换台机器就是死路径,跨环境会整片报错。
- 🔴 **资源路径只在资源清单写一次(2026-10-16 用户令)**:本包有什么资源、落在哪、被谁引用,**唯一登记处**是 `references/manifest.md` 的「资源索引」表;别的文字里**只写资源名**(如「样式套目录」「工具箱·design-capture」),⛔ 不把路径抄进散文、段文档、脚本注释与模板。理由(用户原话:「为什么这么多地方引用一个样式库,是不是技能中没有统一索引机制」):路径一抄成 N 处,改一次目录就要改 N 个地方,**漏一处还不报错**。清单里标 `只写一次` 的资源,其路径字面量只许出现在清单本身与清单 `许可字面量` 列登记的文件里。
- 🔴 **改完本包跑一次资源索引对账**(同一道令):`python "<技能根>/session-mechanism/scripts/check_resource_index.py" --pkg "<本包根>"`(两个技能包共用这一份实现)。它报四类:落点不存在 / 登记的引用点不是真的 / 有人绕开清单在别处写了路径字面量 / 登记了却没人用的资源。⛔ 有 🔴 不算改完,不静默放过。
## 征询外部模型(GPT)的提问口径(单一真源)
@@ -247,11 +249,16 @@ DESIGN.md 说明:`@google/design.md` 提供 `lint` / `diff` / `export` / `spec
- 图要**表达结构或流程**(二选一或兼具)—— 一张图看完就知道「由哪几块组成、怎么连起来」或「一件事分几步走」;⛔ 不做纯装饰性配图。
- 图表达这份文档**覆盖的东西之间的关系**,按段定画什么:
· ①段(`research/` 五份)—— 画对象与流向:为谁解决什么、信息从哪来到哪去。
· ②段(文档根 `产品规划/prd/` 两份)—— 画页面骨架:有哪几页、每页几个板块、跨页关系怎么走。
· ①段 `research/1b-独立分析/<竞品名>.md` —— 每个候选一份,图要画该候选管哪个环节、缺哪个环节(通常是「环节覆盖条」)。
· ②段 `prd/2a-产品功能.md` —— 画**功能归组**:功能组有几组、每组覆盖哪几段、各多少条(页面此时还没定,⛔ 不画页面骨架)。
· ②段 `prd/2b-界面布局.md` —— 画**页面骨架**:有哪几页、每页几个板块、跨页关系怎么走。
· ③段(`ui/` 下的产物与 `DESIGN.md`)—— 画页面结构与操作动线:用户办成一件事实际经过哪几页、每页做什么、哪里要来回跳。
· ④段(产品文档)—— 画页面结构图(各页面与其下的功能编号)+ 用户路径:各场景怎么串起来。
· 跨段 `专题/` —— 按该篇讲什么定:讲方法画方法的分层或步骤,讲盘点画对比矩阵,讲落地画数据流或结构。
- **一份文档一张自己的图**:图要对着这份文档的内容画,⛔ 不借用兄弟文档的图(借用必然出现「图说别的、文说这个」)。
- 画图用 `diagram-design`,⛔ 不手写 Mermaid(判据见「工具选择规则」那张表)。
- 图里每格写清名字、线标方向;图与正文互相对得上 —— 正文新增或改了结构,图要跟着改,两处不许各说各的。
- **收口跑机检**:`python scripts/check_figures.py --ws <工作区或产品根>`。它逐份扫 `产品规划/` 下除 `归档-过期版/` 的 md,判定三件事:开头 8 行内有 `![…](…)`、引用的图文件在位、同一张图没有被两份文档共用。报 FAIL 就不算收口。
## 每段的标准收尾格式
@@ -6,12 +6,12 @@ agent_created: true
# design-capture · 网站设计风格抓取(③段独立工具)
把「一个网址」变成「一套可选样式模板」:抓源站 → 落原始设计系统 → 生成 `design-system-<名>/` 模板包(与 `assets/design-systems/design-system-tiaoyue/` 同构),随后可被 D1 定调当普通样式套用。
把「一个网址」变成「一套可选样式模板」:抓源站 → 落原始设计系统 → 生成 `design-system-<名>/` 模板包(与③段**样式套目录**里那套 `design-system-tiaoyue` 同构),随后可被 D1 定调当普通样式套用。
## 一、什么时候用
- 用户说「**获取 XXX 网站的设计风格**」「抓这个网站的配色/字号/组件」「按这个网站新建一套样式」。
- ③段 D1 定调时,现有 `assets/design-systems/` 里没有合适的套 → 从某个标杆网站**现场新建一套**。
- ③段 D1 定调时,现有**样式套目录**(落点见本技能 `references/manifest.md` 的「样式套目录」行)里没有合适的套 → 从某个标杆网站**现场新建一套**。
## 二、怎么用(两步)
@@ -31,7 +31,7 @@ python scripts/build_style_package.py --raw raw.json --out ./design-system-<名>
- 产出:`SKILL.md` + `assets/tokens.css`(+`tokens-dark.css`)+ `assets/brand.json` + `references/{components.md,library.json,design-system.html,capture-notes.md}`。
第三步 · 装进样式库(供 D1 选用)
把生成目录整体放进 `assets/design-systems/design-system-<名>/`,即成为可选样式;③段 D1 定调时与 open-design 的套**同权,每次只选一套**。
把生成目录整体放进**样式套目录**(落点见本技能 `references/manifest.md` 的「样式套目录」行)下的 `design-system-<名>/`,即成为可选样式;③段 D1 定调时与 open-design 的套**同权,每次只选一套**。
## 三、边界(如实登记)
@@ -4,7 +4,7 @@
design-capture · 设计系统模板生成器(③段工具)
做什么:把抓取 raw JSON(capture_design_system.mjs 的产出)转成一套「可选样式」模板包,
与 skills/.../assets/design-systems/design-system-tiaoyue/ 同构,可直接被 D1 定调选用。
与③段**样式套目录**里那套 design-system-tiaoyue 同构(落点见技能内 references/manifest.md),可直接被 D1 定调选用。
输出(默认写入 --out 目录):
SKILL.md 规范总纲(含七语义色、排版、几何、组件用法、生成步骤)
+58
View File
@@ -0,0 +1,58 @@
# manifest · 资源索引(product-planning)
> **这一份管什么**:本包「有哪些资源、落在哪、被谁引用」的**唯一登记处**。
> 散文与段文档里**只写资源名**(本表第一列),路径**只在本表写一次** —— 目录一搬,只改这一行。
> **机检**:改完包跑
> `python "<技能根>/session-mechanism/scripts/check_resource_index.py" --pkg "<本包根>"`
> (两包共用一份实现,⛔ 不各写一份)。它做双向对账:落点是否存在 / 登记的引用点是否为真 /
> 是否有人绕开本表在别处写路径字面量 / 有没有登记了却没人用的资源。
>
> **`口径` 列**:`只写一次` = 该资源的路径字面量只许出现在本表与 `许可字面量` 列登记的文件里,
> 出现在别处机检直接报 🔴(这就是「避免资源到处引用」的硬闸门);
> `可多次` = 只登记「谁在用、在哪」,不限字面量(代码路径、规程路径这类必须精确到文件)。
>
> **`被谁引用` 与 `许可字面量` 别混**:前者是「谁在用」,可由机检 `--sync-refs` 自动回写;
> 后者是「谁被允许写路径字面量」,**人工开的口子**,⛔ 自动回写会把它冲成「谁都许可」、G3 就变空闸门。
>
> **加新资源**:在本表加一行即可。引用它的地方写资源名,⛔ 不要把路径抄进散文 ——
> 抄进去就会成为下一处「改目录要改 N 个地方、漏一处还不报错」。
| 资源 | 落点 | 干什么 | 被谁引用 | 许可字面量 | 口径 | 入仓 |
|---|---|---|---|---|---|---|
| 样式套目录 | `references/stage-delivery/assets/design-systems/` | ③段自带设计套(每个项目只选一套;tiaoyue 那套在此) | SKILL.md、assets/design-capture/SKILL.md、assets/design-capture/scripts/build_style_package.py、references/stage-delivery/SKILL.md、references/stage-delivery/references/execution-runbook.md、references/stage-requirements/SKILL.md | `references/stage-delivery/references/execution-runbook.md` | 只写一次 | 否 |
| 工具箱·diagram-design | `assets/diagram-design/` | ②④段画图(41 种图型,MIT) | SKILL.md、assets/diagram-design/SKILL.md、assets/diagram-design/assets/example-loop-terminal.html、assets/diagram-design/references/doctor.md、assets/diagram-design/references/export-registry.md、assets/diagram-design/references/export.md、assets/diagram-design/references/import-drawio.md、assets/diagram-design/references/import-excalidraw.md、assets/diagram-design/references/import-mermaid.md、assets/diagram-design/references/onboarding.md、assets/diagram-design/references/primitive-terminal.md、assets/diagram-design/references/profiles.md(共 17 个) | — | 可多次 | 是 |
| 工具箱·design-capture | `assets/design-capture/` | 抓网站设计风格(色彩 / 排版 / 组件) | SKILL.md、assets/design-capture/ATTRIBUTION.md、assets/design-capture/SKILL.md、assets/design-capture/scripts/build_style_package.py、assets/design-capture/scripts/capture_design_system.mjs、references/stage-delivery/SKILL.md、references/stage-delivery/assets/design-systems/design-system-tiaoyue/assets/component-library/components.css、references/stage-delivery/references/execution-runbook.md | — | 可多次 | 是 |
| 工具箱·element-picker | `assets/element-picker/` | 浏览器里点选元素,取出 CSS 选择器与所属网页 | SKILL.md、assets/element-picker/SKILL.md、references/stage-delivery/SKILL.md | — | 可多次 | 是 |
| 工具箱·video-capture | `assets/video-capture/` | 只剩交接说明;实体是全局技能 `video-capture` | SKILL.md、assets/video-capture/ATTRIBUTION.md、assets/video-capture/SKILL.md、references/stage-delivery/SKILL.md | — | 可多次 | 是 |
| ②段模板·产品规划模板 | `references/stage-requirements/assets/产品规划模板.md` | ②段两张表的表头唯一定义处 | references/stage-requirements/SKILL.md | — | 可多次 | 是 |
| ④段模板·产品文档模板 | `references/stage-proto-doc/assets/产品文档模板.html` | ④段产品文档模板 | SKILL.md、references/stage-proto-doc/SKILL.md、references/stage-proto-doc/references/doc-area-spec.md | — | 可多次 | 是 |
| 同根技能·oil-ui-pro | `<技能根>/oil-ui-pro/` | ③段方法主线(基础层设计系统 / 评分循环) | SKILL.md、references/stage-delivery/SKILL.md、references/stage-delivery/references/execution-runbook.md、references/stage-delivery/references/layouts-tooling.md | — | 可多次 | 是 |
| 同根技能·open-design | `<技能根>/open-design/` | ③段模板与 craft 判据 | assets/design-capture/ATTRIBUTION.md、assets/design-capture/SKILL.md、assets/design-capture/scripts/build_style_package.py、assets/design-capture/scripts/capture_design_system.mjs、references/stage-delivery/SKILL.md、references/stage-delivery/assets/design-systems/design-system-tiaoyue/assets/brand.json、references/stage-delivery/assets/design-systems/design-system-tiaoyue/assets/tokens.css、references/stage-delivery/assets/design-systems/design-system-tiaoyue/references/capture-notes.md、references/stage-delivery/assets/design-systems/design-system-tiaoyue/references/known-conflicts.md、references/stage-delivery/references/execution-runbook.md、references/stage-delivery/references/layouts-tooling.md | — | 可多次 | 是 |
| 同根技能·humanizer | `<技能根>/humanizer/` | 文案判据的唯一来源 | SKILL.md、references/stage-discovery/SKILL.md | — | 可多次 | 是 |
| 同根技能·browser-harness | `<技能根>/browser-harness/` | 浏览器实测 | references/stage-delivery/SKILL.md、references/stage-delivery/references/execution-runbook.md、references/stage-delivery/scripts/_common.py、references/stage-delivery/scripts/grab_selftest.py、references/stage-delivery/scripts/run_viewports.py | — | 可多次 | 是 |
| 全局技能·video-capture | `<技能根>/video-capture/` | 取视频 + 抽帧(实体件) | SKILL.md、assets/video-capture/ATTRIBUTION.md、assets/video-capture/SKILL.md、references/stage-delivery/SKILL.md | — | 可多次 | 是 |
| 机检·资源索引对账 | `<技能根>/session-mechanism/scripts/check_resource_index.py` | 本表的双向对账机检(两个技能包共用) | SKILL.md | — | 可多次 | 是 |
| ①段规程 | `references/stage-discovery/` | ①段(调研方案)流程规程 | SKILL.md、references/stage-discovery/SKILL.md、references/stage-discovery/references/grill-me.md、references/stage-requirements/SKILL.md、scripts/check_naming.py | — | 可多次 | 是 |
| ②段规程 | `references/stage-requirements/` | ②段(需求结构)流程规程 | SKILL.md、references/stage-delivery/SKILL.md、references/stage-discovery/SKILL.md、references/stage-requirements/SKILL.md、scripts/check_naming.py | — | 可多次 | 是 |
| ③段规程 | `references/stage-delivery/` | ③段(界面交付)流程规程 | SKILL.md、references/stage-delivery/SKILL.md、references/stage-delivery/references/execution-runbook.md、references/stage-delivery/references/layouts-tooling.md、references/stage-requirements/SKILL.md、scripts/check_naming.py、scripts/selftest_product_root.py | — | 可多次 | 是 |
| ④段规程 | `references/stage-proto-doc/` | ④段(说明文档)流程规程 | SKILL.md、references/stage-delivery/SKILL.md、references/stage-proto-doc/SKILL.md、references/stage-proto-doc/references/doc-area-spec.md、references/stage-proto-doc/references/guided-tour.md、scripts/check_naming.py | — | 可多次 | 是 |
| 本包脚本 | `scripts/` | 命名闸门 / 用词闸门 / 产品根自检 | SKILL.md、assets/design-capture/SKILL.md、assets/diagram-design/SKILL.md、assets/diagram-design/assets/example-beeswarm-dark.html、assets/diagram-design/assets/example-beeswarm-full.html、assets/diagram-design/assets/example-beeswarm.html、assets/diagram-design/assets/example-bubble-dark.html、assets/diagram-design/assets/example-bubble-full.html、assets/diagram-design/assets/example-bubble.html、assets/diagram-design/assets/example-bump-dark.html、assets/diagram-design/assets/example-bump-full.html、assets/diagram-design/assets/example-bump.html(共 70 个) | — | 可多次 | 是 |
## 为什么「样式套目录」被单独设成「只写一次」
用户 2026-10-16 原话:**「为什么这么多地方引用 一个样式库,是不是技能中没有统一索引机制」**。
取证(2026-10-16 实测,6 个文件、20 处路径字面量):③段 `SKILL.md` 9 处、③段运行手册 5 处、
`assets/design-capture/SKILL.md` 3 处、②段 `SKILL.md` 1 处、`assets/design-capture/scripts/build_style_package.py` 1 处、缓存 1 处。
其中「供给索引」「怎么读它」「跨段同源路径」三类引用**目的不同,本身合理**;真正的缺陷是
**路径字面量被反复手抄** —— 改一次目录要改 N 个地方,**漏一处不报错**。
⇒ 处置:路径收敛到本表这一行,散文改写资源名「样式套目录」;
**唯一保留字面量的引用点**=`references/stage-delivery/references/execution-runbook.md` 的 D−1「三处供给仍在位」检查
(那一步真的要判目录在不在,已登记在上表 `许可字面量` 列 ⇒ 机检 G3 放行它)。
## 与「技能级 `assets/`」那条口径的分工
入口 `SKILL.md` 那条红线(凡引**工具**一律写「技能级 `assets/<工具名>/`」,2026-10-16 22:57 用户令)
**继续有效**,与本表不冲突:那条规定的是**引用工具时写什么形态**,本表登记的是**这些资源落在哪、谁在用**。
⇒ 工具类资源在上表里一律 `可多次`,机检只登记、不限制字面量。
@@ -24,7 +24,7 @@ description: 产品规划第③段,界面交互。设计工程供给默认来
| 供给位 | 默认来源 | 可选来源 | 管什么 | 用在哪 |
|---|---|---|---|---|
| 方法主线 | `oil-ui-pro`(全局技能,按技能名引用) | 无 | 方向探索 → 建结构 → 取实证 → 独立评审打分 → 验证交付 | 全段;3a / 3d 最重 |
| 定调与令牌 | 自带样式库 `assets/design-systems/<选定一套>/`(随段携带,现 1 套 `design-system-tiaoyue`) | `assets/open-design/design-systems/<选定一套>/`(153 套) | 调性、全套令牌、组件形态。⚠️ **能力边界(2026-10-13 订正)**:自带样式库**不止调色板级** —— `design-system-tiaoyue/assets/component-library/`(采集于 2026-10-12)含 **9 个板块的整页快照**(`snapshot/<板块>.html`,去脚本、图片 URL 绝对化,7 个板块与线上逐像素一致率 ≥99.3%)、**345 个自有组件族**(`gallery.html` 是可视化总库,带搜索与一键复制 HTML)与**整站 CSS 原样合并**(`tiaoyue-all.css`,53 张 sheet / 1.11 MB)。⇒ **有目标产品整页快照就直接改快照当原型页**:打开对应板块的 snapshot(`snapshot/<板块>.html`)、改文案、删模块,立刻得到像素级同款的整页;要单个组件就走组件库的「复制 HTML + 引一次 tiaoyue-all.css」。⛔ 仍不许把「供给在位」读成「不必核对」:快照只反映抓取时刻,JS 运行时状态(轮播帧、滚动位置、动态 class)还原不了,那部分要在 3d 里声明为无来源。(本节 2026-10-08 的原表述「只到调色板级…不含源站的界面骨架」写在 component-library 采集之前,已过期作废。) | 3a 的 D1 |
| 定调与令牌 | 自带**样式套目录**(`<选定一套>/`,随段携带,现 1 套 `design-system-tiaoyue`;落点见 `references/manifest.md`) | `<技能根>/open-design/design-systems/<选定一套>/`(153 套) | 调性、全套令牌、组件形态。⚠️ **能力边界(2026-10-13 订正)**:自带样式库**不止调色板级** —— `design-system-tiaoyue/assets/component-library/`(采集于 2026-10-12)含 **9 个板块的整页快照**(`snapshot/<板块>.html`,去脚本、图片 URL 绝对化,7 个板块与线上逐像素一致率 ≥99.3%)、**345 个自有组件族**(`gallery.html` 是可视化总库,带搜索与一键复制 HTML)与**整站 CSS 原样合并**(`tiaoyue-all.css`,53 张 sheet / 1.11 MB)。⇒ **有目标产品整页快照就直接改快照当原型页**:打开对应板块的 snapshot(`snapshot/<板块>.html`)、改文案、删模块,立刻得到像素级同款的整页;要单个组件就走组件库的「复制 HTML + 引一次 tiaoyue-all.css」。⛔ 仍不许把「供给在位」读成「不必核对」:快照只反映抓取时刻,JS 运行时状态(轮播帧、滚动位置、动态 class)还原不了,那部分要在 3d 里声明为无来源。(本节 2026-10-08 的原表述「只到调色板级…不含源站的界面骨架」写在 component-library 采集之前,已过期作废。) | 3a 的 D1 |
| 版式骨架 | `references/layouts-tooling.md`(工具型页面用) | `<技能根>/open-design/design-templates/web-prototype/`(营销页向;工具型⛔ 不许套) | 工具型九档的名单与判读见 `references/layouts-tooling.md` §0(⛔ 本块不复述名单;2026-10-08 追加「导航栏」一档 = §4.9) | 3b |
| 工艺数值判据 | `references/execution-runbook.md` §3.4 + `references/layouts-tooling.md` §5.5 | `<技能根>/open-design/craft/`(13 份) | 字阶 / 配色 / 状态齐备 / 动效纪律 / 反 AI 味 / 无障碍。⚠️ **未选可选档时,后四项(反 AI 味 / 无障碍 / 动效纪律 / 表单校验)没有供给来源** ⇒ 必须在 3d 审查的留痕件(`产品原型/designs/3d-审查报告.md`,或用 `DESIGN.md` 的〈审查/核对〉节替代;两者都见 §3d「审计报告落盘」)里逐项显式记为**本段证据缺口**(写「无供给来源,本项未判」),⛔ 不许默不作声地跳过、也⛔ 不许拿别的判据冒充它过了 | 3a 判据、3d 终检 |
| 独立评审协议 | `oil-ui-pro` 的 `references/visual-review.md` + `references/tools.md` | 无 | 没看过制作过程的评审打分 + 截图取证 | 3d |
@@ -46,12 +46,12 @@ description: 产品规划第③段,界面交互。设计工程供给默认来
| 要什么 | 套内路径 |
|---|---|
| 入口(规范总纲、生成时的参考范围) | `assets/design-systems/design-system-tiaoyue/SKILL.md` |
| 入口(规范总纲、生成时的参考范围) | 样式套目录/`design-system-tiaoyue/SKILL.md` |
| 令牌(含暗色一套) | 同目录 `assets/tokens.css` + `assets/tokens-dark.css`(色值原始记录 `assets/brand.json`) |
| 组件形态 | 同目录 `references/components.md` + `references/design-system.html`(组件族清单 `references/library.json`) |
| 已知冲突 / 取舍记录 | 同目录 `references/known-conflicts.md` + `references/capture-notes.md` |
> ⚠️ 路径怎么找,分三类写:**技能级工具箱**(`assets/design-capture/`、`assets/element-picker/`、`assets/diagram-design/`、`assets/video-capture/`,相对**本技能包根**,各段共用);**本段自带资产**(`assets/design-systems/`,相对本段 `SKILL.md`);**同根技能**写 `<技能根>/<技能名>/`(`open-design` 用 `<技能根>/open-design/...`,`oil-ui-pro` 按技能名引用)。⛔ 不按绝对路径爬、⛔ 不写死 `../` 层数(位置一变就失效且不报错)。
> ⚠️ 路径怎么找,分三类写:**技能级工具箱**(`assets/design-capture/`、`assets/element-picker/`、`assets/diagram-design/`、`assets/video-capture/`,相对**本技能包根**,各段共用);**本段自带资产**(如**样式套目录**,相对本段 `SKILL.md`,落点见 `references/manifest.md`);**同根技能**写 `<技能根>/<技能名>/`(`open-design` 用 `<技能根>/open-design/...`,`oil-ui-pro` 按技能名引用)。⛔ 不按绝对路径爬、⛔ 不写死 `../` 层数(位置一变就失效且不报错)。
> 🔴 定调来源唯一:每次设计只选一套,默认与可选**不混用**(混用 = 没有调性)。套名与选择理由写进 `DESIGN.md`。
> ⛔ 判据正文仍只在本段(`references/execution-runbook.md` 与 `references/layouts-tooling.md`)。⚠️ 供给是分层的,分层定义见 §供给:`oil-ui-pro` 是**基础层**,本段自有判据是**叠加层**;同一条判据两处都有且口径不同时,⛔ 本段不许放宽基础层,只许更严、更具体,并在 runbook §3.4 标注「本项目追加」。
> ⛔ 不许把 `oil-ui-pro` 的评分循环当成 D 阶段的替代:它是评审方法,Gate-1/2/3 该过还得过。
@@ -122,9 +122,9 @@ description: 产品规划第③段,界面交互。设计工程供给默认来
> ⚠️ 3b 只取 §供给·版式骨架 的默认档。可选档那套(`web-prototype`)是营销落地页向,只在判「要不要套它的流程」时读。
> ⚠️ 本表只写「哪一步取哪个供给位」,⛔ 不写路径、不写默认判断 —— 那些只在 §供给 定义一次。
> 本段 `references/` 只放流程规则,⛔ 不放风格;随段携带的样式风格一律放 `assets/design-systems/<套>/`(🔴 2026-10-07 用户令两条:「把 `design-system-tiaoyue` 整合到 `product-planning` 作为一种样式风格」+「后续可以添加多种风格,每次只能选择一种进行设计」⇒ 只把「不放风格」这条放宽到 `assets/`,`references/` 仍不放)。
> ⚠️ `assets/design-systems/` 下的套**不入技能仓**(🔴 2026-10-16 用户令:`design-system-tiaoyue` 整个文件夹不提交,理由=体积 14 MB 且可 CDP 重采)—— 新机器取仓后这一层是空的,属正常;要用自带套就按本文件 §供给 的说明另取,或按套内 `references/capture-notes.md` 重采。
> ⚠️ 续加新风格时的硬要求:目录名与可选档同形(`assets/design-systems/<套名>/`),套内自带入口文件(`SKILL.md` 或 `DESIGN.md`);⛔ 不许改已入套的文件内容,原样搬入、只在本文件登记去向。
> 本段 `references/` 只放流程规则,⛔ 不放风格;随段携带的样式风格一律放**样式套目录**下的 `<套>/`(落点见 `references/manifest.md`)(🔴 2026-10-07 用户令两条:「把 `design-system-tiaoyue` 整合到 `product-planning` 作为一种样式风格」+「后续可以添加多种风格,每次只能选择一种进行设计」⇒ 只把「不放风格」这条放宽到承载资产的 `assets/`,`references/` 仍不放)。
> ⚠️ **样式套目录**下的套**不入技能仓**(🔴 2026-10-16 用户令:`design-system-tiaoyue` 整个文件夹不提交,理由=体积 14 MB 且可 CDP 重采)—— 新机器取仓后这一层是空的,属正常;要用自带套就按本文件 §供给 的说明另取,或按套内 `references/capture-notes.md` 重采。
> ⚠️ 续加新风格时的硬要求:目录名与可选档同形(`<套名>/`,落在**样式套目录**下),套内自带入口文件(`SKILL.md` 或 `DESIGN.md`);⛔ 不许改已入套的文件内容,原样搬入、只在本文件登记去向。
> 🔴 定调来源唯一(两档见 §供给·定调与令牌):每次设计只选一套,⛔ 不许混用两档(混用 = 没有调性)。套名与选择理由写进 `DESIGN.md`。
> 既有项目中凡引用旧风格来源(`minimalist-ui` / 皮肤族 / `ui-ux-pro-max` 检索结果)的 `DESIGN.md` 行,重跑 3a 时一律改写为选定套 + 留痕对照。
@@ -195,7 +195,7 @@ Gate-1 方向门(硬闸,不可跳)——按本表逐项自检(字段定
⚠️ 两份工具型文件的分工(2026-10-05 补):本技能 `references/layouts-tooling.md` 给可粘贴 HTML 骨架 + 逐条判据正文(§5.5),是默认档;选了可选档时,它那份 `tooling.md` 另给四形态判定句 + 通用红线纲要,只作指路。⛔ 判据只在 `layouts-tooling.md` 展开,`tooling.md` 只指路,两处展开必然漂。
形态判定一句话:页面上能数出「并列的同类记录」⇒ 列表型(工具型默认首选);数不出、页面围绕单个对象展开 ⇒ 详情型;主操作要在两个工作面之间来回 ⇒ 侧区型。
⛔ 不许拿营销页骨架顶替工具型,那是「没做形态判定」的默认行为,等于退回 18 轮前的病根。判不出形态就去改 D0 的 `结构骨架` 字段,⛔ 不许随手挑一个。
- ⭐ 先看供给里有没有**目标产品整页快照**(`assets/design-systems/<选定套>/assets/component-library/snapshot/<板块>.html`):有 ⇒ 复制快照当原型页,改文案、删模块;没有 ⇒ 才判页型挑骨架。⛔ 不许从零手写 `<section>`。用了可选档时,可选档那套的 `layouts.md` 开头的类清单(`section` / `container` / `card` / `btn-primary` / `grid-3` …)必须在种子 `template.html` 的 `<style>` 里存在;缺哪个就补进 `<style>`,⛔ 不许在标签上内联一堆临时样式。
- ⭐ 先看供给里有没有**目标产品整页快照**(**样式套目录**/`<选定套>/assets/component-library/snapshot/<板块>.html`,落点见 `references/manifest.md`):有 ⇒ 复制快照当原型页,改文案、删模块;没有 ⇒ 才判页型挑骨架。⛔ 不许从零手写 `<section>`。用了可选档时,可选档那套的 `layouts.md` 开头的类清单(`section` / `container` / `card` / `btn-primary` / `grid-3` …)必须在种子 `template.html` 的 `<style>` 里存在;缺哪个就补进 `<style>`,⛔ 不许在标签上内联一堆临时样式。
- 输出形态分两种,按当前项目的产出契约选:
· **往目标产品里加功能**(本项目=这种)⇒ 产出契约=**可移植目录**:目录内全部相对引用、双击可开、不依赖外部服务;明确允许引目标产品的整站样式表(如 `tiaoyue-all.css`)与同目录 `assets/`,整目录同层交付,⛔ 不许只交单个 html。
· **无目标产品、独立新做** ⇒ 单文件档:单文件 HTML、自包含、双击可开(与 `web-prototype` 的产出契约一致:只有 `index.html` 一个文件)。
@@ -35,7 +35,7 @@
> ⚠️ 2026-10-02 已重接必读源。原必读表指向 `ui-page-design/references/02_~05_*.md` 与 `vendor/*`,该目录实测已不在磁盘上(工作区与全局技能根两处都查过),照旧表走 D0 读不到任何一份必读文档。现改为引同根技能 `<技能根>/open-design/`与技能 `oil-ui-pro`(按技能名)。
> 改动原则:判据类全部交出去,只保留 craft 没有对应的东西。
开工前必读供给的位置与分工:默认档是 `oil-ui-pro`(入口 `SKILL.md`)+ 本段自带样式库 `assets/design-systems/`;选了可选档时,另读它的 `craft/README.md`(读一份就知道有哪些规约、怎么按需取)。定义与行名见本段 `SKILL.md` §供给。
开工前必读供给的位置与分工:默认档是 `oil-ui-pro`(入口 `SKILL.md`)+ 本段自带**样式套目录**(落点见 `references/manifest.md`);选了可选档时,另读它的 `craft/README.md`(读一份就知道有哪些规约、怎么按需取)。定义与行名见本段 `SKILL.md` §供给。
其余不许一次全读。同一时刻只读 1~2 份,用完释放;`design-systems/` 153 套、`craft/` 13 份全读必然互相稀释。
@@ -80,7 +80,7 @@
| 步 | 动作 | 验收判据 |
|---|---|---|
| −1 | 确认三处供给仍在位:`design-systems/`(并记录本项目选定套名)、`craft/`、`design-templates/web-prototype/` 都存在 | 三处都在位;`DESIGN.md` 记录的上次套名已找到 |
| −1 | 确认三处供给仍在位:**样式套目录**(`references/stage-delivery/assets/design-systems/`,并记录本项目选定套名)、`craft/`、`design-templates/web-prototype/` 都存在 | 三处都在位;`DESIGN.md` 记录的上次套名已找到 |
| −1b | 套名一致 → 直接进 D0 | 开工声明里写一句「选定套 `<套名>`,与项目记录一致」 |
| −1c | 套名不一致或供给缺失 → 停下报告,不许拿别的套顶上,也不许凭记忆写风格 | 产出供给变更清单(逐条:变了什么 → 本项目现状 → 要改什么),在会话里呈现并获用户确认后才改 `DESIGN.md` |
@@ -146,7 +146,7 @@
> 2. **版式结构**:选定套里记「外壳怎么分(侧栏/顶栏/主区)」「内容区用列表还是卡片网格」的那份。
> 3. **组件族**:选定套里列组件族与样张的那份。
>
> ⛔ **文件名随档而异,按该套目录里实际有的读**:本包默认档那套(`assets/design-systems/design-system-tiaoyue/`)
> ⛔ **文件名随档而异,按该套目录里实际有的读**:本包默认档那套(**样式套目录**/`design-system-tiaoyue/`)
> 给组件的是 `references/components.md`(组件族)+ `references/design-system.html`(样张),
> 它**没有** `components.html` —— 那是**可选档 153 套**的命名。
> 🔴 2026-10-08 实测事故:D1 步骤原写 `components.html` ⇒ 在默认档里**按名字找不到** ⇒ 那一次只取到了
@@ -112,7 +112,7 @@ description: 产品规划第②段,产品功能。只做一件事:把①段
本份专管界面骨架,⛔ 不写功能条目的有无与优先级(那是 `2a-产品功能.md`)。一句话分工:`2a` 管「做哪些事」,`2b` 管「这些事落在哪几页、每页长什么结构」。
🔴 **骨架怎么来(2026-10-16 补)**:现读**目标产品整页快照**再挑板块 —— 路径与③段同源:`references/stage-delivery/assets/design-systems/<选定套>/assets/component-library/snapshot/<板块>.html`。②段从快照的板块集里**挑**(挑哪几块、怎么排),③段按挑好的骨架**做**;板块名一律照抄快照,⛔ 不许自造(第 1 轮返工的病根就是自造 `nav-item` × 21)。本项目真正用到的快照是 `snapshot/script.html`:选不到对应板块时,写明用的是哪一份快照、为什么。
🔴 **骨架怎么来(2026-10-16 补)**:现读**目标产品整页快照**再挑板块 —— 路径与③段同源:③段**样式套目录**/`<选定套>/assets/component-library/snapshot/<板块>.html`(落点见 `references/manifest.md`)。②段从快照的板块集里**挑**(挑哪几块、怎么排),③段按挑好的骨架**做**;板块名一律照抄快照,⛔ 不许自造(第 1 轮返工的病根就是自造 `nav-item` × 21)。本项目真正用到的快照是 `snapshot/script.html`:选不到对应板块时,写明用的是哪一份快照、为什么。
| 问 | 回答 | 内容 |
|---|---|---|
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python
"""产品规划文档的「开头必须有图」机检(单一真源:SKILL.md §产出文档开头必须有图)。
用法:
python scripts/check_figures.py --ws <工作区或产品根>
判定三件事(任一不过即 FAIL):
① 每份落盘 md(`产品规划/` 下,排除 `归档-过期版/`)开头 8 行内有 `![…](…)`
② 引用的图文件在位(相对该 md 所在目录解析)
③ 同一张图没有被两份文档共用(一份文档一张自己的图)
输出:逐份一行;末尾给 PASS/FAIL 与计数。退出码 0=全过,1=有 FAIL。
"""
import argparse
import re
import sys
from pathlib import Path
SKIP_DIRS = {"归档-过期版", "node_modules", ".git"}
FIG_RE = re.compile(r"!\[[^\]]*\]\(([^)\s]+)")
def fmt(p: Path) -> str:
try:
return str(p.relative_to(p.anchor and Path(p.anchor) or Path(".")))
except Exception:
return str(p)
def resolve_product_root(ws: Path) -> Path | None:
"""认产品根:自身含 产品规划/ 即产品根;否则在 项目/<名>/ 或下一层里找唯一一个。"""
if (ws / "产品规划").is_dir():
return ws
cands = [d for d in (ws / "项目").glob("*") if (d / "产品规划").is_dir()] if (ws / "项目").is_dir() else []
if not cands:
cands = [d for d in ws.glob("*/产品规划") if d.is_dir()]
cands = [d.parent for d in cands]
if len(cands) == 1:
return cands[0]
if not cands:
return None
print("⚠️ 找到多个候选产品根,请直接传产品根路径:")
for c in cands:
print(" ", c)
return None
def head_lines(p: Path, n: int = 8) -> list[str]:
out = []
try:
with p.open(encoding="utf-8", errors="replace") as f:
for line in f:
if line.strip():
out.append(line.rstrip("\n"))
if len(out) >= n:
break
except Exception as e:
print(" 读取失败:%s" % e)
return out
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--ws", required=True, help="工作区根或产品根")
a = ap.parse_args()
root = resolve_product_root(Path(a.ws).resolve())
if root is None:
print("FAIL 认不出产品根:%s" % a.ws)
return 1
base = root / "产品规划"
print("产品根 = %s" % root)
docs = [p for p in base.rglob("*.md")
if not (set(p.parts) & SKIP_DIRS)
and not p.name.startswith(("索引", "本轮回报"))]
docs.sort()
if not docs:
print("FAIL 产品规划下没有 md 文档")
return 1
used: dict[str, list[Path]] = {}
fails = 0
for d in docs:
rel = d.relative_to(root)
hit = None
for line in head_lines(d):
m = FIG_RE.search(line)
if m:
hit = m.group(1)
break
if not hit:
print(" ❌ 无图 %s(开头 8 行没有 ![..](..))" % rel)
fails += 1
continue
target = (d.parent / hit).resolve()
if not target.exists():
print(" ❌ 图不在位 %s → %s" % (rel, hit))
fails += 1
continue
key = str(target).lower()
used.setdefault(key, []).append(rel)
print(" ✅ %s → %s" % (rel, hit))
shared = {k: v for k, v in used.items() if len(v) > 1}
for k, v in shared.items():
names = "、".join(str(x) for x in v)
print(" ❌ 图被共用 %s 被 %d 份文档共用(%s)" % (Path(k).name, len(v), names))
fails += len(v) - 1
print("—" * 40)
print("文档 %d 份,图 %d 张,问题 %d 处" % (len(docs), len(used), fails))
if fails:
print("FAIL")
return 1
print("PASS")
return 0
if __name__ == "__main__":
sys.exit(main())