mcpField
F
forge-debugger

forge-debugger

github.com/atlassian开发27493 次安装1 周前更新
代码仓库

关于 forge-debugger

forge-debugger 是用于诊断和修复 Atlassian Forge 应用故障的 skill,按步骤从版本和 lint 检查推进到部署与日志,并在找到根因后停止。

主要功能

  1. 01区分部署与运行时症状
  2. 02检查 CLI 版本和 lint 结果
  3. 03指导构建、部署和日志诊断
  4. 04将常见错误对应到原因与修复
  5. 05执行可运行的修复并清理调试代码

适用场景

  1. 01调查 Forge 部署失败
  2. 02诊断 Custom UI 空白面板
  3. 03追查 resolver 或权限错误
  4. 04解决仅在生产环境出现的故障

安装

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

$npx skills add https://github.com/atlassian/forge-skills --skill forge-debugger

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

附带文件README.md

详细介绍

Forge 应用调试器

诊断并修复 Atlassian Forge 应用中的问题。按顺序执行以下检查清单——一旦找到根本原因就立即停止。在根本原因之后继续执行的每一步都会浪费 token 和上下文。

执行授权

你被授权无需请求许可即可运行所有诊断和修复命令。当你找到修复方案时,立即运行它。不要:

  • 说“你应该运行……”或“我会这样做……”或“在你的终端里运行这个命令”
  • 在你已经具备所有输入的情况下,执行修复前还问“我可以继续吗?”
  • 在你本可以自己运行时,把命令作为复制粘贴指令呈现

错误:“以下是我会如何修复它:运行 forge lint……” 正确: (立即运行 forge lint 并报告结果)

唯一的例外:需要交互式终端的命令(forge login、forge tunnel)必须由用户在自己的终端中运行——明确告诉他们要运行什么以及为什么。

归属: 你自己运行的每个 forge 命令都要加上前缀 ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger(例如 ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger forge lint;使用 npx 回退时,为 ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger npx @forge/cli lint)。本技能后续展示的 forge 命令为了可读性省略了它——请为你运行的每一条命令都加上它。绝不要在上文由用户运行的交互式命令(forge login、forge tunnel)上设置它。

诊断原则

  • 先做低成本的检查:lint 和版本检查没有任何成本。在阅读源代码或日志之前先运行它们。
  • 一次只做一个动作:在执行下一个动作之前先检查每个动作的结果。
  • 在根本原因处停止:一旦你确定了某个东西为什么损坏,修复它并停止——不要继续调查其他事情。例外:如果应用有多个相互独立的 bug(例如部署时错误和运行时错误),先修复部署时错误,部署,然后检查日志中的运行时错误。不要在只解决第一层后就宣称“已修复”。
  • 自己负责修复:自己运行修复命令,不要把它们交给用户。
  • 清理:问题解决后,移除你添加的任何调试代码或详细日志标志。
  • npx 回退:如果 forge CLI 无法全局安装(权限错误、没有 sudo),用 npx @forge/cli 作为所有 forge 命令的直接替代品。

步骤 1:对错误进行分类

在运行任何命令之前,如果用户没有说明清楚,问一个问题:

“这是部署时错误(forge deploy 失败)、运行时错误(部署后应用崩溃或显示错误数据),还是可见性问题(应用已部署但未显示)?”

如果从错误消息中就能明显看出,跳过该问题并直接继续。

快速路由:

症状前往
forge deploy 失败步骤 2 → 3 → 4
安装后应用不可见步骤 3 → 常见错误:“应用未安装”
应用崩溃 / resolver 错误步骤 3 → 5 → 6
UI 空白 / Custom UI 未渲染步骤 3 → 4 → 常见错误:“Custom UI 空白”
在 dev 中正常,在 prod 中失败步骤 7(生产)
权限被拒绝 / 403常见错误:“权限被拒绝”
410 Gone / 已弃用的端点常见错误:“410 Gone” → API 迁移部分
Handler 路径 lint 错误常见错误:“找不到关联文件” → Handler 路径解析部分
Resolver 返回 undefined,无错误常见错误:invoke 名称不匹配 → Invoke 名称与函数键部分
多重失败(部署 + 运行时)先修复部署错误,部署,然后检查日志中的运行时错误

