mcpField
M
metabase-modular-embedding-version-upgrade

metabase-modular-embedding-version-upgrade

github.com/metabase开发54372 次安装1 天前更新
代码仓库

关于 metabase-modular-embedding-version-upgrade

用于升级 Metabase 模块化嵌入项目的技能。它扫描 SDK 用法、整理特定版本的 API 变更目录,迁移受影响文件并通过类型检查验证。

主要功能

  1. 01SDK 与 embed.js 升级流程
  2. 02项目用法与版本检测
  3. 03解析具体类型的 API 变更目录
  4. 04逐文件迁移与验证

适用场景

  1. 01升级 React 嵌入 SDK 依赖
  2. 02更新 Modular embedding 集成
  3. 03迁移前检查 API 变更

安装

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

$npx skills add https://github.com/metabase/agent-skills --skill metabase-modular-embedding-version-upgrade

安装后在 Claude Code 中输入/metabase-modular-embedding-version-upgrade确认已加载。

附带文件scripts/prepare.shscripts/read-sources.sh

详细介绍

执行约定

请按顺序执行工作流步骤,不要跳过任何步骤。先创建检查清单,然后逐一执行每个步骤,并提供证据明确标记为已完成。每个步骤的输出都会传递给下一步,因此跳过步骤会导致迁移错误。

如果因信息缺失或工具故障而无法完成某个步骤,你必须:

  1. 将该步骤记录为 ❌ blocked,
  2. 准确说明缺少什么信息/发生了什么故障,
  3. 停止(不要继续后续步骤)。
必需的输出结构

你的回复应按以下顺序包含这些部分:

  1. Step 0: 升级计划检查清单
  2. Step 1 结果:项目扫描
  3. Step 2 结果:d.ts 差异/目标文档(主要路径或备用路径)
  4. Step 3:变更目录
  5. Step 4:逐文件迁移(每个文件一个小节)
  6. Step 5:类型检查验证
  7. Step 6:最终总结

每个步骤部分都应以状态行结尾:

  • Status: ✅ complete 或 Status: ❌ blocked
证据要求
  • 第 1 步:列出每个匹配的文件路径及对应的 grep 行(SDK 导入或 Modular 嵌入 API 调用/脚本标签)。完整的文件分析在第 4 步进行。
  • 第 2 步(主要路径):展示 d.ts 文件之间的差异输出。(混合/备用路径):列出每个已获取的 URL,并确认文件已加载到上下文中。此处不要分析或解析类型——这是第 3 步的工作。
  • 第 3 步:结构化变更目录——列出每个已更改/已移除/已添加的符号及其完整解析后的具体类型。
  • 第 4 步:逐个文件说明——发现的 SDK/Modular 嵌入用法(组件、属性、配置选项、回调、数据流)、影响该文件的目录条目、发现的无效用法、应用的精确差异。
  • 第 5 步:运行的精确命令,以及剩余错误的摘要(如有)。
性能

此工作流旨在通过最大限度地并行处理来提高效率:

Round 1 (grep+glob+pkg) ──► Round 2 (prepare.sh) ──► Round 3 (read-sources.sh) ──► Step 3 (catalog, inline)
                                                                                          │
                                                                                    Step 4 per-file:
                                                                                     ├── Read FileA → match catalog → validate → fix
                                                                                     ├── Read FileB → match catalog → validate → fix
                                                                                     └── Read FileC → match catalog → validate → fix
                                                                                           │
                                                                                     Step 5 (typecheck) ──► Step 6

在 Claude Code 中,使用并行工具调用或 run_in_background: true 运行子 Agent。

不要解析仓库分支、提交、PR 或议题——这些内容对版本差异分析无关且会造成干扰。

第 1+2 步的工具调用轮数预算

第 1+2 步必须在 3 轮工具调用内完成。

第 1 轮——发现(在同一条消息中并发执行):

  • 搜索 @metabase/embedding-sdk-react 导入(返回文件路径——此时不要读取文件)
  • 查找锁文件(yarn.lock、pnpm-lock.yaml、package-lock.json)
  • 读取 package.json(获取当前版本)
  • npm view @metabase/embedding-sdk-react version(如果用户未指定目标版本)

