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

@linjz/opencode-qqbot

v0.3.15

Published

QQ Bot for OpenCode AI - chat with AI coding assistant via QQ

Readme

OpenCode QQ Bot

通过 QQ 机器人与 OpenCode AI 编程助手对话——双向监控桌面会话、远程发起任务、权限审批与选择弹窗直达 QQ、图片语音双向、长任务不丢答案。

npm version License QQ Bot Bun TypeScript

面向中文用户。OpenCode V2(桌面后台服务)+ QQ 官方开放平台机器人(C2C 单聊 / 群聊 @)。

功能一览

| 能力 | 说明 | |---|---| | 双向对话 | QQ 消息直达 opencode 会话,AI 回复推回 QQ(markdown 渲染、长文自动结构化分条:表格不拆散、代码块围栏自动修补) | | 桌面会话镜像 | 📋 摘要卡:桌面会话的最近一轮问答实时推送到 QQ(默认全文) | | 进度观察 | /watch 订阅工具调用里程碑(🔧 命令摘要/退出码),节流合并推送 | | 权限审批 | opencode 发起权限请求 → QQ 收 🔐 四键卡片(允许一次/总是允许/拒绝/忽略),点按钮静默生效(点击后按钮回显 ✓,其余置灰),也可文字回复"允许/总是/拒绝" | | 选择弹窗桥接 | opencode 的 Form(选择/多选/布尔/文本)→ QQ 📝 卡片,点按钮或回字母(A/B/C)作答;桌面端回合发起的审批/表单同样推送(常驻监听,12s 轮询,bot 空闲也收得到) | | 远程指令 | /new /stop /status /sessions /history /model /agent /rename /watch /mirror /progress /queue /send | | 富媒体 | 收图(原生附件给 AI 看图);收语音(QQ 内置 ASR 免费转文字进 prompt);发图/发文件(AI 回复含 QQ_SEND_FILE: <路径> 标记或 /send <路径> 指令,20MB 上限) | | 引用上下文 | 长按引用某条消息提问,AI 能感知被引用的内容(我方回复也会入索引缓存) | | 长任务不丢 | 前台 30min 超时 → 后台等待(SSE + 轮询,最长 24h);停滞 30min 主动提醒(带「已停滞/状态不明/已终结未回传」状态位 + 最近工具动作 + 无进展时长) | | 投递幂等 | 双层去重:同 msgId 跨进程原子占位 + 同内容在途指纹(窗口=并发在途;已完成消息的重发按重发处理);同文长回复 24h 出站去重;「已收到」受理回执默认关(QQ_ACK_RECEIPT=1 调试召回) | | 重启恢复 | 网关 session/seq 落盘,重启优先 RESUME(服务端只补断线窗口,不重放 backlog);在途台账启动对账——已答补投、在跑重挂、排队挂失只通知永不误派 | | 渲染保真 | 出站有序列表 1. 自动转 1、(QQ 渲染器对 N. 型会跨段续编,实测 N、/一、 完全保真),代码块内不动、幂等 | | 自恢复 | 开机竞态退避、端口漂移自动发现与热换基、巡检告警(QQ 主动消息)、看门狗进程守护、单实例锁心跳 + 60s 周期自检(锁被他人接管/锁文件消失 → 自杀退出,杜绝多实例暗跑) | | 安全 | fail-closed 名单准入(名单外一律拒绝)、下载域白名单、日志密钥打码、推送内容脱敏、危险命令审批由 opencode 权限表驱动(QQ 端四键直达) |

快速开始

前置条件

  1. QQ 机器人凭据:到 QQ 开放平台 创建机器人,拿到 AppID 与 AppSecret(沙箱调试先在管理端配沙箱账号;正式环境需配服务器公网 IP 白名单)。
  2. OpenCode V2 在本机运行(bot 连接其后台服务 API)。
  3. 运行时:bun 或 node 任一(推荐 bun;node ≥ 20 亦可,自动改用内置运行包)。

选形态(二选一)

| | 插件形态(推荐) | 独立部署形态 | |---|---|---| | 适合 | 本机已有 opencode,想装完即用 | 服务器/自定义常驻方式 | | 安装 | opencode plugin add @linjz/opencode-qqbot(或 plugins 数组加 "@linjz/opencode-qqbot") | npm i -g @linjz/opencode-qqbot(或 github:linjz3376/opencode-qqbot) | | 常驻 | 插件自动拉起 bot,serve 重启自动恢复 | 自管:openqq 前台 / systemd / 任务计划 | | 配置入口 | npx @linjz/opencode-qqbot setup(扫码)或手写 ~/.openqq/.env | 同上(装完全局命令也可用 openqq-setup) |

开发者从源码直装插件形态:bun run deploy:plugin(全量包解到全局插件目录,与应用者拿到的发布物一致)。

配置(~/.openqq/.env,单点密钥)