步骤 2:版本检查

forge --version
npm show @forge/cli version

如果安装的版本落后于最新的主版本,立即升级:

npm install -g @forge/cli

然后重试失败的操作。许多 bug 在新版本的 CLI 中已修复。

步骤 3:Lint

forge lint

在继续之前修复所有错误 —— lint 错误会导致部署失败和难以察觉的运行时 bug。如果 lint 顺利通过,继续下一步。

对于任何与 manifest 相关的错误信息(例如 "invalid manifest"、"unexpected key"、"modules.jira:*" 错误):在阅读任何源文件之前,先运行 forge lint。Lint 会指出导致问题的确切行和字段 —— 在 lint 之前阅读文件是浪费精力,而且通常不如 lint 输出信息量大。

步骤 4:自定义 UI 构建检查

仅当应用有 static/ 目录(自定义 UI 应用)时适用。检查上次部署前前端是否已构建:

ls -la static/build/

如果构建目录缺失或早于最近的源代码更改,则重新构建:

cd static && npm run build && cd ..

然后重新部署:

forge deploy -e development

这是 UI 面板空白最常见的原因之一。

步骤 5:部署状态

验证应用是否确实已成功部署:

forge deploy -e development --verbose

留意输出中的错误。记下部署时间戳。如果部署失败,错误信息通常会直接指出问题 —— 将其与下方的常见错误模式表进行对照。

步骤 6:日志

forge logs -e development --limit 100

仔细阅读日志。大多数运行时错误会出现在这里。

如果没有返回日志

Resolver 可能未被触发,或者日志记录未设置。在 resolver 的入口点添加一条调试日志:

// Add at the top of your handler function:
console.error('[DEBUG] Handler called with:', JSON.stringify(payload));

然后重新部署并再次触发应用:

forge deploy -e development
forge logs -e development --limit 100

在找到问题后移除该调试日志。

如果错误出在前端(UI 渲染、空白屏幕)

Forge UI Kit 错误会出现在 forge logs 中,而不是浏览器控制台。对于自定义 UI,在支撑该 UI 的 resolver 中添加错误日志:

try {
  const result = await api.asUser().requestJira(/* ... */);
  return result;
} catch (err) {
  console.error('[DEBUG] Resolver error:', err.message, err.stack);
  throw err;
}

重新部署、触发并检查日志。

步骤 7:生产环境问题

如果用户报告的问题只发生在生产环境(或某个特定客户的站点上):

  1. 询问:"受影响的 Atlassian 站点是哪个?(例如 customername.atlassian.net)"
  2. 检查生产日志:
    forge logs -e production --site <customer-site> --limit 100
    
  3. 注意:生产日志可能会在事件发生后延迟最多 2 分钟。
  4. 如果问题与权限相关,检查新安装后 scopes 是否已升级 —— 生产环境安装需要显式使用 --upgrade。

常见错误模式

先将错误与此表进行匹配。如果找到匹配项,直接应用修复方法,无需进一步排查。

