mcpField
S
sb-hub

sb-hub

github.com/strongeron开发3979 次安装4 周前更新
代码仓库

关于 sb-hub

sb-hub 是用于 Storybook 应用审计流程的只读导航与编排技能。它检查项目状态、推荐一个后续技能,或按产物门槛协调完整审计流程。

主要功能

  1. 01只读诊断项目就绪情况
  2. 02推荐一个后续工作步骤
  3. 03按门槛编排审计阶段
  4. 04依据状态和产物恢复流程
  5. 05转交技能异常报告

适用场景

  1. 01审计前检查代码仓库状态
  2. 02根据现有产物确定下一技能
  3. 03按序执行审计并创建 Storybook 内容
  4. 04恢复中断的审计流程

MCP 相关

它会检查 Storybook 的 addon-mcp 是否已接入,并据此选择 sb-stories 的执行路径。README 未说明它提供 MCP 服务端接口。

安装

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

$npx skills add https://github.com/strongeron/storybook-workbench --skill sb-hub

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

包含的文件

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

CONTEXT.md
agents/
openai.yaml
references/
end-to-end-flow.md
runbook.md
scripts/
report-issue.sh

详细介绍

sb-hub — 入门检查 · 编排 · 导航

Hub。你不会在这里编写内容——你要检查状态并进行路由。有三种只读模式;按意图选择。阅读一次 CONTEXT.md,了解共享词汇、存储映射和恢复协议。

按模式加载(不要一开始就加载两个参考文件):

  • references/runbook.md —— 导航引擎(状态检测 → 下一步)。在 模式 0 / 模式 2(诊断 /“接下来做什么”)时加载。
  • references/end-to-end-flow.md(约 220 行)——“杂乱应用 → 设计系统”的完整流水线示例。仅在模式 1(编排完整审计)时加载。 对于模式 0 入门检查或模式 2 下一步查询,不要加载它——这些模式只需 runbook.md。

规范上下文(单一来源)。 此软件包中恰好有一个 CONTEXT.md(共享词汇 · STORAGE MAP · 恢复)。它不会被手动重复创建:在软件包/插件安装中,每项技能都会读取同一个文件(CONTEXT.md / ${CLAUDE_PLUGIN_ROOT}/CONTEXT.md);独立运行 npx skills add <skill> 时,会附带构建过程打包的逐字节相同副本,并在更新时刷新。sb-hub 是编排器——如果技能是单独安装的,请通过 sb-hub 进行路由,以确保流水线和共享词汇保持权威。

解析软件包位置

脚本位于 scripts/。在此仓库中:${CLAUDE_PLUGIN_ROOT}/scripts/。 作为插件安装时,使用 ${CLAUDE_PLUGIN_ROOT}/scripts/。

CORE=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}   # shared scripts: "$CORE/scripts/<name>"

选择模式

用户意图模式
“准备好了吗”“我该从哪里开始”,全新/未知仓库0 · 入门检查
“审计这个应用”“把整个流程跑完”“为这个应用构建 Storybook”1 · 编排
“接下来做什么”,或任意动词已追加到台账之后2 · 导航(默认)
“这不对”“行为异常”“报告 bug”,某项技能运行出错3 · 报告

模式 0 — 入门检查(阶段 0 诊断,只读)

对于全新的杂乱应用:在运行任何动词之前,探查技术栈和就绪状态,输出报告并推荐第一步。无提示、无写入——可重复运行。

echo "━━ Phase 0 — readiness ━━"
grep -q '"react"' package.json 2>/dev/null && echo "  [ok]   React" || echo "  [warn] no React in package.json"
grep -qE '"vite"|"@vitejs' package.json 2>/dev/null && echo "  [ok]   Vite" || echo "  [info] not Vite (skill targets React+Vite)"
test -d .storybook && grep -q '"storybook"' package.json 2>/dev/null && echo "  [ok]   Storybook present" || echo "  [warn] NO_STORYBOOK → start with sb-setup"
test -d node_modules && echo "  [ok]   node_modules present" || echo "  [warn] deps not installed — run your package-manager install"
lock=$(ls package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null | head -1); echo "  [info] lockfile: ${lock:-none}"
grep -q '@storybook/addon-mcp' package.json 2>/dev/null && test -f .mcp.json && echo "  [info] MCP wired → sb-stories uses with-mcp" || echo "  [info] no addon-mcp → without-mcp path"
if find .storybook -maxdepth 1 -name '*.json' 2>/dev/null | grep -q .; then
  find .storybook -maxdepth 1 -name '*.json' | sed 's/^/  [ok]   discovery: /'