以上四项工具调用必须放在同一条消息中。

第 2 轮——运行 prepare.sh + 获取文档(并发执行):

bash <skill-path>/scripts/prepare.sh {CURRENT} {TARGET} --sdk
# or for Modular embedding (embed.js):
bash <skill-path>/scripts/prepare.sh {CURRENT} {TARGET} --embedjs

务必传入 --sdk 或 --embedjs,以指明嵌入类型。该脚本会执行以下操作:打包两个版本的 npm 包(仅 SDK)、检查 d.ts,并获取并截断变更日志。它会输出 SDK_TMPDIR 和 d.ts 可用性。

在同一条消息中,获取当前版本和目标版本的 llms-embedding-full.txt(URL 格式见“允许使用的文档来源”)。

第 3 轮——read-sources.sh(单次 Bash 调用——仅限参考数据,不读取项目文件):

bash <skill-path>/scripts/read-sources.sh {SDK_TMPDIR}

将 SDK 参考数据(d.ts 差异或原始 d.ts、变更日志)输出到 stdout。不会读取项目文件——第 4 步会逐一读取这些文件。

第 3 轮之后,无需额外工具调用,即可输出第 1 步结果(grep 得到的文件列表)+ 第 2 步结果 + 第 3 步变更目录。不要将第 3 步视为单独的思考阶段——加载数据后应立即接着生成目录。

范围

此技能处理以下内容的升级:

  • @metabase/embedding-sdk-react(React SDK,v52+)——使用主要路径或备用路径
  • 通过 embed.js 实现的 Modular 嵌入(v56+)——始终使用备用路径(无可用 npm 类型)
    • v56–v57:文档位于 embedded-analytics-js.md
    • v58+:文档拆分为 components.md、appearance.md、authentication.md
此技能不处理的内容
  • 在不同嵌入技术之间迁移

允许使用的文档来源

使用此 URL 获取特定版本的 llms-embedding-full.txt:

https://www.metabase.com/docs/v0.{VERSION}/llms-embedding-full.txt

URL 中的版本格式为 v0.58(规范化方式:去掉开头的 v 或 0.,省略补丁版本号;例如,0.58.1 → 58 → URL 使用 v0.58)。这个文件包含该版本的所有嵌入文档,并针对大模型进行了优化。

其他限制:

  • 不要使用 GitHub PR、issue 或 npm 页面
  • 不要通过变更日志链接跳转到 GitHub,也不要猜测 URL

检测版本

在第 1 轮中完成所有版本检测(参见工具调用轮次预算),不要将其作为单独的预备步骤。

  • 当前版本:从项目的 package.json 中读取 @metabase/embedding-sdk-react 的版本(检查 dependencies 和 devDependencies)。对于 monorepo,还要检查工作区级别的 package.json 文件。
  • 目标版本:
    • 如果用户指定了版本,则使用该版本。
    • 否则运行 npm view @metabase/embedding-sdk-react version,并将其纳入第 1 轮的并发工具调用。
  • 包管理器:根据锁文件判断:yarn.lock → yarn,pnpm-lock.yaml → pnpm,package-lock.json → npm。在步骤 4 中使用对应的安装命令(例如,yarn install、pnpm install)。

如果未安装该包,或用户正在升级模块化嵌入(embed.js):

  • 向用户询问当前和目标 Metabase 实例版本。模块化嵌入(embed.js)由 Metabase 实例提供,因此其版本与实例版本一致。在 Claude Code 中,使用 AskUserQuestion 工具提问。
  • 在用户回答前,将步骤 0 标记为 ❌ blocked。

跨多个版本升级

当升级跨越重要的结构性变更边界时(例如,v0.54 → v0.58 跨越了 v0.55 的身份验证配置变更和 v0.58 的文档布局变更),将其作为一次迁移直接升级到目标版本,不要进行中间升级。不过,在步骤 3 中,检查身份验证配置演变部分,并处理升级路径中的所有破坏性变更。例如,v0.52 → v0.58 意味着身份验证配置结构发生了变化(v0.55),并新增了 jwtProviderUri(v0.58)——迁移时需要体现这两项变更。