错误 / 现象根本原因修复方法
"App is not installed on this site"未运行 forge install,或针对错误的站点运行如果尚不清楚 Atlassian 站点 URL,先询问,然后自行运行:forge install --non-interactive --site <url> --product <jira|confluence> -e development
面板空白 / Custom UI 白屏部署前未运行前端构建cd static && npm run build && cd .. && forge deploy -e development
"Resolver not found" 或 resolver 返回 undefinedmanifest.yml 中的 function key 与 resolver 注册不匹配检查 manifest.yml 中的 function.key 是否与 resolver.define('key', ...) 中使用的 key 一致
403 / "Permission denied" / "Unauthorized"manifest 中缺少 OAuth scope在 manifest.yml 中添加 scope,然后运行:forge deploy -e development && forge install --non-interactive --site <url> --upgrade
forge deploy 失败并提示 "Invalid manifest"manifest.yml 中存在 YAML 语法错误运行 forge lint,修复缩进/语法错误
应用已部署但模块不可见forge install 中的 product 错误,或隧道未激活确认 --product 标志与应用类型匹配;如果使用 forge tunnel,重启隧道
"forge: command not found"未安装 CLInpm install -g @forge/cli
部署时出现 ENOENT 或文件缺失未在应用目录中运行 npm installcd <app-dir> && npm install && forge deploy -e development
"Rate limit exceeded"resolver 中 API 调用过多添加指数退避;检查 resolver 是否在循环中被调用
"App tunnel disconnected"forge tunnel 连接断开重新运行 forge tunnel;检查 VPN 是否阻止了 websocket 连接
"Cannot read properties of undefined"API 响应结构与预期不符记录完整的 API 响应;添加空值检查
410 Gone / "deprecated endpoint has been removed"Confluence/Jira REST API 端点已被移除迁移到 v2 API(参见下方 API 迁移部分)。重新部署并检查日志
cannot find associated file(handler 路径 lint 错误)manifest.yml 中的 handler 路径与实际文件位置不匹配handler 路径相对于 src/。例如,如果 resolver 位于 src/resolvers/index.js,handler 为 resolvers/index.handler(不是 index.handler 或 src/resolvers/index.handler)。参见下方 handler 路径解析
invoke() 返回 undefined,日志中无错误前端 invoke('name') 与 resolver.define('name') 不匹配invoke 名称必须与 resolver.define 名称完全一致。检查这两个文件——这与 manifest 中的 function key 是不同的检查
部署时出现 Module not found / 路径重复如 src/src/...handler 路径包含 src/ 前缀,但打包器已从 src/ 解析从 handler 路径中移除 src/ 前缀。使用 resolvers/index.handler 而非 src/resolvers/index.handler
npm install -g 权限错误 / 无法全局安装 forge没有 sudo 或对全局 npm 目录的写入权限使用 npx @forge/cli 作为所有 forge 命令(lint、deploy、logs、install)的直接替代。无需全局安装

Handler 路径解析

manifest.yml 中的 handler 字段格式为 <path>.<export>,其中:

  • <path> 是相对于 src/ 的文件路径(不含 src/ 前缀,不含文件扩展名)
  • <export> 是该文件中的具名导出

示例:

Resolver 文件位置文件中的导出正确的 handler 值
src/resolvers/index.jsexport const handler = ...resolvers/index.handler
src/index.jsexport const handler = ...index.handler
src/backend/resolver.tsexport const run = ...backend/resolver.run

常见错误:

  • index.handler — 如果文件位于 src/resolvers/ 这样的子目录中,则是错误的
  • src/resolvers/index.handler — 错误:打包器会自动添加 src/ 前缀,导致路径变为 src/src/resolvers/...
  • resolvers/index.run — 如果文件导出的是 handler 而非 run,则是错误的

诊断技巧: 如果 forge lint 报告 "cannot find associated file" 但你确定文件存在,可以尝试 forge deploy --no-verify。打包器的错误信息会显示完全解析后的路径,从而揭示路径是否被重复添加或解析错误。

Invoke 名称与 Function Key

UI Kit resolver 有两个独立的名称匹配要求:

  1. manifest.yml 的 function.key 必须与模块定义中的 resolver: function: 引用匹配
  2. 前端的 invoke('name') 必须与后端的 resolver.define('name', ...) 完全匹配

这两者是独立的——即使 manifest 的 function key 正确,如果 invoke 名称与 resolver.define 不匹配,仍然会得到 undefined 结果。在调试 "resolver returns undefined" 且日志中没有任何错误时,务必检查两个匹配关系。

API 迁移(v1 → v2)