else echo "  [info] no discovery JSON yet → sb-inventory not run"; fi
grep -q 'storiesLocation:' .storybook/audit/status.md 2>/dev/null && echo "  [ok]   stories location decided" || echo "  [warn] stories location undecided → sb-setup must ASK (isolated .storybook/stories/ vs co-located) before sb-stories"

操作示例——迁移到一半的应用(已安装 Storybook,尚未进行任何审计):

━━ Phase 0 — readiness ━━
  [ok]   React
  [ok]   Vite
  [ok]   Storybook present
  [ok]   node_modules present
  [info] lockfile: pnpm-lock.yaml
  [info] no addon-mcp → without-mcp path
  [info] no discovery JSON yet → sb-inventory not run
  [warn] stories location undecided → sb-setup must ASK …

→ 已存在 Storybook,但没有发现 JSON,且 stories 的位置尚未确定,因此不要直接跳到 sb-stories。先指定 sb-setup(以记录 stories 的位置),然后再指定 sb-inventory。这个顺序——先 setup,再 inventory,最后 stories——正是这道关卡的意义:[info]/[warn] 行是路由信号,不是噪声。

软件包写入的所有内容都位于 .storybook/ 下(参见 CONTEXT.md STORAGE MAP)——如果发现其他位置有输出,请标记。唯一需要做的决定是 stories 的存放位置;如果尚未确定,请指定 sb-setup(它会询问)。