工作流前准备

升级计划清单(开始任何其他工作前必须完成)

创建清单以跟踪进度。在 Claude Code 中,使用 TaskCreate/TaskUpdate 工具:

  • 步骤 1:扫描项目用法
  • 步骤 2:提取 d.ts 差异或获取文档
  • 步骤 3:整理变更目录
  • 步骤 4:逐个文件迁移(每个文件创建一个子任务)
  • 步骤 5:进行类型检查并修复问题
  • 步骤 6:最终总结
路径选择

确定使用哪条路径:

  • 如果升级 @metabase/embedding-sdk-react → 尝试主要路径(d.ts 差异);如果 d.ts 不可用,则使用备用路径(在步骤 2 中确定)
  • 如果升级模块化嵌入(embed.js)→ 使用备用路径(完全跳过 d.ts 提取)

工作流

步骤 1:扫描项目代码

将扫描结果保留在主上下文中(不要委派给子 Agent),因为步骤 3 需要这些结果进行交叉比对。

升级 SDK(@metabase/embedding-sdk-react):

步骤 1 在第 1 轮中完成——仅使用 grep,不读取文件。

  • 搜索所有从 @metabase/embedding-sdk-react 导入内容的位置。这会返回文件路径和匹配的导入行。
  • 同时检测包管理器(使用 glob 查找锁文件)。
  • 输出:文件列表,以及 grep 结果中可见的 SDK 导入内容。

升级模块化嵌入(embed.js):

  • 没有可供 grep 的 npm 包。改为在代码库中搜索:
    • Metabase 嵌入 <script> 标签(例如,匹配 metabase.js、embed.js、embedding-sdk 或 Metabase 实例 URL 等模式)
    • 调用 Metabase 嵌入 API 的 JS 代码(例如,MetabaseEmbed、Metabase.embed、window.MetabaseEmbed、initMetabase、组件初始化调用)
  • 输出:文件列表,以及匹配的 grep 行。
步骤 2:提取 API 变更

在第 2 轮运行 prepare.sh(参见轮次预算)。该脚本会输出:

  • SDK_TMPDIR — 包含两个 SDK 包的临时目录(在第 3 轮将其传递给 read-sources.sh)
  • current_dts=yes/no、target_dts=yes/no — d.ts 是否可用(用于信息性输出)
  • DTS_DIFF_PATH — d.ts 差异文件(如果两个版本都有 d.ts)
  • CURRENT_DTS_PATH / TARGET_DTS_PATH — 原始 d.ts 路径(仅混合模式)

你无需手动读取这些文件——read-sources.sh 会处理。

步骤 3:构建变更目录(步骤 1–2 均完成 ✅ 后)

**范围:仅记录会影响步骤 1 的 grep 输出中可见符号的变更。**例如,如果 grep 显示导入了 MetabaseProvider、InteractiveQuestion 和 CollectionBrowser,则仅记录这些组件及其 props/类型/回调的变更。跳过项目未导入的组件变更。

从 d.ts 差异、文档对比和变更日志中提取变更,并整理为目录:

  • 已移除的导出/props/类型
  • 已重命名的符号(旧名称 → 新名称)
  • 类型已变更的 props——将每个类型别名解析为其具体类型。不要止步于别名名称——即使别名未变,其底层类型也可能已经变化。例如,SdkCollectionId 在当前版本中可能是 number,而在目标版本中可能是 number | "personal" | "root" | "tenant" | SdkEntityId。
  • 签名已变更的函数/回调(参数数量、参数类型、返回类型)
  • 已添加的 props/导出(仅限步骤 1 的 grep 输出中的组件,用于信息性输出)
  • 已弃用的 API(包括建议的替代项)
  • 身份验证配置变更——请特别留意。具体信息见变更日志和文档。请查找:类型重命名、fetchRequestToken 签名变更,以及 jwtProviderUri 等新增属性。
目录格式
## Change Catalog (v0.54 → v0.58)

