npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-qq-v2

v0.2.0

Published

QQ bot (C2C) <-> opencode bridge plugin (V2 port)

Readme

opencode-qq (V2 适配版)

把 OpenCode 接入 QQ 单聊的桥接插件:在 QQ 里和 AI 对话,驱动 opencode 干活。

本仓库基于 opencode-qq v0.1.0 移植,使其兼容 OpenCode v2(@opencode/plugin 2.x + EffectTS 运行时)。

功能

  • 对话驱动 opencode:QQ 单聊消息直达 opencode 会话,AI 回复发回 QQ;每个 QQ 用户对应一个长期会话,重启后延续。
  • 图片理解:单聊里发的图片转交给 opencode 多模态处理。
  • 任务完成 / 出错推送:opencode 会话完成(✅)或出错(❌)时主动推送到 QQ。
  • QQ 远程审批权限:opencode 发出权限请求时直接在 QQ 里回复「同意 / 拒绝」。
  • 内置指令:/new 重置会话、/status 查看状态、/help 帮助。

V2 适配改动(相对原版 v0.1.0)

  1. 插件入口:async (input) => Hooks(V1)→ Plugin.define({ id, setup(ctx) })(V2 Promise API)。
  2. 客户端调用:input.client.session.* → ctx.session.*(create / prompt / switchModel)、ctx.permission.reply、ctx.model.default。
  3. 事件模型:message.part.updated → session.text.delta;完成事件 session.idle → session.execution.succeeded;session.error → session.execution.failed。
  4. 工具钩子:tool.execute.after Hooks 回调 → ctx.tool.hook("execute.after", cb)。
  5. 取网关地址补鉴权:GET /gateway 现在要求 Authorization: QQBot <token> 头,原版缺失导致一直 401。
  6. C2C 消息字段修正:发送者 openid 取 d.author.user_openid(原版误用 d.openid),消息 ID 取 d.id(原版误用 d.msg_id)。
  7. 配置路径修正:Windows 上 process.env.HOME 为空,改用 os.homedir()。
  8. 双加载幂等保护:opencode 启动分两阶段加载本地插件,加 started 标志避免重复启动 QQ 网关。
  9. 回复格式:单聊不支持 markdown 消息类型(msg_type:2),默认改纯文本;流式 stream_messages 会产生不完整文本与 ● 收尾标记,默认关闭流式。
  10. 单实例锁 + 自动接管:QQ 网关对同一 bot 只保留一个活跃连接,多实例会互踢。新增 proper-lockfile 跨平台文件锁(锁文件 ~/.config/opencode/opencode-qq-<appId>.lock):只有抢到锁的实例连接 QQ;其余实例进入待命,每 5 秒重试,宿主退出后自动接管(崩溃则靠 30 秒心跳超时判定僵尸锁后接管)。

安装(本地路径)

  1. 克隆本仓库到本地,例如 ~/.config/opencode/plugins/opencode-qq。
  2. 安装依赖:npm install(只需 ws)。
  3. 在 ~/.config/opencode/opencode.json 的 plugin 数组中加入本目录的反斜杠绝对路径:
{
  "plugin": [
    "C:\\Users\\<你>\\ .config\\opencode\\plugins\\opencode-qq"
  ]
}

注意用反斜杠(Windows 原生分隔符),正斜杠会被 opencode 规范化为另一份,导致重复加载。

  1. 重启 opencode。

配置

创建 ~/.config/opencode/opencode-qq.json:

{
  "appId": "你的AppID",
  "appSecret": "你的AppSecret",
  "sandbox": true,
  "allowlist": [],
  "model": "deepseek/deepseek-v4-pro",
  "markdownReply": false,
  "streaming": false,
  "events": { "toolProgress": false }
}

| 字段 | 默认 | 说明 | |------|------|------| | appId / appSecret | 必填 | QQ 开放平台机器人凭据 | | sandbox | false | 未提审上线的 bot 用 true(沙箱环境);已上线用 false | | allowlist | [] | openid 白名单,空 = 不限制 | | model | 无 | 覆盖模型,providerID/modelID;不填用 opencode 全局默认模型 | | markdownReply | true | 是否用 Markdown 发送(单聊请设 false,否则「该消息类型不支持查看」) | | streaming | true | 流式打字机(有截断/● 尾巴问题,建议 false) | | events.toolProgress | false | 是否推送工具执行进度 |

也可用环境变量 QQ_BOT_APPID / QQ_BOT_APPSECRET 代替文件凭据。

多实例行为(单实例锁)

QQ 网关对同一 bot 只保留一个活跃连接,多个 opencode 实例同时连接会互相踢下线。插件用 proper-lockfile 文件锁保证同一 bot 只有一个「宿主」实例连接 QQ。

| 场景 | 行为 | |---|---| | 第 1 个实例启动 | 抢到锁 → 成为宿主 → 连接 QQ | | 第 2 个实例启动 | 抢锁失败 → 待命(不连 QQ,不互踢) | | 宿主正常退出 | 释放锁 | | 宿主崩溃 | 心跳中断,30 秒后锁被判为僵尸锁 | | 待命实例 | 每 5 秒重试抢锁,成功后自动接管 |

  • 锁文件:~/.config/opencode/opencode-qq-<appId>.lock,按 AppID 隔离,不同 bot 互不影响。
  • 心跳:宿主每 10 秒刷新一次锁,证明自己还活着。
  • 僵尸锁:30 秒无心跳视为宿主已死,待命实例可抢占。
  • 接管空窗:宿主退出后,待命实例最多 5 秒(重试间隔)内接管,QQ bot 短暂下线几秒后自动恢复。

前置条件

  1. 在 QQ 开放平台 创建机器人,拿到 AppID 与 AppSecret。
  2. 未上线阶段需在管理端配置沙箱单聊账号,并把 sandbox 设为 true。
  3. 正式环境需在管理端填写服务器公网出口 IP 白名单。

日志

调试日志写入 ~/.config/opencode/opencode-qq.log,包含网关连接、消息收发、会话处理全链路,便于排查。

License

MIT