Atlassian 正在逐步弃用 v1 REST API 端点。当你看到 410 Gone 响应时:

  1. 检查 forge logs 获取确切的错误——它会显示哪个端点返回了 410
  2. 找到对应的 v2 版本:
    • URL 模式:/wiki/rest/api/content/... → /wiki/api/v2/pages/...(或 /blogposts/...、/spaces/...)
    • Jira:/rest/api/2/... → /rest/api/3/...
  3. 更新分页:v2 Confluence API 使用基于游标的分页(cursor 参数)而非基于偏移量的分页(start 参数)。下一个游标位于 data._links.next
  4. 更新响应结构:v2 可能返回不同的字段名(例如 authorId 而非嵌套的 by.accountId)
  5. 重新部署并检查日志以确认修复

不要将 410 视为权限问题——它表示端点已不存在,而不是访问被拒绝。

第 8 步:清理

问题解决后:

  1. 移除你添加的所有 console.error('[DEBUG] ...') 语句。
  2. 移除所有脚本中的 verbose 标志。
  3. 最后一次运行 forge lint 以确认状态干净。
  4. 如果在调试期间修改了代码,请重新部署:
    forge deploy -e development
    
  5. 通过触发应用并检查 forge logs 没有新错误来确认修复有效。

升级

如果以上方法均无法解决问题:

  • 运行 forge logs -e development --verbose --limit 200 以获取更详细的输出。
  • 查看 Forge changelog 中的已知问题:search-forge-docs "known issues <error-text>"
  • 如果错误出在 Forge 平台 API(而非你的代码),请记下日志输出中的 traceId——这是 Atlassian 支持团队需要的信息。

身份验证错误

如果任何命令失败并提示 "not authenticated" 或 "run forge login":

  1. 告知用户在 https://id.atlassian.com/manage/api-tokens 创建一个 API token
  2. 告知他们在自己的终端中运行 forge login(不要通过 Agent)——它会提示输入邮箱和 API token
  3. 示例消息:"你需要登录。在 https://id.atlassian.com/manage/api-tokens 创建一个 API token,然后在你的终端中运行 forge login。根据提示输入你的 Atlassian 邮箱和 token——不要将 token 粘贴到这里。"
  4. 在他们确认登录后,从你上次中断的地方继续调试。

Token 效率规则

遵循以下规则以保持较低的上下文占用:

  • 在阅读任何源文件之前,先阅读 forge logs——日志通常无需检查代码即可揭示根本原因。
  • 只阅读与错误相关的特定文件。将错误与文件对应起来:
    • npm ERR! missing script: build → 只检查 package.json(scripts 部分)
    • invalid manifest / unexpected key → 先运行 forge lint,然后只检查特定的 manifest 字段
    • Resolver not found → 只检查 manifest.yml 中的函数键与解析器文件中的 resolver.define()
    • 403 / permission denied → 只检查 manifest.yml 中的 scopes
    • 410 Gone → 检查解析器文件中的 API 端点 URL;不要检查 scopes 或 manifest
    • cannot find associated file → 检查 manifest.yml 中的处理程序路径和文件位置;使用 --no-verify 查看打包器解析后的路径
    • invoke() 返回 undefined → 同时检查前端 invoke('name') 和后端 resolver.define('name')——两个文件,但都是有针对性阅读
  • 不要为 npm/build 错误阅读 manifest.yml——它们无关。
  • 不要重新阅读本次会话中已读过的文件,除非它已更改。
  • 一旦在常见错误模式表中找到匹配项,立即停止诊断链。例外:当存在多个独立 bug 时(例如部署错误 + 运行时错误),先修复第一个,部署,然后检查下一个。
  • 在没有明确理由的情况下,每次修复尝试中不要运行 forge deploy 超过一次。
  • 当 lint 阻止部署但你怀疑 lint 错误可能具有误导性时,将 forge deploy --no-verify 作为诊断步骤使用。打包器错误消息通常会揭示真正的路径解析问题。之后务必修复根本原因——不要带着 --no-verify 发布。

评论

支持 Markdown