mcpField
E
extract

extract

github.com/adobe设计与 UI316508 次安装今天更新
代码仓库

关于 extract

extract 是 Stardust 的网站采集技能,面向需要了解现有网站页面与品牌表现的设计和迁移工作。它用浏览器抓取页面并生成当前状态快照,不制定设计方向,也不修改线上网站。

主要功能

  1. 01发现并筛选网站页面
  2. 02使用 Playwright 渲染采集页面
  3. 03提取品牌表面与页面内容
  4. 04写入当前状态快照和采集日志
  5. 05支持限定页面、数量及品牌来源

适用场景

  1. 01为网站重设计建立现状快照
  2. 02采集迁移所需的页面内容与动态信号
  3. 03比较同品牌多个网站的品牌表现
  4. 04针对指定路径刷新页面快照

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/adobe/skills --skill extract

安装后在 Claude Code 中输入/extract确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
brand-review-template.md
brand-surface.md
cross-site-sources.md
current-state-schema.md
ia-extraction.md
playwright-recipe.md
prep-mode.md
scripts/
crawl.mjs
style-census.mjs
thumb.mjs
scripts/test/
crawl.test.mjs
style-census.test.mjs
thumb.test.mjs

详细介绍

stardust:extract

抓取现有网站,解析每个页面,提取品牌表层, 并在 stardust/current/ 下生成采用 stardust 格式的当前状态快照。输出描述网站是什么;后续子命令会使用它来决定网站应该是什么。

此技能具有描述性:不会设定方向,不会进行批评,也不会修改线上网站。它只会写入 stardust/current/,并更新 stardust/state.json。

输入

  • <url> — 必填。要抓取的网站源站。例如:https://example.com、 https://example.com/shop。路径会将同源抓取范围缩小到 该子树。
  • --cap <N> — 可选。覆盖默认的 5 页上限。上限有意设得较小—— 5 页样本(主页 + 四个信息架构 支柱/模板)足以进行跨页面品牌聚合、 系统组件检测以及品牌审查 HTML 的生成;确有需要进行更深入的抓取时, 可提高上限(例如 --cap 25)。
  • --all — 可选。完全取消上限;过滤掉无用页面后,提取所有 已发现的页面。等同于 --cap 0。 用户临时要求完整抓取时使用。
  • --pages <slug,slug,...> — 可选。将抓取范围限制为指定 路径(根据 reference/ia-extraction.md 推导出的 slug)。绕过 上限。
  • --refresh <slug> — 可选。重新提取 state.json 中已存在的一个页面。
  • --single — 可选。等同于 --cap 1。适用于测试。
  • --wait <fast|medium|spec|auto> — 可选。每页的等待策略。 默认为 medium。参见 reference/playwright-recipe.md § 等待模式。
  • --no-junk-filter — 可选。在发现阶段禁用默认的无用页面过滤器 (参见 reference/ia-extraction.md § 过滤)。
  • --no-consent-dismiss — 可选。跳过预检时对同意提示 / Cookie 横幅的关闭操作(参见 reference/playwright-recipe.md § 预检:关闭同意提示)。适用于改版范围包含同意提示界面的情况,或必须 避免关闭操作产生的副作用(激活原本不会运行的脚本)的情况。 默认会关闭提示,以免横幅影响截图、语气 聚合和各区块的样式。
  • --dynamics — 可选,仅限迁移。在每个页面 JSON 的 dynamic 部分记录动态表层的可达性 信号(数据端点、表单、模态框触发器、播放器 ID),并汇总到 _crawl-log.json#dynamicSurface 中。 由 prepare-migration、replica 和 migrate 的安全网设置;不会由 单独执行的 extract、uplift 或 audit 设置——动态内容属于迁移范畴。 深度和分类由 stardust 的 dynamics 技能负责。
  • --concurrency <n> — 可选。用于逐页捕获循环的并行浏览器上下文数量。默认为 4; 合理范围为 4–8。参见 § 并发。
  • --brand-source <url> — 可选,可重复指定。额外的同品牌源站,其品牌表层会补充主要 提取内容(浅层捕获:主页 + 最多 2 个导航链接页面)。 参见 § 跨站点品牌来源。
  • --design-source <url> — 可选。设计供体源站:其 设计系统会捕获到 stardust/canon-source/,并作为固定的改版目标;主要源站则提供 内容。参见 § 跨站点品牌来源。
  • --prep — 可选。以 migrate-prep 模式运行:取消上限, 为每个页面分类,检测模块候选项,捕获有类型的内容槽位,输出预备摘要。参见下文的预备模式。通常通过 prepare-migration 编排技能 调用,而不是直接调用。

设置

先运行主技能的设置流程 (skills/stardust/SKILL.md § 设置):检查 impeccable 依赖项、 加载上下文、读取状态。