### fetchRequestToken
- Change: signature changed
- Old: `(url: string) => Promise<any>`
- New: `() => Promise<{jwt: string}>` (resolved from `MetabaseFetchRequestTokenFn`)
- Severity: 🔴 Breaking

### SdkCollectionId (type widening)
- Change: type widened
- Old: `number`
- New: `number | "personal" | "root" | "tenant" | SdkEntityId`
- Affects: any prop/callback param typed as `SdkCollectionId`, including `item.id` in CollectionBrowser callbacks
- Severity: 🔴 Breaking for code storing in `number`-typed variables

### SdkDashboardId (type widening)
- Change: type widened
- Old: `number`
- New: `number | string | SdkEntityId`
- Affects: any prop/callback param typed as `SdkDashboardId`
- Severity: 🔴 Breaking for code storing in `number`-typed variables

### jwtProviderUri
- Change: new property added to `MetabaseProvider` authConfig
- Severity: 🟢 Info — can replace manual `fetchRequestToken`

### questionHeight
- Change: new optional prop on `StaticQuestion`
- Severity: 🟢 Info

该目录是步骤 4 的输入。必须包含已完全解析的具体类型——步骤 4 的子 Agent 需要这些信息来评估兼容性,而无需重新读取 d.ts。

步骤 4:逐文件迁移(并行)

根据变更目录,独立分析并修复每个项目文件。这是并行处理的主要环节。

**逐文件处理前:**更新 package.json 版本并安装依赖。如果 Docker 文件中存在 Metabase 实例版本,也要更新(docker-compose.yml、Dockerfile、.env)。这些操作只需执行一次,无需逐文件执行。

逐文件任务(针对步骤 1 文件列表中的每个文件):

对每个文件进行一次处理,合并读取、分析和修复:

  1. 读取文件——这是首次加载该文件内容。提取使用的 SDK 组件、钩子、类型、属性、点语法子组件(例如,<InteractiveQuestion.Title />、<InteractiveQuestion.FilterBar />)以及回调数据流。
  2. 匹配目录条目——目录中的哪些变更会影响此文件的用法?
  3. 根据目标 API 验证当前用法——即使两个版本之间没有破坏性变更,该文件也可能已经使用了无效的属性名称、错误的属性名称、不存在的组件名称或不正确的签名。将文件中的每处用法与目标版本的 API(d.ts 或文档)进行比对,并标记所有不匹配之处。这能发现升级不会自动修复的既有错误——这在仅使用 JS 的项目和 EmbedJS 集成中尤其常见,因为没有类型检查器来捕获这些错误。
  4. 深入分析——对于每个目录匹配项或无效用法:
    • 将文件中的当前用法与目录中的目标类型进行比对
    • 对于回调属性:追踪此文件中回调参数字段的流向(状态设置器、变量、API 调用、路由参数)。检查接收类型是否与目标版本中可能扩大的类型兼容。例如,若 onClick: (item) => setSelectedId(item.id) 且目录指出 item.id 的类型从 number 扩大为 SdkCollectionId,而 setSelectedId 的类型为 useState<number>,则标记为破坏性变更。
  5. 应用修复——编辑文件以迁移所有破坏性变更并更正所有无效用法。
  6. 报告——输出此文件中发现并更改的内容。

并行化策略:

  • ≤ 10 个文件:由主 Agent 处理所有文件——逐个读取文件、匹配目录、修复并继续下一个文件。
  • > 10 个文件:将文件分成 3–5 个子 Agent 批次(平均分配)。每个子 Agent 接收其文件路径和完整的变更目录,读取每个文件、应用修复并汇报。在 Claude Code 中,使用 run_in_background: true 启动。
逐文件输出示例
## src/components/CollectionPage.tsx

### Catalog matches:
- SdkCollectionId type widening → affects `onClick` callback
- (no other catalog entries match this file)

### Analysis:
- `onClick: (item) => setSelectedId(item.id)`
  - `item.id` is now `SdkCollectionId` (number | "personal" | "root" | "tenant" | SdkEntityId)
  - `setSelectedId` is `useState<number | undefined>[1]`
  - 🔴 BREAKING: string variants won't fit `number` state

