seo-platform-detect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseseo-platform-detect
seo-platform-detect
The profile decides three things no module can decide on its own: which platform-conditional check
ids fire, which findings are because the platform owns the thing, and which fix
adapter will reach for. Run it once per audit, right after the snapshot, before dispatch.
not_applicablefixDetection is orthogonal to the vertical: answers what kind of site is this,
this skill answers what is it built on. Both feed one .
seo-vertical-detectprofile.jsonprofilenot_applicablefixDetection 与 vertical 相互正交: 回答“这是什么类型的站点”,此 skill 回答“它构建在什么之上”。二者共同生成一个 。
seo-vertical-detectprofile.jsonWhen to run
何时运行
In the normal and flow you do not run this yourself: already calls the
same over the run's homepage snapshot and persists the result as .
Read that file first. Run the script directly only when you need a signal the headless pass could not
use — for repo/package signals, for the WordPress plugin verdict — or when
you are working outside the runner. Either way it is one run per audit, before the dispatch envelopes
are built; every subagent reads the same profile.
/audit/geoaudit.mjsdetect()<run_dir>/profile.json--path <project>--probe在正常的 和 流程中,你无需自行运行: 已针对本次 run 的首页 snapshot 调用相同的 ,并将结果持久化为 。先读取该文件。仅在以下情况下直接运行脚本:需要 headless pass 无法使用的 signal—— 用于 repo/package signals, 用于 WordPress plugin 判定——或者正在 runner 之外工作。无论采用哪种方式,每次 audit 在构建 dispatch envelopes 之前运行一次;所有 subagent 都读取同一份 profile。
/audit/geoaudit.mjsdetect()<run_dir>/profile.json--path <project>--probeHow to run
如何运行
bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/detect-platform.mjs" --snapshot "<run_dir>/pages/<home-slug>.json"Add flags when they apply, and only then:
- when the user gave a local project (
--path <project>). This is the only way repo and package signals are consulted; without it, Payload is undetectable and Next.js router detection falls back to DOM markers. It is also what turns--projecton, which is what makes local file fixes possible at all.capabilities.local_files - when the target is reachable and a WordPress plugin verdict matters. It requests
--probe,/wp-json/,/.well-known/ucpand/products.json— four GETs, no more. The REST namespace list is the only reliable way to tell Yoast from Rank Math from AIOSEO; HTML comments name a plugin that printed a comment, not one that is active./wp-sitemap.xml - to persist it instead of piping the stdout JSON.
--out "<run_dir>/profile.platform.json"
Offline / fixture mode (used by the tests, and by you when there is no network):
.
--html <file> [--headers <json>] [--cookies <json>] [--probes <json>] [--url <u>]Exit codes: 0 ok · 1 bad invocation or unreadable input · 2 fetch failure.
bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/detect-platform.mjs" --snapshot "<run_dir>/pages/<home-slug>.json"仅在适用时添加相应 flags:
- 当用户提供 local project()时,使用
--project。这是读取 repo 和 package signals 的唯一方式;不使用它,Payload 将无法检测,Next.js router detection 也会回退到 DOM markers。它还会开启--path <project>,而这是实现 local file fixes 的必要条件。capabilities.local_files - 当目标可访问且需要判定 WordPress plugin 时,使用 。它会请求
--probe、/wp-json/、/.well-known/ucp和/products.json——共四次 GET,不会发出更多请求。REST namespace list 是区分 Yoast、Rank Math 和 AIOSEO 的唯一可靠方式;HTML comments 只能表明某个 plugin 打印了一条 comment,并不能证明它处于 active 状态。/wp-sitemap.xml - 使用 将结果持久化到文件,而不是通过管道输出 stdout JSON。
--out "<run_dir>/profile.platform.json"
离线 / fixture 模式(tests 使用,你在无网络时也使用):
。
--html <file> [--headers <json>] [--cookies <json>] [--probes <json>] [--url <u>]退出码:0 成功 · 1 参数调用错误或输入不可读 · 2 fetch failure。
What comes back
返回内容
{ version: "detect-platform/1", target, platform, framework, cms_plugins[], hosting, environment, capabilities, write_targets[], candidates, vertical_hints[], cards[], sources, notes[] }Each of / / / carries its own
( ≥ 8 with ≥ 2 signal kinds, ≥ 5, ≥ 2) and the that produced it.
A layer with less evidence than that is — an unresolved platform is a result, not a gap.
Report it as unresolved and let the run continue on ; never round a up in prose.
platformframeworkcms_plugins[]hostingconfidencehighmediumlowsignalsnullinstructionslowFour layers are scored independently, so headless setups resolve correctly: a WordPress backend with
a Next.js front end yields and , and
becomes . Follow whenever the cards disagree.
platform: wordpressframework: nextjscapabilities.head_ownerframeworkhead_owner{ version: "detect-platform/1", target, platform, framework, cms_plugins[], hosting, environment, capabilities, write_targets[], candidates, vertical_hints[], cards[], sources, notes[] }每个 / / / 都各自带有 ( ≥ 8 且至少有 2 种 signal kinds, ≥ 5, ≥ 2)以及产生该结论的 。证据少于相应门槛的 layer 为 ——未解析的 platform 本身就是结果,而不是缺口。将其报告为 unresolved,然后让本次 run 在 的基础上继续;绝不在描述中将 向上取整。
platformframeworkcms_plugins[]hostingconfidencehighmediumlowsignalsnullinstructionslow四个 layer 独立评分,因此 headless setup 可以被正确解析:采用 Next.js front end 的 WordPress backend 会同时得到 和 ,而 会变为 。当 cards 出现分歧时,遵循 。
platform: wordpressframework: nextjscapabilities.head_ownerframeworkhead_ownerMerging into profile.json
合并到 profile.json
<run_dir>/profile.jsonseo-vertical-detectaudit.mjsdetect()vertical--verticaljson
{ "version": "detect-platform/1", "platform": {…}, "framework": {…}, "cms_plugins": [],
"hosting": {…}, "environment": {…}, "capabilities": {…}, "write_targets": [],
"candidates": {…}, "vertical_hints": [], "cards": [], "sources": {…}, "notes": [],
"vertical": { "primary": "ecommerce", "also": [], "multilingual": false, "locales": [] } }Pass to as signals, never as verdicts — it must still cite
its own evidence. Pass to the scorer
(), which suppresses noindex-type severity-5 caps on
a non-production host and reports them as expected instead.
vertical_hints[]seo-vertical-detectenvironment.kindscore.mjs --environment preview|staging|local<run_dir>/profile.jsonseo-vertical-detectaudit.mjsdetect()vertical--verticaljson
{ "version": "detect-platform/1", "platform": {…}, "framework": {…}, "cms_plugins": [],
"hosting": {…}, "environment": {…}, "capabilities": {…}, "write_targets": [],
"candidates": {…}, "vertical_hints": [], "cards": [], "sources": {…}, "notes": [],
"vertical": { "primary": "ecommerce", "also": [], "multilingual": false, "locales": [] } }将 作为信号传给 ,绝不要将其当作结论——它仍必须引用自己的 evidence。将 传给 scorer();这样在 non-production host 上会抑制 noindex 类型的 severity-5 caps,并将其报告为预期结果。
vertical_hints[]seo-vertical-detectenvironment.kindscore.mjs --environment preview|staging|localWhich card goes to which subagent
哪个 subagent 应获得哪些 card
profile.cards[]references/platforms/<id>.mdplatform_cardsplatformprofile.json"shopify (high) · theme head · staging theme available · environment production"- emit the card's §10 check ids when the rule matches;
- card §4 items ⇒ naming the owner in
not_applicable— never a silent pass, never aevidence.observedfor something the platform will not let anyone change.fail
Hand out the platform card, the framework card and any plugin card together; a headless site legibly
needs all three. When is true, also tell the agents that every fix
they propose will be delivered as a click-path, so must be human-readable prose rather
than a diff.
capabilities.instructions_onlyfix_previewprofile.cards[]references/platforms/<id>.mdplatform_cardsplatformprofile.json"shopify (high) · theme head · staging theme available · environment production"- 规则匹配时,输出该 card 的 §10 check ids;
- card §4 中的项目 ⇒ ,并在
not_applicable中指明 owner——绝不能静默通过,也绝不能对平台不允许任何人更改的事项判定为evidence.observed。fail
将 platform card、framework card 和所有适用的 plugin card 一并分发给 subagent;headless site 显然需要三者。当 为 true 时,还应告知 agents,他们提出的每项 fix 都将以 click path 的形式交付,因此 必须是人类可读的 prose,而不是 diff。
capabilities.instructions_onlyfix_previewHonesty
诚实性
- in
needslists credential key names. Presence is checked forwrite_targets/CLAUDE_PLUGIN_OPTION_<KEY>— values are never read, printed or logged.<KEY>means "not configured", never "wrong key".ready: false - Cookie names are evidence; cookie values are never recorded.
- Repo signals are absent without , probe signals absent without
--path, and the profile's--probesays so. Repeat that in the report rather than presenting a partial profile as complete.notes[] - A signal marked in a card's §12 may support a detection verdict but must never support a write. When a fix depends on an unverified API detail, the answer is
UNVERIFIED.needs_api
- 中的
write_targets列出 credential 的 key names。系统只检查needs/CLAUDE_PLUGIN_OPTION_<KEY>是否存在——绝不读取、打印或记录其值。<KEY>表示“未配置”,绝不表示“key 错误”。ready: false - Cookie 名称属于 evidence;Cookie 值绝不记录。
- 未提供 时不存在 repo signals,未提供
--path时不存在 probe signals,profile 的--probe会注明这些情况。在报告中重复这些缺失情况,而不要将 partial profile 当作 complete profile。notes[] - card 的 §12 中标记为 的 signal 可以支持 detection 结论,但绝不能支持 write。当某项 fix 依赖未经验证的 API detail 时,答案应为
UNVERIFIED。needs_api