此子命令的其他检查:

  1. Playwright 可用性。提取步骤需要真实的浏览器。按以下顺序检测 Playwright:先检测 Playwright MCP 服务,再检测项目可导入的 playwright 模块。npx playwright 探测并不足够——它只能确认 CLI 可用(CLI 会解析全局安装),但配方和 scripts/crawl.mjs 使用 import { chromium } from 'playwright',而 ESM 模块解析不会使用全局安装或 NODE_PATH——即使 npx playwright --version 成功,导入仍会抛出 ERR_MODULE_NOT_FOUND。确认从项目根目录可以解析导入该模块(探测命令:node -e "import('playwright').then(()=>process.exit(0))");如果无法解析,请先运行 npm i -D playwright pixelmatch pngjs cheerio --legacy-peer-deps(安装为开发依赖,切勿使用 --no-save——#125),或使用 Playwright MCP 服务,然后再进行爬取。在 aem-boilerplate 目标项目上必须使用 --legacy-peer-deps 标志(这些项目固定使用 eslint@8,不加该标志时,普通的 npm i 会在考虑 playwright 之前就以 ERESOLVE 退出)。不要只相信 CLI 探测结果。

    **--no-save 安装是临时的。**之后任何真正的 npm i(例如添加开发依赖的设置步骤)都会清理不在清单中的包,悄无声息地在流水线运行中途移除 playwright。所有后续会进行渲染的技能(prototype、migrate、deploy、diff)都必须在各自运行开始时重新执行导入可解析性探测,失败时重新安装,而不能假设 extract 安装的依赖仍然存在。

    **脚本位置很重要。**ESM 会从脚本所在目录解析 import 'playwright',而插件目录中不包含 node_modules:请将每个脚本逐字节复制到项目中(stardust/scripts/…),并运行副本。 内置爬虫。 skills/extract/scripts/crawl.mjs 是此子命令的 可运行参考实现,涵盖浏览器配置 + 机器人管理回退、关闭同意提示、 等待 + 滚动、捕获列表、逐页全页截图 (assets/screenshots/<slug>.png,由第 2.5 阶段的 视觉检查使用)、响应验证,以及 § 捕获卫生强化(可见性筛选、丢弃拦截页、 SPA 外壳标记、模态框 textContent 捕获、跟踪像素 降权、跨页面重复检测)。优先调用它,而不是每次都 手写 Playwright 脚本;扩展其页面内的 capture(),以涵盖尚未输出的任何配方字段。

  2. 源站冲突。 如果 stardust/state.json 已记录 site.originUrl,而新的 <url> 属于不同源站,请停止并 先询问,再覆盖现有内容。Stardust 不会在一个项目中 静默混合两个网站。 流程防护(仅限迁移请求)。 如果请求包含迁移意图(“migrate”、“to EDS”、“re-platform”、“1:1”、“replica”),且 stardust/state.json 已存在——或即将创建——但没有 flow,请在爬取前交回主技能 § 两种迁移流程:流程应在该处选择并写入;保留设计的请求通过 replica 进入(它会自行调用此技能并传入 --prep)。用于重新设计、审核或升级的普通 extract <url> 不受影响。(记录:在同设计迁移中,将原始 URL 上的 extract 作为入口;随后 Agent 在 replica 旁构建了自己的导入器。)

  3. 浏览器上下文。 为每个捕获工作线程打开一个新的 BrowserContext(§ 并发;默认值为 4)。按照 reference/playwright-recipe.md § 预检执行同意提示关闭预检:关闭同意提示,除非设置了 --no-consent-dismiss。 Cookie 会在同一上下文中保留,但不会跨上下文保留—— 因此需在每个上下文中重新建立同意状态(在工作线程的 首个页面上重新执行关闭操作,或克隆探测上下文的 storageState)。将解析后的方法记录在 _crawl-log.json#consent.method 中。

  4. 机器人管理探测。 如果本次运行中的首次导航返回 ERR_HTTP2_PROTOCOL_ERROR 或 ERR_QUIC_PROTOCOL_ERROR, 或者在原本应快速响应的源站上一直挂起,直至达到整个硬性上限,不要在无头模式下重试——按照 § 失败模式 → 机器人管理拦截切换到有头 Chrome,并将切换记录在 _crawl-log.json#discovery.fetchTechnique 中,以便重跑时直接以有头模式启动,无需再次发现此问题。

流程

阶段 1 — 发现

在爬取前发现页面清单。流程见 reference/ia-extraction.md。概要如下:

  1. 获取 <origin>/sitemap.xml,然后获取 <origin>/sitemap_index.xml, 再检查 robots.txt 中的 Sitemap: 指令。

  2. 如果无法访问站点地图,则从 <url> 开始执行同源 BFS 爬取,深度限制为 3,并从渲染后的 HTML 中提取链接。

  3. 过滤发现的 URL 列表:仅保留同源 URL,排除 mailto:、tel:、仅锚点链接、仅查询参数不同的链接、 常见资源路径(.css、.js、.pdf、图片扩展名)。

  4. 去重末尾斜杠不同的 URL。

  5. 应用垃圾页面过滤器(reference/ia-extraction.md § 垃圾页面过滤器),除非设置了 --no-junk-filter。向用户展示 过滤后的列表,以便用户覆盖选择。

  6. 应用上限(默认为 5,也可使用 --cap,或使用 --all 表示不限数量), 并静默继续。输出所保留和剔除内容的信息摘要,但不要等待用户 确认。想要更改范围的用户可以在命令执行时主动指定:

    $stardust extract https://example.com              # default 5 pages
    $stardust extract https://example.com --cap 25     # bump to 25
    $stardust extract https://example.com --all        # lift the cap
    $stardust extract https://example.com --pages home,about,pricing
    $stardust extract https://example.com --single     # just the entry URL
    

    Agent 从用户的提示中读取主动提出的范围意图(例如“提取所有页面”“只查看首页和定价页面” 或“进行完整爬取”),并应用等效的标志。意图明确后无需再次确认。

    信息性输出(不是提示——应立即继续):

    Discovered 38 pages on https://example.com (sitemap.xml).
    Filtered as likely junk (5): /test/, /sample-page/, /holiday1/, ...
    Selecting 5 highest-priority pages:
      - / (home)
      - /about
      - /pricing
      - /products
      - /contact
    
    Cut (28 pages, --all to lift): /blog/post-1, /blog/post-2, ...
    
    Extracting...
    

    选择启发式:优先使用页面类型清单,然后按分数排序(首页 + IA 支柱关键词 + 站点地图优先级 − 归档 / 版本标记)。上限的优先级规则见 reference/ia-extraction.md § 页面选择和 § 优先级。 仅包含英文的关键词列表对于本地化网站而言是已知限制。

  7. 将发现的列表写入 stardust/current/_crawl-log.json (若文件不存在则创建),其中包含 _provenance 和完整的发现推理过程,包括 filteredAsJunk[] 和 userChoice。这是审计记录,不是状态文件。

阶段 2 — 逐页提取

对于符合数量上限的列表中的每个页面,按照 reference/playwright-recipe.md 使用 Playwright 进行渲染。根据 § 并发, 并发执行截图。每个页面都必须遵循该流程——尤其不得跳过等待、滚动或 截图列表步骤:

  • 视口为 1440 × 900 @ 2× DPR
  • 按配置的等待模式等待(默认为 medium;参见 reference/playwright-recipe.md 中的 § 等待模式)
  • 通过 prefers-reduced-motion: reduce 禁用动画
  • 等待结束后,以 4 个视口高度为步长滚动到底部,每步暂停 300 ms,然后返回顶部——此步骤对于触发延迟加载和由 IntersectionObserver 驱动的内容是必需的
  • 在每页的 _provenance 中记录 waitMs 和 waitMode

每页截图(完整模式见 reference/current-state-schema.md):

  • 页面元数据(标题、meta 描述、OG 标签、主题颜色)

  • 语义结构:标题大纲、地标角色、各个区块

  • 主视觉标题 + 导语(已解析)——heroHeadline / heroLede 根据字号 × 主视觉区域选取,并过滤无关内容和隐藏状态;如果无法选取,则使用干净的 meta 描述作为回退(依据 reference/playwright-recipe.md § Capture list 5-bis)。适用于由 JS 渲染的网站:此类网站按文档顺序排列的标题可能显示的是模态框 / 促销内容 / 计数器等无关内容, 而非真正的标语。

  • 内容:各区块中的可见文本(完整的 innerText,不截断,依据 reference/playwright-recipe.md § Capture list 7)、结构化段落(body[])、列表、常见问题问答对,以及评论 / 推荐语引文(依据 § Capture list 7-bis)。如果没有这些结构化字段, 迁移时标题下的所有正文区域都会回退为占位符签名。

  • CTA 标签和 href 目标、链接清单(内部与外部)

  • 各区块的计算样式摘要:主色、使用中的字体系列、间距规律、圆角、阴影

  • 媒体清单:捕获 img 的 currentSrc / srcset,保留查询字符串,并附上 resolves 标志(使用浏览器 UA + Referer 发起 HEAD/GET 请求)、固有尺寸、内联 SVG 计数、视频 / iframe 是否存在、cssBackgrounds[](包括依据 § Capture list 11 遍历伪元素 ::before / ::after),以免 background-image 主视觉和装饰图案悄然消失,并在迁移发布 about:error 之前标记返回 404 的 CDN 图片。

  • 通过网络拦截捕获字体文件(依据 § Capture list 16):将每个 woff2 / woff / ttf / otf 响应保存到 assets/fonts/,并在 _brand-extraction.json#type.files[] 中记录, 同时标明许可状态。

  • 图标字体检测(依据 § Capture list 17):当页面使用 [class^="icon-"],且其 ::before 的字体系列不是默认值并包含码点时,捕获字体系列、保存文件, 并在 _brand-extraction.json#iconFont 中记录 iconClass → codepoint 对照表。

  • 交互元素:表单(含字段类型)、按钮、通过 ARIA 角色检测到的模态框

  • 全页截图保存到 assets/screenshots/<slug>.png — 由捆绑爬虫在等待 / 滚动稳定后通过脚本捕获(对于极高的页面,回退为仅视口截图;模式记录在 _signals.screenshotMode 中,相对路径记录在页面 JSON 的 screenshot 字段中)

  • 动态表层(仅使用 --dynamics 时)——每页的可达性信号:端点、第三方脚本主机、表单、模态框触发器、 播放器 ID、水合提示,记录在页面 JSON 的 dynamic 区段和 _crawl-log.json#dynamicSurface 中(架构见 reference/current-state-schema.md § Dynamic)。这些仅作为证据;stardust 的 dynamics 子技能会深入探测各种类型并作出判断。

保存到 stardust/current/pages/<slug>.json,并将 _provenance 设为 第一个键。捆绑爬虫还会将稳定后的渲染 DOM 原样保存为 stardust/current/pages/<slug>.html(等待 / 滚动稳定后调用 page.content();路径记录在记录的 renderedHtml 字段中)。只捕获一次,离线解析:每个下游导入器或同级生成器都基于此产物执行提取 — 免费、可复现且可追溯 — 而不是针对每种选择器猜测重新运行实时探测(切换前记录到:每种页面类型需进行 4 次以上实时往返)。实时探测仅用于静态 DOM 无法回答的问题:几何尺寸和计算样式。将引用的媒体保存到 stardust/current/assets/media/, 保留原文件名,并附加较短的内容哈希。 实时渲染证据(禁止合成)。 除非页面的 _provenance 包含 renderedBy: "playwright"、ISO-8601 格式的 fetchedAt、正整数 waitMs、配方中指定的 waitMode,以及处于 2xx/3xx 范围内的最终 httpStatus,否则不得在 state.json 中将页面标记为 extracted。reference/current-state-schema.md § Live-render evidence 强制执行这五个字段构成的契约,而每个下游阶段都会根据 skills/stardust/reference/state-machine.md § Provenance validation 通过 validateProvenance() 读取并验证这些字段。根据 _brand-extraction.json、URL 模式和已捕获图片合成页面记录——也就是 2026-04-30 的电商捷径——正是此保护措施旨在防止的故障模式。当 Agent(或受委派的子 Agent)无法满足某个页面的契约时,将该页面视为第 2 阶段失败:在 _crawl-log.json#crawl.failures[] 下记录 errorClass: "ProvenanceMissing",然后继续。

每成功写入一个页面后,立即在 state.json 中将其标记为 extracted。如果页面失败,在 _crawl-log.json 中记录错误并继续——提取过程尽力处理每个页面。

第 2.5 阶段 — 视觉验证

在编写任何下游内容之前,查看每个已捕获页面的截图(assets/screenshots/<slug>.png)——多模态模型会读取图像——并对照提取记录进行验证:

  • 记录中的主视觉(标题 + 素材)是否与图像像素所示内容相符?
  • 提取出的配色方案与图像像素相比是否合理?
  • cssBackgrounds: [] 这样的记录是否可信,还是画面中明显存在图像——说明捕获过程静默失败?
  • 是否捕获到了 Logo?
  • 页面是否确实已渲染——而不是同意提示页、机器人拦截页或空白的 SPA 外壳?

通过缩略图查看整个页面—— node stardust/scripts/thumb.mjs stardust/current/assets/screenshots/<slug>.png --width 480 (skills/extract/scripts/thumb.mjs,复制到 crawl.mjs 旁边;使用方框滤波缩小,因此 1 px 线条和极细边框仍会保留;默认 150 KB 的 --max-bytes 上限会先将过大的页面重新编码为更窄的图像,仅在最后才裁剪,且宽度绝不会低于页面宽度的 60 %)——切勿查看全分辨率截图;查看细节时,应裁剪完整捕获图。检查对象是整个页面:先阅读脚本输出的 stdout 行,再在其显示的比例低于 100 时(cropped at <n>px of <H> = <share>%),使用相同命令并添加 --offset <n>,同时查看 <slug>-thumb-<n>.png;重复此操作,直到 rows <n>-<end>px 行的结尾达到 <H>。一次记录在案的无人值守运行中,缩略图保留了每个页面中位数为 28 % 的内容,检查时将其作为页面进行读取。只有在 thumb.mjs 写入缩略图后(≤ 150 KB,或 stderr 指定的最低限度缩略图,退出代码为 1),该缩略图才会进入上下文;或者,视觉检查由读取缩略图并为每个页面返回一行结果的子 Agent 执行 (<slug>: ok | recaptured | suspect — <note>);一次记录在案的无人值守运行将 8 个 *-thumb.png 文件(每个 268–608 KB)读入同一个上下文——为 8 个判定输入了 3.2 MB 的像素数据。

发现不匹配时,继续之前,按升级阶梯重新捕获该页面:将等待模式提高一级(reference/playwright-recipe.md § Wait modes),然后使用带界面的 Chrome(§ Bot-management fallback),最后创建一个全新的浏览器上下文。将每个页面的结果记录在 _crawl-log.json#visionCheck[] 中:

{ "slug": "pricing", "verdict": "recaptured", "notes": "record said zero CSS backgrounds; screenshot shows a full-bleed photo hero" }

verdict 为 "ok" | "recaptured" | "suspect" 之一——suspect 表示经过升级处理后仍存在不匹配;下游阶段会将该记录视为不可靠。视觉检查是捕获检查的权威依据;启发式防护措施(低媒体标记、spaShellSuspect、重复哈希)仍可作为低成本的早期信号,但不再单独作为关卡。

第 3 阶段 — 品牌表层提取

在捕获阶段(2–2.5)之后运行。随着并发页面捕获完成,聚合可以增量进行(§ 并发),但写入的文件必须反映每个已提取页面,包括 § 跨站点品牌来源中的品牌来源页面。 根据 reference/brand-surface.md 生成 stardust/current/_brand-extraction.json。部分字段仅来自主页(徽标、语气样本、语域启发式);驱动 DESIGN.md 的视觉令牌(配色、圆角、阴影、字体)则汇总自所有已提取页面,以避免 brand-surface.md § 聚合范围中记录的主页偏差。

计算样式普查——运行随附工具;不要编写探针。 node <plugin>/skills/extract/scripts/style-census.mjs(与 crawl.mjs 一样复制到项目中,§ 设置)会测量每个已捕获页面在 1440 宽度下的样式,并写入 stardust/current/_computed-styles.json;如果断点包含 360,则添加 --width 360。再对每个页面进行一次在线检查——爬取完成后在后台运行一次;它会像其他在线工具一样通过 live-session.mjs 打开在线端。从文件的 aggregate 中读取配色、字体、图案和悬停值,并从各自的 sources[](url、selector、prop)引用来源;各页面的详细信息位于 pages[url][width] 下。

内容上限模型——运行随附探针;不要编写提取脚本(#124)。 node stardust/scripts/replica/cap-probe.mjs <archetype-url>… --write-design stardust/current/DESIGN.json(replica 的脚本;与 live-session.mjs 一起复制)会以 1440 宽度及一个推导出的宽屏宽度渲染每个原型——max(2560, 最大上限 × 1.25);在上限对应的宽度进行探测无法发现上限——并将所有停止增长的盒子(类型 shell / content / module、像素值、定义方式、层级)记录到 extensions.breakpoints:containerMaxWidth(--max-width 来源;流式布局时为 null)、probeWidth、caps[]、modules[]。普查完成后,每个原型导航一次(绝不与普查同时进行),此时 DESIGN.json 已编写完成(探针会合并内容)。无论数值如何,shell 上的上限或每个原型都有的上限都属于设计意图;capRegister 会列出单模块上限或原型间不一致的上限,供不一致项登记册使用。 上限模型绝不记录布局断点:重新设计目标保留自己的两个断点;复刻版本保留源站的断点,或将其映射到 --target-breakpoints。 捕获:

  • Logo(标志):按 v1 优先级链依次查找:内联 SVG → 带有类似 logo 的 class/id 的 <img> → apple-touch-icon → og:image → favicon → 合成占位图。保存至 stardust/current/assets/logo.<ext>。
  • Favicon——始终将其作为独立资源捕获(不依赖 logo 链),保存至 stardust/current/assets/favicon.<ext>,详见 reference/playwright-recipe.md § Favicon capture。后续,prototype 会将其嵌入建议页面的 head 中,deploy 会将其部署到 Edge Delivery 站点。
  • 配色方案——汇总所有已提取页面中计算得出的颜色(背景、文本、强调色、边框、悬停状态)。按频率排序、合并近似颜色,并输出按角色命名的列表(背景、表面、文本、主色、次要色、强调色)。
  • 字体——列出正在使用的字体系列及其字重、字号和计算得出的行高。区分标题字体系列和正文字体系列。运行模块化比例审计(brand-surface.md § Modular-scale audit),并输出 scaleAudit.kind = "modular" | "ad-hoc"。
  • 视觉特征——标志性圆角半径(跨页面非零值的众数,按元素数量加权)、阴影组合(跨页面排名前 3 的不同阴影)、渐变清单、常见模式(chip、徽章、卡片、带图像的 hero)。如果仅主页模式与跨页面模式不一致,在 _provenance.notes 中注明差异。
  • 语气样例——正文的首段、hero 标题、3 个有代表性的 CTA 标签,以及有代表性的链接列表。供之后的 direct 使用,但现在就提取,以免后续还需网络往返。
  • Hero 图像——将主页的主要视觉资源提升为 voice.heroImage(详见 reference/brand-surface.md § heroImage resolution),让下游 prototype 选用实际的 hero 图像,而非原始媒体列表中的 og:image。
  • Hero 媒介(标志性)——当 hero/首屏包含动态资源(背景 <video> / HLS / canvas / WebGL / Lottie / 动画 SVG / 滚动驱动的动态效果)时,将其提升为 voice.heroMedium(详见 reference/brand-surface.md § heroMedium resolution)。这是页面的标志性特征;如果不提升,下游 prototype 会将其简化为静态 hero。非 null 的 heroMedium 会在 prototype 阶段触发标志性特征保留(skills/stardust/reference/intent-dimensions.md § 8b)。
  • 图标字体——根据 reference/playwright-recipe.md § Capture list 17 检测到图标字体时,在 _brand-extraction.json#iconFont 中填入字体系列、文件路径,以及 iconClass → codepoint 表,以便 prototype 渲染品牌的实际图标。
  • 系统组件——跨页面重复出现的 DOM 块(站点页眉、站点页脚、交叉推广条、常驻 CTA、面包屑)。根据标题序列 + CTA 标签指纹检测,详见 reference/brand-surface.md § System components。必需——这些通常是最关键的页面区域,在重新设计目标中不得悄然消失。
  • 来源——根据 reference/brand-surface.md § Origins,在 _brand-extraction.json#origins[] 中为每个贡献来源添加一条记录。单一来源的运行输出包含一条记录的数组;品牌来源运行则按来源归属扩展后的证据。

不要臆造值。每个捕获的值都必须在 _brand-extraction.json 中注明来源选择器或 URL,以便追溯。

阶段 4 — 填充 stardust/current/PRODUCT.md 和 DESIGN.md

当前状态的 PRODUCT.md 和 DESIGN.md 是描述性文档,而非创作文档——无需进行访谈,因为用户在此处并非定义意图,而是由 Agent 描述现有网站。直接按照 impeccable 的格式规范编写(impeccable 的 skill 目录由 node <plugin>/skills/stardust/scripts/impeccable-version-check.mjs --where 输出;请按章节阅读每份规范,不要一次性通读):

  • 对于 PRODUCT.md,遵循 impeccable 的 reference/init.md § 编写 PRODUCT.md 中的章节结构。文件顺序:首先是 stardust 的 块(根据 `../stardust/reference/artifact-map.md` § 来源信息,这与此 skill 编写的每个文件一致),然后是 `# Product`,接着是原样保留的 注释,然后依次为 Platform(web)、Users、Product Purpose、Positioning、Capabilities and Constraints、Brand Commitments、Evidence on Hand、Product Principles、Accessibility & Inclusion;没有内容的章节应省略,不要凑内容。在 Brand Commitments 下记录对品牌语域的推测(看起来像营销/落地页的网站 → brand;工具/仪表板 → product;难以判断 → brand 并附注)、观察到的品牌个性,以及观察到的反面参考。Evidence on Hand 列出 stardust/current/ 下已捕获的内容及其路径。根据已捕获的文案和品牌表面信息填写 Users、Product Purpose、Positioning 和 Product Principles。凡是必须推断的地方,在该章节标记 _provenance: inferred,并用一句话说明依据。
  • 对于 DESIGN.md 和 DESIGN.json,遵循 impeccable 的 reference/document.md 中的格式规范。根据已捕获的设计令牌填写 frontmatter(colors、typography、rounded、spacing、components)。DESIGN.json 的 extensions 块应包含 v1 的 componentStyle、motifs 和 voice 数组,确保不遗漏任何信息;并逐字保留 breakpoints——即 cap-probe 尺寸模型。

Stardust 不会对当前状态文件调用 $impeccable init(以前称为 teach)或 $impeccable document:这些命令会写入项目根目录(即目标目录),并运行访谈。Stardust 会直接编写描述性快照。impeccable 的格式规范才是约定;运行时命令不是。

项目根目录中的目标状态 PRODUCT.md 和 DESIGN.md 将由 $stardust direct 在流水线的阶段 2 编写,不在此处编写。

阶段 5 — 渲染 stardust/current/brand-review.html

阶段 4 写入描述性 PRODUCT.md 和 DESIGN.md 后,按照 reference/brand-review-template.md 生成当前状态的品牌评审。

品牌评审 HTML 是人类可以首先直观检查的页面,用于在确定重设计方向前验证提取结果——JSON 中不易察觉的误读(错误的主导圆角、遗漏的系统组件、只受单页影响的调色板偏差)可以一目了然,而且此时修正成本仍然很低(重新提取很快;重新定向和重新制作原型则不然)。

模板是必需的。特别是:

  1. 运行 reference/brand-review-template.md § 检测器中列出的张力检测器。每条规则都是机械式的;只要符合触发条件,就生成一张张力卡片。如果数据太少而无法评估,评审可以不包含任何张力,但必须始终运行这些检测器。
  2. 使用品牌自身捕获的颜色和字体渲染,不要使用 stardust 外壳。
  3. 嵌入所有 CSS;除非实时网站本身已加载,否则不要加载外部 JavaScript 或字体。
  4. 为每个章节注明来源工件(例如,在「Typography」下标注 _brand-extraction.json § type)。

如果某个章节缺少数据,请省略该章节——不要编造占位内容。顶部的覆盖情况提示应反映缺失内容。

阶段 6 — 更新状态并报告

Phase 2-5 的所有写入成功后:

  1. 更新 stardust/state.json(架构见 skills/stardust/reference/state-machine.md):

    • site.originUrl、site.extractedAt、site.pageCap、 site.totalDiscovered、site.crawled
    • pages[] — 每个已爬取页面对应一条记录,status: "extracted", 填写 currentStatePath,prototypePath 和 migratedPath 留空
    • designSource — 仅在使用了 --design-source 时填写: 根据 § 跨站点品牌来源,为每项记录 { url, capturedAt, path }
  2. 打印一屏摘要:

    Extracted https://example.com (5/38 pages, sitemap.xml)
    
    stardust/current/
      PRODUCT.md, DESIGN.md, DESIGN.json, brand-review.html,
      pages/ (5), assets/logo.svg, _brand-extraction.json, _crawl-log.json
    
    Per-page evidence:
      slug         live  waitMode               waitMs   status  media(img/bg)
      /            yes   medium                 2380     200     38/6
      /pricing     yes   medium                 1940     200     9/0   ⚠ low-media
      /contact     yes   domcontentloaded(fb)   8000     200     3/0
      ...
    
    Wait summary: 4 resolved at medium (avg 2.4s), 1 fallback (timed out at 8s)
      → /contact may be under-captured; consider --refresh
    Media summary: 1 page flagged low-media (/pricing) — see media-coverage check
    Vision check: 4 ok, 1 recaptured (/pricing) — _crawl-log.json#visionCheck
    
    Open stardust/current/brand-review.html to verify the extraction
    before running $stardust direct.
    
    Coverage note: extracted 5 of 38 discovered pages; 5 pages
    covering distinct templates is usually sufficient for the
    cross-page brand surface. Widen with --cap <N> or --pages.
    
    Next: $stardust direct  (resolve a redesign direction)
    

    逐页证据表为必填项。当 _provenance.renderedBy === "playwright" 且 waitMs > 0 时,live 列为 yes,否则为 no。no 行表示该页面记录 并非由 Playwright 实时渲染生成 — 该可见列是针对写入时保护措施旨在防止的 故障模式所设的纵深防御信号(2026-04-30 电商运行)。维护者查看摘要时, 每一行都应显示 yes。

    按每个页面的 _provenance.waitMode 分组并计算 waitMs 的平均值,以此 汇总等待时间。将 waitMode 以 (fallback) 结尾的 slug 列为 --refresh 候选项(表格中为节省宽度显示为 (fb))。

    media(img/bg) 列是针对图片的类似纵深防御信号。它显示 <media.imgs 的数量> / <media.cssBackgrounds 的数量>。如果页面 看起来属于品牌/营销类(register 为 brand,或使用落地页/解决方案/ 产品模板),但 cssBackgrounds: [] 且大型栅格图很少(没有任何 media.imgs 条目的固有宽度 ≥ 600),则将该行标记为 ⚠ low-media。 这种组合是背景图片 / 延迟加载媒体遍历悄然失败的特征 — 即使采集流程 按规格执行了完整的背景遍历(playwright-recipe.md § Capture list 11), 仍悄无声息地未采集到任何内容,最终交付的采集结果依然没有图片(2026-06-26 某 SaaS 网站:每个页面的 cssBackgrounds: [],所有产品图片均丢失)。 标记的行提示应使用 --refresh 重新运行该页面(如果问题仍然存在,则按 § Bot-management fallback 改用有头 Chrome)。维护者查看摘要时,应将 bg 计数全为零且 register 为 brand 的网站视为可疑,而不是认为 “此网站不使用背景图片”。

跨站点品牌来源

两个标志会将采集范围扩展到主源站之外 — 只要使用任一标志,就必须完整 阅读 reference/cross-site-sources.md。两者都需要显式启用;不使用时本节 不生效。

核心约定(合并规则和采集形状见参考文档):

  • --brand-source <url>(可重复使用)— 同品牌的关联站点会进行浅层采集 (首页 + ≤2 个导航链接页面,使用完整采集配方 + 来源信息),存放在 stardust/current/brand-sources/<host>/ 下。 这些是证据,不是清单:永不写入 state.json.pages[]。 其配色、字体、视觉元素和语气证据会汇总至 _brand-extraction.json,并按来源标注(origins[]);冲突时以主站为准; 扩展后的特征会标注来源,绝不凭空编造。不会纳入系统组件、voiceTable 和交叉推广检测。
  • --design-source <url> — 设计参考站会采集到 stardust/canon-source/ (形状与 current/ 相同,使用默认上限),其描述性 DESIGN.md/json 按 Phase 4 规则生成,并写入 state.json.designSource = { url, capturedAt, path: "stardust/canon-source/" }。direct 会将该参考站的系统指定为目标(其 § 模式 A);参考站证据不会汇总至主站的 _brand-extraction.json。

同品牌站点发现

在主爬取完成后(阶段 2–2.5),从已采集的证据中提取可能属于同一品牌的站点源 — 不进行额外导航:

  • 指向其他站点的页脚 / 导航链接
  • “我们的品牌” / “我们的公司”页面
  • 其他域名上的 hreflang 替代页面
  • 子域名系列(shop.、careers.、国家/地区子域名)
  • 已采集页面中相匹配的 og:site_name

在爬取报告和 _crawl-log.json#siblingCandidates[] 中列出候选站点,并注明置信度及证据行:

{ "origin": "https://example.co.uk", "confidence": "high", "evidence": "hreflang alternate on 4/5 pages", "decision": "included" }
  • **交互模式:**提出建议 — “发现 3 个可能的同品牌站点 — 是否以 --brand-source 纳入?” — 并根据回答继续。
  • 无人干预模式(state.json.handsOff 为 true):自动将最多 2 个高置信度候选站点作为品牌来源纳入;在 siblingCandidates[].decision 中记录决定。

发现过程有上限且开销低:提取过程仅读取已采集的证据,每个纳入的同品牌站点仅进行浅层品牌来源采集(≤ 3 个页面)。绝不能让爬取规模失控。

输出

路径用途
stardust/current/PRODUCT.md对现有站点的描述性策略(impeccable 格式)
stardust/current/DESIGN.md描述性视觉系统(Stitch 格式)
stardust/current/DESIGN.json包含图案、风格、组件扩展内容的配套文件
stardust/current/brand-review.html对提取结果进行自包含的视觉审阅(首个可直观查看的产物)
stardust/current/pages/<slug>.json每页解析后的结构与内容
stardust/current/pages/<slug>.html定稿的渲染 DOM(爬虫配套文件;离线解析,绝不重新抓取)
stardust/current/assets/logo.<ext>提取的徽标
stardust/current/assets/favicon.<ext>站点 favicon(核心资源;原型页面的 head 与部署流程都会使用)
stardust/current/assets/media/页面引用的提取媒体资源
stardust/current/assets/screenshots/每页的整页截图,由 crawl.mjs 脚本捕获(阶段 2.5 视觉检查关卡 + 品牌审阅)
stardust/current/_brand-extraction.json汇总后的品牌表面信息(配色、字体、图案、风格、系统组件)
stardust/current/_crawl-log.json发现与爬取审计轨迹(包括 visionCheck[]、siblingCandidates[];仅使用 --dynamics 时汇总 dynamicSurface 覆盖范围)
stardust/current/brand-sources/<host>/浅层同品牌站点采集结果(仅使用 --brand-source 时生成)
stardust/canon-source/设计参考来源采集结果 + 描述性 DESIGN.md/json(仅使用 --design-source 时生成)
stardust/state.json已更新站点与各页面的状态(以及 designSource 标记)

并发

页面采集并发运行:阶段 2 队列由 4–8 个并行浏览器上下文处理(--concurrency,默认值为 4)。每个工作线程拥有自己的 BrowserContext;每个上下文都会重新建立同意状态(设置步骤 3)。媒体资源的 resolves / HEAD 检查通过 Promise.all 批量执行。品牌表面信息聚合(阶段 3)可以随着页面完成而逐步进行,但写入的 _brand-extraction.json 必须反映每个已提取页面的内容。打包的爬虫通过线程池实现此功能(crawl.mjs --concurrency <n>)。

跨进程行为遵循 state-machine.md:stardust 不会加锁。同一项目上的两个并发提取操作遵循最后写入者胜出原则。请在用户报告中说明这一点;不要尝试规避。

故障模式

  • 爬取过程中网络故障。 继续执行,在 _crawl-log.json 中记录, 最终以部分状态结束。state.json 仅反映已成功 提取的页面。用户可以重新运行;除非使用 --refresh <slug>, 否则会跳过已提取的页面。
  • HTTP 4xx/5xx、非 HTML 内容、软 404。 按照 reference/playwright-recipe.md § Response validation 中的说明显式 验证。每种情况都会产生独立的错误类别(HTTPError、 ContentTypeError、EmptyPageError),并记录在 _crawl-log.json#crawl.failures[] 中。失败的页面不会在 state.json 中显示为 extracted,而是只出现在失败日志中。 如果没有此验证,5xx 页面会悄然被当作空内容成功处理,并将错误数据 传播到 direct 和 prototype。
  • 登录墙。 不要尝试进行身份验证。如果主页 重定向到登录页面,只捕获该页面,将其余页面标记为 无法访问,并询问用户如何继续(通过 Playwright 配置提供 Cookie、更改入口 URL,或将范围限定为公开页面)。
  • 机器人管理拦截(Akamai / Cloudflare / F5 / Imperva)。 如果首次导航返回 ERR_HTTP2_PROTOCOL_ERROR、 ERR_QUIC_PROTOCOL_ERROR,或在 TLS/H2 指纹检查期间一直挂起直至达到硬性上限, 问题出在默认捆绑 Chromium 的无头模式下的 JA3/H2 指纹检测,而不是身份验证或网络。 按照 reference/playwright-recipe.md § Bot-management fallback,切换到 headless: false, channel: 'chrome'。不要重试无头模式: 结果会完全相同。带头模式的回退方案适用于大多数企业/电商网站; playwright-extra + stealth 插件是处理剩余情况的非标准备用方案。带头模式会弹出可见窗口, 对交互式运行可以接受,但对无人值守流水线不可接受——首次触发时应向用户说明这一点。资源采集注意事项:页面级机器人拦截通常不会限制资源——即使所有页面导航都受到挑战(Cloudflare challenge,已在实际环境中确认),媒体/CSS/字体 URL 通常仍会向普通浏览器 UA 的 curl 返回 200。启用页面内抓取机制前,先用 curl 探测一个资源;页面内采集是备用方案,而非默认方案。
  • 仅由 JavaScript 提供的内容。 Playwright 已能处理此类内容。如果配置的等待条件在该模式的硬性上限内始终未触发(参见 reference/playwright-recipe.md § Wait modes),则回退到 domcontentloaded,并捕获已渲染的内容。在每页的 _provenance.waitMode 中记录 此回退,并在最终报告的等待摘要行中说明。
  • 尝试合成(禁止)。 当 Agent(或委派的 子 Agent)无法对页面执行真实的 Playwright 渲染时——无论是由于时间紧迫、令牌预算不足,还是工具/网络故障——唯一正确的结果是将该页面记录为 Phase 2 失败(在 _crawl-log.json#crawl.failures[] 中设置 errorClass: "ProvenanceMissing"),然后继续。严禁根据 _brand-extraction.json、URL 模式, 以及放置在“语义匹配”模板位置的已捕获图片,合成页面记录。 此捷径生成的输出与成功运行的结果无法区分,并会将 虚构内容传播到所有下游阶段 (2026-04-30 电商运行:25 个页面中有 20 个由合成生成,直到四个阶段之后才被发现)。

准备模式(--prep)

使用 --prep 调用时,extract 会执行扩展流程,为迁移准备清单——运行任何 --prep 提取之前,请完整阅读 reference/prep-mode.md。发现模式运行(不带 --prep)保持不变: 数量上限较低、不进行类型标注、不检测模块。此标志供 prepare-migration 编排器使用,但也支持直接调用。

核心约定(流程、格式和检测规则详见参考文档):

  • --prep 隐含 --all——迁移覆盖需要完整的垃圾项过滤后清单, 而非发现模式的数量上限。
  • 页面类型(landing | article | listing | program | form | static | unique)由 LLM 推断并写入 state.json.pages[].type (发现模式运行会将 type 留空);用户在 direct --prep 中确认。
  • 模块候选项(依据参考文档中的信号源优先级检测到的跨页面结构重复项) 会以 status: "candidate" 草拟到 DESIGN.json.extensions.modules[] 中;每页 JSON 都会按页面类型获得一个 类型化的 slots 部分。
  • 任何流程进入第 2 阶段之前,都必须解决 locale 根路径捕获缺口。 爬取完成后,crawl.mjs 会获取每个已捕获的 locale 根路径(由一个或两个 locale 代码段构成的路径——/en、/fr-ca、/ca/en),列出该页面中 链接到的同源、且位于其自身路径下的目标,并标记未被捕获的目标: _crawl-log.json#captureGaps(包含 root、slug、 linked、uncaptured[] 的 roots[],以及可直接用于台账的字符串 detail),并输出一行 [crawl] capture gaps: stderr。将 roots[] 复制到 state.json.site.captureGaps(site 块属于 extract;未捕获目标绝不会成为 pages[] 行),并在结束提取的台账 end 行中原样保留 detail—— ledger.mjs extract prep end --detail "… uncaptured first-level targets: ca/en 15, fr/fr 0"(replica 的 extract end 也会重复该内容)—— 让负责人现在就决定如何处理缺口(通过 --pages 扩大范围,或将其记录为 范围欠项),而不是等到上线链接审计时再处理:两次有记录的无人值守运行都将 /ca/en 捕获为 locale 根路径,而源站上存在 15 个 /ca/en/* 页面, 结果六小时后才发现有 15 个链接返回 404,且缺口超过了 12 页的交付阈值。
  • 此处记录了标头约定(../diff/SKILL.md § The header contract);准备摘要中的摘要行用于确定标头大小。
  • 准备摘要取代第 6 阶段报告;其中必须包含 Provenance: <live>/<total> live 行,任何低于 <total>/<total> 的 比例都意味着运行未通过综合检查,且尚未完成。
  • 将提取工作委派给子 Agent 时,子 Agent 提示词必须明确禁止合成, 并要求在返回内容中提供逐页证据表和等待摘要行 (reference/prep-mode.md § Sub-agent prompt requirements); 三项中缺少任何一项都属于违反流程配方。

参考资料

  • reference/playwright-recipe.md — 视口、捕获列表、徽标定位器链。
  • reference/ia-extraction.md — 站点地图 + BFS 爬取 + 数量上限流程。
  • reference/current-state-schema.md — 逐页 JSON 架构。
  • reference/brand-surface.md — 汇总品牌表层架构。
  • reference/brand-review-template.md — 当前状态品牌评审 HTML 约定 + Tensions 检测器。
  • reference/prep-mode.md — 完整的 --prep 流程(类型标注、模块候选项、类型化插槽、准备摘要、子 Agent 要求)。
  • reference/cross-site-sources.md — 完整的 --brand-source / --design-source 流程(浅层捕获、合并规则、规范来源捐赠方)。
  • skills/stardust/reference/state-machine.md — state.json 约定。
  • skills/stardust/reference/artifact-map.md — 来源信息结构。

评论

支持 Markdown