oh-aireport
v1.1.1
Published
Use npm to configure OpenCode / Claude Code / Codex with AI coding issue reporting (webhook / GitCode / local sink).
Maintainers
Readme
oh-aireport
oh-aireport 是 AI 编码问题反馈能力包,用于给 OpenCode、Claude Code 和 Codex 安装问题上报入口,并提供 JS CLI 生成结构化 issue payload。
当前源码版本:1.1.1(尚未发布)。要求 Node.js 24 或更新版本。
源码新增精简反馈模板(尚未发布):本次模板 schema 为 2.0.0,与 npm 包版本分别管理。下面的精简字段、证据和样例适用于当前源码;安装章节中的 npm 1.1.0 不包含这些改动。试用新版请在仓库目录运行 node bin/cli.js setup all --skip-email 并重启 Agent;MCP 使用下文的本地开发注册方式。
1.1.0 新增 MCP Server,提供 6 个工具与 3 个资源,支持 OpenCode、Claude Code 和 Codex;CLI 与 MCP 共用 IssueService。MCP 接入方法见下文「MCP 集成」。
1.0.0 新增 setup、check、update、verify-update;install 保留为 setup 的兼容入口。三个 Agent 分别绑定持久化运行版本,不依赖 npx 缓存或全局 npm 包。完整行为与验收说明见 1.0.0 安装与升级。
1.0.0 已实现反馈现场关联第一阶段:三种 Agent 在反馈入口冻结原始会话及项目,使用 context_file 传递到上报流程;缓存按工作区、Agent、宿主和会话隔离。旧根级 metadata.json 不再自动补全会话。当前冻结的是关联信息,尚未自动采集问题前后的对话正文、工具失败输出或完整日志。
能做什么
- 为 OpenCode 安装 slash command、
oh-ai-report插件、argv helper,并自动注册到 OpenCode 全局配置。 - 为 Claude Code 安装
/report-ai-issue命令和可选 hook,并可合并settings.json。 - 为 Codex 安装
oh-ai-reportskill 和 PowerShell wrapper。 - 保存公司邮箱作为提交人标识;默认只接受
@huawei.com/@h-partners.com,可用OHAI_COMPANY_EMAIL_DOMAINS扩展域名白名单。 - 从 CLI 或 JSON 文件生成结构化 issue payload。
- 支持
local、webhook、gitcode三类 sink。 - 可被聚合安装器
oh-aicoding-tool report ...调用。
快速使用
先确认 Node.js 版本,再安装到需要使用的 Agent。以下单行命令可在 PowerShell、Bash 或 zsh 中执行;请将示例邮箱替换为自己的公司邮箱。
node --version
npx [email protected] setup all --email [email protected]
npx [email protected] check all只安装一个 Agent 时,选择对应命令:
npx [email protected] setup opencode --email [email protected]
npx [email protected] setup claude --email [email protected]
npx [email protected] setup codex --email [email protected]目标含义:
opencode:安装 OpenCode 命令、插件、插件 helper,并注册./plugins/oh-ai-report.ts。claude:安装 Claude Code 命令;默认同时安装 hook,可用--skip-hook跳过。codex:安装 Codex skill 和 wrapper;支持CODEX_HOME。both:安装 OpenCode + Claude Code。all:安装 OpenCode + Claude Code + Codex。
三种 Agent 都安装成功时,check all 的输出示例为:
opencode: ok, version 1.1.0
claude: ok, version 1.1.0
codex: ok, version 1.1.0安装后完整退出并重启对应 Agent,再在发生问题的项目会话中反馈。check 检查本地安装,不代表已验证远端建单或真实模型调用。
跳过邮箱写入(需要时可之后重新运行 setup --email ...):
npx [email protected] setup opencode --skip-email预览安装动作:
npx [email protected] setup opencode --dry-run在 Agent 中反馈:使用方法与样例
直接描述已经发生的问题即可;已知时补充任务期望、实际结果和影响。Agent 保留用户原话,整理可观察事实与带来源的证据;Agent 根据已知事实选择问题分类;不明确时使用「其他」,无需用户补齐优先级、原因、改进方向或分派建议。
新版报告结构
正文依次展示「用户反馈 → 问题摘要(包含问题分类)→ 问题表现 → 相关证据 → 基础信息」。没有额外事实时省略「问题表现」;没有证据时明确写明「未附相关证据;当前仅依据用户反馈」。邮箱、Agent、模型、原始 Session 固定放在底部,未知时显示「未采集」,故障及上报 Session、项目、分支、提交、时间和 Trace 等已知信息随后列出。
- 用户反馈:保留原话,不擅自扩大影响或补写原因。
- 问题摘要:Agent 根据用户原话和已知证据生成简短的事实摘要,分类放在摘要中。分类为模型输出错误、工具调用失败、Skill 缺陷、上下文缺失、环境问题或其他;不确定时为其他。直接调用 CLI/MCP 时由调用方提供摘要,未提供时显示「未提供」,工具不会自行调用模型。
- 问题表现:可选的实际结果、明确的期望及已知影响;与原话或摘要相同的实际表现不重复展示。
- 相关证据:按事件顺序提供问题前的用户要求、相关助手回复、失败调用和错误原文,以及触发反馈前已发生的后续结果。只附当前可见或用户提供的相关片段,标注来源;消息/调用 ID 已知才填写。不得用上报过程中产生的对话或错误替代原始现场。
- 基础信息:优先复用冻结现场;上报会话的模型、项目和 Session 不能覆盖已有的原始现场。没有冻结值时可补充明确已知的模型或邮箱,不能推测。
证据不会自动从完整历史或日志目录读取。手工截取、脱敏的片段需设置相应标记;超过长度限制会校验失败,不会静默截断。问题发生时间仅在确知时填写,不用冻结时间或反馈时间替代。
查看完整输入样例、报告正文及正文 JSON。样例中的对话、错误、邮箱、模型、时间和 ID 均为演示数据;渲染样例数据仅用于展示和测试,不是可复用的现场快照。
OpenCode
在问题发生的项目会话中输入:
/report-ai-issue 执行设备调试时,HDC 工具返回 device not found;预期能连接开发板,实际无法继续调试,请按环境问题反馈。也可以自然语言触发:
请把刚才 HDC 连接失败的问题反馈给团队。预期能发现开发板,实际返回 device not found,导致调试中断。Slash command 通过上报子任务调用 report_ai_issue 工具,并携带进入子任务前冻结的现场;自然语言反馈由当前 Agent 直接调用同一工具。--plugin-only 安装不包含 slash command。
Claude Code
在当前开发会话中输入:
/report-ai-issue 刚才生成的单元测试调用了不存在的接口,编译失败。预期使用项目已有接口,实际需要手工修改,请按模型输出错误反馈。也可直接说「请反馈刚才生成的测试无法编译的问题」。默认安装的 hook 负责在反馈入口采集现场;使用 --skip-hook 时,主 Agent 需要先采集上下文,再把快照传给上报流程。
Codex
Codex 使用 oh-ai-report skill。在发生问题的会话中明确指定:
请使用 oh-ai-report 上报这个问题:本次修改遗漏了之前约定的错误处理,预期保留失败分支,实际直接返回成功,影响异常场景验证。Skill 会先冻结当前项目与会话,再整理并提交报告;Windows 可通过安装的 PowerShell wrapper 执行,macOS/Linux 使用 Node.js CLI。
如何确认结果
成功回复格式如下,实际 ID、链接或路径由工具返回:
已上报:<实际 issue_id> <远端 Issue 链接或本地 JSON 路径>本地路径表示报告已保存到本地;远端建单需检查返回的 webhook_url 或 gitcode_url。失败时会返回错误,不能仅凭生成了 issue_id 判断远端创建成功。
Agent 集成默认使用 webhook。如仅需本地试用,在启动 Agent 的终端设置 OHAI_REPORT_SINK=local,再从同一终端启动 Agent:
# PowerShell
$env:OHAI_REPORT_SINK = "local"# Bash / zsh
export OHAI_REPORT_SINK=local直接执行 CLI create 时默认使用 local;要远端建单需显式传 --sink webhook 或 --sink gitcode。
检查与升级
npx [email protected] check all --json
npx [email protected] verify-update all --json
npx oh-aireport@latest update all --dry-run
npx oh-aireport@latest update all
npx oh-aireport@latest check allcheck:离线检查已有安装。ok表示健康,missing表示未安装,unmanaged表示旧安装尚未纳入管理,broken表示文件或配置异常。all只检查检测到的安装;检查某个特定 Agent 可用check codex等。verify-update:先检查本地安装,再查询 npm 最新版本;只检查,不升级。update all:升级已有安装,可迁移旧版入口;保留邮箱和无关配置,不自动安装缺少的 Agent。升级后重启对应 Agent。setup/update安装的是正在执行的 npm 包版本。固定到 1.1.0 可用npx [email protected] update all;获取最新版使用@latest。
如果使用全局命令,可先执行 npm install -g [email protected]。仅升级全局 npm 包不会更新 Agent 已绑定的运行时,还需执行 oh-aireport update all。
命令
以下裸命令适用于已全局安装的情况;未全局安装时,将 oh-aireport 替换为 npx [email protected]。
oh-aireport setup all [--email [email protected]]
oh-aireport check all [--json]
oh-aireport update all [--skip-email] [--dry-run]
oh-aireport verify-update all [--json]
oh-aireport install opencode [--email [email protected]|[email protected]] [--skip-email]
oh-aireport install claude [--email [email protected]|[email protected]] [--skip-email]
oh-aireport install codex [--email [email protected]|[email protected]] [--skip-email]
oh-aireport install both [--email [email protected]|[email protected]] [--skip-email]
oh-aireport install all [--email [email protected]|[email protected]] [--skip-email]
oh-aireport create [...ohai-report args]
oh-aireport metadata [...ohai-report args]
oh-aireport context capture --source codex --cwd <project> --json兼容入口:
opencode-ohai-report安装选项
| 选项 | 说明 |
| --- | --- |
| --email <email> | 非交互式写入公司邮箱;默认要求 @huawei.com 或 @h-partners.com |
| --skip-email | 不询问、不写入邮箱配置 |
| --dry-run | 只打印动作,不修改文件 |
| --skip-env | 不写入用户级 OHAI_REPORT_CLI 环境变量 |
| --plugin-only | OpenCode only:只复制插件,跳过命令 |
| --skip-hook | Claude only:跳过 hook 和 settings 合并 |
交互式安装可输入公司邮箱,回车保留原设置。非交互安装可通过 --email 或环境变量 OHAI_INSTALL_USER_EMAIL 更新邮箱;也可用 --skip-email 明确跳过。update 默认保留邮箱,只有显式 --email 才修改。安装器跨平台运行;Windows 用 PowerShell 设兼容环境变量,Linux/macOS 写 shell rc 文件。--skip-env 不影响已经绑定运行路径的集成。
OpenCode 安装内容
OpenCode 安装会写入:
~/.config/opencode/commands/report-ai-issue.md~/.config/opencode/skills/issue-dispatch/SKILL.md~/.config/opencode/plugins/oh-ai-report.ts~/.config/opencode/plugins/oh-ai-report-argv.mjs~/.config/opencode/ohai-report/email.json~/.config/opencode/opencode.json(或已有的opencode.jsonc)中的plugin列表- 用户级
OHAI_REPORT_CLI
运行时会复制到:
~/.config/ohai-report/runtimes/<版本>/<内容摘要>/
~/.config/ohai-report/runtime.json三种 Agent 共享上述托管运行目录,各自绑定安装时的版本,不依赖临时 npx 缓存。设置 XDG_CONFIG_HOME 时,OpenCode 和共享运行目录使用该配置根目录。
如果需要覆盖全局邮箱,可在项目内写入:
<project>/.ohai-report/user_email.json内容格式:
{"user_email":"[email protected]"}Claude Code 安装内容
Claude Code 安装会写入:
~/.claude/commands/report-ai-issue.md~/.claude/commands/dispatch-issue.md~/.claude/ohai-report/email.json~/.claude/hooks/ohai-report-hook.js~/.claude/settings.json中的 hook 配置- 用户级
OHAI_REPORT_CLI
使用 --skip-hook 时只安装命令和运行时,不复制 hook、不合并 settings.json。Claude 安装会优先读取 Claude 自己的邮箱配置;没有时会复用 OpenCode 已保存的邮箱。
Codex 安装内容
Codex 安装会写入:
~/.codex/skills/oh-ai-report/SKILL.md~/.codex/skills/oh-ai-report/codex-report-issue.ps1~/.codex/skills/issue-dispatch/SKILL.md~/.codex/ohai-report/email.json- 用户级
OHAI_REPORT_CLI - 用户级
OHAI_REPORT_CODEX_SCRIPT
Codex 入口是 skill,不是 /report-ai-issue slash command。安装器会优先使用 CODEX_HOME,未设置时写入 ~/.codex。Skill 中写入本次安装的 CLI 路径,wrapper 内绑定同一版本,优先于继承的环境变量。
安装后请完整退出并重启 OpenCode、Claude Code 或 Codex,让命令、插件、hook、skill 和用户级环境变量生效。
创建 issue payload
本节使用未发布的源码版本。在本仓库目录执行,--cwd 指向实际发生问题的项目(示例以 . 表示当前项目),默认只生成本地报告。从其他目录执行时,将 bin/cli.js 换成该文件的绝对路径。
从字段创建本地报告
node bin/cli.js create --source opencode --cwd . --title "HDC 找不到开发板" --user-description "刚才 HDC 返回 device not found,请反馈这个问题" --metadata auto --sink local --json只有 title 和 user_description 是问题内容的必填字段:
| 字段 | 说明 |
| --- | --- |
| title | 标题,最多 80 字符 |
| user_description | 用户原始描述,最多 2000 字符 |
| actual_behavior / expected_behavior | 可选:实际表现与明确的期望,各最多 400 字符 |
| impact | 可选:已知影响 |
| summary | AI 根据已知事实生成的问题摘要,最多 800 字符;兼容旧调用,未提供时显示「未提供」 |
| occurred_at | 可选:已知的问题发生时间,ISO 8601,必须包含时区 |
| evidence | 可选:带来源的证据数组,最多 10 条,每条正文最多 12000 字符 |
| severity | 可选:用户明确指定的 P0 / P1 / P2 / P3,不再默认 P2 |
| category | 可选问题分类:模型输出错误、工具调用失败、Skill 缺陷、上下文缺失、环境问题、其他;省略或无法确定时为「其他」 |
CLI 参数使用连字符(如 --expected-behavior),JSON 字段使用下划线(如 expected_behavior)。
旧的场景、角色、分类分析、原因、改进方向和分派建议等字段仍可读取并保存在 payload 中,正文不展示,也不要求 Agent 填写。已有的远端标签与分发接口保持兼容。template_version 标识正文模板版本。
从 JSON 文件创建
带对话与失败输出时使用 JSON 文件,避免命令行引号损坏。以下是简短输入样例(UTF-8,无 BOM):
{
"title": "生成的测试调用了不存在的接口",
"user_description": "请反馈刚才生成的测试无法编译的问题。",
"summary": "用户反馈生成的测试编译失败,编译器报告 TS2305。",
"category": "模型输出错误",
"actual_behavior": "编译报 TS2305,未执行测试。",
"evidence": [{
"type": "error",
"source": "用户提供的编译输出",
"content": "error TS2305: Module has no exported member 'createMockClient'.",
"truncated": true
}]
}node bin/cli.js create --source claude --cwd . --issue-file examples/issue-input.json --metadata auto --sink local --json返回 JSON 包含 ok、issue_id、path、context_file 和三类会话 ID。path 指向完整报告;原始会话未知时 ID 留空。报告保存在 <项目>/.ohai-report/issues/<issue_id>.json,同时更新 <项目>/.ohai-report/latest.json。
上面的命令读取仓库中的完整样例。自己的输入文件可用绝对路径传入 --issue-file。Codex PowerShell wrapper 同样支持 -IssueFile,相对路径按 -Cwd 解析;最简输入可用 -Title 和 -UserDescription。
每条 evidence 必填 type(conversation / tool / error)、source(真实来源说明)和 content(原文)。可选字段包括 role(user / assistant / tool)、session_id、message_id、tool_call_id、tool_name、command、整数 exit_code、布尔值 truncated 和 redacted。未知 ID 省略;截断与脱敏由调用方完成并如实标记。
可选字段通过 JSON 或 --field 追加,例如 --impact "本次测试未能运行"。完整字段和限制见 schema。
先冻结现场,再跨会话上报
通常由 Agent 集成完成这两步。手动接入或委派上报时,先在原始项目采集,再将返回的 context_file 原样传入 create。
| 字段 | 含义 |
| --- | --- |
| origin_session_id | 原始开发任务所在会话;兼容字段 session_id 也指向它 |
| failure_session_id | 实际发生故障的会话,例如执行失败的子任务;未知时留空 |
| report_session_id | 执行最终上报的会话,可以与原始会话相同 |
| report_context.incident_workspace | 触发反馈时冻结的项目目录和 Git 信息 |
| reporting_workspace | 执行最终上报时的工作目录信息 |
下面是 PowerShell 示例,从源码仓库目录开始,将 $project 替换为问题项目绝对路径并准备该项目的 issue-input.json;示例中的会话 ID 仅用于演示,真实反馈应替换为宿主提供的真实 ID,未知时省略相应参数。
$cli = (Resolve-Path ./bin/cli.js).Path
$project = "D:\path\to\actual-project"
$issueFile = Join-Path $project "issue-input.json"
$capturedJson = node "$cli" context capture --source codex --cwd "$project" --session-id "demo-origin-session" --failure-session-id "demo-failure-session" --json
if ($LASTEXITCODE -ne 0) { throw "采集现场失败" }
$context = $capturedJson | ConvertFrom-Json
# 上报可以在另一会话或目录执行,但必须复用同一份 context_file。
node "$cli" create --source codex --cwd "$project" --context-file "$($context.context_file)" --report-session-id "demo-report-session" --issue-file "$issueFile" --sink local --json结果中的原始、故障和上报会话分别对应三个示例 ID。即使上报时切换目录,报告仍保存到冻结的原始项目中。快照按会话隔离并带完整性校验,不要手工修改快照文件,也不要把其他 Agent 的快照传给当前 --source。
冻结快照保存关联信息,不自动读取对话正文和失败输出。新版通过 evidence 显式携带相关片段;trigger_message_id、anchor_message_id、tool_call_id 仍只是关联标识,不代表已保存对应正文。
补充观测关联信息
宿主已提供真实 session、message、trace 等 ID 时,可在采集现场之前写入对应会话的 metadata;以下值是占位示例:
npx [email protected] metadata update --source opencode --cwd . --session-id "opencode-session-xxx" --message-id "msg-xxx" --trace-id "langfuse-trace-xxx" --observation-id "obs-xxx" --json后续采集必须使用相同项目、Agent、宿主和会话标识,才能读到这份缓存。已经冻结的快照不会被之后的 metadata 更新覆盖。
Sink
| Sink | 行为 |
| --- | --- |
| local | 写入 .ohai-report/issues/*.json |
| webhook | POST 到 webhook,远端操作成功后保存本地副本 |
| gitcode | 创建 GitCode/Gitee Issue,远端操作成功后保存本地副本 |
使用前面的 JSON 文件提交到指定 webhook(将 URL 替换为实际服务地址):
node bin/cli.js create --source claude --cwd . --issue-file examples/issue-input.json --sink webhook --webhook-url "https://feedback.example.com/webhook" --json直连 GitCode 时,先在运行环境中配置 OHAI_GITCODE_TOKEN、OHAI_GITCODE_OWNER 和 OHAI_GITCODE_REPO,再执行:
node bin/cli.js create --source claude --cwd . --issue-file examples/issue-input.json --sink gitcode --jsonwebhook / gitcode 命令会真实发送报告。远端调用失败时 CLI 返回错误;需要先保留草稿可先运行 --sink local。
Webhook URL 解析顺序:
--webhook-urlOHAI_WEBHOOK_URL或WEBHOOK_URL- 内置默认配置
常用环境变量:
| 变量 | 作用 |
| --- | --- |
| OHAI_WEBHOOK_URL / WEBHOOK_URL | Webhook 地址 |
| OHAI_WEBHOOK_SECRET / WEBHOOK_SECRET | 可选 webhook secret |
| OHAI_WEBHOOK_TIMEOUT / WEBHOOK_TIMEOUT | Webhook 超时秒数 |
| OHAI_WEBHOOK_LABELS | 逗号分隔的 webhook labels |
| OHAI_GITCODE_OWNER / GITCODE_OWNER | GitCode/Gitee owner |
| OHAI_GITCODE_REPO / GITCODE_REPO | 仓库路径 |
| OHAI_GITCODE_TOKEN / GITCODE_ACCESS_TOKEN | 访问令牌 |
| OHAI_GITCODE_API_BASE | GitCode API 根地址 |
| OHAI_GITCODE_LABELS | 逗号分隔的 GitCode labels |
| OHAI_GITCODE_LABEL_MAINTAINER / OHAI_GITCODE_MAINTAINER | 允许缺失标签时自动创建 |
| OHAI_GITCODE_NEW_LABEL_COLOR | 自动创建标签时使用的颜色 |
| OHAI_USER_EMAIL | 提交人邮箱 |
MCP 集成(MCP Server)
除前述「slash command → 插件/hook/skill → spawn CLI」链路外,本仓还提供 MCP Server:AI Agent(OpenCode / Claude Code / Codex)可通过 MCP 协议直连,调用 6 个工具 + 3 个资源,无需 spawn CLI 进程。两条链路共享同一套编排逻辑(src/service.js 的 IssueService,含 1.0 反馈现场关联),不会出现能力漂移。
何时用哪条链路
| 场景 | 推荐链路 |
|---|---|
| Agent 已装 slash command / 插件 / hook / skill,且偏好命令式触发 | CLI 链路(/report-ai-issue) |
| Agent 原生支持 MCP,希望工具发现与调用走 MCP 协议(无需安装命令模板) | MCP 直连 |
| 需要在不同项目复用同一 server、按 workspace 隔离现场 | MCP 直连(cwd 入参) |
启动 MCP Server
npm run mcp # node src/mcp-server.js
npx -y --package [email protected] ohai-report # 已发布版本的 MCP binServer 通过 stdio 收发 JSON-RPC;启动 banner 写到 stderr(不污染 stdout JSON-RPC 通道)。零运行时依赖(手写 MCP stdio JSON-RPC,不依赖 @modelcontextprotocol/sdk),启动毫秒级。
注册到三端 Agent(推荐:各 agent 原生 mcp add)
分别在各 agent 自身的 CLI 注册——让 agent 自己写它自己的配置最稳,oh-aireport 不直写别家配置文件。oh-aireport 已把 MCP server 作为 npm bin ohai-report 暴露(package.json 里 "ohai-report": "src/mcp-server.js"),按发布版 / 本地开发两种方式选其一。
发布版(npm 包,推荐)——从 npm 拉取启动,无需关心本地仓库或运行目录路径:
# OpenCode
opencode mcp add --global ohai-report -- npx -y --package [email protected] ohai-report
# Claude Code(-s user 写到用户作用域,跨项目持久)
claude mcp add -s user ohai-report -- npx -y --package [email protected] ohai-report
# Codex
codex mcp add ohai-report -- npx -y --package [email protected] ohai-report全局安装(npm install -g oh-aireport)后可去掉 npx -y,直接用稳定 bin,启动更快:
opencode mcp add --global ohai-report -- ohai-report
claude mcp add -s user ohai-report -- ohai-report
codex mcp add ohai-report -- ohai-report本地开发(仓库路径)——把 <repo-path> 替换为本仓绝对路径(如 E:\project\emailnew\oh-aireport):
opencode mcp add --global ohai-report -- node <repo-path>/src/mcp-server.js
claude mcp add -s user ohai-report -- node <repo-path>/src/mcp-server.js
codex mcp add ohai-report -- node <repo-path>/src/mcp-server.js敏感变量不要写进注册命令:
OHAI_GITCODE_TOKEN/OHAI_WEBHOOK_URL等在启动 agent 前于 shell 里export/$env:设好即可——MCP server 作为 agent 的子进程会继承该环境,无需把 token 硬编码进配置。作用域:Claude 的
-s可选local(项目本地)/project(项目共享)/user(跨项目持久,推荐)。OpenCode、Codex 的作用域模型不同,按各自mcp add --help选。版本冻结替代方案:若已用
npx oh-aireport setup安装并希望绑定固定版本(不随 npm 包更新或 npx 缓存变化),可改用 setup 生成的托管运行目录注册:node ~/.config/ohai-report/runtimes/<版本>/<hash>/src/mcp-server.js。其中<hash>是 runtime 文件内容的 sha256 前 16 位(冲突时附-<uuid>),可从~/.config/ohai-report/runtime.json的targets.<agent>.runtime_dir字段查到完整路径。日常推荐用上面的npx/ 全局 bin 方式。
Windows 故障排查(MCP 启动报
EPERM rmdir):npx 启动时若报EPERM: operation not permitted, rmdir ...\node_modules\oh-aireport(退出码 48),通常是杀毒软件扫描或残留 node 进程占用了 npx 缓存目录。执行以下命令后重启 agent 即可恢复:taskkill /IM node.exe /F Remove-Item -Recurse -Force "$env:LOCALAPPDATA\npm-cache\_npx"
取消注册
Claude / Codex 用各自原生 mcp remove;OpenCode 没有 mcp remove 命令,本仓提供独立脚本填这个缺口(JSONC-safe,保留注释与无关配置,删前 .bak 备份)。该脚本已作为 npm bin ohai-mcp 暴露(package.json 里 "ohai-mcp": "src/mcpUnregister.js"),独立于 bin/cli.js,不受 Node≥24 门约束(纯 JS,≥18 可跑)——注销无需本地仓库路径,用 npx -y -p oh-aireport ohai-mcp 即可。
# Claude Code(与上面 -s user 注册对应;若同名多 scope 报错则加 --scope user)
claude mcp remove ohai-report
# Codex
codex mcp remove ohai-report
# OpenCode(无原生 remove,用本仓 bin ohai-mcp;无需本地仓库路径)
npx -y -p oh-aireport ohai-mcp unregister opencode # 默认删 ohai-report(v2 mcp.servers 下 / v1 mcp. 扁平,两结构都查)
npx -y -p oh-aireport ohai-mcp unregister opencode --cwd <project> # 指定项目目录(默认当前目录)
npx -y -p oh-aireport ohai-mcp unregister opencode --name <server> # 改名注册过的 server
npx -y -p oh-aireport ohai-mcp unregister opencode --json # 机器可读输出ohai-mcp unregister opencode(即 src/mcpUnregister.js)行为:
- 扩展名:
opencode.json与opencode.jsonc都查(JSONC tokenizer 兼容纯 JSON,注释原样保留)。 - 位置:项目级(
--cwd,默认当前目录)与全局(~/.config/opencode,尊重XDG_CONFIG_HOME)两处都查,找到mcp.servers.<name>(v2)或mcp.<name>(v1)就删;两处都有就两处都删;都没有则报"未注册"(no-op,不改任何文件)。 - 安全:删前把原文件备份到
<file>.bak;只按 token 边界切掉目标条目,不重写整份文档——注释、尾逗号、无关 server 与配置全部保留。 - 删后
mcp若变空对象则留"mcp": {}(无害,可自行清理或保留)。
opencode mcp logout <name>只清 OAuth 凭证、不删 server 注册;本仓本地 stdio server 不走 OAuth,注销用不到它。Claude/Codex 的remove会同时清掉配置与凭证。
或直接编辑配置文件(辅助参考)
完整配置文件见 examples/mcp-clients/,可直接复制修改(将 <repo-path> 替换为本仓绝对路径):
opencode-v2.json— OpenCode v2(嵌套mcp.servers.ohai-report,opencode mcp add实际写入此结构)opencode-v1.json— OpenCode v1(扁平mcp.ohai-report)claude-code.json— Claude Code(mcpServers.ohai-report,type: stdio)codex.toml— Codex(含startup_timeout_sec=30/tool_timeout_sec=180提示)
按版本选:v2 用
opencode-v2.json(mcp.servers.<name>),v1 用opencode-v1.json(mcp.<name>)。不确定版本就别手改——用opencode mcp add注册,OpenCode 会按你的版本写对结构。注销同理:npx -y -p oh-aireport ohai-mcp unregister opencode(或node src/mcpUnregister.js unregister opencode)两种结构都查。
OpenCode v2 配置文件示例(嵌套):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"ohai-report": {
"type": "local",
"command": ["node", "<repo-path>/src/mcp-server.js"],
"enabled": true,
"environment": { "OHAI_GITCODE_TOKEN": "{env:OHAI_GITCODE_TOKEN}" }
}
}
}
}OpenCode v1 配置文件示例(扁平,少一层 servers):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ohai-report": {
"type": "local",
"command": ["node", "<repo-path>/src/mcp-server.js"],
"enabled": true,
"environment": { "OHAI_GITCODE_TOKEN": "{env:OHAI_GITCODE_TOKEN}" }
}
}
}工具清单(6 个)
| 工具 | 用途 | 与 CLI 等价 |
|---|---|---|
| report_ai_issue | 上报问题(local/gitcode/webhook sink + 现场冻结) | create |
| update_metadata | 更新 session-scoped metadata | metadata update |
| list_recent_issues | 列最近 issue(按 mtime 倒序,只读) | — |
| get_latest_issue | 读 latest.json 完整 payload(只读) | — |
| get_metadata | 读 session-scoped metadata(与 update_metadata 同 scope) | — |
| validate_issue | dry-run 校验字段(不创建) | — |
report_ai_issue 的 context_file / report_session_id 入参与 CLI create --context-file / --report-session-id 等价,走同一现场冻结流程:传入 context_file 时复用已冻结快照,否则按 cwd/source/session 现场采集。
源码新版 report_ai_issue 必填 title、user_description、source(opencode / claude / codex)及 cwd(当前问题项目路径)。MCP server 的启动目录不能代替当前项目。evidence、actual_behavior、expected_behavior、impact、occurred_at 可直接作为顶层参数传入;optional_fields 保留旧调用兼容。顶层字段优先于同名 optional_fields,兼容的 field 数组最后覆盖。
以下是复用冻结现场创建本地报告的调用示例;context_file 使用采集返回的真实路径,项目路径和 Session ID 同样替换为真实值,source 使用实际宿主 Agent:
{
"name": "report_ai_issue",
"arguments": {
"source": "codex",
"cwd": "/workspace/actual-project",
"context_file": "/absolute/path/to/returned-context.json",
"origin_session_id": "demo-origin",
"failure_session_id": "demo-failure",
"report_session_id": "demo-reporter",
"title": "测试编译失败",
"summary": "用户反馈生成的测试编译失败,编译器报告 TS2305。",
"user_description": "刚才生成的测试编译不过,请反馈一下。",
"evidence": [{
"type": "error",
"source": "故障会话中的编译工具返回",
"session_id": "demo-failure",
"tool_call_id": "demo-build-call",
"content": "error TS2305: Module has no exported member 'createMockClient'.",
"exit_code": 2,
"truncated": true
}],
"sink": "local"
}
}同会话直接上报时可按上述参数采集;跨会话或委派上报须先在原始会话调用 CLI context capture,再把返回的 context_file 传入 MCP,防止从上报进程环境采集模型或邮箱。MCP 本次未新增独立的现场冻结工具,也不会自动追溯完整对话。正文格式与 CLI、三种 Agent 入口一致。
资源清单(3 个,只读)
| URI | 内容 |
|---|---|
| ohai-report://schema | Issue 字段 schema 全文(源码 v2.0.0) |
| ohai-report://latest | 当前 workspace 的 latest.json |
| ohai-report://config | sink 默认值 + 公司邮箱域名摘要 |
三端均支持 resources 读取:OpenCode / Codex 用
list_mcp_resources/read_mcp_resource;Claude Code 用@ohai-report:schema引用。
错误协议
所有工具返回 MCP 标准格式 { content: [{type:"text", text:"<JSON>"}], isError }:成功 isError:false;校验失败/sink 错误/未预期异常 isError:true,content[0].text 解析后含 {ok:false, errors?:[] | error, status_code?, body?}。
验证脚本
npm run verify:mcp # MCP 协议级 smoke test(42 项:握手/工具/资源/错误协议)
npm run verify:mcp-clients # 三端集成 smoke test(26 项:v1/v2 配置合法性/启动时间/SIGINT 退出)与 CLI 链路共存:配置正交,但工具同名需二选一
本仓 MCP 链路独立于 setup:setup 只装 CLI 链路(slash command + 插件/hook/skill),不自动注册 MCP server。MCP 注册走各 agent 原生 mcp add(见上「注册到三端 Agent」),注销走各 agent 原生 mcp remove 或本仓 bin ohai-mcp(OpenCode,npx -y -p oh-aireport ohai-mcp unregister opencode)。两条链路可独立启用、互不耦合。
配置层面无冲突:CLI 链路(setup 写入的命令/插件/hook/skill 模板)与 MCP 链路(OpenCode mcp.servers.ohai-report(v2)/ mcp.ohai-report(v1)、Claude mcpServers.ohai-report、Codex [mcp_servers.ohai-report])落在不同配置位置,二者可物理共存。
但工具层面存在同名重叠,OpenCode 尤需注意:
| Agent | CLI 链路暴露的工具 | MCP 链路暴露的工具 | 同名? |
|---|---|---|---|
| OpenCode | 插件 oh-ai-report 的 report_ai_issue(tool: 注册) | MCP server ohai-report 的 report_ai_issue | 是,两者都叫 report_ai_issue |
| Claude Code | /report-ai-issue 命令(prompt 模板,由模型执行) | MCP report_ai_issue 工具 | 命令非工具,但模型执行命令时仍可能改调 MCP 工具 |
| Codex | oh-ai-report skill | MCP report_ai_issue 工具 | skill 与 MCP 工具并存 |
OpenCode 用命名空间区分两个同名工具(插件工具在插件命名空间下,MCP 工具是 tools["ohai-report"].report_ai_issue),不会硬冲突,但模型会同时看到两个 report_ai_issue。
AI 优先调哪个,取决于触发方式(无硬优先级机制):
/report-ai-issueslash command → 确定走 CLI 链路的插件工具。该命令是subtask: true,其指令明确写死「调用 OpenCode 插件工具report_ai_issue」,子任务被指示调插件那个,路径确定。- 自然语言上报(如"帮我反馈这个问题")→ 模型自选,无保证。主 Agent 从可见工具里挑一个
report_ai_issue,两个都在场时取决于模型判断,两者的description都涉及"上报/escalate",可能选任一个。
两个工具的能力差异(最终都调共享的 IssueService,但插件工具更"聪明"):
| 维度 | 插件工具(CLI 链路) | MCP 工具 |
|---|---|---|
| 现场快照注入 | 自动:slash command 子任务注入 context_file;自然语言调用时插件用会话快照 + capture("tool_fallback") 自动采集 | 不自动:仅当入参带 context_file 时复用,否则走 create_fallback 兜底采集 |
| 会话约束 | 有:检查父会话,子任务无快照时返 original_context_required,禁止重新采集 | 无此约束 |
| 底层 | spawn bin/cli.js create → IssueService | 直接调 IssueService |
建议二选一,避免同名工具让模型在自然语言上报时摇摆:
- 依赖
/report-ai-issueslash command + 自动现场冻结 → 只装 CLI 链路(setup opencode/claude/codex),不注册 MCP server。 - 希望走标准 MCP 协议、模型自主发现工具、不依赖 slash command → 只装 MCP,不跑
setup。setup opencode --plugin-only仍会注册插件工具,不能消除同名工具重叠。 - 两条都装只在需要"slash 走插件 + 另有 MCP 原生直连需求"时考虑,且要接受自然语言路径的模型自选行为。
Metadata 来源
--metadata auto 会读取当前会话对应的 .ohai-report/sessions/<scope-hash>/metadata.json、环境变量和 git context;不再从旧根级缓存猜测会话。常用环境变量包括:
OHAI_SESSION_IDOPENCODE_SESSION_IDCODEX_SESSION_IDCODEX_THREAD_IDCLAUDE_SESSION_IDOHAI_HOST_INSTANCE_IDLANGFUSE_SESSION_IDLANGFUSE_TRACE_ID/TRACE_IDLANGFUSE_OBSERVATION_ID/OHAI_OBSERVATION_ID/OBSERVATION_IDOPENCODE_MESSAGE_ID/OHAI_MESSAGE_IDOHAI_OPENCODE_SUBAGENT/OPENCODE_SUBAGENTOPENCODE_MODEL/CODEX_MODEL/OHAI_MODELLANGFUSE_URL/LANGFUSE_TRACE_URLOHAI_USER_ID/OHAI_EMPLOYEE_ID/OPENCODE_EMPLOYEE_ID/LANGFUSE_USER_ID/USER_IDOHAI_USER_EMAIL/USER_EMAIL/GIT_AUTHOR_EMAILOHAI_USER_NAMEOHAI_TEAM
当已有 trace_id 但未配置 langfuse_url 时,如果设置了 LANGFUSE_BASE_URL 或 LANGFUSE_HOST,并提供 LANGFUSE_PROJECT_ID,CLI 会自动拼接 trace 链接。
开发与验证
从源码验证时,在本仓库目录用 node bin/cli.js 替代 npx [email protected]。例如 node bin/cli.js setup all --skip-email 会安装到当前用户配置。
npm run check
npm test
npm pack --dry-run
npm run self:verify -- --targets=opencode --email [email protected]
npm run self:verify -- --targets=codex --email [email protected]目录说明:
| 路径 | 说明 |
| --- | --- |
| bin/cli.js | npm 命令入口(安装、检查、升级、现场采集和报告创建) |
| .opencode/ | OpenCode 命令和插件模板 |
| .claude/ | Claude Code 命令模板 |
| .codex/ | Codex skill 模板 |
| src/installer.js | 纯 JS 安装逻辑(跨平台,替代旧 PowerShell/bash 脚本) |
| scripts/ | Claude hook、Codex wrapper、self-verify 脚本 |
| src/ | JS CLI 实现(create/metadata、sinks、metadata 等) |
| schemas/ | issue payload schema |
| docs/ | 架构和说明文档 |