手机 QQ 扫码绑定(自动写凭据;connector 按需临时安装):

npx @linjz/opencode-qqbot setup
# 独立部署形态装过 -g 的话也可直接:openqq-setup

或手工创建:

QQ_APP_ID=你的AppID
QQ_APP_SECRET=你的AppSecret
ALLOWED_USERS=你的QQ openid   # fail-closed:必填,非名单用户一律拒绝
OPENCODE_BASE_URL=http://127.0.0.1:<端口>/api   # opencode 桌面服务地址(2.1.x 端口动态;失联时 bot 启动会自动发现)
OPENCODE_PASSWORD=opencode 服务密码(桌面端服务配置的 Basic auth 密码)
QQ_SANDBOX=false

启动

  • 插件形态:无需手动启动——装好插件 + 配好凭据后,插件巡检自动拉起 bot;opencode 服务重启也会自动恢复。
  • 独立部署形态:openqq 前台运行;常驻按 OS 自选(Windows 用 deploy/ 任务计划脚本;Linux systemd --user;macOS launchd 或 nohup)。

~/.config/systemd/user/openqq.service:

[Unit]
Description=OpenCode QQ Bot
After=network.target

[Service]
Type=simple
ExecStart=openqq
Restart=on-failure
RestartSec=30
# 凭据与数据目录(.env 写入后权限自动 0600)
Environment=HOME=%h

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now openqq
# 登录外也常驻:loginctl enable-linger $USER

~/Library/LaunchAgents/net.opencode-qqbot.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>net.opencode-qqbot</string>
  <key>ProgramArguments</key>
  <array><string>/usr/local/bin/openqq</string></array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/tmp/openqq.out.log</string>
  <key>StandardErrorPath</key><string>/tmp/openqq.err.log</string>
</dict></plist>
launchctl load ~/Library/LaunchAgents/net.opencode-qqbot.plist

单实例:bot 启动时持文件锁(~/.openqq/openqq-<appId>.lock,10s 心跳、30s 僵尸判定)——双开时后到实例待命,宿主退出后自动接管,避免同 bot 多实例被 QQ 网关互踢。QQ_INSTANCE_LOCK=false 可关闭。

跨平台:bot 本体零 OS 分支(纯 TS,与 QQ 官方 SDK 同形态);运行时 bun 优先、node ≥20 自动兜底(跑内置运行包)。Linux/macOS 常驻用 systemd --user 或 nohup 即可;端口自动发现在三个系统都可用(Linux 走 ss -tln,macOS 走 netstat -an -p tcp,Windows 走 netstat -ano -p tcp)。

指令一览

| 指令 | 说明 | |---|---| | /new | 开新会话 | | /stop(别名 /cancel) | 中止当前生成并清空忙碌队列 | | /status | 服务器/会话/模型/Agent 状态 | | /sessions | 列出会话并可选择切换 | | /history [N] | 最近 N 轮历史(默认 3,上限 10;换行/代码块/表格完整保留) | | /model | 查看或切换模型(session 级) | | /agent | 查看或切换 Agent | | /rename <名> | 重命名当前会话 | | /watch / /watch off | 观察模式:工具调用里程碑实时推送 | | /progress | 手动进度查询:工具调用/失败统计、当前在途状态(本地事件源,零模型调用) | | /queue | 忙碌队列:查看 / clear 清空 / drop <编号> 定点删除(忙碌时消息自动 FIFO 排队) | | /mirror | 摘要镜像开关 | | /send <路径> | 把白名单目录内的文件/图片发到 QQ |

环境变量(可选调优)

| 变量 | 默认 | 说明 | |---|---|---| | QQ_ACTIVE_DAILY_LIMIT | 100 | 主动消息日配额(QQ 官方限制 1000/天/关系,留余量) | | QQ_PASSIVE_RIDE_WINDOW_MS | 300000 | 主动降级前"骑"被动窗口的时间窗 | | QQ_STREAM_STAGGER_MS | 300 | 多片回复片间错峰(0=一次性全发) | | QQ_SESSION_IDLE_HOURS | 6 | 闲置会话回收阈值 | | QQ_INTERACTION_WATCH_SECONDS | 12 | 常驻交互监听轮询间隔(0=关闭) | | QQ_REDISPATCH_MAX_AGE_MS | 7200000 | 启动对账时丢失消息的自动重派窗口(0=关闭自动重派只通知;受台账 24h 清账线封顶) | | QQ_ACK_RECEIPT | 关 | 受理即回执气泡「已收到,正在处理」(调试期设 true/on/1 开启) | | QQ_GATEWAY_STATE_MAX_HOURS | 6 | 网关会话持久化恢复窗口(超龄 / RESUME 被拒自动回退 IDENTIFY) | | QQ_EVENT_PROBE | 关 | 插件侧事件探针(true 时全量事件类型落 ~/.openqq/opencode-events.jsonl,诊断用) | | OPENCODE_TURN_TIMEOUT_MINUTES | 30 | 前台回合时限(超时转后台等待) | | QQ_DIGEST_ANSWER_MAX_CHARS | 0(全文) | 摘要卡答案截断上限 | | QQ_HISTORY_USER_CLIP / QQ_HISTORY_TEXT_CLIP | 500 / 1200 | /history 用户/AI 行截断 | | QQ_SEND_EXTRA_ROOTS | — | /send 额外允许目录(逗号分隔) |