发现数据是预先计算的。 发现层数据是 .storybook/ 下的 JSON: project-inventory(+ tokens.map、storyCoverage)· component-usage · flows · design-system-health · component-states · prop-shapes · page-patterns · runtime。 前四项会在 Storybook 中渲染(嵌入的 autodocs + 封装器),并由 refresh-usage.sh 一起刷新;其余是编写输入(按需重新生成)。不要通过 shell 扫描重新推导脚本已经写入 .storybook/*.json 的内容——请读取字段。

然后输出 → Start: <first verb>——如果是 NO_STORYBOOK,则为 sb-setup,否则为 sb-inventory。不要运行该动词;只需指定它,然后停止。对于完整的新项目流程,交由模式 1 处理。

模式 1 — 编排(运行完整审计 → stories)

“端到端审计这个应用。”按顺序运行流水线,在各阶段之间设置关卡——只有在前一个产物存在后才能继续(发现脚本会原子写入,因此已存在的 JSON 就是完整的)。不要直接运行同级脚本;请调用各项专用技能并验证其输出。

  1. sb-setup——如果 Mode 0 报告了 NO_STORYBOOK,或故事文件的位置尚未确定。门槛:.storybook/ 和 package.json 中的 "storybook" 都已就位,且 .storybook/audit/status.md 中已记录 storiesLocation(sb-setup 会询问用户:使用独立的 .storybook/stories/,还是与组件放在一起),并且 .storybook/runtime.json 已存在(discover-runtime.py——共享预览需要提供的 provider 树/根 CSS/portal/MSW),然后才能进入步骤 2。
  2. sb-inventory——识别真实组件与占位组件,以及占主导地位的设计系统。门槛:.storybook/project-inventory.json 已存在。
  3. sb-health——检查设计系统健康状况。门槛:.storybook/design-system-health.json 已存在;如果 designSystem.mixed 为真或大量使用原始十六进制颜色值,则在编写故事前提示转交 /ds-runbook。
  4. sb-flows——路由图和导航边。门槛:.storybook/flows.json 已存在。
  5. sb-stories <Component>——为每个需要故事的组件编写故事:按 components.storyCoverage.needsStory[] 的顺序处理(先处理自身没有故事且被导入最多的组件),每个组件都由 validate-stories.sh 自行检查。若 storyCoverage.source == "storybook-index",则以 storyCoverage.withRegisteredStory/needsCount 作为准确的进度指标(根据 Storybook 的 index.json 对照——即 Storybook 实际注册的故事);否则使用 withColocatedStory/needsCount(这是启发式指标;withStory 只是宽松的上限——它也会计入仅为 mock 而导入的组件)。编写完成后重新运行 sb-inventory(或 sb-audit),以从索引刷新覆盖率并缩减 needsStory[],持续迭代直至列表为空。
  6. sb-wrappers——将每个步骤的输出渲染为视图:ProjectInventory(步骤 2 之后)、DesignSystemHealth/TokenMatrix(步骤 3 的健康检查之后)、AppFlowGraph/JourneyGraph(步骤 4 之后),以及编写故事时使用的 StateGrid/StateMatrix(步骤 5)。数据包装器需要先有对应步骤的 JSON——参见 sb-wrappers 中的 “When in the flow”。
  7. sb-audit——故事落地后定期调查偏移情况并生成决策看板;运行 refresh-usage.sh(见下文)。

源自 Figma 的设计系统(可选分支,在步骤 1 之后)。 上述流程以代码为先(审计现有内容)。如果已批准的 Figma 文件是事实来源,则在编写故事前插入 sb-figma,以建立基础令牌的一致性:它会将 Figma MCP 变量保存到 .storybook/figma/,写入 .storybook/figma-token-parity.json(颜色/间距/字体,OKLCH→hex),为 Foundations/Colors|Tokens|Type 故事接入 figmaVar/figmaHex,并报告偏移情况。它为 sb-health(步骤 3)提供补充,而非取而代之:健康检查会检查代码内部的令牌集;sb-figma 则补充设计与代码之间、健康检查无法看到的维度。(通过 Figma 交付已批准的组件也属于 sb-figma,并通过 sb-stories 编写;仍在迭代、尚未定稿的设计则继续使用 sb-explore。)

每个阶段完成后,在 .storybook/audit/findings.md 中追加一条发现。遇到的第一个未通过的门槛处立即停止,并告知用户该修复哪个动词。(模式:带硬性门槛的有序流程,类似 lfg。)

保持渲染数据最新(使用情况层)。 四个渲染后的 JSON(inventory · component-usage · flows · design-system-health)会提供给 autodocs 使用情况嵌入内容——UsageSection 只需在 preview.ts 的 docs.page 中接入一次,就会在每个组件的文档以及每个基础内容(Colors/Semantic/Typography/Scales = 令牌表,Health = 审计发现)中添加“此应用中的实际用法”。refresh-usage.sh --docs 会一并重新运行这四项,让重建结果反映实际情况;sb-audit 每次运行都会执行此操作,并且应在 CI 中、storybook build 之前运行。(设置过程会接入 docs.page 组合——参见 sb-setup install-wizard。)

模式 2 — 导航(默认 — 指定唯一的下一步)

检查状态和账本,推荐一个且仅一个满足前置条件的下一项精确技能。

test -d .storybook && grep -q '"storybook"' package.json 2>/dev/null && echo STORYBOOK_PRESENT || echo NO_STORYBOOK
ls .storybook/*.json 2>/dev/null            # which discovery JSONs exist
cat .storybook/audit/status.md 2>/dev/null  # ledger / resume point
# DRIFT — source/story files changed since the last discovery (newer than the inventory JSON). Plain
# `find -newer` → cross-agent (no git, no Claude hook), works on uncommitted/untracked files. Lists the
# exact files that moved this session; if any, the discovery JSONs are stale → refresh before routing.
if [ -f .storybook/project-inventory.json ]; then
  find src app components .storybook/stories \( -name '*.tsx' -o -name '*.ts' \) \
    -newer .storybook/project-inventory.json 2>/dev/null | grep -v '\.storybook/.*\.json' | head -20
fi
# COVERAGE — READ the field the script already wrote (CONTEXT.md doctrine: never re-derive). Extract
# ONLY storyCoverage so the FULL object surfaces complete — never a truncated dump of the whole
# inventory. Prefer the authoritative `withRegisteredStory` (source=storybook-index, reconciled against
# index.json); fall back to the heuristic `withColocatedStory`. needsStory[] is the iterate list.
if [ -f .storybook/project-inventory.json ]; then
  python3 - <<'PY'
import json
try: c = json.load(open(".storybook/project-inventory.json"))["components"]["storyCoverage"]
except Exception: raise SystemExit
src = c.get("source", "heuristic")
done = c.get("withRegisteredStory") if src == "storybook-index" else c.get("withColocatedStory", 0)
print(f"coverage: {done}/{c.get('real',0)} components have a story [{src}] · {c.get('needsCount',0)} need one")
if c.get("needsStory"):
    extra = " …" if c.get("needsCount", 0) > 8 else ""
    print("iterate next (sb-stories): " + ", ".join(c["needsStory"][:8]) + extra)
PY
fi

如果 DRIFT 列出了文件,说明发现阶段生成的 JSON 与代码不再匹配 — 先转到 sb-inventory(或定期检查时转到 sb-audit)进行刷新,再指定下一步:它的 refresh-usage.sh 会重新运行清单、使用情况和流程检查,并将故事覆盖情况与 Storybook 自身的 index.json(权威数据,而非根据基本文件名猜测)进行核对。然后转到下一步 — 准确指定一个:

状态下一步技能
NO_STORYBOOK将引导安装推迟到 npm create storybook@latest + npx storybook skills setup,然后进行协调sb-setup
没有 project-inventory.json先发现真实项目与伪项目sb-inventory
清单已完成,没有 design-system-health.json编写内容前先检查健康状况sb-health
健康检查已完成,没有 flows.json记录导航 + 应用地图sb-flows
清单无误,想要编写故事编写一个组件sb-stories <Component>
新建/重新设计的组件,尚未决定 — 正在迭代方案沙盒迭代(+ Figma 节点)sb-explore
已批准的 Figma 设计 — 映射基础令牌(颜色/间距/字体),或交付已批准的组件Figma → 生产环境 Storybooksb-figma
检查 Figma 与代码的令牌一致性 /“设计系统是否与 Figma 同步”一致性 + 漂移报告sb-figma
将组件关联回 Figma(Code Connect)/“在 Figma Dev Mode 中显示我的代码”代码 → 设计(反向)sb-figma
定期检查漂移调查 + 决策面板sb-audit
Explore 达到毕业门槛推广到生产环境sb-ship

探索 vs 交付(两者都支持 Figma — 按阶段分流,而非按“是否使用 Figma”): 尚未决定 / 正在尝试方案 → sb-explore(实验室)→ sb-ship(毕业)。已在 Figma 中批准 → sb-figma(直接交付到生产环境)。sb-figma 会自行编写基础令牌故事;对于已批准的组件,它会提取设计,然后按照 sb-stories 的规则编写故事。它会将每项 Figma MCP 输出保存到 .storybook/figma/(清单 + 每个工具对应的文件),以便整个流水线可复现、可迭代,而不受 MCP 限制。

**恢复规则(CONTEXT.md):**读取 status.md + 检查哪些 JSON 文件存在;从第一个未完成的步骤继续。切勿将之前会话中写了一半的文件视为已完成 — 重新运行该步骤。

模式 3 — 报告(技能运行出错 / 行为异常)

当用户表示某个技能执行有误、结果意外或发生故障时,帮助他们提交一份有用的报告 — 不要只是道歉。使用 Agent 原生报告器起草报告,然后提供提交命令。

CORE=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}
"$CORE/scripts/report-issue.sh" --asked "<what they asked>" --observed "<what happened>" --expected "<what they wanted>"

如果问题由 sb-figma 引起,请添加 --gaps:草稿会按类型列出 .storybook/figma/gaps.json 中尚未解决的问题数量(不含名称或值)。

它会生成一份经过脱敏的草稿(仅包含版本信息 + .storybook/*.json 的结构/数量 — 不含源代码、令牌值或组件名称),并打印 gh issue create … 命令 + 空白 Issue URL。它不会发起网络请求 — 由用户提交。根据对话填写 --asked/--observed/--expected,向用户显示草稿路径 + gh 命令,并且仅在用户提出要求时,才主动帮他们运行 gh。如需指定其他仓库:SB_ISSUE_REPO=owner/name。一份好的报告会成为复现案例 → 新的评估用例 → 修复 → field-learnings.md 条目 — 这个循环能避免下一次运行再次遇到相同问题。

绝不(编排失败模式及其原因)

  • 绝不要在关卡失败或结果为空时继续推进 Mode 1 中的流程——每个阶段的 .storybook/*.json 都是下一阶段的前置条件(先准备基础设计令牌,再处理组件;先准备流程,再生成应用映射)。跳过任一阶段,后续阶段就会基于缺失的事实依据开展工作,导致产出不足却不易察觉。
  • 绝不要通过 shell 扫描来重新推导 CONTEXT——脚本已经写入 .storybook/*.json 文件,这些文件就是状态本身。手动搜索会导致结果偏离脚本捕获的信息和封装器渲染的内容;引用字段,不要重新计算。
  • 绝不要将上一次会话中只写了一半的产物视为完整——每个文件的写入都是原子的,但中断的运行可能会在流程执行到一半时停止。检查 status.md,并从第一个未完成的步骤重新运行。
  • 绝不要在这里编写内容——中心负责检查和路由。在中心编写故事或封装器会绕过专用技能自身的检查和反模式;请调用该技能。
  • 绝不要手动复制 CONTEXT.md——每个技能都读取唯一的规范文件(CONTEXT.md);复制文件迟早会产生偏差。

跨 Agent

  • Claude:此技能是 /sb-hub(Mode 2 /“下一步做什么”是默认模式;/sb-hub onboard 或 /sb-hub audit this app 会选择 Mode 0 / 1)。
  • Codex:$sb-hub what's next · $sb-hub onboard · $sb-hub audit this app。
  • 工作循环:运行一个动词 → 将内容追加到 .storybook/audit/findings.md → 再次询问 sb-hub(Mode 2)→ 它会指出下一个针对性技能 → 运行该技能。

评论

支持 Markdown