### Fix applied:
- Widened state: `useState<number | undefined>` → `useState<SdkCollectionId | undefined>`
- Added import: `import type { SdkCollectionId } from '@metabase/embedding-sdk-react'`

Status: ✅ complete
第 5 步:验证类型检查(批量修复)

对于 SDK 升级(TypeScript 项目):

  1. 运行一次类型检查 — 运行项目的类型检查命令(例如 npm run typecheck、tsc --noEmit,或项目构建工具对应的命令)。
  2. 一次性分析所有错误 — 阅读完整的错误输出,并按根本原因对所有与 SDK 相关的错误进行分类(例如“移除了属性”“类型签名变更”“导出项重命名”)。根本原因相同的错误应一起修复。
  3. 查找预期类型 — 对于每个不同的出错符号,搜索 node_modules/@metabase/embedding-sdk-react/dist/index.d.ts,以了解目标类型。先完成所有查找,再进行任何修复,避免在阅读和编辑之间来回切换。
  4. 一次性应用所有修复 — 在重新运行类型检查前,修复所有文件中的所有错误。在 Claude Code 中,尽可能在同一条消息中发出所有 Edit 调用。
  5. 最后运行一次类型检查进行验证 — 重新运行类型检查命令。如果出现新错误(例如,某项修复引发了次生问题),请再应用一批修复并重新运行。如果经过 3 轮批量修复后仍有错误,将第 5 步标记为 ❌ 受阻,并报告无法解决的错误。

对于 SDK 升级(纯 JavaScript 项目):

  • 没有可用的类型检查器。请改为手动检查第 4 步中的每项更改是否符合目标 SDK 的 API:
    • 确认函数签名匹配(参数数量、返回类型)
    • 确认属性名称和值符合目标版本的预期
    • 检查是否有导入项重命名或导出项移除
  • 将第 5 步标记为 ✅ 已完成,并注明验证是手动进行的(无 TypeScript)。

对于 Modular embedding(embed.js)升级:

  • 没有 npm 类型可用于类型检查。请改为:
    • 如果项目使用 TypeScript,运行类型检查命令,捕获迁移引入的任何常规 TS 错误。
    • 如果项目是纯 JavaScript,则跳过类型检查。改为手动检查所有更改过的嵌入配置对象是否符合目标版本文档中的选项。
  • 将第 5 步标记为 ✅ 已完成,并注明执行了哪些验证。
第 6 步:输出摘要

按以下部分组织内容:

1. 已修复的破坏性变更 — 列出每项破坏性变更、严重程度和所做的处理:

  • 🔴 破坏性变更(会导致构建或运行时错误):例如,“将 fetchRequestToken 从 1 个参数迁移为 0 个参数的签名”
  • 🟡 弃用(目前可用,之后会失效):例如,“将 appearance 属性重命名为 theme — 已更新”

2. 弃用警告 — 列出目标版本中仍可使用但已标记为弃用的 API。请包含推荐的替代方案,方便用户规划后续变更。

3. 可用的新功能 — 列出项目可能受益的相关新 API 或选项(例如,用 jwtProviderUri 替代手动调用 fetchRequestToken)。简要指出即可,不要特别推荐。

4. 实例要求 — 目标 SDK 版本所需的最低 Metabase 实例版本。如果项目包含 docker-compose 或类似文件,请注明是否也更新了实例版本。

5. 技术细节 — 使用的路径(主要 d.ts 差异/混合/备用文档)、升级的版本(从 → 到)、使用的包管理器。

重试策略

URL 获取:

  • 如果获取 llms-embedding-full.txt 返回 404,可能是该版本的文档不存在 — 静默跳过。
  • 对于其他错误(5xx、超时、网络):立即重试一次。如果仍然失败,将该步骤标记为 ❌ 受阻并停止。

npm pack:

  • 如果 npm pack 针对某个版本失败,该版本可能不存在于 npm 上。将其标记为 ❌ 受阻并告知用户。

评论

支持 Markdown