架构

四层(每文件带 @input/@output/@pos 头注释):

src/qq/        QQ 传输层(WS 网关 / REST API / 发送器 / 媒体)
src/opencode/  opencode V2 客户端(REST + SSE 事件流 / 会话 / 历史渲染)
src/core/      业务域(审批/卡片/表单桥/投递/镜像/巡检/端口发现/限额/上下文缓存/发文件,及投递幂等 inbound-dedupe、网关持久化 gateway-state、在途台账 inflight-journal、单实例锁 instance-lock)
src/bridge.ts  编排门面 + 命令系统 commands.ts + 入口 index.ts

测试

npm run verify        # tsc + 28 个单元套件(受理幂等/网关持久化/回合归属/渲染适配/台账恢复等)
npm run test:e2e      # 五套 e2e(需 opencode 服务在跑)

排障

| 症状 | 先看 | |---|---| | QQ 无响应 | 日志 %TEMP%\opencode\openqqNN.log;看门狗 %TEMP%\opencode\watchdog.log | | ECONNREFUSED | 桌面服务端口漂移——重启 bot 会自动发现新端口(~/.openqq/last-discovered.json 留痕) | | 桌面弹窗卡住任务 | 后台等待会发带任务的停滞通告(含最近动作与无进展时长);/stop 可终止 | | 日志见「已有实例待命」 | 单实例锁生效中——另一实例持锁(60s 自检会在锁异动时收敛双活,正常无需处理) |

平台注意事项

以下发现来自真实部署(Windows 11 / OpenCode v2.2.2),插件无法修复但会反复绊倒用户,集中存档:

QQ 平台侧

  1. token 接口 POST https://bots.qq.com/app/getAppAccessToken 的参数是 clientSecret(旧文档写作 appSecret);报错 100016 invalid appid or secret 极具误导性——先核对字段名,别急着重置密钥。
  2. token 与正式/沙箱无关,统一走正式域名 bots.qq.com;沙箱域名 sandbox.api.sgroup.qq.com 没有 token 端点(请求会返回 11001 不支持的调用)。
  3. 沙箱 bot 有独立网关:GET https://sandbox.api.sgroup.qq.com/gateway → wss://sandbox.api.sgroup.qq.com/websocket;沙箱 bot 连正式网关会被 4914 拒绝。

OpenCode 侧

  1. opencode plugin add 偶发无输出挂起(>3min),重试通常成功。
  2. opencode reload 只增不删:plugins 数组移除的条目在服务端内存不卸载(旧插件的定时器仍存活),彻底生效需重启服务。
  3. 全局插件目录扫描器只认根级入口(package.json exports 指向 ./dist 子路径会被跳过),仅影响本地目录形态;npm 包形态无此限制。
  4. opencode plugin update 必须带 scope 全名(@linjz/opencode-qqbot),裸写包短名报 Plugin is not configured。
  5. npm 插件缓存在 ~/.cache/opencode/npm/<pkg>@<tag>/<时间戳>/,update 会新建时间戳目录——对「在缓存文件上打本地补丁」的用户,补丁会静默失效;请避免在缓存副本上打补丁。

与 OpenCode 桌面版能力对齐矩阵

QQ 桥的本质是「opencode 交互事件 → QQ 交互原语」的适配器。桌面版 TUI 能处理的每类阻塞式交互,QQ 侧应有对应物(桥接或明确降级):

| 桌面端交互类型 | QQ 侧现状 | 差距 | |---|---|---| | 权限审批(PermissionRequest) | ✅ 四键卡片(允许一次/总是/拒绝/忽略)+ 文字回复 + 桌面端挂起的审批同样推送(常驻监听 12s) | 无 | | 单字段 Form(单选/多选/布尔/文本) | ✅ 字母按钮卡片 + 文本解析 + 30min TTL + form-journal 持久化 | 无 | | 多字段 Form(Questions) | ⚠️ 回退「请在桌面端完成」(明确降级) | 逐字段向导为候选增强(见提案,未实施) | | 未来 opencode 新增交互类型 | ⚠️ 无对齐机制,只能事后逐个补 | 按矩阵验收:要么随版本桥接、要么登记为「明确降级」,不允许出现未定义状态 |

原则:未支持的类型永远给出明确文案 + 桌面端指引,不允许静默丢弃;多字段向导等增强按最小侵入接入。

License

MIT